From 1e366a559be4aec4ad4d3cf3e954b8e62a20d2f3 Mon Sep 17 00:00:00 2001 From: teranisi Date: Mon, 3 Apr 2000 06:59:08 +0000 Subject: [PATCH] Import 1.x. --- BUGS | 1 + BUGS.ja | 1 + COPYING | 16 + ChangeLog | 21 + INSTALL | 180 + INSTALL.ja | 190 + Makefile | 56 + NEWS | 133 + NEWS.ja | 136 + README | 71 + README.ja | 71 + WL-ELS | 107 + WL-MK | 329 ++ doc/TODO.ja | 16 + doc/wl-ja.texi | 5969 +++++++++++++++++++ doc/wl.texi | 6031 ++++++++++++++++++++ elmo/ChangeLog | 14 + elmo/elmo-archive.el | 1054 ++++ elmo/elmo-cache.el | 737 +++ elmo/elmo-cache2.el | 338 ++ elmo/elmo-database.el | 74 + elmo/elmo-date.el | 144 + elmo/elmo-dop.el | 551 ++ elmo/elmo-filter.el | 197 + elmo/elmo-imap4.el | 1588 ++++++ elmo/elmo-internal.el | 263 + elmo/elmo-localdir.el | 466 ++ elmo/elmo-localnews.el | 133 + elmo/elmo-maildir.el | 478 ++ elmo/elmo-msgdb.el | 720 +++ elmo/elmo-multi.el | 365 ++ elmo/elmo-nntp.el | 1349 +++++ elmo/elmo-pipe.el | 142 + elmo/elmo-pop3.el | 673 +++ elmo/elmo-util.el | 1617 ++++++ elmo/elmo-vars.el | 330 ++ elmo/elmo2.el | 1023 ++++ elmo/mmelmo-1.el | 110 + elmo/mmelmo-2.el | 142 + elmo/mmelmo-imap4-1.el | 350 ++ elmo/mmelmo-imap4-2.el | 394 ++ elmo/mmelmo-imap4.el | 41 + elmo/mmelmo.el | 159 + elmo/utf7.el | 258 + etc/ChangeLog.1.ja | 2031 +++++++ etc/ChangeLog.2 | 1608 ++++++ etc/ChangeLog.2.ja | 1290 +++++ etc/ChangeLog.3 | 2967 ++++++++++ etc/ChangeLog.3.ja | 3066 ++++++++++ etc/icons/archive.xpm | 28 + etc/icons/closed.xpm | 23 + etc/icons/draft.xpm | 25 + etc/icons/elmo.xpm | 19 + etc/icons/filter.xpm | 34 + etc/icons/imap.xpm | 27 + etc/icons/internal.xpm | 29 + etc/icons/local.xpm | 26 + etc/icons/localnews.xpm | 24 + etc/icons/maildir.xpm | 26 + etc/icons/multi.xpm | 25 + etc/icons/news.xpm | 24 + etc/icons/opened.xpm | 24 + etc/icons/pipe.xpm | 28 + etc/icons/plugged.xpm | 28 + etc/icons/pop.xpm | 26 + etc/icons/queue.xpm | 27 + etc/icons/trash-e.xpm | 24 + etc/icons/trash.xpm | 25 + etc/icons/unplugged.xpm | 28 + etc/icons/wl-draft-insert-signature-up.xpm | 38 + etc/icons/wl-draft-kill-up.xpm | 43 + etc/icons/wl-draft-send-from-toolbar-down.xpm | 42 + etc/icons/wl-draft-send-from-toolbar-up.xpm | 41 + etc/icons/wl-draft-up.xpm | 42 + etc/icons/wl-draft-yank-original-up.xpm | 42 + etc/icons/wl-exit-up.xpm | 42 + etc/icons/wl-folder-check-current-entity-up.xpm | 43 + etc/icons/wl-folder-empty-trash-up.xpm | 42 + ...wl-folder-jump-to-current-entity-no-sync-up.xpm | 41 + etc/icons/wl-folder-jump-to-current-entity-up.xpm | 41 + etc/icons/wl-folder-next-entity-up.xpm | 53 + etc/icons/wl-folder-prev-entity-up.xpm | 53 + etc/icons/wl-folder-read-up.xpm | 55 + etc/icons/wl-folder-select-entity-up.xpm | 55 + etc/icons/wl-folder-sync-current-entity-up.xpm | 55 + etc/icons/wl-folder-zoom-entity-up.xpm | 55 + etc/icons/wl-logo.xbm | 622 ++ etc/icons/wl-logo.xpm | 438 ++ etc/icons/wl-message-extract-content-up.xpm | 43 + etc/icons/wl-message-next-content-up.xpm | 53 + etc/icons/wl-message-play-content-up.xpm | 41 + etc/icons/wl-message-prev-content-up.xpm | 53 + etc/icons/wl-message-quit-up.xpm | 42 + etc/icons/wl-message-read-up.xpm | 55 + etc/icons/wl-summary-delete-up.xpm | 43 + etc/icons/wl-summary-exit-up.xpm | 42 + etc/icons/wl-summary-forward-up.xpm | 41 + .../wl-summary-jump-to-current-message-up.xpm | 42 + etc/icons/wl-summary-mark-as-important-up.xpm | 43 + etc/icons/wl-summary-next-page-up.xpm | 53 + etc/icons/wl-summary-next-up.xpm | 53 + etc/icons/wl-summary-prev-page-up.xpm | 53 + etc/icons/wl-summary-prev-up.xpm | 53 + etc/icons/wl-summary-read-up.xpm | 55 + etc/icons/wl-summary-reply-up.xpm | 42 + etc/icons/wl-summary-reply-with-citation-up.xpm | 42 + etc/icons/wl-summary-sync-force-update-up.xpm | 55 + etc/ja.Emacs | 100 + samples/en/dot.addresses | 15 + samples/en/dot.folders | 72 + samples/en/dot.wl | 372 ++ samples/ja/dot.addresses | 13 + samples/ja/dot.folders | 73 + samples/ja/dot.wl | 382 ++ utils/bbdb-wl.el | 254 + utils/im-wl.el | 178 + utils/rfc2368.el | 152 + utils/sasl/README.en | 17 + utils/sasl/lisp/digest-md5.el | 144 + utils/sasl/lisp/hex-util.el | 73 + utils/sasl/lisp/hmac-def.el | 85 + utils/sasl/lisp/hmac-md5.el | 95 + utils/sasl/lisp/hmac-sha1.el | 80 + utils/sasl/lisp/md5-dl.el | 66 + utils/sasl/lisp/md5-el.el | 408 ++ utils/sasl/lisp/md5.el | 65 + utils/sasl/lisp/sasl.el | 156 + utils/sasl/lisp/scram-md5.el | 154 + utils/sasl/lisp/sha1-dl.el | 56 + utils/sasl/lisp/sha1-el.el | 408 ++ utils/sasl/lisp/sha1.el | 77 + utils/sasl/lisp/unique-id.el | 92 + utils/sasl/src/md5-dl.c | 85 + utils/sasl/src/sha1-dl.c | 84 + utils/ssl.el | 201 + utils/wl-mailto.el | 130 + wl/ChangeLog | 31 + wl/tm-wl.el | 285 + wl/wl-address.el | 381 ++ wl/wl-demo.el | 201 + wl/wl-dnd.el | 103 + wl/wl-draft.el | 1854 ++++++ wl/wl-expire.el | 729 +++ wl/wl-fldmgr.el | 1388 +++++ wl/wl-folder.el | 2679 +++++++++ wl/wl-highlight.el | 1224 ++++ wl/wl-message.el | 615 ++ wl/wl-mime.el | 369 ++ wl/wl-mule.el | 299 + wl/wl-nemacs.el | 172 + wl/wl-refile.el | 204 + wl/wl-score.el | 1499 +++++ wl/wl-summary.el | 5872 +++++++++++++++++++ wl/wl-template.el | 194 + wl/wl-thread.el | 1427 +++++ wl/wl-util.el | 820 +++ wl/wl-vars.el | 1949 +++++++ wl/wl-xmas.el | 463 ++ wl/wl.el | 811 +++ 159 files changed, 68923 insertions(+) create mode 100644 BUGS create mode 100644 BUGS.ja create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 INSTALL create mode 100644 INSTALL.ja create mode 100644 Makefile create mode 100644 NEWS create mode 100644 NEWS.ja create mode 100644 README create mode 100644 README.ja create mode 100644 WL-ELS create mode 100644 WL-MK create mode 100644 doc/TODO.ja create mode 100644 doc/wl-ja.texi create mode 100644 doc/wl.texi create mode 100644 elmo/ChangeLog create mode 100644 elmo/elmo-archive.el create mode 100644 elmo/elmo-cache.el create mode 100644 elmo/elmo-cache2.el create mode 100644 elmo/elmo-database.el create mode 100644 elmo/elmo-date.el create mode 100644 elmo/elmo-dop.el create mode 100644 elmo/elmo-filter.el create mode 100644 elmo/elmo-imap4.el create mode 100644 elmo/elmo-internal.el create mode 100644 elmo/elmo-localdir.el create mode 100644 elmo/elmo-localnews.el create mode 100644 elmo/elmo-maildir.el create mode 100644 elmo/elmo-msgdb.el create mode 100644 elmo/elmo-multi.el create mode 100644 elmo/elmo-nntp.el create mode 100644 elmo/elmo-pipe.el create mode 100644 elmo/elmo-pop3.el create mode 100644 elmo/elmo-util.el create mode 100644 elmo/elmo-vars.el create mode 100644 elmo/elmo2.el create mode 100644 elmo/mmelmo-1.el create mode 100644 elmo/mmelmo-2.el create mode 100644 elmo/mmelmo-imap4-1.el create mode 100644 elmo/mmelmo-imap4-2.el create mode 100644 elmo/mmelmo-imap4.el create mode 100644 elmo/mmelmo.el create mode 100644 elmo/utf7.el create mode 100644 etc/ChangeLog.1.ja create mode 100644 etc/ChangeLog.2 create mode 100644 etc/ChangeLog.2.ja create mode 100644 etc/ChangeLog.3 create mode 100644 etc/ChangeLog.3.ja create mode 100644 etc/icons/archive.xpm create mode 100644 etc/icons/closed.xpm create mode 100644 etc/icons/draft.xpm create mode 100644 etc/icons/elmo.xpm create mode 100644 etc/icons/filter.xpm create mode 100644 etc/icons/imap.xpm create mode 100644 etc/icons/internal.xpm create mode 100644 etc/icons/local.xpm create mode 100644 etc/icons/localnews.xpm create mode 100644 etc/icons/maildir.xpm create mode 100644 etc/icons/multi.xpm create mode 100644 etc/icons/news.xpm create mode 100644 etc/icons/opened.xpm create mode 100644 etc/icons/pipe.xpm create mode 100644 etc/icons/plugged.xpm create mode 100644 etc/icons/pop.xpm create mode 100644 etc/icons/queue.xpm create mode 100644 etc/icons/trash-e.xpm create mode 100644 etc/icons/trash.xpm create mode 100644 etc/icons/unplugged.xpm create mode 100644 etc/icons/wl-draft-insert-signature-up.xpm create mode 100644 etc/icons/wl-draft-kill-up.xpm create mode 100644 etc/icons/wl-draft-send-from-toolbar-down.xpm create mode 100644 etc/icons/wl-draft-send-from-toolbar-up.xpm create mode 100644 etc/icons/wl-draft-up.xpm create mode 100644 etc/icons/wl-draft-yank-original-up.xpm create mode 100644 etc/icons/wl-exit-up.xpm create mode 100644 etc/icons/wl-folder-check-current-entity-up.xpm create mode 100644 etc/icons/wl-folder-empty-trash-up.xpm create mode 100644 etc/icons/wl-folder-jump-to-current-entity-no-sync-up.xpm create mode 100644 etc/icons/wl-folder-jump-to-current-entity-up.xpm create mode 100644 etc/icons/wl-folder-next-entity-up.xpm create mode 100644 etc/icons/wl-folder-prev-entity-up.xpm create mode 100644 etc/icons/wl-folder-read-up.xpm create mode 100644 etc/icons/wl-folder-select-entity-up.xpm create mode 100644 etc/icons/wl-folder-sync-current-entity-up.xpm create mode 100644 etc/icons/wl-folder-zoom-entity-up.xpm create mode 100644 etc/icons/wl-logo.xbm create mode 100644 etc/icons/wl-logo.xpm create mode 100644 etc/icons/wl-message-extract-content-up.xpm create mode 100644 etc/icons/wl-message-next-content-up.xpm create mode 100644 etc/icons/wl-message-play-content-up.xpm create mode 100644 etc/icons/wl-message-prev-content-up.xpm create mode 100644 etc/icons/wl-message-quit-up.xpm create mode 100644 etc/icons/wl-message-read-up.xpm create mode 100644 etc/icons/wl-summary-delete-up.xpm create mode 100644 etc/icons/wl-summary-exit-up.xpm create mode 100644 etc/icons/wl-summary-forward-up.xpm create mode 100644 etc/icons/wl-summary-jump-to-current-message-up.xpm create mode 100644 etc/icons/wl-summary-mark-as-important-up.xpm create mode 100644 etc/icons/wl-summary-next-page-up.xpm create mode 100644 etc/icons/wl-summary-next-up.xpm create mode 100644 etc/icons/wl-summary-prev-page-up.xpm create mode 100644 etc/icons/wl-summary-prev-up.xpm create mode 100644 etc/icons/wl-summary-read-up.xpm create mode 100644 etc/icons/wl-summary-reply-up.xpm create mode 100644 etc/icons/wl-summary-reply-with-citation-up.xpm create mode 100644 etc/icons/wl-summary-sync-force-update-up.xpm create mode 100644 etc/ja.Emacs create mode 100644 samples/en/dot.addresses create mode 100644 samples/en/dot.folders create mode 100644 samples/en/dot.wl create mode 100644 samples/ja/dot.addresses create mode 100644 samples/ja/dot.folders create mode 100644 samples/ja/dot.wl create mode 100644 utils/bbdb-wl.el create mode 100644 utils/im-wl.el create mode 100644 utils/rfc2368.el create mode 100644 utils/sasl/README.en create mode 100644 utils/sasl/lisp/digest-md5.el create mode 100644 utils/sasl/lisp/hex-util.el create mode 100644 utils/sasl/lisp/hmac-def.el create mode 100644 utils/sasl/lisp/hmac-md5.el create mode 100644 utils/sasl/lisp/hmac-sha1.el create mode 100644 utils/sasl/lisp/md5-dl.el create mode 100644 utils/sasl/lisp/md5-el.el create mode 100644 utils/sasl/lisp/md5.el create mode 100644 utils/sasl/lisp/sasl.el create mode 100644 utils/sasl/lisp/scram-md5.el create mode 100644 utils/sasl/lisp/sha1-dl.el create mode 100644 utils/sasl/lisp/sha1-el.el create mode 100644 utils/sasl/lisp/sha1.el create mode 100644 utils/sasl/lisp/unique-id.el create mode 100644 utils/sasl/src/md5-dl.c create mode 100644 utils/sasl/src/sha1-dl.c create mode 100644 utils/ssl.el create mode 100644 utils/wl-mailto.el create mode 100644 wl/ChangeLog create mode 100644 wl/tm-wl.el create mode 100644 wl/wl-address.el create mode 100644 wl/wl-demo.el create mode 100644 wl/wl-dnd.el create mode 100644 wl/wl-draft.el create mode 100644 wl/wl-expire.el create mode 100644 wl/wl-fldmgr.el create mode 100644 wl/wl-folder.el create mode 100644 wl/wl-highlight.el create mode 100644 wl/wl-message.el create mode 100644 wl/wl-mime.el create mode 100644 wl/wl-mule.el create mode 100644 wl/wl-nemacs.el create mode 100644 wl/wl-refile.el create mode 100644 wl/wl-score.el create mode 100644 wl/wl-summary.el create mode 100644 wl/wl-template.el create mode 100644 wl/wl-thread.el create mode 100644 wl/wl-util.el create mode 100644 wl/wl-vars.el create mode 100644 wl/wl-xmas.el create mode 100644 wl/wl.el diff --git a/BUGS b/BUGS new file mode 100644 index 0000000..5495f34 --- /dev/null +++ b/BUGS @@ -0,0 +1 @@ +Cannot communicate with UW imapd with qmail patch. diff --git a/BUGS.ja b/BUGS.ja new file mode 100644 index 0000000..92aadd5 --- /dev/null +++ b/BUGS.ja @@ -0,0 +1 @@ +qmail $BBP1~$N(B UW imapd $B$N%a%C%;!<%8$r07$($J$$!#(B diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..0744792 --- /dev/null +++ b/COPYING @@ -0,0 +1,16 @@ +Copyright (C) 1998,1999,2000 Yuuichi Teranishi + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Emacs; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..e4cc6a4 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,21 @@ +2000-03-30 Yuuichi Teranishi + + * wl/ChangeLog: New file. + * elmo/ChangeLog: New file. + * etc/ChangeLog.1.ja: Renamed from etc/ChangeLog.alpha.ja. + * etc/ChangeLog.2: Renamed from etc/ChangeLog.beta. + * etc/ChangeLog.2.ja: Renamed from etc/ChangeLog.beta.ja. + * etc/ChangeLog.3: Renamed from ChangeLog. + * etc/ChangeLog.3.ja: Renamed from ChangeLog.ja. + + * WL-MK (WLDIR): Changed to "./wl". + (ICONDIR): New variable. + (config-wl-package-subr): set wl-icon-dir as ICONDIR. + (compile-wl-package-xmas): refer WLDIR. + + * README.ja: Renamed from 00README.ja. + * README: Renamed from 00README. + + * wl: New directory. + All wl-related files are moved to this directory. + diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..bce4642 --- /dev/null +++ b/INSTALL @@ -0,0 +1,180 @@ + + How to install Wanderlust + + Time-stamp: <00/03/14 20:05:52 teranisi> + Kaoru Takahashi, + Yuuichi Teranishi, + Tsunehiko Baba + +Required environment +==================== + + Before installing Wanderlust, please install either of the following + MIME modules. SEMI is recommended because it's more functional. + + SEMI (1.13.4 or later) + tm (8.7 or later) + + If you use Mule based on Emacs 19.28 or earlier, please install tm. + SEMI does not support Emacs 19.28 or earlier. + + SEMI only supports relatively new Emacsen like Emacs 20.xx, XEmacs, etc. + But Mule based on Emacs 19.34 can also run SEMI. + See the following web page to get more information (written by Japanese). + + http://www.jpl.org/elips/INSTALL-SEMI-ja.html + + +(a) SEMI + + SEMI requires APEL and FLIM packages. + Recommended combination of APEL, FLIM and SEMI are: + + APEL 10.2, FLIM 1.12.7 and SEMI 1.13.4 + or + APEL 10.2, FLIM 1.13.2 and SEMI 1.13.7 + + Combination of APEL 10.2 and FLIM 1.12.7 makes following error + while compiling FLIM 1.12.7. + + 'Please install latest APEL 7.3 or later.' + + In this case, please comment out following lines in FLIM-CFG. + + (or (fboundp 'write-region-as-binary) + (error "Please install latest APEL 7.3 or later.")) + (or (fboundp 'insert-file-contents-as-binary) + (error "Please install latest APEL 7.3 or later.")) + + You can download these packages from following URLs. + + APEL: ftp://ftp.m17n.org/mule/apel/ + FLIM: ftp://ftp.m17n.org/mule/flim/ + SEMI: ftp://ftp.m17n.org/mule/semi/ + + Please install APEL, FLIM, SEMI in order. + Generally 'make install' will do the job. + To get full information, please refer README.en within each package. + + You can also use many other FLIM/SEMI variants. + Combination of the latest versions should work. + For example, following combination is confirmed to work. + + APEL 10.2, Chao 1.14.1 and REMI 1.14.1 + +(b) tm + + The tm, whose version is 8.7 or later, is recommended. Please + obtain from the following web site. + + http://cvs.m17n.org/tomo/comp/emacsen/tm/tm-8/ + + To get full information, please refer README.en within package. + + +Installation +============ + +(a) Edit Makefile + + Edit EMACS, LISPDIR, and so on in Makefile. + + EMACS Emacs command name. + LISPDIR site-lisp directory. + + If LISPDIR is not specified (or NONE by default), it is automatically + detected. + +(b) Bytecompile and Install + + Please do following. + + % make + % make install + + If you use Emacs without subdirs.el (e.g. Mule 2.3 based on Emacs + 19.28), the following error message ocasinally appears. + + Cannot open load file: mime-setup + + In this case, add directories of custom, APEL, FLIM, SEMI to + EMACSLOADPATH (environment variable), or add those directories to + load-path in WL-CFG. + + +Install as a XEmacs package +=========================== + + Wanderlust is able to be installed as one of XEmacs (21.0 or later) + packages. After installation as a XEmacs package, you do not need + configurations of autoload, icon path in your own .emacs file. + +(a) Edit Makefile + + Edit XEMACS, PACKAGEDIR, and so on in Makefile. + + XEMACS XEmacs command name. + PACKAGEDIR package directory. + + If PACKAGEDIR is not specified (NONE by default) and the SEMI + modules have been installed, it is automatically detected. + +(b) Bytecompile and Install + + Please do following. + + % make package + % make install-package + + Install with Info file. + + +load-path +========= + + If you are using Emacs 20.3 or later, or XEmacs, there are no need + of setting about load-path. + + If you are using Emacs 20.2 or earlier, please add directory of + Wanderlust to load-path. + + If you install by default setting, with Emacs 19.29 or later, Emacs + 20.1, or Emacs 20.2, you can write subdirs.el for example: + + -------------------------------------------------------------------- + (normal-top-level-add-to-load-path + '("apel" "flim" "semi" "wl")) + -------------------------------------------------------------------- + + If you are using Emacs 19.28 or earlier, you can't use subdirs.el. + Please you write setting about load-path in site configuration file. + + +Manual +====== + + Manual is described in Info format. Please do following. + + % make info + % make install-info + + If you install Wanderlust as a XEmacs package, Info file is already + installed too, so there are no need of these commands. + + Manual directory is automatically detected. Of course, it can be + configured by INFODIR in Makefile. + + +Sample configuration file +========================= + + Wanderlust requires following three configuration files. + + ~/.addresses Address Book + ~/.folders Folder Book + ~/.wl Wanderlust Configuration (loaded at startup) + + Each sample file (dot.addresses, dot.folders, dot.wl) exists on + samples/en/ directory. Please refer them. + + To get full information, please read Info file. diff --git a/INSTALL.ja b/INSTALL.ja new file mode 100644 index 0000000..a238f52 --- /dev/null +++ b/INSTALL.ja @@ -0,0 +1,190 @@ + + Wanderlust $B$N%$%s%9%H!<%kJ}K!(B + + Time-stamp: <00/03/14 20:06:38 teranisi> + Kaoru Takahashi $B9b660j(B, + Yuuichi Teranishi $B;{@>M50l(B + +MIME$BMQ%b%8%e!<%k$N%$%s%9%H!<%k(B +============================== + + Wanderlust $B$r;H$&$?$a$K$O!"0J2<$N$I$A$i$+$N(B MIME $BMQ%b%8%e!<%k$r%$%s(B + $B%9%H!<%k$7$F$*$/I,MW$,$"$j$^$9!#5!G=$,=<e(B) + tm (8.7 $B0J>e(B) + + Emacs 19.28 $B0JA0$r%Y!<%9$H$7$?(B Mule $B$r$*;H$$$N>l9g$O(B tm $B$r%$%s%9%H!<(B + $B%k$7$F$/$@$5$$!#(BSEMI $B$OF0$-$^$;$s!#(B + + Emacs 19.34 $B%Y!<%9$N(B Mule $B$G$O(B SEMI $B$rF0:n$5$;$k$3$H$b2DG=$G$9!#(B + $B2<5-$N%Z!<%8$,;29M$K$J$j$^$9!#(B + + http://www.jpl.org/elips/INSTALL-SEMI-ja.html + + +(a) SEMI $B$N%$%s%9%H!<%k(B + + SEMI $B$K$O(B APEL, FLIM $B$H8F$P$l$k%Q%C%1!<%8$bI,MW$G$9!#(B + $B?d>)$5$l$k(B APEL, FLIM, SEMI $B$NAH9g$;$O0J2<$NDL$j$G$9!#(B + + APEL 10.2, FLIM 1.12.7, SEMI 1.13.4 + $B$^$?$O!"(B + APEL 10.2, FLIM 1.13.2, SEMI 1.13.7 + + APEL 10.2 $B$H(B FLIM 1.12.7 $B$NAH9g$;$G$O!"(BFLIM 1.12.7 $B$N%3%s%Q%$%k;~$K(B + + 'Please install latest APEL 7.3 or later.' + + $B$H$$$&%(%i!<$,H/@8$9$k>l9g$,$"$j$^$9!#$3$N>l9g!"(BFLIM-CFG $B$N0J2<$N9T$r(B + $B%3%a%s%H%"%&%H$7$F2<$5$$!#(B + + (or (fboundp 'write-region-as-binary) + (error "Please install latest APEL 7.3 or later.")) + (or (fboundp 'insert-file-contents-as-binary) + (error "Please install latest APEL 7.3 or later.")) + + APEL, FLIM, SEMI, $B%Q%C%1!<%8$O$=$l$>$l0J2<$N(B URL $B$GF~\$7$$%$%s%9%H!<%k$NJ}K!$O3F%Q%C%1!<%8$KE:IU$5$l$F$$$k%I%-%e%a%s%H(B + (README.ja, README.en) $B$r;2>H$7$F$/$@$5$$!#(B + + $B$=$NB>!"(BFLIM, SEMI $B$K$O$$$m$$$m$JJQ7A%P!<%8%g%s$,B8:_$7$^$9$,!"(B + $B$=$l$i$N$$$:$l$bMxMQ$9$k$3$H$,2DG=$G$9!#(B + $B4pK\E*$K:G?7HG$NAH9g$;$J$iF0:n$9$k$O$:$G$9!#(B + $BNc$($P!"0J2<$NAH9g$;$NF0:n$,3NG'$5$l$F$$$^$9!#(B + + APEL 10.2, Chao 1.14.1, REMI 1.14.1 + +(b) tm $B$N%$%s%9%H!<%k(B + + tm 8.7 $B0J9_$N%P!<%8%g%s$,I,MW$G$9!#F~\$7$$%$%s%9%H!<%k$NJ}K!$O%Q%C%1!<%8$KE:IU$5$l$F$$$k%I%-%e%a%s%H(B + (README.en) $B$r;2>H$7$F$/$@$5$$!#(B + + +$BDL>o$N%$%s%9%H!<%k(B +================== + +(a)Makefile $B$NJT=8(B + + Makefile $B$O!"(BEMACS, LISPDIR $B$NItJ,$rJT=8$7$F$/$@$5$$!#(B + + EMACS $B;HMQ$7$F$$$k(B Emacs $B$N%3%^%s%IL>$r;XDj(B + LISPDIR $B%$%s%9%H!<%k@h$r;XDj(B + + LISPDIR $B$OFC$K;XDj$7$J$/$F$b(B (NONE $B$N$^$^$G$b(B) $B<+F0E*$K%$%s%9%H!<%k(B + $B@h$r8!=P$7$^$9!#(B + +(b)$B%P%$%H%3%s%Q%$%k!&%$%s%9%H!<%k(B + + $B0J2<$rl9g$O!"(Bcustom, APEL, FLIM, SEMI $B$N%$%s%9%H!<%k@h$r4D6-JQ?t(B + EMACSLOADPATH $B$K2C$($k$+!"E83+%G%#%l%/%H%j$N(B WL-CFG $B$H$$$&%U%!%$%kCf(B + $B$G(B load-path $B$rDL$7$F$*$/$H$h$$$G$7$g$&!#(B + + +XEmacs $B$N%Q%C%1!<%8$H$7$F%$%s%9%H!<%k(B +===================================== + + Wanderlust $B$O(B XEmacs (21.0 $B0J9_(B) $B$N%Q%C%1!<%8$N$R$H$D$H$7$F%$%s%9%H!<(B + $B%k$9$k$3$H$b2DG=$G$9!#%Q%C%1!<%8$H$7$F%$%s%9%H!<%k$9$k$H!"(Bautoload + $B$N@_Dj!"%"%$%3%s$N%Q%9@_Dj$r8D?M$N(B .emacs $B$K5-=R$7$J$/$F$b(B + Wanderlust $B$r@5>o$K5/F0$G$-$k$h$&$K$J$j$^$9!#(B + +(a)Makefile $B$NJT=8(B + + Makefile $B$O!"(BXEMACS, PACKAGEDIR $B$NItJ,$rJT=8$7$F$/$@$5$$!#(B + + XEMACS $B;HMQ$7$F$$$k(B XEmacs $B$N%3%^%s%IL>$r;XDj(B + PACKAGEDIR package $B$N%G%#%l%/%H%j$r;XDj(B + + PACKAGEDIR $B$OFC$K;XDj$7$J$/$F$b(B (NONE $B$N$^$^$G$b(B)$B!"(BSEMI $B$,%$%s%9%H!<(B + $B%k$5$l$F$$$l$P<+F0E*$K8!=P$5$l$^$9!#(B + + +(b)$B%P%$%H%3%s%Q%$%k!&%$%s%9%H!<%k(B + + $B0J2<$rl9g$O!"(B + load-path $B$r@_Dj$9$kI,MW$O$"$j$^$;$s!#(B + + Emacs 20.2 $B0JA0$r$*;H$$$J$i!"(BWanderlust $B$r(B install $B$7$?>l=j$r(B + load-path $B$K@_Dj$7$F$/$@$5$$!#(B + + $B$b$7(B Emacs 19.29 $B0J9_$^$?$O(B Emacs 20.1, Emacs 20.2 $B$r;H$C$F=i4|@_Dj(B + $B$G%$%s%9%H!<%k$7$?$N$J$i!"l9g$O<+F0E*$K(B Info $B%U%!%$%k(B + $B$b%$%s%9%H!<%k$5$l$k$N$G$3$l$i$NA`:n$OI,MW$"$j$^$;$s!#(B + + $B%^%K%e%"%k$N%$%s%9%H!<%k@h$O<+F08!=P$5$l$^$9!#(B(Makefile $BCf$N(B INFODIR + $B$G$b@_Dj2DG=$G$9(B) + + +$B%5%s%W%k@_Dj(B +============ + + Wanderlust $B$N@_Dj%U%!%$%k$K$O!"(B + + ~/.addresses $B%"%I%l%9D"(B + ~/.folders $B%U%)%k%@@_Dj(B + ~/.wl Wanderlust $B$N@_Dj(B ($B5/F0;~$KFI$_9~$^$l$k(B) + + $B$N;0$D$,$"$j$^$9!#(B + + $B$=$l$>$l!"(Bsamples/ja/ $B%G%#%l%/%H%j$N2<$K%5%s%W%k@_Dj(B + (dot.addresses, dot.folders, dot.wl) $B$,$"$j$^$9$N$G!"(B + $B3F<+$G%[!<%`%G%#%l%/%H%j$K%3%T!<$7$FJT=8$9$k$J$I$7$F$/$@$5$$!#(B + + $B>\$7$$@_Dj$O(B Info $B$r8fMw$/$@$5$$!#(B diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..55874cd --- /dev/null +++ b/Makefile @@ -0,0 +1,56 @@ +# +# Please specify your Emacs here. +# +EMACS = emacs +# To install Wanderlust for XEmacs 21 or later, +# running 'make install-package' is recommended. +# 'make install-package' refers $XEMACS instead of $EMACS. +XEMACS = xemacs +# +# Target directory to install the Wanderlust package. +# (Automatically detected if this line is unchanged.) +# +LISPDIR = NONE +#LISPDIR = /usr/local/lib/mule/site-lisp + +INFODIR = NONE +#INFODIR = /usr/local/share/info + +# For XEmacs package. +PACKAGEDIR = NONE + + +################# No need to modify following lines #################### +FLAGS = -batch -q -no-site-file + +elc: + $(EMACS) $(FLAGS) -l WL-MK -f compile-wl-package $(LISPDIR) + +install-elc: + $(EMACS) $(FLAGS) -l WL-MK -f install-wl-package $(LISPDIR) + +uninstall-elc: + $(EMACS) $(FLAGS) -l WL-MK -f uninstall-wl-package $(LISPDIR) + +clean-elc: + rm -f wl/*.elc wl/auto-autoloads.el wl/custom-load.el elmo/*.elc utils/*.elc utils/hmac/lisp/*.elc + +package: + $(XEMACS) $(FLAGS) -l WL-MK -f compile-wl-package-xmas $(PACKAGEDIR) + +install-package: + $(XEMACS) $(FLAGS) -l WL-MK -f install-wl-package-xmas $(PACKAGEDIR) + +info: + $(EMACS) $(FLAGS) -l WL-MK -f wl-texinfo-format $(INFODIR) + +install-info: + $(EMACS) $(FLAGS) -l WL-MK -f install-wl-info $(INFODIR) + +all: elc + +install: install-elc + +uninstall: uninstall-elc + +clean: clean-elc diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..9846dd2 --- /dev/null +++ b/NEWS @@ -0,0 +1,133 @@ +Wanderlust NEWS -- User-visible changes in Wanderlust. 21 Mar 2000 + +* Changes in version 1.1.1. + +** Directory structure is changed. + +*** 00README, 00README.ja is renamed to README, README.ja. + +*** All wl-* files are moved to the directory 'wl'. + +* Changes in version 1.1.0 from 1.0.3. + +** Install + +*** tm7 is not supported anymore. +see the file INSTALL for details. + +*** WL_PREFIX and ELMO_PREFIX default as "wl" +(defvar WL_PREFIX "wl") +(defvar ELMO_PREFIX "wl") + +e.g. install directory is + 1.0.3 /usr/local/share/emacs/site-lisp/ + 1.1.0 /usr/local/share/emacs/site-lisp/wl/ + +*** Change default macro in Makefile. +EMACS = emacs +XEMACS = xemacs +use $(XEMACS), `package' and `install-package' target. + +*** Install not only *.elc, but also *.el. + +*** English document (wl.texi). + +** New feature + +*** Modified UTF7 support. +Now international mailbox name can be used in IMAP4 in the Emacsen +with unicode feature. + +*** Scoring support. + +*** New plugged system. + +*** IMAP4 support became more generic. +Many IMAP4 servers are supported. + +*** New authentication type + IMAP4: CRAM-MD5, DIGEST-MD5, STARTTLS + POP3: CRAM-MD5, DIGEST-MD5, SCRAM-MD5, STARTTLS + NNTP: STARTTLS + SMTP: STARTTLS + +*** New folder type + | Pipe Folder Incorporate message. + . Maildir Folder Now Maildir is one of the folder type. + 'cache Cache Folder View internal cache. + +*** Message buffer cache +Next message is prefetched while idle time. + +*** Sticky summary is enhanced. +Now message buffer is also sticky. +You can specify always-sticky summary. + +** misc + +*** Eliminated wl-draft-prepared-config-alist +unified with wl-draft-config-alist. + +*** POP-before-SMTP variables are re-arranged. + +*** Ask non-existing folder. + When FCC: contains new folder. + When auto-refile specified new folder. + +*** Change fetch threshold and confirm settings. +wl-prefetch-confirm-threshold, wl-cache-fetch-threshold. + +*** Can use petname for completion. + +*** Change Message-ID generator. + +*** wl-demo.el support bitmap-mule. + +*** Allow function type `smtp-server' value. + +*** Make sendlog when `wl-draft-sendlog' is non-nil. + +*** `wl-summary-incorporate-marks' + +*** Reserve prefetching while off-line status. + +*** Draft use new frame when `wl-draft-use-frame' is non-nil. + +*** New variable `wl-user-mail-address-list' . + +*** New variable `wl-local-domain' for set FQDN. + +*** Server side unread status is used in IMAP4 folder. + +*** Change defaults + wl-mime-charset iso-2022-jp => x-ctext + wl-summary-move-order 'new => 'unread + wl-tmp-dir TMPDIR => ~/tmp/ + +*** New hooks + wl-draft-send-hook + wl-draft-reedit-hook + wl-mime-edit-preview-message-hook + wl-folder-suspend-hook + wl-summary-toggle-disp-folder-message-resumed-hook + wl-summary-line-inserted-hook + wl-thread-update-children-number-hook + mmelmo-header-inserted-hook + mmelmo-entity-content-inserted-hook + +*** New function + wl-save + wl-summary-write + wl-summary-supersedes-message + wl-fldmgr-delete + wl-refile-guess-by-msgid + wl-address-user-mail-address-p + wl-summary-jump-to-msg-by-message-id-via-nntp + wl-summary-temp-mark-pick + +* For details of changes, see the file ChangeLog. + +Local variables: +mode: outline +paragraph-separate: "[ ]*$" +end: diff --git a/NEWS.ja b/NEWS.ja new file mode 100644 index 0000000..511373c --- /dev/null +++ b/NEWS.ja @@ -0,0 +1,136 @@ +Wanderlust NEWS ($BF|K\8lHG(B) -- User-visible changes in Wanderlust. 21 Mar 2000 + +* 1.1.1 $B$NJQ99E@(B. + +** $B%G%#%l%/%H%j9=@.$,$+$o$j$^$7$?!#(B + +*** 00README, 00README.ja $B$O(B README, README.ja $B$KJQ99$5$l$^$7$?!#(B + +*** wl-* $B$N%U%!%$%k$O(B 'wl' $B%G%#%l%/%H%j$K0\F0$7$^$7$?!#(B + +* 1.0.3 $B$+$i(B version 1.1.0 $B$X$NJQ99E@(B + +** $B%$%s%9%H!<%k(B + +*** tm7 $B$O%5%]!<%H$5$l$J$/$J$j$^$7$?!%(B + +$B$/$o$7$/$O(B INSTALL.ja $B$r8fMw2<$5$$!%(B + +*** WL_PREFIX $B$H(B ELMO_PREFIX $B$N=i4|@_Dj$,(B "wl" $B$K$J$j$^$7$?!%(B +(defvar WL_PREFIX "wl") +(defvar ELMO_PREFIX "wl") + +$BNc$($P!$%$%s%9%H!<%k%G%#%l%/%H%j$O!$(B + 1.0.3 /usr/local/share/emacs/site-lisp/ + 1.1.0 /usr/local/share/emacs/site-lisp/wl/ +$B$H$J$j$^$9!%(B + +*** Makefile $B$NJQ?t$N%G%U%)%k%HCM$,JQ$o$j$^$7$?!%(B + +EMACS = emacs +XEMACS = xemacs +$(XEMACS) $B$O!$(B`package' $B$d(B `install-package' $B$N(B target $B$G;2>H$5$l$^$9!%(B + +*** *.el $B%U%!%$%k$b%$%s%9%H!<%k$5$l$k$h$&$K$J$j$^$7$?!%(B + +*** $B1Q8lHG%I%-%e%a%s%H(B (wl.texi) $B$,IU$-$^$7$?!%(B + +** $B?75!G=(B + +*** Modified UTF7 $B$,%5%]!<%H$5$l$^$7$?!%(B +$B%f%K%3!<%I$,07$($k(B Emacs $B$G$O!$(BIMAP4 $B$GF|K\8l%a!<%k%\%C%/%9L>$r;XDj$G$-$^$9!%(B + +*** $B%9%3%"5!G=$,IU$-$^$7$?!%(B + +*** $B%W%i%04IM}5!G=$,IU$-$^$7$?!%(B + +*** IMAP4 $B$,$h$jHFMQE*$K$J$j$^$7$?!%(B +$BB?$/$N(B IMAP4 $B%5!<%P$GF0$/$h$&$K$J$j$^$7$?!%(B + +*** $B$$$/$D$+$NG'>ZJ}<0$,%5%]!<%H$5$l$^$7$?!%(B + IMAP4: CRAM-MD5, DIGEST-MD5, STARTTLS + POP3: CRAM-MD5, DIGEST-MD5, SCRAM-MD5, STARTTLS + NNTP: STARTTLS + SMTP: STARTTLS + +*** $B?7$7$$%U%)%k%@7?$,2C$o$j$^$7$?!%(B + | $B%Q%$%W%U%)%k%@(B $B%a%C%;!<%8$rC$($J$$%5%^%j(B)$B$,3HD%$5$l$^$7$?!%(B +$B%a%C%;!<%8%P%C%U%!$b%5%^%j$KBP1~$7$FMQ0U$5$l$k$h$&$K$J$j$^$7$?!%(B +$B>o$K%9%F%#%C%-!<$K$J$k%U%)%k%@$r@_Dj$G$-$k$h$&$K$J$j$^$7$?!%(B + +** $B$=$NB>(B + +*** $BJQ?t(B wl-draft-prepared-config-alist $B$OGQ;_$5$l$^$7$?!%(B +wl-draft-config-alist $B$KE}9g$5$l$^$7$?!%(B + +*** POP-before-SMTP $B4XO"$NJQ?t$,@0M}$5$l$^$7$?!%(B + +*** $BB8:_$7$J$$%U%)%k%@$r:n$k$+$I$&$+3NG'$9$k$h$&$K$J$j$^$7$?!%(B + FCC: $B$K?7$7$$%U%)%k%@L>$r;XDj$7$?$H$-$d!$(Bauto-refile $B$G(B + $B?7$7$$%U%)%k%@L>$r;XDj$7$?$H$-$K%U%)%k%@$r:n$k$+$I$&$+3NG'$7$^$9!%(B + +*** $B%W%j%U%'%C%A$N3NG'$K4X$9$k@_Dj$NJQ?t$,2C$o$j$^$7$?!%(B +wl-prefetch-confirm-threshold, wl-cache-fetch-threshold. + +*** $B%U%)%k%@L>$N$"$@L>$r%U%)%k%@L>F~NO$GJd40$G$-$k$h$&$K$J$j$^$7$?!%(B + +*** Message-ID $B$N@8@.J}K!$,JQ$o$j$^$7$?!%(B + +*** Mule $B$G$O%S%C%H%^%C%W$N%*!<%W%K%s%0%G%b2hLL$,=P$k$h$&$K$J$j$^$7$?!%(B + +*** `smtp-server' $B$K4X?t$r;XDj$G$-$^$9!%(B + +*** $BAw?.%m%0$,J]B8$5$l$k$h$&$K$J$j$^$7$?!%(B +`wl-draft-sendlog' $B$,(B non-nil $B$N>l9g!$(B'sendlog' $B%U%!%$%k$KJ]B8$5$l$^$9!%(B + +*** $B%*%U%i%$%s=hM}$G%W%j%U%'%C%A$rM=Ls$G$-$k$h$&$K$J$j$^$7$?!%(B + +*** `wl-summary-incorporate-marks' + +*** `wl-draft-use-frame' $B$,(B non-nil $B$J$i%U%l!<%`$r@8@.$7$^$9!%(B + +*** $B?75,JQ?t(B `wl-user-mail-address-list'$B!%(B + +*** $B?75,JQ?t(B `wl-local-domain'$B!%(B + +*** IMAP4 $B$G%5!<%PB&$NL$FI>uBV$r;2>H$9$k$h$&$K$J$j$^$7$?!%(B + +*** $B=i4|@_Dj$,JQ99$5$l$?JQ?t(B + wl-mime-charset iso-2022-jp => x-ctext + wl-summary-move-order 'new => 'unread + wl-tmp-dir TMPDIR => ~/tmp/ + +*** $B?75,(B hook + wl-draft-send-hook + wl-draft-reedit-hook + wl-mime-edit-preview-message-hook + wl-folder-suspend-hook + wl-summary-toggle-disp-folder-message-resumed-hook + wl-summary-line-inserted-hook + wl-thread-update-children-number-hook + mmelmo-header-inserted-hook + mmelmo-entity-content-inserted-hook + +*** $B?75,%3%^%s%I(B + wl-save + wl-summary-write + wl-summary-supersedes-message + wl-fldmgr-delete + wl-refile-guess-by-msgid + wl-address-user-mail-address-p + wl-summary-jump-to-msg-by-message-id-via-nntp + wl-summary-temp-mark-pick + +* $BJQ99E@$N>\:Y$O(B ChangeLog $B$r8fMw2<$5$$!%(B + +Local variables: +mode: outline +paragraph-separate: "[ ]*$" +end: diff --git a/README b/README new file mode 100644 index 0000000..e01331f --- /dev/null +++ b/README @@ -0,0 +1,71 @@ + + Wanderlust -- Yet Another Message Interface on Emacsen + by Yuuichi Teranishi + Time-stamp: <2000-02-24 00:26:49 teranisi> + +Wanderlust is a mail/news management system with IMAP4rev1 support for Emacs. + +Features: + + * Implementation in elisp only. + * Support of IMAP4rev1 [1], NNTP [2], POP(POP3[3]/APOP), MH and Maildir. + * Integrated access to messages based on Folder Specifications like Mew[4]. + * Key bindings and mark processing like Mew. + * Management of threads and unread messages. + * Folder mode to select and edit subscribed folders. + * Message cache, Disconnected Operation. + * MH-like FCC (FCC: %Backup is possible). + * Full support of MIME (by SEMI or tm[5]). + * Draft editing of mail and news as a same interface. + * Icon based interface for the list of Folder (XEmacs). + * Skip fetching of a large message part of MIME(IMAP4). + * Server side searching (IMAP4), internationalized searching is available. + * Virtual folder. + * Compressed folder. + * Automatic expiration of old messages. + * Automatic refiling. + * Draft templates. + +System Requirements: + + * Emacs19 or later. + * tm or SEMI (version 1.13.4 or later). + +Install: + +See INSTALL to install. + +Web Page: + +Wanderlust Official web page is available at: + +http://www.gohome.org/wl/. + +You can get latest Wanderlust version from there. + +Mailing List: + +Wanderlust Mailing List + +Via the Wanderlust ML, we discuss about Wanderlust, announce the latest +release in Japanese. + +To subscribe, send mail to wl-ctl@lists.airs.net, with '# guide' as +the message body. + +References: + +[1] M. Crispin, "INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4rev1", RFC 2060, + 1996. +[2] B. Kantor and P. Lapsley, "Network News Transfer Protocol: A + Proposed Standard for the Stream-Based Transmission of News", RFC + 977, 1986. +[3] J. Myers, M. Rose, "Post Office Protocol - Version 3", RFC 1929, 1996. +[4] "Mew -- Messaging in the Emacs World", + (Copyright (C) 1994, 1995, 1996, 1997, 1998 Mew developing team.) + Available from http://www.mew.org/. +[5] "tm -- MIME package for GNU Emacs", + (Copyright (C) 1994, 1995, 1996 MORIOKA Tomohiko) + Latest tm package is available from + ftp://ftp.jaist.ac.jp/pub/GNU/elisp/ + diff --git a/README.ja b/README.ja new file mode 100644 index 0000000..123033f --- /dev/null +++ b/README.ja @@ -0,0 +1,71 @@ + + Wanderlust -- Yet Another Message Interaface on Emacsen + by Yuuichi Teranishi + Time-stamp: <99/12/06 18:55:57 teranisi> + +Wanderlust $B$O(B Emacs $B>e$GF0$/(B IMAP4rev1 $BBP1~$N%a!<%k(B/$B%K%e!<%94IM}%7%9%F%`$G$9!#(B + +Features: + + * elisp $B$N$_$K$h$kA[%U%)%k%@!#(B + * $BB?$$F|$b0B?4$N!"%^%k%A%"!<%+%$%PBP1~05=L%U%)%k%@!#(B + * $B%U%)%k%@Cf$N8E$$5-;v$r<+F0E*$K%"!<%+%$%V(B/$B:o=|$7$F@0M}$9$k(B expire $B5!G=!#(B + * $B<+F0%j%U%!%$%k!#(B + * $BDj7?%a%C%;!<%8$NAw?.$KJXMx$J%F%s%W%l!<%H5!G=!#(B + +$BI,MW>r7o(B: + + * Emacs19 $B!A(B + * tm (8.7 $B0J9_(B) or SEMI (1.13.4 $B0J9_(B) + +Install: + + $B%$%s%9%H!<%k$NJ}K!$K$D$$$F$O!"(BINSTALL.ja $B$r8fMw$/$@$5$$!#(B + +Web Page: + + Wanderlust $B$N(B Official Web $B%Z!<%8$N(B URL $B$O0J2<$NDL$j$G$9!#(B + + http://www.gohome.org/wl/ + + $B$3$3$+$i%Q%C%1!<%8$N%@%&%s%m!<%I$b2DG=$G$9!#(B + +$B%a!<%j%s%0%j%9%H(B: + + Wanderlust Mailing List + + Wanderlust $B$K4X$9$k5DO@$O$3$N%a%$%j%s%0%j%9%H$G9T$o$l$^$9!#(B + $B:G?7%P!<%8%g%s$N%"%J%&%s%9$b$3$A$i$KN.$l$^$9!#(B + + wl-ctl@lists.airs.net $B08$N%a!<%k$NK\J8$K!"(B + + # guide + + $B$H=q$$$?%a!<%k$rAw$k$HF~2q$N%,%$%I$,<+F0E*$K$b$i$($^$9!#(B + +References: + +[1] M. Crispin, "INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4rev1", RFC 2060, + 1996. +[2] B. Kantor and P. Lapsley, "Network News Transfer Protocol: A + Proposed Standard for the Stream-Based Transmission of News", RFC + 977, 1986. +[3] J. Myers, M. Rose, "Post Office Protocol - Version 3", RFC 1929, 1996. +[4] "Mew -- Messaging in the Emacs World", + (Copyright (C) 1994, 1995, 1996, 1997, 1998 Mew developing team.) + Available from http://www.mew.org/. +[5] "tm -- MIME package for GNU Emacs", + (Copyright (C) 1994, 1995, 1996 MORIOKA Tomohiko) diff --git a/WL-ELS b/WL-ELS new file mode 100644 index 0000000..a440b26 --- /dev/null +++ b/WL-ELS @@ -0,0 +1,107 @@ +;;; WL-ELS -*-Emacs-Lisp-*- +;;; Time-stamp: <00/03/01 09:58:40 teranisi> + +;;;;;;;;;;;;;;;;;;;;; DO NOT EDIT THIS FILE ;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;; INTERNAL USE ONLY ;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; generic modules +(defconst WL-MODULES '( + wl wl-folder wl-summary wl-message + wl-vars wl-draft wl-util wl-address + wl-highlight wl-demo wl-refile wl-thread + wl-fldmgr wl-expire wl-template wl-score + )) + +(defconst ELMO-MODULES '( + elmo-util elmo-imap4 elmo-nntp elmo-archive + elmo-localdir elmo-msgdb elmo-vars elmo2 + elmo-cache elmo-multi elmo-filter elmo-pipe + elmo-dop elmo-pop3 elmo-localnews elmo-maildir + elmo-date elmo-internal utf7 + )) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Emacsen +;; (< 20 emacs-major-version) && !(featurep 'mule) +(cond + ((featurep 'xemacs) + (setq WL-MODULES (append WL-MODULES (list 'wl-dnd 'wl-xmas))) + (setq ELMO-MODULES (append (list 'elmo-database) ELMO-MODULES))) + ((fboundp 'nemacs-version) + (setq WL-MODULES (append WL-MODULES (list 'wl-nemacs)))) + ((featurep 'mule) + (setq WL-MODULES (append WL-MODULES (list 'wl-mule))))) + +(defconst WL-AUTOLOAD-MODULES '( + auto-autoloads custom-load + )) + +(if (or (fboundp 'dynamic-link) + ;; static + (fboundp 'open-database)) + (add-to-list 'ELMO-MODULES 'elmo-database)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; tm-8 / SEMI + +(if (module-installed-p 'mime-view) + (progn + (defconst wl-use-semi t) + (setq WL-MODULES (append WL-MODULES (list 'wl-mime))) + (setq ELMO-MODULES (append ELMO-MODULES (list 'mmelmo 'mmelmo-imap4)))) + (defconst wl-use-semi nil) + (setq WL-MODULES (append WL-MODULES (list 'tm-wl))) + ) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; FLIM 1.12 / FLIM 1.13 +(cond + ((module-installed-p 'luna) + ;; FLIM 1.13 (SEMI/tm-8) + (defconst wl-use-luna t) + (setq ELMO-MODULES + (append ELMO-MODULES + (list 'mmelmo-2 + 'mmelmo-imap4-2)))) + (wl-use-semi + ;; FLIM 1.12 + (defconst wl-use-luna nil) + (setq ELMO-MODULES + (append ELMO-MODULES + (list 'mmelmo-1 + 'mmelmo-imap4-1)))) + ) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Utils +(defvar UTILS-MODULES '(rfc2368 wl-mailto)) + +;; OpenSSL/SSLeay package is also needed. +(if (module-installed-p 'base64) + (add-to-list 'UTILS-MODULES 'ssl)) + +(defconst SASL-MODULES '(hmac-def hmac-md5 hmac-sha1 + hex-util md5-dl md5-el md5 + sha1-dl sha1-el sha1 sasl + scram-md5 digest-md5 unique-id)) + +(defvar modules-alist + (list + (cons ELMODIR ELMO-MODULES) + (cons WLDIR WL-MODULES) + (if (module-installed-p 'bbdb) + (cons UTILSDIR (list 'bbdb-wl))) + (if (exec-installed-p "imput") + (cons UTILSDIR (list 'im-wl))) + (if wl-install-utils + (cons UTILSDIR UTILS-MODULES)) + ;; sasl does not work under Nemacs. + (if (and wl-install-sasl + (not (fboundp 'nemacs-version))) + (cons SASLDIR SASL-MODULES)) + )) diff --git a/WL-MK b/WL-MK new file mode 100644 index 0000000..09cb8f7 --- /dev/null +++ b/WL-MK @@ -0,0 +1,329 @@ +;;; -*- Emacs-Lisp -*- +;;; WL-MK for byte-compile, install, uninstall +;;; +;;; Original by OKUNISHI Fujikazu +;;; Modified by Yuuichi Teranishi +;;; +;;; Time-stamp: <2000-03-30 15:55:13 teranisi> + +;;;;;;;;;;;;;;;;;;;;; DO NOT EDIT THIS FILE ;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;; INTERNAL USE ONLY ;;;;;;;;;;;;;;;;;;;;; + +;;; Code + +(defvar WLDIR "./wl") +(defvar ELMODIR "./elmo") +(defvar DOCDIR "./doc") +(defvar ICONDIR "./etc/icons") +(defvar UTILSDIR "./utils") +(defvar SASLDIR "./utils/sasl/lisp") +(defvar WL_PREFIX "wl") +(defvar ELMO_PREFIX "wl") + +(defvar COMPRESS-SUFFIX-LIST '("" ".gz" ".Z" ".bz2")) + +(defvar wl-install-utils nil + "if Non-nil, install `wl-utils-modules'.") +(defvar wl-install-sasl nil + "if Non-nil, install sasl utilities.") + +;;; INFO +(defconst wl-ja-info "wl-ja.info") +(defconst wl-ja-texi "wl-ja.texi") +(defconst wl-en-info "wl.info") +(defconst wl-en-texi "wl.texi") + +(defvar wl-info-lang "ja" + "The language of info file (\"ja\" or \"en\").") + +;; for Nemacs (dirty!) +(or (fboundp 'file-executable-p) + (fset 'file-executable-p 'file-exists-p)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(require 'cl) +(defvar INFODIR nil) + +(condition-case () (require 'custom) (error nil)) +;; for wl-vars.el +(unless (and (fboundp 'defgroup) + (fboundp 'defcustom) + ;; ignore broken module + (not (featurep 'tinycustom))) + (require 'backquote) + (defmacro defgroup (&rest args)) + (defmacro defcustom (symbol value &optional doc &rest args) + (let ((doc (concat "*" (or doc "")))) + (` (defvar (, symbol) (, value) (, doc))))) + ) + +(setq byte-compile-warnings '(free-vars unresolved callargs redefine)) + +;; v18, v19 +(if (or (boundp 'MULE) + (fboundp 'nemacs-version)) + (setq max-lisp-eval-depth 400)) + +(condition-case () (require 'easymenu) (error nil)) + +(defvar config-wl-package-done nil) + +(defun config-wl-package-subr () + (unless config-wl-package-done + (setq config-wl-package-done t) + (setq load-path (cons (expand-file-name ".") load-path)) + (setq load-path (cons (expand-file-name WLDIR) + (cons (expand-file-name ELMODIR) load-path))) + (setq wl-icon-dir (expand-file-name ICONDIR)) +;;; load custom file if exists. + (load "./WL-CFG" t nil t) +;;; load-path + (if wl-install-utils + (setq load-path (cons (expand-file-name UTILSDIR) load-path))) + (if wl-install-sasl + (setq load-path (cons (expand-file-name SASLDIR) load-path))) + (require 'install) + (load "./WL-ELS") + (condition-case () + (require 'mime-setup) + (error (error "No MIME module was detected. Please install SEMI or tm."))) + (if wl-use-semi + (princ (concat "\nUse SEMI" + (if wl-use-luna " with LUNA\n" " without LUNA\n"))) + (princ "\nUse tm.\n")))) + +(defun config-wl-package () + (config-wl-package-subr) + ;; LISPDIR check. + (let ((elispdir (car command-line-args-left))) + (if (string= elispdir "NONE") + (defvar LISPDIR (install-detect-elisp-directory)) + (defvar LISPDIR elispdir))) + (princ (format "LISPDIR is %s\n\n" LISPDIR)) + (setq command-line-args-left (cdr command-line-args-left))) + + +(defun wl-scan-source (path) + (let (ret) + (mapcar + '(lambda (x) + (mapcar '(lambda (y) + (setq ret (append (list y (concat y "c")) ret))) + (directory-files x nil "\\(.+\\)\\.el$" t))) + path) + ret)) + + +(defun wl-uninstall (objs path) + ;(message (mapconcat 'identity objs " ")) + (mapcar + '(lambda (x) + (let ((filename (expand-file-name x path))) + (if (and (file-exists-p filename) + (file-writable-p filename)) + (progn + (princ (format "%s was uninstalled.\n" filename)) + (delete-file filename))))) + objs)) + + +(defun compile-wl-package () + ;; For nemacs byte compiler's strange behavior(?). + (config-wl-package) + (if (fboundp 'nemacs-version) + (load (expand-file-name "wl.el" WLDIR))) + (mapcar + '(lambda (x) + (compile-elisp-modules (cdr x) (car x))) + modules-alist)) + +(defun install-wl-package () + (compile-wl-package) + (let ((wl-install-dir (expand-file-name WL_PREFIX LISPDIR)) + (elmo-install-dir (expand-file-name ELMO_PREFIX LISPDIR))) + (mapcar + '(lambda (x) + (install-elisp-modules (cdr x) (car x) + (if (string= (car x) ELMODIR) + elmo-install-dir + wl-install-dir))) + modules-alist))) + + +(defun uninstall-wl-package () + (config-wl-package) + (let ((wl-install-dir (expand-file-name WL_PREFIX + LISPDIR)) + (elmo-install-dir (expand-file-name ELMO_PREFIX + LISPDIR))) + (wl-uninstall (wl-scan-source (list WLDIR UTILSDIR SASLDIR)) + wl-install-dir) + (wl-uninstall (wl-scan-source (list ELMODIR)) + elmo-install-dir) + )) + + +(defun config-wl-package-xmas () + (if (not (featurep 'xemacs)) + (error "This directive is only for XEmacs.")) + (config-wl-package-subr) + ;; PACKAGEDIR check. + (let (package-dir) + (and (setq package-dir (car command-line-args-left)) + (if (string= "NONE" package-dir) + (defvar PACKAGEDIR + (if (boundp 'early-packages) + (let ((dirs (append (if early-package-load-path + early-packages) + (if late-package-load-path + late-packages) + (if last-package-load-path + last-packages))) + dir) + (while (not (file-exists-p + (setq dir (car dirs)))) + (setq dirs (cdr dirs))) + dir))) + (defvar PACKAGEDIR package-dir))) + (princ (format "PACKAGEDIR is %s\n\n" PACKAGEDIR)) + (setq command-line-args-left (cdr command-line-args-left)))) + +;; from SEMI-MK +(defun compile-wl-package-xmas () + (config-wl-package-xmas) + (setq autoload-package-name "wl") + (add-to-list 'command-line-args-left WLDIR) + (batch-update-directory) + (add-to-list 'command-line-args-left WLDIR) + (Custom-make-dependencies) + ;; WL-AUTOLOAD-MODULES + (compile-elisp-modules WL-AUTOLOAD-MODULES WLDIR) + (mapcar + '(lambda (x) + (compile-elisp-modules (cdr x) (car x))) + modules-alist)) + +(defun install-wl-package-xmas () + (compile-wl-package-xmas) + (let ((LISPDIR (expand-file-name "wl" + (expand-file-name "lisp" + PACKAGEDIR))) + (DATADIR (expand-file-name "wl" + (expand-file-name "etc" + PACKAGEDIR))) + (INFODIR (expand-file-name "info" PACKAGEDIR))) + (or (file-exists-p DATADIR) + (make-directory DATADIR t)) + (or (file-exists-p INFODIR) + (make-directory INFODIR t)) + ;; copy xpm files + (mapcar '(lambda (x) + (let* ((src-file-nondirectory (file-name-nondirectory x)) + (dst-file (expand-file-name src-file-nondirectory + DATADIR))) + (princ (format "%s->%s\n" + x ; fullpath + dst-file)) + (copy-file x dst-file t))) + (directory-files "etc/icons" t "xpm")) + (mapcar '(lambda (x) + (install-elisp-modules (cdr x) (car x) LISPDIR)) + modules-alist) + ;; WL-AUTOLOAD-MODULES + (install-elisp-modules WL-AUTOLOAD-MODULES WLDIR LISPDIR) + ;; + (wl-texinfo-format) + (wl-texinfo-install))) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Texinfo stuff + +(defun wl-texinfo-format-file (lang) + (let ((infofile (symbol-value (intern (format "wl-%s-info" lang)))) + (texifile (symbol-value (intern (format "wl-%s-texi" lang))))) + (require 'wl-vars) ;; for 'wl-cs-local + (or (file-newer-than-file-p (expand-file-name infofile DOCDIR) + (expand-file-name texifile DOCDIR)) + (let (obuf beg) + (find-file (expand-file-name texifile DOCDIR)) + (setq obuf (current-buffer)) + ;; texinfmt.el 2.37 or earlier can't format @direntry + (require 'texinfmt) + (unless (fboundp 'texinfo-format-direntry) + (goto-char (point-min)) + (when (re-search-forward "^@direntry" nil t) + (replace-match "@ifinfo\nSTART-INFO-DIR-ENTRY")) + (when (re-search-forward "^@end direntry" nil t) + (replace-match "END-INFO-DIR-ENTRY\n@end ifinfo")) + (set-buffer-modified-p nil)) + ;; We can't know file names if splitted. + (texinfo-format-buffer t) + ;; Emacs20.2's default is 'raw-text-unix. + (and (fboundp 'set-buffer-file-coding-system) + (set-buffer-file-coding-system wl-cs-local)) + (save-buffer) + (kill-buffer (current-buffer)) ;; info + (kill-buffer obuf)) ;; texi + ))) + +(defun wl-texinfo-format () + (unless INFODIR + (setq INFODIR (wl-detect-info-directory))) + (cond ((listp wl-info-lang) + (mapcar 'wl-texinfo-format-file wl-info-lang)) + ((stringp wl-info-lang) + (wl-texinfo-format-file wl-info-lang)))) + +(defun wl-texinfo-install-file (lang) + (let ((infofile (symbol-value (intern (format "wl-%s-info" lang))))) + (install-file infofile DOCDIR INFODIR))) + +(defun wl-texinfo-install () + (cond ((listp wl-info-lang) + (mapcar 'wl-texinfo-install-file wl-info-lang)) + ((stringp wl-info-lang) + (wl-texinfo-install-file wl-info-lang)))) + +(defun wl-primary-info-file () + "Get primary info file (for wl-detect-info-directory)." + (cond + ((listp wl-info-lang) + (let ((wl-info-lang (car wl-info-lang))) + (wl-primary-info-file))) + ((stringp wl-info-lang) + (symbol-value (intern (format "wl-%s-info" wl-info-lang)))))) + +(defun wl-detect-info-directory () + (config-wl-package-subr) + (if (fboundp 'nemacs-version) + (error "Cannot format info on Nemacs. Please use another formatter.")) + ;; INFODIR check. + (require 'info) + (let ((infodir (car command-line-args-left)) + (info (wl-primary-info-file)) + previous INFODIR) + (setq INFODIR + (if (string= infodir "NONE") + (if (setq previous + (exec-installed-p info Info-directory-list + COMPRESS-SUFFIX-LIST)) + ;;(progn + ;;(condition-case nil (delete-file previous)) + (directory-file-name (file-name-directory previous));) + (car Info-directory-list)) + infodir)) + (setq command-line-args-left (cdr command-line-args-left)) + (princ (format "INFODIR is %s\n\n" INFODIR)) + INFODIR)) + +(defun install-wl-info () + (wl-texinfo-format) + (wl-texinfo-install)) + + +;;; ToDo +;;; * MORE refine code (^_^; + +;;; End diff --git a/doc/TODO.ja b/doc/TODO.ja new file mode 100644 index 0000000..e908b30 --- /dev/null +++ b/doc/TODO.ja @@ -0,0 +1,16 @@ +$B%M%C%H%o!<%/4X78$N%3!<%I$r(B elmo-network $B$K=8Ls(B +product $B$rDj5A$9$k(B +elmo-search $B$G(B msgdb $B$H%U%)%k%@K\BN$r%7!<%`%l%9$K8!:w(B +pick/virtual $B$N(B completion $BE}9g(B +msgdb $B9=B$$N8+D>$7$H(B obarray $B2=(B +POP3 $B$N(B UIDL $BBP1~(B +$B=EMW%^!<%/$N4IM}(B +$B%5%^%j%U%)!<%^%C%H<+M32=(B +$B%W%j%U%'%C%AM=Ls%^!<%/(B +$BJV;v:Q$_!"%U%)%o!<%I:Q$_%^!<%/(B +virtual $B4V$G(B msgdb $B6&M-(B +MIME Bcc +wl-summary-other-frame-list +rfc2192, rfc2193, rfc2221 (imap referral $B$N=hM}(B) +imap.el $B$H$NE}9g(B($B6l$7$$5$$,$7$F$-$?(B) +$B$"$d$7$2$J%3!<%I$r$X$i$7$?$$(B diff --git a/doc/wl-ja.texi b/doc/wl-ja.texi new file mode 100644 index 0000000..5f097d7 --- /dev/null +++ b/doc/wl-ja.texi @@ -0,0 +1,5969 @@ +\input texinfo @c -*-texinfo -*- coding: iso-2022-jp -*- +@c %**start of header +@setfilename wl-ja.info +@settitle Wanderlust -- Yet Another Message Interface On Emacsen -- +@c @documentlanguage ja +@c %**end of header +@c Wanderlust $B$N(B texinfo +@set Time-stamp: <2000-04-03 14:29:40 teranisi> +@set version 1.1.0 +@synindex pg cp +@finalout + +@direntry +* Wanderlust-ja: (wl-ja). Yet Another Message Interface On Emacsen +@end direntry + +@c permissions text appears in an Info file before the first node. +@ifinfo +This file documents Wanderlust, +Yet another message interface on Emacsen. + +$B$3$N%U%!%$%k$O(B Emacs $B$GF0$/%a!<%k(B/$B%K%e!<%94IM}%7%9%F%`(B +Wanderlust $B$K4X$9$k@bL@=q$G$9!#(B + +Copyright @copyright{} 1998, 1999, 2000 @w{Yuuichi Teranishi}. +@c Copyright @copyright{} 1998, 1999, 2000 @w{Yuuichi Teranishi}, @* +@c @w{Fujikazu Okunishi}, @w{Masahiro Murata}, +@c @w{Kenichi Okada} and @w{Kaoru Takahashi}. + +This edition is for Wanderlust version @value{version}. + +$B$3$NHG$O(B Wanderlust version @value{version} $B$KBP1~$7$^$9!#(B + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +$BCx:n8"I=<($H$3$N5v2DJ8$,$9$Y$F$NJ#@=$KB8:_$9$k8B$j!"(B +$B$3$N@bL@=q$N$^$C$?$/F10l$NJ#@=$r:n$j!"G[I[$9$k$3$H$r5v2D$9$k!#(B + +@ignore +Permission is granted to process this file through TeX and print the +results, provided the printed document carries copying permission +notice identical to this one except for the removal of this paragraph +(this paragraph not being relevant to the printed manual). + +$B$3$NCJMn$,H$5$l$^$;$s(B)$B!#(B + +@end ignore +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the entire +resulting derived work is distributed under the terms of a permission +notice identical to this one. + +$BF10lJ#@=$N>r7o$N2<$G!"$=$l$K$h$C$FF@$i$l$?7k2L$b$3$N5v2DJ8$NI=<($HF10l$N(B +$B>r7o$N$b$H$GG[I[$9$k8B$j!"$3$N@bL@=q$N=$@5HG$NJ#@=$r$7!"G[I[$9$k$3$H$r5v(B +$B2D$9$k!#(B + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions. + +$B>e5-$N=$@5HG$K4X$9$k>r7o$N2<$G!"$3$N@bL@=q$NK]Lu$NJ#@=$r:n$j!"(B +$BG[I[$9$k$3$H$r5v2D$9$k!#(B +@end ifinfo + +@titlepage +@sp 10 +@title Wanderlust $B%f!<%6%^%K%e%"%k(B (ver. @value{version}) +@author Yuuichi Teranishi $B;{@>M50l(B +@author Fujikazu Okunishi $B1|@>F#OB(B +@author Masahiro Murata $BBr7o$N2<$G!"$=$l$K$h$C$FF@$i$l$?7k2L$r$3$N5v2DJ8$NI=<($HF10l$N(B +$B>r7o$N$b$H$GG[I[$9$k8B$j!"$3$N@bL@=q$N=$@5HG$NJ#@=$r$7!"G[I[$9$k$3$H$r5v(B +$B2D$9$k!#(B + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions. + +$B>e5-$N=$@5HG$K4X$9$k>r7o$N2<$G!"$3$N@bL@=q$NK]Lu$NJ#@=$r:n$j!"(B +$BG[I[$9$k$3$H$r5v2D$9$k!#(B +@end titlepage + + +@c +@c Top +@c +@ifinfo +@node Top, Introduction, (dir), (dir) +@top Wanderlust $B%f!<%6%^%K%e%"%k(B + +@flushright +Yuuichi Teranishi $B;{@>M50l(B +Fujikazu Okunishi $B1|@>F#OB(B +Masahiro Murata $BBA[%U%)%k%@!#(B +@item $BB?$$F|$b0B?4$N!"%^%k%A%"!<%+%$%PBP1~05=L%U%)%k%@!#(B +@item $B%U%)%k%@Cf$N8E$$5-;v$r<+F0E*$K%"!<%+%$%V(B/$B:o=|$7$F@0M}$9$k(B expire $B5!G=!#(B +@item $B<+F0%j%U%!%$%k!#(B +@item $BDj7?%a%C%;!<%8$NAw?.$KJXMx$J%F%s%W%l!<%H5!G=!#(B +@end itemize + +Wanderlust $B$O(B Emacs 19.28$B!A(B $B$r%Y!<%9$H$7$?(B Mule, Emacs 20.2$B!A(B, XEmacs +20.4$B!A!"(B $B$*$h$S(B MS Windows $B>e$GF0$/(B Meadow 1.00, Mule for Windows v1.22, +NTEmacs(Windows NT) $B$GF0:n$9$k$3$H$,3NG'$5$l$F$$$^$9!#(BOS/2 $B>e$GF0:n$9$k(B +PMMule $B$bEvA3(B OK $B$G$9!#$5$i$K!"(BNemacs 3.3.2 $B>e$G$b!"(B($B;H$($k5!G=$O8BDj$5(B +$B$l$k$b$N$N(B) $BF0:n$9$k$3$H$,3NG'$5$l$F$$$^$9!#(B + +$B$^$?!"(BWanderlust $B$,@\B3$7$FF0:n$9$k$3$H$,3NG'$5$l$F$$$k(B IMAP $B%5!<%P$O(BUW +imapd 4.2, 4.3, 4.4, 4.5, 4.6, 4.7, 4.7a, Cyrus imapd 1.4, Cyrus imapd 1.5.19, +AIR MAIL(AIRCimapd release 2.00) $B$G$9!#(B + + +@c +@c Start Me Up +@c +@node Start Me Up, Folders, Introduction, Top +@chapter Wanderlust $B$r5/F0$9$k(B +@cindex Start up + +Wanderlust $B$r5/F0$9$k$^$G$KI,MW$Jo$KF0:n$5$;$k$K$O!"$^$:!"(BSEMI $B$b$7$/$O(B tm $B$,%$%s%9(B +$B%H!<%k$5$l$F$$$kI,MW$,$"$j$^$9!#(B + +Emacs19.28 $B0JA0$r%Y!<%9$H$7$?(B mule $B$r$*;H$$$N>l9g$O(B SEMI $B$,F0$+$J$$$O$:(B +@footnote{Emacs 19.34 $B%Y!<%9$N(B Mule $B$G$O(B SEMI $B$rF0:n$5$;$k$3$H$b2DG=$G$9!#(B@* +@samp{http://www.jpl.org/elips/INSTALL-SEMI-ja.html} $B$,;29M$K$J$j$^$9!#(B} +$B$J$N$G(B tm $B$r%$%s%9%H!<%k$7$^$9!#(B +(tm $B$O%P!<%8%g%s(B 8.7 $B0J9_$r$4MxMQ$/$@$5$$!#(B) + +SEMI $B$,;H$($k(B Emacsen $B$G$O!"(Btm $B$h$j$b5!G=$N=<H$7$F(B +$B$/$@$5$$!#(B + +SEMI, tm $B$O0J2<$N>l=j$+$i%@%&%s%m!<%I$G$-$^$9!#(B + +@example +SEMI: ftp://ftp.m17n.org/mule/semi/ +tm: http://cvs.m17n.org/tomo/comp/emacsen/tm/tm-8/ +@end example + +SEMI $B$K$O(B APEL, FLIM $B$H8F$P$l$k%Q%C%1!<%8$bI,MW$G$9!#(B +FLIM, APEL $B$O0J2<$N>l=j$+$i%@%&%s%m!<%I$G$-$^$9!#(B + +@example +FLIM: ftp://ftp.m17n.org/mule/flim/ +APEL: ftp://ftp.m17n.org/mule/apel/ +@end example + +APEL, FLIM, SEMI $B$N=g$K%$%s%9%H!<%k$7$F$/$@$5$$!#(B +$B4pK\E*$K$9$Y$F(B @samp{make install} $B$N)$5$l$k(B APEL, FLIM, SEMI $B$N%P!<%8%g%s$NAH9g$;$O!"0J2<$NDL$j$G$9!#(B + +@itemize @minus +@item APEL 10.2, FLIM 1.12.7, SEMI 1.13.4 +@item APEL 10.2, FLIM 1.13.2, SEMI 1.13.7 +@end itemize + +APEL 10.2 $B$H(B FLIM 1.12.7 $B$NAH9g$;$G$O!"(BFLIM 1.12.7 $B$N%3%s%Q%$%k;~$K(B + +@example +Please install latest APEL 7.3 or later. +@end example + +$B$H$$$&%(%i!<$,H/@8$9$k>l9g$,$"$j$^$9!#$3$N>l9g!"(BFLIM-CFG $B$N0J2<$N9T$r(B +$B%3%a%s%H%"%&%H$7$F2<$5$$!#(B + +@example +(or (fboundp 'write-region-as-binary) + (error "Please install latest APEL 7.3 or later.")) +(or (fboundp 'insert-file-contents-as-binary) + (error "Please install latest APEL 7.3 or later.")) +@end example + +$B$=$NB>!"(BFLIM, SEMI $B$K$O$$$m$$$m$JJQ7A%P!<%8%g%s$,B8:_$7$^$9$,!"(B +$B$=$l$i$N$$$:$l$bMxMQ$9$k$3$H$,2DG=$G$9!#(B +$B4pK\E*$K:G?7HG$NAH9g$;$J$iF0:n$9$k$O$:$G$9!#(B +$BNc$($P!"0J2<$NAH9g$;$NF0:n$,3NG'$5$l$F$$$^$9!#(B + +@itemize @minus +@item APEL 10.2, Chao 1.14.1, REMI 1.14.1 +@end itemize + +@c APEL, FLIM, SEMI $B$+(B tm $B$N%P!<%8%g%s%"%C%W$r9T$C$?>l9g$O!"(B +@c Wanderlust $B$r%$%s%9%H!<%k$7$J$*$7$F$/$@$5$$!#(B + + +@node Download, Install, MIME Modules, Start Me Up +@section $B%Q%C%1!<%8$NF~l=j$+$i%@%&%s%m!<%I$G$-$^$9!#(B + +$B0lo$N(B SSL $B$rMxMQ$9$k$K$O(B $BK\%Q%C%1!<%8$N(B @file{utils} $B%G%#%l%/%H%j$K$"$k(B +@file{ssl.el} $B$r%$%s%9%H!<%k$9$kI,MW$,$"$j$^$9!#(B +$B$J$*$+$D!"(BOpenSSL $B$K4^$^$l$k(B openssl $B$K%Q%9$,DL$C$F$$$kI,MW$,$"$j$^$9!#(B +STARTTLS $B$rMxMQ$9$k$K$O!"$5$i$K!"(Bstarttls $B%Q%C%1!<%8$r%$%s%9%H!<%k(B +$B$9$kI,MW$,$"$j$^$9!#(B +starttls $B%Q%C%1!<%8$O0J2<$N>l=j$+$iF~o$N%$%s%9%H!<%k(B + +@file{Makefile} $B$O(B @code{LISPDIR}, @code{EMACS} $B$N$"$?$j$rJT=8$7$^$9!#(B +@code{LISPDIR} $B$K$O%Q%C%1!<%8$N%$%s%9%H!<%k@h!"(B +@code{EMACS} $B$K$OMxMQ$9$k(B Emacs $B$N%3%^%s%IL>$r;XDj$7$^$9!#(B + +@example +% make +% make install +@end example + +@file{Makefile} $BCf$N(B @code{LISPDIR} $B$rJQ99$;$:!"(B +$B$=$N$^$^(B(@samp{NONE} $B$N$^$^$G$b(B)$B%$%s%9%H!<%k$7$?>l9g!"(B +$B<+F0E*$K%$%s%9%H!<%k@h$rE,Ev$K8!=P$7$^$9!#(B +$Bl9g$O!"(B +custom, apel, flim, semi $B$N%$%s%9%H!<%k@h$r4D6-JQ?t(B @code{EMACSLOADPATH} +$B$K2C$($k$+!"E83+%G%#%l%/%H%j$N(B @file{WL-CFG} $B$H$$$&%U%!%$%kCf$G(B +load-path $B$rDL$7$F$*$/$H$h$$$G$7$g$&!#(B + +$B$^$?!"(BBBDB $B$rMxMQ$7$?$$>l9g!"(BBBDB $B$X$b(B load-path $B$rDL$7$F$*$/$HI,MW$J%b(B +$B%8%e!<%k$,%P%$%H%3%s%Q%$%k(B/$B%$%s%9%H!<%k$5$l$^$9!#(B +@xref{BBDB}. + +@subsection WL-CFG + +@file{WL-CFG} $B$H$$$&%U%!%$%k$,E83+%G%#%l%/%H%j$KB8:_$9$k$H!"(B +$B%$%s%9%H!<%k;~$K(B load $B$5$l$k$h$&$K$J$C$F$$$^$9!#(B +$B%$%s%9%H!<%k$G(B SEMI $BEy$N(B load-path $B$N@_Dj$,I,MW$G$"$l$P!"(B +@file{WL-CFG} $B$K@_Dj$7$F$/$@$5$$!#(B + +$B%$%s%9%H!<%k@h$O(B @file{Makefile}$BCf$N(B @code{LISPDIR} $B$G;XDj$7$^$9$,!"(B +$Bo$K5/F0$G$-$k$h$&$K$J$j$^$9!#(B + +XEmacs $B$N(B package $B$H$7$F%$%s%9%H!<%k$9$k$K$O0J2<$N$h$&$K$7$^$9!#(B + +@example +% vi Makefile +% make package +% make install-package +@end example + +package $B$N%G%#%l%/%H%j$O(B SEMI $B$,%$%s%9%H!<%k$5$l$F$$$l$P<+F08!=P$5$l$^$9!#(B +(@file{Makefile} $BCf$N(B PACKAGEDIR $B$G$b@_Dj2D(B) + +@subsection $B%$%s%9%H!<%k$7$J$$$GMxMQ(B + +Wanderlust $B$O%P%$%H%3%s%Q%$%k!"%$%s%9%H!<%k$7$J$/$F$b!"(B +wl, elmo $B$N%G%#%l%/%H%j$K(B load-path $B$,@_Dj$5$l$F$$$l$P5/F0$9$k$3$H$,$G$-$^$9!#(B +$BNc$($P(B @file{~/work} $B$K%Q%C%1!<%8$rE83+$7$?>l9g!"(B +@file{.emacs} $B$K0J2<$N@_Dj$r$9$k$H5/F0$G$-$^$9!#(B + +@lisp +(add-to-list 'load-path "~/work/wl-(@var{version})") +(add-to-list 'load-path "~/work/wl-(@var{version})/elmo") +@end lisp + +@subsection $B%^%K%e%"%k$K$D$$$F(B + +$B%^%K%e%"%k$O(B Info $B7A<0$G$9!#(B +$B%$%s%9%H!<%k$9$k$K$O2<5-$rl9g$O<+F0E*$K(B Info $B%U%!%$%k$b(B +$B%$%s%9%H!<%k$5$l$k$N$G$3$l$i$NA`:n$OI,MW$"$j$^$;$s!#(B + +$B$^$?!"2<5-$K$b%^%K%e%"%k$,$"$j$^$9!#(B + +@example +http://www.gohome.org/wl/doc/wl-euc_toc.html +@end example + + +@node Minimal Settings, Mail Addresses, Install, Start Me Up +@section .emacs $B$N@_Dj(B +@cindex Minimal Settings +@cindex Settings +@cindex Configuration +@cindex .emacs +@cindex .wl + +Wanderlust $B$N%Q%C%1!<%8$K$OBg$-$/J,$1$FFs$D$N%b%8%e!<%k72$,4^$^$l$F$$$^$9!#(B + +@table @samp +@item ELMO (elmo-*.el) +$B$9$Y$F$r%U%)%k%@$K8+$;$k%b%8%e!<%k72$G$9!#(BWanderlust $B$N%P%C%/%(%s%I$G$9!#(B +@item WL (wl-*.el) +Wanderlust $BK\BN$NF0:n$r7h$a$k%b%8%e!<%k72$G$9!#(BELMO $B$N%U%m%s%H%(%s%I$G$9!#(B +@end table + +$B%f!<%6$O(B @code{elmo-*}, @code{wl-*} $B$G;O$^$kJQ?t$N@_Dj$rJQ$($k$3$H$K$h$C$F(B +Wanderlust $B$NF0:n$r%+%9%?%^%$%:$G$-$^$9!#(B + +$B:GDc8BI,MW$J@_Dj$O0J2<$NDL$j$G$9!#(B + +@lisp +;; @r{SEMI/tm $B$r;H$&$?$a$N@_Dj(B} +(load "mime-setup") + +;; @r{autoload $B$N@_Dj(B} +;; @r{(XEmacs $B$N(B package $B$H$7$F%$%s%9%H!<%k$5$l$F$$$k>l9g!"I,MW$"$j$^$;$s(B)} +(autoload 'wl "wl" "Wanderlust" t) +(autoload 'wl-draft "wl-draft" "Write draft with Wanderlust." t) + +;; @r{$B%"%$%3%s$rCV$/%G%#%l%/%H%j(B (XEmacs $B$N$_(B)$B!#=i4|@_Dj$O(B nil$B!#(B} +;; @r{(XEmacs $B$N(B package $B$H$7$F%$%s%9%H!<%k$5$l$F$$$k>l9g!"I,MW$"$j$^$;$s(B)} +(setq wl-icon-dir "~/work/wl/etc") + +;; @r{$B%a!<%k$rAw?.$9$k(B SMTP $B%5!<%P!#(B $B=i4|@_Dj$O(B "localhost"$B!#(B} +(setq wl-smtp-posting-server "your.smtp.server.com") +;; @r{$B%K%e!<%9Ej9FMQ$N(B NNTP $B%5!<%P!#(B $B=i4|@_Dj$O(B nil$B!#(B} +(setq wl-nntp-posting-server "your.nntp.server.com") +@end lisp + +Wanderlust $B5/F08e!"(B@file{~/.wl} $B$,B8:_$9$l$P%m!<%I$5$l$^$9$N$G!"(BWanderlust $B$K(B +$B8GM-$N@_Dj$O(B @file{~/.wl} $B$K5-=R$7$F$*$1$P@0M}$7$d$9$$$G$7$g$&!#(B +face $B$N@_Dj$O(B @file{.emacs} $B$K=q$/$3$H$O$G$-$J$$$N$G(B +@file{~/.wl} $B$K=q$$$F$/$@$5$$!#(B +@xref{Highlights}. + +($B>e5-$N$&$A!"(B@samp{(load "mime-setup")} $B0J30$O(B @file{~/.wl} $B$K5-=R$G$-$^$9!#(B) + +@subsection mail-user-agent +@cindex Default Mailer +@cindex Mailer, Default +@vindex mail-user-agent +@findex compose-mail + +$B0J2<$N$h$&$J@_Dj$r(B @file{.emacs} $BEy$K$7$F$*$/$H!"(B@kbd{C-x m} +(@code{compose-mail}) $BEy$K$h$C$F(B Wanderlust $B$N%I%i%U%H%b!<%I$,5/F0$5$l$k(B +$B$h$&$K$J$j$^$9!#(BWanderlust $B$r(B Emacs $B>e$NI8=`%a!<%i$H$7$F;H$$$?$$>l9g$O(B +$B@_Dj$7$F$*$/$H$h$$$G$7$g$&!#(B +$B$?$@$7!"$3$l$O(B @code{mail-user-agent} $B$NDj5A$,2DG=$J(B Emacs $B$N>l9g$N$_M-8z$G$9!#(B +@c @xref{Mail Methods, , ,emacs}. + +@lisp +(autoload 'wl-user-agent-compose "wl-draft" nil t) +(if (boundp 'mail-user-agent) + (setq mail-user-agent 'wl-user-agent)) +(if (fboundp 'define-mail-user-agent) + (define-mail-user-agent + 'wl-user-agent + 'wl-user-agent-compose + 'wl-draft-send + 'wl-draft-kill + 'mail-send-hook)) +@end lisp + + +@node Mail Addresses, Folder Definition, Minimal Settings, Start Me Up +@section $B%"%I%l%9D"$NDj5A(B +@cindex Address book Definition +@cindex .addresses +@cindex Alias, Address + +$B%"%I%l%9%U%!%$%k(B @file{~/.addresses} $B$r:n@.$7!"<+J,MQ$KJT=8$7$^$9!#(B + +@file{~/.addresses} $B$K=q$+$l$?%G!<%?$O!"%I%i%U%H:n@.;~$N%"%I%l%9Jd40%G!<%?$H$7$F(B +$BMxMQ$5$l$k$[$+!"%5%^%jI=<($G$NL>A0I=<(Ey$K$bMQ$$$i$l$^$9!#(B +$B%"%I%l%9Jd40$d%5%^%j$NI=<($K6E$kI,MW$,$J$$>l9g$O!"$3$N9`$OHt$P$7$F$b9=$$$^$;$s!#(B +$B$^$?!"5/F0$7$?$"$H$G%5%^%j$N%P%C%U%!$+$i(B @file{~/.addresses} $B$K%"%I%l%9$r(B +$BDI2C(B/$BJQ99(B/$B:o=|$9$k$3$H$b2DG=$G$9!#(B + +$B=q$-J}$O$H$F$bC1=c$G$9!#$3$s$J$+$s$8$G$9!#(B + +@example +# +# @r{@samp{#} $B$G;O$^$k9T$O%3%a%s%H!#(B} +# @r{$B6u9T$OL5;k!#(B} +# +# @r{$B%a!<%k%"%I%l%9(B ``$B$"$@L>(B'' ``$BK\L>(B''} +# +teranisi@@gohome.org "$B$F$i$K$7(B" "$B;{@>M50l(B" +foo@@bar.gohome.org "Foo $B$5$s(B" "John Foo" +bar@@foo.gohome.org "Bar $B$5$s(B" "Michael Bar" +@end example + +@noindent +$B0l9T$,0l?MJ,$NDj5A$G$9!#(B + +$B(B''$B!"(B +$B%I%i%U%H:n@.;~$N%"%I%l%9>pJs$H$7$F(B``$BK\L>(B''$B$,$D$+$o$l$^$9!#(B +$B;n$7$F$_$F!"3NG'$7$F$+$i$NJ}$,$o$+$j$d$9$$$H;W$o$l$^$9!#(B +$B$A$g$C$H=q$$$F;n$7$F$_$F$+$i!"$^$?%"%I%l%9D"$NDj5A$r$d$j$J$*$9$N$,$h$$$G$7$g$&!#(B + +$B$^$?!"JQ?t(B @code{wl-alias-file} $B$N%U%!%$%k$K(B MH $B$N(B alias file $B$,;XDj$5$l$F(B +$B$$$l$P!"%I%i%U%H:n@.;~$N%"%I%l%9>pJs$H$7$F;H$o$l$^$9!#(B + + +@node Folder Definition, Start Wanderlust, Mail Addresses, Start Me Up +@section $B9XFI$9$k%U%)%k%@$NDj5A(B +@cindex Folder Definition +@cindex .folders + +$B9XFI$9$k%U%)%k%@$r%U%!%$%k(B @file{~/.folders} $B$KDj5A$7$^$9!#(B +@file{~/.folders} $B$K=q$+$l$?FbMF$,$=$N$^$^$"$J$?$N9XFI$9$k%U%)%k%@$H$J$j$^$9!#(B + +$B5/F0$7$?$"$H$G%U%)%k%@0lMw$N%P%C%U%!$+$i9XFI%U%)%k%@$rDI2C(B/$BJT=8$9$k$3$H(B +$B$b2DG=$G$9$N$G!"$3$N9`$OHt$P$7$F$b9=$$$^$;$s!#(B + +@file{~/.folders} $B$N=q$-J}$O$H$F$bC1=c$G$9!#$3$s$J$+$s$8$G$9!#(B + +@example +# +# @r{@samp{#} $B$G;O$^$k9T$O%3%a%s%H!#(B} +# @r{$B6u9T$OL5;k!#(B} +# +# @r{$B%U%)%k%@(B} "@r{$B$"$@L>(B}" +# @r{($B$"$@L>$OL5$/$F$b$h$$(B)} +# +%inbox "$BO$G>\$7$/@bL@$7$^$9!#(B + +@samp{@var{$B%0%k!<%WL>(B}@{} $B$H(B @samp{@}} $B$G0O$^$l$?ItJ,$O0l$D$N%0%k!<%W$H$J$j$^$9!#(B +$B$R$H$D$N%0%k!<%W$O%U%)%k%@%b!<%I$G$O3+JD$G$-$k%G%#%l%/%H%j$N$h$&$K8+$($^$9!#(B +$B$$$/$D$+$N%U%)%k%@$r$^$H$a$F@0M}$9$k$N$KJXMx$G$9!#(B + +$BCm0U$9$Y$-$J$N$O!"(B@samp{@var{$B%0%k!<%WL>(B}@{} $B$H(B @samp{@}} $B$O#19T$r@jNN$7$F=q$/(B +$BI,MW$,$"$k$3$H$G$9(B($B$3$l$O%Q!<%5$,%@%5$$$+$i$G$9(B)$B!#(B + +$B%0%k!<%W$K$O!"#2$D$Ne$NNc$N(B @samp{Emacsen} $B$N$h$&$K(B +$BD>@\<+J,$G9%$-$J%U%)%k%@$r%0%k!<%W$H$7$FDj5A$9$k%?%$%W$G$9!#(B + +$B$b$&0l$D$O!">e$NNc$N(B @samp{+} $B$N$h$&$J(B @dfn{$B%"%/%;%9%0%k!<%W(B} $B$G$9!#(B +$B$3$l$O!"$"$k%U%)%k%@$K4^$^$l$k%5%V%U%)%k%@A4$F$r0l$D$N%0%k!<%W$H$9$k$b$N$G$9!#(B +($B$3$l$O%U%)%k%@$N%?%$%W$K$h$C$F0c$$$^$9!#Nc$($P(B @samp{+} $B$J$i(B + MH $B$N%5%V%G%#%l%/%H%j$9$Y$F$,$R$H$D$N%0%k!<%W$H$J$j$^$9!#(B) + +$BJN,$7$F5/F0$7$^$9!#(B + + +@c +@c Folders +@c +@node Folders, Folder, Start Me Up, Top +@chapter Wanderlust $B$G07$($k%U%)%k%@$?$A(B +@cindex Folder Type + +$B0J2<$G$O(B Wanderlust $B$G07$($k%U%)%k%@$K$D$$$F@bL@$7$^$9!#(B + +Wanderlust $B$O(B ELMO $B$N%$%s%?%U%'!<%9$rMxMQ$7$F$$$k$?$a!"(BELMO $B%b%8%e!<%k$K(B +$B$h$C$F%5%]!<%H$5$l$F$$$l$P!"$I$s$J%U%)%k%@$G$bMxMQ$9$k$3$H$,$G$-$^$9!#(B + +$B%P!<%8%g%s(B @value{version} $B8=:_!"MQ0U$5$l$F$$$k%U%)%k%@$N(B'[':' '$B%f!<%6L>(B' ['/' '$BG'>ZK!(B']]['@@' '$B%[%9%HL>(B'][':' '$B%]!<%HHV9f(B']['!'] + +$BG'>ZK!$K$O(B "auth" ($B%(%s%3!<%I$7$F%Q%9%o!<%I$rAw?.(B)$B$+(B + "cram-md5" (cram-md5$B$K$h$kG'>Z(B)$B$+(B + "login" ($B@8%Q%9%o!<%I$rAw?.(B) $B$N$$$:$l$+$r;XDj!#(B + +(cram-md5 $B$K$h$kG'>Z$r9T$J$&$K$O(B $BK\%Q%C%1!<%8$N(B utils/sasl/ $B$r%$%s%9%H!<%k$9$k(B +$BI,MW$,$"$j$^$9!#(B) + +default $BCM(B: + +$B%f!<%6L>(B -> $BJQ?t(B @code{elmo-default-imap4-user} $B$NCM!#(B + $B=i4|@_Dj$O(B $B4D6-JQ?t(B USER $B$+!"(BLOGNAME $B$+!"(B(user-login-name) $B$NJV$jCM!#(B +$BG'>ZK!(B -> $BJQ?t(B @code{elmo-default-imap4-authenticate-type} $B$NCM!#(B + $B=i4|@_Dj$O(B "auth"$B!#(B +$B%[%9%HL>(B -> $BJQ?t(B @code{elmo-default-imap4-server} $B$NCM!#(B + $B=i4|@_Dj$O(B "localhost"$B!#(B +$B%]!<%HHV9f(B-> $BJQ?t(B @code{elmo-default-imap4-port} $B$NCM!#(B + $B=i4|@_Dj$O(B "143"$B!#(B + +$B%a%$%s$G;HMQ$9$k(B IMAP $B%5!<%P$rJQ?t(B @code{elmo-default-imap4-server} +$B$K;XDj$9$k$H!"$$$A$$$A%U%)%k%@L>$K%[%9%HL>$r=q$+$:$K$9$_$^$9!#Nc$($P%U%!(B +$B%$%"%&%)!<%k$r1[$($J$1$l$P$J$i$J$$>l9g$G$b(B @samp{foo%imap@@geteway} $B$N$h(B +$B$&$K;XDj$G$-$^$9!#(B + +$B%U%)%k%@L>$N:G8e$K(B '!' $B$,IU$$$F$$$k$H!"(BSSL (Secure Socket Layer)$B$r(B +$BMxMQ$7$F%3%M%/%7%g%s$rD%$j$^$9!#(B'!!' $B$@$H!"(BSTARTTLS$B$K$h$j(B +SSL$B%3%M%/%7%g%s$rD%$j$^$9!#(B +$BJQ?t(B @code{elmo-default-imap4-ssl} $B$NCM$,(B non-nil $B$J$i!"(B'!' $B$rIU$1(B +$B$J$/$F$b(B SSL $B$r;H$$$^$9!#(B'starttls $B$J$i(B '!!' $B$r0UL#$7$^$9!#(B + +(SSL $B$rMxMQ$9$k$K$O(B $BK\%Q%C%1!<%8$N(B utils/ssl.el $B$r%$%s%9%H!<%k$9$k(B +$BI,MW$,$"$j$^$9!#$J$*$+$D!"(BOpenSSL$B$K4^$^$l$k(Bopenssl$B$K%Q%9$,DL$C$F$$$k(B +$BI,MW$,$"$j$^$9!#(B +STARTTLS $B$rMxMQ$9$k$K$O!"$5$i$K!"(Bstarttls$B%Q%C%1!<%8$r%$%s%9%H!<%k(B +$B$9$kI,MW$,$"$j$^$9!#(B) + +$BG'>ZK!$H$7$F!"(B"auth" $B$b$7$/$O(B "cram-md5" $B$r;XDj$7$?>l9g!"%Q%9%o!<%I$r(B +$B%(%s%3!<%I$7$FAw?.$7$^$9!#$?$@$7!"%5!<%PB&$,%Q%9%o!<%I$r%(%s%3!<%I$7$F(B +$Bl9g$O!"3NG'$N$N$A!"(B"login" ($B@8%Q%9%o!<%I$rAw$k(B) +$B$K@ZBX$($^$9!#JQ?t(B @code{elmo-imap4-force-login} $B$,(B non-nil $B$J$i$P!"(B +$B3NG'L5$7$K(B "login" $B$K@ZBX$($^$9(B($B=i4|@_Dj$O(B nil)$B!#(B + +$BNc(B: %inbox -> IMAP $B$N%a!<%k%\%C%/%9!"(B"inbox" + %#mh/inbox -> IMAP $B$N%a!<%k%\%C%/%9!"(B"#mh/inbox" + + %inbox:hoge -> IMAP $B$N%a!<%k%\%C%/%9!"(B"inbox" $B$X%f!<%6(B "hoge" $B$G%"%/%;%9!#(B + %inbox:hoge/login@@server1 + -> server1 $B>e$N(B IMAP $B$N%a!<%k%\%C%/%9(B "inbox" $B$X(B + $B%f!<%6(B "hoge" $B$G!"@8%Q%9%o!<%I$rAw$C$F(B("login"$B$G(B) + $B%"%/%;%9!#(B +@end example + +@subsection $BF|K\8l%a!<%k%\%C%/%9L>$N07$$(B(Modified UTF7) + +$B;HMQ$7$F$$$k(B Emacs $B$,%f%K%3!<%I$KBP1~$7$F$*$j!$$+$D!"JQ?t(B +@code{elmo-imap4-use-modified-utf7} $B$K(B non-nil $B$NCM$r@_Dj$7$F$$$k>l9g(B($B%G(B +$B%U%)%k%H$O(B nil)$B!"F|K\8l(B($B$d$=$NB>$N1Q8l0J30$N8@8l(B)$B$G%a!<%k%\%C%/%9L>$r(B +$B;XDj$9$k$3$H$,$G$-$^$9!#(B + +$B%f%K%3!<%I$r07$($k(B Emacs $B$K$O0J2<$,$"$j$^$9!#(B + +@itemize @bullet +@item Emacs 20.3 $B0J9_(B + Mule-UCS + +Emacs 20 $B$G$O!"(BMule-UCS $B$,%$%s%9%H!<%k$5$l$F$$$l$P%f%K%3!<%I$r07$($^$9!#(B +Mule-UCS $B$O0J2<$N(B URL $B$+$iF~u!"(BXEmacs 21.2 $B$G%f%K%3!<%I(B(UTF-8)$B$r07$&$K$O!"(Bucs-conv $B%Q%C%1!<%8$,I,(B +$BMW$G$9!#(Bucs-conv $B$O0J2<$N(B anonymous cvs $B7PM3$GF~$r07$&$K$O!"$5$i$K!"%3%^%s%I(B u7tou8, +u8tou7 $B$,%$%s%9%H!<%k$5$l$F$$$kI,MW$,$"$j$^$9!#$3$l$i$N%3%^%s%I$O0J2<$+(B +$B$iF~(B'[[':' '$B%f!<%6L>(B']['@@' '$B%[%9%HL>(B'][':' '$B%]!<%HHV9f(B']]['!'] + +default $BCM(B: +$B%[%9%HL>(B -> $BJQ?t(B @code{elmo-default-nntp-server} $B$NCM!#=i4|@_Dj$O(B "localhost"$B!#(B +$B%f!<%6L>(B -> $BJQ?t(B @code{elmo-default-nntp-user} $B$NCM!#=i4|@_Dj$O(B nil$B!#(B +$B%]!<%HHV9f(B-> $BJQ?t(B @code{elmo-default-nntp-port} $B$NCM!#(B + $B=i4|@_Dj$O(B 119$B!#(B + +$B%f!<%6L>$,(B non-nil $B$N>l9g$O(BAUTHINFO$B$K$h$kG'>Z$r9T$J$$$^$9!#(B +$B%U%)%k%@L>$N:G8e$K(B '!' $B$,IU$$$F$$$k$H!"(BSSL $B$rMxMQ$7$F%3%M%/%7%g%s$rD%$j$^$9!#(B +'!!' $B$@$H!"(BSTARTTLS$B$K$h$j(BSSL$B%3%M%/%7%g%s$rD%$j$^$9!#(B +$BJQ?t(B @code{elmo-default-nntp-ssl} $B$NCM$,(B non-nil $B$J$i!"(B'!' $B$rIU$1(B +$B$J$/$F$b(B SSL $B$r;H$$$^$9!#(B'starttls $B$J$i(B '!!' $B$r0UL#$7$^$9!#(B +(SSL $B$rMxMQ$9$k$K$O(B $BK\%Q%C%1!<%8$N(B utils/ssl.el $B$r%$%s%9%H!<%k$9$k(B +$BI,MW$,$"$j$^$9!#$J$*$+$D!"(BOpenSSL$B$K4^$^$l$k(Bopenssl$B$K%Q%9$,DL$C$F$$$k(B +$BI,MW$,$"$j$^$9!#(B +STARTTLS $B$rMxMQ$9$k$K$O!"$5$i$K!"(Bstarttls$B%Q%C%1!<%8$r%$%s%9%H!<%k(B +$B$9$kI,MW$,$"$j$^$9!#(B) + + +$BNc(B: -fj.rec.tv -> $B%K%e!<%9%0%k!<%W!"(Bfj.rec.tv$B!#(B + -fj.rec.tv@@newsserver -> newsserver $B>e$N%K%e!<%9%0%k!<%W!"(Bfj.rec.tv$B!#(B +@end example + + +@node MH Folder, Maildir Folder, NNTP Folder, Folders +@section MH $B%U%)%k%@(B +@cindex MH Folder +@cindex @samp{+} +@pindex MH +@cindex Maildir + +MH $B7A<0(B(1$B%U%!%$%k(B1$B%a!<%k(B)$B$GJ]B8$5$l$?%a!<%k$rFI$`$?$a$N%U%)%k%@$G$9!#(B + +@example +$B=q<0(B: '+' '$B%G%#%l%/%H%jL>(B' + +$B%G%#%l%/%H%jL>$O!"DL>o!"JQ?t(B @code{elmo-localdir-folder-path} +($B=i4|@_Dj$O(B @file{~/Mail}) $B$+$i$NAjBP%Q%9$G$9$,!"(B +@samp{/} $B$d(B @samp{~} $B$G;O$^$C$F$$$l$P@dBP%Q%9$H8+Pv$7$^$9(B +($B%I%i%$%V%l%?!<$bF1MM$G$9(B)$B!#(B + +$B%a%C%;!<%8$,J]B8$5$l$k%U%!%$%k$N%U%!%$%kL>$K$O!"%a%C%;!<%8HV9f$,;HMQ$5$l$^$9!#(B + +$BNc(B: +inbox -> "~/Mail/inbox" + +from/teranisi -> "~/Mail/from/teranisi" + +~/test -> "~/test" +@end example + +@node Maildir Folder, News Spool Folder, MH Folder, Folders +@section Maildir $B%U%)%k%@(B +@cindex Maildir Folder +@cindex @samp{.} +@pindex Maildir + +Maildir $B7A<0(B(1$B%U%!%$%k(B1$B%a!<%k(B)$B$GJ]B8$5$l$?%a!<%k$rFI$`$?$a$N%U%)%k%@$G$9!#(B + +@example +$B=q<0(B: '.' '$B%G%#%l%/%H%jL>(B' + +$B%G%#%l%/%H%jL>$O!"DL>o!"JQ?t(B @code{elmo-maildir-folder-path} ($B=i4|@_Dj$O(B +@file{~/Maildir}) $B$+$i$NAjBP%Q%9$G$9$,!"(B@samp{/} $B$d(B @samp{~} $B$G;O$^$C$F(B +$B$$$l$P@dBP%Q%9$H8+Pv$7$^$9(B($B%I%i%$%V%l%?!<$bF1MM$G$9(B)$B!#(B + +Maildir $B$O!"(Bcur$B!"(Bnew$B!"(Btmp $B$N%G%#%l%/%H%j$r4^$s$G$$$^$9!#2<$N(B cur $B%G%#%l%/%H%j$G$9!#;XDj%G%#%l(B +$B%/%H%jD>2<$N(B new $B%G%#%l%/%H%j$K4^$^$l$k%a%C%;!<%8%U%!%$%k$O!"%"%/%;%9;~(B +$B$K(B cur $B%G%#%l%/%H%j$X0\F0$5$l$^$9!#$^$?!"(Btmp $B%G%#%l%/%H%j$K4^$^$l!"(B36 $B;~(B +$B4V0J>e%"%/%;%9$,L5$$%a%C%;!<%8%U%!%$%k$O:o=|$5$l$^$9!#(B + +$B$3$NF0:n$O(B @samp{http://cr.yp.to/proto/maildir.html} +($BF|K\8lLu$O(B @samp{http://www.jp.qmail.org/q103/jman5/maildir.html}) +$B$K=>$C$F$$$^$9!#(B + +$BNc(B: . -> "~/Maildir" + .inbox -> "~/Maildir/inbox" + .from/teranisi -> "~/Maildir/from/teranisi" + .~/test -> "~/test" +@end example + +@node News Spool Folder, Archive Folder, Maildir Folder, Folders +@section News Spool $B%U%)%k%@(B +@cindex News spool Folder +@cindex @samp{=} +@pindex gnspool + +Mew/IM $B$,Ds>'$9$k!"%m!<%+%k$KJ]B8$5$l$?%K%e!<%95-;v$rFI$_=q$-$9$k$?$a$N(B +$B%U%)%k%@$G$9!#(BNNTP $B7PM3$G$O$J$/!"(Bgnspool $B$J$I$r;H$C$Fl9g$K$=$N%9%W!<%k$rD>@\FI$`!"$H$$$&;H$$J}$bA[Dj$7$F$$$^$9!#(B + +@example +$B=q<0(B: '=' '$B%G%#%l%/%H%jL>(B' + +$B%G%#%l%/%H%jL>$O!"JQ?t(B @code{elmo-localnews-folder-path} + ($B=i4|@_Dj$O(B @file{~/News}) +$B$G;XDj$5$l$?%G%#%l%/%H%j$N%5%V%G%#%l%/%H%j$r;X$7$^$9!#(B +$B%G%#%l%/%H%j$N6h@Z$j$O(B @samp{.} $B$G$b2D$G$9!#(B + +$BNc(B: =fj/os/os2 -> "~/News/fj/os/os2" + =fj.os.bsd.freebsd -> "~/News/fj/os/bsd/freebsd" +@end example + + +@node Archive Folder, POP Folder, News Spool Folder, Folders +@section $B%"!<%+%$%V%U%)%k%@(B +@cindex Archive Folder +@cindex @samp{$} +@c @pindex ange-ftp + +Info-ZIP $B$d(B LHA $B$J$I$G05=L$5$l$?%"!<%+%$%V%U%!%$%k$r0l$D$N%U%)%k%@$H$7(B +$B$F07$$$^$9!#(B + +@example +$B=q<0(B: '$' '$B%G%#%l%/%H%jL>(B' [';' $B%"!<%+%$%P%?%$%W(B ';' $B%W%l%U%#%/%9(B] + +$B!X%G%#%l%/%H%jL>!Y$O!"DL>o!"JQ?t(B @code{elmo-archive-folder-path} +($B=i4|@_Dj$O(B @file{~/Mail}) $B$+$i$NAjBP%Q%9$G$9$,!"(B +@samp{/} $B$d(B @samp{~} $B$G;O$^$C$F$$$l$P@dBP%Q%9$H8+Pv$7$^$9(B +($B%I%i%$%V%l%?!<$b(B OK)$B!#(B +ange-ftp $BI=5-$b(B ange-ftp, efs $B$,;H$($k4D6-$G$O(B OK $B$G$9!#(B + +$B%U%)%k%@$Ne=R$N%G%#%l%/%H%j$K$"$k(B +@code{elmo-archive-basename}($B=i4|CM$O(B "elmo-archive")$B$K$J$j$^$9!#(B +$B$?$@$7!"%G%#%l%/%H%j$G$J$/%U%!%$%k$G$"$C$?>l9g!"$=$N%U%!%$%k$r%U%)%k%@(B +$B$H8+Pv$7$^$9!#(B +$B3HD%;R$O%"!<%+%$%PKh$K<+F0E*$K(B($BF0E*$K(B)$BA*Br$5$l$^$9!#(B + +$B!X%"!<%+%$%P%?%$%W!Y$r>JN,$7$?>l9g!"JQ?t(B @code{elmo-archive-default-type} +($B=i4|@_Dj$O(B 'zip)$B$,;2>H$5$l$^$9!#(B + +$B!X%W%l%U%#%/%9!Y$O!"=q8K$,%G%#%l%/%H%j9=B$$r$b$C$F$$$k>l9g$K!"$=$N%G%#(B +$B%l%/%H%jItJ,$r;XDj$7$^$9!#(B +$B$3$l$Ol9g!"(B@file{msend.tar.gz} $B$O(B @file{spool/1} $B$N(B +$B$h$&$J9=B$$J$N$G!"(B"spool" $B$r;XDj$7$^$9!#(B + +$BNc(B: $teranisi -> "~/Mail/teranisi/elmo-archive.zip" + $bsd/freebsd;lha -> "~/Mail/bsd/freebsd/elmo-archive.lzh" + $/foo@@server:~/bar;zoo -> server $B>e$N(B "~/bar/elmo-archive.zoo" + $d:/msend.tar.gz;tgz;spool -> "d:/msend.tar.gz" +@end example + +@menu +* Archiver:: $BBP1~(B($B2DG=(B)$B%"!<%+%$%P(B +* Archive Tips:: TIPS +* Archive Vars:: $B%+%9%?%^%$%:JQ?t(B +@end menu + + +@node Archiver, Archive Tips, Archive Folder, Archive Folder +@subsection $B%"!<%+%$%V%U%)%k%@$,BP1~$7$F$$$k(B($BBP1~2DG=$J(B)$B%"!<%+%$%P(B +@cindex Archiver +@pindex LHA +@pindex Info-ZIP +@pindex UNZIP +@pindex ZOO +@pindex RAR +@pindex TAR +@pindex GNU TAR + +$B%G%U%)%k%H$G0J2<$N%"!<%+%$%P$KBP1~$7$^$9!#(B + +@example + LHA, Info-ZIP/UNZIP, ZOO, RAR ;; $B%U%k%9%Z%C%/(B + GNU TAR('tgz, 'tar) ;; $B%G%U%)%k%H$G$O1\Mw@lMQ(B +@end example + +$BJ#?t%U%!%$%k$r#1%W%m%;%9$G0l$D$N=q8K$X$^$H$a$k$3$H$,$G$-$k%"!<%+%$%P$G(B +$B$"$l$P!"I,MW$JJQ?t$rDI2CDj5A$9$k$@$1$G;H$($k2DG=@-$,$"$j$^$9(B(ARJ/UNARJ, +ARC $B$O!"C$9(B +('mv) $B$3$H$,$G$-$J$$E@$G??LLL\$K%5%]!<%H$7$F$$$^$;$s(B)$B!#(B +$BJ#?t%U%!%$%k$r0l$D$K$^$H$a$i$l$J$$E@$G(B gzip, bzip, bzip2 $B$O;H$($^$;$s!#(B +$BI8=`=PNO$X2rE`$G$-$J$$%"!<%+%$%P$K$bI8=`$G$OBP1~$7$^$;$s!#(B + +@subsection $B3F(B OS $B$G$N%"!<%+%$%P$K4X$9$kFC5-;v9`(B + +$B%U%k%9%Z%C%/$GFI$_=q$-2DG=$J$3$H$,3NG'$5$l$F$$$k%"!<%+%$%P$O!"0J2<$N$H$*(B +$B$j$G$9(B(@samp{*} $B0u$N$b$N$O=hM}B.EY$J$I$NE@$G:G$bE,$7$F$$$k$b$N(B)$B!#(B + +@example +[OS/2] Warp4.0J(w/o VoiceType)+Fx00505/emx0.9c(fix04)/PMMule,EmacsPM + LHA OS/2 version Rel.2.06b Feb 18, 1998 + *UnZip 5.32 of 3 November 1997, by Info-ZIP. + *Zip 2.2 (November 3rd 1997). + Zoo archiver, zoo 2.1 $@asis{}Date: 91/07/09 02:10:34 $ + GNU tar version 1.10 - AK 2.58 (DBCS/SJIS) 981216(homy)$BHG(B + gzip 1.2.4 (18 Aug 93) + bzip2 $B%Q%C%A(B(by $BHSED$5$s(B) + +[UN|X] FreeBSD 2.2.7-RELEASE, Linux 2.0.30, Solaris2.6, HP-UX 9.07 + LHa for UNIX V 1.14c + UnZip 5.32 of 3 November 1997 + Zip 2.2 (November 3rd 1997) + GNU tar 1.12 (1.11.x $B$OIT2D(B) + gzip 1.2.4 (18 Aug 93) + +[Win32] Win.98/Meadow + Lha32 version 1.28 + Zip 2.2 + UnZip 5.40 + GNU tar 1.11.8 + 1.5(WIN32) + GZIP 1.2.4 + RAR 2.06 + +$B"((B LHA $B$K4X$9$kCm0U(B + +OS/2 $B$N>l9g!"(BPeter Fitzsimmons $B;a:n$N(B LH/2 $B$K$OBP1~$7$^$;$s!#J?>>HG$r$*(B +$B;H$$$/$@$5$$!#(B +Win32 $B$G$O(B DOS $BHG$G$J$/!"(BLHa32 $B$G$J$$$HF0$+$J$$$H$N$3$H$G$9!#(B + +$B"((B GNU tar $B$K4X$9$kCm0U(B + +GNU tar $B$O=q8K$+$i$N:o=|$KLdBj$,$"$k$b$N$,B?$$$N$G!"FC$KCm0U$7$F$/$@$5$$!#(B +$B=q8K$,GK2u$5$l$k4m81@-$,9b$$$N$G!"%U%k%9%Z%C%/$GFI$_=q$-$9$kA0$K(B +--delete -f $B$r=e5-$N$b$N$G$O(B +$B:#$N$H$3$mLdBj$OJs9p$5$l$F$$$^$;$s!#(B +@end example + + +@node Archive Tips, Archive Vars, Archiver, Archive Folder +@subsection TIPS +@cindex Archive Tips + +$B2wE,$K0\9T$9$k$K$O!"(Bwl-summary-archive() $B$rl9g$O!"(B +$BJQ?t(B @code{elmo-archive-treat-file} $B$r(B non-nil $B$K@_Dj$9$kI,MW$,$"$j$^$9!#(B +$B$J$*!"(BOS/2 $B>e$G$N%F%9%H$G$O!"(BMule2.3(19.28) $B$H(B Emacs20.2 $B$G$O=hM}B.EY$K(B +$B05E]E*$J0c$$$,$"$j$^$9!#(B +$B2wE,$K;H$&$K$O(B Emacs20 $B$r$*4+$a$7$^$9(B(re-search $B$NB.EY$NLdBj$@$H$9$k$H(B +19.3x $B0J>e$+$I$&$+$,6-$K$J$k$G$7$g$&(B)$B!#(B + +$B$^$?!"0l$D$N=q8K%U%!%$%k$KB?$/$N%U%!%$%k$,4^$^$l$F$$$k$H%"!<%+%$%P5/F0;~(B +$B$N%*!<%P!<%X%C%I$,2CB.EYE*$KA}2C$9$k(B($BFC$K(B LHA $B$N>l9g(B)$B$?$a!"(B150 $BDLDxEY!"(B +$B:GBg$G$b(B 200$BDL$^$G$K$7$F$*$/$H!"%9%H%l%9$J$/FI$_=q$-$G$-$k$G$7$g$&!#(B + +$B$J$*!"EvA3$N$3$H$J$,$i(B + +@lisp +(setq wl-fcc "$backup") +(setq wl-trash-folder "$trash;lha") +@end lisp + +@noindent +$B$b2DG=$G$9(B@t{:-)}$B!#(B + + +@node Archive Vars, , Archive Tips, Archive Folder +@subsection $B%"!<%+%$%V%U%)%k%@$K4X$9$kJQ?t(B +@cindex Archive variables + +@table @code +@item elmo-archive-default-type +@vindex elmo-archive-default-type +$B%G%U%)%k%H$N%"!<%+%$%P%?%$%W$r(B symbol $B$G;XDj$7$^$9!#=i4|CM$O(B 'zip $B$G$9!#(B + +@item elmo-archive-@var{type}-method-alist +@vindex elmo-archive-TYPE-method-alist +$B%"!<%+%$%P$N(B @var{type} +($Be$H%;%C%H$G%U%k%9%Z%C%/(B + 'cp ('cp-pipe) ;; +@end example + +@noindent +$B$G$9!#3g8LFb$N$b$N$O!"$J$/$F$b9=$$$^$;$s(B($B$"$l$PM%@hE*$K;H$$$^$9(B)$B!#(B + +@item elmo-archive-suffix-alist +@vindex elmo-archive-suffix-alist +$B%"!<%+%$%P%?%$%W(B(symbol) $BKh$KBP1~$9$k=q8K$N3HD%;R$r5-=R$7$^$9!#(B + +@item elmo-archive-file-regexp-alist +@vindex elmo-archive-file-regexp-alist +$B=q8K$N%j%9%H1\Mw;~$N=PNO$+$i%U%!%$%kL>$ruBV$G$O(B)$B%"!<%+%$%P$r%7%'%k$r7PM3$;$:$K5/F0$7(B +$B$^$9!#(Belisp $B%l%Y%k$G$N%3%^%s%IJ8;zNs$NAm%P%$%H?t$K$O@)8B$O$J$$$H$N$3$H$J(B +$B$N$G!"B?$/$N%Q%i%a!<%?$r0lEY$KM?$($FF0$+$;$k$+$I$&$+$O(B OS $B%l%Y%k$NLdBj$K(B +$B$J$j$^$9!#$3$l$O!"Nc$($P?tI4DLC10L$N%a%C%;!<%8$r0lEY$K>C5n$G$-$k$+$I$&$+(B +$B$NLdBj!"$HFI$_BX$($F$/$@$5$$!#(B +OS/2 $B$G$O%7%'%k$r2p$5$:$KH/9T$G$-$k%3%^%s%IJ8;zNs$O(B 8190 $B%P%$%H$^$G$J$N(B +$B$G!"M>M5$r8+$F%G%U%)%k%H$r(B 8000 $B$K$7$F$$$^$9!#(BOS/2 REXX $B$d%7%'%k%9%/%j%W(B +$B%H$J$I$r3z$^$9>l9g!"%7%'%k$N]$H$J$k%U%!%$%k$N%j%9%H$rI8=`F~NO$+$il9g!"#1(B +$B%W%m%;%9$G=hM}$9$k$3$H$,$G$-$^$9!#(B +@end table + + +@node POP Folder, Multi Folder, Archive Folder, Folders +@section POP $B%U%)%k%@(B +@cindex POP Folder +@cindex @samp{&} +@cindex RFC 1939 +@cindex POP3 +@cindex APOP + +RFC 1939 $B$G5,Dj$5$l$?(B POP3 $B$rMxMQ$7$F%a!<%k$rFI$`$?$a$N%U%)%k%@$G$9!#(B + +@example +$B=q<0(B: '&' ['$B%f!<%6L>(B'][['/' '$BG'>ZK!(B']['@@' '$B%[%9%HL>(B'][':' '$B%]!<%HHV9f(B']]['!'] + +$BG'>ZK!$K$O!"0J2<$N(B 2 $BZ(B) + "apop" (APOP $B$GG'>Z(B) + +default $BCM(B: +$B%f!<%6L>(B -> $BJQ?t(B @code{elmo-default-pop3-user} $B$NCM!#(B + $B=i4|@_Dj$O(B $B4D6-JQ?t(B USER $B$+!"(BLOGNAME $B$+!"(B(user-login-name) $B$NJV$jCM!#(B +$BG'>ZK!(B -> $BJQ?t(B @code{elmo-default-pop3-authenticate-type} $B$NCM!#(B + $B=i4|@_Dj$O(B "user"$B!#(B +$B%[%9%HL>(B -> $BJQ?t(B @code{elmo-default-pop3-server} $B$NCM!#(B + $B=i4|@_Dj$O(B "localhost"$B!#(B +$B%]!<%HHV9f(B -> $BJQ?t(B @code{elmo-pop3-default-port} $B$NCM!#(B + $B=i4|@_Dj$O(B 110$B!#(B + +$BNc(B: &hoge@@localhost -> localhost $B$X%f!<%6(B "hoge" $B$G%"%/%;%9!#(B + &hoge@@popserver:109 -> $B%[%9%H(B "popserver" $B$N%]!<%H(B 109 $BHV$X(B + $B%f!<%6(B "hoge" $B$G%"%/%;%9!#(B +@end example + +APOP $B$rMxMQ$9$k$K$O!"(B@file{md5.el} $B$,I,MW$G$9!#(B +(XEmacs$B$G$O!"I,MW$"$j$^$;$s!#(B) +@file{md5.el} $B$O(B $BK\%Q%C%1!<%8$N(B @file{utils/sasl/lisp/} $B$+(B + Emacs/W3 $B%Q%C%1!<%8(B + +@example +http://www.cs.indiana.edu/elisp/w3/docs.html +@end example + +$B$^$?$O!"(BLCD archive $B$+$iF~$N:G8e$K(B '!' $B$,IU$$$F$$$k$H!"(BSSL $B$rMxMQ$7$F%3%M%/%7%g%s$rD%$j$^$9!#(B +$BJQ?t(B @code{elmo-default-pop-ssl} $B$NCM$,(B non-nil $B$J$i!"(B'!' $B$rIU$1(B +$B$J$/$F$b(B SSL $B$r;H$$$^$9!#(B'starttls $B$J$i(B '!!' $B$r0UL#$7$^$9!#(B +(SSL $B$rMxMQ$9$k$K$O(B $BK\%Q%C%1!<%8$N(B utils/ssl.el $B$r%$%s%9%H!<%k$9$k(B +$BI,MW$,$"$j$^$9!#$J$*$+$D!"(BOpenSSL$B$K4^$^$l$k(Bopenssl$B$K%Q%9$,DL$C$F$$$k(B +$BI,MW$,$"$j$^$9!#(B +STARTTLS $B$rMxMQ$9$k$K$O!"$5$i$K!"(Bstarttls$B%Q%C%1!<%8$r%$%s%9%H!<%k(B +$B$9$kI,MW$,$"$j$^$9!#(B) + +@node Multi Folder, Filter Folder, POP Folder, Folders +@section $B%^%k%A%U%)%k%@(B +@cindex Multi Folder +@cindex @samp{*} +@cindex Folder, Multiple +@cindex Folder, Marge + +$BJ#?t$N%U%)%k%@$r2>A[E*$K0l$D$K8+$($k$h$&$K$9$k%U%)%k%@$G$9!#(B + +@example +$B=q<0(B: '*' '$B%U%)%k%@(B' [',' '$B%U%)%k%@(B'] ... [',' '$B%U%)%k%@(B'] + +'*' $B$N8e$K(B $B%U%)%k%@(B,$B%U%)%k%@(B,@dots{},$B%U%)%k%@(B $B$N$h$&$K(B ',' ($B%3%s%^(B)$B$G6h@Z$C$F(B +$B0l$D$K8+$($k$h$&$K$7$?$$%U%)%k%@72$r;XDj$7$^$9!#(B + +$BNc(B: + *-fj.editor.xemacs,-fj.editor.mule,-fj.editor.emacs + -> -fj.editor.xemacs, -fj.editor.mule, -fj.editor.emacs $B$,0l$D$N(B + $B%U%)%k%@$H$7$F8+$($k!#(B + + *+inbox,-fj.rec.tv,%inbox + -> +inbox, -fj.rec.tv, %inbox $B$,0l$D$N%U%)%k%@$H$7$F8+$($k!#(B + +@end example + + +@node Filter Folder, Pipe Folder, Multi Folder, Folders +@section $B%U%#%k%?%U%)%k%@(B +@cindex Filter Folder +@cindex @samp{/} +@cindex Folder, Filtering +@cindex Folder, Virtual + +$B;XDj$7$?>r7o$rK~$?$9%a%C%;!<%8$N$_$r4^$`2>A[E*$J%U%)%k%@$G$9!#(B + +@example +$B=q<0(B: '/' '$B>r7o(B' '/' '$B%U%)%k%@(B' + +$B!X>r7o!Y$K$O!"0J2<$r=q$1$^$9!#(B + +1. $BItJ,%U%#%k%?!'(B "first:$B?t;z(B", "last:$B?t;z(B" + +first: $BA4%a%C%;!<%8$N@hF,$+$i(B'$B?t;z(B'$B$N?t$@$1%a%C%;!<%8$r@Z$j=P$7$^$9!#(B +last: $BA4%a%C%;!<%8$NKvHx$+$i(B'$B?t;z(B'$B$N?t$@$1%a%C%;!<%8$r@Z$j=P$7$^$9!#(B + +$BNc(B: + /last:10/-fj.os.linux -> -fj.os.linux $B$N:G6a$N(B 10 $B8D$N%a%C%;!<%8(B + $B$N$_$rI=<($9$k%U%)%k%@(B + /first:20/%inbox -> %inbox $B$N:G=i$N(B 20 $B8D$rI=<($9$k%U%)%k%@(B + +2. $BF|IU$1%U%#%k%?!'(B "since:$BF|IU(B" "before:$BF|IU(B" + +since: '$BF|IU(B'$B$h$j:G6a$N%a%C%;!<%8$N$_$r $B:rF|(B +lastweek -> $B@h=5$N:#F|(B +lastmonth -> $B@h7n$N:#F|(B +lastyear -> $B5nG/$N:#F|(B +'$B?t;z(B'daysago -> '$B?t;z(B' $BF|A0(B (e.x. 3daysago) +'$BF|(B'-'$B7n$NN,L>(B'-'$BG/(B' -> $BF|IU$1$=$N$b$N$N;XDj(B (ex. 1-Nov-1998) + +$BNc(B: + /since:3daysago/+inbox $B"*(B $B:G6a#3F|4V$N(B +inbox $BCf$N%a%C%;!<%8!#(B + /before:yesterday/+inbox $B"*(B $B$-$N$&$h$j0JA0$N(B +inbox $BCf$N%a%C%;!<%8!#(B + +3. $B%U%#!<%k%I%U%#%k%?!'(B "$B%U%#!<%k%IL>(B=$BJ8;zNs(B" + +$B%a%C%;!<%8$N%U%#!<%k%I$NCf?H$,%^%C%A$9$k%a%C%;!<%8$r!Y!"!XJ8;zNs!Y$KBgJ8;z>.J8;z$N6hJL$O$"$j$^$;$s!#(B + +$BNc(B: + /from=teranisi/+inbox -> +inbox $B$G!"(BFrom: $B%U%#!<%k%I$K(B "teranisi" + $B$H$$$&J8;zNs$r4^$`%a%C%;!<%8$N%U%)%k%@(B + /body=$B$J$s$H$+(B/%inbox -> %inbox $B$G!"K\J8$K(B "$B$J$s$H$+(B" + $B$H$$$&J8;zNs$r4^$`%a%C%;!<%8$N%U%)%k%@(B + +"|" $B$G6h@Z$C$F(B OR $B>r7o$r;XDj$G$-$^$9!#(B +$B$^$?!"(B/tocc=xxxx/ $B$O!"(B/to=xxxx|cc=xxxx/ $B$HF1$8$K$J$j$^$9!#(B + +$BNc(B: + + /from=teranisi|to=teranisi/+inbox + -> +inbox $B$G(BTo: $B%U%#!<%k%I$+(B From: $B%U%#!<%k%I$K(B + "teranisi" $B$r4^$`%a%C%;!<%8$N%U%)%k%@(B + /tocc=teranisi/+inbox -> +inbox $B$G!"(BTo: $B%U%#!<%k%I$+(B Cc: $B%U%#!<%k%I$K(B + "teranisi" $B$r4^$`%a%C%;!<%8$N%U%)%k%@(B + +$B1~MQJT(B + + %inbox,/from=teranisi/%inbox@@server + -> %inbox$B!"$*$h$S!"(B + %inbox@@server $B$NCf$G(B From $B%U%#!<%k%I$,(B "teranisi" $B$N%a%C%;!<%872!"(B + $B$r$$$C$Z$s$KI=<($9$k%U%)%k%@!#(B + + /last:100//to=teranisi/*+inbox,%inbox + -> +inbox $B$H(B %inbox $BCf$N%a%C%;!<%8$N$&$A!"(B + To: $B%U%#!<%k%I$,(B "teranisi" $B$K%^%C%A$9$k(B + $B%a%C%;!<%8$N:G6a$N(B100$B8D$rI=<($9$k%U%)%k%@!#(B + + /from=hogehoge//last:20//tocc=teranisi/%#mh/inbox@@localhost + ($B"*$G@^$jJV$7!# %#mh/inbox@@localhost $B$NCf$G!"(BTo $B$+(B Cc $B$K(B "teranisi" $B$,4^$^$l$k(B + $B%a%C%;!<%8$N:G6a$N(B 20 $B8D$N$&$A!"(BFrom $B$,(B "hogehoge" $B$N$b$N$r(B + $BI=<($9$k%U%)%k%@!#(B + +;;; --- $Be$N@)Ls(B --- +;;; $B8=:_$N$H$3$m!"(Bnntp $B%U%)%k%@$OF|IU%U%#%k%?!"%U%#!<%k%I%U%#%k%?(B +;;; $B$r=q$1$^$;$s!#(B +;;; $B$^$?!"(Bimap4 $B%U%)%k%@(B $B$G$O(B rfc2060 $B$N(B search $B%3%^%s%I$K$=$N$^$^(B +;;; $BM?$($i$l$k$b$N$7$+>r7o$N%U%#!<%k%IL>$K=q$1$^$;$s!#(B +;;; (-> to,cc,from,subject,body $B$N$_(B) +;;; localdir $B$N%U%)%k%@$K$OG$0U$N%U%#!<%k%IL>$r=q$1$^$9!#(B +@end example + + +@node Pipe Folder, Internal Folder, Filter Folder, Folders +@section $B%Q%$%W%U%)%k%@(B +@cindex Pipe Folder +@cindex @samp{|} +@cindex Get Message +@cindex Download Message +@cindex Incorporate Message + +$B%U%)%k%@1\Mw;~$K!"<+F0E*$K%a%C%;!<%8$Nl9g$O!"(B + +|&username@@popserver|+inbox + +$B$N$h$&$K;XDj$9$k$H!"%U%)%k%@$NI=<($r99?7$9$k$H$-$K(B +&username@@popserver $B$+$i!"(B+inbox $B$X%a%C%;!<%8$,<+F0E*$K %inbox $B$+$i(B %myinbox $B$X%a%C%;!<%8$r &user@@popserver1 $B$H(B &user@@popserver2 $B$+$i(B +inbox $B$X%a%C%;!<%8$r(B + $BA[%U%)%k%@$G$9!#(B +$B=EMW%^!<%/$r%a%C%;!<%8$K$D$1$F$*$$$F!"$"$H$+$i8+D>$7$?$$$H$-$J$I$KJXMx$G$9!#(B + +$B$3$N%U%)%k%@$G%a%C%;!<%8$r:o=|$9$k$H!"$=$N%a%C%;!<%8$K$D$$$F$$$?(B @samp{$} +$B%^!<%/$,:o=|$5$l$^$9!#(B +$B$^$?!"$3$N%U%)%k%@$K%a%C%;!<%8$rDI2C$9$k$H!"$=$N%a%C%;!<%8$K$O(B @samp{$} $B%^!<%/(B +$B$,IU$1$i$l$^$9!#(B + +'cache/00 $B!A(B 1F $B$O%M%C%H%o!<%/7PM3$GFI$s$@%a%C%;!<%8$N%-%c%C%7%e$K%"%/%;(B +$B%9$9$k$?$a$N%U%)%k%@$G$9!#(B00 $B!A(B 1F $B$K$O!"%-%c%C%7%e%G%#%l%/%H%j(B +(@file{~/.elmo/cache})$B$N%5%V%G%#%l%/%H%jL>$r;XDj$7$^$9!#(B +@end example + +@c +@c Folder +@c +@node Folder, Summary, Folders, Top +@chapter $B%U%)%k%@%b!<%I(B +@cindex Folder + +$B5/F0$7$F:G=i$K8=$l$k$N$,%U%)%k%@%b!<%I(B($B%U%)%k%@$N0lMwI=<((B)$B$G$9!#(B + +$B%U%)%k%@%b!<%I$G$O!"FI$_$?$$%U%)%k%@$NA*Br!"9XFI%U%)%k%@$NJT=8$r9T$J$$$^$9!#(B + +@menu +* Selecting Folder:: $BFI$_$?$$%U%)%k%@$NA*Br(B +* Folder Manager:: $B9XFI%U%)%k%@$NJT=8(B +@end menu + + +@node Selecting Folder, Folder Manager, Folder, Folder +@section $BFI$_$?$$%U%)%k%@$NA*Br(B +@cindex Selecting Folder + +@subsection $B;HMQJ}K!(B(TIPS) + +@subsubsection $B?75,?t!"L$FI?t$N%A%'%C%/(B + +$B%U%)%k%@%b!<%I$N8+$?$a$O$3$s$J46$8$K$J$k$O$:$G$9!#(B +(XEmacs $B$G$O$b$&$A$g$C$H$+$C$3$h$/8+$($k$O$:$G$9(B @t{;-)}) + +@example +[-]Desktop:14186/35580/67263 + $B(B:$BL$F14|(B($B?75,(B)$B?t(B/$BL$FI?t(B/$BAm?t!Y(B +@end example + +@noindent +$B$G$9!#(B +$B%A%'%C%/$7$?$$%U%)%k%@$N>e$K%+!<%=%k$r9g$o$;$F(B @kbd{s} $B$r2!$9$H!"(B +$B$3$l$i$N?t$,:G?7$N$b$N$K99?7$5$l$^$9!#(B +$B$?$/$5$s?75,%a%C%;!<%8$,$"$k$H?'$,JQ$o$j$^$9!#(B + +$B%U%)%k%@%b!<%IA4BN$O(B @samp{Desktop} $B$H$$$&%0%k!<%W%U%)%k%@$K$J$j$^$9!#(B +$B%0%k!<%W%U%)%k%@$O%j%?!<%s%-!<$G3+JD$G$-$^$9!#(B +$B%0%k!<%W%U%)%k%@$KBP$9$kA`:n$O!"$=$N%0%k!<%W%U%)%k%@$KB0$9$kA4$F$N;R(B +$B%U%)%k%@$KBP$9$k0l3g$7$?A`:n$H$7$F07$o$l$^$9!#(B +$BNc$($P!"(B@samp{[-]Emacsen} $B$N$H$3$m$K%+!<%=%k$r9g$o$;$F(B @kbd{s} $B$r2!$9$H!"(B +$B$3$l$K4^$^$l$k#6$D$N%U%)%k%@$NI=<($r:G?7$N$b$N$K99?7$7$^$9!#(B + +@subsubsection $B%U%)%k%@$NA*Br(B +$B%U%)%k%@$N9T$K%+!<%=%k$rCV$$$F%j%?!<%s(B($B%9%Z!<%9(B)$B%-!<$r2!$9$H$=$N%U%)%k%@$NFbMF$rI=<($9$k%5%^%j%b!<%I$K0\F0$7$^$9!#(B + +$B$3$N$H$-!"JQ?t(B @code{wl-stay-folder-window} $B$,(B non-nil $B$J$i%5%^%j$K0\F0$7$?$H$-$K%U%)%k%@%P%C%U%!$N1&$K%5%^%j$N%P%C%U%!$,8=$l$^$9!#(B + +@subsection $B%-!<%P%$%s%I(B + +$B%U%)%k%@%b!<%I$G$N%U%)%k%@A*Br$K4X$9$k%3%^%s%I$N%-!<%P%$%s%I$O0J2<$NDL$j$G$9!#(B + +@table @kbd +@item @key{SPC} +@itemx @key{RET} +@kindex @key{SPC} (Folder) +@kindex @key{RET} (Folder) +@findex wl-folder-jump-to-current-entity +$B8=:_%+!<%=%k$,$"$k9T$N%U%)%k%@$N%5%^%jI=<($X0\F0$7$^$9!#(B +$B%0%k!<%W%U%)%k%@$K%+!<%=%k$,$"$k>l9g$O!"%0%k!<%W%U%)%k%@$N3+JD$r9T$J$$$^$9!#(B +$B%"%/%;%9%0%k!<%W$G$O!"(Bprefix argument $B$D$-$G%0%k!<%W%U%)%k%@$r3+$/$H!"(B +$BFbMF$r:G?7$N%j%9%H$K99?7$7$^$9!#(B +$B%"%/%;%9%0%k!<%W$,3,AX9=B$$K$J$C$F$$$k>l9g$O:F5"E*$K99?7$7$^$9!#(B +(@code{wl-folder-jump-to-current-entity}) + +@item M-@key{RET} +@kindex M-@key{RET} (Folder) +@findex wl-folder-update-recursive-current-entity +$B8=:_%+!<%=%k$,$"$k%"%/%;%9%0%k!<%W$NFbMF$r:G?7$N%j%9%H$K99?7$7$^$9!#(B +$B%"%/%;%9%0%k!<%W$,3,AX9=B$$K$J$C$F$$$k>l9g$O:F5"E*$K99?7$7$^$9!#(B +(@code{wl-folder-update-recursive-current-entity}) + +@item w +@kindex w (Folder) +@findex wl-summary-write +$B?75,%I%i%U%H$rMQ0U$7$^$9!#(B +(@code{wl-summary-write}) + +@item W +@kindex W (Folder) +@findex wl-summary-write-current-newsgroup +$B8=:_%+!<%=%k$,$"$k%U%)%k%@$,(B NNTP $B%U%)%k%@$J$i!"(B +Newsgroups $B%U%#!<%k%I$rJd$C$F%I%i%U%H$rMQ0U$7$^$9!#(B +(@code{wl-summary-write-current-newsgroup}) + +@item s +@kindex s (Folder) +@findex wl-folder-check-current-entity +$B8=:_%+!<%=%k$,$"$k9T$N%U%)%k%@$NL$F14|%a%C%;!<%8?t$r99?7$7$^$9!#(B +(@code{wl-folder-check-current-entity}) + +@item S +@kindex S (Folder) +@findex wl-folder-sync-current-entity +$B8=:_%+!<%=%k$,$"$k9T$N%U%)%k%@$N%5%^%j$r99?7$7$^$9!#(B +(@code{wl-folder-sync-current-entity}) + +@item r s +@kindex r s (Folder) +@findex wl-folder-check-region +$B%j!<%8%g%s$K$"$k%U%)%k%@$NL$F14|%a%C%;!<%8?t$r99?7$7$^$9!#(B +(@code{wl-folder-check-region}) + +@item r S +@kindex r S (Folder) +@findex wl-folder-sync-region +$B%j!<%8%g%s$K$"$k%U%)%k%@$N%5%^%j$r99?7$7$^$9!#(B +(@code{wl-folder-sync-region}) + +@item P +@kindex P (Folder) +@findex wl-folder-prev-unread +$B$R$H$D>e$NL$FI$,$"$k%U%)%k%@(B($B$b$7$/$O%0%k!<%W(B)$B$K0\F0$7$^$9!#(B +(@code{wl-folder-prev-unread}) + +@item N +@kindex N (Folder) +$B$R$H$D2<$NL$FI$,$"$k%U%)%k%@(B($B$b$7$/$O%0%k!<%W(B)$B$K0\F0$7$^$9!#(B +(@code{wl-folder-next-unread}) + +@item p +@kindex p (Folder) +$B$R$H$D>e$N%U%)%k%@$X0\F0$7$^$9!#(B +(@code{wl-folder-prev-entity}) + +@item n +@kindex n (Folder) +$B$R$H$D2<$N%U%)%k%@$X0\F0$7$^$9!#(B +(@code{wl-folder-next-entity}) + +@item J +@kindex J (Folder) +$B;XDj$7$?%U%)%k%@$X%+!<%=%k$r0\F0$7$^$9!#(B +(@code{wl-folder-jump-folder}) + +@item I +@kindex I (Folder) +@findex wl-folder-prefetch-current-entity +$B8=:_%+!<%=%k$,$"$k9T$N%U%)%k%@$KBP$7$F!"(B +@code{wl-summary-incorporate}$B$K$h$j!"(B +$B?7Ce5-;v$r%W%j%U%'%C%A$7$^$9!#(B +$B%0%k!<%W%U%)%k%@$K%+!<%=%k$,$"$k>l9g$O!"(B +$B:F5"E*$Kl9g$O!"(B +$B:F5"E*$KuBV$r%;!<%V$7$^$9!#(B +(@code{wl-save}) + +@item M-t +@kindex M-t (Folder) +Wanderlust $B$N%*%U%i%$%s%b!<%I(B/$B%*%s%i%$%s%b!<%I$r%H%0%k$7$^$9!#(B +(@code{wl-toggle-plugged}) + +@item C-t +@kindex C-t (Folder) +Wanderlust $B$N%5!<%P!&%]!<%HJL$N%*%U%i%$%s(B/$B%*%s%i%$%s$rJQ99$7$^$9!#(B +(@code{wl-plugged-change}) +@end table + +@subsection $B%+%9%?%^%$%:JQ?t(B + +@table @code +@item wl-folders-file +@vindex wl-folders-file +$B=i4|@_Dj$O(B "~/.folders"$B!#(B +$B9XFI$9$k%U%)%k%@$r5-=R$9$k%U%!%$%k$NL>A0$G$9!#(B + +@item wl-folder-info-save +@vindex wl-folder-info-save +$B=i4|@_Dj$O(B t$B!#(B +$Be$2D>$7$?$H$-$KA02s$NL$FI?t$J$I$N7k2L$r;H$$$^$o$7$9$k$+$I$&$+!"$G$9!#(B + +@item wl-stay-folder-window +@vindex wl-stay-folder-window +$B=i4|@_Dj$O(B nil$B!#(B +Non-nil $B$J$i%5%^%j$K0\F0$7$?$H$-$K%U%)%k%@%P%C%U%!$N1&$K%5%^%j$N%P%C%U%!$,8=$l$^$9!#(B + +@item wl-folder-window-width +@vindex wl-folder-window-width +$B=i4|@_Dj$O(B 20$B!#(B +@code{wl-stay-folder-window} $B$,(B non-nil $B$N$H$-$K$N$3$9%U%)%k%@%P%C%U%!$N%&%#%s%I%&$NI}$G$9!#(B + +@item wl-folder-many-unsync-threshold +@vindex wl-folder-many-unsync-threshold +$B=i4|@_Dj$O(B 70$B!#(B +$BL$F14|?t$,$?$/$5$s$+$I$&$+$NogCM!#$3$NCM$r1[$($k$H?'$,JQ$o$j$^$9!#(B + +@item wl-folder-desktop-name +@vindex wl-folder-desktop-name +$B=i4|@_Dj$O(B "Desktop"$B!#(B +$B%H%C%W$N%0%k!<%W$NL>A0$G$9!#(B + +@item wl-folder-petname-alist +@vindex wl-folder-petname-alist +$B=i4|@_Dj$O(B nil$B!#(B +$B%U%)%k%@$NK\L>$H$"$@L>$N(B cons $B$N%j%9%H$G$9!#(B + +@item wl-folder-access-subscribe-alist +@vindex wl-folder-access-subscribe-alist +$B=i4|@_Dj$O(B nil$B!#(B +$B%"%/%;%9%0%k!<%W$N%j%9%Hl9g$O%U%)%k%@$N@55,I=8=$K%^%C%A(B +$B$7$?%U%)%k%@$N$_I=<($7!"9XFI%U%i%0$,(B nil $B$N>l9g$O%U%)%k%@$N@55,I=8=$K%^%C(B +$B%A$7$?%U%)%k%@$OI=<($5$l$J$/$J$j$^$9!#$?$@$7!"9XFI%U%i%0$,(B non-nil $B$G$b(B +$B4{$K(B unsubscribe $B$5$l$F$$$k%U%)%k%@$OI=<($5$l$^$;$s!#$^$?!"%U%)%k%@$N@5(B +$B5,I=8=$OJ#?t8D5-=R$G$-$^$9!#(B + +$BNc(B: + +@example +'(("^-fj$" . (t "^-fj\\.\\(comp\\|editor\\|mail\\)" + "^-fj\\.\\(net\\|news\\|os\\|rec\\)")) + ("^-$" . (t "^-\\(fj\\|tnn\\|japan\\|gnu\\|comp\\)")) + ("^\\+ml$" . (nil "^\\+ml$" "^\\+ml/tmp"))) +@end example + +@item wl-folder-hierarchy-access-folders +@vindex wl-folder-hierarchy-access-folders +$B=i4|@_Dj$O(B '("-" "-alt")$B!#(B +$B3,AX9=B$$K:n@.$9$k%"%/%;%9%0%k!<%W%U%)%k%@$N%j%9%H!#(B + +$BNc$($P!"0J2<$N$h$&$K(B +@code{wl-folder-hierarchy-access-folders} $B$r@_Dj$9$k$H!"(B + +@lisp +(setq wl-folder-hierarchy-access-folders + '("-" "-alt" "-japan" "-comp" "-comp.unix")) +@end lisp + +$B@\JT=8$9$k$^$G$b$J$/!"(B +$B%U%)%k%@%b!<%I$+$i$b%U%)%k%@$NDI2C(B/$B:o=|(B/$B%0%k!<%W$NDj5A$J$I$NJT=8$,2DG=$H$J$C$F$$$^$9!#(B + + +@subsection $B;HMQJ}K!(B(TIPS) + +@subsubsection $B%U%)%k%@$NDI2C(B + +@kbd{m a} $B$G?75,$K9XFI$9$k%U%)%k%@$rDI2C$7$^$9!#(B +@kbd{m g} $B$G%0%k!<%W$,DI2C$5$l$^$9!#(B +$B$3$N%0%k!<%W$K%U%)%k%@$rDI2C$9$k$K$O!"$^$:$3$N%0%k!<%W$r3+$$$?>uBV$K$7$^$9!#(B +$B$=$7$Fo$NJ8=qJT=8$N9TJT=8$HF1$8$h$&$K%U%)%k%@$N0LCV$rJQ992DG=$G$9!#(B + +@subsubsection $B%^%k%A%U%)%k%@$N:n@.J}K!(B + +@enumerate +@item +@kbd{m q}$B$G(B @code{wl-fldmgr-cut-entity-list} $B$r>C$7$^$9!#(B +@item +@kbd{C-k} $B$+(B @kbd{M-c} $B$G%U%)%k%@$r:o=|!"$^$?$O%3%T!<$7$^$9!#(B +@item +@kbd{m m} $B$r(B(petname)$B$d%U%#%k%?$N:o=|(B + +$B$"$@L>$d%U%#%k%?$N@_Dj$G$O!"(Bminibuffer $B$G(B ""(NULL) $B$rF~NO$9$k$H(B +$B$"$@L>$d%U%#%k%?$,:o=|$5$l$^$9!#(B + +@subsubsection $B6u%0%k!<%W$X$NDI2C(B + +@kbd{m g} $B$J$I$G%0%k!<%W$r:n@.$7$?8e!"$3$N%0%k!<%W$K%U%)%k%@$rDI2C$9$k$K(B +$B$O!"$^$:$3$N%0%k!<%W$r3+$$$?>uBV$K$7$^$9!#$=$7$FuBV$G$O$=$N%0%k!<%W$H(B +$BF1$8%l%Y%k$KA^F~$5$l$^$9!#8@MU$G@bL@$9$k$N$OFq$7$$$N$Ge$K$"$k%0%k!<%W$N3+JD>uBV$K(B +$B$h$jA^F~$5$l$k0LCV$,0[$J$k$N$G$9!#(B + +@subsubsection save$B;~$N8@8l%3!<%I(B + +@code{wl-folders-file} $B$r(B save $B$9$k$H$-$O(B @code{wl-mime-charset} $B$N8@8l%3!<%I$K$J$j$^$9!#(B + +@subsubsection $B%U%#%k%?%U%)%k%@$N:n@.(B + +$B%U%#%k%?%U%)%k%@$N:n@.%3%^%s%I$O%+!<%=%k>e$N%U%)%k%@$r%U%#%k%?IU$-$KJQ99(B +$B$7$^$9!#$b$7%+!<%=%k>e$N%U%)%k%@$r;D$7$?$^$^?7$?$K%U%#%k%?%U%)%k%@$r:n@.(B +$B$9$k>l9g$O!"$^$:%3%T!<$7$F$+$i%U%#%k%?$r:n@.$7!"$=$N8e%3%T!<$7$?%U%)%k%@(B +$B$rA^F~$7$^$9!#(B +$B%U%#%k%?%U%)%k%@:n@.;~$K$O0lEY$KJ#?t$N(B($BB?CJ$N(B)$B%U%#%k%?$,;XDj$G$-$^$9!#(B +""(NULL)$B$rF~NO$9$l$P!"@hF,$N%U%#%k%?$OA4$F:o=|$5$l$^$9!#(B + +@subsubsection $B%U%)%k%@$NJB$SJQ$((B + +$B%0%k!<%WFb$N%U%)%k%@$rJB$SJQ$($9$k:]!"(B@code{wl-fldmgr-sort-func} $B$K;XDj(B +$B$5$l$?4X?t$rMQ$$$^$9!#=i4|@_Dj$G$O(B @code{wl-fldmgr-sort-standard} $B$,;XDj(B +$B$5$l$F$*$j!"$3$l$O%"%k%U%!%Y%C%H=g$KJB$S$+$(%0%k!<%W$O:G=i$K$9$k4X?t$G$9!#(B +$BJB$SJQ$($O;XDj$7$?%0%k!<%W$N$_9T$$!"2<0L$N%0%k!<%W$^$GJB$SJQ$($O$7$^$;$s!#(B +$B$D$^$j!"(Brecursive $B$K$O9T$$$^$;$s!#(B + +@subsubsection $B%"%/%;%9%0%k!<%WFb$NI=<($7$J$$%U%)%k%@$N;XDj(B + +$B%"%/%;%9%0%k!<%W$r3+$/$HDL>oA4$F$N%U%)%k%@$,I=<($5$l$^$9$,!"(B +$BI=<($7$J$$%U%)%k%@$r;XDj$9$k$3$H$b$G$-$^$9!#(B +$B0J2<$NA`:n$O%"%/%;%9%0%k!<%WFb$G$N$_M-8z$G$9!#(B + +$B%3%^%s%I(B @code{wl-fldmgr-unsubscribe} (@kbd{u}) $B$O%+!<%=%k0LCV$N%U%)%k%@$N(B +$BI=<((B(subscribe)$B!&HsI=<((B(unsubscribe)$B@_Dj$r%H%0%k$7$^$9!#$=$l$KBP$7$F(B +@code{wl-fldmgr-unsubscribe-region} (@kbd{U}) $B$O;XDjHO0O$N%U%)%k%@$rHsI=<($K(B +$B$7$^$9!#(Bunsubscribe $B$O%H%0%k$7$^$9$,!"(Bregion $B$@$HDL>o%H%0%k$K$J$i(B +$B$J$$$3$H$KCm0U2<$5$$!#(Bregion $B$N>l9g%H%0%k$K$9$k$h$j$I$A$i$+$K@_Dj$5(B +$B$;$kJ}$,;H$$$d$9$$$H9M$($3$N$h$&$K$7$F$$$^$9!#$7$+$7!">e5-(B2$B$D$N4X?t$H(B +$B$b(B prefix argument $B$NCM$,@5$J$i%U%)%k%@$rHsI=<(!"Ii$J$iI=<(!"(B0$B$J$i(B +$B%H%0%k$5$;$^$9!#(B + +$B$^$?%-!<$K$O3d$jEv$F$F$$$^$;$s$,!"%U%)%k%@$rI=<($K@_Dj$9$k$@$1$N(B +@code{wl-fldmgr-subscribe} $B$H(B @code{wl-fldmgr-subscribe-region} $B$bMQ0U$7$F(B +$B$$$^$9!#;HMQ$9$k>l9g$OE,Ev$J%-!<$K3d$jEv$F$F$/$@$5$$!#(B + +$B$5$i$K!"%"%/%;%9%0%k!<%WFb$G(B @code{wl-fldmgr-cut} $B$H(B +@code{wl-fldmgr-cut-region} $B$r$l(B +@code{wl-fldmgr-unsubscribe} $B$H(B @code{wl-fldmgr-unsubscribe-region} $B$rl9g$O2hLL$+$i$b>C(B +$B5n$9$k$3$H$G$9!#(B + +@subsubsection $B%"%/%;%9%0%k!<%WFb$NA`:n(B + +$B%"%/%;%9%0%k!<%WFb$G$b:o=|$dA^F~$,9T$($^$9!#$H$$$C$F$b$C$F!"(BWanderlust $B0J30$G%U%)%k%@$,JQ99$5$l$?>l9g!"(B +$B$=$N%U%)%k%@$r$rJQ99$7$^$9!#(B +$B%U%)%k%@$rJQ99$9$k>l9g$O(B msgdb $B$N%Q%9$bJQ99$7$^$9!#(B +(@code{wl-fldmgr-rename}) + +@item * +@itemx m m +@kindex * (Folder) +@kindex m m(Folder) +@findex wl-fldmgr-make-multi +$B%^%k%A%U%)%k%@$r:n@.$7$^$9(B (cut, copy $B$5$l$?%U%)%k%@$r7k9g$7$^$9(B)$B!#(B +(@code{wl-fldmgr-make-multi}) + +@item | +@itemx m f +@kindex | (Folder) +@kindex m f (Folder) +@findex wl-fldmgr-make-filter +$B%U%#%k%?%U%)%k%@$r:n@.$7$^$9(B ($BA*Br$7$?%U%)%k%@$K(Bfilter$B$rIU$1$^$9(B)$B!#(B +(@code{wl-fldmgr-make-filter}) + +@item M-c +@itemx m c +@kindex M-c (Folder) +@kindex m c (Folder) +@findex wl-fldmgr-copy +$B%U%)%k%@$r%3%T!<$9$k(B ($B%0%k!<%W$O%3%T!(B(petname)$B$rIU$1$k!#(B +(@code{wl-fldmgr-set-petname}) + +@item m q +@kindex m q (Folder) +@findex wl-fldmgr-clear-cut-entity-list +cut, copy $B$7$?%U%)%k%@>pJs(B(cut-list)$B$r>C$9!#(B +(@code{wl-fldmgr-clear-cut-entity-list}) + +@item m s +@kindex m s (Folder) +@findex wl-fldmgr-sort +$B%0%k!<%WFb$N%U%)%k%@$rJB$SJQ$($k(B ($B$=$N%0%k!<%W3,AX$N$_(B)$B!#(B +(@code{wl-fldmgr-sort}) + +@item m C-s +@kindex m C-s (Folder) +@findex wl-fldmgr-save +wl-folders-file $B$K(B save $B$9$k!#(B +(@code{wl-fldmgr-save}) +@end table + +[$B0J2<$NA`:n$O%"%/%;%9%0%k!<%W$KBP$7$F$N$_M-8z(B] + +@table @kbd +@item u +@itemx m u +@kindex u (Folder) +@kindex m u (Folder) +@findex wl-fldmgr-unsubscribe +$B%U%)%k%@$NI=<((B/$BHsI=<($N@_Dj!#(B +(@code{wl-fldmgr-unsubscribe}) + +@item U +@itemx r u +@kindex U (Folder) +@kindex r u (Folder) +@findex wl-fldmgr-unsubscribe-region +$B;XDjHO0O$K$"$k%U%)%k%@$NI=<((B/$BHsI=<($N@_Dj!#(B +(@code{wl-fldmgr-unsubscribe-region}) + +@item l +@itemx m l +@kindex l (Folder) +@kindex m l (Folder) +@findex wl-fldmgr-access-display-normal +$B8=:_M-8z$J%U%)%k%@$N$_0lMwI=<($9$k!#(B +(@code{wl-fldmgr-access-display-normal}) + +@item L +@itemx m L +@kindex L (Folder) +@kindex m L (Folder) +@findex wl-fldmgr-access-display-all +$BHsI=<($N%U%)%k%@$b4^$a$FA4$F$N%U%)%k%@$r0lMwI=<($9$k!#(B +(@code{wl-fldmgr-access-display-all}) + +@item C-c C-o +@kindex C-c C-o (Folder) +@findex wl-jump-to-draft-buffer +$B%I%i%U%H%P%C%U%!$,$"$l$P0\F0$7$^$9!#(B $BJ#?t$N%I%i%U%H%P%C%U%!$,B8:_$9$k>l9g$O!"(B +$Bl9g$O!"%I%i%U%H%U%)%k%@$+$i%U%!%$%k$r(B($BB8:_$9$l$P(B) +$BFI$_9~$_$^$9!#(B +(@code{wl-jump-to-draft-buffer}) +@end table + + +@subsection $B%+%9%?%^%$%:JQ?t(B + +@table @code +@item wl-interactive-save-folders +@vindex wl-interactive-save-folders +$B=i4|@_Dj$O(B t$B!#(B +$B%U%)%k%@JQ99$NA`:n$r9T$C$?>l9g!"(BWanderlust $B=*N;;~$b$7$/$O(B Emacs $B=*N;;~$K(B + save $B$9$k$+3NG'$r9T$$$^$9!#(Bnil $B$@$H3NG'$J$7$G(B save $B$7$^$9!#(B + +@item wl-fldmgr-make-backup +@vindex wl-fldmgr-make-backup +$B=i4|@_Dj$O(B t$B!#(B +Non-nil $B$J$i!"(Bsave$B$9$k:]$K(B @file{~/.folders.bak} $B$K%P%C%/%"%C%W$rl9g(B)$B!#(B + +@item wl-fldmgr-sort-group-first +@vindex wl-fldmgr-sort-group-first +$B=i4|@_Dj$O(B t$B!#(B +Non-nil $B$J$i!"(B@code{wl-fldmgr-sort-standard} $B$GJB$SBX$($k$H$-%0%k!<%W$r:G(B +$B=i$K$9$k!#(Bnil $B$J$i!"%0%k!<%W$b4^$a$F%"%k%U%!%Y%C%H=g$KJB$SBX$($^$9!#(B + +@item wl-folder-check-async +@vindex wl-folder-check-async +$B=i4|@_Dj$O(B t$B!#(B +Non-nil $B$N>l9g!"%U%)%k%@$N?75,%a%C%;!<%8?t$N%A%'%C%/$rHsF14|$K9T$J$$$^$9!#(B +$B%K%e!<%9%0%k!<%W$N%A%'%C%/$,BgI}$KB.$/$J$j$^$9!#(B + +@item wl-folder-check-fast +@vindex wl-folder-check-fast +$B=i4|@_Dj$O(B nil$B!#(B +Non-nil $B$N>l9g!"%U%)%k%@$N?75,%a%C%;!<%8?t$N%A%'%C%/$r9T$&$?$S$K(B +$B%U%)%k%@$NI=<($r99?7$7$^$;$s!#(B + +@item wl-folder-notify-deleted +@vindex wl-folder-notify-deleted +$B=i4|@_Dj$O(B nil$B!#(B +@c nil means? +Non-nil $B$J$i%a%C%;!<%8$,:o=|$5$l$?$H$-$K%U%)%k%@%b!<%I$GL$FI?t$r%A%'%C%/(B +$B$9$k$HIi$NCM$,I=<($5$l$^$9!#(B +$BCM$,(B 'sync $B$J$i$P!"%a%C%;!<%8$,:o=|$5$l$F$$$?$H$-$K%U%)%k%@$NFbMF$HF14|$r(B +$B(B + +$B%U%)%k%@$NJT=8$K4X$7$F!"0J2<$N$h$&$J;E3]$1$d@)8B$,$"$j$^$9!#(B + +@enumerate +@item +cut $B$d(B copy $B$r9T$&$H!"%9%?%C%/$N$h$&$KJQ?t(B @code{wl-fldmgr-cut-entity-list} + $B$K$?$^$C$F$$$-$^$9!#(Bpaste(yank) $B$O(B cut $B$d(B copy $B$7$?C10L$G(B + (region $B$G(B copy $B$7$?$J$i$=$N(B region $BFb$N%U%)%k%@$,(B $B0lEY$K(B) $BEG$-=P$5$l$^$9!#(B + +@item +Desktop $B%0%k!<%W$N(B cut, copy $B$O$G$-$^$;$s!#$^$?!"(BDesktop $B30$X$NA^F~$O$G$-$^$;$s!#(B + +@item +$B%0%k!<%W$N(B copy $B$O$G$-$^$;$s!#(B + +@item +$B%"%/%;%9%0%k!<%W$NA`:n$O%"%/%;%9%0%k!<%W$KB0$7$F$$$k%U%)%k%@$N$_BP>](B +$B$H$J$j$^$9!#(B + +@item +$BA4BN$GF1$8L>A0$N%0%k!<%W$OJ#?t:n$l$^$;$s!#(B + +@item +$BF1$8%0%k!<%W(B($B3,AX(B)$B$KF1$8%U%)%k%@$O:n$l$^$;$s!#3,AX$,0c$($PJ#?t:n$l$^$9!#(B +$B0[$J$k%U%)%k%@$KF1$8$"$@L>$O;XDj$G$-$^$;$s!#(B +@end enumerate + + +@c +@c Summary +@c +@node Summary, Message, Folder, Top +@chapter $B%5%^%j%b!<%I(B + +@section $B;HMQJ}K!(B(TIPS) + +@subsection $B%5%^%j$NI=<(FbMF(B + +$B%U%)%k%@%b!<%I$GFI$_$?$$%U%)%k%@$rA*Br$9$k$H!"%5%^%j%b!<%I$K0\F0$7$^$9!#(B +$B%5%^%j%b!<%I$K$O!"0J2<$N$h$&$K%a%C%;!<%8$N0lMw$,I=<($5$l$^$9!#(B + +@example + 377 09/16($B?e(B)11:57 [+1: $BKLL\$5$s(B ] Bug? + 381 09/17($BLZ(B)00:16 [+3: $B1|@>$5$s(B ] elmo-lha.el -- LHA interface + 384 09/17($BLZ(B)01:32 [+1: $B$F$i$K$7(B ] wl-0.6.2 + 389 N09/18($B6b(B)01:07 [+2: $B$F$i$K$7(B ] wl-0.6.3 +@end example + +$B3F%a%C%;!<%8$O!"0l9T$K(B + +@example +$B%a%C%;!<%8HV9f!"0l;~E*%^!<%/!"1JB3E*%^!<%/!"F|IU$1!":9=P?M!"(B $B%5%V%8%'%/%H(B +@end example + +@noindent +$B$N=g$KI=<($5$l$^$9!#8=:_%P!<%8%g%s$G$OI=<($rJQ99$9$k$3$H$O$G$-$^$;$s!#(B + +$B%a%C%;!<%8HV9f$O$=$N%U%)%k%@Cf$K$"$k%a%C%;!<%8$K$D$1$i$l$?HV9f$G$9!#(B +News $B%U%)%k%@$G$O(B article $BHV9f!"(BIMAP $B%U%)%k%@$G$O(B UID$B!"(BMH $B%U%)%k%@$G$O(B +$B%U%!%$%kL>$G$9!#(B + +$B0l;~E*(B/$B1JB3E*%^!<%/$K$D$$$F$O!"$"$H$G>\$7$/@bL@$7$^$9!#(B + +$BF|IU$1$O!"7n(B/$BF|(B($BMKF|(B)$B;~(B:$BJ,(B $B$N$h$&$KI=<($5$l$^$9!#MKF|$rF|K\8l$G$O$J$/1Q8lI=5-$7$?$$>l9g$O!"(B@code{wl-summary-weekday-name-lang} $B$r(B "en" $B$K@_Dj$7$F$/$@$5$$!#(B + +$B:9=P?M$O!"%9%l%C%I$N?<$5J,%$%s%G%s%H$5$l$FI=<($5$l$^$9!#:9=P?M$NL>A0$O!"(B +$B%"%I%l%9D"$K$"$@L>$,$"$l$P$"$@L>$GI=<($7$^$9!#$"$@L>I=5-$r$d$a$?$$>l9g$O!"(B +@code{wl-use-petname} $B$r(B nil $B$K@_Dj$7$F$/$@$5$$!#(B + +$B:9=P?M$NItJ,$K$"$k(B @samp{+2} $B$N$h$&$J?t;z$NI=<($O!"(B +$B$=$N%a%C%;!<%8$KBP$9$kJV;v$N?t$rI=$7$^$9!#(B +$BNc$($P(B @samp{+2} $B$J$i(B 2 $BDL$"$C$?$3$H$r<($7$^$9!#(B + +$B%5%V%8%'%/%H$O!"%a%C%;!<%8$N(B Subject $B%U%#!<%k%I$G$9!#(B +$BF1$8%9%l%C%I$G!"$+$D?F$HF1$8%5%V%8%'%/%H$r;}$D%a%C%;!<%8$J$iI=<($5$l$^$;$s!#(B +$B%a!<%j%s%0%j%9%H$J$I$NDL$7HV9fI=<($OL5;k$5$l$^$9!#%5%V%8%'%/%H$,$J$$>l9g!"(B +$BJQ?t(B @code{wl-summary-no-subject-message} $B$NFbMF$,I=<($5$l$^$9!#(B + +@subsection $B0l;~E*%^!<%/(B +@cindex Mark, Temporary + +$B0l;~E*%^!<%/$O!"%a%C%;!<%8$rA`:n$9$k$?$a%^!<%/$G$9!#(B + +$B0l;~E*%^!<%/$K$O!"(B@samp{*}, @samp{D}, @samp{o}, @samp{O} $B$,$"$j$^$9!#(B + +@table @samp +@item * +$B$^$H$a=hM}MQ%^!<%/$G$9!#(B +@kbd{m} $B$G$O$8$^$k%3%^%s%I$G(B @samp{*}$B%^!<%/$N$D$$$?%a%C%;!<%8BP$7$F0l3g$7$?=hM}(B +$B$,$G$-$^$9!#(B + +@item D +$B:o=|$9$k%a%C%;!<%8$KIU$/%^!<%/$G$9!#(B@kbd{d} $B$r2!$9$HIU$-$^$9!#(B + +@item o +$B%j%U%!%$%k$9$k%a%C%;!<%8$KIU$/%^!<%/$G$9!#(B +@kbd{o}$B$r2!$9$H!"%j%U%!%$%k@h$rJ9$$$FMh$k$N$GEz$($k$H!"%j%U%!%$%k@h$N%U%)%k%@>pJs$H$H$b$KIU$1$i$l$^$9!#(B + +@item O +$B%3%T!<$9$k%a%C%;!<%8$KIU$/%^!<%/$G$9!#(B +@kbd{O}$B$r2!$9$H!"%3%T!<@h$rJ9$$$FMh$k$N$GEz$($k$H!"%3%T!<@h$N%U%)%k%@>pJs$H$H$b$KIU$1$i$l$^$9!#(B +@end table + +@kbd{x} $B$r2!$9$3$H$K$h$j!"(B@samp{D}, @samp{o}, @samp{O} $B$N%^!<%/$,$D$1$i$l$?%a%C%;!<%8$N:o=|!"%j%U%!%$%k!"%3%T!<$,uBV$r$7$a$9%^!<%/$G$9!#(B + +$B1JB3E*%^!<%/$K$O!"(B@samp{N}, @samp{U}, @samp{!}, @samp{u}, @samp{$} $B$,$"$j$^$9!#(B + + +@table @samp +@item N +$B?75,%a%C%;!<%8$KIU$-$^$9!#(B +@item U +$BL$FI%a%C%;!<%8$KIU$-$^$9!#(B +@item ! +$BL$FI%a%C%;!<%8$KIU$-$^$9!#(B@samp{U} $B$H$N0c$$$O!"(B@samp{!} $B$N%a%C%;!<%8$O(B +$B%-%c%C%7%e$5$l$F$$$k$3$H$G$9!#(B +@item u +$B4{FI%a%C%;!<%8$KIU$-$^$9!#%^!<%/$J$7$H$N0c$$$O!"(B@samp{u} $B$N%a%C%;!<%8$O(B +$B%-%c%C%7%e$5$l$F$$$J$$$3$H$G$9!#(B +@item $ +@kbd{$} $B%-!<$r2!$9$H!"(B@samp{$} $B%^!<%/$,IU$-$^$9!#(B +$B$3$N%^!<%/$O(BEmacs$B$r=*N;$7$F$bJ]B8$5$l$k$?$a!"$"$H$GJV;v$r=q$-$?$$>l9g$J$I!"3P$($F$*$-$?$$=EMW$J%a%C%;!<%8$KIU$1$F$*$/$HJXMx$G$9!#(B@samp{$} $B$NIU$$$?%a%C%;!<%8$O!"%K%e!<%95-;v$d%5!<%P>e$N(BIMAP$B%U%)%k%@$N%a%C%;!<%8$,(B expire $B$5$l$k$J$I$7$F>C$($?>l9g$b;D$j$^$9!#(B +@item $B$J$7(B +$B4{FI%a%C%;!<%8$K$O%^!<%/$,B8:_$7$^$;$s!#(B +@end table + +@samp{N}, @samp{U}, @samp{u} $B$O!"(B +$B$=$N%a%C%;!<%8$,%-%c%C%7%e$5$l$F$$$J$$$3$H$r$7$a$7$F$$$^$9!#(B +$B$3$l$i$N%^!<%/$,IU$$$F$$$J$$>l9g!"(B +$B$D$^$j!"$=$N%a%C%;!<%8$,%-%c%C%7%e$5$l$F$$$k>l9g$O!"(B +$B%M%C%H%o!<%/$K@\B3$5$l$F$$$J$/$F$b(B IMAP $B%U%)%k%@$N%a%C%;!<%8$d(B +NNTP $B%U%)%k%@$N%K%e!<%95-;v$rFI$`$3$H$,$G$-$^$9!#(B + +@subsection $B%a%C%;!<%8$NFI$_$9$9$a$+$?(B + +$B4pK\E*$K%9%Z!<%9%-!<$r2!$9$@$1$GFI$_?J$a$k$3$H$,$G$-$^$9!#(B +$B%5%^%j$NI=<(FbMF$r%U%)%k%@$N:G?7$N>uBV$K9g$o$;$k(B($BF14|$9$k(B)$B$K$O!"(B +@kbd{s} $B$r2!$7$^$9!#(B + +@kbd{N} $B$GC$7$^$9!#(B + +@subsection $B%P%C%U%!%-%c%C%7%e$H@hFI$_5!G=(B + +@code{elmo-use-buffer-cache} $B$,(B non-nil $B$G$"$l$P!"(B +$B0lEYFI$s$@%a%C%;!<%8$,0lDj?t%P%C%U%!$KJ];}$5$l$^$9!#(B +$BJ];}$9$k%P%C%U%!$N?t$O(B @code{elmo-buffer-cache-size} $B$G;XDj$7$^$9!#(B + +$B$^$?!"%a%C%;!<%8$rFI$s$G$$$k4V$Kl9g!"$b$7(B localdir $B$H(B imap4 $B%U%)%k%@$,:.:_$7$?(B multi$B%U%)%k%@$G$O(B +imap4 $B$N%a%C%;!<%8$@$1$,@hFI$_$5$l$^$9!#(B +$B$3$NJQ?t$O(B @code{wl-cache-prefetch-folder-list} $B$h$j$bM%@h$5$l$^$9!#(B + +$B$b$7!"(Blocaldir $B$H(B localnews $B%U%)%k%@$b@hFI$_$9$k>l9g$O(B($B@55,I=8=(B)$B$N%j%9%H$G;XDj$7$^$9!#(B +@end table + +@subsection $B<+F0%j%U%!%$%k(B + +$B%a%C%;!<%8$N%X%C%@>pJs$+$iG$0U$N%U%)%k%@$X?6$jJ,$1$k<+F0%j%U%!%$%k5!G=$,(B +@kbd{C-o} (@code{wl-summary-auto-refile}) $B$G;HMQ$G$-$^$9!#<+F0%j%U%!%$%k$O(B +msgdb $B$N(B overview $B>pJs$r85$K?6$jJ,$1$7$^$9!#(B +$BI8=`$G$O(B @samp{From} @samp{Subject} @samp{To} @samp{Cc} $B$,4^$^$l$F$$$^$9!#(B +$B$3$l0J30$N3HD%9`L\$G?6$jJ,$1$7$?$$$H$-$K$O!"(B + +@lisp +(setq elmo-msgdb-extra-fields + '("x-ml-name" + "reply-to" + "sender" + "mailing-list" + "newsgroups")) +@end lisp + +@noindent +$B$H$7$F3HD%9`L\$,(B msgdb $B$K4^$^$l$k$h$&$K$7$F$/$@$5$$!#$9$G$Kr7o$K(B +$B%^%C%A$7$?%a%C%;!<%8$K%j%U%!%$%k%^!<%/$,IU2C$5$l$^$9!#(B@kbd{x} $B$G%j%U%!%$(B +$B%k$rr7o$,M%@h$5$l$^$9!#(B + +@code{wl-summary-auto-refile-skip-marks} $B$r@_Dj$9$k$3$H$K$h$j!"(B +$B<+F0%j%U%!%$%k$NBP>]$H$9$k%a%C%;!<%8$rJQ99$9$k$3$H$,$G$-$^$9!#(B +$BI8=`$G$O(B @samp{N} @samp{U} @samp{!} $B$,@_Dj$5$l$F$*$j!"(B +$B$3$l$i$N1JB3E*%^!<%/$N$D$$$?%a%C%;!<%8$O!"<+F0%j%U%!%$%k$7$^$;$s!#(B +$B$D$^$jI8=`$G$OL$FI$N%a%C%;!<%8$r<+F0%j%U%!%$%k$7$J$$$3$H$K$J$j$^$9!#(B +$B$9$Y$F$N%a%C%;!<%8$r<+F0%j%U%!%$%k$NBP>]$K$9$k$K$O!"(B + +@lisp +(setq wl-summary-auto-refile-skip-marks nil) +@end lisp + +@noindent +$B$NMM$K(B @code{wl-summary-auto-refile-skip-marks} $B$r(B nil $B$K$7$^$9!#(B + + +@subsection $B%9%F%#%C%-!<%5%^%j(B +@cindex Summary, Sticky +@cindex Sticky Summary + +$B%9%F%#%C%-!<%5%^%j$O!"(B@kbd{q} $B$G8=:_$N%5%^%j$r=*N;$7$F$b%P%C%U%!$,>C$($J(B +$B$$!"$=$NL>$NDL$j%9%F%#%C%-!<(B($B$7$D$3$$(B)$B%5%^%j$G$9!#(B + +@kbd{C-u g} $B$G%U%)%k%@0\F0$9$k$+!"DL>o$N%5%^%j$G(B @kbd{M-s} +(@code{wl-summary-stick}) $B$r$O!"(B@samp{Summary:@var{$B%U%)%k%@L>(B}} $B$H$J$j$^$9!#(B +@kbd{C-x b} (@code{switch-to-buffer}) $B$J$I$G!"E,Ev$K@ZBX$($l$P$$$D$G$b;2(B +$B>H$G$-$^$9!#%9%F%#%C%-!<%5%^%j$r=*N;$9$k$K$O(B @kbd{C-u q} $B$G$9!#$=$NB>$N(B +$BA`:n$K4X$7$F$ODL>o$N%5%^%j$HF1MM$G$9!#(B + +$BJQ?t(B @code{wl-summary-always-sticky-folder-list} $B$K%U%)%k%@L>(B($B@55,I=8=(B) +$B$N%j%9%H$r@_Dj$9$k$3$H$K$h$j!"%U%)%k%@0\F0;~$K<+F0E*$K%9%F%#%C%-!<%5%^%j$H$9$k$3$H$b$G$-$^$9!#(B + +@section $B%-!<%P%$%s%I(B +@cindex Keybind, Summary Mode +@cindex Keybind, Summary Buffer + +$B%5%^%j%b!<%I$N%-!<%P%$%s%I$O0J2<$NDL$j$G$9!#(B + +@table @kbd +@item @key{SPC} +@kindex @key{SPC} (Summary) +@findex wl-summary-read +$B8=:_%+!<%=%k$,$"$k9T$N%a%C%;!<%8$r%a%C%;!<%8%P%C%U%!$KI=<($7$^$9!#(B +(@code{wl-summary-read}) + +@item . +@kindex . (Summary) +@findex wl-summary-redisplay +$B8=:_%+!<%=%k$,$"$k9T$N%a%C%;!<%8$r:FI=<($7$^$9!#(B +prefix argument $B$D$-$J$i$P%-%c%C%7%e$,B8:_$7$F$bL5;k$7$F:FFI$_9~$_$7D>$7$^$9!#(B +(@code{wl-summary-redisplay}) + +@item < +@kindex < (Summary) +@findex wl-summary-display-top +$B:G=i$N%a%C%;!<%8$rI=<($7$^$9!#(B +(@code{wl-summary-display-top}) + +@item > +@kindex > (Summary) +@findex wl-summary-display-bottom +$B:G8eHx$N%a%C%;!<%8$rI=<($7$^$9!#(B +(@code{wl-summary-display-bottom}) + +@item @key{BS} +@itemx @key{DEL} +@kindex @key{BS} (Summary) +@kindex @key{DEL} (Summary) +$BA0$N%Z!<%8$rI=<($7$^$9!#(B +@findex wl-summary-prev-page +(@code{wl-summary-prev-page}) + +@item @key{RET} +@kindex @key{RET} (Summary) +@findex wl-summary-next-line-content +$B%+!<%=%k9T$N%a%C%;!<%8$,I=<(Cf$G$"$l$P%a%C%;!<%8$r0l9T>e$K%9%/%m!<%k$7$^$9!#(B +$BI=<(Cf$G$J$1$l$P!"I=<($7$^$9!#(B +(@code{wl-summary-next-line-content}) + +@item / +@kindex / (Summary) +@findex wl-thread-open-close +$B%+!<%=%k9T$N%9%l%C%I$N3+JD$r%H%0%k$7$^$9!#(B +(@code{wl-thread-open-close}) + +@item [ +@kindex [ (Summary) +$BA4$F$N%9%l%C%I$r3+$-$^$9!#(B +@findex wl-thread-open-all +(@code{wl-thread-open-all}) + +@item ] +@kindex ] (Summary) +$BA4$F$N%9%l%C%I$rJD$8$^$9!#(B +@findex wl-thread-close-all +(@code{wl-thread-close-all}) + +@item - +@itemx M-@key{RET} +@kindex - (Summary) +@kindex M-@key{RET} (Summary) +@findex wl-summary-prev-line-content +$B%+!<%=%k9T$N%a%C%;!<%8$,I=<(Cf$G$"$l$P%a%C%;!<%8$r0l9T2<$K%9%/%m!<%k$7$^$9!#(B +$BI=<(Cf$G$J$1$l$P!"I=<($7$^$9!#(B +(@code{wl-summary-prev-line-content}) + +@item g +@kindex g (Summary) +@findex wl-summary-goto-folder +$B0c$&%U%)%k%@$K0\F0$7$^$9!#(B +(@code{wl-summary-goto-folder}) + +@item c +@kindex c (Summary) +$BA4$F$N%a%C%;!<%8$rFI$s$@$3$H$K$7$^$9!#(B +@findex wl-summary-mark-as-read-all +(@code{wl-summary-mark-as-read-all}) + +@item a +@kindex a (Summary) +@findex wl-summary-reply +$B8=:_%+!<%=%k$,$"$k9T$N%a%C%;!<%8$X$NJV;vMQ$N%I%i%U%H$rMQ0U$7$^$9!#(B +(@code{wl-summary-reply}) + +@item A +@kindex A (Summary) +@findex wl-summary-reply-with-citation +$B8=:_%+!<%=%k$,$"$k9T$N%a%C%;!<%8$X$NJV;vMQ$N%I%i%U%H$rK\J8$r0zMQ$7$FMQ0U$7$^$9!#(B +(@code{wl-summary-reply-with-citation}) + +@item C +@kindex C (Summary) +@findex wl-summary-cancel-message +$B8=:_$N%+!<%=%k$,$"$k9T$N%a%C%;!<%8$,<+J,$,=P$7$?%K%e!<%95-;v$N>l9g!"$=$NEj9F$r%-%c%s%;%k$7$^$9!#(B +(@code{wl-summary-cancel-message}) + +@item E +@kindex E (Summary) +@findex wl-summary-reedit +$B8=:_%+!<%=%k$,$"$k9T$N%a%C%;!<%8$NFbMF$r$b$D%I%i%U%H$rMQ0U$7$^$9!#(B +$B$b$7!"(Bprefix argument $B$D$-$G$N?M$KE>Aw$9$k%I%i%U%H$rMQ0U$7$^$9!#(B +(@code{wl-summary-forward}) + +@item $ +@kindex $ (Summary) +@findex wl-summary-mark-as-important +@samp{$} $B%^!<%/$r$D$1$^$9!#$9$G$K(B @samp{$} $B%^!<%/$,$"$l$P:o=|$7$^$9!#(B +(@code{wl-summary-mark-as-important}) + +@item y +@itemx e +@kindex y (Summary) +@kindex e (Summary) +$B8=:_%+!<%=%k$,$"$k9T$N%a%C%;!<%8$rJ]B8$7$^$9!#(B +@findex wl-summary-save +(@code{wl-summary-save}) + +@item n +@kindex n (Summary) +@findex wl-summary-next +$B0l$D2<$N%a%C%;!<%8$X0\F0$7$^$9!#(B +(@code{wl-summary-next}) + +@item p +@kindex p (Summary) +@findex wl-summary-prev +$B0l$D>e$N%a%C%;!<%8$X0\F0$7$^$9!#(B +(@code{wl-summary-prev}) + +@item N +@kindex N (Summary) +@findex wl-summary-down +$B2eJ}8~$K$"$kL$FI$b$7$/$O(B @samp{$}$B%^!<%/$D$-$N%a%C%;!<%8$X0\F0$7$^$9!#(B +(@code{wl-summary-up}) + +@item w +@kindex w (Summary) +@findex wl-draft +$B?75,%I%i%U%H$rMQ0U$7$^$9!#(B +(@code{wl-draft}) + +@item W +@kindex W (Summary) +@findex wl-draft-write-current-newsgroup +$B8=:_$N%5%^%j$,%K%e!<%9%0%k!<%W$N>l9g!"(BNewsgroups:$B%U%#!<%k%I$rJd$C$F(B +$B%I%i%U%H$rMQ0U$7$^$9!#(B +(@code{wl-draft-write-current-newsgroup}) + +@item H +@kindex H (Summary) +@findex wl-summary-redisplay-all-header +$B8=:_%+!<%=%k$,$"$k9T$N%a%C%;!<%8$r!"$9$Y$F$N%X%C%@>pJs$H$H$b$KI=<($7$^$9!#(B +(@code{wl-summary-redisplay-all-header}) + +@item M +@kindex M (Summary) +@findex wl-summary-redisplay-no-mime +$B8=:_%+!<%=%k$,$"$k9T$N%a%C%;!<%8$r!"(BMIME $B2r@O$9$k$3$H$J$/I=<($7$^$9!#(B +(@code{wl-summary-redisplay-no-mime}) + +@item B +@kindex B (Summary) +@findex wl-summary-burst +$B8=:_%+!<%=%k$,$"$k9T$N%a%C%;!<%8$,(B +MIME $B$G%+%W%;%k2=$5$l$?J#?t$N%a%C%;!<%84^$`>l9g!"(B +$B$=$l$i$r8=:_$N%U%)%k%@$K$[$I$-$^$9(B($BL$l9g$OJQ99(B/$B:o=|$b$G$-$^$9!#(B +prefix argument $B$D$-$GuBV$r:G?7$N$b$N$K99?7$7$^$9!#(B +(@code{wl-status-update}) + +@item | +@kindex | (Summary) +@findex wl-summary-pipe-message +$B8=:_$N%a%C%;!<%8$NFbMF$rB>$N%W%m%;%9$K%Q%$%W7PM3$G0z$-EO$7$^$9!#(B +(@code{wl-summary-pipe-message}) + +@item # +@kindex # (Summary) +@findex wl-summary-print-message +$B8=:_$N%a%C%;!<%8$NFbMF$r0u:~$7$^$9!#(B +Emacs20 $B!A(B $B$G$O(B ps-print $B$r;H$$$^$9!#(B +$BGr9u%W%j%s%?$G$O!"(B@code{wl-ps-print-buffer-func} $B$r(B +'ps-print-buffer $B$K@_Dj$7$?$[$&$,$h$$$+$b$7$l$^$;$s!#(B +(@code{wl-summary-print-message}) + +@item q +@kindex q (Summary) +@findex wl-summary-exit +$B8=:_$N%U%)%k%@$rC&=P$7$^$9!#(B +(@code{wl-summary-exit}) + +@item j +@kindex j (Summary) +@findex wl-summary-jump-to-current-message +$B8=:_I=<(Cf$N%a%C%;!<%8$N%P%C%U%!$K0\F0$7$^$9!#(B +(@code{wl-summary-jump-to-current-message}) + +@item J +@kindex J (Summary) +$B$[$+$N%a%C%;!<%8$K%8%c%s%W$7$^$9!#(B +@findex wl-summary-jump-to-msg +(@code{wl-summary-jump-to-msg}) + +@item I +@kindex I (Summary) +$B%5%^%j$NI=<($r99?7$7$?$"$H!"(B +@code{wl-summary-incorporate-marks} $B$K4^$^$l$k%^!<%/$r;}$D%a%C%;!<%8$r(B +$B%W%j%U%'%C%A$7$^$9!#(B +@findex wl-summary-incorporate +(@code{wl-summary-incorporate}) + +@item M-j +@kindex M-j (Summary) +@findex wl-summary-jump-to-msg-by-message-id +$BF~NO$7$?%a%C%;!<%8(BID $B$r$b$D%a%C%;!<%8$N9T$K%8%c%s%W$7$^$9!#(B +@code{elmo-use-database} $B$,(B non-nil$B$J$i!"8=:_$N%5%^%j0J30$+$i$b(B +$B8uJd$r8!:w$7$^$9!#(B +(@code{wl-summary-jump-to-msg-by-message-id}) + +@item ^ +@kindex ^ (Summary) +$B8=:_$N%a%C%;!<%8$N?F%a%C%;!<%8$K0\F0$7$^$9!#(B +@findex wl-summary-jump-to-parent-message +(@code{wl-summary-jump-to-parent-message}) + +@item ! +@kindex ! (Summary) +@findex wl-summary-mark-as-unread +$B%+!<%=%k$,$"$k9T$N%a%C%;!<%8$rFI$^$J$+$C$?$3$H$K$7$^$9!#(B +(@code{wl-summary-mark-as-unread}) + +@item s +@kindex s (Summary) +@findex wl-summary-sync +$B%a%C%;!<%8$N0lMwI=<($N99?7%l%s%8(B(all, update, rescan, first, last)$B$NF~NO$rr7o$r;}$D%a%C%;!<%8$N$_$r$b$D2>A[%U%)%k%@$X0\F0$7$^$9!#(B +prefix argument $B$D$-$GA[%U%)%k%@$+$iC&=P$7$^$9!#(B +@findex wl-summary-virtual +(@code{wl-summary-virtual}) + +@item @key{TAB} +@kindex @key{TAB} (Summary) +@findex wl-summary-goto-last-displayed-msg +$B$5$C$-I=<($7$?%a%C%;!<%8$KHt$S$^$9!#(B +(@code{wl-summary-goto-last-displayed-msg}) + +@item ? +@kindex ? (Summary) +$BM?$($i$l$?>r7o$r;}$D%a%C%;!<%8$K$^$H$a=hM}%^!<%/(B @samp{*} $B$r$D$1$^$9!#(B +@findex wl-summary-pick +(@code{wl-summary-pick}) + +@item R +@kindex R (Summary) +@findex wl-summary-mark-as-read +$B%+!<%=%k9T$N%a%C%;!<%8$rFI$s$@$3$H$K$7$^$9!#(B +(@code{wl-summary-mark-as-read}) + +@item i +@kindex i (Summary) +$B%+!<%=%k9T$N%a%C%;!<%8$r%W%j%U%'%C%A$7$^$9!#(B +@findex wl-summary-prefetch +(@code{wl-summary-prefetch}) + +@item x +@kindex x (Summary) +$B$9$Y$F$N(B @samp{D}, @samp{o}, @samp{O} $B%^!<%/$rA0$K%j%U%!%$%k$7$?%U%)%k%@$HF1$8%U%)%k%@08$K!"(B +$B%j%U%!%$%k%^!<%/$r$D$1$^$9!#(B +@findex wl-summary-refile-prev-destination +(@code{wl-summary-refile-prev-destination}) + +@item d +@kindex d (Summary) +@findex wl-summary-delete +$B%+!<%=%k9T$N%a%C%;!<%8$K:o=|%^!<%/$r$D$1$^$9!#(B +(@code{wl-summary-delete}) + +@item u +@kindex u (Summary) +@findex wl-summary-unmark +$B%+!<%=%k9T$N%a%C%;!<%8$K%^!<%/$,$"$l$P:o=|$7$^$9!#(B +(@code{wl-summary-unmark}) + +@item U +@kindex U (Summary) +$B;XDj$7$?%^!<%/$r$9$Y$F:o=|$7$^$9!#(B +@findex wl-summary-unmark-all +(@code{wl-summary-unmark-all}) + +@item r R +@kindex r R (Summary) +@findex wl-summary-mark-as-read-region +$B;XDj%j!<%8%g%s$K$"$k%a%C%;!<%8$rA4$FFI$s$@$3$H$K$7$^$9!#(B +(@code{wl-summary-mark-as-read-region}) + +@item r $ +@kindex r $ (Summary) +@findex wl-summary-mark-as-important-region +$B;XDj%j!<%8%g%s$K$"$k%a%C%;!<%8A4$F$K(B @samp{$} $B%^!<%/$r$D$1$^$9!#(B +$B$9$G$K(B @samp{$} $B%^!<%/$,$"$l$P:o=|$7$^$9!#(B +(@code{wl-summary-mark-as-important-region}) + +@item r ! +@kindex r ! (Summary) +@findex wl-summary-mark-as-unread-region +$B;XDj%j!<%8%g%s$K$"$k%a%C%;!<%8$rA4$FFI$^$J$+$C$?$3$H$K$7$^$9!#(B +(@code{wl-summary-mark-as-unread-region}) + +@item r i +@kindex r i (Summary) +@findex wl-summary-prefetch-region +$B;XDj%j!<%8%g%s$K$"$k%a%C%;!<%8$rA4$F%W%j%U%'%C%A$7$^$9!#(B +(@code{wl-summary-prefetch-region}) + +@item r x +@kindex r x (Summary) +@findex wl-summary-exec-region +$B;XDj%j!<%8%g%s$K$"$k%a%C%;!<%8$K$D$$$?(B @samp{D}, @samp{o}, @samp{O} $B%^!<%/$rC$7$^$9!#(B +(@code{wl-summary-delete-all-temp-marks}) +@findex wl-summary-delete-all-temp-marks + +@item m a +@kindex m a (Summary) +$BA4$F$K$^$H$a=hM}MQ%^!<%/(B @samp{*} $B$rIU$1$^$9!#(B +(@code{wl-summary-target-mark-all}) +@findex wl-summary-target-mark-all + +@item m t +@kindex m t (Summary) +$B$^$H$a=hM}MQ%^!<%/(B @samp{*} $B$r8=:_$N%9%l%C%I$K$D$1$^$9!#(B +@findex wl-summary-target-mark-thread +(@code{wl-summary-target-mark-thread}) + +@item m r +@kindex m r (Summary) +@findex wl-summary-target-mark-region +$B;XDj$5$l$?%j!<%8%g%s$K$^$H$a=hM}MQ%^!<%/(B @samp{*} $B$r$D$1$^$9!#(B +(@code{wl-summary-target-mark-region}) + +@item m A +@kindex m A (Summary) +@findex wl-summary-target-mark-reply-with-citation +$B$^$H$a=hM}MQ%^!<%/(B @samp{*} $B$N$D$$$?%a%C%;!<%8$r0zMQ$7$FJV;v$r=q$/%I%i%U%H(B +$B$rMQ0U$7$^$9!#(B +(@code{wl-summary-target-mark-reply-with-citation}) + +@item m f +@kindex m f (Summary) +@findex wl-summary-target-mark-forward +$B$^$H$a=hM}MQ%^!<%/(B @samp{*} $B$N$D$$$?%a%C%;!<%8$r%U%)%o!<%I$9$k%I%i%U%H$r(B +$BMQ0U$7$^$9!#(B +(@code{wl-summary-target-mark-forward}) + +@item m U +@kindex m U (Summary) +@findex wl-summary-target-mark-uudecode +$B$^$H$a=hM}MQ%^!<%/(B @samp{*} $B$N$D$$$?%a%C%;!<%8$r$^$H$a$F(B uudecode $B$7$^$9!#(B +(@code{wl-summary-target-mark-uudecode}) + +@item m ? +@kindex m ? (Summary) +@findex wl-summary-target-mark-pick +$B$^$H$a=hM}MQ%^!<%/(B @samp{*} $B$N$D$$$?%a%C%;!<%8$N$J$+$G!"(B +$B>r7o$K%^%C%A$9$k%a%C%;!<%8$N(B @samp{*} $B%^!<%/$N$_$r;D$7$^$9!#(B +(@code{wl-summary-target-mark-pick}) + +@item M-t +@kindex M-t (Summary) +@findex wl-toggle-plugged +Wanderlust $B$N%*%U%i%$%s%b!<%I(B/$B%*%s%i%$%s%b!<%I$r%H%0%k$7$^$9!#(B +(@code{wl-toggle-plugged}) + +@item C-t +@kindex C-t (Summary) +Wanderlust $B$N%5!<%P!&%]!<%HJL$N%*%U%i%$%s(B/$B%*%s%i%$%s$rJQ99$7$^$9!#(B +(@code{wl-plugged-change}) + +@item C-c C-o +@kindex C-c C-o (Summary) +@findex wl-jump-to-draft-buffer +$B%I%i%U%H%P%C%U%!$,$"$l$P0\F0$7$^$9!#(B $BJ#?t$N%I%i%U%H%P%C%U%!$,B8:_$9$k>l9g$O!"(B +$Bl9g$O!"%I%i%U%H%U%)%k%@$+$i%U%!%$%k$r(B($BB8:_$9$l$P(B) +$BFI$_9~$_$^$9!#(B +(@code{wl-jump-to-draft-buffer}) +@end table + +@section $B%+%9%?%^%$%:JQ?t(B + +@table @code +@item wl-summary-move-order +@vindex wl-summary-move-order +$B=i4|@_Dj$O(B 'unread$B!#(B +$B%a%C%;!<%8$rFI$_?J$a$k$H$-$K!"2?$rM%@h$9$k$+$r;XDj$7$^$9!#(B +$B?75,%a%C%;!<%8$rM%@h$7$?$$$H$-$O(B 'new $B$r@_Dj$7$^$9!#(B +$BL$FI$r%a%C%;!<%8$rM%@h$7$?$$$H$-$O(B 'unread $B$r@_Dj$7$^$9!#(B +nil $B$J$iC1=c$KuBV$G%5%^%j$KI=<($5$l$^$9!#(B + +@item wl-thread-open-reading-thread +@vindex wl-thread-open-reading-thread +$B=i4|@_Dj$O(B t$B!#(B +Non-nil $B$J$i!"JD$8$?>uBV$N(B thread $B$X0\F0$7$?;~$K<+F0E*$K(B thread $B$r3+$-$^$9!#(B + +@item wl-summary-exit-next-move +@vindex wl-summary-exit-next-move +$B=i4|@_Dj$O(B t$B!#(B +Non-nil $B$J$i!"%5%^%j$r=*N;$9$k$H$-$K$N%U%)%k%@$K0\F0$9$k$H%U%)%k%@%b!<%I$G$N%+!<%=%k0LCV$b9g$o$;$F0\F0$7$^$9!#(B + +@item wl-summary-weekday-name-lang +@vindex wl-summary-weekday-name-lang +$B=i4|@_Dj$O(B "ja"$B!#(B +$B%5%^%j$NMKF|I=<($N8@8l$r;XDj$7$^$9!#(B +"en" $B$J$i1Q8l!"(B"fr" $B$J$i%U%i%s%98l!"(B"de" $B$J$i%I%$%D8l$H$J$j$^$9!#(B + +@item wl-summary-fix-timezone +@vindex wl-summary-fix-timezone +$B=i4|@_Dj$O(B "JST"$B!#(B +$B%5%^%j$NF|;~I=<($r;XDj$7$?%?%$%`%>!<%s$KD>$7$^$9!#(B +nil $B$J$i(B GMT $B$KD>$7$^$9!#(B + +@item wl-use-petname +@vindex wl-use-petname +$B=i4|@_Dj$O(B t$B!#(B +Non-nil $B$J$i%5%^%j$N(B From $BItJ,$K$"$@L>$rI=<($7$^$9!#(B + +@item wl-break-pages +@vindex wl-break-pages +$B=i4|@_Dj$O(B t$B!#(B +Non-nil $B$J$i!"(B@samp{^L} $B$G2~%Z!<%8$7$F%a%C%;!<%8$rI=<($7$^$9!#(B + +@item wl-message-window-size +@vindex wl-message-window-size +$B=i4|@_Dj$O(B '(1 . 4)$B!#(B +$B%5%^%j$rI=<($9$k%&%#%s%I%&$H%a%C%;!<%8K\BN$rI=<($9$k%&%#%s%I%&$NHf$r(B cons $B$G;XDj$7$^$9!#(Bcar:cdr $B$,(B $B%5%^%j(B:$B%a%C%;!<%8(B $B$G$9!#(B + +@item wl-summary-recenter +@vindex wl-summary-recenter +$B=i4|@_Dj$O(B t$B!#(B +Non-nil $B$J$i$PI=<($7$?$H$-$KI=<(Cf$N%a%C%;!<%8$N%5%^%j9T$r(B +$B%&%#%s%I%&$NCf1{IU6a$K0\F0$5$;$^$9!#(B + +@item wl-summary-indent-length-limit +@vindex wl-summary-indent-length-limit +$B=i4|@_Dj$O(B 46$B!#(B +$B@_Dj$5$l$?CM0J>e%5%^%j$r(B indent $B$7$^$;$s!#(B +nil $B$J$i%5%^%j$N(B indent $B$rL5@)8B$K$7$^$9!#(B + +@item wl-summary-no-from-message +@vindex wl-summary-no-from-message +$B=i4|@_Dj$O(B "nobody@@nowhere?"$B!#(B +$B%a%C%;!<%8$K(B From: $B$,L5$+$C$?>l9g$K%5%^%j$KI=<($9$kJ8;zNs$G$9!#(B + +@item wl-summary-no-subject-message +@vindex wl-summary-no-subject-message +$B=i4|@_Dj$O(B "(WL:No Subject in original.)"$B!#(B +$B%a%C%;!<%8$K(B Subject: $B$,L5$+$C$?>l9g$K%5%^%j$KI=<($9$kJ8;zNs$G$9!#(B + +@item wl-summary-width +@vindex wl-summary-width +$B=i4|@_Dj$O(B 80$B!#(B +$B%5%^%j$NI=<(I}$r@_Dj$5$l$?CM$K@Z$j5M$a$^$9!#(B +nil $B$J$iI=<(I}$r@Z$j5M$a$^$;$s!#(B + +@item wl-use-folder-petname +@vindex wl-use-folder-petname +$B=i4|@_Dj$O(B '(modeline)$B!#(B +petname $B$r;HMQ$9$k>l=j(B(symbol)$B$N%j%9%H$r;XDj$7$^$9!#(B +$B;XDj$G$-$k(B symbol $B$Oe$+2<$+$r@Z$jBX$($k!#(B +$BFI$s$G$$$kJ}8~$r0U<1$7$?$$$H$-$O(B t $B$K$9$k$H$h$$$G$7$g$&!#(B + +@item wl-from-width +@vindex wl-from-width +$B=i4|@_Dj$O(B 17$B!#(B +$B%5%^%j$N(B From $BItJ,$NI=<(I}$G$9!#(B + +@item wl-summary-divide-thread-when-subject-changed +@vindex wl-summary-divide-thread-when-subject-changed +$B=i4|@_Dj$O(B nil$B!#(B +Non-nil $B$J$i%5%V%8%'%/%H$,JQ$o$C$?$H$-$K%9%l%C%I$r@Z$j$^$9!#(B + +@item wl-summary-search-via-nntp +@vindex wl-summary-search-via-nntp +$B=i4|@_Dj$O(B 'confirm$B!#(B +Non-nil $B$J$i(B @code{wl-summary-jump-to-msg-by-message-id} $B$G!"(B +$B%a%C%;!<%8$r8+$D$1$k$3$H$,$G$-$J$+$C$?$H$-$K!"(B +@code{wl-summary-jump-to-msg-by-message-id-via-nntp} $B$r8F$S!"(B +@code{elmo-default-nntp-server} $B$G;XDj$5$l$?%5!<%P$+$i8!:w$7$^$9!#(B +$B$3$N$H$-(B @code{elmo-default-nntp-user}, @code{elmo-default-nntp-port}, +@code{elmo-default-nntp-ssl} $B$G;XDj$7$?>r7o$G%5!<%P$H@\B3$7$^$9!#(B +'confirm $B$J$i(B @code{elmo-default-nntp-*} $B$G;XDj$5$l$?%5!<%P$+$i8!:w$9$k$+!"(B +$B%5!<%P$r;XDj$9$k$+$r3NG'$7$^$9!#(B +$B$3$N>l9g!"%5!<%P$N%[%9%HL>!"$b$7$/$O(B @samp{-:username@@servername:119!} +$B$N$h$&$K(B NTTP$B%U%)%k%@7A<0$G$N;XDj$,2DG=$G$9!#(B + +@item wl-summary-keep-cursor-command +@vindex wl-summary-keep-cursor-command +$B=i4|@_Dj$O(B '(wl-summary-goto-folder wl-summary-goto-last-visited-folder)$B!#(B +$B$9$G$KB8:_$9$k%5%^%j$X0\F0$7$?$H$-$K99?7$;$:!"%+!<%=%k0LCV$rJ]B8$9$k(B +$B%3%^%s%I$N%j%9%H$G$9!#(B + +@item wl-summary-update-confirm-threshold +@vindex wl-summary-update-confirm-threshold +$B=i4|@_Dj$O(B 500$B!#(B +$B$3$NCM$h$j%5%^%j$N99?7?t$,B?$$>l9g!"0lItJ,$@$199?7$9$k$+$I$&$+!"(B($B@55,I=8=(B)$B$N%j%9%H$r@_Dj$9$k$3$H$K$h$j!"(B +$B<+F0E*$K%9%F%#%C%-!<%5%^%j$H$9$k$+$I$&$+$r%U%)%k%@Kh$K;XDj$7$^$9!#(B + +@item wl-summary-reserve-mark-list +@vindex wl-summary-reserve-mark-list +$B=i4|@_Dj$O!"(B'("o" "O" "D")$B!#(B +$B$3$N%j%9%H$K$"$k0l;~%^!<%/$O!">C$5$J$$$+$.$j>e=q$-$5$l$^$;$s!#(B + +@item wl-summary-skip-mark-list +@vindex wl-summary-skip-mark-list +$B=i4|@_Dj$O!"(B'("D")$B!#(B +$B$3$N%j%9%H$K$"$k0l;~%^!<%/$,IU$$$?%a%C%;!<%8$O!"%+!<%=%k0\F0$G%9%-%C%W(B +$B$5$l$^$9!#(B + +@item wl-fetch-confirm-threshold +@vindex wl-fetch-confirm-threshold +$B=i4|@_Dj$O(B 30000 (bytes)$B!#(B@code{wl-fetch-confirm-threshold} $B$r1[$($k%5%$%:$N(B +$B%a%C%;!<%8$rI=<($9$k;~$O!"3NG'$r5a$a$^$9!#(Bnil $B$K$9$k$H!"3NG'$;$:$KI=<($7$^$9!#(B + +@item wl-prefetch-threshold +@vindex wl-prefetch-threshold +$B=i4|@_Dj$O(B 30000 (bytes)$B!#(B@code{wl-prefetch-threshold} $B$r1[$($k%5%$%:$N(B +$B%a%C%;!<%8$O!"(B@code{wl-prefetch-confirm} $B$,(B non-nil $B$N>l9g!"(B +$B%W%j%U%'%C%A;~$K3NG'$r5a$a$^$9!#(B@code{wl-prefetch-threshold}$B$r(B nil $B$K$9$k$H!"(B +@code{wl-prefetch-confirm} $B$NCM$K$+$+$o$i$:%W%j%U%'%C%A$r$l$N%I%-%e%a%s%H$r;2>H$7$F$/$@$5$$!#(B +@xref{MIME-View, , ,mime-ui-ja, a MIME user interface for GNU Emacs}. + +$B%a%C%;!<%8$N@hF,$G(B @kbd{p}$B!"%a%C%;!<%8$N:G8eHx$G(B @kbd{n} $B$r2!$9$H!"(B +$B%5%^%j%b!<%I$KLa$j$^$9!#(B +$B$^$?!"(B@kbd{l} $B$r2!$9$H!"%5%^%j%b!<%I%P%C%U%!$NI=<($,%H%0%k$5$l$^$9!#(B + +@section $B%-!<%P%$%s%I(B +@cindex Keybind, Message Mode +@cindex Keybind, Message Buffer + +@table @kbd +@item l +@kindex l (Message) +@findex wl-message-toggle-disp-summary +$B%5%^%j%b!<%I%P%C%U%!$rI=<($9$k$+$I$&$+$r%H%0%k$7$^$9!#(B +(@code{wl-message-toggle-disp-summary}) + +@item Button-2 +@findex wl-message-refer-article-or-url +@kindex Button-2 (Message) +$B%^%&%9%]%$%s%?$N0LCV$K(B Message-ID $B$,$"$C$?$H$-$KBP1~$9$k%a%C%;!<%8$,(B +$B8+$D$+$l$PI=<($7$^$9!#(B +(@code{wl-message-refer-article-or-url}) + +@item Button-4 ($B%[%$!<%k$D$-%^%&%9$N%[%$!<%k$r>e$X(B) +@kindex Button-4 (Message) +@findex wl-message-wheel-down +$B%a%C%;!<%8$r>e$K%9%/%m!<%k$7$^$9!#%a%C%;!<%8$NKvHx$^$GE~C#$9$k$H!"(B +$Be$K%9%/%m!<%k$7$^$9!#%a%C%;!<%8$N@hF,$^$GE~C#$9$k$H!"(B +$BA0$N%a%C%;!<%8$K0\F0$7$^$9!#(B +(@code{wl-message-wheel-up}) +@end table + +@section $B%+%9%?%^%$%:JQ?t(B + +@table @code +@item wl-message-window-size +@vindex wl-message-window-size +$B=i4|@_Dj$O(B @code{'(1 . 4)}$B!#(Bcons $B%;%k$G!"(Bcar $BCM(B: cdr $BCM$,(B +$B%5%^%j$N%&%#%s%I%&I}!'%a%C%;!<%8$N%&%#%s%I%&I}$H$J$j$^$9!#(B +@end table + + +@c +@c Draft +@c +@node Draft, Disconnected Operations, Message, Top +@chapter $B%I%i%U%H%P%C%U%!(B + +$B%5%^%j%b!<%I$G(B @kbd{w} $B$r2!$9Ey$9$k$3$H$K$h$j?75,%I%i%U%H%P%C%U%!$,(B +$BMQ0U$5$l$^$9!#$3$N%P%C%U%!$G%a!<%k!"%K%e!<%95-;v$N(B($B?75,(B)$BJT=8!"Aw?.$r9T$$$^$9!#(B + +@section $B;H$$J}(B(TIPS) + +$B4pK\$O(B Emacs $BI8=`$N%a!<%k%b!<%I$G$9!#(B + +@subsection $B%"%I%l%9$NJd40(B + +$B=i4|>uBV$G$O(B To: $B$K%+!<%=%k$,$"$j$^$9!#(B +$BAw?.Ajl9g$O!"(BNewsgroups: $B%U%#!<%k%I$r<+J,$G=q$-2C$($F$/$@$5$$!#%U%#!<%k%IL>$O(B @kbd{@key{TAB}} $B$GJd40$7$^$9!#(B + +$BJT=8Cf$N%I%i%U%H$r%;!<%V$9$k$H!"(B@code{wl-draft-folder} $B$K@_Dj$5$l$?%I%i%U%H%U%)%k%@$KDI2C$5$l$^$9!#(B + +FCC: $B%U%#!<%k%I$GAw?.$7$?%a%C%;!<%8$N%3%T!<$rJ]B8$7$F$*$/%U%)%k%@$r;XDj$9$k$3$H$,$G$-$^$9!#(B + +@subsection $B%a%C%;!<%8$NJT=8(B + +$B%^%k%A%Q!<%H$NJT=8$O(B SEMI/tm $B$N(B MIME $BJT=8%b!<%I$rMxMQ$7$F$$$^$9!#(B +$BJT=8$NJ}K!$O3F%Q%C%1!<%8IUB0$N%I%-%e%a%s%H$r;2>H$7$F$/$@$5$$!#(B +@xref{Mail Methods, , ,mime-ui-ja, a MIME user interface for GNU Emacs}. + +@subsection $B%a%C%;!<%8$NF0E*$JJQ99(B +@vindex wl-draft-config-alist +@c @cindex Chage Message +@c @cindex Message, Chage Dynamic + +@code{wl-draft-config-alist} $B$r@_Dj$9$k$3$H$G!"(B +$B%X%C%@$d$=$NB>$N>pJs$K$h$j!"<+F0E*$KB>$N%X%C%@$dK\J8$rJQ99$9$k$3$H(B +$B$,$G$-$^$9!#(B + +$BJQ?t(B @code{wl-draft-config-alist} $B$K$D$$$F@bL@$7$^$9!#(B +$B$3$NJQ?t$N=i4|@_Dj$O(B nil$B$G$9!#(B + +$BNc$($P0J2<$N$h$&$K@_Dj$9$k$H!"(B@code{wl-draft-send-and-exit} $B$d(B +@code{wl-draft-send} $B$re$G$9!#(B\n") ;; @r{$BK\J8KvHx$XJ8;zNs$rA^F~$7$^$9(B} + )) +@end lisp + +@code{wl-draft-config-alist} $B$OH(B) +@end example + +$B$^$?!"$3$l$i$O(B @code{wl-draft-config-sub-func-alist} $B$KDj5A$5$l$F(B +$B$*$j!"JQ99$7$?$j<+J,$G:n$C$?4X?t$rDI2C$9$k$3$H$,$G$-$^$9!#4X(B +$B?t$N=q$-J}$O$3$3$G@bL@$9$k$h$jD>@\%3!<%I$r8+$?J}$,J,$+$j$d$9(B +$B$$$G$7$g$&$+$i>JN,$7$^$9!#(B + +$B3FMWAG$N(B1$BHVL\$K$O(B "$B%X%C%@$N@55,I=8=(B" $B$+(B elisp$B<0(B $B$r;XDj$7$^$9!#(Belisp$B<0$N(B +$B>l9g$OI>2A$7$?CM$,(Bnon-nil$B$N>l9g$KE,MQ$5$l$^$9!#(B + +$B$^$?!"%G%U%)%k%H$G$OJ#?t$NMWAG$,%^%C%A$^$?$O(Bnon-nil$B$K$J$C$?>l9g$K!"(B +$B$=$NA4$F$,E,MQ$5$l$^$9$,!"JQ?t(B @code{wl-draft-config-matchone} $B$r(B +t $B$K$9$k$3$H$G:G=i$K%^%C%A$7$?(B1$B$D$@$1$rE,MQ$9$k$3$H$b$G$-$^$9!#(B + +$BMWAG$N(B2$BHVL\$K$O(B cons $B$+4X?t$N(B list $B$r;XDj$7$^$9!#(B +cons $B$K$O%X%C%@$N(B Field $B$+JQ?t!"%5%V4X?t$r;XDj$7!"(B +Field $B$r;XDj$7$?>l9g$O$=$N(B Field $B$rJQ99!"(B +$BJQ?t$r;XDj$7$?>l9g$O0l;~E*$K$=$NJQ?tCM$rJQ99$7$^$9!#(B + +$BCM$K$O(B string $B$dJQ?t$NB>!"(Belisp$B<0$,$=$N$^$^5-=R$G$-!"$b$7!"(BField $B$NCM$,(B +nil $B$J$i$P$=$N(B Field $B$r:o=|$7$^$9!#(B + +$B$D$E$$$F!"l9g!"(B +$BJV?.85$N%X%C%@$K%^%C%A$9$l$PE,MQ$5$l$k$h$&$K$J$j$^$9!#(B +$B$?$@$7!"(B@code{wl-draft} $B$rl9g$OL5(B +$B;k$5$l$^$9!#(B + +$BCm0UE@$H$7$F$O!"(B +$B$3$N(B @code{wl-draft-config-alist} $B$O!"(B@code{wl-draft-send-and-exit} $B$d(B +@code{wl-draft-send} $B$rl9g$O!"(B@kbd{C-c C-e} (@code{wl-draft-config-exec}) $B$rl9g$O!"A0(B($B%F%s%W%l!<%HL>(B)$B$r$D$1$k$@$1$G$9!#(B +$B3FMWAG$NDj5A$O(B @code{wl-draft-config-alist} $B$HF1$8$G$"$k$N$G!"(B +(a)$B$N$h$&$KJL$N%F%s%W%l!<%H$r8F$V$3$H$b2DG=$G$9!#(B + +$B%3%^%s%I(B@code{wl-template-select}$B$rl9g!"(B +$B%I%i%U%H%P%C%U%!$N2<$KE,MQ8e$N%P%C%U%!%&%#%s%I%&$,I=<($5$l$k$N$G!"(B +$B$=$l$r8+$J$,$i(B @kbd{n} $B$H(B @kbd{p} $B$GA*Br$7$^$9!#(B +$B$=$7$F%j%?!<%s%-!<$G7hDj$9$k$Hl9g$J$K$bE,MQ$5$l$^$;$s!#$J$*!"(B +@code{wl-template-buffer-lines} $B$G%&%#%s%I%&$NBg$-$5$,JQ99$G$-$^$9!#(B + +@code{wl-template-visible-select} $B$,(B nil $B$N>l9g!"%_%K%P%C%U%!$G%F%s%W%l!<%HL>(B +$B$rF~NO$9$k$3$H$GA*Br$7$^$9!#(B + +$B$^$?!"(B@code{wl-draft-config-alist} $B$NNc$N$h$&$KNc$($P(B + +@example +(template . "default") +@end example + +@noindent +$B$H=q$/$3$H$G(B "default" $B$N%F%s%W%l!<%H$rE,MQ$9$k$3$H$,$G$-$^$9!#(B + +@subsection POP-before-SMTP$B$K$h$k%a!<%k$NAw?.(B +@cindex POP-before-SMTP + +POP-before-SMTP$B$K$h$k%a!<%k$NAw?.$,$G$-$^$9!#(B +$B@_Dj$O!"(B + +@lisp +(setq wl-draft-send-mail-func 'wl-draft-send-mail-with-pop-before-smtp) +@end lisp + +@noindent +$B$N(B1$B9T$N$_$G$9$,!"I,MW$K1~$8$F0J2<$NJQ?t$r@_Dj$7$F$/$@$5$$!#(B + +@table @code +@item wl-pop-before-smtp-user +POP-before-SMTP $B$GG'>Z$r9T$J$&$H$-$N(BPOP$B%f!<%6L>$G$9!#(B +$B@_Dj$5$l$F$$$J$$>l9g$O(B @code{elmo-default-pop3-user} $B$,;H$o$l$^$9!#(B + +@item wl-pop-before-smtp-server +POP-before-SMTP $B$GG'>Z$r9T$J$&$H$-$N(BPOP$B%5!<%PL>$G$9!#(B +$B@_Dj$5$l$F$$$J$$>l9g$O(B @code{elmo-default-pop3-server} $B$,;H$o$l$^$9!#(B + +@item wl-pop-before-smtp-authenticate-type +POP-before-SMTP $B$GG'>Z$r9T$J$&$H$-$N(BPOP$BG'>ZJ}<0$G$9!#(B +$B@_Dj$5$l$F$$$J$$>l9g$O(B @code{elmo-default-pop3-authenticate-type} +$B$,;H$o$l$^$9!#(B + +@item wl-pop-before-smtp-port +POP-before-SMTP $B$GG'>Z$r9T$J$&$H$-$N(BPOP$B%]!<%HHV9f$G$9!#(B +$B@_Dj$5$l$F$$$J$$>l9g$O(B @code{elmo-default-pop3-port} $B$,;H$o$l$^$9!#(B + +@item wl-pop-before-smtp-ssl +Non-nil $B$J$i(B SSL $B$rMxMQ$7$F(B POP$B%3%M%/%7%g%s$rD%$j$^$9!#(B +'starttls$B$J$i(BSTARTTLS (RFC2595)$B$rMxMQ$7$F%3%M%/%7%g%s$,D%$i$l$^$9!#(B +$B@_Dj$5$l$F$$$J$$>l9g$O(B @code{elmo-default-pop3-ssl} $B$,;H$o$l$^$9!#(B +@end table + +POP-before-SMTP$BMQ$NJQ?t(B (@code{wl-pop-before-smtp-*}) +$B$,@_Dj$5$l$F$$$J$$>l9g$O!"(B +POP $B%U%)%k%@$N@_Dj(B (@code{elmo-default-pop3-*}) $B$,MQ$$$i$l$^$9!#(B +$B$=$N$?$a!"(BSMTP$B%5!<%P$H(BPOP$B%5!<%P$NH$7$F$/$@$5$$!#(B + +@example +http://spam.ayamura.org/tools/smPbS.html +http://www.iecc.com/pop-before-smtp.html +@end example + +@section $B%-!<%P%$%s%I(B +@cindex Keybind, Draft Mode +@cindex Keybind, Draft Buffer + +@table @kbd +@item C-c C-y +@kindex C-c C-y (Draft) +@findex wl-draft-yank-original +$B8=:_I=<(Cf$N%a%C%;!<%8%P%C%U%!$NFbMF$r0zMQ$7$^$9!#(B +(@code{wl-draft-yank-original}) + +@item C-c C-p +@kindex C-c C-p (Draft) +@findex wl-draft-preview-message +$B8=:_$N%I%i%U%H$NFbMF$r%W%l%S%e!<$7$^$9!#(B +MIME $B$N%^%k%A%Q!<%H%a%C%;!<%8$N3NG'$K;H$&$HJXMx$G$9!#(B +(@code{wl-draft-preview-message}) + +@item C-c C-s +@kindex C-c C-s (Draft) +@findex wl-draft-send +$B8=:_$N%I%i%U%H$NFbMF$rAw?.$7$^$9!#%I%i%U%H%P%C%U%!$O>C5n$7$^$;$s!#(B +$BJ#?t$N?M$K>/$7$:$DFbMF$rJQ$($F%a%C%;!<%8$rAw$j$?$$>l9g$KJXMx$G$9!#(B +(@code{wl-draft-send}) + +@item C-c C-c +@kindex C-c C-c (Draft) +@findex wl-draft-send-and-exit +$B8=:_$N%I%i%U%H$NFbMF$rAw?.$7!"%I%i%U%H%P%C%U%!$r>C5n$7$^$9!#(B +(@code{wl-draft-send-and-exit}) + +@item C-x C-s +@kindex C-x C-s (Draft) +@findex wl-draft-save +$B8=:_$N%I%i%U%H$r%;!<%V$7$^$9!#(B +(@code{wl-draft-save}) + +@item C-c C-k +@kindex C-c C-k (Draft) +@findex wl-draft-kill +$B8=:_$N%I%i%U%H$rGK4~$7$^$9!#(B +$B%;!<%V$7$F$$$?>l9g!"(B@samp{+draft} $B%U%)%k%@$+$i$b:o=|$5$l$^$9!#(B +(@code{wl-draft-kill}) + +@c @item C-x k +@c @kindex C-x k (Draft) +@c @findex wl-draft-mimic-kill-buffer +@c $B8=:_$N%I%i%U%H$rGK4~$7$^$9!#(B +@c (@code{wl-draft-mimic-kill-buffer}) + +@item C-c C-z +@kindex C-c C-z (Draft) +@findex wl-draft-save-and-exit +$B8=:_$N%I%i%U%H$r%;!<%V$7!"%I%i%U%H%P%C%U%!$r>C5n$7$^$9!#(B +$B%I%i%U%H$NJT=8$rCfCG$7$?$$$H$-$KJXMx$G$9!#(B +@samp{+draft} $B%U%)%k%@$KF~$C$F(B @kbd{E} (@code{wl-summary-reedit} $B$r2!$;$P!"(B +$BJT=8$r:F3+$G$-$^$9!#(B +(@code{wl-draft-save-and-exit}) + +@item C-c C-r +@kindex C-c C-r (Draft) +@findex wl-caesar-region +$B;XDj$5$l$?%j!<%8%g%s$r%7!<%60E9f$G%(%s%3!<%I(B/$B%G%3!<%I$7$^$9!#(B +(@code{wl-caesar-region}) + +@item M-t +@kindex M-t (Draft) +@findex wl-toggle-plugged +Wanderlust $B$N%*%U%i%$%s%b!<%I(B/$B%*%s%i%$%s%b!<%I$r%H%0%k$7$^$9!#(B +(@code{wl-toggle-plugged}) + +@item C-c C-o +@kindex C-c C-o (Draft) +@findex wl-jump-to-draft-buffer +$BB>$N%I%i%U%H%P%C%U%!$,$"$l$P0\F0$7$^$9!#(B +$B$^$?!"(Bprefix argument $B$r$D$1$k$3$H$K$h$j!"%P%C%U%!$,B8:_$7$F$$$J$$>l9g$O!"(B +$B%I%i%U%H%U%)%k%@$+$i%U%!%$%k$r(B($BB8:_$9$l$P(B)$BFI$_9~$_$^$9!#(B +(@code{wl-jump-to-draft-buffer}) + +@item C-c C-e +@kindex C-c C-e (Draft) +@findex wl-draft-config-exec +@code{wl-draft-config-alist}$B$rE,MQ$7$^$9!#(B +(@code{wl-draft-config-exec}) + +@item C-c C-j +@kindex C-c C-j (Draft) +@findex wl-template-select +$B%F%s%W%l!<%H$rA*Br$7$^$9!#(B +(@code{wl-template-select}) + +@item C-c C-a +@kindex C-c C-a (Draft) +@findex wl-draft-insert-x-face-field +$B%U%!%$%k(B @file{~/.xface} ($BJQ?t(B @code{wl-x-face-file} $B$NCM(B) $B$NFbMF$r(B +$B%I%i%U%H%P%C%U%!$K(B X-Face$B%U%#!<%k%I$H$7$FA^F~$7$^$9!#(B + +Encode $B$5$l$?(B X-Face $BJ8;zNs$r$"$i$+$8$a%U%!%$%k(B @file{~/.xface} +$B$NFbMF$KMQ0U$7$F$*$/I,MW$,$"$j$^$9!#(B +(@code{wl-draft-insert-x-face-field}) +@end table + +@section $B%+%9%?%^%$%:JQ?t(B + +@table @code +@item wl-subscribed-mailing-list +@vindex wl-subscribed-mailing-list +$B=i4|@_Dj$O(B nil$B!#(B +$B;22C$7$F$$$k%a!<%j%s%0%j%9%H!#(B +$BJV;v$N%I%i%U%H$rMQ0U$9$k$H$-$K(B Mail-Followup-To $B$d(B Cc $B$K$3$l$i$,(B +$B4^$^$l$k$H$-$O<+J,$N%"%I%l%9$r=|$-$^$9!#(B +$B$^$?!"%j%U%!%$%k@h$r3P$($k$H$-$K$3$l$i$,(B To $B$+(B Cc $B$K4^$^$l$k$H$-(B +$B$K$O!"$=$N%"%I%l%9$G%j%U%!%$%k@h$r3P$($^$9!#(B + +@item wl-insert-mail-followup-to +@vindex wl-insert-mail-followup-to +$B=i4|@_Dj$O(B nil$B!#(B +Non-nil $B$J$i!"(BMail-Followup-To $B%U%#!<%k%I$r(B +$B%I%i%U%H%P%C%U%!$K<+F0E*$KA^F~$7$^$9!#(B + +@item wl-insert-mail-reply-to +@vindex wl-insert-mail-reply-to +$B=i4|@_Dj$O(B nil$B!#(B +Non-nil $B$J$i!"(BMail-Reply-To $B%U%#!<%k%I$r(B +$B%I%i%U%H%P%C%U%!$K<+F0E*$KA^F~$7$^$9!#(B + +@item wl-auto-insert-x-face +@vindex wl-auto-insert-x-face +$B=i4|@_Dj$O(B t$B!#(B +Non-nil $B$G$+$D!"(BEncode $B$5$l$?(B X-Face $BJ8;zNs$r(B @file{~/.xface} +($BJQ?t(B @code{wl-x-face-file} $B$NCM$G$9(B)$B$NFbMF$KMQ0U$7$F$*$/$H!"(B +$B%I%i%U%H$,=`Hw$5$l$k$H$-$K<+F0E*$K(B X-Face$B%U%#!<%k%I$H$7$FA^F~$5$l$^$9!#(B +nil$B$N>l9g$O<+F0E*$K$OA^F~$5$l$^$;$s$,!"(B@kbd{C-c C-a} $B$r2!$9$H%X%C%@It$K(B +$BA^F~$5$l$^$9!#(B + +@item wl-insert-message-id +@vindex wl-insert-message-id +$B=i4|@_Dj$O(B t$B!#(B +Non-nil $B$J$i!"Aw?.;~$K(B Message-ID $B%U%#!<%k%I$r<+F0E*$KA^F~$7$^$9!#(B + +@item wl-local-domain +@vindex wl-local-domain +$B=i4|@_Dj$O(B nil$B!#(B +nil $B$J$i$P(B Message-ID $B$N%I%a%$%s%Q!<%H$O4X?t(B @code{system-name} $B$NJVCM$,(B +$B@_Dj$5$l$^$9!#(B +@code{system-name} $B$,(B FQDN ($B$D$^$j!"(B@samp{smtp.gohome.org} $B$N$h$&$J(B +$B%[%9%H$N%U%k%M!<%`(B) $B$rJV$5$J$$>l9g$O!"(B +$B$3$NJQ?t$K(B @strong{$BI,$:(B} $B%[%9%HL>$r=|$$$?%I%a%$%sL>(B (@samp{gohome.org}$B$J$I(B) $B$r(B +$B@_Dj$7$F$/$@$5$$!#(B $B$b$7!"%0%m!<%P%k$J(BIP$B$r;}$?$J$$>l9g$O!"(B +@code{wl-message-id-domain}$B$r@_Dj$7$F$/$@$5$$!#(B +(Message-ID $B$N%I%a%$%s$,$*$+$7$$$H!"(B +$B%M%C%H%K%e!<%9$G$U$/$mC!$-$K$"$C$F$7$^$&2DG=@-$,$"$j$^$9!#(B) +$B$^$?!"$3$NCM$,@_Dj$5$l$F$$$k>l9g!"(B +@code{system-name} $B$K$3$NCM$rIU2C$7$?%[%9%HL>$,(B +SMTP $B$N(B HELO $B$N0z?t$H$7$FMxMQ$5$l$^$9!#(B + +@item wl-message-id-domain +@vindex wl-message-id-domain +$B=i4|@_Dj$O(B nil$B!#(B +Non-nil $B$J$i!"(BMessage-ID $B$N%I%a%$%s%Q!<%H$K;HMQ$5$l$^$9!#(B +$B%0%m!<%P%k$J(B IP $B$r;}$?$J$$>l9g$J$I!"%I%a%$%s%Q!<%H$r7h$a$i$l$J$$>l9g$O!"(B +@code{wl-message-id-domain} $B$K0l0U$JJ8;zNs(B +($BNc$($P!"%a!<%k%"%I%l%9$J$I(B)$B$r@_Dj$7$F$/$@$5$$!#(B + +@item wl-draft-config-alist +@vindex wl-draft-config-alist +$B=i4|@_Dj$O(B nil$B!#(B +$BAw?.D>A0$K%I%i%U%H%a%C%;!<%8$rJQ99$7$^$9!#(B +$B<+F0E*$K(B @code{wl-draft-config-alist} $B$NFbMF$,E,MQ$5$l$k$N$OAw?.;~$K0lEY(B +$B$@$1$G$9!#$b$7!$l9g$O!$(B@kbd{C-c C-e} +(@code{wl-draft-config-exec}) $B$r;HMQ$7$F$/$@$5$$!#$3$N%3%^%s%I$O2?EY$G$b(B +$BE,MQ$G$-$^$9!#(B + +@item wl-template-alist +@vindex wl-template-alist +$B=i4|@_Dj$O(B nil$B!#(B +$B%I%i%U%H%P%C%U%!$GE,MQ$9$k%F%s%W%l!<%H$r@_Dj$7$^$9!#(B + +@item wl-draft-config-matchone +@vindex wl-draft-config-matchone +$B=i4|@_Dj$O(B nil$B!#(B +Non-nil $B$J$i(B @code{wl-draft-config-alist} $B$NE,MQ;~$K:G=i$K%^%C%A$7$?MWAG(B +$B$N$_$rE,MQ$7$^$9!#(Bnil $B$J$i%^%C%A$7$?$b$N$9$Y$F$rE,MQ$7$^$9!#(B + +@item wl-template-visible-select +@vindex wl-template-visible-select +$B=i4|@_Dj$O(B t$B!#(B +Non-nil $B$J$iJL%&%#%s%I%&$KE,MQ8e$N>uBV$rI=<($7$J$,$i%F%s%W%l!<%H$rA*Br$7$^$9!#(B + +@item wl-template-confirm +@vindex wl-template-confirm +$B=i4|@_Dj$O(B nil$B!#(B +Non-nil $B$J$i%&%#%s%I%&$rI=<($7$J$,$i%F%s%W%l!<%H$rA*Br$9$k>l9g!"%j%?!<%s(B +$B%-!<$GA*Br$9$k;~$K3NG'$r9T$$$^$9!#(B + +@item wl-template-buffer-lines +@vindex wl-template-buffer-lines +$B=i4|@_Dj$O(B 7$B!#(B +@code{wl-template-visible-select}$B$,(B non-nil $B$N>l9g!"(B +$BE,MQ8e$N>uBV$rI=<($9$k%&%#%s%I%&$NBg$-$5$r;XDj$7$^$9!#(B + +@item wl-draft-reply-buffer-style +@vindex wl-draft-reply-buffer-style +$B=i4|@_Dj$O(B 'split$B!#(B +'split $B$H(B 'full $B$,;XDj$G$-$^$9!#(B +'full $B$J$iJV;v$r=q$/$H$-$K%U%l!<%`A4BN$r;H$C$?%I%i%U%H%P%C%U%!$,(B +$BMQ0U$5$l$^$9!#(B + +@item wl-from +@vindex wl-from +$B=i4|@_Dj$OJQ?t(B @code{user-mail-address} $B$NCM!#(B +$B@_Dj$5$l$?CM$r%I%i%U%H$N(B From $B%U%#!<%k%I$H$7$F:G=i$+$iA^F~$7$^$9!#(B + +@item wl-envelope-from +@vindex wl-envelope-from +$B=i4|@_Dj$O(B nil$B!#(B +$B@_Dj$5$l$?CM$r(B envelope from (MAIL FROM) $B$K;HMQ$7$^$9!#(B +nil $B$J$i(B @code{wl-from} $B$N%"%I%l%9ItJ,$r;HMQ$7$^$9!#(B + +@item wl-user-mail-address-list +@vindex wl-user-mail-address-list +$B=i4|@_Dj$O(B nil$B!#(B +$B%f!<%6$N%"%I%l%9%j%9%H$G$9!#(B +$B%"%I%l%9$rJ#?t;}$C$F$$$k>l9g$O@_Dj$7$F$/$@$5$$!#(B + +@item wl-fcc +@vindex wl-fcc +$B=i4|@_Dj$O(B nil$B!#(B +Non-nil $B$J$i!"@_Dj$5$l$?CM$r%I%i%U%H$N(B FCC $B$H$7$F:G=i$+$iA^F~$7$^$9!#(B + +@item wl-bcc +@vindex wl-bcc +$B=i4|@_Dj$O(B nil$B!#(B +Non-nil $B$J$i!"@_Dj$5$l$?CM$r%I%i%U%H$N(B Bcc $B$H$7$F:G=i$+$iA^F~$7$^$9!#(B + +@item wl-reply-subject-prefix +@vindex wl-reply-subject-prefix +$B=i4|@_Dj$O(B "Re: "$B!#(B +$BJV?.;~$N%I%i%U%H$N(B Subject $B$G!"855-;v$N(B Subject $B$N@hF,$KIU$12C$($kJ8;zNs$G$9!#(B + +@item wl-draft-enable-queuing +@vindex wl-draft-enable-queuing +$B=i4|@_Dj$O(B t$B!#(B +$B%*%U%i%$%sAw?.$9$k$+$I$&$+$r<($9%U%i%0$G$9!#(BNon-nil $B$J$i%*%U%i%$%sAw?.$7$^$9!#(B + +@item wl-auto-flush-queue +@vindex wl-auto-flush-queue +$B=i4|@_Dj$O(B t$B!#(B +$B%*%s%i%$%s$K$J$C$?$H$-$K<+F0E*$K%-%e!<$rAw?.$9$k$+$I$&$+$r<($9%U%i%0$G$9!#(B +Non-nil $B$J$i<+F0E*$KAw?.$7$^$9(B ($B$$$A$*$&(B @code{y-or-n-p} $B$G3NG'$7$^$9(B)$B!#(B +$Bl9g!">o$K(B To, Cc $B$+$i<+J,$N(B +$B%a!<%k%"%I%l%9$r:o=|$7$^$9!#(B + +@item wl-smtp-posting-server +@vindex wl-smtp-posting-server +$B=i4|@_Dj$O(B nil$B!#(B +$B%a!<%kAw?.;~$N(B SMTP $B%5!<%PL>$G$9!#(B + +@item wl-smtp-posting-user +@vindex wl-smtp-posting-user +$B=i4|@_Dj$O(B nil$B!#(B +SMTP AUTH$B$K$h$kG'>Z$r9T$J$&$H$-$N%f!<%6L>$G$9!#(B +nil$B$J$i(B @code{smtp-authenticate-user} $B$r;H$$$^$9!#(B + +@item wl-smtp-authenticate-type +@vindex wl-smtp-authenticate-type +$B=i4|@_Dj$O(B nil$B!#(B +SMTP AUTH$B$K$h$kG'>Z$r9T$J$&$H$-$NG'>ZJ}<0$G$9!#(B +nil$B$N$^$^$J$i(B @code{smtp-authenticate-type}$B$rMxMQ$7$^$9!#(B +$B$=$l$G$b!"(Bnil$B$J$iG'>Z$r9T$$$^$;$s!#(B + +@item wl-smtp-connection-type +@vindex wl-smtp-connection-type +$B=i4|@_Dj$O(B nil$B!#(B +SMTP$B$N%3%M%/%7%g%s$r$I$N$h$&$KD%$k$+$r;XDj$7$^$9!#(B +nil$B$J$i(B @code{smtp-connection-type} $B$rMxMQ$7$^$9!#(B +'starttls$B$J$i(BSTARTTLS (RFC2595)$B$rMxMQ$7$F%3%M%/%7%g%s$,D%$i$l$^$9!#(B + +@item wl-nntp-posting-server +@vindex wl-nntp-posting-server +$B=i4|@_Dj$O(B nil$B!#(B +$B%K%e!<%9Ej9F;~$N(B NNTP $B%5!<%PL>$G$9!#(B +nil$B$J$i(B @code{elmo-default-nntp-server} $B$r;H$$$^$9!#(B + +@item wl-nntp-posting-user +@vindex wl-nntp-posting-user +$B=i4|@_Dj$O(B nil$B!#(B +$B%K%e!<%9Ej9F;~$K(BAUTHINFO$B$K$h$kG'>Z$r9T$J$&$H$-$N%f!<%6L>$G$9!#(B +nil$B$J$i(B @code{elmo-default-nntp-user} $B$r;H$$$^$9!#(B +$B$=$l$G$b!"(Bnil$B$J$i(BAUTHINFO$B$K$h$kG'>Z$r9T$J$$$^$;$s!#(B + +@item wl-nntp-posting-port +@vindex wl-nntp-posting-port +$B=i4|@_Dj$O(B nil$B!#(B +$B%K%e!<%9Ej9F;~$N(B NNTP $B%5!<%P$N%]!<%HHV9f!#(B +nil$B$J$i(B @code{elmo-default-nntp-server} $B$r;H$$$^$9!#(B + +@item wl-nntp-posting-ssl +@vindex wl-nntp-posting-ssl +$B=i4|@_Dj$O(B nil$B!#(B +nil$B$J$i(B @code{elmo-default-nntp-ssl} $B$rI>2A$7$^$9!#(B +Non-nil$B$J$i%K%e!<%9Ej9F;~$K(BSSL$B$rMxMQ$7$^$9!#(B +'starttls$B$J$i(BSTARTTLS (RFC2595)$B$rMxMQ$7$F%3%M%/%7%g%s$,D%$i$l$^$9!#(B + +@item wl-pop-before-smtp-user +@vindex wl-pop-before-smtp-user +$B=i4|@_Dj$O(B nil$B!#(B +POP-before-SMTP$B$G(BPOP$B$r9T$J$&$H$-$N%f!<%6L>$G$9!#(B +nil$B$N$^$^$J$i(B @code{elmo-default-pop3-user}$B$rMxMQ$7$^$9!#(B + +@item wl-pop-before-smtp-server +@vindex wl-pop-before-smtp-server +$B=i4|@_Dj$O(B nil$B!#(B +POP-before-SMTP$B$G(BPOP$B$r9T$J$&$H$-$N%5!<%PL>$G$9!#(B +nil$B$N$^$^$J$i(B @code{elmo-default-pop3-server}$B$rMxMQ$7$^$9!#(B + +@item wl-pop-before-smtp-authenticate-type +@vindex wl-pop-before-smtp-authenticate-type +$B=i4|@_Dj$O(B nil$B!#(B +POP-before-SMTP$B$G(BPOP$B$r9T$J$&$H$-$NG'>ZJ}<0$G$9!#(B +nil$B$N$^$^$J$i(B @code{elmo-default-pop3-authenticate}$B$rMxMQ$7$^$9!#(B + +@item wl-pop-before-smtp-port +@vindex wl-pop-before-smtp-port +$B=i4|@_Dj$O(B nil$B!#(B +POP-before-SMTP$B$G(BPOP$B$r9T$J$&$H$-$N%]!<%HHV9f$G$9!#(B +nil$B$N$^$^$J$i(B @code{elmo-default-pop3-port}$B$rMxMQ$7$^$9!#(B + +@item wl-pop-before-smtp-ssl +@vindex wl-pop-before-smtp-ssl +$B=i4|@_Dj$O(B nil$B!#(B +POP-before-SMTP$B$G(BSSL$B$rMxMQ$9$k$+$I$&$+$r<($9%U%i%0$G$9!#(B +nil$B$N$^$^$J$i(B @code{elmo-default-pop3-ssl}$B$rMxMQ$7$^$9!#(B +'starttls$B$J$i(BSTARTTLS (RFC2595)$B$rMxMQ$7$F%3%M%/%7%g%s$,D%$i$l$^$9!#(B + +@item wl-draft-queue-save-variables +@vindex wl-draft-queue-save-variables +$B%*%U%i%$%sAw?.;~$K%-%e!<$K3JG<$5$l$?%a%C%;!<%8$K$D$$$FJ]B8$7$F$*$/JQ?t$r(B +$B%j%9%H$G;XDj$7$^$9!#(B + +@item wl-draft-sendlog +@vindex wl-draft-sendlog +$B=i4|@_Dj$O(B t$B!#(B +t $B$J$i(B @file{~/.elmo/sendlog} $B$KAw?.%m%0$r=PNO$7$^$9!#(B +$B%m%0$r=PNO$9$k%?%$%_%s%0$O(B smtp, qmail $B$K$h$kAw?.!"(Bfcc, queuing $B$K$h$k%U%)(B +$B%k%@$X$N3JGl9g$b(B)$B!#$?$@$7!"(Bim-wl.el $B$K$h$kAw?.$O(B sendlog $B$K(B +$B$O=PNO$;$:$K(B imput $B$N%m%05!G=$K$*$^$+$;$7$^$9!#(B + +@item wl-draft-sendlog-max-size +@vindex wl-draft-sendlog-max-size +$B=i4|@_Dj$O(B 20000 ($B%P%$%H(B)$B!#(B +@code{wl-draft-sendlog} $B$,(B t $B$N>l9g!"(B +$BJ]B8$7$?%m%0$NBg$-$5$,;XDj$7$?Bg$-$50J>e$K$J$l$P!"%m%0$r%m!<%F!<%7%g%s$7$^$9!#(B +@end table + + +@c +@c Dsiconnected Operations +@c +@node Disconnected Operations, Expire and Archive, Draft, Top +@chapter $B%*%U%i%$%s=hM}(B +@cindex Disconnected Operations +@cindex Offline +@cindex Unplugged + +@section $B%*%U%i%$%s%b!<%I(B + +Wanderlust $B$K$O%*%s%i%$%s%b!<%I$H%*%U%i%$%s%b!<%I$,$"$j$^$9!#(B +$B%*%U%i%$%s%b!<%I$G$O!"%M%C%H%o!<%/7PM3$G$J$1$l$PFI$a$J$$%a%C%;!<%8$O(B +$B%"%/%;%9$G$-$^$;$s(B($B%-%c%C%7%e$5$l$F$$$l$P%"%/%;%9$G$-$^$9(B)$B!#(B + +$B%b!<%I%i%$%s$K(B @samp{[ON]} $B$H=P$F$$$k$H$-$O(B +$B%*%s%i%$%s%b!<%I$K$"$k$3$H$r<($7$F$$$^$9!#(B +$B%b!<%I%i%$%s$K(B @samp{[--]} $B$H=P$F$$$k$H$-$O%*%U%i%$%s%b!<%I$G$9!#(B +$B%U%)%k%@%b!<%I!"%5%^%j%b!<%I$G(B @kbd{M-t} $B$r2!$9$H%*%U%i%$%s(B/$B%*%s%i%$%s$N@Z$jBX$($,$G$-$^$9!#(B + +@file{~/.wl} $B$J$I$GJQ?t(B @code{wl-plugged} $B$r(B nil $B$K@_Dj$7$F$+$i5/F0$9$k$H!"(B +$B5/F0;~$+$i%*%U%i%$%s%b!<%I$H$J$j$^$9!#(B + +$B0J2<$NA`:n$O(B($BBP>]$H$J$k%a%C%;!<%8$,%-%c%C%7%e$5$l$F$$$l$P(B) +$B%*%U%i%$%s%b!<%I$G$be$KH?1G$5$l$^$9!#(B + +@section $B%a%C%;!<%8$NAw?.(B + +$B%*%U%i%$%s>uBV$G%a!<%k(B/$B%K%e!<%95-;v$rAw?.$G$-$^$9!#(B +(im-wl.el $B$r$*;H$$$N>l9g$O!"4X78$"$j$^$;$s!#(B) +$B%*%U%i%$%s$N$H$-$KAw?.$5$l$?%a%C%;!<%8$O(B +$B%-%e!<%U%)%k%@(B @samp{+queue} $B$KN/$j$^$9!#(B +$BN/$C$?%a%C%;!<%8$O!"%*%s%i%$%s$K$J$C$?$H$-$K0l5$$KAw?.$5$l$^$9!#(B + +$B%*%U%i%$%s$N$&$A$K(B @samp{+queue} $B$rK,$l$F!"(B +$B%-%e!<$K$"$k%a%C%;!<%8$NFbMF$r3NG'$G$-$^$9!#(B +$B%a%C%;!<%8$r:o=|$9$k$3$H$b2DG=$G$9!#(B +($B:o=|$5$l$?%a%C%;!<%8$O%*%s%i%$%s$K$J$C$F$bAw?.$5$l$^$;$s!#(B) + +@c $B%-%e!<$K$"$k%a%C%;!<%8$r:FJT=8$9$k$3$H$b2DG=$G$9$,!"(B +@c $BLdBj$,5/$3$k2DG=@-$,$"$j$^$9$N$G$*4+$a$G$-$^$;$s!#(B + +@section $B%j%U%!%$%k(B/$B%3%T!<(B(IMAP4) + +$B%*%U%i%$%s>uBV$N$"$$$@$Ke$N%a%C(B +$B%;!<%8$H(B Message-ID $B$,0lCW$7$?>l9g$N$_:o=|$7$^$9!#$^$?!"%-%e!<=hM};~$K%j(B +$B%U%!%$%k(B/$B%3%T!<@h$K;XDj$5$l$?%U%)%k%@$K%a%C%;!<%8$rDI2C$9$k$N$K<:GT$7$?(B +$B$H$-$O(B @samp{+lost+found} $B%U%)%k%@$KDI2C$5$l$^$9!#(B + +@section $B%U%)%k%@@8@.(B(IMAP4) + +IMAP $B%U%)%k%@$N@8@.$b%*%U%i%$%s>uBV$Gl9g!"%*%U%i%$%sCf$K@8@.$5$l$?%U%)%k%@$X%j%U%!%$%k$5$l(B +$B$?%a%C%;!<%8$O(B "+lost+found" $B%U%)%k%@$KDI2C$5$l$^$9!#(B + +@section $B%^!<%/IU$1(B(IMAP4) + +IMAP $B%U%)%k%@$K$"$k%a%C%;!<%8$KBP$9$kL$FI(B/$B4{FI$N>pJs!"$*$h$S!"(B +$B=EMW%^!<%/(B @samp{$} $B$,$D$$$F$$$k$+$I$&$+!"$b%*%U%i%$%sCf$NJQ99$,%*%s%i%$%s$K(B +$B$J$C$?$H$-$K%5!<%P$KH?1G$5$l$^$9!#(B + +@section $B%W%j%U%'%C%A(B(IMAP4, NNTP) + +IMAP $B$b$7$/$O(B NNTP $B%U%)%k%@$K$"$k%a%C%;!<%8$KBP$7$F!"%W%j%U%'%C%A$NM=Ls(B +$B$r$7$^$9!#%W%j%U%'%C%A$NM=Ls$,$5$l$?%a%C%;!<%8$O(B @samp{!} $B$,IU$-$^$9$,!"(B +$B$3$N;~E@$G$O%-%c%C%7%e$5$l$F$*$i$:!"%*%s%i%$%s$K$J$C$?$H$-$K%5!<%P$+$i(B +$B%W%j%U%'%C%A$5$l$^$9!#(B + +$BJQ?t(B @code{elmo-enable-disconnected-operation} $B$,(B nil $B$J$i!"(B +$B$3$l$i$N(B IMAP4 $B$H(B NNTP$B$K4X$9$k%*%U%i%$%s=hM}$OC$9$H(B Wanderlust $B$,8mF0:n$9$k$*$=$l$,$"$j$^$9!#(B +$B%-%c%C%7%e$r>C$7$?$$$H$-$O(B +@kbd{M-x elmo-cache-expire-by-size} +$B$r]$H$J$k%a%C%;!<%8$N(B +$B%-%c%C%7%e$O:o=|$7$^$;$s!#(B + +@section $B%5!<%P!&%]!<%HJL$N%*%s%i%$%s!"%*%U%i%$%s$N@Z$jBX$((B + +$B>e5-$N(B @kbd{M-t} $B$K$h$kA`:n$G$O%M%C%H%o!<%/$N>uBV$r0l3g$7$F@Z$jBX$($^$9$,!"(B +$B%5!<%P!&%]!<%HJL$K%*%s%i%$%s$H%*%U%i%$%s$r@Z$jBX$($k$3$H$b$G$-$^$9!#(B + +$B%U%)%k%@%b!<%I!"%5%^%j%b!<%I$G(B @kbd{C-t} $B$r2!$9$H0J2<$N$h$&$J(B +wl-plugged-mode $B$KF~$j!"$3$N%b!<%I$G3F%]!<%H$N(B plug $B>uBV$rJQ99$7$^$9!#(B + +@example +Queuing:[ON] AutoFlushQueue:[--] DisconnectedOperation:[ON] +[ON](wl-plugged) + [--]hosta + [--]smtp +queue: 2 msgs (1,2) @dots{}@r{sending queue} + [--]nntp(119) +queue: 1 msg (3) @dots{}@r{sending queue} + [ON]hostb + [--]imap4/cram-md5(143) %#mh/wl(prefetch-msgs:3,mark-as-important:1) + %inbox(delete-msgids:1) @dots{}@r{dop queue} + [ON]nntp(119) + [ON]smtp +@end example + +1$B9TL\$O%*%U%i%$%sA`:n$K4X78$9$kuBV$rI=<($7!"(B +$B$=$l$>$l$N%i%Y%kMs$G(B @kbd{@key{SPC}} $B$d(B @kbd{@key{RET}} $B$r2!$9$3$H$G(B +$BJQ?t$NCM$r4JC1$KJQ99$G$-$k$h$&$K$J$C$F$$$^$9!#(B + +@example +"Queuing" wl-draft-enable-queuing +"AutoFlushQueue" wl-auto-flush-queue +"DisconnectedOperation" elmo-enable-disconnected-operation +@end example + +$B$3$3$G!"(B@samp{[ON]} $B$O$=$NJQ?t$NCM$,(B t $B$G$"$k$3$H$r!"(B +@samp{[--]} $B$O(B nil $B$G$"$k$3$H$r<($7$F$$$^$9!#(B + +$B$^$?!"(B2$B9TL\0J9_$G$O%5!<%P$H%]!<%H$N%*%s%i%$%s$H%*%U%i%$%s>uBV$rI=<($7!"(B +@samp{[ON]} $B$O$=$N%5!<%P$d%]!<%H$,%*%s%i%$%s$G$"$k$3$H$r!"(B +@samp{[--]} $B$O%*%U%i%$%s$G$"$k$3$H$r<($7$F$$$^$9(B +(XEmacs $B$G$O%"%$%3%s$GI=<($5$l$^$9(B)$B!#(B +$B$=$7$F$=$l$>$l$N9T$G(B @kbd{@key{SPC}} $B$d(B @kbd{@key{RET}} $B$r2!$9$3$H$G(B +$B>uBV$r@Z$jBX$($k$3$H$,$G$-$^$9!#(B + +sending queue $B$O%*%U%i%$%sAw?.;~$K(B @samp{+queue} $B%U%)%k%@$K3JG<$5$l$F$$$k(B +$BAw?.BT$A$N%a%C%;!<%8$r;X$7!"(B +dop queue $B$O%*%U%i%$%s$G9T$C$?%j%U%!%$%k(B/$B%3%T!uBV$,2hLL$KI=<($5$l$^$9!#(B +$B>e5-Nc$G$O!"(Bsending queue $B$K$O(B hosta $B$N(B smtp $B8~$1$K(B 2 $B$D(B +(queue $B%U%)%k%@$N(B1$BHV$H(B2$BHV(B)$B$H!"(B +hosta $B$N(B nntp $B8~$1$K(B 1 $B$D(B(3$BHV(B)$B$N%a%C%;!<%8$,$"$j!"(B +dop queue $B$K$O(B @samp{%inbox} $B$NA`:n$,(B1$B$D$H!"(B +@samp{%#mh/wl} $B$NA`:n$,(B2$B$D$"$k$3$H$r<($7$F$$$^$9!#(B + +$B$3$N%b!<%I$G(B2$B9TL\$K$"$k(B (wl-plugged) $B$rJQ99$9$k$H!"(Bwl-plugged $BJQ?t$,JQ99$5(B +$B$l!"$3$l$K$h$j%b!<%I%i%$%s$N(B indicator $B$HA4BN$N(B $B%]!<%H(B plug $B>uBV$,(B +ON/OFF $B$5$l$^$9!#(B +$B$^$?!"3F%5!<%P$d%]!<%H$N(B plug $B>uBV$rJQ99$9$k$H!"(B +@code{elmo-plugged-condition} ($B8e=R(B)$B$N@_Dj$H3F%]!<%H$N(B plug $B>uBV$K$h$j(B 2$B9TL\$N(B +wl-plugged $B$,JQ2=$7$^$9!#(B + +@section $B5/F0;~$N%*%U%i%$%s>uBV@_Dj(B + +$BA0=R$NDL$j!"(B@file{~/.wl} $B$J$I$GJQ?t(B @code{wl-plugged} $B$r(B nil $B$K@_Dj$7$F$+$i5/F0$9(B +$B$k$H!"5/F0;~$+$i%*%U%i%$%s%b!<%I$K$9$k$3$H$,$G$-$^$9$,!"$5$i$K:Y$+$/%5!<%P(B +$B$d%]!<%HKh$K%*%U%i%$%s>uBV$r@_Dj$9$k$3$H$b$G$-$^$9!#(B +$BJ;$;$FJQ?t(B @code{wl-reset-plugged-alist} $B$b;2>H2<$5$$!#(B + +$BDL>o!"5/F0;~$K$O(B @file{~/.folder} $B$H(B @code{wl-smtp-posting-server}, +@code{wl-nntp-posting-server} $B$J$I$+$i3F%]!<%H$N(B plug $B>uBV$,<+F0E*$KDI2C$5$l$^$9(B +$B$,!"$3$l$i$N%]!<%H$N(Bplug$B>uBV$rJQ99$7$?$j!">e5-0J30$N%]!<%H$rDI2C$7$?$j$9$k(B +$B>l9g$K$O(B @code{wl-make-plugged-hook} $B$KJQ99$9$k4X?t$r5-=R$7$^$9!#(B + +@lisp +(add-hook 'wl-make-plugged-hook + '(lambda () + (elmo-set-plugged plugged$BCM(B(t/nil) server port) + ;; @r{server,port$B$N(Bplug$B>uBV$r?75,DI2C$b$7$/$OJQ99$9$k(B} + (elmo-set-plugged plugged$BCM(B(t/nil) server) + ;; @r{port $B$r>JN,$9$k$H(Bserver$B$NA4(Bport$B$,JQ99$5$l$k(B} + ;; @r{(port $B$r>JN,$7$F?75,$NDI2C$O$G$-$J$$(B)} + )) +@end lisp + +@section $B%+%9%?%^%$%:JQ?t(B + +@table @code +@item wl-plugged +@vindex wl-plugged +$B$3$NCM$r(B nil $B$K@_Dj$7$F(B Wanderlust $B$r5/F0$9$k$H!"(B +$B5/F0;~$+$i%*%U%i%$%s%b!<%I$H$J$j$^$9!#(B + +@item wl-queue-folder +@vindex wl-queue-folder +$B=i4|@_Dj$O(B "+queue"$B!#Aw?.%-%e!<$N%a%C%;!<%8$,N/$k%U%)%k%@!#(B + +@item wl-auto-flush-queue +@vindex wl-auto-flush-queue +$B=i4|@_Dj$O(B t$B!#%*%s%i%$%s$K$J$C$?$H$-$K<+F0E*$K%-%e!<$rAw?.$9$k$+$I$&$+!#(B +Non-nil $B$J$i<+F0E*$KAw?.$7$^$9(B ($B$$$A$*$&(B @code{y-or-n-p} $B$G3NG'$7$^$9(B)$B!#(B +$Br7o(B +$B$r3F%]!<%H$N(Bplug$B>uBV$K$h$j;XDj$7$^$9!#(B + +@example +'one : 1$B$D0J>e$N%]!<%H$,(B plugged $B$J$i(B plugged $B$G$"$k(B +'all : $BA4$F$N%]!<%H$,(B plugged $B$J$i(B plugged $B$G$"$k(B +'independent : $B%]!<%H$N(B plug $B>uBV$K4X78$J$/(B wl-plugged (elmo-plugged) + $B$r;2>H$9$k(B +function : $B4X?t$NLa$jCM$K$h$jJQ2=$9$k(B + $BI8=`$GMQ0U$5$l$F$$$k4X?t(B + 'elmo-plug-on-by-servrs + : $BJQ?t(B elmo-plug-on-servers $B$G;XDj$7$?%5!<%P$N(B plug + $B>uBV$K$h$jJQ2=$9$k(B + 'elmo-plug-on-by-exclude-servers + : $BJQ?t(B elmo-plug-on-exclude-servers $B$G;XDj$7$?0J30$N(B + $B%5!<%P$N(B plug $B>uBV$K$h$jJQ2=$9$k(B + elmo-plug-on-exclude-servers $B$N%G%U%)%k%HCM$O(B + '("localhost" + (system-name) + (system-name)$B$+$i%I%a%$%sIt$r=|$$$?$b$N(B) + $B$G$"$k(B +@end example + +@example +$BNc(B1: + (setq elmo-plugged-condition 'all) +$BNc(B2: + (setq elmo-plug-on-servers '("smtpserver" "newsserver")) + (setq elmo-plugged-condition 'elmo-plug-on-by-servers) +$BNc(B3: + (setq elmo-plug-on-exclude-servers '("localhost" "myname")) + (setq elmo-plugged-condition 'elmo-plug-on-by-exclude-servers) +@end example + +@item wl-reset-plugged-alist +@vindex wl-reset-plugged-alist +$B=i4|@_Dj$O(B t$B!#(BNon-nil $B$J$i(B Wanderlust $B$N5/F0;~$K%5!<%P!&%]!<%HJL$N%W%i%0(B +$B>uBV$r(B @code{wl-plugged} $B$NCM$K$h$j=i4|2=$7$^$9!#(B + +nil $B$J$i!"(BEmacs $B$,F0:n$7$F$$$k4V!"A02s=*N;$7$?;~E@$N%W%i%0>uBV$rJ];}$7$^$9!#(B +$B8@$$49$($l$P(B nil $B$G$"$C$F$b(B Emacs $B$r:F5/F0$9$k$H=i4|2=$5$l$^$9!#(B +@end table + + +@c +@c Expire and Archive +@c +@node Expire and Archive, Scoring, Disconnected Operations, Top +@chapter $B%a%C%;!<%8$N<+F0:o=|$H%"!<%+%$%V(B +@cindex Expire and Archive + +@menu +* Expire:: $B4|8B%a%C%;!<%8$N<+F0:o=|!"%"!<%+%$%V(B +* Archive:: $BA4%a%C%;!<%8$N%"!<%+%$%V(B +@end menu + + +@node Expire, Archive, Expire and Archive, Expire and Archive +@section $B%a%C%;!<%8$N<+F0:o=|(B +@cindex Expire Message + +Expire $B$H$O!";XDj$7$?4|4V$r2a$.$?8E$$%a%C%;!<%8$r:o=|$9$k5!G=$G$9!#(B + +$B$7$+$7!"(B@code{wl-expire} $B$G$O%a%C%;!<%8$rC1=c$K>C$9$@$1$G$O$J$/!";XDj$7$?%"!<%+(B +$B%$%V%U%)%k%@$K0\F0$9$k$3$H$b=PMh$^$9!#(B + +@section $B;H$$J}(B + +@code{wl-expire-alist}$B$r@_Dj$7$F!"%U%)%k%@%b!<%I$G(B @kbd{e}$B!"$b$7$/$O%5%^(B +$B%j%b!<%I$G(B @kbd{M-e} $B$r2!$7$^$9!#(B + +@subsection @code{wl-expire-alist}$B$N@_Dj(B + +$BJN,$9$k$H(B n1 + 1 $B$K$J$j$^$9!#(B +$BNc$($PCM$,(B 510 $B$J$i%a%C%;!<%8$,(B 510 $B0J>e$N$H$-$K(B expire $B$rl9g!"IQHK$K%a!<%k$,Mh$k%U%)%k%@$G(B +$B$OKh2s(B expire $B$rl9g!"(B +$B$3$N$h$&$J%a%C%;!<%8$b4^$a$F(B 500 $B8D$K$J$k$h$&$K(B expire $B$5$l$^$9!#(B +nil $B$N>l9g$O>e5-%a%C%;!<%80J30$G(B 500 $B$K$J$k$h$&$K(B expire $B$7$^$9!#(B + +@item (date d1) +$B%a%C%;!<%8$NF|IU$K$h$j:o=|$r9T$$$^$9!#(B + +d1 $B$O8=:_$h$j2?F|A0$N%a%C%;!<%8$r:o=|$9$k$I$&$+$G$"$j!"(B +$BNc$($PCM$,(B 7 $B$J$i(B 7$BF|$h$jA0$N%a%C%;!<%8$r:o=|$7$^$9!#(B +$B$J$*!"$3$NF|IU$H$O%a%C%;!<%8$N(BDate$B%U%#!<%k%I$NF|IU$G$"$j!"(B +$B%a%C%;!<%8$,%U%)%k%@$KF~$C$?F|IU$G$O$J$$$3$H$KCm0U$7$F$/$@$5$$!#(B + +$B$b$7!"%a%C%;!<%8$K(B Date$B%U%#!<%k%I$,$J$+$C$?$j!"(BDate$B%U%#!<%k%I$,IT@5$JCM(B +$B$J$i!"(Bexpire $B$5$l$^$;$s$N$G!":o=|$9$k%a%C%;!<%8$N%j%9%H!"$=$7(B +$B$F%5%^%j$N(Bmsgdb$B>pJs$,EO$5$l$^$9!#(B +$B$^$?4X?tL>$N8e$K4X?tFH<+$N0z?t$b;XDj$G$-$^$9!#(B +$B$J$*!"$3$N4X?t$K$O(B@code{wl-summary-expire-reserve-marks}$B$G;XDj$7$?%a%C%;!<(B +$B%8$b4^$s$@%j%9%H$,EO$5$l$^$9$N$G!"FH<+$K4X?t$r:n$k>l9g$OCm0U$7$F$/$@$5$$!#(B + +$B$3$3$G;XDj$G$-$k4X?t$K$O!"I8=`$G]$N%a%C%;!<%8HV9f$KBP$9$k%"!<%+%$%V%U%)%k%@$K(Brefile$B$7$^$9!#(B +$BNc$($P!"(B102 $BHV$G$"$k$J$i(B @file{wl-00100.zip}$B!"(B +390 $BHV$G$"$k$J$i(B @file{wl-00300.zip}$B!"$J$I$N$h$&$K$G$9!#(B +$B$J$*!"(B@code{wl-expire-archive-files} $B$r(B 200 $B$K$9$k$H!"(B +@file{wl-00000.zip}, @file{wl-00200.zip}, @file{wl-00400.zip}, +@dots{} $B$K(B refile $B$7$F$$$-$^$9!#(B + +refile $B@h$N%"!<%+%$%V%U%)%k%@$O:o=|85$N%U%)%k%@L>$K$h$jl9g$H$7$F$"$D$+$o$l$^$9(B) + +@table @code +@item $B%U%)%k%@%?%$%W$,(Blocaldir + +@code{$ArchiveDir/foldername-xxxxx.zip} +$BNc$($P(B @samp{+ml/wl} $B$O(B @samp{$ml/wl;zip} +(@file{~/Mail/ml/wl-00100.zip})$B$H$J$j$^$9!#(B + +@item $B%U%)%k%@%?%$%W$,(Blocaldir$B0J30(B +@code{$ArchiveDir/foldertype/foldername-xxxxx.zip} + +$BNc$($P!"(B@samp{%#mh/ml/wl} $B$O(B @samp{$imap4/#mh/ml/wl;zip} + +(@file{~/Mail/imap4/#mh/ml/wl-00100.zip})$B$H$J$j$^$9!#(B +@end table + +$B$9$J$o$A!"(Blocaldir $B$N>l9g$O$K4^$^$l$^$;$s$,!"$=$l0J30$O$K4^$^$l$k$N$G$9!#(B +$B$^$?!"(B@code{wl-expire-archive-folder-prefix} $B$K$h$j!"(B +$B%"!<%+%$%V%U%)%k%@$KIU$1$k(B prefix $B$,@)8f$G$-$^$9!#(B +@code{wl-expire-archive-folder-prefix}$B$N@bL@$rNI$/8+$F$*$$$F$/$@$5$$!#(B + +@item wl-expire-archive-number2 +$B;XDj$7$?8D?t$4$H$K%"!<%+%$%V%U%)%k%@$K(Brefile$B$7$^$9!#(B + +@samp{wl-expire-archive-number1} +$B$H0[$J$kE@$O%a%C%;!<%8HV9f$K4X78$J$/%"!<%+%$%V%U%)%k%@$,;XDj?t$KC#$9$k$^$G$=$N%U%)%k%@$K(B refile $B$9$k!"$H$$$&E@$G$9!#(B +$B$J$*!"(Brefile $B@h$N%"!<%+%$%V%U%)%k%@$O(B @code{wl-expire-archive-number1} +$B$HF1$8$h$&$K7hDj$5$l$^$9!#(B + +@item wl-expire-archive-date +$B%a%C%;!<%8$NF|IU(B($BG/7n(B)$B$4$H$K%"!<%+%$%V%U%)%k%@$K(Brefile$B$7$^$9!#(B + +$BNc$($P!"(B1998$BG/(B12$B7n$N%a%C%;!<%8$O(B @code{$folder-199812;zip} +$B$K(Brefile$B$5$l$^$9!#(B +$B$J$*!"F|IU$NItJ,0J30$N%"!<%+%$%V%U%)%k%@L>$O(B @code{wl-expire-archive-number1} +$B$HF1$8$h$&$K7hDj$5$l$^$9!#(B +@end table + +$B$^$?!">e5-$N(B3$B$D$NI8=`4X?t$G$O(B @code{wl-expire-alist} $B$G$NBh(B1$B0z?t$K(B non-nil $B$r;XDj$9$k$H!"(B +$B%U%)%k%@$N%a%C%;!<%8HV9f$r$=$N$^$^J]B8$9$k$3$H$,$G$-$^$9!#(B +$BNc$($P!"$N8e$KB3$1$F;XDj$7$^$9!#(B + +@example +("^\\+ml/wl$" (number 300 310) wl-expire-archive-number1 t) +@end example + +$B0z?t$r;XDj$7$J$$>l9g$O!"3F%"!<%+%$%V%U%)%k%@$4$H$K(B 1 $B$+$i=g$KHV9f$,M?$((B +$B$i$l$FJ]B8$5$l$^$9!#(B +@end table + +@subsection important$B$dL$FI%a%C%;!<%8$N07$$(B + +$B:o=|@h$K(B 'remove $B$d(B 'trash$B!"%U%)%k%@L>!"I8=`4X?t$N$$$:$l$r;XDj$7$?>l9g$G(B +$B$b!"(B@code{wl-summary-expire-reserve-marks}$B$G;XDj$7$?%^!<%/$N%a%C%;!<%8(B +($B0J2l9g$O3NG'$;$:$K<+F0$C$F!"(B@samp{Desktop} $B%0%k!<%W$r;XDj$9$l(B +$B$P(B@code{wl-expire-alist}$B$K%^%C%A$9$kA4$F$N%U%)%k%@$G(B expire $B$,e5-$NI8=`4X?t(B @code{wl-expire-archive-number1} $B$J$I$G:n@.$7$?%"!<%+%$%V(B +$B%U%)%k%@$r07$&>l9g$O!"JQ?t(B @code{elmo-archive-treat-file} $B$r(B non-nil $B$K@_(B +$BDj$7$F$*$/I,MW$,$"$j$^$9!#(B + +@subsection $BF0:n3NG'(B + +'remove $B$r;XDj$9$k>l9g$O!"$^$:(B 'trash $B$K$7$F4|BTDL$j$K%a!<%k$,(B +@code{wl-trash-folder} $B$K0\F0$5$l$k$3$H$r3NG'$7$F$+$i(B 'remove $B$KJQ$($k$H(B +$B$h$$$G$7$g$&!#$$$-$J$j(B 'remove $B$r;XDj$9$k$N$O4m81$G$9!#(B + +$B$^$?!"(B@code{wl-expire-archive-number1}$B$J$I$N4X?t$rMxMQ$9$k>l9g!"(B +$B$^$:$O;HMQ$9$k%"!<%+%$%P%?%$%W(B('zip $B$d(B 'lha)$B$J$I$N%U%)%k%@$r;n$7$K$D$/$C(B +$B$F!"@5$7$/DI2C$G$-$k$+$I$&$+$r3NG'$7$F$/$@$5$$!#(B +$B$?$H$(!"(B@code{wl-expire-alist} $B$d(B @code{elmo-archive} $B$N@_Dj$,@5$7$/$F$b!"(B +$B%"!<%+%$%V%W%m%0%i%`$,@5$7$/F0$+$J$1$l$P$I$3$K$bJ]B8$5$l$:$K(B +$B%a%C%;!<%8$,>C$($F$7$^$&$+$bCN$l$^$;$s!#(B + +$B%"!<%+%$%V%U%)%k%@$NF0:n$,3NG'$G$-!" $ml/wl-00600;tgz;wl (600 601 602) +@end example + +$B:G=i$N9`L\$OF0:n$r<($9$b$N$G!"(Bdelete, copy, move $B$,$"$j$^$9!#$G!"(Bcopy $B$H(B move $B$N>l9g$O(B@samp{->}$B$KB3$1$F%3%T!<$b$7(B +$B$/$O0\F0@h$N%U%)%k%@L>$,5-O?$5$l$^$9!#:G8e$N9`L\$O!"l9g!"0\F08e$G$O$J$/0\F0A0$N%a%C(B +$B%;!<%8HV9f$G$9(B)$B!#(B + +@subsection reserve$B%a%C%;!<%8$N(Brefile + +$BI8=`$GMQ0U$5$l$F$$$k(B3$B$D$N4X?t$G$O!"(Breserve$B%a%C%;!<%8$O%"!<%+%$%V%U%)%k%@(B +$B$K%3%T!<$7$^$9$,!"85$N%U%)%k%@$+$i$O:o=|$7$J$$$h$&$K$J$C$F$$$^$9!#$J$*!"(B +important$B%^!<%/$J$I$O>o$K;D$k$?$a!"2?EY$b%3%T!<$5$l$k$3$H$,$J$$$h$&$K(B +@file{~/.elmo/expired-alist} $B$K5-O?$9$k$h$&$K$7$F$$$^$9!#(B +$B$?$@$7!"(Breserve$B%a%C%;!<%8$,(Brefile$BBP>]$K$J$C$?$H$-$N$_$G$9!#(B +$B$^$?!"(B@code{wl-summary-archive} $B$J$I$G%3%T!<$5$l$k>l9g$O5-O?$5$l$^$;$s!#(B + +$B%m%05!G=$rM-8z$K$7$F$$$?>l9g$O!"(Brefile $B;~$K$ODL>o(B move $B$,5-(B +$BO?$5$l$^$9$,!"(Breserve$B%a%C%;!<%8$,4^$^$l$F$$$k$H!"(Bcopy $B$H(B +delete $B$KJ,$1$F5-O?$5$l$^$9!#$3$l$O(B reserve$B%a%C%;!<%8$r4^$a$?%a%C(B +$B%;!<%8$r%3%T!<$7$?8e!"(Breserve$B%a%C%;!<%8$r=|$$$?%a%C%;!<%8$r:o=|$9$k!"(B +$B$H$$$&=hM}$r9T$C$F$$$k$?$a$G$9!#(B + +@section $B%+%9%?%^%$%:JQ?t(B + +@table @code +@item wl-expire-alist +@vindex wl-expire-alist +$B=i4|@_Dj$O(B nil$B!#(B +expire $B$r9T$&%U%)%k%@$H(B expire $BJ}K!$N;XDj$r9T$$$^$9!#>\$7$/$O>e5-$N(B +@code{wl-expire-alist}$B$N@_Dj$r$4Mw2<$5$$!#(B + +@item wl-summary-expire-reserve-marks +@vindex wl-summary-expire-reserve-marks +$B=i4|@_Dj$O0J2<$N%j%9%H!#(B + +@lisp +(list wl-summary-important-mark + wl-summary-new-mark + wl-summary-unread-mark + wl-summary-unread-uncached-mark + wl-summary-unread-cached-mark) +@end lisp + +expire $B$r9T$C$F$b!"%U%)%k%@$K$O;D$7$F$*$/%a%C%;!<%8$N%^!<%/$r;XDj$7$^$9!#(B +$B%^!<%/$K$O(B $B1JB3E*%^!<%/(B $B$N$_;XDj$G$-$^$9!#(B +$B0l;~E*%^!<%/$O;XDj$G$-$^$;$s!#(B + +$B%G%U%)%k%H$N$h$&$K%j%9%H$G;XDj$9$k$H$=$N%^!<%/$N%a%C%;!<%8$r;D$9$3$H$,$G(B +$B$-$kB>!"0J2<$N;XDj$b$G$-$^$9!#(B + +@table @code +@item 'all +$B1JB3%^!<%/$NIU$$$?$9$Y$F$N%a%C%;!<%8$r;D$7$^$9!#(B +$B$D$^$j!"%G%U%)%k%H$G@_Dj$5$l$F$$$k%^!<%/0J30$K(B +@code{wl-summary-read-uncached-mark} $B$,4^$^$l$^$9!#(B + +@item 'none +$B$I$s$J%^!<%/$NIU$$$?%a%C%;!<%8$G$"$C$F$b!"DL>o$N4{FI%a%C%;!<%8$HF1$807$$(B +$B$r$7$^$9!#$9$J$o$A!"(Bimportant$B%a%C%;!<%8$G$"$C$F$b:o=|$5$l$^$9!#(B +@end table + +@item wl-expire-archive-files +@vindex wl-expire-archive-files +$B=i4|@_Dj$O(B 100$B!#(B +$B$R$H$D$N%"!<%+%$%V%U%)%k%@$KJ];}$9$k%a%C%;!<%8?t$r;XDj$7$^$9!#(B + +@item wl-expire-number-with-reserve-marks +@vindex wl-expire-number-with-reserve-marks +$B=i4|@_Dj$O(B nil$B!#(B +Non-nil $B$K$9$k$H!"(B +$B:o=|%a%C%;!<%8$N;XDj$G(B number $B$r;XDj$7$?$H$-!"(B +$B;D$7$F$*$/%a%C%;!<%8?t$K(B @code{wl-summary-expire-reserve-marks} $B$G@_Dj$5(B +$B$l$?%a%C%;!<%8$r4^$a$^$9!#(B + +@item wl-expire-archive-get-folder-func +@vindex wl-expire-archive-get-folder-func +$B=i4|@_Dj$O(B 'wl-expire-archive-get-folder$B!#(B + +$B:o=|@h$NI8=`4X?t$G%"!<%+%$%V%U%)%k%@L>$r$NJQ99$G$-$^$9$,!"$b$C$HJ#;($J;XDj$r(B +$B$7$?$$>l9g$O?7$?$K4X?t$r:n$C$F$3$NJQ?t$K@_Dj$7$^$9!#(B + +$B4X?t(B@code{wl-expire-archive-get-folder}$B$N%+%9%?%^%$%:JQ?t$K$Ol9g$O(B @code{wl-expire-archive-folder-num-regexp} +$B$b9g$o$;$k$h$&$K$7$F$/$@$5$$!#(B + +@item wl-expire-archive-date-folder-name-fmt +@vindex wl-expire-archive-date-folder-name-fmt +$B=i4|@_Dj$O(B "%s-%%04d%%02d;%s"$B!#(B +@code{wl-expire-archive-date} +$B$G;HMQ$5$l$k%"!<%+%$%V$N%U%)%k%@$N(B format $B7A<0$NJ8;zNs$r;XDj$7$^$9!#(B +$B$J$*!"(B2$BEY(B @code{format} $B$G;XDj$9$k$?$a!"(B +$B$+$J$i$:HV9f$NItJ,$O(B @samp{%%d} $B$K$7$J$/$F$O$J$j$^$;$s!#(B +$B$^$?!"%a%C%;!<%8$NG/$H7n$,M?$($i$l$k$?$a!"(B@code{%%d} $B$O(B2$B$DI,MW$G$9!#(B + +$B$b$7!"JQ99$9$k>l9g$O(B @code{wl-expire-archive-date-folder-num-regexp} +$B$b9g$o$;$k$h$&$K$7$F$/$@$5$$!#(B + +@item wl-expire-archive-folder-type +@vindex wl-expire-archive-folder-type +$B=i4|@_Dj$O(B 'zip$B!#(B +$B%"!<%+%$%V%U%)%k%@$N%"!<%+%$%P%?%$%W$r;XDj$7$^$9!#(B + +@item wl-expire-archive-folder-prefix +@vindex wl-expire-archive-folder-prefix +$B=i4|@_Dj$O(B nil$B!#(B +$B%"!<%+%$%V%U%)%k%@$KIU$1$k(B prefix $B$r;XDj$7$^$9!#(B +$B$?$@$7!"%"!<%+%$%V%U%)%k%@$K(B prefix ($B%G%#%l%/%H%j9=B$(B)$B$rIU$1$k;EMM$O(B +$B$*$^$15!G=$G$9$N$G!"$+$i(B +$BHV9f$r$+$i(B +$BHV9f$rl9g!"4{$KB8:_$7$F$$$k%"!<%+%$%V%U%)%k%@$N:GBg%a%C%;!<%8HV9f$h$j$b(B +$B8E$$%a%C%;!<%8$,$"$C$?>l9g$K3NG'$7$F$+$i:o=|$7$^$9!#(B +nil$B$N>l9g$O3NG'$;$:$K:o=|$7$^$9!#(B + +$B$J$*!"I8=`4X?t$N0z?t$K(B non-nil $B$r;XDj$7$FHV9f$rJ];}$9$k$h$&$K$7$?>l9g$N(B +$B$_M-8z$G$9!#(B + +@item wl-expire-use-log +@vindex wl-expire-use-log +$B=i4|@_Dj$O(B nil$B!#(B +Non-nil $B$K$9$k$H!"(B@file{~/.elmo/expired-log}$B$K(B expire $B$NC$9I,MW$,$"$j$^$9!#(B + +@item wl-expire-add-seen-list +@vindex wl-expire-add-seen-list +$B=i4|@_Dj$O(B t$B!#(B + +Non-nil $B$N>l9g!"(Bexpire $B$K$h$j%a%C%;!<%8$r(B refile $B$7$?>l9g!"4{FI>pJs$r(B +refile$B@h$N%U%)%k%@$KEA$($k$h$&$K$7$^$9!#(B + +$B$?$@$7!"(Brefile$B@h$N%U%)%k%@$r(B Wanderlust$B>e$+$iFI$^$J$$$H!"(B +@file{~/.elmo/}$B0J2<$K$"$k(B @file{seen} $B%U%!%$%k$,Bg$-$/$J$C$F$$$/$N$G!"(B +$B%"!<%+%$%V%U%)%k%@$J$I$KC1$KJ]B8$7$F$*$/$@$1$J$i(B + nil $B$K@_Dj$7$F$*$/$H$h$$$G$7$g$&!#(Bnil $B$K@_Dj$7$F$b!"(B +refile$B$7$?%"!<%+%$%V%U%)%k%@$rFI$`$H$-$K?75,%a%C%;!<%807$$$5$l$k$@$1$G!"(B +expire $B$J$I$NF0:n$K$O1F6A$O$"$j$^$;$s!#(B + +@item wl-expire-folder-update-msgdb +@vindex wl-expire-folder-update-msgdb +$B=i4|@_Dj$O(B t$B!#(B +t $B$N>l9g!"%U%)%k%@%b!<%I$G(B expire $B$rpJs$r(Bupdate$B$7$F$+$i(Bexpire$B$r$N@55,I=8=$N%j%9%H$r;XDj$7$?>l9g$O!"%^%C%A$7$?%U%)%k%@$N(B +$B$_%5%^%j>pJs$r(Bupdate$B$9$k!#(B +@end table + + +@node Archive, , Expire, Expire and Archive +@section $B%a%C%;!<%8$N%"!<%+%$%V(B + +@subsection $B%a%C%;!<%8$N%"!<%+%$%V(B +@kbd{M-x wl-summary-archive} $B$G%U%)%k%@A4BN$r%"!<%+%$%V%U%)%k%@$K%3%T!<$7$^(B +$B$9!#4{$K%"!<%+%$%V%U%)%k%@$,$"$k>l9g!"?75,%a%C%;!<%8$N$_DI2C$7$^$9!#(B + +@code{wl-expire-alist} $B$HF1$8MM$K!"%U%)%k%@L>$K1~$8$F$I$N$h$&$K%"!<%+%$%V(B +$B$9$k$+$r(B @code{wl-archive-alist} $B$G;XDj$7$^$9!#Nc$($P0J2<$N$h$&$K$J$j$^(B +$B$9!#(B + +@lisp +(setq wl-archive-alist + '(("^\\+tmp$" wl-archive-date) + ("^\\+outbox$" wl-archive-number2) + (".*" wl-archive-number1) + )) +@end lisp + +$B3F%j%9%H$NMWAG$OA0$+$i$*2r$j$NDL$jl9g(B +$B$O!"$3$l$i$N4X?t$r;HMQ$9$k$H$h$$$G$7$g$&!#(B +$B$^$?!"(Bexpire $B$r9T$&A0$N%P%C%/%"%C%W$dF0:n$r3NG'$9$k$N$K$bM-8z$G$9!#(B +$B$b$C$H$b!"%"!<%+%$%V8e$K(Bexpire$B$G(Brefile$B$9$k$H!"(Brefile$B$;$:$K:o=|$9$k$@$1$K(B +$B$J$j$^$9!#(B + +$B%G%U%)%k%H$G$O%3%T!<@h$N%"!<%+%$%V%U%)%k%@$O(B +@code{wl-expire-archive-get-folder-func} $B$K=>$C$F<+F0E*$K7hDj$5$l$^$9$,!"(B +prefix argument $B$rIU$1$F(B @kbd{C-u M-x wl-summary-archive} $B$G!"%U%)%k%@Fb$K$"$k%a%C%;!<%8$N%j%9%H!"%5%^%j$N(Bmsgdb$B>pJs!"(B +$B$N(B3$B$D$N0z?t$,EO$5$l$^$9!#(B +$B$b$A$m$s%f!<%6$,FH<+$K:n$C$F;XDj$9$k$3$H$,$G$-$^$9!#(B +@end table + + +@c +@c Scoring +@c +@node Scoring, Customization, Expire and Archive, Top +@chapter $B%9%3%"(B +@cindex Scoring +@c @cindex Kill File + +$B%9%3%"$H$O!"%a%C%;!<%8$K%9%3%"(B($BCM(B)$B$r$D$1!"(B +$B$=$NCM$K$h$j4{FI%^!<%/$rIU$1$?$j%5%^%j$+$i>C$7$?$j$9$k5!G=$G$9!#(B + +$B$3$N5!G=$K$h$C$F=EMW$J%a%C%;!<%8$K(B temp $B%^!<%/$d(B important $B%^!<%/$r$D$1$?(B +$B$j!"(Bspam $B5-;v$J$I$NFI$_$?$/$J$$%a%C%;!<%8$K4{FI%^!<%/$r$D$1$?$j$9$k$3$H$,(B +$B$G$-$^$9!#(B + +$B$3$N%9%3%"5!G=$O(B Gnus $B$N%9%3%"$H$[$\F1Ey$N5!G=$r;}$A!"$^$?%9%3%"%U%!%$%k$N(B +$B=q<0$b$[$\F1$8$G$9!#$?$@$7!"4v$D$+$OL$BP1~$G$"$C$?$j(B Wanderlust $BFCM-$N5!G=(B +$B$,$"$C$?$j$7$^$9!#(B + +@menu +* Score Commands:: $B%9%3%"$K4X$9$k%3%^%s%I(B +* Score File Format:: $B%9%3%"%U%!%$%k$N=q<0(B +@end menu + + +@node Score Commands, Score File Format, Scoring, Scoring +@section $B%9%3%"$K4X$9$k%3%^%s%I(B +@cindex Score Commands + +@subsection $B%9%3%"%U%!%$%k$N;XDjJ}K!(B + +$BJQ?t(B @code{wl-score-folder-alist} +$B$K%U%)%k%@L>$KBP1~$7$?%9%3%"%U%!%$%kL>$+%9%3%"$rDj5A$7$?JQ?t$r@_Dj$7$^$9!#(B + +@lisp +(setq wl-score-folder-alist + '(("^-.*" + "news.SCORE" + "my.SCORE") + (".*" + "all.SCORE"))) +@end lisp + +$B%9%3%"%U%!%$%kL>$N%Q%9$r>JN,$7$?>l9g$O!"(B +$BJQ?t(B @code{wl-score-files-dir} $B$G;XDj$7$?%G%#%l%/%H%j$K$"$k$b$N$H$7$^$9!#(B + +$B$^$?!"(B@code{wl-score-folder-alist} $B$N@_Dj$K4X$o$i$:(B +$B%G%U%)%k%H$N%9%3%"%U%!%$%k(B @code{wl-score-default-file} (@file{all.SCORE}) + $B$OI,$:FI$_9~$^$l$^$9(B($B%U%!%$%k$,B8:_$7$F$$$J$/$F$b$+$^$$$^$;$s(B)$B!#(B +$B$7$?$,$C$F!">e5-Nc$N(B @samp{^-.*} $B$K%^%C%A$7$?%U%)%k%@$G$O(B +@file{news.SCORE}, @file{my.SCORE}, @file{all.SCORE} $B$N(B3$B$D$N%9%3%"%U%!%$%k(B +$B$,FI$_9~$^$l$k$3$H$K$J$j$^$9!#(B + +@subsection $B%9%3%"%U%!%$%k$NBP>]%a%C%;!<%8(B + +$B%9%3%"$O%5%^%j$N(B update $B;~$K0l;~E*$K(B @code{wl-summary-score-marks} +$B$G;XDj$7$?%a%C%;!<%8$N$_$K$D$1$i$l$^$9!#(B +$B$D$^$j%5%^%j$+$iH4$1$k$H%a%C%;!<%8$K$D$1$i$l$?%9%3%"$O>C5n$5$l!"(B +$B%G%U%)%k%H$N%9%3%"CM$KLa$j$^$9!#(B + +@subsection $B%9%3%"%U%!%$%k$N:n@.(B + +$B$^$:%5%^%j%P%C%U%!$GE,Ev$J%a%C%;!<%8$K0\F0$7$F$+$i(B @kbd{L} $B$r%?%$%W$7$^(B +$B$9!#$=$N8e%_%K%P%C%U%!$G$NF~NO$r5a$a$i$l$^$9$N$G!"$D$E$1$F(B @kbd{s}, +@kbd{s}, @kbd{p} $B$H%?%$%W$7$F$_$F$/$@$5$$!#$9$k$H(B Subject $B$NJ8;zNs$,F~NO(B +$B$5$l$F$$$k>uBV$K$J$j$^$9$N$G!"E,Ev$KJT=8$7$?$N$A(B @kbd{@key{RET}} $B$r2!$7$^$9!#(B + +$B$3$l$G!"F~NO$7$?J8;zNs$HF1$8(B Subject $B$r;}$D%a%C%;!<%8$KBP$7$F%9%3%"(B +-1000 $B$,$D$1$i$l$k$h$&$K$J$j$^$9!#$D$^$j!"$3$N$h$&$J%9%3%"%U%!%$%k$,<+F0E*(B +$B$K:n@.$5$l$?$3$H$K$J$j$^$9!#(B + +$BC5n$7$F$+$i(B +@kbd{C-c C-c} $B$9$k$HJT=8Cf$N%9%3%"%U%!%$%k$r:o=|$7$^$9!#(B + +@subsection TIPS + +@subsubsection $B%9%3%"%U%!%$%k$NA*Br(B + +@code{wl-summary-increase-score} $B$H(B @code{wl-summary-lower-score} $B$H$GDI(B +$B2C$9$k%9%3%"%U%!%$%k$O(B @code{wl-score-change-score-file} $B$GJQ99$9$k$3$H(B +$B$,$G$-$^$9!#(B + +@subsubsection $B%9%3%"$N2C;;(B + +@code{wl-summary-increase-score} $B$d(B @code{wl-summary-lower-score}$B!"(B +@code{wl-score-edit-insert-entry} $B$GF1$8%(%s%H%j$rDI2C$7$?>l9g!"(B +$B%9%3%"$,2C;;$5$l$^$9!#(B + +$B$?$H$($P!"(B@kbd{L a} $B$G%9%3%"$,(B -1000 $B$N(B @samp{from} $B%(%s%H%j$r:n@.$7$?8e!"(B +$B:FEY(B @kbd{C-u 200 L a} $B$G%9%3%"$,(B -200 $B$N(B @samp{from} $B%(%s%H%j$r:n@.$9$k$H!"(B +$B%9%3%"$,(B -1200 $B$N%(%s%H%j$,(B1$B$D:n@.$5$l$k$3$H$K$J$j$^$9!#(B + +@subsubsection Thread$B%-!<$N:n@.(B + +@code{wl-summary-increase-score} $B$+(B @code{wl-summary-lower-score} $B$G(B +@samp{Thread}$B%-!<$r:n@.$9$k$H!";R%9%l%C%I$N(B @samp{Message-ID} $B$bA4$F(B +$BDI2C$5$l$^$9!#(B + +@subsubsection Followup$B%-!<$N:n@.(B + +@code{wl-summary-increase-score} $B$+(B @code{wl-summary-lower-score} $B$G(B +@samp{Followup}$B%-!<$r:n@.$9$k$H!"%+!<%=%k>e$N%a%C%;!<%8$N(B +@samp{Message-ID} $B$b(B @samp{References} $B%-!<$KDI2C$5$l$^$9!#(B +$B$b$7!"(B@code{wl-score-auto-make-followup-entry} $B$,(B non-nil $B$G$"$l$P(B +@code{wl-score-expiry-days} $B$G;XDj$7$?F|$K$A0JFb$NA4(Bfollowup$BBP>]$N%a%C%;!<(B +$B%8$N(B @samp{Message-ID} $B$,DI2C$5$l$^$9!#(B + +@subsection $B%-!<%P%$%s%I(B + +@table @kbd +@item K +@kindex K (Summary) +@findex wl-summary-increase-score +$B8=:_$N%a%C%;!<%8$N%9%3%"$r9b$/$7$^$9!#(B +$BF1;~$K%9%3%"%(%s%H%j$,%9%3%"%U%!%$%k$KDI2C$5$l$^$9!#(B +$B$^$?!"(Bprefix argument $B$G%9%3%"$NCM$r@_Dj$9$k$3$H$,$G$-$^$9!#(B + +@item L +@kindex L (Summary) +@findex wl-summary-lower-score +$B8=:_$N%a%C%;!<%8$N%9%3%"$rDc$/$7$^$9!#(B +$BF1;~$K%9%3%"%(%s%H%j$,%9%3%"%U%!%$%k$KDI2C$5$l$^$9!#(B +$B$^$?!"(Bprefix argument $B$G%9%3%"$NCM$r@_Dj$9$k$3$H$,$G$-$^$9!#(B + +@item h R +@kindex h R (Summary) +@findex wl-summary-rescore +$B%9%3%"$rE,MQ$7D>$7$^$9!#(B +$B$?$@$7!"4{$K%9%3%"$,$D$1$i$l$F$$$k%a%C%;!<%8$K$O!"?7$?$K%9%3%"$O$D$-$^$;$s!#(B + +@item h c +@kindex h c (Summary) +@findex wl-score-change-score-file +$B8=:_A*Br$7$F$$$k%9%3%"%U%!%$%k$rJQ99$7$^$9!#(B + +@item h e +@kindex h e (Summary) +@findex wl-score-edit-current-scores +$B8=:_A*Br$7$F$$$k%9%3%"%U%!%$%k$rJT=8$7$^$9!#(B +$B%9%3%"%U%!%$%k$,J#?t$"$k>l9g@h$K;XDj$5$l$?%U%!%$%k$,A*Br$5$l$^$9!#(B + +@item h f +@kindex h f (Summary) +@findex wl-score-edit-file +$BG$0U$N%9%3%"%U%!%$%k$rJT=8$7!"$3$N%9%3%"%U%!%$%k$rA*Br$7$^$9!#(B + +@item h F +@kindex h F (Summary) +@findex wl-score-flush-cache +$BFI$_9~$s$@%9%3%"%U%!%$%k$O0lC6%-%c%C%7%e$5$l$^$9$,!"$=$N%-%c%C%7%e$r>C5n$7$^$9!#(B +Wanderlust $B0J30$GD>@\%9%3%"%U%!%$%k$rJQ99$7$?>l9g$O!"(B +$B%-%c%C%7%e$r>C5n$7$F:FFI$_9~$_$9$kI,MW$,$"$j$^$9!#(B + +@item h m +@kindex h m (Summary) +@findex wl-score-set-mark-below +$B4{FI%^!<%/$rIU$1$k(B($BFI$s$@$3$H$K$9$k(B)$B%9%3%"4p=`CM$r@_Dj$7$^$9!#(B +$B$3$NCM$h$j$b>.$5$J%9%3%"$,4{FI$K$J$j$^$9!#(B + +@item h x +@kindex h x (Summary) +@findex wl-score-set-expunge-below +$B%5%^%j$+$i>C5n$9$k%9%3%"4p=`CM$r@_Dj$7$^$9!#(B +$B$3$NCM$h$j$b>.$5$J%9%3%"$,>C5n$5$l$^$9!#(B +$B>C5n$H$$$C$F$bI=<($5$l$J$$$@$1$G$"$j!"%5%^%j>pJs$d%U%)%k%@$+$i$O:o=|$5$l$^(B +$B$;$s!#(B +$B>C5n$5$l$?%a%C%;!<%8$O(B rescan-noscore $B$K$h$j:F$SI=<($9$k$3$H$,$G$-$^$9!#(B +@end table + +@subsection $B%9%3%"JT=8%P%C%U%!$N%-!<%P%$%s%I(B + +@table @kbd +@item C-c C-k +@kindex C-c C-k (Score Mode) +@findex wl-score-edit-kill +$BJT=8Cf$N%U%!%$%k$rGK4~$7$^$9!#(B + +@item C-c C-c +@kindex C-c C-c (Score Mode) +@findex wl-score-edit-exit +$BJT=8Cf$N%U%!%$%k$rJ]B8$7$F!"JT=8%b!<%I$r=*N;$7$^$9!#(B + +@item C-c C-p +@kindex C-c C-p (Score Mode) +@findex wl-score-pretty-print +$B%9%3%"$re:No$KI=<($7D>$7$^$9!#(B + +@item C-c C-d +@kindex C-c C-d (Score Mode) +@findex wl-score-edit-insert-date +$B5*85A0(B1$BG/(B12$B7n(B31$BF|$+$i$NF|?t$rA^F~$7$^$9!#(B +$B4|8BIU$-$N%9%3%"$r:n$k$H$-$K4|8B$NMWAG(B(3$BHVL\(B)$B$K;HMQ$7$^$9!#(B + +@item C-c C-s +@kindex C-c C-s (Score Mode) +@findex wl-score-edit-insert-header +$B%5%^%j%P%C%U%!$GA*Br$7$F$$$k%a%C%;!<%8$N%X%C%@$rA^F~$7$^$9!#(B + +@item C-c C-e +@kindex C-c C-e (Score Mode) +@findex wl-score-edit-insert-entry +$B%5%^%j%P%C%U%!$GA*Br$7$F$$$k%a%C%;!<%8$N%9%3%"%(%s%H%j$rDI2C$7$^$9!#(B +@end table + +@subsection $B%+%9%?%^%$%:JQ?t(B + +@table @code +@item wl-summary-default-score +@vindex wl-summary-default-score +$B=i4|@_Dj$O(B 0$B!#(B +$B%9%3%"$N%G%U%)%k%HCM$r@_Dj$7$^$9!#$3$NCM$r85$K%9%3%"$,2C8:$5$l$^$9!#(B + +@item wl-summary-important-above +@vindex wl-summary-important-above +$B=i4|@_Dj$O(B nil$B!#(B +$B$3$NCM$h$jBg$-$$%9%3%"$KBP$7$F(B important$B%^!<%/(B(@samp{$}) $B$r$D$1$^$9!#(B +nil $B$N>l9g$O%^!<%/$rIU$1$^$;$s!#(B + +@item wl-summary-temp-above +@vindex wl-summary-temp-above +$B=i4|@_Dj$O(B nil$B!#(B +$B$3$NCM$h$jBg$-$$%9%3%"$KBP$7$F(B temp$B%^!<%/(B(@samp{*}) $B$r$D$1$^$9!#(B +nil $B$N>l9g$O%^!<%/$rIU$1$^$;$s!#(B + +@item wl-summary-mark-below +@vindex wl-summary-mark-below +$B=i4|@_Dj$O(B 0$B!#(B +$B$3$NCM$h$j>.$5$J%9%3%"$KBP$7$F4{FI%^!<%/$r$D$1$^$9(B($BFI$s$@$3$H$K$7$^$9(B)$B!#(B + +@item wl-summary-expunge-below +@vindex wl-summary-expunge-below +$B=i4|@_Dj$O(B nil$B!#(B +$B$3$NCM$h$j>.$5$J%9%3%"$O%5%^%j$+$i>C5n$7$^$9!#(B +nil $B$N>l9g$O>C5n$7$^$;$s!#(B + +@item wl-summary-score-marks +@vindex wl-summary-score-marks +$B=i4|@_Dj$O(B '("N" "!" "U")$B!#(B +$B%9%3%"$r$D$1$k%a%C%;!<%8$N%^!<%/$r;XDj$7$^$9!#(B + +@item wl-use-scoring +@vindex wl-use-scoring +$B=i4|@_Dj$O(B t$B!#(B +Non-nil $B$J$i%9%3%"5!G=$rM-8z$K$7$^$9!#(B + +@item wl-score-files-dir +@vindex wl-score-files-dir +$B=i4|@_Dj$O(B "~/.elmo/"$B!#(B +$B%9%3%"%U%!%$%k$r%G%U%)%k%H$N%G%#%l%/%H%j$r;XDj$7$^$9!#(B + +@item wl-score-interactive-default-score +@vindex wl-score-interactive-default-score +$B=i4|@_Dj$O(B 1000$B!#(B +$B%9%3%"%U%!%$%k$G%9%3%"MWAG$,(B nil $B$N;~$KMQ$$$k%9%3%"$r;XDj$7$^$9!#(B +$B$^$?!"(B@code{wl-summary-increase-score} $B$d(B @code{wl-summary-lower-score} +$B$G$D$1$k%9%3%"CM$G$bMQ$$$i$l$^$9!#$?$@$7!"(B +@code{wl-score-header-default-entry} $B$N%9%3%"CM$,(B nil $B$N;~!#(B + +@item wl-score-expiry-days +@vindex wl-score-expiry-days +$B=i4|@_Dj$O(B 7$B!#(B +$B4|8BIU$-%9%3%"$r:o=|$9$kF|?t$r;XDj$7$^$9!#(B + +@item wl-score-update-entry-dates +@vindex wl-score-update-entry-dates +$B=i4|@_Dj$O(B t$B!#(B +Non-nil $B$J$i4|8BIU$-%9%3%"$r:o=|$9$k5!G=$rM-8z$K$7$^$9!#(B + +@item wl-score-header-default-entry +@vindex wl-score-header-default-entry +@code{wl-summary-increase-score} $B$d(B @code{wl-summary-lower-score}$B!"(B +@code{wl-score-edit-insert-entry} $B$G%9%3%"%(%s%H%j$r:n@.$9$k>l9g$N(B +$B3F%X%C%@$N%G%U%)%k%HCM$r@_Dj$7$^$9!#(B + +@item wl-score-simplify-fuzzy-regexp +@vindex wl-score-simplify-fuzzy-regexp +$B%9%3%"%(%s%H%j$N7?$G(B fuzzy $B$r;XDj$7$?>l9g!"(B +$BJ8;zNs$+$i:o=|$9$k@55,I=8=$r;XDj$7$^$9!#(B +Subject $B$G;HMQ$5$l$k$3$H$,B?$$$N$G!"%G%U%)%k%H$G$O(B +$B%a%$%j%s%0%j%9%H%W%m%0%i%`$G$D$1$i$l$k(B prefix $B$r;XDj$7$F$$$^$9!#(B + +@item wl-summary-rescore-partial-threshold +@vindex wl-summary-rescore-partial-threshold +$B=i4|@_Dj$O(B 200$B!#(B +sync-all $B$d(B rescan $B$,l9g!"%5%^%j$N:G8e$+$i;XDj$5$l$??t$N%a%C%;!<%8$@$1!"(B +$BItJ,E*$K%9%3%"IU$1$,E,MQ$5$l$^$9!#(B + +@item wl-summary-auto-sync-marks +@vindex wl-summary-auto-sync-marks +Non-nil $B$J$i$P!"%5%^%jF14|;~$KL$FI(B/$B=EMW%^!<%/$bF14|$7$^$9!#(B +$BL$FI%^!<%/$O!"(BIMAP4 $B%5!<%P>e$NL$FI>pJs$,H?1G$5$l$^$9!#(B +$B=EMW%^!<%/$O(B IMAP4 $B%5!<%P>e$N=EMW>pJs(B(Flagged $B%U%i%0$,$D$$$F$$$k$+(B)$B!"(B +$B$*$h$S(B 'mark $B%U%)%k%@$NFbMF$,!"H?1G$5$l$^$9!#(B +$B=i4|@_Dj$O(B t$B!#(B +@end table + + +@node Score File Format, , Score Commands, Scoring +@section $B%9%3%"%U%!%$%k=q<0(B +@cindex Score File Format + +$B%9%3%"%U%!%$%k$N=q<0$O(B Gnus $B$HF1$8$J$N$G!"(BGnus $B$G;HMQ$7$F$$$?(B +$B%9%3%"%U%!%$%k$,$=$N$^$^MxMQ$G$-$^$9!#(B +$B$?$@$7!"4v$D$+$N%-!<$OBP1~$7$F$$$J$+$C$?$j(B Wanderlust $BFCM-$N%-!<$,$"$C$?$j(B +$B$7$^$9$N$G!"40A4$K8_49@-$,$"$k$o$1$G$O$"$j$^$;$s!#(B + +@example +(("subject" + ("for sale" -1000 nil s) + ("$BLY$1(B" -1000 nil s)) + ("from" + ("spam@@spamspamspam" -10000 nil s)) + ("followup" + ("my@@address" 3001 nil s)) + ("chars" + (1000000 -10 nil >)) + (important 5000) + (temp 3000) + (mark 0) + (expunge -3000)) +@end example + +@table @code +@item $BJ8;zNs(B (STRING) +$B%-!<$,J8;zNs$G$"$k>l9g!"%^%C%A$5$;$k%X%C%@$NL>A0$r;XDj$7$^$9!#(B +$B$3$N%-!<$K$OA0$N%U%#!<%k%I$,BP>]$H$J$j$^$9!#(B + +$B$3$N%-!<$N8e$K%9%3%"%(%s%H%j$rG$0U$N?t$@$1;XDj$7!"(B +$B$3$N3F%9%3%"%(%s%H%j$Ol9g$O?t;z$G!"$=$l0J30$OJ8;z(B +$BNs$r;XDj$7$^$9!#(B + +@item +$B%9%3%"MWAG!##1HVL\$NMWAG$,%^%C%A$7$?>l9g!"$=$N%a%C%;!<%8$N%9%3%"$r$3$NCMJ,(B +$BA}8:$5$;$^$9!#(B + +@item +$B4|8B$NMWAG!#(Bnil $B$J$i1JB3(B(permanent)$B;XDj$G!"(B +$B?t;z(B($BF|?t(B)$B$J$i0lDj4|4V(B(@code{wl-score-expiry-days})$B%^%C%A$7$J$$$H:o=|$5$l$^$9!#(B +$B$3$NF|?t$O5*85A0(B1$BG/(B12$B7n(B31$BF|$+$i7P2a$7$?F|$K$A$G$9!#(B + +@item +$B7?$NMWAG!##1HVL\$NMWAG$r%^%C%A$5$;$kJ}K!$r;XDj$7$^$9!#(B +$B%-!<$K$h$C$F;XDj$G$-$k7?$,0[$J$j$^$9!#(B + +@table @dfn +@item From, Subject, References, Message-Id +$B$3$l$i$NJ8;zNs$N%-!<$KBP$7$F$O!"(B@code{r} $B$H(B @code{R} ($B@55,I=8=(B) (regexp) +$B$d!"(B@code{s} $B$H(B @code{S} ($BJ8;zNs$N0lIt(B) (substring)$B!"(B@code{e} $B$H(B +@code{E} ($B@53N$J9gCW(B) (exact match)$B!"$=$l$K(B @code{f} $B$H(B @code{F} +($B$"$$$^$$(B) (fuzzy) $B$,;XDj$G$-$^$9!#(B +@code{R}, @code{S}, @code{E}, @code{F} $B$OBgJ8;z>.J8;z$r6hJL$7$F%^%C%A$5$;$^$9!#(B + +@item Lines, Chars +$B$3$l$i$O?t;z$NBg>.$r;XDj$7$^$9!#$=$N5-9f$O}, @code{=}, @code{>=}, @code{<=} + +@item Followup +$B$3$N%-!<$O!"(B@code{From}$B%X%C%@!<$K%^%C%A$7!"(B +$B$=$N%a%C%;!<%8$X$NA4$F$N%U%)%m!<%"%C%W$KBP$7$F%9%3%"$r$D$1$^$9!#(B +$B$?$H$($P!"<+J,<+?H$N5-;v$X$N%U%)%m!<%"%C%W$N%9%3%"$rA}$d$7$?$j$9$k$N$KJXMx$G$9!#(B + +@code{f} $B$r=|$$$F(B @code{From} $B%-!<$HF1$87?$,;XDj=PMh$^$9!#(B +$B$^$?!"<+F0E*$K%9%3%"%U%!%$%k$K(B @samp{Followup} $B%(%s%H%j$,DI2C$5$l$^$9!#(B + +@item Thread +$B$3$N%-!<$O!"(B@code{Message-ID} @var{x} $B$G;O$^$C$F$$$k(B($B%5%V(B)$B%9%l%C%I$K%9%3%"$rIU$1$k>l9g$K;XDj$7$^$9!#(B +$B$3$l$O(B @code{References} $B%X%C%@!<$K(B @var{x} $B$r;}$D$=$l$>$l$N5-;v$K?7$7$$(B +@samp{Thread} $B%(%s%H%j$r<+F0E*$KDI2C$7$^$9!#(B +$B$3$l$K$h$j!"A4$F$NAD@h$N(B @code{Message-ID} $B$r(B @code{References} $B$K4^$s$G$$$J$$>l9g$G$b!"(B +$B3Nl9g$N$_0UL#$r;}$A$^$9!#(B +@code{Subject} $B$d(B @code{From} $B$J$I$NI8=`0J30$N%X%C%@$K%^%C%A$5$;$?$$>l9g$K(B +$B$=$N%X%C%@$r;XDj$7$^$9!#(B +$B$?$@$7!";XDj$7$?%X%C%@$O(B @code{elmo-msgdb-extra-fields} $B$K$b@_Dj$9$kI,MW$,$"$j$^$9!#(B +$B$7$?$,$C$F!"3HD%%X%C%@$,.$5$$%9%3%"$N%a%C%;!<%8$K$O4{FI%^!<%/$r$D$1$^$9!#(B +$B%G%U%)%k%HCM$O(B @code{wl-summary-mark-below} $B$G;XDj$5$l$^$9!#(B + +@item expunge +$B$3$NCM$h$j>.$5$$%9%3%"$N%a%C%;!<%8$O%5%^%j$+$i>C5n$7$^$9!#(B +$B%G%U%)%k%HCM$O(B @code{wl-summary-expunge-below} $B$G;XDj$5$l$^$9!#(B + +@item mark-and-expunge +@code{mark} $B$H(B @code{expunge} $B$rF1;~$K;XDj$7$^$9!#(B +$B$D$^$j!"$3$NCM$h$j>.$5$$%9%3%"$N%a%C%;!<%8$O4{FI%^!<%/$r$D$1!"%5%^%j$+$i>C5n$7$^$9!#(B + +@item temp +$B$3$NCM$h$jBg$-$$%9%3%"$N%a%C%;!<%8$K$O(B temp $B%^!<%/$r$D$1$^$9!#(B +$B%G%U%)%k%HCM$O(B @code{wl-summary-temp-above} $B$G;XDj$5$l$^$9!#(B + +@item important +$B$3$NCM$h$jBg$-$$%9%3%"$N%a%C%;!<%8$K$O(B important $B%^!<%/$r$D$1$^$9!#(B +$B%G%U%)%k%HCM$O(B @code{wl-summary-important-above} $B$G;XDj$5$l$^$9!#(B +@end table + +@subsection $BCm0U;v9`(B + +@code{extra} $B%-!<$O$b$A$m$s!"(B@code{lines} $B$H(B @code{xref} $B%-!<$r;HMQ$9$k(B +$B>l9g$G$b!"(B@code{elmo-msgdb-extra-fields} $B$r@_Dj$9$kI,MW$,$"$j$^$9!#(B + +@lisp +(setq elmo-msgdb-extra-fields '("lines" "xref")) +@end lisp + +$B$=$NB>!"2<5-$N@)8B;v9`$,$"$j$^$9!#(B + +@itemize @bullet +@item $B%5%^%j>pJs$K4^$^$l$k(B@samp{References}$B%U%#!<%k%I$K$O:G8e$N(B +@samp{Message-ID}$B$7$+B8:_$7$J$$$?$a!"(B@code{references}$B%-!<$b$=$N(B +@samp{Message-ID}$B$K$7$+%^%C%A$7$J$$!#(B +@end itemize + +$B%U%)%k%@H$G$-$k%-!<$N0lMw!#(B + +@example + chars lines xref extra +localdir,localnews $B!{(B $B"$(B $B"$(B $B"$(B +nntp (xover$BBP1~(B) $B!{(B $B"$(B $B"$(B $B!_(B + (xover$BHsBP1~(B) $B!_(B $B"$(B $B"$(B $B"$(B +imap4 $B!{(B $B"$(B $B"$(B $B"$(B +pop3 $B!_(B $B"$(B $B"$(B $B"$(B + + $B!{(B: $B;2>H$G$-$k(B + $B!_(B: $B;2>H$G$-$J$$(B($BL5;k$5$l$k(B) + $B"$(B: @code{elmo-msgdb-extra-fields} $B$r@_Dj$9$l$P;2>H$G$-$k(B +@end example + + +@c +@c Customization +@c +@node Customization, Mailing List, Scoring, Top +@chapter Wanderlust $B$N%+%9%?%^%$%:(B +@cindex Customization + +@menu +* Living with other packages:: $B%Q%C%1!<%8$N$"$k@83h(B +* Highlights:: $B%O%$%i%$%H$N@_Dj(B +* Advanced Settings:: $B%+%9%?%^%$%:!A1~MQJT!A(B +* Customizable Valiables:: $B$=$NB>$N%+%9%?%^%$%:JQ?t0lMw(B +@end menu + + +@node Living with other packages, Highlights, Customization, Customization +@section $B%Q%C%1!<%8$N$"$k@83h(B + +$BB>$N%Q%C%1!<%8$r;H$&$?$a$N@_DjNc$G$9!#(B + +@menu +* BBDB:: BBDB +* supercite:: supercite.el +* mu-cite:: mu-cite.el +* x-face-mule:: x-face-mule.el +* dired-dd:: dired-dd.el +@end menu + + +@node BBDB, supercite, Living with other packages, Living with other packages +@subsection bbdb.el +@pindex BBDB + +@file{util/bbdb-wl.el} $B$r(B load-path $B$K$*$$$F0J2<$N$h$&$K@_Dj$9$l$P(B OK $B$G$9!#(B + +$B%$%s%9%H!<%k;~$K(B load-path $B>e$K(B BBDB $B$,$"$l$P!"(B +@file{bbdb-wl.el} $B$O%P%$%H%3%s%Q%$%k(B/$B%$%s%9%H!<%k$5$l$^$9!#(B +@xref{Install}. + +@lisp +(require 'bbdb-wl) + +(bbdb-wl-setup) +;; @r{$B%]%C%W%"%C%WI=<((B} +(setq bbdb-use-pop-up t) +;; @r{$B<+F0<}=8(B} +(setq bbdb/mail-auto-create-p t) +(setq signature-use-bbdb t) +(setq bbdb-north-american-phone-numbers-p nil) +;; @r{$B%5%^%j$K(B bbdb $B$NL>A0$rI=<((B} :-)$B!#(B +(setq wl-summary-from-func 'bbdb-wl-from-func) +;; @r{$B<+F0E*$K(B ML $B%U%#!<%k%I$r2C$($k(B} +(add-hook 'bbdb-notice-hook 'bbdb-auto-notes-hook) +(setq bbdb-auto-notes-alist '(("X-ML-Name" (".*$" ML 0)))) +@end lisp + + +@node supercite, mu-cite, BBDB, Living with other packages +@subsection sc.el(supercite), sc-register.el +@pindex sc +@pindex supercite + +$B$U$D$&$N(B mailer $B$HF1$8@_Dj$G(B OK $B$G$9!#0J2<$O!"@_Dj$N0lNc$G$9!#(B + +@lisp +(autoload 'sc-cite-original "sc" nil t) +(setq mail-yank-hooks 'sc-cite-original) +(setq sc-preferred-header-style 1) +(setq sc-electric-references-p nil) +(setq sc-citation-leader "") +(setq sc-load-hook '(lambda () (require 'sc-register))) +(setq sc-preferred-attribution 'registeredname) +@end lisp + + +@node mu-cite, x-face-mule, supercite, Living with other packages +@subsection mu-cite.el +@pindex mu-cite + +$B$U$D$&$N(B mailer $B$HF1$8@_Dj$G(B OK $B$G$9!#0J2<$O!"@_Dj$N0lNc$G$9!#(B + +mu-cite 8.0$B0JA0$N%P!<%8%g%s$r$*;H$$$J$i!"(B +$B0J2<$N$h$&$K@_Dj$7$F$/$@$5$$!#(B + +@lisp +(autoload 'mu-cite/cite-original "mu-cite" nil t) +(setq mail-citation-hook 'mu-cite/cite-original) +@end lisp + +mu-cite 8.1$B0J9_$N%P!<%8%g%s$r$*;H$$$J$i!"(B +$B0J2<$N$h$&$K@_Dj$7$F$/$@$5$$!#(B + +@lisp +(autoload 'mu-cite-original "mu-cite" nil t) +(add-hook 'mail-citation-hook (function mu-cite-original)) +@end lisp + +@node x-face-mule, dired-dd, mu-cite, Living with other packages +@subsection x-face-mule.el +@pindex x-face-mule +@pindex bitmap-mule + +x-face-mule $B$N%P!<%8%g%s$K$h$C$F@_Dj$,0[$J$j$^$9!#(B + +x-face-mule 0.19$B0JA0$N%P!<%8%g%s$r$*;H$$$J$i!"(B +$B0J2<$N$h$&$K@_Dj$7$F$/$@$5$$!#(B + +@lisp +(setq wl-highlight-x-face-func + (function + (lambda (beg end) + (x-face-mule:x-face-decode-message-header)))) +(require 'x-face-mule) +@end lisp + +x-face-mule 0.20 $B0J9_$N%P!<%8%g%s$r$*;H$$$J$i!"(B +$B0J2<$N$h$&$K@_Dj$7$F$/$@$5$$!#(B + +@lisp +(setq wl-highlight-x-face-func + (function + (lambda (beg end) + (x-face-mule-x-face-decode-message-header)))) +(require 'x-face-mule) +@end lisp + +bitmap-mule 8.0$B0J9_$KIUB0$N(B @file{x-face-mule.el} +$B$r$*;H$$$K$J$k>l9g$O0J2<$N$h$&$K@_Dj$7$F$/$@$5$$!#(B + +@lisp +(autoload 'x-face-decode-message-header "x-face-mule") +(setq wl-highlight-x-face-func + (function x-face-decode-message-header)) +@end lisp + +Encode $B:Q$_$N(B X-Face $BJ8;zNs$r(B @file{~/.xface} +($BJQ?t(B @code{wl-x-face-file} $B$NCM$G$9(B)$B$NFbMF$KMQ0U$7$F$*$/$H!"(B +$B%I%i%U%H$,=`Hw$5$l$k$H$-$K<+F0E*$K(B X-Face$B%U%#!<%k%I$H$7$FA^F~$5$l$^$9!#(B +($BJQ?t(B @code{wl-auto-insert-x-face} $B$,(B non-nil $B$N>l9g(B) + + +@node dired-dd, , x-face-mule, Living with other packages +@subsection dired-dd(Dired-DragDrop) +@pindex Dired-DragDrop +@pindex Dired-DD +@cindex Drag and Drop + +dired-dd $B%Q%C%1!<%8$K4^$^$l$k(B @file{dired-dd-mime.el} $B$rAH$_9~$a$P!"(BGNU Emacs +$B$GJT=8Cf$NAp9F%P%C%U%!$X(B dired $B$+$i(B Drag&Drop $B$9$k$@$1$G4JC1$K%^%k%A%Q!<(B +$B%H$r:n@.$G$-$^$9(B($B$b$C$H$b!"(BWanderlust $B@lMQ$G$O$J$/(B tm/SEMI $BHFMQ$G$9$,(B)$B!#(B + +@lisp +;; @r{dired-dd:} http://www.asahi-net.or.jp/~pi9s-nnb/dired-dd-home.html +(add-hook 'dired-load-hook + (function + (lambda () + (load "dired-x") + ;; @r{Set dired-x variables here.} + ;; @r{To and flo@dots{}} + (if window-system + (progn (require 'dired-dd) + (require 'dired-dd-mime)))))) +@end lisp + + +@node Highlights, Advanced Settings, Living with other packages, Customization +@section $B%O%$%i%$%H$N@_Dj(B + +@subsection $B%+%9%?%^%$%:JQ?t(B + +@table @code +@item wl-summary-highlight +@vindex wl-summary-highlight +$B=i4|@_Dj$O(B t$B!#%5%^%j$N%O%$%i%$%H$r9T$&$+$I$&$+!#(B +Non-nil $B$J$i%5%^%j$N%O%$%i%$%H$r9T$$$^$9!#(B + +@item wl-highlight-max-summary-lines +@vindex wl-highlight-max-summary-lines +$B=i4|@_Dj$O(B 10000$B!#(B +$B%5%^%j$N9T?t$,$3$NCM$h$jBg$-$$>l9g!"%5%^%j$N%O%$%i%$%H$r9T$$$^$;$s!#(B + +@item wl-summary-highlight-partial-threshold +@vindex wl-summary-highlight-partial-threshold +$B=i4|@_Dj$O(B 1000$B!#(B +$B%5%^%jA4BN$r%O%$%i%$%H$9$k$+$I$&$+$NogCM!#(B +$B$3$NCM$r1[$($k9T?t$N%a%C%;!<%8$,%5%^%j$KB8:_$9$k>l9g!"(B +$BItJ,E*$J%O%$%i%$%H$r9T$$$^$9!#(B + +@item wl-summary-partial-highlight-above-lines +@vindex wl-summary-partial-highlight-above-lines +$B=i4|@_Dj$O(B 30$B!#(B +@code{wl-summary-highlight-partial-threshold}$B$r1[$($k9T?t$N%a%C%;!<%8$,(B +$B%5%^%j$KB8:_$9$k>l9g!"%P%C%U%!Kv$+$i!"%+!<%=%k9T$h$j$3$NCM$N9T?tJ,$@$1(B +$B>e$N%a%C%;!<%8$^$GItJ,E*$J%O%$%i%$%H$,9T$J$o$l$^$9!#(B +($B$3$NCM$r(B nil $B$K$9$k$H%P%C%U%!Kv$+$i(B + @code{wl-summary-highlight-partial-threshold}$B9TJ,$@$1%O%$%i%$%H$5$l$k(B + $B$h$&$K$J$j$^$9!#(B) + +@item wl-highlight-body-too +@vindex wl-highlight-body-too +$B=i4|@_Dj$O(B t$B!#(B +Non-nil $B$J$i%I%i%U%H$*$h$S%a%C%;!<%8$NK\J8$b%O%$%i%$%H$NBP>]$H$7$^$9!#(B + +@item wl-highlight-message-header-alist +@vindex wl-highlight-message-header-alist +$B%I%i%U%H$*$h$S%a%C%;!<%8$N%X%C%@$N%O%$%i%$%H$r9T$&:]$K!"(B +$B=EMW(B (@code{wl-highlight-message-important-header-contents})$B$J!"(B +$BFsHVL\$K=EMW(B (@code{wl-highlight-message-important-header-contents2})$B$J!"(B +$B$=$7$F=EMW$G$O$J$$(B (@code{wl-highlight-message-unimportant-header-contents}) +$B$3$H$rI=$9(B face $B$r$=$l$>$l$I$N%a%C%;!<%8%X%C%@$K3d$jEv$F$k$+$r@_Dj$7$^$9!#(B +$BF1MM$K!"G$0U$N@55,I=8=$KBP$7$FG$0U$N(Bface$B$r3d$jEv$F$k$3$H$b$G$-$^$9!#(B + +@item wl-highlight-citation-prefix-regexp +@vindex wl-highlight-citation-prefix-regexp +$B%I%i%U%H$*$h$S%a%C%;!<%8$NK\J8Fb$N0zMQ9T$r<($9@55,I=8=$r;XDj$7$^$9!#(B +$B$3$N@55,I=8=$K%^%C%A$7$?K\J8$O!"(B +(@code{wl-highlight-message-cited-text-*})$B$G;XDj$5$l$k(Bface$B$G%O%$%i%$%H$5$l$^$9!#(B + +@item wl-highlight-highlight-citation-too +@vindex wl-highlight-highlight-citation-too +$B=i4|@_Dj$O(B nil$B!#(B +Non-nil $B$J$i(B@code{wl-highlight-citation-prefix-regexp}$B$GM?$($i$l$k(B +$B0zMQ9T$N0zMQ$r<($9@55,I=8=<+BN$b%O%$%i%$%H$NBP>]$H$7$^$9!#(B + +@item wl-highlight-citation-header-regexp +@vindex wl-highlight-citation-header-regexp +$B0zMQ$r;O$a$k$3$H$r<($9%X%C%@$N@55,I=8=$r;XDj$7$^$9!#(B +$B$3$N@55,I=8=$K%^%C%A$7$?K\J8$O!"(B +@code{wl-highlight-message-headers}$B$G;XDj$5$l$k(Bface$B$G%O%$%i%$%H$5$l$^$9!#(B + +@item wl-highlight-max-message-size +@vindex wl-highlight-max-message-size +$B=i4|@_Dj$O(B 10000$B!#(B +$B%a%C%;!<%8$,$3$NCM$h$jBg$-$$>l9g!"%a%C%;!<%8$N%O%$%i%$%H$r9T$$$^$;$s!#(B +$B$3$l$K$h$j(Buuencode$B$dHs>o$KBg$-$J%@%$%8%'%9%H$J$I$N(B +$B%O%$%i%$%H$NM^;_$r9T$$$^$9!#(B + +@item wl-highlight-signature-separator +@vindex wl-highlight-signature-separator +$B%7%0%K%A%c$N6-3&$rI=$9@55,I=8=$r;XDj$7$^$9!#(B +$B@55,I=8=$G$b!"@55,I=8=$N%j%9%H$G$b9=$$$^$;$s!#(B +$B$3$N@55,I=8=$K%^%C%A$7$?>l=j0J9_$N%a%C%;!<%8$O!"(B +@code{wl-highlight-message-signature}$B$G;XDj$5$l$k(Bface$B$G%O%$%i%$%H$5$l$^$9!#(B + +@item wl-max-signature-size +@vindex wl-max-signature-size +$B=i4|@_Dj$O(B 400$B!#(B +$B%7%0%K%A%c$r%O%$%i%$%H$9$k>l9g!"(B +$B%O%$%i%$%H$9$k:GBg$N%7%0%J%A%c$NBg$-$5$r;XDj$7$^$9!#(B + +@item wl-use-highlight-mouse-line +@vindex wl-use-highlight-mouse-line +$B=i4|@_Dj$O(B t$B!#(B +Non-nil $B$J$i%U%)%k%@%b!<%I!"%5%^%j%b!<%I$J$I$G(B +$B%^%&%9%]%$%s%?$N9T$r%O%$%i%$%H$NBP>]$H$7$^$9!#(B +@end table + +@subsection $BJ8;z$N?'!"%U%)%s%H$N@_Dj(B + +$BJ8;z$N?'$d!"%U%)%s%H$rJQ$($k$K$O!"(BWanderlust $B$GDj5A$5$l$F$$$k(B face $B$rJQ99(B +$B$9$kI,MW$,$"$j$^$9!#%U%)%s%H$rJQ$($?$$$H$-$O(B set-face-font$B!"?'$rJQ$($?$$$H(B +$B$-$O(B set-face-foreground $B$J$I$r;H$($P$h$$$G$7$g$&!#(Bface $B$N@_Dj$O(B @file{.emacs} $B$K(B +$B=q$/$3$H$O$G$-$J$$$N$G(B @file{~/.wl} $B$K=q$$$F$/$@$5$$!#(B + +$B$?$H$($P!"%7%0%K%A%c$N?'$r2+?'$KJQ$($?$$$H$-$O!"(B + +@lisp +(set-face-foreground 'wl-highlight-message-signature "yellow") +@end lisp + +@noindent +$B$r(B @file{~/.wl} $B$K=q$-$^$9!#(B + +$B0J2<$K(B Wanderlust $B$GDj5A$5$l$F$$$k(B face $B$K$D$$$F@bL@$7$^$9!#(B + +@table @code +@item wl-highlight-message-headers +$B%a%C%;!<%8%X%C%@$NL>A0ItJ,$N(B face $B$G$9!#(B + +@item wl-highlight-message-header-contents +$B%a%C%;!<%8%X%C%@$NFbMFItJ,$N(B face $B$G$9!#(B + +@item wl-highlight-message-important-header-contents +$B%a%C%;!<%8%X%C%@$NFbMF$N$&$A=EMW$JItJ,$N(B face $B$G$9!#(B +$B%G%U%)%k%H$G$O!"(BSubject $B$NFbMFItJ,$,@_Dj$5$l$F$$$^$9!#(B +$B$3$NCM$O(B @code{wl-highlight-message-header-alist} + $B$rJQ99$9$l$PJQ$($k$3$H$,$G$-$^$9!#(B + +@item wl-highlight-message-important-header-contents2 +$B%a%C%;!<%8%X%C%@$NFbMF$N$&$A=EMW$JItJ,$N(B face $B$=$N#2$G$9!#(B +$B%G%U%)%k%H$G$O!"(BFrom $B$H(B To $B$NFbMFItJ,$,@_Dj$5$l$F$$$^$9!#(B +$B$3$NCM$O(B @code{wl-highlight-message-header-alist} + $B$rJQ99$9$l$PJQ$($k$3$H$,$G$-$^$9!#(B + +@item wl-highlight-message-unimportant-header-contents +$B%a%C%;!<%8%X%C%@$NFbMF$N$&$A=EMW$G$O$J$$ItJ,$N(B face $B$G$9!#(B +$B%G%U%)%k%H$G$O!"(BX- $B$G;O$^$k%X%C%@$H(B User-Agent $B$NFbMFItJ,$,@_Dj$5$l$F$$$^$9!#(B +$B$3$NCM$O(B @code{wl-highlight-message-header-alist} + $B$rJQ99$9$l$PJQ$($k$3$H$,$G$-$^$9!#(B + +@item wl-highlight-message-citation-header +$B%a%C%;!<%8$N0zMQ%X%C%@ItJ,$N(B face $B$G$9!#(B + +@item wl-highlight-message-cited-text-* +$B%a%C%;!<%8$N0zMQ%F%-%9%HItJ,$N(B face $B$G$9!#(B +$B:G8e$K$O?t;z$,$D$-!"(B10 $BCJ3,$^$G0zMQ$4$H$K?'J,$1$G$-$k$h$&$K$7$F$$$^$9!#(B + +@item wl-highlight-message-signature +$B%a%C%;!<%8$N%7%0%K%A%cItJ,$N(B face $B$G$9!#(B +$B=i4|@_Dj$O!"L@?'%P%C%/$G$O(B khaki $B0E?'%P%C%/$G$O(B DarkSlateBule $B$G$9!#(B + +@item wl-highlight-header-separator-face +$B%I%i%U%H$N%a%C%;!<%8$N%X%C%@%;%Q%l!<%?$N(B face $B$G$9!#(B + +@item wl-highlight-summary-important-face +$B%5%^%j$G=EMW%^!<%/$N$D$$$?%a%C%;!<%89T$N(B face $B$G$9!#(B + +@item wl-highlight-summary-new-face +$B%5%^%j$G?75,%^!<%/$N$D$$$?%a%C%;!<%89T$N(B face $B$G$9!#(B + +@item wl-highlight-summary-displaying-face +$B%5%^%j$G8=:_I=<(Cf$N%a%C%;!<%89T$N(B face $B$G$9!#(B +$B$3$N(B face $B$O(B overlay $B$5$l$^$9!#(B + +@item wl-highlight-thread-indent-face +$B%5%^%j$G8=:_I=<(Cf$N%a%C%;!<%89T$N(B face $B$G$9!#(B + +@item wl-highlight-summary-unread-face +$B%5%^%j$GL$FI%^!<%/$N$D$$$?%a%C%;!<%89T$N(B face $B$G$9!#(B + +@item wl-highlight-summary-deleted-face +$B%5%^%j$G:o=|%^!<%/$N$D$$$?%a%C%;!<%89T$N(B face $B$G$9!#(B + +@item wl-highlight-summary-refiled-face +$B%5%^%j$G%j%U%!%$%k%^!<%/$N$D$$$?%a%C%;!<%89T$N(B face $B$G$9!#(B + +@item wl-highlight-refile-destination-face +$B%5%^%j$G%j%U%!%$%k%^!<%/$NIU$$$?%a%C%;!<%89T$N!"(B +$B%j%U%!%$%k@h>pJs$NItJ,$K$D$/(B face $B$G$9!#(B + +@item wl-highlight-summary-copied-face +$B%5%^%j$G%3%T!<%^!<%/$N$D$$$?%a%C%;!<%89T$N(B face $B$G$9!#(B + +@item wl-highlight-summary-target-face +$B%5%^%j$G0l;~=hM}MQ%^!<%/(B @samp{*} $B$N$D$$$?%a%C%;!<%89T$N(B face $B$G$9!#(B + +@item wl-highlight-summary-thread-top-face +$B%5%^%j$G%9%l%C%I%H%C%W$N%a%C%;!<%89T$N(B face $B$G$9!#(B + +@item wl-highlight-summary-normal-face +$B%5%^%j$G%9%l%C%I%H%C%W$G$O$J$$%a%C%;!<%89T$N(B face $B$G$9!#(B + +@item wl-highlight-folder-unknown-face +$B%U%)%k%@%b!<%I$G!"$$$/$DL$F14|%a%C%;!<%8$,$"$k$+$o$+$i$J$$%U%)%k%@$N(B + face $B$G$9!#(B + +@item wl-highlight-folder-zero-face +$B%U%)%k%@%b!<%I$G!"L$F14|%a%C%;!<%8$,$J$$%U%)%k%@$N(B face $B$G$9!#(B + +@item wl-highlight-folder-few-face +$B%U%)%k%@%b!<%I$G!"L$F14|%a%C%;!<%8$,$9$3$7$"$k%U%)%k%@$N(B face $B$G$9!#(B + +@item wl-highlight-folder-many-face +$B%U%)%k%@%b!<%I$G!"L$F14|%a%C%;!<%8$,$?$/$5$s$"$k%U%)%k%@$N(B face $B$G$9!#(B +$B!V$9$3$7!W$H!V$?$/$5$s!W$N@Z$lL\$O!"(B +$BJQ?t(B @code{wl-folder-many-unsync-threshold} $B$G@_Dj$5$l$^$9!#(B + +@item wl-highlight-folder-unread-face +$B%U%)%k%@%b!<%I$G!"L$F14|%a%C%;!<%8$,$J$/$FL$FI%a%C%;!<%8$,$"$k(B +$B%U%)%k%@$N(B face $B$G$9!#(B + +@item wl-highlight-folder-killed-face +$B%U%)%k%@%b!<%I$G!"%"%/%;%9%0%k!<%WCf$N:o=|$5$l$?%U%)%k%@$N(B face $B$G$9!#(B + +@item wl-highlight-folder-opened-face +$B%U%)%k%@%b!<%I$G!"3+$$$?%0%k!<%W$K$D$/(B face $B$G$9!#(B +$BJQ?t(B @code{wl-highlight-group-folder-by-numbers} $B$,(B nil $B$N$H$-M-8z$G$9!#(B + +@item wl-highlight-folder-closed-face +$B%U%)%k%@%b!<%I$G!"JD$8$?%0%k!<%W$K$D$/(B face $B$G$9!#(B +$BJQ?t(B @code{wl-highlight-group-folder-by-numbers} $B$,(B nil $B$N$H$-M-8z$G$9!#(B + +@item wl-highlight-folder-path-face +$B%U%)%k%@%b!<%I$G!"8=:_A*BrCf$N%U%)%k%@$^$G$N%Q%9$K$D$/(B face $B$G$9!#(B + +@item wl-highlight-logo-face +$B%G%b$G%m%4$K$D$/(B face $B$G$9!#(B + +@item wl-highlight-demo-face +$B%G%b$NJ8;zNs(B($B%P!<%8%g%sHV9f$J$I(B)$B$K$D$/(B face $B$G$9!#(B +@end table + + +@node Advanced Settings, Customizable Valiables, Highlights, Customization +@section $B%+%9%?%^%$%:!A1~MQJT!A(B + +@menu +* Draft for Reply:: $BJV;vMQ%I%i%U%H(B +* Thread Format:: $B%9%l%C%I$N8+$?L\(B +* User-Agent Header:: User-Agent $B%X%C%@(B +@end menu + + +@node Draft for Reply, Thread Format, Advanced Settings, Advanced Settings +@subsection $BJV;vMQ%I%i%U%H(B + +Mailng List $B$N5-;v$KJV;v$r=q$/$H$-$O!"%5%^%j%b!<%I$G(B @kbd{a} $B$r2!$7$?$@$1$G(B +$B855-;v$N(B Reply-To $B$K$"$k%"%I%l%9$r(B To $B$KMQ0U$7$F$[$7$$!"$H$$$&>l9g$O!"(B +$B0J2<$N$h$&$K$7$?$i$h$$$G$7$g$&!#(B + +@lisp +(setq wl-draft-reply-without-argument-list + '(("Mail-Followup-To" . (("Mail-Followup-To") nil ("Newsgroups"))) + ("Followup-To" . (nil nil ("Followup-To"))) + (("X-ML-Name" "Reply-To") . (("Reply-To") nil nil)) + ("From" . (("From") ("To" "Cc") ("Newsgroups"))))) +@end lisp + +@noindent +("X-ML-Name" $B%U%#!<%k%I5Z$S(B "Reply-To" $B%U%#!<%k%I$NN>J}$,855-;v$K(B +$BB8:_$9$k>l9g$@$1(B To: $B$K855-;vCf$N(B Reply-To: $B%U%#!<%k%I$,=`Hw$5$l$^$9!#(B) + +@c @noindent +@c ($B:G8e$N9T$N0UL#$O!"(BTo: $B$K855-;vCf$N(B From $B%U%#!<%k%I$,!"(BCc: $B$K855-;v$N(B +@c To $B%U%#!<%k%I$*$h$S(B Cc $B%U%#!<%k%I!"$=$7$F(B Newsgroups: $B$K855-;v$N(B +@c Newsgroups $B%U%#!<%k%I$,$=$l$>$l(B ($B$"$l$P(B) $B=`Hw$5$l$k$H$$$&$3$H$G$9!#(B) + + +@node Thread Format, User-Agent Header, Draft for Reply, Advanced Settings +@subsection $B%9%l%C%I$N8+$?$a(B + +@example + 389 09/18($B6b(B)01:07 [ $B$F$i$K$7(B ] wl-0.6.3 + 390 09/18($B6b(B)07:25 +-[ $BDEM8$5$s(B ] + 391 09/18($B6b(B)19:24 +-[ $BB$5$s(B ] + 396 09/20($BF|(B)22:11 | +-[ $BDEM8$5$s(B ] + 398 09/21($B7n(B)00:17 | +-[ $BDEM8$5$s(B ] + 408 09/21($B7n(B)22:37 | +-[ $B1|@>$5$s(B ] + 411 09/22($B2P(B)01:34 | +-[ $BDEM8$5$s(B ] + 412 09/22($B2P(B)09:28 | +-[ $B$F$i$K$7(B ] + 415 09/22($B2P(B)11:52 | +-[ $BDEM8$5$s(B ] + 416 09/22($B2P(B)12:38 | +-[ $B$F$i$K$7(B ] + 395 09/20($BF|(B)21:49 +-[ $B1|@>$5$s(B ] + 397 09/21($B7n(B)00:15 +-[ $B1|@>$5$s(B ] +@end example + +$B%9%l%C%I$N8+$?$a$r>e5-$N$h$&$K$7$?$$>l9g$N@_Dj$O0J2<$NDL$j$G$9!#(B + +@lisp +(setq wl-thread-indent-level 2) +(setq wl-thread-have-younger-brother-str "+") +(setq wl-thread-youngest-child-str "+") +(setq wl-thread-vertical-str "|") +(setq wl-thread-horizontal-str "-") +(setq wl-thread-space-str " ") +@end lisp + +$B;^$rI=<($7$J$$$h$&$K$7$?$$>l9g$N@_Dj$O0J2<$N$h$&$K$7$^$9!#(B + +@lisp +(setq wl-thread-indent-level 2) +(setq wl-thread-have-younger-brother-str " ") +(setq wl-thread-youngest-child-str " ") +(setq wl-thread-vertical-str " ") +(setq wl-thread-horizontal-str " ") +(setq wl-thread-space-str " ") +@end lisp + +@node User-Agent Header, , Thread Format, Advanced Settings +@subsection User-Agent + + X-Mailer $B%U%#!<%k%I$d(B User-Agent $B%U%#!<%k%I$K6E$j$?$$$H$$$&(B +$BJQ$o$C$?$R$H$O!"E,Ev$KJ8;zNs$r(B insert $B$9$k4X?t$r<+J,$N9%$-$J$h$&$KDj5A$7$F(B +@code{wl-generate-mailer-string-func} $B$K@_Dj$7$F$/$@$5$$!#(B + +$B0J2<$O@_Dj$N0lNc$G$9!#(B + +@lisp +(setq wl-generate-mailer-string-func + (function + (lambda () + (concat "X-Mailer: " + (format "%s/%s (%s)" wl-appname wl-version wl-codename))))) +@end lisp + + +@node Customizable Valiables, , Advanced Settings, Customization +@section $B$=$NB>$N%+%9%?%^%$%:JQ?t0lMw(B + +$B$=$NB>$N%+%9%?%^%$%:JQ?t0lMw!#(B + +@table @code +@item wl-default-folder +@vindex wl-default-folder +$B=i4|@_Dj$O(B "%inbox"$B!#%U%)%k%@0\F0;~$J$I$N%G%U%)%k%HCM$H$J$j$^$9!#(B + +@item wl-draft-folder +@vindex wl-draft-folder +$B=i4|@_Dj$O(B "+draft"$B!#%I%i%U%H$r%;!<%V$9$k%U%)%k%@$G$9!#(B +localdir $B%U%)%k%@$G$"$kI,MW$,$"$j$^$9!#(B + +@item wl-trash-folder +@vindex wl-trash-folder +$B=i4|@_Dj$O(B "+trash"$B!#%4%_H"%U%)%k%@$G$9!#(B +$B$3$NCM$rJQ99$7$?$H$-$O(B Wanderlust $B$r:F5/F0$9$k$3$H$r$*4+$a$7$^$9!#(B + +@item wl-interactive-exit +@vindex wl-interactive-exit +$B=i4|@_Dj$O(B t$B!#(B +Non-nil $B$J$i$P!"(BWanderlust $B=*N;;~$K3NG'$r9T$$$^$9!#(B + +@item wl-interactive-send +@vindex wl-interactive-send +$B=i4|@_Dj$O(B nil$B!#(B +Non-nil $B$J$i$P!"%a!<%kAw?.;~$KK\Ev$KAw?.$7$F$h$$$+$r3NG'$7$^$9!#(B + +@item wl-folder-sync-range-alist +@vindex wl-folder-sync-range-alist +$B=i4|@_Dj$O!"0J2<$NCM!#(B +@example +(("^&.*$" . "all") + ("^\\+draft$\\|^\\+queue$" . "all")) +@end example +$B%U%)%k%@L>$N@55,I=8=$H%U%)%k%@0\F0;~$N%5%^%j99?7%l%s%8O"A[%j%9%H$G$9!#(B +$B99?7%l%s%8$K$O(B wl-summary-sync $B$GF~NO$G$-$kCM$N$$$:$l$+(B +(all, update, rescan, rescan-noscore, first, last) $B$r;XDj$7$^$9!#(B +$B%^%C%A$7$J$+$C$?>l9g$O!"(Bupdate $B$H$J$j$^$9!#(B + +@item wl-ask-range +@vindex wl-ask-range +$B=i4|@_Dj$O(B t$B!#(B +nil $B$J$i!"(Bfolder $B0\F0;~$N%5%^%j99?7$G(B @code{wl-folder-sync-range-alist} $B$NCM$r(B +$B;HMQ$7$^$9!#(B + +@item wl-mime-charset +@vindex wl-mime-charset +$B=i4|@_Dj$O(B 'x-ctext$B!#(B +MIME $B$G$O$J$$%a%C%;!<%8$N>l9g(B (Content-Type $B$,$J$$%a!<%k$J$I(B) $B$d!"(B +$B%5%^%j$NI=<($GMQ$$$i$l$k(B MIME charset $B$G$9!#(B +(Nemacs $B$H$=$NB>$N(B Emacs $B$G%5%^%j$r6&M-$7$?$$>l9g$O!"(B +$B$3$NCM$r(B 'iso-2022-jp $B$H$7$F$/$@$5$$!#(B) + +@item wl-search-mime-charset +@vindex wl-search-mime-charset +$B=i4|@_Dj$O(B 'iso-2022-jp$B!#(B +$B8!:w$GMQ$$$k(B MIME charset $B$G$9!#(B + +@item wl-highlight-folder-with-icon +@vindex wl-highlight-folder-with-icon +XEmacs $B$N$_M-8z$G$9!#=i4|@_Dj$O(B XEmacs $B$K0MB8$7$^$9(B($B%"%$%3%s$r;HMQ$G$-$k(BXEmacs $B$G$O(B t $B$K$J$j$^$9(B)$B!#(B + +@item wl-strict-diff-folders +@vindex wl-strict-diff-folders +$B%U%)%k%@L>$N@55,I=8=$N%j%9%H$G$9!#(B +$B%U%)%k%@%b!<%I$G(B @kbd{s} $B$r2!$9$J$I$7$FL$FI$N%a%C%;!<%8?t$r(B +$B%A%'%C%/$7$?>l9g!"DL>o$O4J0WE*$JJ}K!$G%A%'%C%/$7$F$$$^$9(B($B=hM}$OB.$$$,!"@53N$G$O$J$$(B)$B!#(B +$B$3$NJQ?t$K%^%C%A$9$k%U%)%k%@$O$^$8$a$K%A%'%C%/$7$^$9!#(B +IMAP4 $B%U%)%k%@$KBP$9$k>r7o%U%#%k%?%U%)%k%@$N$h$&$J>l9g$K$O!"(B +$B$3$NJQ?t$K%^%C%A$9$k$h$&@_Dj$9$k$H$h$$$G$7$g$&!#(B +$B=i4|@_Dj$O(B nil$B!#(B + +@item wl-folder-use-server-diff +@vindex wl-folder-use-server-diff +$B%U%)%k%@%b!<%I$G(B @kbd{s} $B$r2!$9$J$I$7$FL$FI$N%a%C%;!<%8?t$r%A%'%C%/$7$?(B +$B>l9g!"DL>o$O(B($B%5!<%P>e$N%a%C%;!<%8?t(B)$B!](B($B%m!<%+%k$K$"$k%a%C%;!<%8?t(B)$B$,L$FI(B +$B$H$_$J$5$l$^$9!#$7$+$7!"$3$NJQ?t$,(BNon-nil $B$J$i$P!"%5!<%P>e$NL$FI$N%a%C%;!<(B +$B%8?t$r%A%'%C%/$7$^$9!#(BIMAP4 $B%U%)%k%@$K$N$_1F6A$,$"$j$^$9!#$?$@$7!"JQ?t(B +@code{elmo-imap4-disuse-server-flag-mailbox-regexp} $B$K%^%C%A$9$k%a!<%k%\%C%/%9(B +$B$N(B IMAP4 $B%U%)%k%@$O!"$3$NJQ?t$K%^%C%A$7$F$b%5!<%P>e$NL$FI$N%a%C%;!<%8?t(B +$B$r%A%'%C%/$7$^$;$s!#=i4|@_Dj$O(B t$B!#(B + +@item wl-auto-check-folder-name +@vindex wl-auto-check-folder-name +$B=i4|@_Dj$O(B nil$B!#(B +Non-nil $B$J$i$P!"@_Dj$5$l$?CM$r;}$D%U%)%k%@$NL$FI?t$r5/F0;~$K%A%'%C%/$7$^$9!#(B +'none $B$J$i$P!"5/F0;~$K%A%'%C%/$7$^$;$s!#(B +list $B$J$i$P!"(Blist $B$K@_Dj$5$l$?A4$F$N%U%)%k%@$r5/F0;~$K%A%'%C%/$7$^$9!#(B + +@item wl-auto-uncheck-folder-list +@vindex wl-auto-uncheck-folder-list +$B=i4|@_Dj$O(B '("\\$.*")$B!#(B +@code{wl-auto-check-folder-name} $B$K;XDj$5$l$?%0%k!<%W$K4^$^$l$F$$$F$b(B +$B5/F0;~$KL$FI%A%'%C%/$7$J$$%U%)%k%@L>$N@55,I=8=$N%j%9%H$G$9!#(B + +@item wl-auto-check-folder-list +@vindex wl-auto-check-folder-list +$B=i4|@_Dj$O(B nil$B!#(B +@code{wl-auto-check-folder-name} $B$K;XDj$5$l$?%0%k!<%W$K4^$^$l$F$$$?$i(B +$B5/F0;~$KI,$:L$FI%A%'%C%/$9$k%U%)%k%@L>$N@55,I=8=$N%j%9%H$G$9!#(B +@code{wl-auto-uncheck-folder-list} $B$h$j$bM%@h$7$^$9!#(B + +@item wl-no-save-folder-list +@vindex wl-no-save-folder-list +$B=i4|@_Dj$O(B '("^/.*$")$B!#(B +$B%;!<%V$7$J$$%U%)%k%@L>$N@55,I=8=$N%j%9%H$G$9!#(B + +@item wl-save-folder-list +@vindex wl-save-folder-list +$B=i4|@_Dj$O(B nil$B!#(B +$B%;!<%V$9$k%U%)%k%@L>$N@55,I=8=$N%j%9%H$G$9!#(B +@code{wl-no-save-folder-list} $B$h$j$bM%@h$7$^$9!#(B + +@item wl-folder-mime-charset-alist +@vindex wl-folder-mime-charset-alist +$B=i4|@_Dj$O0J2<$N%j%9%H!#(B + +@lisp +'(("^-alt\\.chinese" . big5) + ("^-relcom\\." . koi8-r) + ("^-tw\\." . big5) + ("^-han\\." . euc-kr) + ) +@end lisp + +$B%U%)%k%@L>$N@55,I=8=$H(B MIME charset $B$NO"A[%j%9%H$G$9!#(B +$B%^%C%A$7$J$+$C$?>l9g$O(B @code{wl-mime-charset} $B$,;H$o$l$^$9!#(B + +@item wl-folder-init-load-access-folders +@vindex wl-folder-init-load-access-folders +$B=i4|@_Dj$O(B nil$B!#(B +$B=i4|2=;~$KFCDj$N%"%/%;%9%0%k!<%W$N$_%m!<%I$9$k>l9g$K!"$=$N%0%k!<%W$N%j(B +$B%9%H$r;XDj$7$^$9!#(B +nil$B$N>l9g$O(B @code{wl-folder-init-no-load-access-folders} $B$,;2>H$5$l$^$9!#(B + +@item wl-folder-init-no-load-access-folders +@vindex wl-folder-init-no-load-access-folders +$B=i4|@_Dj$O(B nil$B!#(B +$B=i4|2=;~$KFCDj$N%"%/%;%9%0%k!<%W$r=|$$$F%m!<%I$9$k>l9g$K!"%m!<%I$7$J$$(B +$B%"%/%;%9%0%k!<%W$N%j%9%H$r;XDj$7$^$9!#(B +@code{wl-folder-init-load-access-folders} $B$,(B non-nil $B$N>l9g$OL5;k$5$l$^$9!#(B + +@item wl-delete-folder-alist +@vindex wl-delete-folder-alist +$B=i4|@_Dj$O(B '(("^-" . remove))$B!#(B +delete mark $B$r$D$1$?%a%C%;!<%8$r:o=|$9$kJ}?K$r@_Dj$7$^$9!#(B +$B%j%9%H$N3FMWAG$O%U%)%k%@$H:o=|@h$K$J$C$F$*$j!":o=|@h$K$O(B : `wl-trash-folder'$B$K0\F0$9$k!#(B +@end example + +@item wl-refile-policy-alist +@vindex wl-refile-policy-alist +$B=i4|@_Dj$O(B '(("^[-=]" . copy) (".*" . move))$B!#(B +refile mark $B$r$D$1$k:]!"%a%C%;!<%8$r0\F0$9$k$+%3%T!<$9$k$+$r;XDj$7$^$9!#(B +$B%j%9%H$N3FMWAG$K$O%U%)%k%@$H(B copy $B$^$?$O(B move $B$N(B cons cell $B$r;XDj$7$^$9!#(B + +@item wl-x-face-file +@vindex wl-x-face-file +$B=i4|@_Dj$O(B "~/.xface"$B!#(B +Encode $B:Q$_$N(B X-Face $BJ8;zNs$rFbMF$H$9$k%U%!%$%kL>$G$9!#(B +@xref{x-face-mule}. + +@item wl-demo-display-logo +@vindex wl-demo-display-logo +Non-nil $B$J$i$P%*!<%W%K%s%0%G%b$G%S%C%H%^%C%W$N%$%a!<%8$rI=<($7$^$9!#(B + +@item elmo-use-database +@vindex elmo-use-database +XEmacs $B$N$_M-8z$G$9!#=i4|@_Dj$O!"(BXEmacs $B$K0MB8$7$^$9!#(B +(dbm $B$N5!G=$r$b$D(B XEmacs $B$J$i$P(B t $B$H$J$j$^$9!#(B) +Non-nil $B$J$i$P(B dbm $B$r;H$C$F(B Message-ID $B$N4IM}$r9T$J$$$^$9!#(B + +@item elmo-passwd-alist-file-name +@vindex elmo-passwd-alist-file-name +$B=i4|@_Dj$O(B "passwd"$B!#(B +$B%Q%9%o!<%I$r%;!<%V$7$F$*$/%U%!%$%k$NL>A0$G$9!#(B +$B%3%^%s%I(B @code{elmo-passwd-alist-save} $B$rl9g$O(B t $B$K$7$F$/$@$5$$!#(B +@c non-nil means? + +@item elmo-nntp-default-use-listgroup +@vindex elmo-nntp-default-use-listgroup +$B=i4|@_Dj$O(B t$B!#(B +NNTP $B$K$*$$$F(B $BAm5-;v?t$rD4$Y$k$?$a$K!"(B@samp{listgroup} $B$r;H$&!#(B +nil $B$J$i$P(B @samp{group} $B$N7k2L$rMQ$$$^$9!#(B +@samp{group} $B$r;H$&$H!"@53N$5$K$O7g$1$^$9$,!"pJs$rl9g$,$"$k$h$&$G$9!#(B +POP3 $B;2>H;~$K=hM}$,%O%s%0$9$k$h$&$J>l9g$O!"(Bt$B$K$9$k$H$$$$$+$b$7$l$^$;$s!#(B + +@item elmo-dop-flush-confirm +@vindex elmo-dop-flush-confirm +$B=i4|@_Dj$O!"(Bt$B!#(B +Non-nil $B$J$i$P%*%U%i%$%s=hM}$GN/$C$?=hM}$r} +@end display + +Wanderlust $B$K4X$9$k5DO@$O$3$N%a%$%j%s%0%j%9%H$G9T$o$l$^$9!#(B +$B:G?7%P!<%8%g%s$N%"%J%&%s%9$b$3$A$i$KN.$l$^$9!#(B + +@t{wl-ctl@@lists.airs.net} $B08$N%a!<%k$NK\J8$K!"(B + +@example +# guide +@end example + +@noindent +$B$H=q$$$?%a!<%k$rAw$k$HF~2q$N%,%$%I$,<+F0E*$K$b$i$($^$9!#(B + +$B%P%0Js9p$d%Q%C%A$NAwIU$b$3$A$i$N%a!<%j%s%0%j%9%H$XAw$C$F$/$@$5$$!#(B +$B%a!<%j%s%0%j%9%H$N%a%s%P$G$J$/$H$b!"Aw?.$G$-$k@_Dj$K$J$C$F$$$^$9!#(B + +$B%a!<%j%s%0%j%9%H$N3'MM$K$O5.=E$J8f=u8@!"(B +$B%3!<%I$r$?$/$5$s8fDs6!$$$?$@$$$F$*$j$^$9!#(B +$B$3$N>l$re$2$^$9!#(B + +@c +@c Addition +@c +@node Addition, Index, Mailing List, Top +@chapter $B$*$^$1(B + +@section $BN,Nr(B + +@example +1998 3/05 MH $B%a%C%;!<%8$r%9%l%C%II=<($9$k%W%m%H%?%$%W$r:n$C$F$_$k!#(B + 3/10 elisp $B$K$h$k(B msgdb $B$N$7$/$_$r$D$/$k!#(B + 3/26 IMAP $B$H(B NNTP $B$b%9%l%C%II=<($G$-$k$h$&$K$J$k!#(B + 4/13 $B%9%l%C%II=<(MQ%b%8%e!<%k$r(B elmo $B$H$7$F$^$H$a$O$8$a$k!#(B + 5/01 0.1.0 $B%\%m%\%m$N(B initial version $B$,40@.!#(B + 6/12 tm-ja ML $B$G!"(BIMAP $BBP1~$N(B elisp $B%a!<%i$r:n$C$F$$$k!"(B + $B$H$D$$8}$r3j$Y$i$;$F$7$^$&!#(B + 6/16 tm-ja, elips ML $B$G(B 0.1.3 $B$r%"%J%&%s%9!#(B + 6/22 $BKLL\$5$s$N$*$+$2$G(B northeye.org $B$G%a!<%j%s%0%j%9%H$,%9%?!<%H!#(B + 7/01 mm-backend $BBP1~(B(0.3.0)$B!#(B + 8/25 multi $B%U%)%k%@DI2C(B(0.5.0)$B!#(B + 8/28 filter $B%U%)%k%@DI2C(B(0.5.1)$B!#(B + 9/10 $B%9%l%C%I$,3+JD$G$-$k$h$&$K$J$k(B(0.6.0)$B!#(B + 9/11 fldmgr by $BB$5$s(B(0.6.3)$B!#(B + 9/24 $B%9%l%C%I$N;^$rI=<((B(0.6.5)$B!#(B + 9/28 $B05=L%U%)%k%@$,%^%k%A%"!<%+%$%P$KBP1~(B by $B1|@>$5$s!#(B + 10/28 $B%*%U%i%$%s=hM}(B (0.7.4)$B!#(B + 12/09 $B%Y!<%?%P!<%8%g%s$K!#(B + 12/21 wl-expire by $BBA0(B + +Wanderlust $B$K$O!"8&5f(B $BJ|O2JJ!$(B $BN99TG.!$(B $BN9?4!'(B have $B!A(B $BJ|O2JJ$,$"$k!%(B +@end display + +@noindent +$B$H$$$&0UL#$,$"$j$^$9!#$,!"L>A0$K$?$$$7$F?<$$0U?^$O$"$j$^$;$s!#(B +($B6/$$$F8@$($P!"(BIMAP @t{=>} $B$I$3$G$b%a!<%k$,FI$a$k(B @t{=>} $BJ|O2JJ(B ?) + +elmo $B$O!"(B@samp{Elisp Library for Message Orchestration} $B$NN,$G$9!#(B +$B:G=i$O$"$N@V$$$L$$$0$k$_$N$D$b$j$G$7$?$,!"(B +$BJ|O2(B @t{=>} $BI:N.(B @t{=>} $BF;I8(B @t{=>} St.@: Elmo's fire @t{=>} elmo $B$H$$$&!"(B +$B$=$l$C$]$$O"A[$b2DG=$G$9!#(B + +@section $B%3!<%I%M!<%`(B + +$B3F%P!<%8%g%s$K$O%3!<%I%M!<%`$,$D$$$F$$$^$9(B($B$[$H$s$I>iCL$G$9(B)$B!#(B +$B$$$^$N$H$3$m(B 1980 $BG/Be$NJF%S%k%\!<%I;o%H%C%W(B 40 $B%R%C%H(B + +(@samp{http://www.summer.com.br/~pfilho/html/top40/index.html}) + +$B$+$i%"%k%U%!%Y%C%H=g$KE,Ev$K9%$-$J$b$N$r%T%C%/%"%C%W$7$F;H$C$F$$$^$9!#(B + + +@node Index, , Addition, Top +@unnumbered $B:w0z(B + +@menu +* Concept Index:: $B35G0:w0z(B +* Key Index:: $B%-!<%P%$%s%I:w0z(B +* Variable Index:: $BJQ?t:w0z(B +* Function Index:: $B4X?t:w0z(B +@end menu + +@node Concept Index, Key Index, Index, Index +@unnumberedsec $B35G0:w0z(B +@printindex cp + +@node Key Index, Variable Index, Concept Index, Index +@unnumberedsec $B%-!<%P%$%s%I:w0z(B +@printindex ky + +@node Variable Index, Function Index, Key Index, Index +@unnumberedsec $BJQ?t:w0z(B +@printindex vr + +@node Function Index, , Variable Index, Index +@unnumberedsec $B4X?t:w0z(B +@printindex fn + +@summarycontents +@contents +@bye diff --git a/doc/wl.texi b/doc/wl.texi new file mode 100644 index 0000000..dd54aaf --- /dev/null +++ b/doc/wl.texi @@ -0,0 +1,6031 @@ +\input texinfo @c -*-texinfo -*- coding: iso-2022-jp -*- +@c %**start of header +@setfilename wl.info +@settitle Wanderlust -- Yet Another Message Interface On Emacsen -- +@c @documentlanguage en +@c %**end of header +@c texinfo of Wanderlust +@set Time-stamp: <2000-04-03 14:30:38 teranisi> +@set version 1.1.0 +@synindex pg cp +@finalout + +@direntry +* Wanderlust: (wl). Yet Another Message Interface On Emacsen +@end direntry + +@c permissions text appears in an Info file before the first node. +@ifinfo +This file documents Wanderlust, +Yet another message interface on Emacsen. + +Copyright @copyright{} 1998, 1999, 2000 @w{Yuuichi Teranishi}. +@c Copyright @copyright{} 1998, 1999, 2000 @w{Yuuichi Teranishi}, @* +@c @w{Fujikazu Okunishi}, @w{Masahiro Murata}, +@c @w{Kenichi Okada}, @w{Kaoru Takahashi}, @w{Bun Mizuhara} +and @w{Masayuki Osada}. + +This edition is for Wanderlust version @value{version}. + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +@ignore +Permission is granted to process this file through TeX and print the +results, provided the printed document carries copying permission +notice identical to this one except for the removal of this paragraph +(this paragraph not being relevant to the printed manual). + +@end ignore +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the entire +resulting derived work is distributed under the terms of a permission +notice identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions. + +@end ifinfo + +@titlepage +@sp 10 +@title Wanderlust User's Manual (ver. @value{version}) +@author Yuuichi Teranishi +@author Fujikazu Okunishi +@author Masahiro Murata +@author Kenichi Okada +@author Kaoru Takahashi +@author Bun Mizuhara +@author Masayuki Osada +@page + +@vskip 0pt plus 1filll +Copyright @copyright{} 1998, 1999, 2000 @w{Yuuichi Teranishi}. +@c Copyright @copyright{} 1998, 1999, 2000 @w{Yuuichi Teranishi}, @* +@c @w{Fujikazu Okunishi}, @w{Masahiro Murata}, +@c @w{Kenichi Okada}, @w{Kaoru Takahashi}, +@c @w{Bun Mizuhara} and @w {Masayuki Osada} + +This manual is for Wanderlust version @value{version}. + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the entire +resulting derived work is distributed under the terms of a permission +notice identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions. + +@end titlepage + + +@c +@c Top +@c +@ifinfo +@node Top, Introduction, (dir), (dir) +@top Wanderlust User's Manual + +@flushright +Yuuichi Teranishi +Fujikazu Okunishi +Masahiro Murata +Kenichi Okada +Kaoru Takahashi +Bun Mizuhara +Masayuki Osada +Last Modified@value{Time-stamp:} +@end flushright + +This manual is for Wanderlust@value{version}. + +@end ifinfo + +@menu +* Introduction:: Read this first. +* Start Me Up:: Invoking Wanderlust. +* Folders:: How to specify folders. +* Folder:: Selecting and editing folders. +* Summary:: Reading and refiling messages. +* Message:: Saving and playing MIME multipart entities. +* Draft:: Draft buffer, sending mail and news. +* Disconnected Operations:: Off-Line management +* Expire and Archive:: Automatic expiration and archiving of messages. +* Scoring:: Score of the messages. +* Customization:: Customizing Wanderlust. +* Mailing List:: Wanderlust mailing list +* Addition:: Additional Information +* Index:: Key index. +@end menu + + +@c +@c Introduction +@c +@node Introduction, Start Me Up, Top, Top +@chapter Introduction of Wanderlust +@cindex Introduction + +Wanderlust is an mail/news management system on Emacsen. +It supports IMAP4rev1(RFC2060), NNTP, POP and local message files. + +The main features of Wanderlust: + +@itemize @minus +@item Pure elisp implementation. +@item Supports IMAP4rev1, NNTP, POP(POP3/APOP), MH and Maildir format. +@item Unified access method to messages based on Mew-like Folder Specification. +@item Mew-like Key-bind and mark handling. +@item Manages unread messages. +@item Interactive thread display. +@item Folder Mode shows the list of subscribed folders. +@item Message Cache, Disconnected Operation (Read Only). +@item MH-like FCC. (FCC: %Backup and FCC: $Backup is allowed). +@item MIME compliant (by SEMI or tm). +@item Transmission of news and mail are unified by Message transmitting draft. +@item Graphical list of folders (XEmacs). +@item View a part of message without retrieving the whole message (IMAP4). +@item Server-side message look up (IMAP4). Multi-byte characters are allowed. +@item Virtual Folders. +@item Supports compressed folder using common archiving utilities. +@item Old articles in folders are automatically removed/archived (Expiration). +@item Automatic re-file. +@item Template function makes it convenient to send fixed form messages. +@end itemize + +Wanderlust is supposed to run on Mules based on Emacs 19.28, 19.34, +Emacs 20.2 or later, XEmacs 20.4 or later, Meadow 1.00 or later(on MS Windows), +Mule for Windows v1.22 (on MS Windows), NTEmacs(Windows NT). +PMMule on OS/2 is also supported. Wanderlust runs even on Nemacs 3.3.2 +based on Emacs 18.55, 18.59 (with limited functionality). + +IMAP4 connectivity with UW imapd 4.2, 4.3, 4.4, 4.5, 4.6, 4.7, 4.7a, +Cyrus imapd 1.4, Cyrus imapd 1.5.19, AIR MAIL(AIRCimapd release 2.00) +and ExpressMail are confirmed to work with Wanderlust. + +@c +@c Start Me Up +@c +@node Start Me Up, Folders, Introduction, Top +@chapter Start up Wanderlust +@cindex Start up + + +The necessary procedure for starting Wanderlust is explained in steps here. + +(Of course, you need a mail/news readable environment in advance) + +@menu +* MIME Modules:: Installing the MIME modules. +* Download:: Download and extract the packages. +* Install:: Byte-compile and install. +* Minimal Settings:: @file{.emacs} setup. +* Mail Addresses:: Address book definition. +* Folder Definition:: Folder definition. +* Start Wanderlust:: Starting Wanderlust +@end menu + + +@node MIME Modules, Download, Start Me Up, Start Me Up +@section Installing MIME modules +@cindex MIME modules +@pindex APEL +@pindex FLIM +@pindex SEMI +@pindex tm + +SEMI or tm must be installed to make Wanderlust work correctly. + +SEMI does not run on Emacs19.28 or earlier +@footnote{SEMI runs on Emacs 19.34. @* +@samp{http://www.jpl.org/elips/INSTALL-SEMI-ja.html} describes how to.}, +so you must install tm, the predecessor of SEMI. (tm version 8.7 or later +is needed.) + +However, SEMI is recommended because of its wider functionality. +Partial download function in IMAP4 is enabled only when SEMI is installed. + +Refer to the documents of each package for detailed installation procedure. + +SEMI and tm can be downloaded from these sites: + +@example +SEMI: ftp://ftp.m17n.org/mule/semi/ +tm: http://cvs.m17n.org/tomo/comp/emacsen/tm/tm-8/ +@end example + +You need packages named APEL and FLIM to use SEMI. +You can download FLIM and APEL from following URLs. + +@example +FLIM: ftp://ftp.m17n.org/mule/flim/ +APEL: ftp://ftp.m17n.org/mule/apel/ +@end example + +You have to install APEL, FLIM and SEMI in this order. +Generally @samp{make install} will do the job. +(In XEmacs 21, @samp{make install-package}.) + +Recommended combination of APEL, FLIM and SEMI are: + +@itemize @minus +@item APEL 10.2, FLIM 1.12.7 and SEMI 1.13.4 +@item APEL 10.2, FLIM 1.13.2 and SEMI 1.13.7 +@end itemize + +Combination of APEL 10.2 and FLIM 1.12.7 makes following error +while compiling FLIM 1.12.7. + +@example +Please install latest APEL 7.3 or later. +@end example + +In this case, please comment out following lines in FLIM-CFG. + +@example +(or (fboundp 'write-region-as-binary) + (error "Please install latest APEL 7.3 or later.")) +(or (fboundp 'insert-file-contents-as-binary) + (error "Please install latest APEL 7.3 or later.")) +@end example + +You can also use many other FLIM/SEMI variants. Combination of the +latest versions should work. For example, following combination is +confirmed to work. + +@itemize @minus +@item APEL 10.2, Chao 1.14.1 and REMI 1.14.1 +@end itemize + +@c You have to re-install Wanderlust +@c if you upgraded APEL, FLIM, SEMI or tm. + +@node Download, Install, MIME Modules, Start Me Up +@section Download and Extract the Package +@cindex Download + +You can download Wanderlust package from following sites: + +Original site: +@example +ftp://ftp.gohome.org/wl/ +@end example + +Mirrored ftp/http sites: + +@example +ftp://ftp.jaist.ac.jp/pub/GNU/elisp/ftp.gohome.org/wl/ +ftp://daidai.kuis.kyoto-u.ac.jp/pub/mirror/ftp.gohome.org/pub/elisp/wl/ +http://www.jpl.org/elips/ +http://www.ring.gr.jp/archives/text/elisp/wl/ +ftp://ftp.ring.gr.jp/pub/text/elisp/wl/ +ftp://opaopa.org/pub/mirror/elisp/wl/ +@end example + +Extract the obtained package to your working directory: + +@example +% cd ~/work +% tar zxvf wl-(@var{version}).tar.gz +% cd wl-(@var{version}) +@end example + +@subsection To use SSL (Secure Socket Layer) + +SSL (Secure Socket Layer) can be used for +SMTP, IMAP, NNTP and POP connections in Wanderlust. + +There are two ways to use SSL. One is to start SSL negotiation just after +the connection establishment (generic way). +The other one is to start SSL negotiation by invoking STARTTLS command in +the each session. + +To use the formar SSL (generic SSL), you must install @file{ssl.el} in the +@file{utils} directory. OpenSSL command @file{openssl} is also required +to use @file{ssl.el}. You must set PATH to the directory that OpenSSL +commands are installed. + +To use the latter SSL(STARTTLS), you must install starttls package in +addition to above. +You can download starttls package from the following site. + +@example +ftp://opaopa.org/pub/elisp/ +@end example + +@node Install, Minimal Settings, Download, Start Me Up +@section Byte-compile and install +@cindex Byte-compile +@cindex Compile +@cindex Install +@cindex Makefile +@cindex Make + +@subsection Installation + +Edit @code{LISPDIR} and @code{EMACS} in @file{Makefile}. +Set the Emacs's command name to @code{EMACS}. +Set package installation directory to @code{LISPDIR}. +Then, please execute following commands. + +@example +% make +% make install +@end example + +Destination directory is auto-probed if you leave @code{LISPDIR} +in @file{Makefile} as is. (That is, leave it as NONE) + +If you are using an Emacs variant which does not merge specified directory +to load-path (e.g. Mule 2.3 based on Emacs 19.28), +then you will see the error message: + +@example +Cannot open load file: mime-setup +@end example + +@noindent +In this case, either add destination directories of custom, apel, flim and semi +to environmental variable EMACSLOADPATH, or define load-path in @file{WL-CFG} +in extracted directory. + +If you want to use BBDB, then the necessary modules are byte-compiled and +installed when BBDB directory is added to load-path. +@xref{BBDB}. + +@subsection WL-CFG + +Contents of the file @file{WL-CFG} is loaded under installation if a file +with that name exists in extracted directory. You can use @file{WL-CFG} to +configure load-path to extra packages such as SEMI if needed. + +If you want to specify the install directory of Wanderlust related +files, then set following variables in @file{WL-CFG} + +@table @code +@item WL_PREFIX +A directory to install WL modules. +This directory is relative directory from @code{LISPDIR}. +WL modules include @file{wl*.el}, @file{wl*.elc} files. +@c Modules under the directory @file{util/} are also installed if +@c it detected as necessary. + +@item ELMO_PREFIX +A directory to install ELMO modules. +This directory is relative directory from @code{LISPDIR}. +ELMO modules include @file{elmo*.el}, @file{elmo*.elc} files. +@c @file{utf7.el}, @file{utf7.elc} are also included in the ELMO. +@end table + +@noindent +Default value of @code{WL_PREFIX} and @code{ELMO_PREFIX} are @file{wl}. + +If you want to install ELMO related files under a sub-directory +such as "elmo" then add following to @file{WL-CFG}: + +@lisp +(setq ELMO_PREFIX "elmo") +@end lisp + +@noindent + +@subsection Install as a XEmacs package +@cindex XEmacs package +@cindex XEmacs package install +@cindex Package, XEmacs +@cindex Package install, XEmacs +@c @cindex install-package + +It is possible to install Wanderlust as one of packages of XEmacs (21.0 +or greater). Configuration for autoload and icon-path in local +@file{.emacs} files are no longer necessary, if you install Wanderlust +as a package. + +Follow the next example to install Wanderlust as an XEmacs package. + +@example +% vi Makefile +% make package +% make install-package +@end example + +package directory is auto-probed, if SEMI is installed. +(you can also specify it with @code{PACKAGEDIR} in @file{Makefile}) + +@subsection Run in place + +If wl and elmo directories are defined in load-path, then byte-compilation +and installation are not necessary to start Wanderlust. For example, +if package is extracted in @file{~/work}, Wanderlust can be invoked with +following setting in @file{.emacs}. + +@lisp +(add-to-list 'load-path "~/work/wl-(@var{version})") +(add-to-list 'load-path "~/work/wl-(@var{version})/elmo") +@end lisp + +@node Minimal Settings, Mail Addresses, Install, Start Me Up +@section Set up .emacs +@cindex Minimal Settings +@cindex Settings +@cindex Configuration +@cindex .emacs +@cindex .wl + +The Wanderlust package contains two module groups. + +@table @samp +@item ELMO (elmo-*.el) +These modules show everything as folders. This is the back-end for Wanderlust. +@item WL (wl-*.el) +These modules controls the behavior of main body of Wanderlust. +They are also the front-end for ELMO. +@end table + +You can customize the behavior of Wanderlust by changing the value +of environmental variables which begins with @code{elmo-*} and @code{wl-*}. + +The minimal requirement for settings is as the following. + +@lisp +;; The setting to use SEMI/tm +(load "mime-setup") + +;; autoload configuration +;; (These are not required if Wanderlust is installed as XEmacs package) +(autoload 'wl "wl" "Wanderlust" t) +(autoload 'wl-draft "wl-draft" "Write draft with Wanderlust." t) + +;; Directory where icons are placed (XEmacs Only). Default value is nil. +;; (This is not required if Wanderlust is installed as XEmacs package) +(setq wl-icon-dir "~/work/wl/etc") + +;; SMTP server for mail posting. Default: "localhost" +(setq wl-smtp-posting-server "your.smtp.server.com") +;; NNTP server for news posting. Default: "localhost" +(setq wl-nntp-posting-server "your.nntp.server.com") +@end lisp + +@file{~/.wl} is automatically loaded when Wanderlust starts up (if such a +file exists). So it is convenient to gather Wanderlust specific settings +in @file{~/.wl}. Settings for "face" must be written in @file{~/.wl}, +because you can't write them in @file{.emacs} +(if you write it to @file{.emacs}, you'll get an error). +@xref{Highlights}. + +All above described settings except (load "mime-setup") can be written in +@file{~/.wl}). + +@subsection mail-user-agent +@cindex Default Mailer +@cindex Mailer, Default +@vindex mail-user-agent +@findex compose-mail + +If you write following setting in you @file{.emacs}, you can +start Wanderlust draft mode by typing @kbd{C-x m} (@code{compose-mail}). +This means it enables you to run Wanderlust as a default mail composer + of Emacs. + +It is effective only when your Emacs can define @code{mail-user-agent}. +@c @xref{Mail Methods, , ,emacs}. + +@lisp +(autoload 'wl-user-agent-compose "wl-draft" nil t) +(if (boundp 'mail-user-agent) + (setq mail-user-agent 'wl-user-agent)) +(if (fboundp 'define-mail-user-agent) + (define-mail-user-agent + 'wl-user-agent + 'wl-user-agent-compose + 'wl-draft-send + 'wl-draft-kill + 'mail-send-hook)) +@end lisp + + +@node Mail Addresses, Folder Definition, Minimal Settings, Start Me Up +@section Address book +@cindex Address book Definition +@cindex .addresses +@cindex Alias, Address + +The file @file{~/.addresses} is a simple address book for Wanderlust. +Make address file @file{~/.addresses}, and edit to suit your requirement. + +The data written in @file{~/.addresses} are used for address completion +under draft editing mode. Furthermore, they are used when showing names +in summary display mode. You can safely skip this section, if you don't +want to customize address completion and summary display. +It is possible to add/change/remove addresses from @file{~/.addresses} in +summary buffer after Wanderlust is invoked. @refill + +The format is very simple. Like this. @refill + +@example +# +# @r{Lines begin with @samp{#} are comment.} +# @r{Empty lines are ignored} +# +# @r{Format of each line:} +# @r{email-address ``nickname'' ``realname''} +# +teranisi@@gohome.org "Yuuichi" "Yuuichi Teranishi" +foo@@bar.gohome.org "Mr. Foo" "John Foo" +bar@@foo.gohome.org "Mr. Bar" "Michael Bar" +@end example + +@noindent + +One line defines one persons description. + +Actually, in default setup, "nickname" is used in summary-mode and "real name" +is used in draft preparation mode. This behavior is better understood if you +try it and confirmed the function first. You can write and try a small +definition, so you will know the idea of the address book before writing a big +one. + +And, if MH alias file is specified in variable @code{wl-alias-file}, +it is used as an address information in the draft preparation mode. + +@node Folder Definition, Start Wanderlust, Mail Addresses, Start Me Up +@section Folder Definition +@cindex Folder Definition +@cindex .folders + +Define the folders you want to subscribe in file @file{~/.folders}. +The contents written in @file{~/.folders} become the folders which +you subscribe to as it is. + +You can skip this section because it is possible to add/edit the +subscribe folders from the buffer for list of folders. + +Format for @file{~/.folders} is very simple. Here is an example: + +@example +# +# @r{Lines begin with @samp{#} are comment.} +# @r{Empty lines are ignored} +# +# @r{folder name} "@r{folder nickname}" +# @r{(nicknames are not necessary)} +# +%inbox "Inbox" ++trash "Trash" ++draft "Drafts" +%#mh/Backup@@my.imap.server.com "Sent" +# Folder Group +Emacsen@{ + %#mh/spool/wl "Wanderlust ML" + %#mh/spool/elips "ELIPS ML" + %#mh/spool/tm-ja "tm Japanese ML" + %#mh/spool/xemacs-beta "XEmacs beta" + -fj.news.reader.gnus@@other.nntp.server.com "Gnus Net news" + *-fj.editor.xemacs,-fj.editor.mule,-fj.editor.emacs "fj's Emacsen" +@} +# +# @r{If folder name ends with @samp{/}, that means an `access group',} +# @r{all subfolders automatically included in one folder group.} +# +%#mh/expire@@localhost / +# @r{All MH folders are included in one folder group.} ++ / +@end example + +Each line contains one folder you want to read. The definition of folders +will be explained in detail in the next section. + +The part surrounded by @samp{@var{group name}@{} and @samp{@}} will become one folder group. +One folder group is treated as a directory which can bed opened and closed in +folder mode. It is convenient for collecting some folders and putting them +in order. + +Please note that @samp{@var{group name}@{} and @samp{@}} occupies one +line and you have to write it that way (It is because the parser sucks). + +There are two types of groups. One is like @samp{Emacsen} from above +example which the user chooses his favorite folders as a group. + +The other one is @dfn{access group} like @samp{+} from above example. +It makes all the sub-folders in a folder to a group. +(It differs from the type of the folder. For example, @samp{+} makes entire + MH sub-directories to one group) + +This behavior is better understood if you try it and confirmed the function +first. You can write and try a small folder definition, so you will know the +idea of the folder function before writing the real one. + +@node Start Wanderlust, , Folder Definition, Start Me Up +@section Start Wanderlust +@cindex Start Wanderlust + +If installation and configuration worked well, you can invoke Wanderlust by +typing following command in Emacs. + +@example +M-x wl +@end example + +@noindent + +After initialization, Folder Mode which shows the list of folders will appear. +That means the folders you defined in the @file{~/.folders} are listed +If you start Wanderlust with prefix argument like @kbd{C-u M-x wl}, you +can skip folder checking. + +@c +@c Folders +@c +@node Folders, Folder, Start Me Up, Top +@chapter Wanderlust's folders +@cindex Folder Type + +This chapter describes the folder types which Wanderlust is able to handle. + +Wanderlust uses ELMO as it's interface, so every folder types supported +by ELMO is usable in Wanderlust. + +As of version @value{version}, 10 types of folders are predefined. These are +IMAP, NNTP, LocalDir(MH), News Spool, POP, Archive, Multi, Filter, Pipe +and Internal folder types. + +@menu +* IMAP Folder:: @samp{%} -- IMAP folder +* NNTP Folder:: @samp{-} -- NNTP folder +* MH Folder:: @samp{+} -- MH folder +* Maildir Folder:: @samp{.} -- Maildir folder +* News Spool Folder:: @samp{=} -- News spool folder +* Archive Folder:: @samp{$} -- Archive folder +* POP Folder:: @samp{&} -- POP folder +* Multi Folder:: @samp{*} -- Multi folder +* Filter Folder:: @samp{/} -- Filter folder +* Pipe Folder:: @samp{|} -- Pipe folder +* Internal Folder:: @samp{'} -- Internal folder +@end menu + + +@node IMAP Folder, NNTP Folder, Folders, Folders +@section IMAP Folder +@cindex IMAP Folder +@cindex @samp{%} +@cindex RFC 2060 +@cindex IMAP4rev1 + +A folder to access e-mails via IMAP4rev1 protocol (RFC 2060). + +@example +Format: '%' 'IMAP mailbox'[':' 'username' ['/' 'authenticate-type']]['@@' 'hostname'][':' 'port']['!'] + +You can specify +"auth" (encoded password transmission), "cram-md5" (cram-md5 authentication) +and "login" (plain password transmission) as authenticate-type. +(To use cram-md5 authentication, you must install utils/sasl package.) + +default: + +username -> The value of @code{elmo-default-imap4-user}. + Initial setting is `USER' environment variable or + `LOGNAME' environment variable or return value of + (user-login-name). +authenticate-type -> The value of @code{elmo-default-imap4-authenticate-type}. + Initial setting is "auth". +hostname -> The value of @code{elmo-default-imap4-server}. + Initial setting is "localhost". +port -> The value of @code{elmo-default-imap4-port}. + Initial setting is 143. + +You can omit the hostname from folder names if you set +@code{elmo-default-imap4-server} as your main IMAP server. +For example, you can specify a folder as @samp{foo%imap@@geteway} even +if you have to go through a firewall. + +SSL (Secure Socket Layer) connection will be used if a folder name +ends with '!'. Or, if the value of @code{elmo-default-imap4-ssl} is non-nil, +SSL will be the default connection. +If a folder name ends with '!!', STARTTLS connection will be established. +if the value of @code{elmo-default-imap4-ssl} is 'starttls, +STARTTLS will be the default connection. + +If you specify "auth" or "cram-md5" as authentication method, the password +is sent in encoded form. But, if your server is unable to receive an encoded +password, authentication will fall back to "login" (that is, sending password +in raw format) after confirmation to user. If @code{elmo-imap4-force-login} +is non-nil, authentication will fall back to "login" without confirmation +(default value is nil). + +Example: %inbox -> IMAP mailbox "inbox" + %#mh/inbox -> IMAP mailbox "#mh/inbox" + + %inbox:hoge -> IMAP mailbox "inbox" of user "hoge". + %inbox:hoge/login@@server1 + -> server1's IMAP mailbox "inbox" + of user "hoge", with plain password authentication + ("login"). +@end example + +@subsection International mailbox names (Modified UTF7) + +You can use international mailbox names in 'IMAP mailbox' part, if you +are using Emacs which can treat unicode and +@code{elmo-imap4-use-modified-utf7} is set to non-nil value (default +value is nil). + +Currently, following Emacsen can treat unicode. + +@itemize @bullet +@item Emacs 20.3 or later + Mule-UCS + +If you installed Mule-UCS package, Emacs can treat unicode. +You can obtain Mule-UCS package from following URL. + +@example +ftp://ftp.m17n.org/pub/mule/Mule-UCS/ +@end example + +@item XEmacs 21.2.13 or later + ucs-conv package + +By default, XEmacs 21 cannot treat unicodes, but if you installed +ucs-conv package, it can. +You can obtain ucs-conv package from following anonymous CVS. + +@example +:pserver:anonymous@@cvs.m17n.org:/cvs/root +Password: NULL (Just enter return key) +@end example + +You also need utf7 conversion programs, u7tou8 and u8tou7 to use international +mailbox name in the current XEmacs. +These programs are included in the UTF7 package which can be obtained +from following URL. + +@example +ftp://ftp.ifcss.org/pub/software/unix/convert/utf7.tar.gz +@end example +@end itemize + +@node NNTP Folder, MH Folder, IMAP Folder, Folders +@section NNTP Folder +@cindex NNTP Folder +@cindex @samp{-} + +A folder to access USENET news via NNTP protocol (RFC 977). +One newsgroup is treated as a folder. + +@example +Format: '-' 'newsgroup'[[':' 'username']['@@' 'hostname'][':' 'port']]['!'] + +default: +hostname -> The value of @code{elmo-default-nntp-server}. + Initial setting is "localhost". +username -> The value of @code{elmo-default-nntp-user}. + Initial setting is nil. +port -> The value of @code{elmo-default-nntp-port}. + Initial setting is 119. + +AUTHINFO is used as authentication method if the username is non-nil. +SSL will be default method if @code{elmo-default-nntp-ssl} is non-nil even +if the folder name doesn't end with '!' +If a folder name ends with '!!', STARTTLS connection will be established. +if the value of @code{elmo-default-nntp-ssl} is 'starttls, +STARTTLS will be the default connection. + +Example: -fj.rec.tv -> Newsgroup `fj.rec.tv'. + -fj.rec.tv@@newsserver -> Newsgroup `fj.rec.tv' on newsserver. +@end example + +@node MH Folder, Maildir Folder, NNTP Folder, Folders +@section MH Folder +@cindex MH Folder +@cindex @samp{+} +@pindex MH + +A folder to access MH format mail (1 file is 1 mail). + +@example +Format: '+' 'directory-name' + +Normally, directory paths are relative to variable +@code{elmo-localdir-folder-path} (default is @file{~/Mail}), but if it +starts with @samp{/} or @samp{~}, then it is treated as an absolute path +(this is also true for drive-letters). + +Message number is used for the name of the message file. + +Example: +inbox -> "~/Mail/inbox" + +from/teranisi -> "~/Mail/from/teranisi" + +~/test -> "~/test" +@end example + +@node Maildir Folder, News Spool Folder, MH Folder, Folders +@section Maildir Folder +@cindex Maildir Folder +@cindex @samp{.} +@pindex Maildir + +A folder to access to Maildir format (1 file is 1 mail). + +@example +Format: '.' 'directory-name' + +Normally, directory paths are relative to variable +@code{elmo-maildir-folder-path} (default is @file{~/Maildir}), but if it +starts with @samp{/} or @samp{~}, then it is treated as an absolute path +(this is also true for drive-letters). + +Maildir contains @file{cur}, @file{new} and @file{tmp} subdirectories. +Messages are contained in the @file{cur} directory. All +message files in the @file{new} directory are moved to @file{cur} +directory when you access to the folder. All message files contained in +the @file{tmp} directory and not accessed for 36 hours are deleted. + +These behaviors are defined the @samp{http://cr.yp.to/proto/maildir.html}. + +Example: . -> "~/Maildir" + .inbox -> "~/Maildir/inbox" + .from/teranisi -> "~/Maildir/from/teranisi" + .~/test -> "~/test" +@end example + +@node News Spool Folder, Archive Folder, Maildir Folder, Folders +@section News Spool Folder +@cindex News spool Folder +@cindex @samp{=} +@pindex gnspool + +This folder handles locally saved news articles which are proposed by Mew/IM. +You can also read articles directly from a spool-file which is retrieved +by an utility like gnspool. + +@example +Format: '=' 'directory-name' + +directory-name is sub-directory to the directory defined by variable +@code{elmo-localnews-folder-path} (default is "~/News") +You can use @samp{.} as directory delimiter as well as @samp{/}. + +Example: =fj/os/os2 -> "~/News/fj/os/os2" + =fj.os.bsd.freebsd -> "~/News/fj/os/bsd/freebsd" +@end example + +@node Archive Folder, POP Folder, News Spool Folder, Folders +@section Archive Folder +@cindex Archive Folder +@cindex @samp{$} +@c @pindex ange-ftp + +This method can handle archive files, which are compressed by utilities +such as Info-ZIP or LHA, as one folder. + +@example +Format: '$' 'path-name' [';' archiver-type ';' prefix] + +`path-name' is the relative path from @code{elmo-archive-folder-path} +(initial setting is @file{~/Mail}). +If path-name begins with @samp{/} or @samp{~} or `drive-letter of DOS', +path-name is treated as absolute path. +ange-ftp format is also permitted under the environment of ange-ftp, efs. + +The actual file name of the archive folder is +@code{elmo-archive-basename}(Initial setting is "elmo-archive") +under the path-name. If a file named path-name exists, it is treated as +folder. The suffix is automatically decided for archiver-type. + +If `archiver-type' is omitted, @code{elmo-archive-default-type} +(Initial setting is 'zip) is referred. + +`prefix' specifies the internal directory structure of the archive. +For example, if the ML server is fml, @file{msend.tar.gz} has a structure like +@file{spool/1}, so you have to specify "spool" as `prefix'. + +Example: $teranisi -> "~/Mail/teranisi/elmo-archive.zip" + $bsd/freebsd;lha -> "~/Mail/bsd/freebsd/elmo-archive.lzh" + $/foo@@server:~/bar;zoo -> "~/bar/elmo-archive.zoo" on ftp server + $d:/msend.tar.gz;tgz;spool -> "d:/msend.tar.gz" +@end example + +@menu +* Archiver:: Archivers supported +* Archive Tips:: TIPS +* Archive Vars:: Customization +@end menu + + +@node Archiver, Archive Tips, Archive Folder, Archive Folder +@subsection Supported Archives +@cindex Archiver +@pindex LHA +@pindex Info-ZIP +@pindex UNZIP +@pindex ZOO +@pindex RAR +@pindex TAR +@pindex GNU TAR + +By default, following archives are supported. + +@example + LHA, Info-ZIP/UNZIP, ZOO, RAR ;; full-access + GNU TAR('tgz, 'tar) ;; read-only +@end example + +If your archiver can include multiple files in one archive, you have a +possibility use it as an archiver of Wanderlust (ARJ/UNARJ, ARC is one +of the candidate. TAR is supported read-only because it cannot delete +file in the archive ('mv)). + +gzip, bzip, bzip2 cannot be used as an archiver of Wanderlust because +they cannot include multiple files. Archivers that cannot extract files +to standard output are also not supported. + +@subsection OS specific information about archiver. + +Behaviors of the following archivers are confirmed by further experiences. +(@samp{*} mark means recommended archiver). + +@example +[OS/2] Warp4.0J(w/o VoiceType)+Fx00505/emx0.9c(fix04)/PMMule,EmacsPM + LHA OS/2 version Rel.2.06b Feb 18, 1998 + *UnZip 5.32 of 3 November 1997, by Info-ZIP. + *Zip 2.2 (November 3rd 1997). + Zoo archiver, zoo 2.1 $@asis{}Date: 91/07/09 02:10:34 $ + GNU tar version 1.10 - AK 2.58 (DBCS/SJIS) 981216(homy) version + gzip 1.2.4 (18 Aug 93) + bzip2 patch(by Iida-san) + +[UN|X] FreeBSD 2.2.7-RELEASE, Linux 2.0.30, Solaris2.6, HP-UX 9.07 + LHa for UNIX V 1.14c + UnZip 5.32 of 3 November 1997 + Zip 2.2 (November 3rd 1997) + GNU tar 1.12 (1.11.x is no good) + gzip 1.2.4 (18 Aug 93) + +[Win32] Win.98/Meadow + Lha32 version 1.28 + Zip 2.2 + UnZip 5.40 + GNU tar 1.11.8 + 1.5(WIN32) + GZIP 1.2.4 + RAR 2.06 + +* Caution about LHA + +If you are an OS/2 user, Peter Fitzsimmons's LH/2 is not supported. +Hiramatsu version of LHA is only supported. +In Win32, LHa32 is only supported (DOS version is no good). + +* Caution about GNU tar + +You have to take care about GNU tar's version because +many version has problem on deleting file from archive. + +Please test --delete -f options work. Otherwise, your archive will be +destroyed. No problem is reported on above versions of GNU tar. +@end example + + +@node Archive Tips, Archive Vars, Archiver, Archive Folder +@subsection TIPS +@cindex Archive Tips + +For comfortable migration, usage of wl-summary-archive() (@pxref{Archive}) or +Expire (@pxref{Expire}) is recommended. +To treat archive folders created by expiration, +you must set non-nil value to @code{elmo-archive-treat-file}. + +On the OS/2, there is a great difference between Mule2.3(19.28) and Emacs20.2 +in processing speed. For comfortable use, Emacs20 is recommended. +(If re-search's performance is the problem, 19.3x or later may be okay.) + +If many files are included in one archive, +it takes long time to access to the archive folder because +archiver starting overhead is increased (especially LHA). +150-200 messages in one archive is recommended. + +Of course, following is possible @t{:-)} +(meanings of these variables are described later.) +@lisp +(setq wl-fcc "$backup") +(setq wl-trash-folder "$trash;lha") +@end lisp + +@noindent + + +@node Archive Vars, , Archive Tips, Archive Folder +@subsection Variables About Archive Folder +@cindex Archive variables + +@table @code +@item elmo-archive-default-type +@vindex elmo-archive-default-type +The initial setting is 'zip. +Set archiver type by symbol. + +@item elmo-archive-@var{type}-method-alist +@vindex elmo-archive-TYPE-method-alist +Define archiver @var{type}'s methods. +(@var{type} is @samp{lha}, @samp{zip}, @samp{zoo}, @samp{tgz} etc) +Each element of the alist is following. + +@example + (action . (exec-name options)) ;; external program and its option. + (action . function) ;; function +@end example + +Currently available actions are following. + +@example + 'ls, 'cat ('cat-headers) ;; Minimal setting(read-only) + 'mv ('mv-pipe), 'rm ('rm-pipe) ;; full-access (with above) + 'cp ('cp-pipe) ;; +@end example + +@noindent +In above actions, +actions enclosed with braces are optional (They are used for better +performance). + +@item elmo-archive-suffix-alist +@vindex elmo-archive-suffix-alist +An alist of archiver-type (symbol) and suffix. + +@item elmo-archive-file-regexp-alist +@vindex elmo-archive-file-regexp-alist +An alist of a regexp to get file number from list output of archiver +and archiver-type (symbol). + +@item elmo-archive-method-list +@vindex elmo-archive-method-list +A list of elmo-archive-@var{type}-method-alist +(@var{type} is a symbol of archiver-type). + +@item elmo-archive-lha-dos-compatible +@vindex elmo-archive-lha-dos-compatible +The initial setting is t on OS/2 and Win32. +If non-nil, LHA is DOS (Mr. Yoshizaki original) compatible. + +@item elmo-archive-cmdstr-max-length +@vindex elmo-archive-cmdstr-max-length +The initial setting is 8000. + +Max length of command line argument for external archiver program. +Emacs does not have a limit of command line byte length, but some OS +(e.x OS/2) have. It depends on the OS. Archive folder is affected by +this limit because it calls external archiver program directly (not +called via shell). For example, you cannot delete messages if archiver +program must receive larger bytes of arguments to delete. OS/2 have a +command line argument limit of 8190 bytes, so we defined default as 8000 +with some margin. + +However, you don't have an influence of command line argument limit +if the archiver has `actions' to receive target file information from +standard input (rm-pipe, mv-pipe, cat-headers action). +@end table + +@node POP Folder, Multi Folder, Archive Folder, Folders +@section POP Folder +@cindex POP Folder +@cindex @samp{&} +@cindex RFC 1939 +@cindex POP3 +@cindex APOP + +A folder to access e-mails via POP3 protocol (RFC 1939). + +@example +Format: '&' ['username'][['/' 'authenticate-type']['@@' 'hostname'][':' 'port']]['!'] + +You can specify +"user" (plain password transmission) or "apop" (APOP authentication) +as authenticate-type. + +default: +username -> The value of @code{elmo-default-pop3-user}. + Initial setting is `USER' environment variable or + `LOGNAME' environment variable or return value of + (user-login-name). +authenticate-type -> The value of @code{elmo-default-pop3-authenticate-type}. + Initial setting is "user". +hostname -> The value of @code{elmo-default-pop3-server}. + Initial setting is "localhost". +port -> The value of @code{elmo-pop3-default-port}. + Initial setting is 110. + +Example: &hoge@@localhost -> access to localhost as user "hoge". + &hoge@@popserver:109 -> access to the server "popserver" on port 109 + as user "hoge". +@end example + +To use apop as an authenticate-type, @file{md5.el} is needed +(XEmacs doesn't need @file{md5.el}). +@file{md5.el} is included in @file{utils/sasl/lisp/} or Emacs/W3 package + +@example +http://www.cs.indiana.edu/elisp/w3/docs.html +@end example + +or LCD archive (GPL2). + +If the last character of the folder name is '!', Wanderlust connects to +the POP server via SSL (Secure Socket Layer). If you set non-nil +value to @code{elmo-default-pop-ssl}, you don't have to put '!' in the +end of the folder name to use SSL. +If a folder name ends with '!!', STARTTLS connection will be established. +if the value of @code{elmo-default-pop-ssl} is 'starttls, +STARTTLS will be the default connection. + +@node Multi Folder, Filter Folder, POP Folder, Folders +@section Multi Folder +@cindex Multi Folder +@cindex @samp{*} +@cindex Folder, Multiple +@cindex Folder, Marge + +A folder to access to a folder which collects messages from +multiple folders virtually. + +@example +Format: '*' 'folder' [',' 'folder'] ... [',' 'folder'] + +After '*' character, specify multiple folders you want to collect +separated by ',' like folder1,folder2,@dots{},folderN. + +Example: + *-fj.editor.xemacs,-fj.editor.mule,-fj.editor.emacs + -> -fj.editor.xemacs, -fj.editor.mule and -fj.editor.emacs are + treated as one folder. + + *+inbox,-fj.rec.tv,%inbox + -> +inbox, -fj.rec.tv and %inbox are treated as one folder. + +@end example + + +@node Filter Folder, Pipe Folder, Multi Folder, Folders +@section Filter Folder +@cindex Filter Folder +@cindex @samp{/} +@cindex Folder, Filtering +@cindex Folder, Virtual + +A folder to access to a folder which collects all messages that +satisfy a condition virtually. + +@example +Format: '/' 'condition' '/' 'target-folder' + +In the 'condition' part, you can specify following. + +1. Partial filter: "first:NUMBER", "last:NUMBER" + +first: 'NUMBER' messages are picked from top of folder. +last: 'NUMBER' messages are picked from bottom of folder. + +Example: + /last:10/-fj.os.linux -> Latest 10 messages from -fj.os.linux are picked. + /first:20/%inbox -> First 20 messages from %inbox are picked. + +2. Date filter: "since:DATE" "before:DATE" + +since: only messages arrived since 'DATE' are picked. +before: only messages arrived before 'DATE' are picked. + +You can specify following as 'DATE'. + +yesterday -> a day before today. +lastweek -> same day of last week. +lastmonth -> same day of last month. +lastyear -> same day of last year. +'NUMBER'daysago -> 'NUMBER' days ago. (e.x. '3daysago') +'DAY'-'MONTH'-'YEAR' -> specify date directly (ex. 1-Nov-1998) + +Example: + /since:3daysago/+inbox -> messages arrived since 3 days ago in +inbox + are picked. + /before:yesterday/+inbox -> messages arrived before yesterday in +inbox + are picked. + +3. Field filter: "FIELD=VALUE" + +All messages that have FIELD and its value is VALUE are picked. +'FIELD' and 'VALUE' are case insensitive. + +Example: + /from=teranisi/+inbox -> In +inbox, messages which have From: field + and its value includes "teranisi" string are picked. + /body=foo/%inbox -> In %inbox, messages which have "foo" text + are picked. + +If you can split conditions by character "|", it is considered as OR condition. +/tocc=xxxx/ is an abbreviation of /to=xxxx|cc=xxxx/. + +Example: + + /from=teranisi|to=teranisi/+inbox + -> In +inbox, messages are picked if + the message's To: field includes + "teranisi" or From: field includes "teranisi". + /tocc=teranisi/+inbox -> In +inbox, messages are picked if + the message's To: field or Cc: field includes + "teranisi". + +Advanced example: + + %inbox,/from=teranisi/%inbox@@server + -> Messages in %inbox or + message is in the %inbox@@server folder and it's From field + includes "teranisi" are collected. + + /last:100//to=teranisi/*+inbox,%inbox + -> Latest 100 messages which is in the +inbox or %inbox folder + and To: field matches "teranisi". + + /from=hogehoge//last:20//tocc=teranisi/%#mh/inbox@@localhost + -> Pick messages which have From: field and it includes "hogehoge" + from latest 20 messages in the %#mh/inbox@@localhost + and To: or Cc: field includes "teranisi". + +;;; --- Limit of implementation --- +;;; In the current implementation, NNTP folder does not treat date filter and +;;; field filter. +;;; In IMAP4 folder, field filter only supports fields which can be +;;; passed directly to rfc2060's search command. +;;; (i.e. to,cc,from,subject and body) +;;; Localdir folder treats arbitrary field name. +@end example + +@node Pipe Folder, Internal Folder, Filter Folder, Folders +@section Pipe Folder +@cindex Pipe Folder +@cindex @samp{|} +@cindex Get Message +@cindex Download Message +@cindex Incorporate Message + +In the pipe folder, messages are automatically transferred from the source +folder to destination folder. + +@example +Format: '|' source-folder '|' destination-folder + +When you access to the pipe folder, messages are automatically transferred +from source-folder to destination-folder. +It is convenient if you want to download messages to local disk via POP. +For example, if you specify following + +|&username@@popserver|+inbox + +and access to it, messages are downloaded automatically from +&username@@popserver to +inbox. + +Example: %inbox|%myinbox -> Download %inbox to %myinbox. + *&user@@popserver1,&user@@popserver2|+inbox + -> Download from &user@@popserver1 and &user@@popserver2 to +inbox. +@end example + +After messages are moved, a hook @code{elmo-pipe-drained-hook} is called. + +@node Internal Folder, , Pipe Folder, Folders +@section Internal folder +@cindex Internal Folder +@cindex @samp{'} +@cindex Folder, @samp{$} mark + +A folder to access to internal messages of Wanderlust. + +@example +Format: 'mark + or + 'cache/00 - 1F + +A folder named 'mark is a special virtual folder which collects messages +which have important mark @samp{$}. + +You can review important messages at once after you put important marks +on the messages in the different folders. + +In this folder, if you delete message, important mark @samp{$} put on +the message is removed. If you append messages to this folder, the +message will have @samp{$} mark. + +You can access to the cached messages fetched via network by accessing +to the folders named 'cache/00 - 1F. 00 - 1F are the name of the +subdirectories of the cache directory (@file{~/.elmo/cache}). +@end example + +@c +@c Folder +@c +@node Folder, Summary, Folders, Top +@chapter Folder mode +@cindex Folder + +After you start Wanderlust, folder mode is appeared firstly. +It contains folder list you subscribed. +You can select and edit folders in this mode. + +@menu +* Selecting Folder:: Select folder you want to read. +* Folder Manager:: Editing folders. +@end menu + + +@node Selecting Folder, Folder Manager, Folder, Folder +@section Selecting Folder +@cindex Selecting Folder + +@subsection Usage (TIPS) + +@subsubsection Check new, unread number + +Folder mode looks like this. +(In XEmacs, it looks much nicer @t{;-)}) + +@example +[-]Desktop:14186/35580/67263 + Inbox:3/10/10 + Trash:2/7/10 + Drafts:0/0/3 + Sent:0/9/348 + [-]Emacsen:0/34/4837 + Wanderlust ML:0/0/558 + ELIPS ML:0/0/626 + tm:0/0/821 + XEmacs Beta:0/29/255 + Mew:0/0/998 + Mule-Win32:0/0/1491 + fj's Emacsen:0/5/88 +@end example + + +Each line means: + +@example +FOLDER-NAME:NEW-NUMBER/UNREAD-NUMBER/ALL-NUMBER +@end example + +@noindent + +@kbd{s} key on the folder line updates these numbers. +It changes its color if it has many new messages. + +The whole folder mode is a folder group named @samp{Desktop}. +Folder group open/close by return key. +A operation to a folder group is treated as operations on the +children folders. +For example, when you type @kbd{s} on @samp{[-]Emacsen}, +six children folders update its unread number status. + +@subsubsection Select Folder + +To enter summary mode of the folder, type return (or spece) key on +the folder line. +If the variable @code{wl-stay-folder-window} has non-nil value, +summary window appears on the right of the folder mode window. + +@subsection Key bindings + +Folder mode's key binding (related to selecting folders) is following. + +@table @kbd +@item @key{SPC} +@itemx @key{RET} +@kindex @key{SPC} (Folder) +@kindex @key{RET} (Folder) +@findex wl-folder-jump-to-current-entity +Enter to the summary mode of the folder at the current cursor point. +If the cursor is on the top of folder group line, +the folder group is opened or closed. +When the cursor is on the access group and this command is called +with prefix argument, folder children list is updated to the newest one. +(Children list is updated recursively if the access folder has hierarchical +structure.) +(@code{wl-folder-jump-to-current-entity}) + +@item M-@key{RET} +@kindex M-@key{RET} (Folder) +@findex wl-folder-update-recursive-current-entity +Folder children list of the access group at the current cursor point +is updated to the newest one. +(Children list is updated recursively if the access folder has hierarchical +structure.) +(@code{wl-folder-update-recursive-current-entity}) + +@item w +@kindex w (Folder) +@findex wl-summary-write +Create a new draft message. +(@code{wl-summary-write}) + +@item W +@kindex W (Folder) +@findex wl-summary-write-current-newsgroup +If the current cursor point is on the NNTP folder, +create a new draft message which already has newsgroups field. +(@code{wl-summary-write-current-newsgroup}) + +@item s +@kindex s (Folder) +@findex wl-folder-check-current-entity +Update new and unread number information of the folder at the current +cursor point. +(@code{wl-folder-check-current-entity}) + +@item S +@kindex S (Folder) +@findex wl-folder-sync-current-entity +Update summary information of the folder at the current cursor point. +(@code{wl-folder-sync-current-entity}) + +@item r s +@kindex r s (Folder) +@findex wl-folder-check-region +Update new and unread number information of the folders in the currently +selected region. +(@code{wl-folder-check-region}) + +@item r S +@kindex r S (Folder) +@findex wl-folder-sync-region +Update summary information of the folders in the currently selected region. +(@code{wl-folder-sync-region}) + +@item P +@kindex P (Folder) +@findex wl-folder-prev-unread +Jump cursor to the folder which have unread messages on the upward from +current cursor point. +(@code{wl-folder-prev-unread}) + +@item N +@kindex N (Folder) +Jump cursor to the folder which have unread messages on the downward +from current cursor point. +(@code{wl-folder-next-unread}) + +@item p +@kindex p (Folder) +Move cursor to the folder on the previous line. +(@code{wl-folder-prev-entity}) + +@item n +@kindex n (Folder) +Move cursor to the folder on the next line. +(@code{wl-folder-next-entity}) + +@item J +@kindex J (Folder) +Jump to the folder specified by the user input. +(@code{wl-folder-jump-folder}) + +@item I +@kindex I (Folder) +@findex wl-folder-prefetch-current-entity +Prefetch new messages of the folder at the current cursor point by +@code{wl-summary-incorporate}. +If the cursor is on the folder group, it is executed recursively. +(@code{wl-folder-prefetch-current-entity}) + +@item c +@kindex c (Folder) +@findex wl-folder-mark-as-read-all-current-entity +Mark all unread messages of the folder at the current cursor point as read. +If the cursor is on the folder group, it is executed recursively. +(@code{wl-folder-mark-as-read-all-current-entity}) + +@item f +@kindex f (Folder) +@findex wl-folder-goto-first-unread-folder +Enter summary mode of the first unread folder. +(@code{wl-folder-goto-first-unread-folder}) + +@item E +@kindex E (Folder) +@findex wl-folder-empty-trash +Empty trash. +(@code{wl-folder-empty-trash}) + +@item o +@kindex o (Folder) +@findex wl-folder-open-all-unread-folder +All unread folder is opened. +(@code{wl-folder-open-all-unread-folder}) + +@item / +@kindex / (Folder) +@findex wl-folder-open-close +Folder group is opened/closed. +(@code{wl-thread-open-close}) + +@item [ +@kindex [ (Folder) +All folder group is opened. +(@code{wl-folder-open-all}) + +@item ] +@kindex ] (Folder) +All folder group is closed. +(@code{wl-folder-close-all}) + +@item q +@kindex q (Folder) +Quit Wanderlust. +(@code{wl-exit}) + +@item z +@kindex z (Folder) +Suspend Wanderlust. +(@code{wl-folder-suspend}) + +@item M-s +@kindex M-s (Folder) +Save current folder status. +(@code{wl-save}) + +@item M-t +@kindex M-t (Folder) +Toggle Wanderlust's offline/online status. +(@code{wl-toggle-plugged}) + +@item C-t +@kindex C-t (Folder) +Start Wanderlust's plug-status manager. +(@code{wl-plugged-change}) +@end table + +@subsection Customize variables + +@table @code +@item wl-folders-file +@vindex wl-folders-file +The initial setting is "~/.folders". +Subscribed folders are described (saved) in this file. + +@item wl-folder-info-save +@vindex wl-folder-info-save +The initial setting is t. +If non-nil, unread information is saved and used in the next Wanderlust session. + +@item wl-stay-folder-window +@vindex wl-stay-folder-window +The initial setting is nil. +If non-nil, summary window is appeared on the right side of the folder buffer. + +@item wl-folder-window-width +@vindex wl-folder-window-width +The initial setting is 20. +Folder mode's window width when @code{wl-stay-folder-window} is non-nil. + +@item wl-folder-many-unsync-threshold +@vindex wl-folder-many-unsync-threshold +The initial setting is 70. +If the number of unread messages is more than this value, +folder color is changed. + +@item wl-folder-desktop-name +@vindex wl-folder-desktop-name +The initial setting is "Desktop". +The name of top folder group. + +@item wl-folder-petname-alist +@vindex wl-folder-petname-alist +The initial setting is nil. +An alist of folder's realname and its nickname. + +@item wl-folder-access-subscribe-alist +@vindex wl-folder-access-subscribe-alist +The initial setting is nil. + +Control automatic subscribing and unsubscribing of the children list +of access groups. + +Each element is: + +('regexp of access-folder' . ('subscribe-flag' 'regexp-of-folders' @dots{})) + +If subscribe-flag is non-nil, folders which have name matched to +regexp-of-folders are displayed. Otherwise, hidden. +However, already unsubscribed folder is not displayed even +when the subscribe-flag is non-nil. Multiple regexp-of-folders can be specified. + +Example: + +@example +'(("^-fj$" . (t "^-fj\\.\\(comp\\|editor\\|mail\\)" + "^-fj\\.\\(net\\|news\\|os\\|rec\\)")) + ("^-$" . (t "^-\\(fj\\|tnn\\|japan\\|gnu\\|comp\\)")) + ("^\\+ml$" . (nil "^\\+ml$" "^\\+ml/tmp"))) +@end example + +@item wl-folder-hierarchy-access-folders +@vindex wl-folder-hierarchy-access-folders +The initial setting is '("-" "-alt"). +A list of access groups which creates children folder list hierarchically. + +For example, if you specify +@code{wl-folder-hierarchy-access-folders} like following, + +@lisp +(setq wl-folder-hierarchy-access-folders + '("-" "-alt" "-japan" "-comp" "-comp.unix")) +@end lisp + +such access group hierarchy is obtained. + +@example + [-]-:912/912/3011 + [-]-fj:674/674/1314 + -fj.comp.announce:0/0/2 + -fj.comp.dev.cdrom:0/0/0 + @dots{} + [+]-japan:238/238/1688 + [-]-comp:0/0/4 + [-]-comp.unix:0/0/0 + -comp.unix.admin:0/0/0 + -comp.unix.dos-under-unix:0/0/0 + -comp.unix.programmer:0/0/0 + [-]-comp.unix.bsd:0/0/23 + -comp.unix.bsd.freebsd.announce:0/0/0 + @dots{} +@end example + +If you opened @samp{-} in this example, only the direct children is created +(@samp{-fj}, @samp{-japan}, @samp{-tnn}, @dots{}). +second hierarchy (@samp{-fj.comp.announce}, @dots{}, @samp{-comp.unix}, @dots{}) +is not created until the children access group is opened. +@end table + + +@node Folder Manager, , Selecting Folder, Folder +@section Editing Folders +@cindex Folder Manager +@cindex Folder, Edit +@cindex Folder, Subscribe +@cindex Folder, Unsubscribe + +As described before, subscribed folder list is saved in @file{~/.folders} file. +But you don't have to edit @file{~/.folders} directly. +You can append, delete, edit folders from folder mode. + +@subsection Usage (Tips) + +@subsubsection Append Folder + +@kbd{m a} appends new folder to the folder mode. +@kbd{m g} appends new folder group. +To append new folder to this group, firstly open it, +then execute append command in the next line. + +@subsubsection Edit Folder + +You can cut folder by @kbd{C-k}, paste by @kbd{C-y}. +Thus, you can change folder position as if you were editing a normal file. + +@subsubsection Create Multi Folder. + +@enumerate +@item +Type @kbd{m q} to clear @code{wl-fldmgr-cut-entity-list}. +@item +Cut folder by @kbd{C-k} or copy folder by @kbd{M-c}. +@item +Type @kbd{m m}, then you can create multi folder. +@end enumerate + +@subsubsection Delete Nickname, Filter + +You can delete nickname or filter by putting ""(NULL) from the minibuffer +while appending. + +@subsubsection Append Folder to Empty Group + +To append new folder to the empty folder group +(after you create folder group by typing @kbd{m g}), +firstly open it, then execute append command in the next line. +If it is closed, folder is appended on the same level with +the above folder group. It is difficult to explain by words so try it. +In other words, appended position depends on the +above folder group's open/close status. + +@subsubsection Charset of the Folders File. + +@code{wl-mime-charset} is used for saving @code{wl-folders-file}. + +@subsubsection Create Filter + +@kbd{m f} adds filter to the folder at the current cursor point. +To create new filter folder and leave the current folder unchanged, +copy it @kbd{M-c}, make filter @kbd{m f} and paste it @kbd{C-y}. +Multiple filter can be specified while appending filter. +If you put ""(NULL), filter is deleted. + +@subsubsection Sort Folders + +Sorting of the folders is executed by the function specified by +@code{wl-fldmgr-sort-func}. +The initial setting is @code{wl-fldmgr-sort-standard}, +which sorts alphabetically. +Sorting affects only on the current folder group. It does not +affect on the child groups. + +@subsubsection Hiding Folders in the Access Group + +Usually, access group displays all children folders, but you can set +some folders hidden. Following operations are only available on access +group. + +Command @code{wl-fldmgr-unsubscribe} (@kbd{u}) toggles +the visibility (subscribe/unsubscribe) of the folder at current cursor point. + +Against this, @code{wl-fldmgr-unsubscribe-region} (@kbd{U}) hides folders +in the specified region. Note that @code{wl-fldmgr-unsubscribe-region} +does not toggle while @code{wl-fldmgr-unsubscribe} toggles. These two +commands accept prefix argument and if the argument has positive number, +the unsubscribe it. If the prefix argument has negative value, folder +becomes visible and if zero, folder visibility is toggled. + +The other commands, @code{wl-fldmgr-subscribe} and +@code{wl-fldmgr-subscribe-region} are also prepared (not binded to the +key). + +Moreover, if @code{wl-fldmgr-cut} or @code{wl-fldmgr-cut-region} is +executed in the access group, they have a same effect with +@code{wl-fldmgr-unsubscribe} and @code{wl-fldmgr-unsubscribe-region}. +The difference is that cut(-region) commands deletes folders from the +current buffer. + +@subsubsection Operations in the Access Group + +You can insert and delete folders in the access group like usual folder +group. But insert and delete commands can be only available for the +children folders of the access group and they only sets the subscribe +status. In other words, insertion of the folder means subscribing, +deletion means unsubscribing. +@footnote{In the current implementation, +it is faster to delete region than to unsubscribe region.} + +To update the access group when children folders are inserted or deleted +by other way (other than Wanderlust), +open the access group by typing @kbd{C-u @key{RET}}. +@xref{Selecting Folder}. + +The order of children folders of access group is saved after +insertion/deletion/sorting. +If you set @code{wl-force-fetch-folders} to non-nil or open access group +by typing @kbd{C-u @key{RET}}, disappeared folders are deleted and +newly created folders are inserted on the top of the access group. + +@subsection Key bindings +@cindex Keybind, Folder Mode +@cindex Keybind, Folder Buffer + +Key bindings on the folder mode related to folder editing are shown below. +All bindings starts with @kbd{m}, and primary commands are binded to +one stroke key binding. + +@table @kbd +@item m a +@kindex m a (Folder) +@findex wl-fldmgr-add +Insert a folder. +(@code{wl-fldmgr-add}) + +@item + +@itemx m g +@kindex + (Folder) +@kindex m g (Folder) +@findex wl-fldmgr-make-group +Create a folder group. +(@code{wl-fldmgr-make-group}) + +@itemx m A +@kindex m A (Folder) +@findex wl-fldmgr-make-access-group +Create an access group. +(@code{wl-fldmgr-make-access-group}) + +@item m d +@kindex m d (Folder) +@findex wl-fldmgr-delete +Delete folder itself and msgdb. +If the folder itself cannot be deleted like NNTP folder, +only msgdb is deleted. +(@code{wl-fldmgr-delete}) + +@item R +@itemx m R +@kindex R (Folder) +@kindex m R (Folder) +@findex wl-fldmgr-rename +Change the name of folder or folder group. +msgdb's path is also changed. +(@code{wl-fldmgr-rename}) + +@item * +@itemx m m +@kindex * (Folder) +@kindex m m(Folder) +@findex wl-fldmgr-make-multi +Create a multi folders in the cutlist (cut, copied folders). +(@code{wl-fldmgr-make-multi}) + +@item | +@itemx m f +@kindex | (Folder) +@kindex m f (Folder) +@findex wl-fldmgr-make-filter +Create a filter folder. (Put a filter on the folder). +(@code{wl-fldmgr-make-filter}) + +@item M-c +@itemx m c +@kindex M-c (Folder) +@kindex m c (Folder) +@findex wl-fldmgr-copy +Copy folder (it is not available on folder group). +(@code{wl-fldmgr-copy}) + +@item M-w +@itemx m W +@kindex M-w (Folder) +@kindex m W (Folder) +@findex wl-fldmgr-copy-region +Copy folders in the specified region. +(@code{wl-fldmgr-copy-region}) + +@item C-k +@itemx m k +@kindex C-k (Folder) +@kindex m k (Folder) +@findex wl-fldmgr-cut +Cut folder. Folder itself is not deleted. +(@code{wl-fldmgr-cut}) + +@item C-w +@itemx m C-w +@kindex C-w (Folder) +@kindex m C-w (Folder) +@findex wl-fldmgr-cut-region +Cut folders in the specified region. +(@code{wl-fldmgr-cut-region}) + +@item C-y +@itemx m y +@kindex C-y (Folder) +@kindex m y (Folder) +@findex wl-fldmgr-yank +Paste folders that are copied or cut (folders in the cut-list). +(@code{wl-fldmgr-yank}) + +@item m p +@kindex m p (Folder) +@findex wl-fldmgr-set-petname +Put nickname on the folder. +(@code{wl-fldmgr-set-petname}) + +@item m q +@kindex m q (Folder) +@findex wl-fldmgr-clear-cut-entity-list +Clear the cut-list. (cut, copied folder information is cleared, +you cannot paste after this) +(@code{wl-fldmgr-clear-cut-entity-list}) + +@item m s +@kindex m s (Folder) +@findex wl-fldmgr-sort +Sort folders in the current folder group. +(@code{wl-fldmgr-sort}) + +@item m C-s +@kindex m C-s (Folder) +@findex wl-fldmgr-save +Save current folder view to the @file{wl-folders-file}. +(@code{wl-fldmgr-save}) +@end table + +[Following commands are only available on the access groups] + +@table @kbd +@item u +@itemx m u +@kindex u (Folder) +@kindex m u (Folder) +@findex wl-fldmgr-unsubscribe +Set the visibility of folder (subscribe/unsubscribe). +(@code{wl-fldmgr-unsubscribe}) + +@item U +@itemx r u +@kindex U (Folder) +@kindex r u (Folder) +@findex wl-fldmgr-unsubscribe-region +Set the visibility of the folders (subscribe/unsubscribe) in the +specified region. +(@code{wl-fldmgr-unsubscribe-region}) + +@item l +@itemx m l +@kindex l (Folder) +@kindex m l (Folder) +@findex wl-fldmgr-access-display-normal +List folders that are currently available. +(@code{wl-fldmgr-access-display-normal}) + +@item L +@itemx m L +@kindex L (Folder) +@kindex m L (Folder) +@findex wl-fldmgr-access-display-all +List all folders regardless of the subscription status. +(@code{wl-fldmgr-access-display-all}) + +@item C-c C-o +@kindex C-c C-o (Folder) +@findex wl-jump-to-draft-buffer +Move to the draft buffer if available. If multiple draft buffer exists, +moved to one after another. If prefix argument is specified, load draft +folder's message to the draft buffer and jump to it. +(@code{wl-jump-to-draft-buffer}) +@end table + + +@subsection Customize variables + +@table @code +@item wl-interactive-save-folders +@vindex wl-interactive-save-folders +The initial setting is t. +If non-nil and folder view is modified, confirm saving it before +Wanderlust or Emacs exits. +If nil, save without confirmation. + +@item wl-fldmgr-make-backup +@vindex wl-fldmgr-make-backup +The initial setting is t. +If non-nil, @file{~/.folders.bak} is created before saving the folder status. + +@item wl-fldmgr-sort-func +@vindex wl-fldmgr-sort-func +The initial setting is 'wl-fldmgr-sort-standard. +A function to sort folders. +By default function, folders are sorted alphabetically and +folder group is put on top +(when @code{wl-fldmgr-sort-group-first} is non-nil). + +@item wl-fldmgr-sort-group-first +@vindex wl-fldmgr-sort-group-first +The initial setting is t. +If non-nil, @code{wl-fldmgr-sort-standard} precedes folder group. +If nil, it does not care whether it is folder group or not. + +@item wl-folder-check-async +@vindex wl-folder-check-async +The initial setting is t. +If non-nil, check folder's unread status asynchronously. +It boosts newsgroup checking. + +@item wl-folder-check-fast +@vindex wl-folder-check-fast +The initial setting is nil. +If non-nil, it does not update folder status while checking. +@c it is obsolete? +@item wl-folder-notify-deleted +@vindex wl-folder-notify-deleted +The initial setting is nil. +@c nil means? +If non-nil, negative value is displayed when the message is deleted. +If 'sync, folder is synchronized when the message is deleted. +If nil, message deletion is ignored. +@end table + +@subsection Miscellanea + +Following is a note for folder editing. + +@enumerate +@item +cut or copy stacks the folder in the @code{wl-fldmgr-cut-entity-list}. +paste(yank) command pastes the folders on one cut or copy command +(If copy command is executed by region, folders in the region are pasted +by one paste command) + +@item +You cannot cut 'Desktop' group. +Also, you cannot paste folders at the outside of the 'Desktop'. + +@item +You cannot copy folder group. + +@item +Operations on the access group are only available for the folders +in the same access group. + +@item +You cannot create a folder which has same name with the folders already exist. + +@item +You cannot insert folders which have same name in one group. +You can insert them in the different groups. +You cannot put same nickname to the different folders. +@end enumerate + + +@c +@c Summary +@c +@node Summary, Message, Folder, Top +@chapter Summary Mode + +@section Usage (Tips) + +@subsection Summary Content + +After you select the folder via folder mode, you enter to the summary mode. +In the summary mode, messages are displayed like following. + +@example + 377 09/16(Wed)11:57 [+1: Takuro Kitame ] Bug? + 381 09/17(Thu)00:16 [+3: Fujikazu Okuni ] elmo-lha.el -- LHA interface + 384 09/17(Thu)01:32 [+1: Yuuichi Terani ] wl-0.6.2 + 389 N09/18(Fri)01:07 [+2: Yuuichi Terani ] wl-0.6.3 +@end example + +Each line displays: + +@example +Message number, Temporal mark, Persistent mark, Date, Sender, Subject +@end example + +@noindent +You cannot change this in the current version. + +'Message number' is the message's unique number in the folder. In the NNTP +folder, it is article number, in the IMAP folder, it is UID and in the +MH folder, it is the filename of the message. + +Temporal and Persistent marks are described later. + +'Date' is displayed like 'Month/Day(Week Day)Hour:Minute'. +Default setting displays week day in Japanese, but if you want to +display it in English, set the value of @code{wl-summary-weekday-name-lang} +as "en". + +'Sender's indentation corresponds to the depth of the thread. +Sender name is displayed as nickname if it is defined in the address book. +Set @code{wl-use-petname} as nil, if you want to quit displaying with nickname. + +If number is printed at the head of 'sender' part like @samp{+2}, +that means the message have 2 follow messages. + +'Subject' is the Subject header field of the message. If the message +have same subject with the parent message, it is not displayed. Some +mailing list puts its sequence number in the subject field, but it is +ignored. @code{wl-summary-no-subject-message} is displayed when the +message has empty subject field. + +@subsection Temporary Marks +@cindex Mark, Temporary + +There are four temporary marks, +@samp{*}, @samp{D}, @samp{o} and @samp{O}. +Temporary marks indicates message operations. + +@table @samp +@item * +Target mark. +You can execute a command on the all messages that have @samp{*} mark, +with the key bindings which begins with @kbd{m}. + +@item D +The mark to delete. You can put @samp{D} by typing @kbd{d} key. + +@item o +The mark to refile. +After you type @kbd{o} key, prompt appears to input refile destination. +Your answer is printed in the summary line. + +@item O +The mark to refile. +You can put this mark by typing @kbd{O} key. +The difference between this mark and refile mark is, +this mark does not delete the message while latter does. +@end table + +@kbd{x} key executes @samp{D}, @samp{o} and @samp{O} marks. + +@subsection Persistent Marks + +There are five persistent marks, +@samp{N}, @samp{U}, @samp{!}, @samp{u} and @samp{$}. + +The persistent mark indicates the message's status and it is saved. +Each persistent mark indicates: + +@table @samp +@item N +It is new message. +@item U +It is unread message. +@item ! +It is unread but cached message. +@item u +It is read but it is not cached. +@item $ +It is important message. You can put @samp{$} mark by typing @kbd{$} +key (if already exists, the mark is deleted). It is convenient to put +this mark on the messages to remember (If you want to remember to write +a reply for the message, for example) because this mark remains after +you exited Emacs. Messages with the @samp{$} mark remains in the folder +even the message itself is deleted in the actual folder. + +@item None +If the message is read and cached (or local message),there are no +persistent mark. +@end table + +@samp{N}, @samp{U} and @samp{u} indicates that the message have no +cache. Messages with the marks other than these, you can read them in +the offline status even they are in the IMAP folder or netnews folder. + +@subsection How To Read + +Basically, you can read messages only typing space key again and again. + +To update summary status to the newest status (synchronize), +type @kbd{s} key. + +You can jump to next unread message by typing @kbd{N} key, and @kbd{n} key +moves cursor to the next message. +Enter message buffer by typing @kbd{j} key. +To operate multipart, you have to enter to the message buffer. + +@subsection Thread Operations + +For example, the following line indicates one thread (a context of a topic). + +@example + 384 09/17(Thu)01:32 [+1: Teranishi ] wl-0.6.2 +@end example + +@noindent + +If you type @kbd{/} on this line, the thread is opened and it changes +the appearance like following. + +@example + 384 09/17(Thu)01:32 [ Teranishi ] wl-0.6.2 + 388 09/17(Thu)22:34 +-[ Murata san ] +@end example + +(Message 388 is the replied message to the message 384.) +If you type @kbd{/} key once again, the thread is closed. +With prefix argument, @kbd{/} opens all children threads. + +Commands with the key binding that begins with @kbd{t} executes commands +on the messages in the thread. + +@subsection Cache File + +The messages which have to access via network (e.x. IMAP, NNTP folder) +are cached as a local file. +The cache file is saved under the directory @file{~/.elmo/cache}. + +To expire cache, type following. + +@example +M-x elmo-cache-expire-by-size +@end example + +@noindent + +The command deletes cache files to the specified size by the order of +last accessed time. + +@subsection Buffer Cache and Prefetching + +If the value of @code{elmo-use-buffer-cache} is non-nil, +the messages that are read are kept in the cache buffer. +It is called `buffer cache'. +The number of cache buffer is specified by @code{elmo-buffer-cache-size}. + +There are message prefetching mechanism in the Wanderlust that prefetches next +message while you are reading. This function requires that the value of +@code{elmo-use-buffer-cache} is non-nil. + +You can control the message prefetching mechanism by these two variables. + +@table @code +@item wl-cache-prefetch-folder-type-list +@vindex wl-cache-prefetch-folder-type-list +The initial setting is '(nntp imap4). +It specifies the folder types in which message prefetching is enabled. +In the initial setting, multi folder that contains localdir and imap4 +prefetches only imap4 messages. +This variable precedes the value of @code{wl-cache-prefetch-folder-list}. + +If you want to prefetch localdir and localnews also, following setting is needed. +@lisp +(setq wl-cache-prefetch-folder-type-list + '(nntp imap4 localdir localnews)) +@end lisp + +@item wl-cache-prefetch-folder-list +@vindex wl-cache-prefetch-folder-list +The initial setting is nil. +A list of regexp of folders to enable message prefetching. +@end table + +@subsection Auto Refile + +You refile messages automatically, by typing @kbd{C-o} +(@code{wl-summary-auto-refile}). It decides destination of refile by +the content of the message header information (information in the msgdb). + +By default, @samp{From}, @samp{Subject}, @samp{To} and @samp{Cc} is available. +If you want to decide destination by other header fields, +set the variable @code{elmo-msgdb-extra-fields} like following. + +@lisp +(setq elmo-msgdb-extra-fields + '("x-ml-name" + "reply-to" + "sender" + "mailing-list" + "newsgroups")) +@end lisp + +@noindent + +By this setting, Wanderlust saves extra fields in the msgdb. You have +to type @kbd{s all} to get extra fields for the messages that are +already exists in the summary. + +Then, specify the refile rule in the @code{wl-refile-rule-alist} like +following. + +@lisp +(setq wl-refile-rule-alist + '( + ("x-ml-name" + ("^Wanderlust" . "+wl") + ("^Elisp" . "+elisp")) + ("From" + ("teranisi@@isl.ntt.co.jp" . "+teranisi")))) +@end lisp + +After these setting, refile marks are automatically put on the condition +matched messages by typing @kbd{C-o} (@code{wl-summary-auto-refile}). +The rule matched first is applied. + +Messages which have @code{wl-summary-auto-refile-skip-marks} is skipped +auto refiling. +By default, @samp{N}, @samp{U} and @samp{!} is specified, so the messages +with these persistent marks are not automatically refiled. +It means Wanderlust does not execute auto refile on unread messages by +the default setting. +To execute auto refile on all messages, set following. + +@lisp +(setq wl-summary-auto-refile-skip-marks nil) +@end lisp + +@subsection Sticky Summary +@cindex Summary, Sticky +@cindex Sticky Summary + +The buffer of the `sticky summary' does not killed by typing @kbd{q}. + +Sticky buffer is created by entering the summary by typing @kbd{C-u g} or +type @kbd{M-s} (@code{wl-summary-stick}) on the normal summary. + +The buffer name of the sticky summary becomes like +@samp{Summary:@var{folder-name}}. + +You can visit the sticky summary at any time by @kbd{C-x b} +(@code{switch-to-buffer}). To exit sticky summary, type @kbd{C-u +q}. Other operations in the sticky summary are same as normal summary. + +@code{wl-summary-always-sticky-folder-list} specifies the folders that are +automatically sticked. + +@section Key bindings +@cindex Keybind, Summary Mode +@cindex Keybind, Summary Buffer + +Key bindings of the summary mode are shown below. + +@table @kbd +@item @key{SPC} +@kindex @key{SPC} (Summary) +@findex wl-summary-read +Proceed reading a message at the current cursor point. +(@code{wl-summary-read}) + +@item . +@kindex . (Summary) +@findex wl-summary-redisplay +Redisplay a message at the current cursor point. +If this command is called with prefix argument, +Redisplay message regardless of the message cache (message is re-loaded +from source). +(@code{wl-summary-redisplay}) + +@item < +@kindex < (Summary) +@findex wl-summary-display-top +Display the top message in the folder. +(@code{wl-summary-display-top}) + +@item > +@kindex > (Summary) +@findex wl-summary-display-bottom +Display the bottom message in the folder. +(@code{wl-summary-display-bottom}) + +@item @key{BS} +@itemx @key{DEL} +@kindex @key{BS} (Summary) +@kindex @key{DEL} (Summary) +Display the previous page of the message at the current cursor point. +@findex wl-summary-prev-page +(@code{wl-summary-prev-page}) + +@item @key{RET} +@kindex @key{RET} (Summary) +@findex wl-summary-next-line-content +Display the next line of the message at the current cursor point. +Display the message at the current cursor point if it is not displayed yet. +(@code{wl-summary-next-line-content}) + +@item / +@kindex / (Summary) +@findex wl-thread-open-close +Toggle open or close the thread at the current cursor point. +(@code{wl-thread-open-close}) + +@item [ +@kindex [ (Summary) +Open all threads. +@findex wl-thread-open-all +(@code{wl-thread-open-all}) + +@item ] +@kindex ] (Summary) +Close all threads. +@findex wl-thread-close-all +(@code{wl-thread-close-all}) + +@item - +@itemx M-@key{RET} +@kindex - (Summary) +@kindex M-@key{RET} (Summary) +@findex wl-summary-prev-line-content +Display the previous line of the message at the current cursor point. +Display the message at the current cursor point if it is not displayed yet. +(@code{wl-summary-prev-line-content}) + +@item g +@kindex g (Summary) +@findex wl-summary-goto-folder +Go to other folder. +(@code{wl-summary-goto-folder}) + +@item c +@kindex c (Summary) +Mark all messages in the folder as read. +@findex wl-summary-mark-as-read-all +(@code{wl-summary-mark-as-read-all}) + +@item a +@kindex a (Summary) +@findex wl-summary-reply +Prepare a draft for reply the message at the current cursor point. +(@code{wl-summary-reply}) + +@item A +@kindex A (Summary) +@findex wl-summary-reply-with-citation +Prepare a draft for reply the message at the current cursor point. +(@code{wl-summary-reply-with-citation}) + +@item C +@kindex C (Summary) +@findex wl-summary-cancel-message +If the message at current cursor point is your own netnews article, +cancel it. +(@code{wl-summary-cancel-message}) + +@item E +@kindex E (Summary) +@findex wl-summary-reedit +Prepare a draft for re-editing the message at current cursor point. +If the message at current cursor point is your own netnews article, +a draft for `supersedes message' for the message is prepared. +(@code{wl-summary-reedit}) + +@item M-e +@kindex M-e (Summary) +@findex wl-summary-resend-bounced-mail +If the message at current cursor point is a bounced message, +a draft for re-sending original message is prepared. +(@code{wl-summary-resend-bounced-mail}) + +@item f +@kindex f (Summary) +@findex wl-summary-forward +A draft for forwarding the message at current cursor point is prepared. +(@code{wl-summary-forward}) + +@item $ +@kindex $ (Summary) +@findex wl-summary-mark-as-important +Put @samp{$} mark on the message at current cursor point. +If already marked as @samp{$}, delete it. +(@code{wl-summary-mark-as-important}) + +@item y +@itemx e +@kindex y (Summary) +@kindex e (Summary) +Save the message at current cursor point. +@findex wl-summary-save +(@code{wl-summary-save}) + +@item n +@kindex n (Summary) +@findex wl-summary-next +Move cursor to the next message. +(@code{wl-summary-next}) + +@item p +@kindex p (Summary) +@findex wl-summary-prev +Move cursor to the previous message. +(@code{wl-summary-prev}) + +@item N +@kindex N (Summary) +@findex wl-summary-down +Move cursor to the downward message which is unread or marked +as @samp{$}. +(@code{wl-summary-down}) + +@item P +@kindex P (Summary) +@findex wl-summary-up +Move cursor to the upward message which is unread or marked +as @samp{$}. +(@code{wl-summary-up}) + +@item w +@kindex w (Summary) +@findex wl-draft +Prepare a new draft. +(@code{wl-draft}) + +@item W +@kindex W (Summary) +@findex wl-draft-write-current-newsgroup +Prepare a new draft. +If the current folder is netnews folder, Newsgroups: field is completed. +(@code{wl-draft-write-current-newsgroup}) + +@item H +@kindex H (Summary) +@findex wl-summary-redisplay-all-header +Redisplay the message at current cursor point with all header fields. +(@code{wl-summary-redisplay-all-header}) + +@item M +@kindex M (Summary) +@findex wl-summary-redisplay-no-mime +Redisplay the message at current cursor point without MIME analysis. +(@code{wl-summary-redisplay-no-mime}) + +@item B +@kindex B (Summary) +@findex wl-summary-burst +If the message at current cursor point has +encapsulates multiple messages using MIME, +de-capsulate and extract them on the current folder. +(@code{wl-summary-burst}) + +@item @@ +@kindex @@ (Summary) +@findex wl-summary-edit-addresses +Append/change/delete the message's sender information to the address book +@file{~/.addresses} interactively. +If this command is called with prefix argument, arbitrary address can be edited. +(@code{wl-summary-edit-petname}) + +@item Z +@kindex Z (Summary) +@findex wl-status-update +Sync up address book status with @file{~/.addresses}'s content. +(@code{wl-status-update}) + +@item | +@kindex | (Summary) +@findex wl-summary-pipe-message +Pipe current message's content to the external process. +(@code{wl-summary-pipe-message}) + +@item # +@kindex # (Summary) +@findex wl-summary-print-message +Print out current message's content. +It uses ps-print module in Emacs 20.x. +If you don't use color printer, you might want to set +@code{wl-ps-print-buffer-func} to 'ps-print-buffer. +(@code{wl-summary-print-message}) + +@item q +@kindex q (Summary) +@findex wl-summary-exit +Exit current folder. +(@code{wl-summary-exit}) + +@item j +@kindex j (Summary) +@findex wl-summary-jump-to-current-message +Jump cursor to the currently displayed message's window. +(@code{wl-summary-jump-to-current-message}) + +@item J +@kindex J (Summary) +Jump cursor to the other message. +@findex wl-summary-jump-to-msg +(@code{wl-summary-jump-to-msg}) + +@item I +@kindex I (Summary) +Update summary status and +prefetch all messages which have marks included in the +@code{wl-summary-incorporate-marks}. +@findex wl-summary-incorporate +(@code{wl-summary-incorporate}) + +@item M-j +@kindex M-j (Summary) +@findex wl-summary-jump-to-msg-by-message-id +Jump cursor to the message which have specified Message-Id. +If @code{elmo-use-database} is non-nil, other folder is also searched. +(@code{wl-summary-jump-to-msg-by-message-id}) + +@item ^ +@kindex ^ (Summary) +Jump to parent message. +@findex wl-summary-jump-to-parent-message +(@code{wl-summary-jump-to-parent-message}) + +@item ! +@kindex ! (Summary) +@findex wl-summary-mark-as-unread +Mark as unread the message at current cursor point. +(@code{wl-summary-mark-as-unread}) + +@item s +@kindex s (Summary) +@findex wl-summary-sync +Synchronize summary view after prompting the update range +(all, update, rescan, first, last). + +@example +all ...Discard current summary and update all message. +update ...Update the difference between summary and the folder itself. +rescan ...Rescan the msgdb and display again. +rescan-noscore ...Rescan the msgdb and display again (without scoring). +first, last ...Move to the filter folder(partial filter). +@end example + +@noindent +(@code{wl-summary-sync}) + +@item S +@kindex S (Summary) +@findex wl-summary-sort +Sort summary order. +You can sort by date, from, number and subject. +(@code{wl-summary-sort}) + +@item T +@kindex T (Summary) +@findex wl-summary-toggle-thread +Toggle the threading. +(@code{wl-summary-toggle-thread}) + +@item l +@kindex l (Summary) +@findex wl-summary-toggle-disp-folder +Toggle displaying of folder window. +(@code{wl-summary-toggle-disp-folder}) + +@item v +@kindex v (Summary) +Toggle displaying of message window. +@findex wl-summary-toggle-disp-msg +(@code{wl-summary-toggle-disp-msg}) + +@item V +@kindex V (Summary) +Move to the virtual folder with the condition specified. +If called with prefix argument and current folder is virtual, exit it. +@findex wl-summary-virtual +(@code{wl-summary-virtual}) + +@item @key{TAB} +@kindex @key{TAB} (Summary) +@findex wl-summary-goto-last-displayed-msg +Jump to the message which is displayed last. +(@code{wl-summary-goto-last-displayed-msg}) + +@item ? +@kindex ? (Summary) +Put @samp{*} mark on the messages that satisfies the specified condition. +@findex wl-summary-pick +(@code{wl-summary-pick}) + +@item R +@kindex R (Summary) +@findex wl-summary-mark-as-read +Mark as read the message at the current cursor point. +(@code{wl-summary-mark-as-read}) + +@item i +@kindex i (Summary) +Prefetch the message at the current cursor point. +@findex wl-summary-prefetch +(@code{wl-summary-prefetch}) + +@item x +@kindex x (Summary) +Execute @samp{D}, @samp{o} and @samp{O} marks. +@findex wl-summary-exec +(@code{wl-summary-exec}) + +@item * +@kindex * (Summary) +@findex wl-summary-target-mark-line +Put target mark on the message at the current cursor point. +(@code{wl-summary-target-mark-line}) + +@item o +@kindex o (Summary) +Put refile mark on the message at the current cursor point. +@findex wl-summary-refile +(@code{wl-summary-refile}) + +@item C-o +@kindex C-o (Summary) +Execute auto refile. +@findex wl-summary-auto-refile +(@code{wl-summary-auto-refile}) + +@item O +@kindex O (Summary) +Put copy mark on the message at the current cursor point. +@findex wl-summary-copy +(@code{wl-summary-copy}) + +@item M-o +@kindex M-o (Summary) +Put refile mark on the message at the current cursor point with the destination +previously specified. +@findex wl-summary-refile-prev-destination +(@code{wl-summary-refile-prev-destination}) + +@item d +@kindex d (Summary) +@findex wl-summary-delete +Put delete mark on the message at the current cursor point. +(@code{wl-summary-delete}) + +@item u +@kindex u (Summary) +@findex wl-summary-unmark +Unmark the temporal mark on the message at the current cursor point. +(@code{wl-summary-unmark}) + +@item U +@kindex U (Summary) +Unmark all the temporal marks. +@findex wl-summary-unmark-all +(@code{wl-summary-unmark-all}) + +@item r R +@kindex r R (Summary) +@findex wl-summary-mark-as-read-region +Mark as read messages in the specified region. +(@code{wl-summary-mark-as-read-region}) + +@item r $ +@kindex r $ (Summary) +@findex wl-summary-mark-as-important-region +Mark as important @samp{$} messages in the specified region. +If @samp{$} already exists, it is deleted. +(@code{wl-summary-mark-as-important-region}) + +@item r ! +@kindex r ! (Summary) +@findex wl-summary-mark-as-unread-region +Mark as unread messages in the specified region. +(@code{wl-summary-mark-as-unread-region}) + +@item r i +@kindex r i (Summary) +@findex wl-summary-prefetch-region +Prefetch messages in the specified region. +(@code{wl-summary-prefetch-region}) + +@item r x +@kindex r x (Summary) +@findex wl-summary-exec-region +Execute @samp{D}, @samp{o} and @samp{O} marks on the messages in the +specified region. +(@code{wl-summary-exec-region}) + +@item r * +@kindex r * (Summary) +@findex wl-summary-target-mark-region +Put target mark on the messages in the specified region. +(@code{wl-summary-target-mark-region}) + +@item r o +@kindex r o (Summary) +@findex wl-summary-refile-region +Put refile mark on the messages in the specified region. +(@code{wl-summary-refile-region}) + +@item r O +@kindex r O (Summary) +@findex wl-summary-copy-region +Put copy mark on the messages in the specified region. +(@code{wl-summary-copy-region}) + +@item r d +@kindex r d (Summary) +@findex wl-summary-delete-region +Put delete mark on the messages in the specified region. +(@code{wl-summary-delete-region}) + +@item r u +@kindex r u (Summary) +@findex wl-summary-unmark-region +Delete temporal mark on the messages in the specified region. +(@code{wl-summary-unmark-region}) + +@item r y +@kindex r y (Summary) +Save messages in the specified region. +@findex wl-summary-save-region +(@code{wl-summary-save-region}) + +@item t R +@kindex t R (Summary) +@findex wl-thread-mark-as-read +Mark as read messages which are the descendant of the current thread. +With prefix argument, it affects on the all messages in the thread tree. +(@code{wl-thread-mark-as-read}) + +@item t $ +@kindex t $ (Summary) +@findex wl-thread-mark-as-important +Put important mark @samp{$} on the messages which are the +descendant of the current thread. +If @samp{$} mark exists, it is deleted. +With prefix argument, it affects on the all messages in the thread tree. +(@code{wl-thread-mark-as-important}) + +@item t ! +@kindex t ! (Summary) +@findex wl-thread-mark-as-unread +Mark as unread messages which are the descendant of the current thread. +With prefix argument, it affects on the all messages in the thread tree. +(@code{wl-thread-mark-as-unread}) + +@item t i +@kindex t i (Summary) +@findex wl-thread-prefetch +Prefetch messages which are the descendant of the current thread. +With prefix argument, it affects on the all messages in the thread tree. +(@code{wl-thread-prefetch}) + +@item t x +@kindex t x (Summary) +@findex wl-thread-exec +Execute @samp{D}, @samp{o} and @samp{O} marks on the messages which are +the descendant of the current thread. With prefix argument, it affects +on the all messages in the thread tree. +(@code{wl-thread-exec}) + +@item t * +@kindex t * (Summary) +@findex wl-thread-target-mark +Put target mark @samp{*} on the messages which are the descendant of the +current thread. With prefix argument, it affects on the all messages in +the thread tree. +(@code{wl-thread-target-mark}) + +@item t o +@kindex t o (Summary) +@findex wl-thread-refile +Put refile mark on the messages which are the descendant of the current thread. +With prefix argument, it affects on the all messages in the thread tree. +(@code{wl-thread-refile}) + +@item t O +@kindex t O (Summary) +@findex wl-thread-copy +Put copy mark on the messages which are the descendant of the current thread. +With prefix argument, it affects on the all messages in the thread tree. +(@code{wl-thread-copy}) + +@item t d +@kindex t d (Summary) +@findex wl-thread-delete +Put delete mar on the messages which are the descendant of the current thread. +With prefix argument, it affects on the all messages in the thread tree. +(@code{wl-thread-delete}) + +@item t u +@kindex t u (Summary) +@findex wl-thread-unmark + +Unmark temporal mark on the messages which are the descendant of the +current thread. With prefix argument, it affects on the all messages in +the thread tree. +(@code{wl-thread-unmark}) + +@item t y +@kindex t y (Summary) +@findex wl-thread-save +Save messages which are the descendant of the current thread. +With prefix argument, it affects on the all messages in the thread tree. +(@code{wl-thread-save}) + +@item m i +@kindex m i (Summary) +@findex wl-summary-target-mark-prefetch +Prefetch all messages which have target mark @samp{*}. +(@code{wl-summary-target-mark-prefetch}) + +@item m R +@kindex m R (Summary) +@findex wl-summary-target-mark-mark-as-read +Mark as read all messages which have target mark @samp{*}. +(@code{wl-summary-target-mark-mark-as-read}) + +@item m $ +@kindex m $ (Summary) +@findex wl-summary-target-mark-mark-as-important +Mark as important all messages which have target mark @samp{*}. +If already marked as @samp{$}, it is deleted. +(@code{wl-summary-target-mark-mark-as-important}) + +@item m ! +@kindex m ! (Summary) +@findex wl-summary-target-mark-mark-as-unread +Mark as unread all messages which have target mark @samp{*}. +(@code{wl-summary-target-mark-mark-as-unread}) + +@item m o +@kindex m o (Summary) +@findex wl-summary-target-mark-refile +Put refile mark on the messages which have target mark @samp{*}. +(@code{wl-summary-target-mark-refile}) + +@item m O +@kindex m O (Summary) +@findex wl-summary-target-mark-copy +Put copy mark on the messages which have target mark @samp{*}. +(@code{wl-summary-target-mark-copy}) + +@item m d +@kindex m d (Summary) +@findex wl-summary-target-mark-delete +Put delete mark on the messages which have target mark @samp{*}. +(@code{wl-summary-target-mark-delete}) + +@item m y +@kindex m y (Summary) +@findex wl-summary-target-mark-save +Save messages which have target mark @samp{*}. +(@code{wl-summary-target-mark-save}) + +@item m u +@kindex m u (Summary) +Unmark all temporal marks. +(@code{wl-summary-delete-all-temp-marks}) +@findex wl-summary-delete-all-temp-marks + +@item m a +@kindex m a (Summary) +Put target mark @samp{*} on the all messages. +(@code{wl-summary-target-mark-all}) +@findex wl-summary-target-mark-all + +@item m t +@kindex m t (Summary) +Put target mark @samp{*} on the messages in the current thread. +@findex wl-summary-target-mark-thread +(@code{wl-summary-target-mark-thread}) + +@item m r +@kindex m r (Summary) +@findex wl-summary-target-mark-region +Put target mark @samp{*} on the messages in the specified region. +(@code{wl-summary-target-mark-region}) + +@item m A +@kindex m A (Summary) +@findex wl-summary-target-mark-reply-with-citation +Prepare a draft which cites all messages which have target mark @samp{*}. +(@code{wl-summary-target-mark-reply-with-citation}) + +@item m f +@kindex m f (Summary) +@findex wl-summary-target-mark-forward +Prepare a draft which forwards all messages which have target mark @samp{*}. +(@code{wl-summary-target-mark-forward}) + +@item m U +@kindex m U (Summary) +@findex wl-summary-target-mark-uudecode +Uudecode the messages which have target mark @samp{*}. +(@code{wl-summary-target-mark-uudecode}) + +@item m ? +@kindex m ? (Summary) +@findex wl-summary-target-mark-pick +Pick messages from the @samp{*} marked messages. +That is, @samp{*} marks on the messages are remained +if the specified condition is satisfied. +(@code{wl-summary-target-mark-pick}) + +@item M-t +@kindex M-t (Summary) +@findex wl-toggle-plugged +Toggle offline/online status of Wanderlust. +(@code{wl-toggle-plugged}) + +@item C-t +@kindex C-t (Summary) +Start Wanderlust's plug-status manager. +(@code{wl-plugged-change}) + +@item C-c C-o +@kindex C-c C-o (Summary) +@findex wl-jump-to-draft-buffer +Move to the draft buffer if available. If multiple draft buffer exists, +moved to one after another. If prefix argument is specified, load draft +folder's message to the draft buffer and jump to it. +(@code{wl-jump-to-draft-buffer}) +@end table + +@section Customize variables + +@table @code +@item wl-summary-move-order +@vindex wl-summary-move-order +The initial setting is 'unread. +Specify cursor moving policy. +If you want to precede new messages, set 'new. +If you want to precede unread messages, set 'unread. +If nil, proceed to next message. + +@item wl-auto-select-first +@vindex wl-auto-select-first +The initial setting is nil. +If non-nil, first message is automatically displayed. + +@item wl-auto-select-next +@vindex wl-auto-select-next +The initial setting is nil. +If non-nil, jump to next summary automatically. +If 'unread, jump to next unread folder's summary after confirmation. +If 'skip-no-unread, unread folders are automatically skipped. + +@item wl-thread-insert-opened +@vindex wl-thread-insert-opened +The initial setting is nil. +If non-nil, thread is inserted as opened. + +@item wl-thread-open-reading-thread +@vindex wl-thread-open-reading-thread +The initial setting is t. +If non-nil, reading thread is automatically opened though it is closed thread. + +@item wl-summary-exit-next-move +@vindex wl-summary-exit-next-move +The initial setting is t. +If non-nil, move to next folder at summary exit. + +@item wl-folder-move-cur-folder +@vindex wl-folder-move-cur-folder +The initial setting is nil. +If non-nil, cursor position on the folder is moved. + +@item wl-summary-weekday-name-lang +@vindex wl-summary-weekday-name-lang +The initial setting is "ja". +Specify language of the weekday. +"en" displays English, "fr" displays French, "de" displays Deutsch. + +@item wl-summary-fix-timezone +@vindex wl-summary-fix-timezone +The initial setting is "JST". +Timezone to adjust summary's timezone. +If nil, adjust to UTC. + +@item wl-use-petname +@vindex wl-use-petname +The initial setting is t. +If non-nil, sender part displays nickname. + +@item wl-break-pages +@vindex wl-break-pages +The initial setting is t. +If non-nil, message is splitted as pages by @samp{^L}. + +@item wl-message-window-size +@vindex wl-message-window-size +The initial setting is '(1 . 4). +A cons cell to specify the rate of summary and message window. +car:cdr corresponds summary:message. + +@item wl-summary-recenter +@vindex wl-summary-recenter +The initial setting is t. +If non-nil, cursor point is moved to the center of the summary window. + +@item wl-summary-indent-length-limit +@vindex wl-summary-indent-length-limit +The initial setting is 46. +Specify the limit of thread indent level. +If nil, max indent level is unlimited. + +@item wl-summary-no-from-message +@vindex wl-summary-no-from-message +The initial setting is "nobody@@nowhere?". +A string which is displayed when there's no From: field in the message. + +@item wl-summary-no-subject-message +@vindex wl-summary-no-subject-message +The initial setting is "(WL:No Subject in original.)". +A string which is displayed when there's no Subject: field in the message. + +@item wl-summary-width +@vindex wl-summary-width +The initial setting is 80. +Width of summary line. If nil, summary line's width is as is. + +@item wl-use-folder-petname +@vindex wl-use-folder-petname +The initial setting is '(modeline). +A list of display policy (symbol) of folder nickname. +Available symbols are: + +@table @code +@item modeline +Display folder petname on modeline. +@item ask-folder +Destination folder is notified as nickname if +@code{wl-auto-select-next} is non-nil. +@item read-folder +You can input folder name by nickname in the function +@code{wl-summary-read-folder}. +@end table + +@item wl-summary-move-direction-toggle +@vindex wl-summary-move-direction-toggle +The initial setting is t. +If non-nil, last executed @kbd{p}, @kbd{P}, @kbd{n}, @kbd{N} toggles +the direction of cursor move. +If you want to aware of reading direction, set this to t. + +@item wl-from-width +@vindex wl-from-width +The initial setting is 17. +Width of sender part of summary line. + +@item wl-summary-divide-thread-when-subject-changed +@vindex wl-summary-divide-thread-when-subject-changed +The initial setting is nil. +If non-nil, thread is splitted if the subject is changed. + +@item wl-summary-search-via-nntp +@vindex wl-summary-search-via-nntp +The initial setting is 'confirm. +If non-nil and @code{wl-summary-jump-to-msg-by-message-id} failed, +call @code{wl-summary-jump-to-msg-by-message-id-via-nntp} and +search message from the NNTP server @code{elmo-default-nntp-server}. +The value of @code{elmo-default-nntp-user}, @code{elmo-default-nntp-port}, +@code{elmo-default-nntp-ssl} are used. If 'confirm, server name can +be specified. You can specify NNTP folder format like +@samp{-:username@@servername:119!}. + +@item wl-summary-keep-cursor-command +@vindex wl-summary-keep-cursor-command +The initial setting is +'(wl-summary-goto-folder wl-summary-goto-last-visited-folder). +When you entered to summary by these commands and the target summary +buffer already exists, summary status is not automatically updated and +cursor position is saved. + +@item wl-summary-update-confirm-threshold +@vindex wl-summary-update-confirm-threshold +The initial setting is 500. +If updated message number is larger than this value, +confirm whether drop them or not. + +@item wl-summary-always-sticky-folder-list +@vindex wl-summary-always-sticky-folder-list +The initial setting is nil. +@code{wl-summary-always-sticky-folder-list} specifies the folders that are +automatically sticked. Each element is regexp of folder name. + +@item wl-summary-reserve-mark-list +@vindex wl-summary-reserve-mark-list +The initial setting is '("o" "O" "D"). +If a message is already marked as temporal marks in this list, +the message is not marked by any mark command. + +@item wl-summary-skip-mark-list +@vindex wl-summary-skip-mark-list +The initial setting is '("D"). +If a message is already marked as temporal marks in this list, +the message is skipped at cursor move. + +@item wl-fetch-confirm-threshold +@vindex wl-fetch-confirm-threshold +The initial setting is 30000 (bytes). +If displaying message has larger size than this value, +Wanderlust confirms whether fetch the message or not. +If nil, the message is fetched without confirmation. + +@item wl-prefetch-threshold +@vindex wl-prefetch-threshold +The initial setting is 30000 (bytes). +If prefetching message has larger size than this value and +@code{wl-prefetch-confirm} is non-nil, +Wanderlust confirms whether prefetch the message or not. +If @code{wl-prefetch-threshold} is nil, the message is prefetched +without confirmation. + +@item wl-prefetch-confirm +@vindex wl-prefetch-confirm +The initial setting is t. If non-nil, +Wanderlust confirms whether prefetch the message or not if the +message has larger size than @code{wl-prefetch-threshold}. + +@item wl-cache-fetch-threshold +@vindex wl-cache-fetch-threshold +The initial setting is 30000 (bytes). +The messages which have larger size than @code{wl-fetch-confirm-threshold} +are skipped buffer caching mechanism. If nil, any messages are prefetched by +buffer caching mechanism. + +@item elmo-imap4-use-cache +@vindex elmo-imap4-use-cache +The initial setting is t. +If non-nil, messages read via IMAP4 are cached. + +@item elmo-nntp-use-cache +@vindex elmo-nntp-use-cache +The initial setting is t. +If non-nil, messages read via NNTP are cached. + +@item elmo-pop3-use-cache +@vindex elmo-pop3-use-cache +The initial setting is t. +If non-nil, messages read via POP3 are cached. +@end table + +@c +@c Message +@c +@node Message, Draft, Summary, Top +@chapter Message Buffer + +Message Buffers utilize MIME-View mode of SEMI/tm. +For operational procedures and key bindings, refer to respective +documents. +@xref{MIME-View, , ,mime-ui-ja, a MIME user interface for GNU Emacs}. + +@kbd{p} at the top of a message or @kbd{n} at the bottom of a message +brings you back to Summary mode. +@kbd{l} toggles display of Summary mode buffer. + +@section Key Bindings + +@table @kbd + +@item l +@kindex l (Message) +@findex wl-message-toggle-disp-summary +Toggles display of Summary mode buffer. +(@code{wl-message-toggle-disp-summary}) + +@item Button-2 +@findex wl-message-refer-article-or-url +@kindex Button-2 (Message) +Assumes Message-ID at the mouse pointer, and shows the corresponding +message if found. +(@code{wl-message-refer-article-or-url}) + +@item Button-4 (upward movement of a wheel) +@kindex Button-4 (Message) +@findex wl-message-wheel-down +Scrolls the message backwards. When the top of the message is hit, +moves to the previous message. +(@code{wl-message-wheel-down}) + +@item Button-5 (downward movement of a wheel) +@kindex Button-5 (Message) +@findex wl-message-wheel-up +Scrolls the message forward. When the bottom of the message is hit, +moves to the next message. +(@code{wl-message-wheel-up}) +@end table + +@section Customizable Variables + +@table @code +@item wl-message-window-size +@vindex wl-message-window-size +Initial setting is @code{'(1 . 4)}. It is a cons cell and the ratio of +its car and cdr value corresponds to the ratio of Summary and Message +windows. +@end table + +@c +@c Draft +@c +@node Draft, Disconnected Operations, Message, Top +@chapter Draft Buffer + +At Summary mode, pressing @kbd{w} and the like creates a new draft +buffer. You can edit and send mail and news articles in this buffer. + +@section Tips + +Basically it is Emacs-standard mail mode. + +@subsection Address Completion + +Initially, the cursor is at the To: field. Fill in recipients +addresses. @kbd{@key{TAB}} completes them. + +If you want to submit a news article, add Newsgroups: field by +yourself. Field names can be completed by @kbd{@key{TAB}}. + +If you save the draft buffer you are editing, it is appended to the +folder specified by @code{wl-draft-folder}. + +Using FCC: field, you can specify the folder to which a copy of the +message is saved when it is sent. + +@subsection Editing Messages + +Multi-part editing utilize MIME edit mode of SEMI/tm. For procedures of +editing, refer to respective documents. +@xref{Mail Methods, , ,mime-ui-ja, a MIME user interface for GNU Emacs}. + +@subsection Dynamic Modification of Messages +@vindex wl-draft-config-alist + +@c @cindex Change Message +@c @cindex Message, Change Dynamic + +You can set @code{wl-draft-config-alist} so that header and body of the +message will automatically modified depending on information of header +and others. + +The initial setting of @code{wl-draft-config-alist} is nil. + +In the example below, the header is modified when +@code{wl-draft-send-and-exit} or @code{wl-draft-send} is invoked. +You can set @code{wl-interactive-send} to non-nil so as to confirm +changes before sending the message. + +@lisp +(setq wl-draft-config-alist + '(((string-match "aaa.ne.jp$" (system-name)) + ;; @r{applied if the expression is non-nil} + (wl-smtp-posting-server . "mailserver-B") + (wl-nntp-posting-server . "newsserver-B") + ;; @r{settings of temporary variables} + ) + ("^To: .*user@@aaa.bbb.com" + ;; @r{applied if it matches the header of the draft buffer} + ("Organization" . (format "Go %s" my-webpage))) + ;; @r{you can write elisp expressions here (eval only)} + (top . "Hello.\n") ;; @r{inserted at the top of the body} + (bottom . "\nBye.\n") ;; @r{inserted at the bottom of the body} + )) +@end lisp + +The format of @code{wl-draft-config-alist} is: + +@example +'(("regexp of the header" or elisp expression + ("Field" . value(elisp expression)) + (variable . value(elisp expression)) + (sub-function . value(elisp expression)) + function + @dots{}) + ("regexp of the header" or elisp expression + ("Field" . value(elisp expression)) + @dots{})) +@end example + +Per default, there are 10 following sub-functions. + +@example +'header: Inserts the specified string at the bottom of the header. +'header-file: Inserts the specified file at the bottom of the header. +'x-face: Inserts "X-Face" field with the content of the specified file. +'top: Inserts the specified string at the top of the body. +'top-file: Inserts the specified file at the top of the body. +'body: Replaces the body with the specified string. + Specifying nil deletes the entire body string. +'body-file: Replaces the body with the content of the specified file. +'bottom: Inserts the specified string at the bottom of the body. +'bottom-file: Inserts the specified file at the top of the body. +'template: Applies the specified template. + (refer to the next subsection) +@end example + +These are defined in @code{wl-draft-config-sub-func-alist} and you can +change them or add your own functions. If you read the code, you can +easily find how to write the functions. + +At the first of each item, "a regular expression of the header" or an +elisp expression should be specified. In the case of an elisp +expression, the item is applied when the expression is evaluated +non-nil. + +Per default, when multiple items match or are evaluated non-nil, all +such items are applied, but if you set a variable +@code{wl-draft-config-matchone} to t, only the first matching one is +applied. + +At the second of the item, a cons or a list of functions should be +specified. The car part of the cons should be a header field, a +variable, or a sub-function. When a header field is specified, the field +will be modified. If a variable is specified, the value of the variable +will be modified temporarily. + +In the cdr part of a cons, not only a variable but also an elisp +expression can be specified as is. If the car part is a header field +and the cdr part is nil, the field will be deleted. + +See the next example as well: + +@lisp +(setq wl-draft-config-alist + '((reply ;; @r{(1)} + "X-ML-Name: \\(Wanderlust\\|emacs-mime-ja\\|apel-ja\\)" + ;; @r{applied if it matches the header of the buffer being replied} + (body . " Hello.\n") + (template . "default") + ))) +@end lisp + +As in the (1) above, if a header regexp is prepended with @code{reply}, +it is applied when the draft is prepared by @code{wl-summary-reply} for +example, and when it matches the header being replied. It is ignored +when there is no buffer being replied, like after @code{wl-draft} was +invoked. + +Note that @code{wl-draft-config-alist} is applied only once when +@code{wl-draft-send-and-exit} or @code{wl-draft-send} is invoked. +Therefore, if you want to apply @code{wl-draft-config-alist} again after +aborting transmission, execute @kbd{C-c C-e} +(@code{wl-draft-config-exec}). + +If you want to apply @code{wl-draft-config-alist} when a draft buffer is +prepared, do the following: + +@lisp +(add-hook 'wl-mail-setup-hook 'wl-draft-config-exec) +@end lisp + +@subsection Inserting Templates +@cindex Template +@cindex Apply Template + +Set a variable @code{wl-template-alist}, and type +@kbd{C-c C-j} or @kbd{M-x wl-template-select} +in the draft buffer. + +The format of @code{wl-template-alist} is almost the same as +@code{wl-draft-config-alist}. + +@lisp +(setq wl-template-alist + '(("default" + ("From" . wl-from) + ("Organization" . "~/.wl sample") + (body . "Hello.\n")) + ("report" + (template . "default") ;; @r{(a)} + ("To" . "jousi@@kaisha.jp") + ("Subject" . "Report") + (body-file . "~/work/report.txt") + ) + )) +@end lisp + +As you can see, the only difference is item (template) names such as +"default" and "report", instead of a regexp of header. +Because definition of each item is the same as +@code{wl-draft-config-alist}, you can call another template, like (a). + +Executing the command @code{wl-template-select} results in template +selection, but the result differs depending on variable +@code{wl-template-visible-select}. + +If @code{wl-template-visible-select} is t (default), a buffer window is +shown below the draft buffer. You can select a template by @kbd{n} and +@kbd{p} seeing the buffer window. + +Press the RETURN key and the template is actually applied to the draft +buffer. If you press @kbd{q}, nothing is applied. In addition, you can +adjust the window size by @code{wl-template-buffer-lines}. + +If @code{wl-template-visible-select} is nil, you should type the name of +the template in the mini buffer. + +As shown in the example in @code{wl-draft-config-alist}, you can select +"default" template by writing: + +@example +(template . "default") +@end example + +@noindent + +@subsection Sending mail by POP-before-SMTP +@cindex POP-before-SMTP + +You can send mail by POP-before-SMTP with this single line: + +@lisp +(setq wl-draft-send-mail-func 'wl-draft-send-mail-with-pop-before-smtp) +@end lisp + +@noindent +Configure the following variables if you need. + +@table @code +@item wl-pop-before-smtp-user +The POP user name for POP-before-SMTP authentication. +If unset, @code{elmo-default-pop3-user} is used. + +@item wl-pop-before-smtp-server +The POP server name for POP-before-SMTP authentication. +If unset, @code{elmo-default-pop3-server} is used. + +@item wl-pop-before-smtp-authenticate-type +The POP authentication method for POP-before-SMTP authentication. +If unset, @code{elmo-default-pop3-authenticate-type} is used. + +@item wl-pop-before-smtp-port +The POP port number for POP-before-SMTP authentication. +If unset, @code{elmo-default-pop3-port} is used. + +@item wl-pop-before-smtp-ssl +If non-nil, POP connection is established using SSL. +If 'starttls, STARTTLS (RFC2595) connection will be established. +If unset, @code{elmo-default-pop3-ssl} is used. +@end table + +If variables for POP-before-SMTP (@code{wl-pop-before-smtp-*}) are +unset, settings for POP folders (@code{elmo-default-pop3-*}) are +used. +Therefore, if SMTP server and POP server are actually the same, and if +POP folder per default (such as @samp{&}) is available, no settings are +required. + +Refer to the following URL about POP-before-SMTP. + +@example +http://spam.ayamura.org/tools/smPbS.html +http://www.iecc.com/pop-before-smtp.html +@end example + +@section Key Bindings +@cindex Keybind, Draft Mode +@cindex Keybind, Draft Buffer + +@table @kbd + +@item C-c C-y +@kindex C-c C-y (Draft) +@findex wl-draft-yank-original +Cites the content of the current message buffer. +(@code{wl-draft-yank-original}) + +@item C-c C-p +@kindex C-c C-p (Draft) +@findex wl-draft-preview-message +Previews the content of the current draft. +This is useful for previewing MIME multi-part messages. +(@code{wl-draft-preview-message}) + +@item C-c C-s +@kindex C-c C-s (Draft) +@findex wl-draft-send +Sends the content of the current draft. Does not erase the draft buffer. +This is useful for sending multiple messages, which are a little different +from each other. +(@code{wl-draft-send}) + +@item C-c C-c +@kindex C-c C-c (Draft) +@findex wl-draft-send-and-exit +Sends the content of the current draft and erases the draft buffer. +(@code{wl-draft-send-and-exit}) + +@item C-x C-s +@kindex C-x C-s (Draft) +@findex wl-draft-save +Save the current draft. +(@code{wl-draft-save}) + +@item C-c C-k +@kindex C-c C-k (Draft) +@findex wl-draft-kill +Kills the current draft. +(@code{wl-draft-kill}) + +@c @item C-x k +@c @kindex C-x k (Draft) +@c @findex wl-draft-mimic-kill-buffer +@c Kills the current draft. +@c (@code{wl-draft-mimic-kill-buffer}) + +@item C-c C-z +@kindex C-c C-z (Draft) +@findex wl-draft-save-and-exit +Saves the current draft, and erases the draft buffer. +This is useful if you want to suspend editing of the draft. +You can resume editing by pressing @kbd{E} (@code{wl-summary-reedit}) in +the @samp{+draft} folder. +(@code{wl-draft-save-and-exit}) + +@item C-c C-r +@kindex C-c C-r (Draft) +@findex wl-caesar-region +Encodes or decodes the specified region in Caesar cipher. +(@code{wl-caesar-region}) + +@item M-t +@kindex M-t (Draft) +@findex wl-toggle-plugged +Toggles off-line/on-line states of Wanderlust. +(@code{wl-toggle-plugged}) + +@item C-c C-o +@kindex C-c C-o (Draft) +@findex wl-jump-to-draft-buffer +Jumps to the other draft buffer, if exists. +With prefix argument, reads a file (if any) from the draft folder when +there is no such buffer. +(@code{wl-jump-to-draft-buffer}) + +@item C-c C-e +@kindex C-c C-e (Draft) +@findex wl-draft-config-exec +Applies @code{wl-draft-config-alist}. +(@code{wl-draft-config-exec}) + +@item C-c C-j +@kindex C-c C-j (Draft) +@findex wl-template-select +Selects a template. +(@code{wl-template-select}) + +@item C-c C-a +@kindex C-c C-a (Draft) +@findex wl-draft-insert-x-face-field +Inserts the content of a file @file{~/.xface} (the value of the variable +@code{wl-x-face-file}) as an X-Face field in the draft buffer. + +There should be encoded X-Face strings as a content of a file @file{~/.xface}. +(@code{wl-draft-insert-x-face-field}) +@end table + +@section Customizable Variables + +@table @code +@item wl-subscribed-mailing-list +@vindex wl-subscribed-mailing-list +The initial setting is nil. +Mailing lists to which you subscribe. +If any of these are contained in To or Cc field of a reply draft, +removes your own address from Mail-Followup-To and Cc. +And if any of these are contained in To or Cc field of a message to be +automatically re-filed, the destination folder will be leaned in +connection with the address. +@item wl-insert-mail-followup-to +@vindex wl-insert-mail-followup-to +The initial setting is nil. +If non-nil, Mail-Followup-To field is automatically inserted in the +draft buffer. + +@item wl-insert-mail-reply-to +@vindex wl-insert-mail-reply-to +The initial setting is nil. +If non-nil, Mail-Reply-To field is automatically inserted in the +draft buffer. + +@item wl-auto-insert-x-face +@vindex wl-auto-insert-x-face +The initial setting is t. +If non-nil and there is an encoded X-Face string in a file +@file{~/.xface} (the value of the variable @code{wl-x-face-file}), +inserts it as an X-Face field in the draft buffer. +If nil, it is not automatically inserted. Press @kbd{C-c C-a} to insert. + +@item wl-insert-message-id +@vindex wl-insert-message-id +The initial setting is t. +If non-nil, Message-ID field is automatically inserted on the +transmission. + +@item wl-local-domain +@vindex wl-local-domain +The initial setting is nil. +If nil, the return value of the function @code{system-name} will be +used as the domain part of Message-ID. + +If @code{system-name} does not return FQDN (i.e. the full name of the +host, like @samp{smtp.gohome.org}), you @strong{must} set this variable to the +string of the local domain name without hostname (like @samp{gohome.org}). +That is, a concatenation of @code{system-name} "." @code{wl-local-domain} +is used as domain part of the Message-ID. + +If your terminal does not have global IP, set the value of +@code{wl-message-id-domain}. +(You might be beaten up on the Net News if you use invalid Message-ID.) + +Moreover, +concatenation of @code{system-name} "." @code{wl-local-domain} +will be used as an argument to the HELO command in SMTP. + +@item wl-message-id-domain +@vindex wl-message-id-domain +The initial setting is nil. +If non-nil, this value is used as a domain part of the Message-ID. +If your terminal does not have global IP, set unique string to this value +(e.x. your e-mail address). + +@item wl-message-id-domain +@vindex wl-message-id-domain +The initial setting is nil. +If nil, the return value of the function @code{system-name} will be +used as the domain part of Message-ID. +If @code{system-name} does not return FQDN (i.e. the full name of the +host, like smtp.gohome.org), you @strong{must} set this variable to the +string of the full name of the host. Otherwise, you might be beaten up +on the Net News. + +@item wl-draft-config-alist +@vindex wl-draft-config-alist +The initial setting is nil. +Modifies the draft message just before the transmission. +The content of @code{wl-draft-config-alist} will be automatically +applied only once on the transmission. If you want to apply it +manually, use @kbd{C-c C-e}. This command can be used many times. + +@item wl-template-alist +@vindex wl-template-alist +The initial setting is nil. +This variable specifies the template to be applied in the draft buffer. + +@item wl-draft-config-matchone +@vindex wl-draft-config-matchone +The initial setting is nil. +If non-nil, only the first matching item is used when +@code{wl-draft-config-alist} is applied. If nil, all matching items are +used. + +@item wl-template-visible-select +@vindex wl-template-visible-select +The initial setting is t. +If non-nil, you can preview the result of the template selection in +another window. + +@item wl-template-confirm +@vindex wl-template-confirm +The initial setting is nil. +If non-nil, asks for confirmation when you press the enter key to select +template while previewing. + +@item wl-template-buffer-lines +@vindex wl-template-buffer-lines +The initial setting is 7. +If @code{wl-template-visible-select} is non-nil, this variable specifies +the size of the preview window. + +@item wl-draft-reply-buffer-style +@vindex wl-draft-reply-buffer-style +The initial setting is 'split. +'split or 'full can be specified. +In the case of 'full, the whole frame will be used for a reply draft +buffer when it is prepared. + +@item wl-from +@vindex wl-from +The initial setting is the value of the variable @code{user-mail-address}. +The value of this variable is inserted as a From field of the draft when +it is prepared. + +@item wl-envelope-from +@vindex wl-envelope-from +The initial setting is nil. +The value of this variable is used for envelope from (MAIL FROM). +If nil, the address part of @code{wl-from} is used. + +@item wl-user-mail-address-list +@vindex wl-user-mail-address-list +The initial setting is nil. +This is the User's address list. If you have multiple addresses, +set this variable. + +@item wl-fcc +@vindex wl-fcc +The initial setting is nil. +If non-nil, the value of this variable is inserted as a FCC of the draft +when it is prepared. + +@item wl-bcc +@vindex wl-bcc +The initial setting is nil. +If non-nil, the value of this variable is inserted as a Bcc of the draft +when it is prepared. + +@item wl-reply-subject-prefix +@vindex wl-reply-subject-prefix +The initial setting is "Re: ". +In the Subject of the reply draft, this string is prepended to the +Subject of being replied. + +@item wl-draft-enable-queuing +@vindex wl-draft-enable-queuing +The initial setting is t. +This flag controls off-line transmission. If non-nil, the draft is +sent off-line. + +@item wl-auto-flush-queue +@vindex wl-auto-flush-queue +The initial setting is t. +This flag controls automatic transmission of the queue when Wanderlust +becomes on-line. If non-nil, the queue is automatically transmitted +(with confirmation by @code{y-or-n-p}). If you want to transmit it +manually, press @kbd{F} in the folder mode. + +@item wl-draft-always-delete-myself +@vindex wl-draft-always-delete-myself +If non-nil, always removes your own address from To and CC when you are +replying to the mail addressed to you. + +@item wl-smtp-posting-server +@vindex wl-smtp-posting-server +The initial setting is nil. +This is the SMTP server name for mail transmission. + +@item wl-smtp-posting-user +@vindex wl-smtp-posting-user +The initial setting is nil. +This is the user name for SMTP AUTH authentication. +If nil, @code{smtp-authenticate-user} is used. + +@item wl-smtp-authenticate-type +@vindex wl-smtp-authenticate-type +The initial setting is nil. +This is the authentication method for SMTP AUTH authentication. +If nil, @code{smtp-authenticate-type} is used. +If it is still nil, authentication will not be carried out. + +@item wl-smtp-connection-type +@vindex wl-smtp-connection-type +The initial setting is nil. +This variable specifies how to establish SMTP connections. +If nil, @code{smtp-connection-type} is used. +If it is 'starttls, STARTTLS (RFC2595) is used. + +@item wl-nntp-posting-server +@vindex wl-nntp-posting-server +The initial setting is nil. +This is the NNTP server name used for news submission. +If nil, @code{elmo-default-nntp-server} is used. + +@item wl-nntp-posting-user +@vindex wl-nntp-posting-user +The initial setting is nil. +This is the user name for AUTHINFO authentication on news submission. +If nil, @code{elmo-default-nntp-user} is used. +If it is still nil, AUTHINFO authentication will not be carried out. + +@item wl-nntp-posting-port +@vindex wl-nntp-posting-port +The initial setting is nil. +This is the port number of the NNTP server used for news submission. +If nil, @code{elmo-default-nntp-server} is used. + +@item wl-nntp-posting-ssl +@vindex wl-nntp-posting-ssl +The initial setting is nil. +If nil, @code{elmo-default-nntp-ssl} is evaluated. +If non-nil, SSL is used for news submission. +If 'starttls, STARTTLS (RFC2595) connection will be established. + +@item wl-pop-before-smtp-user +@vindex wl-pop-before-smtp-user +The initial setting is nil. +This is the POP user name for POP-before-SMTP. +If it is nil, @code{elmo-default-pop3-user} is used. + +@item wl-pop-before-smtp-server +@vindex wl-pop-before-smtp-server +The initial setting is nil. +This is the POP server name for POP-before-SMTP. +If it is nil, @code{elmo-default-pop3-server} is used. + +@item wl-pop-before-smtp-authenticate-type +@vindex wl-pop-before-smtp-authenticate-type +The initial setting is nil. +This is the authentication method for POP-before-SMTP authentication. +If it is nil, @code{elmo-default-pop3-authenticate} is used. + +@item wl-pop-before-smtp-port +@vindex wl-pop-before-smtp-port +The initial setting is nil. +This is the POP port number for POP-before-SMTP. +If it is nil, @code{elmo-default-pop3-port} is used. + +@item wl-pop-before-smtp-ssl +@vindex wl-pop-before-smtp-ssl +The initial setting is nil. +This flag controls the use of SSL for POP-before-SMTP. +If it is nil, @code{elmo-default-pop3-ssl} is used. + +@item wl-draft-queue-save-variables +@vindex wl-draft-queue-save-variables +Specifies a list of variable to which queued messages are saved on the +off-line transmission. + +@item wl-draft-sendlog +@vindex wl-draft-sendlog +The initial setting is t. +If t, transmission log is written in @file{~/.elmo/sendlog}. +It is written when drafts are sent by smtp or qmail, and when they are +saved into folders by fcc or queuing (it is written even if the +transmission fails). +But transmission by im-wl.el is not written in the sendlog and left to +the logging function of imput. + +@item wl-draft-sendlog-max-size +@vindex wl-draft-sendlog-max-size +The initial setting is 20000 (in bytes). +If @code{wl-draft-sendlog} is t, the log is rotated when it grows beyond +the size specified by this variable. +@end table + + +@c +@c Disconnected Operations +@c +@node Disconnected Operations, Expire and Archive, Draft, Top +@chapter Off-line Management +@cindex Disconnected Operations + +@section Off-line State + +Wanderlust has on-line and off-line states. +In the off-line state, you cannot access messages via network, unless +they are cached. + +@samp{[ON]} in the mode line indicates the on-line state. +@samp{[--]} in the mode line indicates the off-line state. +In folder or summary modes, press @kbd{M-t} to switch between off- +and on-line. + +You can invoke Wanderlust in the off-line state by setting +@code{wl-plugged} to nil in @file{~/.wl} or anything appropriate. + +Even in the off-line state, provided that relevant messages are cached, +and the variable @code{elmo-enable-disconnected-operation} (described +later) is non-nil, you can: + +@itemize @minus +@item transmit messages +@item re-file and copy (IMAP4) +@item create folders (IMAP4) +@item mark (IMAP4) +@item pre-fetch (IMAP4, NNTP) +@end itemize + +As soon as Wanderlust becomes on-line, such operations invoked +off-line are reflected in the servers via network. + +@section Transmission of Messages + +You can send mail/news messages off-line (if you are using im-wl.el, it +is irrelevant). Messages sent off-line are accumulated in the queue +folder, @samp{+queue}. These messages are transmitted at once when +Wanderlust becomes on-line. + +You can visit @samp{+queue} in the off-line state and confirm content +of messages in the queue. You can also remove messages. Removed messages +are not transmitted even in the on-line state. + +@section Re-file and Copy (IMAP4) + +Re-file and copy operations to IMAP folders invoked during the off-line +state are accumulated in the queue, and reflected in the server side +when Wanderlust becomes on-line. If you visit destination folders after +off-line re-file or copy, it looks as if messages were appended even in +off-line state. + +For the safety reasons, messages re-filed off-line are removed from +source folders only if their Message-ID match messages on the servers. +While the queue is processed, messages that failed to be re-filed or +copied to the specified folders are appended to the folder +@samp{+lost+found}. + +@section Creation of Folders (IMAP4) + +You can create IMAP folders off-line. The creation of folders are +reflected in the servers when Wanderlust becomes on-line. At that time, +if folders failed to be created on the servers for any reasons, messages +re-filed to such folders are appended to the folder "+lost+found". + +@section Marking (IMAP4) + +Off-line changes in unread/read and importance mark @samp{$} information +are also reflected in the servers when Wanderlust becomes on-line. + +@section Pre-fetching (IMAP4, NNTP) + +You can make reservations for pre-fetching messages in IMAP or NNTP +folders. Reserved messages are marked with @samp{!} but not cached +yet. When Wanderlust becomes on-line, they are pre-fetched from +servers. + +If the variable @code{elmo-enable-disconnected-operation} is nil, these +off-line operations for IMAP4 and NNTP do not take place, and off-line +re-file, copy or suchlike simply results in error. + +Because off-line operations use cache files, it is a bad idea to erase +them by hand; it may cause Wanderlust to malfunction. + +If you want to remove caches, be sure to execute +@kbd{M-x elmo-cache-expire-by-size}. +@code{elmo-cache-expire-by-size} does not remove caches for messages +relevant to off-line operations. + +@section Switching On-line/Off-line per Server/Port + +@kbd{M-t} described above switches networking states as a whole, but you +can switch on-line/off-line per server/port. + +Pressing @kbd{C-t} in the folder or summary modes brings you in +wl-plugged-mode shown below, in which you can change the plugged state +for each port. + +@example +Queuing:[ON] AutoFlushQueue:[--] DisconnectedOperation:[ON] +[ON](wl-plugged) + [--]hosta + [--]smtp +queue: 2 msgs (1,2) @dots{}@r{sending queue} + [--]nntp(119) +queue: 1 msg (3) @dots{}@r{sending queue} + [ON]hostb + [--]imap4/cram-md5(143) %#mh/wl(prefetch-msgs:3,mark-as-important:1) + %inbox(delete-msgids:1) @dots{}@r{dop queue} + [ON]nntp(119) + [ON]smtp +@end example + +The first line indicates status of the following three variables, and +simply pressing @kbd{@key{SPC}} or @kbd{@key{RET}} in each labelled +column modifies the values of these variables. + +@example +"Queuing" wl-draft-enable-queuing +"AutoFlushQueue" wl-auto-flush-queue +"DisconnectedOperation" elmo-enable-disconnected-operation +@end example + +where @samp{[ON]} means its value is t, and @samp{[--]} means nil. + +The second and after lines indicate on-line/off-line states of servers +and ports, where @samp{[ON]} stands for on-line and @samp{[--]} for +off-line (in XEmacs, they are shown with icons). Pressing +@kbd{@key{SPC}} or @kbd{@key{RET}} in each line switches its state. + +"sending queue" means messages accumulated in the folder @samp{+queue} +for off-line transmission, and "dop queue" means off-line operations +when @code{elmo-enable-disconnected-operation} is t. +@c If the variable @code{elmo-enable-disconnected-operation} is non-nil, +@c off-line operations are enabled. + +They are displayed if there are any of them. In the example above, +in the sending queue there are two messages (the first and the second +in the queue folder) for smtp to hosta and one (the third) for nntp to +hosta, and in the dop queue there are one for @samp{%inbox} and two for +@samp{%#mh/wl}. + +If you change (wl-plugged) in the second line, the variable +@code{wl-plugged} is changed, so that the mode line indicator and +plugged states of all ports are affected. +If you change plugged states of any servers or ports, wl-plugged in the +second line is affected depending on @code{elmo-plugged-condition} +settings and the plugged state of each port. + +@section Invoking Wanderlust in the Off-line State + +As described before, if you set @code{wl-plugged} to nil in @file{~/.wl} +or anything appropriate, you can invoke Wanderlust in the off-line +state. You can specify off-line state on a per server or port basis. +Refer to @code{wl-reset-plugged-alist} also. + +Usually, when Wanderlust starts up, the plugged state of each port is +read from @file{~/.folder} and @code{wl-smtp-posting-server}, +@code{wl-nntp-posting-server} and so on. If you want to change the +plugged state of these ports or to add other ports, configure +@code{wl-make-plugged-hook} with a function. + +@lisp +(add-hook 'wl-make-plugged-hook + '(lambda () + (elmo-set-plugged plugged-value(t/nil) server port) + ;; @r{add or change plugged states of the port of the server} + (elmo-set-plugged plugged-value(t/nil) server) + ;; @r{if the port is omitted, all ports are affected} + ;; @r{(you cannot omit the port if you newly add the server)} + )) +@end lisp + +@section Customizable Variables + +@table @code +@item wl-plugged +@vindex wl-plugged +If this variable is set to nil, Wanderlust starts up in off-line mode from +the beginning. + +@item wl-queue-folder +@vindex wl-queue-folder +The initial setting is "+queue". +This is the folder in which messages in the transmission queue are +accumulated. + +@item wl-auto-flush-queue +@vindex wl-auto-flush-queue +The initial setting is t. +This flag controls automatic transmission of the queue when Wanderlust +becomes on-line. If non-nil, the queue is automatically transmitted +(with confirmation by @code{y-or-n-p}). If you want to transmit it +manually, press @kbd{F} in the folder mode. + +@item elmo-enable-disconnected-operation +@vindex elmo-enable-disconnected-operation +The initial setting is nil. Controls off-line operations regarding IMAP4. +If non-nil, off-line operations are carried out. + +@item elmo-lost+found-folder +@vindex elmo-lost+found-folder +The initial setting is "+lost+found". +This is the folder to which messages are saved when they fails to be +appended while the off-line re-file/copy queue is processed. + +@item elmo-plugged-condition +@vindex elmo-plugged-condition +The initial setting is 'one. +The value of @code{wl-plugged} reflects the return value of the function +@code{elmo-plugged-p} (without arguments). +This variable @code{elmo-plugged-condition} specifies the condition on +which the return value of (elmo-plugged-p) should be t depending on the +plugged state of each port. + +@example +'one : plugged if one or more ports are plugged. +'all : plugged if all ports are plugged. +'independent : reflects wl-plugged (elmo-plugged) regardless of plugged + states of the ports. +function : reflects the return value of the function + functions available per default + 'elmo-plug-on-by-servers + : reflects the plugged state of the servers specified by the + variable elmo-plug-on-servers. + 'elmo-plug-on-by-exclude-servers + : reflects the plugged state of the servers that are not + in elmo-plug-on-exclude-servers. + elmo-plug-on-exclude-servers defaults to + '("localhost" + (system-name) + (system-name)without the domain part) +@end example + +@example +Example 1: + (setq elmo-plugged-condition 'all) +Example 2: + (setq elmo-plug-on-servers '("smtpserver" "newsserver")) + (setq elmo-plugged-condition 'elmo-plug-on-by-servers) +Example 3: + (setq elmo-plug-on-exclude-servers '("localhost" "myname")) + (setq elmo-plugged-condition 'elmo-plug-on-by-exclude-servers) +@end example + +@item wl-reset-plugged-alist +@vindex wl-reset-plugged-alist +The initial setting is t. If non-nil, plugged states are initialized on +a per server or port basis when Wanderlust starts up. + +If nil, plugged states are retained while Emacs is running. +In other words, they are initialized when Emacs is restarted even if the +value is nil. +@end table + +@c +@c Expire and Archive +@c +@node Expire and Archive, Scoring, Disconnected Operations, Top +@chapter Automatic Expiration and Archiving of Messages +@cindex Expire and Archive + +@menu +* Expire:: Expiration and Archiving +* Archive:: Archiving All Messages +@end menu + + +@node Expire, Archive, Expire and Archive, Expire and Archive +@section Expiration +@cindex Expire Message + +Expiration means deletion of old messages which have outlasted a +certain period of time. + +@code{wl-expire} supports not only simple deletion, but also moving to +specified archiving folders. + +@section How to Use + +Configure @code{wl-expire-alist} and press @kbd{e} in the folder mode, +or @kbd{M-e} in the summary mode. + +@subsection Configuring @code{wl-expire-alist} + +An example configuration of @code{wl-expire-alist} is shown below. +Everything in this @code{wl-expire-alist} makes a great difference in +expiration, so be careful. +I advise you to set @code{wl-expire-use-log} to t, especially in the +initial stage. + +@lisp +(setq wl-expire-alist + '(("^\\+trash$" (date 14) remove) + ;; @r{delete} + ("^\\+tmp$" (date 7) trash) + ;; @r{re-file to @code{wl-trash-folder}} + ("^\\+outbox$" (number 300) "$outbox;lha") + ;; @r{re-file to the specific folder} + ("^\\+ml/tmp$" nil) + ;; @r{do not expire} + ("^\\+ml/wl$" (number 500 510) wl-expire-archive-number1 t) + ;; @r{archive by message number (retaining numbers)} + ("^\\+ml/.*" (number 300 310) wl-expire-archive-number2 t) + ;; @r{archive by a fixed number (retaining numbers)} + ("^\\+nikki$" (date 30) wl-expire-archive-date) + ;; @r{archive by year and month (numbers discarded)} + )) +@end lisp + +Items in the list has the format of: + +@example +("regexp_for_folders" (specification_of_messages_to_be_deleted) destination) +@end example + +@noindent + +The folder is examined if it matches "regexp_for_folders" from the +beginning of the list. If you invoke expiration on the folder that does +not match any of them, nothing will happen. +And if either the second or the third element of the item is nil, +expiration will not take place. + +You can use any one of the following for +specification_of_message_to_be_deleted: + +@table @code +@item (number n1 [n2]) +deletes messages depending on the number of messages in the folder. + +n1 is the number of messages which should survive deletion, for example +if its value is 500, the newest 500 messages survive and the rests are +deleted. + +n2 is the number of messages in the folder on which expiration should +take place, which defaults to n1 + 1. For example if its value is 510, +folders with 510 or more messages are expired. +If you configured automatic expiration, frequently used folders may +expire every time it receive messages, and you may be annoyed with the +long delay in reading mail. +In that case, you can set a wide margin between n2 and n1, so that +expiration would not take place until a certain number of messages +accumulate. + +Messages with marks in @code{wl-summary-expire-reserve-marks} (marked +with important/new/unread) are not deleted. +If @code{wl-expire-number-with-reserve-marks} is non-nil, the folder +will expire so as to have 500 messages including such ones. +Otherwise, it will have 500 messages except such ones. + +@item (date d1) +deletes messages depending on the dates. + +Messages dated d1 or more days ago are deleted, for example if its value +is seven, messages seven days old or more are deleted. +Note that the date is the one in the Date field of the message, not when +the message entered the folder. + +Messages with no or invalid Date field does not expire; you might have +to delete them by hand. +@end table + +You can use any one of the following in the place of destination: + +@table @code +@item 'remove +deletes the messages instantly. + +@item 'trash +moves the messages to @code{wl-trash-folder}. + +@item string(folder) +moves the messages to the specified folder. + +It would be useful for specifying an archiving folder, but because this +does not move important messages, it might be better to use the +standard functions described below. + +@item function +invokes the specified function. + +To the function, three arguments are passed: a folder name, a list of +messages to be deleted, and msgdb information of the summary. +You can specify function-specific arguments after the name of the +function. +Note that the list contains messages with marks in +@code{wl-summary-expire-reserve-marks}, be careful in writing your own +function. + +These are three standard functions; they moves messages to an archive +folder in the specified way. This means old messages can be compressed +and saved in a file, being deleted from the original folder. + +@table @code +@item wl-expire-archive-number1 +re-files to archiving folders corresponding to the message numbers of +the messages being deleted. +For example, a message numbered 102 will be re-filed to +@file{wl-00100.zip}, 390 to @file{wl-00300.zip}, and so on. +If @code{wl-expire-archive-files} is 200, messages will be re-filed to +@file{wl-00000.zip}, @file{wl-00200.zip}, @file{wl-00400.zip}, @dots{}. + +The archiving folders to which messages are re-filed are determined by +the name of the folder as follows +(in this case, archiving folders are handled as if +@code{elmo-archive-treat-file} were non-nil). + +@table @code +@item If the folder type is localdir: + +@code{$ArchiveDir/foldername-xxxxx.zip} +For example, @samp{+ml/wl} corresponds to @samp{$ml/wl;zip} +(@file{~/Mail/ml/wl-00100.zip}). + +@item The folder type is other than localdir: +@code{$ArchiveDir/foldertype/foldername-xxxxx.zip} + +For example, @samp{%#mh/ml/wl} corresponds to +@samp{$imap4/#mh/ml/wl;zip} (@file{~/Mail/imap4/#mh/ml/wl-00100.zip}). +@end table + +As you can see, in the case of localdir, the folder type is not included +in the path name, but otherwise it is included. +And you can control the prefix to the archiving folder name by +@code{wl-expire-archive-folder-prefix}. +Refer to @code{wl-expire-archive-folder-prefix} for details. + +@item wl-expire-archive-number2 +re-files every certain number of messages to archiving folders. + +This differs from @samp{wl-expire-archive-number1} in that this re-files +to the folder up to the specified number regardless of message numbers. +The archiving folders to which messages are re-filed are determined in the +same way as @code{wl-expire-archive-number1}. + +@item wl-expire-archive-date +re-files messages depending on its date (year and month) to archive +folders. + +For example, a message dated December 1998 is re-filed to +@code{$folder-199812;zip}. +The name of the archiving folders except the date part are determined in +the same way as @code{wl-expire-archive-number1}. +@end table + +You can set the first argument to these three standard functions to non-nil +in @code{wl-expire-alist} so as to retain message numbers in the folder. +For example, it can be specified just after the name of the function: + +@example +("^\\+ml/wl$" (number 300 310) wl-expire-archive-number1 t) +@end example + +If you omit the argument, consecutive numbers from 1 are assigned for +each archiving folder. +@end table + +@subsection Treatment for Important or Unread Messages + +If you specify any of 'remove, 'trash, a folder name, or a standard +function, messages with marks in @code{wl-summary-expire-reserve-marks} +(which are called @dfn{reserved messages} thereafter) are retained. + +Per default, this variable include the important, new, and unread marks, +so that messages with these marks are not removed. +Note that you cannot include the temporary mark (i.e. temporary marks +are removed anyway), and be sure to process temporary marks before you +invoke expiration. + +@subsection Auto Expiration + +The following setup invokes expiration when you move into the summary +mode. There will be no confirmation, so make sure you made no mistake +in regexp and other settings before you set up this. + +@lisp +(add-hook 'wl-summary-prepared-pre-hook + 'wl-summary-expire) +@end lisp + +In the folder mode, you can invoke expiration per group as well as per +folder. Therefore, if you specify @samp{Desktop} group, all folders +matching @code{wl-expire-alist} expire. + +@section Tips + +@subsection Treating archive folders. +To treat archive folders created by @code{wl-expire-archive-number1} and so on, +you must set non-nil value to @code{elmo-archive-treat-file}. + +@subsection Confirming + +If you are to use 'remove, try 'trash at first and see messages move to +@code{wl-trash-folder} as expected, then replace it with 'remove. +It would be dangerous to use 'remove from the beginning. + +If you are to use @code{wl-expire-archive-number1} and the like, try to +make a folder of the archiver type ('zip or 'lha) and see if you can +append messages to it. +Even if settings in @code{wl-expire-alist} and @code{elmo-archive} are +correct, messages would not be saved anywhere and disappeared in case +the archiver program fails. + +After you make sure you can archive to the folder correctly, you can +invoke expiration and utilize the log. + +If you set @code{wl-expire-use-log} to t, @file{~/.elmo/expired-log} +should contain the log, for example: + +@example +delete +ml/wl (593 594 595 596 597 598 599) +move +ml/wl -> $ml/wl-00600;tgz;wl (600 601 602) +@end example + +The first column indicates the operation, i.e. delete, copy, or move. +The next is the name of the folder that expired. In the case of copy +and move, the destination folder is recorded after @samp{->}. +The last is the list of message numbers that are actually deleted or +moved (in the case of copy and move, the number is the one in the source +folder, rather than the destination folder). + +@subsection Re-filing Reserved Messages + +The three standard functions copy reserved messages to the archive +folder, but do not delete them from the source folder. Because +reserved messages and the like always remain, they are recorded in +@file{~/.elmo/expired-alist} so that they are not copied over and over +again. They are not recorded if copied by @code{wl-summary-archive}. + +If you enabled logging, usually "move" is recorded for re-filing, but +instead "copy" and "delete" are recorded separately if reserved messages +are involved. +This is because it actually copies messages including reserved, then +deletes ones except reserved in that case. + +@section Customizable Variables + +@table @code +@item wl-expire-alist +@vindex wl-expire-alist +The initial setting is nil. +This variable specifies folders and methods to expire. For details, +refer to @code{wl-expire-alist} settings above. + +@item wl-summary-expire-reserve-marks +@vindex wl-summary-expire-reserve-marks +The initial setting is the list below. + +@lisp +(list wl-summary-important-mark + wl-summary-new-mark + wl-summary-unread-mark + wl-summary-unread-uncached-mark + wl-summary-unread-cached-mark) +@end lisp + +Messages with these marks are retained in the folder, even after +expiration. +Only permanent marks can be listed, not temporary marks. + +You can list marks one by one as in the default; you can use the +following settings as well: + +@table @code +@item 'all +All messages with permanent marks are retained, +i.e. @code{wl-summary-read-uncached-mark} is included in addition to the +defaults. + +@item 'none +All messages are handled as usual ones that are already read, no matter +what marks they have; even important messages are deleted. +@end table + +@item wl-expire-archive-files +@vindex wl-expire-archive-files +The initial setting is 100. +This variable specifies the number of messages to be retained in one +archiving folder. + +@item wl-expire-number-with-reserve-marks +@vindex wl-expire-number-with-reserve-marks +The initial setting is nil. +If non-nil, if expiring messages are specified by "number", messages +with @code{wl-summary-expire-reserve-marks} are also retained. + +@item wl-expire-archive-get-folder-func +@vindex wl-expire-archive-get-folder-func +The initial setting is 'wl-expire-archive-get-folder. + +This variable specifies a function that returns the name of an archiving +folder for standard functions in the place of destination. +You can use the following three variables for simple modification of +folder names; if you want more complex settings, define your own +function in this variable. + +@code{wl-expire-archive-get-folder} can be customized by these +variables: +@itemize @bullet +@item wl-expire-archive-folder-name-fmt +@item wl-expire-archive-folder-type +@item wl-expire-archive-folder-prefix +@end itemize + +@item wl-expire-archive-folder-name-fmt +@vindex wl-expire-archive-folder-name-fmt +The initial setting is "%s-%%05d;%s". +This is a format string for archiving folders used in +@code{wl-expire-archive-number1} and @code{wl-expire-archive-number2}. +Note that you must specify the message number by @samp{%%d}, because it +is parsed twice by @code{format}. + +If you modify this, adjust @code{wl-expire-archive-folder-num-regexp} as +well. + +@item wl-expire-archive-date-folder-name-fmt +@vindex wl-expire-archive-date-folder-name-fmt +The initial setting is "%s-%%04d%%02d;%s". +This is a format string for archiving folders used in +@code{wl-expire-archive-date}. +Note that you must specify the message number by @samp{%%d}, because it +is parsed twice by @code{format}. +There should be @code{%%d} twice, one for the year and the other for the +month. + +If you modify this, adjust +@code{wl-expire-archive-date-folder-num-regexp} as well. + +@item wl-expire-archive-folder-type +@vindex wl-expire-archive-folder-type +The initial setting is 'zip. +This variable specifies an archiver type of the archiving folders. + +@item wl-expire-archive-folder-prefix +@vindex wl-expire-archive-folder-prefix +The initial setting is nil. +This variable specifies the prefix (directory structure) to archiving +folders. +Exercise extreme caution in using this feature, as it has not been +seriously tested. +In the worst case, there is a fear of destructing archiving folders. + +@table @code +@item nil +There will be no prefix. + +@item 'short +For example, @samp{+ml/wl} will be prefixed by @samp{wl}, resulting in +@samp{$ml/wl-00000;zip;wl}. + +@item t +For example, @samp{+ml/wl} will be prefixed by prefix @samp{ml/wl}, +resulting in + +@samp{$ml/wl-00000;zip;ml/wl}. +@end table + +@item wl-expire-archive-folder-num-regexp +@vindex wl-expire-archive-folder-num-regexp +The initial setting is "-\\([-0-9]+\\);". +This variable specifies the regular expression to be used for getting +message numbers from multiple archiving folders specified by +@code{elmo-list-folders}. +Set it in accordance with @code{wl-expire-archive-folder-name-fmt}. + +@item wl-expire-archive-date-folder-num-regexp +@vindex wl-expire-archive-date-folder-num-regexp +The initial setting is "-\\([-0-9]+\\);". +This is the regular expression to be used for getting message numbers +from multiple archiving folders specified by @code{elmo-list-folders}. +Set it in accordance with @code{wl-expire-archive-date-folder-name-fmt}. + +@item wl-expire-delete-oldmsg-confirm +@vindex wl-expire-delete-oldmsg-confirm +The initial setting is t. +If non-nil, messages older than the one with the largest number will be +deleted with confirmation. +If nil, they are deleted without confirmation. + +This feature is valid only if non-nil is specified as a argument to the +standard functions so as to retain numbers. + +@item wl-expire-use-log +@vindex wl-expire-use-log +The initial setting is nil. +If non-nil, expiration logs are recorded in @file{~/.elmo/expired-log}. +They are appended but not truncated or rotated automatically; you might +need to remove it manually. + +@item wl-expire-add-seen-list +@vindex wl-expire-add-seen-list +The initial setting is t. + +If non-nil, when messages are re-filed by expiration, read/unread +information is passed to the destination folder. + +However if you do not read the destination folder from Wanderlust, +@file{seen} under @file{~/.elmo/} grows larger and larger, so you might +want to set this to nil if you are simply saving to some archiving +folders. Even if its value is nil, messages in the archiving folders +are simply treated as unread; it does not affect expiration itself. + +@item wl-expire-folder-update-msgdb +@vindex wl-expire-folder-update-msgdb +The initial setting is t. +If t, in the folder mode, expiration is carried out after updating +summary information. +If you specified a list of regular expressions of folder names, summary +information is updated for matching folders only. +@end table + + +@node Archive, , Expire, Expire and Archive +@section Archiving Messages + +@subsection Archiving Messages +@kbd{M-x wl-summary-archive} copies the whole folder to archiving +folders. If there are the archiving folders already, only new messages +are appended. + +You can use @code{wl-archive-alist} in order to specify how messages are +archived according to their folder names, as in @code{wl-expire-alist}. +For example: + +@lisp +(setq wl-archive-alist + '(("^\\+tmp$" wl-archive-date) + ("^\\+outbox$" wl-archive-number2) + (".*" wl-archive-number1) + )) +@end lisp + +Each item in the list has the following format: + +@example +("folders_regexp" deleting_function) +@end example + +As you can see, you can only use a function after @samp{folders_regexp}. +Per default, there are three functions: + +@itemize @bullet +@item wl-archive-number1 +@item wl-archive-number2 +@item wl-archive-date +@end itemize + +As inferred from their names, they work similarly to "expire" versions, +other than the following points: + +@itemize @minus +@item No messages are deleted +@item Message numbers are retained even if invoked without arguments +@end itemize + +These functions are good to archive all messages in a folder by their +numbers or by their dates. +These are also useful for backup or confirmation purposes before +expiration. +If you try to re-file them after they are archived, they are deleted but +not re-filed. + +Per default, the archiving folders to which messages are copied are +determined automatically by @code{wl-expire-archive-get-folder-func}. +You can copy to a specific folder by invoking with a prefix argument, +i.e. @kbd{C-u M-x wl-summary-archive}. + +Note that this feature has not been seriously tested, because you can +simply copy to an archiving folder, for example by +@code{wl-summary-copy-region}. + +The archiving folders are determined by the same logic as in +@code{wl-summary-expire}; the following customizable variables are +relevant: + +@itemize @bullet +@item wl-expire-archive-files +@item wl-expire-archive-get-folder-func +@item wl-expire-archive-folder-name-fmt +@item wl-expire-archive-folder-type +@item wl-expire-archive-folder-prefix +@item wl-expire-archive-folder-num-regexp +@end itemize + +@subsection Customizable Variables + +@table @code +@item wl-archive-alist +@vindex wl-archive-alist +The initial setting is '((".*" wl-archive-number1)). + +This variable specifies a function that copies to archiving folders. +To the function, three arguments are passed: a folder name, a list of +messages in the folder, and msgdb information of the summary. +Needless to say, you can use your own function. +@end table + + +@c +@c Scoring +@c +@node Scoring, Customization, Expire and Archive, Top +@chapter Score of the Messages +@cindex Scoring +@c @cindex Kill File + +Scoring is the function that associates a score (value) with each +message, and marks as read or deletes from the summary according to it. + +You can put temp or important marks on essential messages, or read marks +on the ones you do not want to read, for example spam articles. + +This scoring function has a capability and a format similar to the one +that Gnus has, although there are some unsupported features and +Wanderlust specifics. + +@menu +* Score Commands:: Score Commands +* Score File Format:: Score File Format +@end menu + + +@node Score Commands, Score File Format, Scoring, Scoring +@section Score Commands +@cindex Score Commands + +@subsection Score File Specification + +@code{wl-score-folder-alist} specifies score files or variables in which +scores are defined, corresponding to folder names. + +@lisp +(setq wl-score-folder-alist + '(("^-.*" + "news.SCORE" + "my.SCORE") + (".*" + "all.SCORE"))) +@end lisp + +If paths to the score files are omitted, the directory specified in the +variable @code{wl-score-files-dir} is assumed. + +No matter what you write in @code{wl-score-folder-alist}, the default +score file @code{wl-score-default-file} (@file{all.SCORE}) is always +read (it does not have to exist). +Therefore, in the example above, the three score files, +@file{news.SCORE}, @file{my.SCORE}, and @file{all.SCORE} are read for +the folders that matches @samp{^-.*}. + +@subsection Scored Messages + +Scores are attached to the messages that are specified by +@code{wl-summary-score-marks} temporarily when the summary is updated; +when you exit from the summary, the scores are removed and reverts to +the defaults. + +@subsection Creation of Score Files + +In the summary buffer, move to an appropriate message and type @kbd{L}. +Then type @kbd{s}, @kbd{s}, and @kbd{p} at a prompt in a mini-buffer. +The string in Subject is presented. Edit it and press @kbd{@key{RET}}. + +This makes -1000 are scored for messages with the same Subject as the +string you entered. That is, such a score file is created +automatically. + +Then, try typing @kbd{h} and @kbd{e} in the same summary buffer. +The score file you just made appears. +This buffer is called "score editing buffer" thereafter. +When you type @kbd{C-c C-e} in it, you are prompted in the mini-buffer +as you are previously; type @kbd{a}. Then a score entry for "From" +should be inserted. +In this way, you can create a score file easily either in the summary +buffer or in the score editing buffer. + +By the way, you might be aware the numbers of key strokes are different +between @kbd{s s p} and @kbd{a}. +This is determined by @code{wl-score-header-default-entry}. +This variable specifies the default score entries corresponding to +header fields. +For example, for "subject" field, a type and a time limit are prompted, +but for "from" field, they are fixed upon automatically as substring and +permanent respectively. +However, score values can be modified by the prefix argument. +Typing @kbd{?} at the mini-buffer shows a help on keys and corresponding +headers and types. + +At last, type @kbd{C-c C-c} in the score editing buffer. This saves the +score file and terminates the edit mode. Typing @kbd{C-c C-c} after +erasing contents of the buffer deletes the score file being edited. + +@subsection Tips + +@subsubsection Selecting Score Files + +You can change score files to which scores are appended by +@code{wl-summary-increase-score} and @code{wl-summary-lower-score} by +@code{wl-score-change-score-file}. + +@subsubsection Summing Up the Score + +If you add the same entries by @code{wl-summary-increase-score}, +@code{wl-summary-lower-score}, and @code{wl-score-edit-insert-entry}, +scores for the entry is summed up. + +For example, if you create @samp{from} entry with the score of -1000 by +@kbd{L a} and again @samp{from} with -200, one entry with the score of +-1200 will be created as a result. + +@subsubsection Creating Thread Key + +Creating @samp{Thread} key by @code{wl-summary-increase-score} or +@code{wl-summary-lower-score} appends @samp{Message-ID} of all children. + +@subsubsection Creating Followup Key + +Creating @samp{Followup} key by @code{wl-summary-increase-score} or +@code{wl-summary-lower-score} appends @samp{Message-ID} of the message +at the cursor to @samp{References} key. +If @code{wl-score-auto-make-followup-entry} is non-nil, +@samp{Message-ID} of all messages to be followed up within dates +specified by @code{wl-score-expiry-days}. + +@subsection Key Bindings + +@table @kbd +@item K +@kindex K (Summary) +@findex wl-summary-increase-score +Increases the score for the current message. +And the score entry is appended to the score file at the same moment. +You can specify the score value by a prefix argument. + +@item L +@kindex L (Summary) +@findex wl-summary-lower-score +Decreases the score for the current message. +And the score entry is appended to the score file at the same moment. +You can specify the score value by a prefix argument. + +@item h R +@kindex h R (Summary) +@findex wl-summary-rescore +Re-applies the scoring. +However, already scored messages are not scored anew. + +@item h c +@kindex h c (Summary) +@findex wl-score-change-score-file +Changes the score file currently selected. + +@item h e +@kindex h e (Summary) +@findex wl-score-edit-current-scores +Edits the score file currently selected. +If there are multiple score files, the previously specified one is +selected. + +@item h f +@kindex h f (Summary) +@findex wl-score-edit-file +Edits an arbitrary score file and selects it. + +@item h F +@kindex h F (Summary) +@findex wl-score-flush-cache +Erases caches associated to the score files that are read. +If you modified score files directly (from other than Wanderlust), you +need to re-read them after erasing the cache. + +@item h m +@kindex h m (Summary) +@findex wl-score-set-mark-below +Specifies the criterion for scores to be marked as read. +Messages with scores less than this value are marked as read. + +@item h x +@kindex h x (Summary) +@findex wl-score-set-expunge-below +Specifies the criterion for scores to be deleted from the summary. +Messages with scores less than this value are deleted. +"Deleted" means it is not shown; they are not removed from the summary +information or the folder. +The deleted messages can be shown by rescan-noscore again. +@end table + +@subsection Key Bindings in the Score Editing Buffer + +@table @kbd +@item C-c C-k +@kindex C-c C-k (Score Mode) +@findex wl-score-edit-kill +Abandons the file being edited. + +@item C-c C-c +@kindex C-c C-c (Score Mode) +@findex wl-score-edit-exit +Saves the file being edited, and quits from the edit mode. + +@item C-c C-p +@kindex C-c C-p (Score Mode) +@findex wl-score-pretty-print +Re-draws the score. + +@item C-c C-d +@kindex C-c C-d (Score Mode) +@findex wl-score-edit-insert-date +Inserts the number of dates from Dec. 31, 1 B.C. +It is used for creating the third factor of time-limited scores. + +@item C-c C-s +@kindex C-c C-s (Score Mode) +@findex wl-score-edit-insert-header +Inserts the header of the message selected in the summary buffer. + +@item C-c C-e +@kindex C-c C-e (Score Mode) +@findex wl-score-edit-insert-entry +Inserts the score entry of the message selected in the summary buffer. +@end table + +@subsection Customizable Variables + +@table @code +@item wl-summary-default-score +@vindex wl-summary-default-score +The initial setting is zero. +This variable specifies the default value of the score. +The score is increased or decreased based upon this value. + +@item wl-summary-important-above +@vindex wl-summary-important-above +The initial setting is nil. +Messages with scores larger than this value are attached with the +important mark (@samp{$}). +If nil, no important marks are attached. + +@item wl-summary-temp-above +@vindex wl-summary-temp-above +The initial setting is nil. +Messages with scores larger than this value are attached with the temp +mark (@samp{*}). +If nil, no temp marks are attached. + +@item wl-summary-mark-below +@vindex wl-summary-mark-below +The initial setting is zero. +Messages with scores smaller than this value are marked as read. + +@item wl-summary-expunge-below +@vindex wl-summary-expunge-below +The initial setting is nil. +Messages with scores smaller than this value are deleted from the +summary. +If nil, they are not deleted. + +@item wl-summary-score-marks +@vindex wl-summary-score-marks +The initial setting is '("N" "!" "U"). +Messages with these marks are scored. + +@item wl-use-scoring +@vindex wl-use-scoring +The initial setting is t. +If non-nil, scoring is enabled. + +@item wl-score-files-dir +@vindex wl-score-files-dir +The initial setting is "~/.elmo/". +The default directory for score files. + +@item wl-score-interactive-default-score +@vindex wl-score-interactive-default-score +The initial setting is 1000. +This value is used as a score when a score factor is nil in the score +file. +It is also used in @code{wl-summary-increase-score} and +@code{wl-summary-lower-score}, on condition that the value of +@code{wl-score-header-default-entry} is nil. + +@item wl-score-expiry-days +@vindex wl-score-expiry-days +The initial setting is 7. +This is the number of days before time-limited scores are deleted. + +@item wl-score-update-entry-dates +@vindex wl-score-update-entry-dates +The initial setting is t. +If non-nil, it enables deletion of time-limited scores. + +@item wl-score-header-default-entry +@vindex wl-score-header-default-entry +Specifies the default value for each header field for score entries +created by @code{wl-summary-increase-score}, +@code{wl-summary-lower-score}, and @code{wl-score-edit-insert-entry}. + +@item wl-score-simplify-fuzzy-regexp +@vindex wl-score-simplify-fuzzy-regexp +In the case of a type of a score entry is "fuzzy", this specifies a +regular expression to be deleted from the string. +Because this is usually used for Subject, the default is prefixes that +are attached by mailing list programs. + +@item wl-summary-rescore-partial-threshold +@vindex wl-summary-rescore-partial-threshold +The initial setting is 200. +When sync-all or rescan is executed, if there are messages more than +this value, only the last same number of messages as this value are +scored. + +@item wl-summary-auto-sync-marks +@vindex wl-summary-auto-sync-marks +If non-nil, unread/important marks are synchronized when the summary +does. +Unread marks reflect information on the IMAP4 server. +Important marks reflect information on the IMAP4 server (flagged or +not), and contents of 'mark folder. +The initial setting is t. +@end table + + +@node Score File Format, , Score Commands, Scoring +@section Score File Format +@cindex Score File Format + +The format of score files are the same as Gnus, and basically you can +use Gnus score files as they are. But they are not fully compatible +because some keys are not supported and there are Wanderlust specifics. + +@example +(("subject" + ("for sale" -1000 nil s) + ("profit" -1000 nil s)) + ("from" + ("spam@@spamspamspam" -10000 nil s)) + ("followup" + ("my@@address" 3001 nil s)) + ("chars" + (1000000 -10 nil >)) + (important 5000) + (temp 3000) + (mark 0) + (expunge -3000)) +@end example + +@table @code +@item string +If the key is a string, it is the name of the header to be matched. +The following keys are available: +@code{Subject}, @code{From}, @code{Date}, @code{Message-ID}, +@code{References}, @code{To}, @code{Cc}, @code{Chars}, @code{Lines}, +@code{Xref}, @code{Extra}, @code{Followup}, @code{Thread} +@code{Chars} and @code{Lines} mean the size and the number of lines of +the message, respectively. @code{Extra}, @code{Followup}, @code{Thread} +are described later. +The rest corresponds the field of the same name. + +Arbitrary numbers of core entries are specified after the key. +Each score entry consists of these five factors: + +@enumerate +@item +A factor that matches header. This should be a number in the cases of +"lines" and "chars", otherwise a string. + +@item +A score factor. When the first item matches, the score of the message +is increased or decreased by this value. + +@item +A time limiting factor. If nil, the score is permanent, and in the case +of a number, the score is deleted if it does not match for days +(@code{wl-score-expiry-days}) from the date specified by this. +The date is since Dec. 31, 1 B.C. + +@item +A type factor. This specifies the way the first factor matches. +Available types depend on keys. + +@table @dfn +@item From, Subject, References, Message-ID +For these keys in string, @code{r} and @code{R} (regexp), +@code{s} and @code{S} (substring), @code{e} and @code{E} (exact match), +as well as @code{f} and @code{F} (fuzzy) can be used. +@code{R}, @code{S}, @code{E}, and @code{F} are case sensitive. + +@item Lines, Chars +For these keys, the following five numerical relative operators can be +used: @code{<}, @code{>}, @code{=}, @code{>=}, @code{<=}. + +@item Followup +This key matches @code{From} header, and scores all follow-ups to the +message. +For example, it would be useful for increasing scores for follow-ups to +you own article. + +You can use the same types as @code{From} except for @code{f}. +And a @samp{Followup} entry is automatically appended to the score file. + +@item Thread +This key scores (sub-)threads beginning with @code{Message-ID} @var{x}. +A @samp{Thread} entry is automatically appended for each article that +has @var{x} in the @code{References} header. +You can make sure the whole thread including messages that does not have +all ancestors @code{Message-ID} in @code{References} is scored. + +You can use the same types as @code{References} except for @code{f}. +And a @samp{Thread} entry is automatically appended to the score file. +@end table + +@item +A factor for extension header. This is meaningful only if the key is +@code{Extra}. +This specifies headers to be matched other than standard headers like +@code{Subject} and @code{From}. +Note that you should specify the header in +@code{elmo-msgdb-extra-fields} also. +Therefore it does not work in folders where extension headers cannot be +retrieved. + +@end enumerate + +The sum of these scores @emph{after all factors are applied} becomes the +score of the message. + +@cindex Score File Atoms +@item mark +Messages with a score less than this value is marked as read. +The default is @code{wl-summary-mark-below}. + +@item expunge +Messages with a score less than this value is deleted from the summary. +The default is @code{wl-summary-expunge-below}. + +@item mark-and-expunge +Both @code{mark} and @code{expunge} are applied, +i.e. messages with a score less than this value is marked as read and +deleted from the summary. + +@item temp +Messages with a score greater than this value is attached with temp +marks. +The default is @code{wl-summary-temp-above}. + +@item important +Messages with a score greater than this value is attached with important +marks. +The default is @code{wl-summary-important-above}. +@end table + +@subsection Caveats + +Not to mention the @code{extra} key, if @code{lines} or @code{xref} keys +are used, you need to set @code{elmo-msgdb-extra-fields}. + +@lisp +(setq elmo-msgdb-extra-fields '("lines" "xref")) +@end lisp + +There are other restrictions as shown below: + +@itemize @bullet +@item Because @samp{References} field in the summary information +contains only the last @samp{Message-ID}, @code{references} key matches +the last one only. +@end itemize + +Keys that can be seen by folder of types: + +@example + chars lines xref extra +localdir,localnews Y E E E +nntp (supporting xover) Y E E N + (otherwise) N E E E +imap4 Y E E E +pop3 N E E E + + Y: can be seen + N: cannot be seen (ignored) + E: can be seen with @code{elmo-msgdb-extra-fields} settings +@end example + + +@c +@c Customization +@c +@node Customization, Mailing List, Scoring, Top +@chapter Customizing Wanderlust +@cindex Customization + +@menu +* Living with other packages:: Living with other packages +* Highlights:: Highlights +* Advanced Settings:: Advanced Settings +* Customizable Variables:: Customizable Variables +@end menu + + +@node Living with other packages, Highlights, Customization, Customization +@section Living with other packages + +Examples with other packages. + +@menu +* BBDB:: BBDB +* supercite:: supercite.el +* mu-cite:: mu-cite.el +* x-face-mule:: x-face-mule.el +* dired-dd:: dired-dd.el +@end menu + + +@node BBDB, supercite, Living with other packages, Living with other packages +@subsection bbdb.el +@pindex BBDB + +Place @file{util/bbdb-wl.el} on the load-path and do the following +settings. + +If BBDB is on the load-path at the installation, @file{bbdb-wl.el} is +byte-compiled and installed. +@xref{Install}. + +@lisp +(require 'bbdb-wl) + +(bbdb-wl-setup) +;; @r{enable pop-ups} +(setq bbdb-use-pop-up t) +;; @r{auto collection} +(setq bbdb/mail-auto-create-p t) +(setq signature-use-bbdb t) +(setq bbdb-north-american-phone-numbers-p nil) +;; @r{shows the name of bbdb in the summary} :-) +(setq wl-summary-from-func 'bbdb-wl-from-func) +;; @r{automatically add mailing list fields} +(add-hook 'bbdb-notice-hook 'bbdb-auto-notes-hook) +(setq bbdb-auto-notes-alist '(("X-ML-Name" (".*$" ML 0)))) +@end lisp + +@node supercite, mu-cite, BBDB, Living with other packages +@subsection sc.el(supercite), sc-register.el +@pindex sc +@pindex supercite + +The same setting as usual mailers should be OK. The following is an +example of settings. + +@lisp +(autoload 'sc-cite-original "sc" nil t) +(setq mail-yank-hooks 'sc-cite-original) +(setq sc-preferred-header-style 1) +(setq sc-electric-references-p nil) +(setq sc-citation-leader "") +(setq sc-load-hook '(lambda () (require 'sc-register))) +(setq sc-preferred-attribution 'registeredname) +@end lisp + + +@node mu-cite, x-face-mule, supercite, Living with other packages +@subsection mu-cite.el +@pindex mu-cite + +The same setting as usual mailers should be OK. The following is an +example of settings. + +If you use mu-cite version 8.0 or earlier: + +@lisp +(autoload 'mu-cite/cite-original "mu-cite" nil t) +(setq mail-citation-hook 'mu-cite/cite-original) +@end lisp + +If you use mu-cite version 8.1 or later: + +@lisp +(autoload 'mu-cite-original "mu-cite" nil t) +(add-hook 'mail-citation-hook (function mu-cite-original)) +@end lisp + +@node x-face-mule, dired-dd, mu-cite, Living with other packages +@subsection x-face-mule.el +@pindex x-face-mule +@pindex bitmap-mule + +It depends on the version of x-face-mule. +If you use x-face-mule 0.19 or older, do the following: + +@lisp +(setq wl-highlight-x-face-func + (function + (lambda (beg end) + (x-face-mule:x-face-decode-message-header)))) + +If you use x-face-mule 0.20 or later, try the following. + +(setq wl-highlight-x-face-func + (function + (lambda (beg end) + (x-face-mule-x-face-decode-message-header)))) +(require 'x-face-mule) +@end lisp + +Use these settings when you use @file{x-face-mule.el} attached to +bitmap-mule 8.0 or later. + +@lisp +(autoload 'x-face-decode-message-header "x-face-mule") +(setq wl-highlight-x-face-func + (function x-face-decode-message-header)) +@end lisp + +If there is an encoded X-Face string in a file @file{~/.xface} (the value +of the variable @code{wl-x-face-file}), it is inserted as a X-Face field +in the draft buffer (if @code{wl-auto-insert-x-face} is non-nil). + + +@node dired-dd, , x-face-mule, Living with other packages +@subsection dired-dd(Dired-DragDrop) +@pindex Dired-DragDrop +@pindex Dired-DD +@cindex Drag and Drop + +If you embed @file{dired-dd-mime.el} in the dired-dd package, you can +compose multi-part by simple Drag&Drop from dired to the draft buffer +being edited in GNU Emacs (this feature is not Wanderlust specific, but +general-purpose for tm/SEMI). + +@lisp +;; @r{dired-dd:} http://www.asahi-net.or.jp/~pi9s-nnb/dired-dd-home.html +(add-hook + 'dired-load-hook + (function + (lambda () + (load "dired-x") + ;; @r{Set dired-x variables here.} + ;; @r{To and flo@dots{}} + (if window-system + (progn (require 'dired-dd) + (require 'dired-dd-mime)))))) +@end lisp + + +@node Highlights, Advanced Settings, Living with other packages, Customization +@section Highlights + +@subsection Customizable Variables + +@table @code +@item wl-summary-highlight +@vindex wl-summary-highlight +The initial setting is t. +If non-nil, the summary is highlighted. + +@item wl-highlight-max-summary-lines +@vindex wl-highlight-max-summary-lines +The initial setting is 10000. +The summary is not highlighted if it has more lines than this value. + +@item wl-summary-highlight-partial-threshold +@vindex wl-summary-highlight-partial-threshold +The initial setting is 1000. +This is a threshold whether the whole summary is highlighted. +If there are more lines of messages in the summary, it is partially +highlighted. + +@item wl-summary-partial-highlight-above-lines +@vindex wl-summary-partial-highlight-above-lines +The initial setting is 30. +If there are more lines of messages than +@code{wl-summary-highlight-partial-threshold} in the summary, messages +after the point that is the same number of lines as this value above the +cursor line are highlighted partially. +(If this value is nil, the last same number of lines as the value of +@code{wl-summary-highlight-partial-threshold} are highlighted.) + +@item wl-highlight-body-too +@vindex wl-highlight-body-too +The initial setting is t. +If non-nil, bodies of drafts and messages are also highlighted. + +@item wl-highlight-message-header-alist +@vindex wl-highlight-message-header-alist +When highlighting headers of drafts and messages, this variable +specifies which faces are allocated to important +(@code{wl-highlight-message-important-header-contents}), secondly +important (@code{wl-highlight-message-important-header-contents2}), and +unimportant (@code{wl-highlight-message-unimportant-header-contents}) +message headers. +Similarly, it can be used for allocating arbitrary faces to arbitrary +regular expressions. + +@item wl-highlight-citation-prefix-regexp +@vindex wl-highlight-citation-prefix-regexp +Specifies a regular expression to which quoted lines in bodies of +drafts and messages match. +Bodies matching to this regular expression are highlighted by the faces +specified by (@code{wl-highlight-message-cited-text-*}). + +@item wl-highlight-highlight-citation-too +@vindex wl-highlight-highlight-citation-too +The initial setting is nil. +If non-nil, the quoting regular expression itself given by +@code{wl-highlight-citation-prefix-regexp} is also highlighted. + +@item wl-highlight-citation-header-regexp +@vindex wl-highlight-citation-header-regexp +Specifies a regular expression that denotes beginning of quotation. +Bodies matching to this regular expression are highlighted by the face +specified by @code{wl-highlight-message-headers}. + +@item wl-highlight-max-message-size +@vindex wl-highlight-max-message-size +The initial setting is 10000. +If a message is larger than this value, it will not be highlighted. +With this variable, highlight is suppressed for uuencode or huge digest +messages. + +@item wl-highlight-signature-separator +@vindex wl-highlight-signature-separator +Specifies regular expressions that denotes the boundary of a signature. +It can be a regular expression, or a list of ones. +Messages after the place that matches this regular expression are +highlighted by the face specified by +@code{wl-highlight-message-signature}. + +@item wl-max-signature-size +@vindex wl-max-signature-size +The initial setting is 400. +This is the largest size for a signature to be highlighted. + +@item wl-use-highlight-mouse-line +@vindex wl-use-highlight-mouse-line +The initial setting is t. +If non-nil, the line pointed by the mouse is highlighted in the folder +mode, summary mode, and the like. +@end table + +@subsection Setting Colors and Fonts of the Characters + +If you want to change colors or fonts of the characters, you need to +modify faces defined in Wanderlust. Use set-face-font if you want to +change fonts, and set-face-foreground for colors, and so on. +You cannot write face settings in @file{.emacs}; write in @file{~/.wl}. + +For example, if you want to change the color for signatures to yellow, +write + +@lisp +(set-face-foreground 'wl-highlight-message-signature "yellow") +@end lisp + +@noindent +in @file{~/.wl}. + +Faces defined in Wanderlust: + +@table @code +@item wl-highlight-message-headers +The face for field names of message headers. + +@item wl-highlight-message-header-contents +The face for field bodies of message headers. + +@item wl-highlight-message-important-header-contents +The face for important parts of message headers. +Per default, this face is used for a body of Subject field. +You can change its value by editing +@code{wl-highlight-message-header-alist}. + +@item wl-highlight-message-important-header-contents2 +The face for secondly important parts of message headers. +Per default, this face is used for bodies of From and To fields. +You can change its value by editing +@code{wl-highlight-message-header-alist}. + +@item wl-highlight-message-unimportant-header-contents +The face for unimportant parts of message headers. +Per default, this face is used for bodies of X- fields User-Agent fields. +You can change its value by editing +@code{wl-highlight-message-header-alist}. + +@item wl-highlight-message-citation-header +The face for headers of quoted messages. + +@item wl-highlight-message-cited-text-* +The face for texts of quoted messages. +The last "*" is a single figure so that 10 different colors can be used +according to citation levels. + +@item wl-highlight-message-signature +The face for signatures of messages. +The initial settings are khaki for light background colors, and +DarkSlateBlue for dark background colors. + +@item wl-highlight-header-separator-face +The face for header separators of draft messages. + +@item wl-highlight-summary-important-face +The face for message lines with important marks in the summary. + +@item wl-highlight-summary-new-face +The face for message lines with new marks in the summary. + +@item wl-highlight-summary-displaying-face +The face for the message line that is currently displayed. +This face is overlaid. + +@item wl-highlight-thread-indent-face +The face for the threads that is currently displayed. + +@item wl-highlight-summary-unread-face +The face for message lines with unread marks in the summary. + +@item wl-highlight-summary-deleted-face +The face for message lines with delete marks in the summary. + +@item wl-highlight-summary-refiled-face +The face for message lines with re-file marks in the summary. + +@item wl-highlight-refile-destination-face +The face for re-file information part of message lines with re-file +marks in the summary. + +@item wl-highlight-summary-copied-face +The face for message lines with copy marks in the summary. + +@item wl-highlight-summary-target-face +The face for message lines with temp marks @samp{*} in the summary. + +@item wl-highlight-summary-thread-top-face +The face for message lines that are on the top of the thread in the +summary. + +@item wl-highlight-summary-normal-face +The face for message lines that are not on top of the thread in the +summary. + +@item wl-highlight-folder-unknown-face +The face for folders that are not known to have how many unsync messages +in the folder mode. + +@item wl-highlight-folder-zero-face +The face for folders that have no unsync messages in the folder mode. + +@item wl-highlight-folder-few-face +The face for folders that have some unsync messages in the folder mode. + +@item wl-highlight-folder-many-face +The face for folders that have many unsync messages in the folder mode. +The boundary between `some' and `many' is specified by the variable +@code{wl-folder-many-unsync-threshold}. + +@item wl-highlight-folder-unread-face +The face for folders that have no unsync but unread messages in the +folder mode. + +@item wl-highlight-folder-killed-face +The face for folders that are deleted from the access group in the +folder mode. + +@item wl-highlight-folder-opened-face +The face for open groups in the folder mode. +It is meaningful when @code{wl-highlight-group-folder-by-numbers} is nil. + +@item wl-highlight-folder-closed-face +The face for close groups in the folder mode. +It is meaningful when @code{wl-highlight-group-folder-by-numbers} is nil. + +@item wl-highlight-folder-path-face +The face for the path to the currently selected folder in the folder +mode. + +@item wl-highlight-logo-face +The face for logo in the demo. + +@item wl-highlight-demo-face +The face for strings (for example, a version number) in the demo. +@end table + +@node Advanced Settings, Customizable Variables, Highlights, Customization +@section Advanced Settings + +@menu +* Draft for Reply:: Draft for Reply +* Thread Format:: Appearance of Thread +* User-Agent Header:: User-Agent Header +@end menu + + +@node Draft for Reply, Thread Format, Advanced Settings, Advanced Settings +@subsection Draft for Replay + +If you want, when you replying to articles in mailing lists, the address +in Reply-To field of the original message to be prepared to To field of +the reply draft by simply pressing @kbd{a} in the summary mode, try the +following settings: + +@lisp +(setq wl-draft-reply-without-argument-list + '(("Mail-Followup-To" . (("Mail-Followup-To") nil ("Newsgroups"))) + ("Followup-To" . (nil nil ("Followup-To"))) + (("X-ML-Name" "Reply-To") . (("Reply-To") nil nil)) + ("From" . (("From") ("To" "Cc") ("Newsgroups"))))) +@end lisp + +@noindent +(Only if there are both of "X-ML-Name" and "Reply-To" fields in the +original message, Reply-To: field in the original is copied to To: +field.) + +@node Thread Format, User-Agent Header, Draft for Reply, Advanced Settings +@subsection Appearance of Threads + +@example + 389 09/18(Fri)01:07 [ Teranishi ] wl-0.6.3 + 390 09/18(Fri)07:25 +-[ Tsumura-san ] + 391 09/18(Fri)19:24 +-[ Murata-san ] + 392 09/20(Sun)21:49 +-[ Okunishi-san ] + 396 09/20(Sun)22:11 | +-[ Tsumura-san ] + 398 09/21(Mon)00:17 | +-[ Tsumura-san ] + 408 09/21(Mon)22:37 | +-[ Okunishi-san ] + 411 09/22(Tue)01:34 | +-[ Tsumura-san ] + 412 09/22(Tue)09:28 | +-[ Teranishi ] + 415 09/22(Tue)11:52 | +-[ Tsumura-san ] + 416 09/22(Tue)12:38 | +-[ Teranishi ] + 395 09/20(Sun)21:49 +-[ Okunishi-san ] + 397 09/21(Mon)00:15 +-[ Okunishi-san ] +@end example + +Settings to make appearance of threads like shown above: + +@lisp +(setq wl-thread-indent-level 2) +(setq wl-thread-have-younger-brother-str "+") +(setq wl-thread-youngest-child-str "+") +(setq wl-thread-vertical-str "|") +(setq wl-thread-horizontal-str "-") +(setq wl-thread-space-str " ") +@end lisp + +If you do not want to see branches, do the following: + +@lisp +(setq wl-thread-indent-level 2) +(setq wl-thread-have-younger-brother-str " ") +(setq wl-thread-youngest-child-str " ") +(setq wl-thread-vertical-str " ") +(setq wl-thread-horizontal-str " ") +(setq wl-thread-space-str " ") +@end lisp + + +@node User-Agent Header, , Thread Format, Advanced Settings +@subsection User-Agent + +If you are eccentric enough to elaborate X-Mailer or User-Agent fields, +define a function that inserts appropriate strings as you like, and set +it to @code{wl-generate-mailer-string-func}. + +The following is an example. + +@lisp +(setq wl-generate-mailer-string-func + (function + (lambda () + (concat "X-Mailer: " + (format "%s/%s (%s)" wl-appname wl-version wl-codename))))) +@end lisp + +@node Customizable Variables, , Advanced Settings, Customization +@section Customizable Variables + +Customizable variables that have not been described yet: + +@table @code +@item wl-default-folder +@vindex wl-default-folder +The initial setting is "%inbox". This is the default value for moving to +a folder and the like. + +@item wl-draft-folder +@vindex wl-draft-folder +The initial setting is "+draft". It is the folder to which drafts are +saved. It must be a localdir folder. + +@item wl-trash-folder +@vindex wl-trash-folder +The initial setting is "+trash". It is the wastebasket folder. +If you changed this variable, you had better restart Wanderlust. + +@item wl-interactive-exit +@vindex wl-interactive-exit +The initial setting is t. +If non-nil, you are asked for confirmation when Wanderlust terminates. + +@item wl-interactive-send +@vindex wl-interactive-send +The initial setting is nil. +If non-nil, you are asked for confirmation when mail is sent. + +@item wl-folder-sync-range-alist +@vindex wl-folder-sync-range-alist +The initial setting is the list shown below: +@example +(("^&.*$" . "all") + ("^\\+draft$\\|^\\+queue$" . "all")) +@end example +This is an associative list of regular expressions of folder names and +update range of the summary. +Update range is one of the "all", "update", "rescan", "rescan-noscore", "first" + and "last". If a folder do not match, "update" is used. + +@item wl-ask-range +@vindex wl-ask-range +The initial setting is t. +If nil, the value of @code{wl-folder-sync-range-alist} is used for +updating the summary when you changed folders. + +@item wl-mime-charset +@vindex wl-mime-charset +The initial setting is 'x-ctext. +This is the MIME charset for messages that are not MIME (e.g. without +Content-Type). This value also used as default charset for summary. +(If you want to share Summary on Nemacs and other Emacsen, +set this value as 'iso-2022-jp.) + +@item wl-search-mime-charset +@vindex wl-search-mime-charset +The initial setting is 'iso-2022-jp. +This is used as a MIME charset for searching. + +@item wl-highlight-folder-with-icon +@vindex wl-highlight-folder-with-icon +This is meaningful for XEmacs only. The initial setting depends on +XEmacs (t for XEmacs with icons). + +@item wl-strict-diff-folders +@vindex wl-strict-diff-folders +This is a list of regular expressions of folders. +Unread messages are checked, for example when you press @kbd{s} in +the folder mode, usually in a brief way (rapidly processed but not +accurate). +The folders matching this variable are seriously checked. +You may want to set this variable so as to match conditional filter +folders for IMAP4 folders. +The initial setting is nil. + +@item wl-folder-use-server-diff +@vindex wl-folder-use-server-diff +When unread messages are checked, for example when you press @kbd{s} in +the folder mode, usually (the number of messages on the server) - (the +number of local messages) will be the number of unread messages. +However, if this variable is non-nil, the number of unread messages on +the server is checked. This affects IMAP4 folders only, but IMAP4 +folders in mail boxes matching +@code{elmo-imap4-disuse-server-flag-mailbox-regexp} are not checked for +the number of unread messages on the server, even if they matches this +variable. The initial setting is t. + +@item wl-auto-check-folder-name +@vindex wl-auto-check-folder-name +The initial setting is nil. +If non-nil, the folder with the name of the value is checked for unread +messages at the start. +If it is 'none, no folders are checked. +If it is a list, all folders in the list are checked at the start. + +@item wl-auto-uncheck-folder-list +@vindex wl-auto-uncheck-folder-list +The initial setting is '("\\$.*"). +Folders with the name matching this variable are not checked for unread +messages at the start, even if they are included in the groups in +@code{wl-auto-check-folder-name}. + +@item wl-auto-check-folder-list +@vindex wl-auto-check-folder-list +The initial setting is nil. +Folders with the name matching this variable are always checked for +unread messages at the start, if they are included in the groups in +@code{wl-auto-check-folder-name}. +This takes precedence over @code{wl-auto-uncheck-folder-list}. + +@item wl-no-save-folder-list +@vindex wl-no-save-folder-list +The initial setting is '("^/.*$"). +This is a list of regular expressions of folders not to be saved. + +@item wl-save-folder-list +@vindex wl-save-folder-list +The initial setting is nil. +This is a list of regular expressions of folders to be saved. +This takes precedence over @code{wl-no-save-folder-list}. + +@item wl-folder-mime-charset-alist +@vindex wl-folder-mime-charset-alist +The initial setting is the list shown below: + +@lisp +'(("^-alt\\.chinese" . big5) + ("^-relcom\\." . koi8-r) + ("^-tw\\." . big5) + ("^-han\\." . euc-kr) + ) +@end lisp + +This is an associative list of regular expressions of folder names and +MIME charsets. +If a folder do not match, @code{wl-mime-charset} is used. + +@item wl-folder-init-load-access-folders +@vindex wl-folder-init-load-access-folders +The initial setting is nil. +This is a list of access groups to be loaded specifically at the start. +If it is nil, @code{wl-folder-init-no-load-access-folders} is referred. + +@item wl-folder-init-no-load-access-folders +@vindex wl-folder-init-no-load-access-folders +The initial setting is nil. +This is a list of access groups not to be loaded specifically at the +start. +It is ignored if @code{wl-folder-init-load-access-folders} is non-nil. + +@item wl-delete-folder-alist +@vindex wl-delete-folder-alist +The initial setting is '(("^-" . remove)). +This list determines disposition of messages with delete marks. +Each item in the list is a folder and destination; you can specify any +one of the following in the place of destination: + +@example +'remove or 'null : deletes the messages instantly. +string : moves the messages to the specific folder. +'trash or others : moves the messages to `wl-trash-folder'. +@end example + +@item wl-refile-policy-alist +@vindex wl-refile-policy-alist +The initial setting is '(("^[-=]" . copy) (".*" . move)). +This list determines whether messages with re-file marks are moved or +copied. +Each item in the list is a cons cell of a folder and copy or move. + +@item wl-x-face-file +@vindex wl-x-face-file +The initial setting is "~/.xface". +The name of the file that contains encoded X-Face strings. +@xref{x-face-mule}. + +@item wl-demo-display-logo +@vindex wl-demo-display-logo +If non-nil, bitmap image is shown on the opening demo. + +@item elmo-use-database +@vindex elmo-use-database +This is meaningful for XEmacs only. The initial setting depends on +XEmacs (t for XEmacs with dbm). +If non-nil, Message-ID is controlled by dbm. + +@item elmo-passwd-alist-file-name +@vindex elmo-passwd-alist-file-name +The initial setting is "passwd". +This is the name of the file in which passwords are saved. +@code{elmo-passwd-alist-save} saves current passwords to the file. + +@item elmo-nntp-list-folders-use-cache +@vindex elmo-nntp-list-folders-use-cache +The initial setting is 600 (in seconds). +This is period in seconds during which results of @samp{list} and +@samp{list active} in NNTP are cached. If it is nil, they are not +cached. + +@item elmo-nntp-max-number-precedes-list-active +@vindex elmo-nntp-max-number-precedes-list-active +The initial setting is nil. +If non-nil, the number of article obtained by @samp{list active} in NNTP +are used as the maximum article number of the folder. +Set this to t if you are using for example INN 2.3 as an NNTP server, +and if the number of read messages is not correct. + +@item elmo-nntp-default-use-listgroup +@vindex elmo-nntp-default-use-listgroup +The initial setting is t. +If non-nil, @samp{listgroup} is used for checking the total number of +articles. +If it is nil, @samp{group} is used. In the latter case, the processing +will be a little faster at the sacrifice of accuracy. + +@item elmo-pop3-send-command-synchronously +@vindex elmo-pop3-send-command-synchronously +The initial setting is nil. +If non-nil, POP3 commands are issued synchronously. Some implementation +of POP3 server fails to get summary information without this setting. +You may have to set this variable to t, if the process hangs while +looking up POP3. + +@item elmo-dop-flush-confirm +@vindex elmo-dop-flush-confirm +The initial setting is t. +If non-nil, you are asked for confirmation if accumulated off-line +operations are executed. +@end table + + +@c +@c Mailing List +@c +@node Mailing List, Addition, Customization, Top +@chapter Wanderlust Mailing List + +@display +Wanderlust Mailing List @t{} +@end display + +Topics related to Wanderlust are discussed in the mailing list. +The latest version is also announced there (in Japanese, sorry). + +A guide can be obtained automatically by sending mail to +@t{wl-ctl@@lists.airs.net} with the body + +@example +# guide +@end example +Please send bug reports or patches to the mailing list. +You can post to the mailing list even though you are not a member of it. + +I would like to express my thanks to the members of the mailing list for +valuable advice and many pieces of code they contributed. + + +@c +@c Addition +@c +@node Addition, Index, Mailing List, Top +@chapter Additional Information + +@section Brief History + +@example +1998 3/05 Tried to make a prototype that displays MH messages in threads. + 3/10 Made a msgdb mechanism by elisp. + 3/26 IMAP and NNTP can be displayed in threads. + 4/13 Began to assemble thread display modules as elmo. + 5/01 Finished 0.1.0, initial version with many defects. + 6/12 I made a slip of the tongue and said I was writing elisp + mailer supporting IMAP + 6/16 0.1.3 was announced at tm-ja, elisp ML. + 6/22 Thanks to Kitame-san, the mailing list started at northeye.org. + 7/01 Support for mm-backend (0.3.0). + 8/25 multi folder added (0.5.0). + 8/28 filter folder added (0.5.1). + 9/10 You can open/close threads (0.6.0). + 9/11 fldmgr by Murata-san made editing folders easy. + 9/18 lha folders added by Okunishi-san (0.6.3). + 9/24 Display of branches of threads (0.6.5). + 9/28 Compression folder supporting multiple archivers by Okunishi-san. + 10/28 Off-line operations (0.7.4). + 12/09 Becomes beta version. + 12/21 wl-expire by Murata-san. +1999 2/03 auto-refile by Tsumura-san. + 4/28 wl-template by Murata-san. + 5/18 Released 1.0.0 stable. + 7/5 Scoring by Murata-san (2.1.0). +@end example + +See @file{ChangeLog} for details. + +@section The Name + +According to a dictionary, Wanderlust has the meaning: + +@display +wanderlust + n eager longing for or impulse towards travelling in distant lands + [Ger, fr wandern to wander + lust desire, pleasure] +@end display + +@noindent +but I had no profound intention. +(if farfetched, IMAP @t{=>} you can read mail anywhere @t{=>} desire to +wander ?) + +Elmo is the abbreviation of @samp{Elisp Library for Message +Orchestration}. +At first I meant the red puppet in the Sesame Street, but you may +associate it with +Wandering @t{=>} Drifting @t{=>} Guidepost @t{=>} St.@: Elmo's fire @t{=>} elmo. + +@section Code Names + +Each versions has code names (they are almost jokes). +Currently they are picked up alphabetically from the top 40 hits of +U.S. Billboard magazines in 1980s. + +(@samp{http://www.summer.com.br/~pfilho/html/top40/index.html}) + + +@node Index, , Addition, Top +@unnumbered Index + +@menu +* Concept Index:: Concept Index +* Key Index:: Key Index +* Variable Index:: Variable Index +* Function Index:: Function Index +@end menu + +@node Concept Index, Key Index, Index, Index +@unnumberedsec Concept Index +@printindex cp + +@node Key Index, Variable Index, Concept Index, Index +@unnumberedsec Key Index +@printindex ky + +@node Variable Index, Function Index, Key Index, Index +@unnumberedsec Variable Index +@printindex vr + +@node Function Index, , Variable Index, Index +@unnumberedsec Function Index +@printindex fn + +@summarycontents +@contents +@bye diff --git a/elmo/ChangeLog b/elmo/ChangeLog new file mode 100644 index 0000000..11ba6ae --- /dev/null +++ b/elmo/ChangeLog @@ -0,0 +1,14 @@ +2000-04-03 Yuuichi Teranishi + + * elmo-pop3.el (elmo-pop3-open-connection): Enclose with + as-binary-process. + +2000-03-29 Daiki Ueno + + * elmo-util.el (elmo-display-progress): Fixed. + +2000-03-27 Daiki Ueno + + * elmo-util.el (elmo-display-progress): New function. + All other related modules are changed. + diff --git a/elmo/elmo-archive.el b/elmo/elmo-archive.el new file mode 100644 index 0000000..323d47b --- /dev/null +++ b/elmo/elmo-archive.el @@ -0,0 +1,1054 @@ +;;; elmo-archive.el -- Archive folder of ELMO. + +;; Copyright 1998,1999,2000 OKUNISHI Fujikazu +;; Yuuichi Teranishi + +;; Author: OKUNISHI Fujikazu +;; Keywords: mail, net news +;; Created: Sep 13, 1998 +;; Revised: Dec 15, 1998 + +;; This file is part of ELMO (Elisp Library for Message Orchestration). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; +;; TODO: +;; [$B%\%=(B] append-msgs() $B$,M_$7$$!J$1$I(B multi-refile $BIT2D!K!#(B +;; Info-Zip $B@lMQ%(!<%8%'%s%H$rMQ$$$?F|K\8l8!:w!J(BOS/2 $B@lMQ!K!#(B + +;;; Code: +;; + +(require 'elmo-msgdb) +(require 'emu) +(require 'std11) +(eval-when-compile (require 'elmo-localdir)) + +;;; Const +(defconst elmo-archive-version "v0.18 [990729/alpha]") + +;;; User vars. +(defvar elmo-archive-lha-dos-compatible + (memq system-type '(OS/2 emx windows-nt)) + "*If non-nil, regard your LHA as compatible to DOS version.") + +(defvar elmo-archive-use-izip-agent (memq system-type '(OS/2 emx)) + "*If non-nil, use the special agent in fetching headers.") + +(defvar elmo-archive-folder-path "~/Mail" + "*Base directory for archive folders.") + +(defvar elmo-archive-basename "elmo-archive" + "*Common basename of archive folder file, w/o suffix.") + +(defvar elmo-archive-cmdstr-max-length 8000 ; SASAKI Osamu's suggestion + "*Command line string limitation under OS/2, exactly 8190 bytes.") + +(defvar elmo-archive-fetch-headers-volume 50 + "*Quantity of article headers to fetch per once.") + +(defvar elmo-archive-dummy-file ".elmo-archive" + "*Name of dummy file that will be appended when the folder is null.") + +(defvar elmo-archive-check-existance-strict t + "*Check existance of archive contents if non-nil.") + +(defvar elmo-archive-load-hook nil + "*Hook called after loading elmo-archive.el.") + +(defvar elmo-archive-treat-file nil + "*Treat archive folder as a file if non-nil.") + +;;; MMDF parser -- info-zip agent w/ REXX +(defvar elmo-mmdf-delimiter "^\01\01\01\01$" + "*Regular expression of MMDF delimiter.") + +(defvar elmo-unixmail-delimiter "^From \\([^ \t]+\\) \\(.+\\)" + "*Regular expression of UNIX Mail delimiter.") + +(defvar elmo-archive-header-regexp "^[ \t]*[-=][-=][-=][-=]" + "*Common regexp of the delimiter in listing archive.") ;; marche + +(defvar elmo-archive-file-regexp-alist + (append + (if elmo-archive-lha-dos-compatible + '((lha . "^%s\\([0-9]+\\)$")) ; OS/2,DOS w/ "-x" + '((lha . "^.*[ \t]%s\\([0-9]+\\)$"))) + '((zip . "^.*[ \t]%s\\([0-9]+\\)$") + (zoo . "^.*[ \t]%s\\([0-9]+\\)$") + (tar . "^%s\\([0-9]+\\)$") ; ok + (tgz . "^%s\\([0-9]+\\)$") ; ok + (rar . "^[ \t]%s\\([0-9]+\\)$")))) + +(defvar elmo-archive-suffix-alist + '((lha . ".lzh") ; default +; (lha . ".lzs") + (zip . ".zip") + (zoo . ".zoo") +; (arc . ".arc") +; (arj . ".arj") + (rar . ".rar") + (tar . ".tar") + (tgz . ".tar.gz"))) + +;;; lha +(defvar elmo-archive-lha-method-alist + (if elmo-archive-lha-dos-compatible + ;; OS/2 + '((cp . ("lha" "u" "-x")) + (mv . ("lha" "m" "-x")) + (rm . ("lha" "d")) + (ls . ("lha" "l" "-x")) + (cat . ("lha" "p" "-n")) + (ext . ("lha" "x")) ; "-x" + ) + ;; some UN|X + '((cp . ("lha" "u")) + (mv . ("lha" "m")) + (rm . ("lha" "d")) + (ls . ("lha" "l")) + (cat . ("lha" "pq")) + (ext . ("lha" "x"))))) + +;;; info-zip/unzip +(defvar elmo-archive-zip-method-alist + '((cp . ("zip" "-9q")) + (cp-pipe . ("zip" "-9q@")) + (mv . ("zip" "-mDq9")) + (mv-pipe . ("zip" "-mDq9@")) + (rm . ("zip" "-dq")) + (rm-pipe . ("zip" "-dq@")) + (ls . ("unzip" "-lq")) + (cat . ("unzip" "-pq")) + (ext . ("unzip")) + (cat-headers . ("izwlagent" "--cat")))) + +;;; zoo +(defvar elmo-archive-zoo-method-alist + '((cp . ("zoo" "aq")) + (cp-pipe . ("zoo" "aqI")) + (mv . ("zoo" "aMq")) + (mv-pipe . ("zoo" "aMqI")) + (rm . ("zoo" "Dq")) + (ls . ("zoo" "l")) ; normal + (cat . ("zoo" "xpq")) + (ext . ("zoo" "xq")))) + +;;; rar +(defvar elmo-archive-rar-method-alist + '((cp . ("rar" "u" "-m5")) + (mv . ("rar" "m" "-m5")) + (rm . ("rar" "d")) + (ls . ("rar" "v")) + (cat . ("rar" "p" "-inul")) + (ext . ("rar" "x")))) + +;;; GNU tar (*.tar) +(defvar elmo-archive-tar-method-alist + (if elmo-archive-lha-dos-compatible + '((ls . ("gtar" "-tf")) + (cat . ("gtar" "--posix Oxf")) + (ext . ("gtar" "-xf")) + ;;(rm . ("gtar" "--posix" "--delete" "-f")) ;; well not work + ) + '((ls . ("gtar" "-tf")) + (cat . ("gtar" "-Oxf")) + (ext . ("gtar" "-xf")) + ;;(rm . ("gtar" "--delete" "-f")) ;; well not work + ))) + +;;; GNU tar (*.tar.gz, *.tar.Z, *.tar.bz2) +(defvar elmo-archive-tgz-method-alist + '((ls . ("gtar" "-ztf")) + (cat . ("gtar" "-Ozxf")) + (create . ("gtar" "-zcf")) + ;;(rm . elmo-archive-tgz-rm-func) + (cp . elmo-archive-tgz-cp-func) + (mv . elmo-archive-tgz-mv-func) + (ext . ("gtar" "-zxf")) + ;; tgz special method + (decompress . ("gzip" "-d")) + (compress . ("gzip")) + (append . ("gtar" "-uf")) + ;;(delete . ("gtar" "--delete" "-f")) ;; well not work + )) + +(defvar elmo-archive-method-list + '(elmo-archive-lha-method-alist + elmo-archive-zip-method-alist + elmo-archive-zoo-method-alist +; elmo-archive-tar-method-alist + elmo-archive-tgz-method-alist +; elmo-archive-arc-method-alist +; elmo-archive-arj-method-alist + elmo-archive-rar-method-alist)) + +;;; Internal vars. +(defvar elmo-archive-method-alist nil) +(defvar elmo-archive-suffixes nil) + + +;;; Macro +(defmacro elmo-archive-get-method (type action) + (` (cdr (assq (, action) (cdr (assq (, type) + elmo-archive-method-alist)))))) + +(defmacro elmo-archive-get-suffix (type) + (` (cdr (assq (, type) + elmo-archive-suffix-alist)))) + +(defmacro elmo-archive-get-regexp (type) + (` (cdr (assq (, type) + elmo-archive-file-regexp-alist)))) + +(defsubst elmo-archive-call-process (prog args &optional output) + (= (apply 'call-process prog nil output nil args) 0)) + +(defsubst elmo-archive-call-method (method args &optional output) + (cond + ((functionp method) + (funcall method args output)) + (t + (elmo-archive-call-process + (car method) (append (cdr method) args) output)))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Scan Folder + +(defsubst elmo-archive-list-folder-subr (file type prefix &optional nonsort) + "*Returns list of number-file(int, not string) in archive FILE. +TYPE specifies the archiver's symbol." + (let* ((method (elmo-archive-get-method type 'ls)) + (args (list file)) + (file-regexp (format (elmo-archive-get-regexp type) + (elmo-concat-path (regexp-quote prefix) ""))) + buf file-list header-end) + (when (file-exists-p file) + (save-excursion + (set-buffer (setq buf (get-buffer-create " *ELMO ARCHIVE ls*"))) + (unless (elmo-archive-call-method method args t) + (error "%s exited abnormally!" method)) + (goto-char (point-min)) + (when (re-search-forward elmo-archive-header-regexp nil t) + (forward-line 1) + (setq header-end (point)) + (when (re-search-forward elmo-archive-header-regexp nil t) + (beginning-of-line) + (narrow-to-region header-end (point)) + (goto-char (point-min)))) + (while (and (re-search-forward file-regexp nil t) + (not (eobp))) ; for GNU tar 981010 + (setq file-list (nconc file-list (list (string-to-int + (match-string 1)))))) + (kill-buffer buf))) + (if nonsort + (cons (or (elmo-max-of-list file-list) 0) (length file-list)) + (sort file-list '<)))) + +(defun elmo-archive-list-folder (spec) + (let* ((type (nth 2 spec)) + (prefix (nth 3 spec)) + (arc (elmo-archive-get-archive-name (nth 1 spec) type spec))) + (elmo-archive-list-folder-subr arc type prefix))) + +(defun elmo-archive-max-of-folder (spec) + (let* ((type (nth 2 spec)) + (prefix (nth 3 spec)) + (arc (elmo-archive-get-archive-name (nth 1 spec) type spec))) + (elmo-archive-list-folder-subr arc type prefix t))) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Folder related functions + +(defsubst elmo-archive-get-archive-directory (name) + ;; allow fullpath. return format is "/foo/bar/". + (if (file-name-absolute-p name) + (if (find-file-name-handler name 'copy-file) + name + (expand-file-name name)) + (expand-file-name name elmo-archive-folder-path))) + +(defun elmo-archive-get-archive-name (folder type &optional spec) + (let ((dir (elmo-archive-get-archive-directory folder)) + (suffix (elmo-archive-get-suffix type)) + filename dbdir) + (if elmo-archive-treat-file + (if (string-match (concat (regexp-quote suffix) "$") folder) + (expand-file-name + folder + elmo-archive-folder-path) + (expand-file-name + (concat folder suffix) + elmo-archive-folder-path)) + (if (and (not (find-file-name-handler dir 'copy-file)) ; dir is local. + (or (not (file-exists-p dir)) + (file-directory-p dir))) + (expand-file-name + (concat elmo-archive-basename suffix) + dir) + ;; for full-path specification. + (if (and (find-file-name-handler dir 'copy-file) ; ange-ftp, efs + spec) + (progn + (setq filename (expand-file-name + (concat elmo-archive-basename suffix) + (setq dbdir (elmo-msgdb-expand-path nil spec)))) + (if (file-directory-p dbdir) + (); ok. + (if (file-exists-p dbdir) + (error "File %s already exists" dbdir) + (elmo-make-directory dbdir))) + (if (not (file-exists-p filename)) + (copy-file + (if (file-directory-p dir) + (expand-file-name + (concat elmo-archive-basename suffix) + dir) + dir) + filename)) + filename) + dir))))) + +(defun elmo-archive-folder-exists-p (spec) + (file-exists-p + (elmo-archive-get-archive-name (nth 1 spec) (nth 2 spec) spec))) + +(defun elmo-archive-folder-creatable-p (spec) + t) + +(defun elmo-archive-create-folder (spec) + (let* ((dir (directory-file-name ;; remove tail slash. + (elmo-archive-get-archive-directory (nth 1 spec)))) + (type (nth 2 spec)) + (arc (elmo-archive-get-archive-name (nth 1 spec) type))) + (if elmo-archive-treat-file + (setq dir (directory-file-name (file-name-directory dir)))) + (cond ((and (file-exists-p dir) + (not (file-directory-p dir))) + ;; file exists + (error "Create folder failed; File \"%s\" exists" dir)) + ((file-directory-p dir) + (if (file-exists-p arc) + t ; return value + (elmo-archive-create-file arc type spec))) + (t + (elmo-make-directory dir) + (elmo-archive-create-file arc type spec) + t)))) + +(defun elmo-archive-create-file (archive type spec) + (save-excursion + (let* ((tmp-dir (directory-file-name + (elmo-msgdb-expand-path nil spec))) + (dummy elmo-archive-dummy-file) + (method (or (elmo-archive-get-method type 'create) + (elmo-archive-get-method type 'mv))) + (args (list archive dummy))) + (when (null method) + (ding) + (error "WARNING: read-only mode: %s (method undefined)" type)) + (cond + ((file-directory-p tmp-dir) + ()) ;nop + ((file-exists-p tmp-dir) + ;; file exists + (error "Create directory failed; File \"%s\" exists" tmp-dir)) + (t + (elmo-make-directory tmp-dir))) + (elmo-bind-directory + tmp-dir + (write-region (point) (point) dummy nil 'no-msg) + (prog1 + (elmo-archive-call-method method args) + (if (file-exists-p dummy) + (delete-file dummy))) + )))) + +(defun elmo-archive-delete-folder (spec) + (let* ((arc (elmo-archive-get-archive-name (nth 1 spec) (nth 2 spec)))) + (if (not (file-exists-p arc)) + (error "no such file: %s" arc) + (delete-file arc) + t))) + +(defun elmo-archive-rename-folder (old-spec new-spec) + (let* ((old-arc (elmo-archive-get-archive-name + (nth 1 old-spec) (nth 2 old-spec))) + (new-arc (elmo-archive-get-archive-name + (nth 1 new-spec) (nth 2 new-spec)))) + (unless (and (eq (nth 2 old-spec) (nth 2 new-spec)) + (equal (nth 3 old-spec) (nth 3 new-spec))) + (error "not same archive type and prefix")) + (if (not (file-exists-p old-arc)) + (error "no such file: %s" old-arc) + (if (file-exists-p new-arc) + (error "already exists: %s" new-arc) + (rename-file old-arc new-arc) + t)))) + +(defun elmo-archive-list-folders (spec &optional hierarchy) + (let ((folder (concat "$" (nth 1 spec))) + (elmo-localdir-folder-path elmo-archive-folder-path)) + (if elmo-archive-treat-file + (let* ((path (elmo-localdir-get-folder-directory spec)) + (base-folder (or (file-name-directory (nth 1 spec)) "")) + (suffix (nth 2 spec)) + (prefix (if (string= (nth 3 spec) "") + "" (concat ";" (nth 3 spec)))) + (dir (if (file-directory-p path) + path (file-name-directory path))) + (name (if (file-directory-p path) + "" (file-name-nondirectory path))) + (flist (and (file-directory-p dir) + (directory-files dir nil name nil))) + (regexp (format "^\\(.*\\)\\(%s\\)$" + (mapconcat + '(lambda (x) (regexp-quote (cdr x))) + elmo-archive-suffix-alist + "\\|")))) + (delq + nil + (mapcar + '(lambda (x) + (when (and (string-match regexp x) + (eq suffix + (car + (rassoc (elmo-match-string 2 x) + elmo-archive-suffix-alist)))) + (format "$%s;%s%s" + (elmo-concat-path base-folder (elmo-match-string 1 x)) + suffix prefix) + )) + flist))) + (elmo-localdir-list-folders-subr folder hierarchy)))) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Article file related functions +;;; read(extract) / append(move) / delete(delete) / query(list) + +(defun elmo-archive-read-msg (spec number outbuf) + (save-excursion + (let* ((type (nth 2 spec)) + (arc (elmo-archive-get-archive-name (nth 1 spec) type spec)) + (prefix (nth 3 spec)) + (method (elmo-archive-get-method type 'cat)) + (args (list arc (elmo-concat-path + prefix (int-to-string number))))) + (set-buffer outbuf) + (erase-buffer) + (when (file-exists-p arc) + (and + (as-binary-process + (elmo-archive-call-method method args t)) + (elmo-delete-cr-get-content-type)))))) + +(defun elmo-archive-append-msg (spec string &optional msg no-see) ;;; verrrrrry slow!! + (let* ((type (nth 2 spec)) + (prefix (nth 3 spec)) + (arc (elmo-archive-get-archive-name (nth 1 spec) type)) + (method (elmo-archive-get-method type 'mv)) + (tmp-buffer (get-buffer-create " *ELMO ARCHIVE mv*")) + (next-num (or msg + (1+ (if (file-exists-p arc) + (car (elmo-archive-max-of-folder spec)) 0)))) + (tmp-dir (elmo-msgdb-expand-path nil spec)) + newfile) + (when (null method) + (ding) + (error "WARNING: read-only mode: %s (method undefined)" type)) + (save-excursion + (set-buffer tmp-buffer) + (erase-buffer) + (let ((tmp-dir (expand-file-name prefix tmp-dir))) + (when (not (file-directory-p tmp-dir)) + (elmo-make-directory (directory-file-name tmp-dir)))) + (setq newfile (elmo-concat-path + prefix + (int-to-string next-num))) + (unwind-protect + (elmo-bind-directory + tmp-dir + (if (and (or (functionp method) (car method)) + (file-writable-p newfile)) + (progn + (insert string) + (as-binary-output-file + (write-region (point-min) (point-max) newfile nil 'no-msg)) + (elmo-archive-call-method method (list arc newfile))) + nil)) + (kill-buffer tmp-buffer))))) + +;;; (localdir, maildir, localnews, archive) -> archive +(defun elmo-archive-copy-msgs (dst-spec msgs src-spec + &optional loc-alist same-number) + (let* ((dst-type (nth 2 dst-spec)) + (arc (elmo-archive-get-archive-name (nth 1 dst-spec) dst-type)) + (prefix (nth 3 dst-spec)) + (p-method (elmo-archive-get-method dst-type 'mv-pipe)) + (n-method (elmo-archive-get-method dst-type 'mv)) + (new (unless same-number + (1+ (car (elmo-archive-max-of-folder dst-spec))))) + (src-dir (elmo-localdir-get-folder-directory src-spec)) + (tmp-dir + (file-name-as-directory (elmo-msgdb-expand-path nil dst-spec))) + (do-link t) + src tmp newfile tmp-msgs) + (when (not (elmo-archive-folder-exists-p dst-spec)) + (elmo-archive-create-folder dst-spec)) + (when (null (or p-method n-method)) + (ding) + (error "WARNING: read-only mode: %s (method undefined)" dst-type)) + (when (and same-number + (not (eq (car src-spec) 'maildir)) + (string-match (concat prefix "$") src-dir) + (or + (elmo-archive-get-method dst-type 'cp-pipe) + (elmo-archive-get-method dst-type 'cp))) + (setq tmp-dir (substring src-dir 0 (match-beginning 0))) + (setq p-method (elmo-archive-get-method dst-type 'cp-pipe) + n-method (elmo-archive-get-method dst-type 'cp)) + (setq tmp-msgs (mapcar '(lambda (x) + (elmo-concat-path prefix (int-to-string x))) + msgs)) + (setq do-link nil)) + (when do-link + (let ((tmp-dir (expand-file-name prefix tmp-dir))) + (when (not (file-directory-p tmp-dir)) + (elmo-make-directory (directory-file-name tmp-dir)))) + (while msgs + (setq newfile (elmo-concat-path prefix (int-to-string + (if same-number + (car msgs) + new)))) + (setq tmp-msgs (nconc tmp-msgs (list newfile))) + (elmo-copy-file + ;; src file + (elmo-call-func src-spec "get-msg-filename" (car msgs) loc-alist) + ;; tmp file + (expand-file-name newfile tmp-dir)) + (setq msgs (cdr msgs)) + (unless same-number (setq new (1+ new))))) + (save-excursion + (elmo-bind-directory + tmp-dir + (cond + ((functionp n-method) + (funcall n-method (cons arc tmp-msgs))) + (p-method + (let ((p-prog (car p-method)) + (p-prog-arg (cdr p-method))) + (elmo-archive-exec-msgs-subr1 + p-prog (append p-prog-arg (list arc)) tmp-msgs))) + (t + (let ((n-prog (car n-method)) + (n-prog-arg (cdr n-method))) + (elmo-archive-exec-msgs-subr2 + n-prog (append n-prog-arg (list arc)) tmp-msgs (length arc))))))))) + +;;; archive -> (localdir, localnews, archive) +(defun elmo-archive-copy-msgs-froms (dst-spec msgs src-spec + &optional loc-alist same-number) + (let* ((src-type (nth 2 src-spec)) + (arc (elmo-archive-get-archive-name (nth 1 src-spec) src-type)) + (prefix (nth 3 src-spec)) + (p-method (elmo-archive-get-method src-type 'ext-pipe)) + (n-method (elmo-archive-get-method src-type 'ext)) + (tmp-dir + (file-name-as-directory (elmo-msgdb-expand-path nil src-spec))) + (tmp-msgs (mapcar '(lambda (x) (elmo-concat-path + prefix + (int-to-string x))) + msgs)) + result) + (unwind-protect + (setq result + (and + ;; extract messages + (save-excursion + (elmo-bind-directory + tmp-dir + (cond + ((functionp n-method) + (funcall n-method (cons arc tmp-msgs))) + (p-method + (let ((p-prog (car p-method)) + (p-prog-arg (cdr p-method))) + (elmo-archive-exec-msgs-subr1 + p-prog (append p-prog-arg (list arc)) tmp-msgs))) + (t + (let ((n-prog (car n-method)) + (n-prog-arg (cdr n-method))) + (elmo-archive-exec-msgs-subr2 + n-prog (append n-prog-arg (list arc)) tmp-msgs (length arc))))))) + ;; call elmo-*-copy-msgs of destination folder + (elmo-call-func dst-spec "copy-msgs" + msgs src-spec loc-alist same-number))) + ;; clean up tmp-dir + (elmo-bind-directory + tmp-dir + (while tmp-msgs + (if (file-exists-p (car tmp-msgs)) + (delete-file (car tmp-msgs))) + (setq tmp-msgs (cdr tmp-msgs)))) + result))) + +(defun elmo-archive-delete-msgs (spec msgs) + (save-excursion + (let* ((type (nth 2 spec)) + (prefix (nth 3 spec)) + (arc (elmo-archive-get-archive-name (nth 1 spec) type)) + (p-method (elmo-archive-get-method type 'rm-pipe)) + (n-method (elmo-archive-get-method type 'rm)) + (msgs (mapcar '(lambda (x) (elmo-concat-path + prefix + (int-to-string x))) + msgs))) + (cond ((functionp n-method) + (funcall n-method (cons arc msgs))) + (p-method + (let ((p-prog (car p-method)) + (p-prog-arg (cdr p-method))) + (elmo-archive-exec-msgs-subr1 + p-prog (append p-prog-arg (list arc)) msgs))) + (n-method + (let ((n-prog (car n-method)) + (n-prog-arg (cdr n-method))) + (elmo-archive-exec-msgs-subr2 + n-prog (append n-prog-arg (list arc)) msgs (length arc)))) + (t + (ding) + (error "WARNING: not delete: %s (method undefined)" type))) ))) + +(defun elmo-archive-exec-msgs-subr1 (prog args msgs) + (let ((buf (get-buffer-create " *ELMO ARCHIVE exec*"))) + (set-buffer buf) + (insert (mapconcat 'concat msgs "\n")) ;string + (unwind-protect + (= 0 + (apply 'call-process-region (point-min) (point-max) + prog nil nil nil args)) + (kill-buffer buf)))) + +(defun elmo-archive-exec-msgs-subr2 (prog args msgs arc-length) + (let ((max-len (- elmo-archive-cmdstr-max-length arc-length)) + (n (length msgs)) + rest i sum) + (setq rest msgs) ;string + (setq i 1) + (setq sum 0) + (catch 'done + (while (and rest (<= i n)) + (mapcar '(lambda (x) + (let* ((len (length x)) + (files (member x (reverse rest)))) + ;; total(previous) + current + white space + (if (<= max-len (+ sum len 1)) + (progn + (unless + (elmo-archive-call-process + prog (append args files)) + (throw 'done nil)) + (setq sum 0) ;; reset + (setq rest (nthcdr i rest))) + (setq sum (+ sum len 1))) + (setq i (1+ i)))) msgs)) + (throw 'done + (or (not rest) + (elmo-archive-call-process prog (append args rest)))) + ))) + +(defsubst elmo-archive-article-exists-p (arc msg type) + (if (not elmo-archive-check-existance-strict) + t ; nop + (save-excursion ;; added 980915 + (let* ((method (elmo-archive-get-method type 'ls)) + (args (list arc msg)) + (buf (get-buffer-create " *ELMO ARCHIVE query*")) + (error-msg "\\(no file\\|0 files\\)") + ret-val) + (set-buffer buf) + (erase-buffer) + (elmo-archive-call-method method args t) + ;; pointer: point-max + (setq ret-val (not (re-search-backward error-msg nil t))) + (kill-buffer buf) + ret-val)))) + +(defun elmo-archive-tgz-common-func (args exec-type &optional copy) + (let* ((arc (car args)) + (tmp-msgs (cdr args)) + (decompress (elmo-archive-get-method 'tgz 'decompress)) + (compress (elmo-archive-get-method 'tgz 'compress)) + (exec (elmo-archive-get-method 'tgz exec-type)) + (suffix (elmo-archive-get-suffix 'tgz)) + (tar-suffix (elmo-archive-get-suffix 'tar)) + arc-tar ret-val + ) + (when (null (and decompress compress exec)) + (ding) + (error "WARNING: special method undefined: %s of %s" + (or (if (null decompress) 'decompress) + (if (null compress) 'compress) + (if (null exec) exec-type)) + 'tgz)) + (unless tar-suffix + (ding) + (error "WARNING: `tar' suffix undefined")) + (if (string-match (concat (regexp-quote suffix) "$") arc) + (setq arc-tar + (concat (substring arc 0 (match-beginning 0)) tar-suffix)) + (error "%s: not match suffix [%s]" arc suffix)) + (and + ;; decompress + (elmo-archive-call-process + (car decompress) (append (cdr decompress) (list arc))) + ;; append (or delete) + (elmo-archive-exec-msgs-subr2 + (car exec) (append (cdr exec) (list arc-tar)) tmp-msgs (length arc-tar)) + ;; compress + (setq ret-val + (elmo-archive-call-process + (car compress) (append (cdr compress) (list arc-tar))))) + ;; delete tmporary messages + (if (and (not copy) + (eq exec-type 'append)) + (while tmp-msgs + (if (file-exists-p (car tmp-msgs)) + (delete-file (car tmp-msgs))) + (setq tmp-msgs (cdr tmp-msgs)))) + ret-val)) + +(defun elmo-archive-tgz-cp-func (args &optional output) + (elmo-archive-tgz-common-func args 'append t)) + +(defun elmo-archive-tgz-mv-func (args &optional output) + (elmo-archive-tgz-common-func args 'append)) + +(defun elmo-archive-tgz-rm-func (args &optional output) + (elmo-archive-tgz-common-func args 'delete)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; MessageDB functions (from elmo-localdir.el) + +(defsubst elmo-archive-msgdb-create-entity-subr (number) + (let (header-end) + (elmo-set-buffer-multibyte default-enable-multibyte-characters) + (goto-char (point-min)) + (if (re-search-forward "\\(^--.*$\\)\\|\\(\n\n\\)" nil t) + (setq header-end (point)) + (setq header-end (point-max))) + (narrow-to-region (point-min) header-end) + (elmo-msgdb-create-overview-from-buffer number))) + +(defsubst elmo-archive-msgdb-create-entity (method archive number type &optional prefix) ;; verrrry slow!! + (let* ((msg (elmo-concat-path prefix (int-to-string number))) + (arg-list (list archive msg))) + (when (elmo-archive-article-exists-p archive msg type) + ;; insert article. + (as-binary-process + (elmo-archive-call-method method arg-list t)) + (elmo-archive-msgdb-create-entity-subr number)))) + +(defun elmo-archive-msgdb-create-as-numlist (spec numlist new-mark + already-mark seen-mark + important-mark seen-list) + (when numlist + (save-excursion ;; 981005 + (if (and elmo-archive-use-izip-agent + (elmo-archive-get-method (nth 2 spec) 'cat-headers)) + (elmo-archive-msgdb-create-as-numlist-subr2 + spec numlist new-mark already-mark seen-mark important-mark + seen-list) + (elmo-archive-msgdb-create-as-numlist-subr1 + spec numlist new-mark already-mark seen-mark important-mark + seen-list))))) + +(defalias 'elmo-archive-msgdb-create 'elmo-archive-msgdb-create-as-numlist) + + +(defun elmo-archive-msgdb-create-as-numlist-subr1 (spec numlist new-mark + already-mark seen-mark + important-mark + seen-list) + (let* ((type (nth 2 spec)) + (file (elmo-archive-get-archive-name (nth 1 spec) type spec)) + (method (elmo-archive-get-method type 'cat)) + (tmp-buf (get-buffer-create " *ELMO ARCHIVE msgdb*")) + overview number-alist mark-alist entity + i percent num message-id seen gmark) + (save-excursion + (set-buffer tmp-buf) + (setq num (length numlist)) + (setq i 0) + (message "Creating msgdb...") + (while numlist + (erase-buffer) + (setq entity + (elmo-archive-msgdb-create-entity + method file (car numlist) type (nth 3 spec))) + (when entity + (setq overview + (elmo-msgdb-append-element + overview entity)) + (setq number-alist + (elmo-msgdb-number-add + number-alist + (elmo-msgdb-overview-entity-get-number entity) + (car entity))) + (setq message-id (car entity)) + (setq seen (member message-id seen-list)) + (if (setq gmark + (or (elmo-msgdb-global-mark-get message-id) + (if (elmo-cache-exists-p message-id) ; XXX + (if seen + nil + already-mark) + (if seen + seen-mark + new-mark)))) + (setq mark-alist + (elmo-msgdb-mark-append + mark-alist + (elmo-msgdb-overview-entity-get-number entity) + gmark)))) + (setq i (1+ i)) + (setq percent (/ (* i 100) num)) + (elmo-display-progress + 'elmo-archive-msgdb-create-as-numlist-subr1 "Creating msgdb..." + percent) + (setq numlist (cdr numlist))) + (kill-buffer tmp-buf) + (message "Creating msgdb...done.") + (list overview number-alist mark-alist)) )) + +;;; info-zip agent +(defun elmo-archive-msgdb-create-as-numlist-subr2 (spec numlist new-mark + already-mark seen-mark + important-mark + seen-list) + (let* ((buf (get-buffer-create " *ELMO ARCHIVE headers*")) + (delim1 elmo-mmdf-delimiter) ;; MMDF + (delim2 elmo-unixmail-delimiter) ;; UNIX Mail + (type (nth 2 spec)) + (prefix (nth 3 spec)) + (method (elmo-archive-get-method type 'cat-headers)) + (prog (car method)) + (args (cdr method)) + (arc (elmo-archive-get-archive-name (nth 1 spec) type)) + n i percent num result overview number-alist mark-alist + msgs case-fold-search) + (set-buffer buf) + (setq num (length numlist)) + (setq i 0) + (message "Creating msgdb...") + (while numlist + (setq n (min (1- elmo-archive-fetch-headers-volume) + (1- (length numlist)))) + (setq msgs (reverse (memq (nth n numlist) (reverse numlist)))) + (setq numlist (nthcdr (1+ n) numlist)) + (erase-buffer) + (insert + (mapconcat + 'concat + (mapcar '(lambda (x) (elmo-concat-path prefix (int-to-string x))) msgs) + "\n")) + (message "Fetching headers...") + (as-binary-process (apply 'call-process-region + (point-min) (point-max) + prog t t nil (append args (list arc)))) + (goto-char (point-min)) + (cond + ((looking-at delim1) ;; MMDF + (setq result (elmo-archive-parse-mmdf msgs + new-mark + already-mark seen-mark + seen-list)) + (setq overview (append overview (nth 0 result))) + (setq number-alist (append number-alist (nth 1 result))) + (setq mark-alist (append mark-alist (nth 2 result)))) +; ((looking-at delim2) ;; UNIX MAIL +; (setq result (elmo-archive-parse-unixmail msgs)) +; (setq overview (append overview (nth 0 result))) +; (setq number-alist (append number-alist (nth 1 result))) +; (setq mark-alist (append mark-alist (nth 2 result)))) + (t ;; unknown format + (error "unknown format!"))) + (setq i (+ n i)) + (setq percent (/ (* i 100) num)) + (elmo-display-progress + 'elmo-archive-msgdb-create-as-numlist-subr2 "Creating msgdb..." + percent)) + (kill-buffer buf) + (list overview number-alist mark-alist)) ) + +(defun elmo-archive-parse-mmdf (msgs new-mark + already-mark + seen-mark + seen-list) + (let ((delim elmo-mmdf-delimiter) + number sp ep rest entity overview number-alist mark-alist ret-val + message-id seen gmark) + (goto-char (point-min)) + (setq rest msgs) + (while (and rest (re-search-forward delim nil t) + (not (eobp))) + (setq number (car rest)) + (setq sp (1+ (point))) + (setq ep (prog2 (re-search-forward delim) + (1+ (- (point) (length delim))))) + (if (>= sp ep) ; no article! + () ; nop + (save-excursion + (narrow-to-region sp ep) + (setq entity (elmo-archive-msgdb-create-entity-subr number)) + (setq overview + (elmo-msgdb-append-element + overview entity)) + (setq number-alist + (elmo-msgdb-number-add + number-alist + (elmo-msgdb-overview-entity-get-number entity) + (car entity))) + (setq message-id (car entity)) + (setq seen (member message-id seen-list)) + (if (setq gmark + (or (elmo-msgdb-global-mark-get message-id) + (if (elmo-cache-exists-p message-id) ; XXX + (if seen + nil + already-mark) + (if seen + seen-mark + new-mark)))) + (setq mark-alist + (elmo-msgdb-mark-append + mark-alist + (elmo-msgdb-overview-entity-get-number entity) + gmark))) + (setq ret-val (append ret-val (list overview number-alist mark-alist))) + (widen))) + (forward-line 1) + (setq rest (cdr rest))) + ret-val)) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Search functions + +(defsubst elmo-archive-field-condition-match (spec number condition prefix) + (save-excursion + (let* ((type (nth 2 spec)) + (arc (elmo-archive-get-archive-name (nth 1 spec) type spec)) + (method (elmo-archive-get-method type 'cat)) + (args (list arc (elmo-concat-path prefix (int-to-string number))))) + (elmo-set-work-buf + (when (file-exists-p arc) + (as-binary-process + (elmo-archive-call-method method args t)) + (elmo-set-buffer-multibyte default-enable-multibyte-characters) + (decode-mime-charset-region (point-min)(point-max) elmo-mime-charset) + (elmo-buffer-field-condition-match condition)))))) + +(defun elmo-archive-search (spec condition &optional from-msgs) + (let* (;;(args (elmo-string-to-list key)) + ;; XXX: I don't know whether `elmo-archive-list-folder' + ;; updates match-data. + ;; (msgs (or from-msgs (elmo-archive-list-folder spec))) + (msgs (or from-msgs (elmo-archive-list-folder spec))) + (num (length msgs)) + (i 0) + (case-fold-search nil) + ret-val) + (while msgs + (if (elmo-archive-field-condition-match spec (car msgs) + condition + (nth 3 spec)) + (setq ret-val (cons (car msgs) ret-val))) + (setq i (1+ i)) + (elmo-display-progress + 'elmo-archive-search "Searching..." + (/ (* i 100) num)) + (setq msgs (cdr msgs))) + (nreverse ret-val))) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Misc functions + +(defun elmo-archive-check-validity (spec validity-file) + t) ; ok. + +(defun elmo-archive-sync-validity (spec validity-file) + t) ; ok. + + +;;; method(alist) +(if (null elmo-archive-method-alist) + (let ((mlist elmo-archive-method-list) ; from mew-highlight.el + method type str) + (while mlist + (setq method (car mlist)) + (setq mlist (cdr mlist)) + (setq str (symbol-name method)) + (string-match "elmo-archive-\\([^-].*\\)-method-alist$" str) + (setq type (intern-soft + (elmo-match-string 1 str))) + (setq elmo-archive-method-alist + (cons (cons type + (symbol-value method)) + elmo-archive-method-alist))))) + +;;; valid suffix(list) +(if (null elmo-archive-suffixes) + (let ((slist elmo-archive-suffix-alist) + tmp) + (while slist + (setq tmp (car slist)) + (setq elmo-archive-suffixes + (nconc elmo-archive-suffixes (list (cdr tmp)))) + (setq slist (cdr slist))))) + +(defun elmo-archive-use-cache-p (spec number) + elmo-archive-use-cache) + +(defun elmo-archive-local-file-p (spec number) + nil) + +(defun elmo-archive-get-msg-filename (spec number &optional loc-alist) + (let ((tmp-dir (file-name-as-directory (elmo-msgdb-expand-path nil spec))) + (prefix (nth 3 spec))) + (expand-file-name + (elmo-concat-path prefix (int-to-string number)) + tmp-dir))) + +(defalias 'elmo-archive-sync-number-alist + 'elmo-generic-sync-number-alist) +(defalias 'elmo-archive-list-folder-unread + 'elmo-generic-list-folder-unread) +(defalias 'elmo-archive-list-folder-important + 'elmo-generic-list-folder-important) +(defalias 'elmo-archive-commit 'elmo-generic-commit) + +;;; End +(run-hooks 'elmo-archive-load-hook) +(provide 'elmo-archive) + +;;; elmo-archive.el ends here diff --git a/elmo/elmo-cache.el b/elmo/elmo-cache.el new file mode 100644 index 0000000..f0ea53c --- /dev/null +++ b/elmo/elmo-cache.el @@ -0,0 +1,737 @@ +;;; elmo-cache.el -- Cache modules for Elmo. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi +;; Copyright 2000 Kenichi OKADA + +;; Author: Yuuichi Teranishi +;; Kenichi OKADA +;; Keywords: mail, net news +;; Time-stamp: <00/03/01 09:57:55 teranisi> + +;; This file is part of ELMO (Elisp Library for Message Orchestration). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; +(require 'elmo-vars) +(require 'elmo-util) + +(defun elmo-cache-delete (msgid folder number) + "Delete cache file associated with message-id 'MSGID', FOLDER, NUMBER." + (let ((path (elmo-cache-exists-p msgid folder number))) + (if path (delete-file path)))) + +(defsubst elmo-cache-to-msgid (filename) + (concat "<" (elmo-recover-msgid-from-filename filename) ">")) + +(defun elmo-cache-force-delete (path &optional locked) + "Delete cache file." + ;; for safety... + (unless (string-match elmo-cache-dirname path) + (error "%s is not cache file!" path)) + (let (message-id) + (if (or (elmo-msgdb-global-mark-get + (setq message-id + (elmo-cache-to-msgid (file-name-nondirectory path)))) + (member message-id locked)) + nil ;; Don't delete caches with mark (or locked message). + (if (and path + (file-directory-p path)) + (progn + (mapcar 'delete-file (directory-files path t "^[^\\.]")) + (delete-directory path)) + (delete-file path)) + t))) + +(defun elmo-cache-delete-partial (msgid folder number) + "Delete cache file only if it is partial message." + (if msgid + (let ((path1 (elmo-cache-get-path msgid)) + path2) + (if (and path1 + (file-exists-p path1)) + (if (and folder + (file-directory-p path1)) + (when (file-exists-p (setq path2 + (expand-file-name + (format "%s@%s" + number + (elmo-safe-filename + folder)) + path1))) + (delete-file path2) + (unless (directory-files path1 t "^[^\\.]") + (delete-directory path1)))))))) + +(defun elmo-cache-read (msgid &optional folder number outbuf) + "Read cache contents to outbuf" + (save-excursion + (let ((path (elmo-cache-exists-p msgid folder number))) + (when path + (if outbuf (set-buffer outbuf)) + (erase-buffer) + (as-binary-input-file (insert-file-contents path)) + t)))) + +(defun elmo-cache-expire () + (interactive) + (let* ((completion-ignore-case t) + (method (completing-read (format "Expire by (%s): " + elmo-cache-expire-default-method) + '(("size" . "size") + ("age" . "age"))))) + (if (string= method "") + (setq method elmo-cache-expire-default-method)) + (funcall (intern (concat "elmo-cache-expire-by-" method))))) + +(defun elmo-read-float-value-from-minibuffer (prompt &optional initial) + (let ((str (read-from-minibuffer prompt initial))) + (cond + ((string-match "[0-9]*\\.[0-9]+" str) + (string-to-number str)) + ((string-match "[0-9]+" str) + (string-to-number (concat str ".0"))) + (t (error "%s is not number" str))))) + +(defun elmo-cache-expire-by-size (&optional kbytes) + "Expire cache file by size. +If KBYTES is kilo bytes (This value must be float)." + (interactive) + (let ((size (or kbytes + (and (interactive-p) + (elmo-read-float-value-from-minibuffer + "Enter cache disk size (Kbytes): " + (number-to-string + (if (integerp elmo-cache-expire-default-size) + (float elmo-cache-expire-default-size) + elmo-cache-expire-default-size)))) + (if (integerp elmo-cache-expire-default-size) + (float elmo-cache-expire-default-size)))) + (locked (elmo-dop-lock-list-load)) + (count 0) + (Kbytes 1024) + total beginning) + (message "Checking disk usage...") + (setq total (/ (elmo-disk-usage + (expand-file-name + elmo-cache-dirname elmo-msgdb-dir)) Kbytes)) + (setq beginning total) + (message "Checking disk usage...done.") + (let ((cfl (elmo-cache-get-sorted-cache-file-list)) + (deleted 0) + oldest + cur-size cur-file) + (while (and (<= size total) + (setq oldest (elmo-cache-get-oldest-cache-file-entity cfl))) + (setq cur-file (expand-file-name (car (cdr oldest)) (car oldest))) + (if (file-directory-p cur-file) + (setq cur-size (elmo-disk-usage cur-file)) + (setq cur-size + (/ (float (nth 7 (file-attributes cur-file))) + Kbytes))) + (when (elmo-cache-force-delete cur-file locked) + (setq count (+ count 1)) + (message "%d cache(s) are expired." count)) + (setq deleted (+ deleted cur-size)) + (setq total (- total cur-size))) + (message "%d cache(s) are expired from disk (%d Kbytes/%d Kbytes)." + count deleted beginning)))) + +(defun elmo-cache-make-file-entity (filename path) + (cons filename (elmo-get-last-accessed-time filename path))) + +(defun elmo-cache-get-oldest-cache-file-entity (cache-file-list) + (let ((cfl cache-file-list) + flist firsts oldest-entity wonlist) + (while cfl + (setq flist (cdr (car cfl))) + (setq firsts (append firsts (list + (cons (car (car cfl)) + (car flist))))) + (setq cfl (cdr cfl))) +; (prin1 firsts) + (while firsts + (if (and (not oldest-entity) + (cdr (cdr (car firsts)))) + (setq oldest-entity (car firsts))) + (if (and (cdr (cdr (car firsts))) + (cdr (cdr oldest-entity)) + (> (cdr (cdr oldest-entity)) (cdr (cdr (car firsts))))) + (setq oldest-entity (car firsts))) + (setq firsts (cdr firsts))) + (setq wonlist (assoc (car oldest-entity) cache-file-list)) + (and wonlist + (setcdr wonlist (delete (car (cdr wonlist)) (cdr wonlist)))) + oldest-entity)) + +(defun elmo-cache-get-sorted-cache-file-list () + (let ((dirs (directory-files + (expand-file-name elmo-cache-dirname elmo-msgdb-dir) + t "^[^\\.]")) + (i 0) num + elist + ret-val) + (setq num (length dirs)) + (message "Collecting cache info...") + (while dirs + (setq elist (mapcar (lambda (x) + (elmo-cache-make-file-entity x (car dirs))) + (directory-files (car dirs) nil "^[^\\.]"))) + (setq ret-val (append ret-val + (list (cons + (car dirs) + (sort + elist + (lambda (x y) + (< (cdr x) + (cdr y)))))))) + (setq i (+ i 1)) + (elmo-display-progress + 'elmo-cache-get-sorted-cache-file-list "Collecting cache info..." + (/ (* i 100) num)) + (setq dirs (cdr dirs))) + ret-val)) + +(defun elmo-cache-expire-by-age (&optional days) + (let ((age (or (and days (int-to-string days)) + (and (interactive-p) + (read-from-minibuffer + (format "Enter days (%s): " + elmo-cache-expire-default-age))) + (int-to-string elmo-cache-expire-default-age))) + (dirs (directory-files + (expand-file-name elmo-cache-dirname elmo-msgdb-dir) + t "^[^\\.]")) + (locked (elmo-dop-lock-list-load)) + (count 0) + curtime) + (if (string= age "") + (setq age elmo-cache-expire-default-age) + (setq age (string-to-int age))) + (setq curtime (current-time)) + (setq curtime (+ (* (nth 0 curtime) + (float 65536)) (nth 1 curtime))) + (while dirs + (let ((files (directory-files (car dirs) t "^[^\\.]")) + (limit-age (* age 86400))) + (while files + (when (> (- curtime (elmo-get-last-accessed-time (car files))) + limit-age) + (when (elmo-cache-force-delete (car files) locked) + (setq count (+ 1 count)) + (message "%d cache file(s) are expired." count))) + (setq files (cdr files)))) + (setq dirs (cdr dirs))))) + +(defun elmo-cache-save (msgid partial folder number &optional inbuf) + "If partial is non-nil, save current buffer (or INBUF) as partial cache." + (condition-case nil + (save-excursion + (let* ((path (if partial + (elmo-cache-get-path msgid folder number) + (elmo-cache-get-path msgid))) + dir tmp-buf) + (when path + (setq dir (directory-file-name (file-name-directory path))) + (if (not (file-exists-p dir)) + (elmo-make-directory dir)) + (if inbuf (set-buffer inbuf)) + (goto-char (point-min)) + (as-binary-output-file (write-region (point-min) (point-max) + path nil 'no-msg))))) + (error))) + +(defun elmo-cache-exists-p (msgid &optional folder number) + "Returns the path if the cache exists." + (save-match-data + (if msgid + (let ((path (elmo-cache-get-path msgid))) + (if (and path + (file-exists-p path)) + (if (and folder + (file-directory-p path)) + (if (file-exists-p (setq path (expand-file-name + (format "%s@%s" + (or number "") + (elmo-safe-filename + folder)) + path))) + path + ) + ;; not directory. + path)))))) + +(defun elmo-cache-search-all (folder condition from-msgs) + (let* ((number-alist (elmo-msgdb-number-load + (elmo-msgdb-expand-path folder))) + (nalist number-alist) + (num (length number-alist)) + cache-file + ret-val + case-fold-search msg + percent i) + (setq i 0) + (while nalist + (if (and (setq cache-file (elmo-cache-exists-p (cdr (car nalist)) + folder + (car (car nalist)))) + (elmo-file-field-condition-match cache-file condition)) + (setq ret-val (append ret-val (list (caar nalist))))) + (setq i (1+ i)) + (setq percent (/ (* i 100) num)) + (elmo-display-progress + 'elmo-cache-search-all "Searching..." + percent) + (setq nalist (cdr nalist))) + ret-val)) + +(defun elmo-cache-collect-sub-directories (init dir &optional recursively) + "Collect subdirectories under 'dir'" + (let ((dirs + (delete (expand-file-name elmo-cache-dirname + elmo-msgdb-dir) + (directory-files dir t "^[^\\.]"))) + ret-val) + (setq dirs (elmo-delete-if (lambda (x) (not (file-directory-p x))) dirs)) + (setq ret-val (append init dirs)) + (while (and recursively dirs) + (setq ret-val + (elmo-cache-collect-sub-directories + ret-val + (car dirs) recursively)) + (setq dirs (cdr dirs))) + ret-val)) + +(defun elmo-msgid-to-cache (msgid) + (when (and msgid + (string-match "<\\(.+\\)>$" msgid)) + (elmo-replace-msgid-as-filename (elmo-match-string 1 msgid)))) + +(defun elmo-cache-get-path (msgid &optional folder number) + "Get path for cache file associated with MSGID, FOLDER, and NUMBER." + (if (setq msgid (elmo-msgid-to-cache msgid)) + (expand-file-name + (expand-file-name + (if folder + (format "%s/%s/%s@%s" + (elmo-cache-get-path-subr msgid) + msgid + (or number "") + (elmo-safe-filename folder)) + (format "%s/%s" + (elmo-cache-get-path-subr msgid) + msgid)) + (expand-file-name elmo-cache-dirname + elmo-msgdb-dir))))) + +(defsubst elmo-cache-get-path-subr (msgid) + (let ((chars '(?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9 ?A ?B ?C ?D ?E ?F)) + (clist (string-to-char-list msgid)) + (sum 0)) + (while clist + (setq sum (+ sum (car clist))) + (setq clist (cdr clist))) + (format "%c%c" + (nth (% (/ sum 16) 2) chars) + (nth (% sum 16) chars)))) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; buffer cache module + +(defconst elmo-buffer-cache-name " *elmo cache*") + +(defvar elmo-buffer-cache nil + "Message cache. (old ... new) order alist with association + ((\"folder\" message \"message-id\") . cache-buffer)") + +(defmacro elmo-buffer-cache-buffer-get (entry) + (` (cdr (, entry)))) + +(defmacro elmo-buffer-cache-folder-get (entry) + (` (car (car (, entry))))) + +(defmacro elmo-buffer-cache-message-get (entry) + (` (cdr (car (, entry))))) + +(defmacro elmo-buffer-cache-entry-make (fld-msg-id buf) + (` (cons (, fld-msg-id) (, buf)))) + +(defmacro elmo-buffer-cache-hit (fld-msg-id) + "Return value assosiated with key." + (` (elmo-buffer-cache-buffer-get + (assoc (, fld-msg-id) elmo-buffer-cache)))) + +(defun elmo-buffer-cache-sort (entry) + (let* ((pointer (cons nil elmo-buffer-cache)) + (top pointer)) + (while (cdr pointer) + (if (equal (car (cdr pointer)) entry) + (setcdr pointer (cdr (cdr pointer))) + (setq pointer (cdr pointer)))) + (setcdr pointer (list entry)) + (setq elmo-buffer-cache (cdr top)))) + +(defun elmo-buffer-cache-add (fld-msg-id) + "Adding (fld-msg-id . buf) to the top of \"elmo-buffer-cache\". +Returning its cache buffer." + (let ((len (length elmo-buffer-cache)) + (buf nil)) + (if (< len elmo-buffer-cache-size) + (setq buf (get-buffer-create (format "%s%d" elmo-buffer-cache-name len))) + (setq buf (elmo-buffer-cache-buffer-get (nth (1- len) elmo-buffer-cache))) + (setcdr (nthcdr (- len 2) elmo-buffer-cache) nil)) + (setq elmo-buffer-cache + (cons (elmo-buffer-cache-entry-make fld-msg-id buf) + elmo-buffer-cache)) + buf)) + +(defun elmo-buffer-cache-delete () + "Delete the most recent cache entry." + (let ((buf (elmo-buffer-cache-buffer-get (car elmo-buffer-cache)))) + (setq elmo-buffer-cache + (nconc (cdr elmo-buffer-cache) + (list (elmo-buffer-cache-entry-make nil buf)))))) + +(defun elmo-buffer-cache-clean-up () + "A function to flush all decoded messages in cache list." + (interactive) + (let ((n 0) buf) + (while (< n elmo-buffer-cache-size) + (setq buf (concat elmo-buffer-cache-name (int-to-string n))) + (elmo-kill-buffer buf) + (setq n (1+ n)))) + (setq elmo-buffer-cache nil)) + +;;; +;;; cache backend by Kenichi OKADA +;;; + +(defsubst elmo-cache-get-folder-directory (spec) + (if (file-name-absolute-p (nth 1 spec)) + (nth 1 spec) ; already full path. + (expand-file-name (nth 1 spec) + (expand-file-name elmo-cache-dirname elmo-msgdb-dir)))) + +(defun elmo-cache-msgdb-expand-path (spec) + (let ((fld-name (nth 1 spec))) + (expand-file-name fld-name + (expand-file-name "internal/cache" + elmo-msgdb-dir)))) + +(defun elmo-cache-number-to-filename (spec number) + (let ((number-alist + (elmo-cache-list-folder-subr spec nil t))) + (elmo-msgid-to-cache + (cdr (assq number number-alist))))) + +(if (boundp 'nemacs-version) + (defsubst elmo-cache-insert-header (file) + "Insert the header of the article (Does not work on nemacs)." + (as-binary-input-file + (insert-file-contents file))) + (defsubst elmo-cache-insert-header (file) + "Insert the header of the article." + (let ((beg 0) + insert-file-contents-pre-hook ; To avoid autoconv-xmas... + insert-file-contents-post-hook + format-alist) + (when (file-exists-p file) + ;; Read until header separator is found. + (while (and (eq elmo-localdir-header-chop-length + (nth 1 + (as-binary-input-file + (insert-file-contents + file nil beg + (incf beg elmo-localdir-header-chop-length))))) + (prog1 (not (search-forward "\n\n" nil t)) + (goto-char (point-max))))))))) + +(defsubst elmo-cache-msgdb-create-overview-entity-from-file (number file) + (save-excursion + (let ((tmp-buffer (get-buffer-create " *ELMO Cache Temp*")) + insert-file-contents-pre-hook ; To avoid autoconv-xmas... + insert-file-contents-post-hook header-end + (attrib (file-attributes file)) + ret-val size mtime) + (set-buffer tmp-buffer) + (erase-buffer) + (if (not (file-exists-p file)) + () + (setq size (nth 7 attrib)) + (setq mtime (timezone-make-date-arpa-standard + (current-time-string (nth 5 attrib)) (current-time-zone))) + ;; insert header from file. + (catch 'done + (condition-case nil + (elmo-cache-insert-header file) + (error (throw 'done nil))) + (goto-char (point-min)) + (setq header-end + (if (re-search-forward "\\(^--.*$\\)\\|\\(\n\n\\)" nil t) + (point) + (point-max))) + (narrow-to-region (point-min) header-end) + (setq ret-val (elmo-msgdb-create-overview-from-buffer number size mtime)) + (kill-buffer tmp-buffer)) + ret-val)))) + +(defun elmo-cache-msgdb-create-as-numlist (spec numlist new-mark + already-mark seen-mark + important-mark seen-list) + (when numlist + (let ((dir (elmo-cache-get-folder-directory spec)) + (nalist (elmo-cache-list-folder-subr spec nil t)) + overview number-alist mark-alist entity message-id + i percent len num seen gmark) + (setq len (length numlist)) + (setq i 0) + (message "Creating msgdb...") + (while numlist + (setq entity + (elmo-cache-msgdb-create-overview-entity-from-file + (car numlist) + (expand-file-name + (elmo-msgid-to-cache + (setq message-id (cdr (assq (car numlist) nalist)))) dir))) + (if (null entity) + () + (setq num (elmo-msgdb-overview-entity-get-number entity)) + (setq overview + (elmo-msgdb-append-element + overview entity)) + (setq number-alist + (elmo-msgdb-number-add number-alist num message-id)) + (setq seen (member message-id seen-list)) + (if (setq gmark (or (elmo-msgdb-global-mark-get message-id) + (if seen + nil + new-mark))) + (setq mark-alist + (elmo-msgdb-mark-append + mark-alist + num + gmark)))) + (setq i (1+ i)) + (setq percent (/ (* i 100) len)) + (elmo-display-progress + 'elmo-cache-msgdb-create-as-numlist "Creating msgdb..." + percent) + (setq numlist (cdr numlist))) + (message "Creating msgdb...done.") + (list overview number-alist mark-alist)))) + +(defalias 'elmo-cache-msgdb-create 'elmo-cache-msgdb-create-as-numlist) + +(defun elmo-cache-list-folders (spec &optional hierarchy) + (let ((folder (concat "'cache" (nth 1 spec)))) + (elmo-cache-list-folders-subr folder hierarchy))) + +(defun elmo-cache-list-folders-subr (folder &optional hierarchy) + (let ((case-fold-search t) + folders curdir dirent relpath abspath attr + subprefix subfolder) + (condition-case () + (progn + (setq curdir + (expand-file-name + (nth 1 (elmo-folder-get-spec folder)) + (expand-file-name elmo-cache-dirname elmo-msgdb-dir))) + (if (string-match "^[+=$!]$" folder) ;; localdir, archive, localnews + (setq subprefix folder) + (setq subprefix (concat folder elmo-path-sep))) + ;; include parent + ;(setq folders (list folder))) + (setq dirent (directory-files curdir nil "^[01][0-9A-F]$")) + (catch 'done + (while dirent + (setq relpath (car dirent)) + (setq dirent (cdr dirent)) + (setq abspath (expand-file-name relpath curdir)) + (and + (eq (nth 0 (setq attr (file-attributes abspath))) t) + (setq subfolder (concat subprefix relpath)) + (setq folders (nconc folders (list subfolder)))))) + folders) + (file-error folders)))) + +(defsubst elmo-cache-list-folder-subr (spec &optional nonsort nonalist) + (let* ((dir (elmo-cache-get-folder-directory spec)) + (flist (mapcar 'file-name-nondirectory + (elmo-delete-if 'file-directory-p + (directory-files + dir t "^[^@]+@[^@]+$" t)))) + (folder (concat "'cache/" (nth 1 spec))) + (number-alist (or (elmo-msgdb-number-load + (elmo-msgdb-expand-path folder)) + (list nil))) + nlist) + (setq nlist + (mapcar '(lambda (filename) + (elmo-cache-filename-to-number filename number-alist)) + flist)) + (if nonalist + number-alist + (if nonsort + (cons (or (elmo-max-of-list nlist) 0) (length nlist)) + (sort nlist '<))))) + +(defsubst elmo-cache-filename-to-number (filename number-alist) + (let* ((msgid (elmo-cache-to-msgid filename)) + number) + (or (car (rassoc msgid number-alist)) + (prog1 + (setq number (+ (or (caar (last number-alist)) + 0) 1)) + (if (car number-alist) + (nconc number-alist + (list (cons number msgid))) + (setcar number-alist (cons number msgid))))))) + +(defun elmo-cache-append-msg (spec string message-id &optional msg no-see) + (let ((dir (elmo-cache-get-folder-directory spec)) + (tmp-buffer (get-buffer-create " *ELMO Temp buffer*")) + filename) + (save-excursion + (set-buffer tmp-buffer) + (erase-buffer) + (setq filename (expand-file-name (elmo-msgid-to-cache message-id) dir)) + (unwind-protect + (if (file-writable-p filename) + (progn + (insert string) + (as-binary-output-file + (write-region (point-min) (point-max) filename nil 'no-msg)) + t) + nil) + (kill-buffer tmp-buffer))))) + +(defun elmo-cache-delete-msg (spec number locked) + (let* ((dir (elmo-cache-get-folder-directory spec)) + (file (expand-file-name + (elmo-cache-number-to-filename spec number) dir))) + ;; return nil if failed. + (elmo-cache-force-delete file locked))) + +(defun elmo-cache-read-msg (spec number outbuf &optional set-mark) + (save-excursion + (let* ((dir (elmo-cache-get-folder-directory spec)) + (file (expand-file-name + (elmo-cache-number-to-filename spec number) dir))) + (set-buffer outbuf) + (erase-buffer) + (when (file-exists-p file) + (as-binary-input-file (insert-file-contents file)) + (elmo-delete-cr-get-content-type))))) + +(defun elmo-cache-delete-msgs (spec msgs) + (let ((locked (elmo-dop-lock-list-load))) + (not (memq nil + (mapcar '(lambda (msg) (elmo-cache-delete-msg spec msg locked)) + msgs))))) + +(defun elmo-cache-list-folder (spec); called by elmo-cache-search() + (elmo-cache-list-folder-subr spec)) + +(defun elmo-cache-max-of-folder (spec) + (elmo-cache-list-folder-subr spec t)) + +(defun elmo-cache-check-validity (spec validity-file) + t) + +(defun elmo-cache-sync-validity (spec validity-file) + t) + +(defun elmo-cache-folder-exists-p (spec) + (file-directory-p (elmo-cache-get-folder-directory spec))) + +(defun elmo-cache-folder-creatable-p (spec) + nil) + +(defun elmo-cache-create-folder (spec) + nil) + +(defun elmo-cache-search (spec condition &optional from-msgs) + (let* ((number-alist (elmo-cache-list-folder-subr spec nil t)) + (msgs (or from-msgs (mapcar 'car number-alist))) + (num (length msgs)) + (i 0) case-fold-search ret-val) + (while msgs + (if (elmo-file-field-condition-match + (expand-file-name + (elmo-msgid-to-cache + (cdr (assq (car msgs) number-alist))) + (elmo-cache-get-folder-directory spec)) + condition) + (setq ret-val (cons (car msgs) ret-val))) + (setq i (1+ i)) + (elmo-display-progress + 'elmo-cache-search "Searching..." + (/ (* i 100) num)) + (setq msgs (cdr msgs))) + (nreverse ret-val))) + +;;; (localdir, maildir, localnews) -> cache +(defun elmo-cache-copy-msgs (dst-spec msgs src-spec + &optional loc-alist same-number) + (let ((dst-dir + (elmo-cache-get-folder-directory dst-spec)) + (next-num (1+ (car (elmo-cache-list-folder-subr dst-spec t)))) + (number-alist + (elmo-msgdb-number-load + (elmo-msgdb-expand-path nil src-spec)))) + (if same-number (error "Not implemented")) + (while msgs + (elmo-copy-file + ;; src file + (elmo-call-func src-spec "get-msg-filename" (car msgs) loc-alist) + ;; dst file + (expand-file-name + (elmo-msgid-to-cache + (cdr (assq (if same-number (car msgs) next-num) number-alist))) + dst-dir)) + (if (and (setq msgs (cdr msgs)) + (not same-number)) + (setq next-num (1+ next-num)))) + t)) + +(defun elmo-cache-use-cache-p (spec number) + nil) + +(defun elmo-cache-local-file-p (spec number) + t) + +(defun elmo-cache-get-msg-filename (spec number &optional loc-alist) + (expand-file-name + (elmo-cache-number-to-filename spec number) + (elmo-cache-get-folder-directory spec))) + +(defalias 'elmo-cache-sync-number-alist + 'elmo-generic-sync-number-alist) +(defalias 'elmo-cache-list-folder-unread + 'elmo-generic-list-folder-unread) +(defalias 'elmo-cache-list-folder-important + 'elmo-generic-list-folder-important) +(defalias 'elmo-cache-commit 'elmo-generic-commit) + +(provide 'elmo-cache) + +;;; elmo-cache.el ends here diff --git a/elmo/elmo-cache2.el b/elmo/elmo-cache2.el new file mode 100644 index 0000000..9c45e94 --- /dev/null +++ b/elmo/elmo-cache2.el @@ -0,0 +1,338 @@ +;;; elmo-cache2.el -- Cache Folder Interface for ELMO. + +;; Author: Kenichi OKADA +;; Keywords: mail, net news +;; Time-stamp: <00/03/01 09:58:07 teranisi> + +;; This file is part of ELMO (Elisp Library for Message Orchestration). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; + +(require 'emu) +(require 'std11) + +(require 'elmo-cache) +(require 'elmo-msgdb) + +(defsubst elmo-cache-get-folder-directory (spec) + (if (file-name-absolute-p (nth 1 spec)) + (nth 1 spec) ; already full path. + (expand-file-name (nth 1 spec) + (expand-file-name elmo-cache-dirname elmo-msgdb-dir)))) + +(defun elmo-cache-msgdb-expand-path (spec) + (let ((fld-name (nth 1 spec))) + (expand-file-name fld-name + (expand-file-name "internal/cache" + elmo-msgdb-dir)))) + +(defun elmo-cache-number-to-filename (spec number) + (let ((number-alist + (elmo-cache-list-folder-subr spec nil t))) + (elmo-msgid-to-cache + (cdr (assq number number-alist))))) + +(if (boundp 'nemacs-version) + (defsubst elmo-cache-insert-header (file) + "Insert the header of the article (Does not work on nemacs)." + (as-binary-input-file + (insert-file-contents file))) + (defsubst elmo-cache-insert-header (file) + "Insert the header of the article." + (let ((beg 0) + insert-file-contents-pre-hook ; To avoid autoconv-xmas... + insert-file-contents-post-hook + format-alist) + (when (file-exists-p file) + ;; Read until header separator is found. + (while (and (eq elmo-localdir-header-chop-length + (nth 1 + (as-binary-input-file + (insert-file-contents + file nil beg + (incf beg elmo-localdir-header-chop-length))))) + (prog1 (not (search-forward "\n\n" nil t)) + (goto-char (point-max))))))))) + +(defsubst elmo-cache-msgdb-create-overview-entity-from-file (number file) + (save-excursion + (let ((tmp-buffer (get-buffer-create " *ELMO Cache Temp*")) + insert-file-contents-pre-hook ; To avoid autoconv-xmas... + insert-file-contents-post-hook header-end + (attrib (file-attributes file)) + ret-val size mtime) + (set-buffer tmp-buffer) + (erase-buffer) + (if (not (file-exists-p file)) + () + (setq size (nth 7 attrib)) + (setq mtime (timezone-make-date-arpa-standard + (current-time-string (nth 5 attrib)) (current-time-zone))) + ;; insert header from file. + (catch 'done + (condition-case nil + (elmo-cache-insert-header file) + (error (throw 'done nil))) + (goto-char (point-min)) + (setq header-end + (if (re-search-forward "\\(^--.*$\\)\\|\\(\n\n\\)" nil t) + (point) + (point-max))) + (narrow-to-region (point-min) header-end) + (setq ret-val (elmo-msgdb-create-overview-from-buffer number size mtime)) + (kill-buffer tmp-buffer)) + ret-val)))) + +(defun elmo-cache-msgdb-create-as-numlist (spec numlist new-mark + already-mark seen-mark + important-mark seen-list) + (when numlist + (let ((dir (elmo-cache-get-folder-directory spec)) + (nalist (elmo-cache-list-folder-subr spec nil t)) + overview number-alist mark-alist entity message-id + i percent len num seen gmark) + (setq len (length numlist)) + (setq i 0) + (message "Creating msgdb...") + (while numlist + (setq entity + (elmo-cache-msgdb-create-overview-entity-from-file + (car numlist) + (expand-file-name + (elmo-msgid-to-cache + (setq message-id (cdr (assq (car numlist) nalist)))) dir))) + (if (null entity) + () + (setq num (elmo-msgdb-overview-entity-get-number entity)) + (setq overview + (elmo-msgdb-append-element + overview entity)) + (setq number-alist + (elmo-msgdb-number-add number-alist num message-id)) + (setq seen (member message-id seen-list)) + (if (setq gmark (or (elmo-msgdb-global-mark-get message-id) + (if seen + nil + new-mark))) + (setq mark-alist + (elmo-msgdb-mark-append + mark-alist + num + gmark)))) + (setq i (1+ i)) + (setq percent (/ (* i 100) len)) + (message "Creating msgdb...%d%%" percent) + (setq numlist (cdr numlist))) + (message "Creating msgdb...done.") + (list overview number-alist mark-alist)))) + +(defalias 'elmo-cache-msgdb-create 'elmo-cache-msgdb-create-as-numlist) + +(defun elmo-cache-list-folders (spec &optional hierarchy) + (let ((folder (concat "!" (nth 1 spec)))) + (elmo-cache-list-folders-subr folder hierarchy))) + +(defun elmo-cache-list-folders-subr (folder &optional hierarchy) + (let ((case-fold-search t) + folders curdir dirent relpath abspath attr + subprefix subfolder) + (condition-case () + (progn + (setq curdir + (expand-file-name (nth 1 (elmo-folder-get-spec folder)) + (expand-file-name elmo-cache-dirname elmo-msgdb-dir))) + (if (string-match "^[+=$!]$" folder) ;; localdir, archive, localnews + (setq subprefix folder) + (setq subprefix (concat folder elmo-path-sep)) + ;; include parent + (setq folders (list folder))) + (setq dirent (directory-files curdir nil "^[01][0-9A-F]$")) + (catch 'done + (while dirent + (setq relpath (car dirent)) + (setq dirent (cdr dirent)) + (setq abspath (expand-file-name relpath curdir)) + (and + (eq (nth 0 (setq attr (file-attributes abspath))) t) + (setq subfolder (concat subprefix relpath)) + (setq folders (nconc folders (list subfolder)))))) + folders) + (file-error folders)))) + +(defsubst elmo-cache-list-folder-subr (spec &optional nonsort nonalist) + (let* ((dir (elmo-cache-get-folder-directory spec)) + (flist (directory-files dir nil "^[^@]+@[^@]+$" t)) + (folder (concat "!" (nth 1 spec))) + (number-alist (or (elmo-msgdb-number-load (elmo-msgdb-expand-path folder)) + (list nil))) + nlist) + (setq nlist + (mapcar '(lambda (filename) + (elmo-cache-filename-to-number filename number-alist)) + flist)) + (if nonalist + number-alist + (if nonsort + (cons (or (elmo-max-of-list nlist) 0) (length nlist)) + (sort nlist '<))))) + +(defsubst elmo-cache-filename-to-number (filename number-alist) + (let* ((msgid (elmo-cache-to-msgid filename)) + number) + (or (car (rassoc msgid number-alist)) + (prog1 + (setq number (+ (or (caar (last number-alist)) + 0) 1)) + (if (car number-alist) + (nconc number-alist + (list (cons number msgid))) + (setcar number-alist (cons number msgid))))))) + +(defun elmo-cache-append-msg (spec string message-id &optional msg no-see) + (let ((dir (elmo-cache-get-folder-directory spec)) + (tmp-buffer (get-buffer-create " *ELMO Temp buffer*")) + filename) + (save-excursion + (set-buffer tmp-buffer) + (erase-buffer) + (setq filename (expand-file-name (elmo-msgid-to-cache message-id) dir)) + (unwind-protect + (if (file-writable-p filename) + (progn + (insert string) + (as-binary-output-file + (write-region (point-min) (point-max) filename nil 'no-msg)) + t) + nil) + (kill-buffer tmp-buffer))))) + +(defun elmo-cache-delete-msg (spec number) + (let* ((dir (elmo-cache-get-folder-directory spec)) + (file (expand-file-name + (elmo-cache-number-to-filename spec number) dir))) + (if (and (file-exists-p file) + (file-writable-p file) + (not (file-directory-p file))) + (progn (delete-file file) + t)))) + +(defun elmo-cache-read-msg (spec number outbuf &optional set-mark) + (save-excursion + (let* ((dir (elmo-cache-get-folder-directory spec)) + (file (expand-file-name + (elmo-cache-number-to-filename spec number) dir))) + (set-buffer outbuf) + (erase-buffer) + (when (file-exists-p file) + (as-binary-input-file (insert-file-contents file)) + (elmo-delete-cr-get-content-type))))) + +(defun elmo-cache-delete-msgs (spec msgs) + (mapcar '(lambda (msg) (elmo-cache-delete-msg spec msg)) + msgs)) + +(defun elmo-cache-list-folder (spec); called by elmo-cache-search() + (elmo-cache-list-folder-subr spec)) + +(defun elmo-cache-max-of-folder (spec) + (elmo-cache-list-folder-subr spec t)) + +(defun elmo-cache-check-validity (spec validity-file) + t) + +(defun elmo-cache-sync-validity (spec validity-file) + t) + +(defun elmo-cache-folder-exists-p (spec) + (file-directory-p (elmo-cache-get-folder-directory spec))) + +(defun elmo-cache-folder-creatable-p (spec) + nil) + +(defun elmo-cache-create-folder (spec) + nil) + +(defun elmo-cache-search (spec condition &optional from-msgs) + (let* ((number-alist (elmo-cache-list-folder-subr spec nil t)) + (msgs (or from-msgs (mapcar 'car number-alist))) + (num (length msgs)) + (i 0) case-fold-search ret-val) + (while msgs + (if (elmo-file-field-condition-match + (expand-file-name + (elmo-msgid-to-cache + (cdr (assq (car msgs) number-alist))) + (elmo-cache-get-folder-directory spec)) + condition) + (setq ret-val (cons (car msgs) ret-val))) + (setq i (1+ i)) + (message "Searching...%d%%" (/ (* i 100) num)) + (setq msgs (cdr msgs))) + (nreverse ret-val))) + +;;; (localdir, maildir, localnews) -> cache +(defun elmo-cache-copy-msgs (dst-spec msgs src-spec + &optional loc-alist same-number) + (let ((dst-dir + (elmo-cache-get-folder-directory dst-spec)) + (next-num (1+ (car (elmo-cache-list-folder-subr dst-spec t)))) + (number-alist + (elmo-msgdb-number-load + (elmo-msgdb-expand-path nil src-spec)))) + (if same-number (error "Not implemented")) + (while msgs + (elmo-copy-file + ;; src file + (elmo-call-func src-spec "get-msg-filename" (car msgs) loc-alist) + ;; dst file + (expand-file-name + (elmo-msgid-to-cache + (cdr (assq (if same-number (car msgs) next-num) number-alist))) + dst-dir)) + (if (and (setq msgs (cdr msgs)) + (not same-number)) + (setq next-num (1+ next-num)))) + t)) + +(defun elmo-cache-use-cache-p (spec number) + nil) + +(defun elmo-cache-local-file-p (spec number) + t) + +(defun elmo-cache-get-msg-filename (spec number &optional loc-alist) + (expand-file-name + (elmo-cache-number-to-filename spec number) + (elmo-cache-get-folder-directory spec))) + +(defalias 'elmo-cache-sync-number-alist + 'elmo-generic-sync-number-alist) +(defalias 'elmo-cache-list-folder-unread + 'elmo-generic-list-folder-unread) +(defalias 'elmo-cache-list-folder-important + 'elmo-generic-list-folder-important) +(defalias 'elmo-cache-commit 'elmo-generic-commit) + +(provide 'elmo-cache2) + +;;; elmo-cache2.el ends here diff --git a/elmo/elmo-database.el b/elmo/elmo-database.el new file mode 100644 index 0000000..2b6a61b --- /dev/null +++ b/elmo/elmo-database.el @@ -0,0 +1,74 @@ +;;; elmo-database.el -- Database module for ELMO. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <2000-01-07 00:19:44 teranisi> + +;; This file is part of ELMO (Elisp Library for Message Orchestration). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; +(require 'elmo-vars) +(require 'elmo-msgdb) + +(defvar elmo-database-msgid nil) +(defvar elmo-database-msgid-filename "msgid") + +(defun elmo-database-get (dbsym dbname) + (if (not (and (symbol-value dbsym) + (database-live-p (symbol-value dbsym)))) + (set dbsym (open-database (expand-file-name + dbname + elmo-msgdb-dir + ))) + (symbol-value dbsym))) + +(defun elmo-database-close () + (and elmo-database-msgid + (database-live-p elmo-database-msgid) + (close-database elmo-database-msgid))) + +(defun elmo-database-msgid-put (msgid folder number) + (let ((db (elmo-database-get 'elmo-database-msgid + elmo-database-msgid-filename))) + (and msgid db + (progn + (remove-database msgid db) + (put-database msgid (prin1-to-string + (list folder number)) db))))) + +(defun elmo-database-msgid-delete (msgid) + (remove-database msgid (elmo-database-get + 'elmo-database-msgid + elmo-database-msgid-filename))) + +(defun elmo-database-msgid-get (msgid) + (let ((match (get-database msgid (elmo-database-get + 'elmo-database-msgid + elmo-database-msgid-filename)))) + (and match (read match)))) + +(provide 'elmo-database) + +;;; elmo-database.el ends here diff --git a/elmo/elmo-date.el b/elmo/elmo-date.el new file mode 100644 index 0000000..7dd66bb --- /dev/null +++ b/elmo/elmo-date.el @@ -0,0 +1,144 @@ +;;; elmo-date.el -- Date processing module for ELMO. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <00/03/14 19:38:44 teranisi> + +;; This file is part of ELMO (Elisp Library for Message Orchestration). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; + + +(require 'path-util) +(if (module-installed-p 'timezone) + (require 'timezone)) +(require 'elmo-vars) + +(defvar elmo-date-descriptions + '((yesterday . [0 0 1]) + (lastweek . [0 0 7]) + (lastmonth . [0 1 0]) + (lastyear . [1 0 0]))) + +(defun elmo-date-get-description (datevec) + (format "%d-%s-%d" + (aref datevec 2) + (car (rassq (aref datevec 1) + timezone-months-assoc)) + (aref datevec 0))) + +(defun elmo-date-get-datevec (description) + (cond + ((not elmo-date-match) + (error "date match is not available")) + ((string-match "^[ \t]*\\([0-9]+\\)?[ \t]*\\([a-zA-Z]+\\)$" description) + (let ((today + (save-match-data + (timezone-fix-time (current-time-string) (current-time-zone) + nil))) + (number + (string-to-int + (if (match-beginning 1) + (elmo-match-string 1 description) + "0"))) + (suffix (downcase (elmo-match-string 2 description))) + pair) + (if (setq pair (assq (intern suffix) elmo-date-descriptions)) + (elmo-datevec-substitute today (cdr pair)) + (if (string= "daysago" suffix) + (elmo-date-get-offset-datevec today number) + (error "%s is not supported yet" suffix))))) + ((string-match "[0-9]+-[A-Za-z]+-[0-9]+" description) + (timezone-fix-time + (concat (elmo-replace-in-string description "-" " ") " 0:00") + nil nil)))) + +(defun elmo-datevec-substitute (datevec1 datevec2) + (if (/= (aref datevec2 2) 0) + (elmo-date-get-offset-datevec datevec1 (aref datevec2 2)) + (let ((year (- (aref datevec1 0) (aref datevec2 0))) + (month (- (aref datevec1 1) (aref datevec2 1))) + (timezone (current-time-zone))) + (while (<= month 0) + (setq year (1- year) + month (+ 12 month))) + (timezone-fix-time + (format "%d %s %d 0:00 %s" + (aref datevec1 2) + (car (rassq month timezone-months-assoc)) + year + (cadr timezone)) nil nil)))) + +(defun elmo-date-get-week (year month mday) + (let ((wday (symbol-value (intern (format + "elmo-weekday-name-%s" + elmo-lang)))) + y1 days p) + (setq y1 (- year 1)) + (setq days (- (+ (* y1 365) (/ y1 400) (/ y1 4)) (/ y1 100))) + (setq p 1) + (while (< p month) + (setq days (+ days (timezone-last-day-of-month p year))) + (setq p (+ p 1)) + ) + (setq days (+ days mday)) + (aref wday (% days 7)))) + +(defun elmo-date-get-offset-datevec (datevec offset &optional time) + (let ((year (aref datevec 0)) + (month (aref datevec 1)) + (day (aref datevec 2)) + (hour (aref datevec 3)) + (minute (aref datevec 4)) + (second (aref datevec 5)) + (timezone (aref datevec 6)) + day-number p + day-of-month) + (setq p 1) + (setq day-number (- (timezone-day-number month day year) + offset)) + (while (<= day-number 0) + (setq year (1- year) + day-number (+ (timezone-day-number 12 31 year) + day-number))) + (while (> day-number (setq day-of-month + (timezone-last-day-of-month p year))) + (setq day-number (- day-number day-of-month)) + (setq p (1+ p))) + (setq month p) + (setq day day-number) + (timezone-fix-time + (format "%d %s %d %s %s" + day + (car (rassq month timezone-months-assoc)) + year + (if time + (format "%d:%d:%d" hour minute second) + "0:00") + (cadr timezone)) nil nil))) + +(provide 'elmo-date) + +;;; elmo-date.el ends here diff --git a/elmo/elmo-dop.el b/elmo/elmo-dop.el new file mode 100644 index 0000000..3643a42 --- /dev/null +++ b/elmo/elmo-dop.el @@ -0,0 +1,551 @@ +;;; elmo-dop.el -- Modules for Disconnected Operations on ELMO. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <00/03/14 19:39:23 teranisi> + +;; This file is part of ELMO (Elisp Library for Message Orchestration). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; + +(require 'elmo-vars) +(require 'elmo-msgdb) +(require 'elmo-util) +(eval-when-compile + (require 'elmo-imap4) + (require 'elmo-localdir)) + +;; global variable. +(defvar elmo-dop-queue nil + "A list of (folder-name function-to-be-called argument-list). +Automatically loaded/saved.") + +(defun elmo-dop-queue-append (folder function argument) + (let ((operation (list (format "%s" folder) function argument))) + (elmo-dop-queue-load) + (unless (member operation elmo-dop-queue) ;; don't append same operation + (setq elmo-dop-queue + (append elmo-dop-queue + (list operation))) + (elmo-dop-queue-save)))) + +(defun elmo-dop-queue-flush () + (elmo-dop-queue-load) ; load cache. + (elmo-dop-queue-merge) + (let ((queue elmo-dop-queue) + (count 0) + len) + (while queue + (if (elmo-folder-plugged-p (caar queue)) + (setq count (1+ count))) + (setq queue (cdr queue))) + (when (> count 0) + (if (elmo-y-or-n-p + (format "%d pending operation(s) exists. Perform now?" count) + (not elmo-dop-flush-confirm) t) + (progn + (message "") + (sit-for 0) + (let ((queue elmo-dop-queue) + (performed 0) + (i 0) + (num (length elmo-dop-queue)) + folder func failure) + (while queue + ;; now perform pending processes. + (setq failure nil) + (setq i (+ 1 i)) + (message "Flushing queue....%d/%d." i num) + (condition-case err + (if (not (elmo-folder-plugged-p (nth 0 (car queue)))) + (setq failure t) + (setq folder (nth 0 (car queue)) + func (nth 1 (car queue))) + (cond + ((string= func "prefetch-msgs") + (elmo-prefetch-msgs + folder + (nth 2 (car queue)))) ;argunemt + ((string= func "append-operations") + (elmo-dop-flush-pending-append-operations + folder nil t)) + (t + (elmo-call-func + folder + func + (nth 2 (car queue)) ;argunemt + )))) + (quit (setq failure t)) + (error (setq failure err))) + (if failure + ;; create-folder was failed. + (when (and (string= func "create-folder-maybe") + (elmo-y-or-n-p + (format + "Create folder %s failed. Abort creating?" + folder) + (not elmo-dop-flush-confirm) t)) + (elmo-dop-save-pending-messages folder) + (setq elmo-dop-queue (delq (car queue) elmo-dop-queue))) + (setq elmo-dop-queue (delq (car queue) elmo-dop-queue)) + (setq performed (+ 1 performed))) + (setq queue (cdr queue))) + (message "%d/%d operation(s) are performed successfully." + performed num) + (sit-for 1) ; + (elmo-dop-queue-save))) + (if (elmo-y-or-n-p "Clear all pending operations?" + (not elmo-dop-flush-confirm) t) + (let ((queue elmo-dop-queue)) + (while queue + (if (string= (nth 1 (car queue)) "append-operations") + (elmo-dop-append-list-save (nth 0 (car queue)) nil)) + (setq queue (cdr queue))) + (setq elmo-dop-queue nil) + (message "All pending operations are cleared.") + (elmo-dop-queue-save)) + (message ""))) + count))) + +(defconst elmo-dop-merge-funcs + '("delete-msgids" + "prefetch-msgs" + "unmark-important" + "mark-as-important" + "mark-as-read" + "mark-as-unread")) + +(defun elmo-dop-queue-merge () + (let ((queue elmo-dop-queue) + new-queue match-queue que) + (while (setq que (car queue)) + (if (and + (member (cadr que) elmo-dop-merge-funcs) + (setq match-queue + (car (delete nil + (mapcar '(lambda (new-queue) + (if (and + (string= (car que) (car new-queue)) + (string= (cadr que) (cadr new-queue))) + new-queue)) + new-queue))))) + (setcar (cddr match-queue) + (append (nth 2 match-queue) (nth 2 que))) + (setq new-queue (append new-queue (list que)))) + (setq queue (cdr queue))) + (setq elmo-dop-queue new-queue))) + +(defun elmo-dop-queue-load () + (save-excursion + (setq elmo-dop-queue + (elmo-object-load + (expand-file-name elmo-queue-filename + elmo-msgdb-dir))))) + +(defun elmo-dop-queue-save () + (save-excursion + (elmo-object-save + (expand-file-name elmo-queue-filename + elmo-msgdb-dir) + elmo-dop-queue))) + +(defun elmo-dop-lock-message (message-id &optional lock-list) + (let ((locked (or lock-list + (elmo-object-load + (expand-file-name + elmo-msgdb-lock-list-filename + elmo-msgdb-dir))))) + (setq locked (cons message-id locked)) + (elmo-object-save + (expand-file-name elmo-msgdb-lock-list-filename + elmo-msgdb-dir) + locked))) + +(defun elmo-dop-unlock-message (message-id &optional lock-list) + (let ((locked (or lock-list + (elmo-object-load + (expand-file-name elmo-msgdb-lock-list-filename + elmo-msgdb-dir))))) + (setq locked (delete message-id locked)) + (elmo-object-save + (expand-file-name elmo-msgdb-lock-list-filename + elmo-msgdb-dir) + locked))) + +(defun elmo-dop-lock-list-load () + (elmo-object-load + (expand-file-name elmo-msgdb-lock-list-filename + elmo-msgdb-dir))) + +(defun elmo-dop-lock-list-save (lock-list) + (elmo-object-save + (expand-file-name elmo-msgdb-lock-list-filename + elmo-msgdb-dir) + lock-list)) + +(defun elmo-dop-append-list-load (folder &optional resume) + (elmo-object-load + (expand-file-name (if resume + elmo-msgdb-resume-list-filename + elmo-msgdb-append-list-filename) + (elmo-msgdb-expand-path folder)))) + +(defun elmo-dop-append-list-save (folder append-list &optional resume) + (if append-list + (elmo-object-save + (expand-file-name (if resume + elmo-msgdb-resume-list-filename + elmo-msgdb-append-list-filename) + (elmo-msgdb-expand-path folder)) + append-list) + (condition-case () + (delete-file (expand-file-name (if resume + elmo-msgdb-resume-list-filename + elmo-msgdb-append-list-filename) + (elmo-msgdb-expand-path folder))) + (error)))) + +(defun elmo-dop-deleting-numbers-to-msgids (alist numbers appended) + "returns (new-appended . deleting-msgids)." + (let (msgid deleting-msgids) + (while numbers + (setq msgid (cdr (assq (car numbers) alist))) + (if (member msgid appended) + (setq appended (delete msgid appended)) + (setq deleting-msgids (append deleting-msgids (list msgid)))) + (setq numbers (cdr numbers))) + (cons appended deleting-msgids))) + +(defun elmo-dop-delete-msgs (folder msgs msgdb) + (save-match-data + (let ((folder-numbers (elmo-make-folder-numbers-list folder msgs)) + appended-deleting) + (while folder-numbers + (if (eq (elmo-folder-get-type (car (car folder-numbers))) + 'imap4) + (if elmo-enable-disconnected-operation + (progn + (setq appended-deleting + (elmo-dop-deleting-numbers-to-msgids + (elmo-msgdb-get-number-alist msgdb) + msgs ; virtual number + (elmo-dop-append-list-load folder))) + (if (cdr appended-deleting) + (elmo-dop-queue-append + (car (car folder-numbers)) ; real folder + "delete-msgids" ;; for secure removal. + (cdr appended-deleting))) + (elmo-dop-append-list-save folder (car appended-deleting))) + (error "Unplugged")) + ;; not imap4 folder...delete now! + (elmo-call-func (car (car folder-numbers)) "delete-msgs" + (cdr (car folder-numbers)))) + (setq folder-numbers (cdr folder-numbers)))) + t)) + +(defun elmo-dop-prefetch-msgs (folder msgs) + (save-match-data + (elmo-dop-queue-append folder "prefetch-msgs" msgs))) + +(defun elmo-dop-list-folder (folder) + (if (or (memq (elmo-folder-get-type folder) + '(imap4 nntp pop3 filter pipe)) + (and (elmo-multi-p folder) (not (elmo-folder-local-p folder)))) + (if elmo-enable-disconnected-operation + (let* ((number-alist (elmo-msgdb-number-load + (elmo-msgdb-expand-path folder))) + (number-list (mapcar 'car number-alist)) + (append-list (elmo-dop-append-list-load folder)) + (append-num (length append-list)) + alreadies + (i 0) + max-num) + (while append-list + (if (rassoc (car append-list) number-alist) + (setq alreadies (append alreadies + (list (car append-list))))) + (setq append-list (cdr append-list))) + (setq append-num (- append-num (length alreadies))) + (setq max-num + (or (nth (max (- (length number-list) 1) 0) + number-list) 0)) + (while (< i append-num) + (setq number-list + (append number-list + (list (+ max-num i 1)))) + (setq i (+ 1 i))) + number-list) + (error "Unplugged")) + ;; not imap4 folder...list folder + (elmo-call-func folder "list-folder"))) + +(defun elmo-dop-count-appended (folder) + (length (elmo-dop-append-list-load folder))) + +(defun elmo-dop-call-func-on-msgs (folder func-name msgs msgdb) + (let ((append-list (elmo-dop-append-list-load folder)) + (number-alist (elmo-msgdb-get-number-alist msgdb)) + matched) + (if (eq (elmo-folder-get-type folder) 'imap4) + (progn + (while append-list + (if (setq matched (car (rassoc (car append-list) number-alist))) + (setq msgs (delete matched msgs))) + (setq append-list (cdr append-list))) + (if msgs + (elmo-dop-queue-append folder func-name msgs))) + ;; maildir... XXX hard coding..... + (if (not (featurep 'elmo-maildir)) + (require 'maildir)) + (funcall (intern (format "elmo-maildir-%s" func-name)) + (elmo-folder-get-spec folder) + msgs msgdb)))) + +(defun elmo-dop-max-of-folder (folder) + (if (eq (elmo-folder-get-type folder) 'imap4) + (if elmo-enable-disconnected-operation + (let* ((number-alist (elmo-msgdb-number-load + (elmo-msgdb-expand-path folder))) + (number-list (mapcar 'car number-alist)) + (append-list (elmo-dop-append-list-load folder)) + (append-num (length append-list)) + alreadies + (i 0) + max-num) + (while append-list + (if (rassoc (car append-list) number-alist) + (setq alreadies (append alreadies + (list (car append-list))))) + (setq append-list (cdr append-list))) + (setq max-num + (or (nth (max (- (length number-list) 1) 0) number-list) + 0)) + (cons (- (+ max-num append-num) (length alreadies)) + (- (+ (length number-list) append-num) (length alreadies)))) + (error "Unplugged")) + ;; not imap4 folder. + (elmo-call-func folder "max-of-folder"))) + +(defun elmo-dop-save-pending-messages (folder) + (message (format "Saving queued message in %s..." elmo-lost+found-folder)) + (let* ((append-list (elmo-dop-append-list-load folder)) + file-string) + (while append-list + (when (setq file-string (elmo-get-file-string ; message string + (elmo-cache-get-path + (car append-list)))) + (elmo-append-msg elmo-lost+found-folder file-string) + (elmo-dop-unlock-message (car append-list))) + (setq append-list (cdr append-list)) + (elmo-dop-append-list-save folder nil))) + (message (format "Saving queued message in %s...done." + elmo-lost+found-folder))) + +(defun elmo-dop-flush-pending-append-operations (folder &optional appends resume) + (message "Appending queued messages...") + (let* ((append-list (or appends + (elmo-dop-append-list-load folder))) + (appendings append-list) + (i 0) + (num (length append-list)) + failure file-string) + (when resume + ;; Resume msgdb changed by elmo-dop-msgdb-create. + (let* ((resumed-list (elmo-dop-append-list-load folder t)) + (number-alist (elmo-msgdb-number-load + (elmo-msgdb-expand-path folder))) + (appendings append-list) + pair dels) + (while appendings + (if (setq pair (rassoc (car appendings) number-alist)) + (setq resumed-list (append resumed-list + (list (car appendings))))) + (setq appendings (cdr appendings))) + (elmo-dop-append-list-save folder resumed-list t))) + (while appendings + (setq failure nil) + (setq file-string (elmo-get-file-string ; message string + (elmo-cache-get-path + (car appendings)))) + (when file-string + (condition-case () + (elmo-append-msg folder file-string (car appendings)) + (quit (setq failure t)) + (error (setq failure t))) + (setq i (+ 1 i)) + (message (format "Appending queued messages...%d" i)) + (if failure + (elmo-append-msg elmo-lost+found-folder + file-string (car appendings)))) + (elmo-dop-unlock-message (car appendings)) + (setq appendings (cdr appendings))) + ;; All pending append operation is flushed. + (elmo-dop-append-list-save folder nil) + (elmo-commit folder) + (unless resume + ;; delete '(folder "append-operations") in elmo-dop-queue. + (let (elmo-dop-queue) + (elmo-dop-queue-load) + (setq elmo-dop-queue (delete (list folder "append-operations" nil) + elmo-dop-queue)) + (elmo-dop-queue-save)))) + (message "Appending queued messages...done.")) + +(defun elmo-dop-folder-exists-p (folder) + (if (and elmo-enable-disconnected-operation + (eq (elmo-folder-get-type folder) 'imap4)) + (file-exists-p (elmo-msgdb-expand-path folder)) + (elmo-call-func folder "folder-exists-p"))) + +(defun elmo-dop-create-folder (folder) + (if (eq (elmo-folder-get-type folder) 'imap4) + (if elmo-enable-disconnected-operation + (elmo-dop-queue-append folder "create-folder-maybe" nil) + (error "Unplugged")) + (elmo-call-func folder "create-folder"))) + +(defun elmo-dop-delete-folder (folder) + (error "Unplugged")) + +(defun elmo-dop-rename-folder (old-folder new-folder) + (error "Unplugged")) + +(defun elmo-dop-append-msg (folder string message-id &optional msg) + (if elmo-enable-disconnected-operation + (if message-id + (progn + (unless (elmo-cache-exists-p message-id) + (elmo-set-work-buf + (insert string) + (elmo-cache-save message-id nil folder msg (current-buffer)))) + (let ((append-list (elmo-dop-append-list-load folder)) + (number-alist (elmo-msgdb-number-load + (elmo-msgdb-expand-path folder)))) + (when (and ; not in current folder. + (not (rassoc message-id number-alist)) + (not (member message-id append-list))) + (setq append-list + (append append-list (list message-id))) + (elmo-dop-lock-message message-id) + (elmo-dop-append-list-save folder append-list) + (elmo-dop-queue-append folder "append-operations" nil)) + t)) + nil) + (error "Unplugged"))) + +(defalias 'elmo-dop-msgdb-create 'elmo-dop-msgdb-create-as-numlist) + +(defun elmo-dop-msgdb-create-as-numlist (folder numlist new-mark already-mark + seen-mark important-mark + seen-list) + (if (or (eq (elmo-folder-get-type folder) 'imap4) + (eq (elmo-folder-get-type folder) 'nntp)) + (if elmo-enable-disconnected-operation + (let* ((num-alist (elmo-msgdb-number-load + (elmo-msgdb-expand-path folder))) + (number-list (mapcar 'car num-alist)) + (ov (elmo-msgdb-overview-load + (elmo-msgdb-expand-path folder))) + (append-list (elmo-dop-append-list-load folder)) + (num (length numlist)) + (i 0) + overview number-alist mark-alist msgid ov-entity + max-num percent seen gmark) + (setq max-num + (or (nth (max (- (length number-list) 1) 0) number-list) + 0)) + (while numlist + (if (setq msgid + (nth (+ (length append-list) + (- (car numlist) max-num 1 num)) + append-list)) + (progn + (setq overview + (elmo-msgdb-append-element + overview + (elmo-localdir-msgdb-create-overview-entity-from-file + (car numlist) + (elmo-cache-get-path msgid)))) + (setq number-alist + (elmo-msgdb-number-add number-alist + (car numlist) msgid)) + (setq seen (member msgid seen-list)) + (if (setq gmark + (or (elmo-msgdb-global-mark-get msgid) + (if (elmo-cache-exists-p + msgid + folder + (car number-alist)) + (if seen + nil + already-mark) + (if seen + seen-mark) + new-mark))) + (setq mark-alist + (elmo-msgdb-mark-append + mark-alist (car numlist) gmark)))) + + (when (setq ov-entity (assoc + (cdr (assq (car numlist) num-alist)) + ov)) + (setq overview + (elmo-msgdb-append-element + overview ov-entity)) + (setq number-alist + (elmo-msgdb-number-add number-alist + (car numlist) + (car ov-entity))) + (setq seen (member ov-entity seen-list)) + (if (setq gmark + (or (elmo-msgdb-global-mark-get (car ov-entity)) + (if (elmo-cache-exists-p + msgid + folder + (car ov-entity)) + (if seen + nil + already-mark) + (if seen + seen-mark) + new-mark))) + (setq mark-alist + (elmo-msgdb-mark-append + mark-alist (car numlist) gmark))))) + (setq i (1+ i)) + (setq percent (/ (* i 100) num)) + (elmo-display-progress + 'elmo-dop-msgdb-create-as-numlist "Creating msgdb..." + percent) + (setq numlist (cdr numlist))) + (list overview number-alist mark-alist)) + (error "Unplugged")) + ;; not imap4 folder... + (elmo-call-func folder "msgdb-create" numlist new-mark already-mark + seen-mark important-mark seen-list))) + +(provide 'elmo-dop) + +;;; elmo-dop.el ends here diff --git a/elmo/elmo-filter.el b/elmo/elmo-filter.el new file mode 100644 index 0000000..3446140 --- /dev/null +++ b/elmo/elmo-filter.el @@ -0,0 +1,197 @@ +;;; elmo-filter.el -- Filtered Folder Interface for ELMO. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <00/03/13 18:58:42 teranisi> + +;; This file is part of ELMO (Elisp Library for Message Orchestration). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; +(require 'elmo-msgdb) + +(defun elmo-filter-msgdb-create (spec numlist new-mark already-mark + seen-mark important-mark seen-list) + (if (eq (nth 2 spec) 'partial) + (elmo-msgdb-create (nth 2 spec) + numlist + new-mark + already-mark + seen-mark important-mark seen-list) + (elmo-msgdb-create-as-numlist (nth 2 spec) + numlist + new-mark + already-mark + seen-mark important-mark seen-list))) + +(defun elmo-filter-msgdb-create-as-numlist (spec numlist new-mark already-mark + seen-mark important-mark + seen-list) + (elmo-msgdb-create-as-numlist (nth 2 spec) + numlist + new-mark + already-mark + seen-mark important-mark seen-list)) + +(defun elmo-filter-list-folders (spec &optional hierarchy) + nil) + +(defun elmo-filter-append-msg (spec string &optional msg no-see) + (elmo-call-func (nth 2 spec) "append" string)) + +(defun elmo-filter-read-msg (spec number outbuf) + (elmo-call-func (nth 2 spec) "read-msg" number outbuf)) + +(defun elmo-filter-delete-msgs (spec msgs) + (elmo-call-func (nth 2 spec) "delete-msgs" msgs)) + +(defun elmo-filter-list-folder (spec) + (let ((filter (nth 1 spec)) + (folder (nth 2 spec)) + msgs) + (cond + ((vectorp filter) + (cond ((string= (elmo-filter-key filter) + "last") + (setq msgs (elmo-list-folder folder)) + (nthcdr (max (- (length msgs) + (string-to-int (elmo-filter-value filter))) + 0) + msgs)) + ((string= (elmo-filter-key filter) + "first") + (setq msgs (elmo-list-folder folder)) + (let ((rest (nthcdr (string-to-int (elmo-filter-value filter) ) + msgs))) + (mapcar '(lambda (x) + (delete x msgs)) rest)) + msgs))) + ((listp filter) + (elmo-search folder filter))))) + +(defun elmo-filter-list-folder-unread (spec mark-alist unread-marks) + (let ((filter (nth 1 spec)) + (folder (nth 2 spec)) + msgs pair) + (cond + ((vectorp filter) + (cond ((string= (elmo-filter-key filter) + "last") + (setq msgs (elmo-list-folder-unread folder mark-alist + unread-marks)) + (nthcdr (max (- (length msgs) + (string-to-int (elmo-filter-value filter))) + 0) + msgs)) + ((string= (elmo-filter-key filter) + "first") + (setq msgs (elmo-list-folder-unread folder + mark-alist + unread-marks)) + (let ((rest (nthcdr (string-to-int (elmo-filter-value filter) ) + msgs))) + (mapcar '(lambda (x) + (delete x msgs)) rest)) + msgs))) + ((listp filter) + (elmo-list-filter + (elmo-search folder filter) + (elmo-list-folder-unread folder mark-alist unread-marks)))))) + +(defun elmo-filter-list-folder-important (spec overview) + (let ((filter (nth 1 spec)) + (folder (nth 2 spec)) + msgs pair) + (cond + ((vectorp filter) + (cond ((string= (elmo-filter-key filter) + "last") + (setq msgs (elmo-list-folder-important folder overview)) + (nthcdr (max (- (length msgs) + (string-to-int (elmo-filter-value filter))) + 0) + msgs)) + ((string= (elmo-filter-key filter) + "first") + (setq msgs (elmo-list-folder-important folder overview)) + (let ((rest (nthcdr (string-to-int (elmo-filter-value filter) ) + msgs))) + (mapcar '(lambda (x) + (delete x msgs)) rest)) + msgs))) + ((listp filter) + (elmo-list-filter + (mapcar + '(lambda (x) (elmo-msgdb-overview-entity-get-number x)) + overview) + (elmo-list-folder-important folder overview)))))) + +(defun elmo-filter-max-of-folder (spec) + (elmo-max-of-folder (nth 2 spec))) + +(defun elmo-filter-folder-exists-p (spec) + (elmo-folder-exists-p (nth 2 spec))) + +(defun elmo-filter-folder-creatable-p (spec) + (elmo-call-func (nth 2 spec) "folder-creatable-p")) + +(defun elmo-filter-create-folder (spec) + (elmo-create-folder (nth 2 spec))) + +(defun elmo-filter-search (spec condition &optional numlist) + ;; search from messages in this folder + (elmo-list-filter + numlist + (elmo-call-func (nth 2 spec) "search" condition + (elmo-filter-list-folder spec)))) + +(defun elmo-filter-use-cache-p (spec number) + (elmo-call-func (nth 2 spec) "use-cache-p" number)) + +(defun elmo-filter-local-file-p (spec number) + (elmo-call-func (nth 2 spec) "local-file-p" number)) + +(defun elmo-filter-commit (spec) + (elmo-commit (nth 2 spec))) + +(defun elmo-filter-plugged-p (spec) + (elmo-folder-plugged-p (nth 2 spec))) + +(defun elmo-filter-set-plugged (spec plugged add) + (elmo-folder-set-plugged (nth 2 spec) plugged add)) + +(defun elmo-filter-get-msg-filename (spec number &optional loc-alist) + ;; This function may be called when elmo-filter-local-file-p() + ;; returns t. + (elmo-call-func (nth 2 spec) "get-msg-filename" number loc-alist)) + +(defun elmo-filter-sync-number-alist (spec number-alist) + (elmo-call-func (nth 2 spec) "sync-number-alist" number-alist)) + +(defun elmo-filter-server-diff (spec) + (elmo-call-func (nth 2 spec) "server-diff")) + +(provide 'elmo-filter) + +;;; elmo-filter.el ends here diff --git a/elmo/elmo-imap4.el b/elmo/elmo-imap4.el new file mode 100644 index 0000000..66f3d0b --- /dev/null +++ b/elmo/elmo-imap4.el @@ -0,0 +1,1588 @@ +;;; elmo-imap4.el -- IMAP4 Interface for ELMO. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <00/03/14 19:40:38 teranisi> + +;; This file is part of ELMO (Elisp Library for Message Orchestration). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +(require 'elmo-vars) +(require 'elmo-util) +(require 'elmo-msgdb) +(require 'elmo-date) +(require 'elmo-cache) +(require 'utf7) + +;;; Code: +(condition-case nil + (progn + (require 'sasl)) + (error)) +;; silence byte compiler. +(eval-when-compile + (require 'cl) + (condition-case nil + (progn + (require 'starttls) + (require 'sasl)) + (error)) + (defun-maybe sasl-cram-md5 (username passphrase challenge)) + (defun-maybe sasl-digest-md5-digest-response + (digest-challenge username passwd serv-type host &optional realm)) + (defun-maybe starttls-negotiate (a)) + (defun-maybe elmo-generic-list-folder-unread (spec mark-alist unread-marks)) + (defsubst-maybe utf7-decode-string (string &optional imap) string)) + +(defvar elmo-imap4-use-lock t + "USE IMAP4 with locking process.") +;; +;; internal variables +;; +(defvar elmo-imap4-seq-prefix "elmo-imap4") +(defvar elmo-imap4-seqno 0) +(defvar elmo-imap4-connection-cache nil + "Cache of imap connection.") +(defvar elmo-imap4-use-uid t + "Use UID as message number.") + +;; buffer local variable +(defvar elmo-imap4-read-point 0) + +(defvar elmo-imap4-extra-namespace-alist + '(("^{.*/nntp}.*$" . ".")) ; Default is for UW's remote nntp mailbox... + "Extra namespace alist. A list of cons cell like: (REGEXP . DELIMITER) ") + +;; buffer local variable +(defvar elmo-imap4-server-capability nil) +(defvar elmo-imap4-server-namespace nil) + +(defvar elmo-imap4-lock nil) + +;; For debugging. +(defvar elmo-imap4-debug nil + "Non-nil forces IMAP4 folder as debug mode. +Debug information is inserted in the buffer \"*IMAP4 DEBUG*\"") + +(defsubst elmo-imap4-debug (message &rest args) + (if elmo-imap4-debug + (with-current-buffer (get-buffer-create "*IMAP4 DEBUG*") + (goto-char (point-max)) + (insert (apply 'format message args) "\n")))) + +(defun elmo-imap4-flush-connection () + (interactive) + (let ((cache elmo-imap4-connection-cache) + buffer process) + (while cache + (setq buffer (car (cdr (car cache)))) + (if buffer (kill-buffer buffer)) + (setq process (car (cdr (cdr (car cache))))) + (if process (delete-process process)) + (setq cache (cdr cache))) + (setq elmo-imap4-connection-cache nil))) + +(defsubst elmo-imap4-get-process (spec) + (elmo-imap4-connection-get-process (elmo-imap4-get-connection spec))) + +(defun elmo-imap4-process-folder-list (string) + (with-temp-buffer + (let ((case-fold-search t) + mailbox-list val) + (elmo-set-buffer-multibyte nil) + (insert string) + (goto-char (point-min)) + ;; XXX This doesn't consider literal name response. + (while (re-search-forward + "\\* LIST (\\([^)]*\\)) \"[^\"]*\" \\([^\n]*\\)$" nil t) + (unless (string-match "noselect" + (elmo-match-buffer 1)) + (setq val (elmo-match-buffer 2)) + (if (string-match "^\"\\(.*\\)\"$" val) + (setq val (match-string 1 val))) + (setq mailbox-list + (append mailbox-list + (list val))))) + mailbox-list))) + +(defun elmo-imap4-list-folders (spec &optional hierarchy) + (save-excursion + (let* ((root (elmo-imap4-spec-folder spec)) + (process (elmo-imap4-get-process spec)) + (delim (or + (cdr + (elmo-string-matched-assoc root + (save-excursion + (set-buffer + (process-buffer process)) + elmo-imap4-server-namespace))) + "/")) + response result append-serv ssl) + ;; Append delimiter + (if (and root + (not (string= root "")) + (not (string-match (concat "\\(.*\\)" + (regexp-quote delim) + "\\'") + root))) + (setq root (concat root delim))) + (elmo-imap4-send-command (process-buffer process) + process + (format "list \"%s\" *" root)) + (setq response (elmo-imap4-read-response (process-buffer process) + process)) + (setq result (elmo-imap4-process-folder-list response)) + (unless (string= (elmo-imap4-spec-username spec) + elmo-default-imap4-user) + (setq append-serv (concat ":" (elmo-imap4-spec-username spec)))) + (unless (string= (elmo-imap4-spec-hostname spec) + elmo-default-imap4-server) + (setq append-serv (concat append-serv "@" (elmo-imap4-spec-hostname + spec)))) + (unless (eq (elmo-imap4-spec-port spec) + elmo-default-imap4-port) + (setq append-serv (concat append-serv ":" + (int-to-string + (elmo-imap4-spec-port spec))))) + (unless (eq (setq ssl (elmo-imap4-spec-ssl spec)) + elmo-default-imap4-ssl) + (if ssl + (setq append-serv (concat append-serv "!"))) + (if (eq ssl 'starttls) + (setq append-serv (concat append-serv "!")))) + (mapcar '(lambda (fld) + (concat "%" (elmo-imap4-decode-folder-string fld) + (and append-serv + (eval append-serv)))) + result)))) + +(defun elmo-imap4-folder-exists-p (spec) + (let ((process (elmo-imap4-get-process spec))) + (elmo-imap4-send-command (process-buffer process) + process + (format "status \"%s\" (messages)" + (elmo-imap4-spec-folder spec))) + (elmo-imap4-read-response (process-buffer process) process))) + +(defun elmo-imap4-folder-creatable-p (spec) + t) + +(defun elmo-imap4-create-folder-maybe (spec dummy) + "Create folder if necessary." + (if (not (elmo-imap4-folder-exists-p spec)) + (elmo-imap4-create-folder spec))) + +(defun elmo-imap4-create-folder (spec) + (let ((process (elmo-imap4-get-process spec)) + (folder (elmo-imap4-spec-folder spec))) + (when folder +;; For UW imapd 4.6, this workaround is needed to create #mh mailbox. +; (if (string-match "^\\(#mh/\\).*[^/]$" folder) +; (setq folder (concat folder "/"))) ;; make directory + (elmo-imap4-send-command (process-buffer process) + process + (format "create %s" folder)) + (if (null (elmo-imap4-read-response (process-buffer process) + process)) + (error "Create folder %s failed" folder) + t)))) + +(defun elmo-imap4-delete-folder (spec) + (let ((process (elmo-imap4-get-process spec)) + msgs) + (when (elmo-imap4-spec-folder spec) + (when (setq msgs (elmo-imap4-list-folder spec)) + (elmo-imap4-delete-msgs spec msgs)) + (elmo-imap4-send-command (process-buffer process) process "close") + (elmo-imap4-read-response (process-buffer process) process) + (elmo-imap4-send-command (process-buffer process) + process + (format "delete %s" + (elmo-imap4-spec-folder spec))) + (if (null (elmo-imap4-read-response (process-buffer process) + process)) + (error "Delete folder %s failed" (elmo-imap4-spec-folder spec)) + t)))) + +(defun elmo-imap4-rename-folder (old-spec new-spec) + (let ((process (elmo-imap4-get-process old-spec))) + (when (elmo-imap4-spec-folder old-spec) + (elmo-imap4-send-command (process-buffer process) process "close") + (elmo-imap4-read-response (process-buffer process) process) + (elmo-imap4-send-command (process-buffer process) + process + (format "rename %s %s" + (elmo-imap4-spec-folder old-spec) + (elmo-imap4-spec-folder new-spec))) + (if (null (elmo-imap4-read-response (process-buffer process) process)) + (error "Rename folder from %s to %s failed" + (elmo-imap4-spec-folder old-spec) + (elmo-imap4-spec-folder new-spec)) + t)))) + +(defun elmo-imap4-max-of-folder (spec) + (save-excursion + (let* ((process (elmo-imap4-get-process spec)) + response) + (elmo-imap4-send-command (process-buffer process) + process + (format "status \"%s\" (uidnext messages)" + (elmo-imap4-spec-folder spec))) + (setq response (elmo-imap4-read-response (process-buffer process) + process)) + (when (and response (string-match + "\\* STATUS [^(]* \\(([^)]*)\\)" response)) + (setq response (read (downcase (elmo-match-string 1 response)))) + (cons (- (cadr (memq 'uidnext response)) 1) + (cadr (memq 'messages response))))))) + +(defun elmo-imap4-get-connection (spec) + (let* ((user (elmo-imap4-spec-username spec)) + (server (elmo-imap4-spec-hostname spec)) + (port (elmo-imap4-spec-port spec)) + (auth (elmo-imap4-spec-auth spec)) + (ssl (elmo-imap4-spec-ssl spec)) + (user-at-host (format "%s@%s" user server)) + ret-val result buffer process proc-stat + user-at-host-on-port) + (if (not (elmo-plugged-p server port)) + (error "Unplugged")) + (setq user-at-host-on-port + (concat user-at-host ":" (int-to-string port) + (if (eq ssl 'starttls) "!!" (if ssl "!")))) + (setq ret-val (assoc user-at-host-on-port + elmo-imap4-connection-cache)) + (if (and ret-val + (or (eq (setq proc-stat + (process-status (cadr (cdr ret-val)))) + 'closed) + (eq proc-stat 'exit))) + ;; connection is closed... + (progn + (kill-buffer (car (cdr ret-val))) + (setq elmo-imap4-connection-cache + (delete ret-val elmo-imap4-connection-cache)) + (setq ret-val nil))) + (if ret-val + (progn + (setq ret-val (cdr ret-val)) ;; connection cache exists. + ret-val) + (setq result + (elmo-imap4-open-connection server user auth port + (elmo-get-passwd user-at-host) + ssl)) + (if (null result) + (error "Connection failed")) + (elmo-imap4-debug "Connected to %s" user-at-host-on-port) + (setq buffer (car result)) + (setq process (cdr result)) + (when (and process (null buffer)) + (elmo-remove-passwd user-at-host) + (delete-process process) + (error "Login failed")) + (setq elmo-imap4-connection-cache + (append elmo-imap4-connection-cache + (list + (cons user-at-host-on-port + (setq ret-val (list buffer process + ""; current-folder.. + )))))) + ret-val))) + +(defun elmo-imap4-process-filter (process output) + (save-match-data + (with-current-buffer (process-buffer process) + (goto-char (point-max)) + (insert output) + (forward-line -1) + (beginning-of-line) + (if (looking-at (concat + "\\(^" + elmo-imap4-seq-prefix + (int-to-string elmo-imap4-seqno) + "\\|^\\* OK\\|^\\* BYE\\'\\|^\\+\\)[^\n]*\n\\'")) + (progn + (setq elmo-imap4-lock nil) ; unlock process buffer. + (elmo-imap4-debug "unlock(%d) %s" elmo-imap4-seqno output)) + (elmo-imap4-debug "continue(%d) %s" elmo-imap4-seqno output)) + (goto-char (point-max))))) + +(defun elmo-imap4-read-response (buffer process &optional not-command) + (save-excursion + (set-buffer buffer) + (let ((case-fold-search nil) + (response-string nil) + (response-continue t) + (return-value nil) + match-end) + (while response-continue + (goto-char elmo-imap4-read-point) + (while (not (search-forward "\r\n" nil t)) + (accept-process-output process) + (goto-char elmo-imap4-read-point)) + + (setq match-end (point)) + (setq response-string + (buffer-substring elmo-imap4-read-point (- match-end 2))) + (goto-char elmo-imap4-read-point) + (if (looking-at (format "%s[0-9]+ OK.*$\\|\\+.*$" + elmo-imap4-seq-prefix)) + (progn (setq response-continue nil) + (setq elmo-imap4-read-point match-end) + (setq return-value + (if return-value + (concat return-value "\n" response-string) + response-string))) + (if (looking-at (format "\\(. BYE.*\\|%s[0-9]+ \\(NO\\|BAD\\).*\\)$" + elmo-imap4-seq-prefix)) + (progn (setq response-continue nil) + (setq elmo-imap4-read-point match-end) + (elmo-imap4-debug "error response: %s" response-string) + (setq return-value nil)) + (setq elmo-imap4-read-point match-end) + (if not-command + (setq response-continue nil)) + (setq return-value + (if return-value + (concat return-value "\n" response-string) + response-string))) + (setq elmo-imap4-read-point match-end))) + return-value))) + +(defun elmo-imap4-read-contents (buffer process) + "Read OK response" + (save-excursion + (set-buffer buffer) + (let ((case-fold-search nil) + (response-string nil) + match-end) + (goto-char elmo-imap4-read-point) + (while (not (re-search-forward + (format "%s[0-9]+ \\(NO\\|BAD\\|OK\\).*$" + elmo-imap4-seq-prefix) + nil t)) + (accept-process-output process) + (goto-char elmo-imap4-read-point)) + (beginning-of-line) + (setq match-end (point)) + (setq response-string (buffer-substring + elmo-imap4-read-point match-end)) + (if (eq (length response-string) 0) + nil + response-string)))) + +(defun elmo-imap4-read-bytes (buffer process bytes) + (save-excursion + (set-buffer buffer) + (let ((case-fold-search nil) + (return-value nil) + start gc-message) + (setq start elmo-imap4-read-point);; starting point + (while (< (point-max) (+ start bytes)) + (accept-process-output process)) + (setq return-value (buffer-substring + start (+ start bytes))) + (setq return-value (elmo-delete-cr return-value)) + (setq elmo-imap4-read-point bytes) + return-value))) + +(defun elmo-imap4-read-body (buffer process bytes outbuf) + (let (start gc-message ret-val) + (with-current-buffer buffer + (setq start elmo-imap4-read-point) + (while (< (point-max) (+ start bytes)) + (accept-process-output process)) + (with-current-buffer outbuf + (erase-buffer) + (insert-buffer-substring buffer start (+ start bytes)) + (setq ret-val (elmo-delete-cr-get-content-type))) + (setq elmo-imap4-read-point (+ start bytes)) + ret-val))) + +(defun elmo-imap4-noop (connection) + (let ((buffer (car connection)) + (process (cadr connection))) + (save-excursion + (elmo-imap4-send-command buffer + process "noop") + (elmo-imap4-read-response buffer process)))) + +(defun elmo-imap4-commit (spec) + (save-excursion + (let ((connection (elmo-imap4-get-connection spec)) + response ret-val beg end) + (and (not (null (elmo-imap4-spec-folder spec))) + (if (not (string= (elmo-imap4-connection-get-cwf connection) + (elmo-imap4-spec-folder spec))) + (if (null (setq response + (elmo-imap4-select-folder + (elmo-imap4-spec-folder spec) + connection))) + (error "Select folder failed")) + (if elmo-imap4-use-select-to-update-status + (elmo-imap4-select-folder + (elmo-imap4-spec-folder spec) + connection) + (elmo-imap4-check connection))))))) + +(defun elmo-imap4-check (connection) + (let ((process (elmo-imap4-connection-get-process connection))) + (save-excursion + (elmo-imap4-send-command (process-buffer process) + process "check") + (elmo-imap4-read-response (process-buffer process) process)))) + +(defun elmo-imap4-select-folder (folder connection) + (let ((process (elmo-imap4-connection-get-process connection)) + response) + (save-excursion + (unwind-protect + (progn + (elmo-imap4-send-command (process-buffer process) + process (format "select \"%s\"" + folder)) + (setq response (elmo-imap4-read-response + (process-buffer process) process))) + (if (null response) + (progn + (setcar (cddr connection) nil) + (error "Select folder failed")) + (setcar (cddr connection) folder)))) + response)) + +(defun elmo-imap4-check-validity (spec validity-file) + "get uidvalidity value from server and compare it with validity-file." + (let* ((process (elmo-imap4-get-process spec)) + response) + (save-excursion + (elmo-imap4-send-command (process-buffer process) + process + (format "status \"%s\" (uidvalidity)" + (elmo-imap4-spec-folder spec))) + (setq response (elmo-imap4-read-response + (process-buffer process) process)) + (if (string-match "UIDVALIDITY \\([0-9]+\\)" response) + (string= (elmo-get-file-string validity-file) + (elmo-match-string 1 response)) + nil)))) + +(defun elmo-imap4-sync-validity (spec validity-file) + "get uidvalidity value from server and save it to validity-file." + (let* ((process (elmo-imap4-get-process spec)) + response) + (save-excursion + (elmo-imap4-send-command (process-buffer process) + process + (format "status \"%s\" (uidvalidity)" + (elmo-imap4-spec-folder spec))) + (setq response (elmo-imap4-read-response + (process-buffer process) process)) + (if (string-match "UIDVALIDITY \\([0-9]+\\)" response) + (progn + (elmo-save-string + (elmo-match-string 1 response) + validity-file) + t) + nil)))) + +(defsubst elmo-imap4-list (spec str) + (save-excursion + (let* ((connection (elmo-imap4-get-connection spec)) + (process (elmo-imap4-connection-get-process connection)) + response ret-val beg end) + (and (elmo-imap4-spec-folder spec) + (if (not (string= (elmo-imap4-connection-get-cwf connection) + (elmo-imap4-spec-folder spec))) + (if (null (setq response + (elmo-imap4-select-folder + (elmo-imap4-spec-folder spec) + connection))) + (error "Select folder failed")) + ;; for status update. + (if elmo-imap4-use-select-to-update-status + (elmo-imap4-select-folder (elmo-imap4-spec-folder spec) + connection) + (unless (elmo-imap4-check connection) + ;; Check failed...not selected?? + (elmo-imap4-select-folder (elmo-imap4-spec-folder spec) + connection))))) + (elmo-imap4-send-command (process-buffer process) + process + (format (if elmo-imap4-use-uid + "uid search %s" + "search %s") str)) + (setq response (elmo-imap4-read-response (process-buffer process) + process)) + (if (and response (string-match "\\* SEARCH" response)) + (progn + (setq response (substring response (match-end 0))) + (if (string-match "\n" response) + (progn + (setq end (match-end 0)) + (setq ret-val (read (concat "(" (substring + response + 0 end) ")")))) + (error "SEARCH failed")))) + ret-val))) + +(defun elmo-imap4-list-folder (spec) + (elmo-imap4-list spec "all")) + +(defun elmo-imap4-list-folder-unread (spec mark-alist unread-marks) + (if (elmo-imap4-use-flag-p spec) + (elmo-imap4-list spec "unseen") + (elmo-generic-list-folder-unread spec mark-alist unread-marks))) + +(defun elmo-imap4-list-folder-important (spec overview) + (and (elmo-imap4-use-flag-p spec) + (elmo-imap4-list spec "flagged"))) + +(defun elmo-imap4-search-internal (process buffer filter) + (let ((search-key (elmo-filter-key filter)) + word response) + (cond + ((or (string= "since" search-key) + (string= "before" search-key)) + (setq search-key (concat "sent" search-key)) + (elmo-imap4-send-command buffer process + (format + (if elmo-imap4-use-uid + "uid search %s %s" + " search %s %s") + search-key + (elmo-date-get-description + (elmo-date-get-datevec + (elmo-filter-value filter)))))) + (t + (setq word (encode-mime-charset-string (elmo-filter-value filter) + elmo-search-mime-charset)) + (elmo-imap4-send-command buffer process + (format + (if elmo-imap4-use-uid + "uid search CHARSET %s%s %s {%d}" + " search CHARSET %s%s %s {%d}") + (symbol-name elmo-search-mime-charset) + (if (eq (elmo-filter-type filter) 'unmatch) + " not" "") + (elmo-filter-key filter) + (length word))) + (if (null (elmo-imap4-read-response buffer process t)) + (error "Searching failed because of server capability??")) + (elmo-imap4-send-string buffer process word))) + (if (null (setq response (elmo-imap4-read-response buffer process))) + (error "Search failed for %s" (elmo-filter-key filter))) + (if (string-match "^\\* SEARCH\\([^\n]*\\)$" response) + (read (concat "(" (elmo-match-string 1 response) ")")) + (error "SEARCH failed")))) + +(defun elmo-imap4-search (spec condition &optional from-msgs) + (save-excursion + (let* ((connection (elmo-imap4-get-connection spec)) + (process (elmo-imap4-connection-get-process connection)) + response ret-val len word) + (if (and (elmo-imap4-spec-folder spec) + (not (string= (elmo-imap4-connection-get-cwf connection) + (elmo-imap4-spec-folder spec))) + (null (elmo-imap4-select-folder + (elmo-imap4-spec-folder spec) connection))) + (error "Select folder failed")) + (while condition + (setq response (elmo-imap4-search-internal process + (process-buffer process) + (car condition))) + (setq ret-val (nconc ret-val response)) + (setq condition (cdr condition))) + (if from-msgs + (elmo-list-filter + from-msgs + (elmo-uniq-list (sort ret-val '<))) + (elmo-uniq-list (sort ret-val '<)))))) + +(defsubst elmo-imap4-value (value) + (if (eq value 'NIL) nil + value)) + +(defmacro elmo-imap4-nth (pos list) + (` (let ((value (nth (, pos) (, list)))) + (if (eq 'NIL value) + nil + value)))) + +(defun elmo-imap4-use-flag-p (spec) + (not (string-match elmo-imap4-disuse-server-flag-mailbox-regexp + (elmo-imap4-spec-folder spec)))) + +(defsubst elmo-imap4-make-address (name mbox host) + (cond (name + (concat name " <" mbox "@" host ">")) + (t + (concat mbox "@" host)))) + +(static-cond + ((fboundp 'float) + ;; Emacs can parse dot symbol. + (defvar elmo-imap4-rfc822-size "RFC822\.SIZE") + (defvar elmo-imap4-header-fields "HEADER\.FIELDS") + (defmacro elmo-imap4-replace-dot-symbols ()) ;; noop + ) + (t + ;; Cannot parse dot symbol, replace it. + (defvar elmo-imap4-rfc822-size "RFC822_SIZE") + (defvar elmo-imap4-header-fields "HEADER_FIELDS") + (defmacro elmo-imap4-replace-dot-symbols () + (goto-char (point-min)) + (while (re-search-forward "RFC822\\.SIZE" nil t) + (replace-match elmo-imap4-rfc822-size)) + (goto-char (point-min)) + (while (re-search-forward "HEADER\\.FIELDS" nil t) + (replace-match elmo-imap4-header-fields)) + (goto-char (point-min))))) + +(defsubst elmo-imap4-make-attributes-object (string) + (save-match-data + (elmo-set-work-buf + (elmo-set-buffer-multibyte nil) + (insert string) + (goto-char (point-min)) + (let ((case-fold-search t)) + (goto-char (point-min)) + (while (re-search-forward "{\\([0-9]+\\)}\r\n" nil t) + (let (str) + (goto-char (+ (point) + (string-to-int (elmo-match-buffer 1)))) + (setq str (save-match-data + (elmo-replace-in-string + (buffer-substring (match-end 0) (point)) + "\r" ""))) + (delete-region (match-beginning 0) (point)) + (insert (prin1-to-string str)))) + (goto-char (point-min)) + (elmo-imap4-replace-dot-symbols) + (read (current-buffer)))))) + + +(defun elmo-imap4-parse-overview-string (string) + (if (null string) + (error "Getting overview failed")) + (with-temp-buffer + (let (ret-val beg attr number) + (elmo-set-buffer-multibyte nil) + (insert string) + (goto-char (point-min)) + (setq beg (point)) + (if (re-search-forward "^\* \\([0-9]+\\) FETCH" + nil t) + (progn + (setq beg (point)) + (unless elmo-imap4-use-uid + (setq number (string-to-int (elmo-match-buffer 1)))) + (while (re-search-forward + "^\* \\([0-9]+\\) FETCH" + nil t) + (setq attr (elmo-imap4-make-attributes-object + (buffer-substring beg (match-beginning 0)))) + (setq beg (point)) + (unless elmo-imap4-use-uid + (setq attr(nconc (list 'UID number) attr)) + (setq number (string-to-int (elmo-match-buffer 1)))) + (setq ret-val (cons attr ret-val))) + ;; process last one... + (setq attr (elmo-imap4-make-attributes-object + (buffer-substring beg (point-max)))) + (unless elmo-imap4-use-uid + (setq attr(nconc (list 'UID number) attr))) + (setq ret-val (cons attr ret-val)))) + (nreverse ret-val)))) + +(defun elmo-imap4-create-msgdb-from-overview-string (str + folder + new-mark + already-mark + seen-mark + important-mark + seen-list + &optional numlist) + (let ((case-fold-search t) + (size-sym (intern elmo-imap4-rfc822-size)) + overview attr-list attr pair section + number important message-id from-list from-string + to-string cc-string + number-alist mark-alist + reference subject date-string size flags gmark seen + index extras extra-fields sym value) + (setq attr-list (elmo-imap4-parse-overview-string str)) + (while attr-list + (setq attr (car attr-list)) + ;; Remove section data. (origin octed is not considered.(OK?)) + (setq section (cadr (memq 'BODY attr))) + (if (vectorp section) + (delq section attr)) + ;; number + (setq number (cadr (memq 'UID attr))) + (when (or (null numlist) + (memq number numlist)) + (while attr + (setq sym (car attr)) + (setq value (cadr attr)) + (setq attr (cdr (cdr attr))) + (cond + ((eq sym 'UID)) + ;; noop + ((eq sym 'FLAGS) + (setq flags value)) + ((eq sym size-sym) + (setq size value)) + ((eq sym 'BODY) + (setq extra-fields (elmo-collect-field-from-string value t))) + ((eq sym 'ENVELOPE) + ;; According to rfc2060, + ;; 0 date, 1 subject, 2 from, 3 sender, + ;; 4 reply-to, 5 to, 6 cc, 7 bcc, 8 in-reply-to, 9 message-id. + (setq date-string (elmo-imap4-nth 0 value)) + (setq subject (elmo-mime-string (or (elmo-imap4-nth 1 value) + elmo-no-subject))) + (setq from-list (car (elmo-imap4-nth 2 value))) + (setq from-string (or + (and (or (elmo-imap4-nth 0 from-list) + (elmo-imap4-nth 2 from-list) + (elmo-imap4-nth 3 from-list)) + (elmo-delete-char + ?\" + (elmo-imap4-make-address + (elmo-imap4-nth 0 from-list) + (elmo-imap4-nth 2 from-list) + (elmo-imap4-nth 3 from-list)) + 'uni)) + elmo-no-from)) + (setq to-string (mapconcat + '(lambda (to) + (elmo-imap4-make-address + (elmo-imap4-nth 0 to) + (elmo-imap4-nth 2 to) + (elmo-imap4-nth 3 to))) + (elmo-imap4-nth 5 value) ",")) + (setq cc-string (mapconcat + '(lambda (cc) + (elmo-imap4-make-address + (elmo-imap4-nth 0 cc) + (elmo-imap4-nth 2 cc) + (elmo-imap4-nth 3 cc))) + (elmo-imap4-nth 6 value) ",")) + (setq reference (elmo-msgdb-get-last-message-id + (elmo-imap4-nth 8 value))) + (setq message-id (elmo-imap4-nth 9 value))))) + (when (setq pair (assoc "references" extra-fields)) + (setq extra-fields (delq pair extra-fields))) + (unless reference + (setq reference (elmo-msgdb-get-last-message-id (cdr pair)))) + (setq overview + (elmo-msgdb-append-element + overview + (cons message-id + (vector number + reference + (elmo-mime-string from-string) + (elmo-mime-string subject) + date-string + to-string + cc-string + size + extra-fields)))) + (if (memq 'Flagged flags) + (elmo-msgdb-global-mark-set message-id important-mark)) + (setq number-alist + (elmo-msgdb-number-add number-alist number message-id)) + (setq seen (member message-id seen-list)) + (if (setq gmark (or (elmo-msgdb-global-mark-get message-id) + (if (elmo-cache-exists-p message-id) ;; XXX + (if (or (memq 'Seen flags) seen) + nil + already-mark) + (if (or (memq 'Seen flags) seen) + (if elmo-imap4-use-cache + seen-mark) + new-mark)))) + (setq mark-alist (elmo-msgdb-mark-append + mark-alist + number + ;; managing mark with message-id is evil. + gmark)))) + (setq attr-list (cdr attr-list))) + (list overview number-alist mark-alist))) + +(defun elmo-imap4-add-to-cont-list (cont-list msg) + (let ((elist cont-list) + (ret-val cont-list) + entity found) + (while (and elist (not found)) + (setq entity (car elist)) + (cond + ((and (consp entity) + (eq (+ 1 (cdr entity)) msg)) + (setcdr entity msg) + (setq found t)) + ((and (integerp entity) + (eq (+ 1 entity) msg)) + (setcar elist (cons entity msg)) + (setq found t)) + ((or (and (integerp entity) (eq entity msg)) + (and (consp entity) + (<= (car entity) msg) + (<= msg (cdr entity)))) ; included + (setq found t))); noop + (setq elist (cdr elist))) + (if (not found) + (setq ret-val (append cont-list (list msg)))) + ret-val)) + +(defun elmo-imap4-make-number-set-list (msg-list &optional chop-length) + "Make RFC2060's message set specifier from MSG-LIST. +Returns a list of (NUMBER . SET-STRING). +SET-STRING is the message set specifier described in RFC2060. +NUMBER is contained message number in SET-STRING. +Every SET-STRING does not contain number of messages longer than CHOP-LENGTH. +If CHOP-LENGTH is not specified, message set is not chopped." + (let (count cont-list set-list) + (setq msg-list (sort msg-list '<)) + (while msg-list + (setq cont-list nil) + (setq count 0) + (unless chop-length + (setq chop-length (length msg-list))) + (while (and (not (null msg-list)) + (< count chop-length)) + (setq cont-list + (elmo-imap4-add-to-cont-list + cont-list (car msg-list))) + (incf count) + (setq msg-list (cdr msg-list))) + (setq set-list + (cons + (cons + count + (mapconcat + (lambda (x) + (cond ((consp x) + (format "%s:%s" (car x) (cdr x))) + ((integerp x) + (int-to-string x)))) + cont-list + ",")) + set-list))) + (nreverse set-list))) + +;; +;; set mark +;; read-mark -> "\\Seen" +;; important -> "\\Flagged" +;; +;; (delete -> \\Deleted) +(defun elmo-imap4-mark-set-on-msgs (spec msgs mark &optional unmark no-expunge) + "SET flag of MSGS as MARK. +If optional argument UNMARK is non-nil, unmark." + (save-excursion + (let* ((connection (elmo-imap4-get-connection spec)) + (process (elmo-imap4-connection-get-process connection)) + (msg-list (copy-sequence msgs)) + set-list ent) + (if (and (elmo-imap4-spec-folder spec) + (not (string= (elmo-imap4-connection-get-cwf connection) + (elmo-imap4-spec-folder spec))) + (null (elmo-imap4-select-folder + (elmo-imap4-spec-folder spec) connection))) + (error "Select folder failed")) + (setq set-list (elmo-imap4-make-number-set-list msg-list)) + (when set-list + (elmo-imap4-send-command (process-buffer process) + process + (format + (if elmo-imap4-use-uid + "uid store %s %sflags.silent (%s)" + "store %s %sflags.silent (%s)") + (cdr (car set-list)) + (if unmark "-" "+") + mark)) + (unless (elmo-imap4-read-response (process-buffer process) process) + (error "Store %s flag failed" mark)) + (unless no-expunge + (elmo-imap4-send-command + (process-buffer process) process "expunge") + (unless (elmo-imap4-read-response (process-buffer process) process) + (error "Expunge failed")))) + t))) + +(defun elmo-imap4-mark-as-important (spec msgs) + (and (elmo-imap4-use-flag-p spec) + (elmo-imap4-mark-set-on-msgs spec msgs "\\Flagged" nil 'no-expunge))) + +(defun elmo-imap4-mark-as-read (spec msgs) + (and (elmo-imap4-use-flag-p spec) + (elmo-imap4-mark-set-on-msgs spec msgs "\\Seen" nil 'no-expunge))) + +(defun elmo-imap4-unmark-important (spec msgs) + (and (elmo-imap4-use-flag-p spec) + (elmo-imap4-mark-set-on-msgs spec msgs "\\Flagged" 'unmark + 'no-expunge))) + +(defun elmo-imap4-mark-as-unread (spec msgs) + (and (elmo-imap4-use-flag-p spec) + (elmo-imap4-mark-set-on-msgs spec msgs "\\Seen" 'unmark 'no-expunge))) + +(defun elmo-imap4-delete-msgs (spec msgs) + (elmo-imap4-mark-set-on-msgs spec msgs "\\Deleted")) + +(defun elmo-imap4-delete-msgs-no-expunge (spec msgs) + (elmo-imap4-mark-set-on-msgs spec msgs "\\Deleted" nil 'no-expunge)) + +(defun elmo-imap4-msgdb-create-as-numlist (spec numlist new-mark already-mark + seen-mark important-mark + seen-list) + "Create msgdb for SPEC for NUMLIST." + (elmo-imap4-msgdb-create spec numlist new-mark already-mark + seen-mark important-mark seen-list t)) + +(defun elmo-imap4-msgdb-create (spec numlist new-mark already-mark seen-mark + important-mark seen-list &optional as-num) + "Create msgdb for SPEC." + (when numlist + (save-excursion + (let* ((connection (elmo-imap4-get-connection spec)) + (process (elmo-imap4-connection-get-process connection)) + (filter (and as-num numlist)) + (case-fold-search t) + (extra-fields (if elmo-msgdb-extra-fields + (concat " " (mapconcat + 'identity + elmo-msgdb-extra-fields " ")) + "")) + rfc2060 count ret-val set-list ov-str length) + (setq rfc2060 (with-current-buffer (process-buffer process) + (if (memq 'imap4rev1 elmo-imap4-server-capability) + t + (if (memq 'imap4 elmo-imap4-server-capability) + nil + (error "No IMAP4 capability!!"))))) + (setq count 0) + (setq length (length numlist)) + (setq set-list (elmo-imap4-make-number-set-list + numlist + elmo-imap4-overview-fetch-chop-length)) + (message "Getting overview...") + (if (and (elmo-imap4-spec-folder spec) + (not (string= (elmo-imap4-connection-get-cwf connection) + (elmo-imap4-spec-folder spec))) + (null (elmo-imap4-select-folder + (elmo-imap4-spec-folder spec) connection))) + (error "Select imap folder %s failed" + (elmo-imap4-spec-folder spec))) + (while set-list + (elmo-imap4-send-command + (process-buffer process) + process + ;; get overview entity from IMAP4 + (format + (if rfc2060 + (concat + (if elmo-imap4-use-uid "uid " "") + "fetch %s (envelope body.peek[header.fields (references" + extra-fields + ")] rfc822.size flags)") + (concat + (if elmo-imap4-use-uid "uid " "") + "fetch %s (envelope rfc822.size flags)")) + (cdr (car set-list)))) + ;; process string while waiting for response + (with-current-buffer (process-buffer process) + (if ov-str + (setq ret-val + (elmo-msgdb-append + ret-val + (elmo-imap4-create-msgdb-from-overview-string + ov-str + (elmo-imap4-spec-folder spec) + new-mark already-mark seen-mark important-mark + seen-list filter))))) + (setq count (+ count (car (car set-list)))) + (setq ov-str (elmo-imap4-read-contents (process-buffer process) + process)) + (elmo-display-progress + 'elmo-imap4-msgdb-create "Getting overview..." + (/ (* count 100) length)) + (setq set-list (cdr set-list))) + ;; process last one. + (with-current-buffer (process-buffer process) + (if ov-str + (setq ret-val + (elmo-msgdb-append + ret-val + (elmo-imap4-create-msgdb-from-overview-string + ov-str + (elmo-imap4-spec-folder spec) + new-mark already-mark seen-mark important-mark + seen-list filter))))) + (message "Getting overview...done.") + ret-val)))) + +(defun elmo-imap4-parse-response (string) + (if (string-match "^\\*\\(.*\\)$" string) + (read (concat "(" (elmo-match-string 1 string) ")")))) + +(defun elmo-imap4-parse-capability (string) + (if (string-match "^\\*\\(.*\\)$" string) + (read (concat "(" (downcase (elmo-match-string 1 string)) ")")))) + +(defun elmo-imap4-parse-namespace (obj) + (let ((ns (cdr obj)) + (i 0) + prefix delim + cur namespace-alist) + ;; 0: personal, 1: other, 2: shared + (while (< i 3) + (setq cur (elmo-imap4-nth i ns)) + (incf i) + (while cur + (setq prefix (elmo-imap4-nth 0 (car cur))) + (setq delim (elmo-imap4-nth 1 (car cur))) + (if (and prefix delim + (string-match (concat "\\(.*\\)" + (regexp-quote delim) + "\\'") + prefix)) + (setq prefix (substring prefix (match-beginning 1)(match-end 1)))) + (setq namespace-alist (nconc namespace-alist + (list (cons + (concat "^" (regexp-quote prefix) + ".*$") + delim)))) + (setq cur (cdr cur)))) + (append + elmo-imap4-extra-namespace-alist + (sort namespace-alist + '(lambda (x y) + (> (length (car x)) + (length (car y)))))))) + +(defun elmo-imap4-open-connection (imap4-server user auth port passphrase ssl) + "Open Imap connection and returns +the list of (process session-buffer current-working-folder). +Return nil if connection failed." + (let ((process nil) + (host imap4-server) + process-buffer ret-val response capability) + (catch 'done + (as-binary-process + (setq process-buffer + (get-buffer-create (format " *IMAP session to %s:%d" host port))) + (save-excursion + (set-buffer process-buffer) + (elmo-set-buffer-multibyte nil) + (make-variable-buffer-local 'elmo-imap4-server-capability) + (make-variable-buffer-local 'elmo-imap4-lock) + (erase-buffer)) + (setq process + (elmo-open-network-stream "IMAP" process-buffer host port ssl)) + (and (null process) (throw 'done nil)) + (set-process-filter process 'elmo-imap4-process-filter) + ;; flush connections when exiting... + (save-excursion + (set-buffer process-buffer) + (make-local-variable 'elmo-imap4-read-point) + (setq elmo-imap4-read-point (point-min)) + (if (null (setq response + (elmo-imap4-read-response process-buffer process t))) + (throw 'done nil) + (when (string-match "^\\* PREAUTH" response) + (setq ret-val (cons process-buffer process)) + (throw 'done nil))) + (elmo-imap4-send-command process-buffer process "capability") + (setq elmo-imap4-server-capability + (elmo-imap4-parse-capability + (elmo-imap4-read-response process-buffer process))) + (setq capability elmo-imap4-server-capability) + (if (eq ssl 'starttls) + (if (and (memq 'starttls capability) + (progn + (elmo-imap4-send-command process-buffer process "starttls") + (setq response + (elmo-imap4-read-response process-buffer process))) + + (string-match + (concat "^\\(" elmo-imap4-seq-prefix + (int-to-string elmo-imap4-seqno) + "\\|\\*\\) OK") + response)) + (starttls-negotiate process) + (error "STARTTLS aborted"))) + (if (or (and (string= "auth" auth) + (not (memq 'auth=login capability))) + (and (string= "cram-md5" auth) + (not (memq 'auth=cram-md5 capability))) + (and (string= "digest-md5" auth) + (not (memq 'auth=digest-md5 capability)))) + (if (or elmo-imap4-force-login + (y-or-n-p + (format + "There's no %s capability in server. continue?" auth))) + (setq auth "login") + (error "Login aborted"))) + (cond + ((string= "auth" auth) + (elmo-imap4-send-command + process-buffer process "authenticate login" 'no-lock) + ;; Base64 + (when (null (elmo-imap4-read-response process-buffer process t)) + (setq ret-val (cons nil process)) + (throw 'done nil)) + (elmo-imap4-send-string + process-buffer process (elmo-base64-encode-string user)) + (when (null (elmo-imap4-read-response process-buffer process t)) + (setq ret-val (cons nil process)) + (throw 'done nil)) + (elmo-imap4-send-string + process-buffer process (elmo-base64-encode-string passphrase)) + (when (null (elmo-imap4-read-response process-buffer process)) + (setq ret-val (cons nil process)) + (throw 'done nil)) + (setq ret-val (cons process-buffer process))) + ((string= "cram-md5" auth) + (elmo-imap4-send-command + process-buffer process "authenticate cram-md5" 'no-lock) + (when (null (setq response + (elmo-imap4-read-response + process-buffer process t))) + (setq ret-val (cons nil process)) + (throw 'done nil)) + (setq response (cadr (split-string response " "))) + (elmo-imap4-send-string + process-buffer process + (elmo-base64-encode-string + (sasl-cram-md5 user passphrase + (elmo-base64-decode-string response)))) + (when (null (elmo-imap4-read-response process-buffer process)) + (setq ret-val (cons nil process)) + (throw 'done nil)) + (setq ret-val (cons process-buffer process))) + ((string= "digest-md5" auth) + (elmo-imap4-send-command + process-buffer process "authenticate digest-md5" 'no-lock) + (when (null (setq response + (elmo-imap4-read-response + process-buffer process t))) + (setq ret-val (cons nil process)) + (throw 'done nil)) + (setq response (cadr (split-string response " "))) + (elmo-imap4-send-string + process-buffer process + (elmo-base64-encode-string + (sasl-digest-md5-digest-response + (elmo-base64-decode-string response) + user passphrase "imap" host) + 'no-line-break)) + (when (null (elmo-imap4-read-response + process-buffer process t)) + (setq ret-val (cons nil process)) + (throw 'done nil)) + (elmo-imap4-send-string process-buffer process "") + (when (null (elmo-imap4-read-response process-buffer process)) + (setq ret-val (cons nil process)) + (throw 'done nil)) + (setq ret-val (cons process-buffer process))) + (t ;; not auth... try login + (elmo-imap4-send-command + process-buffer process + (format "login %s \"%s\"" user + (elmo-replace-in-string passphrase + "\"" "\\\\\"")) + nil 'no-log) ;; No LOGGING. + (if (null (elmo-imap4-read-response process-buffer process)) + (setq ret-val (cons nil process)) + (setq ret-val (cons process-buffer process))))) + ;; get namespace of server if possible. + (when (memq 'namespace elmo-imap4-server-capability) + (elmo-imap4-send-command process-buffer process "namespace") + (setq elmo-imap4-server-namespace + (elmo-imap4-parse-namespace + (elmo-imap4-parse-response + (elmo-imap4-read-response process-buffer process)))))))) + ret-val)) + +(defun elmo-imap4-get-seqno () + (setq elmo-imap4-seqno (+ 1 elmo-imap4-seqno))) + +(defun elmo-imap4-setup-send-buffer (string) + (let ((tmp-buf (get-buffer-create " *elmo-imap4-setup-send-buffer*"))) + (save-excursion + (save-match-data + (set-buffer tmp-buf) + (erase-buffer) + (elmo-set-buffer-multibyte nil) + (insert string) + (goto-char (point-min)) + (if (eq (re-search-forward "^$" nil t) + (point-max)) + (insert "\n")) + (goto-char (point-min)) + (while (search-forward "\n" nil t) + (replace-match "\r\n")))) + tmp-buf)) + +(defun elmo-imap4-send-command (buffer process command &optional no-lock + no-log) + "Send COMMAND string to server with sequence number." + (save-excursion + (set-buffer buffer) + (when (and elmo-imap4-use-lock + elmo-imap4-lock) + (elmo-imap4-debug "send: (%d) is still locking." elmo-imap4-seqno) + (error "IMAP4 process is locked; Please try later (or plug again)")) + (erase-buffer) + (goto-char (point-min)) + (setq elmo-imap4-read-point (point)) + (unless no-lock + ;; for debug. + (if no-log + (elmo-imap4-debug "lock(%d): (No-logging command)." (+ elmo-imap4-seqno 1)) + (elmo-imap4-debug "lock(%d): %s" (+ elmo-imap4-seqno 1) command)) + (setq elmo-imap4-lock t)) + (process-send-string process (concat (format "%s%d " + elmo-imap4-seq-prefix + (elmo-imap4-get-seqno)) + command)) + (process-send-string process "\r\n"))) + +(defun elmo-imap4-send-string (buffer process string) + "Send STRING to server." + (save-excursion + (set-buffer buffer) + (erase-buffer) + (goto-char (point-min)) + (setq elmo-imap4-read-point (point)) + (process-send-string process string) + (process-send-string process "\r\n"))) + +(defun elmo-imap4-read-part (folder msg part) + (save-excursion + (let* ((spec (elmo-folder-get-spec folder)) + (connection (elmo-imap4-get-connection spec)) + (process (elmo-imap4-connection-get-process connection)) + response ret-val bytes) + (when (elmo-imap4-spec-folder spec) + (when (not (string= (elmo-imap4-connection-get-cwf connection) + (elmo-imap4-spec-folder spec))) + (if (null (setq response + (elmo-imap4-select-folder + (elmo-imap4-spec-folder spec) connection))) + (error "Select folder failed"))) + (elmo-imap4-send-command (process-buffer process) + process + (format + (if elmo-imap4-use-uid + "uid fetch %s body.peek[%s]" + "fetch %s body.peek[%s]") + msg part)) + (if (null (setq response (elmo-imap4-read-response + (process-buffer process) + process t))) + (error "Fetch failed")) + (save-match-data + (while (string-match "^\\* OK" response) + (if (null (setq response (elmo-imap4-read-response + (process-buffer process) + process t))) + (error "Fetch failed")))) + (save-match-data + (if (string-match ".*{\\([0-9]+\\)}" response) + (setq bytes + (string-to-int + (elmo-match-string 1 response))) + (error "Fetch failed"))) + (if (null (setq response (elmo-imap4-read-bytes + (process-buffer process) process bytes))) + (error "Fetch message failed")) + (setq ret-val response) + (elmo-imap4-read-response (process-buffer process) + process)) ;; ignore remaining.. + ret-val))) + +(defun elmo-imap4-prefetch-msg (spec msg outbuf) + (elmo-imap4-read-msg spec msg outbuf 'unseen)) + +(defun elmo-imap4-read-msg (spec msg outbuf + &optional leave-seen-flag-untouched) + (save-excursion + (let* ((connection (elmo-imap4-get-connection spec)) + (process (elmo-imap4-connection-get-process connection)) + response ret-val bytes) + (as-binary-process + (when (elmo-imap4-spec-folder spec) + (when (not (string= (elmo-imap4-connection-get-cwf connection) + (elmo-imap4-spec-folder spec))) + (if (null (setq response + (elmo-imap4-select-folder + (elmo-imap4-spec-folder spec) + connection))) + (error "Select folder failed"))) + (elmo-imap4-send-command (process-buffer process) + process + (format + (if elmo-imap4-use-uid + "uid fetch %s body%s[]" + "fetch %s body%s[]") + msg + (if leave-seen-flag-untouched + ".peek" ""))) + (if (null (setq response (elmo-imap4-read-response + (process-buffer process) + process t))) + (error "Fetch failed")) + (save-match-data + (while (string-match "^\\* OK" response) + (if (null (setq response (elmo-imap4-read-response + (process-buffer process) + process t))) + (error "Fetch failed")))) + (save-match-data + (if (string-match ".*{\\([0-9]+\\)}" response) + (setq bytes + (string-to-int + (elmo-match-string 1 response))) + (error "Fetch failed"))) + (setq ret-val (elmo-imap4-read-body + (process-buffer process) + process bytes outbuf)) + (elmo-imap4-read-response (process-buffer process) + process)) ;; ignore remaining.. + ) + ret-val))) + +(defun elmo-imap4-setup-send-buffer-from-file (file) + (let ((tmp-buf (get-buffer-create + " *elmo-imap4-setup-send-buffer-from-file*"))) + (save-excursion + (save-match-data + (set-buffer tmp-buf) + (erase-buffer) + (as-binary-input-file + (insert-file-contents file)) + (goto-char (point-min)) + (if (eq (re-search-forward "^$" nil t) + (point-max)) + (insert "\n")) + (goto-char (point-min)) + (while (search-forward "\n" nil t) + (replace-match "\r\n")))) + tmp-buf)) + +(defun elmo-imap4-delete-msgids (spec msgids) + "If actual message-id is matched, then delete it." + (let ((message-ids msgids) + (i 0) + (num (length msgids))) + (while message-ids + (setq i (+ 1 i)) + (message "Deleting message...%d/%d" i num) + (elmo-imap4-delete-msg-by-id spec (car message-ids)) + (setq message-ids (cdr message-ids))) + (let* ((connection (elmo-imap4-get-connection spec)) + (process (elmo-imap4-connection-get-process connection))) + (elmo-imap4-send-command (process-buffer process) + process "expunge") + (if (null (elmo-imap4-read-response (process-buffer process) + process)) + (error "Expunge failed"))))) + +(defun elmo-imap4-delete-msg-by-id (spec msgid) + (save-excursion + (let* ((connection (elmo-imap4-get-connection spec)) + (process (elmo-imap4-connection-get-process connection)) + ;;(size (length string)) + response msgs) + (if (and (elmo-imap4-spec-folder spec) + (not (string= (elmo-imap4-connection-get-cwf connection) + (elmo-imap4-spec-folder spec))) + (null (elmo-imap4-select-folder + (elmo-imap4-spec-folder spec) + connection))) + (error "Select folder failed")) + (save-excursion + (elmo-imap4-send-command (process-buffer process) + process + (format + (if elmo-imap4-use-uid + "uid search header message-id \"%s\"" + "search header message-id \"%s\"") + msgid)) + (setq response (elmo-imap4-read-response + (process-buffer process) process)) + (if (and response + (string-match "^\\* SEARCH\\([^\n]*\\)$" response)) + (setq msgs (read (concat "(" (elmo-match-string 1 response) ")"))) + (error "SEARCH failed")) + (elmo-imap4-delete-msgs-no-expunge spec msgs))))) + +(defun elmo-imap4-append-msg-by-id (spec msgid) + (save-excursion + (let* ((connection (elmo-imap4-get-connection spec)) + (process (elmo-imap4-connection-get-process connection)) + send-buf) + (if (and (elmo-imap4-spec-folder spec) + (not (string= (elmo-imap4-connection-get-cwf connection) + (elmo-imap4-spec-folder spec))) + (null (elmo-imap4-select-folder + (elmo-imap4-spec-folder spec) connection))) + (error "Select folder failed")) + (save-excursion + (setq send-buf (elmo-imap4-setup-send-buffer-from-file + (elmo-cache-get-path msgid))) + (set-buffer send-buf) + (elmo-imap4-send-command (process-buffer process) + process + (format "append %s (\\Seen) {%d}" + (elmo-imap4-spec-folder spec) + (buffer-size))) + (process-send-string process (buffer-string)) + (process-send-string process "\r\n") ; finished appending. + ) + (kill-buffer send-buf) + (if (null (elmo-imap4-read-response (process-buffer process) + process)) + (error "Append failed"))) + t)) + +(defun elmo-imap4-append-msg (spec string &optional msg no-see) + (save-excursion + (let* ((connection (elmo-imap4-get-connection spec)) + (process (elmo-imap4-connection-get-process connection)) + send-buf) + (if (and (elmo-imap4-spec-folder spec) + (not (string= (elmo-imap4-connection-get-cwf connection) + (elmo-imap4-spec-folder spec))) + (null (elmo-imap4-select-folder (elmo-imap4-spec-folder spec) + connection))) + (error "Select folder failed")) + (save-excursion + (setq send-buf (elmo-imap4-setup-send-buffer string)) + (set-buffer send-buf) + (elmo-imap4-send-command (process-buffer process) + process + (format "append %s %s{%d}" + (elmo-imap4-spec-folder spec) + (if no-see "" "(\\Seen) ") + (buffer-size))) + (if (null (elmo-imap4-read-response (process-buffer process) + process)) + (error "Cannot append messages to this folder")) + (process-send-string process (buffer-string)) + (process-send-string process "\r\n") ; finished appending. + ) + (kill-buffer send-buf) + (current-buffer) + (if (null (elmo-imap4-read-response (process-buffer process) + process)) + (error "Append failed"))) + t)) + +(defun elmo-imap4-copy-msgs (dst-spec msgs src-spec &optional expunge-it same-number) + "Equivalence of hostname, username is assumed." + (save-excursion + (let* ((src-folder (elmo-imap4-spec-folder src-spec)) + (dst-folder (elmo-imap4-spec-folder dst-spec)) + (connection (elmo-imap4-get-connection src-spec)) + (process (elmo-imap4-connection-get-process connection)) + (mlist msgs)) + (if (and src-folder + (not (string= (elmo-imap4-connection-get-cwf connection) + src-folder)) + (null (elmo-imap4-select-folder + src-folder connection))) + (error "Select folder failed")) + (while mlist + (elmo-imap4-send-command (process-buffer process) + process + (format + (if elmo-imap4-use-uid + "uid copy %s %s" + "copy %s %s") + (car mlist) dst-folder)) + (if (null (elmo-imap4-read-response (process-buffer process) + process)) + (error "Copy failed") + (setq mlist (cdr mlist)))) + (when expunge-it + (elmo-imap4-send-command (process-buffer process) + process "expunge") + (if (null (elmo-imap4-read-response (process-buffer process) + process)) + (error "Expunge failed"))) + t))) + +(defun elmo-imap4-server-diff (spec) + "get server status" + (save-excursion + (let* ((connection (elmo-imap4-get-connection spec)) + (process (elmo-imap4-connection-get-process connection)) + response) + ;; commit when same folder. + (if (string= (elmo-imap4-connection-get-cwf connection) + (elmo-imap4-spec-folder spec)) + (elmo-imap4-commit spec)) + (elmo-imap4-send-command (process-buffer process) + process + (format + "status \"%s\" (unseen messages)" + (elmo-imap4-spec-folder spec))) + (setq response (elmo-imap4-read-response + (process-buffer process) process)) + (when (string-match "\\* STATUS [^(]* \\(([^)]*)\\)" response) + (setq response (read (downcase (elmo-match-string 1 response)))) + (cons (cadr (memq 'unseen response)) + (cadr (memq 'messages response))))))) + +(defun elmo-imap4-use-cache-p (spec number) + elmo-imap4-use-cache) + +(defun elmo-imap4-local-file-p (spec number) + nil) + +(defun elmo-imap4-port-label (spec) + (concat "imap4" + (if (nth 6 spec) "!ssl" ""))) + +(defsubst elmo-imap4-portinfo (spec) + (list (elmo-imap4-spec-hostname spec) (elmo-imap4-spec-port spec))) + +(defun elmo-imap4-plugged-p (spec) + (apply 'elmo-plugged-p + (append (elmo-imap4-portinfo spec) + (list nil (quote (elmo-imap4-port-label spec)))))) + +(defun elmo-imap4-set-plugged (spec plugged add) + (apply 'elmo-set-plugged plugged + (append (elmo-imap4-portinfo spec) + (list nil nil (quote (elmo-imap4-port-label spec)) add)))) + +(defalias 'elmo-imap4-sync-number-alist 'elmo-generic-sync-number-alist) + +(provide 'elmo-imap4) + +;;; elmo-imap4.el ends here diff --git a/elmo/elmo-internal.el b/elmo/elmo-internal.el new file mode 100644 index 0000000..2c5fd14 --- /dev/null +++ b/elmo/elmo-internal.el @@ -0,0 +1,263 @@ +;;; elmo-internal.el -- Internal Interface for ELMO. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <2000-03-03 11:12:17 teranisi> + +;; This file is part of ELMO (Elisp Library for Message Orchestration). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; +(require 'elmo-localdir) + +(defsubst elmo-internal-list-folder-subr (spec &optional nonsort) + (let* ((directive (nth 1 spec)) + (arg (nth 2 spec)) + (flist (elmo-list-folder-by-location + spec + (elmo-internal-list-location directive arg)))) + (if nonsort + (cons (or (elmo-max-of-list flist) 0) + (length flist)) + (sort flist '<)))) + +(defun elmo-internal-list-folder (spec) + (elmo-internal-list-folder-subr spec)) + +(defun elmo-internal-list-folder-by-location (spec location &optional msgdb) + (let* ((path (elmo-msgdb-expand-path nil spec)) + (location-alist + (if msgdb + (elmo-msgdb-get-location msgdb) + (elmo-msgdb-location-load path))) + (i 0) + result pair + location-max modified) + (setq location-max + (or (elmo-max-of-list (mapcar 'car location-alist)) 0)) + (when location-max + (while location + (if (setq pair (rassoc (car location) location-alist)) + (setq result + (append result + (list (cons (car pair) (car location))))) + (setq i (1+ i)) + (setq result (append result + (list + (cons (+ location-max i) (car location)))))) + (setq location (cdr location)))) + (setq result (sort result '(lambda (x y) + (< (car x)(car y))))) + (if (not (equal result location-alist)) + (setq modified t)) + (if modified + (elmo-msgdb-location-save path result)) + (mapcar 'car result))) + +(defun elmo-internal-list-location (directive arg) + (let ((mark-alist + (or elmo-msgdb-global-mark-alist + (setq elmo-msgdb-global-mark-alist + (elmo-object-load (expand-file-name + elmo-msgdb-global-mark-filename + elmo-msgdb-dir))))) + result) + (mapcar (function (lambda (x) + (setq result (cons (car x) result)))) + mark-alist) + (nreverse result))) + +(defun elmo-internal-msgdb-create-entity (number loc-alist) + (elmo-localdir-msgdb-create-overview-entity-from-file + number + (elmo-cache-get-path (cdr (assq number loc-alist))))) + +(defun elmo-internal-msgdb-create (spec numlist new-mark + already-mark seen-mark + important-mark + seen-list + &optional msgdb) + (when numlist + (let* ((directive (nth 1 spec)) + (arg (nth 2 spec)) + (loc-alist (if msgdb (elmo-msgdb-get-location msgdb) + (elmo-msgdb-location-load (elmo-msgdb-expand-path + nil spec)))) + (loc-list (elmo-internal-list-location directive arg)) + overview number-alist mark-alist entity + i percent num location pair) + (setq num (length numlist)) + (setq i 0) + (message "Creating msgdb...") + (while numlist + (setq entity + (elmo-internal-msgdb-create-entity + (car numlist) loc-alist)) + (if (null entity) + () + (setq overview + (elmo-msgdb-append-element + overview entity)) + (setq number-alist + (elmo-msgdb-number-add number-alist + (elmo-msgdb-overview-entity-get-number + entity) + (elmo-msgdb-overview-entity-get-id + entity))) + (setq location (cdr (assq (car numlist) loc-alist))) + (unless (memq location seen-list) + (setq mark-alist + (elmo-msgdb-mark-append + mark-alist + (elmo-msgdb-overview-entity-get-number + entity) + ;(nth 0 entity) + (or (elmo-msgdb-global-mark-get + (elmo-msgdb-overview-entity-get-id + entity)) + (if (elmo-cache-exists-p + (elmo-msgdb-overview-entity-get-id + entity)) + already-mark + new-mark)))))) + (setq i (1+ i)) + (setq percent (/ (* i 100) num)) + (elmo-display-progress + 'elmo-internal-msgdb-create "Creating msgdb..." + percent) + (setq numlist (cdr numlist))) + (message "Creating msgdb...done.") + (list overview number-alist mark-alist loc-alist)))) + +(defalias 'elmo-internal-msgdb-create-as-numlist 'elmo-internal-msgdb-create) + +(defun elmo-internal-list-folders (spec &optional hierarchy) + ;; XXX hard cording. + (unless (nth 1 spec) ; toplevel. + (list (list "'cache") "'mark"))) + +(defvar elmo-internal-mark "$") + +(defun elmo-internal-append-msg (spec string &optional msg no-see) + (elmo-set-work-buf + (insert string) + (let* ((msgid (elmo-field-body "message-id")) + (path (elmo-cache-get-path msgid)) + dir) + (when path + (setq dir (directory-file-name (file-name-directory path))) + (if (not (file-exists-p dir)) + (elmo-make-directory dir)) + (as-binary-output-file (write-region (point-min) (point-max) + path nil 'no-msg))) + (elmo-msgdb-global-mark-set msgid elmo-internal-mark)))) + +(defun elmo-internal-delete-msgs (spec msgs &optional msgdb) + (let ((loc-alist (if msgdb (elmo-msgdb-get-location msgdb) + (elmo-msgdb-location-load (elmo-msgdb-expand-path + nil spec))))) + (mapcar '(lambda (msg) (elmo-internal-delete-msg spec msg + loc-alist)) + msgs))) + +(defun elmo-internal-delete-msg (spec number loc-alist) + (let ((pair (assq number loc-alist))) + (elmo-msgdb-global-mark-delete (cdr pair)))) + +(defun elmo-internal-read-msg (spec number outbuf &optional msgdb) + (save-excursion + (let* ((loc-alist (if msgdb (elmo-msgdb-get-location msgdb) + (elmo-msgdb-location-load (elmo-msgdb-expand-path + nil spec)))) + (file (elmo-cache-get-path (cdr (assq number loc-alist))))) + (set-buffer outbuf) + (erase-buffer) + (when (file-exists-p file) + (as-binary-input-file (insert-file-contents file)) + (elmo-delete-cr-get-content-type))))) + +(defun elmo-internal-max-of-folder (spec) + (elmo-internal-list-folder-subr spec t)) + +(defun elmo-internal-check-validity (spec) + nil) + +(defun elmo-internal-sync-validity (spec) + nil) + +(defun elmo-internal-folder-exists-p (spec) + t) + +(defun elmo-internal-folder-creatable-p (spec) + nil) + +(defun elmo-internal-create-folder (spec) + nil) + +(defun elmo-internal-search (spec condition &optional from-msgs msgdb) + (let* ((mark-alist + (or elmo-msgdb-global-mark-alist + (setq elmo-msgdb-global-mark-alist + (elmo-object-load (expand-file-name + elmo-msgdb-global-mark-filename + elmo-msgdb-dir))))) + (loc-alist (if msgdb (elmo-msgdb-get-location msgdb) + (elmo-msgdb-location-load (elmo-msgdb-expand-path + nil spec)))) + cache-file + ret-val + case-fold-search msg + percent i num) + (setq num (length loc-alist)) + (setq i 0) + (while loc-alist + (if (and (setq cache-file (elmo-cache-exists-p (cdr (car loc-alist)))) + (elmo-file-field-condition-match cache-file + condition)) + (setq ret-val (append ret-val (list (car (car loc-alist)))))) + (setq i (1+ i)) + (setq percent (/ (* i 100) num)) + (elmo-display-progress + 'elmo-internal-search "Searching..." + percent) + (setq loc-alist (cdr loc-alist))) + ret-val)) + +(defun elmo-internal-use-cache-p (spec number) + nil) + +(defun elmo-internal-local-file-p (spec number) + nil ;; XXXX + ) + +(defalias 'elmo-internal-sync-number-alist 'elmo-generic-sync-number-alist) +(defalias 'elmo-internal-list-folder-unread + 'elmo-generic-list-folder-unread) +(defalias 'elmo-internal-list-folder-important + 'elmo-generic-list-folder-important) +(defalias 'elmo-internal-commit 'elmo-generic-commit) + +(provide 'elmo-internal) + +;;; elmo-internal.el ends here diff --git a/elmo/elmo-localdir.el b/elmo/elmo-localdir.el new file mode 100644 index 0000000..068b076 --- /dev/null +++ b/elmo/elmo-localdir.el @@ -0,0 +1,466 @@ +;;; elmo-localdir.el -- Localdir Interface for ELMO. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <00/03/22 00:03:39 teranisi> + +;; This file is part of ELMO (Elisp Library for Message Orchestration). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; + +(require 'emu) +(require 'std11) + +(eval-when-compile + (require 'elmo-cache)) +(require 'elmo-msgdb) + +(defsubst elmo-localdir-get-folder-directory (spec) + (if (file-name-absolute-p (nth 1 spec)) + (nth 1 spec) ; already full path. + (expand-file-name (nth 1 spec) + (cond ((eq (car spec) 'localnews) + elmo-localnews-folder-path) + (t + elmo-localdir-folder-path))))) + +(defun elmo-localdir-msgdb-expand-path (spec) + (let ((fld-name (nth 1 spec))) + (expand-file-name fld-name + (expand-file-name "localdir" + elmo-msgdb-dir)))) + +(defun elmo-localdir-number-to-filename (spec dir number &optional loc-alist) + (expand-file-name (int-to-string number) dir)) + +(if (boundp 'nemacs-version) + (defsubst elmo-localdir-insert-header (file) + "Insert the header of the article (Does not work on nemacs)." + (as-binary-input-file + (insert-file-contents file))) + (defsubst elmo-localdir-insert-header (file) + "Insert the header of the article." + (let ((beg 0) + insert-file-contents-pre-hook ; To avoid autoconv-xmas... + insert-file-contents-post-hook + format-alist) + (when (file-exists-p file) + ;; Read until header separator is found. + (while (and (eq elmo-localdir-header-chop-length + (nth 1 + (as-binary-input-file + (insert-file-contents + file nil beg + (incf beg elmo-localdir-header-chop-length))))) + (prog1 (not (search-forward "\n\n" nil t)) + (goto-char (point-max))))))))) + + +(defsubst elmo-localdir-msgdb-create-overview-entity-from-file (number file) + (save-excursion + (let ((tmp-buffer (get-buffer-create " *ELMO LocalDir Temp*")) + insert-file-contents-pre-hook ; To avoid autoconv-xmas... + insert-file-contents-post-hook header-end + (attrib (file-attributes file)) + ret-val size mtime) + (set-buffer tmp-buffer) + (erase-buffer) + (if (not (file-exists-p file)) + () + (setq size (nth 7 attrib)) + (setq mtime (timezone-make-date-arpa-standard + (current-time-string (nth 5 attrib)) (current-time-zone))) + ;; insert header from file. + (catch 'done + (condition-case nil + (elmo-localdir-insert-header file) + (error (throw 'done nil))) + (goto-char (point-min)) + (setq header-end + (if (re-search-forward "\\(^--.*$\\)\\|\\(\n\n\\)" nil t) + (point) + (point-max))) + (narrow-to-region (point-min) header-end) + (setq ret-val (elmo-msgdb-create-overview-from-buffer number size mtime)) + (kill-buffer tmp-buffer)) + ret-val + )))) + +(defun elmo-localdir-msgdb-create-entity (dir number) + (elmo-localdir-msgdb-create-overview-entity-from-file + number (expand-file-name (int-to-string number) dir))) + +(defun elmo-localdir-msgdb-create-as-numlist (spec numlist new-mark + already-mark seen-mark + important-mark seen-list) + (when numlist + (let ((dir (elmo-localdir-get-folder-directory spec)) + overview number-alist mark-alist entity message-id + i percent len num seen gmark) + (setq len (length numlist)) + (setq i 0) + (message "Creating msgdb...") + (while numlist + (setq entity + (elmo-localdir-msgdb-create-entity + dir (car numlist))) + (if (null entity) + () + (setq num (elmo-msgdb-overview-entity-get-number entity)) + (setq overview + (elmo-msgdb-append-element + overview entity)) + (setq number-alist + (elmo-msgdb-number-add number-alist + num + (elmo-msgdb-overview-entity-get-id + entity))) + (setq message-id (elmo-msgdb-overview-entity-get-id entity)) + (setq seen (member message-id seen-list)) + (if (setq gmark (or (elmo-msgdb-global-mark-get message-id) + (if (elmo-cache-exists-p message-id) ; XXX + (if seen + nil + already-mark) + (if seen + nil ;;seen-mark + new-mark)))) + (setq mark-alist + (elmo-msgdb-mark-append + mark-alist + num + gmark)))) + (setq i (1+ i)) + (setq percent (/ (* i 100) len)) + (elmo-display-progress + 'elmo-localdir-msgdb-create-as-numlist "Creating msgdb..." + percent) + (setq numlist (cdr numlist))) + (message "Creating msgdb...done.") + (list overview number-alist mark-alist)))) + +(defalias 'elmo-localdir-msgdb-create 'elmo-localdir-msgdb-create-as-numlist) + +(defvar elmo-localdir-list-folders-spec-string "+") +(defvar elmo-localdir-list-folders-filter-regexp "^\\(\\.\\.?\\|[0-9]+\\)$") + +(defun elmo-localdir-list-folders (spec &optional hierarchy) + (let ((folder (concat elmo-localdir-list-folders-spec-string (nth 1 spec)))) + (elmo-localdir-list-folders-subr folder hierarchy))) + +(defun elmo-localdir-list-folders-subr (folder &optional hierarchy) + (let ((case-fold-search t) + folders curdir dirent relpath abspath attr + subprefix subfolder) + (condition-case () + (progn + (setq curdir + (expand-file-name (nth 1 (elmo-folder-get-spec folder)) + elmo-localdir-folder-path)) + (if (string-match "^[+=$.]$" folder) ; localdir, archive, localnews + (setq subprefix folder) + (setq subprefix (concat folder elmo-path-sep)) + ;; include parent + (setq folders (list folder))) + (setq dirent (directory-files curdir)) + (catch 'done + (while dirent + (setq relpath (car dirent)) + (setq dirent (cdr dirent)) + (setq abspath (expand-file-name relpath curdir)) + (and + (not (string-match + elmo-localdir-list-folders-filter-regexp + relpath)) + (eq (nth 0 (setq attr (file-attributes abspath))) t) + (if (eq hierarchy 'check) + (throw 'done (nconc folders t)) + t) + (setq subfolder (concat subprefix relpath)) + (setq folders (nconc folders + (if (and hierarchy + (if elmo-have-link-count + (< 2 (nth 1 attr)) + (cdr + (elmo-localdir-list-folders-subr + subfolder 'check)))) + (list (list subfolder)) + (list subfolder)))) + (or + hierarchy + (and elmo-have-link-count (>= 2 (nth 1 attr))) + (setq folders + (nconc folders (cdr (elmo-localdir-list-folders-subr + subfolder hierarchy)))))))) + folders) + (file-error folders)))) + +(defsubst elmo-localdir-list-folder-subr (spec &optional nonsort) + (let* ((dir (elmo-localdir-get-folder-directory spec)) + (flist (mapcar 'string-to-int + (directory-files dir nil "^[0-9]+$" t)))) + (if nonsort + (cons (or (elmo-max-of-list flist) 0) (length flist)) + (sort flist '<)))) + +(defun elmo-localdir-append-msg (spec string &optional msg no-see) + (let ((dir (elmo-localdir-get-folder-directory spec)) + (tmp-buffer (get-buffer-create " *ELMO Temp buffer*")) + (next-num (or msg + (1+ (car (elmo-localdir-list-folder-subr spec t))))) + filename) + (save-excursion + (set-buffer tmp-buffer) + (erase-buffer) + (setq filename (expand-file-name (int-to-string + next-num) + dir)) + (unwind-protect + (if (file-writable-p filename) + (progn + (insert string) + (as-binary-output-file + (write-region (point-min) (point-max) filename nil 'no-msg)) + t) + nil + ) + (kill-buffer tmp-buffer))))) + +(defun elmo-localdir-delete-msg (spec number) + (let (file + (dir (elmo-localdir-get-folder-directory spec)) + (number (int-to-string number))) + (setq file (expand-file-name number dir)) + (if (and (string-match "[0-9]+" number) ; for safety. + (file-exists-p file) + (file-writable-p file) + (not (file-directory-p file))) + (progn (delete-file file) + t)))) + +(defun elmo-localdir-read-msg (spec number outbuf &optional set-mark) + (save-excursion + (let* ((number (int-to-string number)) + (dir (elmo-localdir-get-folder-directory spec)) + (file (expand-file-name number dir))) + (set-buffer outbuf) + (erase-buffer) + (when (file-exists-p file) + (as-binary-input-file (insert-file-contents file)) + (elmo-delete-cr-get-content-type))))) + +(defun elmo-localdir-delete-msgs (spec msgs) + (mapcar '(lambda (msg) (elmo-localdir-delete-msg spec msg)) + msgs)) + +(defun elmo-localdir-list-folder (spec); called by elmo-localdir-search() + (elmo-localdir-list-folder-subr spec)) + +(defun elmo-localdir-max-of-folder (spec) + (elmo-localdir-list-folder-subr spec t)) + +(defun elmo-localdir-check-validity (spec validity-file) + (let* ((dir (elmo-localdir-get-folder-directory spec)) + (cur-val (nth 5 (file-attributes dir))) + (file-val (read + (or (elmo-get-file-string validity-file) + "nil")))) + (cond + ((or (null cur-val) (null file-val)) nil) + ((> (car cur-val) (car file-val)) nil) + ((= (car cur-val) (car file-val)) + (if (> (cadr cur-val) (cadr file-val)) nil t)) ; t if same + (t t)))) + +(defun elmo-localdir-sync-validity (spec validity-file) + (save-excursion + (let* ((dir (elmo-localdir-get-folder-directory spec)) + (tmp-buffer (get-buffer-create " *ELMO TMP*")) + (number-file (expand-file-name elmo-msgdb-number-filename dir))) + (set-buffer tmp-buffer) + (erase-buffer) + (prin1 (nth 5 (file-attributes dir)) tmp-buffer) + (princ "\n" tmp-buffer) + (if (file-writable-p validity-file) + (write-region (point-min) (point-max) + validity-file nil 'no-msg) + (message (format "%s is not writable." number-file))) + (kill-buffer tmp-buffer)))) + +(defun elmo-localdir-folder-exists-p (spec) + (file-directory-p (elmo-localdir-get-folder-directory spec))) + +(defun elmo-localdir-folder-creatable-p (spec) + t) + +(defun elmo-localdir-create-folder (spec) + (save-excursion + (let ((dir (elmo-localdir-get-folder-directory spec))) + (if (file-directory-p dir) + () + (if (file-exists-p dir) + (error "Create folder failed") + (elmo-make-directory dir)) + t + )))) + +(defun elmo-localdir-delete-folder (spec) + (let* ((dir (elmo-localdir-get-folder-directory spec))) + (if (not (file-directory-p dir)) + (error "no such directory: %s" dir) + (elmo-delete-directory dir t) + t))) + +(defun elmo-localdir-rename-folder (old-spec new-spec) + (let* ((old (elmo-localdir-get-folder-directory old-spec)) + (new (elmo-localdir-get-folder-directory new-spec)) + (new-dir (directory-file-name (file-name-directory new)))) + (if (not (file-directory-p old)) + (error "no such directory: %s" old) + (if (file-exists-p new) + (error "already exists directory: %s" new) + (if (not (file-exists-p new-dir)) + (elmo-make-directory new-dir)) + (rename-file old new) + t)))) + +(defsubst elmo-localdir-field-condition-match (spec number condition) + (elmo-file-field-condition-match + (expand-file-name (int-to-string number) + (elmo-localdir-get-folder-directory spec)) + condition)) + +(defun elmo-localdir-search (spec condition &optional from-msgs) + (let* ((msgs (or from-msgs (elmo-localdir-list-folder spec))) + (num (length msgs)) + (i 0) case-fold-search ret-val) + (while msgs + (if (elmo-localdir-field-condition-match spec (car msgs) + condition) + (setq ret-val (cons (car msgs) ret-val))) + (setq i (1+ i)) + (elmo-display-progress + 'elmo-localdir-search "Searching..." + (/ (* i 100) num)) + (setq msgs (cdr msgs))) + (nreverse ret-val))) + +;;; (localdir, maildir, localnews) -> localdir +(defun elmo-localdir-copy-msgs (dst-spec msgs src-spec + &optional loc-alist same-number) + (let ((dst-dir + (elmo-localdir-get-folder-directory dst-spec)) + (next-num (1+ (car (elmo-localdir-list-folder-subr dst-spec t))))) + (while msgs + (elmo-copy-file + ;; src file + (elmo-call-func src-spec "get-msg-filename" (car msgs) loc-alist) + ;; dst file + (expand-file-name (int-to-string + (if same-number (car msgs) next-num)) + dst-dir)) + (if (and (setq msgs (cdr msgs)) + (not same-number)) + (setq next-num + (if (and (eq (car dst-spec) 'localdir) + (elmo-localdir-locked-p)) + ;; MDA is running. + (1+ (car (elmo-localdir-list-folder-subr dst-spec t))) + (1+ next-num))))) + t)) + +(defun elmo-localdir-pack-number (spec msgdb arg) + (let ((dir (elmo-localdir-get-folder-directory spec)) + (onum-alist (elmo-msgdb-get-number-alist msgdb)) + (omark-alist (elmo-msgdb-get-mark-alist msgdb)) + (oov (elmo-msgdb-get-overview msgdb)) + i flist onum mark new-mark-alist total) + (setq i 1) + (setq flist + (if elmo-pack-number-check-strict + (elmo-call-func spec "list-folder") ;; allow localnews + (mapcar 'car onum-alist))) + (setq total (length flist)) + (while flist + (elmo-display-progress + 'elmo-localdir-pack-number "Packing..." + (/ (* i 100) total)) + (setq onum (car flist)) + (when (not (eq onum i)) ;; why \=() is wrong.. + (elmo-bind-directory + dir + ;; xxx nfs,hardlink + (rename-file (int-to-string onum) (int-to-string i) t)) + ;; update overview + (elmo-msgdb-overview-entity-set-number + (elmo-msgdb-overview-get-entity-by-number + oov onum) i) + ;; update number-alist + (setcar (assq onum onum-alist) i)) + ;; update mark-alist + (when (setq mark (cadr (assq onum omark-alist))) + (setq new-mark-alist + (elmo-msgdb-mark-append + new-mark-alist + i mark))) + (setq i (1+ i)) + (setq flist (cdr flist))) + (message "Packing...done.") + (list (elmo-msgdb-get-overview msgdb) + onum-alist + new-mark-alist + (elmo-msgdb-get-location msgdb)))) + +(defun elmo-localdir-use-cache-p (spec number) + nil) + +(defun elmo-localdir-local-file-p (spec number) + t) + +(defun elmo-localdir-get-msg-filename (spec number &optional loc-alist) + (expand-file-name + (int-to-string number) + (elmo-localdir-get-folder-directory spec))) + +(defun elmo-localdir-locked-p () + (if elmo-localdir-lockfile-list + (let ((lock elmo-localdir-lockfile-list)) + (catch 'found + (while lock + (if (file-exists-p (car lock)) + (throw 'found t)) + (setq lock (cdr lock))))))) + +(defalias 'elmo-localdir-sync-number-alist + 'elmo-generic-sync-number-alist) +(defalias 'elmo-localdir-list-folder-unread + 'elmo-generic-list-folder-unread) +(defalias 'elmo-localdir-list-folder-important + 'elmo-generic-list-folder-important) +(defalias 'elmo-localdir-commit 'elmo-generic-commit) + +(provide 'elmo-localdir) + +;;; elmo-localdir.el ends here diff --git a/elmo/elmo-localnews.el b/elmo/elmo-localnews.el new file mode 100644 index 0000000..67a3a6a --- /dev/null +++ b/elmo/elmo-localnews.el @@ -0,0 +1,133 @@ +;;; elmo-localnews.el -- Local News Spool Interface for ELMO. + +;; Copyright 1998,1999,2000 OKUNISHI Fujikazu +;; Yuuichi Teranishi + +;; Author: OKUNISHI Fujikazu +;; Time-stamp: <2000-01-24 12:20:07 teranisi> + +;; This file is part of ELMO (Elisp Library for Message Orchestration). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; +(require 'elmo-localdir) + +(defmacro elmo-localnews-as-newsdir (&rest body) + (` (let ((elmo-localdir-folder-path elmo-localnews-folder-path)) + (,@ body)))) + +(defun elmo-localnews-msgdb-create-as-numlist (spec numlist new-mark + already-mark seen-mark + important-mark seen-list) + (when numlist + (elmo-localnews-as-newsdir + (elmo-localdir-msgdb-create-as-numlist spec numlist new-mark + already-mark seen-mark + important-mark seen-list)))) + +(defalias 'elmo-localnews-msgdb-create 'elmo-localnews-msgdb-create-as-numlist) + +(defun elmo-localnews-list-folders (spec &optional hierarchy) + (let ((folder (concat "=" (nth 1 spec)))) + (elmo-localnews-as-newsdir + (elmo-localdir-list-folders-subr folder hierarchy)))) + +(defun elmo-localnews-append-msg (spec string &optional msg no-see) + (elmo-localnews-as-newsdir + (elmo-localdir-append-msg spec string))) + +(defun elmo-localnews-delete-msgs (dir number) + (elmo-localnews-as-newsdir + (elmo-localdir-delete-msgs dir number))) + +(defun elmo-localnews-read-msg (spec number outbuf) + (elmo-localnews-as-newsdir + (elmo-localdir-read-msg spec number outbuf))) + +(defun elmo-localnews-list-folder (spec) + (elmo-localnews-as-newsdir + (elmo-localdir-list-folder-subr spec))) + +(defun elmo-localnews-max-of-folder (spec) + (elmo-localnews-as-newsdir + (elmo-localdir-list-folder-subr spec t))) + +(defun elmo-localnews-check-validity (spec validity-file) + (elmo-localnews-as-newsdir + (elmo-localdir-check-validity spec validity-file))) + +(defun elmo-localnews-sync-validity (spec validity-file) + (elmo-localnews-as-newsdir + (elmo-localdir-sync-validity spec validity-file))) + +(defun elmo-localnews-folder-exists-p (spec) + (elmo-localnews-as-newsdir + (elmo-localdir-folder-exists-p spec))) + +(defun elmo-localnews-folder-creatable-p (spec) + t) + +(defun elmo-localnews-create-folder (spec) + (elmo-localnews-as-newsdir + (elmo-localdir-create-folder spec))) + +(defun elmo-localnews-delete-folder (spec) + (elmo-localnews-as-newsdir + (elmo-localdir-delete-folder spec))) + +(defun elmo-localnews-rename-folder (old-spec new-spec) + (elmo-localnews-as-newsdir + (elmo-localdir-rename-folder old-spec new-spec))) + +(defun elmo-localnews-search (spec condition &optional from-msgs) + (elmo-localnews-as-newsdir + (elmo-localdir-search spec condition from-msgs))) + +(defun elmo-localnews-copy-msgs (dst-spec msgs src-spec + &optional loc-alist same-number) + (elmo-localdir-copy-msgs + dst-spec msgs src-spec loc-alist same-number)) + +(defun elmo-localnews-pack-number (spec msgdb arg) + (elmo-localnews-as-newsdir + (elmo-localdir-pack-number spec msgdb arg))) + +(defun elmo-localnews-use-cache-p (spec number) + nil) + +(defun elmo-localnews-local-file-p (spec number) + t) + +(defun elmo-localnews-get-msg-filename (spec number &optional loc-alist) + (elmo-localnews-as-newsdir + (elmo-localdir-get-msg-filename spec number loc-alist))) + +(defalias 'elmo-localnews-sync-number-alist 'elmo-generic-sync-number-alist) +(defalias 'elmo-localnews-list-folder-unread + 'elmo-generic-list-folder-unread) +(defalias 'elmo-localnews-list-folder-important + 'elmo-generic-list-folder-important) +(defalias 'elmo-localnews-commit 'elmo-generic-commit) + +(provide 'elmo-localnews) + +;;; elmo-localnews.el ends here diff --git a/elmo/elmo-maildir.el b/elmo/elmo-maildir.el new file mode 100644 index 0000000..df092c4 --- /dev/null +++ b/elmo/elmo-maildir.el @@ -0,0 +1,478 @@ +;;; elmo-maildir.el -- Maildir interface for ELMO. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <00/03/22 00:14:31 teranisi> + +;; This file is part of ELMO (Elisp Library for Message Orchestration). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; + +(eval-when-compile (require 'cl)) +(require 'elmo-util) +(require 'elmo-localdir) + +(defvar elmo-maildir-sequence-number-internal 0 + "Sequence number for the pid part of unique filename. +This variable should not be used in elsewhere.") + +(defsubst elmo-maildir-get-folder-directory (spec) + (if (file-name-absolute-p (nth 1 spec)) + (nth 1 spec) ; already full path. + (expand-file-name (nth 1 spec) + elmo-maildir-folder-path))) + +(defun elmo-maildir-number-to-filename (dir number loc-alist) + (let ((location (cdr (assq number loc-alist)))) + (and location (elmo-maildir-get-filename location dir)))) + +(defun elmo-maildir-get-filename (location dir) + "Get a filename that is corresponded to LOCATION in DIR." + (expand-file-name + (let ((file (file-name-completion (symbol-name location) + (expand-file-name "cur" dir)))) + (if (eq file t) location file)) + (expand-file-name "cur" dir))) + +(defsubst elmo-maildir-list-location (dir &optional child-dir) + (let* ((cur-dir (expand-file-name (or child-dir "cur") dir)) + (cur (directory-files cur-dir + nil "^[^.].*$" t)) + seen-list seen sym list) + (setq list + (mapcar + (lambda (x) + (if (string-match "^\\([^:]+\\):\\([^:]+\\)$" x) + (progn + (setq seen nil) + (save-match-data + (if (string-match + "S" + (elmo-match-string 2 x)) + (setq seen t))) + (setq sym (intern (elmo-match-string 1 x))) + (if seen + (setq seen-list (cons sym seen-list))) + sym) + (intern x))) + cur)) + (cons list seen-list))) + +(defun elmo-maildir-msgdb-create-entity (dir number loc-alist) + (elmo-localdir-msgdb-create-overview-entity-from-file + number + (elmo-maildir-number-to-filename dir number loc-alist))) + +(defun elmo-maildir-cleanup-temporal (dir) + ;; Delete files in the tmp dir which are not accessed + ;; for more than 36 hours. + (let ((cur-time (current-time)) + (count 0) + last-accessed) + (mapcar (function + (lambda (file) + (setq last-accessed (nth 4 (file-attributes file))) + (when (or (> (- (car cur-time)(car last-accessed)) 1) + (and (eq (- (car cur-time)(car last-accessed)) 1) + (> (- (cadr cur-time)(cadr last-accessed)) + 64064))) ; 36 hours. + (message "Maildir: %d tmp file(s) are cleared." + (setq count (1+ count))) + (delete-file file)))) + (directory-files (expand-file-name "tmp" dir) + t ; full + "^[^.].*$" t)))) + +(defun elmo-maildir-update-current (spec) + "Move all new msgs to cur in the maildir" + (let* ((maildir (elmo-maildir-get-folder-directory spec)) + (news (directory-files (expand-file-name "new" + maildir) + nil + "^[^.].*$" t))) + ;; cleanup tmp directory. + (elmo-maildir-cleanup-temporal maildir) + ;; move new msgs to cur directory. + (mapcar (lambda (x) + (rename-file + (expand-file-name x (expand-file-name "new" maildir)) + (expand-file-name (concat x ":2,") + (expand-file-name "cur" maildir)))) + news))) + +(defun elmo-maildir-set-mark (filename mark) + "Mark the file in the maildir. MARK is a character." + (if (string-match "^\\([^:]+:2,\\)\\(.*\\)$" filename) + (let ((flaglist (string-to-char-list (elmo-match-string + 2 filename)))) + (unless (memq mark flaglist) + (setq flaglist (sort (cons mark flaglist) '<)) + (rename-file filename + (concat (elmo-match-string 1 filename) + (char-list-to-string flaglist))))))) + +(defun elmo-maildir-delete-mark (filename mark) + "Mark the file in the maildir. MARK is a character." + (if (string-match "^\\([^:]+:2,\\)\\(.*\\)$" filename) + (let ((flaglist (string-to-char-list (elmo-match-string + 2 filename)))) + (when (memq mark flaglist) + (setq flaglist (delq mark flaglist)) + (rename-file filename + (concat (elmo-match-string 1 filename) + (if flaglist + (char-list-to-string flaglist)))))))) + +(defsubst elmo-maildir-set-mark-msgs (spec mark msgs msgdb) + (let ((dir (elmo-maildir-get-folder-directory spec)) + (locs (if msgdb + (elmo-msgdb-get-location msgdb) + (elmo-msgdb-location-load (elmo-msgdb-expand-path nil spec)))) + file) + (while msgs + (if (setq file (elmo-maildir-number-to-filename dir (car msgs) locs)) + (elmo-maildir-set-mark file mark)) + (setq msgs (cdr msgs))))) + +(defsubst elmo-maildir-delete-mark-msgs (spec mark msgs msgdb) + (let ((dir (elmo-maildir-get-folder-directory spec)) + (locs (if msgdb + (elmo-msgdb-get-location msgdb) + (elmo-msgdb-location-load (elmo-msgdb-expand-path nil spec)))) + file) + (while msgs + (if (setq file (elmo-maildir-number-to-filename dir (car msgs) locs)) + (elmo-maildir-delete-mark file mark)) + (setq msgs (cdr msgs))))) + +(defun elmo-maildir-mark-as-important (spec msgs &optional msgdb) + (elmo-maildir-set-mark-msgs spec ?F msgs msgdb)) + +(defun elmo-maildir-unmark-important (spec msgs &optional msgdb) + (elmo-maildir-delete-mark-msgs spec ?F msgs msgdb)) + +(defun elmo-maildir-mark-as-read (spec msgs &optional msgdb) + (elmo-maildir-set-mark-msgs spec ?S msgs msgdb)) + +(defun elmo-maildir-mark-as-unread (spec msgs &optional msgdb) + (elmo-maildir-delete-mark-msgs spec ?S msgs msgdb)) + +(defun elmo-maildir-msgdb-create (spec numlist new-mark + already-mark seen-mark + important-mark + seen-list + &optional msgdb) + (when numlist + (let* ((dir (elmo-maildir-get-folder-directory spec)) + (loc-alist (if msgdb (elmo-msgdb-get-location msgdb) + (elmo-msgdb-location-load (elmo-msgdb-expand-path + nil spec)))) + (loc-seen (elmo-maildir-list-location dir)) + (loc-list (car loc-seen)) + (seen-list (cdr loc-seen)) + overview number-alist mark-alist entity + i percent num location pair) + (setq num (length numlist)) + (setq i 0) + (message "Creating msgdb...") + (while numlist + (setq entity + (elmo-maildir-msgdb-create-entity + dir (car numlist) loc-alist)) + (if (null entity) + () + (setq overview + (elmo-msgdb-append-element + overview entity)) + (setq number-alist + (elmo-msgdb-number-add number-alist + (elmo-msgdb-overview-entity-get-number + entity) + (elmo-msgdb-overview-entity-get-id + entity))) + (setq location (cdr (assq (car numlist) loc-alist))) + (unless (member location seen-list) + (setq mark-alist + (elmo-msgdb-mark-append + mark-alist + (elmo-msgdb-overview-entity-get-number + entity) + (or (elmo-msgdb-global-mark-get + (elmo-msgdb-overview-entity-get-id + entity)) + new-mark))))) + (setq i (1+ i)) + (setq percent (/ (* i 100) num)) + (elmo-display-progress + 'elmo-maildir-msgdb-create "Creating msgdb..." + percent) + (setq numlist (cdr numlist))) + (message "Creating msgdb...done.") + (list overview number-alist mark-alist loc-alist)))) + +(defalias 'elmo-maildir-msgdb-create-as-numlist 'elmo-maildir-msgdb-create) + +(defun elmo-maildir-list-folders (spec &optional hierarchy) + (let ((elmo-localdir-folder-path elmo-maildir-folder-path) + (elmo-localdir-list-folders-spec-string ".") + (elmo-localdir-list-folders-filter-regexp + "^\\(\\.\\.?\\|cur\\|tmp\\|new\\)$") + elmo-have-link-count folders) + (setq folders (elmo-localdir-list-folders spec hierarchy)) + (if (eq (length (nth 1 spec)) 0) ; top + (setq folders (append + (list (concat elmo-localdir-list-folders-spec-string + (nth 1 spec))) + folders))) + (elmo-delete-if + (function (lambda (folder) + (not (or (listp folder) (elmo-folder-exists-p folder))))) + folders))) + +(static-cond + ((>= emacs-major-version 19) + (defun elmo-maildir-make-unique-string () + "This function generates a string that can be used as a unique +file name for maildir directories." + (let ((cur-time (current-time))) + (format "%.0f.%d_%d.%s" + (+ (* (car cur-time) + (float 65536)) (cadr cur-time)) + (emacs-pid) + (incf elmo-maildir-sequence-number-internal) + (system-name))))) + ((eq emacs-major-version 18) + ;; A fake function for v18 + (defun elmo-maildir-make-unique-string () + "This function generates a string that can be used as a unique +file name for maildir directories." + (unless (fboundp 'float-to-string) + (load-library "float")) + (let ((time (current-time))) + (format "%s%d.%d.%s" + (substring + (float-to-string + (f+ (f* (f (car time)) + (f 65536)) + (f (cadr time)))) + 0 5) + (cadr time) + (% (abs (random t)) 10000); dummy pid + (system-name)))))) + +(defun elmo-maildir-temporal-filename (basedir) + (let ((filename (expand-file-name + (concat "tmp/" (elmo-maildir-make-unique-string)) + basedir))) + (unless (file-exists-p (file-name-directory filename)) + (make-directory (file-name-directory filename))) + (while (file-exists-p filename) + ;; (sleep-for 2) ; I don't want to wait. + (setq filename + (expand-file-name + (concat "tmp/" (elmo-maildir-make-unique-string)) + basedir))) + filename)) + +(defun elmo-maildir-append-msg (spec string &optional msg no-see) + (let ((basedir (elmo-maildir-get-folder-directory spec)) + filename) + (condition-case nil + (with-temp-buffer + (setq filename (elmo-maildir-temporal-filename basedir)) + (insert string) + (as-binary-output-file + (write-region (point-min) (point-max) filename nil 'no-msg)) + ;; add link from new. + (elmo-add-name-to-file + filename + (expand-file-name + (concat "new/" (file-name-nondirectory filename)) + basedir)) + t) + ;; If an error occured, return nil. + (error)))) + +(defun elmo-maildir-delete-msg (spec number loc-alist) + (let ((dir (elmo-maildir-get-folder-directory spec)) + file) + (setq file (elmo-maildir-number-to-filename dir number loc-alist)) + (if (and (file-writable-p file) + (not (file-directory-p file))) + (progn (delete-file file) + t)))) + +(defun elmo-maildir-read-msg (spec number outbuf &optional msgdb) + (save-excursion + (let* ((loc-alist (if msgdb (elmo-msgdb-get-location msgdb) + (elmo-msgdb-location-load (elmo-msgdb-expand-path + nil spec)))) + (dir (elmo-maildir-get-folder-directory spec)) + (file (elmo-maildir-number-to-filename dir number loc-alist))) + (set-buffer outbuf) + (erase-buffer) + (when (file-exists-p file) + (as-binary-input-file (insert-file-contents file)) + (elmo-delete-cr-get-content-type))))) + +(defun elmo-maildir-delete-msgs (spec msgs &optional msgdb) + (let ((loc-alist (if msgdb (elmo-msgdb-get-location msgdb) + (elmo-msgdb-location-load (elmo-msgdb-expand-path + nil spec))))) + (mapcar '(lambda (msg) (elmo-maildir-delete-msg spec msg + loc-alist)) + msgs))) + +(defsubst elmo-maildir-list-folder-subr (spec &optional nonsort) + (let* ((dir (elmo-maildir-get-folder-directory spec)) + (flist (elmo-list-folder-by-location + spec + (car (elmo-maildir-list-location dir)))) + (news (car (elmo-maildir-list-location dir "new")))) + (if nonsort + (cons (+ (or (elmo-max-of-list flist) 0) (length news)) + (+ (length flist) (length news))) + (sort flist '<)))) + +(defun elmo-maildir-list-folder (spec) + (elmo-maildir-update-current spec) + (elmo-maildir-list-folder-subr spec)) + +(defun elmo-maildir-max-of-folder (spec) + (elmo-maildir-list-folder-subr spec t)) + +(defalias 'elmo-maildir-check-validity 'elmo-localdir-check-validity) + +(defalias 'elmo-maildir-sync-validity 'elmo-localdir-sync-validity) + +(defun elmo-maildir-folder-exists-p (spec) + (let ((basedir (elmo-maildir-get-folder-directory spec))) + (and (file-directory-p (expand-file-name "new" basedir)) + (file-directory-p (expand-file-name "cur" basedir)) + (file-directory-p (expand-file-name "tmp" basedir))))) + +(defun elmo-maildir-folder-creatable-p (spec) + t) + +(defun elmo-maildir-create-folder (spec) + (let ((basedir (elmo-maildir-get-folder-directory spec))) + (condition-case nil + (progn + (mapcar (function (lambda (dir) + (setq dir (expand-file-name dir basedir)) + (or (file-directory-p dir) + (progn + (elmo-make-directory dir) + (set-file-modes dir 448))))) + '("." "new" "cur" "tmp")) + t) + (error)))) + +(defun elmo-maildir-delete-folder (spec) + (let ((basedir (elmo-maildir-get-folder-directory spec))) + (condition-case nil + (let ((tmp-files (directory-files + (expand-file-name "tmp" basedir) + t "[^.].*"))) + ;; Delete files in tmp. + (and tmp-files (mapcar 'delete-file tmp-files)) + (mapcar + (function + (lambda (dir) + (setq dir (expand-file-name dir basedir)) + (if (not (file-directory-p dir)) + (error) + (elmo-delete-directory dir t)))) + '("new" "cur" "tmp" ".")) + t) + (error)))) + +(defun elmo-maildir-search (spec condition &optional from-msgs msgdb) + (save-excursion + (let* ((msgs (or from-msgs (elmo-maildir-list-folder spec))) + (loc-alist (if msgdb (elmo-msgdb-get-location msgdb) + (elmo-msgdb-location-load (elmo-msgdb-expand-path + nil spec)))) + (dir (elmo-maildir-get-folder-directory spec)) + (i 0) + case-fold-search ret-val + percent num + (num (length msgs)) + msg-num) + (while msgs + (setq msg-num (car msgs)) + (if (elmo-file-field-condition-match + (elmo-maildir-number-to-filename + dir (car msgs) loc-alist) + condition) + (setq ret-val (append ret-val (list msg-num)))) + (setq i (1+ i)) + (setq percent (/ (* i 100) num)) + (elmo-display-progress + 'elmo-maildir-search "Searching..." + percent) + (setq msgs (cdr msgs))) + ret-val))) + +;;; (maildir) -> maildir +(defun elmo-maildir-copy-msgs (dst-spec msgs src-spec + &optional loc-alist same-number) + (let (srcfile) + (while msgs + (setq srcfile + (elmo-maildir-get-msg-filename src-spec (car msgs) loc-alist)) + (elmo-copy-file + ;; src file + srcfile + ;; dst file + (expand-file-name + (file-name-nondirectory srcfile) + (concat (elmo-maildir-get-folder-directory dst-spec) "/cur"))) + (setq msgs (cdr msgs)))) + t) + +(defun elmo-maildir-use-cache-p (spec number) + nil) + +(defun elmo-maildir-local-file-p (spec number) + t) + +(defun elmo-maildir-get-msg-filename (spec number &optional loc-alist) + (elmo-maildir-number-to-filename + (elmo-maildir-get-folder-directory spec) + number (or loc-alist (elmo-msgdb-location-load + (elmo-msgdb-expand-path + nil spec))))) + +(defalias 'elmo-maildir-sync-number-alist + 'elmo-generic-sync-number-alist) +(defalias 'elmo-maildir-list-folder-unread + 'elmo-generic-list-folder-unread) +(defalias 'elmo-maildir-list-folder-important + 'elmo-generic-list-folder-important) + +(provide 'elmo-maildir) + +;;; elmo-maildir.el ends here diff --git a/elmo/elmo-msgdb.el b/elmo/elmo-msgdb.el new file mode 100644 index 0000000..595a435 --- /dev/null +++ b/elmo/elmo-msgdb.el @@ -0,0 +1,720 @@ +;;; elmo-msgdb.el -- Message Database for Elmo. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <00/03/06 13:24:13 teranisi> + +;; This file is part of ELMO (Elisp Library for Message Orchestration). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; + +(eval-when-compile (require 'cl)) +(require 'elmo-vars) +(require 'elmo-util) +(require 'emu) +(require 'std11) +(require 'elmo-cache) + +(defun elmo-msgdb-expand-path (folder &optional spec) + (convert-standard-filename + (let* ((spec (or spec (elmo-folder-get-spec folder))) + (type (car spec)) + fld) + (cond + ((eq type 'imap4) + (setq fld (elmo-imap4-spec-mailbox spec)) + (if (string= "inbox" (downcase fld)) + (setq fld "inbox")) + (if (eq (string-to-char fld) ?/) + (setq fld (substring fld 1 (length fld)))) + (expand-file-name + fld + (expand-file-name (or (elmo-imap4-spec-username spec) "nobody") + (expand-file-name (or + (elmo-imap4-spec-hostname spec) + "nowhere") + (expand-file-name + "imap" + elmo-msgdb-dir))))) + ((eq type 'nntp) + (expand-file-name + (elmo-nntp-spec-group spec) + (expand-file-name (or (elmo-nntp-spec-hostname spec) "nowhere") + (expand-file-name "nntp" + elmo-msgdb-dir)))) + ((eq type 'maildir) + (expand-file-name (elmo-safe-filename (nth 1 spec)) + (expand-file-name "maildir" + elmo-msgdb-dir))) + ((eq type 'folder) + (expand-file-name (elmo-safe-filename (nth 1 spec)) + (expand-file-name "folder" + elmo-msgdb-dir))) + ((eq type 'multi) + (expand-file-name (elmo-safe-filename folder) + (expand-file-name "multi" + elmo-msgdb-dir))) + ((eq type 'filter) + (expand-file-name + (elmo-safe-filename folder) + (expand-file-name "filter" + elmo-msgdb-dir))) + ((eq type 'archive) + (expand-file-name + (directory-file-name + (concat + (elmo-replace-in-string + (elmo-replace-in-string + (elmo-replace-in-string + (nth 1 spec) + "/" "_") + ":" "__") + "~" "___") + "/" (nth 3 spec))) + (expand-file-name (concat (symbol-name type) "/" + (symbol-name (nth 2 spec))) + elmo-msgdb-dir))) + ((eq type 'pop3) + (expand-file-name + (elmo-safe-filename (elmo-pop3-spec-username spec)) + (expand-file-name (elmo-pop3-spec-hostname spec) + (expand-file-name + "pop" + elmo-msgdb-dir)))) + ((eq type 'localnews) + (expand-file-name + (elmo-replace-in-string (nth 1 spec) "/" ".") + (expand-file-name "localnews" + elmo-msgdb-dir))) + ((eq type 'internal) + (expand-file-name (elmo-safe-filename (concat (symbol-name (nth 1 spec)) + (nth 2 spec))) + (expand-file-name "internal" + elmo-msgdb-dir))) + ((eq type 'cache) + (expand-file-name (elmo-safe-filename (nth 1 spec)) + (expand-file-name "internal/cache" + elmo-msgdb-dir))) + (t ; local dir or undefined type + ;; absolute path + (setq fld (nth 1 spec)) + (if (file-name-absolute-p fld) + (setq fld (elmo-safe-filename fld))) + (expand-file-name fld + (expand-file-name (symbol-name type) + elmo-msgdb-dir))))))) + +(defsubst elmo-msgdb-append-element (list element) + (if list + ;(append list (list element)) + (nconc list (list element)) + ;; list is nil + (list element))) + +(defsubst elmo-msgdb-get-overview (msgdb) + (car msgdb)) +(defsubst elmo-msgdb-get-number-alist (msgdb) + (cadr msgdb)) +(defsubst elmo-msgdb-get-mark-alist (msgdb) + (caddr msgdb)) +(defsubst elmo-msgdb-get-location (msgdb) + (cadddr msgdb)) + +;; +;; number <-> Message-ID handling +;; +(defsubst elmo-msgdb-number-add (alist number id) + (let ((ret-val alist)) + (setq ret-val + (elmo-msgdb-append-element ret-val (cons number id))) + ret-val)) + +;;; +;; parsistent mark handling +;; (for global!) + +(defvar elmo-msgdb-global-mark-alist nil) + +(defun elmo-msgdb-global-mark-delete (msgid) + (let* ((path (expand-file-name + elmo-msgdb-global-mark-filename + elmo-msgdb-dir)) + (malist (or elmo-msgdb-global-mark-alist + (setq elmo-msgdb-global-mark-alist + (elmo-object-load path)))) + match) + (when (setq match (assoc msgid malist)) + (setq elmo-msgdb-global-mark-alist + (delete match elmo-msgdb-global-mark-alist)) + (elmo-object-save path elmo-msgdb-global-mark-alist)))) + +(defun elmo-msgdb-global-mark-set (msgid mark) + (let* ((path (expand-file-name + elmo-msgdb-global-mark-filename + elmo-msgdb-dir)) + (malist (or elmo-msgdb-global-mark-alist + (setq elmo-msgdb-global-mark-alist + (elmo-object-load path)))) + match) + (if (setq match (assoc msgid malist)) + (setcdr match mark) + (setq elmo-msgdb-global-mark-alist + (nconc elmo-msgdb-global-mark-alist + (list (cons msgid mark))))) + (elmo-object-save path elmo-msgdb-global-mark-alist))) + +(defun elmo-msgdb-global-mark-get (msgid) + (cdr (assoc msgid (or elmo-msgdb-global-mark-alist + (setq elmo-msgdb-global-mark-alist + (elmo-object-load + (expand-file-name + elmo-msgdb-global-mark-filename + elmo-msgdb-dir))))))) + +;; +;; number <-> location handling +;; +(defsubst elmo-msgdb-location-load (dir) + (elmo-object-load + (expand-file-name + elmo-msgdb-location-filename + dir))) + +(defsubst elmo-msgdb-location-add (alist number location) + (let ((ret-val alist)) + (setq ret-val + (elmo-msgdb-append-element ret-val (cons number location))) + ret-val)) + +(defsubst elmo-msgdb-location-save (dir alist) + (elmo-object-save + (expand-file-name + elmo-msgdb-location-filename + dir) alist)) + +(defun elmo-list-folder-by-location (spec locations &optional msgdb) + (let* ((path (elmo-msgdb-expand-path nil spec)) + (location-alist (if msgdb + (elmo-msgdb-get-location msgdb) + (elmo-msgdb-location-load path))) + (locations-in-db (mapcar 'cdr location-alist)) + result new-locs new-alist deleted-locs i + modified) + (setq new-locs + (elmo-delete-if (function + (lambda (x) (member x locations-in-db))) + locations)) + (setq deleted-locs + (elmo-delete-if (function + (lambda (x) (member x locations))) + locations-in-db)) + (setq modified new-locs) + (setq i (or (elmo-max-of-list (mapcar 'car location-alist)) 0)) + (mapcar + (function + (lambda (x) + (setq location-alist + (delq (rassoc x location-alist) location-alist)))) + deleted-locs) + (while new-locs + (setq i (1+ i)) + (setq new-alist (cons (cons i (car new-locs)) new-alist)) + (setq new-locs (cdr new-locs))) + (setq result (nconc location-alist new-alist)) + (setq result (sort result (lambda (x y) (< (car x)(car y))))) + (if modified (elmo-msgdb-location-save path result)) + (mapcar 'car result))) + +;;; +;; persistent mark handling +;; (for each folder) +(defun elmo-msgdb-mark-set (alist id mark) + (let ((ret-val alist) + entity) + (setq entity (assq id alist)) + (if entity + (if (eq mark nil) + ;; delete this entity + (setq ret-val (delq entity alist)) + ;; set mark + (setcar (cdr entity) mark)) + (if mark + (setq ret-val (elmo-msgdb-append-element ret-val + (list id mark))))) + ret-val)) + +(defun elmo-msgdb-mark-append (alist id mark) + "Append mark" + (setq alist (elmo-msgdb-append-element alist + (list id mark)))) + +(defun elmo-msgdb-mark-alist-to-seen-list (number-alist mark-alist seen-marks) + "Make seen-list from mark-alist" + (let ((seen-mark-list (string-to-char-list seen-marks)) + ret-val ent) + (while number-alist + (if (setq ent (assq (car (car number-alist)) mark-alist)) + (if (and (cadr ent) + (memq (string-to-char (cadr ent)) seen-mark-list)) + (setq ret-val (cons (cdr (car number-alist)) ret-val))) + (setq ret-val (cons (cdr (car number-alist)) ret-val))) + (setq number-alist (cdr number-alist))) + ret-val)) + +;; +;; overview handling +;; + +(defsubst elmo-msgdb-get-field-value (field-name beg end buffer) + (save-excursion + (save-restriction + (set-buffer buffer) + (narrow-to-region beg end) + (elmo-field-body field-name)))) + +(defun elmo-multiple-field-body (name &optional boundary) + (save-excursion + (save-restriction + (std11-narrow-to-header boundary) + (goto-char (point-min)) + (let ((case-fold-search t) + (field-body nil)) + (while (re-search-forward (concat "^" name ":[ \t]*") nil t) + (setq field-body + (nconc field-body + (list (buffer-substring-no-properties + (match-end 0) (std11-field-end)))))) + field-body)))) + +(defun elmo-multiple-fields-body-list (field-names &optional boundary) + "Return list of each field-bodies of FIELD-NAMES of the message header +in current buffer. If BOUNDARY is not nil, it is used as message +header separator." + (save-excursion + (save-restriction + (std11-narrow-to-header boundary) + (let* ((case-fold-search t) + (s-rest field-names) + field-name field-body) + (while (setq field-name (car s-rest)) + (goto-char (point-min)) + (while (re-search-forward (concat "^" field-name ":[ \t]*") nil t) + (setq field-body + (nconc field-body + (list (buffer-substring-no-properties + (match-end 0) (std11-field-end)))))) + (setq s-rest (cdr s-rest))) + field-body)))) + +(defsubst elmo-msgdb-remove-field-string (string) + (if (string-match (concat std11-field-head-regexp "[ \t]*") string) + (substring string (match-end 0)) + string)) + +(defsubst elmo-msgdb-get-last-message-id (string) + (if string + (save-match-data + (let (beg) + (elmo-set-work-buf + (insert string) + (goto-char (point-max)) + (when (search-backward "<" nil t) + (setq beg (point)) + (if (search-forward ">" nil t) + (elmo-replace-in-string + (buffer-substring beg (point)) "\n[ \t]*" "")))))))) + +(defun elmo-msgdb-number-load (dir) + (elmo-object-load + (expand-file-name elmo-msgdb-number-filename dir))) + +(defun elmo-msgdb-overview-load (dir) + (elmo-object-load + (expand-file-name elmo-msgdb-overview-filename dir))) + +(defun elmo-msgdb-mark-load (dir) + (elmo-object-load + (expand-file-name elmo-msgdb-mark-filename dir))) + +(defsubst elmo-msgdb-seen-load (dir) + (elmo-object-load (expand-file-name + elmo-msgdb-seen-filename + dir))) + +(defun elmo-msgdb-number-save (dir obj) + (elmo-object-save + (expand-file-name elmo-msgdb-number-filename dir) + obj)) + +(defun elmo-msgdb-mark-save (dir obj) + (elmo-object-save + (expand-file-name elmo-msgdb-mark-filename dir) + obj)) + +(defsubst elmo-msgdb-seen-save (dir obj) + (elmo-object-save + (expand-file-name elmo-msgdb-seen-filename dir) + obj)) + +(defsubst elmo-msgdb-overview-save (dir overview) + (elmo-object-save + (expand-file-name elmo-msgdb-overview-filename dir) + overview)) + +(defun elmo-msgdb-delete-msgs (folder msgs msgdb &optional reserve-cache) + "Delete MSGS from FOLDER in MSGDB. +content of MSGDB is changed." + (save-excursion + (let* ((msg-list msgs) + (dir (elmo-msgdb-expand-path folder)) + (overview (or (car msgdb) + (elmo-msgdb-overview-load dir))) + (number-alist (or (cadr msgdb) + (elmo-msgdb-number-load dir))) + (mark-alist (or (caddr msgdb) + (elmo-msgdb-mark-load dir))) + message-id) + ;; remove from current database. + (while msg-list + (setq message-id (cdr (assq (car msg-list) number-alist))) + (if (and (not reserve-cache) message-id) + (elmo-cache-delete message-id + folder (car msg-list))) + ;; This is no good!!!! + ;(setq overview (delete (assoc message-id overview) overview)) + (setq overview + (delq + (elmo-msgdb-overview-get-entity-by-number overview + (car msg-list)) + overview)) + (setq number-alist + (delq (assq (car msg-list) number-alist) number-alist)) + (setq mark-alist (delq (assq (car msg-list) mark-alist) mark-alist)) + (setq msg-list (cdr msg-list))) + (setcar msgdb overview) + (setcar (cdr msgdb) number-alist) + (setcar (cddr msgdb) mark-alist)) + t)) ;return value + +(defsubst elmo-msgdb-set-overview (msgdb overview) + (setcar msgdb overview)) + +(defsubst elmo-msgdb-set-number-alist (msgdb number-alist) + (setcar (cdr msgdb) number-alist)) + +(defsubst elmo-msgdb-set-mark-alist (msgdb mark-alist) + (setcar (cddr msgdb) mark-alist)) + +(defsubst elmo-msgdb-overview-entity-get-references (entity) + (and entity (aref (cdr entity) 1))) + +;; entity -> parent-entity +(defsubst elmo-msgdb-overview-get-parent-entity (entity database) + (setq entity (elmo-msgdb-overview-entity-get-references entity)) + ;; entity is parent-id. + (and entity (assoc entity database))) + +(defsubst elmo-msgdb-overview-entity-get-number (entity) + (and entity (aref (cdr entity) 0))) + +(defsubst elmo-msgdb-overview-entity-get-from-no-decode (entity) + (and entity (aref (cdr entity) 2))) + +(defsubst elmo-msgdb-overview-entity-get-from (entity) + (and entity + (aref (cdr entity) 2) + (decode-mime-charset-string (aref (cdr entity) 2) + elmo-mime-charset))) + +(defsubst elmo-msgdb-overview-entity-set-number (entity number) + (and entity (aset (cdr entity) 0 number)) + entity) + ;(setcar (cadr entity) number) entity) + +(defsubst elmo-msgdb-overview-entity-set-from (entity from) + (and entity (aset (cdr entity) 2 from)) + entity) + +(defsubst elmo-msgdb-overview-entity-get-subject (entity) + (and entity + (aref (cdr entity) 3) + (decode-mime-charset-string (aref (cdr entity) 3) + elmo-mime-charset))) + +(defsubst elmo-msgdb-overview-entity-get-subject-no-decode (entity) + (and entity (aref (cdr entity) 3))) + +(defsubst elmo-msgdb-overview-entity-set-subject (entity subject) + (and entity (aset (cdr entity) 3 subject)) + entity) + +(defsubst elmo-msgdb-overview-entity-get-date (entity) + (and entity (aref (cdr entity) 4))) + +(defsubst elmo-msgdb-overview-entity-get-to (entity) + (and entity (aref (cdr entity) 5))) + +(defsubst elmo-msgdb-overview-entity-get-cc (entity) + (and entity (aref (cdr entity) 6))) + +(defsubst elmo-msgdb-overview-entity-get-size (entity) + (and entity (aref (cdr entity) 7))) + +(defsubst elmo-msgdb-overview-entity-get-id (entity) + (and entity (car entity))) + +(defsubst elmo-msgdb-overview-entity-get-extra-field (entity field-name) + (let ((extra (and entity (aref (cdr entity) 8)))) + (and extra + (cdr (assoc field-name extra))))) + +(defun elmo-msgdb-overview-get-entity-by-number (database number) + (let ((db database) + entity) + (catch 'loop + (while db + (if (eq (elmo-msgdb-overview-entity-get-number (car db)) number) + (progn + (setq entity (car db)) + (throw 'loop nil)) + (setq db (cdr db))))) + entity)) + +;; +;; deleted message handling +;; +(defun elmo-msgdb-killed-list-load (dir) + (elmo-object-load + (expand-file-name elmo-msgdb-killed-filename dir) + nil t)) + +(defun elmo-msgdb-killed-list-save (dir killed-list) + (elmo-object-save + (expand-file-name elmo-msgdb-killed-filename dir) + killed-list)) + +(defun elmo-msgdb-killed-message-p (killed-list msg) + (and killed-list + (not (listp + (catch 'found + (mapcar + (function + (lambda (entity) + (cond + ((integerp entity) + (if (eq entity msg) + (throw 'found t))) + ((consp entity) + (if (and (<= (car entity) msg) + (<= msg (cdr entity))) + (throw 'found t))))) + killed-list))))))) + +(defun elmo-msgdb-set-as-killed (killed-list msg) + "if cons cell, set car-cdr messages as killed. +if integer, set number th message as killed." + (let ((dlist killed-list) + (ret-val killed-list) + entity found) + (cond + ((integerp msg) + (while (and dlist (not found)) + (setq entity (car dlist)) + (if (or (and (integerp entity) (eq entity msg)) + (and (consp entity) + (<= (car entity) msg) + (<= msg (cdr entity)))) + (setq found t)) + (setq dlist (cdr dlist)) + ) + (if (not found) + (setq ret-val (elmo-msgdb-append-element killed-list msg))) + ) + ((consp msg) + (while (and dlist (not found)) + (setq entity (car dlist)) + (if (integerp entity) + (cond + ((and (<= (car msg) entity)(<= entity (cdr msg))) + (setcar dlist msg) + (setq found t) + ) + ((= (1- (car msg)) entity) + (setcar dlist (cons entity (cdr msg))) + (setq found t) + ) + ((= (1+ (cdr msg)) entity) + (setcar dlist (cons (car msg) entity)) + (setq found t) + )) + ;; entity is consp + (cond ; there are four patterns + ((and (<= (car msg) (car entity)) + (<= (cdr entity) (cdr msg))) + (setcar dlist msg) + (setq found t)) + ((and (< (car entity)(car msg)) + (< (cdr msg) (cdr entity))) + (setq found t)) + ((and (<= (car msg) (car entity)) + (<= (cdr msg) (cdr entity))) + (setcar dlist (cons (car msg) (cdr entity))) + (setq found t)) + ((and (<= (car entity) (car msg)) + (<= (cdr entity) (cdr msg))) + (setcar dlist (cons (car entity) (cdr msg))) + (setq found t)))) + (setq dlist (cdr dlist))) + (if (not found) + (setq ret-val (elmo-msgdb-append-element killed-list msg))))) + ret-val)) + +(defun elmo-msgdb-finfo-load () + (elmo-object-load (expand-file-name + elmo-msgdb-finfo-filename + elmo-msgdb-dir) + elmo-mime-charset t)) + +(defun elmo-msgdb-finfo-save (finfo) + (elmo-object-save (expand-file-name + elmo-msgdb-finfo-filename + elmo-msgdb-dir) + finfo elmo-mime-charset)) + +(defun elmo-msgdb-flist-load (folder) + (let ((flist-file (expand-file-name + elmo-msgdb-flist-filename + (elmo-msgdb-expand-path folder (list 'folder folder))))) + (elmo-object-load flist-file nil t))) + +(defun elmo-msgdb-flist-save (folder flist) + (let ((flist-file (expand-file-name + elmo-msgdb-flist-filename + (elmo-msgdb-expand-path folder (list 'folder folder))))) + (elmo-object-save flist-file flist))) + +(defun elmo-crosspost-alist-load () + (elmo-object-load (expand-file-name + elmo-crosspost-alist-filename + elmo-msgdb-dir) + nil t)) + +(defun elmo-crosspost-alist-save (alist) + (elmo-object-save (expand-file-name + elmo-crosspost-alist-filename + elmo-msgdb-dir) + alist)) + +(defsubst elmo-msgdb-create-overview-from-buffer (number &optional size time) + "Create overview entity from current buffer. +Header region is supposed to be narrowed." + (save-excursion + (let ((extras elmo-msgdb-extra-fields) + message-id references from subject to cc date + extra field-body) + (elmo-set-buffer-multibyte default-enable-multibyte-characters) + (setq message-id (elmo-field-body "message-id")) + (setq references + (or (elmo-msgdb-get-last-message-id + (elmo-field-body "in-reply-to")) + (elmo-msgdb-get-last-message-id + (elmo-field-body "references")))) + (setq from (elmo-mime-string (elmo-delete-char + ?\" + (or + (elmo-field-body "from") + elmo-no-from)))) + (setq subject (elmo-mime-string (or (elmo-field-body "subject") + elmo-no-subject))) + (setq date (or (elmo-field-body "date") time)) + (setq to (mapconcat 'identity (elmo-multiple-field-body "to") ",")) + (setq cc (mapconcat 'identity (elmo-multiple-field-body "cc") ",")) + (or size + (if (setq size (elmo-field-body "content-length")) + (setq size (string-to-int size)) + (setq size 0)));; No mean... + (while extras + (if (setq field-body (elmo-field-body (car extras))) + (setq extra (cons (cons (downcase (car extras)) + field-body) extra))) + (setq extras (cdr extras))) + (cons message-id (vector number references + from subject date to cc + size extra)) + ))) + +(defun elmo-msgdb-overview-sort-by-date (overview) + (sort overview + (function + (lambda (x y) + (condition-case nil + (string< + (timezone-make-date-sortable + (elmo-msgdb-overview-entity-get-date x)) + (timezone-make-date-sortable + (elmo-msgdb-overview-entity-get-date y))) + (error)))))) + +(defun elmo-msgdb-sort-by-date (msgdb) + (message "Sorting...") + (let ((overview (elmo-msgdb-get-overview msgdb))) + (setq overview (elmo-msgdb-overview-sort-by-date overview)) + (message "Sorting...done.") + (list overview (nth 1 msgdb)(nth 2 msgdb)))) + +(defsubst elmo-msgdb-search-overview-entity (number number-alist overview) + (let ((message-id (cdr (assq number number-alist))) + ovs) + (if message-id + (assoc message-id overview) + (elmo-msgdb-overview-get-entity-by-number overview number)))) + +(defsubst elmo-msgdb-append (msgdb msgdb-append) + (list + (nconc (car msgdb) (car msgdb-append)) + (nconc (cadr msgdb) (cadr msgdb-append)) + (nconc (caddr msgdb) (caddr msgdb-append)) + (nconc (cadddr msgdb) (cadddr msgdb-append)))) + +(defun elmo-msgdb-delete-path (folder &optional spec) + (let ((path (elmo-msgdb-expand-path folder spec))) + (if (file-directory-p path) + (elmo-delete-directory path t)))) + +(defun elmo-msgdb-rename-path (old-folder new-folder &optional old-spec new-spec) + (let* ((old (directory-file-name (elmo-msgdb-expand-path old-folder old-spec))) + (new (directory-file-name (elmo-msgdb-expand-path new-folder new-spec))) + (new-dir (directory-file-name (file-name-directory new)))) + (if (not (file-directory-p old)) + () + (if (file-exists-p new) + (error "already exists directory: %s" new) + (if (not (file-exists-p new-dir)) + (elmo-make-directory new-dir)) + (rename-file old new))))) + +(provide 'elmo-msgdb) + +;;; elmo-msgdb.el ends here diff --git a/elmo/elmo-multi.el b/elmo/elmo-multi.el new file mode 100644 index 0000000..afa7669 --- /dev/null +++ b/elmo/elmo-multi.el @@ -0,0 +1,365 @@ +;;; elmo-multi.el -- Multiple Folder Interface for ELMO. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <00/03/14 19:41:07 teranisi> + +;; This file is part of ELMO (Elisp Library for Message Orchestration). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; + +(require 'elmo-msgdb) +(require 'elmo-vars) +(require 'elmo2) + +(defun elmo-multi-msgdb (msgdb base) + (list (mapcar (function + (lambda (x) + (elmo-msgdb-overview-entity-set-number + x + (+ base + (elmo-msgdb-overview-entity-get-number x))))) + (nth 0 msgdb)) + (mapcar (function + (lambda (x) (cons + (+ base (car x)) + (cdr x)))) + (nth 1 msgdb)) + (mapcar (function + (lambda (x) (cons + (+ base (car x)) + (cdr x)))) (nth 2 msgdb)))) + +(defun elmo-multi-msgdb-create-as-numlist (spec numlist new-mark already-mark + seen-mark important-mark + seen-list) + (when numlist + (let* ((flds (cdr spec)) + overview number-alist mark-alist entity + one-list-list + cur-number + i percent num + ret-val) + (setq one-list-list (elmo-multi-get-intlist-list numlist)) + (setq cur-number 0) + (while (< cur-number (length flds)) + (setq ret-val + (elmo-msgdb-append + ret-val + (elmo-multi-msgdb + (elmo-msgdb-create-as-numlist (nth cur-number flds) + (nth cur-number one-list-list) + new-mark already-mark + seen-mark important-mark + seen-list) + (* elmo-multi-divide-number (1+ cur-number))))) + (setq cur-number (1+ cur-number))) + (elmo-msgdb-sort-by-date ret-val)))) + +;; returns append-msgdb +(defun elmo-multi-delete-crossposts (already-msgdb append-msgdb) + (let* ((number-alist (elmo-msgdb-get-number-alist append-msgdb)) + (dummy (copy-sequence (append + number-alist + (elmo-msgdb-get-number-alist already-msgdb)))) + (cur number-alist) + to-be-deleted + overview mark-alist + same) + (while cur + (setq dummy (delq (car cur) dummy)) + (if (setq same (rassoc (cdr (car cur)) dummy)) ;; same message id is remained + (unless (= (/ (car (car cur)) elmo-multi-divide-number) + (/ (car same) elmo-multi-divide-number)) + ;; base is also same...delete it! + (setq to-be-deleted (append to-be-deleted (list (car cur)))))) + (setq cur (cdr cur))) + (setq overview (elmo-delete-if + (function + (lambda (x) + (assq + (elmo-msgdb-overview-entity-get-number x) + to-be-deleted))) + (elmo-msgdb-get-overview append-msgdb))) + (setq mark-alist (elmo-delete-if + (function + (lambda (x) + (assq + (car x) to-be-deleted))) + (elmo-msgdb-get-mark-alist append-msgdb))) + ;; keep number-alist untouched for folder diff!! + (cons (and to-be-deleted (length to-be-deleted)) + (list overview number-alist mark-alist)))) + +(defun elmo-multi-msgdb-create (spec numlist new-mark already-mark + seen-mark important-mark seen-list) + (when numlist + (let* ((flds (cdr spec)) + overview number-alist mark-alist entity + one-list-list + cur-number + i percent num + ret-val) + (setq one-list-list (elmo-multi-get-intlist-list numlist)) + (setq cur-number 0) + (while (< cur-number (length flds)) + (setq ret-val + (elmo-msgdb-append + ret-val + (elmo-multi-msgdb + (elmo-msgdb-create (nth cur-number flds) + (nth cur-number one-list-list) + new-mark already-mark + seen-mark important-mark + seen-list) + (* elmo-multi-divide-number (1+ cur-number))))) + (setq cur-number (1+ cur-number))) + (elmo-msgdb-sort-by-date ret-val)))) + +(defun elmo-multi-list-folders (spec &optional hierarchy) + ;; not implemented. + nil) + +(defun elmo-multi-append-msg (spec string) + (error "Cannot append messages to multi folder")) + +(defun elmo-multi-read-msg (spec number outbuf) + (let* ((flds (cdr spec)) + (folder (nth (- (/ number elmo-multi-divide-number) 1) flds)) + (number (% number elmo-multi-divide-number))) + (elmo-call-func folder "read-msg" number outbuf))) + +(defun elmo-multi-delete-msgs (spec msgs) + (let ((flds (cdr spec)) + one-list-list + (cur-number 0)) + (setq one-list-list (elmo-multi-get-intlist-list msgs)) + (while (< cur-number (length flds)) + (elmo-delete-msgs (nth cur-number flds) + (nth cur-number one-list-list)) + (setq cur-number (+ 1 cur-number))) + t)) + +(defun elmo-multi-mark-alist-list (mark-alist) + (let ((cur-number 0) + one-alist result) + (while mark-alist + (setq cur-number (+ cur-number 1)) + (setq one-alist nil) + (while (and mark-alist + (eq 0 + (/ (- (car (car mark-alist)) + (* elmo-multi-divide-number cur-number)) + elmo-multi-divide-number))) + (setq one-alist (nconc + one-alist + (list + (list (% (car (car mark-alist)) + (* elmo-multi-divide-number cur-number)) + (cadr (car mark-alist)))))) + (setq mark-alist (cdr mark-alist))) + (setq result (nconc result (list one-alist)))) + result)) + +(defun elmo-multi-list-folder-unread (spec mark-alist unread-marks) + (let* ((flds (cdr spec)) + (cur-number 0) + mark-alist-list + ret-val) + (setq mark-alist-list (elmo-multi-mark-alist-list mark-alist)) + (while flds + (setq cur-number (+ cur-number 1)) + (setq ret-val (append + ret-val + (mapcar + (function + (lambda (x) + (+ + (* elmo-multi-divide-number cur-number) x))) + (elmo-list-folder-unread (car flds) + (car mark-alist-list) + unread-marks)))) + (setq mark-alist-list (cdr mark-alist-list)) + (setq flds (cdr flds))) + ret-val)) + +(defun elmo-multi-list-folder-important (spec overview) + (let* ((flds (cdr spec)) + (cur-number 0) + ret-val) + (while flds + (setq cur-number (+ cur-number 1)) + (setq ret-val (append + ret-val + (mapcar + (function + (lambda (x) + (+ + (* elmo-multi-divide-number cur-number) x))) + (elmo-list-folder-important (car flds) overview)))) + (setq flds (cdr flds))) + ret-val)) + +(defun elmo-multi-list-folder (spec) + (let* ((flds (cdr spec)) + (cur-number 0) + ret-val) + (while flds + (setq cur-number (+ cur-number 1)) + (setq ret-val (append + ret-val + (mapcar + (function + (lambda (x) + (+ + (* elmo-multi-divide-number cur-number) x))) + (elmo-list-folder (car flds))))) + (setq flds (cdr flds))) + ret-val)) + +(defun elmo-multi-folder-exists-p (spec) + (let* ((flds (cdr spec))) + (catch 'exists + (while flds + (unless (elmo-folder-exists-p (car flds)) + (throw 'exists nil)) + (setq flds (cdr flds))) + t))) + +(defun elmo-multi-folder-creatable-p (spec) + (let* ((flds (cdr spec))) + (catch 'creatable + (while flds + (when (and (elmo-call-func (car flds) "folder-creatable-p") + (not (elmo-folder-exists-p (car flds)))) + ;; If folder already exists, don't to `creatable'. + ;; Because this function is called, when folder doesn't exists. + (throw 'creatable t)) + (setq flds (cdr flds))) + nil))) + +(defun elmo-multi-create-folder (spec) + (let* ((flds (cdr spec))) + (catch 'create + (while flds + (unless (or (elmo-folder-exists-p (car flds)) + (elmo-create-folder (car flds))) + (throw 'create nil)) + (setq flds (cdr flds))) + t))) + +(defun elmo-multi-search (spec condition &optional numlist) + (let* ((flds (cdr spec)) + (cur-number 0) + numlist-list cur-numlist ; for filtered search. + ret-val) + (if numlist + (setq numlist-list + (elmo-multi-get-intlist-list numlist t))) + (while flds + (setq cur-number (+ cur-number 1)) + (when numlist + (setq cur-numlist (car numlist-list)) + (if (null cur-numlist) + ;; t means filter all. + (setq cur-numlist t))) + (setq ret-val (append + ret-val + (elmo-list-filter + cur-numlist + (mapcar + (function + (lambda (x) + (+ + (* elmo-multi-divide-number cur-number) x))) + (elmo-call-func + (car flds) "search" condition))))) + (when numlist + (setq numlist-list (cdr numlist-list))) + (setq flds (cdr flds))) + ret-val)) + +(defun elmo-multi-use-cache-p (spec number) + (elmo-call-func (nth (- (/ number elmo-multi-divide-number) 1) + (cdr spec)) + "use-cache-p" + (% number elmo-multi-divide-number))) + +(defun elmo-multi-local-file-p (spec number) + (elmo-call-func (nth (- (/ number elmo-multi-divide-number) 1) + (cdr spec)) + "local-file-p" + (% number elmo-multi-divide-number))) + +(defun elmo-multi-commit (spec) + (mapcar 'elmo-commit (cdr spec))) + +(defun elmo-multi-plugged-p (spec) + (let* ((flds (cdr spec))) + (catch 'plugged + (while flds + (unless (elmo-folder-plugged-p (car flds)) + (throw 'plugged nil)) + (setq flds (cdr flds))) + t))) + +(defun elmo-multi-set-plugged (spec plugged add) + (let* ((flds (cdr spec))) + (while flds + (elmo-folder-set-plugged (car flds) plugged add) + (setq flds (cdr flds))))) + +(defun elmo-multi-get-msg-filename (spec number &optional loc-alist) + (elmo-call-func (nth (- (/ number elmo-multi-divide-number) 1) + (cdr spec)) + "get-msg-filename" + (% number elmo-multi-divide-number) + loc-alist)) + +(defun elmo-multi-sync-number-alist (spec number-alist) + (let ((folder-list (cdr spec)) + (number-alist-list + (elmo-multi-get-number-alist-list number-alist)) + (multi-base 0) + append-alist result-alist) + (while folder-list + (incf multi-base) + (setq append-alist + (elmo-call-func (nth (- multi-base 1) (cdr spec)) ;; folder name + "sync-number-alist" + (nth (- multi-base 1) number-alist-list))) + (mapcar + (function + (lambda (x) + (setcar x + (+ (* elmo-multi-divide-number multi-base) (car x))))) + append-alist) + (setq result-alist (nconc result-alist append-alist)) + (setq folder-list (cdr folder-list))) + result-alist)) + +(provide 'elmo-multi) + +;;; elmo-multi.el ends here diff --git a/elmo/elmo-nntp.el b/elmo/elmo-nntp.el new file mode 100644 index 0000000..ee7dda8 --- /dev/null +++ b/elmo/elmo-nntp.el @@ -0,0 +1,1349 @@ +;;; elmo-nntp.el -- NNTP Interface for ELMO. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <00/03/14 19:41:50 teranisi> + +;; This file is part of ELMO (Elisp Library for Message Orchestration). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; + +(require 'elmo-msgdb) +(eval-when-compile + (condition-case nil + (progn + (require 'starttls)) + (error)) + (require 'elmo-cache) + (require 'elmo-util) + (defun-maybe starttls-negotiate (a))) + +;; +;; internal variables +;; + +(defvar elmo-nntp-connection-cache nil + "Cache of NNTP connection.") +;; buffer local variable + +(defvar elmo-nntp-list-folders-use-cache 600 + "*Time to cache of list folders, as the number of seconds. +Don't cache if nil.") + +(defvar elmo-nntp-list-folders-cache nil) +(defvar elmo-nntp-groups-hashtb nil) +(defvar elmo-nntp-groups-async nil) +(defvar elmo-nntp-header-fetch-chop-length 200) + +(defvar elmo-nntp-read-point 0) + +(defvar elmo-nntp-send-mode-reader t) + +(defvar elmo-nntp-opened-hook nil) + +(defvar elmo-nntp-get-folders-securely nil) + +(defvar elmo-nntp-default-use-xover t) + +(defvar elmo-nntp-default-use-listgroup t) + +(defvar elmo-nntp-default-use-list-active t) + +(defvar elmo-nntp-server-command-alist nil) + + +(defconst elmo-nntp-server-command-index '((xover . 0) + (listgroup . 1) + (list-active . 2))) + +(put 'elmo-nntp-setting 'lisp-indent-function 1) + +(defmacro elmo-nntp-setting (spec &rest body) + (` (let* ((ssl (elmo-nntp-spec-ssl (, spec))) + (port (elmo-nntp-spec-port (, spec))) + (user (elmo-nntp-spec-username (, spec))) + (server (elmo-nntp-spec-hostname (, spec))) + (folder (elmo-nntp-spec-group (, spec))) + (connection (elmo-nntp-get-connection server user port ssl)) + (buffer (car connection)) + (process (cadr connection))) + (,@ body)))) + +(defmacro elmo-nntp-get-server-command (server port) + (` (assoc (cons (, server) (, port)) elmo-nntp-server-command-alist))) + +(defmacro elmo-nntp-set-server-command (server port com value) + (` (let (entry) + (unless (setq entry (cdr (elmo-nntp-get-server-command + (, server) (, port)))) + (setq elmo-nntp-server-command-alist + (nconc elmo-nntp-server-command-alist + (list (cons (cons (, server) (, port)) + (setq entry + (vector + elmo-nntp-default-use-xover + elmo-nntp-default-use-listgroup + elmo-nntp-default-use-list-active)) + ))))) + (aset entry + (cdr (assq (, com) elmo-nntp-server-command-index)) + (, value))))) + +(defmacro elmo-nntp-xover-p (server port) + (` (let ((entry (elmo-nntp-get-server-command (, server) (, port)))) + (if entry + (aref (cdr entry) + (cdr (assq 'xover elmo-nntp-server-command-index))) + elmo-nntp-default-use-xover)))) + +(defmacro elmo-nntp-set-xover (server port value) + (` (elmo-nntp-set-server-command (, server) (, port) 'xover (, value)))) + +(defmacro elmo-nntp-listgroup-p (server port) + (` (let ((entry (elmo-nntp-get-server-command (, server) (, port)))) + (if entry + (aref (cdr entry) + (cdr (assq 'listgroup elmo-nntp-server-command-index))) + elmo-nntp-default-use-listgroup)))) + +(defmacro elmo-nntp-set-listgroup (server port value) + (` (elmo-nntp-set-server-command (, server) (, port) 'listgroup (, value)))) + +(defmacro elmo-nntp-list-active-p (server port) + (` (let ((entry (elmo-nntp-get-server-command (, server) (, port)))) + (if entry + (aref (cdr entry) + (cdr (assq 'list-active elmo-nntp-server-command-index))) + elmo-nntp-default-use-list-active)))) + +(defmacro elmo-nntp-set-list-active (server port value) + (` (elmo-nntp-set-server-command (, server) (, port) 'list-active (, value)))) + +(defsubst elmo-nntp-max-number-precedes-list-active-p () + elmo-nntp-max-number-precedes-list-active) + +(defsubst elmo-nntp-folder-postfix (user server port ssl) + (concat + (and user (concat ":" user)) + (if (and server + (null (string= server elmo-default-nntp-server))) + (concat "@" server)) + (if (and port + (null (eq port elmo-default-nntp-port))) + (concat ":" (if (numberp port) + (int-to-string port) port))) + (unless (eq ssl elmo-default-nntp-ssl) + (if (eq ssl 'starttls) + "!!" + (if ssl "!"))))) + +(defun elmo-nntp-flush-connection () + (interactive) + (let ((cache elmo-nntp-connection-cache) + buffer process) + (while cache + (setq buffer (car (cdr (car cache)))) + (if buffer (kill-buffer buffer)) + (setq process (car (cdr (cdr (car cache))))) + (if process (delete-process process)) + (setq cache (cdr cache))) + (setq elmo-nntp-connection-cache nil))) + +(defun elmo-nntp-get-connection (server user port ssl) + (let* ((user-at-host (format "%s@%s" user server)) + (user-at-host-on-port (concat + user-at-host ":" (int-to-string port) + (if (eq ssl 'starttls) "!!" (if ssl "!")))) + ret-val result buffer process errmsg proc-stat) + (if (not (elmo-plugged-p server port)) + (error "Unplugged")) + (setq ret-val (assoc user-at-host-on-port elmo-nntp-connection-cache)) + (if (and ret-val + (or (eq (setq proc-stat + (process-status (cadr (cdr ret-val)))) + 'closed) + (eq proc-stat 'exit))) + ;; connection is closed... + (progn + (kill-buffer (car (cdr ret-val))) + (setq elmo-nntp-connection-cache + (delete ret-val elmo-nntp-connection-cache)) + (setq ret-val nil))) + (if ret-val + (cdr ret-val) + (setq result (elmo-nntp-open-connection server user port ssl)) + (if (null result) + (progn + (if process (delete-process process)) + (if buffer (kill-buffer buffer)) + (error "Connection failed")) + (setq buffer (car result)) + (setq process (cdr result)) + (setq elmo-nntp-connection-cache + (nconc elmo-nntp-connection-cache + (list + (cons user-at-host-on-port + (setq ret-val (list buffer process nil)))))) + ret-val)))) + +(defun elmo-nntp-process-filter (process output) + (save-excursion + (set-buffer (process-buffer process)) + (goto-char (point-max)) + (insert output))) + +(defun elmo-nntp-read-response (buffer process &optional not-command) + (save-excursion + (set-buffer buffer) + (let ((case-fold-search nil) + (response-string nil) + (response-continue t) + (return-value nil) + match-end) + (while response-continue + (goto-char elmo-nntp-read-point) + (while (not (search-forward "\r\n" nil t)) + (accept-process-output process) + (goto-char elmo-nntp-read-point)) + + (setq match-end (point)) + (setq response-string + (buffer-substring elmo-nntp-read-point (- match-end 2))) + (goto-char elmo-nntp-read-point) + (if (looking-at "[23][0-9]+ .*$") + (progn (setq response-continue nil) + (setq elmo-nntp-read-point match-end) + (setq return-value + (if return-value + (concat return-value "\n" response-string) + response-string))) + (if (looking-at "[^23][0-9]+ .*$") + (progn (setq response-continue nil) + (setq elmo-nntp-read-point match-end) + (setq return-value nil)) + (setq elmo-nntp-read-point match-end) + (if not-command + (setq response-continue nil)) + (setq return-value + (if return-value + (concat return-value "\n" response-string) + response-string))) + (setq elmo-nntp-read-point match-end))) + return-value))) + +(defun elmo-nntp-read-raw-response (buffer process) + (save-excursion + (set-buffer buffer) + (let ((case-fold-search nil)) + (goto-char elmo-nntp-read-point) + (while (not (search-forward "\r\n" nil t)) + (accept-process-output process) + (goto-char elmo-nntp-read-point)) + (buffer-substring elmo-nntp-read-point (- (point) 2))))) + +(defun elmo-nntp-read-contents (buffer process) + (save-excursion + (set-buffer buffer) + (let ((case-fold-search nil) + match-end) + (goto-char elmo-nntp-read-point) + (while (not (re-search-forward "^\\.\r\n" nil t)) + (accept-process-output process) + (goto-char elmo-nntp-read-point)) + (setq match-end (point)) + (elmo-delete-cr + (buffer-substring elmo-nntp-read-point + (- match-end 3)))))) + +(defun elmo-nntp-read-body (buffer process outbuf) + (with-current-buffer buffer + (let ((start elmo-nntp-read-point) + end) + (goto-char start) + (while (not (re-search-forward "^\\.\r\n" nil t)) + (accept-process-output process) + (goto-char start)) + (setq end (point)) + (with-current-buffer outbuf + (erase-buffer) + (insert-buffer-substring buffer start (- end 3)) + (elmo-delete-cr-get-content-type))))) + +(defun elmo-nntp-goto-folder (server folder user port ssl) + (let* ((connection (elmo-nntp-get-connection server user port ssl)) + (buffer (car connection)) + (process (cadr connection)) + (cwf (caddr connection))) + (save-excursion + (condition-case () + (if (not (string= cwf folder)) + (progn + (elmo-nntp-send-command buffer + process + (format "group %s" folder)) + (if (elmo-nntp-read-response buffer process) + (setcar (cddr connection) folder))) + t) + (error + nil))))) + +(defun elmo-nntp-list-folders-get-cache (folder buf) + (when (and elmo-nntp-list-folders-use-cache + elmo-nntp-list-folders-cache + (string-match (concat "^" + (regexp-quote + (or + (nth 1 elmo-nntp-list-folders-cache) + ""))) + (or folder ""))) + (let* ((cache-time (car elmo-nntp-list-folders-cache))) + (unless (elmo-time-expire cache-time + elmo-nntp-list-folders-use-cache) + (save-excursion + (set-buffer buf) + (erase-buffer) + (insert (nth 2 elmo-nntp-list-folders-cache)) + (goto-char (point-min)) + (and folder + (keep-lines (concat "^" (regexp-quote folder) "\\."))) + t + ))))) + +(defsubst elmo-nntp-catchup-msgdb (msgdb max-number) + (let (msgdb-max number-alist) + (setq number-alist (elmo-msgdb-get-number-alist msgdb)) + (setq msgdb-max (car (nth (max (- (length number-alist) 1) 0) + number-alist))) + (if (or (not msgdb-max) + (and msgdb-max max-number + (< msgdb-max max-number))) + (elmo-msgdb-set-number-alist + msgdb + (nconc number-alist (list (cons max-number nil))))))) + +(defun elmo-nntp-list-folders (spec &optional hierarchy) + (elmo-nntp-setting spec + (let* ((cwf (caddr connection)) + (tmp-buffer (get-buffer-create " *ELMO NNTP list folders TMP*")) + response ret-val top-ng append-serv use-list-active start) + (save-excursion + (set-buffer tmp-buffer) + (if (and folder + (elmo-nntp-goto-folder server folder user port ssl)) + (setq ret-val (list folder))) ;; add top newsgroups + (unless (setq response (elmo-nntp-list-folders-get-cache + folder tmp-buffer)) + (when (setq use-list-active (elmo-nntp-list-active-p server port)) + (elmo-nntp-send-command buffer + process + (concat "list" + (if (and folder + (null (string= folder ""))) + (concat " active" + (format " %s.*" folder) "")))) + (if (elmo-nntp-read-response buffer process t) + (if (null (setq response (elmo-nntp-read-contents + buffer process))) + (error "NNTP List folders failed") + (when elmo-nntp-list-folders-use-cache + (setq elmo-nntp-list-folders-cache + (list (current-time) folder response))) + (erase-buffer) + (insert response)) + (elmo-nntp-set-list-active server port nil) + (setq use-list-active nil))) + (when (null use-list-active) + (elmo-nntp-send-command buffer process "list") + (if (null (and (elmo-nntp-read-response buffer process t) + (setq response (elmo-nntp-read-contents + buffer process)))) + (error "NNTP List folders failed")) + (when elmo-nntp-list-folders-use-cache + (setq elmo-nntp-list-folders-cache + (list (current-time) nil response))) + (erase-buffer) + (setq start nil) + (while (string-match (concat "^" + (regexp-quote + (or folder "")) ".*$") + response start) + (insert (match-string 0 response) "\n") + (setq start (match-end 0))))) + (goto-char (point-min)) + (let ((len (count-lines (point-min) (point-max))) + (i 0) regexp) + (if hierarchy + (progn + (setq regexp + (format "^\\(%s[^. ]+\\)\\([. ]\\).*\n" + (if folder (concat folder "\\.") ""))) + (while (looking-at regexp) + (setq top-ng (elmo-match-buffer 1)) + (if (string= (elmo-match-buffer 2) " ") + (if (not (or (member top-ng ret-val) + (assoc top-ng ret-val))) + (setq ret-val (nconc ret-val (list top-ng)))) + (if (member top-ng ret-val) + (setq ret-val (delete top-ng ret-val))) + (if (not (assoc top-ng ret-val)) + (setq ret-val (nconc ret-val (list (list top-ng)))))) + (setq i (1+ i)) + (and (zerop (% i 10)) + (elmo-display-progress + 'elmo-nntp-list-folders "Parsing active..." + (/ (* i 100) len))) + (forward-line 1) + )) + (while (re-search-forward "\\([^ ]+\\) .*\n" nil t) + (setq ret-val (nconc ret-val + (list (elmo-match-buffer 1)))) + (setq i (1+ i)) + (and (zerop (% i 10)) + (elmo-display-progress + 'elmo-nntp-list-folders "Parsing active..." + (/ (* i 100) len)))))) + (kill-buffer tmp-buffer) + (unless (string= server elmo-default-nntp-server) + (setq append-serv (concat "@" server))) + (unless (eq port elmo-default-nntp-port) + (setq append-serv (concat append-serv ":" (int-to-string port)))) + (unless (eq ssl elmo-default-nntp-ssl) + (if ssl + (setq append-serv (concat append-serv "!"))) + (if (eq ssl 'starttls) + (setq append-serv (concat append-serv "!")))) + (mapcar '(lambda (fld) + (if (consp fld) + (list (concat "-" (car fld) + (and user + (concat ":" user)) + (and append-serv + (concat append-serv)))) + (concat "-" fld + (and user + (concat ":" user)) + (and append-serv + (concat append-serv))))) + ret-val))))) + +(defun elmo-nntp-make-msglist (beg-str end-str) + (elmo-set-work-buf + (let ((beg-num (string-to-int beg-str)) + (end-num (string-to-int end-str)) + i) + (setq i beg-num) + (insert "(") + (while (<= i end-num) + (insert (format "%s " i)) + (setq i (1+ i))) + (insert ")") + (goto-char (point-min)) + (read (current-buffer))))) + +(defun elmo-nntp-list-folder (spec) + (elmo-nntp-setting spec + (let* ((server (format "%s" server)) ;; delete text property + response retval use-listgroup) + (save-excursion + (when (setq use-listgroup (elmo-nntp-listgroup-p server port)) + (elmo-nntp-send-command buffer + process + (format "listgroup %s" folder)) + (if (not (elmo-nntp-read-response buffer process t)) + (progn + (elmo-nntp-set-listgroup server port nil) + (setq use-listgroup nil)) + (if (null (setq response (elmo-nntp-read-contents buffer process))) + (error "Fetching listgroup failed")) + (setq retval (elmo-string-to-list response)))) + (if use-listgroup + retval + (elmo-nntp-send-command buffer + process + (format "group %s" folder)) + (if (null (setq response (elmo-nntp-read-response buffer process))) + (error "Select folder failed")) + (setcar (cddr connection) folder) + (if (and + (string-match "211 \\([0-9]+\\) \\([0-9]+\\) \\([0-9]+\\) [^.].+$" + response) + (> (string-to-int (elmo-match-string 1 response)) 0)) + (elmo-nntp-make-msglist + (elmo-match-string 2 response) + (elmo-match-string 3 response)) + nil)))))) + +(defun elmo-nntp-max-of-folder (spec) + (let* ((port (elmo-nntp-spec-port spec)) + (user (elmo-nntp-spec-username spec)) + (server (elmo-nntp-spec-hostname spec)) + (ssl (elmo-nntp-spec-ssl spec)) + (folder (elmo-nntp-spec-group spec))) + (if elmo-nntp-groups-async + (let* ((fld (concat folder + (elmo-nntp-folder-postfix user server port ssl))) + (entry (elmo-get-hash-val fld elmo-nntp-groups-hashtb))) + (if entry + (cons (nth 2 entry) + (car entry)) + (error "No such newsgroup \"%s\"" fld))) + (let* ((connection (elmo-nntp-get-connection server user port ssl)) + (buffer (car connection)) + (process (cadr connection)) + response e-num end-num) + (if (not connection) + (error "Connection failed")) + (save-excursion + (elmo-nntp-send-command buffer + process + (format "group %s" folder)) + (setq response (elmo-nntp-read-response buffer process)) + (if (and response + (string-match + "211 \\([0-9]+\\) \\([0-9]+\\) \\([0-9]+\\) [^.].+$" + response)) + (progn + (setq end-num (string-to-int + (elmo-match-string 3 response))) + (setq e-num (string-to-int + (elmo-match-string 1 response))) + (cons end-num e-num)) + (if (null response) + (error "Selecting newsgroup \"%s\" failed" folder) + nil))))))) + +(defconst elmo-nntp-overview-index + '(("number" . 0) + ("subject" . 1) + ("from" . 2) + ("date" . 3) + ("message-id" . 4) + ("references" . 5) + ("size" . 6) + ("lines" . 7) + ("xref" . 8))) + +(defun elmo-nntp-create-msgdb-from-overview-string (str + folder + new-mark + already-mark + seen-mark + important-mark + seen-list + &optional numlist) + (let (ov-list gmark message-id seen + ov-entity overview number-alist mark-alist num + extras extra ext field field-index) + (setq ov-list (elmo-nntp-parse-overview-string str)) + (while ov-list + (setq ov-entity (car ov-list)) + ;; INN bug?? +; (if (or (> (setq num (string-to-int (aref ov-entity 0))) +; 99999) +; (<= num 0)) +; (setq num 0)) +; (setq num (int-to-string num)) + (setq num (string-to-int (aref ov-entity 0))) + (when (or (null numlist) + (memq num numlist)) + (setq extras elmo-msgdb-extra-fields + extra nil) + (while extras + (setq ext (downcase (car extras))) + (when (setq field-index (cdr (assoc ext elmo-nntp-overview-index))) + (setq field (aref ov-entity field-index)) + (when (eq field-index 8) ;; xref + (setq field (elmo-msgdb-remove-field-string field))) + (setq extra (cons (cons ext field) extra))) + (setq extras (cdr extras))) + (setq overview + (elmo-msgdb-append-element + overview + (cons (aref ov-entity 4) + (vector num + (elmo-msgdb-get-last-message-id + (aref ov-entity 5)) + ;; from + (elmo-mime-string (elmo-delete-char + ?\" + (or + (aref ov-entity 2) + elmo-no-from) 'uni)) + ;; subject + (elmo-mime-string (or (aref ov-entity 1) + elmo-no-subject)) + (aref ov-entity 3) ;date + nil ; to + nil ; cc + (string-to-int + (aref ov-entity 6)) ; size + extra ; extra-field-list + )))) + (setq number-alist + (elmo-msgdb-number-add number-alist num + (aref ov-entity 4))) + (setq message-id (aref ov-entity 4)) + (setq seen (member message-id seen-list)) + (if (setq gmark (or (elmo-msgdb-global-mark-get message-id) + (if (elmo-cache-exists-p message-id);; XXX + (if seen + nil + already-mark) + (if seen + (if elmo-nntp-use-cache + seen-mark) + new-mark)))) + (setq mark-alist + (elmo-msgdb-mark-append mark-alist + num gmark)))) + (setq ov-list (cdr ov-list))) + (list overview number-alist mark-alist))) + +(defun elmo-nntp-msgdb-create-as-numlist (spec numlist new-mark already-mark + seen-mark important-mark + seen-list) + "Create msgdb for SPEC for NUMLIST." + (elmo-nntp-msgdb-create spec numlist new-mark already-mark + seen-mark important-mark seen-list + t)) + +(defun elmo-nntp-msgdb-create (spec numlist new-mark already-mark + seen-mark important-mark + seen-list &optional as-num) + (when numlist + (save-excursion + (elmo-nntp-setting spec + (let* ((cwf (caddr connection)) + (filter (and as-num numlist)) + beg-num end-num cur length + ret-val ov-str use-xover) + (if (and folder + (not (string= cwf folder)) + (null (elmo-nntp-goto-folder server folder user port ssl))) + (error "group %s not found" folder)) + (when (setq use-xover (elmo-nntp-xover-p server port)) + (setq beg-num (car numlist) + cur beg-num + end-num (nth (1- (length numlist)) numlist) + length (+ (- end-num beg-num) 1)) + (message "Getting overview...") + (while (<= cur end-num) + (elmo-nntp-send-command buffer process + (format + "xover %s-%s" + (int-to-string cur) + (int-to-string + (+ cur + elmo-nntp-overview-fetch-chop-length)))) + (with-current-buffer buffer + (if ov-str + (setq ret-val + (elmo-msgdb-append + ret-val + (elmo-nntp-create-msgdb-from-overview-string + ov-str + folder + new-mark + already-mark + seen-mark + important-mark + seen-list + filter + ))))) + (if (null (elmo-nntp-read-response buffer process t)) + (progn + (setq cur end-num);; exit while loop + (elmo-nntp-set-xover server port nil) + (setq use-xover nil)) + (if (null (setq ov-str (elmo-nntp-read-contents buffer process))) + (error "Fetching overview failed"))) + (setq cur (+ elmo-nntp-overview-fetch-chop-length cur 1)) + (elmo-display-progress + 'elmo-nntp-msgdb-create "Getting overview..." + (/ (* (+ (- (min cur + end-num) + beg-num) 1) 100) length)))) + (if (not use-xover) + (setq ret-val (elmo-nntp-msgdb-create-by-header + folder buffer process numlist + new-mark already-mark seen-mark seen-list)) + (with-current-buffer buffer + (if ov-str + (setq ret-val + (elmo-msgdb-append + ret-val + (elmo-nntp-create-msgdb-from-overview-string + ov-str + folder + new-mark + already-mark + seen-mark + important-mark + seen-list + filter))))) + (message "Getting overview...done.")) + ;; If there are canceled messages, overviews are not obtained + ;; to max-number(inn 2.3?). + (when (and (elmo-nntp-max-number-precedes-list-active-p) + (elmo-nntp-list-active-p server port)) + (elmo-nntp-send-command buffer process + (format "list active %s" folder)) + (if (null (elmo-nntp-read-response buffer process)) + (progn + (elmo-nntp-set-list-active server port nil) + (error "NNTP list command failed"))) + (elmo-nntp-catchup-msgdb + ret-val + (nth 1 (read (concat "(" (elmo-nntp-read-contents + buffer process) ")"))))) + ret-val))))) + +(defun elmo-nntp-sync-number-alist (spec number-alist) + (if (elmo-nntp-max-number-precedes-list-active-p) + (elmo-nntp-setting spec + (if (elmo-nntp-list-active-p server port) + (let* ((cwf (caddr connection)) + msgdb-max max-number) + ;; If there are canceled messages, overviews are not obtained + ;; to max-number(inn 2.3?). + (if (and folder + (not (string= cwf folder)) + (null (elmo-nntp-goto-folder + server folder user port ssl))) + (error "group %s not found" folder)) + (elmo-nntp-send-command buffer process + (format "list active %s" folder)) + (if (null (elmo-nntp-read-response buffer process)) + (error "NNTP list command failed")) + (setq max-number + (nth 1 (read (concat "(" (elmo-nntp-read-contents + buffer process) ")")))) + (setq msgdb-max + (car (nth (max (- (length number-alist) 1) 0) + number-alist))) + (if (or (and number-alist (not msgdb-max)) + (and msgdb-max max-number + (< msgdb-max max-number))) + (nconc number-alist + (list (cons max-number nil))) + number-alist)) + number-alist)))) + +(defun elmo-nntp-msgdb-create-by-header (folder buffer process numlist + new-mark already-mark + seen-mark seen-list) + (let ((tmp-buffer (get-buffer-create " *ELMO Overview TMP*")) + ret-val) + (elmo-nntp-retrieve-headers + buffer tmp-buffer process numlist) + (setq ret-val + (elmo-nntp-msgdb-create-message + tmp-buffer (length numlist) folder new-mark already-mark + seen-mark seen-list)) + (kill-buffer tmp-buffer) + ret-val)) + +(defun elmo-nntp-parse-overview-string (string) + (save-excursion + (let ((tmp-buffer (get-buffer-create " *ELMO Overview TMP*")) + ret-list ret-val beg) + (set-buffer tmp-buffer) + (erase-buffer) + (elmo-set-buffer-multibyte nil) + (insert string) + (goto-char (point-min)) + (setq beg (point)) + (while (not (eobp)) + (end-of-line) + (setq ret-list (save-match-data + (apply 'vector (split-string + (buffer-substring beg (point)) + "\t")))) + (beginning-of-line) + (forward-line 1) + (setq beg (point)) + (setq ret-val (nconc ret-val (list ret-list)))) +; (kill-buffer tmp-buffer) + ret-val))) + +(defun elmo-nntp-get-overview (server beg end folder user port ssl) + (save-excursion + (let* ((connection (elmo-nntp-get-connection server user port ssl)) + (buffer (car connection)) + (process (cadr connection)) +; (cwf (caddr connection)) + response errmsg ov-str) + (catch 'done + (if folder + (if (null (elmo-nntp-goto-folder server folder user port ssl)) + (progn + (setq errmsg (format "group %s not found." folder)) + (throw 'done nil)))) + (elmo-nntp-send-command buffer process + (format "xover %s-%s" beg end)) + (if (null (setq response (elmo-nntp-read-response + buffer process t))) + (progn + (setq errmsg "Getting overview failed.") + (throw 'done nil))) + (if (null (setq response (elmo-nntp-read-contents + buffer process))) + (progn + ;(setq errmsg "Fetching header failed") + (throw 'done nil))) + (setq ov-str response) + ) + (if errmsg + (progn + (message errmsg) + nil) + ov-str)))) + + +(defun elmo-nntp-get-message (server user number folder outbuf port ssl) + "Get nntp message on FOLDER at SERVER. +Returns message string." + (save-excursion + (let* ((connection (elmo-nntp-get-connection server user port ssl)) + (buffer (car connection)) + (process (cadr connection)) + (cwf (caddr connection)) + response errmsg) + (catch 'done + (if (and folder + (not (string= cwf folder))) + (if (null (elmo-nntp-goto-folder server folder user port ssl)) + (progn + (setq errmsg (format "group %s not found." folder)) + (throw 'done nil)))) + (elmo-nntp-send-command buffer process + (format "article %s" number)) + (if (null (setq response (elmo-nntp-read-response + buffer process t))) + (progn + (setq errmsg "Fetching message failed") + (set-buffer outbuf) + (erase-buffer) + (insert "\n\n") + (throw 'done nil))) + (setq response (elmo-nntp-read-body buffer process outbuf)) + (set-buffer outbuf) + (goto-char (point-min)) + (while (re-search-forward "^\\." nil t) + (replace-match "") + (forward-line)) + ) + (if errmsg + (progn + (message errmsg) + nil)) + response))) + +(defun elmo-nntp-get-newsgroup-by-msgid (msgid server user port ssl) + "Get nntp header string." + (save-excursion + (let* ((connection (elmo-nntp-get-connection server user port ssl)) + (buffer (car connection)) + (process (cadr connection))) + (elmo-nntp-send-command buffer process + (format "head %s" msgid)) + (if (elmo-nntp-read-response buffer process) + (elmo-nntp-read-contents buffer process)) + (set-buffer buffer) + (std11-field-body "Newsgroups")))) + +(defun elmo-nntp-open-connection (server user portnum ssl) + "Open NNTP connection and returns +the list of (process session-buffer current-working-folder). +Return nil if connection failed." + (let ((process nil) + (host server) + (port (or portnum + elmo-default-nntp-port)) + (user-at-host (format "%s@%s" user server)) + process-buffer) + (as-binary-process + (catch 'done + (setq process-buffer + (get-buffer-create (format " *NNTP session to %s:%d" host port))) + (save-excursion + (set-buffer process-buffer) + (elmo-set-buffer-multibyte nil) + (erase-buffer)) + (setq process + (elmo-open-network-stream "NNTP" process-buffer host port ssl)) + (and (null process) (throw 'done nil)) + (set-process-filter process 'elmo-nntp-process-filter) + ;; flush connections when exiting...? + ;; (add-hook 'kill-emacs-hook 'elmo-nntp-flush-connection) + (save-excursion + (set-buffer process-buffer) + (elmo-set-buffer-multibyte nil) + (make-local-variable 'elmo-nntp-read-point) + (setq elmo-nntp-read-point (point-min)) + (if (null (elmo-nntp-read-response process-buffer process t)) + (throw 'done nil)) + (if elmo-nntp-send-mode-reader + (elmo-nntp-send-mode-reader process-buffer process)) + ;; starttls + (if (eq ssl 'starttls) + (if (progn + (elmo-nntp-send-command process-buffer process "starttls") + (elmo-nntp-read-response process-buffer process)) + (starttls-negotiate process) + (error "STARTTLS aborted"))) + (if user + (progn + (elmo-nntp-send-command process-buffer process + (format "authinfo user %s" user)) + (if (null (elmo-nntp-read-response process-buffer process)) + (error "Authinfo failed")) + (elmo-nntp-send-command process-buffer process + (format "authinfo pass %s" + (elmo-get-passwd user-at-host))) + (if (null (elmo-nntp-read-response process-buffer process)) + (progn + (elmo-remove-passwd user-at-host) + (error "Authinfo failed"))))) + (run-hooks 'elmo-nntp-opened-hook)) ; XXX + (cons process-buffer process))))) + +(defun elmo-nntp-send-mode-reader (buffer process) + (elmo-nntp-send-command buffer + process + "mode reader") + (if (null (elmo-nntp-read-response buffer process t)) + (error "mode reader failed"))) + +(defun elmo-nntp-send-command (buffer process command &optional noerase) + "Send COMMAND string to server with sequence number." + (save-excursion + (set-buffer buffer) + (when (not noerase) + (erase-buffer) + (goto-char (point-min))) + (setq elmo-nntp-read-point (point)) + (process-send-string process command) + (process-send-string process "\r\n"))) + +(defun elmo-nntp-read-msg (spec msg outbuf) + (elmo-nntp-get-message (elmo-nntp-spec-hostname spec) + (elmo-nntp-spec-username spec) + msg + (elmo-nntp-spec-group spec) + outbuf + (elmo-nntp-spec-port spec) + (elmo-nntp-spec-ssl spec))) + +;(defun elmo-msgdb-nntp-overview-create-range (spec beg end mark) +; (elmo-nntp-overview-create-range hostname beg end mark folder))) + +;(defun elmo-msgdb-nntp-max-of-folder (spec) +; (elmo-nntp-max-of-folder hostname folder))) + +(defun elmo-nntp-append-msg (spec string &optional msg no-see)) + +(defun elmo-nntp-post (hostname content-buf) + (let* (;(folder (nth 1 spec)) + (connection + (elmo-nntp-get-connection + hostname + elmo-default-nntp-user + elmo-default-nntp-port elmo-default-nntp-ssl)) + (buffer (car connection)) + (process (cadr connection)) + response has-message-id + ) + (save-excursion + (set-buffer content-buf) + (goto-char (point-min)) + (if (search-forward mail-header-separator nil t) + (delete-region (match-beginning 0)(match-end 0))) + (setq has-message-id (std11-field-body "message-id")) + (elmo-nntp-send-command buffer process "post") + (if (string-match "^340" (setq response + (elmo-nntp-read-raw-response + buffer process))) + (if (string-match "recommended ID \\(<[^@]+@[^>]+>\\)" response) + (unless has-message-id + (goto-char (point-min)) + (insert (concat "Message-ID: " + (elmo-match-string 1 response) + "\n")))) + (error "POST failed")) + (current-buffer) + (run-hooks 'elmo-nntp-post-pre-hook) + (set-buffer buffer) + (elmo-nntp-send-data process content-buf) + (elmo-nntp-send-command buffer process ".") + ;(elmo-nntp-read-response buffer process t) + (if (not (string-match + "^2" (setq response (elmo-nntp-read-raw-response + buffer process)))) + (error (concat "NNTP error: " response)))))) + +(defun elmo-nntp-send-data-line (process data) + (goto-char (point-max)) + + ;; Escape "." at start of a line + (if (eq (string-to-char data) ?.) + (process-send-string process ".")) + (process-send-string process data) + (process-send-string process "\r\n")) + +(defun elmo-nntp-send-data (process buffer) + (let + ((data-continue t) + (sending-data nil) + this-line + this-line-end) + (save-excursion + (set-buffer buffer) + (goto-char (point-min))) + + (while data-continue + (save-excursion + (set-buffer buffer) + (beginning-of-line) + (setq this-line (point)) + (end-of-line) + (setq this-line-end (point)) + (setq sending-data nil) + (setq sending-data (buffer-substring this-line this-line-end)) + (if (/= (forward-line 1) 0) + (setq data-continue nil))) + + (elmo-nntp-send-data-line process sending-data)))) + + +(defun elmo-nntp-delete-msgs (spec msgs) + "MSGS on FOLDER at SERVER pretended as Deleted. Returns nil if failed." + (let* ((dir (elmo-msgdb-expand-path nil spec)) +; (msgs (mapcar 'string-to-int msgs)) + (killed-list (elmo-msgdb-killed-list-load dir))) + (mapcar '(lambda (msg) + (setq killed-list + (elmo-msgdb-set-as-killed killed-list msg))) + msgs) + (elmo-msgdb-killed-list-save dir killed-list) + t)) + +(defun elmo-nntp-check-validity (spec validity-file) + t) +(defun elmo-nntp-sync-validity (spec validity-file) + t) + +(defun elmo-nntp-folder-exists-p (spec) + (if (elmo-nntp-plugged-p spec) + (elmo-nntp-setting spec + (elmo-nntp-send-command buffer + process + (format "group %s" folder)) + (elmo-nntp-read-response buffer process)) + t)) + +(defun elmo-nntp-folder-creatable-p (spec) + nil) + +(defun elmo-nntp-create-folder (spec) + nil) ; noop + +(defun elmo-nntp-search (spec condition &optional from-msgs) + (error "Search by %s for %s is not implemented yet." condition (car spec)) + nil) + +(defun elmo-nntp-get-folders-info-prepare (spec connection-keys) + (condition-case () + (elmo-nntp-setting spec + (let (key count) + (save-excursion + (set-buffer buffer) + (unless (setq key (assoc (cons buffer process) connection-keys)) + (erase-buffer) + (setq key (cons (cons buffer process) + (vector 0 server user port ssl))) + (setq connection-keys (nconc connection-keys (list key)))) + (elmo-nntp-send-command buffer + process + (format "group %s" folder) + t ;; don't erase-buffer + ) + (if elmo-nntp-get-folders-securely + (accept-process-output process 1)) + (setq count (aref (cdr key) 0)) + (aset (cdr key) 0 (1+ count))))) + (error + (when elmo-auto-change-plugged + (sit-for 1)) + nil)) + connection-keys) + +(defun elmo-nntp-get-folders-info (connection-keys) + (let ((connections connection-keys) + (cur (get-buffer-create " *ELMO NNTP Temp*"))) + (while connections + (let* ((connect (caar connections)) + (key (cdar connections)) + (buffer (car connect)) + (process (cdr connect)) + (count (aref key 0)) + (server (aref key 1)) + (user (aref key 2)) + (port (aref key 3)) + (ssl (aref key 4)) + (hashtb (or elmo-nntp-groups-hashtb + (setq elmo-nntp-groups-hashtb + (elmo-make-hash count))))) + (save-excursion + (elmo-nntp-groups-read-response buffer cur process count) + (set-buffer cur) + (goto-char (point-min)) + (let ((case-replace nil) + (postfix (elmo-nntp-folder-postfix user server port ssl))) + (if (not (string= postfix "")) + (save-excursion + (replace-regexp "^\\(211 [0-9]+ [0-9]+ [0-9]+ [^ \n]+\\).*$" + (concat "\\1" postfix))))) + (let (len min max group) + (while (not (eobp)) + (condition-case () + (when (= (following-char) ?2) + (read cur) + (setq len (read cur) + min (read cur) + max (read cur)) + (set (setq group (let ((obarray hashtb)) (read cur))) + (list len min max))) + (error (and group (symbolp group) (set group nil)))) + (forward-line 1)))) + (setq connections (cdr connections)))) + (kill-buffer cur))) + +;; original is 'nntp-retrieve-groups [Gnus] +(defun elmo-nntp-groups-read-response (buffer tobuffer process count) + (let* ((received 0) + (last-point (point-min))) + (save-excursion + (set-buffer buffer) + (accept-process-output process 1) + (discard-input) + ;; Wait for all replies. + (message "Getting folders info...") + (while (progn + (goto-char last-point) + ;; Count replies. + (while (re-search-forward "^[0-9]" nil t) + (setq received + (1+ received))) + (setq last-point (point)) + (< received count)) + (accept-process-output process 1) + (discard-input) + (and (zerop (% received 10)) + (elmo-display-progress + 'elmo-nntp-groups-read-response "Getting folders info..." + (/ (* received 100) count))) + ) + ;; Wait for the reply from the final command. + (goto-char (point-max)) + (re-search-backward "^[0-9]" nil t) + (when (looking-at "^[23]") + (while (progn + (goto-char (point-max)) + (not (re-search-backward "\r?\n" (- (point) 3) t))) + (accept-process-output process 1) + (discard-input))) + ;; Now all replies are received. We remove CRs. + (goto-char (point-min)) + (while (search-forward "\r" nil t) + (replace-match "" t t)) + (copy-to-buffer tobuffer (point-min) (point-max))))) + +(defun elmo-nntp-make-groups-hashtb (folders &optional size) + (let ((hashtb (or elmo-nntp-groups-hashtb + (setq elmo-nntp-groups-hashtb + (elmo-make-hash (or size (length folders))))))) + (mapcar + '(lambda (fld) + (or (elmo-get-hash-val fld hashtb) + (elmo-set-hash-val fld nil hashtb))) + folders) + hashtb)) + +;; from nntp.el [Gnus] + +(defsubst elmo-nntp-next-result-arrived-p () + (cond + ((eq (following-char) ?2) + (if (re-search-forward "\n\\.\r?\n" nil t) + t + nil)) + ((looking-at "[34]") + (if (search-forward "\n" nil t) + t + nil)) + (t + nil))) + +(defun elmo-nntp-retrieve-headers (buffer tobuffer process articles) + "Retrieve the headers of ARTICLES." + (save-excursion + (set-buffer buffer) + (erase-buffer) + (let ((number (length articles)) + (count 0) + (received 0) + (last-point (point-min)) + article) + ;; Send HEAD commands. + (while (setq article (pop articles)) + (elmo-nntp-send-command + buffer + process + (format "head %s" article) + t ;; not erase-buffer + ) + (setq count (1+ count)) + ;; Every 200 requests we have to read the stream in + ;; order to avoid deadlocks. + (when (or (null articles) ;All requests have been sent. + (zerop (% count elmo-nntp-header-fetch-chop-length))) + (accept-process-output process 1) + (discard-input) + (while (progn + (set-buffer buffer) + (goto-char last-point) + ;; Count replies. + (while (elmo-nntp-next-result-arrived-p) + (setq last-point (point)) + (setq received (1+ received))) + (< received count)) + (and (zerop (% received 20)) + (elmo-display-progress + 'elmo-nntp-retrieve-headers "Getting headers..." + (/ (* received 100) number))) + (accept-process-output process 1) + (discard-input) + ))) + (message "Getting headers...done") + ;; Remove all "\r"'s. + (goto-char (point-min)) + (while (search-forward "\r\n" nil t) + (replace-match "\n")) + (copy-to-buffer tobuffer (point-min) (point-max))))) + +;; end of from Gnus + +(defun elmo-nntp-msgdb-create-message (buffer len folder new-mark + already-mark seen-mark seen-list) + (save-excursion + (let (beg + overview number-alist mark-alist + entity i num gmark seen message-id) + (set-buffer buffer) + (elmo-set-buffer-multibyte nil) + (goto-char (point-min)) + (setq i 0) + (message "Creating msgdb...") + (while (not (eobp)) + (setq beg (save-excursion (forward-line 1) (point))) + (setq num + (and (looking-at "^2[0-9]*[ ]+\\([0-9]+\\)") + (string-to-int + (elmo-match-buffer 1)))) + (elmo-nntp-next-result-arrived-p) + (when num + (save-excursion + (forward-line -1) + (save-restriction + (narrow-to-region beg (point)) + (setq entity + (elmo-msgdb-create-overview-from-buffer num)) + (when entity + (setq overview + (elmo-msgdb-append-element + overview entity)) + (setq number-alist + (elmo-msgdb-number-add number-alist + (elmo-msgdb-overview-entity-get-number entity) + (car entity))) + (setq message-id (car entity)) + (setq seen (member message-id seen-list)) + (if (setq gmark + (or (elmo-msgdb-global-mark-get message-id) + (if (elmo-cache-exists-p message-id);; XXX + (if seen + nil + already-mark) + (if seen + seen-mark + new-mark)))) + (setq mark-alist + (elmo-msgdb-mark-append + mark-alist + num gmark))) + )))) + (setq i (1+ i)) + (and (zerop (% i 20)) + (elmo-display-progress + 'elmo-nntp-msgdb-create-message "Creating msgdb..." + (/ (* i 100) len))) + ) + (message "Creating msgdb...done.") + (list overview number-alist mark-alist)))) + +(defun elmo-nntp-use-cache-p (spec number) + elmo-nntp-use-cache) + +(defun elmo-nntp-local-file-p (spec number) + nil) + +(defun elmo-nntp-port-label (spec) + (concat "nntp" + (if (elmo-nntp-spec-ssl spec) "!ssl" ""))) + +(defsubst elmo-nntp-portinfo (spec) + (list (elmo-nntp-spec-hostname spec) + (elmo-nntp-spec-port spec))) + +(defun elmo-nntp-plugged-p (spec) + (apply 'elmo-plugged-p + (append (elmo-nntp-portinfo spec) + (list nil (quote (elmo-nntp-port-label spec)))))) + +(defun elmo-nntp-set-plugged (spec plugged add) + (apply 'elmo-set-plugged plugged + (append (elmo-nntp-portinfo spec) + (list nil nil (quote (elmo-nntp-port-label spec)) add)))) + +(defalias 'elmo-nntp-list-folder-unread + 'elmo-generic-list-folder-unread) +(defalias 'elmo-nntp-list-folder-important + 'elmo-generic-list-folder-important) +(defalias 'elmo-nntp-commit 'elmo-generic-commit) + +(provide 'elmo-nntp) + +;;; elmo-nntp.el ends here diff --git a/elmo/elmo-pipe.el b/elmo/elmo-pipe.el new file mode 100644 index 0000000..a6d1c8f --- /dev/null +++ b/elmo/elmo-pipe.el @@ -0,0 +1,142 @@ +;;; elmo-pipe.el -- PIPE Interface for ELMO. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <2000-03-03 14:06:56 teranisi> + +;; This file is part of ELMO (Elisp Library for Message Orchestration). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; + +(require 'elmo-msgdb) + +(defsubst elmo-pipe-spec-src (spec) + (nth 1 spec)) + +(defsubst elmo-pipe-spec-dst (spec) + (nth 2 spec)) + +(defalias 'elmo-pipe-msgdb-create 'elmo-pipe-msgdb-create-as-numlist) + +(defun elmo-pipe-msgdb-create-as-numlist (spec numlist new-mark already-mark + seen-mark important-mark + seen-list) + (elmo-msgdb-create-as-numlist (elmo-pipe-spec-dst spec) + numlist new-mark already-mark + seen-mark important-mark seen-list)) + +(defun elmo-pipe-list-folders (spec &optional hierarchy) + nil) + +(defun elmo-pipe-append-msg (spec string &optional msg no-see) + (elmo-append-msg (elmo-pipe-spec-dst spec) string)) + +(defun elmo-pipe-read-msg (spec number outbuf) + (elmo-call-func (elmo-pipe-spec-dst spec) + "read-msg" + number outbuf)) + +(defun elmo-pipe-delete-msgs (spec msgs) + (elmo-delete-msgs (elmo-pipe-spec-dst spec) msgs)) + +(defvar elmo-pipe-drained-hook nil "A hook called when the pipe is flushed.") + +(defun elmo-pipe-drain (src dst) + (let ((msgdb (elmo-msgdb-load src)) + elmo-nntp-use-cache + elmo-imap4-use-cache + elmo-pop3-use-cache) ; Inhibit caching while moving messages. + (message "Checking %s..." src) + (elmo-move-msgs src (elmo-list-folder src) dst msgdb) + (elmo-msgdb-save src msgdb) + (run-hooks 'elmo-pipe-drained-hook))) + +(defun elmo-pipe-list-folder (spec) + (elmo-pipe-drain (elmo-pipe-spec-src spec) + (elmo-pipe-spec-dst spec)) + (elmo-list-folder (elmo-pipe-spec-dst spec))) + +(defun elmo-pipe-list-folder-unread (spec mark-alist unread-marks) + (elmo-list-folder-unread (elmo-pipe-spec-dst spec) mark-alist unread-marks)) + +(defun elmo-pipe-list-folder-important (spec overview) + (elmo-list-folder-important (elmo-pipe-spec-dst spec) overview)) + +(defun elmo-pipe-max-of-folder (spec) + (let ((src-length (length (elmo-list-folder (elmo-pipe-spec-src spec)))) + (dst-list (elmo-list-folder (elmo-pipe-spec-dst spec)))) + (cons (+ src-length (elmo-max-of-list dst-list)) + (+ src-length (length dst-list))))) + +(defun elmo-pipe-folder-exists-p (spec) + (and (elmo-folder-exists-p (elmo-pipe-spec-src spec)) + (elmo-folder-exists-p (elmo-pipe-spec-dst spec)))) + +(defun elmo-pipe-folder-creatable-p (spec) + (or (elmo-folder-creatable-p (elmo-pipe-spec-src spec)) + (elmo-folder-creatable-p (elmo-pipe-spec-dst spec)))) + +(defun elmo-pipe-create-folder (spec) + (if (and (not (elmo-folder-exists-p (elmo-pipe-spec-src spec))) + (elmo-folder-creatable-p (elmo-pipe-spec-src spec))) + (elmo-create-folder (elmo-pipe-spec-src spec))) + (if (and (not (elmo-folder-exists-p (elmo-pipe-spec-dst spec))) + (elmo-folder-creatable-p (elmo-pipe-spec-dst spec))) + (elmo-create-folder (elmo-pipe-spec-dst spec)))) + +(defun elmo-pipe-search (spec condition &optional numlist) + (elmo-search (elmo-pipe-spec-dst spec) condition numlist)) + +(defun elmo-pipe-use-cache-p (spec number) + (elmo-use-cache-p (elmo-pipe-spec-dst spec) number)) + +(defun elmo-pipe-commit (spec) + (elmo-commit (elmo-pipe-spec-src spec)) + (elmo-commit (elmo-pipe-spec-dst spec))) + +(defun elmo-pipe-plugged-p (spec) + (and (elmo-folder-plugged-p (elmo-pipe-spec-src spec)) + (elmo-folder-plugged-p (elmo-pipe-spec-dst spec)))) + +(defun elmo-pipe-set-plugged (spec plugged add) + (elmo-folder-set-plugged (elmo-pipe-spec-src spec) plugged add) + (elmo-folder-set-plugged (elmo-pipe-spec-dst spec) plugged add)) + +(defun elmo-pipe-local-file-p (spec number) + (elmo-local-file-p (elmo-pipe-spec-dst spec) number)) + +(defun elmo-pipe-get-msg-filename (spec number &optional loc-alist) + (elmo-get-msg-filename (elmo-pipe-spec-dst spec) number loc-alist)) + +(defun elmo-pipe-sync-number-alist (spec number-alist) + (elmo-call-func (elmo-pipe-spec-src spec) + "sync-number-alist" number-alist)) ; ?? + +(defun elmo-pipe-server-diff (spec) + nil) + +(provide 'elmo-pipe) + +;;; elmo-pipe.el ends here diff --git a/elmo/elmo-pop3.el b/elmo/elmo-pop3.el new file mode 100644 index 0000000..bef19c0 --- /dev/null +++ b/elmo/elmo-pop3.el @@ -0,0 +1,673 @@ +;;; elmo-pop3.el -- POP3 Interface for ELMO. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <2000-04-03 09:29:38 teranisi> + +;; This file is part of ELMO (Elisp Library for Message Orchestration). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; + +(require 'elmo-msgdb) +(eval-when-compile + (require 'elmo-util) + (condition-case nil + (progn + (require 'starttls) + (require 'sasl)) + (error)) + (defun-maybe md5 (a)) + (defun-maybe sasl-digest-md5-digest-response + (digest-challenge username passwd serv-type host &optional realm)) + (defun-maybe sasl-scram-md5-client-msg-1 + (authenticate-id &optional authorize-id)) + (defun-maybe sasl-scram-md5-client-msg-2 + (server-msg-1 client-msg-1 salted-pass)) + (defun-maybe sasl-scram-md5-make-salted-pass + (server-msg-1 passphrase)) + (defun-maybe sasl-scram-md5-authenticate-server + (server-msg-1 server-msg-2 client-msg-1 salted-pass)) + (defun-maybe starttls-negotiate (a))) +(condition-case nil + (progn + (require 'sasl)) + (error)) + +(defvar elmo-pop3-exists-exactly t) +(defvar elmo-pop3-read-point nil) +(defvar elmo-pop3-connection-cache nil + "Cache of pop3 connection.") + +(defun elmo-pop3-close-connection (connection &optional process buffer) + (save-excursion + (let* ((buffer (or buffer (nth 0 connection))) + (process (or process (nth 1 connection)))) + (elmo-pop3-send-command buffer process "quit") + (when (null (elmo-pop3-read-response buffer process t)) + (error "POP error: QUIT failed"))))) + +(defun elmo-pop3-flush-connection () + (interactive) + (let ((cache elmo-pop3-connection-cache) + buffer process proc-stat) + (while cache + (setq buffer (car (cdr (car cache)))) + (setq process (car (cdr (cdr (car cache))))) + (if (and process + (not (or (eq (setq proc-stat + (process-status process)) + 'closed) + (eq proc-stat 'exit)))) + (condition-case () + (elmo-pop3-close-connection nil process buffer) + (error))) + (if buffer (kill-buffer buffer)) + ;;(setq process (car (cdr (cdr (car cache))))) + (if process (delete-process process)) + (setq cache (cdr cache))) + (setq elmo-pop3-connection-cache nil))) + +(defun elmo-pop3-get-connection (spec) + (let* ((user (elmo-pop3-spec-username spec)) + (server (elmo-pop3-spec-hostname spec)) + (port (elmo-pop3-spec-port spec)) + (auth (elmo-pop3-spec-auth spec)) + (ssl (elmo-pop3-spec-ssl spec)) + (user-at-host (format "%s@%s" user server)) + ret-val result buffer process errmsg proc-stat + user-at-host-on-port) + (if (not (elmo-plugged-p server port)) + (error "Unplugged")) + (setq user-at-host-on-port + (concat user-at-host ":" (int-to-string port) + (if (eq ssl 'starttls) "!!" (if ssl "!")))) + (setq ret-val (assoc user-at-host-on-port elmo-pop3-connection-cache)) + (if (and ret-val + (or (eq (setq proc-stat + (process-status (cadr (cdr ret-val)))) + 'closed) + (eq proc-stat 'exit))) + ;; connection is closed... + (progn + (kill-buffer (car (cdr ret-val))) + (setq elmo-pop3-connection-cache + (delete ret-val elmo-pop3-connection-cache)) + (setq ret-val nil) + )) + (if ret-val + (cdr ret-val) + (setq result + (elmo-pop3-open-connection + server user port auth + (elmo-get-passwd user-at-host) ssl)) + (if (null result) + (error "Connection failed")) + (setq buffer (car result)) + (setq process (cdr result)) + (when (and process (null buffer)) + (elmo-remove-passwd user-at-host) + (delete-process process) + (error "Login failed") + ) + (setq elmo-pop3-connection-cache + (append elmo-pop3-connection-cache + (list + (cons user-at-host-on-port + (setq ret-val (list buffer process)))))) + ret-val))) + +(defun elmo-pop3-send-command (buffer process command) + (save-excursion + (set-buffer buffer) + (erase-buffer) + (goto-char (point-min)) + (setq elmo-pop3-read-point (point)) + (process-send-string process command) + (process-send-string process "\r\n"))) + +(defun elmo-pop3-send-command-no-erase (buffer process command) + (save-excursion + (set-buffer buffer) + ;(erase-buffer) + (goto-char (point-min)) + (setq elmo-pop3-read-point (point)) + (process-send-string process command) + (process-send-string process "\r\n"))) + +(defun elmo-pop3-read-response (buffer process &optional not-command) + (save-excursion + (set-buffer buffer) + (let ((case-fold-search nil) + (response-string nil) + (response-continue t) + (return-value nil) + match-end) + (while response-continue + (goto-char elmo-pop3-read-point) + (while (not (re-search-forward "\r?\n" nil t)) + (accept-process-output process) + (goto-char elmo-pop3-read-point)) + (setq match-end (point)) + (setq response-string + (buffer-substring elmo-pop3-read-point (- match-end 2))) + (goto-char elmo-pop3-read-point) + (if (looking-at "\\+.*$") + (progn + (setq response-continue nil) + (setq elmo-pop3-read-point match-end) + (setq return-value + (if return-value + (concat return-value "\n" response-string) + response-string + ))) + (if (looking-at "\\-.*$") + (progn + (setq response-continue nil) + (setq elmo-pop3-read-point match-end) + (setq return-value nil)) + (setq elmo-pop3-read-point match-end) + (if not-command + (setq response-continue nil)) + (setq return-value + (if return-value + (concat return-value "\n" response-string) + response-string))) + (setq elmo-pop3-read-point match-end))) + return-value))) + +(defun elmo-pop3-process-filter (process output) + (save-excursion + (set-buffer (process-buffer process)) + (goto-char (point-max)) + (insert output))) + +(defun elmo-pop3-open-connection (server user port auth passphrase ssl) + (let ((process nil) + (host server) + process-buffer ret-val response capability) + (catch 'done + (as-binary-process + (setq process-buffer + (get-buffer-create (format " *POP session to %s:%d" host port))) + (save-excursion + (set-buffer process-buffer) + (elmo-set-buffer-multibyte nil) + (erase-buffer)) + (setq process + (elmo-open-network-stream "POP" process-buffer host port ssl)) + (and (null process) (throw 'done nil)) + (set-process-filter process 'elmo-pop3-process-filter) + ;; flush connections when exiting... + (save-excursion + (set-buffer process-buffer) + (make-local-variable 'elmo-pop3-read-point) + (setq elmo-pop3-read-point (point-min)) + (when (null (setq response + (elmo-pop3-read-response process-buffer process t))) + (setq ret-val (cons nil process)) + (throw 'done nil)) + (when (eq ssl 'starttls) + (elmo-pop3-send-command process-buffer process "stls") + (string-match "^\+OK" + (elmo-pop3-read-response + process-buffer process)) + (starttls-negotiate process)) + (cond ((string= auth "apop") + ;; try only APOP + (if (string-match "^\+OK .*\\(<[^\>]+>\\)" response) + ;; good, APOP ready server + (progn + (require 'md5) + (elmo-pop3-send-command + process-buffer process + (format "apop %s %s" + user + (md5 + (concat (match-string 1 response) + passphrase))))) + ;; otherwise, fail (only APOP authentication) + (setq ret-val (cons nil process)) + (throw 'done nil))) + ((string= auth "cram-md5") + (elmo-pop3-send-command + process-buffer process "auth cram-md5") + (when (null (setq response + (elmo-pop3-read-response + process-buffer process t))) + (setq ret-val (cons nil process)) + (throw 'done nil)) + (elmo-pop3-send-command + process-buffer process + (elmo-base64-encode-string + (sasl-cram-md5 user passphrase + (elmo-base64-decode-string + (cadr (split-string response " "))))))) + ((string= auth "digest-md5") + (elmo-pop3-send-command + process-buffer process "auth digest-md5") + (when (null (setq response + (elmo-pop3-read-response + process-buffer process t))) + (setq ret-val (cons nil process)) + (throw 'done nil)) + (elmo-pop3-send-command + process-buffer process + (elmo-base64-encode-string + (sasl-digest-md5-digest-response + (elmo-base64-decode-string + (cadr (split-string response " "))) + user passphrase "pop" host) + 'no-line-break)) + (when (null (setq response + (elmo-pop3-read-response + process-buffer process t))) + (setq ret-val (cons nil process)) + (throw 'done nil)) + (elmo-pop3-send-command process-buffer process "")) + ((string= auth "scram-md5") + (let (server-msg-1 server-msg-2 client-msg-1 client-msg-2 + salted-pass) + (elmo-pop3-send-command + process-buffer process + (format "auth scram-md5 %s" + (elmo-base64-encode-string + (setq client-msg-1 + (sasl-scram-md5-client-msg-1 user))))) + (when (null (setq response + (elmo-pop3-read-response + process-buffer process t))) + (setq ret-val (cons nil process)) + (throw 'done nil)) + (setq server-msg-1 + (elmo-base64-decode-string + (cadr (split-string response " ")))) + (elmo-pop3-send-command + process-buffer process + (elmo-base64-encode-string + (sasl-scram-md5-client-msg-2 + server-msg-1 + client-msg-1 + (setq salted-pass + (sasl-scram-md5-make-salted-pass + server-msg-1 passphrase))))) + (when (null (setq response + (elmo-pop3-read-response + process-buffer process t))) + (setq ret-val (cons nil process)) + (throw 'done nil)) + (setq server-msg-2 + (elmo-base64-decode-string + (cadr (split-string response " ")))) + (if (null (sasl-scram-md5-authenticate-server + server-msg-1 + server-msg-2 + client-msg-1 + salted-pass)) + (throw 'done nil)) + (elmo-pop3-send-command + process-buffer process "") )) + (t + ;; try USER/PASS + (elmo-pop3-send-command process-buffer process + (format "user %s" user)) + (when (null (elmo-pop3-read-response process-buffer process t)) + (setq ret-val (cons nil process)) + (throw 'done nil)) + (elmo-pop3-send-command process-buffer process + (format "pass %s" passphrase)))) + ;; read PASS or APOP response + (when (null (elmo-pop3-read-response process-buffer process t)) + (setq ret-val (cons nil process)) + (throw 'done nil)) + (setq ret-val (cons process-buffer process))))) + ret-val)) + +(defun elmo-pop3-read-contents (buffer process) + (save-excursion + (set-buffer buffer) + (let ((case-fold-search nil) + match-end) + (goto-char elmo-pop3-read-point) + (while (not (re-search-forward "^\\.\r\n" nil t)) + (accept-process-output process) + (goto-char elmo-pop3-read-point)) + (setq match-end (point)) + (elmo-delete-cr + (buffer-substring elmo-pop3-read-point + (- match-end 3)))))) + +;; dummy functions +(defun elmo-pop3-list-folders (spec &optional hierarchy) nil) +(defun elmo-pop3-append-msg (spec string) nil nil) +(defun elmo-pop3-folder-creatable-p (spec) nil) +(defun elmo-pop3-create-folder (spec) nil) + +(defun elmo-pop3-folder-exists-p (spec) + (if (and elmo-pop3-exists-exactly + (elmo-pop3-plugged-p spec)) + (save-excursion + (let (elmo-auto-change-plugged) ;;don't change plug status. + (condition-case nil + (prog1 + (elmo-pop3-get-connection spec) + (elmo-pop3-flush-connection)) + (error nil)))) + t)) + +(defun elmo-pop3-parse-list-response (string) + (save-excursion + (let ((tmp-buffer (get-buffer-create " *ELMO PARSE TMP*")) + ret-val) + (set-buffer tmp-buffer) + (let ((case-fold-search t)) + (erase-buffer) + (insert string) + (goto-char (point-min)) + (while (re-search-forward "^\\([0-9]*\\)[\t ].*$" nil t) + (setq ret-val + (cons + (string-to-int + (elmo-match-buffer 1)) + ret-val))) + (kill-buffer tmp-buffer) + (nreverse ret-val))))) + +(defun elmo-pop3-list-folder (spec) + (save-excursion + (elmo-pop3-flush-connection) + (let* ((connection (elmo-pop3-get-connection spec)) + (buffer (nth 0 connection)) + (process (nth 1 connection)) + response errmsg ret-val) + (elmo-pop3-send-command buffer process "list") + (if (null (elmo-pop3-read-response buffer process)) + (error "POP List folder failed")) + (if (null (setq response (elmo-pop3-read-contents buffer process))) + (error "POP List folder failed")) + ;; POP server always returns a sequence of serial numbers. + (elmo-pop3-parse-list-response response)))) + +(defun elmo-pop3-max-of-folder (spec) + (save-excursion + (elmo-pop3-flush-connection) + (let* ((connection (elmo-pop3-get-connection spec)) + (buffer (nth 0 connection)) + (process (nth 1 connection)) + (total 0) + response) + (elmo-pop3-send-command buffer process "STAT") + (setq response (elmo-pop3-read-response buffer process)) + ;; response: "^\+OK 2 7570$" + (if (not (string-match "^\+OK[ \t]*\\([0-9]*\\)" response)) + (error "POP STAT command failed") + (setq total + (string-to-int + (substring response (match-beginning 1)(match-end 1 )))) + (cons total total))))) + +(defvar elmo-pop3-header-fetch-chop-length 200) + +(defsubst elmo-pop3-next-result-arrived-p () + (cond + ((eq (following-char) ?+) + (if (re-search-forward "\n\\.\r?\n" nil t) + t + nil)) + ((looking-at "-") + (if (search-forward "\n" nil t) + t + nil)) + (t + nil))) + +(defun elmo-pop3-retrieve-headers (buffer tobuffer process articles) + (save-excursion + (set-buffer buffer) + (erase-buffer) + (let ((number (length articles)) + (count 0) + (received 0) + (last-point (point-min))) + ;; Send HEAD commands. + (while articles + (elmo-pop3-send-command-no-erase + buffer + process + (format "top %s 0" (car articles)) + ) + ; (accept-process-output process 1) + (setq articles (cdr articles)) + (setq count (1+ count)) + ;; Every 200 requests we have to read the stream in + ;; order to avoid deadlocks. + (when (or elmo-pop3-send-command-synchronously + (null articles) ;All requests have been sent. + (zerop (% count elmo-pop3-header-fetch-chop-length))) + (unless elmo-pop3-send-command-synchronously + (accept-process-output process 1)) + (discard-input) + (while (progn + (set-buffer buffer) + (goto-char last-point) + ;; Count replies. + (while (elmo-pop3-next-result-arrived-p) + (setq last-point (point)) + (setq received (1+ received))) + (< received count)) + (and (zerop (% received 20)) + (elmo-display-progress + 'elmo-pop3-retrieve-headers "Getting headers..." + (/ (* received 100) number))) + (accept-process-output process 1) + ;(accept-process-output process) + (discard-input) + ))) + (message "Getting headers...done") + ;; Remove all "\r"'s. + (goto-char (point-min)) + (while (search-forward "\r\n" nil t) + (replace-match "\n")) + (copy-to-buffer tobuffer (point-min) (point-max)) + ;(elmo-pop3-close-connection nil process buffer) ; close connection + ))) + +(defalias 'elmo-pop3-msgdb-create 'elmo-pop3-msgdb-create-as-numlist) +(defun elmo-pop3-msgdb-create-as-numlist (spec numlist new-mark + already-mark seen-mark + important-mark seen-list) + (when numlist + (let* ((connection (elmo-pop3-get-connection spec)) + (buffer (nth 0 connection)) + (process (nth 1 connection)) + response errmsg ret-val) + (elmo-pop3-msgdb-create-by-header buffer process numlist + new-mark already-mark + seen-mark seen-list)))) + +(defun elmo-pop3-msgdb-create-by-header (buffer process numlist + new-mark already-mark + seen-mark + seen-list) + (let ((tmp-buffer (get-buffer-create " *ELMO Overview TMP*")) + ret-val) + (elmo-pop3-retrieve-headers + buffer tmp-buffer process numlist) + (setq ret-val + (elmo-pop3-msgdb-create-message + tmp-buffer + (length numlist) + numlist + new-mark already-mark seen-mark seen-list)) + (kill-buffer tmp-buffer) + ret-val)) + +(defun elmo-pop3-msgdb-create-message (buffer + num numlist new-mark already-mark + seen-mark + seen-list) + (save-excursion + (let (beg + overview number-alist mark-alist + entity i number message-id gmark seen) + (set-buffer buffer) + (elmo-set-buffer-multibyte default-enable-multibyte-characters) + (goto-char (point-min)) + (setq i 0) + (message "Creating msgdb...") + (while (not (eobp)) + (setq beg (save-excursion (forward-line 1) (point))) + (elmo-pop3-next-result-arrived-p) + (save-excursion + (forward-line -1) + (save-restriction + (narrow-to-region beg (point)) + (setq entity + (elmo-msgdb-create-overview-from-buffer + (car numlist))) + (setq numlist (cdr numlist)) + (when entity + (setq overview + (elmo-msgdb-append-element + overview entity)) + (setq number-alist + (elmo-msgdb-number-add number-alist + (elmo-msgdb-overview-entity-get-number entity) + (car entity))) + (setq message-id (car entity)) + (setq seen (member message-id seen-list)) + (if (setq gmark (or (elmo-msgdb-global-mark-get message-id) + (if (elmo-cache-exists-p + message-id) ; XXX + (if seen + nil + already-mark) + (if seen + (if elmo-pop3-use-cache + seen-mark) + new-mark)))) + (setq mark-alist + (elmo-msgdb-mark-append + mark-alist + (elmo-msgdb-overview-entity-get-number entity) + gmark))) + ))) + (setq i (1+ i)) + (and (zerop (% i 20)) + (elmo-display-progress + 'elmo-pop3-msgdb-create-message "Creating msgdb..." + (/ (* i 100) num))) + ) + (message "Creating msgdb...done.") + (list overview number-alist mark-alist)))) + +(defun elmo-pop3-read-body (buffer process outbuf) + (with-current-buffer buffer + (let ((start elmo-pop3-read-point) + end) + (goto-char start) + (while (not (re-search-forward "^\\.\r?\n" nil t)) + (accept-process-output process) + (goto-char start)) + (setq end (point)) + (with-current-buffer outbuf + (erase-buffer) + (insert-buffer-substring buffer start (- end 3)) + (elmo-delete-cr-get-content-type))))) + +(defun elmo-pop3-read-msg (spec number outbuf) + (save-excursion + (let* ((connection (elmo-pop3-get-connection spec)) + (buffer (car connection)) + (process (cadr connection)) + (cwf (caddr connection)) + response errmsg msg) + (elmo-pop3-send-command buffer process + (format "retr %s" number)) + (when (null (setq response (elmo-pop3-read-response + buffer process t))) + (error "Fetching message failed")) + (setq response (elmo-pop3-read-body buffer process outbuf)) + (set-buffer outbuf) + (goto-char (point-min)) + (while (re-search-forward "^\\." nil t) + (replace-match "") + (forward-line)) + response))) + +(defun elmo-pop3-delete-msg (buffer process number) + (let (response errmsg msg) + (elmo-pop3-send-command buffer process + (format "dele %s" number)) + (when (null (setq response (elmo-pop3-read-response + buffer process t))) + (error "Deleting message failed")))) + +(defun elmo-pop3-delete-msgs (spec msgs) + (save-excursion + (let* ((connection (elmo-pop3-get-connection spec)) + (buffer (car connection)) + (process (cadr connection))) + (mapcar '(lambda (msg) (elmo-pop3-delete-msg + buffer process msg)) + msgs)))) + +(defun elmo-pop3-search (spec condition &optional numlist) + (error "Searching in pop3 folder is not implemented yet")) + +(defun elmo-pop3-use-cache-p (spec number) + elmo-pop3-use-cache) + +(defun elmo-pop3-local-file-p (spec number) + nil) + +(defun elmo-pop3-port-label (spec) + (concat "pop3" + (if (elmo-pop3-spec-ssl spec) "!ssl" ""))) + +(defsubst elmo-pop3-portinfo (spec) + (list (elmo-pop3-spec-hostname spec) + (elmo-pop3-spec-port spec))) + +(defun elmo-pop3-plugged-p (spec) + (apply 'elmo-plugged-p + (append (elmo-pop3-portinfo spec) + (list nil (quote (elmo-pop3-port-label spec)))))) + +(defun elmo-pop3-set-plugged (spec plugged add) + (apply 'elmo-set-plugged plugged + (append (elmo-pop3-portinfo spec) + (list nil nil (quote (elmo-pop3-port-label spec)) add)))) + +(defalias 'elmo-pop3-sync-number-alist + 'elmo-generic-sync-number-alist) +(defalias 'elmo-pop3-list-folder-unread + 'elmo-generic-list-folder-unread) +(defalias 'elmo-pop3-list-folder-important + 'elmo-generic-list-folder-important) +(defalias 'elmo-pop3-commit 'elmo-generic-commit) + +(provide 'elmo-pop3) + +;;; elmo-pop3.el ends here diff --git a/elmo/elmo-util.el b/elmo/elmo-util.el new file mode 100644 index 0000000..9c6de8c --- /dev/null +++ b/elmo/elmo-util.el @@ -0,0 +1,1617 @@ +;;; elmo-util.el -- Utilities for Elmo. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <2000-03-29 09:42:41 teranisi> + +;; This file is part of ELMO (Elisp Library for Message Orchestration). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; + +(require 'elmo-vars) +(require 'elmo-date) +(eval-when-compile (require 'cl)) +(require 'std11) +(require 'eword-decode) +(require 'utf7) + +(eval-when-compile + (condition-case nil + (progn + (require 'ssl) + (require 'starttls)) + (error)) + (defun-maybe starttls-negotiate (a)) + (defun-maybe starttls-open-stream (a b c d)) + (defun-maybe open-ssl-stream (a b c d))) + +(defmacro elmo-set-buffer-multibyte (flag) + "Set the multibyte flag of the current buffer to FLAG." + (cond ((boundp 'MULE) + (list 'setq 'mc-flag flag)) + ((featurep 'xemacs) + flag) + ((and (boundp 'emacs-major-version) (>= emacs-major-version 20)) + (list 'set-buffer-multibyte flag)) + (t + flag))) + +(defvar elmo-work-buf-name " *elmo work*") +(defvar elmo-temp-buf-name " *elmo temp*") + +(or (boundp 'default-enable-multibyte-characters) + (defvar default-enable-multibyte-characters (featurep 'mule) + "The mock variable except for Emacs 20.")) + +(defun elmo-base64-encode-string (string &optional no-line-break)) +(defun elmo-base64-decode-string (string)) + +;; base64 encoding/decoding +(require 'mel) +(fset 'elmo-base64-encode-string + (mel-find-function 'mime-encode-string "base64")) +(fset 'elmo-base64-decode-string + (mel-find-function 'mime-decode-string "base64")) + +;; Any Emacsen may have add-name-to-file(), because loadup.el requires it. :-p +;; Check make-symbolic-link() instead. -- 981002 by Fuji +(if (fboundp 'make-symbolic-link) ;; xxx + (defalias 'elmo-add-name-to-file 'add-name-to-file) + (defun elmo-add-name-to-file + (filename newname &optional ok-if-already-exists) + (copy-file filename newname ok-if-already-exists t))) + +(require 'broken) +(broken-facility timezone-y2k + "timezone.el does not clear Y2K." + (or (not (featurep 'timezone)) + (string= (aref (timezone-parse-date "Sat, 1 Jan 00 07:00:00 JST") 0) + "2000"))) + +(when-broken timezone-y2k + (defun timezone-parse-date (date) + "Parse DATE and return a vector [YEAR MONTH DAY TIME TIMEZONE]. +19 is prepended to year if necessary. Timezone may be nil if nothing. +Understands the following styles: + (1) 14 Apr 89 03:20[:12] [GMT] + (2) Fri, 17 Mar 89 4:01[:33] [GMT] + (3) Mon Jan 16 16:12[:37] [GMT] 1989 + (4) 6 May 1992 1641-JST (Wednesday) + (5) 22-AUG-1993 10:59:12.82 + (6) Thu, 11 Apr 16:17:12 91 [MET] + (7) Mon, 6 Jul 16:47:20 T 1992 [MET]" + (condition-case nil + (progn + ;; Get rid of any text properties. + (and (stringp date) + (or (text-properties-at 0 date) + (next-property-change 0 date)) + (setq date (copy-sequence date)) + (set-text-properties 0 (length date) nil date)) + (let ((date (or date "")) + (year nil) + (month nil) + (day nil) + (time nil) + (zone nil)) ;This may be nil. + (cond ((string-match + "\\([^ \t,]+\\),[ \t]+\\([0-9]+\\)[ \t]+\\([^ \t,]+\\)[ \t]+\\([0-9]+:[0-9:]+\\)[ \t]+\\(T[ \t]+\\|\\)\\([0-9]+\\)[ \t]*\\'" date) + ;; Styles: (6) and (7) without timezone + (setq year 6 month 3 day 2 time 4 zone nil)) + ((string-match + "\\([^ \t,]+\\),[ \t]+\\([0-9]+\\)[ \t]+\\([^ \t,]+\\)[ \t]+\\([0-9]+:[0-9:]+\\)[ \t]+\\(T[ \t]+\\|\\)\\([0-9]+\\)[ \t]*\\([-+a-zA-Z0-9]+\\)" date) + ;; Styles: (6) and (7) with timezone and buggy timezone + (setq year 6 month 3 day 2 time 4 zone 7)) + ((string-match + "\\([0-9]+\\)[ \t]+\\([^ \t,]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\([0-9]+:[0-9:]+\\)[ \t]*\\'" date) + ;; Styles: (1) and (2) without timezone + (setq year 3 month 2 day 1 time 4 zone nil)) + ((string-match + "\\([0-9]+\\)[ \t]+\\([^ \t,]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\([0-9]+:[0-9:]+\\)[ \t]*\\([-+a-zA-Z0-9]+\\)" date) + ;; Styles: (1) and (2) with timezone and buggy timezone + (setq year 3 month 2 day 1 time 4 zone 5)) + ((string-match + "\\([^ \t,]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\([0-9]+:[0-9:]+\\)[ \t]+\\([0-9]+\\)" date) + ;; Styles: (3) without timezone + (setq year 4 month 1 day 2 time 3 zone nil)) + ((string-match + "\\([^ \t,]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\([0-9]+:[0-9:]+\\)[ \t]+\\([-+a-zA-Z0-9]+\\)[ \t]+\\([0-9]+\\)" date) + ;; Styles: (3) with timezone + (setq year 5 month 1 day 2 time 3 zone 4)) + ((string-match + "\\([0-9]+\\)[ \t]+\\([^ \t,]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\([0-9]+\\)[ \t]*\\([-+a-zA-Z0-9]+\\)" date) + ;; Styles: (4) with timezone + (setq year 3 month 2 day 1 time 4 zone 5)) + ((string-match + "\\([0-9]+\\)-\\([A-Za-z]+\\)-\\([0-9]+\\)[ \t]+\\([0-9]+:[0-9]+:[0-9]+\\)\\.[0-9]+" date) + ;; Styles: (5) without timezone. + (setq year 3 month 2 day 1 time 4 zone nil)) + ) + (if year + (progn + (setq year + (substring date (match-beginning year) + (match-end year))) + (if (< (length year) 4) + (let ((yr (string-to-int year))) + (when (>= yr 100) + (setq yr (- yr 100))) + (setq year (format "%d%02d" + (if (< yr 70) + 20 + 19) + yr)))) + (let ((string (substring date + (match-beginning month) + (+ (match-beginning month) 3)))) + (setq month + (int-to-string + (cdr (assoc (upcase string) + timezone-months-assoc))))) + (setq day + (substring date (match-beginning day) (match-end day))) + (setq time + (substring date (match-beginning time) + (match-end time))))) + (if zone + (setq zone + (substring date (match-beginning zone) + (match-end zone)))) + (if year + (vector year month day time zone) + (vector "0" "0" "0" "0" nil)) + ) + ) + (t (signal 'invalid-date (list date)))))) + +(defsubst elmo-call-func (folder func-name &rest args) + (let* ((spec (if (stringp folder) + (elmo-folder-get-spec folder) + folder)) + (type (symbol-name (car spec))) + (backend-str (concat "elmo-" type)) + (backend-sym (intern backend-str))) + (unless (featurep backend-sym) + (require backend-sym)) + (apply (intern (format "%s-%s" backend-str func-name)) + spec + args))) + +(defmacro elmo-set-work-buf (&rest body) + "Execute BODY on work buffer. Work buffer remains." + (` (save-excursion + (set-buffer (get-buffer-create elmo-work-buf-name)) + (elmo-set-buffer-multibyte default-enable-multibyte-characters) + (erase-buffer) + (,@ body)))) + +(defmacro elmo-match-substring (pos string from) + "Substring of POSth matched string of STRING. " + (` (substring (, string) + (+ (match-beginning (, pos)) (, from)) + (match-end (, pos))))) + +(defmacro elmo-match-string (pos string) + "Substring POSth matched string." + (` (substring (, string) (match-beginning (, pos)) (match-end (, pos))))) + +(defmacro elmo-match-buffer (pos) + "Substring POSth matched from the current buffer." + (` (buffer-substring-no-properties + (match-beginning (, pos)) (match-end (, pos))))) + +(defmacro elmo-bind-directory (dir &rest body) + "Set current directory DIR and execute BODY." + (` (let ((default-directory (file-name-as-directory (, dir)))) + (,@ body)))) + +(defmacro elmo-folder-get-type (folder) + "Get type of FOLDER." + (` (and (stringp (, folder)) + (cdr (assoc (string-to-char (, folder)) elmo-spec-alist))))) + +(defun elmo-object-load (filename &optional mime-charset no-err) + "Load OBJECT from the file specified by FILENAME. +File content is decoded with MIME-CHARSET." + (if (not (file-readable-p filename)) + nil + (elmo-set-work-buf + (as-binary-input-file + (insert-file-contents filename)) + (when mime-charset + (elmo-set-buffer-multibyte default-enable-multibyte-characters) + (decode-mime-charset-region (point-min) (point-max) mime-charset)) + (condition-case nil + (read (current-buffer)) + (error (unless no-err + (message "Warning: Loading object from %s failed." + filename) + (elmo-object-save filename nil)) + nil))))) + +(defsubst elmo-save-buffer (filename &optional mime-charset) + "Save current buffer to the file specified by FILENAME. +Directory of the file is created if it doesn't exist. +File content is encoded with MIME-CHARSET." + (let ((dir (directory-file-name (file-name-directory filename)))) + (if (file-directory-p dir) + () ; ok. + (unless (file-exists-p dir) + (elmo-make-directory dir))) + (if (file-writable-p filename) + (progn + (when mime-charset + ;;(elmo-set-buffer-multibyte default-enable-multibyte-characters) + (encode-mime-charset-region (point-min) (point-max) mime-charset)) + (as-binary-output-file + (write-region (point-min) (point-max) filename nil 'no-msg))) + (message (format "%s is not writable." filename))))) + +(defun elmo-object-save (filename object &optional mime-charset) + "Save OBJECT to the file specified by FILENAME. +Directory of the file is created if it doesn't exist. +File content is encoded with MIME-CHARSET." + (elmo-set-work-buf + (prin1 object (current-buffer)) + ;;(princ "\n" (current-buffer)) + (elmo-save-buffer filename mime-charset))) + +(defsubst elmo-imap4-decode-folder-string (string) + (if elmo-imap4-use-modified-utf7 + (utf7-decode-string string 'imap) + string)) + +(defsubst elmo-imap4-encode-folder-string (string) + (if elmo-imap4-use-modified-utf7 + (utf7-encode-string string 'imap) + string)) + +(defun elmo-network-get-spec (folder default-server default-port default-tls) + (let (server port tls) + (if (string-match "\\(@[^@:/!]+\\)?\\(:[0-9]+\\)?\\(!*\\)$" folder) + (progn + (if (match-beginning 1) + (setq server (elmo-match-substring 1 folder 1)) + (setq server default-server)) + (if (match-beginning 2) + (setq port + (string-to-int (elmo-match-substring 2 folder 1))) + (setq port default-port)) + (setq tls (elmo-match-string 3 folder)) + (if (and (match-beginning 3) + (> (length tls) 0)) + (setq tls (if (= 2 (length tls)) 'starttls + (string= tls "!"))) + (setq tls default-tls)) + (setq folder (substring folder 0 (match-beginning 0)))) + (setq server default-server + port default-port + tls default-tls)) + (cons folder (list server port tls)))) + +(defun elmo-imap4-get-spec (folder) + (let ((default-user elmo-default-imap4-user) + (default-server elmo-default-imap4-server) + (default-port elmo-default-imap4-port) + (default-tls elmo-default-imap4-ssl) + spec mailbox user auth) + (when (string-match "\\(.*\\)@\\(.*\\)" default-server) + ;; case: default-imap4-server is specified like + ;; "hoge%imap.server@gateway". + (setq default-user (elmo-match-string 1 default-server)) + (setq default-server (elmo-match-string 2 default-server))) + (setq spec (elmo-network-get-spec + folder default-server default-port default-tls)) + (setq folder (car spec)) + (when (string-match + "^\\(%\\)\\([^:@!]*\\)\\(:[^/!]+\\)?\\(/[^/:@!]+\\)?" + folder) + (progn + (setq mailbox (if (match-beginning 2) + (elmo-match-string 2 folder) + elmo-default-imap4-mailbox)) + (setq user (if (match-beginning 3) + (elmo-match-substring 3 folder 1) + default-user)) + (setq auth (if (match-beginning 4) + (elmo-match-substring 4 folder 1) + elmo-default-imap4-authenticate-type)) + (append (list 'imap4 + (elmo-imap4-encode-folder-string mailbox) + user auth) + (cdr spec)))))) + +(defsubst elmo-imap4-spec-mailbox (spec) + (nth 1 spec)) + +(defsubst elmo-imap4-spec-username (spec) + (nth 2 spec)) + +(defsubst elmo-imap4-spec-auth (spec) + (nth 3 spec)) + +(defsubst elmo-imap4-spec-hostname (spec) + (nth 4 spec)) + +(defsubst elmo-imap4-spec-port (spec) + (nth 5 spec)) + +(defsubst elmo-imap4-spec-ssl (spec) + (nth 6 spec)) + +(defsubst elmo-imap4-spec-folder (spec) ;; obsolete + (nth 1 spec)) + +(defsubst elmo-imap4-connection-get-process (conn) + (nth 1 conn)) + +(defsubst elmo-imap4-connection-get-buffer (conn) + (nth 0 conn)) + +(defsubst elmo-imap4-connection-get-cwf (conn) + (nth 2 conn)) + +(defun elmo-nntp-get-spec (folder) + (let (spec group user) + (setq spec (elmo-network-get-spec folder + elmo-default-nntp-server + elmo-default-nntp-port + elmo-default-nntp-ssl)) + (setq folder (car spec)) + (when (string-match + "^\\(-\\)\\([^:@!]*\\)\\(:[^/!]+\\)?\\(/[^/:@!]+\\)?" + folder) + (setq group + (if (match-beginning 2) + (elmo-match-string 2 folder))) + (setq user + (if (match-beginning 3) + (elmo-match-substring 3 folder 1) + elmo-default-nntp-user)) + (append (list 'nntp group user) + (cdr spec))))) + +(defsubst elmo-nntp-spec-group (spec) + (nth 1 spec)) + +(defsubst elmo-nntp-spec-username (spec) + (nth 2 spec)) + +;; future use? +;; (defsubst elmo-nntp-spec-auth (spec)) + +(defsubst elmo-nntp-spec-hostname (spec) + (nth 3 spec)) + +(defsubst elmo-nntp-spec-port (spec) + (nth 4 spec)) + +(defsubst elmo-nntp-spec-ssl (spec) + (nth 5 spec)) + +(defun elmo-localdir-get-spec (folder) + (let (fld-name path) + (when (string-match + "^\\(\\+\\)\\(.*\\)$" + folder) + (if (eq (length (setq fld-name + (elmo-match-string 2 folder))) 0) + (setq fld-name "") + ) + (if (file-name-absolute-p fld-name) + (setq path (expand-file-name fld-name)) + (setq path fld-name)) + ;(setq path (expand-file-name fld-name + ;elmo-localdir-folder-path))) + (list (if (elmo-folder-maildir-p folder) + 'maildir + 'localdir) path)))) + +(defun elmo-maildir-get-spec (folder) + (let (fld-name path) + (when (string-match + "^\\(\\.\\)\\(.*\\)$" + folder) + (if (eq (length (setq fld-name + (elmo-match-string 2 folder))) 0) + (setq fld-name "")) + (if (file-name-absolute-p fld-name) + (setq path (expand-file-name fld-name)) + (setq path fld-name)) + (list 'maildir path)))) + +(defun elmo-folder-maildir-p (folder) + (catch 'found + (let ((li elmo-maildir-list)) + (while li + (if (string-match (car li) folder) + (throw 'found t)) + (setq li (cdr li)))))) + +(defun elmo-localnews-get-spec (folder) + (let (fld-name) + (when (string-match + "^\\(=\\)\\(.*\\)$" + folder) + (if (eq (length (setq fld-name + (elmo-match-string 2 folder))) 0) + (setq fld-name "") + ) + (list 'localnews + (elmo-replace-in-string fld-name "\\." "/"))))) + +(defun elmo-cache-get-spec (folder) + (let (fld-name) + (when (string-match + "^\\(!\\)\\(.*\\)$" + folder) + (if (eq (length (setq fld-name + (elmo-match-string 2 folder))) 0) + (setq fld-name "") + ) + (list 'cache + (elmo-replace-in-string fld-name "\\." "/"))))) + +;; Archive interface by OKUNISHI Fujikazu +(defun elmo-archive-get-spec (folder) + (require 'elmo-archive) + (let (fld-name type prefix) + (when (string-match + "^\\(\\$\\)\\([^;]*\\);?\\([^;]*\\);?\\([^;]*\\)$" + folder) + ;; Drive letter is OK! + (if (eq (length (setq fld-name + (elmo-match-string 2 folder))) 0) + (setq fld-name "") + ) + (if (eq (length (setq type + (elmo-match-string 3 folder))) 0) + (setq type (symbol-name elmo-archive-default-type))) + (if (eq (length (setq prefix + (elmo-match-string 4 folder))) 0) + (setq prefix "")) + (list 'archive fld-name (intern-soft type) prefix)))) + +(defun elmo-pop3-get-spec (folder) + (let (spec user auth) + (setq spec (elmo-network-get-spec folder + elmo-default-pop3-server + elmo-default-pop3-port + elmo-default-pop3-ssl)) + (setq folder (car spec)) + (when (string-match + "^\\(&\\)\\([^:/!]*\\)\\(/[^/:@!]+\\)?" + folder) + (setq user (if (match-beginning 2) + (elmo-match-string 2 folder))) + (if (eq (length user) 0) + (setq user elmo-default-pop3-user)) + (setq auth (if (match-beginning 3) + (elmo-match-substring 3 folder 1) + elmo-default-pop3-authenticate-type)) + (append (list 'pop3 user auth) + (cdr spec))))) + +(defsubst elmo-pop3-spec-username (spec) + (nth 1 spec)) + +(defsubst elmo-pop3-spec-auth (spec) + (nth 2 spec)) + +(defsubst elmo-pop3-spec-hostname (spec) + (nth 3 spec)) + +(defsubst elmo-pop3-spec-port (spec) + (nth 4 spec)) + +(defsubst elmo-pop3-spec-ssl (spec) + (nth 5 spec)) + +(defun elmo-internal-get-spec (folder) + (if (string-match "\\('\\)\\([^/]*\\)/?\\(.*\\)$" folder) + (let* ((item (downcase (elmo-match-string 2 folder))) + (sym (and (> (length item) 0) (intern item)))) + (cond ((or (null sym) + (eq sym 'mark)) + (list 'internal sym (elmo-match-string 3 folder))) + ((eq sym 'cache) + (list 'cache (elmo-match-string 3 folder))) + (t (error "Invalid internal folder spec")))))) + +(defun elmo-multi-get-spec (folder) + (save-match-data + (when (string-match + "^\\(\\*\\)\\(.*\\)$" + folder) + (append (list 'multi) + (split-string + (elmo-match-string 2 folder) + ","))))) + +(defun elmo-filter-get-spec (folder) + (save-match-data + (when (string-match + "^\\(/\\)\\(.*\\)$" + folder) + (let ((spec (elmo-match-string 2 folder)) + filter) + (when (string-match "\\([^/]+\\)/" spec) + (setq filter (elmo-match-string 1 spec)) + (setq spec (substring spec (match-end 0)))) + (cond + ((string-match "^\\(last\\|first\\):\\(.*\\)$" filter) ; partial + (setq filter (vector 'partial + (elmo-match-string 1 filter) + (elmo-match-string 2 filter)))) + (t + (setq filter (elmo-parse-search-condition filter)))) + (list 'filter filter spec))))) + +(defun elmo-pipe-get-spec (folder) + (when (string-match "^\\(|\\)\\([^|]*\\)|\\(.*\\)$" folder) + (list 'pipe + (elmo-match-string 2 folder) + (elmo-match-string 3 folder)))) + +(defun elmo-folder-get-spec (folder) + "return spec of folder" + (let ((type (elmo-folder-get-type folder))) + (if type + (funcall (intern (concat "elmo-" (symbol-name type) "-get-spec")) + folder) + (error "%s is not supported folder type" folder)))) + +(defun elmo-parse-search-condition (condition) + (let ((terms (split-string condition "|")) ; split by OR + term ret-val) + (while terms + (setq term (car terms)) + (cond + ((string-match "^\\([a-zA-Z\\-]+\\)=\\(.*\\)$" term) + (if (save-match-data + (string-match "tocc" (elmo-match-string 1 term))) ;; syntax sugar + (setq ret-val (nconc + ret-val + (list (vector 'match "to" + (elmo-match-string 2 term)) + (vector 'match "cc" + (elmo-match-string 2 term))))) + (setq ret-val (cons (vector 'match + (elmo-match-string 1 term) + (elmo-match-string 2 term)) + ret-val)))) + ((string-match "^\\([a-zA-Z\\-]+\\)!=\\(.*\\)$" term) + (if (save-match-data + (string-match "tocc" (elmo-match-string 1 term))) ;; syntax sugar + (setq ret-val (nconc + ret-val + (list (vector 'unmatch "to" + (elmo-match-string 2 term)) + (vector 'unmatch "cc" + (elmo-match-string 2 term))))) + (setq ret-val (cons (vector 'unmatch + (elmo-match-string 1 term) + (elmo-match-string 2 term)) + ret-val)))) + ((string-match "^\\(since\\|before\\):\\(.*\\)$" term) + (setq ret-val (cons (vector 'date + (elmo-match-string 1 term) + (elmo-match-string 2 term)) + ret-val)))) + (setq terms (cdr terms))) + ret-val)) + +(defun elmo-multi-get-real-folder-number (folder number) + (let* ((spec (elmo-folder-get-spec folder)) + (flds (cdr spec)) + (num number) + (fld (nth (- (/ num elmo-multi-divide-number) 1) flds))) + (cons fld (% num elmo-multi-divide-number)))) + +(defsubst elmo-buffer-replace (regexp &optional newtext) + (goto-char (point-min)) + (while (re-search-forward regexp nil t) + (replace-match (or newtext "")))) + +(defsubst elmo-delete-char (char string &optional unibyte) + (save-match-data + (elmo-set-work-buf + (let ((coding-system-for-read 'no-conversion) + (coding-system-for-write 'no-conversion)) + (if unibyte (elmo-set-buffer-multibyte nil)) + (insert string) + (goto-char (point-min)) + (while (search-forward (char-to-string char) nil t) + (replace-match "")) + (buffer-string))))) + +(defsubst elmo-delete-cr-get-content-type () + (save-excursion + (goto-char (point-min)) + (while (search-forward "\r\n" nil t) + (replace-match "\n")) + (goto-char (point-min)) + (or (std11-field-body "content-type") + t))) + +(defun elmo-delete-cr (string) + (save-match-data + (elmo-set-work-buf + (insert string) + (goto-char (point-min)) + (while (search-forward "\r\n" nil t) + (replace-match "\n")) + (buffer-string)))) + +(defun elmo-uniq-list (lst) + "Distractively uniqfy elements of LST." + (let ((tmp lst)) + (while tmp (setq tmp (setcdr tmp (and (cdr tmp) (delete (car tmp) (cdr tmp))))))) + lst) + +(defun elmo-string-partial-p (string) + (and (stringp string) (string-match "message/partial" string))) + +(defun elmo-get-file-string (filename &optional remove-final-newline) + (elmo-set-work-buf + (let (insert-file-contents-pre-hook ; To avoid autoconv-xmas... + insert-file-contents-post-hook) + (when (file-exists-p filename) + (if filename + (as-binary-input-file (insert-file-contents filename))) + (when (and remove-final-newline + (> (buffer-size) 0) + (= (char-after (1- (point-max))) ?\n)) + (goto-char (point-max)) + (delete-backward-char 1)) + (buffer-string))))) + +(defun elmo-save-string (string filename) + (if string + (elmo-set-work-buf + (as-binary-output-file + (insert string) + (write-region (point-min) (point-max) + filename nil 'no-msg)) + ))) + +(defun elmo-max-of-list (nlist) + (let ((l nlist) + (max-num 0)) + (while l + (if (< max-num (car l)) + (setq max-num (car l))) + (setq l (cdr l))) + max-num)) + +(defun elmo-concat-path (path filename) + (if (not (string= path "")) + (if (string= elmo-path-sep (substring path (- (length path) 1))) + (concat path filename) + (concat path elmo-path-sep filename)) + filename)) + +(defvar elmo-passwd-alist nil) + +(defun elmo-passwd-alist-load () + (save-excursion + (let ((filename (expand-file-name elmo-passwd-alist-file-name + elmo-msgdb-dir)) + (tmp-buffer (get-buffer-create " *elmo-passwd-alist-tmp*")) + insert-file-contents-pre-hook ; To avoid autoconv-xmas... + insert-file-contents-post-hook + ret-val) + (if (not (file-readable-p filename)) + () + (set-buffer tmp-buffer) + (insert-file-contents filename) + (setq ret-val + (condition-case nil + (read (current-buffer)) + (error nil nil)))) + (kill-buffer tmp-buffer) + ret-val))) + +(defun elmo-passwd-alist-save () + "Save password into file." + (interactive) + (save-excursion + (let ((filename (expand-file-name elmo-passwd-alist-file-name + elmo-msgdb-dir)) + (tmp-buffer (get-buffer-create " *elmo-passwd-alist-tmp*"))) + (set-buffer tmp-buffer) + (erase-buffer) + (prin1 elmo-passwd-alist tmp-buffer) + (princ "\n" tmp-buffer) +; (if (and (file-exists-p filename) +; (not (equal 384 (file-modes filename)))) +; (error "%s is not safe.chmod 600 %s!" filename filename)) + (if (file-writable-p filename) + (progn + (write-region (point-min) (point-max) + filename nil 'no-msg) + (set-file-modes filename 384)) + (message (format "%s is not writable." filename))) + (kill-buffer tmp-buffer)))) + +(defun elmo-get-passwd (user-at-host) + "Get password from password pool." + (let (data pass) + (if (not elmo-passwd-alist) + (setq elmo-passwd-alist (elmo-passwd-alist-load))) + (setq data (assoc user-at-host elmo-passwd-alist)) + (if data + (elmo-base64-decode-string (cdr data)) + (setq pass (elmo-read-passwd (format "Password for %s: " + user-at-host) t)) + (setq elmo-passwd-alist + (append elmo-passwd-alist + (list (cons user-at-host + (elmo-base64-encode-string pass))))) + pass))) + +(defun elmo-remove-passwd (user-at-host) + "Remove password from password pool (for failure)." + (setq elmo-passwd-alist + (delete (assoc user-at-host elmo-passwd-alist) + elmo-passwd-alist + ))) + +(defmacro elmo-read-char-exclusive () + (cond ((featurep 'xemacs) + '(let ((table (quote ((backspace . ?\C-h) (delete . ?\C-?) + (left . ?\C-h)))) + event key) + (while (not + (and + (key-press-event-p (setq event (next-command-event))) + (setq key (or (event-to-character event) + (cdr (assq (event-key event) table))))))) + key)) + ((fboundp 'read-char-exclusive) + '(read-char-exclusive)) + (t + '(read-char)))) + +(defun elmo-read-passwd (prompt &optional stars) + "Read a single line of text from user without echoing, and return it." + (let ((ans "") + (c 0) + (echo-keystrokes 0) + (cursor-in-echo-area t) + (log-message-max-size 0) + message-log-max done msg truncate) + (while (not done) + (if (or (not stars) (string= "" ans)) + (setq msg prompt) + (setq msg (concat prompt (make-string (length ans) ?.))) + (setq truncate + (1+ (- (length msg) (window-width (minibuffer-window))))) + (and (> truncate 0) + (setq msg (concat "$" (substring msg (1+ truncate)))))) + (message "%s" msg) + (setq c (elmo-read-char-exclusive)) + (cond ((= c ?\C-g) + (setq quit-flag t + done t)) + ((or (= c ?\r) (= c ?\n) (= c ?\e)) + (setq done t)) + ((= c ?\C-u) + (setq ans "")) + ((and (/= c ?\b) (/= c ?\177)) + (setq ans (concat ans (char-to-string c)))) + ((> (length ans) 0) + (setq ans (substring ans 0 -1))))) + (if quit-flag + (prog1 + (setq quit-flag nil) + (message "Quit") + (beep t)) + (message "") + ans))) + +;; from subr.el +(defun elmo-replace-in-string (str regexp newtext &optional literal) + "Replaces all matches in STR for REGEXP with NEWTEXT string, + and returns the new string. +Optional LITERAL non-nil means do a literal replacement. +Otherwise treat \\ in NEWTEXT string as special: + \\& means substitute original matched text, + \\N means substitute match for \(...\) number N, + \\\\ means insert one \\." + (let ((rtn-str "") + (start 0) + (special) + match prev-start) + (while (setq match (string-match regexp str start)) + (setq prev-start start + start (match-end 0) + rtn-str + (concat + rtn-str + (substring str prev-start match) + (cond (literal newtext) + (t (mapconcat + (function + (lambda (c) + (if special + (progn + (setq special nil) + (cond ((eq c ?\\) "\\") + ((eq c ?&) + (elmo-match-string 0 str)) + ((and (>= c ?0) (<= c ?9)) + (if (> c (+ ?0 (length + (match-data)))) + ; Invalid match num + (error "Invalid match num: %c" c) + (setq c (- c ?0)) + (elmo-match-string c str))) + (t (char-to-string c)))) + (if (eq c ?\\) (progn (setq special t) nil) + (char-to-string c))))) + newtext "")))))) + (concat rtn-str (substring str start)))) + +(defun elmo-string-to-list (string) + (elmo-set-work-buf + (insert string) + (goto-char (point-min)) + (insert "(") + (goto-char (point-max)) + (insert ")") + (goto-char (point-min)) + (read (current-buffer)))) + +(defun elmo-plug-on-by-servers (alist &optional servers) + (let ((server-list (or servers elmo-plug-on-servers))) + (catch 'plugged + (while server-list + (if (elmo-plugged-p (car server-list)) + (throw 'plugged t)) + (setq server-list (cdr server-list)))))) + +(defun elmo-plug-on-by-exclude-servers (alist &optional servers) + (let ((server-list (or servers elmo-plug-on-exclude-servers)) + server other-servers) + (while alist + (when (and (not (member (setq server (caaar alist)) server-list)) + (not (member server other-servers))) + (push server other-servers)) + (setq alist (cdr alist))) + (elmo-plug-on-by-servers alist other-servers))) + +(defun elmo-plugged-p (&optional server port alist label-exp) + (let ((alist (or alist elmo-plugged-alist)) + plugged-info) + (cond ((and (not port) (not server)) + (cond ((eq elmo-plugged-condition 'one) + (catch 'plugged + (while alist + (if (nth 2 (car alist)) + (throw 'plugged t)) + (setq alist (cdr alist))))) + ((eq elmo-plugged-condition 'all) + (catch 'plugged + (while alist + (if (not (nth 2 (car alist))) + (throw 'plugged nil)) + (setq alist (cdr alist))) + t)) + ((functionp elmo-plugged-condition) + (funcall elmo-plugged-condition alist)) + (t ;; independent + elmo-plugged))) + ((not port) ;; server + (catch 'plugged + (while alist + (when (string= server (caaar alist)) + (if (nth 2 (car alist)) + (throw 'plugged t))) + (setq alist (cdr alist))))) + (t + (setq plugged-info (assoc (cons server port) alist)) + (if (not plugged-info) + ;; add elmo-plugged-alist automatically + (progn + (elmo-set-plugged elmo-plugged server port nil nil label-exp) + elmo-plugged) + (if (and elmo-auto-change-plugged + (> elmo-auto-change-plugged 0) + (nth 3 plugged-info) ;; time + (elmo-time-expire (nth 3 plugged-info) + elmo-auto-change-plugged)) + t + (nth 2 plugged-info))))))) + +(defun elmo-set-plugged (plugged &optional server port time + alist label-exp add) + (let ((alist (or alist elmo-plugged-alist)) + label plugged-info) + (cond ((and (not port) (not server)) + (setq elmo-plugged plugged) + ;; set plugged all element of elmo-plugged-alist. + (while alist + (setcdr (cdar alist) (list plugged time)) + (setq alist (cdr alist)))) + ((not port) + ;; set plugged all port of server + (while alist + (when (string= server (caaar alist)) + (setcdr (cdar alist) (list plugged time))) + (setq alist (cdr alist)))) + (t + ;; set plugged one port of server + (setq plugged-info (assoc (cons server port) alist)) + (setq label (if label-exp + (eval label-exp) + (nth 1 plugged-info))) + (if plugged-info + ;; if add is non-nil, don't reset plug state. + (unless add + (setcdr plugged-info (list label plugged time))) + (setq alist + (setq elmo-plugged-alist + (nconc elmo-plugged-alist + (list + (list (cons server port) label plugged time)))))))) + alist)) + +(defun elmo-delete-plugged (&optional server port alist) + (let* ((alist (or alist elmo-plugged-alist)) + (alist2 alist)) + (cond ((and (not port) (not server)) + (setq alist nil)) + ((not port) + ;; delete plugged all port of server + (while alist2 + (when (string= server (caaar alist2)) + (setq alist (delete (car alist2) alist))) + (setq alist2 (cdr alist2)))) + (t + ;; delete plugged one port of server + (setq alist + (delete (assoc (cons server port) alist)) alist))) + alist)) + +(defun elmo-disk-usage (path) + "Get disk usage (bytes) in PATH." + (let ((file-attr + (condition-case () (file-attributes path) (error nil)))) + (if file-attr + (if (nth 0 file-attr) ; directory + (let ((files (condition-case () + (directory-files path t "^[^\\.]") + (error nil))) + (result 0.0)) + ;; (result (nth 7 file-attr))) ... directory size + (while files + (setq result (+ result (or (elmo-disk-usage (car files)) 0))) + (setq files (cdr files))) + result) + (float (nth 7 file-attr)))))) + +(defun elmo-get-last-accessed-time (path &optional dir) + "Returns last accessed time." + (let ((last-accessed (nth 4 (file-attributes (or (and dir + (expand-file-name + path dir)) + path))))) + (if last-accessed + (setq last-accessed (+ (* (nth 0 last-accessed) + (float 65536)) (nth 1 last-accessed))) + 0))) + +(defun elmo-get-last-modification-time (path &optional dir) + "Returns last accessed time." + (let ((last-modified (nth 5 (file-attributes (or (and dir + (expand-file-name + path dir)) + path))))) + (setq last-modified (+ (* (nth 0 last-modified) + (float 65536)) (nth 1 last-modified))))) + +(defun elmo-make-directory (path) + "create directory recursively." + (let ((parent (directory-file-name (file-name-directory path)))) + (if (null (file-directory-p parent)) + (elmo-make-directory parent)) + (make-directory path) + (if (string= path (expand-file-name elmo-msgdb-dir)) + (set-file-modes path 448) ; 700 + ))) + +(defun elmo-delete-directory (path &optional no-hierarchy) + "delete directory recursively." + (let ((dirent (directory-files path)) + relpath abspath hierarchy) + (while dirent + (setq relpath (car dirent) + dirent (cdr dirent) + abspath (expand-file-name relpath path)) + (when (not (string-match "^\\.\\.?$" relpath)) + (if (eq (nth 0 (file-attributes abspath)) t) + (if no-hierarchy + (setq hierarchy t) + (elmo-delete-directory abspath no-hierarchy)) + (delete-file abspath)))) + (unless hierarchy + (delete-directory path)))) + +(defun elmo-list-filter (l1 l2) + "L1 is filter." + (if (eq l1 t) + ;; t means filter all. + nil + (if l1 + (elmo-delete-if (lambda (x) (not (memq x l1))) l2) + ;; filter is nil + l2))) + +(defun elmo-folder-local-p (folder) + "Return whether FOLDER is a local folder or not." + (let ((type (elmo-folder-get-type folder))) + (memq type '(localdir localnews archive maildir internal cache)))) + +(defun elmo-folder-writable-p (folder) + (let ((type (elmo-folder-get-type folder))) + (memq type '(imap4 localdir archive)))) + +(defun elmo-multi-get-intlist-list (numlist &optional as-is) + (let ((numbers (sort numlist '<)) + (cur-number 0) + one-list int-list-list) + (while numbers + (setq cur-number (+ cur-number 1)) + (setq one-list nil) + (while (and numbers + (eq 0 + (/ (- (car numbers) + (* elmo-multi-divide-number cur-number)) + elmo-multi-divide-number))) + (setq one-list (nconc + one-list + (list + (if as-is + (car numbers) + (% (car numbers) + (* elmo-multi-divide-number cur-number)))))) + (setq numbers (cdr numbers))) + (setq int-list-list (nconc int-list-list (list one-list)))) + int-list-list)) + +(defsubst elmo-list-delete-if-smaller (list number) + (let ((ret-val (copy-sequence list))) + (while list + (if (< (car list) number) + (setq ret-val (delq (car list) ret-val))) + (setq list (cdr list))) + ret-val)) + +(defun elmo-list-diff (list1 list2 &optional mes) + (if mes + (message mes)) + (let ((clist1 (copy-sequence list1)) + (clist2 (copy-sequence list2))) + (while list2 + (setq clist1 (delq (car list2) clist1)) + (setq list2 (cdr list2))) + (while list1 + (setq clist2 (delq (car list1) clist2)) + (setq list1 (cdr list1))) + (if mes + (message (concat mes "done."))) + (list clist1 clist2))) + +(defun elmo-list-bigger-diff (list1 list2 &optional mes) + "Returns a list (- +). + is bigger than max of LIST1, in LIST2" + (if (null list2) + (cons list1 nil) + (let* ((l1 list1) + (l2 list2) + (max-of-l2 (or (nth (max 0 (1- (length l2))) l2) 0)) + diff1 num i percent + ) + (setq i 0) + (setq num (+ (length l1))) + (while l1 + (if (memq (car l1) l2) + (if (eq (car l1) (car l2)) + (setq l2 (cdr l2)) + (delq (car l1) l2)) + (if (> (car l1) max-of-l2) + (setq diff1 (nconc diff1 (list (car l1)))))) + (if mes + (progn + (setq i (+ i 1)) + (setq percent (/ (* i 100) num)) + (if (eq (% percent 5) 0) + (elmo-display-progress + 'elmo-list-bigger-diff "%s%d%%" percent mes)))) + (setq l1 (cdr l1))) + (cons diff1 (list l2))))) + +(defun elmo-multi-list-bigger-diff (list1 list2 &optional mes) + (let ((list1-list (elmo-multi-get-intlist-list list1 t)) + (list2-list (elmo-multi-get-intlist-list list2 t)) + result + dels news) + (while (or list1-list list2-list) + (setq result (elmo-list-bigger-diff (car list1-list) (car list2-list) + mes)) + (setq dels (append dels (car result))) + (setq news (append news (cadr result))) + (setq list1-list (cdr list1-list)) + (setq list2-list (cdr list2-list))) + (cons dels (list news)))) + +(defvar elmo-imap4-name-space-regexp-list nil) +(defun elmo-imap4-identical-name-space-p (fld1 fld2) + ;; only on UW? + (if (or (eq (string-to-char fld1) ?#) + (eq (string-to-char fld2) ?#)) + (string= (car (split-string fld1 "/")) + (car (split-string fld2 "/"))) + t)) + +(defun elmo-folder-identical-system-p (folder1 folder2) + "folder1 and folder2 should be real folder (not virtual)." + (cond ((eq (elmo-folder-get-type folder1) 'imap4) + (let ((spec1 (elmo-folder-get-spec folder1)) + (spec2 (elmo-folder-get-spec folder2))) + (and (elmo-imap4-identical-name-space-p + (nth 1 spec1) (nth 1 spec2)) + (string= (elmo-imap4-spec-hostname spec1) + (elmo-imap4-spec-hostname spec2)) ; hostname + (string= (elmo-imap4-spec-username spec1) + (elmo-imap4-spec-username spec2))))) ; username + (t + (elmo-folder-direct-copy-p folder1 folder2)))) + +(defconst elmo-folder-direct-copy-alist + '((localdir . (localdir localnews archive)) + (maildir . (maildir localdir localnews archive)) + (localnews . (localdir localnews archive)) + (archive . (localdir localnews archive)) + (cache . (localdir localnews archive)))) + +(defun elmo-folder-direct-copy-p (src-folder dst-folder) + (let ((src-type (car (elmo-folder-get-spec src-folder))) + (dst-type (car (elmo-folder-get-spec dst-folder))) + dst-copy-type) + (and (setq dst-copy-type + (cdr (assq src-type elmo-folder-direct-copy-alist))) + (memq dst-type dst-copy-type)))) + +(defmacro elmo-filter-type (filter) + (` (aref (, filter) 0))) + +(defmacro elmo-filter-key (filter) + (` (aref (, filter) 1))) + +(defmacro elmo-filter-value (filter) + (` (aref (, filter) 2))) + +(defsubst elmo-buffer-field-condition-match (condition) + (let (term) + (catch 'done + (while condition + (goto-char (point-min)) + (setq term (car condition)) + (cond + ((and (eq (elmo-filter-type term) 'date) + (string= (elmo-filter-key term) "since")) + (let ((date (elmo-date-get-datevec (elmo-filter-value term)))) + (if (string< + (timezone-make-sortable-date (aref date 0) + (aref date 1) + (aref date 2) + (timezone-make-time-string + (aref date 3) + (aref date 4) + (aref date 5))) + (timezone-make-date-sortable (std11-field-body "date"))) + (throw 'done t)))) + ((and (eq (elmo-filter-type term) 'date) + (string= (elmo-filter-key term) "before")) + (let ((date (elmo-date-get-datevec (elmo-filter-value term)))) + (if (string< + (timezone-make-date-sortable (std11-field-body "date")) + (timezone-make-sortable-date (aref date 0) + (aref date 1) + (aref date 2) + (timezone-make-time-string + (aref date 3) + (aref date 4) + (aref date 5)))) + (throw 'done t)))) + ((eq (elmo-filter-type term) 'match) + (if (string= "body" (elmo-filter-key term)) + (progn + (re-search-forward "^$" nil t) ; goto body + (if (search-forward (elmo-filter-value term) nil t) + (throw 'done t))) + (let ((fval (eword-decode-string + (or (std11-field-body (elmo-filter-key term)) "")))) + (if (and fval (string-match (elmo-filter-value term) + fval)) + (throw 'done t))))) + ((eq (elmo-filter-type term) 'unmatch) + (if (string= "body" (elmo-filter-key term)) + (progn + (re-search-forward "^$" nil t) ; goto body + (if (not (search-forward (elmo-filter-value term) nil t)) + (throw 'done t))) + (let ((fval (eword-decode-string + (or (std11-field-body (elmo-filter-key term)) "")))) + (if fval + (if (not (string-match (elmo-filter-value term) + fval)) + (throw 'done t)) + (throw 'done t)))))) ; OK? + (setq condition (cdr condition))) + (throw 'done nil)))) + +(defsubst elmo-file-field-condition-match (file condition) + (elmo-set-work-buf + (as-binary-input-file + (insert-file-contents file)) + (elmo-set-buffer-multibyte default-enable-multibyte-characters) + (decode-mime-charset-region (point-min)(point-max) elmo-mime-charset) + (elmo-buffer-field-condition-match condition))) + +(defun elmo-cross-device-link-error-p (err) + (let ((errobj err) + cur) + (catch 'done + (while errobj + (if (and (stringp (setq cur (car errobj))) + (or (string-match "cross-device" cur) + (string-match "operation not supported" cur))) + (throw 'done t)) + (setq errobj (cdr errobj))) + nil))) + +(defmacro elmo-get-hash-val (string hashtable) + (let ((sym (list 'intern-soft string hashtable))) + (list 'if (list 'boundp sym) + (list 'symbol-value sym)))) + +(defmacro elmo-set-hash-val (string value hashtable) + (list 'set (list 'intern string hashtable) value)) + +;; Make a hash table (default and minimum size is 1024). +(defun elmo-make-hash (&optional hashsize) + (make-vector (if hashsize (max (elmo-create-hash-size hashsize) 1024) 1024) 0)) + +(defsubst elmo-mime-string (string) + "Normalize MIME encoded string." + (and string + (let (str) + (elmo-set-work-buf + (elmo-set-buffer-multibyte default-enable-multibyte-characters) + (setq str (eword-decode-string + (decode-mime-charset-string string elmo-mime-charset))) + (setq str (encode-mime-charset-string str elmo-mime-charset)) + (elmo-set-buffer-multibyte nil) + str)))) + +(defsubst elmo-collect-field (beg end downcase-field-name) + (save-excursion + (save-restriction + (narrow-to-region beg end) + (goto-char (point-min)) + (let ((regexp (concat "\\(" std11-field-head-regexp "\\)[ \t]*")) + dest name body) + (while (re-search-forward regexp nil t) + (setq name (buffer-substring-no-properties + (match-beginning 1)(1- (match-end 1)))) + (if downcase-field-name + (setq name (downcase name))) + (setq body (buffer-substring-no-properties + (match-end 0) (std11-field-end))) + (or (assoc name dest) + (setq dest (cons (cons name body) dest)))) + dest)))) + +(defsubst elmo-collect-field-from-string (string downcase-field-name) + (with-temp-buffer + (insert string) + (goto-char (point-min)) + (let ((regexp (concat "\\(" std11-field-head-regexp "\\)[ \t]*")) + dest name body) + (while (re-search-forward regexp nil t) + (setq name (buffer-substring-no-properties + (match-beginning 1)(1- (match-end 1)))) + (if downcase-field-name + (setq name (downcase name))) + (setq body (buffer-substring-no-properties + (match-end 0) (std11-field-end))) + (or (assoc name dest) + (setq dest (cons (cons name body) dest)))) + dest))) + +(defun elmo-create-hash-size (min) + (let ((i 1)) + (while (< i min) + (setq i (* 2 i))) + i)) + +(defun elmo-safe-filename (folder) + (elmo-replace-in-string + (elmo-replace-in-string + (elmo-replace-in-string folder "/" " ") + ":" "__") + "|" "_or_")) + +(defvar elmo-msgid-replace-chars nil) + +(defsubst elmo-replace-msgid-as-filename (msgid) + "Replace message-id string as filename." + (setq msgid (elmo-replace-in-string msgid " " " ")) + (if (null elmo-msgid-replace-chars) + (setq elmo-msgid-replace-chars + (regexp-quote (mapconcat + 'car elmo-msgid-replace-string-alist "")))) + (while (string-match (concat "[" elmo-msgid-replace-chars "]") + msgid) + (setq msgid (concat + (substring msgid 0 (match-beginning 0)) + (cdr (assoc + (substring msgid + (match-beginning 0) (match-end 0)) + elmo-msgid-replace-string-alist)) + (substring msgid (match-end 0))))) + msgid) + +(defsubst elmo-recover-msgid-from-filename (filename) + "Recover Message-ID from filename." + (let (tmp result) + (while (string-match " " filename) + (setq tmp (substring filename + (match-beginning 0) + (+ (match-end 0) 1))) + (if (string= tmp " ") + (setq tmp " ") + (setq tmp (car (rassoc tmp + elmo-msgid-replace-string-alist)))) + (setq result + (concat result + (substring filename 0 (match-beginning 0)) + tmp)) + (setq filename (substring filename (+ (match-end 0) 1)))) + (concat result filename))) + +(defsubst elmo-copy-file (src dst) + (condition-case err + (elmo-add-name-to-file src dst t) + (error (if (elmo-cross-device-link-error-p err) + (copy-file src dst t) + (error "copy file failed"))))) + +(defmacro elmo-buffer-exists-p (buffer) + (` (when (, buffer) + (funcall (if (stringp (, buffer)) 'get-buffer 'buffer-name) + (, buffer))))) + +(defmacro elmo-kill-buffer (buffer) + (` (when (elmo-buffer-exists-p (, buffer)) + (kill-buffer (, buffer))))) + +(defun elmo-delete-lists (keys list) + "Delete all entries in LIST that equal to KEYS." + (while keys + (setq list (delete (car keys) list)) + (setq keys (cdr keys))) + list) + +(defun elmo-delete-if (pred lst) + "Returns new list contains items which don't satisfy PRED in LST." + (let (result) + (while lst + (unless (funcall pred (car lst)) + (setq result (nconc result (list (car lst))))) + (setq lst (cdr lst))) + result)) + +(defun elmo-list-delete (list1 list2) + "Any element of list1 is deleted from list2." + (while list1 + (setq list2 (delete (car list1) list2)) + (setq list1 (cdr list1))) + list2) + +(defun elmo-list-member (list1 list2) + "If any element of list1 is member of list2, returns t." + (catch 'done + (while list1 + (if (member (car list1) list2) + (throw 'done t)) + (setq list1 (cdr list1))))) + +(defun elmo-count-matches (regexp beg end) + (let ((count 0)) + (save-excursion + (goto-char beg) + (while (re-search-forward regexp end t) + (setq count (1+ count))) + count))) + +(if (fboundp 'display-error) + (defalias 'elmo-display-error 'display-error) + (defun elmo-display-error (error-object stream) + "a tiny function to display error-object to the stream." + (let ((first t) + (errobj error-object) + err-mes) + (while errobj + (setq err-mes (concat err-mes (format + (if (stringp (car errobj)) + "%s" + (if (boundp 'nemacs-version) + "%s" + "%S")) (car errobj)))) + (setq errobj (cdr errobj)) + (if errobj (setq err-mes (concat err-mes (if first ": " ", ")))) + (setq first nil)) + (princ err-mes stream)))) + +(if (fboundp 'lprogress-display) + (defalias 'elmo-display-progress 'lprogress-display) + (defun elmo-display-progress (label format &optional value &rest args) + "Print a progress message." + (if (and (null format) (null args)) + (message nil) + (apply (function message) (concat format " %d%%") + (nconc args (list value)))))) + +(defun elmo-time-expire (before-time diff-time) + (let* ((current (current-time)) + (rest (when (< (nth 1 current) (nth 1 before-time)) + (expt 2 16))) + diff) + (setq diff + (list (- (+ (car current) (if rest -1 0)) (car before-time)) + (- (+ (or rest 0) (nth 1 current)) (nth 1 before-time)))) + (and (eq (car diff) 0) + (< diff-time (nth 1 diff))))) + +(defun elmo-open-network-stream (name buffer host service ssl) + (let ((auto-plugged (and elmo-auto-change-plugged + (> elmo-auto-change-plugged 0))) + process) + (if (eq ssl 'starttls) + (require 'starttls) + (if ssl (require 'ssl))) + (condition-case err + (let (process-connection-type) + (setq process + (if (eq ssl 'starttls) + (starttls-open-stream name buffer host service) + (if ssl + (open-ssl-stream name buffer host service) + (open-network-stream name buffer host service))))) + (error + (when auto-plugged + (elmo-set-plugged nil host service (current-time)) + (message "Auto plugged off at %s:%d" host service) + (sit-for 1)) + (signal (car err) (cdr err)))) + (when process + (process-kill-without-query process) + (when auto-plugged + (elmo-set-plugged t host service)) + process))) + +(if (fboundp 'std11-fetch-field) + (defalias 'elmo-field-body 'std11-fetch-field) ;;no narrow-to-region + (defalias 'elmo-field-body 'std11-field-body)) + +(defmacro elmo-string (string) + "String without text property" + (` (let ((obj (copy-sequence (, string)))) + (set-text-properties 0 (length obj) nil obj) + obj))) + +(defun elmo-y-or-n-p (prompt &optional auto default) + "Same as `y-or-n-p'. +But if optional argument AUTO is non-nil, DEFAULT is returned." + (if auto + default + (y-or-n-p prompt))) + +(defun elmo-string-member (string slist) + "Returns t if STRING is a member of the SLIST." + (catch 'found + (while slist + (if (and (stringp (car slist)) + (string= string (car slist))) + (throw 'found t)) + (setq slist (cdr slist))))) + +(defun elmo-string-match-member (str list &optional case-ignore) + (let ((case-fold-search case-ignore)) + (catch 'member + (while list + (if (string-match (car list) str) + (throw 'member (car list))) + (setq list (cdr list)))))) + +(defsubst elmo-string-delete-match (string pos) + (concat (substring string + 0 (match-beginning pos)) + (substring string + (match-end pos) + (length string)))) + +(defun elmo-string-match-assoc (key alist &optional case-ignore) + (let ((case-fold-search case-ignore) + a) + (catch 'loop + (while alist + (setq a (car alist)) + (if (and (consp a) + (stringp (car a)) + (string-match key (car a))) + (throw 'loop a)) + (setq alist (cdr alist)))))) + +(defun elmo-string-matched-assoc (key alist &optional case-ignore) + (let ((case-fold-search case-ignore) + a) + (catch 'loop + (while alist + (setq a (car alist)) + (if (and (consp a) + (stringp (car a)) + (string-match (car a) key)) + (throw 'loop a)) + (setq alist (cdr alist)))))) + +(defun elmo-string-assoc (key alist) + (let (a) + (catch 'loop + (while alist + (setq a (car alist)) + (if (and (consp a) + (stringp (car a)) + (string= key (car a))) + (throw 'loop a)) + (setq alist (cdr alist)))))) + +(defun elmo-string-rassoc (key alist) + (let (a) + (catch 'loop + (while alist + (setq a (car alist)) + (if (and (consp a) + (stringp (cdr a)) + (string= key (cdr a))) + (throw 'loop a)) + (setq alist (cdr alist)))))) + +(provide 'elmo-util) + +;;; elmo-util.el ends here diff --git a/elmo/elmo-vars.el b/elmo/elmo-vars.el new file mode 100644 index 0000000..43af0ce --- /dev/null +++ b/elmo/elmo-vars.el @@ -0,0 +1,330 @@ +;;; elmo-vars.el -- User variables for ELMO. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <2000-03-24 14:46:43 teranisi> + +;; This file is part of ELMO (Elisp Library for Message Orchestration). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; +(require 'poe) + +(eval-when-compile + (defun-maybe dynamic-link (a)) + (defun-maybe dynamic-call (a b))) + +;; Version info. +(defconst elmo-version "1.1.1") +(defconst elmo-appname "ELMO") + +(defun elmo-version () + (format "%s/%s" elmo-appname elmo-version)) + +;; IMAP4 +(defvar elmo-default-imap4-mailbox "inbox" + "*Default IMAP4 mailbox.") +(defvar elmo-default-imap4-server "localhost" + "*Default IMAP4 server.") +(defvar elmo-default-imap4-authenticate-type "auth" + "*Default Authentication type for IMAP4.") ; "auth" or "login" +(defvar elmo-default-imap4-user (or (getenv "USER") + (getenv "LOGNAME") + (user-login-name)) + "*Default username for IMAP4") +(defvar elmo-default-imap4-port 143 + "*Default Port number of IMAP.") +(defvar elmo-default-imap4-ssl nil + "*Non-nil forces using SSL by default.") + +;; POP3 +(defvar elmo-default-pop3-user (or (getenv "USER") + (getenv "LOGNAME") + (user-login-name)) + "*Default username for POP3") +(defvar elmo-default-pop3-server "localhost" + "*Default POP3 server.") +(defvar elmo-default-pop3-authenticate-type "user" + "*Default Authentication type for POP3") ; "apop" or "user" +(defvar elmo-default-pop3-port 110 + "*Default POP3 port.") +(defvar elmo-default-pop3-ssl nil + "*Non-nil forces using SSL by default.") + +;; NNTP +(defvar elmo-default-nntp-server "localhost" + "*Default NNTP server.") +(defvar elmo-default-nntp-user nil + "*Default User of NNTP. nil means no user authentication.") +(defvar elmo-default-nntp-port 119 + "*Default Port number of NNTP") +(defvar elmo-default-nntp-ssl nil + "*Non-nil forces using SSL by default.") + +(defvar elmo-localdir-folder-path "~/Mail" + "*Local mail folder path.") +(defvar elmo-localnews-folder-path "~/News" + "*Local news folder path.") +(defvar elmo-maildir-folder-path "~/Maildir" + "*Maildir folder path.") +(defvar elmo-maildir-list '("\\+~/Maildir") + "*All Folders that match this list will be treated as Maildir. +Each elements are regexp of folder name (This is obsolete).") +(defvar elmo-msgdb-dir "~/.elmo" + "*ELMO Message Database path.") +(defvar elmo-passwd-alist-file-name "passwd" + "*ELMO Password filename.") +(defvar elmo-warning-threshold 30000 + "*Display warning when the bytes of message exceeds this value.") +(defvar elmo-msg-appended-hook nil + "A hook called when message is appended to database.") +(defvar elmo-msg-deleted-hook nil + "A hook called when message is deleted from database") +(defvar elmo-nntp-post-pre-hook nil + "A hook called just before the nntp posting.") +(defvar elmo-lang "ja" + "Language for displayed messages.") + +(defvar elmo-mime-charset 'iso-2022-jp) +(defvar elmo-search-mime-charset 'iso-2022-jp) + +(defvar elmo-msgdb-mark-filename "mark" + "Mark database.") +(defvar elmo-msgdb-overview-filename "overview" + "Overview database.") +(defvar elmo-msgdb-number-filename "number" + "Message number <=> Message-ID database.") +(defvar elmo-msgdb-location-filename "location" + "Message number <=> Actual location symbol.") +(defvar elmo-msgdb-seen-filename "seen" + "Seen message list for append.") +(defvar elmo-msgdb-killed-filename "killed" + "Deleted messages... contains elmo-killed-msgs-list.") +(defvar elmo-msgdb-validity-filename "validity") +(defvar elmo-msgdb-flist-filename "flist" + "Folder list cache (for access folder).") +(defvar elmo-msgdb-finfo-filename "finfo" + "Folder information cache...list of '(filename . '(new unread all)).") +(defvar elmo-msgdb-append-list-filename "append" + "Appended messages...Structure is same as number-alist. +For disconnected operations.") +(defvar elmo-msgdb-resume-list-filename "resume" + "Resumed messages. For disconnected operations.") +(defvar elmo-msgdb-lock-list-filename "lock" + "Locked messages...list of message-id. +For disconnected operations.") +(defvar elmo-msgdb-global-mark-filename "global-mark" + "Alist of global mark .") +(defvar elmo-lost+found-folder "+lost+found" + "Lost and found.") +(defvar elmo-crosspost-alist-filename "crosspost-alist" + "Alist of crosspost messages.") + +(defvar elmo-use-server-diff t + "Non-nil forces to get unread message information on server.") + +(defvar elmo-imap4-disuse-server-flag-mailbox-regexp "^#mh" ; UW imapd + "If mailbox name matches this value, flags on server are not used except + \Delete flag.") + +(defvar elmo-msgdb-extra-fields nil + "Extra fields for msgdb.") + +(defvar elmo-queue-filename "queue" + "*IMAP pending event queue is saved in this file.") +(defvar elmo-enable-disconnected-operation nil + "*Enable disconnected operations.") + +(defvar elmo-imap4-overview-fetch-chop-length 200 + "*Number of overviews to fetch in one request in imap4.") +(defvar elmo-nntp-overview-fetch-chop-length 200 + "*Number of overviews to fetch in one request in nntp.") +(defvar elmo-localdir-header-chop-length 2048 + "*Number of bytes to get header in one reading from file.") +(defvar elmo-imap4-force-login nil + "*Non-nil forces to try 'login' if there is no 'auth' capability in imapd.") +(defvar elmo-imap4-use-select-to-update-status nil + "*Some imapd have to send select command to update status. +(ex. UW imapd 4.5-BETA?). For these imapd, you must set this variable t.") + +(defvar elmo-imap4-use-modified-utf7 nil + "*Use mofidied UTF-7 (rfc2060) encoding for IMAP4 folder name.") + +(defvar elmo-auto-change-plugged 600 + "*Time to expire change plugged state automatically, +as the number of seconds. Don't change plugged state automatically if nil.") + +(defvar elmo-plugged-condition 'one + "*The condition for `elmo-plugged' becomes on. +If `all', when all port is on. If `one', when even one port is on. +If `independent', independent port plugged. +If function, return value of function.") + +(defvar elmo-plug-on-servers nil) + +(defvar elmo-plug-on-exclude-servers + (list "localhost" + (system-name) + (and (string-match "[^.]+" (system-name)) + (substring (system-name) 0 (match-end 0))))) + +(defvar elmo-plugged-alist nil) + +(defvar elmo-dop-flush-confirm t + "*Flush disconnected operations queue with confirmation.") + +(defvar elmo-path-sep "/" + "*Path separator.") +(defvar elmo-plugged t) +(defvar elmo-use-semi nil) +(defvar elmo-no-subject "(No Subject in original.)" + "*A string used when no subject field exists.") +(defvar elmo-no-from "nobody@nowhere?" + "*A string used when no from field exists.") + +(defvar elmo-multi-divide-number 100000 + "*Multi divider number.") + +;;; User variables for elmo-archive. +(defvar elmo-archive-default-type 'zip + "*Default archiver type. The value must be a symbol.") + +;; database dynamic linking +(defvar elmo-database-dl-module + (expand-file-name "database.so" exec-directory)) + +(defvar elmo-database-dl-handle + (if (and (fboundp 'dynamic-link) + (file-exists-p + elmo-database-dl-module)) + (if (fboundp 'open-database) + t ;; + (dynamic-link elmo-database-dl-module)))) + +(if (and elmo-database-dl-handle + (integerp elmo-database-dl-handle)) + (dynamic-call "emacs_database_init" elmo-database-dl-handle)) + +(defvar elmo-use-database (or (featurep 'dbm) + (featurep 'gnudbm) + (featurep 'berkdb) + (featurep 'berkeley-db) + ;; static/dl-database + (fboundp 'open-database))) + +(defvar elmo-date-match (not (boundp 'nemacs-version)) + "Date match is available or not") + +(defconst elmo-spec-alist + '((?% . imap4) + (?- . nntp) + (?\+ . localdir) + (?\* . multi) + (?\/ . filter) + (?\$ . archive) + (?& . pop3) + (?= . localnews) + (?' . internal) + (?| . pipe) + (?. . maildir))) + +(defvar elmo-debug nil) +(defconst mmelmo-entity-buffer-name "*MMELMO-BUFFER*") + +(defvar elmo-folder-info-hashtb nil + "Array of folder database information '(max length new unread).") + +(defvar elmo-crosspost-message-alist nil + "List of crosspost message.") + +(defvar elmo-cache-expire-default-method "size" + "Default expiration method.") + +(defvar elmo-cache-expire-default-size 30000 + "Cache expiration disk size (Kilo bytes). This must be float value.") + +(defvar elmo-cache-expire-default-age 50 + "Cache expiration age (days).") +(defvar elmo-cache-dirname "cache" + "Directory name for cache storage.") + +(defvar elmo-use-buffer-cache t + "Use buffer cache.") + +(defvar elmo-buffer-cache-size 10 + "*Number of buffer for message cache.") + +(defvar elmo-pack-number-check-strict t + "Pack number strictly.") + +(defvar elmo-have-link-count + (not + ;; OS/2: EMX always returns the link count "1" :-( + (or (memq system-type '(OS/2 emx)) + ;; Meadow seems to have pseudo link count.(suggestion by S.YAMAGUCHI) + (and (eq system-type 'windows-nt) (not (featurep 'meadow))))) + "Your file system has link count, or not.") + +(defvar elmo-weekday-name-en '["Sun" "Mon" "Tue" "Wed" "Thu" "Fri" "Sat"]) +(defvar elmo-weekday-name-ja '["$BF|(B" "$B7n(B" "$B2P(B" "$B?e(B" "$BLZ(B" "$B6b(B" "$BEZ(B"]) +(defvar elmo-weekday-name-fr '["Dim" "Lun" "Mar" "Mer" "Jeu" "Ven" "Sam"]) +(defvar elmo-weekday-name-de '["Son" "Mon" "Die" "Mit" "Don" "Fre" "Sam"]) + +(defvar elmo-msgid-replace-string-alist + '((":" . " c") + ("*" . " a") + ("?" . " q") + ("<" . " l") + (">" . " g") + ("\"" . " d") + ("|" . " p") + ("/" . " s") + ("\\" . " b"))) + +(defvar elmo-archive-use-cache nil + "Use cache in archive folder.") + +(defvar elmo-nntp-use-cache t + "Use cache in nntp folder.") + +(defvar elmo-imap4-use-cache t + "Use cache in imap4 folder.") + +(defvar elmo-pop3-use-cache t + "Use cache in pop3 folder.") + +(defvar elmo-localdir-lockfile-list nil) + +(defvar elmo-nntp-max-number-precedes-list-active nil + "If non-nil, max number of the msgdb is set as the max number of +'list active' (needed for inn 2.3 or later?). ") + +(defvar elmo-pop3-send-command-synchronously nil + "If non-nil, commands are send synchronously. +If server doesn't accept asynchronous commands, this variable should be +set as non-nil.") + +(provide 'elmo-vars) + +;;; elmo-vars.el ends here diff --git a/elmo/elmo2.el b/elmo/elmo2.el new file mode 100644 index 0000000..79dc003 --- /dev/null +++ b/elmo/elmo2.el @@ -0,0 +1,1023 @@ +;;; elmo2.el -- ELMO main file (I don't remember why this is 2). + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <00/03/14 19:43:10 teranisi> + +;; This file is part of ELMO (Elisp Library for Message Orchestration). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; + +(require 'elmo-vars) +(require 'elmo-msgdb) +(require 'elmo-cache) +(require 'elmo-util) +(require 'elmo-dop) +(provide 'elmo2) + +(eval-when-compile + (require 'elmo-localdir) + (require 'elmo-imap4) + (require 'elmo-nntp) + (require 'elmo-pop3) + (require 'elmo-pipe) +; (require 'elmo-multi) + (require 'elmo-filter) + (require 'elmo-archive) + ;(require 'elmo-cache2) + ) + +(if (or (featurep 'dbm) + (featurep 'gnudbm) + (featurep 'berkdb) + (featurep 'berkeley-db)) + (require 'elmo-database)) + +(defun elmo-quit () + (interactive) + (if (featurep 'elmo-imap4) + (elmo-imap4-flush-connection)) + (if (featurep 'elmo-nntp) + (elmo-nntp-flush-connection)) + (if (featurep 'elmo-pop3) + (elmo-pop3-flush-connection)) + (if (get-buffer elmo-work-buf-name) + (kill-buffer elmo-work-buf-name)) + ) + +(defun elmo-cleanup-variables () + (setq elmo-folder-info-hashtb nil + elmo-nntp-groups-hashtb nil + elmo-nntp-list-folders-cache nil + )) + +;; (cons of max . estimated message number) elmo-max-of-folder (folder) +(defun elmo-max-of-folder (folder) + (if (elmo-folder-plugged-p folder) + (elmo-call-func folder "max-of-folder") + (elmo-dop-max-of-folder folder))) + +;; list elmo-list-folder (folder) +(defun elmo-list-folder (folder) + (if (elmo-folder-plugged-p folder) + (elmo-call-func folder "list-folder") + (elmo-dop-list-folder folder))) + +;; list elmo-list-folders (folder) + +(defun elmo-list-folders (folder &optional hierarchy) + (elmo-call-func folder "list-folders" hierarchy)) + +;; bool elmo-folder-exists-p (folder) +(defun elmo-folder-exists-p (folder) + (if (elmo-folder-plugged-p folder) + (elmo-call-func folder "folder-exists-p") + (elmo-dop-folder-exists-p folder))) + +;; bool elmo-folder-creatable-p (folder) +(defun elmo-folder-creatable-p (folder) + (elmo-call-func folder "folder-creatable-p")) + +;; bool elmo-create-folder (folder) +;; create folder +(defun elmo-create-folder (folder) + (if (elmo-folder-plugged-p folder) + (elmo-call-func folder "create-folder") + (elmo-dop-create-folder folder))) + +(defun elmo-delete-folder (folder) + (let ((type (elmo-folder-get-type folder))) + (if (or (not (memq type '(localdir localnews archive imap4 maildir))) + (if (elmo-folder-plugged-p folder) + (elmo-call-func folder "delete-folder") + (elmo-dop-delete-folder folder))) + ;; If folder doesn't support delete folder, delete msgdb path only. + (elmo-msgdb-delete-path folder)))) + +(defun elmo-rename-folder (old-folder new-folder) + (let ((old-type (elmo-folder-get-type old-folder)) + (new-type (elmo-folder-get-type new-folder))) + (if (not (eq old-type new-type)) + (error "not same folder type") + (unless (and (memq old-type '(localdir localnews archive imap4)) + (elmo-folder-identical-system-p old-folder new-folder)) + (error "rename folder not supported")) + (if (elmo-folder-plugged-p old-folder) + (and + (if (or (file-exists-p (elmo-msgdb-expand-path new-folder)) + (elmo-folder-exists-p new-folder)) + (error "already exists folder: %s" new-folder) + t) + (elmo-call-func old-folder "rename-folder" + (elmo-folder-get-spec new-folder)) + (elmo-msgdb-rename-path old-folder new-folder)) + (elmo-dop-rename-folder old-folder new-folder))))) + +(defun elmo-read-msg-no-cache (folder msg outbuf &optional msgdb) + "Read messsage into outbuf without cacheing. +If msgdb is specified, use cache." + (let (ret-val) + (when msgdb + (set-buffer outbuf) + (erase-buffer) + (setq ret-val + (elmo-cache-read + ;; message-id + (cdr (assq msg (elmo-msgdb-get-number-alist msgdb))) + folder msg))) + (if (not ret-val) + (elmo-call-func folder "read-msg" msg outbuf)))) + +(defun elmo-force-cache-msg (folder number msgid &optional loc-alist) + "Force cache message." + (let* ((cache-file (elmo-cache-get-path msgid)) + dir) + (when cache-file + (setq dir (directory-file-name (file-name-directory cache-file))) + (if (not (file-exists-p dir)) + (elmo-make-directory dir)) + (if (elmo-local-file-p folder number) + (elmo-copy-file (elmo-get-msg-filename folder number loc-alist) + cache-file) + (with-temp-buffer + (elmo-call-func folder "read-msg" number (current-buffer)) + (as-binary-output-file + (write-region (point-min) (point-max) cache-file nil 'no-msg))))))) + +(defun elmo-prefetch-msg (folder msg outbuf msgdb) + "Read message into outbuf with cacheing." + (save-excursion + (let* ((number-alist (elmo-msgdb-get-number-alist + (or msgdb (elmo-msgdb-load folder)))) + (dir (elmo-msgdb-expand-path folder)) + (message-id (cdr (assq msg number-alist))) + type + cache-status + ret-val part-num real-fld-num) + (set-buffer outbuf) + (if (elmo-cache-exists-p message-id) + t + ;; cache doesn't exist. + (setq real-fld-num (elmo-get-real-folder-number + folder msg)) + (setq type (elmo-folder-get-type (car real-fld-num))) + (cond ((eq type 'imap4) + (setq ret-val (elmo-imap4-prefetch-msg + (elmo-folder-get-spec (car real-fld-num)) + (cdr real-fld-num) + outbuf))) + ((elmo-folder-local-p (car real-fld-num))) + (t (setq ret-val (elmo-call-func (car real-fld-num) + "read-msg" + (cdr real-fld-num) outbuf)))) + (if ret-val + (elmo-cache-save message-id + (elmo-string-partial-p ret-val) + folder msg)) + (and ret-val t))))) + +(defun elmo-prefetch-msgs (folder msgs) + "prefetch messages for queueing." + (let* ((msgdb (elmo-msgdb-load folder)) + (number-alist (elmo-msgdb-get-number-alist msgdb)) + (len (length msgs)) + (count 0) + msgid msg) + (while msgs + (setq msg (car msgs)) + (setq msgid (cdr (assq msg number-alist))) + (message "%s:Prefetching... %d/%d message(s)" + folder + (setq count (+ 1 count)) len) + (elmo-force-cache-msg folder msg msgid) + (setq msgs (cdr msgs))))) + +;; elmo-read-msg (folder msg outbuf msgdb) +;;; read message +(defun elmo-read-msg (folder msg outbuf msgdb &optional force-reload) + "Read message into outbuf." + (let ((inhibit-read-only t)) + (if (not (elmo-use-cache-p folder msg)) + (elmo-read-msg-no-cache folder msg outbuf msgdb) + (elmo-read-msg-with-cache folder msg outbuf msgdb force-reload)))) + +(defun elmo-read-msg-with-cache (folder msg outbuf msgdb + &optional force-reload) + "Read message into outbuf with cacheing." + (let* ((number-alist (elmo-msgdb-get-number-alist + (or msgdb (elmo-msgdb-load folder)))) + (dir (elmo-msgdb-expand-path folder)) + (message-id (cdr (assq msg number-alist))) + (type (elmo-folder-number-get-type folder msg)) + cache-status + ret-val part-num real-fld-num) + (set-buffer outbuf) + (if (and (not force-reload) + (not (elmo-local-file-p folder msg))) + (setq ret-val (elmo-cache-read message-id folder msg))) + (if ret-val + t + ;; cache doesn't exist. + (setq real-fld-num (elmo-get-real-folder-number + folder msg)) + (if (setq ret-val (elmo-call-func (car real-fld-num) + "read-msg" + (cdr real-fld-num) outbuf)) + (if (not (elmo-local-file-p folder msg)) + (elmo-cache-save message-id + (elmo-string-partial-p ret-val) + folder msg))) + (and ret-val t)))) + +(defun elmo-copy-msgs (src-folder msgs dst-folder &optional msgdb same-number) + (let* ((src-spec (elmo-folder-get-spec src-folder)) + (loc-alist (if msgdb + (elmo-msgdb-get-location msgdb) + (elmo-msgdb-location-load + (elmo-msgdb-expand-path nil src-spec))))) + (if (eq (car src-spec) 'archive) + (elmo-archive-copy-msgs-froms + (elmo-folder-get-spec dst-folder) + msgs src-spec loc-alist same-number) + (elmo-call-func dst-folder "copy-msgs" + msgs src-spec loc-alist same-number)))) + +(defun elmo-move-msgs (src-folder msgs dst-folder + &optional msgdb all done + no-delete-info + no-delete + same-number + unread-marks) + (save-excursion + (let* ((db (or msgdb (elmo-msgdb-load src-folder))) + (number-alist (elmo-msgdb-get-number-alist db)) + (mark-alist (elmo-msgdb-get-mark-alist db)) + (messages msgs) + (len (length msgs)) + (all-msg-num (or all len)) + (done-msg-num (or done 0)) + (tmp-buf (get-buffer-create " *elmo-move-msg*")) + ;elmo-no-cache-flag + ret-val real-fld-num done-copy dir + mes-string message-id src-cache i percent unseen seen-list) + (setq i done-msg-num) + (set-buffer tmp-buf) + (when (and (not (eq dst-folder 'null)) + (elmo-folder-direct-copy-p src-folder dst-folder)) + (message (concat (if no-delete "Copying" "Moving") + " %d message(s)...") (length messages)) + (unless (elmo-copy-msgs src-folder + messages + dst-folder + db + same-number) + (error "Copy message to %s failed" dst-folder)) + (setq done-copy t)) + (while messages + (setq real-fld-num (elmo-get-real-folder-number src-folder + (car messages))) + (setq message-id (cdr (assq (car messages) number-alist))) + ;; seen-list. + (if (and (not (eq dst-folder 'null)) + (not (and unread-marks + (member + (cadr (assq (car messages) mark-alist)) + unread-marks)))) + (setq seen-list (cons message-id seen-list))) + (unless (or (eq dst-folder 'null) done-copy) + (if (and (elmo-folder-plugged-p src-folder) + (elmo-folder-plugged-p dst-folder) + (elmo-folder-identical-system-p (car real-fld-num) + dst-folder)) + ;; online and identical system...so copy 'em! + (unless + (elmo-copy-msgs (car real-fld-num) + (list (cdr real-fld-num)) + dst-folder + db + same-number) + (error "Copy message to %s failed" dst-folder)) + ;; use cache if exists. + (elmo-read-msg src-folder (car messages) tmp-buf msgdb) + (unless (elmo-append-msg dst-folder (buffer-string) message-id + (if same-number (car messages)) + ;; null means all unread. + (or (null unread-marks) + unseen)) + (error "move: append message to %s failed" dst-folder)))) + ;; delete src cache if it is partial. + (elmo-cache-delete-partial message-id src-folder (car messages)) + (setq ret-val (append ret-val (list (car messages)))) + (setq i (+ i 1)) + (setq percent (/ (* i 100) all-msg-num)) + (if no-delete + (elmo-display-progress + 'elmo-move-msgs "Copying messages..." + percent) + (elmo-display-progress + 'elmo-move-msgs "Moving messages..." + percent)) + (setq messages (cdr messages))) + ;; Save seen-list. + (unless (eq dst-folder 'null) + (setq dir (elmo-msgdb-expand-path dst-folder)) + (elmo-msgdb-seen-save dir + (append (elmo-msgdb-seen-load dir) seen-list))) + (kill-buffer tmp-buf) + (if (and (not no-delete) ret-val) + (progn + (if (not no-delete-info) + (message "Cleaning up src folder...")) + (if (and (elmo-delete-msgs src-folder ret-val db) + (elmo-msgdb-delete-msgs src-folder ret-val db t)) + (setq ret-val t) + (message "move: delete messages from %s failed." src-folder) + (setq ret-val nil) + ) + (if (and ret-val + (not no-delete-info)) + (message "Cleaning up src folder...done.") + ) + ret-val) + (if no-delete + (progn + (message "Copying messages...done.") + t) + (if (eq len 0) + (message "No message was moved.") + (message "Moving messages failed.") + nil ; failure + )))))) + +;; boolean elmo-delete-msgs (folder msgs) +(defun elmo-delete-msgs (folder msgs &optional msgdb) + ;; remove from real folder. + (if (elmo-folder-plugged-p folder) + (elmo-call-func folder "delete-msgs" msgs) + (elmo-dop-delete-msgs folder msgs msgdb))) + +;; +;; Server side search. +;; +(defun elmo-search (folder condition &optional from-msgs) + (let ((type (elmo-folder-get-type folder))) + (if (elmo-folder-plugged-p folder) + (elmo-call-func folder "search" condition from-msgs) + (elmo-cache-search-all folder condition from-msgs)))) + +(defun elmo-msgdb-create (folder numlist new-mark already-mark + seen-mark important-mark seen-list) + (if (elmo-folder-plugged-p folder) + (elmo-call-func folder "msgdb-create" numlist new-mark already-mark + seen-mark important-mark seen-list) + (elmo-dop-msgdb-create folder numlist new-mark already-mark + seen-mark important-mark seen-list))) + +(defun elmo-make-folder-numbers-list (folder msgs) + (let ((msg-list msgs) + pair fld-list + ret-val) + (while msg-list + (when (> (car msg-list) 0) + (setq pair (elmo-get-real-folder-number folder (car msg-list))) + (if (setq fld-list (assoc (car pair) ret-val)) + (setcdr fld-list (cons (cdr pair) (cdr fld-list))) + (setq ret-val (cons (cons (car pair) (list (cdr pair))) ret-val)))) + (setq msg-list (cdr msg-list))) + ret-val)) + +(defun elmo-call-func-on-markable-msgs (folder func-name msgs msgdb) + (save-match-data + (let ((folder-numbers (elmo-make-folder-numbers-list folder msgs)) + type) + (while folder-numbers + (if (or (eq + (setq type (car + (elmo-folder-get-spec + (car (car folder-numbers))))) + 'imap4) + (memq type '(maildir internal))) + (if (elmo-folder-plugged-p folder) + (elmo-call-func (car (car folder-numbers)) func-name + (cdr (car folder-numbers))) + (if elmo-enable-disconnected-operation + (elmo-dop-call-func-on-msgs + (car (car folder-numbers)) ; real folder + func-name + (cdr (car folder-numbers)) ; real number + msgdb) + (error "Unplugged")))) + (setq folder-numbers (cdr folder-numbers)))))) + +(defun elmo-unmark-important (folder msgs msgdb) + (elmo-call-func-on-markable-msgs folder "unmark-important" msgs msgdb)) + +(defun elmo-mark-as-important (folder msgs msgdb) + (elmo-call-func-on-markable-msgs folder "mark-as-important" msgs msgdb)) + +(defun elmo-mark-as-read (folder msgs msgdb) + (elmo-call-func-on-markable-msgs folder "mark-as-read" msgs msgdb)) + +(defun elmo-mark-as-unread (folder msgs msgdb) + (elmo-call-func-on-markable-msgs folder "mark-as-unread" msgs msgdb)) + +(defun elmo-msgdb-create-as-numlist (folder numlist new-mark already-mark + seen-mark important-mark seen-list) + (if (elmo-folder-plugged-p folder) + (elmo-call-func folder "msgdb-create-as-numlist" numlist + new-mark already-mark seen-mark important-mark seen-list) + (elmo-dop-msgdb-create-as-numlist + folder numlist new-mark already-mark + seen-mark important-mark seen-list))) + +;; msgdb elmo-msgdb-load (folder) +(defun elmo-msgdb-load (folder &optional spec) + (message "Loading msgdb for %s..." folder) + (let* ((path (elmo-msgdb-expand-path folder spec)) + (ret-val + (list (elmo-msgdb-overview-load path) + (elmo-msgdb-number-load path) + (elmo-msgdb-mark-load path) + (elmo-msgdb-location-load path)))) + (message "Loading msgdb for %s...done." folder) + (elmo-folder-set-info-max-by-numdb folder (nth 1 ret-val)) + ret-val)) + +;; boolean elmo-msgdb-save (folder msgdb) +(defun elmo-msgdb-save (folder msgdb) + (message "Saving msgdb for %s..." folder) + (save-excursion + (let ((path (elmo-msgdb-expand-path folder))) + (elmo-msgdb-overview-save path (car msgdb)) + (elmo-msgdb-number-save path (cadr msgdb)) + (elmo-msgdb-mark-save path (caddr msgdb)) + (elmo-msgdb-location-save path (cadddr msgdb)) + ;(elmo-sync-validity folder);; for validity check!! + )) + (message "Saving msgdb for %s...done." folder) + (elmo-folder-set-info-max-by-numdb folder (cadr msgdb))) + +(defun elmo-msgdb-add-msgs-to-seen-list-subr (msgs msgdb seen-marks seen-list) + "Add to seen list." + (let* ((seen-mark-list (string-to-char-list seen-marks)) + (number-alist (elmo-msgdb-get-number-alist msgdb)) + (mark-alist (elmo-msgdb-get-mark-alist msgdb)) + ent) + (while msgs + (if (setq ent (assq (car msgs) mark-alist)) + (if (memq (string-to-char (cadr ent)) seen-mark-list) + (setq seen-list + (cons (cdr (assq (car msgs) number-alist)) seen-list))) + ;; no mark ... seen... + (setq seen-list + (cons (cdr (assq (car msgs) number-alist)) seen-list))) + (setq msgs (cdr msgs))) + seen-list)) + +(defun elmo-msgdb-add-msgs-to-seen-list (folder msgs msgdb seen-marks) + "Add to seen list." + (unless (eq folder 'null) ;; black hole + (let* ((dir (elmo-msgdb-expand-path folder)) + (seen-list (elmo-msgdb-seen-load dir))) + (setq seen-list + (elmo-msgdb-add-msgs-to-seen-list-subr + msgs msgdb seen-marks seen-list)) + (elmo-msgdb-seen-save dir seen-list)))) + +;; msgdb elmo-append-msg (folder string) +(defun elmo-append-msg (folder string &optional message-id msg no-see) + (let ((type (elmo-folder-get-type folder)) + filename) + (cond ((eq type 'imap4) + (if (elmo-folder-plugged-p folder) + (elmo-call-func folder "append-msg" string msg no-see) + (elmo-dop-append-msg folder string message-id))) + ((eq type 'cache) + (if message-id + (elmo-cache-append-msg + (elmo-folder-get-spec folder) + string message-id msg no-see) + (error "elmo-cache-append-msg require message-id"))) + (t + (elmo-call-func folder "append-msg" string msg no-see))))) + +(defun elmo-check-validity (folder) + (elmo-call-func folder "check-validity" + (expand-file-name + elmo-msgdb-validity-filename + (elmo-msgdb-expand-path folder)))) + +(defun elmo-pack-number (folder msgdb arg) + (if (string-match "^[\\+=].*" folder) + (elmo-call-func folder "pack-number" msgdb arg) + (error "pack-number not supported"))) + +(defun elmo-sync-validity (folder) + (elmo-call-func folder "sync-validity" + (expand-file-name + elmo-msgdb-validity-filename + (elmo-msgdb-expand-path folder)))) + +(defun elmo-use-cache-p (folder number) + (elmo-call-func folder "use-cache-p" number) + ) + +(defun elmo-local-file-p (folder number) + (elmo-call-func folder "local-file-p" number)) + +(defun elmo-folder-portinfo (folder) + (condition-case nil + (elmo-call-func folder "portinfo") + (error))) + +(defun elmo-folder-plugged-p (folder) + (and folder + (or (elmo-folder-local-p folder) + (elmo-call-func folder "plugged-p")))) + +(defun elmo-folder-set-plugged (folder plugged &optional add) + (if (elmo-folder-local-p folder) + nil ;; nop + (elmo-call-func folder "set-plugged" plugged add))) + +(defun elmo-generic-sync-number-alist (spec number-alist) + "Just return number-alist." + number-alist) + +(defun elmo-generic-list-folder-unread (spec mark-alist unread-marks) + (elmo-delete-if + 'null + (mapcar + (function (lambda (x) + (if (member (cadr (assq (car x) mark-alist)) unread-marks) + (car x)))) + mark-alist))) + +(defun elmo-generic-list-folder-important (spec overview) + nil) + +(defun elmo-update-number (folder msgdb) + (when (elmo-folder-plugged-p folder) + (message "Synchronize number...") + (let* ((numlist (elmo-msgdb-get-number-alist msgdb)) + (len (length numlist)) + new-numlist) + (if (eq (length (setq + new-numlist + (elmo-call-func folder "sync-number-alist" numlist))) + len) + nil + (elmo-msgdb-set-number-alist msgdb new-numlist) + (message "Synchronize number...done.") + new-numlist)))) + +(defun elmo-get-msg-filename (folder number &optional loc-alist) + "Available if elmo-local-file-p is t." + (elmo-call-func folder "get-msg-filename" number loc-alist)) + +(defun elmo-strict-folder-diff (fld &optional number-alist) + (interactive) + (let* ((dir (elmo-msgdb-expand-path fld)) + (nalist (or number-alist + (elmo-msgdb-number-load dir))) + (in-db (sort (mapcar 'car nalist) '<)) + (in-folder (elmo-list-folder fld)) + append-list delete-list diff) + (cons (if (equal in-folder in-db) + 0 + (setq diff (elmo-list-diff + in-folder in-db + nil + )) + (setq append-list (car diff)) + (setq delete-list (cadr diff)) + (if append-list + (length append-list) + (if delete-list + (- 0 (length delete-list)) + 0))) + (length in-folder)))) + +(defun elmo-list-folder-unread (folder mark-alist unread-marks) + (elmo-call-func folder "list-folder-unread" mark-alist unread-marks)) + +(defun elmo-list-folder-important (folder overview) + (let (importants) + ;; server side importants...(append only.) + (if (elmo-folder-plugged-p folder) + (setq importants (elmo-call-func folder "list-folder-important" + overview))) + (or elmo-msgdb-global-mark-alist + (setq elmo-msgdb-global-mark-alist + (elmo-object-load (expand-file-name + elmo-msgdb-global-mark-filename + elmo-msgdb-dir)))) + (while overview + (car overview) + (if (assoc (elmo-msgdb-overview-entity-get-id (car overview)) + elmo-msgdb-global-mark-alist) + (setq importants (cons + (elmo-msgdb-overview-entity-get-number + (car overview)) + importants))) + (setq overview (cdr overview))) + importants)) + +(defun elmo-generic-commit (folder) + nil) + +(defun elmo-commit (folder) + (elmo-call-func folder "commit")) + +;; returns cons cell of (unsync . number-of-messages-in-folder) +(defun elmo-folder-diff (fld &optional number-alist) + (interactive) + (let ((type (elmo-folder-get-type fld))) + (cond ((eq type 'multi) + (elmo-multi-folder-diff fld)) + ((and (eq type 'filter) + (or (elmo-multi-p fld) + (not + (vectorp (nth 1 (elmo-folder-get-spec fld))))) + ;; not partial...unsync number is unknown. + (cons nil + (cdr (elmo-folder-diff + (nth 2 (elmo-folder-get-spec fld))))))) + ((and (eq type 'imap4) + elmo-use-server-diff) + (elmo-call-func fld "server-diff")) ;; imap4 server side diff. + (t + (let ((cached-in-db-max (elmo-folder-get-info-max fld)) + (in-folder (elmo-max-of-folder fld)) + (in-db t) + unsync nomif + in-db-max) + (if (or number-alist + (not cached-in-db-max)) + (let* ((dir (elmo-msgdb-expand-path fld)) + (nalist (or number-alist + (elmo-msgdb-number-load dir)))) + ;; No info-cache. + (setq in-db (sort (mapcar 'car nalist) '<)) + (setq in-db-max (or (nth (max 0 (1- (length in-db))) in-db) + 0)) + (if (not number-alist) + ;; Number-alist is not used. + (elmo-folder-set-info-hashtb fld in-db-max + nil)) +;; (or +;; (and in-db (length in-db)) +;; 0))) + ) + ;; info-cache exists. + (setq in-db-max cached-in-db-max)) + (setq unsync (if (and in-db + (car in-folder)) + (- (car in-folder) in-db-max) + (if (and in-folder + (null in-db)) + (cdr in-folder) + (if (null (car in-folder)) + nil)))) + (setq nomif (cdr in-folder)) + (if (and unsync nomif (> unsync nomif)) + (setq unsync nomif)) + (cons (or unsync 0) (or nomif 0))))))) + +(defsubst elmo-folder-get-info (folder &optional hashtb) + (elmo-get-hash-val folder + (or hashtb elmo-folder-info-hashtb))) + +(defun elmo-folder-set-info-hashtb (folder max numbers &optional new unread) + (let ((info (elmo-folder-get-info folder))) + (when info + (or new (setq new (nth 0 info))) + (or unread (setq unread (nth 1 info))) + (or numbers (setq numbers (nth 2 info))) + (or max (setq max (nth 3 info)))) + (elmo-set-hash-val folder + (list new unread numbers max) + elmo-folder-info-hashtb))) + +(defun elmo-multi-get-number-alist-list (number-alist) + (let ((alist (sort number-alist (function (lambda (x y) (< (car x) + (car y)))))) + (cur-number 0) + one-alist ret-val num) + (while alist + (setq cur-number (+ cur-number 1)) + (setq one-alist nil) + (while (and alist + (eq 0 + (/ (- (setq num (car (car alist))) + (* elmo-multi-divide-number cur-number)) + elmo-multi-divide-number))) + (setq one-alist (nconc + one-alist + (list + (cons + (% num (* elmo-multi-divide-number cur-number)) + (cdr (car alist)))))) + (setq alist (cdr alist))) + (setq ret-val (nconc ret-val (list one-alist)))) + ret-val)) + +(defun elmo-multi-folder-diff (fld) + (let ((flds (cdr (elmo-folder-get-spec fld))) + (num-alist-list + (elmo-multi-get-number-alist-list + (elmo-msgdb-number-load (elmo-msgdb-expand-path fld)))) + (count 0) + diffs (unsync 0) (nomif 0)) + (while flds + (setq diffs (nconc diffs (list (elmo-folder-diff (car flds) + (nth count + num-alist-list) + )))) + (setq count (+ 1 count)) + (setq flds (cdr flds))) + (while diffs + (setq unsync (+ unsync (car (car diffs)))) + (setq nomif (+ nomif (cdr (car diffs)))) + (setq diffs (cdr diffs))) + (elmo-folder-set-info-hashtb fld nil nomif) + (cons unsync nomif))) + +(defun elmo-folder-set-info-max-by-numdb (folder msgdb-number) + (let ((num-db (sort (mapcar 'car msgdb-number) '<))) + (elmo-folder-set-info-hashtb + folder + (or (nth (max 0 (1- (length num-db))) num-db) 0) + nil ;;(length num-db) + ))) + +(defun elmo-folder-get-info-max (folder) + "Get folder info from cache." + (nth 3 (elmo-folder-get-info folder))) + +(defun elmo-folder-get-info-length (folder) + (nth 2 (elmo-folder-get-info folder))) + +(defun elmo-folder-get-info-unread (folder) + (nth 1 (elmo-folder-get-info folder))) + +(defun elmo-folder-info-make-hashtb (info-alist hashtb) + (let* ((hashtb (or hashtb + (elmo-make-hash (length info-alist))))) + (mapcar + '(lambda (x) + (let ((info (cadr x))) + (and (intern-soft (car x) hashtb) + (elmo-set-hash-val (car x) + (list (nth 2 info) ;; new + (nth 3 info) ;; unread + (nth 1 info) ;; length + (nth 0 info)) ;; max + hashtb)))) + info-alist) + (setq elmo-folder-info-hashtb hashtb))) + +(defun elmo-crosspost-message-set (message-id folders &optional type) + (if (assoc message-id elmo-crosspost-message-alist) + (setcdr (assoc message-id elmo-crosspost-message-alist) + (list folders type)) + (setq elmo-crosspost-message-alist + (nconc elmo-crosspost-message-alist + (list (list message-id folders type)))))) + +(defun elmo-crosspost-message-delete (message-id folders) + (let* ((id-fld (assoc message-id elmo-crosspost-message-alist)) + (folder-list (nth 1 id-fld))) + (when id-fld + (if (setq folder-list (elmo-delete-lists folders folder-list)) + (setcar (cdr id-fld) folder-list) + (setq elmo-crosspost-message-alist + (delete id-fld elmo-crosspost-message-alist)))))) + + +(defun elmo-get-msgs-with-mark (mark-alist mark) + (let (ret-val) + (while mark-alist + (if (string= (cadr (car mark-alist)) mark) + (cons (car (car mark-alist)) ret-val)) + (setq mark-alist (cdr mark-alist))) + (nreverse ret-val))) + +(defun elmo-buffer-cache-message (fld msg &optional msgdb force-reload) + (let* ((msg-id (cdr (assq msg (elmo-msgdb-get-number-alist msgdb)))) + (hit (elmo-buffer-cache-hit (list fld msg msg-id))) + (read nil)) + (if hit + (elmo-buffer-cache-sort + (elmo-buffer-cache-entry-make (list fld msg msg-id) hit)) + (setq hit (elmo-buffer-cache-add (list fld msg msg-id))) + (setq read t)) + (if (or force-reload read) + (condition-case err + (save-excursion + (set-buffer hit) + (elmo-read-msg fld msg + (current-buffer) + msgdb force-reload)) + (quit + (elmo-buffer-cache-delete) + (error "read message %s/%s is quitted" fld msg)) + (error + (elmo-buffer-cache-delete) + (signal (car err) (cdr err)) + nil))) ;; will not be used + hit)) ;; retrun value + +(defun elmo-read-msg-with-buffer-cache (fld msg outbuf msgdb &optional force-reload) + (if elmo-use-buffer-cache + (let (hit start end) + (when (setq hit (elmo-buffer-cache-message + (elmo-string fld) msg + msgdb force-reload)) + (erase-buffer) + (save-excursion + (set-buffer hit) + (setq start (point-min) end (point-max))) + (insert-buffer-substring hit start end))) + (elmo-read-msg fld msg outbuf msgdb force-reload))) + +(defun elmo-folder-pipe-p (folder) + (let ((type (elmo-folder-get-type folder))) + (cond + ((eq type 'multi) + (let ((flds (cdr (elmo-folder-get-spec folder)))) + (catch 'done + (while flds + (if (elmo-folder-pipe-p (car flds)) + (throw 'done t))) + nil))) + ((eq type 'pipe) + t) + ((eq type 'filter) + (elmo-folder-pipe-p + (nth 2 (elmo-folder-get-spec folder)))) + (t + nil + )))) + +(defun elmo-multi-p (folder) + (let ((type (elmo-folder-get-type folder))) + (cond + ((eq type 'multi) + t) + ((eq type 'pipe) + (elmo-multi-p + (elmo-pipe-spec-dst (elmo-folder-get-spec folder)))) + ((eq type 'filter) + (elmo-multi-p + (nth 2 (elmo-folder-get-spec folder)))) + (t + nil + )))) + +(defun elmo-get-real-folder-number (folder number) + (let ((type (elmo-folder-get-type folder))) + (cond + ((eq type 'multi) + (elmo-multi-get-real-folder-number folder number)) + ((eq type 'pipe) + (elmo-get-real-folder-number + (elmo-pipe-spec-dst (elmo-folder-get-spec folder) ) + number)) + ((eq type 'filter) + (elmo-get-real-folder-number + (nth 2 (elmo-folder-get-spec folder)) number)) + (t + (cons folder number) + )))) + +(defun elmo-folder-get-primitive-spec-list (folder &optional spec-list) + (let ((type (elmo-folder-get-type folder)) + specs) + (cond + ((or (eq type 'multi) + (eq type 'pipe)) + (let ((flds (cdr (elmo-folder-get-spec folder))) + spec) + (while flds + (setq spec (elmo-folder-get-primitive-spec-list (car flds))) + (if (not (memq (car spec) specs)) + (setq specs (append specs spec))) + (setq flds (cdr flds))))) + ((eq type 'filter) + (setq specs + (elmo-folder-get-primitive-spec-list + (nth 2 (elmo-folder-get-spec folder))))) + (t + (setq specs (list (elmo-folder-get-spec folder))) + )) + specs)) + +(defun elmo-folder-get-primitive-folder-list (folder) + (let* ((type (elmo-folder-get-type folder))) + (cond + ((or (eq type 'multi) + (eq type 'pipe)) + (let ((flds (cdr (elmo-folder-get-spec folder))) + ret-val) + (while flds + (setq ret-val (append ret-val + (elmo-folder-get-primitive-folder-list + (car flds)))) + (setq flds (cdr flds))) + ret-val)) + ((eq type 'filter) + (elmo-folder-get-primitive-folder-list + (nth 2 (elmo-folder-get-spec folder)))) + (t + (list folder) + )))) + +(defun elmo-folder-contains-multi (folder) + (let ((cur-spec (elmo-folder-get-spec folder))) + (catch 'done + (while cur-spec + (cond + ((eq (car cur-spec) 'filter) + (setq cur-spec (elmo-folder-get-spec (nth 2 cur-spec)))) + ((eq (car cur-spec) 'pipe) + (setq cur-spec (elmo-folder-get-spec (elmo-pipe-spec-src cur-spec)))) + ((eq (car cur-spec) 'multi) + (throw 'done nil)) + (t (setq cur-spec nil))))) + cur-spec)) + +(defun elmo-folder-contains-type (folder type) + (let ((spec (elmo-folder-get-spec folder))) + (cond + ((eq (car spec) 'filter) + (elmo-folder-contains-type (nth 2 spec) type)) + ((eq (car spec) 'pipe) + (elmo-folder-contains-type (elmo-pipe-spec-dst spec) type)) + ((eq (car spec) 'multi) + (let ((folders (cdr spec))) + (catch 'done + (while folders + (if (elmo-folder-contains-type (car folders) type) + (throw 'done t)) + (setq folders (cdr folders)))))) + ((eq (car spec) type) + t) + (t nil)))) + +(defun elmo-folder-number-get-spec (folder number) + (let ((type (elmo-folder-get-type folder))) + (cond + ((eq type 'multi) + (elmo-multi-folder-number-get-spec folder number)) + ((eq type 'pipe) + (elmo-folder-number-get-spec + (elmo-pipe-spec-dst (elmo-folder-get-spec folder)) number)) + ((eq type 'filter) + (elmo-folder-number-get-spec + (nth 2 (elmo-folder-get-spec folder)) number)) + (t + (elmo-folder-get-spec folder) + )))) + +(defun elmo-folder-number-get-type (folder number) + (car (elmo-folder-number-get-spec folder number))) + +(defun elmo-multi-folder-number-get-spec (folder number) + (let* ((spec (elmo-folder-get-spec folder)) + (flds (cdr spec)) + (fld (nth (- (/ number elmo-multi-divide-number) 1) flds))) + (elmo-folder-number-get-spec fld number))) + +;; autoloads +(autoload 'elmo-imap4-get-connection "elmo-imap4") +(autoload 'elmo-nntp-make-groups-hashtb "elmo-nntp") +(autoload 'elmo-nntp-post "elmo-nntp") +(autoload 'elmo-localdir-max-of-folder "elmo-localdir") +(autoload 'elmo-localdir-msgdb-create-overview-entity-from-file "elmo-localdir") +(autoload 'elmo-multi-folder-diff "elmo-multi") +(autoload 'elmo-archive-copy-msgs-froms "elmo-archive") + +;;; elmo2.el ends here diff --git a/elmo/mmelmo-1.el b/elmo/mmelmo-1.el new file mode 100644 index 0000000..9109817 --- /dev/null +++ b/elmo/mmelmo-1.el @@ -0,0 +1,110 @@ +;;; mmelmo-1.el -- mm-backend (for FLIM 1.12.x) by ELMO. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <00/03/06 18:35:49 teranisi> + +;; This file is part of ELMO (Elisp Library for Message Orchestration). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; + +(require 'mime) +(require 'mime-parse) +(eval-when-compile + (require 'std11)) + +(require 'mmelmo) + +(defvar mmelmo-force-reload nil) +(defvar mmelmo-sort-field-list nil) + +;;; mmelmo: Only the initialization method is different from mmbuffer. +(mm-define-backend elmo (buffer)) + +(mm-define-method initialize-instance ((entity elmo)) + (mime-entity-set-buffer-internal + entity + (get-buffer-create (concat mmelmo-entity-buffer-name "0"))) + (save-excursion + (set-buffer (mime-entity-buffer-internal entity)) + (mmelmo-original-mode) + (let ((buffer-read-only nil) + (location (mime-entity-location-internal entity)) + header-start header-end body-start body-end) + (erase-buffer) + (setq mime-message-structure entity) + (elmo-read-msg-with-buffer-cache (nth 0 location) + (nth 1 location) + (current-buffer) + (nth 2 location) + mmelmo-force-reload) + (setq header-start (point-min)) + (setq body-end (point-max)) + (goto-char header-start) + (if (re-search-forward + (concat "^" (regexp-quote mail-header-separator) "$\\|^$" ) + nil t) + (setq header-end (match-beginning 0) + body-start (if (= header-end body-end) + body-end + (1+ (match-end 0)))) + (setq header-end (point-min) + body-start (point-min))) + (save-restriction + (narrow-to-region header-start header-end) + (mime-entity-set-content-type-internal + entity + (let ((str (std11-fetch-field "Content-Type"))) + (if str + (mime-parse-Content-Type str) + ))) + ) + (mime-entity-set-header-start-internal entity header-start) + (mime-entity-set-header-end-internal entity header-end) + (mime-entity-set-body-start-internal entity body-start) + (mime-entity-set-body-end-internal entity body-end) + ))) + +(mm-define-method insert-header ((entity elmo) + &optional invisible-fields visible-fields) + (mmelmo-insert-sorted-header-from-buffer + (mime-entity-buffer entity) + (mime-entity-header-start-internal entity) + (mime-entity-header-end-internal entity) + invisible-fields visible-fields)) + +(mm-define-method insert-text-content ((entity elmo)) + (insert + (decode-mime-charset-string (mime-entity-content entity) + (or (mime-content-type-parameter + (mime-entity-content-type entity) + "charset") + default-mime-charset) + 'CRLF)) + (run-hooks 'mmelmo-entity-content-inserted-hook)) + +(provide 'mmelmo-1) + +;;; mmelmo-1.el ends here diff --git a/elmo/mmelmo-2.el b/elmo/mmelmo-2.el new file mode 100644 index 0000000..c97f3b7 --- /dev/null +++ b/elmo/mmelmo-2.el @@ -0,0 +1,142 @@ +;;; mmelmo-2.el -- mm-backend (for FLIM 1.13.x) by ELMO. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <2000-03-21 17:39:07 teranisi> + +;; This file is part of ELMO (Elisp Library for Message Orchestration). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; + +(require 'mmelmo-imap4) +(require 'mmelmo) +(require 'mmbuffer) + +(defvar mmelmo-force-reload nil) +(defvar mmelmo-sort-field-list nil) + +(eval-and-compile + (luna-define-class mime-elmo-entity (mime-buffer-entity) + (imap folder number msgdb size)) + (luna-define-internal-accessors 'mime-elmo-entity)) + +(luna-define-method initialize-instance :after ((entity mime-elmo-entity) + &rest init-args) + "The initialization method for elmo. +mime-elmo-entity has its own member variable, +`imap', `folder', `msgdb' and `size'. +imap: boolean. if non-nil, entity becomes mime-elmo-imap4-entity class. +folder: string. folder name. +msgdb: msgdb of elmo. +size: size of the entity." + (if (mime-elmo-entity-imap-internal entity) + ;; use imap part fetching. + ;; child mime-entity's class becomes `mime-elmo-imap4-entity' + ;; which implements `entity-buffer' method. + (progn + (let (new-entity) + (mime-buffer-entity-set-buffer-internal entity nil) + (setq new-entity + (mmelmo-imap4-get-mime-entity + (mime-elmo-entity-folder-internal entity) ; folder + (mime-elmo-entity-number-internal entity) ; number + (mime-elmo-entity-msgdb-internal entity) ; msgdb + )) + (mime-entity-set-content-type-internal + entity + (mime-entity-content-type-internal new-entity)) + (mime-entity-set-encoding-internal + entity + (mime-entity-encoding-internal new-entity)) + (mime-entity-set-children-internal + entity + (mime-entity-children-internal new-entity)) + (mime-elmo-entity-set-size-internal + entity + (mime-elmo-entity-size-internal new-entity)) + (mime-entity-set-representation-type-internal + entity 'mime-elmo-imap4-entity) + entity)) + (set-buffer (mime-buffer-entity-buffer-internal entity)) + (mmelmo-original-mode) + (when (mime-root-entity-p entity) + (let ((buffer-read-only nil) + header-end body-start) + (erase-buffer) + (elmo-read-msg-with-buffer-cache + (mime-elmo-entity-folder-internal entity) + (mime-elmo-entity-number-internal entity) + (current-buffer) + (mime-elmo-entity-msgdb-internal entity) + mmelmo-force-reload) + (goto-char (point-min)) + (if (re-search-forward + (concat "^" (regexp-quote mail-header-separator) "$\\|^$" ) + nil t) + (setq header-end (match-beginning 0) + body-start (if (= (match-end 0) (point-max)) + (point-max) + (1+ (match-end 0)))) + (setq header-end (point-min) + body-start (point-min))) + (mime-buffer-entity-set-header-start-internal entity (point-min)) + (mime-buffer-entity-set-header-end-internal entity header-end) + (mime-buffer-entity-set-body-start-internal entity body-start) + (mime-buffer-entity-set-body-end-internal entity (point-max)) + (save-restriction + (narrow-to-region (mime-buffer-entity-header-start-internal entity) + (mime-buffer-entity-header-end-internal entity)) + (mime-entity-set-content-type-internal + entity + (let ((str (std11-fetch-field "Content-Type"))) + (if str + (mime-parse-Content-Type str) + )))))) + entity)) + +(luna-define-method mime-insert-header ((entity mime-elmo-entity) + &optional invisible-fields + visible-fields) + (mmelmo-insert-sorted-header-from-buffer + (mime-entity-buffer entity) + (mime-buffer-entity-header-start-internal entity) + (mime-buffer-entity-header-end-internal entity) + invisible-fields visible-fields mmelmo-sort-field-list)) + +(luna-define-method mime-insert-text-content :around ((entity + mime-elmo-entity)) + (luna-call-next-method) + (run-hooks 'mmelmo-entity-content-inserted-hook)) + +;(luna-define-method mime-entity-content ((entity mime-elmo-entity)) +; (mime-decode-string +; (with-current-buffer (mime-buffer-entity-buffer-internal entity) +; (buffer-substring (mime-buffer-entity-body-start-internal entity) +; (mime-buffer-entity-body-end-internal entity))) +; (mime-entity-encoding entity))) + +(provide 'mmelmo-2) + +;;; mmelmo-2.el ends here diff --git a/elmo/mmelmo-imap4-1.el b/elmo/mmelmo-imap4-1.el new file mode 100644 index 0000000..1114063 --- /dev/null +++ b/elmo/mmelmo-imap4-1.el @@ -0,0 +1,350 @@ +;;; mmelmo-imap4-1.el -- MM backend of IMAP4 for ELMO (for FLIM 1.12.x). + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <00/03/14 19:43:18 teranisi> + +;; This file is part of ELMO (Elisp Library for Message Orchestration). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; + +(require 'mmelmo) + +(defvar mmelmo-imap4-threshold nil) +(defvar mmelmo-imap4-skipped-parts nil) +(defvar mmelmo-imap4-current-message-structure nil) + +(defun mmelmo-imap4-node-id-to-string (node-id) + (let ((i (length node-id)) + result) + (while (> i 0) + (setq result + (concat result + (if result + (concat "." (int-to-string + (+ 1 (nth (- i 1) node-id)))) + (int-to-string (or + (+ 1 (nth (- i 1) node-id)) + 0))))) + (setq i (- i 1))) + (or result "0"))) + +;; parse IMAP4 body structure entity recursively. +(defun mmelmo-imap4-parse-bodystructure-entity (location node-id entity parent) + (cond + ((listp (car entity));; multipart + (let (cur-entity + children + content-type ret-val + (num 0)) + (setq ret-val + (make-mime-entity-internal 'elmo-imap4 + location + nil ; content-type + nil ; children + parent ; parent + node-id ; node-id + )) + (while (and (setq cur-entity (car entity)) + (listp cur-entity)) + (setq children + (append children + (list + (mmelmo-imap4-parse-bodystructure-entity + (list (nth 0 location) + (nth 1 location) + (nth 2 location) + (append (list num) node-id)) + (append (list num) node-id) + cur-entity + ret-val ; myself as parent + )))) + (setq num (+ num 1)) + (setq entity (cdr entity)) + ) + (mime-entity-set-children-internal ret-val children) + (setq content-type (list (cons 'type 'multipart))) + (setq content-type (append content-type + (list (cons 'subtype + (intern + (downcase (car entity))))))) + (setq content-type (append content-type + (mime-parse-parameters-from-list + (elmo-imap4-nth 1 entity)))) + (mime-entity-set-content-type-internal ret-val content-type) + ret-val)) + (t ;; singlepart + (let (content-type result) + ;; append size information into location + (setq location (append location (list (nth 6 entity)))) + (setq content-type (list (cons 'type (intern (downcase (car entity)))))) + (if (elmo-imap4-nth 1 entity) + (setq content-type (append content-type + (list + (cons 'subtype + (intern + (downcase + (elmo-imap4-nth 1 entity)))))))) + (if (elmo-imap4-nth 2 entity) + (setq content-type (append content-type + (mime-parse-parameters-from-list + (elmo-imap4-nth 2 entity))))) + (setq result (make-mime-entity-internal 'elmo-imap4 + location + content-type ; content-type + nil ; children + parent ; parent + node-id ; node-id + )) + (mime-entity-set-encoding-internal result + (and (elmo-imap4-nth 5 entity) + (downcase + (elmo-imap4-nth 5 entity)))) + result)))) + +(defun mmelmo-imap4-parse-bodystructure-string (location string) + (save-excursion + (let ((tmp-buffer (get-buffer-create " *ELMO bodystructure TMP*")) + (raw-buffer (current-buffer)) + str + entity) + (set-buffer tmp-buffer) + (erase-buffer) + (insert string) + (goto-char (point-min)) + (when (search-forward "FETCH" nil t) + (narrow-to-region (match-end 0) (point-max)) + (while (re-search-forward "{\\([0-9]+\\)}\r\n" nil t) + (goto-char (+ (point) + (string-to-int (elmo-match-buffer 1)))) + (setq str (buffer-substring (match-end 0) (point))) + (delete-region (match-beginning 0) (point)) + (insert (prin1-to-string str))); (insert "\"")) + (setq entity + (nth 1 (memq 'BODYSTRUCTURE + (read (buffer-string))))) + (set-buffer raw-buffer) + (mmelmo-imap4-parse-bodystructure-entity location nil entity nil) + )))) + +(defun mmelmo-imap4-multipart-p (entity) + (eq (cdr (assq 'type (mime-entity-content-type entity))) 'multipart) + ) + +(defun mmelmo-imap4-rfc822part-p (entity) + (eq (cdr (assq 'type (mime-entity-content-type entity))) 'rfc822) + ) + +(defun mmelmo-imap4-textpart-p (entity) + (eq (cdr (assq 'type (mime-entity-content-type entity))) 'text) + ) + +(defun mmelmo-imap4-get-mime-entity (location) + (save-excursion + (let* ((spec (elmo-folder-get-spec (nth 0 location))) + (msg (nth 1 location)) + (connection (elmo-imap4-get-connection spec)) + (process (elmo-imap4-connection-get-process connection)) + (read-it t) + response errmsg ret-val bytes) + (when (elmo-imap4-spec-folder spec) + (save-excursion + (when (not (string= (elmo-imap4-connection-get-cwf connection) + (elmo-imap4-spec-folder spec))) + (if (null (setq response + (elmo-imap4-select-folder + (elmo-imap4-spec-folder spec) connection))) + (error "Select folder failed"))) + (elmo-imap4-send-command (process-buffer process) + process + (format "uid fetch %s bodystructure" + msg)) + (if (null (setq response (elmo-imap4-read-contents + (process-buffer process) process))) + (error "Fetching body structure failed"))) + (mmelmo-imap4-parse-bodystructure-string location + response); make mime-entity + )))) + +(defun mmelmo-imap4-read-part (entity location) + (if (or (not mmelmo-imap4-threshold) + (not (nth 4 location)) + (and (nth 4 location) + mmelmo-imap4-threshold + (<= (nth 4 location) mmelmo-imap4-threshold))) + (cond ((mmelmo-imap4-multipart-p entity)) ; noop + (t + (insert (elmo-imap4-read-part + (nth 0 location) + (nth 1 location) + (mmelmo-imap4-node-id-to-string + (nth 3 location)))) + (mime-entity-set-body-start-internal entity (point-min)) + (mime-entity-set-body-end-internal entity (point-max)))) + (setq mmelmo-imap4-skipped-parts + (append + mmelmo-imap4-skipped-parts + (list (mmelmo-imap4-node-id-to-string + (nth 3 location))))))) + +(defun mmelmo-imap4-read-body (entity) + (let ((location (mime-entity-location-internal entity))) + (mime-entity-set-body-start-internal entity (- (point) 1)) + (if (or (not mmelmo-imap4-threshold) + (not (nth 4 location)) + (and (nth 4 location) + mmelmo-imap4-threshold + (<= (nth 4 location) mmelmo-imap4-threshold))) + (insert (elmo-imap4-read-part (nth 0 location) + (nth 1 location) + "1" + )) + (setq mmelmo-imap4-skipped-parts + (append + mmelmo-imap4-skipped-parts + (list + (mmelmo-imap4-node-id-to-string + (nth 3 location)))))))) + +;;; mm-backend definitions for elmo-imap4 +(mm-define-backend elmo-imap4 (elmo)) + +(mm-define-method initialize-instance ((entity elmo-imap4)) + (let ((new-entity (mmelmo-imap4-get-mime-entity + (mime-entity-location-internal entity)))) + ;; ... + (aset entity 1 + (mime-entity-location-internal new-entity)) + (mime-entity-set-content-type-internal + entity + (mime-entity-content-type-internal new-entity)) + (mime-entity-set-encoding-internal + entity + (mime-entity-encoding-internal new-entity)) + (mime-entity-set-children-internal + entity + (mime-entity-children-internal new-entity)) + (mime-entity-set-body-start-internal + entity + (mime-entity-body-start-internal new-entity)) + (mime-entity-set-body-end-internal + entity + (mime-entity-body-end-internal new-entity)))) + +(mm-define-method entity-buffer ((entity elmo-imap4)) + (let ((buffer (get-buffer-create + (concat mmelmo-entity-buffer-name + (mmelmo-imap4-node-id-to-string + (mime-entity-node-id-internal entity))))) + (location (mime-entity-location-internal entity))) + (set-buffer buffer) + (mmelmo-original-mode) + (mime-entity-set-buffer-internal entity buffer) ; set buffer. + (let ((buffer-read-only nil)) + (erase-buffer) + (if (nth 3 location) ; not top + (progn + (setq mime-message-structure mmelmo-imap4-current-message-structure) + (mmelmo-imap4-read-part entity location)) + ;; TOP + (setq mmelmo-imap4-current-message-structure entity) + (setq mime-message-structure entity) + (setq mmelmo-imap4-skipped-parts nil) + ;; (setq mmelmo-fetched-entire-message nil) + ;; header + (insert (elmo-imap4-read-part (nth 0 location) + (nth 1 location) + "header" + )) + (mime-entity-set-header-start-internal entity (point-min)) + (mime-entity-set-header-end-internal entity (- (point) 1)) + (if (not (mime-entity-children-internal entity)) ; body part! + (progn + (mmelmo-imap4-read-body entity) + (mime-entity-set-body-end-internal entity (point)) + )))) + buffer)) + +(mm-define-method entity-point-min ((entity elmo-imap4)) + (let ((buffer (mime-entity-buffer-internal entity))) + (set-buffer buffer) + (point-min))) + +(mm-define-method entity-point-max ((entity elmo-imap4)) + (let ((buffer (mime-entity-buffer-internal entity))) + (set-buffer buffer) + (point-max))) + +(mm-define-method entity-children ((entity elmo-imap4)) + (let* ((content-type (mime-entity-content-type entity)) + (primary-type (mime-content-type-primary-type content-type))) + (cond ((eq primary-type 'multipart) + (mime-parse-multipart entity) + ) + ((and (eq primary-type 'message) + (memq (mime-content-type-subtype content-type) + '(rfc822 news external-body) + )) + (save-excursion + (set-buffer (mime-entity-buffer-internal entity)) + (mime-entity-set-body-start-internal entity (point-min)) + (mime-entity-set-body-end-internal entity (point-max))) + (mime-parse-encapsulated entity) + )) + )) + +(mm-define-method entity-body-start ((entity elmo-imap4)) + (point-min)) + +(mm-define-method entity-body-end ((entity elmo-imap4)) + (point-max)) + +;; override generic function for dynamic body fetching. +(mm-define-method entity-content ((entity elmo-imap4)) + (save-excursion + (set-buffer (mime-entity-buffer entity)) + (mime-decode-string + (buffer-substring (mime-entity-body-start entity) + (mime-entity-body-end entity)) + (mime-entity-encoding entity)))) + +(mm-define-method fetch-field ((entity elmo-imap4) field-name) + (save-excursion + (let ((buf (mime-entity-buffer-internal entity))) + (when buf + (set-buffer buf) + (save-restriction + (if (and (mime-entity-header-start-internal entity) + (mime-entity-header-end-internal entity)) + (progn + (narrow-to-region + (mime-entity-header-start-internal entity) + (mime-entity-header-end-internal entity)) + (std11-fetch-field field-name)) + nil)))))) + +(provide 'mmelmo-imap4-1) + +;;; mmelmo-imap4-1.el ends here diff --git a/elmo/mmelmo-imap4-2.el b/elmo/mmelmo-imap4-2.el new file mode 100644 index 0000000..2b4f15c --- /dev/null +++ b/elmo/mmelmo-imap4-2.el @@ -0,0 +1,394 @@ +;;; mmelmo-imap4-1.el -- MM backend of IMAP4 for ELMO (for FLIM 1.13.x). + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <00/03/14 19:43:27 teranisi> + +;; This file is part of ELMO (Elisp Library for Message Orchestration). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; +(require 'mmbuffer) +(require 'mmelmo) +(defvar mmelmo-imap4-threshold nil) +(defvar mmelmo-imap4-skipped-parts nil) +(defvar mmelmo-imap4-current-message-structure nil) + +;; Buffer local variable. +(defvar mmelmo-imap4-fetched nil) +(make-variable-buffer-local 'mmelmo-imap4-fetched) + +(defun mmelmo-imap4-node-id-to-string (node-id) + (let ((i (length node-id)) + result) + (while (> i 0) + (setq result + (concat result + (if result + (concat "." (int-to-string + (+ 1 (nth (- i 1) node-id)))) + (int-to-string (or + (+ 1 (nth (- i 1) node-id)) + 0))))) + (setq i (- i 1))) + (or result "0"))) + +;; parse IMAP4 body structure entity recursively. +(defun mmelmo-imap4-parse-bodystructure-object (folder + number msgdb + node-id object parent) + (cond + ((listp (car object));; multipart + (let (cur-obj children content-type ret-val (num 0)) + (setq ret-val + (luna-make-entity + (mm-expand-class-name 'elmo-imap4) + :folder folder + :number number + :msgdb msgdb + :parent parent + :node-id node-id)) + (while (and (setq cur-obj (car object)) + (listp cur-obj)) + (setq children + (append children + (list + (mmelmo-imap4-parse-bodystructure-object + folder number msgdb + (append (list num) node-id) + cur-obj + ret-val ; myself as parent + )))) + (setq num (+ num 1)) + (setq object (cdr object))) + (mime-entity-set-children-internal ret-val children) + (setq content-type (list (cons 'type 'multipart))) + (if (elmo-imap4-nth 0 object) + (setq content-type (append content-type + (list (cons 'subtype + (intern + (downcase + (elmo-imap4-nth + 0 + object)))))))) + (setq content-type (append content-type + (mime-parse-parameters-from-list + (elmo-imap4-nth 1 object)))) + (mime-entity-set-content-type-internal ret-val content-type) + ret-val)) + (t ;; singlepart + (let (content-type ret-val) + ;; append size information into location + (setq content-type (list (cons 'type (intern (downcase (car object)))))) + (if (elmo-imap4-nth 1 object) + (setq content-type (append content-type + (list + (cons 'subtype + (intern + (downcase + (elmo-imap4-nth 1 object)))))))) + (if (elmo-imap4-nth 2 object) + (setq content-type (append content-type + (mime-parse-parameters-from-list + (elmo-imap4-nth 2 object))))) + (setq ret-val + (luna-make-entity + (mm-expand-class-name 'elmo-imap4) + :folder folder + :number number + :size (nth 6 object) + :content-type content-type + :parent parent + :node-id node-id)) + (mime-entity-set-encoding-internal ret-val + (and (elmo-imap4-nth 5 object) + (downcase + (elmo-imap4-nth 5 object)))) + ret-val)))) + +(defun mmelmo-imap4-parse-bodystructure-string (folder number msgdb string) + (with-temp-buffer + (insert string) + (goto-char (point-min)) + (when (search-forward "FETCH" nil t) + (narrow-to-region (match-end 0) (point-max)) + (while (re-search-forward "{\\([0-9]+\\)}\r\n" nil t) + (let (str) + (goto-char (+ (point) + (string-to-int (elmo-match-buffer 1)))) + (setq str (buffer-substring (match-end 0) (point))) + (delete-region (match-beginning 0) (point)) + (insert (prin1-to-string str)))) + (goto-char (point-min)) + (mmelmo-imap4-parse-bodystructure-object + folder ; folder + number ; number + msgdb ; msgdb + nil ; node-id + (nth 1 (memq 'BODYSTRUCTURE (read (current-buffer)))) ; bodystructure-object + nil ; parent + )))) + +(defun mmelmo-imap4-multipart-p (entity) + (eq (cdr (assq 'type (mime-entity-content-type entity))) 'multipart)) + +(defun mmelmo-imap4-rfc822part-p (entity) + (eq (cdr (assq 'type (mime-entity-content-type entity))) 'rfc822)) + +(defun mmelmo-imap4-textpart-p (entity) + (eq (cdr (assq 'type (mime-entity-content-type entity))) 'text)) + +(defun mmelmo-imap4-get-mime-entity (fld number msgdb) + (save-excursion + (let* ((spec (elmo-folder-get-spec fld)) + (connection (elmo-imap4-get-connection spec)) + (folder (elmo-imap4-spec-folder spec)) + response) + (when folder + (save-excursion + (when (not (string= (elmo-imap4-connection-get-cwf connection) + folder)) + (if (null (elmo-imap4-select-folder folder connection)) + (error "Select folder failed"))) + (elmo-imap4-send-command (elmo-imap4-connection-get-buffer + connection) + (elmo-imap4-connection-get-process + connection) + (format + (if elmo-imap4-use-uid + "uid fetch %s bodystructure" + "fetch %s bodystructure") + number)) + (if (null (setq response (elmo-imap4-read-contents + (elmo-imap4-connection-get-buffer + connection) + (elmo-imap4-connection-get-process + connection)))) + (error "Fetching body structure failed"))) + (mmelmo-imap4-parse-bodystructure-string fld number msgdb + response))))) + +(defun mmelmo-imap4-read-part (entity) + (if (or (not mmelmo-imap4-threshold) + (not (mime-elmo-entity-size-internal entity)) + (and (mime-elmo-entity-size-internal entity) + mmelmo-imap4-threshold + (<= (mime-elmo-entity-size-internal entity) + mmelmo-imap4-threshold))) + (progn + (cond ((mmelmo-imap4-multipart-p entity)) ; noop + (t (insert (elmo-imap4-read-part + (mime-elmo-entity-folder-internal entity) + (mime-elmo-entity-number-internal entity) + (mmelmo-imap4-node-id-to-string + (mime-entity-node-id-internal entity)))))) + (setq mmelmo-imap4-fetched t) + (mime-buffer-entity-set-body-start-internal entity (point-min)) + (mime-buffer-entity-set-body-end-internal entity (point-max))) + (setq mmelmo-imap4-fetched nil) + (mime-buffer-entity-set-body-start-internal entity (point-min)) + (mime-buffer-entity-set-body-end-internal entity (point-min)) + (setq mmelmo-imap4-skipped-parts + (append + mmelmo-imap4-skipped-parts + (list (mmelmo-imap4-node-id-to-string + (mime-entity-node-id-internal entity))))))) + +(defun mmelmo-imap4-insert-body (entity) + (mime-buffer-entity-set-body-start-internal entity (- (point) 1)) + (if (or (not mmelmo-imap4-threshold) + (not (mime-elmo-entity-size-internal entity)) + (and (mime-elmo-entity-size-internal entity) + mmelmo-imap4-threshold + (<= (mime-elmo-entity-size-internal entity) + mmelmo-imap4-threshold))) + (insert (elmo-imap4-read-part + (mime-elmo-entity-folder-internal entity) + (mime-elmo-entity-number-internal entity) "1")) + (setq mmelmo-imap4-skipped-parts + (append + mmelmo-imap4-skipped-parts + (list (mmelmo-imap4-node-id-to-string + (mime-entity-node-id-internal entity))))))) + +;;; mime-elmo-imap4-entity class definitions. +(luna-define-class mime-elmo-imap4-entity (mime-buffer-entity) + (imap folder number msgdb size)) +(luna-define-internal-accessors 'mime-elmo-imap4-entity) + +(luna-define-method initialize-instance ((entity mime-elmo-imap4-entity) + &rest init-args) + "The initialization method for elmo-imap4. +mime-elmo-entity has its own instance variable +`imap', `folder', `msgdb', and `size'. +These value must be specified as argument for `luna-make-entity'." + (apply (car (luna-class-find-functions + (luna-find-class 'standard-object) + 'initialize-instance)) + entity init-args)) + +(luna-define-method mime-entity-buffer ((entity mime-elmo-imap4-entity)) + (if (mime-buffer-entity-buffer-internal entity) + (save-excursion + (set-buffer (mime-buffer-entity-buffer-internal entity)) + (unless (mime-root-entity-p entity) + (unless mmelmo-imap4-fetched + (setq mmelmo-imap4-skipped-parts nil) ; No need? + (let ((mmelmo-imap4-threshold + (mime-elmo-entity-size-internal entity))) + (mime-buffer-entity-set-buffer-internal entity nil) + (message "Fetching skipped part...") + (luna-send entity 'mime-entity-buffer entity) + (message "Fetching skipped part...done.")) + (setq mmelmo-imap4-fetched t))) + (mime-buffer-entity-buffer-internal entity)) + (save-excursion + (set-buffer (get-buffer-create + (concat mmelmo-entity-buffer-name + (mmelmo-imap4-node-id-to-string + (mime-entity-node-id-internal entity))))) + (mmelmo-original-mode) + (mime-buffer-entity-set-buffer-internal entity (current-buffer)) + (let ((buffer-read-only nil)) + (erase-buffer) + (mime-entity-node-id entity) + (if (mime-root-entity-p entity) + (progn + ;; root entity + (setq mmelmo-imap4-current-message-structure entity) + (setq mime-message-structure entity) + (setq mmelmo-imap4-skipped-parts nil) + ;; insert header + (insert (elmo-imap4-read-part + (mime-elmo-entity-folder-internal + entity) + (mime-elmo-entity-number-internal entity) + "header")) + (mime-buffer-entity-set-header-start-internal + entity (point-min)) + (mime-buffer-entity-set-header-end-internal + entity (max (- (point) 1) 1)) + (if (null (mime-entity-children-internal entity)) + (progn + (mime-buffer-entity-set-body-start-internal + entity (point)) + ;; insert body if size is OK. + (mmelmo-imap4-insert-body entity) + (mime-buffer-entity-set-body-end-internal + entity (point))))) + (setq mime-message-structure + mmelmo-imap4-current-message-structure) + (mmelmo-imap4-read-part entity))) + (current-buffer)))) + +(luna-define-method mime-goto-header-start-point ((entity mime-elmo-imap4-entity)) + (set-buffer (mime-entity-buffer entity)) + (point-min)) + +(luna-define-method mime-goto-body-end-point ((entity mime-elmo-imap4-entity)) + (set-buffer (mime-entity-buffer entity)) + (point-max)) + +(luna-define-method mime-entity-point-min ((entity mime-elmo-imap4-entity)) + (set-buffer (mime-buffer-entity-buffer-internal entity)) + (point-min)) + +(luna-define-method mime-entity-point-max ((entity mime-elmo-imap4-entity)) + (set-buffer (mime-buffer-entity-buffer-internal entity)) + (point-max)) + +(luna-define-method mime-entity-children ((entity mime-elmo-imap4-entity)) + (let* ((content-type (mime-entity-content-type entity)) + (primary-type (mime-content-type-primary-type content-type))) + (cond ((eq primary-type 'multipart) + (mime-parse-multipart entity)) + ((and (eq primary-type 'message) + (memq (mime-content-type-subtype content-type) + '(rfc822 news external-body) + )) + (save-excursion + (set-buffer (luna-send entity 'mime-entity-buffer entity)) + (mime-buffer-entity-set-body-start-internal entity (point-min)) + (mime-buffer-entity-set-body-end-internal entity (point-max))) + (mime-parse-encapsulated entity))))) + +;; override generic function for dynamic body fetching. +(luna-define-method mime-entity-content ((entity + mime-elmo-imap4-entity)) + (save-excursion + (set-buffer (mime-entity-buffer entity)) + (mime-decode-string + (buffer-substring (mime-buffer-entity-body-start-internal entity) + (mime-buffer-entity-body-end-internal entity)) + (mime-entity-encoding entity)))) + +(luna-define-method mime-entity-fetch-field ((entity mime-elmo-imap4-entity) + field-name) + (save-excursion + (save-restriction + (when (mime-buffer-entity-buffer-internal entity) + (set-buffer (mime-buffer-entity-buffer-internal entity)) + (if (and (mime-buffer-entity-header-start-internal entity) + (mime-buffer-entity-header-end-internal entity)) + (progn + (narrow-to-region + (mime-buffer-entity-header-start-internal entity) + (mime-buffer-entity-header-end-internal entity)) + (std11-fetch-field field-name)) + nil))))) + +(luna-define-method mime-insert-header ((entity mime-elmo-imap4-entity) + &optional invisible-fields + visible-fields) + (mmelmo-insert-sorted-header-from-buffer + (mime-entity-buffer entity) + (mime-buffer-entity-header-start-internal entity) + (mime-buffer-entity-header-end-internal entity) + invisible-fields visible-fields)) + +(luna-define-method mime-entity-header-buffer ((entity mime-elmo-imap4-entity)) + (mime-entity-buffer entity)) + +(luna-define-method mime-entity-body-buffer ((entity mime-elmo-imap4-entity)) + (mime-entity-buffer entity)) + +(luna-define-method mime-write-entity-content ((entity mime-elmo-imap4-entity) + filename) + (save-excursion + (set-buffer (mime-entity-buffer entity)) + (unless mmelmo-imap4-fetched + (setq mmelmo-imap4-skipped-parts nil) ; No need? + (let ((mmelmo-imap4-threshold (mime-elmo-entity-size-internal entity))) + (mime-buffer-entity-set-buffer-internal entity nil) ; To re-fetch. + (message "Fetching skipped part...") + (luna-send entity 'mime-entity-buffer entity) + (message "Fetching skipped part...done."))) + (mime-write-decoded-region (mime-buffer-entity-body-start-internal entity) + (mime-buffer-entity-body-end-internal entity) + filename + (or (mime-entity-encoding entity) "7bit")))) + +(provide 'mmelmo-imap4-2) + +;;; mmelmo-imap4-2.el ends here diff --git a/elmo/mmelmo-imap4.el b/elmo/mmelmo-imap4.el new file mode 100644 index 0000000..53c8f1c --- /dev/null +++ b/elmo/mmelmo-imap4.el @@ -0,0 +1,41 @@ +;;; mmelmo-imap4.el -- MM backend of IMAP4 for ELMO. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <00/03/07 17:00:30 teranisi> + +;; This file is part of ELMO (Elisp Library for Message Orchestration). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; + +(static-if (fboundp 'luna-define-method) + ;; FLIM 1.13 or later + (require 'mmelmo-imap4-2) + ;; FLIM 1.12 + (require 'mmelmo-imap4-1)) + +(provide 'mmelmo-imap4) + +;;; mmelmo-imap4.el ends here diff --git a/elmo/mmelmo.el b/elmo/mmelmo.el new file mode 100644 index 0000000..e7c541e --- /dev/null +++ b/elmo/mmelmo.el @@ -0,0 +1,159 @@ +;;; mmelmo.el -- mm-backend by ELMO. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <00/03/07 17:00:43 teranisi> + +;; This file is part of ELMO (Elisp Library for Message Orchestration). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; + +(require 'elmo-vars) +(require 'elmo-util) +(require 'mime-parse) +(require 'mmbuffer) + +(defvar mmelmo-header-max-column fill-column + "*Inserted header is folded with this value. +If function is specified, its return value is used.") + +(defvar mmelmo-header-inserted-hook nil + "*A hook called when header is inserted.") + +(defvar mmelmo-entity-content-inserted-hook nil + "*A hook called when entity-content is inserted.") + +(defun mmelmo-get-original-buffer () + (save-excursion + (let (ret-val) + (if (setq ret-val + (get-buffer (concat mmelmo-entity-buffer-name "0"))) + ret-val + (set-buffer (setq ret-val + (get-buffer-create + (concat mmelmo-entity-buffer-name "0")))) + (mmelmo-original-mode) + ret-val)))) + +(defun mmelmo-cleanup-entity-buffers () + "Cleanup entity buffers of mmelmo." + (mapcar (lambda (x) + (if (string-match mmelmo-entity-buffer-name x) + (kill-buffer x))) + (mapcar 'buffer-name (buffer-list)))) + +(defun mmelmo-insert-sorted-header-from-buffer (buffer + start end + &optional invisible-fields + visible-fields + sorted-fields) + (let ((the-buf (current-buffer)) + (mode-obj (mime-find-field-presentation-method 'wide)) + field-decoder + f-b p f-e field-name field field-body + vf-alist (sl sorted-fields)) + (save-excursion + (set-buffer buffer) + (save-restriction + (narrow-to-region start end) + (goto-char start) + (while (re-search-forward std11-field-head-regexp nil t) + (setq f-b (match-beginning 0) + p (match-end 0) + field-name (buffer-substring f-b p) + f-e (std11-field-end)) + (when (mime-visible-field-p field-name + visible-fields invisible-fields) + (setq field (intern + (capitalize (buffer-substring f-b (1- p)))) + field-body (buffer-substring p f-e) + field-decoder (inline (mime-find-field-decoder-internal + field mode-obj))) + (setq vf-alist (append (list + (cons field-name + (list field-body field-decoder))) + vf-alist)))) + (and vf-alist + (setq vf-alist + (sort vf-alist + (function (lambda (s d) + (let ((n 0) re + (sf (car s)) + (df (car d))) + (catch 'done + (while (setq re (nth n sl)) + (setq n (1+ n)) + (and (string-match re sf) + (throw 'done t)) + (and (string-match re df) + (throw 'done nil))) + t))))))) + (with-current-buffer the-buf + (while vf-alist + (let* ((vf (car vf-alist)) + (field-name (car vf)) + (field-body (car (cdr vf))) + (field-decoder (car (cdr (cdr vf))))) + (insert field-name) + (insert (if field-decoder + (funcall field-decoder field-body + (string-width field-name) + (if (functionp mmelmo-header-max-column) + (funcall mmelmo-header-max-column) + mmelmo-header-max-column)) + ;; Don't decode + field-body)) + (insert "\n")) + (setq vf-alist (cdr vf-alist))) + (run-hooks 'mmelmo-header-inserted-hook)))))) + +(defun mmelmo-original-mode () + (setq major-mode 'mmelmo-original-mode) + (setq buffer-read-only t) + (elmo-set-buffer-multibyte nil) + (setq mode-name "MMELMO-Original")) + +;; For FLIMs without rfc2231 feature . +(if (not (fboundp 'mime-parse-parameters-from-list)) + (defun mime-parse-parameters-from-list (attrlist) + (let (ret-val) + (if (not (eq (% (length attrlist) 2) 0)) + (message "Invalid attributes.")) + (while attrlist + (setq ret-val (append ret-val + (list (cons (downcase (car attrlist)) + (downcase (car (cdr attrlist))))))) + (setq attrlist (cdr (cdr attrlist)))) + ret-val))) + +(provide 'mmelmo) ; for circular dependency. +(static-if (fboundp 'luna-define-method) + ;; FLIM 1.13 or later + (require 'mmelmo-2) + ;; FLIM 1.12 + (require 'mmelmo-1)) + + +;;; mmelmo.el ends here diff --git a/elmo/utf7.el b/elmo/utf7.el new file mode 100644 index 0000000..81e66ee --- /dev/null +++ b/elmo/utf7.el @@ -0,0 +1,258 @@ +;;; utf7.el --- UTF-7 encoding/decoding for Emacs +;; Copyright (C) 1999 Free Software Foundation, Inc. + +;; Author: Jon K Hellan +;; Keywords: mail + +;; This file is part of GNU Emacs, but the same permissions apply + +;; GNU Emacs is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: +;;; UTF-7 - A Mail-Safe Transformation Format of Unicode - RFC 2152 +;;; This is a transformation format of Unicode that contains only 7-bit +;;; ASCII octets and is intended to be readable by humans in the limiting +;;; case that the document consists of characters from the US-ASCII +;;; repertoire. +;;; In short, runs of characters outside US-ASCII are encoded as base64 +;;; inside delimiters. +;;; A variation of UTF-7 is specified in IMAP 4rev1 (RFC 2060) as the way +;;; to represent characters outside US-ASCII in mailbox names in IMAP. +;;; This library supports both variants, but the IMAP variation was the +;;; reason I wrote it. +;;; The routines convert UTF-7 -> UTF-16 (16 bit encoding of Unicode) +;;; -> current character set, and vice versa. +;;; However, until Emacs supports Unicode, the only Emacs character set +;;; supported here is ISO-8859.1, which can trivially be converted to/from +;;; Unicode. +;;; When decoding results in a character outside the Emacs character set, +;;; an error is thrown. It is up to the application to recover. + +;;; Modified 8 December 1999 by Yuuichi Teranishi so that it will work under +;;; Emacs+Mule-UCS and XEmacs. + +;;; Code: + +(eval-when-compile (require 'cl)) +(eval-when-compile (require 'pces)) +(eval-when-compile (require 'static)) + +;; base64 stuff. +;;(static-if (and (fboundp 'base64-decode-region) +;; (subrp (symbol-function 'base64-decode-region))) +;; (eval-and-compile (fset 'utf7-base64-decode-region 'base64-decode-region)) +;; (require 'mel) +;; (defun utf7-base64-decode-region (start end) +;; (fset 'utf7-base64-decode-string +;; (symbol-function (mel-find-function 'mime-decode-region "base64"))) +;; (utf7-base64-decode-region start end))) + +;;(static-if (and (fboundp 'base64-encode-region) +;; (subrp (symbol-function 'base64-encode-region))) +;; (eval-and-compile (fset 'utf7-base64-encode-region 'base64-encode-region)) +;; (defun utf7-base64-encode-string (start end) +;; (fset 'utf7-base64-encode-region +;; (symbol-function (mel-find-function 'mime-encode-region "base64"))) +;; (utf7-base64-encode-region start end))) + +;; On XEmacs which does not support UTF-16 have to use u7tou8 and u8tou7. +;; These programs are included in +;; ftp://ftp.ifcss.org/pub/software/unix/convert/utf7.tar.gz +(defvar utf7-utf7-to-utf8-program "u7tou8" + "Program to convert utf7 to utf8.") +(defvar utf7-utf8-to-utf7-program "u8tou7" + "Program to convert utf8 to utf7.") + +(defvar utf7-direct-encoding-chars " -%'-*,-[]-} \t\n\r" + "Characters ranges which do not need escaping in UTF-7") +(defvar utf7-imap-direct-encoding-chars + (concat utf7-direct-encoding-chars "+\\\\~") + "Characters ranges which do not need escaping in the IMAP modified variant of UTF-7") + +(defsubst utf7-imap-get-pad-length (len modulus) + "Return required length of padding for IMAP modified base64 fragment." + (mod (- len) modulus)) + +(static-cond + ((and (featurep 'xemacs) + (module-installed-p 'xemacs-ucs)) + (defun utf7-fragment-decode (start end &optional imap) + "Decode base64 encoded fragment from START to END of UTF-7 text in buffer. +Use IMAP modification if IMAP is non-nil." + (require 'xemacs-ucs) + (save-restriction + (narrow-to-region start end) + (when imap + (goto-char start) + (while (search-forward "," nil 'move-to-end) (replace-match "/"))) + (goto-char (point-min)) + (insert "+") + (as-binary-process + (call-process-region (point-min) (point-max) + utf7-utf7-to-utf8-program + t (current-buffer))) + (decode-coding-region (point-min) (point-max) 'utf-8))) + + (defun utf7-fragment-encode (start end &optional imap) + "Decode base64 encoded fragment from START to END of UTF-7 text in buffer. +Use IMAP modification if IMAP is non-nil." + (require 'xemacs-ucs) + (let ((buffer (current-buffer)) + encoded-string) + (setq encoded-string + (with-temp-buffer + (insert-buffer-substring buffer start end) + (save-excursion + (goto-char (point-max)) + (insert "\n")) + (encode-coding-region (point-min) (point-max) 'utf-8) + (as-binary-process + (call-process-region (point-min) (point-max) + utf7-utf8-to-utf7-program + t (current-buffer))) + (goto-char (point-min)) + (when imap + (skip-chars-forward "+") + (delete-region (point-min) (point)) + (insert "&") + (while (search-forward "/" nil t) + (replace-match ","))) + (goto-char (point-max)) + (delete-backward-char 1) + (insert "-") + (buffer-string))) + (delete-region start end) + (insert encoded-string)))) + ((module-installed-p 'un-define) ;; Emacs + (defun utf7-fragment-decode (start end &optional imap) + "Decode base64 encoded fragment from START to END of UTF-7 text in buffer. +Use IMAP modification if IMAP is non-nil." + (require 'un-define) + (save-restriction + (narrow-to-region start end) + (goto-char (point-min)) + (insert "+") + (when imap + (goto-char start) + (while (search-forward "," nil 'move-to-end) (replace-match "/"))) + (decode-coding-region (point-min) (point-max) 'utf-7) + )) + + (defun utf7-fragment-encode (start end &optional imap) + "Encode text from START to END in buffer as UTF-7 escape fragment. +Use IMAP modification if IMAP is non-nil." + (require 'un-define) + (let ((buffer (current-buffer)) + encoded-string) + (setq encoded-string + (with-temp-buffer + (insert-buffer-substring buffer start end) + (encode-coding-region (point-min) + (point-max) 'utf-7) + (goto-char (point-min)) + (when imap + (skip-chars-forward "+") + (delete-region (point-min) (point)) + (insert "&") + (while (search-forward "/" nil t) + (replace-match ","))) + (skip-chars-forward "^= \t\n" (point-max)) + (delete-region (point) (point-max)) + (buffer-string))) + (delete-region start end) + (insert encoded-string)))) + (t + ;; Define as null function. + (defun utf7-fragment-decode (start end &optional imap) + "Encode text from START to END in buffer as UTF-7 escape fragment. +Use IMAP modification if IMAP is non-nil." + ) + + (defun utf7-fragment-encode (start end &optional imap) + "Encode text from START to END in buffer as UTF-7 escape fragment. +Use IMAP modification if IMAP is non-nil." + ))) + +(defun utf7-encode-region (start end &optional imap) + "Encode text in region as UTF-7. +Use IMAP modification if IMAP is non-nil." + (interactive "r") + (save-restriction + ;;(set-buffer-multibyte default-enable-multibyte-characters) + (narrow-to-region start end) + (goto-char start) + (let ((esc-char (if imap ?& ?+)) + (direct-encoding-chars + (if imap utf7-imap-direct-encoding-chars + utf7-direct-encoding-chars))) + (while (not (eobp)) + (skip-chars-forward direct-encoding-chars) + (unless (eobp) + (let ((p (point)) + (fc (following-char)) + (run-length + (skip-chars-forward (concat "^" direct-encoding-chars)))) + (if (and (= fc esc-char) + (= run-length 1)) ; Lone esc-char? + (delete-backward-char 1) ; Now there's one too many + (utf7-fragment-encode p (point) imap)))))))) + +(defun utf7-decode-region (start end &optional imap) + "Decode UTF-7 text in region. +Use IMAP modification if IMAP is non-nil." + (interactive "r") + (save-excursion + (goto-char start) + (let* ((esc-pattern (concat "^" (char-to-string (if imap ?& ?+)))) + (base64-chars (concat "A-Za-z0-9+" + (char-to-string (if imap ?, ?/))))) + (while (not (eobp)) + (skip-chars-forward esc-pattern) + (unless (eobp) + (forward-char) + (let ((p (point)) + (run-length (skip-chars-forward base64-chars))) + (when (and (not (eobp)) (= (following-char) ?-)) + (delete-char 1)) + (unless (= run-length 0) ; Encoded lone esc-char? + (save-excursion + (utf7-fragment-decode p (point) imap) + (goto-char p) + (delete-backward-char 1))))))) + ;;(set-buffer-multibyte default-enable-multibyte-characters) + )) + +(defun utf7-encode-string (string &optional imap) + "Encode UTF-7 string. Use IMAP modification if IMAP is non-nil." + (with-temp-buffer + (insert string) + (utf7-encode-region (point-min) (point-max) imap) + (buffer-string))) + +(defun utf7-decode-string (string &optional imap) + "Decode UTF-7 string. Use IMAP modification if IMAP is non-nil." + (with-temp-buffer + (insert string) + (utf7-decode-region (point-min) (point-max) imap) + (buffer-string))) + +;; For compatibility. +(defalias 'utf7-decode 'utf7-decode-string) +(defalias 'utf7-encode 'utf7-encode-string) + +(provide 'utf7) + +;;; utf7.el ends here diff --git a/etc/ChangeLog.1.ja b/etc/ChangeLog.1.ja new file mode 100644 index 0000000..b9e0896 --- /dev/null +++ b/etc/ChangeLog.1.ja @@ -0,0 +1,2031 @@ +1998-12-02 Yuuichi Teranishi + + * 0.8.8 - "Veronica" + * news $B5-;v$r%-%c%s%;%k$9$k$H$-$b(B wl-mail-send-pre-hook $B$r8F$V(B + $B$h$&$K$7$?!#(B + * im-wl.el $B$NHsF14|(B imput $B$r;H$C$F$$$k>l9g(B news $B5-;v$r(B + $B%-%c%s%;%k$G$-$J$+$C$?$N$r=$@5!#(B + * Summary $B$G(B 'E' reedit $B$7$?$H$-!"(Bdraft $B$N%P%C%U%!$,(B read-only $B$K(B + $B$J$C$F$7$^$&>l9g$,$"$kLdBj$KBP=h!#(B + ($B?@V:$5$s(B $B$h$j8f;XE&!#(B) + * $BJD$8$?%9%l%C%I$r:o=|$7$?$H$-$K$=$N;R$I$b$,9TJ}ITL@$K$J$k$N$r(B + $B=$@5(B($B?@V:$5$s(B $B$h$j8f;XE&!#(B) + * wl-mail-send-pre-hook $B$N8F$P$lJ}$rJQ99!#(B + im-wl.el $B$G(B imput $B$r;H$&>l9g$H(B elisp $BHG$N>l9g$G%P%C%U%!$N>uBV$,(B + $BF1$8$K$J$k$h$&$K$7$?!#(B + +1998-12-01 Yuuichi Teranishi + + * $BJQ?t(B wl-insert-message-id $B$,$^$k$C$-$jL5;k$5$l$F$$$?$N$r=$@5!#(B + +1998-12-01 Masahiro MURATA ($BB + + * update all $B$G%5%^%j$r:n$jD>$9$H$-!$%9%l%C%I$N?F$h$j;R$,e$N4X?t$r:F5"E*$K8F$S=P$5$J$$$h$&=$@5!#(B + * $BJ6$i$o$7$$0l;~JQ?t$NL>A0$r=$@5(B (num -> len, number -> num)$B!#(B + * nntp (not xover) $B$G?75,%a%C%;!<%8$K(B "N" $B%^!<%/$,$D$+$J$$$N$r=$@5!#(B + * wl-auto-select-next $B$,(B t $B$N$H$-$K%5%^%jFb$r0\F0$7$F$b(B + "Updated (-0/+1) message(s)" $B$J$I$NI=<($r>C$5$J$$$h$&$K$7$?!#(B + +1998-11-30 Yuuichi Teranishi + + * msgdb $B$K(B $B:G8e$N(B message-id $B$7$+J]B8$7$J$$$h$&$K$7$?!#(B + * wl-summary-weekday-name-lang $B$, + + * wl-highlight-body-too$B$,(Bnil$B$N;~$O!"%I%i%U%H$N(B body $B$b%O%$%i%$%H$7(B + $B$J$$$h$&$K$7$?!#(B + +1998-11-30 Yuuichi Teranishi + + * [elmo]elmo-localdir-msgdb-create-overview-entity-from-file $BCf$N(B + insert-file-contents $B$G5/$3$k%(%i!<$rL5;k$9$k$h$&$K$7$?!#(B + ($B2,ED$5$s(B $B$h$j8f;XE&!#(B) + * wl-summary-mark-collect $B$,!"JD$8$?%9%l%C%I$G%a%C%;!<%8$r=EJ#$7$F(B + $B=8$a$F$7$^$&$?$a!":o=|;~$K%9%l%C%I$,$*$+$7$/$J$k$3$H$,$"$k$N$r=$@5!#(B + +1998-11-29 OKUNISHI Fujikazu + + * local[dir|news] $B$@$1(B pack $B$r%5%]!<%H!#(B + +1998-11-29 Masahiro MURATA ($BB + + * wl-thread-insert-entity, wl-thread-update-line-on-buffer, + wl-thread-entity-check-prev-mark, + wl-thread-entity-check-next-mark $B$N3F4X?t$G:F5"E*$K(B binding $B$5(B + $B$l$k%m!<%+%kJQ?t$r:o8:$7$?!#(B + * wl-summary.el $B$H(B wl-thread.el $B$N%P%$%H%3%s%Q%$%k;~$N%a%C%;!<%8(B + $B$r:o8:$7$?(B($B%m!<%+%kJQ?t$N@0M}$r$7$?(B)$B!#(B + * timezone-fix-time $B$G%(%i!<$,5/$3$C$F$b%5%^%j$r:n@.$G$-$k$h$&$K(B + $B$7$?!#(B + * $BJ#?t%a%C%;!<%8$G$N%9%l%C%I%"%C%W%G!<%H$H%9%l%C%I:o=|$N9bB.2=$r(B + $B9T$C$?!#(B + * $B%5%^%j>pJs$,$J$$>l9g(B wl-summary-buffer-msgdb $B$,(B '(nil nil nil + nil) $B$K$J$k$3$H$,H?1G$5$l$F$$$J$+$C$?$N$rH?1G$7$?!#(B + * wl-summary-sync $B$N(B update all $B$G8E$$(B entity $B>pJs$,;D$C$F$7$^$&(B + $B$N$r=$@5$7$?!#(Bwl-thread-entities $B$,(B nil $B$K(B set $B$5$l$F$$$J$+$C(B + $B$?$?$a!#(B + * elmo-util.el $B$H(B wl-util.el $B$N4X?t$G8DJL$K%P%C%U%!$r:n$C$F$$$?$N(B + $B$r(B1$B$D$K$^$H$a$F9bB.2=$7$?!#(B + * sample.dot.wl $B$r99?7$7$?!#(Bwl-highlight-group-folder-by-numbers + $B$NDI2C$H!$(Bmy-wl-summary-from-func-petname $B$N%P%0=$@5!#(B + +1998-11-29 Yuuichi Teranishi + + * wl-ja.texi $B$K2CI.!&=$@5!#(B + * [elmo] localdir, archive, pop3, nntp $B$N3F%^!<%/@8@.ItJ,$G(B seen-list + $B$rMxMQ$9$k$h$&=$@5!#(B + * sync-all, sync-update $B$GA0$NL$FI>uBV$r0z$-7Q$0$h$&$K$7$?!#(B + * [elmo] elmo-msgdb-create $B$N0z?t$K(B seen-list $B$rDI2C!#(B + +1998-11-28 OKUNISHI Fujikazu + + * elmo-call-func $B$NJQ99$N$?$a!"5/F0;~$K(Barchive $B%U%)%k%@$N(B + $B%U%)%k%@%A%'%C%/$K<:GT$9$k$h$&$K$J$C$F$7$^$C$?$N$r=$@5!#(B + +1998-11-28 Yuuichi Teranishi + + * $B?75,JQ?t(B wl-summary-weekday-name-lang$B!#%G%U%)%k%H$O(B "ja"$B!#(B + * wl-summary-wday-use-japanese -> $BGQ;_!#(B + * [elmo] elmo-plugged $B$,(B 2 $B2s(B defvar $B$5$l$F$$$?$N$r=$@5(B + ($B;{ED$5$s(B $B$h$j8f;XE&!#(B) + +1998-11-27 Masayuki TERADA + + * [elmo] elmo-folder-identical-system-p $B$N%m%8%C%/$,:xAn$7$F$$$?$N(B + $B$r2~A1!#(B + +1998-11-27 Masahiro MURATA ($BB + + * wl-interactive-exit $B$,(B t $B$N$H$-!$=*N;3NG'$G(B n $B$HEz$($F$+$i:FEY(B + M-x wl $B$r + + * elmo-date $B$,%$%s%9%H!<%i$KF~$C$F$$$J$+$C$?$N$r=$@5!#(B + +1998-11-27 Yuuichi Teranishi + + * 0.8.6 - "True Colors" + * localdir, imap4 $B$O(B since $B$H(B before $B$GF|IU8!:w$G$-$k$h$&$K$7$?!#(B + ($BKLL\$5$s(B $B$N8fMWK>$K4p$E$/(B)$B!#(B + * $BF|IU$1=hM}%b%8%e!<%kMQ?75,%U%!%$%k(B elmo-date.el $B$rDI2C!#(B + * $B%9%l%C%I$,:o=|$5$l$?$H$-!"%9%l%C%I%H%C%W$N%j%9%H$,@5$7$/$J$/$J$k(B + $B$N$r=$@5(B ($BB $B$h$j8f;XE&(B)$B!#(B + * elmo-localdir-copy-msgs $B$K(B (require 'elmo-archive) $B$rDI2C!#(B + ($B;{ED$5$s(B $B$h$j8f;XE&!#(B) + +1998-11-27 Masahiro MURATA ($BB + + * elmo-call-func $B$G(B elmo-folder-get-spec $B$,L5BL$K8F$P$l$F$$$?$N$r(B + $B=$@5!#(B + * .folders $B$NF,$K$D$1$F$$$?%U%)%k%@%?%$%W$N@bL@$r:o=|!#(B + +1998-11-26 Shun-ichi GOTO + + * elmo-read-passwd $B$G(B prompt $B$K(B '%' $B$,4^$^$l$F$$$k$H%(%i!<$K$J$k(B + $B$N$r=$@5!#(B + +1998-11-26 Yuuichi Teranishi + + * $B%9%l%C%I9=B$$N%;!<%V$K$+$+$k;~4V$rC;=L!#(B + $B"*(B $B%;!<%V;~$K$$$A$$$A(B obarray $B$+$i%;!<%V$9$k(Blist $B$r@8@.$9$k$N$r$d$a!"(B + $B%9%l%C%ILZ9=B$$N%N!<%I$N%j%9%H$r%P%C%U%!%m!<%+%kJQ?t$KJ];}$9$k$3$H(B + $B$K$7$?!#(B + * $BJD$8$?%9%l%C%I$K1#$5$l$?%a%C%;!<%8$N=hM}$, + + * 0.8.5 - "Sussudio" + * IMAP4 $B$G(B RFC822 $B$N%Q!<%H$,5pBg$G%9%-%C%W$5$l$?>l9g$K(B mime-entity $B$N(B + body-start $B$H(B body-end $B$, $B$h$j8fMWK>(B) + * $BB $B$h$j8f;XE&(B)$B!#(B + +1998-11-25 Shun-ichi GOTO + + * $B4X?t(B elmo-pop3-get-connection $B$K?7$7$$0z?t(B auth$B$rDI2C!#(B + * $B4X?t(B elmo-pop3-open-connection $B$K?7$7$$0z?t(B auth$B$rDI2C!#(B + * $B?75,4X?t(B elmo-pop-make-apop-digest $B$rDI2C!#(B + * $B?75,JQ?t(B elmo-default-pop3-authenticate-type ($B%G%U%)%k%H$NG'>ZJ}K!(B)$B!#(B + * $B4X?t(B elmo-pop3-open-connection $B$K$F!"(BAPOP$B%3%^%s%I$K$h$kG'>Z$N$?$a$N(B + $B%3!<%I$rDI2C!#(B + * POP $B%U%)%k%@$N=q<0$r(B user[/auth]@host[:port] $B$H$7$?!#(B + * [elmo-pop3] APOP $BBP1~!#(B + +1998-11-24 Yuuichi Teranishi + + * 0.8.4 - "Rosanna" + * 'mo' 'mO' $B$G%^!<%/$,$J$$$H$-@hF,$K%^!<%/$,$D$$$F$7$^$&$N$r=$@5!#(B + * $B%9%l%C%I$,$^$@$&$^$/:o=|$G$-$F$J$+$C$?$N$r=$@5!#(B + ($BDEM8$5$s(B $B$N8f;XE&(B) + * "#" $B$O$d$C$Q$j$^$:$$$N$G(B pop3 $B$N%U%)%k%@J8;z$r(B "&" $B$KJQ99!#(B + ($B8eF#$5$s(BShun-ichi GOTO $B$N8f;XE&(B)$B!#(B + +1998-11-24 Shun-ichi GOTO + + * POP3 $B$O%;%C%7%g%sCf$K?7Ce%a!<%k$r8!=P$9$k5!G=$,$J$$$?$a(B + scan: update $B$7$F$b?7Ce$,8=$l$J$$BP:v$H$7$F(B + list$B;~$K$O6/@)E*$K0lEY%;%C%7%g%s$r@Z$k$h$&$K$7$?!#(B + +1998-11-24 Yuuichi Teranishi + + * 0.8.3 - "Pop Life" + * $B%9%l%C%I$,$&$^$/:o=|$G$-$J$$%P%0$r=$@5!#(B + * elmo-maildir.el $B$,%$%s%9%H!<%k$5$l$J$$$N$r=$@5!#(B + * 0.8.2 - "Open Arms" + +1998-11-23 Yuuichi Teranishi + + * $B%m!<%+%k%K%e!<%9$N%Q%9$N%G%j%_%?$O(B "." $B$G$b$h$$$3$H$K$7$?!#(B + +1998-11-23 OKUNISHI Fujikazu + + * $B%m!<%+%k%K%e!<%9!"(B'=' $B$N%5%]!<%H!#(B + +1998-11-23 Yuuichi Teranishi + + * update $B;~$K%(%i!<$,$"$k$H(B Summary $B$,(B modified $B$K$J$C$F$7$^$&$N$r(B + $B=$@5!#(B + * XEmacs $B$G%"%/%;%9%0%k!<%W$K4^$^$l$k<+J,<+?H$N%"%$%3%s$,(B + $BI=<($5$l$J$$%P%0$r=$@5!#(B + +1998-11-22 Yuuichi Teranishi + + * wl-thread-{open|close}-all $B$G=hM}$N?JD=$rI=<($9$k$h$&$K$7$?!#(B + * $B%9%l%C%I$NF~$l;R4IM}$r$d$a!"%9%l%C%I9=B$$N8!:w$K$O(B + obarray (hashtable) $B$r;H$&$h$&$K$7$?!#(B + ($B8eF#$5$s(B Shun-ichi GOTO $B$N8f=u8@$K4p$E$/(B) + * wl-thread-jump-to-next-unread $B$N(B hereto $B$,$&$^$/F0$+$J$$>l9g$,(B + $B$"$C$?$N$r=$@5!#(B + * elmo-pop3.el $B$r $B$N8f=u8@$K4p$E$/(B) + +1998-11-21 Masahiro MURATA ($BB + + * [typo] wl-draft-enable-queueing -> wl-draft-enable-queuing$B!#(B + * [typo] wl-interacitve-save-folders -> wl-interactive-save-folders$B!#(B + * [wl-ja.texi] x-face-mule $B$N@_DjNc$r=$@5!#(B + +1998-11-21 OKUNISHI Fujikazu + + * [wl-ja.texi] $BJd4V(B -> $BJd40!#(B + +1998-11-21 Yuuichi Teranishi + + * elmo-maildir $B$NDI2C$KH<$&JQ99B??t!#(B + * $B?75,%U%!%$%k(B elmo-maildir.el$B!#(B + * $B?75,JQ?t(B elmo-maildir-list$B!#%^%C%A$9$k(B localdir $B%U%)%k%@$O(B + Maildir $B$H$7$F07$&!#(B + +1998-11-20 OKUNISHI Fujikazu + + * sample.dot.wl $B$G(B msgdb $B$K(B jka-compr $B$rMxMQ$9$kNc$rDI2C!#(B + +1998-11-19 Susumu Wakabayashi + + * $B%I%-%e%a%s%H$NJ8>O$G$$$/$D$+$^$k$,H4$1$F$$$?$N$r=$@5!#(B + +1998-11-18 Masahiro MURATA ($BB + + * $B?75,%U%!%$%k(B sample.dot.wl$B!#(B + +1998-11-17 Yuuichi Teranishi + + * elmo-cache-expire-by-size $B$,(B mule-2.3@19.28 $B$G$bF0$/$h$&$K$7$?!#(B + * $B%O%$%i%$%H$N%G%U%)%k%H@_Dj$O(B wl-highlight-background-mode $B$NCM$r8+$k(B + $B$h$&$K$7$?(B(Takehama Hirohisa $B$5$s!"(B + $B85LZ$5$s(B $B$N8f0U8+$K4p$E$/(B)$B!#(B + * $B?75,JQ?t(B wl-highlight-background-mode$B!#(B + * $B?75,JQ?t(B wl-highlight-group-folder-by-numbers$B!#(B + * $B%0%k!<%W%U%)%k%@$r!"%a%C%;!<%8$N?t$K1~$8$F?'$rJQ$($i$l$k$h$&$K(B + $B$7$?(B($BBg_7$5$s(B $B!"(B + $B85LZ$5$s(B $B$h$j8fMWK>(B)$B!#(B + +1998-11-16 Hidekazu NAKAMURA + + * wl-summary-exit $B$9$k$H$-$K(B Message $B%P%C%U%!$r(B kill $B$9$k$h$&(B + $B$K$7$?!#(B + +1998-11-16 Masahiro MURATA ($BB + + * wl-delete-folder-alist $B$N(B docstring $B$N4V0c$$$r=$@5!#(B + +1998-11-16 Masahiro MURATA ($BB + + * summary $B$N(B update $B;~$K(B important mark $B$NIU$$$?%a%C%;!<%8$,4{$K(B + $BB8:_$7$J$$$H!$%5%^%j$+$i>C$($F$7$^$&$N$r=$@5$7$?!#(B + * $B%a%C%;!<%8$r:o=|$7$?$H$-$N%]%j%7!<$r%f!<%6$,JQ99$G$-$k$h$&$K$7(B + $B$?!#(B + +1998-11-15 Yuuichi Teranishi + + * Message $B%P%C%U%!$,(B modified $B$K$J$C$F$7$^$&$N$r=$@5!#(B + +1998-11-14 Yuuichi Teranishi + + * $B%9%l%C%I$,(B closed $B$J$H$-(B prefetch $B$K<:GT$9$k$N$r=$@5!#(B + * $B%9%l%C%I$N(B prefetch $B;~!"%a%C%;!<%8?t$,$*$+$7$+$C$?$N$r=$@5!#(B + * [elmo-archive] elmo-archive-get-archive-name $B$G!"B8:_$7$J$$(B + $B%U%)%k%@$N$H$-$K4|BT$5$l$k%U%!%$%kL>$,JV$C$FMh$J$$$N$r=$@5!#(B + ($B1|@>$5$s(B $B$N8f;XE&(B) + +1998-11-14 OKUNISHI Fujikazu + + * typo fix elmo-funcall() -> elmo-call-func()$B!#(B + * $B%G%#%l%/%H%j$r7!$kA0$KF1L>$N%U%!%$%k$,B8:_$9$k$+$r??LLL\$K(B + $B%A%'%C%/!#(B + * [elmo-archive] $BIQHK$K8F$P$l$J$$4X?t$O(B defun $B$KLa$7$?!#(B + +1998-11-12 Masahiro MURATA ($BB + + * elmo-localdir.el, elmo-imap4.el, elmo-nntp.el $B$,5/F0;~$+$i(B + load $B$5$l$J$$$h$&$K$7$?!#(B + * nntp$B%U%)%k%@$,(B1$B$D$b$J$/$F$b5/F0;~$K(B elmo-nntp.el $B$,(B load $B$5$l(B + $B$k$N$r=$@5$7$?!#(B + * `wl-summary-prepared-hook' $B$rDI2C!#(B + +1998-11-10 Yuuichi Teranishi + + * 0.8.1 - "Nasty" + +1998-11-09 Yuuichi Teranishi + + * wl-toggle-plugged $B$G(B modeline $B$,IT@53N$JI=<($K$J$C$F$7$^$&>l9g(B + $B$,$"$k$N$r=$@5!#(B + * ps-print.el $B$,L5$$4D6-MQ$N?75,JQ?t(B wl-print-message-func$B!#(B + wl-summary-print-message->wl-summary-print-message-with-ps-print$B!#(B + +1998-11-09 Masahiro MURATA ($BB + + * unplugged $B$J>uBV$G(B local $B%U%)%k%@$N$_$N%0%k!<%W$r%A%'%C%/$9$k(B + $B$H!$%A%'%C%/8e$K(B "Unplugged." $B$N%a%C%;!<%8$,=P$k$N$r=$@5!#(B + +1998-11-09 OKUNISHI Fujikazu + + * MsgDB $B$,(B vector $B2=$5$l$?$N$K(B elmo-archive-parse-mmdf() $B$,BP(B + $B1~$7$F$J$+$C$?!J(BOS/2 $B$G(B 'zip $B$J>l9g$K(B msgdb $B:n@.Cf$K$3$1$k!K(B + $BIT6q9g$r=$@5!#(B + +1998-11-08 Yuuichi Teranishi + + * unplugged $B$J$H$-$O%9%l%C%I%S%e!<$G$b(B wl-summary-cursor-down $B$G(B + cache $B$5$l$F$$$k%a%C%;!<%8$KHt$V$h$&$K$7$?(B + ($BC.@P$5$s(B$B$N8f;XE&(B)$B!#(B + * [elmo] autoload $B2=!#(B + * [elmo] elmo-call-func $B$G(B featurep $B$G$J$$(B backend $B$r(B + require $B$9$k$h$&$K$7$?(B($BB $B$N8f=u8@(B + $B$K4p$E$/(B)$B!#(B + +1998-11-06 Yuuichi Teranishi + + * WL-ELS $B$r(B 0.7.4 $B$N>uBV$KLa$7$?!#(B + * elmo-enable-disconnected-operation $B$,(B nil $B$N$H$-$N(B + $BIT6q9g$r$$$/$D$+=$@5(B($BC.@P$5$s(B$B!"(B + $BB $B$h$j8f;XE&(B) + +1998-11-05 $BIpED(B $BK'?.(B + + * wl-summary-print-message (with ps-print)$B!#(B + +1998-11-05 Yuuichi Teranishi + + * [im-wl] imput $B%W%m%;%9$NHsF14|2=!#(B + +1998-11-05 Masahiro MURATA ($BB + + * rassq -> rassoc$B!#(B + * wl-summary-reedit(wl-draft-reedit) $B$,(Binteger$B2=$K$h$jF0$+$J$/(B + $B$J$C$?$N$r=$@5!#(B + +1998-11-04 Masahiro MURATA ($BB + + * nntp (not xover) $B$,(Binteger$B2=$KBP1~$7$F$$$J$+$C$?$N$r=$@5!#(B + +1998-11-04 Yuuichi Teranishi + + * $BAjJQ$o$i$:(B easymenu $B$N4X?t$,8+IU$+$i$:%(%i!<$K$J$k>l9g$,$"$k$N$G(B + (require 'easymenu) $B$r(B wl-folder.el $B$KDI2C(B(take@isl.ntt.co.jp + $B$h$j8f;XE&(B)$B!#(B + * reply $B$K<:GT$9$k%P%0$r=$@5!#(B + * 0.8.0 - "Manic Monday" + * WL-ELS $B$G(B mime-setup $B$N(B require $B$K<:GT$7$?$i!"(Bmail-mime-setup $B$b(B + $B;n$9$h$&$K$7$?!#(B($BB $B$h$j8f;XE&(B) + +1998-11-03 Yuuichi Teranishi + + * $B?75,4X?t(B elmo-msgdb-overview-entity-get-extra-field$B!#(B + * $B?75,JQ?t(B elmo-msgdb-extra-fields$B!#(B + * '*' $B%^!<%/$,%S%e!<%-%c%C%7%e$K;D$C$F$7$^$&%P%0$r=$@5!#(B + * $B%P%C%U%!$+$i(B overview $B$r@8@.$9$k4X?t$r0l$D$K$^$H$a$?!#(B + * overview $B$r(B vector $B2=!#(B + +1998-11-02 Masahiro MURATA ($BB + + * [fldmgr] access $B%?%$%W0J30$N%0%k!<%W$K$O(B petname $B$,IU$1$i$l$J(B + $B$$$h$&$K$7$?!#(B + * [fldmgr] $B%"%/%;%9%0%k!<%W$rJQ99$7$F:o=|$7$?8e$K%;!<%V$9$k$H!$(B + $B$=$N%"%/%;%9%0%k!<%W$N%j%9%H$,6u$K$J$k$N$r=$@5$7$?!#(B + * [fldmgr] append $B$r$G$-$k$+$.$j(B nconc $B$KCV$-49$($?!#(B + * wl-folder-access-info-alist $B$r(B wl-folder-entity $B$KE}9g$5$;$?!#(B + * new command `wl-folder-open-unread-current-entity', + `wl-folder-open-only-unread-folder'. + * wl-folder-open-all-unread-folder, wl-folder-open-all, + wl-folder-close-all $B$N3F%3%^%s%I$r$9$H!$%P%C%U%!(B + $B>e$N(B id $B$HJQ?t$N(B id $B$,0[$J$C$F$7$^$&$N$r=$@5$7$?!#(B + * wl-folder-exit $B$G=*N;$9$k$H$-!$C$9$h$&$K$7$?!#$^$?!$8uJd$,(B1$B2hLL$K<}$^$i$J$$$H$-$O%9%/(B + $B%m!<%k$9$k$h$&$K$7$?!#(B + +1998-11-30 Yuuichi Teranishi + + * [elmo] imap4, multi, dop $B$N(B msg-num $B$b(B integer $B2=!#(B + +1998-10-29 OKUNISHI Fujikazu + + * [wl-*, elmo-*] msg-num $B$N(B integer $B2=!#(B + * [wl-*, elmo-*. smtp.el] + integer, symbol $B$NHf3S$r(B eq, memq, assq, rassq $B$G$*$3$J$&!#(B + * [elmo-archive] + macro $B$N5-=R0LCV$rA0$NJ}$K0\F0!#(B + +1998-10-29 Yuuichi Teranishi + + * [elmo] $B%*%U%i%$%s!&%P!<%A%c%k(B(imap4 $B$N$_(B...)$B!#(B + * [elmo] $B%*%U%i%$%s!&%U%)%k%@@8@.!#(B + +1998-10-28 Yuuichi Teranishi + + * 0.7.4 - "Luka" + +1998-10-27 Yuuichi Teranishi + + * wl-ja.texi $B$NJ8;z%3!<%I$r(B JIS $B$K$7$?!#(B + * [elmo] $B%*%U%i%$%s!&%j%U%!%$%k(B/$B%3%T! + + * bbdb-wl.el $B$G!"(Bbbdb-user-mail-names $B$,8z$$$F$k$H$-$K(B To $B$K(B + encoded-word $B$,$"$k$H$^$:$$$N$r=$@5!#(B + +1998-10-26 Masahiro MURATA ($BB + + * [elmo] wl-match-buffer->elmo-match-buffer. + +1998-10-25 Masahiro MURATA ($BB + + * elmo-nntp.el $B$N(B typo $B=$@5!#(B + +1998-10-25 Yuuichi Teranishi + + * wl-ja.texi $B$K2CI.(B/$B=$@5!#(B + * wl-generate-mailer-string-func $B$N(B default $B$r(B + 'wl-generate-user-agent-string $B$K$7$?!#(B + * Folder 'F' -- $B%-%e!<$K$"$k%a%C%;!<%8$rAw?.!#(B + * $B?75,JQ?t(B wl-auto-flush-queue $B%H%0%k$7$?$H$-$K<+F0E*$K%-%e!<$rAw$k!#(B + * $B?75,JQ?t(B wl-draft-enable-queueing$B!#(Boffline $B$J$iAw?.$r%-%e!<%$%s%0!#(B + * $B%*%U%i%$%s%a%C%;!<%8Aw?.!#(B + * Folder $B$G(B'$B%4%_H"$r6u$K(B'$B$7$?$"$H!"%5%^%j$,$*$+$7$/$J$k$N$r=$@5!#(B + +1998-10-24 TSUMURA Tomoaki + + * bbdb-wl.el $B$G!"(Bbbdb-user-mail-names $B$,8z$/$h$&$K$7$?!#(B + +1998-10-24 OKUNISHI Fujikazu + + * elmo-archive.el $B$G(B 'tgz $B0J30$G$OFI$a$J$/$J$C$F$?$N$r=$@5!#(B + +1998-10-24 Masahiro MURATA ($BB + + * $BB??t$N%K%e!<%9%0%k!<%W%U%)%k%@$N%A%'%C%/=hM}$rBgI}$K9bB.2=$7$?!#(B + * $BJQ?t(B `wl-folder-newsgroups-alist' $B$rG[Ns(B(vector) + `wl-folder-newsgroups-hashtb' $B$KJQ99$7$?!#(B + * [elmo-nntp] xover $B$KBP1~$7$F$$$J$$%K%e!<%9%5!<%P$G$b(B overview + $B>pJs$,$O$=$l$>$l(B elmo $B$NBP1~$9$k4X?t$N(B alias $B$H$7$?!#(B + * elmo-msgdb-get-field-value $B$,(B2$BEY(B narrow-to-region $B$9$k$N$G!$(B + SEMI $B$N>l9g$K(B std11-fetch-field $B$,$"$k$J$i$=$l$r;H$&$h$&$K$7$?!#(B + +1998-10-24 Yuuichi Teranishi + + * wl-use-semi $B$N(B default $B$r(B (module-installed-p 'mime-view) $B$K$7$?!#(B + * wl-from $B$N(B default $B$r(B user-mail-address $B$K$7$?!#(B + * $B3+;O;~$K(B wl-plugged $B$,(B nil $B$J$i%*%U%i%$%s>uBV$+$i3+;O(B + $B$9$k$h$&$K$7$?!#(B + * view-cache $B$N%;!<%V;~$K0l;~E*%^!<%/$r>C$9$h$&$K$7$?!#(B + * Summary $B$KL$=hM}$N(B refile, delete, copy $B$N%^!<%/$,$"$k$N$K(B + $B=*N;$7$h$&$H$7$?>l9g$O=hM}$9$k$+$I$&$+3NG'$9$k$h$&$K$7$?!#(B + ($BB $B$h$j8f=u8@(B) + +1998-10-22 OKUNISHI Fujikazu + + * [elmo] localdir $B$r$A$g$C$H$@$19bB.2=!#(B + +1998-10-20 Yuuichi Teranishi + + * 0.7.3 - "Kyrie" + * access $B%U%)%k%@$N%U%)%k%@>pJs%U%!%$%k$N(B old compatibility + $B$N%A%'%C%/ItJ,(B(?)$B$r=$@5!#(B + * wl-thread-jump-to-prev-unread $B$r + + * wl-ja.texi $B$K2CI.!#(B + * User-Agent $B%U%#!<%k%I$N@8@.$O4X?t(B wl-generate-user-agent-string $BFb$G(B + $B$N$_9T$J$&$h$&$K$7$?!#(Bmime-edit-insert-user-agent-field $B$,(B t $B$J$i(B + mime-edit-user-agent-value $B$NCM$r;H$&!#(B + * $B%^%k%A%U%)%k%@$G%a%C%;!<%8$,8:$C$?$H$-$K%9%l%C%I9=B$$,$*$+$7$/$J$k(B + $B$3$H$,$"$C$?$N$r=$@5!#(B + * $BJD$8$?%9%l%C%I$N%"%C%W%G!<%H;~$K%O%$%i%$%H$,$*$+$7$+$C$?$r=$@5!#(B + * [elmo] mmelmo-imap4 $B%P%C%/%(%s%I$,%a%=%C%I(B + content-entity $B$G%(%i!<$rH/@8$9$k>l9g$,$"$k$N$r=$@5!#(B + +1998-10-18 OKUNISHI Fujikazu + + * eq $B$G:Q$`$H$3$m!J(Bsymbol $B$NHf3S!K$^$G(B equal $B$,;H$o$l$F$?$N$,(B + $BL\N)$C$?$N$G!"L@$i$+$K(B symbol $B$NHf3S$H$o$+$k$H$3$m$rCV49$7$?!#(B + * wl-folder-accessible-p() $B$K(B 'archive $B$r2C$($?!#(B + * wl-ja.texi $B$N%"!<%+%$%V%U%)%k%@It$N5-=R$N=$@5!#(B + +1998-10-18 Masahiro MURATA ($BB + + * fldmgr $B$G3Fl9g!$(BDesktop $B%0%k!<%W$KB?=E$KL$FI?t$,DI2C$5$l$k$N$r(B + $B=$@5$7$?!#(B + * wl-fldmgr.el $B$N%3!<%I$N(B refine (equal->eq $BEy$r4^$`(B)$B!#(B + +1998-10-16 Yuuichi Teranishi + + * [elmo] capability $B$N%A%'%C%/$,(B XEmacs $B0J30$G$&$^$/F0$+$:!"(B + IMAP4rev1 $B$G$b(B IMAP4 $B$H4*0c$$$9$k$h$&$K$J$C$F$$$?$?$a!"(B + References $B$r;H$C$?%9%l%C%I2=$,(B XEmacs $B0J30$GF0$+$J$/$J$C$F(B + $B$7$^$C$F$$$?$N$r=$@5!#(B + * [fldmgr] $B%U%)%k%@$N%;!<%V;~!"(B.folders $B$,B8:_$7$J$$$H$-!"(B + .bak $B$K(B rename-file $B$7$h$&$H$7$F%(%i!<$K$J$k$N$r=$@5!#(B + * convert-standard-filename $B$G%U%!%$%kL>$K;H$($J$$J8;z$rCV$-49$($k(B + $B$h$&$K$7$?!#(BMule for Win32 $B$X$OFH<+$KBP1~!#(B + * [elmo] $B%M%C%H%o!<%/%W%m%;%9$N(B process-status $B$,(B 'exit $B$N$H$-$b(B + $B%3%M%/%7%g%s$rD%$j$J$*$9$h$&$K$7$?!#(B + +1998-10-14 Yuuichi Teranishi + + * [elmo] XEmacs 21.2 $B$G(B backspace $B$J$I$N(B event $B%-!<$N0lIt$r(B + char $B$H$7$FFI$a$k$h$&$K$9$k%3!<%I$r(B x-pgp-sig $B$+$i%Q%/$i$;$F(B + $B$$$?$@$$$?!#(B + +1998-10-13 Yuuichi Teranishi + + * 0.7.2 - "Joanna" + * [elmo] RFC1730 $B$G$b$=$3$=$3F0$/$h$&$K$7$?!#(B + * $B%+%l%s%H%U%)%k%@$N%O%$%i%$%H$N(B regexp $B=$@5!#(B + * XEmacs $B$N%Q%C%1!<%8$H$7$F%$%s%9%H!<%k$G$-$k$h$&$K$7$?!#(B + (make package; make install-package) + * easymenu $B$O(B require $B$9$k$h$&$K$7$?!#(B + +1998-10-12 Masahiro MURATA ($BB + + * wl-folder-open-folder $B$,@5>o$KF0:n$7$J$/$J$C$?$N$r=$@5$7$?!#(B + * wl-folder-unread-regex $B$N0z?t(B group $B$,(B nil $B$NF0:n$,JQ$o$C$?$N(B + $B$r=$@5$7$?!#(B + * wl-folder-move-cur-folder $B$,(B non-nil $B$N;~$NF0:n$,JQ$o$C$?$N$r(B + $B=$@5$7$?!#(B + * $BF1$8(B entity $B$,J#?t$"$C$?>l9g!$(Bwl-folder-update-unread $B$G$O(B + wl-folder-entity-alist $B$d%0%k!<%W$NI=<(?t$,(B1$B$D$N(B entity $B$7$+99(B + $B?7$5$l$J$$$N$r=$@5$7$?!#(B + +1998-10-12 Yuuichi Teranishi + + * Folder $B%A%'%C%/;~$KL$FI?t$N99?7$,$*$+$7$+$C$?$N$r=$@5(B + * wl-thread- $B7O$N%3%^%s%I$G:G8e$N%a%C%;!<%8$,=hM}$5$l$J$/$J$C$F(B + $B$7$^$C$?$N$r=$@5!#(B($BDEM8$5$s(B $B$N8f;XE&(B) + * 0.7.1 - "In Too Deep" + +1998-10-11 Yuuichi Teranishi + + * [elmo-archive.el] $B%U%)%k%@$N:G8e$,(B "/" $B$@$H(B .folders $B$K(B + $B=q$1$J$$$N$G%U%)%k%@$NBh(B 3 $B%9%Z%C%/(B ($B=q8KFb$N%Q%9>pJs(B)$B$NKvHx$K(B + "/" $B$r$D$1$J$/$F$b$h$$$h$&$K$7$?!#(B + * [elmo] $B%*%U%i%$%s(B FCC$B!#(B + * Message-ID $B$,$J$$$H$-$K(B Summary $B$,$*$+$7$/$J$k$N$r=$@5!#(B + * Folder mode $B$G%0%k!<%W$K$bL$FI?tI=<(!#(B + * [im-wl.el] Message-Id -> Message-ID$B!#(B + +1998-10-11 Masahiro MURATA ($BB + + * [elmo] filter$B$d(Bmulti$B%U%)%k%@Fb$N(B localdir $B%a%C%;!<%8$O(B + cache $B$7$J$$$h$&$K$7$?!#(B + * $B%"%/%;%9%0%k!<%W$O(B rename $B$G$-$J$$$h$&$K$7$?!#(B + * save $B;~$K;HMQ$5$l$F$$$J$$(B petname $B$O:o=|$9$k$h$&$K$7$?!#(B + +1998-10-11 OKUNISHI Fujikazu + + [elmo-archive.el] + * elmo-archive-header-delimiter $B$r=PNO$7$J$$%"!<%+%$%P!J(BGNU tar $B$J$I!K(B + $B$N>l9g!"(Blist-folder-subr() $BFbIt$GL58B%k!<%W$K4Y$k$N$r=$@5$7$?!#(B + * $B1\Mw@lMQ%b!<%I$r@Q6KE*$K%5%]!<%H$9$k$?$a!"=q8K$N2~JQ$rH<$J$&4X?t$K$D(B + $B$$$F$O%a%=%C%I$,Dj5A$5$l$F$k$+$I$&$+$rD4$Y$k$3$H$G%(%i!<$rH/@8$9$k$h(B + $B$&$K$7$?!#(B + * Info-Zip $B$,:G$bE,$7$F$$$k$H$N7kO@$+$i!"%G%U%)%k%H$r(B 'zip $B$K$7$?!#(B + * tar => gtar + [elmo-util.el] + * elmo-archive-get-spec() $B$G%I%i%$%V%l%?!<$bl9g$K(B + Fcc $B$9$k$H(B Fcc $B$5$l$?%a%C%;!<%8$K(B Message-ID: $B$,$D$+$J$$IT6q9g$,H/@8(B + $B$7$F$$$?$N$r=$@5$7$?!#(B + * more typo fix (s/strucuture/structure/g) + +1998-10-10 Yuuichi Teranishi + + * wl-summary-temp-mark-region $B$NHO0O$rJQ99!#(B + ($BDEM8$5$s(B $B$N8f;XE&(B) + +1998-10-09 Yuuichi Teranishi + + * [elmo-archive.el] + ':'->';', ange-ftp/efs $B$X$NBP1~(B, tar+gz $BBP1~(B, $B=q8KFb%Q%9>pJs!#(B + +1998-10-08 Yuuichi Teranishi + + * $B$h$/8F$P$l$k(B defun $B$r(B defsubst $B$KCV$-49$($?(B (scan $B$NB.EY$,Ls(B 20% + $B$/$i$$8~>e(B)$B!#(B + +1998-10-08 pf21 GOTO_Toshiya + + * wl-summary-temp-mark-copy $B$N%a%C%;!<%8$r=$@5!#(B + +1998-10-07 Yuuichi Teranishi + + * Message-Id -> Message-ID$B!#(B + * wl-highlight-message $B$G!"(Bre-search-forward $B$N0z?t$,B-$j$J$+$C$?(B + $B$?$a$K%(%i!<$,5/$3$k>l9g$,$"$k$N$r=$@5!#(B + +1998-10-05 Yuuichi Teranishi + + * $B$$$/$D$+$N%a%C%;!<%8$N(B typo $B$r=$@5!#(B + ($B;086$5$s(B $B$h$j8f;XE&(B) + * 0.7.0 - "Hungry Heart" + +1998-10-04 Masahiro MURATA ($BB + + * $B%K%e!<%95-;v$N9TF,$K$"$k%I%C%H(B(.)$B$r:o$k=hM}$,4V0c$C$F$$$?(B($BM>J,$J(B + $B%I%C%H$,IU$$$?$^$^$K$J$k(B)$B$N$r=$@5$7$?!#(B + * 1$BDL$b5-;v$,$J$$%K%e!<%9%0%k!<%W$G$O(B elmo-nntp-list-folder $B$NLa$jCM(B + $B$,(B nil $B$K$J$k$h$&$K$7$?!#(B + +1998-10-04 OKUNISHI Fujikazu + + * wl-ja.texi $B$N4V0c$$$r=$@5!#(B + +1998-10-04 Yuuichi Teranishi + + * [elmo] $B%^!<%/!&%*%U%i%$%s=hM}$N + + * $B%0%k!<%W$G$b(B petname $B$r$D$1$i$l$k$h$&$K$7$?!#(B + * [elmo] auth->login $B@ZBX$(;~!"(By-or-n-p $B$G3NG'$9$k$h$&$K$7$?!#(B + ($BC.@P(B $B$5$s(B $B$N8f=u8@$K4p$E$/(B) + * [elmo] imapd $B$N(B capability $B$r%A%'%C%/$9$k$h$&$K$7!"(Bauthenticate $B$,(B + $B$G$-$J$1$l$P(B 'auth' $B$G$b(B 'login' $B$GG'>Z$9$k$h$&$K$7$?!#(B + * [elmo] append $B;~$K(B append $B2DG=$+$I$&$+%A%'%C%/$9$k$h$&$K$7$?!#(B + * [elmo] Cyrus imapd $B$KBP1~!#(B + +1998-10-03 OKUNISHI Fujikazu + + * elmo-archive-default-type $B$,;2>H$5$l$F$J$+$C$?$N$r=$@5!#(B + * $B%O!<%I%j%s%/2DG=$+$I$&$+$rD4$Y$k$N$K!"(Badd-name-to-file $B$,$"$k$+(B + $B$I$&$+$rD4$Y$k$N$OA4$/0UL#$,$J$$$N$G!"(Bmake-symbolic-link $B$rD4$Y(B + $B$k$3$H$GBeMQ$7$?!#(B + * elmo-archive-list-folders $B$G:FMxMQ$9$k$?$a$K(B + elmo-localdir-list-folders-subr $B$G$N@55,I=8=$rJQ99!#(B + * elmo-archive-copy-msgs() $B$r archive $B$N;~$@$1M-8z!#(B + +1998-10-02 pf21 GOTO_Toshiya + + * Mule for win32 $B$G$bG'<1$G$-$k$h$&(B wl-highlight.el $B$N?'Dj5A$r(B + $B=$@5!#(B + +1998-10-02 TSUMURA Tomoaki + OKUNISHI Fujikazu + + * wl-ja.texi $B$N4V0c$$$r=$@5!#(B + +1998-10-01 Yuuichi Teranishi + + * citation $B$N%O%$%i%$%H?'$r0zMQ$4$H$KJQ$($k$h$&$K$7$?!#(B + ($BKLL\$5$s(B $B$N8fMWK>$K4p$E$/(B)$B!#(B + * wl-highlight-message-cited-text -> $BGQ;_!#(B + * 0.6.6 - "Get It On" + +1998-09-30 OKUNISHI Fujikazu + + * elmo-archive.el 0.09$B!#(B + +1998-09-30 Yuuichi Teranishi + + * Folder, Summary $B$N%a%K%e!<%P!<$r$A$g$C$H@0M}!#(B + * Message-Id $B$OAw?.;~$K<+F0E*$K$D$1$k$h$&$K$7$?!#(B + +1998-09-30 Masato Taruishi + + * [elmo] user-login-name -> (user-login-name) $B$N=$@5!#(B + +1998-09-30 Masahiro MURATA ($BB + + * $B%"%/%;%9%0%k!<%W$G$b(B fldmgr $B$+$i$"$@L>$rDI2C$G$-$k$h$&$K$7$?!#(B + +1998-09-30 Yuuichi Teranishi + + * .folders $B$K$"$@L>$N$_$rDj5A$9$k(B syntax $B$rDI2C!#(B + * $B%3%^%s%I!"(Bwl-message-refer-article-or-url $B$G(B browse-url $B$r8F$V$N(B + $B$r$d$a!"(Btm/SEMI $B$N(B button-dispatcher $B$r8F$V$h$&$K$7$?!#(B + +1998-09-29 Yuuichi Teranishi + + * wl-summary-forward $B$GF|K\8l%5%V%8%'%/%H$,2=$1$k$N$r=$@5!#(B + ($BIpED$5$s(B $B$h$j8f;XE&(B) + * mime-edit-insert-user-agent-field $B$,(B t $B$J$i(B + mime-edit-user-agent-value $B$NCM$r;H$C$F(B User-Agent: + $B%U%#!<%k%I$rA^F~$9$k$h$&$K$7$?!#(Bnil $B$J$i=>MhDL$j!#(B + +1998-09-28 Yuuichi Teranishi + + * elmo-util.el $B$K(B (require 'cl) $B$rDI2C!#(B + (Hermit-chan ($B$O$_$A$c$s(B) $B$5$s$N8f;XE&(B) + * elmo-filter-msgdb-create $B$N4V0c$$$r=$@5!#(B + ($B1|@>$5$s(B $B$N8f;XE&(B) + +1998-09-28 Masato Taruishi + + * [elmo] IMAP$B$N%0%k!<%W%U%)%k%@$r(B fetch $B$9$k$H$-$K%f!<%6L>$r(B + $BIU2C$7$F$J$$$?$a%f!<%6L>$N0c$&(BIMAP$B%5!<%P$X%"%/%;%9$9$k$HLdBj$,(B + $B5/$-$k$N$r=$@5!#(B + +1998-09-27 Masahiro MURATA ($BB + + * $B%/%m%9%]%9%H5-;v$r4{FI=hM}$9$k;~$KL$FI?t$,@5>o$KH?1G$5$l$J$$$N$r(B + $B=$@5!#(B + * $B%/%m%9%]%9%HBP>]$N%a%C%;!<%8$,JD$8$?%9%l%C%I$NCf$K$"$C$F$bI=<($7(B + $B$F=hM}$9$k$h$&$K$7$?!#(B + * fldmgr $B$G%U%)%k%@$rDI2C$9$k$H$-!$%U%)%k%@>pJs$NH?1G$,$*$+$7$/$J$k(B + $B$N$r=$@5!#(B + +1998-09-27 Yuuichi Teranishi + + * $B?75,JQ?t!"(Bwl-draft-reply-buffer-style$B!#(B + $BCM$,(B 'full $B$J$i!"%j%W%i%$;~$K%U%l!<%`A4BN$r;H$&(B + ($BKLL\$5$s(B $B$h$j8fMWK>(B)$B!#(B + * wl-mail-setup-hook $B$O(B reply $B;~$K$O%P%C%U%!$NFbMF$,3NDj$7$F$+$i(B + $B8F$V$h$&$K$7$?!#(B + * update $B;~$K;R$I$b%9%l%C%I?t$N(B update $B$,$*$+$7$+$C$?$N$r=$@5!#(B + +1998-09-26 OKUNISHI Fujikazu + + * wl-ja.texi $B$K(B elmo-archive $B$N@bL@$rDI2C!#(B + +1998-09-25 OKUNISHI Fujikazu + + * elmo-lha $B2~$a(B elmo-archive.el(lha, info-zip $BBP1~(B) + +1998-09-25 Yuuichi Teranishi + + * HTML $B$N%a!<%k$r(B cite $B$9$k$H(B w3 $B$N(B keymap $B$N(B text-property $B$,(B + $B$D$$$F$-$F$7$^$&$N$r2sHr!#(B + +1998-09-24 Yuuichi Teranishi + + * update $B;~$N%O%$%i%$%HMQ(B regexp $B$,4V0c$C$F$$$?$N$r=$@5!#(B + +1998-09-23 Yuuichi Teranishi + + * 0.6.5 - "Footloose" + * [elmo] Reference $B$H(B In-Reply-To $B$+$i(B message-id $B$r@Z$j=P$9(B + $B%b%8%e!<%k$N(B regexp $B$r=$@5!#(B + * XEmacs $B$G%a%C%;!<%8$N%I%i%C%0!u%I%m%C%W$,I|3h(B + (21.0 $B$N(B API $B$K9g$o$;$?(B)$B!#(B + * [elmo] imap4 $B$G!"%a%C%;!<%8HV9f$,Ht$s$G$$$k$H$-$K(B overview $B$N(B + $B@8@.$K<:GT$9$k$N$r2sHr(B($BKLL\$5$s(B $B$N8f;XE&(B)$B!#(B + * elmo-multi-max-of-folder $B$,$J$$$HE\$i$l$k$N$r2sHr!#(B + ($B1|@>$5$s(B, + $BDEM8$5$s(B $B$h$j8f;XE&(B) + * $B%9%l%C%I;^$N2D;k2=$KH<$&JQ99B??t!#(B + $B%9%l%C%IFb$N%a%C%;!<%8$,J#?t0lEY$K0\F0$7$?$H$-$KI=<($,$:$l$kLdBj(B + ($BB $B$h$j8f;XE&(B)$B$bF1;~$K=$@5!#(B + * $B%9%l%C%I$N;^$r2D;k2=!#(B + ($BC.@P(B $B$5$s(B $B$N8f=u8@$K4p$E$/(B) + * $B?75,JQ?t(B: + wl-thread-indent-level + wl-thread-have-younger-brother-str + wl-thread-youngest-child-str + wl-thread-vertical-str + wl-thread-horizontal-str + wl-thread-space-str + * wl-summary-indent-level -> $BGQ;_!#(B + +1998-09-22 Yuuichi Teranishi + + * wl-thread-goto-bottom-of-sub-thread : + $B%a%C%;!<%8$,;RB9$+$I$&$+!"8+$?$a$GH=CG$9$k$N$r$d$a$?!#(B + * [elmo] IMAP4 $B$@$H(B In-Reply-To $B$K$"$k(B Message-ID $B$r$b$H$K%9%l%C%I(B + $B$,:n$i$l$J$+$C$?$N$r=$@5!#(B + * $B%U%!%$%k%7%9%F%`$r$^$?$,$k(B local $B$I$&$7$N(B refile $B$,%(%i!<$K$J$k$N(B + $B$r=$@5!#(B($B8eF#(B($B$H(B) $B$5$s(B $B$h$j8f;XE&(B) + +1998-09-21 Yuuichi Teranishi + + * $B%4%_H"%U%)%k%@$G$R$H$D$E$D40A4:o=|$7$h$&$H$9$k$HL58B%k!<%W$9$k(B + $B$N$r=$@5!#(B + ($B8eF#(B($B$H(B) $B$5$s(B $B$+$i$b8f;XE&(B) + * 0.6.4 - "Easy Lover" + +1998-09-21 TSUMURA Tomoaki + + * elmo-lha $B$G!"(Bzip $B$J$I$G(B append $B;~$K(B directory $BL>$,$D$+$J$$(B + $B$h$&$K$7$?!#(B + +1998-09-21 OKUNISHI Fujikazu + + * $B?75,%P%C%/%(%s%I$r:n$k;~!"4{B8%3!<%I$G$O(B elmo-msgdb $B$@$1$O(B + $B%Q%C%AF~$l$J$$$H(B localdir $B$K$J$C$F$7$^$&$N$r2sHr$9$k:v!#(B + +1998-09-20 OKUNISHI Fujikazu + + * lha-prog-arg-get-list $B$@$1$,B>$N%*%W%7%g%sJQ?t$HHsBP>N$@$C$?$N$G!"(B + *-getlist $B$K=L$a$?!#(B + * LHA $B>(B OS/2 $BHG$H%*%W%7%g%s8_49$+$I$&$+$r(B + system-type $B$+$iH=Dj$7$F!"<+F0E*$KE,@Z$JCM$r%;%C%H$9$k$h$&$K$7$?!#(B + * lha-file-regexp $B$N(B UN|X $BHG(B LHA $BBP1~$K$h$j(B OS/2 $B$G%^%C%A$7$J$/$J$C$F(B + $B$$$?$N$G0BD>$KD>$7$?!#(B + * elmo-localdir-folder-path $B$H$NBP>N@-$+$i(B elmo-lha-basedir $B$r(B + elmo-lha-folder-path $B$KJQ99!#%G%U%)%k%H$O(B "~/Mail" + * $BB8:_$7$J$$(B LHA $B%U%)%k%@$N>l9g$K(B elmo-lha-list-folder() $B$+$i(B + elmo-lha-list-folder-subr() $B$r8F$S=P$7$F(B lha $B$,0[>o=*N;$7$F$3$1$F$?(B + $B$N$G!"B8:_$7$J$$;~$O%5%V%k!<%A%s$r8F$S=P$5$J$$$h$&$K$7$?!#(B + * elmo-lha-get-archive-name() $B$,%U%k%Q%9$N(B LHA $B%U%)%k%@$rDL$;$k$h$&$K(B + $B$7$?!#(B$/foo/bar $B$N$h$&$K(B "/" $B$G;O$^$k>l9g$O(B /foo/bar.lzh $B$H8+Pv$9!#(B + $B0l;~E*$KG$0U$N%U%)%k%@$r%^%&%s%H$7$?$$$H$-$J$I!#(B + +1998-09-20 Yuuichi Teranishi + + * wl-ja.texi $B$r=q$$$F$_$?!#(B + * tm $B$G$O(B wl-use-folder-petname-on-modeline $B$rL5;k$7$F$$$?$N$r=$@5!#(B + * tm $B$G%*%U%i%$%s>uBV$G(B IMAP $B$N%a%C%;!<%8$rFI$b$&$H$9$k$H%a%C%;!<%8(B + $B%P%C%U%!$K%+!<%=%k$,9T$C$F$7$^$&$N$r=$@5!#(B + +1998-09-19 Yuuichi Teranishi + + * Summary $B$N(B From $BIt$KF|K\8l$,$"$k$HJD$8$?%9%l%C%I$N(B update $B$,(B + $B$*$+$7$/$J$k$N$r=$@5!#(B + * $BFCDj$N%^!<%/$@$1A4$F>C$9!"(B'U' wl-summary-unmark-all$B!#(B + * $B4X?t(B wl-thread-force-open $B$,A4A3%9%l%C%I$r3+$+$J$/$J$C$F$$$?$N$r(B + $BD>$9!#(B + * local->local, IMAP->IMAP $B$N%3%T!<$r:GE,2=!"%a%C%;!<%8$N0\F0$r(B + ($B$?$V$s(B)$B9bB.2=!#(B + * $B%*%U%i%$%s>uBV$G$b(B fldmgr $B$G(B IMAP4 $B%U%)%k%@$rIU$1B-$;$k$h$&$K$7$?!#(B + * ~/.folders $B$,L5$/$F$b5/F0$G$-$k$h$&$K$7$?!#(B + * $B%O%$%i%$%H$,2?$+JQ$@$C$?$N$rD>$7$?(B($B$D$b$j(B)$B!#(B + * partial filter $B$J$i(B unsync $B$r(B nil $B$K$;$:!"IaDL$K%A%'%C%/$9$k(B + $B$h$&$K$7$?(B ($BB $B$N8f=u8@(B)$B!#(B + +1998-09-18 Masahiro MURATA ($BB + + * Folder $B$NL$FI?t$r%A%'%C%/$9$k$?$S$KL$FI?t$,A}$($F9T$/$3$H$,$"$k(B + $B$N$r=$@5!#(B + * elmo-folder-info-alist $B$N(B save $B;~$K$O!$B8:_$7$J$$(B entity $B$N>pJs(B + $B$r:o=|$9$k$h$&$K$7$?!#(B + * fldmgr $B$G@hF,$K%U%)%k%@$rA^F~$7$?>l9g!$(Bwl-folder-entity-alist $B$N99(B + $B?7J}K!$,4V0c$C$F$$$?$N$r=$@5$7$?!#(B + +1998-09-18 TSUMURA Tomoaki + + * $BB8:_$7$J$$(B lha folder $B$K(B refile $B$7$?$H$-$J$I$K!"?75,$K(B lha folder + $B$,:n@.$5$l$J$$$N$r=$@5!#(B + +1998-09-18 Yuuichi Teranishi + + * 0.6.3 - "Danger Zone" + +1998-09-17 Masahiro MURATA ($BB + + * elmo $B$G(B wl $B$N4X?t$r;HMQ$7$F$$$k$N$rD>$7$?!#(B + * Emacs-19 $B$NF1$8J8;zNs$NHf3S(B(equal)$B$G(B nil $B$K$J$k$3$H$,$"$k$?$a!$(B + $B0lIt$N(B member $B$H(B assoc $B$r(B wl-string-member $B$d(B wl-string-assoc $B$K(B + $BCV$-49$($?!#(Bwl-string-assoc $B$O(B $B?75,4X?t!#(B + * wl-folder-goto-first-unread-folder $B$G0lHV:G=i$N(B entity $B$,(B unread $B$N(B + $B>l9g!$$=$N%U%)%k%@$K0\F0$7$J$$$N$r=$@5$7$?!#(B + * folder mode $B$G$N%U%)%k%@$N8!:w;~$K0[$J$k(B petname $B$,%^%C%A$9$k$3$H$,(B + $B$"$k$N$r=$@5$7$?!#(B + * wl-summary-mark-as-read-region $B$N$_(B region $B$,9TKv$^$G$K$J$C$F$$$J$$(B + $B$N$G!$(Bwl-thread-mark-as-read $B$,@5>o$KF0:n$7$J$$$N$r=$@5$7$?!#(B + * $BJ#?t%U%)%k%@$N(B crosspost $B=hM}$K$*$$$F!$(Bmulti $B$d(B filter $B$,J#?t$K$J$C(B + $B$?%U%)%k%@$b9MN8$9$k$h$&$K$7$?!#$^$?!$4{FI=hM}$7$?%a%C%;!<%8?t$rI=(B + $B<($9$k$h$&$K$7$?!#(B + * wl-summary.el $B$K$*$$$F%m!<%+%kJQ?t(B children $B$,(B let $B$G@k8@$5$l$F$$$J(B + $B$+$C$?ItJ,$r=$@5!#(B + +1998-09-17 Yuuichi Teranishi + + * multi $B$N$H$-$K(B mmelmo-imap4 $B$,$*$+$7$+$C$?$N$r=$@5!#(B + * wl-summary-mark-as-read-all $B$,(B local,uncache $B$rL5;k$7$F$7$^$C$F$$$?(B + $B$N$r=$@5!#(B + +1998-09-17 OKUNISHI Fujikazu + + * elmo-lha.el $B$r%^!<%8!#(B + +1998-09-17 Yuuichi Teranishi + + * wl-thread-jump-to-next-unread $B$,(B hereto $B$rL5;k$7$F$$$?$N$r=$@5!#(B + * ':' $B$,%U%!%$%kL>$K;H$o$l$F$$$k$H$^$:$$>l9g$,$"$k$N$G;H$o$J$$$h$&(B + $B$K=$@5(B($B1|@>$5$s(B $B$N8f;XE&(B)$B!#(B + * elmo-lha-search $B$r/=$@5!#(B + +1998-09-16 OKUNISHI Fujikazu + + * $B?75,%U%!%$%k(B elmo-lha.el$B!#(BLHA $BMQ%$%s%?%U%'!<%9!#(B + +1998-09-16 Yuuichi Teranishi + + * 0.6.2 - "China Girl" + * wl-stay-folder-window $B$,(B nil $B$J$i(B E $B$G(B trash $B$r6u$K$9$k$H$-$b(B + $BJ,3d$7$J$$$h$&$K$7$?(B($BKLL\$5$s(B $B$N8f;XE&(B)$B!#(B + * $B?75,JQ?t(B wl-summary-fix-timezone$B!#%5%^%j$N(B Timezone $B$r9g$o$;$k!#(B + * $B%9%l%C%IA`:n%3%^%s%I$r@0M}!#(B + $B$D$$$G$K%^!<%/A`:n!"%j!<%8%g%sA`:n%3%^%s%I$b@0M}!#(B + +1998-09-15 Yuuichi Teranishi + + * wl-thread-open-close $B$G(B refile $B%^!<%/$D$-$N%9%l%C%I$r3+$$$?;~!"(B + refile $B@h$NI=<($,ESCf$^$G$7$+=P$J$+$C$?$N$r=$@5!#(B + * 'O' $B$G%3%T!<$r + + * Emacs-19.34 $B$G$O!$(Bwl-fldmgr-unsubscribe $B$,@5>o$K5!G=$;$:!"(B + $B$^$?F1$8%0%k!<%W$KJ#?t$N(B entity $B$,:n$l$F$7$^$&IT6q9g$r=$@5!#(B + * XEmacs-21.0 $B$G$O!$(Bunsubscribe $B$d(B remove $B$5$l$?%U%)%k%@$K(B + text-property $B$,IU$/$N$r=$@5!#(B + * wl-folder.el $B$NJQ99$KH4$1$,$"$C$?$N$r=$@5!#(B + * $B0[$J$k(B folder $B$NF1$8(B petname $B$O8!=P$9$k$h$&$K$7$?!#(B + * access$B%0%k!<%W$G$b%U%)%k%@$NDI2C!$A^F~!$:o=|$,9T$($k$h$&$K$7$?!#(B + * access$B%0%k!<%W$GI=<($7$J$$%U%)%k%@$r;XDj$G$-$k$h$&$K$7$?!#(B + * fldmgr $B$N(B region$BA`:n$r9bB.2=$7$?!#(B + * access $B%0%k!<%W$N(B fetching $B;~$K?7$7$$%U%)%k%@$H:o=|$5$l$?%U%)%k%@$,(B + $BJ,$+$k$h$&$K$7$?!#?7$7$$%U%)%k%@$O@hF,$KI=<($5$l$^$9!#(B + * wl-summary-move-order $B$,(B 'new $B0J30$@$H(Bwl-thread-jump-to-next-unread + $B$G%(%i!<$K$J$k$N$r=$@5!#(B + * wl-summary-read $B$G + + * Summary $B$G(B o $B$d(B d $B$G%^!<%/$9$k$H$-$K(B + gnus, mh-e $BIw$K!"FI$s$G$$$kJ}8~$r0U<1$7$F0\F0$9$k$h$&$K$7$?!#(B + * $B?75,JQ?t(B wl-summary-move-direction-downward $B$,(B t $B$N;~!"(B + $B:G8e$Ke$+2<$+$r(B + $B@Z$jBX$($k!#(B + +1998-09-13 OKUNISHI Fujikazu + + * $B4X?t(B wl-summary-refer-article-or-url$B!#(B + +1998-09-12 Yuuichi Teranishi + + * 0.6.1 - "Billie Jean" + * $B%9%l%C%I$r3+JD$7$F$b0l;~E*%^!<%/$,>C$($J$$$h$&!"(Bdelete mark, + temp mark $B$rJQ?t$KJ];}$9$k$h$&$K$7$?!#(B + * wl-thread-jump-to-next-unread $B$NCY$5$r$@$$$V7Z8:!#(B + * $B%9%l%C%I$r:o=|$7$?$H$-$KB>$N%a%C%;!<%89T$b>C$7$F$7$^$&>l9g$,$"$k(B + $BIT6q9g$rD>$9!#(B + ($B?9;3$5$s(B $B$N8f;XE&$K$h$k!#(B) + * wl-address.el $BCf$N(B insert-file $B$r(B insert-file-contents $B$KCV$-49$((B + $B$k$N$r$o$9$l$F$?!#(B + ($B?9;3$5$s(B $B$N8f;XE&$K$h$k!#(B) + * wl-fldmgr.el $B$,(B write-file-as-mime-charset $B$r;H$o$J$$$h$&$K$7$?!#(B + * wl-fldmgr.el $B$,(B alist.el $B$r(B require $B$7$J$$$h$&$K$7$?!#(B + * wl-fldmgr.el $B$r%^!<%8!#(B + +1998-09-11 Masahiro MURATA ($BB + + * $B?75,%U%!%$%k(B wl-fldmgr.el$B!#(B + $B%U%)%k%@%b!<%I$+$i(B .folders $B$NJT=8$,2DG=$K$J$C$?!#(B + * wl-folder.el $B$GF1$8(B petname $B$,$"$k$H$-$NIT6q9g$rD>$9!#(B + +1998-09-10 Yuuichi Teranishi + + * mt $B$N$H$-$K%9%l%C%I$r3+$/$h$&$K$7$?!#(B + ($BDEM8$5$s(B $B$N8f=u8@$K4p$E$/(B) + * 0.6.0 - "Angelia" + +1998-09-10 Masahiro MURATA ($BB + + * wl-summary-jump-to-parent-message $B$G;2>H@h$N(B msg-id $B$rF@$k$H$-$K6u(B + $BGr$,4^$^$l$k$?$a$K!$?F%a%C%;!<%8$,;2>H$G$-$J$$>l9g$,$"$k$N$r=$@5$7(B + $B$?!#(B + * wl-parse-newsgroups $B$G(B split-string $B$NBe$o$j$K(B wl-parse $B$r;H$&$h$&(B + $B$K$7$?!#(B + +1998-09-09 Yuuichi Teranishi + + * pick $B$5$l$?%a%C%;!<%8$N%9%l%C%I$O3+$/$h$&$K$7$?!#(B + * thread $BA`:nMQ$N%-!<%P%$%s%I$r(B + '/' -> wl-thread-open-close + '[' -> wl-thread-open-all + ']' -> wl-thread-close-all + $B$H$9$k!#(B + * wl-thread.el $B$K:GDc8BI,MW$J%b%8%e!<%k$,$H$j$"$($:40@.!#(B + * $B?75,JQ?t(B wl-thread-insert-opened$B!#(B + t $B$J$i%9%l%C%I$r3+$$$FA^F~!#(B + nil $B$J$i%9%l%C%I$rJD$8$FA^F~!#%G%U%)%k%H$O(B nil $B$H$7$?!#(B + * elmo $B$G$b0lIt(B append $B$r(B nconc $B$KJQ99$G$-$k$H$3$m$rCV$-49$($F$_$?!#(B + +1998-09-09 Takaaki MORIYAMA + + * wl-folder.el $B$G(Bappend$B$7$F$$$k$H$3$m$GJQ99$G$-$kItJ,$r(Bnconc$B$G(B + $BCV$-49$($?!#(B + * wl-address.el $BCf$N(B insert-file $B$r(B insert-file-contents $B$KCV$-49$($?!#(B + +1998-09-08 Yuuichi Teranishi + + * $B4X?t(B wl-address-setup $B$G(B file-exists-p $B$H(B file-readable-p $B$N(B and $B$r(B + $B $B$h$j8f;XE&(B) + * $B?75,JQ?t(B wl-use-folder-petname-on-modeline $B$,(B t (default $B$O(B t)$B$J$i(B + modeline $B$K(B folder $B$N$"$@L>$r=P$9$h$&$K$7$?!#(B + * $B%5%^%j(B/$B%a%C%;!<%8$N%^%&%9%[%$!<%k40A4(B(?)$BBP1~!#(B + * multi $B$J$i%/%m%9%]%9%H$N5-;v$r>C$9$h$&$K$7$?!#(B + * [elmo] multi $B$O(B Date $B$G(B sort$B!#(B + * [elmo] mark-alist $B$r(B ("Message-Number" . "Mark") $B$N(B assoc list $B$K(B + $BJQ99!#(B + +1998-09-08 Masahiro MURATA ($BB + + * petname $B$N.J8;z$,6hJL$5$l$F$$$?$N$rL5;k$9$k$h$&(B + $B$K$7$?!#(B + * filter $B$d(B multi $B$K$J$k$H!$(Bimap, nntp,localdir $B$NH=CG$,$G$-$F$$$J$$(B + $BItJ,$,$"$C$?$N$r=$@5!#(B + +1998-09-06 Yuuichi Teranishi + + * wl-folder-diff $B$G(B info-alist $B$NCM$rJQ99$9$k$h$&$K$7$?!#(B + * $B?75,%U%!%$%k(B wl-thread.el$B!#(Binteractive $B$J(B thread $BI=<(%b%8%e!<%k72!#(B + ($BC.@P$5$s(B Masato Taruishi $B$N8f=u8@$K4p$E$/(B) + +1998-09-05 Yuuichi Teranishi + + * .folders $B$G!"%U%)%k%@L>$N$&$7$m$K(B "" $B$G$/$/$C$F(B Petname $B$rDj5A(B + $B$G$-$k$h$&$K$7$?!#(B + ($BDEM8$5$s(B $B!"(B + $BC.@P$5$s(B Masato Taruishi $B$N8fDs0F$K4p$E$/(B) + +1998-09-04 Yuuichi Teranishi + + * 0.5.4 - "You Might Think" + * $B?75,JQ?t(B wl-force-fetch-folders $B$,(B non-nil $B$J$i%"%/%;%97?%U%)%k%@$r(B + $B3+$$$?$H$-$K>o$K:G?7$N%j%9%H$r $B$N8f=u8@$K4p$E$/(B) + +1998-09-03 Yuuichi Teranishi + + * unplugged $B$N$H$-$K(B wl-summary-{next|prev} $B$NF0:n$,$*$+$7$/$J$C$F(B + $B$$$?$N$rD>$9!#(B + * wl-draft-send-mail-with-smtp $B$H(B wl-draft-send-mail-with-qmail $B$b(B + wl-mail-send-pre-hook $B$rI>2A$9$k$N$r(B wl-do-fcc() $B $B$N8f;XE&$K$h$k(B) + $B$^$@IT40A4!)(B + * $BNc$($P(B /last:100/... $B$G(B 100 $B8D$J$+$C$?$i%(%i!<$,=P$k$N$r=$@5!#(B + +1998-09-03 Ishikawa Ichiro + + * Message-Id $B$dK\J8$,$J$$%a%C%;!<%8$,$"$k$H$-$NLdBj$r=$@5!#(B + +1998-09-03 TSUMURA Tomoaki + + * Emacs20.2 $B$G(B update $B$,%(%i!<$K$J$kLdBj$r=$@5!#(B + +1998-09-03 OKUNISHI Fujikazu + + * wl-init() $B$G(B wl-demo() $B$9$k%?%$%_%s%0$r(B ~/.wl $B%m!<%I8e$K!#(B + * im-wl.el $B$G(B wl-mail-send-pre-hook $B$rI>2A$9$k$N$r(B wl-do-fcc() $B + + * $B?75,JQ?t(B wl-draft-reply-without-argument-list $B$*$h$S(B + wl-draft-reply-with-argument-list $B$rDI2C!"(Breply $B;~$N%G%U%)%k%H$r(B + $B%+%9%?%^%$%:$G$-$k$h$&$K$7$?!#(B + * ChangeLog $B$,4V0c$C$F$$$?$N$r=$@5!#(B + ($BB $B$h$j8f;XE&(B) + + * 0.5.3 - "Xanadu" + * elmo-nntp-msgdb-create-as-numlist $B$N$3$H$r$o$9$l$F$?$N$G:n$C$?!#(B + ($BDEM8$5$s(B $B$h$j8f;XE&(B) + +1998-09-01 Yuuichi Teranishi + + * $B?75,%U%!%$%k!"(BREADME-FOLDER.ja$B!#(B $B%U%)%k%@$N=q<0$r@bL@$9$k%a%b!#(B + * Summary $B$G(B "V" $BEy$G:n$i$l$?2>A[%U%)%k%@$+$iC&=P$9$k?75,%3%^%s%I!"(B + wl-summary-unvirtual $B$r(B "U" $B$K%P%$%s%I!#(B + * [elmo] elmo-filter-search $B$r$A$g$C$H$^$8$a$KpJs$r(B fetch $B$9$k$N$r$d$a!"(B + $BEv3:ItJ,$N(B envelope $B$rA4It(B fetch $B$7$?$"$H%/%i%$%"%s%HB&$G(B filter + $B$9$k$h$&$K$7$F9bB.2=(B($B%a%b%j;H$&$1$I(B)$B!#(B + +1998-09-01 Masahiro MURATA ($BB + + * wl-auto-select-first $B$,(B nil $B$N$H$-!$:G=i$NL$FI%a%C%;!<%8$K(B + $BHt$V$h$&=$@5!#(B + +1998-09-01 Yuuichi Teranishi + + * update $B$N(B message $B$r=P$9%?%$%_%s%0$rJQ99!#(B + * [elmo] "Message-ID: <>" $B$@$H:o=|$G$-$J$$$H$$$&LdBj$,;D$C$F$$$?$N(B + $B$rD>$9!#(B + +1998-08-31 Yuuichi Teranishi + + * 0.5.2 - "Wild Boys" + * [elmo] $B$^$?$b$d(B "Message-ID: <>" $B$@$HF0$+$J$/$J$C$F$$$?$N$rD>$9!#(B + * [elmo] localdir $B$G!"?t;z$,O"B3E*$G$J$$$HL5BL$K%k!<%W$r2s$k$N$r=$@5!#(B + * wl-summary-goto-folder $B$G!"(Bhighlight $B$N;EJ}$r4V0c$($F$$$?$N$rD>$9!#(B + * XEmacs $B$@$H(B .folders $B$K(B filter $B$r;XDj$7$F$$$k$H%(%i!<$K$J$k$N$r=$@5(B + ($B%"%$%3%s$N$3$H$o$9$l$F$?(B)$B!#(B + ($BDEM8$5$s(B $B$N8f;XE&$K4p$E$/JQ99(B) + * [elmo] elmo-folder-diff $B$G!"(Bfilter $B$N$H$-$K(B multi $B$r;XDj$7$F$$$k$H(B + $B%(%i!<$K$J$k$N$rD>$9!#(B + ($BDEM8$5$s(B $B$N8f;XE&$K4p$E$/JQ99(B) + * [elmo] elmo-filter-append-msg $B$rD>$9!#(B + +1998-08-28 Yuuichi Teranishi + + * 0.5.1 - "Valotte" + * filter $B$NDI2C$KH<$&JQ99B??t!#(B + * $B?75,JQ?t(B wl-folder-no-save-list, wl-folder-save-list$B!#(B + * [elmo] $B?75,%U%!%$%k(B elmo-filter.el$B!#(B + +1998-08-26 Yuuichi Teranishi + + * 0.5.0 - "Uptown Girl" + +1998-08-25 Yuuichi Teranishi + + * multi $B$NDI2C$KH<$&JQ99B??t!#(B + * [elmo] $B?75,%U%!%$%k(B elmo-multi.el$B!#(B + * elmo-cache-expire-by-size $B$r + + * XEmacs $B$GJ#?t(B frame $B$r;H$C$F$$$k>l9g!"(Bonly one window $B$J(B frame $B$G(B + wl-draft-hide $B$9$k$H!"(Bframe $B$4$H>C$($F$7$^$&$N$r2sHr!#(B + +1998-08-24 Yuuichi Teranishi + + * Summary $B$,0lDj9T?t0J>e$"$k>l9g$O!":G=i$KI=<($9$k%a%C%;!<%8$N(B + $B$"$?$j$+$i2<$@$1%O%$%i%$%H$9$k$h$&$K$7$?!#(B + ($B0lDj?t(B = wl-summary-highlight-partial-threshold, default $B$O(B 1000) + * Summary $B$N(B highlight $B$G(B looking-at $B$N2s?t$r8:$i$7$F$A$g$C$H$@$1(B + $B9bB.2=(B(15% $B$/$i$$(B?)$B!#(B + * Summary $B$N(B $B%a%C%;!<%8HV9f$NI=<(7e?t$N@_Dj$rHFMQ2=!#(B + +1998-08-23 Yuuichi Teranishi + + * wl-folder-info-save $B$,(B t $B$J$iL$FI>pJsI=<($b%j%8%e!<%`$9$k$h$&(B + $B$K$7$?!#(B + * elmo-folder-info-save -> wl-folder-info-save (default $B$r(B t $B$K(B)$B!#(B + * fdbinfo -> finfo. + +1998-08-23 Masahiro MURATA ($BB + + * $B3F%U%)%k%@$N:GBg%a%C%;!<%8HV9f$dL$FI?t$r(B cache $B$7$F(B + wl-folder-check-entity $B$r9bB.2=$7$?!#(B + elmo-folder-info-save $B$,(B non-nil $B$J$i(B save $B$7$F$,Jd40$G$-$k$h$&$K$7$?!#(B + * alias $B%U%!%$%k$N2r@O;~$K9TF,$N(B '#' ';' $B$r%3%a%s%H07$$$K$7$?!#(B + * wl-folder-empty-trash $B + + * important-mark $B$r%0%m!<%P%k$K4IM}$9$k$h$&$K$7$?!#(B + +1998-08-21 Yuuichi Teranishi + + * wl-summary-jump-to-parent-msg-by-message-id $B$G!"Ev3:%a%C%;!<%8$,(B + $B0c$&%U%)%k%@$K$"$k>l9g$OHt$V$3$H$b$G$-$k$h$&$K$7$?!#(B + (XEmacs $B$G(B elmo-use-database $B$,(B t $B$N>l9g$N$_(B) + * [elmo] dbm $B%b%8%e!<%k72MQ?75,%U%!%$%k!"(Belmo-database.el $B:n@.!#(B + (XEmacs $B@lMQ(B) + +1998-08-20 Yuuichi Teranishi + + * wl-summary-mark-as-read-all $B$G$$$A$$$A%-%c%C%7%e$,B8:_$9$k$+$I$&$+(B + $B%A%'%C%/$7$J$$$h$&$K$7$?!#(B + * XEmacs $B8~$1(B Opening Logo $B$r0l?7!#(B + * [elmo] elmo-cache-search $B$r?7%-%c%C%7%eJ}<0$KDI=>!#(B + +1998-08-19 Yuuichi Teranishi + + * [elmo] $B%-%c%C%7%e$r%0%m!<%P%k$K4IM}$9$k$h$&$K$7$?!#(B + * [elmo] $B%-%c%C%7%e4IM}%b%8%e!<%k72MQ?75,%U%!%$%k!"(Belmo-cache.el $B$r(B + $B:n@.!#(B + +1998-08-18 OKUNISHI Fujikazu + + * search-parent $B$N=$@5!#(B + +1998-08-17 Yuuichi Teranishi + + * [elmo] imap4 $B$G(B select $B$;$:$K(B list folder $B$9$k$H!" + + * search-parent $B$G2?HVA0$N?F$+$r;XDj$G$-$k$h$&$K$7$?!#(B + +1998-08-16 Yuuichi Teranishi + + * wl-mime.el $B$G!"(Bfollow-current-entity $B$NA0$K(B widen $B$9$k$h$&$K$7$?!#(B + * original buffer $B$r(B read-only $B$K$7$?!#(B + ($B1|@>$5$s(B $B$h$j8f;XE&(B) + +1998-08-16 OKUNISHI Fujikazu + + * wl-break-pages $B$,$A$c$s$HH?1G$5$l$J$$$N$r=$@5!#(B + +1998-08-16 Masahiro MURATA ($BB + + * wl-folder-goto-first-unread-folder, wl-folder-open-all-unread-folder, + wl-folder-open-folder $B$r(B wl-folder-get-path $B$r;H$&$h$&JQ99!#(B + * wl-highlight-folder-path $B$N2~NI!#(B + +1998-08-14 Masahiro MURATA ($BB + + * localdir $B$J(B access $B%0%k!<%W$r(B fetching $B$9$k$H$-$K!$%0%k!<%WL>$K(B + property $B$,$D$$$F$$$k$;$$$G7W$J(B property $B$,IU$/(B + $B$N$r=$@5!#(B + * wl-folder-goto-folder $B$G0\F0$9$k$H$-$K(B + wl-folder-buffer-cur-entity-id $B$r%;%C%H$9$k$h$&$K$7$?!#(B + * $B?75,4X?t(B wl-folder-goto-first-unread-folder ('f') + $BL$FI%a%C%;!<%8$,$"$k:G=i$N%U%)%k%@$K0\F0$9$k!#(B + * $B?75,4X?t(B wl-folder-jump-folder ('J') + $B;XDj$7$?%U%)%k%@$K0\F0$9$k!#$=$N;~!$%U%)%k%@$,B0$7$F$$$k%0%k!<%W(B + $B$r3+$/!#(B + * $B?75,4X?t(B wl-folder-open-all-unread-folder ('o') + $BL$FI%a%C%;!<%8$,$"$k%U%)%k%@$N%0%k!<%W$rA4$F3+$/!#(B + * $B?75,4X?t(B wl-folder-open-folder + $B;XDj$7$?%U%)%k%@$N%0%k!<%W$r3+$/!#(B + +1998-08-14 Yuuichi Teranishi + + * [elmo] delete $B;~!"(Bexpunge $B$N%?%$%_%s%0$rJQ99(B($B$+$J$j9bB.2=(B)$B!#(B + * trash folder $B$G$N(B "D" $B%^!<%/$O(B($B??$N(B)$B:o=|$r$5$s(B $B$h$j8f;XE&(B) + +1998-08-14 Masahiro MURATA ($BB + + * msgdb $B$O(B save $B$5$l$F!$(Bsummary-cache $B$O(B save $B$5$l$J$$>u67$,H/@8$9$k(B + $B>l9g$,$"$k$N$r2sHr!#(B + +1998-08-13 Yuuichi Teranishi + + * Summary $B$KDI2C$5$l$k9T$N(B highlight $B$NJ}K!$rJQ99(B($BB?>/9bB.2=(B)$B!#(B + * $B%G%U%)%k%H$N(B cite $B$@$H(BFrom:$B$K4A;z$,4^$^$l$F$$$k$H(B internal $B$K$J$C$F(B + $B$7$^$&$N$r=$@5!#(B(te@gohome.org $B$h$j8f;XE&(B) + * no-cache-folder $B$G$b!"(Bimportant-mark $B$r$D$1$k$H$-$K%-%c%C%7%e$9$k(B + $B$h$&$K$7$?!#(B($BB $B$h$j8f0U8+(B) + * Message-Id: <> $B$N%a!<%k$,%-%c%C%7%e;~$K%(%i!<$K$J$k$N$r2sHr!#(B + ($B1-;t$5$s(B $B$h$j8f;XE&(B) + * [bbdb-wl.el] bbdb$B%(%s%H%j$r%-%c%C%7%e$9$k$h$&JQ99!#(B + +1998-08-13 OKUNISHI Fujikazu + + * [bbdb-wl.el] Emacs20.x $B$G%(%i!<$,5/$3$k$N$r2sHr!#(B + +1998-08-11 Yuuichi Teranishi + + * wl-set-string-width $B$G!"%;%C%H$7$h$&$H$7$F$$$kD9$5$,(B string $B$H(B + $B$A$g$&$IF1$8$@$H(B XEmacs $B$G$O$J$<$+(B1$BJ8;zD9$/$J$C$F$7$^$&$N$r2sHr!#(B + * [elmo] imap4 $B$N(B bodystructure $B$,F|K\8l$@$C$?$j$9$k$H(B parse $B$K<:GT$9$k$N$r2sHr!#(B + +1998-08-09 Yuuichi Teranishi + + * v0.4.3 - "Starting Over" + * wl-no-cache-folder-list $B$r?7@_!"%^%C%A$7$?%U%)%k%@$O(B + $B%a%C%;!<%8$rFI$s$G$b%-%c%C%7%e$7$J$$!#(B + * elmo-imap4-msgdb-create-range, elmo-nntp-msgdb-create-range + $B$K$*$1$k(B overview $B$N + + * msgdb $B$N%;!<%V$r!"JQ99$,$"$C$?ItJ,$@$19T$&$h$&$K$7$?!#(B + ($BB $B$h$j8f;XE&(B) + +1998-08-07 Fumitoshi UKAI + + * elmo-imap4-msgdb-create-range $B$r9bB.2=!#(B + +1998-08-06 Fumitoshi UKAI + + * msgdb $B$N(B load $B$H(B imap4 select folder $B$rHsF14|$K9T$&(B + wl-summary-msgdb-load-async $B$N + + * v0.4.2 - "Rock Me Amadeus" + * imap4, nntp $B$G(B overview $B$r $B$h$j8f=u8@(B) + * Summary $B$N(B Update $B$G(B, $BDI2C$5$l$?%a%C%;!<%8$N(B highlight $B$NJ}K!$rJQ99!#(B + +1998-08-06 Masahiro MURATA ($BB + + * wl-summary-reedit $B$r(B draft $B%U%)%k%@$G$N(B + $B%X%C%@(B(From$B$J$I(B)$B$rJQ99$9$k5!G=$rDI2C$7$?!#(B + +1998-08-06 Yuuichi Teranishi + + * [elmo] current folder $B$,F1$8$J$i(B select folder $B$7$J$$$h$&$K$7$?!#(B + ($B1-;t$5$s(B $B$h$j8f=u8@(B) + +1998-08-06 Fumitoshi UKAI + + * [elmo] elmo-msgdb-list-diff2 $B$r9bB.2=!#(B + +1998-08-05 Masahiro MURATA ($BB + + * $B%a%C%;!<%8%X%C%@$N(B highlight $B$r$b$C$H<+M3$KDj5A$G$-$k$h$&$K$7$?!#(B + +1998-08-04 Yuuichi Teranishi + + * [elmo] scan $B$NB.EY8~>e$N$?$a$K(B overview $B%G!<%?%Y!<%9$O!"%a%b%j>e!"(B + HDD$B>e$$$:$l$b(B iso-2022-jp($B$=$N%U%)%k%@$N(B mime-charset)$B$GJ]B8$9$k(B + $B$h$&$K$7$?!#(B + * wl-summary-toggle-thread $B$r + + * tm $B$G0zMQ$7$F%j%W%i%$$7$h$&$H$9$k$H(B + (void-variable mime::preview/mother-buffer) $B$K$J$k>l9g$,$"$k$N$r(B + $B2sHr!#(B + +1998-08-04 Yuuichi Teranishi + + * $BJQ?t(B wl-summary-indent-length-limit $B$r?7@_!#(B + $B$I$s$J$K%9%l%C%I$,?<$/$F$b$3$ND9$50J>e%$%s%G%s%H$7$J$$!#(B + $B%G%U%)%k%H$O(B 46 ($B:,5r$J$7(B)$B!#(B + ($B1|@>$5$s(B $B$h$j8f;XE&(B) + +1998-08-03 Yuuichi Teranishi + + * [elmo] localdir $B$N(B search $B;~!"$A$c$s$H(B elmo-mime-charset $B$G(B + decode $B$9$k$h$&$K$7$?!#(B + * wl-summary-sort $B$r + + * $B?75,%a%C%;!<%8$r(B prefetch $B$9$k4X?t(B wl-summary-incorporate $B$rDI2C!#(B + * tm $B$G5pBg%a%C%;!<%8$r$9!#(B + * prefetch $B$9$k$HL$FI?tI=<($,$*$+$7$/$J$k$N$r=$@5!#(B + * wl-folder-sync-entity $B$,@5$7$/%5%^%j%S%e!<%-%c%C%7%e$r99?7$7$J$$(B + $B%P%0$r=$@5!#(B + * wl-summary-down $B$,(B interrupt $B$5$l$?;~$K%+%l%s%H%U%)%k%@>pJs$,(B + $B$*$+$7$/$J$k$N$r=$@5!#(B + * 00README.ja $B$K(B install.el $B$K4X$9$kCm0U=q$-$rDI2C!#(B + ($B1|@>$5$s(B $B$h$j8f=u8@(B) + +1998-07-31 Masahiro MURATA ($BB + + * [elmo] elmo-nntp-list-folder $B$,(B XEmacs $B0J30$GF0$+$J$$%P%0$r=$@5!#(B + +1998-07-31 Yuuichi Teranishi + + * [elmo] imap4 $B$G!"%7%s%0%k%Q!<%H$N5pBg$J%a%C%;!<%8$N>l9g!"(B + $B + + * $B%0%k!<%W%U%)%k%@>e$K%+!<%=%k$,$"$k$H$-$K%4%_H"$r6u$K$9$k$H!"(B + summary window $B$,;D$C$F$7$^$&$N$r2sHr!#(B + * get-text-property $B$NB?MQ$G!"(Bwl-folder-update-unread $BEy$,(B + $BCY$/$J$C$F$$$?$N$G!"6KNO(B get-text-property $B$r8:$i$7$?!#(B + * wl-message-window-size $B$N%G%U%)%k%H$r(B '(1 . 4) $B$K$7$?!#(B + * $BJQ?t(B wl-summary-recenter $B$,(B non-nil $B$J$i!"(Bredisplay $B;~$K(B + recenter $B$9$k$h$&$K$7$?!#(B + * v0.4.0 - "One More Try" + +1998-07-29 Yuuichi Teranishi + + * wl-folder-petname-alist $B$r?7@_!#%^%C%A$7$?$i%U%)%k%@$r$"$@L>I=<(!#(B + * wl-auto-select-next $B$,(B non-nil $B$N$H$-!"(BSPC $B$@$1$G$J$/!"(B + $B8=:_$N%3%^%s%I$,l9g$G$b + + * $B%X%C%@$N%U%)%s%H$N%G%U%)%k%H$r(B bold $B$K$7$?!#(B + * $B8=:_A*Br$5$l$F$$$k%U%)%k%@(B($B$N%Q%9(B)$B$H%a%C%;!<%8$r%O%$%i%$%H$9$k(B + $B$h$&$K$7$?!#(B + * wl-summary-auto-select-next $B$G!"e$G$O(B text-property, + 'wl-folder-entity-id $B$G;2>H$G$-$k$h$&$K$7$?!#(B + wl-folder-entity-alist $B$N9=B$$K$b(B entity-id $B$rDI2C!#(B + +1998-07-26 Yuuichi Teranishi + + * $B%-%c%C%7%e$GK\J88!:w(B($B%-%c%C%7%e8!:w(B)$B$G$-$k$h$&$K$7$?!#(Bimap4 $B$N(B + offline $B>uBV!"$*$h$S!"(Bnntp $B$G$O!"$3$N%-%c%C%7%e8!:w$rMQ$$$k!#(B + * Message-ID $B$K(B "/" $B$,4^$^$l$k$H$-!"%-%c%C%7%e$N%U%!%$%kL>$G$O(B " " + $B$KCV$-49$($k$3$H$K$7$?!#(B + * $B%j%U%!%$%k%^!<%/$rIU$1$?$^$^%U%)%k%@$rC&=P$9$k$H!"%4%_$,%;!<%V(B + $B$5$l$k$N$r2sHr$7$?(B($B$D$b$j(B)$B!#(B + * $B%5%^%j%S%e!<%-%c%C%7%e$N(BHDD$B$X$N=q$-9~$_$r!"JQ99$,$"$k$?$S$G$O$J$/!"(B + $B%U%)%k%@!<$r0\F0!&H4$1$k;~$K0l5$$K=q$-=P$9$h$&$K$7$?!#(B + * NNTP $B$G$b%U%)%k%@%j%9%H$Nl9g!"L$FI%^!<%/$N?t$,(B + $B$*$+$7$/$J$k$N$rD>$7$?(B($B$D$b$j(B)$B!#(B + * $B%U%)%k%@%j%9%H$r%-%c%C%7%e$9$k$h$&$K$7$?!#(B + $B:G?7%j%9%H$K99?7$9$k$K$O!"(BC-u RET $B$G%U%)%k%@$r3+$-D>$9!#(B + unplugged $B>uBV$G$b(B access $B7?%0%k!<%W%U%)%k%@$rMxMQ$G$-$k(B + $B$h$&$K$J$C$?!#(B + +1998-07-24 Masahiro MURATA ($BB + + * wl-auto-select-first $B$r(B non-nil $B$K$9$k$H!$(Bwl-folder-empty-trash + $B$r + + * folder-mode-map $B$G(B "P" $B$r(B wl-folder-prev-unread, "N" $B$r(B + wl-folder-next-unread $B$K$7$?$[$&$,;H$$$d$9$$5$$,$7$F$-$?$N$G(B + $B%G%U%)%k%H$r$=$N$h$&$KJQ99!#(B + * [elmo] elmo-localdir $B$G!"(Boverview $B@8@.;~$N%U%!%$%k$+$i$N%G!<%?(B + $BFI$_9~$_NL$r:o8:!#%a%b%j;HMQNL$,8:$C$?(B($B$O$:(B)$B!#(B + +1998-07-23 Yuuichi Teranishi + + * v0.3.6 - "Never Surrender" + +1998-07-23 Masahiro MURATA ($BB + + * wl-folder.el $B$G!"(Bget-buffer-{window|buffer} $B$,<:GT$7$?$H$-$K(B + $B8mF0:n$9$k$N$r=$@5!#(B + +1998-07-22 Yuuichi Teranishi + + * $B?75,JQ?t(B wl-summary-buffer-mime-charset, wl-folder-mime-charset-alist + $B$r@_CV!"(BSummary $B$N@8@.!"K\J8$N%G%3!<%I$GMxMQ$9$k$h$&$K$7$?!#(B + * MIME-Version $B$,$J$$$H$-$b@8(B JIS $B%5%V%8%'%/%H$r%G%3!<%I$7$FI=<(!#(B + ($B1|@>$5$s(B $B$h$j8f;XE&(B) + * wl-draft-normal-send-func $B$G!"(BDate field $B$rA^F~$9$k$h$&$K$7$?!#(B + * wl-mail-do-fcc-insert-date-header -> wl-draft-insert-date-field + $BL>A0JQ99$HF1;~$K!"(Btimezone.el $B$r;H$&$h$&$K$7$?!#(B + * wl-summary-auto-select-next $B$,(B non-nil $B$N$H$-$NF0:n$,(B IMAP4 + $B%U%)%k%@$G$*$+$7$/$J$C$F$7$^$&$N$r=$@5!#(B + * IMAP4 $B$b%*!<%W%s$9$k$H!$(BEmacs $B$N=*N;;~$K3NG'$r9T$&$N$GL5;k$9$k$h(B + $B$&$K$7$?!#(B + +1998-07-22 Masahiro MURATA ($BB + + * $BL$FI%U%)%k%@!<4V$r0\F0$9$k(B wl-folder-(prev|next)-unread $B$r?75,(B + $B:n@.$7$?!#(B + * $BJQ?t(B `wl-auto-select-first' $B$,(B non-nil $B$J$i!$%U%)%k%@$K0\F08e(B + $B:G=i$NL$FI%a%C%;!<%8$rB(I=<($9$k$h$&$K$7$?!#(B + * $BJQ?t(B `wl-auto-select-next' $B$,(B non-nil $B$J$i!$:G8e$N%a%C%;!<%8$r(B + $BFI$_=*$($?8e$K + + * [elmo] imap4 $B$NK\J88!:w$GF|K\8l$r%-!<$H$7$FM?$($i$l$k$h$&$K$7$?!#(B + +1998-07-21 TSUMURA Tomoaki + + * wl-folder-empty-trash $B$G%U%)%k%@%G!<%?$r6u$K%;%C%H$9$k$H$-$N(B + $B%P%0$rD>$9!#(B + +1998-07-21 Yuuichi Teranishi + + * v0.3.5 - "Miss Me Blind" + +1998-07-21 Masahiro MURATA ($BB + + * WL-ELS $B$G(B ./WL.hack $B$r$A$c$s$H(B load $B$9$k$h$&(B "." $B$r(B load-path $B$K(B + $BDI2C$9$k9T$r0\F0!#(B + +1998-07-17 Yuuichi Teranishi + + * Folder $B$K$b(B unread $B?t$rI=<($9$k$h$&$K$7$?!#$$$/$D$+$N4XO"4X?t$b(B + $BJQ99!#(B($BB $B$5$s$N8f=u8@$K4p$E$/JQ99(B) + * Summary $B$N(B modeline $B$K(B new $B$H(B unread $B$N?t$rI=<($9$k$h$&$K$7$?!#(B + $B%P%C%U%!%m!<%+%kJQ?t!"(Bwl-summary-buffer-unread-count, + wl-summary-buffer-new-count $B$G4IM}!#(B + ($BB $B$5$s$N8f=u8@$K4p$E$/JQ99(B) + * $BL$FI%a!<%k$r(B1$BDLFI$`EY$K(B mark $B%U%!%$%k$r(BHDD$B$K=q$-9~$^$:!"(B + $B%U%)%k%@!<$r0\F0!&H4$1$k;~$K0l5$$K=q$-=P$9$h$&$K$7$?!#(B + ($BB $B$5$s$N8f=u8@$K4p$E$/JQ99(B) + * mark $B%U%!%$%k$K$?$^$K(B (("" nil)) $B$,;D$k%P%0$r=$@5(B + $B$7$?(B($B$D$b$j(B)$B!#(B($BB $B$5$s$h$j8f;XE&(B) + +1998-07-16 Yuuichi Teranishi + + * Semi-vm $B$Ne$N(B `[ON]' $B$,A}2C$7$F$7$^$&%P%0$r=$@5!#(B + ($B1|@>$5$s(B $B$h$j8f;XE&(B) + +1998-07-15 Yuuichi Teranishi + + * v0.3.4 - "La Bamba" wl release. + +1998-07-15 OKUNISHI Fujikazu + + * $BM>7W$J%W%m%Q%F%#$rbuffer-substring-no-properties $B$KCV49!#(B + * wl-summary-redisplay() $B$,I,$:$7$bI,MW$G$J$/!"(B + wl-summary-set-message-buffer-or-redisplay() $B$G:Q$`$H$3$m$OCV49!#(B + +1998-07-14 Yuuichi Teranishi + + * mh $B7A<0$N(B alias file $B$,(B wl-alias-file $B$K@_Dj$5$l$F$$$?$i!"(B + completion $B$G;H$($k$h$&$K$7$?(B($B$D$b$j(B)$B!#(B + * modeline $B$N(B toggle-status $B$r(B mode-line-buffer-identification $B$N(B + $BA0$K=q$/$3$H$K$7$F$_$?!#(B + * wl-draft-insert-message $B$G(B mail-citation-hook $B$H(B mail-yank-hooks $B$r(B + nil $B$K94B+$9$k$N$rK:$l$F$?!#(B + ($B1|@>$5$s(B $B$h$j8f;XE&(B) + * Mule2.3@19.28 $B$K$O(B display-error $B$,$J$$$h$&$J$N$G!"(B + $B$=$l$C$]$$4X?t$r<+A0$GMQ0U$7$?!#(B + ($B1|@>$5$s(B $B$h$j8f;XE&(B) + * wl-summary-redisplay-all-header, wl-summary-redisplay-no-mime $B$G$b(B + $BL$FI%^!<%/=hM}$9$k$h$&$K$7$?!#(B + +1998-07-14 Masahiro MURATA ($BB + + * $B?75,4X?t(B wl-folder-goto-folder, wl-folder-suspend$B!#(B + +1998-07-14 Yuuichi Teranishi + + * wl-mmelmo-message-redisplay: $B$9$G$K(B cache $B$5$l$F$$$k$K$b$+$+$o$i$:(B + $BA4ItFI$`$+$I$&$+$9!#(B + * [elmo] message/partial $B$b%-%c%C%7%e4IM}$G$-$k$h$&$K$7$?!#(B + * [elmo] read-msg $B$NJV$jCM$r(B (content-type . message) $B$H$7$?!#(B + * wl-draft.el: (insert-body) -> (insert body) + +1998-07-13 Yuuichi Teranishi + + * v0.3.3 - "Karma Chameleon" wl release. + +1998-07-13 OKUNISHI Fujikazu + + * $B?75,4X?t(B wl-summary-jump-to-parent-message$B!#(B + +1998-07-13 Yuuichi Teranishi + + * $BL$FI$,$J$$$H$-$O(B update $B;~$K:G8e$N%a%C%;!<%8$K0\F0!#(B + ($BB $B$5$s$N8f;XE&$K4p$E$/JQ99(B) + * elmo-nntp-send-mode-reader $B$G(B response $B$rFI$`$h$&$K$7$?!#(B + +1998-07-12 Masahiro MURATA ($BB + + * $B=i$a$F0\F0$9$k(B folder $B$K0\$k$H!$(Bsummary $B%b!<%I$G(B2$B$DL\$N%a%C%;!<%8$K(B + $B%+!<%=%k$,0\F0$9$kIT6q9g$r=$@5!#(B + * NNTP $B$G:G=i$K(B "mode reader" $B%3%^%s%I$rAw?.$9$k!#(B + * from $B$K0[>o(B(?)$B$JJ8;z$,4^$^$l$F$$$k$H!$(Bwl-substring $BFb$N(B sref $B$G%(%i!<(B + $B$,=P$k$N$rL5;k!#(B + * wl-auto-check-folder-pre-hook $B$rDI2C!#(B + * wl-interactive-exit $B$,(B nil $B$J$i=*N;;~$K3NG'$r + + * News $B5-;v$N%-%c%s%;%k5-;v$r=P$9;~$K(B wl-draft-raw-send $B$r8F$V$h$&$K(B + $B$7$?!#(B + * $B?75,4X?t(B wl-draft-raw-send$B!#(B + * $B?75,4X?t(B wl-mime-request-patrial-message$B!#(B + * WL-ELS, install.el $B$,%$%s%9%H!<%k$5$l$F$$$l$P!"(B + $B<+F0E*$K(B ELISPDIR $B$r8!=P$G$-$k$h$&$K$9$k!#(B + * wl-summary-reedit, wl-draft-open-file $B$N$H$-$O!"(B + edit-again $B$r;H$&$h$&$K$7$?!#(B + * wl-draft-send $B$GAw?.;~$OJL%P%C%U%!$r;H$&$h$&$K$7$?!#(B + ($B $B$5$s$N8f=u8@$K4p$E$/JQ99(B) + * semi-wl.el -> wl-mime.el + ($B $B$5$s$N8f=u8@$K4p$E$/JQ99(B) + * $BJQ?t(B wl-init-file $B$rDI2C!#(Bwl-init $B$G(B load-file $B$9$k!#(B + +1998-07-11 OKUNISHI - PatchMan II - Fujikazu + + * $B5/F0$7$F(B Summary mode $B$K0\9T$;$:!"(BGroup mode $B$+$i$$$-$J$j(B "w" $B$9$k(B + $B;~>l9g$K(B tm-wl.el $B$G4X?t$NL$Dj5A%(%i!<$,=P$kIT6q9g$KBP=h!#(B + * bbdb $B$,FI$^$l$F$$$k$K$b4X$o$i$:!"0l2sL\$N(B compose $B;~$K(B M-[TAB] $B$,(B + $B!J(Btext-mode $B$N!K(Bispell-complete-word() $B$N$^$^!"$H$$$&Ff$N8=>]$KBP=h!#(B + * $B4X?t(B wl-summary-pipe-message $B$rDI2C!#(B + +1998-07-10 Yuuichi Teranishi + + * User-Agent $B%U%#!<%k%I$r@8@.$9$k4X?t!"(Bwl-generate-user-agent-string$B!#(B + * draft-send $BCf$N(B error, quit $B$r(B resume $B$9$k$h$&$K$7$F$_$?!#(B + +1998-07-09 Yuuichi Teranishi + + * wl-folder-{next|prev}-unsync $B$N(B regexp $B$r=$@5!#(B + * Flim-Chao $B$K9g$o$;!"(Bmmelmo $B$N=q$-49$(!#(B + mmelmo $B$r(B mmelmo $B$H(B mmelmo-imap4 $B$KJ,3d!#(B + mmelmo $B$H(B mmelmo-imap4 $B$N(B dispatch $B$O(B FLIM $BB&$KG$$;$k$h$&$K$7$?!#(B + +1998-07-07 Yuuichi Teranishi + + * v0.3.2 - "Jump" wl release. + +1998-07-06 Yuuichi Teranishi + + * wl-draft-send $B$r=$@5!#%(%i!<$r8!CN$G$-$?$H$-$O!"(Bedit-mode $B$KLa$k!#(B + im-wl.el $B$b$=$l$K9g$o$;$F=$@5!#(B + * utils/x-face-wl.el, utils/x-pgp-sig-wl.el deleted. + * elmo-imap4, elmo-nntp $B$b(B coding-system $B4X78$N94B+$r(B + as-binary-* $B$r;H$&$h$&$K$7$?!#(B + +1998-07-06 OKUNISHI Fujikazu + + * coding-system $B4X78$N94B+$r(B as-binary-* $B$r;H$&$h$&$K$9$k!#(B + +1998-07-05 OKUNISHI Fujikazu + + * New im-wl.el + +1998-07-05 Yuuichi Teranishi + + * util/bbdb-wl.el + * wl-summary-update $B8e(B folder$B%b!<%I$NA4%a%C%;!<%8?tI=<($,4V0c$C$F(B + $B$$$?$N$rD>$9!#(B + * wl-message-back-to-summary-hook -> wl-message-exit-hook + * wl-message-back-to-summary -> wl-message-exit + * wl-summary-toggle-disp-off-hook $BDI2C(B + * wl-summary-exit-hook $BDI2C(B + * wl-summary-goto-folder-mode -> wl-summary-exit + * wl-folder-{next|prev}-unsync $B$N(B regexp $B$r=$@5!#(B + * wl-auto-check-folder-name $BDI2C(B + * wl-plugged $B$+$I$&$+$r(B Folder $B%b!<%I$H(B Summary $B%b!<%I$N(B + modeline $B$KI=<(!#(B + * wl-summary-next, wl-summary-prev, wl-summary-cursor-up, + wl-summary-cursor-down $B$O(B unplugged $B$N;~$K$OFI$a$J$$%a%C%;!<%8$r(B + $B$H$P$9$h$&$K$9$k!#(B + * wl-draft-kill $B$G$?$^$K%(%i!<$,=P$k%P%0$r=$@5!#(B + * [elmo] imap4, nntp $B$O(B plugged $B$G$J$1$l$P%(%i!<$H$9$k!#(B + * $B4X?t(B wl-toggle-plugged $B$r $B$5$s$N8f;XE&$K4p$E$/JQ99(B) + +1998-07-04 OKUNISHI Fujikazu + + * x-face-wl.el, x-pgp-sig-wl.el $B$O(B coding-system $B$r94B+$7$J$/$F$h$$!#(B + +1998-07-03 Yuuichi Teranishi + + * Folder $B$N3+JD$r(B delete-region $B$G$d$k$h$&JQ99$7$?!#(B + +1998-07-02 Yuuichi Teranishi + + * v0.3.1 - "Invisible Touch" wl release. + * [elmo] imap4 $B$G(B overview $B $B$5$s$N8f;XE&$K4p$E$/=$@5(B) + * wl-draft-send-with-smtp $B$G(B user-mail-address $B$,@_Dj$5$l$F$$$J(B + $B$1$l$P!"(Bwl-from $B$+$i%a!<%k%"%I%l%9$r $B$5$s$N8f;XE&$K4p$E$/JQ99(B) + +1998-07-01 Yuuichi Teranishi + + * v0.3.0 - "Human Nature" wl release. + * mmelmo backend $B$Nl9g$O(B 1.8.2 $B0J9_$G$J$$$HF0$+$J$$!#(B + * wl-mmelmo-display-message $B$re$N%Q!<%H$r!" mmelmo.el + * (wl-message-mail-p) $B$+(B (wl-message-news-p) $B$N;~$N$_(B wl-draft-send + $B$9$k!#(B + +1998-06-28 Yuuichi Teranishi + + * v0.2.2 - "Girls Just Want To Have Fun" wl release. + * imap4, localdir $B$N%"%$%3%s$N3($rJQ99(B(XEmacs)$B!#(B + * Folder $B0lMw$NI=<($r!"!XL$F14|%a%C%;!<%8?t(B/$BA4%a%C%;!<%8?t!Y$K$7$?!#(B + * [elmo] elmo-localdir-search $B$r + + * WL-ELS $B$r(B Makefile $B$+$i8F$V$h$&$K$9$k!#(B + * WL-ELS $B$K(B install $B$H(B uninstall $B$rDI2C$7$F$_$?!#(B + +1998-06-26 OKUNISHI Fujikazu + + * byte-compile $B$r9bB.$K9T$&$?$a$N(B WL-ELS$B!#(B + * $B%-%c%C%7%e%U%!%$%k$NFI$_=q$-$r!"(Bfile-coding-system-for-read + $B$G$O$J$/(B {in|out}put-coding-system $B$G94B+!#(B + * Makefile $B$N(B bytecomp $B$N%3%^%s%I$r(B -batch $B$,:G=i$KMh$k$h$&$KJQ99!#(B + +1998-06-25 Yuuichi Teranishi + + * folder $B$N3+JD$r$9$3$7%9%`!<%9$KI=<($9$k$h$&$K$7$?!#(B + * draft, trash $B%U%)%k%@$K$OFCJL$J%"%$%3%s$r=P$9$h$&$K$7$?(B(XEmacs)$B!#(B + +1998-06-24 Yuuichi Teranishi + + * elmo-imap4-search $B$r + + * v0.2.1 - "Freedom" wl release. + * wl-draft-insert-signature $B$+$i(B signature.el $B$N(B + insert-signature $B$r8F$V(B (XEmacs $B%D!<%k%P!l9g(B + $B$G$b(B mail-send-hook $B$r(B run-hooks $B$9$k$h$&$K$7$?!#(B + ($BDEM88x6G(B $B$5$s$N8f;XE&$K4p$E$/JQ99(B) + * wl-organization $B$,(B non-nil $B$J$i(B Organization $B%U%#!<%k%I$r(B + $BA^F~$9$k$h$&$K$7$?!#(B + ($BDEM88x6G(B $B$5$s$N8f;XE&$K4p$E$/JQ99(B) + * 00README.ja $B$K%a!<%j%s%0%j%9%H$N@bL@$rDI2C!#(B + +1998-06-22 Yuuichi Teranishi + + * v0.2.0 - "Every Breath You Take" wl release. + * [elmo] nntp $B$G$b%5%$%:$rFI$`$h$&$K$9$k!#(B + * $B%W%j%U%'%C%A;~$b(B wl-fetch-confirm-threshold $B$r1[$($k$b$N$O(B + $Bl9g!"(B + $B:G=i$N%Q!<%H$@$1$rI=<($G$-$k$h$&$K$7$F$_$?!#(B + * $BJQ?t(B wl-fetch-confirm-threshold $B$rDI2C!#(B + $B$3$N%P%$%H?t0J>e$N%a%C%;!<%8$K$D$$$F$O!"(B + $BFI$`$+$I$&$+ + + * $B4X?t(B semi-elmo-imap4-read-first-part, + $B%^%k%A%Q!<%H$N:G=i$N%Q!<%H$@$1$N(B raw-buffer $B$r$D$/$k!#(B + * $B4X?t(B semi-elmo-imap4-get-mime-entity, + bodystructure $B$rFI$s$G!"(Bmime-parse-message $B$N=PNOAjEv$r:n$k!#(B + * [elmo] imap4 $B$G%5%$%:$rFI$`$h$&$K$9$k!#(B + * $B%U%!%$%k(B semi-elmo-imap4.el $B$r?75,DI2C!#(B + +1998-06-18 Yuuichi Teranishi + + * v0.1.4 - "Dancing In The Dark" + * $BJQ?t(B wl-strict-diff-folders $B$rDI2C!#(B + $B$3$NJQ?t$K@_Dj$5$l$?(B IMAP4 $B%U%)%k%@$?$A$O(B + $BL$F14|%a%C%;!<%8?t$N%A%'%C%/$r87L)$K$d$k$h$&$K$7$?!#(B + "%inbox" $B$J$I!"IQHK$KJQ99$5$l$k%U%)%k%@8~$1!#(B + * $B%"%/%;%97?%0%k!<%W%U%)%k%@$r:G=i$K3+$$$?$H$-$K!"(B + $BA4%U%)%k%@$NL$FI?t$,=i4|2=$5$l$F$7$^$&%P%0$r2r>C!#(B + * [elmo] IMAP4 $B$G(B read-msg $B$N$?$S$K(B select folder $B$9$k$N$r(B + $B$d$a$?(B(UW v10.224 $B$h$j8E$$(B imapd $B$@$HLdBj$"$k$+$b(B)$B!#(B + * Summary $B$N(B view $B$r(B cache $B$9$k$H$-$K!"$$$A$$$A1JB3E*%^!<%/(B + $B$r%j%8%e!<%`$5$;$k$N$r$d$a$?!#(B + +1998-06-17 Yuuichi Teranishi + + * 00README.ja $B$N$$$/$D$+$N4V0c$$$rD>$9!#(B + ($B;3LnM5;J(B $B$5$s$h$j8f;XE&(B) + +1998-06-16 Yuuichi Teranishi + + * v0.1.3 - "Centerfold" announced in elips, tm-ja. + +1998-06-15 Yuuichi Teranishi + + * Summary $B$N(B resume-mark $B$H(B highlight $B$r0l2s$N(B scan $B$G(B + $B=*$i$;$k$h$&$K$7$?!#(B + +1998-06-14 Yuuichi Teranishi + + * Folder $B%U%!%$%k$K(B "%#mh /" $B$_$?$$$K=q$1$k$h$&$K$9$k!#(B + * $B%"%/%;%97?%0%k!<%W%U%)%k%@$N>l9g!"3+$/$^$GFbMF$r wl-stay-folder-window$B!#(B + +1998-06-12 Yuuichi Teranishi + + * toolbar $B$N(B refine$B!#(B + * folder-mode $B$NF0:n$r=$@5!#(B + * replicate->prefetch$B!#(B + * refile $B$N?dB,$G<+J,$r3X=,$NBP>]$+$i30$9!#(B + * make $B$r$$$C$Q$D$G!#(B + +1998-06-11 Yuuichi Teranishi + + * $BJV;v$r=q$/;~!"(BCc $B$K<+J,$,;22C$7$F$$$k(B ML $B$H<+J,$,4^$^$l$F$7$^$&(B + $B;~$K$O<+J,$O>C$9$h$&$K$9$k(B($B@5$7$$(B?)$B!#(B + * Mail-Followup-To, Mail-Reply-To $B$KBP1~$7$F$_$?!#(B + +1998-06-10 Yuuichi Teranishi + + * wl-summary-insert-summary $B$r8+D>$7!"%9%l%C%I@8@.B.EY$r(B + $B9bB.2=(B($BLs(B 1.5 $BG\(B)$B!#(B + +1998-06-07 Yuuichi Teranishi + + * Summary $B$G(B News $B5-;v$r%-%c%s%;%k$9$k4X?t(B wl-summary-cancel-message + $B$r?7@_!"(B'C' $B$K%P%$%s%I!#(B + * Newsgroups $B$,IU$$$F$$$l$P(B News $B$K$b%]%9%H$9$k$h$&$K$7$?(B($B$D$b$j(B)$B!#(B + * $B$[$+$N(B SEMI MUA $B$N$3$H$r9M$($F(B toolbar $B$rIU$1$k$N$r(B hook $B$G$O$J$/$9!#(B + +1998-06-02 Yuuichi Teranishi + + * [elmo] "/" $B$r4^$`(B Message-ID $B$r%U%!%$%k$K%;!<%V$9$k$N$K<:GT$9(B + $B$k$N$r2sHr!#(B ("_" $B$KCV49$9$k$h$&$K$7$?$,$$$$$N$+!#(B) + * wl-summary-redisplay $B$G!"(Brecenter $B$9$k$h$&$K$7$?!#(B + * wl-summary-cursor-up $B$G!"(Bimportant-mark $B$r(B regexp-quote $B$9$k$N(B + $BK:$l$F$?!#(B + +1998-05-31 Yuuichi Teranishi + + * $BJQ?t(B wl-draft-folder $B$r@_CV!"(BMew $B$HF1$8$h$&$K!"(BDraft $B%b!<%I$G(B + $B%;!<%V$9$k$H(B wl-draft-folder $B$G;XDj$5$l$?%U%)%k%@$K(B + $B?75,%a%C%;!<%8$H$7$FJ]B8$9$k$h$&$K$7$?!#(B + * Summary $B$G(B TAB $B$r2!$9$HA0$KI=<($7$?%a%C%;!<%8$KLa$k$h$&$K$9$k!#(B + * Summary $B$G!"(Bdefault-directory $B$r(B wl-tmp-dir $B$K$9$k!#(B + * wl-draft-open-file $B$rDI2C!#(B + +1998-05-20 Yuuichi Teranishi + + * v0.1.2 - "Beat It" internal release. + * CVS $B$r;H$$$O$8$a$k!#(B + * Summary $B$N(B highlight $B$r(B2$B!A(B3$BG\9bB.2=!#(B + * te@isl.ntt.co.jp $B$N8f0U8+$K$h$j(B Folder $B$G%P%C%AE*$K(B msgdb $B$r(B + Sync $B$9$k(B "S" wl-folder-sync-current-entity $B$rDI2C!#(B + +1998-05-19 Yuuichi Teranishi + + * $B$d$C$FMh$kJV;v$O:G6a$N%a%C%;!<%8$KBP$9$k$b$N$,B?$$$H$$$&(B + $B%9%l%C%IDI2C$N6I=j@-$rMxMQ$7$F$A$g$C$H$@$1%9%l%C%I@8@.$r9bB.2=!#(B + * qmail-inject $B$r%5%]!<%H!#(B + * $BCfESH>C<$K(B miee.el $B$r%5%]!<%H$7$F$$$?$,!"$H$j$"$($:$d$a$F!"(B + default $B$O(B Semi-gnus $B$K$D$$$F$$$?(B smtp.el $B$rMxMQ$9$k$h$&$K$9$k!#(B + +1998-05-18 Yuuichi Teranishi + + * Makefile $B$N(B ELMODIR $B$r(B elmo $B$K$9$k(B (Report by te@isl.ntt.co.jp)$B!#(B + +1998-05-17 Yuuichi Teranishi + + * Tiny toolbars for XEmacsen$B!#(B + * important $B%^!<%/(B "$" $BIU$-$N%a%C%;!<%8$O!"(Bexpire $B$5$l$F$b>C$5$J$$(B. + * Summary $B$G(B "i" $B$r2!$9$H!"(Breplicate-unreplicated-msgs $B$r + + * Copyright $BI=<($r3F%U%!%$%k$K2C$($k!#(B + * [elmo] mule2.3@19.28 $B$N%@%5$$(B string-match $B$G$b$&$4$/$h$&$K(B imap4 $B$G(B + search all $B$N7k2L$r + + * v0.1.1 - "Amanda". internal release. + * 00README.ja, sample.addresses, sample.folders$B!#(B + * wl-vars.el $B$N@0M}!#(B + * $B$O$d$j$K$N$C$F(B X-MimeOLE: $B$r2C$($k$h$&$K$7$F$_$?!#(B + * XEmacs $B$N(B 'dragdrop $B$KBP1~!#(Bwl-dnd.el + +1998-05-08 Yuuichi Teranishi + + * wl-folder.el $B:F5"E*(B folder $B%Q!<%5!#(B + +1998-05-01 Yuuichi Teranishi + + * Wanderlust $B$H$7$F%Q%C%1!<%82=(B (v0.1.0)$B!#JQ99$,B?$9$.$F5-O?$G$-$:!#(B + (wl-draft.el/wl-address.el/wl-highlight.el $B$NDI2C(B, + SEMI/tm $B$N(B API $B$X$NBP1~(B, + mule2.3 $B$GF0$/$h$&$K$9$k(B, $BEy(B) + +1998-04-17 Yuuichi Teranishi + + * nntp $B$G(B $BB8:_$7$J$$%0%k!<%W$N(B max-of-folder $B$,$3$1$k%P%0$H$j!#(B + +1998-04-13 Yuuichi Teranishi + + * create-summary-line $B$G(B From $B$,(B nil $B$N>l9g$KBP=h!#(BDate $B$b!#(B + * folder-quit $B$G(B kill-buffer $B$K0z?tEO$9$NK:$l$F$?!#(B + * nntp $B$GF1$8%0%k!<%W$X$NA`:n$,B3$$$?>l9g$K$3$1$k%P%0$H$j!#(B + * Makefile $B$G(B lp.el $B$N0MB84X78$r=$@5(B (Report by te@isl.ntt.co.jp)$B!#(B + +1998-03-26 Yuuichi Teranishi + + * v0.09 + * Summary $B$NJ8;z2=$1$r2r>C!"$G$b(B mule2.3 $B$G$&$4$+$J$/$J$C$?!#(B + * update $B$7$?$H$-!"8:$C$?%a%C%;!<%8$,%P%C%U%!$+$i>C$($J$$%P%0$r$H$k!#(B + * v0.08 + * IMAP4 $B$KBP1~!#(B + +1998-03-20 Yuuichi Teranishi + + * folder diff $B$r(B integer list $B$NHf3S$K5"Ce$5$;$k$3$H$K$h$j9bB.2=!#(B + +1998-03-19 Yuuichi Teranishi + + * v0.07 + * Mule-2.3 $B$KBP1~!#(B + * update $B$H(B scan-all $B$rE}9g!#(B + * $B$"$H$G8+D>$7$?$$%a%C%;!<%8$K$D$1$k%^!<%/!"(B"$" -- important mark $B$r(B + $B?7@_!#(B + * update $B$,I,MW$+$I$&$+$N%A%'%C%/$r(B list $B$NHf3S$K5"Ce$5$;$F9bB.2=!#(B + * $B%$%s%G%C%/%9$N%-%c%C%7%eMQ$K(B buffer-local-variable $B$r@_$1!"(B + $BF1$8%P%C%U%!$KBP$9$k#22sL\0J9_$N99?7A`:n$r9bB.2=!#(B + * mt $B$G8=:_$N%9%l%C%I$K0l3g(B "*" $B%^!<%/!#(B + * c $B$GA4$F$N%a%C%;!<%8$r0l3g$7$F4{FI$K!#(B + +1998-03-16 Yuuichi Teranishi + + * v0.06 + * $BI=<(I}$r0lDj$K$9$k!#(B + * update $B$r7Z$/$9$k!#(B + * $B%a%C%;!<%8$,8:$C$?$3$H$b(B update$B!#(B + * cache $B%$%s%5!<%H;~$K%^!<%/$r%j%8%e!<%`!#(B + * font-lock $B$N(B regexp $B$rJQ99!#(B + +1998-03-13 Yuuichi Teranishi + + * v0.05 + * $BL$FI%^!<%/!"(B"!"$B!#(B + * update scan$B!#(B + * font-lock$B!#(B + * $BMKF|$N1Q8l(B/$BF|K\8l@ZBX$($r2DG=$K!#(B + * Petname$B!#(B + +1998-03-10 Yuuichi Teranishi + + * v0.04 + * $BMKF|$rF|K\8l$GI=<(!#(B + * $B%U%#!<%k%ICM$N3MF@$K<:GT$7$J$$$h$&$K(B overview $B:n@.;~$N(B + coding-system-for-read $B$r(B 'junet $B$K94B+!#(B + +1998-03-10 Yuuichi Teranishi + + * v0.03 + * $B%$%s%G%C%/%9$N(B elisp $B%*%V%8%'%/%H2=$K$h$j9bB.2=!#(B + * Date $B$r=P$9(B + * $BF1$8%9%l%C%I$G$b!"0c$&(B Subject $B$J$iI=<((B + +1998-03-06 Yuuichi Teranishi + + * v0.02 + * $B%9%l%C%I$N4V0c$$$rD>$9(B + * indent-level $B$r%+%9%?%^%$%:$G$-$k$h$&$K$9$k!#(B + +1998-03-05 Yuuichi Teranishi + + * v0.01 Summary $B$r%9%l%C%II=<($G$-$k$@$1$N%W%m%H%?%$%W!#(B + diff --git a/etc/ChangeLog.2 b/etc/ChangeLog.2 new file mode 100644 index 0000000..b6d749c --- /dev/null +++ b/etc/ChangeLog.2 @@ -0,0 +1,1608 @@ +1999-05-18 Tsunehiko Baba + + * New File: [ChangeLog.en]. + +1999-05-18 A. SAGATA + + * Fix: + mouse-2 does not work in Message buffer. + +1999-05-18 Yuuichi Teranishi + + * 1.0.0 pre2 - "Kokomo-pre2". + * Fix: + region of hilighting varies when the number of unread messages is + decreased. + (pointed out by Toshihiko Koadama + ). + * Change: + C-cC-s in draft and keybind of menubar is set as local-set-key in + each draft bufer. + * Fix: + wl-summary-mark-as-read-all does not work well when target + messages is hidden in close threads. + (pointed out by Hajime Ohsawa ). + +1999-05-18 Masahiro MURATA + + * Fix: + insert mail body into a different position from position specified + by wl-draft-prepared-config-alist in wl-summary-reply-with-citation. + +1999-05-17 Ken'ichi OKADA + + * Change: [bbdb-wl.el]. + corresponding to change from wl-folder-exit-hook to wl-exit-hook. + +1999-05-17 Yuuichi Teranishi + + * pre 1.0.0 - "Kokomo-pre". + * Change: + not use replace-match(). + +1999-05-17 Ken'ichi OKADA + + * Add: [wl-ja.texi] + about POP-before-SMTP. + * Change: + corresponding to POP-before-SMTP. + +1999-05-17 OKUNISHI Fujikazu + + * Change: + add elmo-multi-get-msg-filename(). + * Change: + wl-message-refer-article-or-url() corresponds to "mailto:". + +1999-05-17 Masahiro MURATA + + * Fix: + not change wl-folder-buffer-cur-{path|entity-id}, when + wl-summary-goto-folder is executed at interactive. + * Change: + not expire when, 2nd and 3rd elements of wl-expire-alist is nil. + +1999-05-17 Ken'ichi OKADA + + * Add: [wl-ja.texi] + about AUTHINFO. + +1999-05-17 A.SAGATA + + * Fix: + hilighting at a line pointed by a mouse. + +1999-05-17 Yuuichi Teranishi + + * Change: + remove BETA. + * Fix: + toobar is not available at Folders on XEmacs. + * Fix: + merging partial does not work well when Subjects are written in + Japanese. + * 0.10.3 - "Jumpin' Jack Flash". + +1999-05-16 Yuuichi Teranishi + + * Fix: + not consider WL_PREFIX, ELMO_PREFIX when doing "make uninstall". + * Change: + not use (point-at-bol), (point-at-eol) for Mule2.3. + * Change: + wl-folder-exit-hook -> wl-exit-hook$B!#(B + * Change: + rename wl-folder-exit -> wl-exit$B!#(B + * Change: + update ja.Emacs. + * Add: [wl-ja.texi] + about wl-summary-print-message. + +1999-05-16 Masahiro MURATA + + * Fix: + not delete a message buffer when there are no unread messages, + even if wl-auto-select-first is t. + +1999-05-15 Yuuichi Teranishi + + * Add: [wl-ja.texi] + about highlight$B!"(Binternal Folder. + * Change: + defvars in wl-highlight move into wl-vars, and is set as defcustom. + * Fix: + error happens when selecting nntp Folder in unplugged. + (pointed out by MARUYAMA Yoshio ). + * Fix: + some inconvinience related to Stick Summary happen when + wl-stay-folder-window is t. + * Change: + hilighting a line pointed by a mouse on Summary from begging of + line to end. + * Change: + change an order of initizalization and messages in wl-init. + not check existence of basic Folder with prefix-arg. + * Change: + save view cache when exiting Sticky Summary. + +1999-05-14 OKUNISHI Fujikazu + + * Fix: + not call wl-mail-setup-hook when doing wl-summary-reedit(). + +1999-05-14 Masahiro MURATA + + * Fix: + modificaton of wl-summary-next-folder-or-exit() is not considered + in case that wl-auto-select-first is t. + * Change: + change of move command is enable when wl-summary-next-no-unread is + t. + +1999-05-14 Ken'ichi OKADA + + * Add: [wl-ja.texi] + about wl-draft-write-current-newsgroup. + +1999-05-13 A.SAGATA + + * Change: + hilight mouse-face without useing mode-motion-hook. + * Change: + add wl-version-show. + +1999-05-13 Koichiro Ohba + + * Add: [wl-ja.texi] + about Sticky Summary. + +1999-05-13 Ken'ichi OKADA + + * Fix: + select an unexpected window after doing wl-summary-forward at a + Folder wl-summary-stick does. + +1999-05-13 Masahiro MURATA + + * Change: + do wl-template without using recursive-edit. + +1999-05-13 Yuuichi Teranishi + + * Change: + add 'x-face as a sub function of wl-draft-config-alist. + * Change: [wl-template] + hilight select buffer. + +1999-05-13 Mito + + * Change: + do (wl-summary-toggle-disp-msg 'off) in + wl-summary-next-folder-or-exit() in order to avoid the event that + previous message is displayed when moveing to other folders. + * Fix: + error happens when calling wl-summary-toggle-disp-msg() if its arg + is off. + +1999-05-13 Masahiro MURATA + + * Fix: + error happens when NNTP Folder is updated by + wl-folder-update-recursive-current-entity. + +1999-05-13 Yuuichi Teranishi + + * Fix: + caching does not work in pop3 and imap4, nntp when + elmo-*-use-cache is nil. + (pointed out by Masahiro MURATA ). + +1999-05-12 OKUNISHI -GTO- Fujikazu + + * Fix: + not read messages in localnews. + args of elmo-localnews-local-file-p() is not enough. + +1999-05-12 Yuuichi Teranishi + + * 0.10.2 - "I'm Your Man". + +1999-05-12 A. SAGATA + + * Add: [wl-ja.texi] + about some commands. + +1999-05-12 Koichiro Ohba + + * Add: [sample.dot.wl] + about auto-refile configuration. + * Add: [wl-ja.texi] + about wl-summary-auto-refile-skip-marks. + +1999-05-12 Masahiro MURATA + + * Fix: + checking newsgroups with upper case letters fails. + +1999-05-12 Yuuichi Teranishi + + * Fix: + read message is not cached in localdir. + * New Variables: wl-ps-print-buffer-func. + assign a function in ps-print. + default is 'ps-print-buffer-with-faces. + (requested by Mito ). + * Change: + display an error message if same name exists between group and + petname when analyzing .folders. + +1999-05-11 Masahiro MURATA + + * Change: + update sample.dot.wl. + * Fix: + description about access group and so on. + +1999-05-11 OKUNISHI -GTO- Fujikazu + + * Fix: + when messages targeted for "$" in filter Folder are local files, + they are marked but not cached. + +1999-05-11 Yuuichi Teranishi + + * Change: + implement partial unification functions for tm. + * Fix: + wl-defface does not work on Nemacs. + * Change: + speed up wl-summary-exec. + * Fix: + not assign 'D' on Summary. + * Fix: + when deleting messages in imap4, the case they are not deleted + from msgdb exists in some thread circumstances. + * Change: + do (sit-for 0) in order to display results at once in + wl-folder-check-one-entity. + * Change: + wl-message-redisplay-hook is unwind-protected in order to make + a cursor position a return to Summary when doing C-g at a prompt + like bbdb. + +1999-05-10 Tomokazu Matsumaru + + * Fix: + hang up POP3 Folder with a lot of messages. + +1999-05-10 Yuuichi Teranishi + + * New Variable: wl-folder-sync-range-alist, wl-default-sync-range. + change default of sync in each folder is enable. + (requested by Toshihiro KAMISHIMA ). + * Fix: + "make" command fails on Mule 2.3. + (pointed out by Toshihiko Koadama + ). + * Fix: + display letters in an unexpected code because wl-vars.el is + written by EUC. + (pointed out by Masahiro MURATA ). + * 0.10.1 - "Harlem Shuffle". + +1999-05-09 Yuuichi Teranishi + + * Fix: (maybe) + make current Folder strange when doing C-g while select-folder in + imap4. + (pointed by Mizuhara ). + * New Variable: elmo-archive-use-cache$B!"(Belmo-nntp-use-cache, + elmo-imap4-use-cache$B!"(Belmo-pop3-use-cache. + determine each read message to cache or not + * Change: + do away with wl-no-cache-folder-list. + * Change: + cache is enable at once after marking as important-mark. + +1999-05-08 Koichiro Ohba + + * Change: [wl-ja.texi] + typo and so on. + +1999-05-08 OKUNISHI Fujikazu + + * Change: [wl-ja.texi] + typo and so on. + +1999-05-05 OKUNISHI Fujikazu + + * Fix: + a cursor does not return to Summary from message buffer after + wl-message-prev-page() in the case that ^L is used for starting a + new page. + * Change: + do rename-file() for *.elc files when doing "make install". + * Change: + because mode-motion-hook is particular for XEmacs, delete error + messages when it is byte-compiled on GNU Emacs. + +1999-05-05 OKUNISHI -GTO- Fujikazu + + * Fix: + errors happens in wl-summary-refile-region, + wl-summary-copy-region, wl-thread-refile, wl-thread-copy. + +1999-05-05 Masahiro MURATA + + * Fix: [elmo-{nntp|imap4|pop3}.el] + case-fold-search is not enable in target buffer. + +1999-05-04 Masahiro MURATA + + * Fix: + variables of wl-draft-config-alist are not enable when + wl-draft-send is aborted once and retried. + +1999-05-01 OKAZAKI Tetsurou + + * Change: + in NNTP Folder enable to read newsgroup having top categories + whose initials are numeral. + +1999-04-30 Masahiro MURATA + + * New Function: wl-defface. + define face as portable. + +1999-04-30 Yuuichi Teranishi + + * Fix: + duplicate a name part of folder when re-editing drafts on edit + from Summary. + (pointed out by OKAZAKI Tetsurou ). + * Fix: + asking where to jump when doing s->rescan in empty Folder occurs. + (pointed out by OKAZAKI Tetsurou ). + * Change: [bbdb-wl] + add (require 'wl). + * Fix: + asking where to jump when doing wl-thread-open-close at a message + with no children and no parents of threads. + * New Commands: wl-summary-drop-unsync, + wl-folder-drop-unsync-current-entity. + make all not synchronous messages no existence. + assing as 'D'. + +1999-04-28 Masahiro MURATA + + * New Variable: wl-draft-prepared-config-alist. + extend some functions in wl-draft-config-alist. + * New File: [wl-template]. + new feature to select or insert template on draft buffer. + +1999-04-28 Yuuichi Teranishi + + * Change: + use wl-draft-mode-map except excepting Nemacs. + (advised by Masahiro MURATA ) + +1999-04-13 Masahiro MURATA + + * Fix: + case-fold-search on Summery buffer is always treated as nil. + * Fix: + return value when elmo-nntp-open-connection fails is different + from it written in docstring. + +1999-04-28 Mito + + * Fix: + mail send command fails when wl-draft-buffer-cur-summary-buffer is + #. + +1999-04-27 Mito + + * Change: + execute confirmation when printing out by '#' on Summary. + +1999-04-27 Ken'ichi OKADA + + * Fix: + wl-summary-refile-region works wrong. + +1999-04-27 Yuuichi Teranishi + + * Fix: + not work on Nemacs. + * Fix: + problems happen when custom does not exist. + * Fix: + merge forgotten patches (including modification for POP3 hang-up + problem). + (pointed out by A.SAGATA ). + * 0.10.0 - "Got My Mind Set On You". + * Fix: + localnews is not treated as local in wl-summary-local-p. + (reported by Kentaro Toda ) + +1999-04-26 Yuuichi Teranishi + + * Change: + implement each backend function of elmo-internal.el. + * Fix: + modify (get-buffer wl-summary-buffer-name) all over for + correspondence to Sticky Summary. + * New command: wl-summary-stick. + change present summary to be sticky. + assign it as \M-s. + +1999-04-23 Yuuichi Teranishi + + * Change: + rewrite partial unification functions for SEMI. + * Change: [bbdb-wl]. + corresponding to Sticky Summary. + * Fix: + wl-default-draft-cite works wrong. + (set a wrong citation title when a cursor on Summary get out of + position.) + +1999-04-23 A. SAGATA + + * Fix: + jump to right message-id by clicking center of left message-id + when body has two message-id at one line. + +1999-04-23 Ken'ichi OKADA + + * Fix: + error happens if it is empty when doing wl-thread-{copy,refile} at + end of line on wl-summary mode. + +1999-04-22 Yuuichi Teranishi + + * Change: + moves to Sticky Summary when moving to Folder with prefix arg. + (former "wl-folder-goto-folder$B!"(Bwl-summary-goto-folder" changes to + wl-folder-goto-folder-subr$B!"(Bwl-summary-goto-folder-subr + respectively.) + * Change: + not re-highlight on draft-buffer by "^L" when + wl-highlight-body-too is nil. + (modified by A.SAGATA ). + * Change: + Sticky Summary. + (requested by Mito ). + * Change: + mmelmo-imap4 succeeds to mmelmo. + +1999-04-21 A. SAGATA + + * Fix: + some bugs in wl-folder-close-parent-entity. + * Change: + extend functions of wl-thread-open-close in order to close its + parents when having no children. + * Change: + wl-folder-close-parent-entity -> wl-folder-open-close. + * Change: + assign wl-folder-open-close as "/". + +1999-04-21 Mito + + * Change: + expand nested aliases. + +1999-04-21 Yuuichi Teranishi + + * Fix: + not set cursor at a first message in wl-summary-goto-folder when + wl-summary-move-order is 'new and the message is marked as "$" and + no marks excepting "$" exists in Folder. + * Fix: + doing wl-summary-cursor-down twice(!) in wl-summary-goto-folder. + +1999-04-21 Kazuyuki IENAGA + + * corresponding to custom. + +1999-04-21 Masahiro MURATA + + * Fix: + not enable to get get information of folders with host name in the + case that server append extra messages to response against group + commands, ex. leafnode. + +1999-04-20 Yuuichi Teranishi + + * New File: [elmo-internal.el]. + Folder for browsing internal data. + +1999-04-19 A. SAGATA + + * New Variable: wl-draft-highlight-and-recenter. + recenter after hilighting by C-l on draft. + * Fix: [elmo-nntp.el]. + args of elmo-nntp-search are wrong. + +1999-04-19 Takaaki MORIYAMA + + * Change: + enable to specify port number in folder definition of nntp. + +1999-04-19 Yuuichi Teranishi + + * Change: + delete keybind \M-O (wl-summary-copy-prev-destination) to avoid + the problems as to a cursor on vt-100. + (pointed out by SUGANO KEI , + advised by A.SAGATA ). + * Fix: + each message number is always set as 0 when the number of messages + is beyond 6 digits. + (pointed out by A.SAGATA ). + +1999-04-19 Ken'ichi OKADA + + * Fix: + not display additional messages on offline when visiting + destination Folder after doing offline refile/copy. + * Change: + execute processing of unread messages on offline. + +1999-04-19 A. SAGATA + + * Change: + delete keybind \M-O in Summary. + +1999-04-17 Koichiro Ohba + + * Add: [wl-ja.texi]. + about wl-summary-auto-refile. + * Add: [wl-ja.texi]. + about wl-summary-auto-refile. + * Change: [sample.dot.wl]. + disable to add Mail-Followup-To and Mail-Reply-To by itself. + +1999-04-14 Yuuichi Teranishi + + * Change: + changes mode of draft buffer to wl-draft-mode that mail-mode + derived. + (advised by Shuhei KOBAYASHI ) + * New Variable: [WL-ELS] WL_PREFIX$B!"(BELMO_PREFIX. + install wl and elmo modules using each values as relative + directory from ELISPDIR. + default is "". + (advised by Shuhei KOBAYASHI ). + * Fix: + when *.elc files compiled by other meacs exists, "make clean" does + not work on other emacs because of loading WL-ELS. + * Fix: + POP hangs up when multiple messages exist. + (reported by Ishikawa Ichiro ). + +1999-04-13 OKAZAKI Tetsurou + + * Fix: [elmo-nntp.el]. + about typo in docstring. + +1999-04-12 A. SAGATA + + * Fix: + all bodies change to signature-face when re-edting by "E" summary + buffer. + * Change: + hilight at a line pointed by mouse in summary mode and folder mode + on XEmacs only. + +1999-04-12 Yuuichi Teranishi + + * Fix: + when on draft a line begins from TAB and the next field is empty + bug to delete the line happens. + (pointed put by A.SAGATA ). + * Fix: + buffer displaying in wrong code remains when doing C-g at once + after typing 'q' on Summary. + (pointed out by Abe ). + * Fix: + pick up Japanese Subject fails on XEmacs. + (pointed out by A.SAGATA ). + * Add: [ChangeLog]. + forget to add a modification against the problem + elmo-nntp-get-folders-info hangs up on 4/2. + (pointed out by Nakagawa Makoto ). + * 0.9.8 - "Faith". + +1999-04-10 Yuuichi Teranishi + + * New Variable: elmo-msgid-replace-string-alist. + define rules of conversion from message-id to cache file name. + +1999-04-09 Yuuichi Teranishi + + * Fix: [elmo-imap4.el]. + LOGIN certification fails when password includes brank space. + (reported by Tadashi KUMANO ). + +1999-04-07 Ken'ichi OKADA + + * Change: + [NNTP] corresponding to AUTHINFO. + +1999-04-07 Yuuichi Teranishi + + * Change: + re-load by C-u even if caches exist. + * Change: + enable to start up by C-g even if network is not connected when + initializing. + +1999-04-06 SHIMADA Mitsunobu + + * Fix: + the bugs to fail to delete or refile mails in Maildir occur. + +1999-04-03 OKAZAKI Tetsurou + + * Fix: [wl-ja.texi]. + description about default value of + wl-insert-mail-(followup|reply)-to is wrong. + +1999-04-02 Masahiro MURATA + + * New Variable: elmo-nntp-get-folders-securely. + when non-nil, modification to avoid elmo-nntp-get-folders-info not + returing is enable. + default is nil. + +1999-04-02 Nakagawa Makoto + + * Fix: + the bug that elmo-nntp-get-folders-info does not return and hangs + up occurs on cnews(?). + +1999-03-31 Yuuichi Teranishi + + * Change: + change petname-alist to obarray. + * New Variable: wl-summary-divide-thread-when-subject-changed. + makes thread when subject changes if it is t. + (requested by akira yamada ). + * New Variable: wl-summary-subject-filter-func. + assign a function to process before comparison with subjects. + * Change: + not funcall wl-summary-from-func and wl-summary-subject-func, + wl-summary-subject-filter-func and fset them at startup. + * Change: + change wl-draft-config-exec-flag to buffer local variable. + * Fix: + error happens by M->j->q on Summary. + (pointed out by Ken'ichi OKADA ). + * Change: + default of face for signature is set as colorful fonts. + +1999-03-30 Ken'ichi OKADA + + * Change: + disable to do 'd' at an empty line. + * Fix: + if there are multiple articles with target message-id in same + folder, elmo-imap4-delete-msg-by-id fails when doing + elmo-dop-queue-flush after deleting one of messages. + +1999-03-29 A. SAGATA + + * Change: + detect signature region wiser. + * Change: + hilight signature. + +1999-03-26 Yuuichi Teranishi + + * Fix: + summary is wrongly displayed when doing goto-folder to present + (same) folder. + (pointed out by OKUNISHI Fujikazu ). + * New Variable: wl-draft-clone-local-variable-regexp. + default is "^mime". + copy values of local variables matching its value to sending + buffer. + +1999-03-26 Ken'ichi OKADA + + * New Command: wl-summary-write-current-newsgroup. + do completiton of Newsgroup: field and prepare draft buffer when + posting messages to the current-folder newsgroup in Summary + mode. + assign 'W'. + +1999-03-25 Hidekazu NAKAMURA + + * Fix: + not call wl-mail-setup-hook in wl-summary-forward(). + +1999-03-25 Yuuichi Teranishi + + * Fix: + merge MURATA's patch that lambda expression is available in + wl-draft-config-alist. + +1999-03-25 Masahiro MURATA + + * Fix: + not decode file created by only one message in + wl-summary-temp-mark-uudecode. + +1999-03-24 Yuuichi Teranishi + + * Fix: + not send messages when default-case-fold-search is nil. + (pointed out by Kenji Kuzuhara ). + +1999-03-24 Ken'ichi OKADA + + * New Command: wl-folder-close-parent-entity. + assign M-SPC. + * New Variable: wl-draft-config-exec-flag. + execute wl-draft-config-exec only once. + +1999-03-21 Yuuichi Teranishi + + * Fix: [im-wl.el] (again). + message-id is wrongly added when wl-insert-message-id is nil. + (pointed out by Ishikawa Ichiro ). + * Fix: (again) + warning messages appear on xemacs with (featurep 'xpm) and -nw + option when startup. + (pointed out by A.SAGATA ). + +1999-03-18 A.SAGATA + + * Add: [wl-ja.texi]. + about completion. + * Change: + when doing completion of headers like "To:" or "Cc:" in draft + completion from lower case letters is enable. + +1999-03-18 Yuuichi Teranishi + + * 0.9.7 - "Everything She Wants". + * Fix: + abort creating msgdb when there are some messages with strange + date in multi Folder. + +1999-03-17 A.SAGATA + + * Add: + a function to edit petname interactively. + +1999-03-17 Yuuichi Teranishi + + * Fix: + can do nothing in present folder when aborting to refile messages + to non-existent IMAP folder. + (pointed out by Abe ). + * Change: + dot distinguish between groups and normal Folders in + wl-folder-next-unsync. + * Fix: + messages is incomplete when doing syncing by toolbar button on + XEmacs. + +1999-03-12 Tsunehiko Baba + + * Fix: [00README]. + +1999-03-12 Masato Taruishi + + * Add: [00README]. + +1999-03-12 Yuuichi Teranishi + + * Change: + if a partial failure occurs in refile or copy, it does not affect + the whole action. + * Change: [wl-ja.texi]. + change construction of each section to be obvious in using pTeX. + (pointed out by Morifuji ) + +1999-03-09 Yuuichi Teranishi + + * Change: + fix confusing problem that cursor moving to end of buffer while + doing refile. + +1999-03-06 Ishikawa Ichiro + + * Fix: [im-wl.el]. + message-id is wrongly added when wl-insert-message-id is nil. + +1999-03-04 Yuuichi Teranishi + + * Change: [tm-wl.el]. + not use (fset 'mime-preview/x-face-function-use-highlight-headers + nil) in tm-wl-setup. + (pointed out by A.SAGATA ). + * New Command: wl-summary-refile-prev-destination. + assign 'M-o'. + (requested by A.SAGATA ). + * New Command: wl-summary-copy-prev-destination. + assign 'M-O'. + +1999-03-05 A.SAGATA + + * Fix: + '\n' is wrongly inserted into User-Agent: when using tm. + * Change: + corresponding to subject like [???, 0000]. + +1999-03-04 A.SAGATA + + * Fix: + warning messages appear on xemacs with (featurep 'xpm) and -nw + option when startup. + * New Variable: wl-auto-insert-x-face. + default is t. + * Change: + when wl-auto-insert-x-face is t and ~/.xface exists it is + automatically inserted. (as usual, default) + * Change: + insertion of X-Face: by wl-draft-insert-x-face-field is enable + when making draft. + * Change: + error messages are displayed if ~/.xface does not exist when doing + C-c C-a. + +1999-03-03 A.SAGATA + + * New Hook: hook wl-summary-refile-hook. + +1999-03-03 Hajime MORITO + + * Change: [wl-ja.texi]. + remove errors in using ptex. + * Fix: [wl-ja.texi]. + not display '{','}'. + +1999-03-03 Yuuichi Teranishi + + * 0.9.6 - "Dirty Diana". + * Change: + [elmo] avoid the problem that expiring cache is disable when there + is a strange cache file. + * New Variable: wl-summary-auto-refile-skip-marks. + unread messages is not target of auto-refile. + (requested by Koichiro Ohba ). + * Fix: + set extra(!) unread flag when displaying messages in imap4 + * Change: [wl-ja.texi]. + delete about wl-summary-wday-use-japanese. + add about wl-summary-weekday-name-lang. + (pointed out by Kunihiro Ishiguro ). + * Add: [wl-ja.texi]. + about wl-summary-fix-timezone. + (pointed out by Iba ). + +1999-03-01 Hermit-chan + + * Fix: + errors happen if M-x wl-draft is done before M-x wl when + wl-draft-folder is configured. + +1999-03-01 Akihiro Motoki + + * Fix: [wl-highlight.el, ChangeLog]. + typo. + +1999-03-01 Yuuichi Teranishi + + * Fix: + not distinguish between all events excepting XEmacs key in + wl-ask-folder. + +1999-02-28 Masahiro MURATA + + * Change: + extend expression of wl-draft-config-alist. + +1999-02-26 TSUMURA Tomoaki + + * Change: [wl-refile.el]. + do downcase in getting extra-field. + * Change: [wl-refile.el]. + delete unnecessary variables. + +1999-02-26 OKAZAKI Tetsurou + + * Fix: + menues of Summary + +1999-02-25 OKUNISHI Fujikazu + + * Fix: + fail to check unread messages in filter Folder. + +1999-02-10 OKUNISHI Fujikazu + + * Change: + avoid font-lock being enable in draft. + +1999-02-24 Yuuichi Teranishi + + * 0.9.5 - "California Girls". + +1999-02-25 Masahiro MURATA + + * Change: + not display minus number and do synchronization when + wl-folder-notify-deleted is 'sync. + +1999-02-24 Yuuichi Teranishi + + * New Variable: wl-folder-notify-deleted. + display minus number when messages are deleted. + default is nil. + * Change: + execute wl-summary-auto-refile by default in closing threads. + execute it in opening all threads if with Prefix argument. + * New Variable: wl-x-face-file. + default is "~/.xface". + +1999-02-16 Ken'ichi OKADA + + * New Variables: elmo-passwd-alist-{load,save}. + load/save password from/to file configured by new variable + elmo-passwd-alist-file-name. + +1999-02-11 Tsunehiko Baba + + * Add: [wl-ja.texi]. + about "~/.xface". + +1999-02-06 TSUMURA Tomoaki + + * Change: + concatinate "\n" firstly before insert header by + wl-draft-replace-field. + +1999-02-06 Ken'ichi OKADA + + * Change: + in imap unread information is reported to destination of copy. + +1999-02-05 Yuuichi Teranishi + + * New Variable: wl-highlight-refile-destination-face. + face for destination of refile. + * Fix: [wl-ja.texi]. + about '$'. + (advised by GOTO ) + +1999-02-04 Yuuichi Teranishi + + * Fix: + hilighting is wrong after checking unread messages in folders on + XEmacs. + +1999-02-03 Ken'ichi OKADA + + * New Variable: wl-folder-prefetch-entity. + assign 'I'. + +1999-02-03 Teruki SHIGITANI + + * Change: [sample.dot.wl]. + function to refer folder name in my-wl-summary-from-func-petname + is called in summary-mode only. + +1999-02-03 TSUMURA Tomoaki + + * New Functions: wl-summary-auto-refile, wl-refile-rule-alist. + +1999-02-02 IMAI Takeshi + + * Fix: + errors happen when doing refile to imap folder in wl-expire. + +1999-01-29 Akihiro Motoki + + * Change: + do widen when views in Summary mode is saved into cache. + +1999-01-22 Masahiro MURATA + + * Change: + extend wl-auto-check-folder-name. + +1999-01-19 Masahiro MURATA + + * Change: + update summary information before doing expire in folder mode. + * Fix: + errors happen because of omission of reserve-marked-msg when no + messages to expire exist. + * Change: + give consideration to year change in elmo-datevec-substitute. + +1999-01-19 Yuuichi Teranishi + + * New Variables: wl-auto-uncheck-folder-list, + wl-auto-check-folder-list. + skip checking group when startup. + checking archive folders is skipped by default. + (requested by Akihiro Motoki ). + * Fix: [elmo-nntp.el]. + getting message-id from server does not work well. + +1999-01-18 Yuuichi Teranishi + + * Add: [wl-ja.texi]. + about mA, mf and so on. + * Change: + not jump to groups having no unread messages in + wl-folder-{prev,next}-unread. (if with Prefix ARG, jumps). + (pointed out by Ken'ichi OKADA ). + * Change: + avoid errors when no folders exist in wl-folder-check-entity. + (pointed out by Ishikawa Ichiro ). + +1999-01-16 OKUNISHI Fujikazu + + * New Variable: wl-summary-temp-mark-uudecode. + * Change: [wl-ja.texi]. + about @item->@defvar. + +1999-01-15 OKUNISHI Fujikazu + + * Fix: + errors happen because of doing reference to non-existent + property when non-existent folders in ~/.foders is specified in + wl-{folder|summary}-goto-folder. + +1999-01-15 TSUMURA Tomoaki + + * Change: [elmo-archive.el]. + check footer in header-regexp. + * CHange: [elmo-archive.el]. + make compression rate of rar high. + +1999-01-15 Masahiro MURATA + + * Fix: + wl-expire does not work on Emacs based on 19.28. + * Fix: [wl-fldmgr.el]. + wl-fldmgr-add does not work on Emacs-19. + +1999-01-14 Masahiro MURATA + + * Fix: + not create hierarchical structure of access groups on Emacs-19 or + before. + * Fix: [wl-fldmgr.el]. + errors happen when inserting folder into empty folder. + * Change: [wl-expire.el]. + stop process in displaying error when calling elmo fails. + +1999-01-14 Yuuichi Teranishi + + * Change: + implement wl-summary-temp-mark-prefetch, which does not work well, + again. + (pointed out by Ken'ichi OKADA ). + * Fix: + a subject of mail prepared in draft buffer is displayed in way of + including ESC code when trying to reply mails with Japanese + subject on Meadow. + (pointed out by Koji IIDA ). + +1999-01-13 TSUMURA Tomoaki + + * Change: + LHA archive is enable on Windows. + +1999-01-13 Yuuichi Teranishi + + * 0.9.4 - "Broken Wings". + * Fix: + not load information of all folders when both + wl-folder-init-no-load-access-folders and + wl-folder-init-load-access-folders are nil. + * Fix: + fetch errors happen when visiting to same folder after leaving + from multi folder in NNTP. + +1999-01-13 Masahiro MURATA + + * Change: + change wl-folder-entity-alist and wl-folder-entity-id-name-alist + to obarray (hashtable). + * Change: + merge wl-folder-entity-alist and elmo-folder-info-alist. + * Change: + fasten display update when checking. + abolish variable wl-folder-check-fast. + * Change: + definition of folder of access group loaded in initialization is + enable. + * Change: + getting lists of access group in hierarchical structure is enable. + * Change: + change mark of unsubscribe folders to '#'. + * Change: + display elapse time in case that processing of operations in + folder mode take a lot of time. + +1999-01-13 Yuuichi Teranishi + + * Change: + make wl-tmp-dir if it does not exist. + (pointed out by Tadashi Kadowaki ). + * Change: + make wl-queue-folder when startup if it does not exist. + +1999-01-12 Ken'ichi OKADA + + * Fix: + xpm is not in center in wl-demo in case that window-width is 100, + for example. + +1999-01-12 TSUMURA Tomoaki + + * Change: [elmo-archive.el]. + add parameter of rar and fix for windows-nt. + +1999-01-12 Yuuichi Teranishi + + * Change: [elmo-nntp.el]. + display all newsgroups by "-/". + (pointed out by Ichiro Ishikawa ). + (notes: this chenge is overwritten by MURATA's patch on 1999-1-13). + * Fix: + behaviour in filter folder at unplugged is wrong. + * Add: + 'mA' (reply with multiple citation to messages with temporary mark). + 'mf' (multiple forward messages with temporary mark). + ($BKLL\$5$s(B $B$N8fMWK>$K4p$E$/(B)$B!#(B + * Fix: + cache is not saved when leaving from Summary after being at + unplugged. + * Change: [elmo-nntp.el]. + corresponding to Cancel-Lock. + +1999-01-08 Yuuichi Teranishi + + * Change: [wl-dnd.el]. + adjust it to API on XEmacs21.2.8. + +1999-01-08 Masahiro MURATA + + * Fix: + not include parent folders in elmo-localdir-list-folders-subr. + +1999-01-06 Ken'ichi OKADA + + * New Hook: wl-highlight-message-hook. + +1999-01-05 OKUNISHI Fujikazu + + * Change: [elmo-util.el]. + specification of elmo-default-imap4-server in a form such as + "hoge%imap_server@gw" is enable. + +1999-01-05 Hironori Fukuchi + + * Fix: + sending process fails though the message "sending...done" is + displayed in minibuffer when non-existent address is written in To + field. + +1999-01-03 OKUNISHI Fujikazu + + * Fix: + To: field is always set as nil because of type in + wl-draft-edit-string. + +1998-12-31 OKUNISHI Fujikazu + + * Fix: + wrongly duplicate parent folder having sub directory in + elmo-localdir-list-folders-subr. + * Change: + wl-break-pages is restricted by being always nil in + wl-summary-redisplay-no-mime. + * Change: + return value of two or more lower directories in + elmo-localdir-list-folders-subr even if file system does not have + concept of link count. + (it is enable on OS/2 version variant and Mule for Win32 by + default). + * Change: + delete uselessness functions not called. + +1998-12-27 Masahiro MURATA + + * Fix: + errors happen when folder having the same name as group exists + before the group. + +1998-12-27 OKUNISHI Fujikazu + + * Change: [wl-folder.el]. + not move to all folders and only do catchup for folders with + new/unread messages in wl-folder-mark-as-read-all-current-entity + (for speed up). + +1998-12-25 Yuuichi Teranishi + + * Fix: + modification to fix display of summary in wrong code does not work + on Emacs 20.2 or below including Meadow. + (pointed out by Tsunehiko Baba ). + +1998-12-24 Yuuichi Teranishi + + * 0.9.3 - "Last Christmas". Christmas limited version(?). + +1998-12-23 Masahiro MURATA + + * Change: + fix not to use "/" as pass separator. + * CHange: + replace delq with delete if possible. + +1998-12-21 Masahiro MURATA + + * New File: [wl-expire.el]. + add a new feature to delete or move old messages automatically. + * Change: + be to autoload wl-fldmgr.el. + * Change: [wl-folder.el]. + arrange and speed up some commands related with automatic open of + groups. + * Change: + not load LOGO files excepting XEmacs in byte-compiling wl-demo.el. + * Fix: [elmo-archive.el]. + errors happen if directories do not exist in + elmo-archive-list-folders when elmo-archive-treat-file is non-nil. + * Fix: + last two patches in [WL 838] is not used. + +1998-12-21 Yuuichi Teranishi + + * Change: + avoid wrong type argument errors when errors happen in sending + process on XEmacs. + (pointed out by Toshihiro KAMISHIMA ). + +1998-12-18 Yuuichi Teranishi + + * Change: + show an atmosphere like Christmas. + * Change: + use decoded letters as arg of wl-draft. + (based on modification by Hidekazu NAKAMURA + ). + * Fix: + display summary in wrong code on Emacs 20.2 or below including + Meadow. + (pointed out by Hidekazu NAKAMURA , + Fujii ). + +1998-12-17 Hidekazu NAKAMURA + + * Change: + avoid result being "Re: Re:" in case of encoding letters including + "Re:". + +1998-12-17 Yuuichi Teranishi + + * 0.9.2 - "Addicted To Love". + +1998-12-17 Masahiro MURATA + + * Fix: [wl-fldmgr.el]. + possible to destory wl-folder-entity-id-name-alist when an empty + folder is deleted. + * Change: [elmo-archive.el]. + to use a function in method is enable. + * Change: [elmo-archive.el]. + to add or to delete messages is enable in 'tgz. + change suffix of 'tgz to ".tar.gz". + * Fix: [elmo-archive.el]. + not give consideration to prefix in + elmo-archive-msgdb-create-as-numlist-subr2. + +1998-12-16 Yuuichi Teranishi + + * Change: + replace contents of commands in menu for mail with it for wl in + draft buffer. + * Change: + define open-network-stream-as-binary if it is not defined so that + smtp.el works well when the latest version apel is not used. + * Change: + adjust smtp.el to the latest version FLIM. + +1998-12-16 Masahiro MURATA + + * Fix: [wl-fldmgr.el]. + wl-folder-newsgroups-hashtb is always nil when adding not nntp + folders. + +1998-12-16 Hidekazu NAKAMURA + + * Change: [WL-ELS]. + not install smtp.el when using SEMI. + +1998-12-15 Yuuichi Teranishi + + * Change: + put date parts of In-Reply-To: in "". + * Change: + storage of summary created by wl-summary-rescan is executed in + finishment of summary not but of scan. + * New Variable: wl-folder-thread-indent-set-alist. + enable to select indent letters of thread in each folder. + change to use wl-thread-indent-level, + wl-thread-have-younger-brother-str, wl-thread-youngest-child-str, + wl-thread-vertical-str, wl-thread-horizontal-str, + wl-thread-space-str as default value when nothing is matched by + using rules defined by it. + * New Variable: wl-folder-weekday-name-lang-alist. + enable to select method to display day of the week in each folder. + change to use wl-summary-weekday-name-lang as default value when + nothing is matched by rules defined by it. + * Fix: [elmo-nntp.el, elmo-imap4.el, elmo-msgdb.el]. + display Chinese or Hangul letters in wrong code because of wrong + creattion of Subject or From for saving msgdb. + * Change: + to {insert|store} cache of summary is done in + as-binary-{input|output}-file, and to do encode/decode is done in + mime-charst of each buffer. + * Change: + call elmo-create-folder even when wl-draft-folder does not exist + in wl-init. + * Change: + become wl-generate-user-agent-string corresponding to Nemacs. + insert version information of tm. + * Fix: + insert child thread into an unexpected position if target message + is hidden in close thread when deleting messages. (maybe) + * Change: [bbdb-wl.el]. + do require necessary modules in byte-compiling. + * Change: + put smtp-via-smtp in (as-binary-process). + (based on reports by + Toshihiko Kodama and others). + * Change: [wl-ja.texi]. + @directory is enable by default. + (pointed out by SENDA Shigeya ). + +1998-12-13 Yuuichi Teranishi + + * New File: [wl-mule.el, wl-nemacs.el]. + * Change: + merge wl-nemacs and a main trunk. + +1998-12-10 Masahiro MURATA + + * Fix: + not refer Reference field instead of In-Reply-To field if + In-Reply-To field contains no message-id. + +1998-12-11 Yuuichi Teranishi + + * 0.9.1 - "Yankee Rose". + +1998-12-10 Masahiro MURATA + + * Change: + change name of draft buffer ("1" -> "+draft/1"). + * New Variable: wl-jump-to-draft-buffer. + * Change: + processing of matching in wl-draft-config-alist continues when is + succeeded once. + * Add Hook: wl-draft-config-exec-hook. + * New Variable: wl-draft-always-delete-myself. + * Fix: + elmo-archive-list-folder always returns nil wrongly when prefix of + archive folder includes numeral. + * Change: + elmo-*-copy-msgs returns non-nil if suceeded. + * Change: + not execute deletion if processing of copy in elmo-move-msgs + fails. + +1998-12-10 Yuuichi Teranishi + + * Change: + use elmo-match-string, elmo-match-buffer if possible. + * Change: + default value os wl-insert-mail-followup-to, + wl-insert-mail-reply-to is nil. + * Change: [wl-ja.info]. + work well on Emacs 20.3. + * Change: + start up by "M-x wl-draft" work well. + * Change: + reduce warning messages in byte-compiling on Mule. + +1998-12-10 TSUMURA Tomoaki + + * Fix: + not update number-alist of msgdb after pack-number. + +1998-12-10 Yuuichi Teranishi + + * Change: + insert Bcc: field regardless of value of mail-self-blind when + wl-bcc is defined (adjustment to an action of wl-fcc). + +1998-12-10 Akihiro Motoki + + * New Variable: wl-bcc. + put value of wl-bcc into Bcc: field when non-nil. + +1998-12-10 SENDA Shigeya + + * Change: [wl-ja.texi]. + fix for XEmacs. + * Fix: [wl-ja.texi]. + one vindex is lack. + * Change: [WL-ELS]. + install info when choosing install-package on XEmacs. + +1998-12-10 Yuuichi Teranishi + + * Fix: + when in the middle of thread there are any messages in close thread + hereafter threads do not be inserted. + +1998-12-09 Masahiro MURATA + + * Add Variables: elmo-move-msgs, elmo-copy-msgs, elmo-append-msg. + move or copy in keeping number in source folder by + elmo-{move|copy}-msg and copy in keeping number specified by + elmo-append-msg. + * Change: + deal with multiple message once when copying from 'localdir to + 'archive. + +1998-12-09 Yuuichi Teranishi + + * 0.9.0 - "With Or Without You". + * Change: [elmo-archive.el]. + delete warning in byte-compiling. + +1998-12-09 OKUNISHI Fujikazu + + * New File: [elmo-archive.el] + "v0.16 [981208/alpha]". + * Change: + make folders of dst-spec in copy-msgs if not. + (pointed out by Masayuki TERADA ). + * Fix: + regexp-quote() of suffix is not executed in get-archive-name when + elmo-archive-treat-file is non-nil. + +1998-12-09 Yuuichi Teranishi + + * Change: + call elmo-create-folder if target folder does not exist in + wl-folder-check-entity. + * Change: + call elmo-create-folder if wl-trash-folder does not exist in + wl-init. + (pointed out by OKUNISHI Fujikazu + ). + +1998-12-08 Yuuichi Teranishi + + * Change: + reduce warnings in byte-compiling on XEmacs, Emacs. + * Fix: + errors happen because of wrong dealing with parent in processing + of mime-entity in mmelmo-imap4. + +1998-12-07 Yuuichi Teranishi + + * Fix: [00README.ja] + address of ML is still old. + +1998-12-06 Masahiro MURATA + + * Fix: + ignore hereto of wl-summary-cursor-up when wl-summary-buffer-view + is 'thread. + * Fix: + return value is wrongly nil if no success-mark exist and cursor + goes into position of failure-mark when hereto is non-nil in + wl-thread-jump-to-next-unread, wl-thread-jump-to-prev-unread. + * Change: + display progress of process in deletion of summary update. + +1998-12-06 OKUNISHI Fujikazu + + * Change: + remove debug code and display elapse time in + elmo-localdir-pack-number. + * Change: + use SPEC in elmo-call-func in order to avoid free var based on + data scope problem (for deletion of byte-compile warning). + +1998-12-05 OKUNISHI Fujikazu + + * Fix: [wl-ja.texi]. + some errors. + +1998-12-05 Masahiro MURATA + + * New Variable: elmo-archive-treat-file. + targets of archive folder are files when non-nil. + +1998-12-04 Masahiro MURATA + + * Fix: + temporary buffers created by elmo still remains after finishing + WL. + * Change: + after doing wl-summary-rescan cursor goes into same position as + before. + * Change: + two periods are not side by side in display of summary update. + * Change: + enable to compele value of Since and Before in wl-summary-pick. + * Change: + arrage lists of completing-read. + * Change: + not display messages if there are no marks excepting marks with + low pirority by wl-summary-move-order even when + wl-auto-select-first is t. + * Change: + return value is t when deletion by elmo-archive-delete-msgs is + success. + +1998-12-04 Yuuichi Teranishi + + * Change: + call wl-summary-unread-message-hook in wl-summary-mark-as-read. + +1998-12-04 Ken'ichi OKADA + + * New Hook: wl-summary-unread-message-hook. + call it when reading unread messages. + +1998-12-03 Masahiro MURATA + + * Fix: + not update display after checking archive folder in folder mode. + +1998-12-03 Yuuichi Teranishi + + * Change: + make a branch for wl_nemacs corresponding to Nemacs. + * Change: + replace old smtp.el with smtp.el in flim-1.12. + adjust to its API. + (deletion of smtp-do-bcc, change of args of smtp-via-smtp). + * Fix: + always ignore wl-insert-message-id in im-wl.el. + * Fix: + errors display in a large size in wl-summary-prefetch-msg. + * Change: + speed up all operations of multi folder by replacement append with + nconc. + +1998-12-02 OKUNISHI Fujikazu + Hironori Fukuchi + + * Fix: [wl-ja.texi]. + fix some errors. + +1998-12-02 Yuuichi Teranishi + + * alpha -> beta. + * Change: + move old ChangeLog to etc directory. diff --git a/etc/ChangeLog.2.ja b/etc/ChangeLog.2.ja new file mode 100644 index 0000000..31f2f27 --- /dev/null +++ b/etc/ChangeLog.2.ja @@ -0,0 +1,1290 @@ +1999-05-18 Yuuichi Teranishi + + * 1.0.0 - "Kokomo" + +1999-05-18 Tsunehiko Baba + + * $B?75,%U%!%$%k(B ChangeLog.en $BDI2C!#(B + +1999-05-18 A. SAGATA + + * Message $B$G(B mouse-2 $B$,F0$+$J$/$J$C$F$$$?$N$r=$@5!#(B + +1999-05-18 Yuuichi Teranishi + + * 1.0.0 pre2 - "Kokomo-pre2" + * Folder $B$G(B $B%0%k!<%W$NCf$NL$FI?t$,8:$k$H%O%$%i%$%H$NHO0O$,JQ$o(B + $B$C$F$7$^$&$N$r=$@5!#(B + ($B>.6L$5$s(B $B$N8f;XE&(B) + * Draft $B$N(B C-cC-s $B$H(B menubar $B$N%-!<%P%$%s%I$O%I%i%U%H%P%C%U%!Kh$K(B + local-set-key $B$9$k$h$&$K$7$?!#(B + * wl-summary-mark-as-read-all $B$,!$%9%l%C%I$,JD$8$?>uBV$G1#$l$F(B + $B$$$k%a%C%;!<%8$KBP$7$F8z$+$J$/$J$C$F$$$?$N$r=$@5!#(B + ($BBg_7$5$s(B $B$N8f;XE&(B) + +1999-05-18 Masahiro MURATA ($BB + + * wl-summary-reply-with-citation $B$G$O(B + wl-draft-prepared-config-alist $B$G$NK\J8A^F~0LCV$,68$&$N$r=$@5(B + $B$7$?!#(B + +1999-05-17 $B2,ED(B $B7r0l(B + + * [bbdb.el] wl-folder-exit-hook -> wl-exit-hook $B$KBP1~!#(B + +1999-05-17 Yuuichi Teranishi + + * pre 1.0.0 - "Kokomo-pre" + * replace-match () $B$r;H$o$J$$$h$&$K$7$?!#(B + +1999-05-17 $B2,ED(B $B7r0l(B + + * POP-before-SMTP $B$N%I%-%e%a%s%HDI2C!#(B + * POP-before-SMTP $B$KBP1~!#(B + +1999-05-17 OKUNISHI Fujikazu + + * elmo-multi-get-msg-filename() $B$,B8:_$7$J$+$C$?$N$GDI2C!#(B + * wl-message-refer-article-or-url() $B$G(B mailto: $B$rDL$9!#(B + +1999-05-17 Masahiro MURATA ($BB + + * wl-summary-goto-folder $B$r(B interactive $B$Gl9g!$(B + wl-folder-buffer-cur-{path|entity-id} $B$,JQ99$5$l$J$$$N$r=$@5$7(B + $B$?!#(B + * wl-expire-alist $B$N(B 2$B!$(B3$BHVL\$NMWAG$N$$$:$l$+$,(B nil $B$N>l9g$O(B + expire $B$7$J$$$h$&$K$7$?!#(B + +1999-05-17 $B2,ED(B $B7r0l(B + + * AUTHINFO $B$K4X$9$kItJ,$N%I%-%e%a%s%HDI2C!#(B + +1999-05-17 A.SAGATA + + * $B%^%&%99T%O%$%i%$%H$N%P%0=$@5!#(B + +1999-05-17 Yuuichi Teranishi + + * $B$"$A$3$A$+$i(B BETA $B$r + + * make uninstall $B$,(B WL_PREFIX, ELMO_PREFIX $B$r9MN8$7$F$$$J$+$C$?$N$r(B + $B=$@5!#(B + * Mule2.3 $B8~$1$K(B (point-at-bol), (point-at-eol) $B$r;H$o$J$$$h$&$K$7$?!#(B + * $BL>A0JQ99(B wl-folder-exit-hook -> wl-exit-hook$B!#(B + * $BL>A0JQ99(B wl-folder-exit -> wl-exit$B!#(B + * ja.Emacs $B$r99?7!#(B + * [wl-ja.texi] wl-summary-print-message $B$N@bL@DI2C!#(B + +1999-05-16 Masahiro MURATA ($BB + + * wl-auto-select-first $B$,(B t $B$G$"$C$F$bL$FI$,$J$$>l9g!$(B + $B%a%C%;!<%8%P%C%U%!$,>C$($J$$$N$r=$@5!#(B + +1999-05-15 Yuuichi Teranishi + + * [wl-ja.texi] highlight$B!"(Binternal $B%U%)%k%@$N@bL@$rDI2C!#(B + * wl-highlight $B$+$i$$$/$D$+$N(B defvar $B$r(B wl-vars $B$K0\$7!"(B + defcustom $B$K$7$?!#(B + * unplugged $B$G(B nntp $B%U%)%k%@$rA*Br$9$k$H%(%i!<$,=P$k$N$r=$@5!#(B + ($B4];3$5$s(B $B$h$j8f;XE&(B) + * wl-stay-folder-window $B$,(B t $B$N$H$-!"(BSticky Summary $B$,Mm$`$H(B + $B%-%c%C%7%e$,99?7$5$l$J$$$J$I$NIT6q9g$,H/@8$7$F$$$?$N$r=$@5!#(B + * Summary $B$N%^%&%99T$N%O%$%i%$%H$r9TF,$+$i9TKv$^$G$K$7$?!#(B + * wl-init $B$N=i4|2=$N=g=x$H%a%C%;!<%8$r0lItJQ99!#(B + prefix-arg $B$D$-$G$O!"4pK\%U%)%k%@$NB8:_$r%A%'%C%/$7$J$$$h$&$K$7$?!#(B + * Sticky Summary $B$r(B exit $B$9$k$H$-$K!"%S%e!<%-%c%C%7%e$b(B + $B%;!<%V$9$k$h$&$K$7$?!#(B + +1999-05-14 OKUNISHI Fujikazu + + * wl-summary-reedit() $B$7$?;~$K(B wl-mail-setup-hook $B$,;2>H$5$l$J$$(B + $B$N$r=$@5!#(B + +1999-05-14 Masahiro MURATA ($BB + + * wl-summary-next-folder-or-exit() $B$N=$@5$,(B + wl-auto-select-first $B$,(B t $B$N>l9g$,9MN8$5$l$F$J$$$N$r=$@5!#(B + * wl-summary-next-no-unread $B$,(B t $B$N$H$-$N0\F0%3%^%s%I$rJQ99$G$-(B + $B$k$h$&$K$7$?!#(B + +1999-05-14 $B2,ED(B $B7r0l(B + + * [wl-ja.texi] wl-draft-write-current-newsgroup $B$N%I%-%e%a%s%HDI2C!#(B + +1999-05-13 A.SAGATA + + * mode-motion-hook $B$rMQ$$$:$K(B mouse-face $B$N(Bhighlight $B$r9T$&;v$K$7$?!#(B + * wl-version-show $B$rDI2C$7$?!#(B + +1999-05-13 Koichiro Ohba + + * [wl-ja.texi] Sticky Summary $B$N@bL@$rDI2C!#(B + +1999-05-13 $B2,ED(B $B7r0l(B + + * wl-summary-stick$B$7$?%U%)%k%@$G!$(Bwl-summary-forward$B$7$?8e!$(B + $BJQ$J%&%$%s%I%&$K9T$C$F$7$^$&$N$r=$@5!#(B + +1999-05-13 Masahiro MURATA ($BB + + * wl-template $B$,(B recursive-edit $B$r;H$o$J$$$h$&$K$7$?!#(B + +1999-05-13 Yuuichi Teranishi + + * wl-draft-config-alist $B$N%5%V4X?t$K(B 'x-face $B$rDI2C!#(B + * [wl-template] select $B%P%C%U%!$r%O%$%i%$%H$9$k$h$&$K$7$?!#(B + +1999-05-13 Mito + + * $B%U%)%k%@$r0\F0$7$F$b!"D>A0$N%a%C%;!<%8$,I=<($5$l$?$^$^$J$N$r(B + $BHr$1$k$?$a(B wl-summary-next-folder-or-exit() $B$G(B + (wl-summary-toggle-disp-msg 'off) $B$9$k$h$&$K$7$?!#(B + * wl-summary-toggle-disp-msg() $B$G(B arg $B$K(B off $B$r;XDj$7$F8F(B + $B$S=P$7$?>l9g%(%i!<$,=P$k$N$r=$@5!#(B + +1999-05-13 Masahiro MURATA ($BB + + * NNTP $B%U%)%k%@$r(B wl-folder-update-recursive-current-entity $B$G99(B + $B?7$9$k$H%(%i!<$K$J$k$N$r=$@5$7$?!#(B + +1999-05-13 Yuuichi Teranishi + + * pop3, imap4, nntp $B$G!"(Belmo-*-use-cache $B$,(B nil $B$N$H$-$K(B + uncached $B$K$J$C$F$7$^$&$N$r=$@5!#(B + ($BB $B$N8f;XE&(B) + +1999-05-12 OKUNISHI -GTO- Fujikazu + + * localnews $B$,FI$a$J$/$J$C$F$$$?%P%0$r=$@5!#$^$?!"(B + elmo-localnews-local-file-p() $B$N0z?t$,B-$j$J$+$C$?$N$r=$@5!#(B + +1999-05-12 Yuuichi Teranishi + + * 0.10.2 - "I'm Your Man" + +1999-05-12 A. SAGATA + + * [wl-ja.texi] $B$$$/$D$+$N%3%^%s%I$N@bL@$rDI2C!#(B + +1999-05-12 Koichiro Ohba + + * [sample.dot.wl] auto-refile $B@_Dj$rDI2C!#(B + * [wl-ja.texi] wl-summary-auto-refile-skip-marks $B$N@bL@$rDI2C!#(B + +1999-05-12 Masahiro MURATA ($BB + + * $BBgJ8;z$N%K%e!<%9%0%k!<%WL>$N%A%'%C%/$K<:GT$9$k$N$r=$@5!#(B + +1999-05-12 Yuuichi Teranishi + + * localdir $B$G4{FI%a%C%;!<%8$,(B uncached $B$K$J$C$F$7$^$&$N$r=$@5!#(B + * $B?75,JQ?t(B wl-ps-print-buffer-func$B!#(Bps-print $B$G;H$&4X?t$r;XDj!#(B + default $B$O(B 'ps-print-buffer-with-faces$B!#(B + ($B?e8M$5$s(B $B$N8fMWK>$K4p$E$/(B)$B!#(B + * .folders $B2r@O;~$K%0%k!<%W$H(B petname $B$KF1$8L>A0$,$G$F$-$?$i(B + $B%(%i!<$r=P$9$h$&$K$7$?!#(B + +1999-05-11 Masahiro MURATA ($BB + + * sample.dot.wl $B$r99?7!#(B + * $B%"%/%;%9%0%k!<%W$N5-=R$N=$@5B>!#(B + +1999-05-11 OKUNISHI -GTO- Fujikazu + + * $B%U%#%k%?%U%)%k%@$G(B "$" $B$r$D$1$kBP>]$,%m!<%+%k%U%!%$%k$G$"$k(B + $B>l9g$K!"%^!<%/$O$D$/$,%-%c%C%7%e$G$-$J$$%P%0$r=$@5!#(B + +1999-05-11 Yuuichi Teranishi + + * tm $B8~$1(B partial $B7k9g4X?t$rl9g$,$"$C$?$N$r=$@5!#(B + * wl-folder-check-one-entity $B$G$9$0$K7k2L$,I=<($5$l$k$h$&(B + (sit-for 0) $B$9$k$h$&$K$7$?!#(B + * wl-message-redisplay-hook $B$r(B unwind-protect $B$7!"(B + bbdb $B$J$I$N(B prompt $B$G(B C-g $B$7$?$H$-$K$b(B Summary + $B$K%+!<%=%k$,La$k$h$&$K$7$?!#(B + +1999-05-10 Tomokazu Matsumaru + + * $B$?$/$5$s%a%C%;!<%8$,$"$k(B POP3 $B%U%)%k%@$,%O%s%0$9$kLdBj$r=$@5!#(B + +1999-05-10 Yuuichi Teranishi + + * $B?75,JQ?t(B wl-folder-sync-range-alist, wl-default-sync-range$B!#(B + $B%U%)%k%@$4$H$K(B sync $B$N%G%U%)%k%H$rJQ$($i$l$k$h$&$K$7$?!#(B + ($B?@V:$5$s(B$B$h$j8fMWK>(B) + * Mule 2.3 $B$G(B make $B$K<:GT$9$k$N$r=$@5!#(B + ($B>.6L$5$s(B $B$N8f;XE&(B) + * wl-vars.el $B$,(B euc $B$K$J$C$F$$$F%9%l%C%I;^$,J8;z2=$1$9$k$N$r=$@5!#(B + ($BB $B$N8f;XE&(B) + * 0.10.1 - "Harlem Shuffle" + +1999-05-09 Yuuichi Teranishi + + * imap4 $B$G!"(Bselect-folder $BCf$K(B C-g $B$9$k$H!"%+%l%s%H%U%)%k%@$,(B + $B$*$+$7$/$J$k$N$r=$@5(B($B$7$?$D$b$j(B)$B!#(B + ($B?e86!wI=@i2H(B $B$5$s$N8f;XE&(B) + * $B?75,JQ?t!"(Belmo-archive-use-cache$B!"(Belmo-nntp-use-cache + elmo-imap4-use-cache$B!"(Belmo-pop3-use-cache$B!#(B + $B$=$l$>$l!"FI$s$@;~$K%a%C%;!<%8$r%-%c%C%7%e$9$k$+$I$&$+$r@_Dj!#(B + * wl-no-cache-folder-list -> $BGQ;_!#(B + * important-mark $B$rIU$1$?=V4V$K%-%c%C%7%e$9$k$h$&$K$7$?!#(B + +1999-05-08 Koichiro Ohba + + * [wl-ja.texi] typo $BB>$N=$@5!#(B + +1999-05-08 OKUNISHI Fujikazu + + * [wl-ja.texi] typo $BB>$N=$@5!#(B + +1999-05-05 OKUNISHI Fujikazu + + * ^L $B$G2~JG$5$l$F$k;~$K8B$j(B wl-message-prev-page() $B$9$k$H%+!<(B + $B%=%k$,%a%C%;!<%8%P%C%U%!$+$i%5%^%j$XLa$i$J$$%P%0$r=$@5!#(B + * make install $B;~$K$O(B *.elc $B$O(B rename-file() $B$9$k!#(B + * mode-motion-hook $B$O(B XEmacs $B8GM-$J$?$a!"(BGNU Emacs $B$G%P%$%H%3(B + $B%s%Q%$%k$9$k$H%(%i!<%a%C%;!<%8$,=P$k$N$rL[$i$;$k!#(B + +1999-05-05 OKUNISHI -GTO- Fujikazu + + * wl-summary-refile-region, wl-summary-copy-region, wl-thread-refile, + wl-thread-copy $B$,%P%0$C$F$$$?$N$r=$@5!#(B + +1999-05-05 Masahiro MURATA ($BB + + * elmo-{nntp|imap4|pop3}.el $B$G(B case-fold-search $B$,A`:nBP>]%P%C%U%!(B + $B$GM-8z$K$J$C$F$$$J$+$C$?$N$r=$@5$7$?!#(B + +1999-05-04 Masahiro MURATA ($BB + + * wl-draft-send $B$r(B1$BEYCfCG$7$?8e$KAw?.$r9T$&$H!$(B + wl-draft-config-alist $B$NJQ?t$,E,MQ$5$l$J$$LdBj$r=$@5$7$?!#(B + +1999-05-01 OKAZAKI Tetsurou + + * NNTP $B%U%)%k%@$G(B top $B%+%F%4%j$NF,J8;z$,?t;z$K$J$C$F$$$k(B + $B%K%e!<%9%0%k!<%W$rFI$a$kMM$K$7$?!#(B + +1999-04-30 Masahiro MURATA ($BB + + * face $B$r%]!<%?%V%k$KDj5A$9$k4X?t!"(Bwl-defface $B$rDj5A!#(B + +1999-04-30 Yuuichi Teranishi + + * $BJT=8Cf$N%I%i%U%H$r(B Summary $B$+$i(B reedit $B$9$k$H%P%C%U%!L>$N(B + $B%U%)%k%@L>ItJ,$,A}?#$7$F$7$^$&$N$r=$@5!#(B + ($B2,:j$5$s(B OKAZAKI Tetsurou $B$h$j8f;XE&(B) + * $B6u%U%)%k%@$G(B s->rescan $B$9$k$H$I$3$K%8%c%s%W$9$k$+?V$$$F$7$^$&(B + $B$N$r=$@5!#(B + ($B2,:j$5$s(B OKAZAKI Tetsurou $B$h$j8f;XE&(B) + * [bbdb-wl] (require 'wl) $B$9$k$h$&$K$7$?!#(B + * Thread $B$N;R$b?F$b$J$$%a%C%;!<%8$G(B wl-thread-open-close $B$9$k$H(B + $B$I$3$K%8%c%s%W$9$k$+?V$$$F$7$^$&$N$r=$@5!#(B + * $B?75,%3%^%s%I!"(Bwl-summary-drop-unsync, + wl-folder-drop-unsync-current-entity$B!#(B + $BA4$F$NL$F14|%a%C%;!<%8$r!"$J$+$C$?$3$H$K$9$k!#(B + 'D' $B$K3d$jEv$F!#(B + +1999-04-28 Masahiro MURATA ($BB + + * $B?75,JQ?t(B wl-draft-prepared-config-alist$B!#(B + wl-draft-config-alist $B$K4v$D$+$N5!G=3HD%$r9T$C$?!#(B + * $B?75,%U%!%$%k(B wl-template$B!#(B + $B%I%i%U%H$K%F%s%W%l!<%H$rA*Br!&A^F~$9$k5!G=$rDI2C$7$?!#(B + +1999-04-28 Yuuichi Teranishi + + * Nemacs $B0J30$O(B wl-draft-mode-map $B$r;H$&$h$&$K$7$?!#(B + ($BB $B$h$j8f=u8@(B) + +1999-04-13 Masahiro MURATA ($BB + + * Summary $B%P%C%U%!$N(B case-fold-search $B$,>o$K(B nil $B$K$J$C$F$7$^$&$N$r(B + $B=$@5!#(B + * elmo-nntp-open-connection $B$,<:GT$7$?$H$-$NJV$jCM$,(B docstring $B$H(B + $B0[$J$C$F$$$?$N$r=$@5!#(B + +1999-04-28 Mito + + * wl-draft-buffer-cur-summary-buffer $B$,(B # $B$K$J$C$?(B + $B$H$-$KAw?.%3%^%s%I$,<:GT$7$F$7$^$&$N$r=$@5!#(B + +1999-04-27 Mito + + * Summary $B$+$i(B '#' $B$G%W%j%s%H$9$k;~$K3NG'$r5a$a$k$h$&$K$7$?!#(B + +1999-04-27 $B2,ED(B $B7r0l(B + + * wl-summary-refile-region $B$,$*$+$7$/$J$C$F$?$N$r=$@5!#(B + +1999-04-27 Yuuichi Teranishi + + * Nemacs $B$GF0$+$J$/$J$C$F$$$?$N$r=$@5!#(B + * custom $B$,$J$$4D6-$GLdBj$,$"$C$?$N$r=$@5!#(B + * $B$$$/$D$+K:$l$F$$$?%Q%C%A$N%^!<%8(B (pop3 $B$,%O%s%0$9$kLdBj$N=$@54^$`(B)$B!#(B + ($B:72eED$5$s(B $B$h$j8f;XE&(B) + * 0.10.0 - "Got My Mind Set On You" + * localnews $B$,(B wl-summary-local-p $B$G(B local $B07$$$5$l$F$$$J$+$C$?$N$r(B + $B=$@5(B($B8MED$5$s(B $B$h$j8fJs9p(B) + +1999-04-26 Yuuichi Teranishi + + * elmo-internal.el $B$N3F%P%C%/%(%s%I4X?t$r + + * SEMI $B$G(B partial $B$r7k9g$9$k4X?t$r=q$-D>$7$?!#(B + * [bbdb-wl] Sticky Summary $B$KBP1~!#(B + * wl-default-draft-cite $B$,%P%0$C$F$$$?$N$r=$@5!#(B + ($B%5%^%j$N%+!<%=%k0LCV$,$:$l$F$$$k$H!"4V0c$C$?(B citation title $B$r(B + $B$D$1$F$7$^$&(B) + +1999-04-23 A. SAGATA + + * body $B$N0l$D$N9T$KFs$D(B message-id$B$,$"$k$H$-$K!":8$N(Bmessage-id$B$r(B + $B??Cf%/%j%C%/$9$k$H1&$N(B message-id $B$KHt$s$G$7$^$&$N$r=$@5!#(B + +1999-04-23 $B2,ED(B $B7r0l(B + + * wl-summary$B%b!<%I$N:G2<9T$N6u9T$G!$(Bwl-thread-{copy,refile}$B$9$k$H!$(B + $B%(%i!<$,=P$k$N$r=$@5!#(B + +1999-04-22 Yuuichi Teranishi + + * prefix arg $B$D$-$G%U%)%k%@0\F0$9$k$H!"(BSticky Summary $B$K(B + $B0\F0$9$k$h$&$K$7$?!#(B + ($B$3$l$^$G$N(B wl-folder-goto-folder$B!"(Bwl-summary-goto-folder $B$r(B + $B$=$l$>$l(B wl-folder-goto-folder-subr$B!"(Bwl-summary-goto-folder-subr + $B$KJQ99(B) + * wl-highlight-body-too $B$,(B nil $B$N;~$K(B draft-buffer $B$G(B"^L" $B$7$F$b(B + re-highlight $B$7$J$$$h$&$K$7$?!#(B + ($B:72eED$5$s(B $B$N=$@5(B)$B!#(B + * $B$7$D$3$$%5%^%j!"(BSticky Summary$B!#(B + ($B?e8M$5$s(B $B$N8fMWK>$K4p$E$/(B)$B!#(B + * mmelmo-imap4 $B$O(B mmelmo $B$r7Q>5$9$k$h$&$K$7$?!#(B + +1999-04-21 A. SAGATA + + * wl-folder-close-parent-entity $B$K%P%0$,$"$C$?$N$r=$@5!#(B + * wl-thread-open-close $B$N5!G=$r3HD%$7!";R$,$J$$>l9g$O?F$r(B close + $B$9$k$h$&$K$7$?!#(B + * wl-folder-close-parent-entity -> wl-folder-open-close + * wl-folder-open-close $B$r(B "/" $B$K%P%$%s%I!#(B + +1999-04-21 Mito + + * $B%M%9%H$7$F$k(B alias $B$bE83+$9$k$h$&$K$7$?!#(B + +1999-04-21 Yuuichi Teranishi + + * wl-summary-move-order $B$,(B 'new$B!"$+$D:G=i$N%a%C%;!<%8$N%^!<%/$,(B + "$" $B$+$D%U%)%k%@Fb$K(B "$" $B0J30$N%^!<%/$,$J$$$H$-!"(B + wl-summary-goto-folder $B$G:G=i$N%a%C%;!<%8$K%+!<%=%k$,9T$+$J$$(B + $B$N$r=$@5!#(B + * wl-summary-goto-folder $B$GL@$i$+$K#22s(B wl-summary-cursor-down $B$r(B + $B9T$C$F$$$?(B(!)$B$N$r=$@5!#(B + +1999-04-21 Kazuyuki IENAGA + + * custom $B$KBP1~!#(B + +1999-04-21 Masahiro MURATA ($BB + + * leafnode $B$J$I(B group $B%3%^%s%I$N%l%9%]%s%9$KM>J,$J%a%C%;!<%8$rIU(B + $B$1$k%5!<%P$G$O!$%[%9%HL>$rIU2C$7$?%U%)%k%@$N>pJs$, + + * $B?75,%U%!%$%k(B elmo-internal.el$B!#(B + $BFbIt%G!<%?$r%V%i%&%:$9$k$?$a$N%U%)%k%@!#(B + +1999-04-19 A. SAGATA + + * $B?75,4X?t(B wl-draft-highlight-and-recenter$B!#%I%i%U%H$G(B C-l $B$9$k$H!"(B + $B%O%$%i%$%H8e(B recenter$B!#(B + * [elmo-nntp] elmo-nntp-search $B$N0z?t$,0c$C$F$$$?$N$r=$@5!#(B + +1999-04-19 Takaaki MORIYAMA + + * nntp $B$N(B folder $BDj5A$K%]!<%H;XDj$r$G$-$k$h$&$K$7$?!#(B + +1999-04-19 Yuuichi Teranishi + + * wl-summary-copy-prev-destination $B$r(B \M-O $B$K3d$j?6$C$F$$$?$N$,(B + vt-100$B$N%+!<%=%k$^$o$j$GLdBj$,$"$C$?$N$G%-!<%P%$%s%I$r30$7$?!#(B + ($B$9$,$N$5$s(B $B$h$j8f;XE&!"(B + $B:72eED$5$s(B $B$h$j8f=u8@(B)$B!#(B + * nntp $B$G%a%C%;!<%8HV9f$,(B 6 $B7e$r1[$($k$HHV9f$,A4It(B 0 $B$K$J$C$F(B + $B$7$^$&$N$r=$@5(B($B:72eED$5$s(B$B$N8f;XE&(B)$B!#(B + +1999-04-19 $B2,ED(B $B7r0l(B + + * $B%*%U%i%$%s!&%j%U%!%$%k(B/$B%3%T!<$N$"$H!"%j%U%!%$%k(B/$B%3%T!<@h$N%U%)%k(B + $B%@$rK,$l$k$H!"%*%U%i%$%s$G$b%a%C%;!<%8$,DI2C$5$l$F$$$k$h$&$K8+$($J$$(B + $B$N$r=$@5!#(B + * $B%*%U%i%$%s;~$NL$FI=hM}$b$9$k$h$&$K=$@5!#(B + +1999-04-19 A. SAGATA + + * $B%5%^%j$N(B \M-O $B$N%P%$%s%I$r30$9!#(B + +1999-04-17 Koichiro Ohba + + * wl-summary-auto-refile $B$N%I%-%e%a%s%HDI2C!#(B + * wl-summary-auto-refile $B$N%-!<%P%$%s%IDI2C!#(B + * sample.dot.wl $B$G(B Mail-Followup-To $B$H(B Mail-Reply-To $B$r<+A0$GIU$1(B + $B$F$$$k$N$r=$@5!#(B + +1999-04-14 Yuuichi Teranishi + + * $B%I%i%U%H%P%C%U%!$N%b!<%I$r(B mail-mode $B$r(B derive $B$7$?(B + wl-draft-mode $B$K$7$?!#(B + ($B>.NS$5$s(B $B$N8f=u8@(B) + * [WL-ELS] $B?75,JQ?t(B WL_PREFIX$B!"(BELMO_PREFIX $B$r@_$1!"(B + $B$=$l$>$l$NCM$r(B ELISPDIR $B$+$i$NAjBP%G%#%l%/%H%j$H$7$F(B + wl, elmo $B%b%8%e!<%k$r%$%s%9%H!<%k$9$k$h$&$K$7$?!#(Bdefault $B$O(B ""$B!#(B + ($B>.NS$5$s(B $B$N8f=u8@(B) + * "make clean" $B$,(B WL-ELS $B$r(B load $B$7$F$7$^$&$N$G!"B>$N(B emacs $B$G(B + compile $B$7$?(B *.elc $B$N$"$k(B source tree $B$GJL$N(B emacs $B$GF0$+$J$$$N$r(B + $B=$@5!#(B + * $BJ#?t%a%C%;!<%8$,$"$k$H(B POP $B$,%O%s%0$7$F$7$^$&$N$r=$@5!#(B + ($B@P@n$5$s(B $B$h$j8fJs9p(B) + +1999-04-13 OKAZAKI Tetsurou + + * [elmo-nntp] docstring $B$N(B typo $B=$@5!#(B + +1999-04-12 A. SAGATA + + * summary buffer$B$G!"(B"E" $B$r2!$7$F(B reedit $B$9$k$H!"(Bbody $B$,A4It(B + signature-face $B$K$J$C$F$7$^$&$N$r=$@5!#(B + * summary mode $B$H(B folder mode $B$N;~$K!"(Bmouse $B9T$r(B + highlight $B$5$;$k(B(xemacs$B$N$_(B)$B!#(B + +1999-04-12 Yuuichi Teranishi + + * $B%I%i%U%H$G!"%?%V$G;O$^$k9T$NC$5$l$F$7$^$&%P%0$r=$@5(B + ($B:72eED$5$s(B$B$N8f;XE&(B)$B!#(B + * Summary $B$G(B 'q' $B$r2!$7$?8e$9$+$5$:(B C-g $B$9$k$HJ8;z2=$1$7$?(B + $B%P%C%U%!$,;D$C$F$7$^$&$N$r=$@5(B($B0$It$5$s(B $B$N8f;XE&(B)$B!#(B + * XEmacs $B$GF|K\8l(B Subject $B$N(B pick $B$,<:GT$9$k$N$r=$@5(B + ($B:72eED$5$s(B$B$N8f;XE&(B)$B!#(B + * 4/2 $B$N(B elmo-nntp-get-folders-info $B$,%O%s%0$7$F$7$^$&=$@5$r(B + ChangeLog $B$K2C$($k$N$rK:$l$F$$$?$N$GDI2C!#(B + ($BCf@n$5$s(B $B$h$j8f;XE&(B)$B!#(B + * 0.9.8 - "Faith" + +1999-04-10 Yuuichi Teranishi + + * $B?75,JQ?t!"(Belmo-msgid-replace-string-alist + Message-id ->$B%-%c%C%7%e$N%U%!%$%kL>$NJQ49%k!<%k$r@_Dj!#(B + +1999-04-09 Yuuichi Teranishi + + * [elmo-imap4] LOGIN $B$G%Q%9%o!<%I$K6uGrJ8;z$,$"$k$P$"$$$K(B + $BG'>Z$K<:GT$9$k$N$r=$@5!#(B + ($B7'Ln$5$s(B $B$h$j8fJs9p(B) + +1999-04-07 $B2,ED(B $B7r0l(B + + * [NNTP] AUTHINFO $B$KBP1~!#(B + +1999-04-07 Yuuichi Teranishi + + * C-u . $B$G!"%-%c%C%7%e$,$"$C$F$b:FFI$_9~$_$9$k$h$&$K$7$?!#(B + * $B=i4|2=;~!"%M%C%H%o!<%/$K$D$J$,$C$F$$$J$/$F$b(B C-g $B$r2!$;$P(B + $B5/F0$G$-$k$h$&$K$7$?!#(B + +1999-04-06 SHIMADA Mitsunobu + + * Maildir $B$N%a!<%k$N:o=|!"%j%U%!%$%k$K<:GT$9$k>l9g$,$"$C$?$N$r=$@5!#(B + +1999-04-03 OKAZAKI Tetsurou + + * [wl-ja.texi] $BJQ?t(B wl-insert-mail-(followup|reply)-to $B$N=i4|@_DjCM(B + $B$N4V0c$$$r=$@5!#(B + +1999-04-02 Masahiro MURATA ($BB + + * $B?75,JQ?t(B elmo-nntp-get-folders-securely$B!#(BNon-nil $B$K$9$k$H(B + elmo-nntp-get-folders-info $B$,La$C$F$3$J$/$J$k$N$r=$@5$9$kJQ99$,(B + $BM-8z$K$J$k!#(Bdefault $B$O(B nil$B!#(B + +1999-04-02 nakagawa@pochi.tis.co.jp ($BCf@n(B $B@?(B) + + * cnews(?) $B$@$H(B elmo-nntp-get-folders-info $B$,La$C$F$3$J$/$J$j!"(B + $B%O%s%0$7$F$7$^$&$N$r=$@5!#(B + +1999-03-31 Yuuichi Teranishi + + * petname-alist $B$r(B obarray $B2=!#(B + * $B?75,JQ?t(B wl-summary-divide-thread-when-subject-changed$B!#(B + t $B$J$i%5%V%8%'%/%H$,JQ$o$C$?$H$-$K%9%l%C%I$r@Z$k$h$&$K$7$?!#(B + ($B$d$^$@$"$-$i$5$s(B $B$N8fMWK>(B) + * $B?75,JQ?t(B wl-summary-subject-filter-func $B%5%V%8%'%/%HHf3SA0$K(B + $B=hM}$r9T$&4X?t$r;XDj!#(B + * wl-summary-from-func, wl-summary-subject-func, + wl-summary-subject-filter-func $B$r(B funcall $B$9$k$N$r$d$a!"(B + $B5/F0;~$K(B fset $B$9$k$h$&$K$7$?!#(B + * wl-draft-config-exec-flag $B$r%P%C%U%!%m!<%+%kJQ?t$K$7$?!#(B + * Summary $B$G(B M->j->q $B$9$k$H%(%i!<$,H/@8$9$k$N$r=$@5!#(B + ($B2,ED$5$s(B$B$N8f;XE&(B) + * signature $B$N(B face $B$N%G%U%)%k%H$r?'$D$-%U%)%s%H$K$7$?!#(B + +1999-03-30 $B2,ED(B $B7r0l(B + + * $B6u9T$G(B'd'$B$G$-$J$$$h$&$K$7$?!#(B + * $B3:Ev$N(BMessage-Id$B$N5-;v$,F1$8%U%)%k%@$KJ#?t$"$k$H$-$K$=$N$&$A0l$D$r(B + $B%*%U%i%$%s$G:o=|$7$F(B elmo-dop-queue-flush $B$9$k$H!$(B + elmo-imap4-delete-msg-by-id$B$,<:GT$9$k$N$r=$@5!#(B + +1999-03-29 A. SAGATA + + * signature $BNN0h$N8!=P$r8-$/$7$?!#(B + * signature $B$r%O%$%i%$%H$9$k$h$&$K$7$?!#(B + +1999-03-26 Yuuichi Teranishi + + * $B8=:_$$$k!JF1$8!K%U%)%k%@$K8m$C$F(B goto-folder $B$9$k$H!"%5%^%j$,(B + $B2=$1$F$7$^$&LdBj$r=$@5(B($B1|@>$5$s(B + $B$N8f;XE&(B)$B!#(B + * $BJQ?t(B wl-draft-clone-local-variable-regexp ($B%G%U%)%k%H$O(B "^mime") + $B$K%^%C%A$9$k%m!<%+%kJQ?t$NCM$rAw?.%P%C%U%!$K%3%T!<$9$k$h$&$K$7$?!#(B + +1999-03-26 $B2,ED(B $B7r0l(B + + * $B?75,%3%^%s%I(B wl-summary-write-current-newsgroup () + Summary$B%b!<%I$G!$(Bcurrent-folder$B$N%K%e!<%9%0%k!<%W$KEj9F$9$k$H$-$K!$(B + Newsgroup: $B%U%#!<%k%I$r$"$i$+$8$aJd4V$7$F$+$i(Bdraft$B%P%C%U%!$rMQ0U(B + $B$9$k!#(B"W" $B$K%P%$%s%I!#(B + +1999-03-25 Hidekazu NAKAMURA + + * wl-summary-forward() $B$G!"(Bwl-mail-setup-hook $B$,8F$P$l$J$+$C$?(B + $B$N$r=$@5!#(B + +1999-03-25 Yuuichi Teranishi + + * $BB + + * wl-summary-temp-mark-uudecode $B$G%a%C%;!<%8(B1$B$D$@$1$N%U%!%$%k(B + $B$,%G%3!<%I$G$-$J$$$N$r=$@5!#(B + +1999-03-24 Yuuichi Teranishi + + * default-case-fold-search $B$,(B nil $B$N>l9g!"%a%C%;!<%8$,Aw?.$5$l$J$$(B + $B$N$r=$@5(B($B3k86$5$s(B$B$N8f;XE&(B)$B!#(B + +1999-03-24 $B2,ED(B $B7r0l(B + + * $B?75,%3%^%s%I(B wl-folder-close-parent-entity$B!"(BM-SPC $B$K%P%$%s%I!#(B + * $B?75,JQ?t(B wl-draft-config-exec-flag $B$r@_$1!"(Bwl-draft-config-exec $B$O(B + $B0lEY$7$+ + + * [im-wl.el] ($B:F(B) wl-insert-message-id $B$r(B nil $B$K@_Dj$7$F$b!"(BMessage-Id + $B$r$D$1$F$7$^$&=$@5(B($B@P@n$5$s(B $B$N8f;XE&(B)$B!#(B + * ($B:F(B)(featurep 'xpm) $B$N(B xemacs $B$r(B -nw $B$G$"$2$?$H$-$K(B wl $B$r5/F0$9$k$H(B + warning $B$,=P$k=$@5(B($B:72eED$5$s(B$B$N8f;XE&(B)$B!#(B + +1999-03-18 A.SAGATA + + * wl-ja.texi $B$K@bL@$rDI2C!#(B + * $B%I%i%U%H$G!"(B "To:" $B$d(B "Cc:" $B$N%X%C%@<+BN$NJd40$r$9$k$H$-$K!"(B + $B>.J8;z$+$i$G$bJd40$9$k$h$&$K$7$?!#(B + +1999-03-18 Yuuichi Teranishi + + * 0.9.7 - "Everything She Wants" + * multi $B%U%)%k%@$K$X$s$JF|IU$1$N%a%C%;!<%8$,$"$k$H(B msgdb $B@8@.$,(B + $BCfCG$5$l$F$7$^$&$N$r=$@5!#(B + +1999-03-17 A.SAGATA + + * petname $B$r%$%s%?%i%/%F%#%V$KJT=8$9$k4X?t$rDI2C!#(B + +1999-03-17 Yuuichi Teranishi + + * IMAP $B$NB8:_$7$J$$%U%)%k%@$K%j%U%!%$%k$7$h$&$H$7$F$d$a$k$H!"$=$N8e(B + $B8=:_$N%U%)%k%@$,A`:nITG=$K$J$C$F$7$^$&%P%0$r=$@5!#(B + ($B0$It$5$s(B $B$N8f;XE&(B)$B!#(B + * wl-folder-next-unsync $B$,%0%k!<%W$HDL>o%U%)%k%@$r6hJL$7$J$$$h$&(B + $B$K$7$?!#(B + * XEmacs $B$N%D!<%k%P!<%\%?%s$r2!$7$F(B sync $B$7$?$H$-$K%a%C%;!<%8$,(B + $BCfESH>C<$@$C$?$N$r=$@5!#(B + +1999-03-12 Tsunehiko Baba + + * 00README $B$r=$@5!#(B + +1999-03-12 Masato Taruishi + + * 00README $B$rDI2C!#(B + +1999-03-12 Yuuichi Teranishi + + * refile, copy $B$,0lIt<:GT$7$F$bA4BN$K1F6A$7$J$$$h$&$K$7$?!#(B + * wl-ja.texi $B$r(B ptex $B$G%U%)!<%^%C%H$7$F8+$d$9$$$h$&(Bsection $B3d$j$r(B + $B9=@.$7$J$*$9(B ($B?9F#$5$s(B $B$h$j8f;XE&(B)$B!#(B + +1999-03-09 Yuuichi Teranishi + + * $B$^$.$i$o$7$$$N$G%j%U%!%$%kCf!"%+!<%=%k$,%P%C%U%!KvHx$K(B + $B0\F0$7$J$$$h$&$K$7$?!#(B + +1999-03-06 Ishikawa Ichiro + + * [im-wl.el] wl-insert-message-id $B$r(B nil $B$K@_Dj$7$F$b!"(BMessage-Id + $B$r$D$1$F$7$^$&$N$r=$@5!#(B + +1999-03-04 Yuuichi Teranishi + + * tm-wl.el $B$N(B tm-wl-setup() $B$G!"(B + (fset 'mime-preview/x-face-function-use-highlight-headers nil) + $B$7$F$$$?$N$r$d$a$k!#(B + ($B:72eED$5$s(B $B$h$j8f;XE&(B) + * $B?75,%3%^%s%I(B wl-summary-refile-prev-destination "M-o" $B$K%P%$%s%I!#(B + ($B:72eED$5$s(B $B$h$j8fMWK>(B) + * $B?75,%3%^%s%I(B wl-summary-copy-prev-destination "M-O" $B$K%P%$%s%I!#(B + +1999-03-05 A.SAGATA + + * tm $B$r;H$C$F$$$k;~$K(B User-Agent: $B$K(B '\n' $B$,F~$C$F$7$^$&$N$r=$@5!#(B + * Subject $B$r(B [???, 0000] $B$N$h$&$K$D$1$k(B ML $B$KBP1~!#(B + +1999-03-04 A.SAGATA + + * (featurep 'xpm) $B$N(B xemacs $B$r(B -nw $B$G$"$2$?$H$-$K(B wl $B$r5/F0$9$k$H(B + warning $B$,=P$k$N$r=$@5!#(B + * $BJQ?t(B wl-auto-insert-x-face $B$NDI2C!#(B(default = t) + * wl-auto-insert-x-face t $B$G$+$D!"(B~/.xface $B$,$"$k$H$-$O<+F0E*$KA^F~!#(B + ($B:#$^$GDL$j(B,default) + * draft $B:n@.;~$K(B wl-draft-insert-x-face-field$B$G(B X-Face: $B$rA^F~2DG=(B + $B$H$7$?!#(B(C-c C-a $B$K%P%$%s%I(B) + * C-c C-a $B$N;~$K!"(B ~/.xface $B$,L5$1$l$P(B error message $B$rH/@8$5$;$k(B + $B$h$&$K$7$?!#(B + +1999-03-03 A.SAGATA + + * $B?75,(B hook wl-summary-refile-hook $B$rDI2C!#(B + +1999-03-03 Hajime MORITO + + * [wl-ja.texi] ptex $B$G@07A$9$k$H%(%i!<$K$J$k$N$r=$@5!#(B + * [wl-ja.texi] '{','}' $B$,I=<($5$l$F$$$J$$ItJ,$r=$@5!#(B + +1999-03-03 Yuuichi Teranishi + + * 0.9.6 - "Dirty Diana" + * [elmo] $B$X$s$J(B cache $B%U%!%$%k$,$"$C$?$H$-$K(B cache $B$N(B expire $B$,(B + $BF0$+$J$+$C$?$N$r2sHr!#(B + * $B?75,JQ?t(B wl-summary-auto-refile-skip-marks$B!#L$FI%a%C%;!<%8$O(B + auto-refile $B$NBP>]$+$i30$7$?!#(B + ($BBg>l$5$s(B $B$h$j8fMWK>(B) + * imap4 $B$G%a%C%;!<%8$rI=<($7$?$H$-$KM>J,$KL$FI%U%i%0$r%;%C%H(B + $B$7$F$$$?(B(!)$B$N$r=$@5!#(B + * [wl-ja.texi] wl-summary-wday-use-japanese $B$N5-=R$r:o=|!#(B + wl-summary-weekday-name-lang $B$N@bL@$rDI2C!#(B + ($B@P9u$5$s(B $B$h$j8f;XE&(B) + * [wl-ja.texi] wl-summary-fix-timezone $B$N5-=R$rDI2C!#(B + ($Bl$5$s(B $B$h$j8f;XE&(B) + +1999-03-01 Hermit-chan + + * wl-draft-folder $B$r@_Dj$7$F$$$k>l9g!"(B + M-x wl $B$9$kA0$K(B M-x wl-draft $B$9$k$H!"(Berror $B$K$J$k$N$r=$@5!#(B + +1999-03-01 Akihiro Motoki + + * wl-highlight $B$H(B ChangeLog $B$N(B typo $B=$@5!#(B + +1999-03-01 Yuuichi Teranishi + + * $B4X?t(B wl-ask-folder $B$,(B XEmacs $B$N%-!<0J30$N%$%Y%s%H$r$9$Y$F(B + $BF1$8$H$_$J$7$F$7$^$&$N$r=$@5!#(B + +1999-02-28 Masahiro MURATA ($BB + + * wl-draft-config-alist $B$N=q<0$r3HD%!#(B + +1999-02-26 TSUMURA Tomoaki + + * [wl-refile] extra-field $B$r + + * Summary $B$N%a%K%e!<$r=$@5!#(B + +1999-02-25 OKUNISHI Fujikazu + + * $B%U%#%k%?%U%)%k%@$NL$FI%A%'%C%/$,<:GT$9$k$N$r=$@5!#(B + +1999-02-10 OKUNISHI Fujikazu + + * draft $B$G(B font-lock $B$,M-8z$K$J$k$N$r2sHr!#(B + +1999-02-24 Yuuichi Teranishi + + * 0.9.5 - "California Girls" + +1999-02-25 Masahiro MURATA ($BB + + * wl-folder-notify-deleted $B$,(B 'sync $B$J$iIi$N?t$rI=<($;$:(B + $BF14|$5$;$k$h$&$K$7$?!#(B + +1999-02-24 Yuuichi Teranishi + + * $B?75,JQ?t(B wl-folder-notify-deleted$B!#%a%C%;!<%8$,:o=|$5$l$F$$$?$H$-(B + $B$KIi$N?t;z$rI=<($7$FCN$i$;$k$+$I$&$+!#(Bdefault $B$O(B nil $B$K$7$?!#(B + * wl-summary-auto-refile $B$r%G%U%)%k%H$G$O%9%l%C%I$rJD$8$?$^$^(B + $B=hM}$9$k$h$&$K$7$?!#(BPrefix argument $B$D$-$J$iA4%9%l%C%I$r3+$$$F(B + $B$+$i + + * $B?75,4X?t(B elmo-passwd-alist-{load,save}$B!#(B + $B?75,JQ?t(B elmo-passwd-alist-file-name $B$K@_Dj$5$l$?%U%!%$%k(B{$B$+$i(B|$B$X(B} + $B%Q%9%o!<%I$r(B{$B%m!<%I(B|$B%;!<%V(B}$B$9$k!#(B + +1999-02-11 Tsunehiko Baba + + * [wl-ja.texi] $B$K(B "~/.xface" $B$N@bL@$rDI2C!#(B + +1999-02-06 TSUMURA Tomoaki + + * wl-draft-replace-field () $B$G(B header $B$r(B insert $B$9$k$H$-$K(B + "\n" $B$r@h$K(B concatinate $B$7$F$+$i(B insert $B$9$k$h$&$K$7$?!#(B + +1999-02-06 $B2,ED(B $B7r0l(B + + * imap $B$GL$FI>pJs$r%3%T!<@h$K$b0z$-7Q$0$h$&$K$7$?!#(B + +1999-02-05 Yuuichi Teranishi + + * refile $B$N08@hMQ$N(B face$B!"(Bwl-highlight-refile-destination-face + $B$r?7@_!#(B + * [wl-ja.texi] '$' $B$N@bL@J8$r=$@5!#(B + ($B8eF#(B($B$H(B)$B$5$s(B $B$h$j8f=u8@(B) + +1999-02-04 Yuuichi Teranishi + + * XEmacs $B$G%U%)%k%@$NL$FI%A%'%C%/8e%O%$%i%$%H$,$*$+$7$/$J$k>l9g$,(B + $B$"$C$?$N$r=$@5!#(B + +1999-02-03 $B2,ED(B $B7r0l(B + + * $B?75,4X?t(B wl-folder-prefetch-entity$B!#(B"I" $B$K%P%$%s%I!#(B + +1999-02-03 Teruki SHIGITANI + + * [sample.dot.wl] my-wl-summary-from-func-petname $B$N(B + folder $BL>$r;2>H$9$kItJ,$r(B summary-mode $B$G$N$_8F$P$l$k$h$&$K$7$?!#(B + +1999-02-03 TSUMURA Tomoaki + + * $B4X?t(B wl-summary-auto-refile, wl-refile-rule-alist $B$NDI2C!#(B + +1999-02-02 IMAI Takeshi + + * wl-expire $B$G(B imap $B@h$K(B refile $B$9$k$H%(%i!<$K$J$k$N$r=$@5!#(B + +1999-01-29 Akihiro Motoki + + * Summary$B%b!<%I$N(B view $B$r(B cache $B$K%;!<%V$9$k$H$-!$(B + widen $B$9$k$h$&$KJQ99!#(B + +1999-01-22 Masahiro MURATA ($BB + + * wl-auto-check-folder-name $B$N3HD%!#(B + +1999-01-19 Masahiro MURATA ($BB + + * $B%U%)%k%@%b!<%I$G(B expire $B$r$9$k;~$K!$%5%^%j>pJs$r(Bupdate$B$7$F$+$i(B + expire $B$,9T$($k$h$&$K$7$?!#(B + * reserve-marked-msg $B$r>J$$$?7k2L!$(Bexpire$B$9$k%a%C%;!<%8$,$J$/(B + $B$J$k$H!$%(%i!<$,5/$3$k$N$r=$@5$7$?!#(B + * elmo-datevec-substitute $B$K$*$$$FG/$r$^$?$0>l9g$r9MN8$7$?!#(B + +1999-01-19 Yuuichi Teranishi + + * $B?75,JQ?t(B wl-auto-uncheck-folder-list, wl-auto-check-folder-list$B!#(B + $B5/F0;~$N%0%k!<%W%A%'%C%/$G%A%'%C%/$r%9%-%C%W$9$k$+$I$&$+@_Dj$G$-$k(B + $B$h$&$K$7$?!#(B($B85LZ$5$s(B $B$h$j8fMWK>(B) + $B%G%U%)%k%H$G$O(B archive $B%U%)%k%@$N%A%'%C%/$r%9%-%C%W!#(B + * [elmo-nntp] $B%5!<%P$+$i(B Message-ID $B$r$b$i$&ItJ,$,%P%0$C$F$$$?$N$r(B + $B=$@5!#(B + +1999-01-18 Yuuichi Teranishi + + * wl-ja.texi $B$r99?7(B (mA, mf $B$N@bL@DI2CEy(B)$B!#(B + * wl-folder-{prev,next}-unread $B$G(B unread $B$G$J$$(Bgroup$B$X$OHt$P$J$$(B + $B$h$&$K$7$?(B(Prefix ARG $B$D$-$J$i(B group $B$X$bHt$V(B)$B!#(B + ($B2,ED$5$s(B $B$N8f;XE&(B) + * wl-folder-check-entity $B$G%U%)%k%@$,$J$/$J$C$F$$$?$H$-$J$I(B + $B%(%i!<$G;_$^$C$F$7$^$&$N$r2sHr!#(B + ($B@P@n$5$s(B $B$h$j8f;XE&(B) + +1999-01-16 OKUNISHI Fujikazu + + * $B?75,4X?t(B wl-summary-temp-mark-uudecode$B!#(B + * wl-ja.texi $B$rJQ99(B (@item->@defvar $BEy(B)$B!#(B + +1999-01-15 OKUNISHI Fujikazu + + * wl-{folder|summary}-goto-folder() $B$G(B ~/.folders $B$K$J$$%U%)%k(B + $B%@$r;XDj$7$?>l9g$K$b!"B8:_$7$J$$(B property $B$r;2>H$7$h$&$H$7$F(B + $B$3$1$k%P%0$r=$@5!#(B + +1999-01-15 TSUMURA Tomoaki + + * [elmo-archive] header-regexp $B$G(B footer $B$b(B check$B!#(B + * [elmo-archive] rar $B$N05=LN($r>e$2$?!#(B + +1999-01-15 Masahiro MURATA ($BB + + * 19.28$B%Y!<%9$N(B Emacs $B$G(B wl-expire $B$,=PMh$J$+$C$?$N$r=$@5$7$?!#(B + * elmo-date $B$GG/$r$^$?$$$@;XDj$,9T$($k$h$&$K$7$?!#(B + * [fldmgr] Emacs-19 $B$G(B wl-fldmgr-add $B$,@5>o$KF0:n$7$J$+$C$?$N$r(B + $B=$@5$7$?!#(B + +1999-01-14 Masahiro MURATA ($BB + + * Emacs-19 $B0JA0$G$O%"%/%;%9%0%k!<%W$N3,AX9=B$$,:n$i$l$J$$$N$r=$(B + $B@5$7$?!#(B + * [fldmgr] $B6u$N%0%k!<%W$K%U%)%k%@$rA^F~$9$k$H%(%i!<$K$J$k$N$r=$(B + $B@5$7$?!#(B + * [expire] elmo $B$N8F=P$7$G<:GT$7$?>l9g$O%(%i!<$G;_$a$k$h$&$K$7$?!#(B + +1999-01-14 Yuuichi Teranishi + + * wl-summary-temp-mark-prefetch $B$,F0$+$J$/$J$C$F$$$?$N$G:F $B$N8f;XE&(B) + * Meadow$B$GF|K\8l(B Subject$B$N%a!<%k$KJV;v$r=q$3$&$H$9$k$H!$(B + $B%I%i%U%H$KMQ0U$5$l$?%a!<%k$N%5%V%8%'%/%H$,!$%(%9%1!<%W(B + $B%3!<%I4]=P$7$G2=$1$F$7$^$&$N$r=$@5!#(B + ($BHSED$5$s(B $B$N8f;XE&(B) + +1999-01-13 TSUMURA Tomoaki + + * Windows $B$G(B LHA archive $B$,F0$/$h$&$K=$@5!#(B + +1999-01-13 Yuuichi Teranishi + + * 0.9.4 - "Broken Wings" + * wl-folder-init-no-load-access-folders $B$H(B + wl-folder-init-load-access-folders $B$NN>J}$,(B nil $B$N$H$-!"(B + $BA4$F$N%U%)%k%@>pJs$r%m!<%I$7$J$+$C$?$N$r=$@5!#(B + * NNTP $B$N(B multi $B%U%)%k%@$rC&=P8e!"F1$8%U%)%k%@$K9T$-D>$9$H!"(B + fetch error $B$,H/@8$9$k>l9g$,$"$C$?$N$r=$@5!#(B + +1999-01-13 Masahiro MURATA ($BB + + * wl-folder-entity-alist $B$H(B wl-folder-entity-id-name-alist $B$r(B + obarray (hashtable) $B$K$7$?!#(B + * wl-folder-entity-alist $B$H(B elmo-folder-info-alist $B$rE}9g$7$?!#(B + * check $B;~$NI=<(99?7$r9bB.2=$7$?!#$^$?!$JQ?t(B + wl-folder-check-fast $B$rGQ;_$7$?!#(B + * $B=i4|2=;~$K%m!<%I$9$k%"%/%;%9%0%k!<%W$N%U%)%k%@$r;XDj$G$-$k$h$&$K(B + $B$7$?!#(B + * $B%"%/%;%9%0%k!<%W$N%j%9%H$r3,AX9=B$$G + + * wl-tmp-dir $B$,$J$1$l$P5/F0;~$K$D$/$k$h$&$K$7$?!#(B + ($BLgOF$5$s(B $B$h$j8f;XE&(B) + * wl-queue-folder $B$,$J$1$l$P5/F0;~$K:n$k$h$&$K$7$?!#(B + +1999-01-12 $B2,ED(B $B7r0l(B + + * window-width $B$,(B 100 $B$N;~$J$I$K!$(Bwl-demo $B$G(B xpm $B$,??$sCf$K$G$J$$(B + $B$N$r=$@5!#(B + +1999-01-12 TSUMURA Tomoaki + + * [elmo-archive] rar $B$N%Q%i%a!<%?DI2C$H(B windows-nt $B8~$1=$@5!#(B + +1999-01-12 Yuuichi Teranishi + + * [elmo-nntp] "-/" $B$GA4%K%e!<%9%0%k!<%W$rI=<($9$k$h$&$K$7$?!#(B + ($B@P@n$5$s(B $B$h$j8f;XE&(B) + ($B$7$+$7(B 1999-1-13 $B$NBe=q$-!#(B) + * unplugged $B$G(B filter $B%U%)%k%@$NF0:n$,$*$+$7$+$C$?$N$r=$@5!#(B + * 'mA' ($B0l;~%^!<%/$D$-%a%C%;!<%8$KBP$9$k%^%k%A0zMQ$D$-%j%W%i%$(B)$B!$(B + 'mf' ($B0l;~%^!<%/$D$-%a%C%;!<%8$N%^%k%A%U%)%o!<%I(B)$B!#(B + ($BKLL\$5$s(B $B$N8fMWK>$K4p$E$/(B)$B!#(B + * unplugged $B$K$7$?$"$H%5%^%j$rC&=P$9$k$H%-%c%C%7%e$,%;!<%V$5$l$J$$(B + $B%P%0$r=$@5!#(B + * [elmo-nntp] Cancel-Lock $B$KBP1~$7$?$D$b$j!#(B + +1999-01-08 Yuuichi Teranishi + + * wl-dnd.el XEmacs21.2.8 $B$N(B API $B$K9g$o$;$?!#(B + +1999-01-08 Masahiro MURATA ($BB + + * elmo-localdir-list-folders-subr() $B$G(B + $B?F%U%)%k%@$,4^$^$l$J$/$J$C$F$7$^$&$N$r=$@5!#(B + +1999-01-06 $B2,ED(B $B7r0l(B + + * $B?75,(B hook$B!$(Bwl-highlight-message-hook $BDI2C!%(B + +1999-01-05 OKUNISHI Fujikazu + + * [elmo-util] elmo-default-imap4-server $B$r(B + "hoge%imap_server@gw" $B$N$h$&$J7A<0$G$b;XDj$G$-$k$h$&$K$7$?!#(B + +1999-01-05 Hironori Fukuchi + + * To$B$KB8:_$7$J$$%"%I%l%9$r=q$$$FAw?.$9$k$H!"%_%K%P%C%U%!$K$O(B + sending...done$B$HI=<($5$l!"@5>o$KAw?.$5$l$?$+$N$h$&$K8+$($k$,(B + $B + + * wl-draft-edit-string() $B$G(B To: $B%U%#!<%k%I$,>o$K(B nil $B$K$5$l$F(B + $B$7$^$&%P%0(B (typo) $B$r=$@5!#(B + +1998-12-31 OKUNISHI Fujikazu + + * elmo-localdir-list-folders-subr() $B$G%5%V%G%#%l%/%H%j$,B8:_$9(B + $B$k?F%U%)%k%@$,=EJ#$7$F$7$^$&%P%0$r=$@5!#(B + * wl-summary-redisplay-no-mime() $B$G$O(B wl-break-pages $B$r(B nil $B$K(B + $BB+G{$9$k!#(B + * elmo-localdir-list-folders-subr() $B$G(B link count $B35G0$N$J$$%U%!(B + $B%$%k%7%9%F%`$G$bFs3,AX0J>e2C$7$?!#(B + +1998-12-27 Masahiro MURATA ($BB + + * $BF1$8L>A0$N%U%)%k%@$,%0%k!<%W$h$j$bA0$KB8:_$9$k$H%(%i!<$,H/@8$9$k$N$r(B + $B=$@5!#(B + +1998-12-27 OKUNISHI Fujikazu + + * [wl-folder] wl-folder-mark-as-read-all-current-entity() $B$GA4(B + $B$F$N%U%)%k%@$K0\F0$;$:!"?75,!?L$FI$,B8:_$9$k%U%)%k%@$@$1$r(B + catchup $B$9$k$h$&$K$7$?!J9bB.2=$N$?$a!K!#(B + +1998-12-25 Yuuichi Teranishi + + * Meadow $BEy$N(B Emacs20.2 $B0J2<$G%5%^%j$,J8;z2=$1$9$k%P%0$N=$@5$r(B + $BH?1G$7K:$l$F$$$?!#(B + ($B$P$P$5$s(B $B$h$j8f;XE&(B)$B!#(B + +1998-12-24 Yuuichi Teranishi + + * 0.9.3 - "Last Christmas" $B%/%j%9%^%98BDjHG(B(?) + +1998-12-23 Masahiro MURATA ($BB + + * $B%Q%9%;%Q%l!<%?$H$7$F(B "/" $B$r;H$C$F$$$?$N$r=$@5$7$?!#(B + * delete $B$N;HMQ$G(B delq $B$G:Q$`$H$3$m$OCV$-49$($?!#(B + +1998-12-21 Masahiro MURATA ($BB + + * $B?75,%U%!%$%k(B wl-expire$B!#(B + $B8E$$%a%C%;!<%8$r<+F0E*$K:o=|!&0\F0$9$k5!G=$rDI2C$7$?!#(B + * wl-fldmgr $B$r(B autoload $B2=$7$?!#(B + * wl-folder $B$G4v$D$+$N%3%^%s%I(B($B%0%k!<%W$N<+F0(Bopen$B4X78(B)$B$N@0M}!&9b(B + $BB.2=$r9T$C$?!#(B + * wl-demo.el $B$N%P%$%H%3%s%Q%$%k$G(B XEmacs $B0J30$G$O%m%4%U%!%$%k$r(B + $BFI$_9~$^$J$$$h$&$K$7$?!#(B + * [elmo-archive] elmo-archive-treat-file $B$,(B non-nil $B$N$H$-!$(B + elmo-archive-list-folders $B$G%G%#%l%/%H%j$,B8:_$7$J$$>l9g$K%(%i!<(B + $B$K$J$k$3$H$,$"$k$N$r=$@5$7$?!#(B + * [WL 838] $B$K$"$k8e$m$N(B2$B$D$N%Q%C%A$,Ev$?$C$F$$$J$+$C$?$N$rH?1G$7(B + $B$?!#(B + +1998-12-21 Yuuichi Teranishi + + * $BAw?.;~$K(B XEmacs $B$G%(%i!<$,H/@8$9$k$H(B wrong type argument $B%(%i!<$,(B + $BH/@8$9$k$N$r2sHr!#(B($B?@V:$5$s(B$B$h$j8f;XE&(B) + +1998-12-18 Yuuichi Teranishi + + * $B%/%j%9%^%9$i$7$$5$J,$r=P$7$F$_$?!#(B + * wl-draft $B$N0z?t$O%G%3!<%I$5$l$?J8;zNs$H$9$k$3$H$K$7$?!#(B + ($BCfB<$5$s(B $B$N=$@5$K4p$E$/JQ99(B) + * Meadow $BEy$N(B Emacs20.2 $B0J2<$G%5%^%j$,J8;z2=$1$9$k%P%0$N=$@5!#(B + ($BCfB<$5$s(B$B!"(B + $BF#0f$5$s(B $B$h$j8fJs9p(B) + +1998-12-17 Hidekazu NAKAMURA + + * "Re:" $B$r4^$a$F%(%s%3!<%I$5$l$k>l9g$K(B "Re: Re:" $B$H$J$C$F$7$^$&(B + $B$N$r2sHr!#(B + +1998-12-17 Yuuichi Teranishi + + * 0.9.2 - "Addicted To Love" + +1998-12-17 Masahiro MURATA ($BB + + * [fldmgr] $B6u$N%0%k!<%W$r:o=|$9$k$H!$(B + wl-folder-entity-id-name-alist $B$,2u$l$k>l9g$,$"$k$N$r=$@5$7$?!#(B + * [elmo-archive] method $B$K4X?t$,Dj5A$G$-$k$h$&$K$7$?!#(B + * [elmo-archive] 'tgz $B7A<0$G$bDI2C$H:o=|$,9T$($k$h$&$K$7$?!#(B + $B$^$?!$(B'tgz $B$N(B suffix $B$r(B ".tar.gz" $B$KJQ99$7$?!#(B + * [elmo-archive] elmo-archive-msgdb-create-as-numlist-subr2() $B$,(B + prefix $B$r9MN8$7$F$J$+$C$?$N$r=$@5!#(B + +1998-12-16 Yuuichi Teranishi + + * Draft $B%P%C%U%!$G!"(BMail $BMQ%a%K%e!<$N%3%^%s%I$NFbMF$r(B + wl $B$N$b$N$KCV$-49$($k$h$&$K$7$?!#(B + * smtp.el $B$,:G?7$N(B apel $B$G$J$/$H$bF0:n$9$k$h$&!"(B + open-network-stream-as-binary $B$,L$Dj5A$J$iDj5A$9$k$h$&$K$7$?!#(B + * smtp.el $B$r:G?7$N(B FLIM $B$N$b$N$K9g$o$;$?!#(B + +1998-12-16 Masahiro MURATA ($BB + + * [fldmgr] nntp$B$G$J$$%U%)%k%@$rDI2C$9$k$H!$(B + wl-folder-newsgroups-hashtb $B$,(B nil $B$K$J$k$N$r=$@5$7$?!#(B + +1998-12-16 Hidekazu NAKAMURA + + * SEMI $B$rMxMQ$9$k>l9g(B smtp.el $B$r%$%s%9%H!<%k$7$J$$$h$&(B WL-ELS $B$r(B + $BJQ99!#(B + +1998-12-15 Yuuichi Teranishi + + * In-Reply-To: $B$NF|IUItJ,$r(B "" $B$G3g$k$h$&$K$7$?!#(B + * wl-summary-rescan $B$G@8@.$5$l$?%5%^%j$NJ]B8$O!"%9%-%c%s=*N;;~$G$O(B + $B$J$/%5%^%j=*N;;~$K$^$H$a$F$d$k$h$&$K$7$?!#(B + * $B?75,JQ?t(B wl-folder-thread-indent-set-alist$B!#%U%)%k%@$4$H$K(B + $B%9%l%C%I$N%$%s%G%s%HJ8;zNs$rA*$Y$k$h$&$K$7$?!#(B + wl-thread-indent-level, wl-thread-have-younger-brother-str, + wl-thread-youngest-child-str, wl-thread-vertical-str, + wl-thread-horizontal-str, wl-thread-space-str $B$O(B + $B$3$l$K%^%C%A$7$J$$>l9g$N(B default $BCM$H$7$FMQ$$$k$h$&JQ99!#(B + * $B?75,JQ?t(B wl-folder-weekday-name-lang-alist$B!#%U%)%k%@$4$H$K(B + $BMKF|I=<($N8@8l$rA*$Y$k$h$&$K$7$?!#(B + wl-summary-weekday-name-lang $B$O$3$l$K%^%C%A$7$J$$>l9g$N(B + default $BCM$H$7$FMQ$$$k$h$&JQ99!#(B + * elmo-nntp.el,elmo-imap4.el,elmo-msgdb.el $B$G!"(Bmsgdb $B$KJ]B8$9$k(B + Subject, From $B$NJ8;zNs$N:n$jJ}$,4V0c$C$F$$$?$?$a!"Cf9q8l$d%O%s%0%k(B + $B$,2=$1$F$7$^$C$F$$$?$N$r=$@5!#(B + * Summary $B$N(B cache $B$N(B{$BA^F~(B|$BJ]B8(B}$B$r(B as-binary-{input|output}-file + $B$G9T$J$&$h$&$K$7!"%P%C%U%!$4$H$N(B mime-charset $B$G(B{encode|decode}$B$9$k(B + $B$h$&$K$7$?!#(B + * wl-init $B$G(B wl-draft-folder $B$,B8:_$7$J$$$H$-$b(B elmo-create-folder () + $B$r8F$V$h$&$K$7$?!#(B + * wl-generate-user-agent-string $B$r(B Nemacs $BBP1~!#(B + $B$D$$$G$K(B tm $B$N%P!<%8%g%s>pJs$bF~$l$k$h$&$K$7$?!#(B + * $B%a%C%;!<%8:o=|;~!"Ev3:%a%C%;!<%8$,JD$8$?%9%l%C%I$K1#$l$F$$$?$H$-$K!"(B + $B;R$I$b%9%l%C%I$r$*$+$7$J0LCV$KA^F~$7$F$7$^$&$3$H$,$"$k$N$r=$@5(B + ($B$7$?$D$b$j!D(B)$B!#(B + * bbdb-wl.el $B$G%P%$%H%3%s%Q%$%k$KI,MW$J%b%8%e!<%k$r(B require $B$9$k(B + $B$h$&$K$7$?!#(B + * smtp-via-smtp $B$r(B (as-binary-process) $B$G3g$C$?!#(B + ($B>.6L(B $B$5$s(B $BB>$h$j$$$?$@$$$?(B + $B8fJs9p$K4p$E$/(B) + * [wl-ja.texi] $B%G%U%)%k%H$G(B @directory $B$,M-8z$K$J$k$h$&$K$7$?!#(B + ($B@iED$5$s(B $B$h$j8f;XE&(B) + +1998-12-13 Yuuichi Teranishi + + * $B?75,%U%!%$%k(B wl-mule.el, wl-nemacs.el$B!#(B + * wl-nemacs $B%V%i%s%A$r%^!<%8!#(B + +1998-12-10 Masahiro MURATA ($BB + + * message-id $B$,4^$^$l$F$$$J$$(B In-Reply-To $B%U%#!<%k%I$,$"$k$H!$Be(B + $B$o$j$K(B Reference $B%U%#!<%k%I$,$"$C$F$b;2>H$5$l$J$$%P%0$r=$@5!#(B + +1998-12-11 Yuuichi Teranishi + + * 0.9.1 - "Yankee Rose" + +1998-12-10 Masahiro MURATA ($BB + + * $B%I%i%U%H%P%C%U%!$NL>A0$rJQ99$7$?!#(B("1" -> "+draft/1") + * $B?75,4X?t(B wl-jump-to-draft-buffer$B!#(B + * wl-draft-config-alist $B$N=hM}$G(B1$B$D%^%C%A$7$F$bB3$1$F=hM}$r9T$&(B + $B$h$&$K$7$?!#(B + * wl-draft-config-exec-hook $B$rDI2C!#(B + * $B?75,JQ?t(B wl-draft-always-delete-myself$B!#(B + * $B%"!<%+%$%V%U%)%k%@$N(B prefix $B$K?t;z$,4^$^$l$F$$$?>l9g!$(B + elmo-archive-list-folder $B$,>o$K(B nil $B$rJV$9$N$r=$@5$7$?!#(B + * elmo-*-copy-msgs $B$O@.8y$9$l$P(B non-nil $B$rJV$9$h$&$K$7$?!#(B + * elmo-move-msgs $B$G$N%3%T!<$K<:GT$9$l$P:o=|$r + + * elmo-match-string, elmo-match-buffer $B$r;H$($k$H$3$m$O;H$&$h$&$K$7$?!#(B + * wl-insert-mail-followup-to, wl-insert-mail-reply-to $B$N(B default $B$r(B + nil $B$K$7$?!#(B + * wl-ja.info $B$r(B Emacs 20.3 $B$G:n$k$h$&$K$7$?!#(B + * "M-x wl-draft" $B$G$b@5$7$/5/F0$G$-$k$h$&$K$7$?!#(B + * Mule $B$b%P%$%H%3%s%Q%$%k;~$N(B Warning $B$r8:$i$7$?!#(B + +1998-12-10 TSUMURA Tomoaki + + * pack-number $B8e$K!"(Bmsgdb $B$N(B number-alist $B$,99?7$5$l$F$J$+$C$?(B + $B$N$r=$@5!#(B + +1998-12-10 Yuuichi Teranishi + + * wl-bcc $B$,@_Dj$5$l$F$$$l$P(B mail-self-blind $B$NCM$K4X78$J$/(B Bcc: $B$r(B + $BA^F~$9$k$h$&$K$7$?(B (wl-fcc $B$HF0:n$r9g$o$;$?(B)$B!#(B + +1998-12-10 Akihiro Motoki + + * $B?75,JQ?t(B wl-bcc$B!#(Bnon-nil $B$N$H$-$O(B wl-bcc $B$NCM$,(B Bcc: $B$KF~$k!#(B + +1998-12-10 SENDA Shigeya + + * XEmacs $B8~$1$K(B wl-ja.texi $B$r=$@5!#(B + * wl-ja.texi $B$G(B vindex$B$,0l$DH4$1$F$$$?$N$r=$@5!#(B + * WL-ELS $B$G(B xemacs $B$N(B install-package $B$N$H$-(B info $B$,%$%s%9%H!<%k(B + $B$5$l$k$h$&$K$7$?!#(B + +1998-12-10 Yuuichi Teranishi + + * $B%9%l%C%I$NESCf$G!"JD$8$?%9%l%C%I$N%a%C%;!<%8$,$"$C$?;~!"(B + $B$=$N%a%C%;!<%80J9_$N%9%l%C%I$,A^F~$5$l$J$$%P%0$,$"$C$?$N$r=$@5!#(B + +1998-12-09 Masahiro MURATA ($BB + + * elmo-move-msgs, elmo-copy-msgs $B$G%*%W%7%g%s;XDj$K$h$j!$%U%)%k(B + $B%@85$NHV9f$N$^$^0\F0!$%3%T!<$9$k5!G=$NDI2C!#4XO"$7$F!$(B + elmo-append-msg $B$b%*%W%7%g%s$G;XDj$7$?HV9f$GDI2C$9$k5!G=$NDI2C!#(B + * 'localdir $B$+$i(B 'archive $B$K%3%T!<$9$k>l9g$O(B1$BEY$KJ#?t$N%a%C%;!<(B + $B%8$r=hM}$9$k$h$&$K$7$?!#(B + +1998-12-09 Yuuichi Teranishi + + * 0.9.0 - "With Or Without You" + * elmo-archive.el $B$N%P%$%H%3%s%Q%$%k;~$K(B Warning $B$,=P$J$$$h$&$K(B + $B$7$?!#(B + +1998-12-09 OKUNISHI Fujikazu + + * elmo-archive.el "v0.16 [981208/alpha]"$B!#(B + * copy-msgs() $B$G(B dst-spec $B$N%U%)%k%@$,$J$1$l$P:n$k$h$&$K$7$?(B + $B!J;{ED$5$s(B Masayuki TERADA $B$N$4;XE&!K!#(B + * elmo-archive-treat-file $B$,(B non-nil $B$N;~$K(B get-archive-name() + $B$G(B suffix $B$,(B regexp-quote() $B$5$l$F$J$$%P%0$r=$@5!#(B + +1998-12-09 Yuuichi Teranishi + + * wl-folder-check-entity $B$GBP>]%U%)%k%@$,$^$@(B + $BB8:_$7$J$$$H$-$O(B elmo-create-folder () $B$r8F$V$h$&$K$7$?!#(B + * wl-init $B$G(B wl-trash-folder $B$,B8:_$7$J$$$H$-$O(B + elmo-create-folder () $B$r8F$V$h$&$K$7$?!#(B + ($B1|@>$5$s(B $B$N8f;XE&(B) + +1998-12-08 Yuuichi Teranishi + + * XEmacs, Emacs $B$G%P%$%H%3%s%Q%$%i$,@8@.$9$k(B Warning $B$r8:$i$7$?!#(B + * mmelmo-imap4 $B$N(B mime-entity $B@8@.ItJ,$G(B parent $B$N07$$$,4V0c$C$F$$(B + $B$?$?$a%(%i!<$,H/@8$9$k>l9g$,$"$C$?$N$r=$@5!#(B + +1998-12-07 Yuuichi Teranishi + + * 00README.ja $B$N%a!<%j%s%0%j%9%H%"%I%l%9$,8E$$$^$^$@$C$?$N$r=$@5!#(B + +1998-12-06 Masahiro MURATA ($BB + + * wl-summary-buffer-view $B$,(B 'thread $B$N;~!$(Bwl-summary-cursor-up + $B$N(B hereto $B$,L5;k$5$l$F$$$?$N$r=$@5$7$?!#(B + * wl-thread-jump-to-next-unread, wl-thread-jump-to-prev-unread$B$G(B + hereto $B$,(B non-nil $B$N$H$-!$(Bsuccess-mark $B$,$J$/%+!<%=%k$,(B + failure-mark $B$N0LCV$K$"$k$H!$La$jCM$,(B nil $B$K$J$k$N$r=$@5$7$?!#(B + * $B%5%^%j$N%"%C%W%G!<%H;~$N:o=|$G=hM}$N?JD=$rI=<($9$k$h$&$K$7$?!#(B + +1998-12-06 OKUNISHI Fujikazu + + * elmo-localdir-pack-number() $B$N%G%P%C%0%3!<%I=|5n$H7P2aI=<(!#(B + * data scope $BLdBj$G(B free var $B$K$J$i$J$$$h$&$K(B elmo-call-func() + $B$G(B SPEC $B$rDL$9$h$&$K$7$?!J(Bbyte-compile warning $B$r>C$9$?$a!K!#(B + +1998-12-05 OKUNISHI Fujikazu + + * wl-ja.texi $B$N$$$/$D$+$N$"$d$^$j$r=$@5!#(B + +1998-12-05 Masahiro MURATA ($BB + + * $B?75,JQ?t(B elmo-archive-treat-file$B!#(Bnon-nil $B$N>l9g(B + $B$O(B archive $B%U%)%k%@$,%U%!%$%k$rBP>]$H$9$k$h$&$K$7$?!#(B + +1998-12-04 Masahiro MURATA ($BB + + * elmo $B$G:n@.$9$k0l;~%P%C%U%!$,(B WL $B$r=*N;$7$F$b;D$k>l9g$,$"$k$N(B + $B$r=$@5$7$?!#(B + * wl-summary-rescan $Bl9g$O%a%C%;!<%8$rI=<($7$J$$$h(B + $B$&$K$7$?!#(B + * elmo-archive-delete-msgs $B$,:o=|$K@.8y$7$?$H$-(B t $B$rJV$9$h$&$K$7$?!#(B + +1998-12-04 Yuuichi Teranishi + + * wl-summary-unread-message-hook $B$r(B + wl-summary-mark-as-read () $B$NCf$G8F$V$h$&JQ99!#(B + +1998-12-04 $B2,ED(B $B7r0l(B + + * $BL$FI5-;v$,FI$^$l$?$H$-$K8F$P$l$k(B wl-summary-unread-message-hook + $B$rDI2C!#(B + +1998-12-03 Masahiro MURATA ($BB + + * folder mode $B$G%"!<%+%$%V%U%)%k%@$r(B check $B$7$F$bI=<($,99?7$5$l$J(B + $B$$$H$-$,$"$k$N$r=$@5!#(B + +1998-12-03 Yuuichi Teranishi + + * wl_nemacs $B%V%i%s%A$r:n@.!"(BNemacs $BBP1~3+;O!#(B + * smtp.el $B$r(B flim-1.12 $BIUB0$N(B smtp.el $B$HF~$l49$(!"(B + $BJQ99$5$l$?(B API $B$K9g$o$;$?(B + (smtp-do-bcc $B$N:o=|!"(Bsmtp-via-smtp $B$N0z?t$NJQ99(B)$B!#(B + * im-wl.el $B$G$bJQ?t(B wl-insert-message-id $B$,$^$k$C$-$jL5;k$5$l$F$$$?(B + $B$N$r=$@5!#(B + * wl-summary-prefetch-msg $B;~!"Bg$-$J%a%C%;!<%8$G%(%i!<$,$G$F$7$^$&(B + $B%(%i!<$r=$@5!#(B + * $BIQHK$K;H$o$l$F$$$?(B append $B$r(B nconc $B$KCV$-49$($k$3$H$G(B + multi $B%U%)%k%@$NF0:n$rA4HL$K9bB.2=!#(B + +1998-12-02 OKUNISHI Fujikazu + Hironori Fukuchi + + * wl-ja.texi $B$N$$$/$D$+$N$"$d$^$j$r=$@5!#(B + +1998-12-02 Yuuichi Teranishi + + * alpha -> beta$B!#(B + * $B$3$l$^$G$N(B ChangeLog $B$r(B etc $B$K0\F0!#(B diff --git a/etc/ChangeLog.3 b/etc/ChangeLog.3 new file mode 100644 index 0000000..57e218a --- /dev/null +++ b/etc/ChangeLog.3 @@ -0,0 +1,2967 @@ +2000-03-24 Yuuichi Teranishi + + * 1.1.0 - "Overjoyed" + +2000-03-23 Yuuichi Teranishi + + * wl-refile.el (wl-refile-guess-func-list): Fixed defvar. + (Pointed out by KOYAMA Tetsuji ) + * 1.1.0pre6 - "Overjoyed-pre6" + * wl-folder.el (wl-create-folder-entity-from-buffer): + Fixed localnews definition problem. + (Pointed out by AOXI Tenghe + and others) + +2000-03-23 OKAZAKI Tetsurou + + * wl-summary.el (wl-summary-mode-menu-spec): Changed wl-draft + to wl-summary-write. + (wl-summary-msg-marked-as-target): + Renamed from wl-summary-msg-marked-as-temp. + * wl-thread.el (wl-thread-close-all): Renamed local variable. + +2000-03-22 Akihiro MOTOKI + + * wl-refile.el (wl-refile-guess-func-list): New variable. + (wl-refile-guess): Use wl-refile-guess-func-list. + +2000-03-22 Yuuichi Teranishi + + * wl-mime.el: Reduced byte compile warnings. + * wl-xmas.el,wl-mule.el,wl-nemacs.el (wl-make-modeline): Defined. + XEmacs shows plugged icon by default. + (Advised by Daiki Ueno ) + * wl-util.el (wl-make-modeline-subr): Renamed from wl-make-modeline. + * utils/bbdb-wl.el (bbdb-wl-update-record): Fixed sticky summary + problem. + (bbdb-wl-update-record, bbdb-wl-get-update-record): + Avoid raw buffer to be multibyte. + * wl-draft.el (wl-draft-reply): Likewise. + * 1.1.0pre5 - "Overjoyed-pre5" + +2000-03-21 Yuuichi Teranishi + + * NEWS.ja: New file. + * elmo-maildir.el (elmo-maildir-list-folders): + Bind elmo-have-link-count as nil. + (Advised by Masahiro MURATA ) + * wl-summary.el (wl-summary-edit-addresses-subr): Downcase addresses. + +2000-03-18 TAKAHASHI Kaoru + + * NEWS: New file. + +2000-03-17 Yuuichi Teranishi + + * wl-message.el (wl-message-follow-current-entity): + Refer original buffer. + (Pointed out by OKAZAKI Tetsurou ) + * elmo-maildir.el (elmo-maildir-list-folders): + Check if directory is Maildir. + (Pointed out by ) + +2000-03-15 Yuuichi Teranishi + + * wl-folder.el (wl-create-folder-entity-from-buffer): + Fixed space regexp. + * wl-summary.el (wl-summary-edit-addresses): Get address from original + buffer. + (wl-summary-prefetch): Don't bind wl-prefetch-threshold as nil. + +2000-03-14 Yuuichi Teranishi + + * 1.1.0pre4 - "Overjoyed-pre4" + * Fixed error messages in all files (don't finish message with ".") + * elmo/elmo-archive.el (elmo-archive-copy-msgs): + Don't use filename when same-number is non-nil in maildir. + * wl-expire.el (wl-expire-archive-get-folder): + Use elmo-replace-msgid-as-filename instead of elmo-safe-filename. + * wl-folder.el (wl-folder-goto-folder-subr): Set default as + wl-default-folder. + (Adviced by okada@opaopa.org (Kenichi OKADA)) + * wl-folder.el (wl-create-folder-entity-from-buffer): + Allow white space in folder name. + * wl-summary.el (wl-summary-jump-to-msg-by-message-id): + Use wl-thread-jump-to-msg when message was found in current folder. + +2000-03-13 Yuuichi Teranishi + + * wl-vars.el (wl-summary-skip-mark-list): New variable. + * wl-summary.el (wl-summary-prefetch): Set wl-prefetch-threshold + nil only when interactive-p. + (Pointed out by Akihiro MOTOKI ) + (wl-summary-exec-subr): Fixed mark counting bug. + (Pointed out by OKAZAKI Tetsurou ) + (wl-summary-next, wl-summary-prev): Use wl-summary-skip-mark-list. + (wl-summary-move-cached-regex): defmacro->defun. + * etc/ja.Emacs: Update. + * elmo-imap4.el (elmo-imap4-search): Regard from-msgs. + * elmo-maildir.el (elmo-maildir-search): Fixed. + * mmelmo-imap4-1.el (mmelmo-imap4-parse-bodystructure-string): + Fixed literal parsing. + +2000-03-13 Masahiro MURATA + + * wl-expire.el: Fixed problem of expiring in filter folder. + * wl-fldmgr.el: Inhibited newline character in folder name or petname. + +2000-03-12 Masahiro MURATA + + * wl-fldmgr.el (wl-fldmgr-get-path-from-buffer): + Fixed problem when wl-desktop group is closed. + +2000-03-11 Masahiro MURATA + + * wl-folder.el (wl-folder-mode-menu-spec): Updated. + +2000-03-08 TAKAHASHI Kaoru + + * wl-vars.el (wl-score-files-dir): Renamed from + wl-score-files-directory. + * wl-score.el (wl-score-edit-file, wl-score-load-file, + wl-score-change-score-file): Ditto. + +2000-03-08 Yuuichi Teranishi + + * wl-vars.el (wl-mime-charset): Set default value as x-ctext. + +2000-03-08 okada@opaopa.org (Kenichi OKADA) + + * elmo-nntp.el (elmo-nntp-list-folders): + Fixed problem when root name is "". + +2000-03-07 Yuuichi Teranishi + + * 1.1.0pre3 - "Overjoyed-pre3" + * elmo-imap4.el (elmo-imap4-create-msgdb-from-overview-string): + Use local unread information. + * elmo2.el (elmo-delete-folder): Added maildir folder. + (elmo-move-msgs): Local unread information was not taken over. + * elmo-maildir.el (elmo-maildir-delete-folder): Rewrite. + * mmelmo.el (mime-parse-parameters-from-list): + Moved from mmelmo-imap4.el. + * wl-message.el (wl-mmelmo-message-redisplay): + Bind mime-display-header-hook as nil. + * wl-mime.el (wl-mime-display-message): Fixed SEMI version detection. + (wl-summary-burst): Don't refer mime-message-structure. + (wl-mime-entity-read-field): New alias/macro. + (wl-mime-combine-message/partial-pieces): + Use wl-mime-entity-read-field. + (mime-edit-user-agent-value): + Workaround for duplicated XEmacs beta version (for SEMI 1.13.4 + or earlier). + +2000-03-06 katsuta@cced.mt.nec.co.jp + + * elmo-util.el (elmo-buffer-field-condition-match): + Fix problem when std11-field-body returns nil. + +2000-03-04 okada@opaopa.org (Kenichi OKADA) + + * wl-summary.el (wl-summary-prefetch-msg): Don't refer mark. + +2000-03-06 Yuuichi Teranishi + + * wl-summary.el (wl-summary-read-folder): Use default when "". + * wl-fldmgr.el, wl-folder.el, etc: Begin message with upcase character. + * wl-draft.el (wl-draft-yank-original): + Fix problem in citation from kill-ring. + * mmelmo-1.el (insert-header): + Use mmelmo-insert-sorted-header-from-buffer. + (insert-text-content): New method. + Add (run-hooks 'mmelmo-entity-content-inserted-hook). + * utils/bbdb-wl.el (bbdb-wl-show-bbdb-buffer): New function. + Added to wl-summary-toggle-disp-folder-message-resumed-hook. + * 1.1.0pre2 - "Overjoyed-pre2" + * elmo-maildir.el (elmo-maildir-sequence-number-internal): New variable. + (elmo-maildir-make-unique-string): Definition for v19. + Don't use elmo-maildir-sequence-number-internal. + (elmo-maildir-temporal-filename): Don't wait 2 seconds. + (toplevel): Added (eval-when-compile (require 'cl). + * wl-summary.el (wl-summary-buffer-number-column-detect): + Don't use return value of re-search-forward. + +2000-03-06 okada@opaopa.org (Kenichi OKADA) + + * elmo-pop3.el (elmo-pop3-port-label): Fixed typo (port->ssl). + * elmo-nntp.el (elmo-nntp-sync-number-alist): + Fixed bug that unread number sometimes becomes negative. + +2000-03-06 Yuuichi Teranishi + + * wl-summary.el (wl-summary-switch-to-clone-buffer): + Take over wl-summary-buffer-number-column, + wl-summary-buffer-number-regexp. + (wl-summary-write): New command. Binded to 'w'. + * wl-draft.el (wl-draft): Added behaviors for wl-summary-write. + +2000-03-05 Yuuichi Teranishi + + * elmo-cache.el (elmo-cache-list-folder-subr): Ignore directories. + * wl-summary.el (wl-summary-insert-line): New function. + (wl-summary-insert-summary, wl-summary-update-thread): + Use `wl-summary-insert-line'. + * wl-thread.el (wl-thread-update-line-on-buffer-sub): + Ditto. + * WL-MK (wl-info-lang): Install each element when listp. + * elmo/elmo-maildir.el (elmo-maildir-append-msg): + Use same name with tmp in new. + (elmo-maildir-list-folders): Contain root. + +2000-03-04 okada@opaopa.org (Kenichi OKADA) + + * wl-summary.el (wl-summary-buffer-set-folder): Deleted column setting. + (wl-summary-goto-folder-subr): Dynamic detecting of column number. + (wl-summary-target-mark-forward): Fixed order of forward. + (wl-summary-cleanup-temp-marks): Delete target marks. + +2000-02-29 Ryota Nishikawa + + * wl-draft.el (wl-draft-send-mail-with-pop-before-smtp): + Workaround for error which occurs in offline status. + +2000-03-04 Yuuichi Teranishi + + * wl-thread.el (wl-thread-update-children-number): + Renamed from wl-thread-update-children-number. + New hook, wl-thread-update-children-number-hook. + +2000-03-04 Masahiro MURATA + + wl-folder.el (wl-folder-sync-entity, + wl-folder-mark-as-read-all-entity, + wl-folder-prefetch-entity): Fixed highlighing in sticky + summary. + +2000-03-03 Yuuichi Teranishi + + * elmo2.el (elmo-move-msgs): Skip saving unread info when target is + 'null. + * elmo-maildir.el (elmo-maildir-make-unique-string): + Renamed from elmo-maildir-create-unique-string. + (Adviced by OKAZAKI Tetsurou ) + * 1.1.0 pre1 - "Overjoyed-pre1" + +2000-03-02 Yuuichi Teranishi + + * wl-draft.el (wl-draft-reply-buffer): New buffer local variable. + (wl-draft-reply): Set `wl-draft-reply-buffer'. + (wl-draft-config-exec): Refer `wl-draft-reply-buffer'. + (wl-draft-reply): Eliminated. + * WL-MK, WL-CFG (wl-info-lang): New variable. + * wl.texi: New file. + * Makefile, WL-MK, WL-CFG: ELISPDIR->LISPDIR. + (Adviced by TAKAHASHI Kaoru ) + * elmo-maildir.el: Rewrite. + * elmo-util.el, elmo-msgdb.el, elmo-vars.el: Define + maildir's spec as '.'. + * wl-folder.el, wl-summary.el, elmo-pop3.el, etc: + Upcase messages' first character. + * elmo-vars.el (elmo-maildir-folder-path): New variable. + * elmo-internal.el (elmo-internal-list-folders): Return + 'cache and 'mark in root. + +2000-03-02 okada@opaopa.org (Kenichi OKADA) + + * elmo-nntp.el: Fixed starttls. + * elmo-nntp.el, elmo-imap4.el: + Fixed a bug that elmo-list-folders deletes "!". + +2000-03-01 TAKAHASHI Kaoru + + * wl-score.el: Use "Invalid" instead of "Illegal" in error + message. + +2000-03-01 okada@opaopa.org (Kenichi OKADA) + + * wl-summary.el (wl-summary-refile-subr): Adjust target name for cache. + * elmo-nntp.el: starttls feature. (experimental) + +2000-03-01 Yuuichi Teranishi + + * elmo-cache2.el: Merged to elmo-cache.el. + * elmo-internal.el, elmo-util.el, elmo-msgdb.el: + Tread 'cache' as a part of internal. + +2000-03-01 okada@opaopa.org (Kenichi OKADA) + + * elmo-cache2.el: New backend 'cache'. + +2000-02-29 IMAI Takeshi + + * wl-expire.el (wl-folder-expire-entity): Fixed highlighing in sticky + summary. + +2000-02-28 Yuuichi Teranishi + + * elmo2.el (elmo-move-msgs): Take over unread status. + Added `unread-marks' argument. + * wl-summary.el (wl-summary-exec): + Take over unread marks to elmo-move-msgs. + (wl-summary-edit-petname): Now To and Cc are also candidate. + (wl-summary-edit-addresses): Renamed from `wl-summary-edit-petname'. + (wl-summary-edit-petname): Eliminated. + (wl-summary-mark-as-unread): Consider cache status. + * wl-vars.el (wl-summary-toggle-disp-folder-message-resumed-hook) + (wl-summary-line-inserted-hook): New hook. + (wl-summary-print-destination): + Put 'wl-summary-destination property. + * wl-thread.el, wl-summary.el: Call wl-summary-line-inserted-hook. + * utils/bbdb-wl.el: + Popup in wl-summary-toggle-disp-folder-message-resumed-hook. + +2000-02-28 Masahiro MURATA + + * Scoring in wl-folder-sync-current-entity. + * wl-summary-buffer-disp-msg sometimes wrong in sticky summary. + +2000-02-25 okada@opaopa.org (Kenichi OKADA) + + * wl-message.el (wl-message-refer-article-or-url): + Don't call wl-summary-redisplay + when wl-summary-jump-to-msg-by-message-id failed. + * wl-vars.el (wl-local-domain): Changed initial setting. + * wl.el (wl-check-environment): Regard wl-local-domain as local domain + without hostname. + * wl-util.el (wl-draft-make-message-id-string): Ditto. + +2000-02-25 Yuuichi Teranishi + + * wl-expire.el (wl-folder-expire-entity): Call wl-summary-save-status. + +2000-02-24 Yuuichi Teranishi + + * wl-vars.el (wl-draft-send-hook): New hook. + * wl-draft.el (wl-draft-send): Call wl-draft-send-hook. + (Demand from Kenichi Sato ) + +2000-02-23 Yuuichi Teranishi + + * elmo-cache.el (elmo-cache-save): + Added (condition-case), a workaround for long file name. + (Report by Mikya Tani ) + * wl-draft.el: Consider FCC IMAP's modified utf7. + (Pointed out by HIRATA Naoto ) + +2000-02-21 Yuuichi Teranishi + + * wl-address.el (wl-address-header-extract-address): Don't + regard '\n' as a e-mail address character. + (Pointed out by + Tomotaka SUWA ) + * mmelmo.el (mmelmo-header-max-column): New variable. + (Demand by Kenichi Sato ) + (mmelmo-header-inserted-hook): New hook. + (mmelmo-entity-content-inserted-hook): New hook. + * mmelmo-2.el (mime-insert-text-content): New entity method. + Call mmelmo-entity-content-inserted-hook. + * mmelmo.el (mmelmo-insert-sorted-header-from-buffer): + Moved from elmo-util.el and use `mmelmo-header-max-column'. + Call mmelmo-header-inserted-hook. + +2000-02-18 Yuuichi Teranishi + + * wl-message.el (wl-mmelmo-message-redisplay): + Use wl-mime-display-message. + (Pointed out by Toshihiko Kodama ) + * wl-mime.el (wl-mime-display-message): New macro/alias. + * 2.2.18 - "Please Forgive Me" + * wl-summary.el (wl-summary-move-cached-regex): + Added ignoring expression of 'D' mark for unplugged status. + * elmo-msgdb.el (elmo-msgdb-expand-path): Downcase IMAP4's INBOX + (Pointed out by Takeshi Chiba ). + * wl-folder.el (wl-create-folder-entity-from-buffer): + Changed expression of detecting access group for '}'. + * wl-message.el (wl-mmelmo-message-redisplay): + Pass major-mode to mime-display-message. + +2000-02-18 Daiki Ueno + + * wl-demo.el: Fixed for Emacs 21. + +2000-02-17 Yuuichi Teranishi + + * mmelmo-imap4-2.el (mime-entity-buffer): Don't change current buffer. + Fetch skipped part. + * mmelmo-imap4-2.el (mime-write-entity-content): + New method. Fetch skipped part. + * mmelmo-imap4-2.el (mmelmo-imap4-fetched): + New buffer local variable. + * elmo-imap4.el (elmo-imap4-server-namespace): + New buffer local variable. + (elmo-imap4-open-connection): + Set elmo-imap4-server-namespace. + (elmo-imap4-parse-namespace): New function. + (elmo-imap4-process-folder-list): + Use elmo-imap4-server-namespace. + (elmo-imap4-extra-namespace-alist): New variable. + * wl-util.el (wl-string-member, wl-string-match-member, + wl-string-delete-match, wl-string-match-assoc, wl-string-rassoc): + Renamed to elmo-* and define as defalias. + +2000-02-17 Yuuichi Teranishi + + * bbdb-wl.el: Added wl-summary-toggle-disp-folder-off-hook's setting. + +2000-02-16 Daiki Ueno + + * wl-demo.el: Caluculate frame's font parameter. + +2000-02-14 Yuuichi Teranishi + + * wl-summary.el (wl-summary-toggle-disp-folder): New implementation. + (Pointed out by Shigeru OKUMURA ) + * wl-draft.el (wl-draft-insert-x-face-field-here): Delete white spaces. + (Pointed out by Akihiro MOTOKI ) + +2000-02-12 Akihiro MOTOKI + + * elmo/elmo-localdir.el + (elmo-localdir-msgdb-create-overview-entity-from-file): + Pass value of `current-time-zone' to `timezone-make-date-arpa-standard'. + +2000-02-10 Yuuichi Teranishi + + * elmo/mmelmo-imap4-2.el (mmelmo-imap4-node-id-to-string): + "header" -> "0". + * elmo/mmelmo-imap4-1.el (mmelmo-imap4-node-id-to-string): + Ditto. + (Pointed out by TSUMURA Tomoaki ) + * wl-message.el (wl-message-follow-current-entity): wl-draft-reply + pass summary buffer to `wl-draft-reply'. + * wl-summary.el (wl-summary-reply): + pass current-buffer to `wl-draft-reply'. + (wl-summary-msgdb-load-async): enclose mailbox with "". + * elmo-imap4.el: Ditto. + +2000-02-09 UENO Kazuaki + + * wl-draft.el (wl-draft-queue-flush): Use `elmo-dop-flush-confirm'. + +2000-02-09 Yuuichi Teranishi + + * wl-draft.el (wl-draft): Changed initialization order. + (Adviced by Taiji.Can@atesoft.advantest.co.jp) + +2000-02-08 Masahiro MURATA + + * wl-score.el (wl-summary-score-update-all-lines): + Consider folder type when putting read-uncached mark. + +2000-02-08 Yuuichi Teranishi + + * wl-summary.el (wl-summary-target-mark-prefetch): Fixed for + uncached message's mark. + (Pointed out by Hironori Fukuchi ) + * wl-summary.el (wl-summary-target-mark-prefetch): + Display progress. Remain '*' marks if not prefetched. + * wl-dnd.el (start-drag): defined with static-cond. + * elmo2.el (elmo-buffer-cache-message): Fixed the bug of `Quit'ting + while reading. + * elmo-filter.el (elmo-filter-list-folder-important): + Don't call 'elmo-search'. + (Adviced by Akihiro MOTOKI ) + +2000-02-07 Daiki Ueno + + * wl-xmas.el (wl-highlight-folder-current-line): + Don't use set-extent-properties. + + * wl-draft.el (wl-smtp-extension-bind): Fixed. + +2000-02-07 Akihiro MOTOKI + + * elmo-util.el (elmo-buffer-field-condition-match): + Compare field value after `eword-decode-string'. + +2000-02-07 Yuuichi Teranishi + + * wl-dnd.el: Eliminated byte-compile warnings. + (Pointed out by okada@opaopa.org (Kenichi OKADA).) + * utils/sasl/sha1.el, utils/sasl/md5-el.el, + utils/sasl/hex-util.el, utils/sasl/sha1-el.el: Update. + (Pointed out by okada@opaopa.org (Kenichi OKADA).) + * wl-vars.el (wl-demo-use-bitmap): Renamed to wl-demo-display-logo. + (wl-demo-display-logo): New variable. + * wl-demo.el: Use wl-demo-display-logo. + +2000-02-07 okada@opaopa.org (Kenichi OKADA) + + * wl-vars.el (wl-demo-use-bitmap): Changed initial value. + +2000-02-07 Yuuichi Teranishi + + * 2.2.17 - "One Of Us" + * elmo-util.el (elmo-y-or-n-p): New function. + * elmo-vars.el (elmo-dop-flush-confirm): New variable. + * elmo-dop.el (elmo-dop-queue-flush): Use elmo-y-or-n-p, + elmo-dop-flush-confirm. + * elmo-imap4.el (elmo-delete-msgids): Display progress. + Call expunge once at last. + +2000-02-07 Daiki Ueno + + * wl-folder.el, wl-xmas.el: Display icons although a frame is opened + by XEmacsen invoked with -nw argument. + +2000-02-06 Yuuichi Teranishi + + * wl-highlight.el (wl-highlight-summary-target-face): New face + (Renamed from ...-temp-face). + * wl-vars.el (wl-demo-use-bitmap): Moved from wl-demo.el. + Defined as defcustom. Initial value is + (module-installed-p 'bitmap). + * wl-demo.el (wl-demo-use-bitmap): Moved to wl-vars.el. + * elmo-vars.el: Require 'poe, eliminated bytecompiling warnings. + * wl-nemacs.el (buffer-disable-undo, rassoc, delete, string-to-number, + window-live-p, completing-read, accept-process-output, + get-buffer-window): Eliminated. + +2000-02-04 TAKAHASHI Kaoru + + * wl-demo.el (wl-demo): Check wl-demo-use-bitmap at run-time. + +2000-02-04 Yuuichi Teranishi + + * INSTALL, INSTALL.ja: Changed tm-8's URL. + * utils/hmac -> utils/sasl. + * WL-ELS: HMAC->SASL. + * WL-MK: HMAC->SASL. + +2000-02-04 Yuuichi Teranishi + + * elmo-localdir.el + (elmo-localdir-msgdb-create-overview-entity-from-file): + Use `timezone-make-date-arpa-standard' instead of `format-time-string'. + * elmo-vars.el (elmo-time-format): Eliminated. + +2000-02-03 Yuuichi Teranishi + + * elmo-dop.el (elmo-dop-queue-flush): Added canceling process of + append-operations. + * wl-summary.el (wl-summary-refile-prev-destination, + wl-summary-copy-prev-destination): Fixed. + (Reported by IMAI Takeshi ) + +2000-02-02 Akihiro MOTOKI + + * wl-vars.el (wl-prefetch-confirm-threshold): Eliminated and separated + to `wl-prefetch-confirm' and `wl-prefetch-threshold'. + (wl-prefetch-confirm, wl-prefetch-threshold): New variable. + * wl-summary.el (wl-summary-prefetch-msg): Use wl-prefetch-confirm, + wl-prefetch-threshold. + +2000-02-02 Daiki Ueno + + * wl-draft.el (wl-smtp-features): `smtp-authenticate-type' is changed + to symbol. + +2000-01-31 okada@opaopa.org (Kenichi OKADA) + + * elmo-nntp.el (elmo-nntp-get-folders-info): Fixed. + +2000-01-31 Daiki Ueno + + * wl-demo.el: Display wl-logo.xpm in Emacs21. + +2000-01-30 TAKAHASHI Kaoru + + * INSTALL, INSTALL.ja: Fixed. + +2000-01-30 OKUNISHI -GTO- Fujikazu + + * WL-ELS: Add elmo-database to ELMO-MODULES + if open-database is already defined. + +2000-01-30 Akihiro MOTOKI + + * elmo-loacaldir.el + (elmo-localdir-msgdb-create-overview-entity-from-file): + If Date: field does not exist, get file's modified time. + * elmo-msgdb.el (elmo-msgdb-create-overview-from-buffer): + Added argument time. + * elmo-vars.el (elmo-time-format): New variable. + +2000-01-29 okada@opaopa.org (Kenichi OKADA) + + * wl-summary.el (wl-summary-jump-to-msg-by-message-id): + Added selecting NNTP server option. + (wl-summary-jump-to-msg-by-message-id-via-nntp) + Now server can be specified like "-:username@servername:8119!". + * elmo-nntp.el (elmo-nntp-folder-postfix): Added argument `ssl'. + +2000-01-29 OKUNISHI -GTO- Fujikazu + + * elmo-vars.el (elmo-database-dl-module, elmo-database-dl-handle): + New variable. + (toplevel): if elmo-database-dl-handle is non-nil, + dynamic_call emacs_database_init. + (elmo-use-database): Set elmo-use-database when open-database + is bound. + * WL-ELS: If 'dynamic-link is bound, add elmo-database to ELMO-MODULES. + +2000-01-28 TAKAHASHI Kaoru + + * wl-demo.el (wl-demo): Fix copyright information. + +2000-01-27 Takeshi Chiba + + * mmelmo-imap4-2.el ([luna]mime-entity-buffer): + section "0" -> "header". + +2000-01-27 Yuuichi Teranishi + + * mmelmo-imap4-2.el (mmelmo-imap4-node-id-to-string): + section "0" -> "header". + * mmelmo-imap4-1.el: Ditto. + +2000-01-26 OKAZAKI Tetsurou + + * elmo-imap4.el (elmo-imap4-create-folder): + UW imapd-4.7 cannot create new folder. + +2000-01-26 Yuuichi Teranishi + + * mmelmo-imap4-2.el (mmelmo-imap4-parse-bodystructure-string): + Retrieve BODYSTRUCTURE. + (mmelmo-imap4-parse-bodystructure-object): + Don't cause error when content-type subtype is NIL. + * mmelmo-imap4-1.el: Ditto. + * utils/hmac/unique-id.el: New file. + * WL-ELS (HMAC-MODULES): Added scram-md5, digest-md5, unique-id. + * wl-dnd.el (wl-dnd-drop-func): Fixed. + * 2.2.16 - "No Son Of Mine" + +2000-01-25 Yuuichi Teranishi + + * wl-vars.el (wl-summary-reserve-mark-list): New variable. + * wl-summary.el: temp-mark -> target-mark changed name. + Use `wl-summary-reserve-mark-list' in mark commands. + * wl-score.el, wl-thread.el: Ditto. + * wl-folder.el (toplevel): require 'wl. + +2000-01-24 Yuuichi Teranishi + + * wl-mule.el, wl-xmas.el, wl-nemacs.el (wl-summary-format-date): + Moved to wl-summary.el. + * utils/hmac/lisp/sasl.el, utils/hmac/lisp/digest-md5.el, + utils/hmac/lisp/scram-md5.el: Update to latest SLIM. + * wl-fldmgr.el (wl-fldmgr-ext): Changed confirm message. + * doc/TODO.ja: Updated. + +2000-01-22 OKAZAKI Tetsurou + + * wl-folder.el (toplevel): Fixed menu. + +2000-01-21 okada@opaopa.org (Kenichi OKADA) + + * elmo-imap4.el: Added DIGEST-MD5 authentication. + * elmo-pop3: Added CRAM-MD5, DIGEST-MD5, SCRAM-MD5 authentication. + +2000-01-21 Yuuichi Teranishi + + * wl-summary.el (toplevel): Changed binding position for + region commands. + (wl-summary-prefetch-region): Prefetch hided messages. + (Reported by OKAZAKI Tetsurou ) + * elmo: Added argument no-see to append-msg, move-msgs. + * elmo-pipe: Specify 'no-see at elmo-msg-move. + * wl-folder.el (wl-folder-mimic-kill-buffer): New command. + (toplevel): Bind ` wl-folder-mimic-kill-buffer' to C-xk, + `wl-save' to C-xC-s. + +2000-01-19 Yuuichi Teranishi + + * wl-nemacs.el (accept-process-output): New function. + * Makefile: Modified comment. + +2000-01-17 Yuuichi Teranishi + + * elmo-util.el (elmo-folder-identical-system-p): Don't treat + folders which have same mailbox name and different server + as identical folder. + (Pointed out by Tatsuya Matsui ) + * wl-address.el (wl-complete-field-body-or-tab): Eliminated argument. + +2000-01-13 Yuuichi Teranishi + + * wl-vars.el + (wl-prefetch-confirm-threshold, wl-cache-fetch-threshold): + New variables. + * wl-summary.el (wl-summary-prefetch-msg): + Use `wl-prefetch-confirm-threshold'. + (wl-cache-prefetch-message): Use `wl-cache-fetch-threshold'. + +2000-01-13 okada@opaopa.org (Kenichi OKADA) + + * wl-message.el + (wl-message-decide-backend, wl-normal-message-redisplay): + Force fetch if `wl-fetch-confirm-threshold' is nil. + +2000-01-11 okada@opaopa.org (Kenichi OKADA) + + * wl-draft.el (wl-draft-delete): + Conscious that `wl-draft-buffer-file-name' is nil. + +2000-01-11 Nishimoto Masaki + + * wl-draft.el (wl-draft-save-and-exit): + Fix the bug that kills unexpected buffer. + +2000-01-11 Yuuichi Teranishi + + * 2.2.15 - "More Than Words" + +2000-01-11 Yoichi NAKAYAMA + + * samples/ja/dot.folders, samples/en/dot.folders: Added description + about 'access group'. + +2000-01-11 Yuuichi Teranishi + + * wl-mime.el, tm-wl.el (wl-draft-preview-message): Display all header. + * wl-summary.el (wl-summary-mode): Don't set tab-width. + (Pointed out by Yoshinari NOMURA ) + (wl-summary-copy, wl-summary-refile): Inhibited copying to + `wl-draft-folder'. + (Pointed out by okada@opaopa.org (Kenichi OKADA)) + (wl-summary-overview-entity-compare-by-date): Ignore error. + (Pointed out by MIZUHARA Bun ) + * wl.el (wl-plugged-mode): Don't set inhibit-read-only. + (Pointed out by Shuhei KOBAYASHI ) + * wl-vars.el (wl-draft-reedit-hook): New hook. + * wl-draft.el (wl-draft-save, wl-draft-mimic-kill-buffer): + New function. + (wl-draft): Don't use buffer names which are already used. + (wl-draft-reedit): run-hook `wl-draft-reedit-hook' instead of + `wl-mail-setup-hook'. + (Requirement by okada@opaopa.org (Kenichi OKADA)) + * wl-xmas.el, wl-mule.el (wl-draft-key-setup): + Binded `wl-draft-save' to `C-xC-s', `wl-draft-mimic-kill-buffer' + to `C-xk'. + * wl-nemacs.el (wl-draft-overload-functions): Ditto. + +2000-01-09 TAKAHASHI Kaoru + + * wl-mule.el, wl-util.el: Fix run time (require 'static). + * wl.el (wl-save): Add docstring. + +2000-01-08 Mito + + * wl-score.el (wl-score-guess-like-gnus): Enclosed with + (when (stringp fld-name)..). + +2000-01-08 Masahiro MURATA + + * wl-draft.el (wl-draft-config-info-operation): New function. + (wl-draft-delete, wl-draft-save-and-exit, wl-draft-reedit): + Use `wl-draft-config-info-operation'. + +2000-01-08 Yuuichi Teranishi + + * wl-demo.el (toplevel): Eliminated warnings when bitmap is not + installed. + (wl-demo-use-bitmap): New variable. + * WL-CFG: Added example of setting wl-demo-use-bitmap to nil. + * wl-nemacs.el (toplevel): Quit timezone emulating (Assume APEL 10). + * wl-demo.el, wl-draft.el, wl-folder.el, wl-util.el, + wl-message.el, wl-summary.el (toplevel): set the return value of + make-local-variable. + (Adviced by Shuhei KOBAYASHI ) + +2000-01-07 Daiki Ueno + + * wl-draft.el (wl-smtp-features, wl-smtp-parse-extension): Fixed. + +2000-01-07 Yuuichi Teranishi + + * wl-draft.el (wl-user-agent-compose): call wl-draft interactively. + (Pointed out by Atsushi Tada ) + * Makefile (EMACS): set default to `emacs'. + (XEMACS): New variable. + (package, install-package): Use $(XEMACS). + * 2.2.14 - "Layla" + * wl-summary.el (wl-summary-mode): Quit setting default-directory. + * wl-vars.el (wl-tmp-dir): set default as "~/tmp/"(cf. WL-ML 3735). + +2000-01-06 Daiki Ueno + + * wl-draft.el (wl-smtp-features): New variable. + (wl-smtp-extension-bind): New macro. + * wl-summary.el (wl-summary-mode-map): + Binded `wl-summary-prev-page' to backspace. + +2000-01-06 Kentaro Yoshitomi + + * elmo-maildir.el (elmo-maildir-create-folder): + Fixed a bug which occurs when directory ends with "/". + +2000-01-06 okada@opaopa.org (Kenichi OKADA) + + * wl-draft.el: sync up with SLIM's smtp.el. + +2000-01-06 Yuuichi Teranishi + + * wl-util.el (wl-load-profile): Moved from wl.el. + * COPYING: New file (renamed from etc/copyright). + * wl-vars.el (wl-smtp-connection-type): Renamed from wl-smtp-use-tls. + * wl-draft.el (wl-draft-send-mail-with-smtp): + Bind smtp-connection-type with wl-smtp-connection-type. + (wl-draft-queue-save-filename): fixed typo. + * wl-vars.el (wl-cs-*): Changed definitions for Nemacs. + * all files: Updated copyright information and checkdoc fix. + +2000-01-05 TAKAHASHI Kaoru + + * wl-ja.texi: Add copyright and permissions text. + +2000-01-05 Yuuichi Teranishi + + * wl-score.el (wl-summary-score-update-all-lines): + Mark as read-uncached when marked by scoring. + * elmo-util.el (elmo-imap4-get-spec): + Fixed a bug which occurs when elmo-default-imap4-ssl is t. + (Reported by Taro FUNAKI ) + * tm-wl.el (wl-draft-yank-current-message-entity): + Fixed binding of mime-viewer/following-method-alist. + (Reported by Taiji.Can@atesoft.advantest.co.jp) + +2000-01-04 OKUNISHI -GTO- Fujikazu + + * wl-message.el (wl-message-decode): + Decode with wl-cs-autoconv when 'no-mime. + +1999-12-31 Kentaro Yoshitomi + + * elmo-maildir.el, elmo-util.el: + Implemented create, delete and copy method of Maildir. + +1999-12-29 Yuuichi Teranishi + + * wl-draft.el (wl-draft): Call `wl-load-profile'. + (Pointed out by Masahiro MURATA ) + * elmo-imap4.el (elmo-imap4-make-number-set-list): New function. + (elmo-imap4-msgdb-create): Use `elmo-imap4-make-number-set-list'. + (elmo-imap4-mark-set-on-msgs): Ditto. + +1999-12-11 okada@opaopa.org (Kenichi OKADA) + + * wl-summary.el (wl-summary-get-sync-range): + Don't claim unplugged in pop3. + +1999-12-28 Nishimoto Masaki + + * elmo-msgdb.el (elmo-msgdb-expand-path): fixed wrong expansion. + +1999-12-28 Yuuichi Teranishi + + * 2.2.13 - "Keep The Faith" + +1999-12-27 Yuuichi Teranishi + + * elmo-util.el (elmo-network-get-spec): New variable. + (elmo-*-get-spec): Rewrote so that 'user' can contain '@'. + (okada@opaopa.org (Kenichi OKADA)'s demand.) + * elmo-imap4.el (elmo-imap4-create-msgdb-from-overview-string): + Corresponded to Emacsen that cannot treat float. + * elmo-pop3.el (elmo-pop3-get-connection): Changed argument. + * check-paren fix. + +1999-12-21 Koga Masato + + * wl-draft.el (wl-draft-reedit): Obey to `wl-draft-use-frame'. + +1999-12-21 Yuuichi Teranishi + + * elmo-vars.el (elmo-imap4-use-modified-utf7): New variable. + +1999-12-20 Yuuichi Teranishi + + * wl-mime.el, tm-wl.el (wl-mime-save-content): Remember last + saved directory. + * wl.el (wl-save): New command. Save current folder status. + (A demand from JINMEI Tatuya .) + * wl-folder.el (wl-folder-mode-map): Binded `wl-save' to "\M-s". + * elmo-util.el (elmo-imap4-get-spec): Use `utf7-encode-string'. + * elmo-imap4.el (elmo-imap4-list-folders): Use `utf7-decode-string'. + * elmo/utf7.el: New file. + +1999-12-20 Daiki Ueno + + * elmo-imap4.el (elmo-imap4-open-connection): Fixed starttls. + * wl-draft.el: featurep->boundp. + +1999-12-17 Yuuichi Teranishi + + * wl-vars.el (wl-search-mime-charset): New variable. + * wl-summary.el (wl-summary-pick): Use `wl-search-mime-charset'. + +1999-12-16 TAKAHASHI Kaoru + + * WL-MK (wl-texinfo-format): Add `@direntry' emulation for + old texinfmt.el. + +1999-12-16 Yuuichi Teranishi + + * wl-draft.el (wl-draft-config-exec): Re-highlight draft. + (Pointed out by Motomichi Matsuzaki ) + * wl-summary.el (toplevel): Changed key bind order of + `wl-summary-temp-mark-region'. + (okada@opaopa.org (Kenichi OKADA)'s report.) + +1999-12-16 okada@opaopa.org (Kenichi OKADA) + + * wl-summary.el (wl-summary-mark-as-important-region, + wl-summary-mark-as-unread-region, + wl-thread-mark-as-important, + wl-thread-mark-as-unread, + wl-summary-temp-mark-mark-as-important, + wl-summary-temp-mark-mark-as-unread): New functions. + (wl-summary-save-region): Eliminated bogus process. + (wl-summary-prefetch-region): Use `elmo-cache-exists-p' + instead of `wl-summary-message-uncached-marks'. + * wl-thread.el (wl-thread-get-children-msgs-uncached): Ditto. + +1999-12-14 okada@opaopa.org (Kenichi OKADA) + + * Changed behavior of TLS in pop and imap + when server does not provide TLS feature. + +1999-12-14 TSUMURA Tomoaki + + * dot.wl: Added an example setting; + wl-default-folder shows ML-name and ML-count and + other folder shows ML-count. + +1999-12-14 Yuuichi Teranishi + + * mmelmo-imap4-2.el (mmelmo-imap4-parse-bodystructure-string): + Fix: Parse fails if JIS filename is contained. + * wl-summary.el (wl-summary-copy): Fixed bug. + (Reported by Hiroshi Watanabe ) + +1999-12-12 Yuuichi Teranishi + + * wl-summary.el (wl-summary-goto-folder-subr): Changed timing + to be sticky (Adviced by Masahiro MURATA ). + * wl-vars.el (wl-folder-sync-range-alist): + Changed range of draft and queue folder. + +1999-12-11 okada@opaopa.org (Kenichi OKADA) + + * wl-summary.el (wl-summary-get-sync-range): + Don't claim unplugged in pop3. + +1999-12-10 OKUNISHI -GTO- Fujikazu + + * Eliminated defalias for elmo function in wl modules. + +1999-12-07 okada@opaopa.org (Kenichi OKADA) + + * elmo-nntp.el: Changed behavior when + elmo-nntp-max-number-precedes-list-active is `t' and + list-active is not provided. + +1999-12-07 TAKAHASHI Kaoru + + * INSTALL.ja: Fixed. + * wl-summary.el (wl-summary-always-sticky-folder-p): New macro. + (wl-summary-goto-folder-subr): Use `wl-summary-always-sticky-folder-p'. + +1999-12-07 Akihiro MOTOKI + + * wl-vars.el (wl-summary-always-sticky-folder-list): New variable. + * wl-summary.el (wl-summary-stick): New optional argument. + (wl-summary-goto-folder-subr): Folders that match + `wl-summary-always-sticky-folder-list' stick automatically. + +1999-12-07 Yuuichi Teranishi + + * INSTALL.ja: Changed to ISO-2022-JP. + * wl-draft.el (wl-draft-send-mail-with-smtp): + Fixed binding of (default-)?case-fold-search. + (Reported by Atsushi Tada , , etc.) + (wl-draft-send): Don't use `with-current-buffer'. + * 2.2.12 - "Joyride" + +1999-12-07 Katsumi Yamaoka + + * etc/icons/wl-logo.xbm: Christmas version. + +1999-12-07 Yuuichi Teranishi + + * elmo-imap4.el (elmo-imap4-parse-overview-string): + Fix: Cannot parse number when elmo-imap4-use-uid is nil. + * utils/hmac/scram-md5.el, utils/hmac/hmac-util.el: Removed. + * wl-summary.el (wl-summary-mark-as-unread): + Fixed wrong-type-argument error. + * wl-folder.el (wl-folder-empty-trash): + Fix: Summary information is incleased everytime. + (Reported by OKAZAKI Tetsurou ) + +1999-12-07 Masahiro MURATA + + * wl-draft.el (wl-draft-condig-exec): + Set wl-draft-config-exec-flag as nil only if wl-draft-config-alist + was applied. + +1999-12-06 Shigeru OKUMURA + + * WL-ELS (HMAC-MODULES): Updated. + +1999-12-06 Tsunehiko Baba + + * INSTALL: New file. + +1999-12-06 Yuuichi Teranishi + + * elmo-imap4.el (elmo-imap4-create-msgdb-from-overview-string): + Fix: filter does not work correctly. + (Reported by Kazuyoshi Mii ) + * 2.2.11 - "Iris" + * utils/hmac/elisp/*.el: Sync up with slim-1.13.4 + * elmo-imap4.el + (elmo-imap4-open-connection): Use `sasl-cram-md5' for cram-md5. + (toplevel): (require 'sasl) instead of (require 'hmac-md5). + Eliminated eval-when-compile. + +1999-12-05 Yuuichi Teranishi + + * wl-summary.el (wl-summary-mark-as-read): + Avoid marking messages which is not in msgdb. + * wl-summary.el (wl-summary-pick): + Notify if no message was picked from msgdb. + +1999-12-04 Yuuichi Teranishi + + * elmo-msgdb.el (elmo-msgdb-overview-get-parent-entity): + Changed argument. + * wl-vars.el (wl-smtp-posting-server): Set default value as nil. + (Adviced by okada@opaopa.org (Kenichi OKADA)) + * elmo-imap4.el (elmo-imap4-create-msgdb-from-overview-string): + downcase extra-field name. + (Pointed out by Takaaki MORIYAMA ) + * elmo-util.el (elmo-collect-field(-from-string)?): + Argument `downcase-field-name' is added. + +1999-12-03 TSUMURA Tomoaki + + * wl-folder.el (wl-folder-empty-trash): + Fix: Summary information is incleased everytime. + +1999-12-03 Nishimoto Masaki + + * wl-summary.el (wl-summary-default-from): Newsgroup name is not + displayed. + +1999-12-03 TAKAHASHI Kaoru + + * INSTALL.ja: New file. + * wl-summary.el (wl-summary-reedit): When reedit draft + for news arcticle, don't add To: header. + +1999-12-03 Yuuichi Teranishi + + * elmo-util.el (elmo-mime-string): Enclose with elmo-set-work-buf. + (Pointed out by Mikiya Tani ) + * etc/icons/wl-logo.xpm: Christmas version. + * elmo-imap4.el (elmo-imap4-make-attributes-object): + Nemacs causes error in read. + * elmo-dop.el (elmo-dop-list-folder): correspond to pipe feature. + (Pointed out by OKAZAKI Tetsurou ) + +1999-12-03 sen_ml@eccosys.com + + * utils/wl-mailto.el: 0.5. + +1999-12-02 Yuuichi Teranishi + + * mmelmo-imap4-1.el: eliminated buffer read only error. + * wl-mime.el, tm-wl.el: Changed key bind of wl-draft-preview-message. + (Based of the report by Makoto.Nakagawa@jp.compaq.com) + * utils/ssl.el: Sync up to newest version. + (Adviced by okada@opaopa.org (Kenichi OKADA)) + * elmo-util.el (elmo-mime-string, elmo-decode-mime-charset-string): + New function. + * elmo-imap4.el: FETCH analyzing module is replaced. + +1999-12-02 Hironori Fukuchi + + * wl-xmas.el: If (featurep 'dragdrop) is nil, + wl-dnd-set-drop-target causes error. + +1999-12-02 okada@opaopa.org (Kenichi OKADA) + + * elmo-util.el: encolsed (require 'starttld) by condition-case. + +1999-12-01 okada@opaopa.org (Kenichi OKADA) + + * Fix: Error occurs when wl-smtp-posting-user is nil in smtp auth. + * Fixed an error which occurs when nntp port number is specified. + +1999-11-27 Masahiro MURATA + + * wl-draft.el (wl-draft-reedit): eliminated judgement by + `(interactive-p)' because it is not interactive. + * New command: wl-fldmgr-delete. + * Rename: wl-fldmgr-rename-group -> wl-fldmgr-rename. + * New function: elmo-folder-creatable-p. + * Create directory when `#mh' type folder is created + in IMAP4 folder. + * wl-folder-check-one-entity creates folder if it does't exist. + * New macro: wl-folder-clear-entity-info. + +1999-11-25 TAKAHASHI Kaoru + + * wl-message.el (wl-message-narrow-to-page): Fixed + `beginning-of-buffer' error occurs, when read "^L\n^L" + inclueded message. + +1999-11-25 Yuuichi Teranishi + + * wl-summary.el (wl-summary-mode): Eliminated argument. + * wl-address.el (wl-address-petname-add-or-change): + Fix: When there's no newline character in the last line of + `.addresses', wrong entry is added. + * elmo-imap4-[12].el (mmelmo-imap4-parse-bodystructure-entity): + Use mime-parse-parameters-from-list. + +1999-11-24 Tetsuya Uemura + + * x-face-xmas-mew-display-x-face -> x-face-xmas-wl-display-x-face + +1999-11-22 okada@opaopa.org (Kenichi OKADA) + + * wl-vars.el (wl-smtp-authenticate-type, wl-smtp-use-tls): + New variable. + * wl-draft.el (wl-draft-send-mail-with-smtp): + Added SMTP TLS feature. + +1999-11-21 okada@opaopa.org (Kenichi OKADA) + + * When wl-summary-jump-to-msg-internal is called via + wl-summary-jump-to-msg-by-message-id-via-nntp, + `scan-type' becomes `update'. + +1999-11-22 Daiki Ueno + + * elmo-imap4.el, elmo-pop3.el: Added STARTTLS feature. + +1999-11-20 Masahiro MURATA + + * wl-draft.el (wl-draft-send-mail-with-smtp): + Bind process-connection-type nil. + +1999-11-20 OKUNISHI -GTO- Fujikazu + + * elmo-util.el (elmo-open-network-stream): + Bind process-connection-type nil. + +1999-11-20 Nishimoto Masaki + + * Fixed an error when an important message is marked-as-important + by scoring, it disappeared. + +1999-11-19 Hironori Fukuchi + + * tm-wl.el: fixed typo. + +1999-11-18 Yasuo OKABE + + * Signal an error when no message is displayed + at wl-draft-insert-message. + +1999-11-17 Yuuichi Teranishi + + * wl-vars.el: New variable wl-summary-showto-folder-regexp. + * wl-summary.el (wl-summary-default-from): + renamed from my-wl-summary-from-func-petname in sample/../dot.wl + (adviced from Masahiro MURATA ) + * wl-summary.el (wl-summary-simple-from): wl-summary-default-from + renamed. + +1999-11-17 Masahiro MURATA + + * wl-message.el (wl-message-get-buffer-create): + Fixed an error which occurs when sticky message is displayed. + +1999-11-17 sen_ml@eccosys.com + + * wl-mailto.el: 0.5-pre1. + +1999-11-16 Yuuichi Teranishi + + * elmo-util.el (elmo-delete-cr-get-content-type): + If Content-Type does not exist, return t. + * 2.2.9 - "Gonna Make You Sweat" + +1999-11-15 Katsumi Yamaoka + + * wl-util.el (wl-unique-id): Don't use current-time and timezone. + +1999-11-14 Masahiro MURATA + + * wl-draft.el, wl-summary.el: Set vaiable wl-draft-reply t in reply, + wl-draft-forward t in forward. + * wl-folder.el, wl.el: Make wl-make-plugged-alist only when + wl-folder made folder list. + +1999-11-14 OKAZAKI Tetsurou + + * elmo-pipe.el (elmo-pipe-use-cache-p): Implemented. + * elmo2.el (elmo-folder-number-get-spec): Fixed. + +1999-11-13 Yuuichi Teranishi + + * wl-draft.el: insert-mail is implemented. + * If 'a' is pushed on MIME button, its part is cited in draft. + * wl-user-agent.el: Removed. + * wl-draft.el: Merged wl-user-agent.el. + * wl-mime.el, tm-wl.el: Rearranged API to MIME modules. + +1999-11-12 okada@opaopa.org (Kenichi OKADA) + + * Fix: elmo-imap4.el: If folder does not exist, + wl-folder-check-current-entity fails. + * wl-draft.el: wl-draft-config-list, wl-template-alist can specify + `header', `header-file'. + +1999-11-12 Katsumi Yamaoka + + * wl-util.el (wl-draft-make-message-id-string, wl-unique-id, + wl-number-base36): New functions. + (wl-unique-id-char): New internal variable. + + * wl-mule.el (wl-draft-make-message-id-string): Remove. + * wl-nemacs.el (wl-draft-make-message-id-string): Remove. + * wl-xmas.el (wl-draft-make-message-id-string): Remove. + + * wl-draft.el (wl-draft-send-mail-with-smtp): Funcall `smtp-server' + if it is a function; leave the handling of Resent-* fields to + `smtp'. + +1999-11-12 Yuuichi Teranishi + + * wl-draft (wl-draft-get-fcc-list): Create folder when FCC contains + new folder. + * Rename: wl-draft-config-body-goto-{top|bottom} + -> wl-draft-body-goto-{top|bottom} + * Rename: wl-summary-confirm-folder-existence -> + wl-folder-confirm-existence. + (Adviced by Masahiro MURATA ) + * Rename: wl-mime-edit-preview-message-hook + -> wl-draft-preview-message-hook + * elmo-nntp.el (elmo-nntp-string-to-vector): Eliminated. + * elmo-util.el (elmo-tokenize-string): Eliminated. + Replaced with split-string + * wl-highlight.el: New face, wl-highlight-logo-face for logo. + +1999-11-11 Katsumi Yamaoka + + * wl-demo.el: Corresponded to bitmap-mule. + * wl-logo.xbm: New file. + * elmo-nntp.el (elmo-nntp-string-to-vector): Unlimit the length of + vector. + (elmo-nntp-parse-overview-string): Don't specify the 2nd arg of + `elmo-nntp-string-to-vector'. + +1999-11-11 Yuuichi Teranishi + + * elmo-imap4.el: Searching fails if Message-ID contains '%'. + (Adviced by OKAZAKI Tetsurou ) + * wl-message.el, mmelmo-[12].el: Rearranged read-only setting. + * Rename: wl-draft-save-and-hide -> wl-draft-save-and-exit. + Binded to C-c C-z. + +1999-11-11 Yasuo OKABE + + * wl-summary.el (wl-summary-temp-mark-forward): + Enclose as multipart/digest if multiple messages are included. + +1999-11-11 okada@opaopa.org (Kenichi OKADA) + + * New variable wl-nntp-posting-port, wl-nntp-posting-ssl. + wl-nntp-posting-{user,server,port,ssl} corresponds to + elmo-default-nntp-{user,server,port,ssl}. + * Set the initial value of wl-nntp-posting-* as nil. + If they are nil, use elmo-default-nntp-* value. + * utils/bbdb-wl.el: If bbdb-use-pop-up is nil, error occurs. + * wl-draft.el: New function wl-draft-save-and-hide. + +1999-11-10 okada@opaopa.org (Kenichi OKADA) + + * wl-demo.el: calculate the displayed position of wl-logo.xpm. + +1999-11-10 Tsutomu Okada + + * wl-message.el (wl-message-refer-article-or-url): + Not to move cursor to message buffer with mouse-button-2. + +1999-11-10 Yuuichi Teranishi + + * wl-summary.el (wl-summary-set-message-buffer-or-redisplay): + Sticky Message sometimes provides wrong message. + (Reported by Mito ) + * wl-util.el (wl-string): alias to elmo-string. + * elmo-util.el (elmo-string): New function. + * New variable: wl-smtp-posting-port. + * Binded wl-summary-resend-bounced-mail to "\eE". + +1999-11-10 OKAZAKI Tetsurou + + * WL-ELS: fixed typo. + +1999-11-10 kurati@bigfoot.com + + * When new folder is created, add it to the completion candidate. + * FCC: If new folder is specified, confirm to create it. + * auto-refile: If new folder is specified, confirm to create it. + +1999-11-10 Yasuo OKABE + + * wl-summary.el (wl-summary-resend-message, + wl-summary-resend-bounced-mail): New command. + * wl-draft.el (wl-draft-dispatch-message): Dont send via nntp + if dispatched message includes Resent-to header. + +1999-11-09 okada@opaopa.org (Kenichi OKADA) + + * wl-summary.el (wl-summary-jump-to-msg-internal): message is not + displayed in some cases. + * wl-summary.el (wl-summary-jump-to-msg-by-message-id-via-nntp): + If there are multiple newsgroup candidates, + newsgroup in the wl-folder-newsgroups-hashtb is preceded. + +1999-11-09 Yuuichi Teranishi + + * 2.2.8 - "Free As A Bird" + +1999-11-08 Yuuichi Teranishi + + * Fix: wl-draft.el (wl-draft-send): C-cC-s becomes insert-signature + after sending. (Reported by Akihiro MOTOKI ) + * WL-MK: (fset 'file-executable-p 'file-exists-p) for Nemacs. + * WL-MK, WL-CFG: Changed default value of WL_PREFIX and ELMO_PREFIX + to "wl". + * New variable: wl-user-mail-address-list. + * New function: wl-address-user-mail-address-p + Judge whether an address is user's or not using + wl-user-mail-address-list and wl-from. + * wl-summary.el (wl-summary-cancel-message, + wl-summary-supersedes-message): Use wl-address-user-mail-address-p + to judge whether an address is user's or not. + (Based on the changes by okada@opaopa.org (Kenichi OKADA)) + * wl-refile.el (wl-refile-learn, wl-refile-guess-by-history): Ditto. + * wl-draft.el (wl-draft-make-mail-followup-to, wl-draft-reply + wl-draft-delete-myself-from-cc): Ditto. + * elmo-filter.el (elmo-filter-list-folder-unread, + elmo-filter-list-folder-important): filtering was not valid. + (Reported by Kazuyoshi Mii ) + +1999-11-08 okada@opaopa.org (Kenichi OKADA) + + * Altered the initialization of POP-before-SMTP variables. + +1999-11-07 okada@opaopa.org (Kenichi OKADA) + + * elmo-nntp.el: Use `list' if `list active' was in vain. + +1999-11-07 Masahiro MURATA + + * Eliminated wl-draft-prepared-confi-alist and unified with + wl-draft-config-alist. + * Take over local variables in wl-template-select. + * Process Fcc after the message sending is finished. + * Changed from user-mail-address to wl-envelope-from in + wl-draft-queue-save-variables. + * Fix: An error occurs in wl-draft-insert-from-field when + user-mail-address is nil. + +1999-11-06 Tetsuya Uemura + + * Display mode map by describe-mode. + +1999-11-06 TAKAHASHI Kaoru + + * wl-folder.el (wl-folder-mode-map): Change key bind of + wl-fldmgr-copy-region. + +1999-11-06 Hironori Fukuchi + + * wl-summary.el (wl-summary-stick): parenthesis position is invalid. + +1999-11-06 Yasuo OKABE + + * utils/wl-user-agent.el: altered to unify the behavior with + sendmail-user-agent. + +1999-11-06 sen_ml@eccosys.com + + * utils/wl-user-agent.el: 0.5. + +1999-11-05 Yuuichi Teranishi + + * elmo-imap4.el: Rearranged all modules. + * elmo-imap4.el: New variable `elmo-imap4-debug'. + Non-nil forces debug information appair on "*IMAP4 DEBUG*" buffer. + * elmo-imap4.el, elmo-pop3.el, elmo-nntp.el: + Number of times of copying entire message is suppressed. + * elmo-imap4.el: Lock the process until the response is returned from + server. + * wl-summary.el: Auto refile failes if wl-refile-rule-alist is nil. + * WL-MK: install-package does not install info. + (Reported by "MATSUBAYASHI 'Shaolin' Kohji" + ) + * elmo-cache.el (elmo-cache-search): Corresponded to partial caching. + (Reported by Yasuo OKABE ) + +1999-11-04 okada@opaopa.org (Kenichi OKADA) + + * Rearranged POP-before-SMTP variables. + * New variable: elmo-default-pop3-user, wl-pop-before-smtp-user, + wl-pop-before-smtp-server, wl-pop-before-smtp-port, + wl-pop-before-smtp-ssl, wl-pop-before-smtp-authenticate-type. + * elmo-pop-before-smtp-* -> wl-pop-before-smtp-* + +1999-11-04 Yuuichi Teranishi + + * wl-mime.el (wl-mime-edit-preview-message): + New hook: wl-mime-edit-preview-message-hook. + * elmo-util.el: Suppressed warnings. + * wl-summary.el (wl-summary-sync-marks): Make mark synchronization + faster. + * elmo-pipe.el (elmo-pipe-max-of-folder): Unread number is not valid + in IMAP4 folders. + (Reported by Toshihiko Kodama ) + +1999-11-03 Yuuichi Teranishi + + * 2.2.7 - "Escapade" + * WL-MK: install-info causes strange INFODIR message. + * Fix: Error occurs the first prefetch from Folder. + (Reported by Kenichi OKADA ) + * mmelmo: changed mime-elmo-entity as subclass of mime-buffer-entity + to avoid effects on other MUAs. + * wl-thread.el: Number is not highlighted when message is appended to + the closed thread. + * Some functions are corresponded with pipe-folder. + +1999-11-03 Masahiro MURATA + + * Change: folder petname can be used for folder name completion. + * Fix: If wl-force-fetch-folders is non-nil, access groups cannot + be opened in the unplugged status. + * wl-fldmgr.el: inhibited to call `wl-fldmgr-set-petname' + in the end of line. + * wl.el: If there is no change in wl-plugged-mode, + wl-toggle-plugged is not called. + * rearranged buffer removal of wl-exit and wl-folder-suspend. + * wl-folder.el: some functions are replaced with + wl-folder-buffer-group-p. + * wl-summary.el: some functions are replaced with + wl-summary-entity-info-msg. + * Change: changed wl-reset-plugged-alist's default value to t. + * Fix: plugged status is reset. + +1999-11-03 TAKAHASHI Kaoru + + * wl-summary.el (wl-summary-reedit): When reedit draft + for news arcticle, don't add To: header. + +1999-11-03 Kenichi OKADA + + * wl-summary.el (wl-summary-write-current-newsgroup): + use elmo-folder-get-primitive-folder-list. + * New command: wl-folder-write-current-newsgroup + * elmo-util.el (elmo-folder-get-primitive-folder-list, + elmo-folder-get-primitive-spec-list): changed for pipe-folder. + * Fix: wl-toggle-plugged fails if the network downed before + elmo-pop3-flush-connection. + +1999-11-03 sike@ic.netlaputa.ne.jp + + * Fix: the problem when Message-Id contains newline. + +1999-11-02 Yuuichi Teranishi + + * 2.2.6 - "Diamonds And Pearls" + * Set plug status to wl-plugged in wl-init. + (Pointed out by Yasuo OKABE ) + * WL-MK: rewrote for Nemacs. + * Rename: wl-address-complete-address + -> wl-complete-field-body + * Rename: wl-address-complete-address-or-tab + -> wl-complete-field-body-or-tab + +1999-11-01 Yuuichi Teranishi + + * Change: simplified the icon init function. + * elmo-pipe: New module. + +1999-11-01 OKAZAKI Tetsurou + + * Fix: typo in WL-ELS. + * Fix: new WL-MK causes error when byte-compiling + wl-user-agent.el and wl-mailto.el. + +1999-10-29 Takaaki MORIYAMA + + * Remove wl-save-status from kill-emacs-hook in wl-exit. + +1999-10-28 OKUNISHI -GTO- Fujikazu + + * new file: WL-ELS. + * WL-MK: rewrote for install.el. + +1999-10-28 okada@opaopa.org (Kenichi OKADA) + + * Fix: wl-ja.texi: key binding of wl-template-select was wrong. + * Fix: synchronize unread number for INN 2.3. + +1999-10-28 TAKAHASHI Kaoru + + * Fix: wl-ja.texi: many fixes. + +1999-10-27 Yuuichi Teranishi + + * Change: binded 'Z' in Folder to `wl-status-update'. + * Fix: wl-summary-goto-last-displayed-msg doesn't jump to + previously displayed message when only one message was displayed. + +1999-10-26 kurati + + * Change: FCC: is also target of completion. + +1999-10-26 Yuuichi Teranishi + + * Change: Sync important mark though folder is in the + unplugged status. + * Change: Check existence of folder before auto-refile. + (Demanding feature by Toshihiko Kodama + ) + * Fix: Mark expunged message as read on IMAP4 server. + +1999-10-22 OKAZAKI Tetsurou + + * Fix: marking of thread causes strange behavior when + cursor is not at the beginning of line. + * Change: Don't move cursor when same folder is specified in + wl-thread-refile. + * Change: Changed message when wl-summary-jump-to-parent-message + failed. + * Change: Changed region adjusting of wl-summary-exec-region to + intuitive way. + +1999-10-25 Masahiro MURATA + + * Fix: wl-fldmgr causes error when group folder is added. + * Change: define wl-defface statically. + * Change: wl-folder-buffer-search-entity matches unread + status unknown. + * Fix: wl-summary-redisplay-no-mime does not set + wl-summary-buffer-disp-msg and wl-current-summary-buffer. + +1999-10-25 Yuuichi Teranishi + + * Change: Check domain name at startup time. + * New variable: wl-local-domain. + For those systems that doesn't return FQDN. + * Change: Deleted horizontal scrollbar for Folder in XEmacs. + (Pointed out by "MATSUBAYASHI 'Shaolin' Kohji" + ) + * New function: wl-mime-edit-preview-message. + * Change: Move cursor on readable message when entered to Summary + in the unplugged status. + * Fix: typo in WL-CFG utils. + (Pointed out by Taiji.Can@atesoft.advantest.co.jp) + * Fix: cannot make info. + (Pointed out by Kazufumi Hayasaka ) + * 2.2.5 - "Come Undone" + +1999-10-24 Mikio Nakajima + + * Fix: simplified double negative. + +1999-10-24 Masahiro MURATA + + * Fix: If FCC is unplugged folder, append to dop-queue. + * Change: New elmo-dop-queue operation "append-operations". + * Change: wl-summary-flush-pending-append-operations takes over + existing message's unread status. + +1999-10-24 Yuuichi Teranishi + + * New file: WL-CFG. + * Fix: FCC to IMAP4 Folder is ignored in the offline status. + (Reported by Masafumi NAKANE ) + * Fix: refile-alist cannot be shared between Emacs and XEmacs. + (Reported by Takuro KITAME ) + * wl-ja.texi: fixed original site of tm, semi. + * Fix: If there are IMAP4 folders which have same name and different + servers, wrong folder is sometimes updated its unread number. + (Reported by Kazuyoshi Mii ) + +1999-10-23 Kenichi OKADA + + * Fix: queued functions not in elmo-dop-merge-funcs are discarded. + +1999-10-23 Masahiro MURATA + + * Change: Plugged status: + display label of every port. + * Change: Plugged status: + displaying dop-queue displayed more in detail. + * Fix: elmo-dop-queue-merge sometimes set elmo-dop-queue to nil. + +1999-10-23 okada@opaopa.org (Kenichi OKADA) + + * Change: elmo-prefetch-msgs displays the progress. + +1999-10-23 Yuuichi Teranishi + + * Set wl-mime-save-content as Wanderlust specific method on SEMI. + * Fix: FLIM-1.12.x fails to merge partial messages. + * WL-MK: Rewrote configuration process. + +1999-10-22 TAKAHASHI Kaoru + + * Rename: wl-score-edit-exit-function -> wl-score-edit-exit-func + +1999-10-22 Takuro KITAME + + * Fix: etc/ja.Emacs: Some values are duplicated. + +1999-10-22 Kenichi OKADA + + * Add: [wl-ja.texi] + Added explanations of wl-summary-save-*, + wl-summary-jump-to-msg-by-message-id-via-nntp, + offline prefetch, wl-folder-jump-to-current-entity, cram-md5, and SSL. + +1999-10-22 Masahiro MURATA + + * Fix: Set md5 CODING to 'binary for XEmacs built-in function. + * Fix: Move from sticky summary to other by "g", + temp mark face is not recovered. + * New variable: wl-prog-uudecode-no-stdout-option. + Non-nil forces save with filename specified in uuencode stream. + +1999-10-21 okada@opaopa.org (Kenichi OKADA) + + * Merge offline queue. + +1999-10-21 Yuuichi Teranishi + + * Change: Don't use std11.el in wl-address-header-extract-address. + +1999-10-20 Masahiro MURATA + + * Change: Don't reset `elmo-plugged-alist' when startup. + +1999-10-20 Yuuichi Teranishi + + * Fix: Emacs 20.2 causes buffer-read-only error on Folder mode. + (Reported by Yasuhiro Ohta + Adviced by TSUMURA Tomoaki ) + * Fix: Check the feature of scrollbar and toolbar on XEmacs. + (Adviced by Shigeru OKUMURA ) + +1999-10-20 Kenichi OKADA + + * Fix: An error occurs when message with invalid header is refiled. + * Fix: Access grop content is not appeared automatically at first + open operation. + +1999-10-19 Yuuichi Teranishi + + * Fix: 'E' in Folder causes error at wl-folder-toggle-disp-summary. + (Reported by Shigeru OKUMURA ) + * Change: Don't use 'eval-after-load' for timezone y2k. + * 2.2.4 - "Black Or White" + +1999-10-19 okada@opaopa.org (Kenichi OKADA) + + * Fix: prefetching removes mark in summary although it was canceled. + * Change: Offline Prefetch. + +1999-10-18 Yuuichi Teranishi + + * Change: inhibit 'm f' command in the last line of Folder mode. + * Change: reduced warnings in byte-compile. + * Added hmac package and ssl.el in utils subdirectory. + (If wl-install-hmac is Non-nil, hmac package is installed.) + * Change: corresponded to FLIM-1.12. + * Fix: IMAP4 folder claims in unplugged status. + * Change: Ask update number in summary if message number is larger + than wl-summary-update-confirm-threshold. + * New variable: wl-summary-update-confirm-threshold + +1999-10-18 okada@opaopa.org (Kenichi OKADA) + + * New variable: wl-summary-search-via-nntp. + if Non-nil, call wl-summary-jump-to-msg-by-message-id-via-nntp in + wl-summary-jump-to-msg-by-message-id. If 'confirm, it confirms. + * New variable: wl-summary-jump-to-msg-by-message-id-via-nntp + Search message by Message-ID via NNTP and change folder. + +1999-10-15 Yuuichi Teranishi + + * Change: call elmo-commit in elmo-imap4-server-diff. + * New function: elmo-commit. + * Fix: wl-folder-check-one-entity removed useless folder check. + * elmo-imap4-max-of-folder: new implementation. + * elmo-imap4-folder-exists-p: new implementation. + +1999-10-14 Mikio Nakajima + + * Fix: wl-ja.texi: typo (@kbd {l} -> @kbd{l}). + +1999-10-14 TAKAHASHI Kaoru + + * Fix: wl-local-variable-p does not work on xemacs. + +1999-10-14 Yuuichi Teranishi + + * Fix: flag on server was not changed when cached message was read. + (Pointed out by Taiji.Can@atesoft.advantest.co.jp) + * Change: Use std11.el in wl-address-header-extract-address. + +1999-10-14 Masafumi NAKANE + + * Fixed Typo: exit-> exist. + +1999-10-13 okada@opaopa.org (Kenichi OKADA) + + * Change: unplugged.xpm: added red. + +1999-10-13 OKAZAKI Tetsurou + + * Fix: elmo-filter-get-spec change was not completed + (elmo-folder-diff). + +1999-10-13 Masahiro MURATA + + * Fix: lighten wl-plugged-mode. + * Fix: wl-draft-raw-send + wl-draft-config-alist was binded to nil. + +1999-10-13 Sasaki Toshiya + + * Change: wl-folder-use-sever-diff-p + If multi-folder contains IMAP4 folder, then t. + +1999-10-13 Yuuichi Teranishi + + * Change: Set filename in 'm U' (wl-summary-temp-mark-uudecode). + * Change: Wheel works in Folder mode. + * Fix: tm-wl.el was not completed. + (Pointed out by Toshihiko Kodama ) + * Change: wl-ja.texi: added explanation of 'OR'. + * Change: removed dependency for time-stamp.el. + +1999-10-12 Yuuichi Teranishi + + * 2.2.3 - "Always" + * read-directroy-name -> wl-read-directory-name. + +1999-10-12 okada@opaopa.org (Kenichi OKADA) + + * New commands: wl-summary-save-region (ry), wl-thread-save (ty), + wl-summary-temp-mark-save (my). + +1999-10-11 Masahiro MURATA + + * New variable: wl-draft-sendlog + Sending log is saved when this value is non-nil. + * New plugged system-II. + +1999-10-10 Yuuichi Teranishi + + * New command: wl-summary-temp-mark-pick (binded to m?). + * New variable: elmo-imap4-disuse-server-flag-mailbox-regexp. + * Rename: wl-address-file-name -> wl-address-file. + * Rename: wl-score-default-file-name -> wl-score-default-file. + * New variable: wl-summary-auto-sync-marks. + Non-nil forces summary to synchronize unread/important marks at 's'. + * Change: default value for wl-stirict-diff-folders is changed to nil. + * Change: important marks are synchronized in server. + * Change: IMAP4 Folder synchronizes unread status with server. + * New command: wl-summary-sync-marks. + * Change: IMAP4 Folder server can display side diff. + * New variable: wl-folder-use-server-diff. + +1999-10-08 Yuuichi Teranishi + + * New variable: wl-envelope-from which sets envelope from. + If nil, wl-from is used as envelope from. + +1999-10-04 Yuuichi Teranishi + + * Change: defined easy saving method as default (for SEMI). + * Change: wl-draft-send kills sending-buffer only when + it is buffer-live-p. + * Change: Folder existence is checked only when folder checking + was failed. + * Fix: wheel causes error when cursor is on message buffer. + +1999-10-04 okada@opaopa.org (Kenichi OKADA) + + * Change: C-u SPC calls wl-folder-update-recursive-current-entity + on group folder. + +1999-10-04 Yuuichi Teranishi + + * Fix: filtered IMAP4 folder queues needless remove process. + (Pointed out by OKAZAKI Tetsurou ) + +1999-10-04 okada@opaopa.org (Kenichi OKADA) + + * Fix: wl-folder-update-recursive-current-entity does not work + when access group has petname. + +1999-10-03 TSUMURA Tomoaki + + * Fix: keys (mail addresses) are downcased when they are registered + to wl-refile-alist. + +1999-10-02 Tetsuya Uemura + + * Change: If number is specified as prefix argument for C-l, + the number is passed to recenter. + +1999-10-01 Yuuichi Teranishi + + * Fix: Avoided mark as read entire message when part was fetched + in IMAP4. + +1999-09-30 OKUNISHI -GTO- Fujikazu + + * Fix: Emacs 20 with argument '-nw' could not print out. + +1999-09-28 Masahiro MURATA + + * Fix: Summary sometimes appears on unexpected window + when moving from Folder to Summary. + * Fix: wl-plugged-change causes error. + * Change: wl-plugged-change can be called from Summary. + +1999-09-27 Yuuichi Teranishi + + * Change: quit loading wl.el in compile time. + (Pointed out by Masahiro MURATA ) + +1999-09-27 Masahiro MURATA + + * Fix: New plugged system sometimes causes an error. + +1999-09-26 Masahiro MURATA + + * Change: New plugged system. + +1999-09-24 OKUNISHI -GTO- Fujikazu + + * Fix: execute wl-summary-redisplay-internal () + instead of wl-summary-set-message-buffer-or-redisplay() to affect + wl-break-pages value in printing. + * Fix: If wl-break-pages is t, next page does not printed. + +1999-09-23 Kenichi OKADA + + * Change: set truncate-line t in folder-mode + when wl-stay-folder-window is non-nil. + +1999-09-23 OKAZAKI Tetsurou + + * Fix: elmo-filter-get-spec change was not completed + (elmo-folder-diff). + +1999-09-23 OKUNISHI -GTO- Fujikazu + + * Change: use file-name-absolute-p () for absolute path detecting. + +1999-09-20 Masahiro MURATA + + * Fix: kill buffers of mime-view-caesar when exit summary. + +1999-09-21 OKUNISHI -GTO- Fujikazu + + * Fix: elmo-safe-filename: corresponded to OS/2 filesystem. + +1999-09-21 Yuuichi Teranishi + + * 2.2.2 - "You Could Be Mine" + * Change: folders in Folder mode are saved ignoring + wl-save-folder-list. + * Change: 'tocc' field means 'To' or 'Cc' in filter spec. + * Change: OR condition, NOT condition are now available in filter + folder. + * Change: wl-uniq-list -> elmo-uniq-list + * Fix: wl-summary-save always complains "No message to save." + * Change: move local-variable-p definition to wl-util.el. + (according to the report from Masahiro MURATA ) + +1999-02-02 IMAI Takeshi + + * Fix: cannot expire to IMAP folder. + +1999-09-20 Masahiro MURATA + + * Fix: kill buffers of mime-view-caesar when exit summary. + +1999-09-19 Shigeru OKUMURA + + * Fix: set process-buffer of open-network-stream as unibyte. + +1999-09-19 OKAZAKI Tetsurou + + * Fix: wl-ja.texi + +1999-09-17 HAYAKAWA akio + + * Change: consider multi folder as local folder if + it contains only local folder. + +1999-09-16 OKUNISHI -GTO- Fujikazu + + * typo fix. + +1999-09-16 Masahiro MURATA + + * Change: recycle message window in one frame. + * Change: resume message window status in wl-summary-goto-folder + according to wl-summary-buffer-disp-msg. + +1999-09-15 OKAZAKI Tetsurou + + * WL-MK: + Fix: install-wl-package ignored wl-install-els for elmo modules. + New function: wl-install-modules + +1999-09-14 Yuuichi Teranishi + + * 2.2.1 - "Wild World" + * typo: stickey -> sticky. + * New function: wl-nemacs.el + local-variable-p for Nemacs. + * Rename: etc/ChangeLog.* -> etc/ChangeLog.*.ja + * Rename: etc/ChangeLog.*.en -> etc/ChangeLog.* + * Fix: XEmacs doesn't show logo. + * Fix: install fails in XEmacs package. + (Pointed out by Hidetomo Machi ) + * Change: wl-ja.texi + Sync up section MIME modules. + * Change: keep info files. + * New function: wl-kill-buffers + * Change: delete Sticky Message buffer in + wl-summary-force-exit and wl-exit. + (Adviced by Masahiro MURATA ) + +1999-09-14 Masahiro MURATA + + * Fix: wl-summary-read causes error in sticky summary under + XEmacs-21.1.6. + +1999-09-14 Koichiro Ohba + + * Fix: ja/dot.wl + elmo-eword-decode-string is still used. + +1999-09-13 Yuuichi Teranishi + + * Change: tm-wl.el + defined some functions by defalias-maybe. + * Remove: smtp.el + flim or clime includes it. + +1999-09-13 Yuuichi Teranishi + + * 2.2.0 - "Vogue" + * smtp.el: Sync up with flim-1.13.2. + * New variable: wl-install-els. + If nil, el files are not installed(for WL-CFG). + * Stickey Message changes for wl-draft-reply etc. + * Rename: wl-drfat-buffer-cur-message-buffer -> + wl-current-message-buffer(moved to wl-util.el) + * Change: elmo-cross-device-link-error-p definition + for MSDOS-mounted filesystem in UNIX. + (According to the report from pf21 GOTO_Toshiya + ) + +1999-09-13 Mito + + * Change: Stickey Message. + * Change: New guess module of score file. + * Change: el files are also installed with elc files. + +1999-09-12 Yuuichi Teranishi + + * New file: samples/en/dot.* + * New directory: samples. + * Move: etc/*.xpm -> etc/icons/*.xpm + * Move: etc/TODO -> doc/TODO.ja + +1999-09-12 OKAZAKI Tetsurou + + * Fix: filter syntax of since, before is changed. + +1999-09-10 OKUNISHI -GTO- Fujikazu + + * im-wl-prog-imput-error-msg -> im-wl-dispatcher-error-msg. + +1999-09-10 Yuuichi Teranishi + + * removed defmacro of convert-standard-filename. + * removed defmacro of open-network-stream-as-binary. + * removed defmacro of with-current-buffer, with-temp-buffer etc. + * elmo-eword-decode-string -> abolished. + +1999-09-09 Yuuichi Teranishi + + * New variable elmo-default-imap4-user. + (According to the advice from Taiji.Can@atesoft.advantest.co.jp) + * 2.1.5 - "Unbelievable" + +1999-09-08 Yuuichi Teranishi + + * New variable: elmo-nntp-max-number-precedes-list-active. + Non-nil precedes max number obtained by `list active' command in nntp. + * New function: elmo-update-number which synchronizes max number of + nntp folder when elmo-nntp-max-number-precedes-list-active is + non-nil. + (Based on Kenichi OKADA 's report.) + +1999-09-06 Akihiro Motoki + + * Fix: elmo-localnews-append-msg has wrong number of arguments. + +1999-09-06 Yuuichi Teranishi + + * [im-wl] Copy `im-wl-prog-imput-error-msg' value to process buffer. + * Change: 'N','P' also ignores if current folder is + (elmo-folder-local-p). + (Adviced by Akihiro Motoki ) + +1999-09-03 Akihiro Motoki + + * Fix: 'p' skipps unread message even in localdir. + * New function: (elmo-folder-local-p) + +1999-09-03 Yuuichi Teranishi + + * Change: key bind of wl-template-select is changed to `C-cC-j'. + (Adviced by TSUMURA Tomoaki + Masahiro MURATA ) + +1999-08-31 Yuuichi Teranishi + + * Change: Message is changed for sending or queueing of draft. + +1999-08-31 OKUNISHI -GTO- Fujikazu + + * Change: [im-wl] quit setting buffer in sub-process. + +1999-08-30 Yuuichi Teranishi + + * Fix: [wl-ja.texi] now IMAP folder collects extra-fields. + (Pointed out by Sasaki Toshiya) + * Fix: Splited MIME message causes deadlock. + (Pointed out by Mikio Nakajima ) + +1999-08-30 OKUNISHI -GTO- Fujikazu + + * new im-wl.el + +1999-08-27 Yuuichi Teranishi + + * Fix: `K'/`L' (wl-summary-increase/lower-score) proceeds to + rule input status in the last line of Summary. + (Adviced by TSUMURA Tomoaki ) + * New variable: elmo-pop3-send-command-synchronously. + Wait sending next command until server response is received. + (According to Atsushi Tada 's patch) + * Fix: mime-store-message/partial-piece causes error in recent SEMI. + * Fix: Toolbar is not appeared in Draft mode in XEmacs. + +1999-08-26 Teruki SHIGITANI + + * Fix: wl-summary-save causes error in the last line of summary. + +1999-08-26 Yuuichi Teranishi + + * Change: default color for light background. + * Fix: invalid filter syntax /last=200/ causes error. + * Fix: imap access group could not specify root. + +1999-08-25 Yuuichi Teranishi + + * 2.1.4 - "Tears In Heaven" + * Change: [wl-ja.texi] Added explanation of C-u . in Summary. + (Pointed out by susumu-w@ops.dti.ne.jp) + +1999-08-24 Yuuichi Teranishi + + * Change: Cause error when refile or delete was failed in + wl-summary-exit. + * Fix: headers in split messages are not encoded. + * Fix: Unread status is not reflected for messages read in + unplugged status. + * Fix: In unplugged status, previous message is displayed if + uncached message is read. + * Fix: temp-mark highlighting doesn't precedes persistent marks in + wl-thread-open-close. (Pointed out by susumu-w@ops.dti.ne.jp) + * Change: wl-thread-insert-message: + don't use wl-summary-goto-top-of-current-thread. + * Change: (wl-summary-goto-top-of-current-thread) new implementation. + * Fix: wl-mail-setup-hook is not called when draft is created by "W". + (Pointed out by Kenichi OKADA ) + * Change: push -> wl-push. + (Pointed out by Masahiro MURATA ) + +1999-08-23 Yuuichi Teranishi + + * Change: quit defaliasing elmo-eword-decode-string. + * Change: display version of flim in User-Agent when tm is used. + * Fix: comparing function of partial ID. + +1999-08-22 Masahiro MURATA + + * Fix: elmo-nntp.el (elmo-nntp-catchup-msgdb): + if overview is not obtained, msgdb becomes (nil nil nil nil). + +1999-08-20 OKUNISHI -GTO- Fujikazu + + * elmo-pop3.el: reorganized elmo-pop3-list-folder. + +1999-08-20 Masahiro MURATA + + * New variable: wl-score-folder-alist-matchone. + * Change: expanded syntax of wl-score-folder-alist. + +1999-08-20 Mito + + * Change: [wl-score] if symbol 'guess' is specified + instead of score file name in wl-score-folder-alist, + file name is guessed from folder name. + +1999-08-19 Masahiro MURATA + + * Fix: (wl-summary-switch-to-clone-buffer): added + wl-summary-buffer-temp-mark-list, wl-summary-default-score, + wl-summary-important-above, wl-summary-temp-above, + wl-summary-mark-below, wl-summary-expunge-below to copy variables. + +1999-08-18 Yuuichi Teranishi + + * Fix: Implemented wl-thread-exec. + (Pointed out by "KJ.TASAKI" ) + * Change: Check remaining temp-marks before sync-all. + (Pointed out by Taiji.Can@atesoft.advantest.co.jp) + * Fix: [elmo-vars.el] berkeley-db fix was not reflected. + (Pointed out by Mikio Nakajima ) + * Fix: y2k problem in timezone-parse-date. + (Pointed out by Masahiro MURATA ) + +1999-08-17 Mikio Nakajima + + * Fix: autload setting of interactive commands in wl-fldmgr.el. + +1999-08-16 Masahiro MURATA + + * Change: Speed up scoring functions. + * Change: wl-summary-sort-by-{from|subject}: faster implementation. + * Change: wl-summary-switch-to-clone-buffer copies + wl-current-score-file and wl-score-alist. + * Added wl-as-mime-charset. + * Change: Use wl-score-mode-mime-charset instead of + wl-score-mode-coding-system. + * Change: set default table size of elmo-make-hash to 1024. + +1999-08-14 susumu-w@ops.dti.ne.jp + + * Fix: wl-thread-jump-to-msg causes error when called as command. + * Change: bind "J" to wl-thread-jump-to-msg in Summary. + * Change: localdir, localnew, maildir ignores unplugged status + in cursor moving. + * Change: t d doesn't take direction into account. + * Fix: c-u t d marks previous thread. + * Fix: 'd' displays next message, but t d does not. + * Change: skip message marked with 'D' in n & p. + +1999-08-14 Yuuichi Teranishi + + * Fix: [elmo] Cannot access remote folder of UW imapd. + +1999-08-04 Yuuichi Teranishi + + * Fix: message body is not displayed in wl-queue-folder. + (Pointed out by ) + * 2.1.3 - "Sukiyaki" + +1999-08-03 Kenichi OKADA + + * Change: Deleted extra Tab/Spaces from ChangeLogs. + * Fix: typo in wl-vars.el. + * Add: [wl-ja.texi] + wl-folder-{prefetch|mark-as-read-all}-current-entity. + +1999-08-03 Yuuichi Teranishi + + * Fix: even when queued messages caused error, they are deleted. + (Pointed out by Mikio Nakajima ) + * mmelmo-imap4.el: mime-goto-header-start-point, + mime-goto-header-end-point, mime-entity-header-buffer, + mime-entity-body-buffer is implemented. + (Pointed out by Taiji.Can@atesoft.advantest.co.jp) + * smtp.el: Trial new option: smtp-notify-success. + * wl-mime.el: merging pertial mesages sometimes failed. + (Pointed out by Shuichi Nishioka ) + * Fix: Multipart message could not be re-edited. + * Fix: temp mark processing is unwind-protected. + (Pointed out by Mito , + Masahiro MURATA , + Taiji.Can@atesoft.advantest.co.jp) + +1999-08-02 Mikio Nakajima + + * Fix: cannot toggle to online when POP3 connection is disappeared. + * Fix: [wl-ja.texi] + wl-toggle-plugged -> wl-draft-toggle-plugged. + +1999-08-01 Mikio Nakajima + + * Fix: If XEmacs is build with configure --with-database=berkdb, + elmo-database.el is not loaded although elmo-use-database + is set as non-nil. + +1999-07-30 Mito + + * Fix: Error causes when Summary's (window-height) is small. + +1999-07-29 Masahiro MURATA + + * Change: copy from (localdir, maildir, localnews, archive) to + (localdir, localnews, archive). + * Fix: wl-summary-pick + If multiple messages have same Message-ID, temp mark is put on only + first message. + * Change: correspond to `Followup-To: poster'. + * New command: wl-summary-supersedes-message + * wl-util.el (wl-string): Use set-text-properties instead of + format. + +1999-07-28 "A. SAGATA" + + * Fix: cannot reply to mails which are sent by user. + +1999-07-27 Masahiro MURATA + + * New function: elmo-multiple-field-body and + elmo-multiple-fields-body-list. + +1999-07-26 Masahiro MURATA + + * Fix: elmo-localnews-copy-msgs is called although it is not defined. + +1999-07-24 HAYAKAWA akio + + * Fix: error causes when wl-(un)plugged-hook is set. + +1999-07-23 Kenichi OKADA + + * Fix: wl-mail-setup-hook is not called when draft is created by "W". + +1999-07-22 Yuuichi Teranishi + + * Fix: wl-summary-cancel-message is not corresponded to + Sticky Summary. + +1999-07-16 Teruki SHIGITANI + + * Fix: [sample.dot.wl] To field is not decoded. + +1999-07-15 Masahiro Murata + + * Fix: void-function wl-summary-rescore-msgs. + +1999-07-15 Yuuichi Teranishi + + * Fix: elmo-imap4 also causes moji-bake in Emacs20 because of + wrong multibyte settings. + * 2.1.2 - "Rico Suave" + +1999-07-14 Yuuichi Teranishi + + * Change: Skip checking when "I" in Summary is invoked with + prefix-arg. + * Fix: In elmo-nntp, multibyte setting for Emacs 20 was invalid. + * Fix: messages with 'u' mark couldn't be set as unread. + * Fix: 'M-x wl-draft' causes error in XEmacs. + (pointed out by Taiji.Can@atesoft.advantest.co.jp) + * Fix: wl-summary-highlight is ignored in wl-summary-update3. + * Change: Display prefetched message number after "I". + * Fix: Summary buffer is set as modified after prefetching. + * Fix: messages marked with "U" cannot be prefetched by "I" in Folder. + (susumu-w@ops.dti.ne.jp) + +1999-07-14 Masahiro MURATA + + * Change: [wl-score] (wl-score-simplify-subject) + use wl-score-simplify-fuzzy-regexp instead of + wl-summary-subject-func. + * Fix: multiple same cache is created in buffer-cache. + +1999-07-13 Masahiro MURATA + + * delete-if -> elmo-delete-if. + +1999-07-13 Yuuichi Teranishi + + * Fix: skipped prefetching messages are not taken into account in 'I'. + (reported by susumu-w@ops.dti.ne.jp) + * 2.1.1 - "Praying For Time" + +1999-07-12 Yuuichi Teranishi + + * wl-draft-insert-signature -> eliminated. + * wl-summary-prefetch-all-new -> eliminated. + * Fix: when password prompt is interrupted by C-g, + wrong-type-argument databasep nil sometimes occurs. + (pointed out by "MATSUBAYASHI 'Shaolin' Kohji" + ) + * New variable: wl-summary-incorporate-marks. + messages with specified marks are prefetched by 'I' in Summary. + * Fix: delete '(elmo-set-buffer-multibyte nil)' from elmo-nntp.el and + mmelmo.el (adviced by Shigeru OKUMURA ) + * Fix: define dummy make-face function in wl-mule.el if not bounded. + (adviced by HAYAKAWA akio , + OKUNISHI -GTO- Fujikazu ) + * Fix: pop3 folder caused in unplugged status. + (pointed out by HAYAKAWA akio .) + +1999-07-12 Masahiro MURATA + + * Fix: fetcing failed if elmo-msgdb-extra-fields is nil. + +1999-07-11 Masahiro MURATA + + * save elmo-crosspost-message-alist. + * Change: use elmo-object-load and elmo-object-save if possible. + * Change: [Scoring] + references or thread entries are not added automatically + in wl-summary-rescan or sync-all. + * extra field can be fetched in imap4 folders. + +1999-07-10 Kenichi OKADA + + * Change: 'W' in localnews also completes Newsgrops field. + +1999-07-08 OKUNISHI -GTO- Fujikazu + + * Fix: internal("'mark") was not work on Nemacs. + +1999-07-07 Yuuichi Teranishi + + * Fix: custom group of wl-summary-mark-below is 'wl-score. + (Pointed out by Masahiro MURATA ) + * Change: In wl-summary-incorporate, use + (wl-summary-prefetch-region (point-min) (point-max)) + instead of wl-summary-prefetch-all-new. + (Adviced by Masahiro MURATA ) + * Fix: C-u . does not work in Summary. + (pointed out by Hideo Matsumoto ) + +1999-07-06 sen_ml@eccosys.com + + * rfc2368.el - version 0.3. + +1999-07-06 Hideo Matsumoto + + * New variable: wl-draft-use-frame. + If non-nil, a new frame is created for draft. + +1999-07-06 Masahiro MURATA + + * Fix: quoted lambda in mapcar of wl-day-number. + * Change: [wl-score.el] + Simplify subject string matching in wl-summary-{increase|lower}-score. + Changed to buffer local variable: wl-current-score-file and + wl-score-alist. + * Change: [wl-summary.el] + timing of setting wl-summary-scored to nil. + * Rename: + wl-score-simplify-subject-fuzzy-regexp -> + wl-score-simplify-fuzzy-regexp + wl-score-simplify-buffer-fuzzy-step -> elmo-buffer-replace. + * Change: [wl-ja.texi] score description is changed. + * Fix: [wl-draft.el] added autoload setting. + * Fix: [sample.dot.wl] + deleted wl-summary-next-no-unread. added score setting. + +1999-07-06 Yuuichi Teranishi + + * Fix: load timing for wl-nemacs.el etc. is changed. + * Fix: defined rassoc for Nemacs. + * Fix: Nemacs causes error when 'm' is typed in Folder mode. + * Fix: default value for wl-use-scoring is set to nil in Nemacs. + * New function: elmo-delete-if. replacement of delete-if. + * Fix: Nemacs bytecompiler causes error (defvar nil nil). + (pointed out by Taiji.Can@atesoft.advantest.co.jp) + * 2.1.0 - "Ordinary World" + +1999-07-05 Yuuichi Teranishi + + * Fix: partial messages couldn't be merged. + (pointed out by Taiji.Can@atesoft.advantest.co.jp) + * Change: + wl-summary-rescore also uses wl-summary-rescore-partial-threshold. + * Change: display processing message in + wl-summary-score-update-all-lines. + +1999-07-04 Masahiro MURATA + + * Add: New key wl-score.el: date, extra, followup, thread. + * Change: File specified by `wl-score-default-file-name' + is always loaded. + * New Feature: Score editing in Summary, Score. + * Change: [wl-vars.el] defcustoms are re-arranged. + * Add: [wl-highlight.el] defface group. + +1999-07-01 Yuuichi Teranishi + + * New Feature: New sync range: rescan-noscore. + * Change: score takes effect on read messages in rescan/sync-all. + * New variable: wl-summary-rescore-partial-threshold. + for scoring in rescan, sync-all. + * wl-edit-again-func->wl-edit-decode-message-func + (adviced by tomo@etl.go.jp (MORIOKA Tomohiko).) + * Change: eliminated japanese comment of elmo-util.el. + * Change: Implementation of wl-refile-alist-setup is changed. + +1999-06-29 TSUMURA Tomoaki + + * Change: Don't check wl-refile-(msgid-)alist is loaded or not + every wl-refile-(msgid-)learn or wl-refile-guess-*. + * Change: Don't execute wl-refile-alist-save every + wl-refile-(msgid-)learn. + * Change: return value of wl-refile-(msgid-)learn. + +1999-06-29 Shuhei KOBAYASHI + + * Change: Enclosed require 'cl by eval-when-compile. + +1999-06-29 OKUNISHI -GTO- Fujikazu + + * Fix: Nemacs couldn't exit folder by [Space] if unread was 0. + * Fix: cl.el' member () overrides poe-18.el' member (). + +1999-06-29 Yuuichi Teranishi + + * Change: corresponded to AIR MAIL(AIRCimapd release 2.00). + (Based on the report from Sasaki Toshiya + ) + +1999-06-29 Yuuichi Teranishi + + * Change: changed the meaning of expunge to + 'mark as read and eliminate from summary buffer'. + * report expunged messages. + +1999-06-28 Shuhei KOBAYASHI + + * Change: Eliminated to use md5-encode in elmo-pop3.el. + +1999-06-28 OKUNISHI -GTO- Fujikazu + + * MK-MK: + quoted (mapcar (lambda ..)) for Emacsen based on v18. + * Fix: Nemacs installes wl-mule.elc. + redefined defgroup(), defcustom(). + * Fix: wl-summary.el, wl-demo.el: + Avoided error for non-float Emacsen. + * Fix: wl-nemacs.el: + dummy completing-read() is added. + read-char-exclusive() causes error. + +1999-06-28 Masahiro MURATA + + * Fix: wl-summary-pick doesn't work correctly if + default-case-fold-search is nil. + * Fix: Although wl-auto-select-next is non-nil, + doesn't change folder if there are more than two important marks. + +1999-06-28 Yuuichi Teranishi + + * New function: wl-summary-delete-all-delete-marks. + * Fix: (wl-summary-cleanup-temp-marks) was called twice. + (pointed out by A.SAGATA ). + +1999-06-27 Masahiro MURATA + + * Change: no scoring when changing folder by + wl-summary-goto-folder-subr. + * Change: Abolished wl-summary-next-no-unread. + * Change: default value of wl-summary-move-order: 'new -> 'unread. + +1999-06-27 OKUNISHI -GTO- Fujikazu + + * Fix: Nemacs causes (wrong-type-argument listp 1). + * Fix: Nemacs causes error because of absense of timer function. + +1999-06-27 Masahiro MURATA + + * Change: set coding system for score file as ctext (*ctext). + +1999-06-26 Kenichi OKADA + + * Add: Handle "nntp:" and "news:" URL like "mailto:". + (-> wl-utils.el) + +1999-06-25 Masahiro MURATA + + * Fix: [wl-score.el] + coding-system processing was wrong. + +1999-06-25 Masahiro MURATA + + * New file: [wl-score.el] + Scoring feature! + * Change: [wl-summary.el] (wl-summary-sync-update3) + Changed the timing of wl-folder-set-folder-updated. + * Change: (wl-summary-update-crosspost) + mark as read without opening thread. + * New function: [wl-util.el] `wl-delete-alist'. + * New macro: [wl-util.el] + `wl-as-coding-system' and emulate function `pp'. + +1999-06-24 pf21 GOTO_Toshiya + + * Add: [wl-ja.texi] + added explanation of wl-thread-open-reading-thread. + +1999-06-24 Kenichi OKADA + + * Fix: elmo-cache-expire causes error. + +1999-06-24 sen_ml@eccosys.com + + * Fix: utils/rfc2368.el. + +1999-06-24 Yuuichi Teranishi + + * 2.0.1 - "Now And Forever" + * Fix(incompletely): + wl-draft-reedit deletes lines before "--text follows this line--" + in message body. + (pointed out by Kenichi OKADA ) + +1999-06-24 MAKINO Takashi + + * New function: wl-refile-guess-by-msgid. + +1999-06-23 Akihiro Motoki + + * Fix: When (setq wl-stay-folder-window t) and started with + 'wl-draft' command, wl-draft-send-and-exit and wl-draft-kill failes. + +1999-06-23 Kenichi OKADA + + * Fix: [wl-ja.texi] + wl-template-alist : file -> body-file + +1999-06-23 Yuuichi Teranishi + + * Change: C-c C-y with prefix in Draft cites from cut buffer. + * Change: elmo-imap4-int-string-to-list: abolished. + (advised by Masahiro MURATA ) + * Change: binded wl-summary-save to 'e' in Summary. + * Change: removed unused let binding in wl-set-string-width. + * Fix: Unplugged MH refile calls elmo-copy-msgs and elmo-append-msg. + (pointed out by Koji IIDA ) + +1999-06-22 Yuuichi Teranishi + + * Fix: wl-draft-prepared-config-exec was binded to C-c C-d and C-c C-e. + * Change: set wl-completion-buf-name as standard "*Completions*". + * Fix: wl-message-buffer-created-hook was not called correctly. + (pointed out by Akihiro Motoki ) + +1999-06-22 Masahiro MURATA + + * Fix: [elmo-nntp.el] XOVER size value was wrong. + * Change: (elmo-nntp-string-to-vector): Renamed from + `elmo-nntp-string-to-list'. + * Change: [elmo-localdir.el] get file size by file-attributes. + +1999-06-21 OKUNISHI -GTO- Fujikazu + + * Change: [elmo-pop3] + elmo-pop3-max-of-folder: new implementation. + +1999-06-21 OKUNISHI -GTO- Fujikazu + + * Change: display syntax errors in .wl. + * tiny additional patch. + +1999-06-19 Masahiro MURATA + + * ignore defface definition when (featurep 'tinycustom). + +1999-06-18 Shigeru OKUMURA + + * Fix: nntp still causes moji-bake. + +1999-06-18 Masahiro MURATA + + * Fix: '@' expands alias address correctly. + +1999-06-16 Yuuichi Teranishi + + * New variable: wl-use-dnd. + +1999-06-16 Masahiro MURATA + + * Change: [elmo-nntp] + elmo-list-folder uses "LISTGROUP" command. + * Change: [elmo-nntp] + keep xover settings for each server. + +1999-06-16 Shigeru OKUMURA + + * Fix: + sjis or euc message causes moji-bake. + +1999-06-16 Yuuichi Teranishi + + * Change: [elmo-imap4] + corresponds cram-md5. + +1999-06-15 Yuuichi Teranishi + + * Fix: [tm-wl.el] + error: Split sender is not specified for `wl-draft-mode'. + (pointed out by Toshihiko Kodama ) + +1999-06-14 Yuuichi Teranishi + + * Fix: [wl-ja.texi] + explanation for `wl-draft-enable-queuing' was duplicated. + (pointed out by Toshihiko Kodama ) + +1999-06-14 OKUNISHI -GTO- Fujikazu + + * Change: + wl-detect-info-directory() detects directory more cleverly. + +1999-06-13 Masahiro MURATA + + * buffer cache. + * New variable: elmo-use-buffer-cache + * buffer cache prefetching is implemented. + * New variable: wl-cache-prefetch-folder-type-list. + * New variable: elmo-buffer-cache-size. + * New variable: wl-cache-prefetch-folder-list. + * New variable: wl-summary-no-mime-folder-list. + +1999-06-13 OKUNISHI -GTO- Fujikazu + + * WL-MK: + Fix: wl-texinfo-format() requires 'wl-vars. + Change: `WL_TEXINFO_NOTAGIFY' was abolished. + Change: Don't keep back `wl-ja.info' in the source-tree when + installing. + +1999-06-13 Sen Nagata + + * New file: utils/wl-use-agent.el, utils/rfc2368.el + +1999-06-11 Yuuichi Teranishi + + * Fix: + argunemt for elmo-imap4-get-connection was invalid. + (pointed out by ) + * 2.0.0 - "Mmmbop" + * Change: + if wl-summary-partial-highlight-above-lines is nil, use + wl-summary-highlight-partial-threshold to highlight summary lines. + * Change: + Updated util/wl-user-agent.el provided by Sen Nagata + (pointed out by OKUNISHI -GTO- Fujikazu + ). + +1999-06-10 Kenichi OKADA + + * Fix: + error occurs when accessing to imap4 or nntp access group + if port number is not default value. + +1999-06-10 Yuuichi Teranishi + + * Rename: + ChangeLog.en -> ChangeLog + ChangeLog -> ChangeLog.ja + * Add: [wl-ja.texi] + added explanation of variable `wl-plugged'. + (adviced by Daisuke Ikeda ) + +1999-06-09 Yuuichi Teranishi + + * New variable: + elmo-default-pop3-ssl, elmo-default-nntp-ssl, elmo-default-imap4-ssl. + * Rename: + elmo-nntp-port -> elmo-default-nntp-port + elmo-imap4-port -> elmo-default-imap4-port. + (Adviced by Kenichi OKADA ) + * Change: [elmo] + use SSL if "!" is specified in the tail of folder name of + imap4, nntp, pop3. + * Fix: [elmo] + connection cache for imap4, nntp, pop3 are conflicted. + +1999-06-09 OKUNISHI -GTO- Fujikazu + + * New variable: elmo-default-pop3-server. + * Fix: [mmelmo-imap4.el]. + * Fix: [wl-ja.texi]. + +1999-06-08 Kenichi OKADA + + * Change: + port nunber can be specified in IMAP4 folder name. + +1999-06-07 Akihiro Motoki + + * Fix: + preserve message order in trash folder. + * Change: + wl-summary-pick can use field names in elmo-msgdb-extra-fields. + +1999-06-07 Yuuichi Teranishi + + * Change: + wl-summary-jump-to-parent-message() precedes In-Reply-To. + (pointed out by A.SAGATA ). + * Change: + if From field matches wl-from, preserve To, Cc, Newsgroups in reply. + (adviced by TSUMURA Tomoaki ) + +1999-06-06 Masahiro MURATA + + * unread message is not highlighted in + wl-folder-mark-as-read-all-entity, wl-folder-sync-entity, + wl-folder-prefetch-entity on sticky summary. + +1999-06-05 Masahiro MURATA + + * Fix: + wl-folder-no-auto-check-folder-p precedes wl-auto-check-folder-list. + * Fix: + wl-summary-switch-to-clone-buffer doesn't copy + wl-summary-buffer-new-count and wl-summary-buffer-unread-count. + * Fix: + wl-folder-empty-trash doesn't show summary. + * Fix: + wl-summary-goto-folder-subr causes error in recenter. + * Fix: + suppress warnings while byte-compiling bbdb-wl.el with bbdb2. + * New variable: + wl-folder-suspend-hook. + +1999-06-06 OKUNISHI -GTO- Fujikazu + + * Fix: + "V" requires sync update. also, "C-u V" requires sync update. + +1999-06-04 OKUNISHI -GTO- Fujikazu + + * Fix: [wl-draft.el (wl-draft-reedit)] + bind change-major-mode-hook to nil to avoid font-lock. + * Fix: [wl-message.el (wl-message-refer-article-or-url)] + move cursor in the summary buffer. + +1999-06-03 Masahiro MURATA + + * Fix: + when move from sticky summary, temp-mark is deleted but + highlight remains. + * Fix: + make wl-summary-buffer-copy-list buffer-local-variables. + * Change: + when entering summary, use set-buffer instead of switch-to-buffer + if function is not called interactive. + +1999-06-03 Yuuichi Teranishi + + * Fix: implemented elmo-imap4-identical-name-space-p. + (pointed out by Takaaki MORIYAMA ) + +1999-06-03 "A. SAGATA" + + * Fix: strange behavior of wl-draft-exit + when sticky summar exists. + * Fix: mR and mf are duplicated in menubar. + * Fix: wl-summary-jump-to-current-message. + +1999-06-02 Yuuichi Teranishi + + * Change: [WL-MK] + compile and install "bbdb-wl" if BBDB exists in install-package for + XEmacs. + * New variable: wl-summary-keep-cursor-command + command list for keep cursor. + * Change: [mmelmo.el, mmelmo-imap4.el] + correspond to FLIM 1.13 API. + +1999-06-02 OKUNISHI -GTO- Fujikazu + + * Change: [WL-MK] + compile and install "bbdb-wl" if BBDB exists. + +1999-06-02 Kenichi OKADA + + * Fix: + suppressed warnings while byte-compiling elmo-pop3.el + * Fix: [WL-MK] + second make causes error after changing elmo-*.el + +1999-06-02 Masahiro MURATA + + * Fix: + new message is not highlighted in sticky summary updating. + +1999-06-01 Yuuichi Teranishi + + * branched from 1.0.1. + +1999-06-01 Masahiro MURATA + + * Change: + if summary buffer already exists, don't update and keep cursor + position when entering summary. + * New variable: wl-ask-range + if non-nil, 'g' uses value of wl-folder-sync-range-alist. + * Change: + store history of wl-summary-read-folder in wl-read-folder-hist. + * New command: wl-summary-goto-last-visited-folder + +1999-06-01 Yuuichi Teranishi + + * 1.0.1 - "The Look" + * Change: + deleted wl-ja.info from package. + +1999-06-01 Sen Nagata + + * New file: [wl-user-agent.el] + support interface of compose-mail. + +1999-05-31 "A. SAGATA" + + * Change: + when draft is finished by sending or quitting, resume folder window + when wl-stay-folder-window is non-nil. + +1999-05-31 Yuuichi Teranishi + + * Change: + wl-folder-sync-range-alist takes effect when + entered to folder from folder mode. + (pointed out by Toshihiro KAMISHIMA ). + * Fix: + multi-reply/forward causes error when wl-draft-reply-buffer-style + is 'full. + (pointed out by A.SAGATA ). + * Change: + don't load msgdb when entered to the sticky summary. + (advised by Masahiro MURATA ) + * Fix: + wl-summary-exit saves msgdb uselessly. + +1999-05-29 OKUNISHI -GTO- Fujikazu + + * Fix: [wl-mime.el, tm-wl.el] + regexp was not regexp-quote'ed in + (tm-)wl-mime-combine-message/partial-pieces() + +1999-05-28 Yuuichi Teranishi + + * Change: + speed up elmo-localdir-search. + +1999-05-26 Shuhei KOBAYASHI + + * Change: + speed up elmo-archive-search. + +1999-05-25 OKUNISHI -GTO- Fujikazu + + * Change: + speed up elmo-move-msgs() for localdir, localnews. + new variable `elmo-localdir-lockfile-list' must be specified for + MDA like procmail. + * Change: + speed up some functions. + +1999-05-24 Kenichi OKADA + + * Change: + support SSL for POP3. + * Change: + in elmo-pop3-get-spec, change type of variable port from string + to integer. + * Fix: + elmo-default-pop3-port,elmo-default-pop3-authenticate-type does + not take effect. + +1999-05-24 "A. SAGATA" + + * Fix: + customize causes some mismatches. + +1999-05-24 Yuuichi Teranishi + + * Change: wl-use-highlight-mouse-line' s default value is set to nil. + +1999-05-21 OKUNISHI -GTO- Fujikazu + + * Rename: + WL-ELS -> WL-MK + +1999-05-20 Yuuichi Teranishi + + * Change: + removed delete-other-windows () in wl-exit (). + * Fix: + Make wl-summary-force-exit interactive + (pointed out by Ishikawa Ichiro ). + +1999-05-20 Hidetoshi Shimokawa + + * Fix: + highlight is not active on ttys when device-class is color. + +1999-05-20 "A. SAGATA" + + * Add: [wl-ja.texi] + about highlights. + +1999-05-19 "A. SAGATA" + + * Add: + wl-highlight-signature-separator. + +1999-05-19 TSUMURA Tomoaki + + * Fix: + wl-summary-jump-to-message-by-message-id does not work well when + parent message is hidden in closed threads. + +1999-05-19 Yuuichi Teranishi + + * Fix: + wl-summary-msgdb-load-async. + * Change: + timing of set-buffer in wl-summary-goto-folder. + * Fix: + wl-summary-mark-as-read-all does not work well when target + messages is hidden in closed threads. + (pointed out by Hajime Ohsawa ). diff --git a/etc/ChangeLog.3.ja b/etc/ChangeLog.3.ja new file mode 100644 index 0000000..aaacf5e --- /dev/null +++ b/etc/ChangeLog.3.ja @@ -0,0 +1,3066 @@ +2000-03-24 Yuuichi Teranishi + + * 1.1.0 - "Overjoyed" + +2000-03-23 Yuuichi Teranishi + + * wl-refile.el (wl-refile-guess-func-list): $BJQ?tDj5A$r=$@5!#(B + (KOYAMA Tetsuji $B$5$s$h$j8f;XE&(B) + * 1.1.0pre6 - "Overjoyed-pre6" + * wl-folder.el (wl-create-folder-entity-from-buffer): localnews $B$NDj5A(B + $B$,$"$@L>Dj5A$K$J$C$F$7$^$&$N$r=$@5!#(B + (AOXI Tenghe $B$5$sB>$h$j8f;XE&(B) + +2000-03-23 OKAZAKI Tetsurou + + * wl-summary.el (wl-summary-mode-menu-spec): wl-draft $B$r(B + wl-summary-write $B$KJQ99!#(B + (wl-summary-msg-marked-as-target): + wl-summary-msg-marked-as-temp $B$+$i2~L>!#(B + * wl-thread.el (wl-thread-close-all): $B6I=jJQ?tL>$rJQ99!#(B + +2000-03-22 Akihiro MOTOKI + + * wl-refile.el (wl-refile-guess-func-list): $B?75,JQ?t!#(B + (wl-refile-guess): wl-refile-guess-func-list $B$r;H$&$h$&$K$7$?!#(B + +2000-03-22 Yuuichi Teranishi + + * wl-mime.el: Byte compile $B$N(B Warning $B$r8:$i$7$?!#(B + * wl-xmas.el,wl-mule.el,wl-nemacs.el (wl-make-modeline): $BDj5A!#(B + XEmacs $B$G$O%W%i%0$N%"%$%3%sI=<($r%G%U%)%k%H$K$7$?!#(B + (Daiki Ueno $B$5$s$h$j8f=u8@(B) + * wl-util.el (wl-make-modeline-subr): wl-make-modeline $B$+$i2~L>!#(B + * utils/bbdb-wl.el (bbdb-wl-update-record): Sticky summary $BBP1~!#(B + (bbdb-wl-update-record, bbdb-wl-get-update-record): + raw buffer $B$,(B multibyte $B$K$J$i$J$$$h$&$K$7$?!#(B + * wl-draft.el (wl-draft-reply): $BF1MM!#(B + * 1.1.0pre5 - "Overjoyed-pre5" + +2000-03-21 Yuuichi Teranishi + + * NEWS.ja: $B?75,%U%!%$%k!#(B + * elmo-maildir.el (elmo-maildir-list-folders): + elmo-have-link-count $B$r(B nil $B$K94B+(B + (Masahiro MURATA ($BB $B$5$s$N8f=u8@(B)$B!#(B + * wl-summary.el (wl-summary-edit-addresses-subr): + $B%"%I%l%9$r(B downcase $B$9$k$h$&$K$7$?!#(B + +2000-03-18 TAKAHASHI Kaoru + + * NEWS: $B?75,%U%!%$%k!#(B + +2000-03-17 Yuuichi Teranishi + + * wl-message.el (wl-message-follow-current-entity): + $B%*%j%8%J%k%P%C%U%!$r;2>H$9$k$h$&$K$7$?(B + (OKAZAKI Tetsurou $B$5$s$N8f;XE&(B)$B!#(B + * elmo-maildir.el (elmo-maildir-list-folders): + Maildir $B$K$J$C$F$$$k$+$I$&$+%A%'%C%/$9$k$h$&$K$7$?!#(B + ( $B$5$s$N8f;XE&(B) + +2000-03-15 Yuuichi Teranishi + + * wl-folder.el (wl-create-folder-entity-from-buffer): $B6uGr$,#28D0J>e(B + $B$"$k>l9g$K2r@O$K<:GT$9$k$N$r=$@5!#(B + * wl-summary.el (wl-summary-edit-addresses): $B%*%j%8%J%k%P%C%U%!$+$i(B + $B%"%I%l%9>pJs$rF@$k$h$&$K$7$?!#(B + (wl-summary-prefetch): wl-prefetch-threshold $B$r(B nil $B$K94B+$9$k$N$O(B + $B$d$a$?!#(B + +2000-03-14 Yuuichi Teranishi + + * 1.1.0pre4 - "Overjoyed-pre4" + * $B%(%i!<%a%C%;!<%8$N:G8e$,(B "." $B$G=*$i$J$$$h$&$K$7$?!#(B + * elmo/elmo-archive.el (elmo-archive-copy-msgs): same-number $B$N$H$-$K(B + maildir $B$J$i%U%!%$%kL>$=$N$^$^$@$H;W$o$J$$$h$&$K$7$?!#(B + * wl-expire.el (wl-expire-archive-get-folder): elmo-safe-filename $B$N(B + $BBe$o$j$K(B elmo-replace-msgid-as-filename $B$r;H$&$h$&$K$7$?!%(B + * wl-folder.el (wl-folder-goto-folder-subr): $B%G%U%)%k%H$r(B + wl-default-folder $B$H$7$?!%(B + (okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) $B$5$s$N8f=u8@(B) + * wl-folder.el (wl-create-folder-entity-from-buffer): + $B%U%)%k%@L>$K6uGr$,4^$^$l$F$$$F$b$h$$$h$&$K$7$?!#(B + * wl-summary.el (wl-summary-jump-to-msg-by-message-id): + $B%+%l%s%H%U%)%k%@$G%?!<%2%C%H$,8+IU$+$C$?>l9g$O(B + wl-thread-jump-to-msg $B$r;H$&$h$&$K$7$?!%(B + +2000-03-13 Yuuichi Teranishi + + * wl-vars.el (wl-summary-skip-mark-list): $B?75,JQ?t!#(B + * wl-summary.el (wl-summary-prefetch): interactive $B$N>l9g$@$1(B + wl-prefetch-threshold $B$r(B nil $B$H$9$k$h$&$K$7$?!#(B + (Akihiro MOTOKI $B$5$s$N8f;XE&(B) + (wl-summary-exec-subr): $B%^!<%/Am?t$N?t$(J}$,4V0c$C$F$$$?$N$r=$@5(B + (OKAZAKI Tetsurou $B$5$s$N8f;XE&(B)$B!#(B + (wl-summary-next, wl-summary-prev): wl-summary-skip-mark-list $B$r;H$&(B + $B$h$&$K$7$?!#(B + (wl-summary-move-cached-regex): defmacro->defun$B!#(B + * etc/ja.Emacs: $B99?7!#(B + * elmo-imap4.el (elmo-imap4-search): from-msgs $B$r9MN8$9$k$h$&$K$7$?!#(B + * elmo-maildir.el (elmo-maildir-search): $B=$@5!#(B + * mmelmo-imap4-1.el (mmelmo-imap4-parse-bodystructure-string): + literal $B$NFI$_ + + * wl-expire.el: Filter folder $B$G(B expire $B=PMh$J$$>l9g$,$"$k$N$r=$@5$7$?!#(B + * wl-fldmgr.el: $B2~9T$r4^$`%U%)%k%@L>$d$"$@L>$J$I$r07$($J$$$h$&$K$7$?!#(B + +2000-03-12 Masahiro MURATA ($BB + + * wl-fldmgr.el (wl-fldmgr-get-path-from-buffer): + wl-desktop group $B$,JD$8$F$$$k$H$-$K%(%i!<$,=P$k>l9g$,$"$k$N$r=$@5!#(B + +2000-03-11 Masahiro MURATA ($BB + + * wl-folder.el (wl-folder-mode-menu-spec): $BDI2C!"99?7!#(B + +2000-03-08 TAKAHASHI Kaoru + + * wl-vars.el (wl-score-files-dir): wl-score-files-directory $B$+$i2~L>!#(B + * wl-score.el (wl-score-edit-file, wl-score-load-file, + wl-score-change-score-file): $BF1>e!#(B + +2000-03-08 Yuuichi Teranishi + + * wl-vars.el (wl-mime-charset): $B%G%U%)%k%HCM$r(B x-ctext $B$H$7$?!#(B + +2000-03-08 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * elmo-nntp.el (elmo-nntp-list-folders): + $B%k!<%H%U%)%k%@L>$,(B "" $B$N$H$-$NIT6q9g$r=$@5!#(B + +2000-03-07 Yuuichi Teranishi + + * 1.1.0pre3 - "Overjoyed-pre3" + * elmo-imap4.el (elmo-imap4-create-msgdb-from-overview-string): + $B%m!<%+%k$NL$FI>pJs$r9MN8$7K:$l$F$$$?$N$r=$@5!#(B + * elmo2.el (elmo-delete-folder): maildir $B$b%U%)%k%@:o=|2DG=$H$7$?!#(B + (elmo-move-msgs): $B%m!<%+%k$NL$FI>pJs$,0z$-7Q$,$l$J$$$N$r=$@5!#(B + * elmo-maildir.el (elmo-maildir-delete-folder): $B=q$-D>$7!#(B + * mmelmo.el (mime-parse-parameters-from-list): mmelmo-imap4.el $B$+$i(B + $B0\F0!#(B + * wl-message.el (wl-mmelmo-message-redisplay): mime-display-header-hook + $B$r(B nil $B$K94B+!#(B + * wl-mime.el (wl-mime-display-message): SEMI $B$N%P!<%8%g%sH=Dj$,(B + $B4V0c$C$F$$$?$N$r=$@5!#(B + (wl-summary-burst): mime-message-structure $B$r;2>H$7$J$$$h$&$K$7$?!#(B + (wl-mime-entity-read-field): $B?75,(B alias/macro$B!#(B + (wl-mime-combine-message/partial-pieces): wl-mime-entity-read-field + $B$r;H$&$h$&$K$7$?!#(B + (mime-edit-user-agent-value): XEmacs beta $B$N%P!<%8%g%sI=<($,=EJ#$9$k(B + $B$N$KBP=h(B (For SEMI 1.13.4 or earlier)$B!#(B + +2000-03-06 katsuta@cced.mt.nec.co.jp + + * elmo-util.el (elmo-buffer-field-condition-match): std11-field-body + $B$,(B nil $B$rJV$9>l9g$KBP=h!#(B + +2000-03-04 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * wl-summary.el (wl-summary-prefetch-msg): $B%^!<%/$r;2>H$7$J$$(B + $B$h$&$K$7$?!#(B + +2000-03-06 Yuuichi Teranishi + + * wl-summary.el (wl-summary-read-folder): "" $B$N$H$-$O%G%U%)%k%H$r;H$&(B + $B$h$&$K$7$?!#(B + * wl-fldmgr.el, wl-folder.el, etc: $B%a%C%;!<%8$OBgJ8;z$G(B + $B;O$^$k$h$&$K$7$?!#(B + * wl-draft.el (wl-draft-yank-original): kill-ring $B$+$i$N(B yank $B$,(B + $BF0$+$J$/$J$C$F$$$?$N$r=$@5!#(B + * mmelmo-1.el (insert-header): mmelmo-insert-sorted-header-from-buffer + $B$r;H$&$h$&$K$7$?!#(B + (insert-text-content): $B?75,%a%=%C%I!#(B + (run-hooks 'mmelmo-entity-content-inserted-hook) $B$9$k$h$&$K$7$?!#(B + * utils/bbdb-wl.el (bbdb-wl-show-bbdb-buffer): $B?75,4X?t!#(B + wl-summary-toggle-disp-folder-message-resumed-hook $B$KDI2C!#(B + * 1.1.0pre2 - "Overjoyed-pre2" + * elmo-maildir.el (elmo-maildir-sequence-number-internal): $B?75,JQ?t!#(B + (elmo-maildir-make-unique-string): + v19 $B8~$1$KDj5A$5$l$F$$$J$+$C$?$N$r=$@5!#$^$?!"(B + elmo-maildir-sequence-number-internal $B$r;H$&$h$&$K$7$?!#(B + (elmo-maildir-temporal-filename): 2 $BICBT$?$J$$$h$&$K$7$?!#(B + (toplevel): (eval-when-compile (require 'cl) $B$rDI2C!#(B + * wl-summary.el (wl-summary-buffer-number-column-detect): + re-search-forward $B$NJV$jCM$r;H$o$J$$$h$&$K$7$?!#(B + +2000-03-06 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * elmo-pop3.el (elmo-pop3-port-label): typo $B=$@5(B (port->ssl)$B!#(B + * elmo-nntp.el (elmo-nntp-sync-number-alist): + folder-mode$B$GL$FI?t$,%^%$%J%9$K$J$C$?$^$^$K$J$k>l9g$,$"$k$N$r=$@5!#(B + +2000-03-06 Yuuichi Teranishi + + * wl-summary.el (wl-summary-switch-to-clone-buffer): + wl-summary-buffer-number-column, + wl-summary-buffer-number-regexp $B$r0z$-7Q$0$h$&$K$7$?!#(B + (wl-summary-write): $B?75,%3%^%s%I!#(B'w' $B$K%P%$%s%I!#(B + * wl-draft.el (wl-draft): wl-summary-write $B8~$1$NF0:n$rDI2C!#(B + +2000-03-05 Yuuichi Teranishi + + * elmo-cache.el (elmo-cache-list-folder-subr): $B%G%#%l%/%H%j$rL5;k!#(B + * wl-summary.el (wl-summary-insert-line): $B?75,4X?t!#(B + (wl-summary-insert-summary, wl-summary-update-thread): + `wl-summary-insert-line' $B$r;H$&$h$&$K$7$?!#(B + * wl-thread.el (wl-thread-update-line-on-buffer-sub): + $BF1>e!#(B + * WL-MK (wl-info-lang): list $B$J$i4^$^$l$k(B lang $B$rA4It%$%s%9%H!<%k$9$k(B + $B$h$&$K$7$?!#(B + * elmo/elmo-maildir.el (elmo-maildir-append-msg): + new $B$G(B tmp $B$N%U%!%$%kL>$r$=$N$^$^;H$&$h$&$K$7$?!#(B + (elmo-maildir-list-folders): $B%k!<%H$r4^$`$h$&$K$7$?!#(B + +2000-03-04 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * wl-summary.el (wl-summary-buffer-set-folder): $B%3%i%`?t$N@_Dj$r:o=|!#(B + (wl-summary-goto-folder-subr): $B%3%i%`?t$rF0E*$K8!=P$9$k$h$&$K$7$?!#(B + (wl-summary-target-mark-forward): $B%U%)%o!<%I=g=x$r=$@5!#(B + (wl-summary-cleanup-temp-marks): $B$^$H$a=hM}%^!<%/$r:o=|$9$k$h$&$K$7$?!#(B + +2000-02-29 nisikawa@nisikawa.org ($B@>@n(B $BN + + * wl-thread.el (wl-thread-update-children-number): + wl-thread-update-children-number $B$+$i2~L>!#(B + $B?75,(B hook$B!"(Bwl-thread-update-children-number-hook $B$r8F$V$h$&$K$7$?!#(B + +2000-03-04 Masahiro MURATA ($BB + + wl-folder.el (wl-folder-sync-entity, + wl-folder-mark-as-read-all-entity, + wl-folder-prefetch-entity): Sticky $B8~$1$N%O%$%i%$%H@_Dj$N=$@5!#(B + +2000-03-03 Yuuichi Teranishi + + * elmo2.el (elmo-move-msgs): target $B$,(B 'null $B$N$H$-$OL$FI$NJ]B8$r(B + $B%9%-%C%W$9$k$h$&$K$7$?!#(B + * elmo-maildir.el (elmo-maildir-make-unique-string): + elmo-maildir-create-unique-string $B$+$iJQ99!#(B + (OKAZAKI Tetsurou $B$5$s$N8f=u8@(B) + * 1.1.0 pre1 - "Overjoyed-pre1" + +2000-03-02 Yuuichi Teranishi + + * wl-draft.el (wl-draft-reply-buffer): $B?75,%P%C%U%!%m!<%+%kJQ?t(B + (wl-draft-reply): `wl-draft-reply-buffer' $B$r@_Dj$9$k$h$&$K$7$?!#(B + (wl-draft-config-exec): `wl-draft-reply-buffer' $B$r;2>H$9$k$h$&$K$7$?!#(B + (wl-draft-reply): $BGQ;_!#(B + * WL-MK, WL-CFG (wl-info-lang): $B?75,JQ?t!#(B + * wl.texi: $B?75,%U%!%$%k!#(B + * Makefile, WL-MK, WL-CFG: ELISPDIR->LISPDIR$B!#(B + (TAKAHASHI Kaoru $B$5$s$h$j8fDs0F(B) + * elmo-maildir.el: $BBgI}$K=q$-D>$7!#(B + * elmo-util.el, elmo-msgdb.el, elmo-vars.el: maildir $B$N5-9f$r(B '.' + $B$H$7$?!#(B + * wl-folder.el, wl-summary.el, elmo-pop3.el, etc: $B%a%C%;!<%8$,BgJ8;z$G(B + $B;O$^$k$h$&$K$7$?!#(B + * elmo-vars.el (elmo-maildir-folder-path): $B?75,JQ?t!#(B + * elmo-internal.el (elmo-internal-list-folders): 'cache $B$H(B 'mark $B$r(B + $BJV5Q$9$k$h$&$K$7$?!#(B + +2000-03-02 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * elmo-nntp.el: starttls $BItJ,$N=$@5!#(B + * elmo-nntp.el, elmo-imap4.el: + list-folders $B$G(B "!" $B%^!<%/$,>C$($F$7$^$&$N$r=$@5!#(B + +2000-03-01 TAKAHASHI Kaoru + + * wl-score.el: $B%(%i!<%a%C%;!<%8$N(B "Illegal" $B$r(B "Invalid" $B$KJQ$($?!#(B + +2000-03-01 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * wl-summary.el (wl-summary-refile-subr): $B%-%c%C%7%e%U%)%k%@$X$N(B + $B%j%U%!%$%k$GL>A0$rE,@Z$J$b$N$K=$@5!#(B + * elmo-nntp.el: starttls $B$KBP1~(B($B + + * elmo-cache2.el: elmo-cache.el $B$K%^!<%8!#(B + * elmo-internal.el, elmo-util.el, elmo-msgdb.el: cache $B%P%C%/%(%s%I$r(B + internal $B$N0lIt$H$7$F07$&$h$&$K$7$?!#(B + +2000-03-01 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * elmo-cache2.el: $B?75,%P%C%/%(%s%I(B 'cache' $BDI2C!#(B + +2000-02-29 IMAI Takeshi + + * wl-expire.el (wl-folder-expire-entity): Sticky $B8~$1$N(B + $B%O%$%i%$%H@_Dj$N=$@5!#(B + +2000-02-28 Yuuichi Teranishi + + * elmo2.el (elmo-move-msgs): $BL$FI>pJs$r0z$-7Q$0$h$&$K$7$?!#(B + $B0z?t(B unread-marks $BDI2C!#(B + (elmo-msgdb-sync): $B:o=|!#(B + * wl-summary.el (wl-summary-exec): + elmo-move-msgs $B$KL$FI%^!<%/$rEO$9$h$&$K$7$?!#(B + (wl-summary-edit-petname): To $B$d(B Cc $B$bJT=8BP>]$H(B + $B$J$k$h$&$K$7$?!#(B + (wl-summary-edit-addresses): wl-summary-edit-petname $B$+$iJQL>!#(B + (wl-summary-edit-petname): $B:o=|!#(B + (wl-summary-mark-as-unread): $B%-%c%C%7%e$rM-8z$+$I$&$+$r9MN8!#(B + * wl-vars.el (wl-summary-toggle-disp-folder-message-resumed-hook) + (wl-summary-line-inserted-hook): $B?75,(B hook$B!#(B + (wl-summary-print-destination): $BHs2D;kNN0h$K(B + 'wl-summary-destination $B%W%m%Q%F%#$rDI2C$9$k$h$&$K$7$?!#(B + * wl-thread.el, wl-summary.el: $B%5%^%j9T$,(B insert $B$5$l$?8e!"(B + wl-summary-line-inserted-hook $B$r8F$V$h$&$K$7$?!#(B + * utils/bbdb-wl.el: + wl-summary-toggle-disp-folder-message-resumed-hook $B$G%]%C%W%"%C%W$9$k(B + $B$h$&$K$7$?!#(B + +2000-02-28 Masahiro MURATA ($BB + + * wl-folder-sync-current-entity $B$G$b(B Scoring $B$9$k$h$&$K$7$?!#(B + * sticky$B%U%)%k%@$G(B wl-summary-buffer-disp-msg $B$H%P%C%U%!$NI=<($,(B + $B$"$C$F$$$J$$$3$H$,$"$k$N$r=$@5$7$?!#(B + +2000-02-25 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * wl-message.el (wl-message-refer-article-or-url): + wl-summary-jump-to-msg-by-message-id$B$r8F$V:]!"5-;v$rH/8+$G$-$J$+$C$?(B + $B>l9g$O!"(Bwl-summary-redisplay $B$7$J$$$h$&$K$7$?!#(B + * wl-vars.el (wl-local-domain): $B=i4|@_DjJQ99!#(B + * wl.el (wl-check-environment): wl-local-domain $B$r(B hostname $B$r(B + $B=|$$$?ItJ,$H$_$J$9$h$&JQ99!#(B + * wl-util.el (wl-draft-make-message-id-string): $BF1>e!#(B + +2000-02-25 Yuuichi Teranishi + + * wl-expire.el (wl-folder-expire-entity): wl-summary-save-status $B$r(B + $B8F$V$h$&$K$7$?!#(B + +2000-02-24 Yuuichi Teranishi + + * wl-vars.el (wl-draft-send-hook): $B?75,(B hook$B!#(B + * wl-draft.el (wl-draft-send): wl-draft-send-hook $B$r8F$V$h$&$K$7$?!#(B + (Kenichi Sato $B$5$s$N8fMWK>(B) + +2000-02-23 Yuuichi Teranishi + + * elmo-cache.el (elmo-cache-save): $B%U%!%$%kL>$,D9$9$.$F%;!<%V$K(B + $B<:GT$9$k>l9g$KHw$($F(B (condition-case) $B$G3g$k$h$&$K$7$?!#(B + (Mikya Tani $B$5$s$N8fJs9p(B) + * wl-draft.el: FCC $B$K(B IMAP $B$NF|K\8l%U%)%k%@$,07$($J$+$C$?$N$r=$@5!#(B + (HIRATA Naoto $B$5$s$N8f;XE&(B) + +2000-02-21 Yuuichi Teranishi + + * wl-address.el (wl-address-header-extract-address): '\n' $B$r%"%I%l%9(B + $BJ8;zNs$H$_$J$7$F$7$^$&>l9g$,$"$k$N$r=$@5!#(B + (Tomotaka SUWA ($B?[K,(B $BM'?r(B) + $B$5$s$N8f;XE&(B) + * mmelmo.el (mmelmo-header-max-column): $B?75,JQ?t!#(B + (Kenichi Sato $B$5$s$h$j8fMWK>(B) + (mmelmo-header-inserted-hook): $B?75,(B hook. + (mmelmo-entity-content-inserted-hook): $B?75,(B hook. + * mmelmo-2.el (mime-insert-text-content): $B?75,(B entity $B%a%=%C%I!#(B + mmelmo-entity-content-inserted-hook $B$r8F$V$h$&$K$7$?!#(B + * mmelmo.el (mmelmo-insert-sorted-header-from-buffer): elmo-util.el + $B$+$i0\F0!"(B`mmelmo-header-max-column' $B$r;H$&$h$&$K$7$?!#(B + $B$^$?!"(Bmmelmo-header-inserted-hook $B$r8F$V$h$&$K$7$?!#(B + +2000-02-18 Yuuichi Teranishi + + * wl-message.el (wl-mmelmo-message-redisplay): wl-mime-display-message + $B$r;H$&$h$&$K$7$?!#(B + (Toshihiko Kodama ($B>.6L(B $BMxI'(B) + $B$5$s$N8f;XE&(B) + * wl-mime.el (wl-mime-display-message): $B?75,(B macro/alias. + * 2.2.18 - "Please Forgive Me" + * wl-summary.el (wl-summary-move-cached-regex): + unplugged $B$G$b(B 'D' $B%^!<%/$r%9%-%C%W$9$k$h$&$K$7$?!#(B + * elmo-msgdb.el (elmo-msgdb-expand-path): IMAP4 $B$N(B INBOX $B$r(B downcase + $B$9$k$h$&$K$7$?(B(Takeshi Chiba $B$5$s$N8f;XE&(B)$B!#(B + * wl-folder.el (wl-create-folder-entity-from-buffer): + $B%"%/%;%9%U%)%k%@Dj5A$K(B '}' $B$r4^$s$G$b$h$$$h$&$K$7$?!#(B + * wl-message.el (wl-mmelmo-message-redisplay): + mime-display-message $B$K%a%8%c!<%b!<%I$rEO$9$h$&$K$7$?!#(B + +2000-02-18 Daiki Ueno + + * wl-demo.el: Emacs 21 $BBP1~$N=$@5!#(B + +2000-02-17 Yuuichi Teranishi + + * mmelmo-imap4-2.el (mime-entity-buffer): $B%+%l%s%H%P%C%U%!$,(B + $BJQ2=$7$J$$$h$&$K$7$?!#(B + $B$^$?!"$^$@%U%'%C%A$5$l$F$$$J$$>l9g!"%U%'%C%A$9$k$h$&$K$7$?!#(B + * mmelmo-imap4-2.el (mime-write-entity-content): + $B?75,%a%=%C%I!#%;!<%V;~$K%9%-%C%W$7$?%Q!<%H$r%U%'%C%A$9$k!#(B + * mmelmo-imap4-2.el (mmelmo-imap4-fetched): + $B?75,%P%C%U%!%m!<%+%kJQ?t!#(B + * elmo-imap4.el (elmo-imap4-server-namespace): + $B?75,%P%C%U%!%m!<%+%kJQ?t!#(B + (elmo-imap4-open-connection): + elmo-imap4-server-namespace $B$r@_Dj$9$k$h$&$K$7$?!#(B + (elmo-imap4-parse-namespace): $B?75,4X?t!#(B + (elmo-imap4-process-folder-list): + elmo-imap4-server-namespace $B$r;H$&$h$&$K$7$?!#(B + (elmo-imap4-extra-namespace-alist): $B?75,JQ?t!#(B + * wl-util.el (wl-string-member, wl-string-match-member, + wl-string-delete-match, wl-string-match-assoc, wl-string-rassoc): + elmo-* $B$K2~L>!"(Bdefalias $B$H$7$?!#(B + +2000-02-17 Yuuichi Teranishi + + * bbdb-wl.el: wl-summary-toggle-disp-folder-off-hook $B$N@_Dj$rDI2C!#(B + +2000-02-16 Daiki Ueno + + * wl-demo.el: frame $B$N(B font parameter $B$G(B $B$,(B + $BM?$($i$l$F$$$k>l9g$K!"(Bfont-info $B$+$iCf1{$N:BI8$r7W;;$9$k$h$&$K$7$?!#(B + +2000-02-14 Yuuichi Teranishi + + * wl-summary.el (wl-summary-toggle-disp-folder): $B%&%#%s%I%&%5%$%:$,(B + $B>.$5$/$J$k>l9g$,$"$k$N$r=$@5!#(B + (Shigeru OKUMURA $B$5$s$N8f;XE&(B) + * wl-draft.el (wl-draft-insert-x-face-field-here): $B:G=i$N6uGr$r:o=|!#(B + (Akihiro MOTOKI $B$5$s$N8f;XE&(B) + +2000-02-12 Akihiro MOTOKI + + * elmo/elmo-localdir.el + (elmo-localdir-msgdb-create-overview-entity-from-file): + `timezone-make-date-arpa-standard' $B$K(B `current-time-zone' $B$NCM$r(B + $BEO$9$h$&$K$7$?!#(B + +2000-02-10 Yuuichi Teranishi + + * elmo/mmelmo-imap4-2.el (mmelmo-imap4-node-id-to-string): + "header" -> "0"$B!#(B + * elmo/mmelmo-imap4-1.el (mmelmo-imap4-node-id-to-string): + $BF1>e!#(B + (TSUMURA Tomoaki $B$5$s$N8f;XE&(B) + * wl-message.el (wl-message-follow-current-entity): wl-draft-reply + $B$N0z?t$K%5%^%j%P%C%U%!$rEO$9$h$&$K$7$?!#(B + * wl-summary.el (wl-summary-reply): wl-draft-reply $B$N0z?t$K(B + current-buffer $B$rEO$9$h$&$K$7$?!#(B + (wl-summary-msgdb-load-async): mailbox $B$r(B "" $B$G3g$k$h$&$K$7$?!#(B + * elmo-imap4.el: $BF1>e!#(B + +2000-02-09 UENO Kazuaki + + * wl-draft.el (wl-draft-queue-flush): elmo-dop-flush-confirm + $B$r;H$&$h$&$K$7$?!#(B + +2000-02-09 Yuuichi Teranishi + + * wl-draft.el (wl-draft): $B=i4|2=$N=g=xJQ99!#(B + (Taiji.Can@atesoft.advantest.co.jp $B$5$s$N8fJs9p$K4p$E$/(B) + +2000-02-08 Masahiro MURATA ($BB + + * wl-score.el (wl-summary-score-update-all-lines): + $B4{FI$K$7$?%a%C%;!<%8$K(B read-uncached mark $B$rIU$1$k;~$K%U%)%k%@ + + * wl-summary.el (wl-summary-target-mark-prefetch): + $B4{FIL$%-%c%C%7%e%^!<%/$,>C$($J$$$N$r=$@5!#(B + (Hironori Fukuchi $B$5$s$N8f;XE&(B) + * wl-summary.el (wl-summary-target-mark-prefetch): + $B%W%j%U%'%C%A$N?JD=$rI=<($9$k$h$&$K$7$?!#$^$?!"(B + $B%-%c%C%7%e$7$J$+$C$?>l9g$O(B '*' $B%^!<%/$r;D$9$h$&$K$7$?!#(B + * wl-dnd.el (start-drag): static-cond $B$GDj5A$7$J$*$7$?!#(B + * elmo2.el (elmo-buffer-cache-message): $BFI$_=P$7Cf$K(B + quit $B$9$k$H0c$&%a%C%;!<%8$rI=<($7$F$7$^$&$N$r=$@5!#(B + * elmo-filter.el (elmo-filter-list-folder-important): + elmo-search $B$N2s?t$r8:$i$7$?(B + (Akihiro MOTOKI $B$5$s$N8f=u8@(B)$B!#(B + +2000-02-07 Daiki Ueno + + * wl-xmas.el (wl-highlight-folder-current-line): + set-extent-properties $B$r;H$o$J$$$h$&$K$7$?!#(B + + * wl-draft.el (wl-smtp-extension-bind): Fixed. + +2000-02-07 Akihiro MOTOKI + + * elmo-util.el (elmo-buffer-field-condition-match): + $B%X%C%@$NCM$r(B eword-decode-string $B$G%G%3!<%I$7$F$+$iHf3S$9$k$h$&$K$7$?!#(B + +2000-02-07 Yuuichi Teranishi + + * wl-dnd.el: $B%P%$%H%3%s%Q%$%k;~$N(B Warning $B$r8:$i$7$?!#(B + (okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) $B$5$s$N8f;XE&(B) + * utils/sasl/sha1.el, utils/sasl/md5-el.el, + utils/sasl/hex-util.el, utils/sasl/sha1-el.el: $B:G?7HG$K(B update$B!#(B + (okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) $B$5$s$N8f;XE&(B) + * wl-vars.el (wl-demo-use-bitmap): wl-demo-display-logo $B$KJQ99!#(B + (wl-demo-display-logo): $B?75,JQ?t!#(B + * wl-demo.el: wl-demo-display-logo $B$r;H$&$h$&$K$7$?!#(B + +2000-02-07 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * wl-vars.el (wl-demo-use-bitmap): $B=i4|CM@_DjJ}K!$rJQ$($?!#(B + +2000-02-07 Yuuichi Teranishi + + * 2.2.17 - "One Of Us" + * elmo-util.el (elmo-y-or-n-p): $B?75,4X?t!#(B + * elmo-vars.el (elmo-dop-flush-confirm): $B?75,JQ?t!#(B + * elmo-dop.el (elmo-dop-queue-flush): elmo-y-or-n-p, + elmo-dop-flush-confirm $B$r;H$&$h$&$K$7$?!#(B + * elmo-imap4.el (elmo-delete-msgids): $B?JD=$rI=<($9$k$h$&$K$7$?!#(B + $B$^$?!"(Bexpunge $B$O:G8e$K#12s$@$1 + + * wl-folder.el, wl-xmas.el: -nw $B$G5/F0$5$l$?(B XEmacs $B$G(B frame $B$r(B + $B3+$$$?>l9g$G$b%"%$%3%s$,I=<($5$l$k$h$&$K$7$?!#(B + +2000-02-06 Yuuichi Teranishi + + * wl-highlight.el (wl-highlight-summary-target-face): $B?75,(B face$B!#(B + (temp-face $B$+$i2~L>(B) + * wl-vars.el (wl-demo-use-bitmap): wl-demo.el $B$+$i0\F0!#(B + defcustom $B$K$7$?!#$^$?!"=i4|CM$r(B (module-installed-p 'bitmap) $B$H$7$?!#(B + * wl-demo.el (wl-demo-use-bitmap): wl-vars.el $B$K0\F0!#(B + * WL-CFG: wl-demo-use-bitmap $B$r:o=|!#(B + * elmo-vars.el: Require 'poe, $B%P%$%H%3%s%Q%$%k;~$N(B warning $B$r8:$i$9!#(B + * wl-nemacs.el (buffer-disable-undo, rassoc, delete, string-to-number, + window-live-p, completing-read, accept-process-output, + get-buffer-window): $B:o=|!#(B + +2000-02-04 TAKAHASHI Kaoru + + * wl-demo.el (wl-demo): wl-demo-use-bitmap $B$r + + * INSTALL, INSTALL.ja: tm-8 $B$N(B URL $B$r99?7!#(B + * utils/hmac -> utils/sasl $B$K2~L>!#(B + * WL-ELS: HMAC->SASL$B!#(B + * WL-MK: HMAC->SASL$B!#(B + +2000-02-04 Yuuichi Teranishi + + * elmo-localdir.el + (elmo-localdir-msgdb-create-overview-entity-from-file): + format-time-string $B$r;H$&$N$r;_$a!"(Btimezone-make-date-arpa-standard + $B$r;H$&$h$&$K$7$?!#(B + * elmo-vars.el (elmo-time-format): $B:o=|!#(B + +2000-02-03 Yuuichi Teranishi + + * elmo-dop.el (elmo-dop-queue-flush): append-operations $B$N%-%c%s%;%k(B + $B=hM}$rDI2C!#(B + * wl-summary.el (wl-summary-refile-prev-destination, + wl-summary-copy-prev-destination): Fixed. + (IMAI Takeshi $B$5$s$N8fJs9p(B) + +2000-02-02 Akihiro MOTOKI + + * wl-vars.el (wl-prefetch-confirm-threshold): $BGQ;_$7!"(B + wl-prefetch-confirm $B$H(B wl-prefetch-threshold $B$KJ,N%!#(B + (wl-prefetch-confirm, wl-prefetch-threshold): $B?75,JQ?t!#(B + * wl-summary.el (wl-summary-prefetch-msg): wl-prefetch-confirm, + wl-prefetch-threshold $B$K=>$&$h$&$K$7$?!#(B + +2000-02-02 Daiki Ueno + + * wl-draft.el (wl-smtp-features): smtp-authenticate-type $B$,(B symbol + $B$K$J$C$?$N$KBP1~!#(B + +2000-01-31 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * elmo-nntp.el (elmo-nntp-get-folders-info): Fixed. + +2000-01-31 Daiki Ueno + + * wl-demo.el: Emacs21 $B$G(B wl-logo.xpm $B$rI=<($9$k$h$&$K$7$?!#(B + +2000-01-30 TAKAHASHI Kaoru + + * INSTALL, INSTALL.ja: Fixed. + +2000-01-30 OKUNISHI -GTO- Fujikazu + + * WL-ELS: $B4{$K(B open-database $B$,Dj5A:Q$_$N>l9g$b(B ELMO-MODULES $B$K(B + elmo-database $B$rDI2C$9$k$h$&$K$7$?!#(B + +2000-01-30 Akihiro MOTOKI + + * elmo-loacaldir.el + (elmo-localdir-msgdb-create-overview-entity-from-file): + Date: $B%U%#!<%k%I$,$J$$>l9g$O!"%U%!%$%k$N:G=*99?7F|$rF|IU$H$7$FI=<($9$k(B + $B$h$&$K$7$?!#(B + * elmo-msgdb.el (elmo-msgdb-create-overview-from-buffer): + $B0z?t(B time $B$rDI2C!#(B + * elmo-vars.el (elmo-time-format): $B?75,JQ?t!#(B + +2000-01-29 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * wl-summary.el (wl-summary-jump-to-msg-by-message-id): + NNTP $B%5!<%P$r;XDj$G$-$k$h$&$K$7$?!#(B + (wl-summary-jump-to-msg-by-message-id-via-nntp) + $B%5!<%P;XDj;~$K!"C1$J$k%5!<%PL>$@$1$G$J$/!"(B + "-:username@servername:8119!"$B$N$h$&$J;XDj$b$G$-$k$h$&$K$7$?!#(B + * elmo-nntp.el (elmo-nntp-folder-postfix): $B0z?t(B ssl $BDI2C!#(B + +2000-01-29 OKUNISHI -GTO- Fujikazu + + * elmo-vars.el (elmo-database-dl-module, elmo-database-dl-handle): + $B?75,JQ?t!#(B + (toplevel): elmo-database-dl-handle $B$,(B non-nil $B$J$i(B + emacs_database_init $B$r(B dynamic_call $B$9$k$h$&$K$7$?!#(B + (elmo-use-database): open-database $B$,$"$l$P(B elmo-use-database $B$r@_Dj!#(B + * WL-ELS: 'dynamic-link $B$,$"$l$P(B ELMO-MODULES $B$K(B elmo-database $B$rDI2C!#(B + +2000-01-28 TAKAHASHI Kaoru + + * wl-demo.el (wl-demo): Fix copyright information. + +2000-01-27 Takeshi Chiba + + * mmelmo-imap4-2.el ([luna]mime-entity-buffer): + section "0" -> "header". + +2000-01-27 Yuuichi Teranishi + + * mmelmo-imap4-2.el (mmelmo-imap4-node-id-to-string): + section "0" -> "header". + * mmelmo-imap4-1.el: $BF1>e!#(B + +2000-01-26 OKAZAKI Tetsurou + + * elmo-imap4.el (elmo-imap4-create-folder): + UW imapd-4.7 $B$G?7$7$/(B folder $B$,:n$l$J$$LdBj$X$NBP=h!#(B + +2000-01-26 Yuuichi Teranishi + + * mmelmo-imap4-2.el (mmelmo-imap4-parse-bodystructure-string): + BODYSTRUCTURE $B$Nl9g$r9MN8$9$k$h$&$K$7$?!#(B + * mmelmo-imap4-1.el: $BF1>e!#(B + * utils/hmac/unique-id.el: $B?75,%U%!%$%k!#(B + * WL-ELS (HMAC-MODULES): scram-md5, digest-md5, unique-id $B$rDI2C!#(B + * wl-dnd.el (wl-dnd-drop-func): Fixed. + * 2.2.16 - "No Son Of Mine" + +2000-01-25 Yuuichi Teranishi + + * wl-vars.el (wl-summary-reserve-mark-list): $B?75,JQ?t!#(B + * wl-summary.el: temp-mark -> target-mark $BL>A0JQ99!#(B + $B0l;~%^!<%/7O%3%^%s%I$G(B `wl-summary-reserve-mark-list' + $B$r;H$&$h$&$K$7$?!#(B + * wl-score.el, wl-thread.el: $BF1>e!#(B + * wl-folder.el (toplevel): require 'wl $B$9$k$h$&$K$7$?!#(B + * elmo-util.el (elmo-imap4-encode-string): optional $B0z?t$rDI2C!#(B + +2000-01-24 Yuuichi Teranishi + + * wl-mule.el, wl-xmas.el, wl-nemacs.el (wl-summary-format-date): + $B:o=|!"(Bwl-summary.el $B$X0\F0!#(B + * utils/hmac/lisp/sasl.el, utils/hmac/lisp/digest-md5.el, + utils/hmac/lisp/scram-md5.el: $B:G?7HG$K(B update$B!#(B + * wl-fldmgr.el (wl-fldmgr-ext): $B3NG'%a%C%;!<%8$rJQ99!#(B + * doc/TODO.ja: $B99?7!#(B + +2000-01-22 OKAZAKI Tetsurou + + * wl-folder.el (toplevel): Fixed menu. + +2000-01-21 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * elmo-imap4.el: DIGEST-MD5 $B$KBP1~!#(B + * elmo-pop3: CRAM-MD5, DIGEST-MD5, SCRAM-MD5$B$KBP1~!#(B + +2000-01-21 Yuuichi Teranishi + + * wl-summary.el (toplevel): $B%j!<%8%g%s7O%-!<%P%$%s%I$NDj5A0LCV$rJQ99!#(B + (wl-summary-prefetch-region): $BJD$8$?%9%l%C%I$N%a%C%;!<%8$r%W%j%U%'%C%A(B + $B$7$J$$$N$r=$@5!#(B(OKAZAKI Tetsurou $B$5$sB>$h$j8fJs9p(B) + * elmo: append-msg, move-msgs $B%a%=%C%I$K0z?t(B no-see $B$rDI2C!#(B + * elmo-pipe: move-msgs $B$G(B 'no-see $B$r;XDj$9$k$h$&$K$7$?!#(B + * wl-folder.el (wl-folder-mimic-kill-buffer): $B?75,%3%^%s%I!#(B + (toplevel): C-xk $B$K(B` wl-folder-mimic-kill-buffer' $B$r!"(B + C-xC-s $B$K(B `wl-save' $B$r$=$l$>$l3d$jEv$F!#(B + +2000-01-19 Yuuichi Teranishi + + * wl-nemacs.el (accept-process-output): $B?75,4X?t!#(B + * Makefile: $B%3%a%s%H=$@5!#(B + +2000-01-17 Yuuichi Teranishi + + * elmo-util.el (elmo-folder-identical-system-p): $BJL%5!<%P$G(B + $BF1$8L>A0$N%a!<%k%\%C%/%9$,F10l;k$5$l$F$7$^$&$N$r=$@5!#(B + (Tatsuya Matsui $B$5$s$N8f;XE&(B) + * wl-address.el (wl-complete-field-body-or-tab): $B0z?t$r$J$/$7$?!#(B + +2000-01-13 Yuuichi Teranishi + + * wl-vars.el + (wl-prefetch-confirm-threshold, wl-cache-fetch-threshold): $B?75,JQ?t!#(B + * wl-summary.el (wl-summary-prefetch-msg): + wl-prefetch-confirm-threshold $B$r;H$&$h$&$K$7$?!#(B + (wl-cache-prefetch-message): wl-cache-fetch-threshold $B$r;H$&$h$&(B + $B$K$7$?!#(B + +2000-01-13 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * wl-message.el + (wl-message-decide-backend, wl-normal-message-redisplay): + wl-fetch-confirm-threshold $B$,(B nil $B$J$i3NG'$7$J$$$h$&$K$7$?!#(B + +2000-01-11 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * wl-draft.el (wl-draft-delete): wl-draft-buffer-file-name $B$,(B + nil $B$N;~$r9MN8$9$k$h$&$K$7$?!#(B + +2000-01-11 Nishimoto Masaki + + * wl-draft.el (wl-draft-save-and-exit): $B4X78$J$$%P%C%U%!$r(B kill + $B$7$F$7$^$&$3$H$,$"$k$N$r=$@5!#(B + +2000-01-11 Yuuichi Teranishi + + * 2.2.15 - "More Than Words" + +2000-01-11 Yoichi NAKAYAMA + + * samples/ja/dot.folders, samples/en/dot.folders: '$B%"%/%;%9%0%k!<%W(B' + $B$N5-=R$r2C$($?!#(B + +2000-01-11 Yuuichi Teranishi + + * wl-mime.el, tm-wl.el (wl-draft-preview-message): $BA4%X%C%@$rI=<((B + $B$9$k$h$&$K$7$?!#(B + * wl-summary.el (wl-summary-mode): tab-width $B$r@_Dj$7$J$$$h$&$K$7$?!#(B + (Yoshinari NOMURA $B$5$s$N8f;XE&(B) + (wl-summary-copy, wl-summary-refile): wl-draft-folder $B$K%3%T!<(B + $B$G$-$J$$$h$&$K$7$?(B + (okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA)$B$5$s$N8f;XE&(B)$B!#(B + (wl-summary-overview-entity-compare-by-date): $B%(%i!<$rL5;k(B + (MIZUHARA Bun $B$5$s$N8f;XE&(B)$B!#(B + * wl.el (wl-plugged-mode): inhibit-read-only $B$N@_Dj$r:o=|!#(B + (Shuhei KOBAYASHI $B$5$s$N8f;XE&(B) + * wl-vars.el (wl-draft-reedit-hook): $B?75,(B hook$B!#(B + * wl-draft.el (wl-draft-save, wl-draft-mimic-kill-buffer): + $B?75,4X?t!#(B + (wl-draft): $B4{$K;H$o$l$F$$$k%P%C%U%!L>$O;H$o$J$$$h$&$K$7$?!#(B + (wl-draft-reedit): wl-mail-setup-hook $B$r(Brun-hook$B$;$:!"$+$o$j$K(B + wl-draft-reedit-hook $B$r(B run-hook $B$9$k$h$&$K$7$?!#(B + (okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA)$B$5$s$N8f;XE&(B)$B!#(B + * wl-xmas.el, wl-mule.el (wl-draft-key-setup): + C-xC-s $B$K(B wl-draft-save $B$r!"(BC-xk $B$K(B wl-draft-mimic-kill-buffer $B$r(B + $B3d$jEv$F$?!#(B + * wl-nemacs.el (wl-draft-overload-functions): $BF1>e!#(B + +2000-01-09 TAKAHASHI Kaoru + + * wl-mule.el, wl-util.el: (require 'static) $B$r(B + (eval-when-compile (require 'static)) $B$KJQ99!#(B + * wl.el (wl-save): $B$N(B docstring $B$rDI2C!#(B + +2000-01-08 Mito + + * wl-score.el (wl-score-guess-like-gnus): (when (stringp fld-name)..) + $B$G3g$C$?!#(B + +2000-01-08 Masahiro MURATA ($BB + + * wl-draft.el (wl-draft-config-info-operation): $B?75,4X?t!#(B + (wl-draft-delete, wl-draft-save-and-exit, wl-draft-reedit): + `wl-draft-config-info-operation' $B$r;H$&$h$&$K$7$?!#(B + +2000-01-08 Yuuichi Teranishi + + * wl-demo.el (toplevel): bitmap $B$,%$%s%9%H!<%k$5$l$F$$$J$$>l9g$K(B + $B%P%$%H%3%s%Q%$%k$G=P$k(B Warning $B$r8:$i$7$?!#(B + (wl-demo-use-bitmap): $B?75,JQ?t!#(Bbitmap $B$N%G%b$rI=<($9$k$+$I$&$+$r;XDj!#(B + $B%G%U%)%k%H$O(B t$B!#(B + * WL-CFG: wl-demo-use-bitmap $B$r(B nil $B$K$9$kNc$rDI2C!#(B + * wl-nemacs.el (toplevel): timezone $B$N%(%_%e%l!<%7%g%s$r;_$a$?(B + (APEL 10 $B!A(B $B$rA0Ds(B)$B!#(B + * wl-demo.el, wl-draft.el, wl-folder.el, wl-util.el, + wl-message.el, wl-summary.el (toplevel): $BL$Dj5AJQ?t$O(B + make-local-variable $B$GF@$i$l$k%7%s%\%k$KCM$r(B set $B$9$k$h$&$K$7$?!#(B + (Shuhei KOBAYASHI $B$5$s$N8f=u8@(B) + +2000-01-07 Daiki Ueno + + * wl-draft.el (wl-smtp-features, wl-smtp-parse-extension): $B=$@5!#(B + +2000-01-07 Yuuichi Teranishi + + * wl-draft.el (wl-user-agent-compose): wl-draft $B$r(B interactive $B$K8F$V(B + $B$h$&$K$7$?!#(B(Atsushi Tada $B$5$s$N8f;XE&(B) + * Makefile (EMACS): $B%G%U%)%k%H$r(B emacs $B$K$7$?!#(B + (XEMACS): $B?75,JQ?t!#(B + (package, install-package): $(XEMACS) $B$r;H$&$h$&$K$7$?!#(B + * 2.2.14 - "Layla" + * wl-summary.el (wl-summary-mode): default-directory $B$r@_Dj$9$k$N$r(B + $B$d$a$?!#(B + * wl-vars.el (wl-tmp-dir): $B%G%U%)%k%H$r(B"~/tmp/" $B$H$7$?(B + (WL-ML 3735 $B$N%9%l%C%I;2>H(B)$B!#(B + +2000-01-06 Daiki Ueno + + * wl-draft.el (wl-smtp-features): $B?75,JQ?t!#(B + (wl-smtp-extension-bind): $B?75,%^%/%m!#(B + * wl-summary.el (wl-summary-mode-map): + wl-summary-prev-page $B$N%-!<%P%$%s%I$r(B backspace $B$K$b3dEv$F$?!#(B + +2000-01-06 Kentaro Yoshitomi + + * elmo-maildir.el (elmo-maildir-create-folder): + $B%G%#%l%/%H%jL>$,(B "/" $B$G=*$k$H$-$K(B error $B$K$J$k$N$r=$@5!#(B + +2000-01-06 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * wl-draft.el: smtp.el $BJQ?tL>$N(B authenticate $B$X$NJQ99$KBP1~!#(B + +2000-01-06 Yuuichi Teranishi + + * wl-util.el (wl-load-profile): wl.el $B$+$i0\F0!#(B + * COPYING: $B?75,%U%!%$%k(B (etc/copyright $B$+$i2~L>(B). + * wl-vars.el (wl-smtp-connection-type): wl-smtp-use-tls $B$+$i2~L>!#(B + * wl-draft.el (wl-draft-send-mail-with-smtp): smtp-connection-type + $B$r(B wl-smtp-connection-type $B$G(B bind $B$9$k$h$&$K$7$?!#(B + (wl-draft-queue-save-filename): fixed typo. + * wl-vars.el (wl-cs-*): Nemacs $B8~$1$NDj5A$rJQ99!#(B + * all files: $BCx:n8"I=<($N99?7!"(Bcheckdoc fix$B!#(B + +2000-01-05 TAKAHASHI Kaoru + + * wl-ja.texi: $BCx:n8"I=<($HJ# + + * wl-score.el (wl-summary-score-update-all-lines): + $B%9%3%"$GFI$s$@$3$H$K$9$k>l9g$K!"L$%-%c%C%7%e$H$9$k$h$&$K$7$?!#(B + * elmo-util.el (elmo-imap4-get-spec): + elmo-default-imap4-ssl $B$,(B t $B$N>l9g$KBP1~$7$F$$$J$+$C$?$N$r=$@5!#(B + (Taro FUNAKI $B$5$s$h$j8fJs9p(B) + * tm-wl.el (wl-draft-yank-current-message-entity): + mime-viewer/following-method-alist $B$N=$@5$b$l$r=$@5!#(B + (Taiji.Can@atesoft.advantest.co.jp $B$5$s$h$j8fJs9p(B) + +2000-01-04 OKUNISHI -GTO- Fujikazu + + * wl-message.el (wl-message-decode): + 'no-mime $B$N$H$-$K(B wl-cs-autoconv $B$G%G%3!<%I$9$k$h$&$K$7$?!#(B + +1999-12-31 Kentaro Yoshitomi + + * elmo-maildir.el, elmo-util.el: Maildir $B%U%)%k%@$N:n@.!":o=|!"(B + $B%3%T!<$XBP1~!#(B + +1999-12-29 Yuuichi Teranishi + + * wl-draft.el (wl-draft): `wl-load-profile' $B$r8F$V$h$&$K$7$?!#(B + (Masahiro MURATA ($BB $B$5$s$N8f;XE&(B) + * elmo-imap4.el (elmo-imap4-make-number-set-list): $B?75,4X?t!#(B + (elmo-imap4-msgdb-create): `elmo-imap4-make-number-set-list' + $B$r;H$&$h$&$K$7$?!#(B + (elmo-imap4-mark-set-on-msgs): $BF1>e!#(B + +1999-12-11 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * wl-summary.el (wl-summary-get-sync-range): + offline $B;~$K(B POP $B%U%)%k%@$KF~$k$?$S$K(B Unplugged $B$HJ86g$r(B + $B8@$o$l$J$$$h$&$K$7$?!#(B + +1999-12-28 Nishimoto Masaki + + * elmo-msgdb.el (elmo-msgdb-expand-path): $B%"!<%+%$%V%U%)%k%@$N%Q%9(B + $BE83+$K<:GT$7$F$$$?$N$r=$@5!#(B + +1999-12-28 Yuuichi Teranishi + + * 2.2.13 - "Keep The Faith" + +1999-12-27 Yuuichi Teranishi + + * elmo-util.el (elmo-network-get-spec): $B?75,4X?t!#(B + (elmo-*-get-spec): $B=q$-D>$7!"%f!<%6L>It$K(B '@' $B$r4^$a$i$l$k$h$&$K$7$?!#(B + (okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) $B$5$s$N8f;XE&$K4p$E$/(B) + * elmo-imap4.el (elmo-imap4-create-msgdb-from-overview-string): + float $B$,07$($J$$(B Emacs $B$X$NBP1~!#(B + * elmo-pop3.el (elmo-pop3-get-connection): $B0z?t$rJQ99!#(B + * check-paren fix. + +1999-12-21 Koga Masato + + * wl-draft.el (wl-draft-reedit): + `wl-draft-use-frame' $B$,8z$/$h$&$K$7$?!#(B + +1999-12-21 Yuuichi Teranishi + + * elmo-vars.el (elmo-imap4-use-modified-utf7): $B?75,JQ?t!#(B + $B%G%U%)%k%H$O(B nil$B!#(B + +1999-12-20 Yuuichi Teranishi + + * wl-mime.el, tm-wl.el (wl-mime-save-content): $B:G8e$K%;!<%V$7$?(B + $B%G%#%l%/%H%j$r3P$($k$h$&$K$7$?!#(B + * wl.el (wl-save): $B?75,%3%^%s%I!#8=:_$N%U%)%k%@>uBVEy$r%;!<%V$9$k!#(B + (JINMEI Tatuya $B$5$s$h$j8fMWK>(B) + * wl-folder.el (wl-folder-mode-map): "\M-s" $B$K(B `wl-save' $B$r%P%$%s%I!#(B + * elmo-util.el (elmo-imap4-get-spec): `utf7-encode-string' $B$r(B + $B;H$&$h$&$K$7$?!#(B + * elmo-imap4.el (elmo-imap4-list-folders): `utf7-decode-string' + $B$r;H$&$h$&$K$7$?!#(B + * elmo/utf7.el: $B?75,%U%!%$%k!#(B + +1999-12-20 Daiki Ueno + + * elmo-imap4.el (elmo-imap4-open-connection): starttls $BBP1~$N=$@5!#(B + * wl-draft.el: featurep->boundp$B!#(B + +1999-12-17 Yuuichi Teranishi + + * wl-vars.el (wl-search-mime-charset): $B?75,JQ?t!#(B + * wl-summary.el (wl-summary-pick): `wl-search-mime-charset' $B$r(B + $B;H$&$h$&$K$7$?!#(B + +1999-12-16 TAKAHASHI Kaoru + + * WL-MK (wl-texinfo-format): $B8E$$(B texinfmt.el $B$r;H$C$F$$(B + $B$k$H$-$K$O(B `@direntry' $B$r%(%_%e%l!<%7%g%s$9$k$h$&$K$7$?!#(B + +1999-12-16 Yuuichi Teranishi + + * wl-draft.el (wl-draft-config-exec): $B%O%$%i%$%H$7$J$*$9$h$&$K$7$?!#(B + (Motomichi Matsuzaki $B$5$s$N8f;XE&(B) + * wl-summary.el (toplevel): `wl-summary-temp-mark-region' $B$N(B + $B%-!<%P%$%s%I=g$rJQ$($?(B (okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + $B$5$s$N8f=u8@(B)$B!#(B + +1999-12-16 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * wl-summary.el (wl-summary-mark-as-important-region, + wl-summary-mark-as-unread-region, + wl-thread-mark-as-important, + wl-thread-mark-as-unread, + wl-summary-temp-mark-mark-as-important, + wl-summary-temp-mark-mark-as-unread): New functions. + (wl-summary-save-region): $BL5BL$J=hM}$r:o=|!%(B + (wl-summary-prefetch-region): wl-summary-message-uncached-marks $B$G(B + $BH=CG$9$k$N$r$d$a!"(Belmo-cache-exists-p$B$r;H$&$h$&$K$7$?!#(B + * wl-thread.el (wl-thread-get-children-msgs-uncached): $BF1>e!#(B + +1999-12-14 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * pop, imap $B$N(B STARTTLS $B$G!"(Btls $B$r;HMQ$9$k$h$&$K;XDj$7$F$$$k$N$K!$(B + $B%5!<%P$,5v2D$7$F$$$J$$>l9g$O!$(Berror $B$r=P$9$h$&$K$7$?!#(B + +1999-12-14 TSUMURA Tomoaki + + * dot.wl: wl-default-folder $B$G$O(B ML-name $B$H(B ML-count $B$rI=<($7!"(B + $B$=$l0J30$N(B folder $B$G$O(B ML-count $B$N$_I=<($9$kNc$rDI2C!#(B + +1999-12-14 Yuuichi Teranishi + + * mmelmo-imap4-2.el (mmelmo-imap4-parse-bodystructure-string): + $B@8(B JIS $B$N%U%!%$%kL>$,$"$C$?$j$9$k$H(B parse $B$K<:GT$9$k$N$r=$@5!#(B + * wl-summary.el (wl-summary-copy): $B#22sL\$N%3%T!<;X<($,EPO?$5$l$J$$$N$r(B + $B=$@5!#(B(Hiroshi Watanabe $B$5$s$h$j8fJs9p(B) + +1999-12-12 Yuuichi Teranishi + + * wl-summary.el (wl-summary-goto-folder-subr): sticky $B$K$9$k(B + $B%?%$%_%s%0$rJQ99(B (Masahiro MURATA ($BB + $B$5$s$N8f;XE&(B)$B!#(B + * wl-vars.el (wl-folder-sync-range-alist): $B%G%U%)%k%H$G%I%i%U%H$H(B + $B%-%e!<$N%l%s%8$r(B "all" $B$H$7$?!#(B + +1999-12-11 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * wl-summary.el (wl-summary-get-sync-range): + offline $B;~$K(B POP $B%U%)%k%@$KF~$k$?$S$K(B Unplugged $B$HJ86g$r(B + $B8@$o$l$J$$$h$&$K$7$?!#(B + +1999-12-10 OKUNISHI -GTO- Fujikazu + + * elmo $B$K$"$k4X?t$r(B defalias $B$7$F$$$k(B wl $B$N4X?t$r(B + elmo $B$N4X?t$KCV$-49$($?!#(B + +1999-12-07 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * elmo-nntp.el: elmo-nntp-max-number-precedes-list-active $B$,(B t + $B$+$D(B list-active $B$,Ds6!$5$l$F$$$J$$>l9g$N5sF0$r=$@5!#(B + +1999-12-07 TAKAHASHI Kaoru + + * INSTALL.ja: $B=$@5!#(B + * wl-summary.el (wl-summary-always-sticky-folder-p): $B?75,%^%/%m!#(B + (wl-summary-goto-folder-subr): (wl-summary-always-sticky-folder-p) + $B$r;H$&$h$&$K$7$?!#(B + +1999-12-07 Akihiro MOTOKI + + * wl-vars.el (wl-summary-always-sticky-folder-list): $B?75,JQ?t!#(B + * wl-summary.el (wl-summary-stick): Optional $B0z?t$r2C$($?!#(B + (wl-summary-goto-folder-subr): wl-summary-always-sticky-folder-list + $B$K%^%C%A$9$k%U%)%k%@$O<+F0E*$K(B Sticky $B$K$J$k$h$&$K$7$?!#(B + +1999-12-07 Yuuichi Teranishi + + * INSTALL.ja: $BJ8;z%3!<%I$r(B ISO-2022-JP $B$K$7$?!#(B + * wl-draft.el (wl-draft-send-mail-with-smtp): + (default-)?case-fold-search $B$N%P%$%s%I0LCV$rJQ99!#(B + (Atsushi Tada $B$5$s!"(B + $BDE6b5WNQ(B $B$5$sB>$h$j8fJs9p(B) + (wl-draft-send): with-current-buffer $B$r;H$o$J$$$h$&$K$7$?!#(B + * 2.2.12 - "Joyride" + +1999-12-07 Katsumi Yamaoka + + * etc/icons/wl-logo.xbm: Christmas version. + +1999-12-07 Yuuichi Teranishi + + * elmo-imap4.el (elmo-imap4-parse-overview-string): + elmo-imap4-use-uid $B$,(B nil $B$N$H$-F0$+$J$+$C$?$N$r=$@5!#(B + * utils/hmac/scram-md5.el, utils/hmac/hmac-util.el: $B:o=|!#(B + * wl-summary.el (wl-summary-mark-as-unread): + wrong-type-argument $B%(%i!<$,=P$k$N$r=$@5!#(B + * wl-folder.el (wl-folder-empty-trash): $B%5%^%jA}?#8=>]$N=$@5$b$l!#(B + (OKAZAKI Tetsurou $B$5$s$N8fJs9p(B) + +1999-12-07 Masahiro MURATA ($BB + + * wl-draft.el (wl-draft-condig-exec): + wl-draft-config-exec-flag $B$O(B wl-draft-config-alist $B$,E,MQ$5$l$?(B + $B$H$-$N$_(B nil $B$K$9$k$h$&JQ99!#(B + +1999-12-06 Shigeru OKUMURA + + * WL-ELS (HMAC-MODULES): $B99?7!#(B + +1999-12-06 Tsunehiko Baba + + * INSTALL: $B?75,%U%!%$%k!#(B + +1999-12-06 Yuuichi Teranishi + + * elmo-imap4.el (elmo-imap4-create-msgdb-from-overview-string): + $B%U%#%k%?$,$&$^$/F0$+$J$$$N$r=$@5!#(B + (Kazuyoshi Mii $B$5$s$h$j8fJs9p(B) + * 2.2.11 - "Iris" + * utils/hmac/lisp/*.el: Sync up with slim-1.13.4. + * elmo-imap4.el + (elmo-imap4-open-connection): cram-md5 $BG'>Z$G(B sasl-cram-md5 $B$r(B + $B;H$&$h$&$K$7$?!#(B + (toplevel): (require 'hmac-md5) $B$G$O$J$/!"(B(require 'sasl) $B$H$9$k(B + $B$h$&$K$7$?!#$^$?!"(Beval-when-compile $B$r30$7$?!#(B + +1999-12-05 Yuuichi Teranishi + + * wl-summary.el (wl-summary-mark-as-read): msgdb $B$KB8:_$7$J$$(B + $B%a%C%;!<%8$K$O%^!<%/$rIU$1$J$$$h$&$K$7$?!#(B + * wl-summary.el (wl-summary-pick): msgdb $BBP>]$N$H$-$K$R$H$D$b(B pick + $B$G$-$J$+$C$?$H$-$K%a%C%;!<%8$r=P$9$h$&$K$7$?!#(B + +1999-12-04 Yuuichi Teranishi + + * elmo-msgdb.el (elmo-msgdb-overview-get-parent-entity): + $B0z?t$rJQ99!#(B + * wl-vars.el (wl-smtp-posting-server): $B=i4|CM$r(B nil $B$H$7$?!#(B + (okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) $B$5$s$N8f=u8@(B) + * elmo-imap4.el (elmo-imap4-create-msgdb-from-overview-string): + extra-field $BL>$r(B downcase $B$9$k$h$&$K$7$?!#(B + (Takaaki MORIYAMA $B$5$s$h$j8f;XE&(B) + * elmo-util.el (elmo-collect-field(-from-string)?): + $B0z?t(B downcase-field-name $B$rA}$d$7$?!#(B + +1999-12-03 TSUMURA Tomoaki + + * wl-folder.el (wl-folder-empty-trash): $B%5%^%jA}?#8=>]$N=$@5!#(B + +1999-12-03 Nishimoto Masaki + + * wl-summary.el (wl-summary-default-from): Newsgroup $BL>$,I=<((B + $B$5$l$J$+$C$?$N$r=$@5!#(B + +1999-12-03 TAKAHASHI Kaoru + + * INSTALL.ja: $B?75,%U%!%$%k!#(B + * draft $B:FJT=8;~$K!"(BNewsgroups: $B%X%C%@$,$"$l$P!"(BTo: $B$rIU2C$7$J$$$h(B + $B$&$K$9$k=$@5$N%^!<%8$7K:$l$r=$@5!#(B + +1999-12-03 Yuuichi Teranishi + + * elmo-util.el (elmo-mime-string): elmo-set-work-buf $B$G3g$k$h$&$K$7$?!#(B + (Mikiya Tani $B$5$s$N8f;XE&(B) + * 2.2.10 - "Human Touch" + * etc/icons/wl-logo.xpm: Christmas version. + * elmo-imap4.el (elmo-imap4-make-attributes-object): + Nemacs $B$G(B read $B$,<:GT$7$F$7$^$&$N$KBP=h!#(B + * elmo-dop.el (elmo-dop-list-folder): pipe $BBP1~K:$l$r=$@5!#(B + (OKAZAKI Tetsurou $B$5$s$N8f;XE&(B) + +1999-12-03 sen_ml@eccosys.com + + * utils/wl-mailto.el: 0.5. + +1999-12-02 Yuuichi Teranishi + + * mmelmo-imap4-1.el: buffer read only $B$N%(%i!<$,=P$k$N$r=$@5!#(B + * wl-mime.el, tm-wl.el: wl-draft-preview-message $B$N%-!<%P%$%s%I$rJQ99!#(B + (Makoto.Nakagawa@jp.compaq.com ($BCf@n(B $B@?(B) $B$5$s$N8fJs9p$K4p$E$/(B) + * utils/ssl.el: $B:G?7HG$KF~$l49$(!#(B + (okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA)$B$5$s$N8f;XE&(B) + * elmo-util.el (elmo-mime-string, elmo-decode-mime-charset-string): + $B?75,4X?t!#(B + * elmo-imap4.el: FETCH $B7k2L2r@O=hM}ItJ,$rBgI}$K=q$-49$($?!#(B + +1999-12-02 Hironori Fukuchi + + * wl-xmas.el: (featurep 'dragdrop) $B$,(B nil $B$N$H$-$K!"(B + wl-dnd-set-drop-target $B$,%(%i!<$rH/@8$9$k>l9g$,$"$k$N$r=$@5!#(B + +1999-12-02 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * starttls.el $B$,$J$$$H%(%i!<$,=P$k$N$r=$@5!#(B + +1999-12-01 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * smtp auth$B$N$H$3$m$G!$(Bwl-smtp-posting-user$B$,(B nil $B$G$b(B + error $B$r=P$5$J$$$h$&$K$7$?!#(B + * nntp$B%U%)%k%@$G%]!<%HHV9f$r;XDj$9$k$H%(%i!<$,=P$k$N$r=$@5(B + +1999-11-27 Masahiro MURATA ($BB + + * wl-draft.el (wl-draft-reedit): interactive $B$G$J$$$N$K(B + wl-mail-setup-hook $B$r8F$V$+$I$&$+$,(B (interactive-p) $B$GH=JL$5$l$F(B + $B$$$?$N$r=$@5!#(B + * New command: wl-fldmgr-delete. + * Rename: wl-fldmgr-rename-group -> wl-fldmgr-rename. + * New function: elmo-folder-creatable-p. + * imap4 $B$G(B #mh $B%?%$%W$N%U%)%k%@$r:n$k$H$-!$I,$:%G%#%l%/%H%j$,:n(B + $B@.$5$l$k$h$&$K$7$?!#(B + * wl-folder-check-one-entity $B$GB8:_$7$J$$%U%)%k%@$r:n@.$9$k$h$&(B + $B$K$7$?!#(B + * New macro: wl-folder-clear-entity-info. + +1999-11-25 TAKAHASHI Kaoru + + * wl-message.el (wl-message-narrow-to-page): "^L\n^L" $B$r4^$`%a%C%;!<(B + $B%8$rFI$`$H$-$K(B `beginning-of-buffer' $B%(%i!<$,=P$J$$$h$&$K$7$?!#(B + +1999-11-25 Yuuichi Teranishi + + * wl-summary-mode $B$N0z?t$r$J$/$7$?!#(B + * wl-address.el (wl-address-petname-add-or-change): + .addresses $B$N:G8e$N9T$K2~9T$,$J$$>l9g$KBP=h!#(B + * elmo-imap4-[12].el (mmelmo-imap4-parse-bodystructure-entity): + mime-parse-parameters-from-list $B$r;H$&$h$&$K$7$?!#(B + +1999-11-24 Tetsuya Uemura + + * x-face-xmas-mew-display-x-face -> x-face-xmas-wl-display-x-face + +1999-11-22 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * wl-vars.el (wl-smtp-authenticate-type, wl-smtp-use-tls): $B?75,JQ?t!#(B + * wl-draft.el (wl-draft-send-mail-with-smtp): SMTP $B$N(B TLS $BBP1~!#(B + +1999-11-21 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * wl-summary-jump-to-msg-internal$B$,(B + wl-summary-jump-to-msg-by-message-id-via-nntp$B$+$i8F$P$l$k$H$-$K!$(B + scan-type$B$,(Bupdate$B$K$J$k$h$&$K$7$?!#(B + +1999-11-22 Daiki Ueno + + * elmo-imap4.el, elmo-pop3.el: STARTTLS $BBP1~!#(B + +1999-11-20 Masahiro MURATA ($BB + + * wl-draft.el (wl-draft-send-mail-with-smtp): + connection $B$rD%$k;~$K(B process-connection-type $B$r(B nil $B$K94B+$7$?!#(B + +1999-11-20 OKUNISHI -GTO- Fujikazu + + * elmo-util.el (elmo-open-network-stream): + connection $B$rD%$k;~$K(B process-connection-type $B$r(B nil $B$K94B+$7$?!#(B + +1999-11-20 Nishimoto Masaki + + * $B4{$K(Bimportant$B%^!<%/$,$D$$$F$$$k%a%C%;!<%8$K(B + important$B$J%9%3%"$,$D$/$H%^!<%/$,>C$($F$7$^$&$N$r=$@5!#(B + +1999-11-19 Hironori Fukuchi + + * tm-wl.el: fixed typo. + +1999-11-18 Yasuo OKABE + + * $BI=<($7$F$$$k%a%C%;!<%8$,$J$$>uBV$G(B wl-draft-insert-message $B$r + + * wl-vars.el: $B?75,JQ?t(B wl-summary-showto-folder-regexp$B!#(B + * wl-summary.el (wl-summary-default-from): + my-wl-summary-from-func-petname $B$K$7$?!#(B + (Masahiro MURATA ($BB $B$5$s$N8f=u8@(B) + * wl-summary.el (wl-summary-simple-from): wl-summary-default-from + $B$+$iL>A0JQ99!#(B + +1999-11-17 Masahiro MURATA ($BB + + * wl-message.el (wl-message-get-buffer-create): + sticky $B%a%C%;!<%8$rI=<($9$k$H$-$K%(%i!<$K$J$k$N$r=$@5$7$?!#(B + +1999-11-17 sen_ml@eccosys.com + + * wl-mailto.el: 0.5-pre1. + +1999-11-16 Yuuichi Teranishi + + * elmo-util.el (elmo-delete-cr-get-content-type): + Content-Type $B$,$J$$$H$-$K(B t $B$rJV5Q$9$k$h$&$K$7$?!#(B + * 2.2.9 - "Gonna Make You Sweat" + +1999-11-15 Katsumi Yamaoka + + * wl-util.el (wl-unique-id): current-time $B$H(B timezone $B$r;H$o$J$$HG!#(B + +1999-11-14 Masahiro MURATA ($BB + + * wl-draft.el, wl-summary.el: reply $B;~$O(B wl-draft-reply $B$r(B t $B$K(B, + forward $B;~$O(B wl-draft-forward $B$r(B t $B$K@_Dj$9$k$h$&$K$7$?!#(B + * wl-folder.el, wl.el: wl-folder $B$G%U%)%k%@%j%9%H$r@8@.$7$?$H$-$N$_!$(B + wl-make-plugged-alist $B$r8F$V$h$&$K$7$?!#(B + +1999-11-14 OKAZAKI Tetsurou + + * elmo-pipe.el (elmo-pipe-use-cache-p): $B + + * wl-nemacs.el: current-time $B + + * wl-util.el (wl-draft-make-message-id-string, wl-unique-id, + wl-number-base36): New functions. + (wl-unique-id-char): New internal variable. + + * wl-mule.el (wl-draft-make-message-id-string): Remove. + * wl-nemacs.el (wl-draft-make-message-id-string): Remove. + * wl-xmas.el (wl-draft-make-message-id-string): Remove. + + * wl-draft.el (wl-draft-send-mail-with-smtp): `smtp-server' $B$,4X?t(B + $B$@$C$?$i(B funcall $B$9$k$h$&$K$7$?(B; Resent-* $B%U%#!<%k%I$N07$$$r(B `smtp' + $B$KG$$;$k$h$&$K$7$?!#(B + +1999-11-12 Yuuichi Teranishi + + * wl-draft (wl-draft-get-fcc-list): FCC $B$K;XDj$5$l$?%U%)%k%@$,(B + $BB8:_$7$J$$$H$-$K%(%i!<$H$;$:!":n@.$9$k$+$I$&$+$-$/$h$&$K$7$?!#(B + * Rename: wl-summary-confirm-folder-existence -> + wl-folder-confirm-existence$B!#(B + (Masahiro MURATA ($BB $B$5$s$N8f=u8@$K(B + $B4p$E$/(B) + * Rename: wl-mime-edit-preview-message-hook + -> wl-draft-preview-message-hook + * elmo-nntp.el (elmo-nntp-string-to-vector): $B4X?t8F$S=P$7$K$9$k$N$r(B + $B;_$a$?!#(B + * elmo-util.el (elmo-tokenize-string): $BGQ;_!#(Bsplit-string $B$GBeMQ!#(B + * wl-highlight.el: $B?75,(B face$B!"(Bwl-highlight-logo-face$B!#%m%4MQ(B face$B!#(B + +1999-11-11 Katsumi Yamaoka + + * wl-demo.el: bitmap-mule $BBP1~!#(B + * wl-logo.xbm: $B?75,%U%!%$%k!#(B + * elmo-nntp.el (elmo-nntp-string-to-vector): vector $B$ND9$5$rL5@)8B(B + $B$K$7$?!#(B + (elmo-nntp-parse-overview-string): `elmo-nntp-string-to-vector' $B$K(B + $BBh#20z?t$rM?$($k$N$r$d$a$?!#(B + +1999-11-11 Yuuichi Teranishi + + * elmo-imap4.el: Message-ID $B$K(B '%' $B$,4^$^$l$F$$$k$H8!:w$K<:GT$9$k$N(B + $B$r=$@5!#(B + (OKAZAKI Tetsurou $B$5$s$N8f=u8@(B) + * wl-message.el, mmelmo-[12].el: read-only $B$N@_Dj$r@0M}!#(B + * wl-draft-save-and-hide -> wl-draft-save-and-exit $B$H$7!"(B + C-c C-z $B$K%P%$%s%I$7$?!#(B + +1999-11-11 Yasuo OKABE + + * wl-summary.el (wl-summary-temp-mark-forward): + $B%^!<%/$5$l$F$$$k%a%C%;!<%8$,J#?t$J$i$PA4BN$r(B multipart/digest $B$G0O$`(B + $B$h$&$K$7$?!#(B + +1999-11-11 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * $B?75,JQ?t(B wl-nntp-posting-port, wl-nntp-posting-ssl + wl-nntp-posting-{user,server,port,ssl}$B$H(B + elmo-default-nntp-{user,server,port,ssl} $B$rBP1~$5$;$k$h$&$K$7$?!#(B + * wl-nntp-posting-* $B$N=i4|@_Dj$O(B nil $B$H$7!"(B + nil $B$N$^$^$J$i(B elmo-default-nntp-* $B$rMxMQ$9$k$h$&$K$7$?!#(B + * utils/bbdb-wl.el: (setq bbdb-use-pop-up nil) $B$N>l9g!"(B + $B%5%^%j$G(B ':' $B$r2!$7$?8e(B q $B$H2!$9$H%(%i!<$,=P$k$N$r=$@5!#(B + * wl-draft.el: $B?75,4X?t(B wl-draft-save-and-hide$B!#(B + +1999-11-10 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * wl-demo$B$G!$(Bwl-logo.xpm$B$NI=<(0LCV$r$A$c$s$H7W;;$9$k$h$&$K$7$?!#(B + +1999-11-10 Tsutomu Okada ($B2,ED(B $BJY(B) + + * wl-message.el (wl-message-refer-article-or-url): + $B%a%C%;!<%8%P%C%U%!$G(B mouse-button-2 $B$r2!$7$F$b%+!<%=%k$,(B + $B%a%C%;!<%8%P%C%U%!$K0\F0$7$J$$$h$&$K$7$?!#(B + +1999-11-10 Yuuichi Teranishi + + * wl-summary.el (wl-summary-set-message-buffer-or-redisplay): + Sticky Message $B$,$"$k$H%*%j%8%J%k%P%C%U%!$,l9g$,$"$k$N$r=$@5!#(B(Mito $B$5$s$h$j8fJs9p(B) + * wl-util.el (wl-string): elmo-string $B$X$N(B alias $B$H$7$?!#(B + * elmo-util.el (elmo-string): $B?75,4X?t!#(B + * $B?75,JQ?t(B wl-smtp-posting-port$B!#(B + * wl-summary-resend-bounced-mail $B$r(B "\eE" $B$K%P%$%s%I!#(B + +1999-11-10 OKAZAKI Tetsurou + + * WL-ELS $B$N(B typo $B$N=$@5$b$l$N=$@5!#(B + +1999-11-10 kurati@bigfoot.com + + * refile $B$G%U%)%k%@:n@.$7$?$H$-$K%U%)%k%@L>Jd408uJd$K2C$o$k$h$&$K$7$?!#(B + * FCC: $B$K?75,%U%)%k%@$r;XDj$7$?;~$K:n@.$9$k$+J9$/$h$&$K$7$?!#(B + * auto-refile $B$N$H$-!"B8:_$7$J$$%U%)%k%@$,$"$C$?;~$K:n@.$9$k$+J9$/!#(B + +1999-11-10 Yasuo OKABE + + * wl-summary.el (wl-summary-resend-message, + wl-summary-resend-bounced-mail): $B?75,%3%^%s%I!#(B + * wl-draft.el (wl-draft-dispatch-message): dispatch $B$5$l$?(B + $B%a%C%;!<%8$,(B Resent-to $B%X%C%@$r4^$s$G$$$?>l9g$O(B Newsgroups $B%X%C%@(B + $B$r;}$C$F$$$F$b%K%e!<%9$K$OAw$i$J$$!#(B + +1999-11-09 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * wl-summary.el (wl-summary-jump-to-msg-internal): $B5-;v$,(B + $BI=<($5$l$J$$>l9g$,$"$k$N$r=$@5!#(B + * wl-summary.el (wl-summary-jump-to-msg-by-message-id-via-nntp): + $B0\F0@h$N%K%e!<%9%0%k!<%W$N8uJd$,J#?t$"$k$H$-$K(B + wl-folder-newsgroups-hashtb $B$K4^$^$l$k$b$N$rM%@h$9$k$h$&$K$7$?!#(B + +1999-11-09 Yuuichi Teranishi + + * 2.2.8 - "Free As A Bird" + +1999-11-08 Yuuichi Teranishi + + * wl-draft.el (wl-draft-send): $BAw?.8e!"(BC-cC-s $B$,(B insert-signature $B$K(B + $B$J$C$F$7$^$&$N$r2sHr!#(B(Akihiro MOTOKI $B$5$s(B + $B$h$j8fJs9p(B) + * WL-MK: Nemacs $B$G$O(B (fset 'file-executable-p 'file-exists-p) $B$H$7$?!#(B + * WL-MK, WL-CFG: WL_PREFIX $B$H(B ELMO_PREFIX $B$N%G%U%)%k%H$r(B "wl" + $B$H$7$?!#(B + * $B?75,JQ?t(B wl-user-mail-address-list$B!#(B + $B%f!<%6$N%a!<%k%"%I%l%9$,J#?t$"$k$H$-$K<+J,$+$I$&$+$NH=Dj$KMQ$$$i$l$k!#(B + * $B?75,4X?t(B wl-address-user-mail-address-p + wl-user-mail-address-list $B$H(B wl-from $B$r;H$C$F<+J,$N%"%I%l%9$+$I$&$+(B + $BH=JL$9$k!#(B + * wl-summary.el (wl-summary-cancel-message, + wl-summary-supersedes-message): wl-address-user-mail-address-p + $B$r;H$C$F%"%I%l%9H=Dj$9$k$h$&$K$7$?!#(B + (okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) $B$5$s$NJQ99$K4p$E$/(B) + * wl-refile.el (wl-refile-learn, wl-refile-guess-by-history): $BF1>e!#(B + * wl-draft.el (wl-draft-make-mail-followup-to, wl-draft-reply + wl-draft-delete-myself-from-cc): $BF1>e!#(B + * elmo-filter.el (elmo-filter-list-folder-unread, + elmo-filter-list-folder-important): $B%U%#%k%?=hM}$,4V0c$C$F$$$?(B + $B$N$r=$@5!#(B(Kazuyoshi Mii $B$5$s$h$j8fJs9p(B) + +1999-11-08 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * POP-before-SMTP $B4XO"JQ?t$N=i4|2=K!$rJQ99!#(B + +1999-11-07 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * elmo-nntp.el: list active $B$,<:GT$7$?$i!$(Blist $B$r + + * wl-draft-prepared-confi-alist $B$rGQ;_$7!$(B + wl-draft-config-alist $B$HE}9g$7$?!#(B + * wl-template-select $B$r5$9$k$h(B + $B$&$K$7$?!#(B + * Fcc $B%U%)%k%@$N=hM}$rAw?.$,@.8y$7$?;~$K9T$&$h$&$K$7$?!#(B + * wl-draft-queue-save-variables $B$NJQ?t$r(B user-mail-address $B$+$i(B + wl-envelope-from $B$KJQ99$7$?!#(B + * wl-draft-insert-from-field $B$K$*$$$F!$(Buser-mail-address $B$,(B nil + $B$N$H$-$K%(%i!<$K$J$k$N$r=$@5$7$?!#(B + +1999-11-06 Tetsuya Uemura + + * describe-mode $B$G%b!<%I%^%C%W$,I=<($5$l$k$h$&$K$7$?!#(B + +1999-11-06 TAKAHASHI Kaoru + + * wl-folder.el (wl-folder-mode-map): + wl-fldmgr-copy-region $B$N%-!<%P%$%s%I$rJQ$($?!#(B + +1999-11-06 Hironori Fukuchi + + * wl-summary.el (wl-summary-stick): $B3g8L$N0LCV$,$:$l$F$$$?$N$r=$@5!#(B + +1999-11-06 Yasuo OKABE + + * utils/wl-user-agent.el: sendmail-user-agent $B$NF0:n$K9g$o$;$?!#(B + +1999-11-06 sen_ml@eccosys.com + + * utils/wl-user-agent.el: 0.5. + +1999-11-05 Yuuichi Teranishi + + * elmo-imap4.el: $B%=!<%9$r$+$J$j@0M}$7$?!#(B + * elmo-imap4.el: $B?75,JQ?t(B elmo-imap4-debug$B!#(B + Non-nil $B$J$i(B "*IMAP4 DEBUG*" $B%P%C%U%!$K%G%P%C%0>pJs$r=PNO$9$k!#(B + * elmo-imap4.el, elmo-pop3.el, elmo-nntp.el: + $B%a%C%;!<%8K\BNFI$_=P$7;~$N%3%T!<2s?t$r:o8:!#(B + * elmo-imap4.el: $B%3%^%s%I$NJVEz$,:G8e$^$GF@$i$l$k$^$G%m%C%/$9$k$h$&$K(B + $B$7$?!#(B + * wl-summary.el: wl-refile-rule-alist $B$,(B nil $B$@$H%*!<%H%j%U%!%$%k$,(B + $B%(%i!<$K$J$k$N$r=$@5!#(B + * WL-MK: install-package $B$G(B info $B$,%$%s%9%H!<%k$5$l$J$$$N$r=$@5!#(B + ("MATSUBAYASHI 'Shaolin' Kohji" $B$5$s(B + $B$h$j8fJs9p(B) + * elmo-cache.el (elmo-cache-search): $BItJ,%-%c%C%7%e$N8!:w$KBP1~(B + $B$7$F$$$J$+$C$?$N$r=$@5(B (Yasuo OKABE + $B$5$s$N8f;XE&(B)$B!#(B + +1999-11-04 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * POP-before-SMTP $B$N@0M}$H3HD%!#(B + * $B?75,JQ?t(B elmo-default-pop3-user, wl-pop-before-smtp-user, + wl-pop-before-smtp-server, wl-pop-before-smtp-port, + wl-pop-before-smtp-ssl, wl-pop-before-smtp-authenticate-type$B!#(B + * elmo-pop-before-smtp-* -> wl-pop-before-smtp-* + +1999-11-04 Yuuichi Teranishi + + * wl-mime.el (wl-mime-edit-preview-message): + $B?75,(B hook: wl-mime-edit-preview-message-hook$B!#(B + * elmo-util.el: $B%P%$%H%3%s%Q%$%i$N=P$9(B Warning $B$r:o8:$7$?!#(B + * wl-summary.el (wl-summary-sync-marks): $B%^!<%/F14|=hM}$rBgI}$K9bB.2=!#(B + * elmo-pipe.el (elmo-pipe-max-of-folder): $BIQHK$K:o=|$5$l$k(B + IMAP4 $B%U%)%k%@$G$OL$FI?t$,$*$+$7$/$J$k$N$r=$@5!#(B + (Toshihiko Kodama ($B>.6L(B $BMxI'(B) + $B$5$s$N8fJs9p$K4p$E$/(B) + +1999-11-03 Yuuichi Teranishi + + * 2.2.7 - "Escapade" + * WL-MK: install-info $B$9$k$H(B INFODIR $B$N%a%C%;!<%8$,$*$+$7$/$J$k$N(B + $B$r=$@5!#(B + * $B5/F0$7$F:G=i$K(B Folder $B%b!<%I$+$i(B prefetch $B$9$k$H%(%i!<$,H/@8$9$k(B + $B$N$r=$@5(B ($B2,ED(B $B7r0l(B (Kenichi OKADA) + $B$5$s$h$j8fJs9p(B)$B!#(B + * mime-elmo-entity $B%/%i%9$r(B mime-buffer-entity $B%/%i%9$N(B + $B%5%V%/%i%9$H$7!"B>$N(B MUA $B$K1F6A$,5Z$P$J$$$h$&$K$7$?!#(B + * $BJD$8$?%9%l%C%I$K%a%C%;!<%8$,DI2C$5$l$?$H$-$KHV9fItJ,$,(B + $B%O%$%i%$%H$5$l$J$+$C$?$N$r=$@5!#(B + * pipe $B$KBP1~$7K:$l$F$$$?ItJ,$rBP1~$5$;$?!#(B + +1999-11-03 Masahiro MURATA ($BB + + * $B%U%)%k%@L>$NJd40$J$I$G!$(Bfolder petname $B$r;HMQ$9$k$h$&$K$7$?!#(B + * wl-force-fetch-folders $B$,(B non-nil $B$N>l9g!$%"%/%;%9%0%k!<%W$,(B + unplugged $B$@$H3+$1$J$/$J$k$N$r=$@5$7$?!#(B + * $B%U%)%k%@%b!<%I$N:G2<9T$G(B wl-fldmgr-set-petname $B$,=PMh$J$$$h$&(B + $B$K$7$?!#(B + * wl-plugged-mode $B$GJQ99$7$J$+$C$?>l9g$O!$(Bwl-toggle-plugged $B$r8F(B + $B$P$J$$$h$&$K$7$?!#(B + * wl-exit $B$H(B wl-folder-suspend $B;~$N%P%C%U%!>C5n$r@0M}$7$?!#(B + * wl-folder.el: $B0lIt$r4X?t(B wl-folder-buffer-group-p $B$GCV$-49$($?!#(B + * wl-summary.el: $B0lIt$r4X?t(B wl-summary-entity-info-msg $B$GCV$-49(B + $B$($?!#(B + * wl-reset-plugged-alist $B$N%G%U%)%k%HCM$r(B t $B$KJQ99$7$?!#(B + * wl-plugged-mode $B$G(B plugged $B>uBV$rJQ99$7$F$bA4It%j%;%C%H$5$l$F(B + $B$7$^$&$N$r=$@5$7$?!#(B + +1999-11-03 TAKAHASHI Kaoru + + * wl-summary.el (wl-summary-reedit): $B%K%e!<%95-;v$N:FJT(B + $B=8;~$K!"(BTo: $B%X%C%@$r2C$($J$$$h$&$K$7$?!#(B + +1999-11-03 $B2,ED(B $B7r0l(B (Kenichi OKADA) + + * wl-summary-write-current-newsgroup $B$G(B + elmo-folder-get-primitive-folder-list$B$r;H$&$h$&$K$7$?!#(B + * $B?75,%3%^%s%I(B wl-folder-write-current-newsgroup + * elmo-folder-get-primitive-folder-list $B$H(B + elmo-folder-get-primitive-spec-list $B$r(B pipe $B%U%)%k%@$KBP1~$5$;$?!%(B + * elmo-pop3-flush-connection$B$9$kA0$KEEOC$r@Z$k$H!$(B + wl-toggle-plugged $B$G$-$J$/$J$k$N$r=$@5!#(B + +1999-11-03 sike@ic.netlaputa.ne.jp + + * Message-Id $B$NESCf$G2~9T$,$"$C$F$bBg>fIW$J$h$&$K$7$?!#(B + +1999-11-02 Yuuichi Teranishi + + * 2.2.6 - "Diamonds And Pearls" + * $B5/F0;~$K(B plug status $B$r(B wl-plugged $B$K9g$o$;$k$h$&$K$7$?!#(B + (Yasuo OKABE $B$5$s$N8f;XE&(B) + * WL-MK: $BBgI}$K=q$-49$($?!#(B + * Rename: wl-address-complete-address + -> wl-complete-field-body + * Rename: wl-address-complete-address-or-tab + -> wl-complete-field-body-or-tab + +1999-11-01 Yuuichi Teranishi + + * $B%U%)%k%@%"%$%3%s=i4|2=4X?t$r4JN,2=!#(B + * elmo-pipe: New module. + +1999-11-01 OKAZAKI Tetsurou + + * WL-ELS $B$N(B typo $B=$@5!#(B + * wl-user-agent.el $B$H(B wl-mailto.el $B$N(B byte-compile $B;~$K(B + "Cannot open load file wl" $B$N%(%i!<$,=P$k$N$r=$@5!#(B + +1999-10-29 Takaaki MORIYAMA + + * wl-exit $B$G(B kill-emacs-hook $B$+$i(B wl-save-status $B$r>C$9$h$&$K$7$?!#(B + +1999-10-28 OKUNISHI -GTO- Fujikazu + + * new file: WL-ELS$B!#(B + * WL-MK: install.el $B$r;H$&$h$&BgI}$K=q$-49$($?!#(B + +1999-10-28 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * wl-ja.texi: wl-template-select $B$N%-!<%P%$%s%I$,4V0c$C$F$$$?$N$r(B + $B=$@5!#(B + * INN 2.3 $B$G$bL$FI?t$,0lCW$9$k$h$&$K$7$?!#(B + +1999-10-28 TAKAHASHI Kaoru ($B9b66(B $B0j(B) + + * wl-ja.texi: $BBgI}$K=$@5!#(B + +1999-10-27 Yuuichi Teranishi + + * Folder $B%b!<%I$G$b(B 'Z' $B$K(B wl-status-update $B$r%P%$%s%I$7$?!#(B + * Fix: wl-summary-goto-last-displayed-msg + $B#1$D$7$+I=<($7$?$3$H$,$J$$;~$KA0$N%a%C%;!<%8$KLa$l$J$+$C$?$N$r(B + $B=$@5!#(B + +1999-10-26 kurati + + * FCC: $B$GJd40$,8z$/$h$&$K$7$?!#(B + +1999-10-26 Yuuichi Teranishi + + * Unplugged $B;~$G$b=EMW%^!<%/$NF14|$O$9$k$h$&$K$7$?!#(B + * auto-refile $B$NA0$KB8:_$9$k$+$I$&$+%A%'%C%/$9$k$h$&$K$7$?!#(B + (Toshihiko Kodama ($B>.6L(B $BMxI'(B) + $B$5$s$N8fMWK>$K4p$E$/(B) + * Fix: score $B$G(B expunge $B$7$?%a%C%;!<%8$O(B IMAP4 $B%5!<%P>e$G$b(B + $BFI$s$@$3$H$K$9$k$3$H$K$7$?!#(B + +1999-10-22 OKAZAKI Tetsurou + + * $B%5%^%j%P%C%U%!(B($B%9%l%C%I%b!<%I(B)$B$G%+!<%=%k$,9TF,$K$J$$$H$-$K(B + $B%9%l%C%I$KBP$9$k(B mark $BA`:n$r$9$k$HF0:n$,JQ$K$J$k$N$r=$@5!#(B + * wl-thread-refile $B$G(B refile $B@h$K(B refile $B85$HF1$8%U%)%k%@$r(B + ($B4V0c$C$F(B)$B;XDj$7$F%(%i!<$H$J$C$?$H$-$K%+!<%=%k$r0\F0$7$J$$MM$K$7$?!#(B + * wl-summary-jump-to-parent-message $B$G(B message $B$N8!:w$,<:GT$7$?;~$N(B + $B%a%C%;!<%8$rJQ$($?!#(B + * wl-summary-exec-region $B$G9TC10L$G$J$$(B region $B$r;XDj$7$?;~$N(B + region $B$NJd@5J}K!$,D>4QE*$G$J$+$C$?$N$rJQ99$7$?!#(B + +1999-10-25 Masahiro MURATA ($BB + + * fldmgr: $B%0%k!<%W%U%)%k%@$rDI2C$9$k$H%(%i!<$K$J$k$N$r=$@5$7$?!#(B + * wl-defface $B$N@_Dj$r(B static $B$K$7$?!#(B + * wl-folder-buffer-search-entity, wl-folder-folder-name $B$G(B + $BL$FI?t$J$IITL@$N%U%)%k%@$K$b%^%C%A$9$k$h$&$K$7$?!#(B + * wl-summary-redisplay-no-mime $B$G$b!$(Bwl-summary-buffer-disp-msg $B$H(B + wl-current-summary-buffer $B$r@_Dj$9$k$h$&$K$7$?!#(B + +1999-10-25 Yuuichi Teranishi + + * $B5/F0;~$K%I%a%$%sL>$,@5$7$$$+%A%'%C%/$9$k$h$&$K$7$?!#(B + * $B?75,JQ?t(B wl-local-domain$B!#(BFQDN $B$rJV$5$J$$%7%9%F%`MQ$N%I%a%$%sL>(B + $B$r@_Dj!#(B + * $B%U%)%k%@%b!<%I$N2#%9%/%m!<%k%P!<$r>C$7$?!#(B + ("MATSUBAYASHI 'Shaolin' Kohji" $B$N(B + $B8fJs9p$K4p$E$/(B) + * $B?75,4X?t(B wl-mime-edit-preview-message$B!#%W%l%S%e!<$N?'$D$1!#(B + * unplugged $B$+$D!"%-%c%C%7%e$5$l$?L$FI$,$J$$$H$-!"(B + $B%+!<%=%k$r%"%/%;%9$G$-$k:G8e$N%a%C%;!<%8$K9g$o$;$k$h$&$K$7$?!#(B + * WL-CFG $B$N(B utils $B$N;XDj$N;EJ}$,$^$A$,$C$F$$$?$N$r=$@5!#(B + (Taiji.Can@atesoft.advantest.co.jp $B$5$s$N8f;XE&(B) + * make info $B$K<:GT$9$k$N$r=$@5!#(B + (Kazufumi Hayasaka $B$5$s$N8f;XE&(B) + * 2.2.5 - "Come Undone" + +1999-10-24 Mikio Nakajima + + * double negative $B$r(B simplify$B!#(B + +1999-10-24 Masahiro MURATA ($BB + + * FCC $B$,(B unplugged folder $B$J$i(B dop $B%-%e!<$KDI2C$9$k$h$&$K$7$?!#(B + * elmo-dop-queue $B$K(B "append-operations" $B$rDI2C$7$?!#(B + * wl-summary-flush-pending-append-operations $B$K$*$$$F4{FI%a%C%;!<(B + $B%8$r0z$-7Q$0$h$&$K$7$?!#(B + +1999-10-24 Yuuichi Teranishi + + * WL-CFG $B$H$7$F$=$l$C$]$$$N$rMQ0U$7$F$_$?!#(B + * $B%*%U%i%$%sAw?.$G(B IMAP4 $B%U%)%k%@$X$N(B FCC $B$,L5;k$5$l$k$N$r=$@5!#(B + (Masafumi NAKANE $B$5$s$h$j8fJs9p(B) + * Emacs $B$H(B XEmacs $B$G(B refile-alist $B$r6&M-$G$-$J$+$C$?$N$r=$@5!#(B + (Takuo KITAME / $BKLL\BsO:(B $B$5$s$h$j8fJs9p(B) + * wl-ja.texi: tm, semi $B$NG[I[85$r=$@5!#(B + * Folder $B%b!<%I$GJL%5!<%P$GF1$8L>A0$N(B IMAP4 $B%U%)%k%@$,$"$C$?$H$-$K!"(B + $BJL$N%U%)%k%@$NL$FI?t$,=q$-JQ$o$C$F$7$^$&$3$H$,$"$k$N$r=$@5!#(B + (Kazuyoshi Mii $B$5$s$h$j8fJs9p(B) + +1999-10-23 $B2,ED(B $B7r0l(B (Kenichi OKADA) + + * elmo-dop-merge-funcs $B$K$J$$A`:n$r!$ + + * port $B$N(B label $B$r<+F0E*$K:n@.$9$k$h$&$K$7$?!#(B + * dop queue $B$NI=<($r>/$7$@$1>\:Y$K$7$?!#(B + * elmo-dop-queue-merge $B$G(B elmo-dop-queue $B$,(B nil $B$K$J$k$3$H$,$"$k$N(B + $B$r=$@5$7$?!#(B + +1999-10-23 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * elmo-prefetch-msgs $B$G!$=hM}$N?J$_$0$"$$$r%+%&%s%H$9$k$h$&$K$7$?!%(B + +1999-10-23 Yuuichi Teranishi + + * wl-mime-save-content $B$r(B SEMI $B$KEPO?$9$k$H$-$K(B Wanderlust $B@lMQ(B + $B%a%=%C%I$H$9$k$h$&$K$7$?!#(B + * FLIM-1.12 $B7O$G(B partial $B$N%^!<%8$K<:GT$9$k$N$r=$@5!#(B + * WL-MK: $BBgI}$K=q$-D>$7$?!#(B + +1999-10-22 TAKAHASHI Kaoru + + * Rename: wl-score-edit-exit-function -> wl-score-edit-exit-func + +1999-10-22 Takuo KITAME / $BKLL\BsO:(B + + * etc/ja.Emacs: $B$$$/$D$+CM$,=EJ#$7$F$$$?$N$r=$@5!#(B + +1999-10-22 $B2,ED(B $B7r0l(B (Kenichi OKADA) + + * [wl-ja.texi] wl-summary-save-* + wl-summary-jump-to-msg-by-message-id-via-nntp + $B%*%U%i%$%s(Bprefetch + wl-folder-jump-to-current-entity + cram-md5,SSL $B$N@bL@$rDI2C!#(B + +1999-10-22 Masahiro MURATA ($BB + + * XEmacs built-in $B$N(B md5 $B$r8F$V$H$-$N(B CODING $B$r(B 'binary $B$K$7$?!#(B + * sticky summary $B$+$i(B "g" $B$GJL$N%U%)%k%@$K0\F0$9$k$H!$(B + temp $B%^!<%/$J$I$,>C$($k$K$b4X$o$i$:(B face $B$,85$KLa$i$J$$$N$r=$@5!#(B + * $B?75,JQ?t(B wl-prog-uudecode-no-stdout-option$B!#(BNon-nil $B$J$i(B + $B;XDj$5$l$?%U%!%$%kL>$G%;!<%V$9$k$h$&$K$7$?!#(B + +1999-10-21 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * $B%*%U%i%$%s=hM}%-%e!<$N%^!<%8=hM}!#(B + +1999-10-21 Yuuichi Teranishi + + * wl-address-header-extract-address $B$G(B std11.el $B$rMxMQ$7$J$$$h$&$K(B + $B$7$?!#(B + +1999-10-20 Masahiro MURATA ($BB + + * wl-reset-plugged-alist $B$,(B nil $B$J$i%5!<%P!&%]!<%HJL$N%W%i%0>uBV$r(B + $B=i4|2=$7$J$$$h$&$K$7$?!#(B + +1999-10-20 Yuuichi Teranishi + + * Emacs 20.2 $B$G$O!"(BFolder $B%b!<%I=i4|2=;~$K(B buffer-read-only + $B$N%(%i!<$,H/@8$9$k$N$r=$@5!#(B + (Yasuhiro Ohta $B$5$s$h$j8fJs9p!"(B + TSUMURA Tomoaki $B$5$s$h$j8f=u8@(B) + * XEmacs $B$G(B scrollbar $B$H(B toolbar $B$N%A%'%C%/$r$9$k$h$&$K$7$?!#(B + (Shigeru OKUMURA $B$5$s$h$j8f=u8@(B) + +1999-10-20 $B2,ED(B $B7r0l(B (Kenichi OKADA) + + * $BIT@5$J%X%C%@$N%a!<%k$r%j%U%!%$%k$7$h$&$H$9$k$H%(%i!<$,H/@8$9$k$N$r(B + $B=$@5!#(B + * $B%"%/%;%9%0%k!<%W$r:G=i$K3+$$$?$H$-$KFbMF$,8=$l$J$/$J$C$F$$$?(B + $B$N$r=$@5!#(B + +1999-10-19 Yuuichi Teranishi + + * Folder $B%b!<%I$N(B 'E' $B$G(B wl-folder-toggle-disp-summary $B$,%(%i!<(B + $B$rH/@8$9$k$N$r=$@5!#(B + (Shigeru OKUMURA $B$5$s$N8fJs9p(B) + * timezone $B$N(B y2k $BBP:v$G(B eval-after-load $B$r;H$o$J$$$h$&$K$7$?!#(B + * 2.2.4 - "Black Or White" + +1999-10-19 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * wl-fetch-confirm-threshold$B$r1[$($k%a%C%;!<%8$r(B + prefetch$B$7$h$&$H$7$?$H$-$K!"(B'n'$B$r2!$7$F%-%c%s%;%k$7$F$b(B + $B%^!<%/$,6u$K$J$C$F$7$^$&%P%0$N=$@5!#(B + * Offline Prefetch$B!#(B + +1999-10-18 Yuuichi Teranishi + + * $B%U%)%k%@%b!<%I$N:G8e$N9T$G(B 'm f' $B$G$-$J$$$h$&$K$7$?!#(B + * $B%P%$%H%3%s%Q%$%k;~$N(B Warning $B$r8:$i$7$?!#(B + * hmac $B%Q%C%1!<%8$H(B ssl.el $B$r(B utils/ $B$K4^$a$F$_$?!#(B + (WL-CFG $B$G(B wl-install-hmac $B$,(B t $B$J$i%$%s%9%H!<%k$9$k$h$&$K$7$?!#(B) + * FLIM-1.12 $B$G$bF0$/$h$&$K$7$?!#(B + * Unplugged $B;~$K(B IMAP4 $B%U%)%k%@$K0\F0$9$k$H%(%i!<$,=P$k$N$r=$@5!%(B + * $B%5%^%j99?7;~!"(Bwl-summary-update-confirm-threshold $B$h$j$b99?7?t$,(B + $BB?$$$J$i$P!"0lItJ,$@$199?7$K$9$k$+$I$&$+!" + + * expire $B$,(B number-or-marker-p error $B$rH/@8$9$k>l9g$,$"$k$N$r=$@5!#(B + * filter $B@8@.;~$K(B tocc $B$GJd40$G$-$k$h$&$K$7$?!#(B + * $B%U%)%k%@%b!<%I$G$N(B filter $B$N:n$jJ}$rJQ99!#(B + +1999-10-15 Yuuichi Teranishi + + * IMAP4 $B%U%)%k%@$NL$FI?t$,@5$7$/H?1G$5$l$k$h$&!$(B + elmo-imap4-server-diff $B;~$K!"(Belmo-imap4-commit $B$9$k$h$&$K$7$?!#(B + * $B?75,4X?t(B elmo-commit$B!#%5!<%P$N>uBV$r%"%C%W%G!<%H$5$;$k!#(B + * wl-folder-check-one-entity $B$,L5BL$K%U%)%k%@$NB8:_$r%A%'%C%/$7$F(B + $B$$$?$N$r=$@5!#(B + * elmo-imap4-max-of-folder: new implementation. + * elmo-imap4-folder-exists-p: new implementation. + +1999-10-14 Mikio Nakajima + + * wl-ja.texi: fixed typo (@kbd {l} -> @kbd{l}). + +1999-10-14 TAKAHASHI Kaoru + + * xemacs $B$G(B wl-local-variable-p $BB>$,F0$+$J$$$N$r=$@5!#(B + +1999-10-14 Yuuichi Teranishi + + * $B%-%c%C%7%e$,$"$k$H$$$/$iFI$s$G$bL$FI%^!<%/$,>C$($J$/$J$C$F$7$^$&$N(B + $B$r=$@5!#(B + (Taiji.Can@atesoft.advantest.co.jp $B$5$s$N8f;XE&(B) + * wl-address-header-extract-address $B$G(B std11.el $B$rMxMQ$9$k$h$&$K$7$?!#(B + +1999-10-14 Masafumi NAKANE + + * Fixed Typo: exit-> exist. + +1999-10-13 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * unplugged.xpm: $B@V$rF~$l$?!#(B + +1999-10-13 OKAZAKI Tetsurou + + * elmo-filter-get-spec $B$N;EMMJQ99$K4X78$9$k=$@51L$l$N=$@51L$l(B + $B$r=$@5(B (elmo-folder-diff)$B!#(B + +1999-10-13 Masahiro MURATA ($BB + + * wl-plugged-mode $B$N%&%#%s%I%&:n@.=hM}$NIi2Y$r7Z$/$7$?!#(B + * wl-draft-raw-send $B$G(B wl-draft-config-alist $B$r(B nil $B$K(B + $B94B+$7$J$$$h$&$K$7$?!#(B + +1999-10-13 Sasaki Toshiya + + * wl-folder-use-sever-diff-p: $B%^%k%A%U%)%k%@$G!"0l$D$G$b(B + IMAP4 $B%U%)%k%@$,$"$l$P(B t $B$K$J$k$h$&$K$7$?!#(B + +1999-10-13 Yuuichi Teranishi + + * 'm U' (wl-summary-temp-mark-uudecode)$B$G!"=PNO@h$N(B + $B%U%!%$%kL>$r;XDj$G$-$k$h$&$K$7$?!#(B + * $B%U%)%k%@%b!<%I$b%[%$!<%k$KBP1~$5$;$?!#(B + * tm-wl.el $B$,JT=8Cf$@$C$?$N$r=$@5!#(B + (Toshihiko Kodama ($B>.6L(B $BMxI'(B) $B$5$s(B + $B$N8f;XE&(B) + * wl-ja.texi: OR $B>r7o$N@bL@$rDI2C!#(B + * time-stamp $B$K0MB8$7$J$$$h$&$K$7$?!#(B + +1999-10-12 Yuuichi Teranishi + + * 2.2.3 - "Always" + * read-directroy-name -> wl-read-directory-name$B!#(B + +1999-10-12 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * $B?75,4X?t(B wl-summary-save-region (ry), wl-thread-save (ty), + wl-summary-temp-mark-save (my)$B!#(B + +1999-10-11 Masahiro MURATA ($BB + + * $B?75,JQ?t(B wl-draft-sendlog$B!#(Bnon-nil $B$J$iAw?.%m%0$r@8@.$9$k!#(B + * New plugged system $BBh#2CF(B. + +1999-10-10 Yuuichi Teranishi + + * $B?75,4X?t(B wl-summary-temp-mark-pick (m? $B$K%P%$%s%I(B)$B!#(B + $B0l;~%^!<%/$,$D$$$?%a%C%;!<%8$rBP>]$H$7$F8!:w!#(B + * $B?75,JQ?t(B elmo-imap4-disuse-server-flag-mailbox-regexp$B!#(B + $BJ8;zNs$,%^%C%A$7$?%a!<%k%\%C%/%9$N%U%i%0$r;H$o$J$$!#(B + $B%G%U%)%k%H$O(B "^#mh"$B!#(B + * wl-address-file-name -> wl-address-file$B!#(B + * wl-score-default-file-name -> wl-score-default-file$B!#(B + * $B?75,JQ?t(B wl-summary-auto-sync-marks$B!#(B + Non-nil $B$J$i%5%^%jF14|;~$KL$FI(B/$B=EMW%^!<%/$bF14|$9$k!#(B + $B%G%U%)%k%H$O(B t$B!#(B + * wl-stirict-diff-folders $B$N%G%U%)%k%H$r(B nil $B$K$7$?!#(B + * $B%5%^%j$G=EMW%^!<%/$rF14|$9$k$h$&$K$7$?!#(B + * IMAP4 $B%U%)%k%@$GL$FI%U%i%0$rF14|$9$k$h$&$K$7$?!#(B + * $B?75,%3%^%s%I(B wl-summary-sync-marks$B!#(B + * IMAP4 $B%U%)%k%@$G%5!<%PB&$NL$FI?t$rI=<($G$-$k$h$&$K$7$?!#(B + * $B?75,JQ?t(B wl-folder-use-server-diff$B!#(B + +1999-10-08 Yuuichi Teranishi + + * $B?75,JQ?t(B wl-envelope-from$B!#(Benvelope from $B$r@_Dj!#(B + nil $B$J$i(B wl-from $B$,(B envelope from $B$H$J$k!#%G%U%)%k%H$O(B nil$B!#(B + +1999-10-04 Yuuichi Teranishi + + * Message $B%P%C%U%!$G(B 'e' $B$r2!$7$?$H$-$N%;!<%V4X?t$r(B + $B$A$g$C$H$@$1?F@Z$J$b$N$r%G%U%)%k%H$H$7$?(B (SEMI $BMQ(B)$B!#(B + * wl-draft-send $B$G!"(Bsending-buffer $B$,(B buffer-live-p $B$N>l9g$@$1(B + kill-buffer $B$9$k$h$&$K$7$F$_$?!#(B + * $BL$FI?t%A%'%C%/;~!"%U%)%k%@$NB8:_$r$$$A$$$AD4$Y$k$N$r$d$a!"(B + $B%A%'%C%/$K<:GT$7$?$H$-$K%U%)%k%@$NB8:_$rD4$Y$k$h$&$K$7$?!#(B + * $B%a%C%;!<%8%P%C%U%!$K%+!<%=%k$,$"$k$H$-$K%[%$!<%k$r2s$9$H%(%i!<(B + $B$K$J$k$N$r=$@5!#(B + +1999-10-04 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * $B%0%k!<%W%U%)%k%@(B($BHs%"%/%;%9%0%k!<%W(B)$B$KBP$7$F!$(B + C-u SPC $B$7$?;~$K!$(Bwl-folder-update-recursive-current-entity $B$r(B + $B8F$V$h$&$K$7$?!%(B + +1999-10-04 Yuuichi Teranishi + + * filter $B$5$l$?(B IMAP4 $B%U%)%k%@$N%*%U%i%$%s=hM}$GL5BL$J:o=|=hM}(B + $B%-%e!<$,N/$k$N$r=$@5!#(B + (OKAZAKI Tetsurou $B$5$s$N8f;XE&(B) + +1999-10-04 okada@opaopa.org ($B2,ED(B $B7r0l(B / Kenichi OKADA) + + * $B%"%/%;%9%0!<%W$K(B Petname $B$r$D$1$k$H(B + wl-folder-update-recursive-current-entity $B$,F0$+$J$+$C$?$N$r=$@5!%(B + +1999-10-03 TSUMURA Tomoaki + + * wl-refile-alist $B$KEPO?$9$k:]$N(B key (mail address) $B$K(B + downcase $B$r$+$1$k$h$&$K$7$?!#(B + +1999-10-02 Tetsuya Uemura + + * $B%I%i%U%H%P%C%U%!$G%a!<%k$r:n@.Cf$K!"(B + C-u 0 C-l $B$J$I$G;XDj$N0LCV$K%+!<%=%k$,9T$/$h$&$K=$@5!#(B + +1999-10-01 Yuuichi Teranishi + + * IMAP4 $B$N%Q!<%H%U%'%C%A$G$O!"$=$N%a%C%;!<%8$rFI$s$@$3$H$K(B + $B$7$J$$$h$&$K$7$?!#(B + +1999-09-30 OKUNISHI -GTO- Fujikazu + + * -nw $B$G5/F0$7$?(B Emacs 20 $B$G%W%j%s%H$G$-$J$$$N$r=$@5!#(B + +1999-09-28 Masahiro MURATA ($BB + + * $B%U%)%k%@$+$i%5%^%j$K0\F0$9$k:]!$%U%)%k%@$rI=<($7$F$$$J$$%&%#%s(B + $B%I%&$K%5%^%j$,I=<($5$l$k$3$H$,$"$k$N$r=$@5$7$?!#(B + * $B%[%9%H$,(B2$B$D0J2<$@$H(B wl-plugged-change $B$G%(%i!<$K$J$k$N$r=$@5!#(B + * $B%5%^%j$G$b(B wl-plugged-change $B$G$-$k$h$&$K$7$?!#(B + +1999-09-27 Yuuichi Teranishi + + * $B%3%s%Q%$%k;~$K(B wl.el $B$r(B load $B$7$J$$$h$&$K$7$?!#(B + (Masahiro MURATA ($BB$B$5$s$N8f;XE&$K(B + $B4p$E$/(B) + +1999-09-27 Masahiro MURATA ($BB + + * New plugged system $B$G(B error $B$,H/@8$9$k>l9g$,$"$k$N$r=$@5!#(B + +1999-09-26 Masahiro MURATA ($BB + + * New plugged system. + +1999-09-24 OKUNISHI -GTO- Fujikazu + + * wl-break-pages $B$r(B nil $B$K94B+$7$F$b(B + wl-summary-set-message-buffer-or-redisplay() $B$G$O:FIA2h$5$l$J$$$N$G!"(B + wl-summary-redisplay-internal () $B$r + + * wl-stay-folder-window t$B$G;H$C$F$$$k$H!$9T$,@^$jJV$5$l$F!$(B + $BHs>o$K8+?I$$$N$G!$(Btruncate-line t$B$K$7$?!#(B + +1999-09-23 OKAZAKI Tetsurou + + * elmo-filter-get-spec $B$N;EMMJQ99$K4X78$9$k=$@51L$l$r=$@5(B + (elmo-folder-diff)$B!#(B + +1999-09-23 OKUNISHI -GTO- Fujikazu + + * localdir $BEy$,@dBP%Q%9$+$I$&$+$r(B file-name-absolute-p $B$GH=Dj$7!"(B + .elmo $B0J2<$K(B db $B$r:n$k$h$&$K$7$?!#(B + +1999-09-20 Masahiro MURATA ($BB + + * mime-view-caesar $B$G:n$i$l$?%P%C%U%!$r>C5n$9$k%3!<%I$,(B + $BKu;&$5$l$F$7$^$C$?$N$rI|3h!#(B + +1999-09-21 OKUNISHI -GTO- Fujikazu + + * $B4X?t(B elmo-safe-filename $B$G(B OS/2 $B$G$O(B "|<>" $B$r%U%!%$%kL>$H$7$F(B + $B;H$($J$$$N$KBP1~!#(B + +1999-09-21 Yuuichi Teranishi + + * 2.2.2 - "You Could Be Mine" + * $B%U%)%k%@%b!<%I$K$"$k%U%)%k%@$O!"(Bwl-save-folder-list $B$NCM$K(B + $B4X78$J$/%;!<%V$9$k$h$&$K$7$F$_$?!#(B + * filter $B$G%U%#!<%k%IL>$K(B 'tocc' $B$r;XDj$9$k$H(B to $B$+(B cc $B$K;XDjJ8;zNs$,(B + $B4^$^$l$k%a%C%;!<%8$rr7o!"(BNOT $B>r7o$r;XDj$G$-$k$h$&$K$7$?!#(B + * wl-uniq-list -> elmo-uniq-list + +1999-09-20 Yuuichi Teranishi + + * timezone.el $B$N(B y2k $BBP:v$NDj5A$rJQ99!#(B + * wl-summary-save $B$G!"%;!<%V8e(B "No message to save." $B$H(B + $B8@$o$l$k$N$r=$@5!#(B + * local-variable-p $B$NDj5A$r(B wl-util.el $B$X0\F0!#(B + (Masahiro MURATA ($BB$B$5$s$N8fJs9p(B + $B$K4p$E$/(B) + +1999-02-02 IMAI Takeshi + + * IMAP $B%U%)%k%@$K(B expire $B$G$-$J$+$C$?$N$r=$@5!#(B + +1999-09-20 Masahiro MURATA ($BB + + * mime-view-caesar $B$G:n$i$l$?%P%C%U%!$r>C5n$9$k%3!<%I$,(B + $BKu;&$5$l$F$7$^$C$?$N$rI|3h!#(B + +1999-09-19 Shigeru OKUMURA + + * open-network-stream $B$N(B process-buffer $B$r(B unibyte $B$K@_Dj!#(B + +1999-09-19 OKAZAKI Tetsurou + + * wl-ja.texi $B$N=$@5!#(B + +1999-09-17 HAYAKAWA akio + + * $B%m!<%+%k$N%U%)%k%@$@$1$G9=@.$5$l$F$$$k%^%k%A%U%)%k%@(B + $B$b%m!<%+%k$H$_$J$9$h$&$K$7$?!#(B + +1999-09-16 OKUNISHI -GTO- Fujikazu + + * typo fix. + +1999-09-16 Masahiro MURATA ($BB + + * 1$B$D$N%U%l!<%`$K$*$$$F%a%C%;!<%8$rI=<($9$k%&%#%s%I%&$O6&M-$9$k(B + $B$h$&$K$7$?!#(B + * wl-summary-goto-folder $B$7$?;~$K!$(Bwl-summary-buffer-disp-msg + $B$NCM$K$h$j%a%C%;!<%8$NI=<($rI|85$9$k$h$&$K$7$?!#(B + +1999-09-15 OKAZAKI Tetsurou + + * make install $B$G(B elmo $B4X78$N(B el $B%U%!%$%k$,L5>r7o$K(B + $B%$%s%9%H!<%k$5$l$F$7$^$&$N$r=$@5!#(B + * $B?75,4X?t(B wl-install-modules$B!#(B + +1999-09-14 Yuuichi Teranishi + + * 2.2.1 - "Wild World" + * typo: stickey -> sticky. + * wl-nemacs.el: Nemacs $B8~$1$K(B local-variable-p $B$rDj5A!#(B + * Rename: etc/ChangeLog.* -> etc/ChangeLog.*.ja + * Rename: etc/ChangeLog.*.en -> etc/ChangeLog.* + * XEmacs $B$G%m%4$,=P$J$$$N$r=$@5!#(B + * XEmacs $B$N%$%s%9%H!<%k4X?t$,$3$o$l$F$$$?$N$r=$@5!#(B + (Hidetomo Machi $B$5$s$N8f;XE&(B) + * wl-ja.texi: MIME $BMQ%b%8%e!<%k$N%$%s%9%H!<%k$N9`$r99?7!#(B + * $B%$%s%9%H!<%k;~!":n$C$?(B info $B%U%!%$%k$r>C$5$J$$$h$&$K$7$?!#(B + * $B?75,4X?t(B wl-kill-buffers$B!#(B + * wl-summary-force-exit $B$H(B wl-exit $B$N$H$-$K(B Sticky Message $B$r:o=|(B + $B$9$k$h$&$K$7$?!#(B + (Masahiro MURATA ($BB$B$5$s$N8f=u8@(B) + +1999-09-14 Masahiro MURATA ($BB + + * XEmacs-21.1.6 $B$G$O(B sticky $B%5%^%j$G(B wl-summary-read $B$,%(%i!<$K$J(B + $B$k$N$r=$@5$7$?!#(B + +1999-09-14 Koichiro Ohba + + * ja/dot.wl $B$N(B elmo-eword-decode-string $B$NJQ991L$l$r=$@5!#(B + +1999-09-13 Yuuichi Teranishi + + * tm-wl.el: SEMI API $B$K$"$o$;$F(B defalias-maybe $B$7$?!#(B + * $B$h$/9M$($?$i(B smtp.el $B$O(B flim|clime $B$K4^$^$l$F$$$k$N$G:o=|!%(B + +1999-09-13 Yuuichi Teranishi + + * 2.2.0 - "Vogue" + * smtp.el: Sync up with flim-1.13.2$B!#(B + * $B?75,JQ?t(B wl-install-els$B!#(Bnil $B$J$i(B el $B%U%!%$%k$r%$%s%9%H!<%k$7$J$$!#(B + (for WL-CFG) + * wl-draft-reply $BEy$r(B Sticky Message $BBP1~!#(B + * wl-drfat-buffer-cur-message-buffer -> + wl-current-message-buffer $B$H$7!"(Bwl-util.el $B$K0\F0!#(B + * elmo-cross-device-link-error-p $B$rJQ99!#(B + (pf21 GOTO_Toshiya $B$5$s$N8fJs9p$K4p$E$/(B) + +1999-09-13 Mito + + * Sticky Message$B!#(B + * Score $B%U%!%$%k$N(B guess $BJ}K!$N3HD%!#(B + * elc $B$@$1$G$J$/(B el $B%U%!%$%k$b%$%s%9%H!<%k$5$l$k$h$&$K$7$?!#(B + +1999-09-12 Yuuichi Teranishi + + * $B%5%s%W%k%U%!%$%k$O(B samples $B%G%#%l%/%H%j$K$^$H$a$k$h$&$K$7$?!#(B + * $B%5%s%W%k%U%!%$%k1Q8lHG$rDI2C!#(B + * etc/*.xpm -> etc/icons/*.xpm + * etc/TODO -> doc/TODO.ja + +1999-09-12 OKAZAKI Tetsurou + + * since, before $B4X78$N=$@5!#(B + +1999-09-10 OKUNISHI -GTO- Fujikazu + + * im-wl-prog-imput-error-msg -> im-wl-dispatcher-error-msg$B!#(B + +1999-09-10 Yuuichi Teranishi + + * convert-standard-filename $B$N(B defmacro $B$rGQ;_!#(B + * open-network-stream-as-binary $B$N(B defmacro $B$r:o=|!#(B + * with-current-buffer, with-temp-buffer $BEy$N(B defmacro $B$r:o=|!#(B + * elmo-eword-decode-string -> $BGQ;_!#(B + +1999-09-09 Yuuichi Teranishi + + * $B?75,JQ?t(B elmo-default-imap4-user$B!%(B + (Taiji.Can@atesoft.advantest.co.jp $B$5$s(B $B$N8f=u8@$K4p$E$/(B) + * 2.1.5 - "Unbelievable" + +1999-09-08 Yuuichi Teranishi + + * $B?75,JQ?t(B elmo-nntp-max-number-precedes-list-active$B!#(B + Non-nil $B$J$i(B list active $B$GF@$i$l$k?t;z$r5-;vHV9f$N:GBgCM$H$7$F07$&!#(B + * $B?75,4X?t(B elmo-update-number$B!#(B + elmo-nntp-max-number-precedes-list-active $B$,(B non-nil $B$N$H$-$K(B + $B%5%^%j$NF14|;~$K!"(Bmsgdb $B$N99?7$,$J$/$F$b5-;vHV9f$N:GBgCM$rF14|(B + $B$5$;$k$h$&$K$7$?!#(B + ($B2,ED(B $B7r0l(B (Kenichi OKADA) $B$5$s$N8f;XE&$K4p$E$/(B) + +1999-09-06 Akihiro Motoki + + * elmo-localnews-append-msg $B$N0z?t$,B-$j$J$+$C$?$N$r=$@5!#(B + +1999-09-06 Yuuichi Teranishi + + * [im-wl] im-wl-prog-imput-error-msg $B$,%P%C%U%!%m!<%+%k$K$J$C$F$b(B + $BBg>fIW$J$h$&!"%W%m%;%9%P%C%U%!$KCM$r%3%T!<$9$k$h$&$K$7$?!#(B + * (elmo-folder-local-p) $B$r;H$C$F!"(B'N','P' $B$b(B local $B$J$i(B plug $B>uBV(B + $B$K4X78$J$/F0:n$9$k$h$&$K$7$?!#(B + (Akihiro Motoki $B$5$s$N8f=u8@(B) + +1999-09-03 Akihiro Motoki + + * 'p' $B$,(B localdir $B$G$bL$FI%a%C%;!<%8$r%9%-%C%W$7$F$7$^$&$N$r=$@5!#(B + * $B?75,4X?t(B (elmo-folder-local-p) + +1999-09-03 Yuuichi Teranishi + + * $B%F%s%W%l!<%HA*Br$N%-!<%P%$%s%I$r(B C-cC-j $B$K$7$?!#(B + (TSUMURA Tomoaki $B$5$s!"(B + Masahiro MURATA ($BB$B$5$s$N8f=u8@(B) + +1999-08-31 Yuuichi Teranishi + + * $B%I%i%U%H$NAw?.;~!"%-%e!<=hM};~$N%a%C%;!<%8$N=P$7J}$rJQ99!#(B + +1999-08-31 OKUNISHI -GTO- Fujikazu + + * [im-wl] $B%5%V%W%m%;%9$N8F$S=P$7;~$K%P%C%U%!$rJQ99$;$:!"(B + $B%W%m%;%9$N=PNO$@$1(B" *Wl Watch*" $B$K8~$1$k$h$&$K$7$?!#(B + +1999-08-30 Yuuichi Teranishi + + * [wl-ja.texi] extra-fields $B$,(B IMAP $B%U%)%k%@$GM-8z$K$J$C$F$$$?$N$r(B + $BH?1G!#(B(Sasaki Toshiya $B$5$s$N8f;XE&(B) + * $BJ,3d$5$l$?(B MIME encode $B$5$l$?%a%C%;!<%8$rAw$m$&$H;W$&$H!"(B + $BL58B%k!<%W$K4Y$C$F$7$^$&$N$r=$@5!#(B + (Mikio Nakajima $B$5$s$N8f;XE&(B) + +1999-08-30 OKUNISHI -GTO- Fujikazu + + * new im-wl.el + +1999-08-27 Yuuichi Teranishi + + * $B:G2<9T$G(B `K'/`L' (wl-summary-increase/lower-score) $B$9$k$H(B, + rule $BF~NO$KFMF~$7$F$7$^$&$N$G(B if $BJ8$r$R$H$DHo$;$?!#(B + (TSUMURA Tomoaki $B$5$s$N8f=u8@(B) + * EMWAC $BEy$N%5!<%P!<$G$O!"%5!<%P!<$+$i$NJVEz$rBT$DA0$K%3%^%s%I$r(B + $BAw$C$F$7$^$&$H$=$N8e%5!<%P!<$+$i$N1~Ez$,$J$/$J$C$F$7$^$&$i$7$$$N$G!"(B + $B?75,JQ?t(B elmo-pop3-send-command-synchronously $B$,(B non-nil $B$J$i(B + $B%5!<%P$NJVEz$rBT$D$h$&$K$7$?!#(B + (Atsushi Tada $B$5$s$N%Q%C%A$K4p$E$/(B) + * $B:G6a$N(B SEMI $B$G(B mime-store-message/partial-piece $B$,F0$+$J$/(B + $B$J$C$?$N$r=$@5!#(B + * XEmacs $B$G%I%i%U%H%b!<%I$N%"%$%3%s$,=P$J$/$J$C$F$$$?$N$r=$@5!#(B + +1999-08-26 Teruki SHIGITANI + + * $B%5%^%j%b!<%I$G:G8e$N9T!J%a%C%;!<%8$,$J$$9T!K$K%+!<%=%k$r$*$$(B + $B$F(B "y" $B$rF~NO$9$k!J(Bwl-summary-save$B$r + + * $BGX7J$,L@?'$N>l9g$N?'$N%G%U%)%k%H$r$A$g$C$HJQ99$7$F$_$?!#(B + * $B%U%#%k%?;XDj$G(B /last=200/ $B$H$7$F$7$^$&$H$^$:$$$3$H$K$J$k$N$r=$@5!%(B + * % $B$N%"%/%;%9%0%k!<%W$H$7$F(B root $B$r;XDj$G$-$J$+$C$?$N$r=$@5!%(B + +1999-08-25 Yuuichi Teranishi + + * 2.1.4 - "Tears In Heaven" + * [wl-ja.texi] Summary $B$N(B C-u . $B$N@bL@$rDI2C(B + (susumu-w@ops.dti.ne.jp $B$N8f;XE&(B)$B!#(B + +1999-08-24 Yuuichi Teranishi + + * $B%U%)%k%@C&=P;~$N%^!<%/l9g!"%5%^%j$K%4%_$,(B + $B;D$C$F$7$^$&$N$G!"<:GT$7$?>l9g$O%(%i!<$rH/@8$9$k$h$&$K$7$?!#(B + * split $B$5$l$?%a%C%;!<%8$N%X%C%@$,(B encode $B$5$l$J$$$3$H$,$"$k$N$r=$@5!#(B + * Unplugged $B$G!$%-%c%C%7%e$5$l$?(BIMAP$B%U%)%k%@$NL$FI%a%C%;!<%8$r(B + $BFI$s$@$3$H$,!$%*%s%i%$%s$K$J$C$?=V4V$K%5!<%PB&$KH?1G$5$l$J$$$N$r(B + $B=$@5!%(B + * Unplugged $B$G!$%U%!%$%k%-%c%C%7%e$5$l$F$$$J$$%a%C%;!<%8$rFI$`$H!$(B + $BA0$N%a%C%;!<%8$,I=<($5$l$F$7$^$&$N$r=$@5!%(B + * $BA4HL$K(B, $B%9%l%C%I$r3+JD$9$k$H(B temp-mark $B$h$j(B mark $B$NJ}$,M%@h(B + $B$5$l$F?'$,$D$/$N$r=$@5(B(susumu-w@ops.dti.ne.jp $B$N8f;XE&(B)$B!%(B + * wl-thread-insert-message: wl-summary-goto-top-of-current-thread $B$r(B + $B;H$o$J$$$h$&$K$7$?!#(B + * wl-summary-goto-top-of-current-thread: $B=q$-D>$7!#(B + * "W" $B$G%I%i%U%H$r:n@.$7$?$H$-$K!$(B + wl-mail-setup-hook $B$,8F$P$l$J$$=$@5$,$J$5$l$F$$$J$+$C$?!%(B + ($B2,ED(B $B7r0l(B (Kenichi OKADA) $B$5$s$N8f;XE&(B) + * push -> wl-push$B!%(B + (Masahiro MURATA ($BB$B$5$s$N8f=u8@(B) + +1999-08-23 Yuuichi Teranishi + + * elmo-eword-decode-string $B$r(B defalias $B$9$k$N$r$d$a$k!#(B + * tm $B$G(B flim $B$,;H$o$l$F$$$l$P(B User-Agent $B$K%P!<%8%g%s$rI=<(!%(B + * partial merge $B4X?t$N(B ID $BHf3SItJ,$r=$@5!%(B + +1999-08-22 Masahiro MURATA ($BB + + * elmo-nntp.el (elmo-nntp-catchup-msgdb): overview $B$,F@$i$l$J$/$F!$(B + msgdb $B$,(B (nil nil nil nil) $B$H$J$k>l9g$KBP=h!#(B + +1999-08-20 OKUNISHI -GTO- Fujikazu + + * elmo-pop3.el: elmo-pop3-list-folder $B$r@0M}!#(B + +1999-08-20 Masahiro MURATA ($BB + + * $B?75,JQ?t(B wl-score-folder-alist-matchone$B!#(B + * wl-score-folder-alist $B$N=q<0$r3HD%$7$?!#(B + +1999-08-20 Mito + + * wl-score-folder-alist $B$N(B score file $B$r;XDj$9$k=j$K(B + guess $B$H$$$&%7%s%\%k$r;XDj$7$?>l9g$O$=$N%U%)%k%@L>$+$i(B score + file $B$r?dB,$9$k$h$&$K$7$?!#(B + +1999-08-19 Masahiro MURATA ($BB + + * (wl-summary-switch-to-clone-buffer): $B%3%T!<$9$kJQ?t$K(B + wl-summary-buffer-temp-mark-list, wl-summary-default-score, + wl-summary-important-above, wl-summary-temp-above, + wl-summary-mark-below, wl-summary-expunge-below $B$rDI2C$7$?!#(B + +1999-08-18 Yuuichi Teranishi + + * $BK:$l5n$i$l$F$$$?(B wl-thread-exec $B$r $B$5$s$N8f;XE&(B) + * sync-all $B$N$H$-$b(B temp-mark $B$,;D$C$F$$$l$P!" $B$5$s$N8f;XE&(B) + * timezone-parse-date $B$N(B y2k $BBP:v!#(B + (Masahiro MURATA ($BB$B$5$s$N8f;XE&(B) + +1999-08-17 Mikio Nakajima + + * wl-fldmgr.el $B$N(B interactive command $B$N(B autoload $B@_Dj$r@0M}!#(B + +1999-08-16 Masahiro MURATA ($BB + + * Scoring $B=hM}$r9bB.2=$7$?!#(B + * wl-summary-sort-by-{from|subject} $B$r9bB.2=$7$?!#(B + * wl-summary-switch-to-clone-buffer $B$GJQ?t(B wl-current-score-file + $B$H(B wl-score-alist $B$b%3%T!<$9$k$h$&$K$7$?!#(B + * $B4X?t(B wl-as-mime-charset $B$rDI2C$7$?!#(B + * Use wl-score-mode-mime-charset instead of + wl-score-mode-coding-system. + * elmo-make-hash $B$N%G%U%)%k%H%F!<%V%k%5%$%:$r(B 1024 $B$H$7$?!#(B + +1999-08-14 susumu-w@ops.dti.ne.jp + + * wl-thread-jump-to-msg $B$,(B interactive $B$G8F$P$l$k$H%(%i!<$K$J$k(B + $B$N$r=$@5!%(B + * Summary $B$N(B "J" $B$K(B wl-thread-jump-to-msg $B$r3d$jEv$F!%(B + * localdir, localnew, maildir $B$K$*$$$F(B unplugged $B$G$b(B + plugged $B$HF1$8$h$&$K(B n,p $B$9$k!%(B + * t d $B$G$OJ}8~$r9MN8$7$F$/$l$J$$$N$r=$@5!%(B + * c-u t d $B$G(B $B$$$C$3A0$N%9%l%C%I$,(B D $B$5$l$F$7$^$&$N$r=$@5!%(B + * d $B$@$H + + * [elmo] UW imapd $B$N%j%b!<%H%U%)%k%@$K%"%/%;%9$G$-$J$+$C$?$N$r=$@5!%(B + +1999-08-04 Yuuichi Teranishi + + * wl-queue-folder $B$K3JG<$5$l$?%a%C%;!<%8$NK\J8$,(B + $BI=<($5$l$J$$$N$r=$@5(B($B?\:j(B $B>:(B $B$5$s$N8f;XE&(B)$B!%(B + * 2.1.3 - "Sukiyaki" + +1999-08-03 $B2,ED(B $B7r0l(B (Kenichi OKADA) + + * ChangeLog $B$+$iM>J,$J(B Tab/Space $B$r:o=|!#(B + * wl-vars.el $B$N(B typo $B=$@5!#(B + * wl-ja.texi: wl-folder-{prefetch|mark-as-read-all}-current-entity + $B$N@bL@$rDI2C!#(B + +1999-08-03 Yuuichi Teranishi + + * $B%-%e!<$KN/$C$?%a%C%;!<%8$NAw?.;~$K%(%i!<$,H/@8$7$F$b%-%e!<$+$i(B + $B>C$($F$7$^$&$N$r=$@5!#(B + (Mikio Nakajima $B$5$s$N8f;XE&(B) + * mmelmo-imap4.el: mime-goto-header-start-point, + mime-goto-header-end-point, mime-entity-header-buffer, + mime-entity-body-buffer $B$rl9g$,$"$k$N$r=$@5!#(B + (Shuichi Nishioka $B$5$s$N8f;XE&(B) + * reedit $B;~$K%^%k%A%Q!<%H$N%a%C%;!<%8$r:FJT=8$G$-$J$/$J$C$F$$$?$N(B + $B$r=$@5!#(B + * $B0l;~%^!<%/$N=hM}$r(B unwind-protect $B$G0O$^$J$$$h$&$K$7!"(B + $B%5%^%jC&=P;~$K0l;~%^!<%/$N=hM}$r(B C-g $B$GCfCG$G$-$k$h$&$K$7$?!#(B + (Mito $B$5$s!"(B + Masahiro MURATA ($BB$B$5$s(B, + Taiji.Can@atesoft.advantest.co.jp $B$5$s$i$N8f;XE&8f=u8@$K4p$E$/(B) + +1999-08-02 Mikio Nakajima + + * POP3 $B$N@\B3$,@Z$l$F$7$^$C$?$H$-$K%*%U%i%$%s$X$N%H%0%k$,(B + $B$G$-$J$$$N$r=$@5!#(B + * wl-ja.texi $B$G(B wl-toggle-plugged $B$,(B wl-draft-toggle-plugged $B$K(B + $B$J$C$F$$$?$N$r=$@5!#(B + +1999-08-01 Mikio Nakajima + + * XEmacs $B$N(B configure $B$K(B --with-database=berkdb $B%*%W%7%g%s$rIU$1(B + $B$F%3%s%Q%$%k$7$F$$$k>l9g!"(Belmo-use-database + $B$r(B non-nil $B$K%;%C%H$7$F$b(B elmo-database.el $B$,(B load $B$5$l$F$J$$$N$r(B + $B=$@5!#(B + +1999-07-30 Mito + + * Summary $B$N(B (window-height) $B$,>.$5$$;~!"(BSPC $B$G%(%i!<$,=P$k$N$r=$@5!#(B + +1999-07-29 Masahiro MURATA ($BB + + * (localdir, maildir, localnews, archive) -> + (localdir, localnews, archive) $B$H$$$&%3%T!<$d0\F0$OD>@\(B link(copy) + $B$9$k$h$&$K$7$?!#(B + * wl-summary-pick $B$K$*$$$F!$F1$8(B Message-ID $B$G$"$kJ#?t$N%a%C%;!<(B + $B%8$K%^%C%A$7$F$b(B1$B$DL\$K$7$+(Btemp$B%^!<%/$,IU$+$J$$$N$r=$@5$7$?!#(B + * Followup-To: poster $B$KBP1~$7$?!#(B + * Superseds $B%a%C%;!<%8$r:n@.$9$k%3%^%s%I(B + wl-summary-supersedes-message $B$r?75,:n@.$7$?!#(B + * wl-util.el (wl-string): Use set-text-properties instead of + format. + +1999-07-28 "A. SAGATA" + + * $B@h$N(B elmo-multiple-field-body $B$N=$@5$G<+J,$,=P$7$?%a!<%k$K(B + reply $B$G$-$J$/$J$C$F$$$?$N$r=$@5!#(B + +1999-07-27 Masahiro MURATA ($BB + + * New function: elmo-multiple-field-body and + elmo-multiple-fields-body-list. $BF1L>$NJ#?t$N%U%#!<%k%I$r + + * elmo-localnews-copy-msgs $B$,L$Dj5A$K$b4X$o$i$:8F$P$l$k$N$r=$@5!#(B + +1999-07-24 HAYAKAWA akio + + * wl-(un)plugged-hook $B$rDj5A$9$k$H%(%i!<$K$J$C$F$7$^$&$N$r=$@5!#(B + +1999-07-23 $B2,ED(B $B7r0l(B (Kenichi OKADA) + + * "W"$B$G%I%i%U%H$r:n@.$7$?$H$-$K(B wl-mail-setup-hook $B$,8F$P$l$J$$(B + $B$N$r=$@5!#(B + +1999-07-22 Yuuichi Teranishi + + * wl-summary-cancel-message $B$r(B Sticky Summary $B$KBP1~$5$;$?!#(B + +1999-07-16 Teruki SHIGITANI + + * sample.dot.wl$BFb$K!"Aw?.$7$?%a%C%;!<%8$N$H$-$O:9=P?M$NBe$o$j$K(BTo$B$d(B + Newsgroups$B$rI=<($9$k5!G=$r + + * Fix: void-function wl-summary-rescore-msgs. + +1999-07-15 Yuuichi Teranishi + + * elmo-imap4 $B$b(B Emacs20 $B$N(B multibyte $B$N@_Dj$,$*$+$7$/$F(B + $BJ8;z2=$1$7$F$$$?$N$r=$@5!#(B + * 2.1.2 - "Rico Suave" + +1999-07-14 Yuuichi Teranishi + + * Summary $B$G$N(B "I" $B$b(B prefix-arg $B$D$-$J$i%A%'%C%/$r%9%-%C%W$9$k(B + $B$h$&$K$7$?!#(B + * elmo-nntp $B$G(B Emacs20 $B$N(B multibyte $B$N@_Dj$,$*$+$7$/$F(B + $BJ8;z2=$1$7$F$$$?$N$r=$@5!#(B + * 'u' $B$N%a%C%;!<%8$rFI$^$J$+$C$?$3$H$K$G$-$J$+$C$?$N$r=$@5!#(B + * XEmacs $B$G$$$-$J$j(B wl-draft $B$r + + * wl-score: (wl-score-simplify-subject) + wl-summary-subject-func $B$r8F$VBe$o$j$K(B + wl-score-simplify-fuzzy-regexp $B$r;HMQ$9$k$h$&$K$7$?!#(B + * $B%P%C%U%!%-%c%C%7%e5!G=$GF1$8%-%c%C%7%e%P%C%U%!$,J#?t$G$-$k$N$r(B + $B=$@5$7$?!#(B + +1999-07-13 Masahiro MURATA ($BB + + * delete-if -> elmo-delete-if$B!#(B + +1999-07-13 Yuuichi Teranishi + + * 'I' $B$G!"%5%$%:$,Bg$-$/$F%W%j%U%'%C%A$r%9%-%C%W$7$F$b(B + $B%W%j%U%'%C%A$7$??t$K4^$^$l$F$7$^$&$N$r=$@5!#(B + (susumu-w@ops.dti.ne.jp $B$5$s$h$j8fJs9p(B) + * 2.1.1 - "Praying For Time" + +1999-07-12 Yuuichi Teranishi + + * wl-draft-insert-signature -> $BGQ;_!#(B + * wl-summary-prefetch-all-new -> $B:o=|!#(B + * C-g $B$G%Q%9%o!<%IF~NO$rCfCG$9$k$H(B wrong-type-argument databasep nil + $B$,=P$k$3$H$,$"$k$N$r=$@5(B($B$7$?$D$b$j(B)$B!#(B + ("MATSUBAYASHI 'Shaolin' Kohji" + $B$5$s$N8fJs9p$K4p$E$/(B) + * $B?75,JQ?t(B wl-summary-incorporate-marks$B!#(B + 'I' $B$G%W%j%U%'%C%A$9$k%^!<%/$r;XDj!#%G%U%)%k%H$O!"(B"N" $B$H(B "U"$B!#(B + * elmo-nntp.el $B$H(B mmelmo.el $B$+$i(B (elmo-set-buffer-multibyte nil) + $B$r:o=|(B (Shigeru OKUMURA $B$5$s$N8f=u8@(B)$B!#(B + * wl-mule.el $B$K(B make-face $B$,Dj5A$5$l$F$$$J$$$H$-$K%@%_!<4X?t$rDj5A!#(B + (HAYAKAWA akio $B$5$s!"(B + OKUNISHI -GTO- Fujikazu $B$5$s$N(B + $B8f=u8@$K4p$E$/(B) + * pop3 $B%U%)%k%@$,(B unplugged $B$G%(%i!<$rH/@8$9$k$N$r=$@5(B($B$7$?$D$b$j(B)$B!#(B + (HAYAKAWA akio $B$5$s$N8f;XE&(B) + +1999-07-12 Masahiro MURATA ($BB + + * elmo-msgdb-extra-fields $B$,(B nil $B$N$H$-!$(Bfetch $B$,<:GT$9$k$N$r=$(B + $B@5$7$?!#(B + +1999-07-11 Masahiro MURATA ($BB + + * elmo-crosspost-message-alist $B$r%U%!%$%k$KJ]B8$9$k$h$&$K$7$?!#(B + * $BJQ?tCM$rJ]B8$9$k:]$O!$$J$k$Y$/(B elmo-object-load $B$H(B + elmo-object-save $B$r;HMQ$9$k$h$&$KJQ99$7$?!#(B + * Scoring $B5!G=$G(B wl-summary-rescan $B$d(B sync-all $B;~$K$O(B references + $B$d(B thread $B$N%(%s%H%j$r<+F0DI2C$7$J$$$h$&$K$7$?!#(B + * imap4 $B%U%)%k%@$G(B extra $B%U%#!<%k%I$, + + * localnews $B$G$b(B 'W' $B$G(B Newsgrops $B$rJd40$7$F%I%i%U%H$r:n@.$G$-$k$h$&(B + $B$K$7$?!#(B + +1999-07-08 OKUNISHI -GTO- Fujikazu + + * Nemacs $B$G(B internal("'mark") $B$,FI$a$J$+$C$?$N$r=$@5!#(B + +1999-07-07 Yuuichi Teranishi + + * wl-summary-mark-below $B$N(Bcustom$B$N%0%k!<%W$r(B 'wl-score $B$K=$@5!#(B + (Masahiro MURATA ($BB $B$5$s$N8f;XE&(B) + * wl-summary-incorporate $B$G!"(Bwl-summary-prefetch-all-new $B$N$+$o$j$K(B + (wl-summary-prefetch-region (point-min) (point-max)) + $B$r;H$&$h$&$K$7$?!#(B + (Masahiro MURATA ($BB $B$5$s$N8f=u8@(B) + * Summary $B$N(B C-u . $B$,8z$+$J$/$J$C$F$$$?$N$r=$@5!#(B + (Hideo Matsumoto $B$5$s$h$j8f;XE&(B) + +1999-07-06 sen_ml@eccosys.com + + * rfc2368.el - version 0.3 + +1999-07-06 Hideo Matsumoto + + * $B?75,JQ?t(B wl-draft-use-frame$B!#(B + draft$B$r3+$/$H$-$K?7$7$$(Bframe$B$r3+$/!#(B + +1999-07-06 Masahiro MURATA ($BB + + * $B4X?t(B wl-day-number $B$N(B mapcar $B$K$"$k(B lambda $B$r(B quote$B!#(B + * wl-score.el: wl-summary-{increase|lower}-score $B$G(B Subject $B$N%^%C(B + $B%AJ8;zNs$r4JN,2=$9$k$h$&$K$7$?!#(B + wl-current-score-file $B$H(B wl-score-alist $B$r(B buffer-local $B$K$7$?!#(B + * wl-summary.el: wl-summary-scored $B$r(B nil $B$K$9$k0LCV$rJQ99$7$?!#(B + * Rename: + wl-score-simplify-subject-fuzzy-regexp -> + wl-score-simplify-fuzzy-regexp + wl-score-simplify-buffer-fuzzy-step -> elmo-buffer-replace. + * wl-ja.texi: $B%9%3%"5!G=$NJQ99!#(B + * wl-draft.el: autoload $B@_Dj$NDI2C!#(B + * sample.dot.wl: wl-summary-next-no-unread$B$N:o=|!#(Bscore$B5!G=$N@_(B + $BDjDI2C!#(B + +1999-07-06 Yuuichi Teranishi + + * Summary $B$N(B C-u . $B$,8z$+$J$/$J$C$F$$$?$N$r=$@5!#(B + (Hideo Matsumoto $B$5$s$h$j8f;XE&(B) + * Nemacs $B$G$O(B wl-summary-{print|remove}-destination $B$r(B + $B%@%_!<4X?t$K$9$k!#(B + * Nemacs $BMQ$K(B rassoc $B$rDj5A!#(B + * Nemacs $B$N(B Folder $B%b!<%I$G(B 'm' $B$r2!$9$H%(%i!<$K$J$k$N$r=$@5!#(B + * Nemacs $B$G$O(B wl-use-scoring $B$N(B default $B$r(B nil $B$K$7$?!#(B + * $B?75,4X?t(B elmo-delete-if$B!#(Breplacement of delete-if$B!#(B + * Nemacs $B$G%P%$%H%3%s%Q%$%k$9$k$H$J$<$+(B (defvar nil nil) $B$N%(%i!<(B + $B$,=P$k$N$r=$@5!#(B + (Taiji.Can@atesoft.advantest.co.jp $B$5$s$h$j8f;XE&(B) + * 2.1.0 - "Ordinary World" + +1999-07-05 Yuuichi Teranishi + + * partial $B$r%^!<%8$G$-$J$+$C$?$N$r=$@5!#(B + (Taiji.Can@atesoft.advantest.co.jp $B$5$s$h$j8f;XE&(B) + * wl-summary-rescore $B$b(B wl-summary-rescore-partial-threshold $B$K=>$&(B + $B$h$&$K$7$F$_$?!#(B + * wl-summary-score-update-all-lines $B$N=hM}Cf%a%C%;!<%8$r=P$9$h$&$K(B + $B$7$?!#(B + +1999-07-04 Masahiro MURATA ($BB + + * wl-score.el: date, extra, followup, thread $B%-!<$rDI2C$7$?!#(B + * `wl-score-default-file-name' $B$G;XDj$5$l$?%9%3%"%U%!%$%k$rI,$:FI$_(B + $B9~$`$h$&$K$7$?!#(B + * $B%5%^%j%P%C%U%!!$$*$h$S%9%3%"JT=8%P%C%U%!$G%9%3%"%U%!%$%k$r:n@.$9$k(B + $B5!G=$rDI2C$7$?!#(B + * wl-vars.el: defcustom $B$r@0M}$7$?!#(B + * wl-highlight.el: defface $B$K%0%k!<%W$rDI2C$7$?!#(B + +1999-07-01 Yuuichi Teranishi + + * $B?75,(B sync $B%l%s%8(B rescan-noscore$B!#%9%3%"$rH?1G$;$:I=<($7$J$*$9!#(B + * rescan/sync-all $B$G$O4{FI%a%C%;!<%8$G$b(B score $B$rH?1G$9$k$h$&$K$7$?!#(B + * $B?75,JQ?t(B wl-summary-rescore-partial-threshold$B!#(Brescan, sync-all $B$G(B + $B%9%3%"IU$1$9$k%a%C%;!<%8?t$N>e8B$r;XDj!#(B + * wl-edit-again-func->wl-edit-decode-message-func + (tomo@etl.go.jp ($BC$9!#(B + * wl-refile-alist-setup $B$N + + * wl-refile-(msgid-)learn $B$d(B, wl-refile-guess-* $B$NCf$G(B, + $BKh2s(B wl-refile-(msgid-)alist $B$,(B load $B$5$l$F$k$+$I$&$+D4$Y$k$N$O(B + $BL5BL$J$N$G5/F0;~$KI,$:(B load $B$9$k$h$&$K$7$?!#(B + * wl-refile-(msgid-)learn $B$,0lEY8F$P$l$kKh$K(B wl-refile-alist-save + $B$9$k$N$O(B, $BL5BL$J$N$G(B WL $B=*N;;~$K0l2s$@$1(B save $B$9$k$h$&$K(B + $B$7$?!#(B + * wl-refile-(msgid-)learn $B$NJV$jCM$rJQ99!#(B + +1999-06-29 Shuhei KOBAYASHI + + * cl $B$N(B require $B$r(B eval-when-compile $B$G3g$j!"=gHV$rJQ$($k!#(B + +1999-06-29 OKUNISHI -GTO- Fujikazu + + * unread $B$,(B 0 $B$N;~(B [Space] $B$G%5%^%j$+$iH4$1$i$l$J$+$C$?$N$r=$@5!#(B + * cl.el $B$N(B member () $B$,(B poe-18.el $B$N(B member () $B$r>e=q$-$7$F$7$^$&(B + $B$N$r=$@5!#(B + +1999-06-29 Yuuichi Teranishi + + * AIR MAIL(AIRCimapd release 2.00) $B$KBP1~!#(B + (Sasaki Toshiya $B$5$s$N8fJs9p(B + $B$K4p$E$/(B) + +1999-06-29 Yuuichi Teranishi + + * wl-score $B$G$N(B expunge $B$r!VFI$s$@$3$H$K$7$F!"(B + $B%5%^%j%P%C%U%!$+$i>C$9$@$1!W$H$7$?!#(B + * update $B;~$K(B expunge $B$7$?$3$H$rJs9p!#(B + +1999-06-28 Shuhei KOBAYASHI + + * elmo-pop3.el $B$G(B md5-encode $B$r;H$o$J$$$h$&$K$7$?!#(B + +1999-06-28 OKUNISHI -GTO- Fujikazu + + * MK-MK: + (mapcar (lambda ..)) $B$,(B v18 $B$G$OF0$+$J$$$N$G(B quote $B$9$k!#(B + Nemacs $B$G$b(B wl-mule.elc $B$,%$%s%9%H!<%k$5$l$k$3$H$K$J$C$F$?$N$r(B + $B=$@5!#(B + defgroup(), defcustom() $BLdBj2sHr%3!<%I$rI|3h!#(B + * wl-summary.el, wl-demo.el: + float $B$,;H$($J$$0lIt$N(B Emacsen $B$G$N%(%i!<2sHr!#(B + * wl-nemacs.el: + completing-read() $B$O0z?t$r8^$D$^$G$7$+l9g$K%(%i!<$K$J$i$J$$$h$&$K(B + $B$9$k!#(B + +1999-06-28 Masahiro MURATA ($BB + + * default-case-fold-search $B$,(B nil $B$N$H$-!$(Bwl-summary-pick $B$,@5>o(B + $B$KF0:n$7$J$$$N$r=$@5$7$?!#(B + * important $B%^!<%/$,(B2$B$D0J>e$"$k$H!$(Bwl-auto-select-next $B$,(Bnon-nil + $B$N$H$-$K + + * $B4X?t(B wl-summary-delete-all-delete-marks () $BDI2C!#(B + * (wl-summary-cleanup-temp-marks) $B$,$J$<$+#22s8F$P$l$F$$$?$N$r=$@5!#(B + ($B:72eED$5$s(B $B$N8f;XE&(B) + +1999-06-27 Masahiro MURATA ($BB + + * folder $B%b!<%I$G(B wl-summary-goto-folder-subr $B$r0l;~E*$K%5%^%j$K0\(B + $BF0$7$?;~$O!$(BScoring $B$5$l$J$$$h$&$K$7$?!#(B + * wl-summary-next-no-unread $B$r:o=|$7!$(Bwl-auto-select-next $B$@$1$G@)(B + $B8f$9$k$h$&$K$7$?!#(B + * wl-summary-move-order $B$N%G%U%)%k%HCM$r(B 'new $B$+$i(B 'unread $B$KJQ99(B + $B$7$?!#(B + +1999-06-27 OKUNISHI -GTO- Fujikazu + + * Nemacs $B$G(B (wrong-type-argument listp 1) $B$,H/@8$9$k$N$r=$@5!#(B + * Nemacs $B$,(B timer $B$,$J$/$F%(%i!<$K$J$k$N$r(B condition-case $B$G2sHr!#(B + +1999-06-27 Masahiro MURATA ($BB + + * $B%9%3%"%U%!%$%k$r(B ctext (*ctext) $B$GFI$_=q$-$9$k$h$&$K$7$?!#(B + +1999-06-26 $B2,ED(B $B7r0l(B (Kenichi OKADA) + + * mailto: $B$HF1MM(B nntp: news: $B$KBP1~$5$;$k4X?t!%(B + (-> wl-utils.el $B$KDI2C!#(B) + +1999-06-25 Masahiro MURATA + + * wl-score.el: coding-system $B$,%P%0$C$F$$$?$N$r=$@5!#(B + +1999-06-25 Masahiro MURATA + + * wl-score.el: $B?75,%U%!%$%k!#(BScore $B5!G=$rDI2C$7$?!#(B + * wl-summary.el: (wl-summary-sync-update3) + wl-folder-set-folder-updated $B$N%?%$%_%s%0$rJQ99$7$?!#(B + * (wl-summary-update-crosspost) $B%9%l%C%I$r%*!<%W%s$;$:$K4{FI%^!<(B + $B%/$rIU$1$k$h$&$KJQ99$7$?!#(B + * wl-util.el: New function `wl-delete-alist'. + New macro `wl-as-coding-system'. Add emulate function `pp'. + +1999-06-24 pf21 GOTO_Toshiya + + * [wl-ja.texi] wl-thread-open-reading-thread $B$N@bL@DI2C!#(B + +1999-06-24 Kenichi OKADA + + * elmo-cache-expire $B$,%(%i!<$rH/@8$9$k$N$r=$@5!#(B + +1999-06-24 sen_ml@eccosys.com + + * utils/rfc2368.el $B$N%P%0=$@5!#(B + +1999-06-24 Yuuichi Teranishi + + * 2.0.1 - "Now And Forever" + * body $B$K(B --text follows this line-- $B$,$"$k$H$=$N9T0JA0$,$J$/$J$k(B + $B$N$r=$@5(B($BIT40A4(B)$B!#(B + ($B2,ED(B $B7r0l(B (Kenichi OKADA) $B$5$s(B + $B$N8f;XE&(B) + +1999-06-24 MAKINO Takashi + + * $B?75,4X?t(B wl-refile-guess-by-msgid$B!#(B + +1999-06-23 Akihiro Motoki + + * wl $B$r5/F0$7$F$$$J$$>uBV(B $B$+$D(B (setq wl-stay-folder-window t)$B$N>l9g!"(B + wl-draft $B$r9T$&$H!"(Bwl-draft-send-and-exit $B$b(B wl-draft-kill $B$b(B + $B<:GT$9$k$N$r=$@5!#(B + +1999-06-23 $B2,ED(B $B7r0l(B (Kenichi OKADA) + + * wl-ja.texi: wl-template-alist $B$N@bL@(B: file -> body-file + +1999-06-23 Yuuichi Teranishi + + * Draft $B$G(B prefix $B$D$-$G(B C-c C-y $B$9$k$H%+%C%H%P%C%U%!$+$i(B + $B0zMQ$9$k$h$&$K$7$F$_$?!#(B + * elmo-imap4-int-string-to-list -> $BGQ;_!#(B + (Masahiro MURATA ($BB$B$5$s$N8f=u8@(B) + * $B:G6a$h$/4V0c$($k$N$G(B Summary $B$N(B 'e' $B$r(B wl-summary-save $B$K(B + $B3d$jEv$F$?!#(B + * wl-set-string-width $B$+$iITMW$H;W$o$l$k(B let $B$ruBV$@$H!$(BMH$B%U%)%k%@4V$G$N(Brefile$B$G!$(Belmo-copy-msgs $B$N$"$H$K(B + elmo-append-msg $B$b8F$P$l$k$N$r=$@5!#(B + (Koji IIDA / $BHSED(B $B9@Fs(B $B$5$s$h$j8f;XE&(B) + +1999-06-22 Yuuichi Teranishi + + * mule/emacs $B$G(B wl-draft-prepared-config-exec $B$,(B + C-c C-d $B$H(B C-c C-e $B$NN>J}$K3d$j$"$F$i$l$F$$$?$N$r=$@5!#(B + * wl-completion-buf-name $B$NCM$r(B + emacs $BI8=`$NJd40MQ%P%C%U%!(B *Completions* $B$K9g$o$;$?!#(B + * wl-message-buffer-created-hook $B$r@_Dj$7$F$bE,@Z$K(B hook $B$,(B + $B8F$P$l$F$$$J$$$N$r=$@5!#(B + (Akihiro Motoki $B$5$s$h$j8f;XE&(B) + +1999-06-22 Masahiro MURATA ($BB + + * elmo-nntp.el: XOVER $B$G$N(B size $B$N + + * elmo-pop3 $B$N(B max-of-folder $B$r8zN(2=!#(B + +1999-06-21 OKUNISHI -GTO- Fujikazu + + * .wl $B$N(B syntax $BEy$N%(%i!<$r$A$c$s$HEG$+$;$k!J%f!<%6$KCN$i$;$k!K(B + $B$h$&$K$7$?!#(B + * $B$*$^$1!#(B + +1999-06-19 Masahiro MURATA ($BB + + * (featurep 'tinycustom) $B$J$i(B defface $B$NDj5A$rL5;k$9$k!#(B + +1999-06-18 Shigeru OKUMURA + + * nntp $B$NJ8;z2=$1$,$^$@D>$C$F$$$J$+$C$?$N$r=$@5!#(B + +1999-06-18 Masahiro MURATA ($BB + + * @ $B$G@5$7$/%"%I%l%9$r(B expand $B$9$k$h$&$K$7$?!#(B + +1999-06-16 Yuuichi Teranishi + + * $B?75,JQ?t(B wl-use-dnd$B!#%I%i%C%0%"%s%I%I%m%C%W5!G=$r$D$+$&$+$I$&$+!#(B + +1999-06-16 Masahiro MURATA ($BB + + * [elmo-nntp] elmo-list-folder $B$G(B "LISTGROUP" $B%3%^%s%I$r;H$&$h$&(B + $B$K$7$?!#(B + * [elmo-nntp] xover $B$N;HMQ2DH]$r%5!<%P$4$H$KJ];}$9$k$h$&$K$7$?!#(B + +1999-06-16 Shigeru OKUMURA + + * Content-Type$B$,(Bsjis$B$d(Beuc$B$@$H(B mail$B$d(Bnews$B$,2=$1$F$7$^$&$N$r=$@5!#(B + +1999-06-16 Yuuichi Teranishi + + * [elmo-imap4] cram-md5 $BBP1~!#(B + +1999-06-15 Yuuichi Teranishi + + * tm $B$G(B error: Split sender is not specified for `wl-draft-mode'. + $B$H=P$k$N$r=$@5!#(B + (Toshihiko Kodama $B$5$s$N8f;XE&(B) + +1999-06-14 Yuuichi Teranishi + + * `wl-draft-enable-queuing' $B$N@bL@$,%@%V$C$F$$$?$N$r=$@5!#(B + (Toshihiko Kodama ($B>.6L(B $BMxI'(B) + $B$5$s$h$j8f=u8@(B) + +1999-06-14 OKUNISHI -GTO- Fujikazu + + * wl-detect-info-directory() $B$r$A$g$C$H8-$/$7$F$_$?!#(B + +1999-06-13 Masahiro MURATA ($BB + + * $B%P%C%U%!%-%c%C%7%e!#(B + $B?75,JQ?t(B elmo-use-buffer-cache $B$,(B non-nil $B$J$i%-%c%C%7%e!#(B + $B%G%U%)%k%H$O(B t$B!#(B + $B0lC6FI$s$@%a%C%;!<%8$r%P%C%U%!$K;D$7$F$*$/5!G=!#(B + * $B%a%C%;!<%8$N@hFI$_(B(cache-prefetch)$B!#(B + $B%a%C%;!<%8$rFI$s$G$$$k4V$K + + * WL-MK: + info $B@8@.;~$N(B codesys $B$N7hDj$O(B wl-vars.el $B$rMxMQ$9$k!#(B + info $B$NJ,3d%*%W%7%g%s$rGQ;_!#(B + info $B$N%$%s%9%H!<%k;~$K$OJ# + + * $B?75,%U%!%$%k(B utils/wl-use-agent.el, utils/rfc2368.el + +1999-06-11 Yuuichi Teranishi + + * mmelmo-imap4-get-mime-entity$B$NCf$N(B + elmo-imap4-get-connection$B$N0z?t$,>/$J$+$C$?$N$r=$@5!#(B + ($B2,ED7r0l$5$s(B$B$N8f=u8@(B) + * 2.0.0 - "Mmmbop" + * wl-summary-partial-highlight-above-lines $B$,(B nil $B$J$i(B + Summary $B3+;O;~$N%+!<%=%k$N0LCV$K4X78$J$/:G8e$+$i(B + wl-summary-highlight-partial-threshold $B9T$@$1%O%$%i%$%H$9$k(B + $B$h$&$K$7$?!#(B + * Sen Nagata $B$5$s:n$N(B util/wl-user-agent.el $B$r(B + $B:G?7HG$K99?7!#(B + ($B1|@>$5$s(B $B$h$j8f;XE&(B) + +1999-06-10 $B2,ED(B $B7r0l(B (Kenichi OKADA) + + * IAMP4$B$H(BNNTP$B$N%"%/%;%9%0%k!<%W$G!$%]!<%HHV9f$,(B + $B%G%U%)%k%H$H0c$&$H%(%i!<$,=P$k$N$r=$@5!#(B + +1999-06-10 Yuuichi Teranishi + + * $B%U%!%$%kL>JQ99(B + ChangeLog.en -> ChangeLog + ChangeLog -> ChangeLog.ja + * [wl-ja.texi] wl-plugged $B$N@bL@$rDI2C!#(B + ($BCSED$5$s(B $B$h$j8f=u8@(B) + +1999-06-09 Yuuichi Teranishi + + * $B?75,JQ?t(B elmo-default-pop3-ssl elmo-default-nntp-ssl + elmo-default-imap4-ssl$B!#(Bnon-nil $B$J$i(B "!" $B$rIU$1$J$/$F$b(B SSL $B$r;H$&!#(B + * $BL>A0JQ99(B + elmo-nntp-port -> elmo-default-nntp-port + elmo-imap4-port -> elmo-default-imap4-port$B!#(B + ($B2,ED$5$s(B $B$N8f=u8@(B) + * [elmo] imap4, nntp, pop3 $B$G%U%)%k%@L>$N:G8e$K(B "!" $B$,$D$$$?$i(B SSL $B$r(B + $B;H$&$h$&$K$7$?!#(B + * [elmo] imap4, nntp, pop3 $B$G%]!<%H$r;XDj$7$F$J$$%5!<%P$H$N%;%C%7%g%s$H(B + $B%]!<%H$r;XDj$7$?F1$8%5!<%P$H$N%;%C%7%g%s$G%3%M%/%7%g%s$,(B + $B$+$A$"$o$J$$$h$&$K$7$?!#(B + +1999-06-09 OKUNISHI -GTO- Fujikazu + + * POP $B$G$bJQ?t(B elmo-default-pop3-server $B$r?7@_!"(B"&USER" $B$@$1$G(B + $B$b%"%/%;%9$G$-$k$h$&$K$7$?!#(B + * mmelmo-imap4.el $B$K%]!<%HHV9f;XDj$N=$@5!#(B + * [wl-ja.texi] $B=$@5!#(B + +1999-06-08 $B2,ED(B $B7r0l(B (Kenichi OKADA) + + * IMAP4 $B%U%)%k%@$G(B port $BHV9f$r;XDj$G$-$k$h$&$K$7$?!#(B + +1999-06-07 Akihiro Motoki + + * $B%a!<%k$N=g=x$,(B $B:o=|A0$N%U%)%k%@$H(B trash$B%U%)%k%@$G5U$K$J$C$F$7$^$&(B + $B$N$r=$@5!#(B + * wl-summary-pick $B$G(B field-name $B$H$7$F(B elmo-msgdb-extra-fields $B$r;XDj(B + $B$G$-$k$h$&$K$7$?!#(B + +1999-06-07 Yuuichi Teranishi + + * wl-summary-jump-to-parent-message() $B$O!"%9%l%C%I$HF1MM(B + In-Reply-To $B$rM%@h$9$k!#(B + ($B:72eED$5$s(B $B$N8f;XE&(B) + * From $B$,(B wl-from $B$K%^%C%A$9$k%a%C%;!<%8$KJV;v$r=q$/$H$-$O!"(B + To, Cc, Newsgroups $B$rJ]B8$9$k!#(B + ($BDEM8$5$s(B $B$N8f=u8@(B) + +1999-06-06 Masahiro MURATA ($BB + + * sticky$B%5%^%j$KBP$7$F!$(Bwl-folder-mark-as-read-all-entity, + wl-folder-sync-entity, wl-folder-prefetch-entity $B$r + + * wl-folder-no-auto-check-folder-p $B$G(B wl-auto-check-folder-list $B$r(B + $BM%@h$5$;$k$h$&$K$7$?!#(B + * wl-summary-switch-to-clone-buffer $B$G(B + wl-summary-buffer-new-count $B$H(B wl-summary-buffer-unread-count $B$,(B + $B%3%T!<$5$l$J$$$N$r=$@5$7$?!#(B + * wl-folder-empty-trash $B$G%5%^%j%P%C%U%!$,I=<($5$l$J$$$N$r=$@5$7$?!#(B + * bbdb2 $B$G(B bbdb-wl.el $B$r%3%s%Q%$%k$9$k;~$N(Bwarning$B$r$J$/$7$?!#(B + * interactive $B$r(B nil $B$K$7$F(B wl-summary-goto-folder-subr $B$7$?:]!$(B + recenter $B$G%(%i!<$,=P$k$3$H$,$"$k$N$r=$@5$7$?!#(B + * bbdb2 $B$G(B bbdb-wl.el $B$r%3%s%Q%$%k$9$k;~$N(Bwarning$B$r$J$/$7$?!#(B + * wl-folder-suspend-hook $B$rDI2C$7$?!#(B + +1999-06-06 OKUNISHI -GTO- Fujikazu + + * "V" $B$G2>A[%U%)%k%@$r:n@.$9$k$H%5%^%j$,I=<($5$l$:!"(Bsync update + $B$7$J$1$l$P$J$i$J$$!#$^$?!"99$K(B "V" $B$7$F$+$i(B "C-u V" $B$G85$N2>A[(B + $B%U%)%k%@$KLa$k$H:F$S%5%^%j$,I=<($5$l$J$/$J$C$F$7$^$&!#(B + +1999-06-04 OKUNISHI -GTO- Fujikazu + + * font-lock $B$K$h$kJ@32$rHr$1$k$?$a!"(Bwl-draft-reedit() $B$G$b(B + change-major-mode-hook $B$r(B nil $B$KB+G{$9$k!#(B + * wl-message-refer-article-or-url() $B$r + + * sticky $B%5%^%j$+$i0\F0$9$k:]!$(Btemp-mark $B$,$D$$$F$$$k$H$=$N(B + $B%^!<%/$O>C$($F$b(B highlight $B$,;D$C$?$^$^$K$J$k$N$r=$@5$7$?!#(B + * wl-summary-buffer-copy-list $B$,(B buffer-local-variables $B$K$J$C$F(B + $B$$$J$+$C$?$N$r=$@5$7$?!#(B + * $B%5%^%j$N0\F0;~$K(B interactive $B$G$J$$>l9g$O(B switch-to-buffer $B$G(B + $B$O$J$/!$(Bset-buffer $B$9$k$h$&$K$7$?!#(B + +1999-06-03 Yuuichi Teranishi + + * $B4X?t(B elmo-imap4-identical-name-space-p $B$r $B$N8f;XE&(B) + * [mmelmo.el, mmelmo-imap4.el] FLIM 1.13 API $B$KBP1~!#(B + +1999-06-03 "A. SAGATA" + + * sticky summary$B$r;H$&$H!"(Bdraft$B=*N;8e!"JL$N(Bsummary$B$KLa$k;v$,$"$k!#(B + * menu $B$K(B mR $B$H(B mf$B$,Fs$D$E$D$"$C$?$N$r=$@5!#(B + * wl-summary-jump-to-current-message $B$,$A$g$C$HJQ$@$C$?$N$r=$@5!#(B + +1999-06-02 Yuuichi Teranishi + + * XEmacs package $B$G$b(B BBDB $B$,B8:_$9$l$P(B utils/bbdb-wl.el $B$b(B + bytecomp/install $B$9$k!#(B + * $B?75,JQ?t(B wl-summary-keep-cursor-command$B!#(B + $B%3%^%s%I$4$H$K%+!<%=%k0LCV$r$=$N$^$^$K$9$k$+$I$&$+$r@_Dj$G$-$k(B + $B$h$&$K$7$?!#(B + +1999-06-02 OKUNISHI -GTO- Fujikazu + + * BBDB $B$,B8:_$9$l$P(B utils/bbdb-wl.el $B$b(B bytecomp/install $B$9$k!#(B + +1999-06-02 $B2,ED(B $B7r0l(B (Kenichi OKADA) + + * elmo-pop3$B$N%P%$%H%3%s%Q%$%k;~$N%r!<%K%s%0$r$H$k!#(B + * [WL-MK] $B0lEY!$(Bmake$B$7$F(Belc$B$r:n$C$?8e$K!$(Belmo-*.el$B$rJQ99$7$F!$(B + $B$b$&0lEY(Bmake$B$9$k$H!$%(%i!<$K$J$k$N$r=$@5!#(B + +1999-06-02 Masahiro MURATA ($BB + + * sticky $B%5%^%j$G$N(B update $B;~$K!$?75,%a%C%;!<%8$,(B highlight $B$5$l$J$/(B + $B$J$C$?$N$r=$@5$7$?!#(B + +1999-06-01 Yuuichi Teranishi + + * 1.0.1 $B$+$iJ,4t!#(B + +1999-06-01 Masahiro MURATA ($BB + + * $B0\F0@h$N%P%C%U%!$,4{$KB8:_$7$F$$$?>l9g$NF0:n$rJQ99$7!"(B + 'g' $B$G8F$P$l$?>l9g$O(B update $B$;$:$K%+!<%=%k0LCV$rJ];}$9$k$h$&$K$7$?!#(B + * 'g' $B$G0\F0$9$k:]!$(Bwl-ask-range($B?75,JQ?t(B) $B$,(B nil $B$J$i!$(B + wl-folder-sync-range-alist $B$NCM$r;HMQ$9$k$h$&$K$7$?!#(B + * wl-summary-read-folder $B$GF~NO$7$?%U%)%k%@L>$N$_$NMzNr$r(B + wl-read-folder-hist $B$K5-O?$9$k$h$&$K$7$?!#(B + * $B8r8_$K%5%^%j$r@Z$jBX$($k?75,%3%^%s%I!"(B + wl-summary-goto-last-visited-folder$B!#(B($B%-!<%P%$%s%I$K$OL$3d$jEv$F(B) + +1999-06-01 Yuuichi Teranishi + + * 1.0.1 - "The Look" + * wl-ja.info $B$r%Q%C%1!<%8$+$i:o=|!#(B + +1999-06-01 Sen Nagata + + * compose-mail $B$N%$%s%?!<%U%'!<%9$r%5%]!<%H!#(B + ($B?75,%U%!%$%k(B wl-user-agent.el $B$rDI2C(B) + +1999-05-31 "A. SAGATA" + + * wl-stay-folder-window $B$,(B non-nil $B$N$H$-!"(Bfull window $B$G(B + draft $B$r:n@.$7$?8e!"(B C-cC-k $B$d(B C-cC-c $B$G!"(Bdraft $B$r=*N;$7$F(B + summary mode $B$KLa$C$?;~$K!"(Bfolder window $B$,>C$($F$7$^$o$J$$(B + $B$h$&$K$7$?!#(B + +1999-05-31 Yuuichi Teranishi + + * folder $B%b!<%I$J$I$+$i%U%)%k%@0\F0$9$k$H$-!"(B + wl-folder-sync-range-alist $B$NCM$rH?1G$9$k$h$&$K$7$?!#(B + ($B?@V:$5$s(B $B$N8f=u8@(B) + * wl-draft-reply-buffer-style $B$,(B 'full $B$N$H$-!"(Bmulti-reply/forward + $B$,%(%i!<$K$J$k$N$r=$@5!#(B + ($B:72eED$5$s(B $B$N8f;XE&(B) + * sticky summary $B$K0\F0$7$?$H$-$O(B msgdb $B$r%m!<%I$7$J$$$h$&$K$7$?!#(B + ($BB $B$N8f=u8@(B) + * wl-summary-exit $B$,L5BL$K%;!<%V$7$F$7$^$&$N$r=$@5!#(B + + +1999-05-29 OKUNISHI -GTO- Fujikazu + + * [wl-mime.el, tm-wl.el] + (tm-)wl-mime-combine-message/partial-pieces() $B$G(B + regexp $B$,(B regexp-quote() $B$5$l$F$J$+$C$?$N$r=$@5!#(B + +1999-05-28 Yuuichi Teranishi + + * elmo-localdir-search $B$r$3$3$m$b$A9bB.2=!#(B + +1999-05-26 Shuhei KOBAYASHI + + * elmo-archive-search $B$r$3$3$m$b$A9bB.2=!#(B + +1999-05-25 OKUNISHI -GTO- Fujikazu + + * $B08@h$,(B localdir, localnews $B$N;~$G$b(B elmo-move-msgs() $B$r9bB.(B + $B2=$7$?!#$J$*!"(Bprocmail $B$J$I$N(B MDA $B$r;H$C$F$$$k>l9g!"JQ?t(B + `elmo-localdir-lockfile-list'$B!J=i4|CM$O(B nil$B!K$K(B MDA $B$,@8@.$9(B + $B$k%m%C%/%U%!%$%kL>$r;XDj$9$k!#(B + * $B$$$/$D$+$N4X?t$r$3$3$m$b$A9bB.2=(B + +1999-05-24 $B2,ED(B $B7r0l(B (Kenichi OKADA) + + * POP3 $B$r(B SSL $B$KBP1~$5$;$?!#(B + * elmo-pop3-get-spec$B$G(B port $B$,(B string $B$@$C$?$N$r(B int $B$K$7$?!#(B + * elmo-default-pop3-port,elmo-default-pop3-authenticate-type$B$r(B + $BH?1G$7$F$$$J$+$C$?$N$r=$@5!#(B + +1999-05-24 "A. SAGATA" + + * customize $B$G4v$D$+(B `mismatch' $B$,=P$F$$$?$N$r=$@5!#(B + +1999-05-21 OKUNISHI -GTO- Fujikazu + + * WL-ELS $B$r(B WL-MK $B$K2~L>!#(B + * make install $B$G(B Emacs $B$,#22s5/F0$5$l$J$$$h$&$K$9$k!#(B + +1999-05-20 Yuuichi Teranishi + + * wl-exit () $BCf$N(B delete-other-windows () $B$r:o=|!#(B + * wl-summary-force-exit $B$r(B interactive $B$K$9$k$N$rK:$l$F$$$?!#(B + ($B@P@n$5$s(B Ishikawa Ichiro $B$N8f;XE&(B) + +1999-05-20 Hidetoshi Shimokawa + + * device-class $B$,(B color $B$N(B tty $B$N$H$-$NIT6q9g$r=$@5!#(B + +1999-05-20 "A. SAGATA" + + * highlight$B$r(Bcustom$B$KBP1~$7$?(B. + * $B%O%$%i%$%HJQ?t$N(Binfo$B$rDI2C$7$?(B. + +1999-05-19 "A. SAGATA" + + * wl-highlight-signature-separator $B$rDI2C!#(B + +1999-05-19 TSUMURA Tomoaki + + * wl-summary-jump-to-message-by-message-id () $B$,(B + $B%9%l%C%I$,JD$8$?>uBV$G1#$l$F$$$k%a%C%;!<%8$KHt$P$J$$$N$r=$@5!#(B + +1999-05-19 Yuuichi Teranishi + + * wl-summary-msgdb-load-async () $B$r=$@5!#(B + * $B%U%)%k%@0\F0;~$N%P%C%U%!@ZBX$($N%?%$%_%s%0$rJQ99!#(B + * wl-summary-mark-as-read-all $B$,!$%9%l%C%I$,JD$8$?>uBV$G1#$l$F(B + $B$$$k%a%C%;!<%8$KBP$7$F8z$+$J$/$J$C$F$$$?$N$r=$@5!#(B + ($BBg_7$5$s(B $B$N8f;XE&(B) + diff --git a/etc/icons/archive.xpm b/etc/icons/archive.xpm new file mode 100644 index 0000000..6b645b9 --- /dev/null +++ b/etc/icons/archive.xpm @@ -0,0 +1,28 @@ +/* XPM */ +static char * lha_xpm[] = { +"16 16 9 1", +" c None", +". c #61856595CF3C", +"X c #E79DE79DE79D", +"o c #BEFBBEFBBEFB", +"O c #000000000000", +"+ c #08200C300820", +"@ c #965896589658", +"# c #C71BC30BC71B", +"$ c #FFFFEBAD79E7", +" ", +" ... ", +" ... ", +" ..... ", +" XXXXX ... ", +" XoooooX . ", +" XooooOoXOXXOX+ ", +" XoooOOoOOoOO@+ ", +" X#oO$OO$OO$O@O ", +" X#O$$O$$O$$O@O ", +" X#O$$O$$O$$O@O ", +" X#O$$O$$O$$O@O ", +" X#O$OO$OO$Oo@O ", +" X@OO@OO@OO@@@O ", +" OOOOOOOOOOOOOO ", +" "}; diff --git a/etc/icons/closed.xpm b/etc/icons/closed.xpm new file mode 100644 index 0000000..ef05ae2 --- /dev/null +++ b/etc/icons/closed.xpm @@ -0,0 +1,23 @@ +/* XPM */ +static char * closed_xpm[] = { +"16 16 4 1", +" c None", +". c #000000000000", +"X c #FFFFE38DB6DA", +"o c #CF3CBAEA9658", +" ", +" ", +" ..... ", +" .XXXXX. ", +".XoooooX....... ", +".XooooooXXXXXXX.", +".Xooooooooooooo.", +".Xooooooooooooo.", +".Xooooooooooooo.", +".Xooooooooooooo.", +".Xooooooooooooo.", +".Xooooooooooooo.", +".Xooooooooooooo.", +" .............. ", +" ", +" "}; diff --git a/etc/icons/draft.xpm b/etc/icons/draft.xpm new file mode 100644 index 0000000..d0b02cf --- /dev/null +++ b/etc/icons/draft.xpm @@ -0,0 +1,25 @@ +/* XPM */ +static char * draft_xpm[] = { +"16 16 6 1", +" c None", +". c #000000000000", +"X c #EFBEFFFFC71B", +"o c #FFFFFFFFFFFF", +"O c #59656595C71B", +"+ c #79E7B2CAF7DE", +" ", +" ........... ..", +" .XXXXXXXXX. ..", +" .XXXXXXXXX..o.", +" .XXXXXXX.ooo.", +" .XXXXXX.oooo.", +" .......X.oooo.", +" .OOOOO.X.ooo. ", +" ........oo.o. ", +" .+++.X.oo.o. ", +" .+o+++..oo.o. ", +" .+o+++++.o.oo. ", +" .OoOOOOO...o.X.", +" .OoOOOOO.X..XX.", +" .OOOOOOO.X.XXX.", +" .......X..... "}; diff --git a/etc/icons/elmo.xpm b/etc/icons/elmo.xpm new file mode 100644 index 0000000..a3aa73d --- /dev/null +++ b/etc/icons/elmo.xpm @@ -0,0 +1,19 @@ +/* XPM */ +static char * elmo2_xpm[] = { +"18 13 3 1", +" c None", +". c #71C66DB6FFFF", +"X c #B6DAEFBEFFFF", +" .. ", +" . .. ", +" .. ... ", +" . ...... . ", +" .......... ", +" .....X.... ", +" ....XX.X.. ", +" ...X.XXX... ", +" ...XXXXXX.... ", +" ...XXXXXXX... ", +" ...XXXXXXX... ", +" ...XXXXX... ", +" ........ "}; diff --git a/etc/icons/filter.xpm b/etc/icons/filter.xpm new file mode 100644 index 0000000..3336a38 --- /dev/null +++ b/etc/icons/filter.xpm @@ -0,0 +1,34 @@ +/* XPM */ +static char * filter_xpm[] = { +"16 16 15 1", +" c None", +". c #CF3CCF3CCF3C", +"X c #E79DE79DE79D", +"o c #CF3CEFBEFFFF", +"O c #FFFF79E7A699", +"+ c #FFFF34D371C6", +"@ c #000000000000", +"# c #BEFBE79DF7DE", +"$ c #B6DADF7DF7DE", +"% c #AEBAD75CEFBE", +"& c #9E79A2899E79", +"* c #A699CF3CEFBE", +"= c #965892488617", +"- c #618565956185", +"; c #9E79C71BE79D", +" ", +" ..XX ", +" .ooooX ", +" .oOOO+o. ", +" .oO+ooO+o.@", +" .####O+##.@", +" X$$$O+$$$.@", +" X%%%%%%%%.@", +" &X**O+**.=@", +" -X;;;;.=@ ", +" --&X...=@ ", +" --&@&&&&@ ", +" --&@ @@@@ ", +" --&@ ", +" &&@ ", +" @@ "}; diff --git a/etc/icons/imap.xpm b/etc/icons/imap.xpm new file mode 100644 index 0000000..1d7794b --- /dev/null +++ b/etc/icons/imap.xpm @@ -0,0 +1,27 @@ +/* XPM */ +static char * imap_xpm[] = { +"16 16 8 1", +" c None", +". c #E79DE79DE79D", +"X c #C71BC30BC71B", +"o c #BEFBBEFBBEFB", +"O c #000000000000", +"+ c #965896589658", +"@ c #61856595CF3C", +"# c #30C230C26185", +" ", +" ..... ", +" .XoooX. ", +" .Xoooooo.....O ", +" .XoooooXXXXo+O ", +" .XooooXXXXoo+O ", +" .XooooXXXooo+O ", +" .XooXXXXXXXX+O ", +" .XoXXXXXXXXX+O ", +" .++++++++++++O ", +" OOOOOOOOOOOOOO ", +" ", +"@@@@##XXXX##@@@@", +" @@@@ ", +" @@ ", +" @@@@@ "}; diff --git a/etc/icons/internal.xpm b/etc/icons/internal.xpm new file mode 100644 index 0000000..eb78519 --- /dev/null +++ b/etc/icons/internal.xpm @@ -0,0 +1,29 @@ +/* XPM */ +static char * internal_xpm[] = { +"16 16 10 1", +" c None", +". c #000000000000", +"X c #E79DCB2B9E79", +"o c #CF3CBAEA9658", +"O c #B6DAA6998617", +"+ c #BEFBE79DF7DE", +"@ c #FFFFFFFFFFFF", +"# c #CF3CCF3CCF3C", +"$ c #51445144FFFF", +"% c #9E79A2899E79", +" ", +" ", +" .... ", +" .XXXX. ", +" .XooooX...... ", +" .Xooo...XXXXO. ", +" .Xoo.+++.oooO. ", +" .Xo.+@@++.ooO. ", +" .Xo.+@@++.ooO. ", +" .Xo.+++++.ooO. ", +" .Xo#.+++.#ooO. ", +" .Xoo#...$$ooO. ", +" .OOOOOOOO$$OO. ", +" .........$$. ", +" %% ", +" "}; diff --git a/etc/icons/local.xpm b/etc/icons/local.xpm new file mode 100644 index 0000000..6f45a09 --- /dev/null +++ b/etc/icons/local.xpm @@ -0,0 +1,26 @@ +/* XPM */ +static char * local_xpm[] = { +"16 16 7 1", +" c None", +". c #000000000000", +"X c #FFFFFFFFFFFF", +"o c #CF3CD34CCF3C", +"O c #E79DE79DE79D", +"+ c #C71BC30BC71B", +"@ c #965896589658", +" ", +" ", +" ......... ", +" .XXXXXX.X. ", +" .XXXXXX.XX. ", +" .XXXXXX....o ", +" .XXXXXXooo.o ", +" .XXXXXXXXX.o ", +" .XXXXXXXXX.o ", +" .XXXXXXXXX.o ", +" OOOOOOOOOOO+++ ", +" O++++++++++@@@ ", +" O++++++++++@@@ ", +" O++++++++++@@@ ", +" .............. ", +" "}; diff --git a/etc/icons/localnews.xpm b/etc/icons/localnews.xpm new file mode 100644 index 0000000..24a3d3e --- /dev/null +++ b/etc/icons/localnews.xpm @@ -0,0 +1,24 @@ +/* XPM */ +static char * localnews_xpm[] = { +"16 16 5 1", +" c None", +". c #000000000000", +"X c #BEFBB2CA69A6", +"o c #FFFFFFFFFFFF", +"O c #EFBEE38D8617", +" ", +" ", +" ............. ", +".X.oooooooooo. ", +".X.oX.X...o.o. ", +"..X.ooooooooo. ", +".X..o..X..X.Xo. ", +" .XX.oooooo.oo. ", +" ..X.oXXXooooo. ", +" ..X.oXXX.o.o.o.", +" .X.OOOOOOOOOo.", +" ..OOOOOOOOOO. ", +" ........... ", +" ", +" ", +" "}; diff --git a/etc/icons/maildir.xpm b/etc/icons/maildir.xpm new file mode 100644 index 0000000..3905f2e --- /dev/null +++ b/etc/icons/maildir.xpm @@ -0,0 +1,26 @@ +/* XPM */ +static char * maildir_xpm[] = { +"16 16 7 1", +" c None", +". c #000000000000", +"X c #FFFFFFFFFFFF", +"o c #CF3CD34CCF3C", +"O c #DF7DD75C79E7", +"+ c #BEFBB2CA69A6", +"@ c #A6999E795965", +" ", +" ", +" ......... ", +" .XXXXXX.X. ", +" .XXXXXX.XX. ", +" .XXXXXX....o ", +" .XXXXXXooo.o ", +" .XXXXXXXXX.o ", +" .XXXXXXXXX.o ", +" .XXXXXXXXX.o ", +" OOOOOOOOOOO+++ ", +" O++++++++++@@@ ", +" O++++++++++@@@ ", +" O++++++++++@@@ ", +" .............. ", +" "}; diff --git a/etc/icons/multi.xpm b/etc/icons/multi.xpm new file mode 100644 index 0000000..f84ad4e --- /dev/null +++ b/etc/icons/multi.xpm @@ -0,0 +1,25 @@ +/* XPM */ +static char * multi_xpm[] = { +"16 16 6 1", +" c None", +". c #9E799A69FFFF", +"X c #000000000000", +"o c #FFFFEBADD75C", +"O c #EFBEFFFFC71B", +"+ c #FFFFFFFFFFFF", +" ", +" ........X ", +" .oooooooX ", +" .o......... ", +" .o.OOOOOOOX ", +" .o.O......... ", +" .o.O.+++++++X ", +" .o.O.+++++++X ", +" .o.O.+.+..++X ", +" .o.O.+++++++X ", +" XX.O.+X+X.++X ", +" .O.+++++XXX ", +" XX.+++++X+X ", +" .+++++XX ", +" XXXXXXX ", +" "}; diff --git a/etc/icons/news.xpm b/etc/icons/news.xpm new file mode 100644 index 0000000..b3d5b98 --- /dev/null +++ b/etc/icons/news.xpm @@ -0,0 +1,24 @@ +/* XPM */ +static char * news_xpm[] = { +"16 16 5 1", +" c None", +". c #000000000000", +"X c #9E799A699E79", +"o c #FFFFFFFFFFFF", +"O c #CF3CD34CCF3C", +" ", +" ", +" ............. ", +".X.oooooooooo. ", +".X.oX.X...o.o. ", +"..X.ooooooooo. ", +".X..o..X..X.Xo. ", +" .XX.oooooo.oo. ", +" ..X.oXXXooooo. ", +" ..X.oXXX.o.o.o.", +" .X.OOOOOOOOOo.", +" ..OOOOOOOOOO. ", +" ........... ", +" ", +" ", +" "}; diff --git a/etc/icons/opened.xpm b/etc/icons/opened.xpm new file mode 100644 index 0000000..631e9ad --- /dev/null +++ b/etc/icons/opened.xpm @@ -0,0 +1,24 @@ +/* XPM */ +static char * opened_xpm[] = { +"16 16 5 1", +" c None", +". c #000000000000", +"X c #9E798E3869A6", +"o c #FFFFE38DB6DA", +"O c #CF3CBAEA9658", +" ", +" ", +" .... ", +" .XXXX. ", +" ....XX....... ", +" .oooo.XXXXXXXX.", +".oOOOOo......XX.", +".oOOOOOoooooo.X.", +" .oOOOOOOOOOO.X.", +" .oOOOOOOOOOOO..", +" .oOOOOOOOOOOO..", +" .oOOOOOOOOOOO.", +" .oOOOOOOOOOOO.", +" ............ ", +" ", +" "}; diff --git a/etc/icons/pipe.xpm b/etc/icons/pipe.xpm new file mode 100644 index 0000000..628be44 --- /dev/null +++ b/etc/icons/pipe.xpm @@ -0,0 +1,28 @@ +/* XPM */ +static char * pipe_xpm[] = { +"16 16 9 1", +" c None", +". c #9E799E79FFFF", +"X c #51445144FFFF", +"o c #2081208169A6", +"O c #00000000FFFF", +"+ c #D75CD75CD75C", +"@ c #FFFF00000000", +"# c #FFFFFFFFFFFF", +"$ c #A699A289A699", +" ", +" ", +" .XXXo ", +" .XXXo ", +" .XXXo ", +"O+@+O.XXXo@+O+@ ", +"+####.XXXo####+$", +"@##.XXXXXXXo##O$", +"+###.XXXXXo###+$", +"O####.XXXo####@$", +"+#####.Xo#####+$", +"@######o######O$", +"+#############+$", +"O+@+O+@+O+@+O+@$", +" $$$$$$$$$$$$$$$", +" "}; diff --git a/etc/icons/plugged.xpm b/etc/icons/plugged.xpm new file mode 100644 index 0000000..03e25df --- /dev/null +++ b/etc/icons/plugged.xpm @@ -0,0 +1,28 @@ +/* XPM */ +static char *plugged[] = { +"32 16 8 1", +" c None", +". c #a6caf0", +"# c #8fa5cf", +"a c #717171", +"b c #5d5d97", +"c c #8488ca", +"d c #9f9f9f", +"e c #7f8080", +" ", +" ", +" ... ", +" .ccb.... ", +" accb####. ", +" .accb#####.. ", +" eeeeeeeeaccb#####.eeeeeeee ", +" dddddddcaccb#####.dedddddd ", +" dddddddcaccb#####.dedddddd ", +" eeeeeeeeaccb#####.eeeeeeee ", +" aaccb####aaa ", +" accbaaaaa ", +" aaaaaaaa ", +" aaa ", +" ", +" " +}; diff --git a/etc/icons/pop.xpm b/etc/icons/pop.xpm new file mode 100644 index 0000000..52d6820 --- /dev/null +++ b/etc/icons/pop.xpm @@ -0,0 +1,26 @@ +/* XPM */ +static char * pop_xpm[] = { +"16 16 7 1", +" c None", +". c #DF7DD75C79E7", +"X c #BEFBB2CA69A6", +"o c #000000000000", +"O c #A6999E795965", +"+ c #61856595CF3C", +"@ c #30C230C26185", +" ", +" ..... ", +" .XXXXX. ", +" .XXXXXXX.....o ", +" .XXXXXXXXXXXOo ", +" .XXXXXXXXXXXOo ", +" .XXXXXXXXXXXOo ", +" .XXXXXXXXXXXOo ", +" .XXXXXXXXXXXOo ", +" .OOOOOOOOOOOOo ", +" oooooooooooooo ", +" ", +"++++@@....@@++++", +" ++++ ", +" ++ ", +" +++++ "}; diff --git a/etc/icons/queue.xpm b/etc/icons/queue.xpm new file mode 100644 index 0000000..bfb7711 --- /dev/null +++ b/etc/icons/queue.xpm @@ -0,0 +1,27 @@ +/* XPM */ +static char * queue_xpm[] = { +"16 16 8 1", +" c None", +". c #69A68E38EFBE", +"X c #000000000000", +"o c #FFFFFFFFFFFF", +"O c #CF3CD34CCF3C", +"+ c #E79DCB2B9E79", +"@ c #CF3CBAEA9658", +"# c #9E798E3869A6", +" . ", +" ... ", +" ..... ", +" ....... ", +" ... ", +" XX...XXX ", +" Xo...oXoX ", +" Xo...oXXXO ", +" XoooooOOXO ", +" XoooooooXO ", +" XoooooooXO ", +" XoooooooXO ", +" +++++++++++@@ ", +" +@@@@@@@@@@## ", +" +@@@@@@@@@@## ", +" XXXXXXXXXXXXX "}; diff --git a/etc/icons/trash-e.xpm b/etc/icons/trash-e.xpm new file mode 100644 index 0000000..6cb4069 --- /dev/null +++ b/etc/icons/trash-e.xpm @@ -0,0 +1,24 @@ +/* XPM */ +static char * trash_xpm[] = { +"16 16 5 1", +" c None", +". c #000000000000", +"X c #BEFBBEFBBEFB", +"o c #E79DE79DE79D", +"O c #71C671C671C6", +" ", +" ....... ", +" .XXXXXXX. ", +" .XXXXXXXXX. ", +" ..XXXXXXX.. ", +" .o.......O. ", +" .oXoXXXOXO. ", +" .oXoXXXOXO. ", +" .oXoXXXOXO. ", +" .oXoXXXOXO. ", +" .oXoXXXOXO. ", +" .oXoXXXOXO. ", +" .oXoXXXOXO. ", +" .XoXXXOX. ", +" ....... ", +" "}; diff --git a/etc/icons/trash.xpm b/etc/icons/trash.xpm new file mode 100644 index 0000000..f1cdc59 --- /dev/null +++ b/etc/icons/trash.xpm @@ -0,0 +1,25 @@ +/* XPM */ +static char * trash_xpm[] = { +"16 16 6 1", +" c None", +". c #000000000000", +"X c #BEFBBEFBBEFB", +"o c #F7DEF7DEF7DE", +"O c #E79DE79DE79D", +"+ c #71C671C671C6", +" ...... ", +" .XXXXXX.. ", +" .XXXXXXX. ", +" .o.....XXX. ", +" ..ooooo.... ", +" .O.......+. ", +" .OXOXXX+X+. ", +" .OXOXXX+X+. ", +" .OXOXXX+X+. ", +" .OXOXXX+X+. ", +" .OXOXXX+X+. ", +" .OXOXXX+X+. ", +" .OXOXXX+X+. ", +" .XOXXX+X. ", +" ....... ", +" "}; diff --git a/etc/icons/unplugged.xpm b/etc/icons/unplugged.xpm new file mode 100644 index 0000000..b690c87 --- /dev/null +++ b/etc/icons/unplugged.xpm @@ -0,0 +1,28 @@ +/* XPM */ +static char * unplugged_xpm[] = { +"32 16 9 1", +" s None c None", +". c tomato", +"X c #a6caf0", +"o c #8488ca", +"O c #5d5d97", +"+ c #8fa5cf", +"@ c #717171", +"# c #7f8080", +"$ c #9f9f9f", +" ", +" ", +" XXX...... ", +" ... ... ", +" ..O ....X ", +" ..oO ...+..XX ", +" ######.ooO ...+++.X##### ", +" $$$$$o.ooO ...@+++.X$#$$$ ", +" $$$$$o.ooO ... @+++.X$#$$$ ", +" ######.ooO... @+++.X##### ", +" ..o... @++..@@ ", +" .... @@..@ ", +" ... ...@ ", +" ...... ", +" ", +" "}; diff --git a/etc/icons/wl-draft-insert-signature-up.xpm b/etc/icons/wl-draft-insert-signature-up.xpm new file mode 100644 index 0000000..ca38e48 --- /dev/null +++ b/etc/icons/wl-draft-insert-signature-up.xpm @@ -0,0 +1,38 @@ +/* XPM */ +static char * wl_draft_insert_signature_up_xpm[] = { +"32 32 3 1", +" c #BEFBBEFBBEFB s backgroundToolBarColor", +". c #000000000000", +"X c #FFFFFFFFFFFF", +" . ", +" .. ", +" .X. ", +" .X. ", +" .XX. ", +" ..XXX. ", +" .XXXX. ", +" .XXXX. ", +" .XXXX. ", +" .XXXXX. ", +" .XX.XX. ", +" .XX.X. ", +" .XX.X. ", +" .X.XX. ", +" ..X. ", +" .. .. ", +" . . ... . ", +" . . . . . . ", +" . .... ... . . ", +" ... ... ... .... ", +" .. .. ... ", +" ", +" ", +" ", +" . ", +" ... ", +" . . ... ... ", +" ... . . . . . ", +" . . . . . . ", +" . . ... . . ", +" ... . . . . ", +" .. "}; diff --git a/etc/icons/wl-draft-kill-up.xpm b/etc/icons/wl-draft-kill-up.xpm new file mode 100644 index 0000000..59f7a90 --- /dev/null +++ b/etc/icons/wl-draft-kill-up.xpm @@ -0,0 +1,43 @@ +/* XPM */ +static char * wl_summary_delete_up_xpm[] = { +"32 32 8 1", +" c #BEFBBEFBBEFB s backgroundToolBarColor", +". c #000000000000", +"X c #E79DCB2B9E79", +"o c #69A68E38EFBE", +"O c #CF3CBAEA9658", +"+ c #FFFFFFFFFFFF", +"@ c #B6DAA6998617", +"# c #965896589658", +" ", +" .... ", +" .XXXX.. ", +" o .XOOOXX.. ", +" oo ..XOOOOOOO.. ", +" ooooooo .++.XOOOOOOOO. ", +" oooooooo .. ..@@@OOOO@. ", +" ooooooooo.+.++...@@@@@. ", +" oooooooo .++..++...... ", +" ooooooo ...++.+.+#... ", +" oo .XO.......@@. ", +" o .XOXOOO@O@@@. ", +" .XOXOOO@O@@@. ", +" .XOXOOO@O@@@. ", +" .XOXOOO@O@@@. ", +" .XOXOOO@O@@@. ", +" .XOXOOO@O@@@. ", +" .XOXOOO@O@@@. ", +" .XOXOOO@O@@@. ", +" .XOXOOO@O@@@. ", +" .XOXOOO@O@@@.## ", +" ..XOOO@O@..#### ", +" .......##### ", +" ######### ", +" . . ", +" .... . . ", +" . . . . . ... . ", +" . . . . . . . . . . ", +" . . ... . ... . ... ", +" . . . . . . . ", +" .... .. . .. . .. ", +" "}; diff --git a/etc/icons/wl-draft-send-from-toolbar-down.xpm b/etc/icons/wl-draft-send-from-toolbar-down.xpm new file mode 100644 index 0000000..07fab96 --- /dev/null +++ b/etc/icons/wl-draft-send-from-toolbar-down.xpm @@ -0,0 +1,42 @@ +/* XPM */ +static char * wl_draft_send_and_exit_down_xpm[] = { +"32 32 7 1", +" c #BEFBBEFBBEFB s backgroundToolBarColor", +". c #000000000000", +"X c #618596586185", +"o c #0000FFFFFFFF", +"O c #FFFFFFFF0000", +"+ c #FFFFE38DA699", +"@ c #9E799A699E79", +" ", +" ", +" ", +" ...... ... ", +" .XXXXX... .oo. ", +" .XXXXXXXX. ... ", +" .XXOXXXX. . ", +" .X....XX. ", +" .......... .. ", +" ........... .oo. ", +" .++.+.++. . .. ", +" .++.+.++. ", +" .++.+.++. ", +" .+++++++. ", +" .+++++. ", +" ....... ", +" .X.XXXX.@@@@@@ ", +" .XXX.XXXX.@@@@@@ ", +" .XXXX.XXX.@@@@@ ", +" .XXXXX.....@@@ ", +" .XXXXXX....@@ ", +" ...........@ ", +" .... ", +" ", +" . ", +" ... . ", +" . . ... ... ", +" ... . . . . . . ", +" . ... . . . . ", +" . . . . . . ", +" ... .. . . ... ", +" "}; diff --git a/etc/icons/wl-draft-send-from-toolbar-up.xpm b/etc/icons/wl-draft-send-from-toolbar-up.xpm new file mode 100644 index 0000000..0455911 --- /dev/null +++ b/etc/icons/wl-draft-send-from-toolbar-up.xpm @@ -0,0 +1,41 @@ +/* XPM */ +static char * wl_draft_send_and_exit_up_xpm[] = { +"32 32 6 1", +" c #BEFBBEFBBEFB s backgroundToolBarColor", +". c #000000000000", +"X c #618596586185", +"o c #FFFFFFFF0000", +"O c #FFFFE38DA699", +"+ c #9E799A699E79", +" ", +" ", +" ", +" ...... ", +" .XXXXX... ", +" .XXXXXXXX. ", +" .XXoXXXX. ", +" .X....XX. ", +" .......... ", +" ........... ", +" .OO.O.OO. ", +" .OO.O.OO. ", +" .OO.O.OO. ", +" .OOOOOOO. ", +" .OOOOO. ", +" ....... ", +" .X.XXXX.++++++ ", +" .XXX.XXXX.++++++ ", +" .XXXX.XXX.+++++ ", +" .XXXXX.....+++ ", +" .XXXXXX....++ ", +" ...........+ ", +" .... ", +" ", +" . ", +" ... . ", +" . . ... ... ", +" ... . . . . . . ", +" . ... . . . . ", +" . . . . . . ", +" ... .. . . ... ", +" "}; diff --git a/etc/icons/wl-draft-up.xpm b/etc/icons/wl-draft-up.xpm new file mode 100644 index 0000000..783bcea --- /dev/null +++ b/etc/icons/wl-draft-up.xpm @@ -0,0 +1,42 @@ +/* XPM */ +static char * wl_draft_up_xpm[] = { +"32 32 7 1", +" c #BEFBBEFBBEFB s backgroundToolBarColor", +". c #000000000000", +"X c #EFBEFFFFC71B", +"o c #FFFFFFFFFFFF", +"O c #9E799A699E79", +"+ c #59656595C71B", +"@ c #79E7B2CAF7DE", +" ", +" ............... . ", +" .XXXXXXXXXXXXX. .. ", +" .XXXXXXXXXXXX..o. ", +" .XXXXXXXXXXX..o. ", +" .XXXXXXXXXXX.oo. ", +" .XXXXXXXXXX..ooo. ", +" .XXXXXXXXX.oooo. ", +" .XXXXXXXX.oooo. ", +" .XXXXXXXX.oooo. ", +" .XXXXXXX.ooooo. ", +" .XXXXXX.oo.oo.OOOOOO ", +" .XXXXXX.oo.o.X.OOOOO ", +" .XXXXXX.oo.o.X.OOO ", +" .......XXXo.oo.XX.OO ", +" .+++++.XXX..o.XXX.O ", +" .......XXXX..XXXX.O OOOO ", +" .@@@.XXXXX.XXXX.OOOOO ", +" .@o@@@.XXXX.XXX.OOOOOO ", +" .@o@@@@@........OOOOO ", +" .+o+++++. . OOOOO ", +" .+o+++++.OOOOOOO ", +" .+++++++.OO ", +" .......OOO ", +" OOOOOOOOO ", +" . . ", +" .. . . . . . ", +" . . . . . . . . ", +" . . . ... . . . ", +" . .. . . . ", +" . . .. . . ", +" "}; diff --git a/etc/icons/wl-draft-yank-original-up.xpm b/etc/icons/wl-draft-yank-original-up.xpm new file mode 100644 index 0000000..a2df68d --- /dev/null +++ b/etc/icons/wl-draft-yank-original-up.xpm @@ -0,0 +1,42 @@ +/* XPM */ +static char * wl_draft_yank_original_up_xpm[] = { +"32 32 7 1", +" c #BEFBBEFBBEFB s backgroundToolBarColor", +". c #000000000000", +"X c #EFBEFFFFC71B", +"o c #FFFFFFFFFFFF", +"O c #9E799A699E79", +"+ c #59656595C71B", +"@ c #79E7B2CAF7DE", +" ", +" ............... .", +" .XXXXXXXXXXXXX. ..", +" .XXXXXXXXXXXX..o.", +" ..............XOXOOOXXXXX..o. ", +" .oooooooooooo.XXXXXXXXXXX.oo. ", +" .o++o ooo.XXOXOOXXXX..ooo. ", +" .o++oooooooo.XXXXXXXXX.oooo. ", +" .oooo ooo.XXXXXXXX.oooo. ", +" .ooooooooooo.XXXXXXXX.oooo. ", +" .ooooooooooo.XXXXXXX.ooooo. ", +" .oooooooooooo.XXXXXX.oo.oo.OOO", +" .oooooooooooo.XXXXXX.oo.o.X.OO", +" .oooooooooooo.XXXXXX.oo.o.X.OO", +" ..................XXXo.oo.XX.O", +" OOOOOOOOOO.+++++.XXX..o.XXX.O", +" OOOOOOOOOO.......XXXX..XXXX.O", +" .@@@.XXXXX.XXXX.OO", +" .@o@@@.XXXX.XXX.OOO", +" .@o@@@@@........OOOO", +" .+o+++++. . OOOOO ", +" .+o+++++.OOOOOOO ", +" .+++++++.OO ", +" .......OOO ", +" . ", +" .. . . ", +" . . .. ... . . ", +" . . . . . .. ", +" .. ... . . .. ", +" . . . . . . . ", +" .. .. .. . . . ", +" "}; diff --git a/etc/icons/wl-exit-up.xpm b/etc/icons/wl-exit-up.xpm new file mode 100644 index 0000000..7eb9182 --- /dev/null +++ b/etc/icons/wl-exit-up.xpm @@ -0,0 +1,42 @@ +/* XPM */ +static char * wl_folder_quit_up_xpm[] = { +"32 32 7 1", +" c #CF3CCF3CCF3C s backgroundToolBarColor", +". c #000000000000", +"X c #FFFFE38DB6DA", +"o c #CF3CBAEA9658", +"O c #AEBAB2CAAEBA", +"+ c #B6DA965869A6", +"@ c #69A68E38EFBE", +" ", +" ", +" ", +" ........... ", +" .XXooooooo.OO ", +" .X.......o.OO ", +" .o.++++X.o.OO ", +" .o.+oooX.o.OO ", +" @ .o.+oooX.o.OO ", +" @@ .o.+oooX.o.OO ", +" @@@@@@@@@ .o.XXXXX.o.OO ", +" @@@@@@@@@@ .o.......o.OO ", +" @@@@@@@@@@@.XXooooooo.OO ", +" @@@@@@@@@@O.XXooooooo.OO ", +" @@@@@@@@@OO.o.......o.OO ", +" OOOOOO@@OO .o.++++X.o.OO ", +" OOOOOO@OO .o.+oooX.o.OO ", +" OO .o.+oooX.o.OO ", +" O .o.+oooX.o.OO ", +" O .o.XXXXX.o.OO ", +" .o.......o.OO ", +" .ooooooooo.OO ", +" ...........OO ", +" OOOOOOOOOOOO ", +" . . ", +" .... . ", +" . . . . ... ", +" ... . . . . ", +" . .. . . ", +" . . . . . ", +" .... . . . . ", +" "}; diff --git a/etc/icons/wl-folder-check-current-entity-up.xpm b/etc/icons/wl-folder-check-current-entity-up.xpm new file mode 100644 index 0000000..5e852dd --- /dev/null +++ b/etc/icons/wl-folder-check-current-entity-up.xpm @@ -0,0 +1,43 @@ +/* XPM */ +static char * wl_folder_check_entity_up_xpm[] = { +"32 32 8 1", +" c #CF3CCF3CCF3C s backgroundToolBarColor", +". c #000000000000", +"X c #FFFFE38DB6DA", +"o c #E79DCB2B9E79", +"O c #B6DAA6998617", +"+ c #CF3CBAEA9658", +"@ c #BEFB492471C6", +"# c #AEBAAAAAAEBA", +" ", +" ", +" ", +" ............ ", +" ...XXXXXXXXXXXX... ", +" .XXXXXXXXXXXXXXXXXX. ", +" .XXXXXXXXXXXXXXXXXX. ", +" ....XXXXXXXXXXXX.... ", +" .ooo............OOO. ", +" .ooo++++++++++++OOO. ", +" .ooo++++++++++++OOO. ", +" .ooo++++@@@@@@++OOO. ", +" .ooo+++@@@@@@@@+OOO. ", +" .ooo+++@@@++@@@+OOO. ", +" .ooo+++@@@++@@@+OOO. ", +" .ooo+++++++@@@++OOO. ", +" .ooo++++++@@@@+++OO. ", +" #...++++++@@@+++...### ", +" ####.....@@@....####### ", +" ########@@@############ ", +" #####@@@########### ", +" ############# ", +" @@@# ", +" @@@# ", +" . @@@# . ", +" ... . . ", +" . . ... . .. . . ", +" . . . . . . .. ", +" . . . ... . .. ", +" . . . . . . . . ", +" ... . . .. .. . . ", +" "}; diff --git a/etc/icons/wl-folder-empty-trash-up.xpm b/etc/icons/wl-folder-empty-trash-up.xpm new file mode 100644 index 0000000..942165e --- /dev/null +++ b/etc/icons/wl-folder-empty-trash-up.xpm @@ -0,0 +1,42 @@ +/* XPM */ +static char * wl_folder_empty_trash_up_xpm[] = { +"32 32 7 1", +" c #BEFBBEFBBEFB s backgroundToolBarColor", +". c #000000000000", +"X c #E79DCB2B9E79", +"o c #CF3CBAEA9658", +"O c #B6DAA6998617", +"+ c #FFFFFFFFFFFF", +"@ c #965896589658", +" ", +" .... ", +" .XXXX.. ", +" .XoooXX.. ", +" .. .Xooooooo.. ", +" . .Xoooooooo. ", +" . ..XXXooooO. ", +" . .OO...OOOOO. ", +" .OOOOOO...... ", +" ... ...OOOOOOO... ", +" .+++. .Xo.......OO. ", +" . ++.. .XoXoooOoOOO. ", +" . +.+. .XoXoooOoOOO. ", +" .. . .XoXoooOoOOO. ", +" . .XoXoooOoOOO. ", +" .XoXoooOoOOO. ", +" .XoXoooOoOOO. ", +" .XoXoooOoOOO. ", +" .XoXoooOoOOO. ", +" @@ .XoXoooOoOOO. ", +" @@@@@ .XoXoooOoOOO.@@ ", +" @@@ ..XoooOoO..@@@@ ", +" .......@@@@@ ", +" @@@@@@@@@ ", +" . ", +" .... . ", +" . .... ... .... . ", +" ... . . . . . . . . ", +" . . . . . . . . . ", +" . . . . . . . .. ", +" .... . . . ... . . ", +" . . "}; diff --git a/etc/icons/wl-folder-jump-to-current-entity-no-sync-up.xpm b/etc/icons/wl-folder-jump-to-current-entity-no-sync-up.xpm new file mode 100644 index 0000000..b5f012c --- /dev/null +++ b/etc/icons/wl-folder-jump-to-current-entity-no-sync-up.xpm @@ -0,0 +1,41 @@ +/* XPM */ +static char * wl_folder_jump_to_current_entity_up_xpm[] = { +"32 32 6 1", +" c #BEFBBEFBBEFB s backgroundToolBarColor", +". c #69A68E38EFBE", +"X c #000000000000", +"o c #9E798E3869A6", +"O c #FFFFE38DB6DA", +"+ c #CF3CBAEA9658", +" ", +" ..... ", +" ..... ", +" ..... ", +" ......... ", +" XXXXXX....... ", +" XooooooX..... ", +" XXXXXXoooX...XXXXX ", +" XOOOOOOXoooo.ooooooX ", +" XO++++++OXXXXXXXXXooX ", +" XO+++++++OOOOOOOOOXoX ", +" XO+++++++++++++++XoX ", +" XO+++++++++++++++XoX ", +" XO++++++++++++++++XX ", +" XO+++++++++++++++XX ", +" XO+++++++++++++++XX ", +" XO++++++++++++++++X ", +" XO+++++++++++++++X ", +" XO+++++++++++++++X ", +" XO+++++++++++++++X ", +" XXXXXXXXXXXXXXXXX ", +" ", +" ", +" ", +" X ", +" XXXX X ", +" X XXX XXX X X X ", +" XXX X X X X X XX ", +" X X X X XXX X ", +" X X X X X X ", +" XXXX X X X XX X ", +" "}; diff --git a/etc/icons/wl-folder-jump-to-current-entity-up.xpm b/etc/icons/wl-folder-jump-to-current-entity-up.xpm new file mode 100644 index 0000000..b5f012c --- /dev/null +++ b/etc/icons/wl-folder-jump-to-current-entity-up.xpm @@ -0,0 +1,41 @@ +/* XPM */ +static char * wl_folder_jump_to_current_entity_up_xpm[] = { +"32 32 6 1", +" c #BEFBBEFBBEFB s backgroundToolBarColor", +". c #69A68E38EFBE", +"X c #000000000000", +"o c #9E798E3869A6", +"O c #FFFFE38DB6DA", +"+ c #CF3CBAEA9658", +" ", +" ..... ", +" ..... ", +" ..... ", +" ......... ", +" XXXXXX....... ", +" XooooooX..... ", +" XXXXXXoooX...XXXXX ", +" XOOOOOOXoooo.ooooooX ", +" XO++++++OXXXXXXXXXooX ", +" XO+++++++OOOOOOOOOXoX ", +" XO+++++++++++++++XoX ", +" XO+++++++++++++++XoX ", +" XO++++++++++++++++XX ", +" XO+++++++++++++++XX ", +" XO+++++++++++++++XX ", +" XO++++++++++++++++X ", +" XO+++++++++++++++X ", +" XO+++++++++++++++X ", +" XO+++++++++++++++X ", +" XXXXXXXXXXXXXXXXX ", +" ", +" ", +" ", +" X ", +" XXXX X ", +" X XXX XXX X X X ", +" XXX X X X X X XX ", +" X X X X XXX X ", +" X X X X X X ", +" XXXX X X X XX X ", +" "}; diff --git a/etc/icons/wl-folder-next-entity-up.xpm b/etc/icons/wl-folder-next-entity-up.xpm new file mode 100644 index 0000000..b4bd524 --- /dev/null +++ b/etc/icons/wl-folder-next-entity-up.xpm @@ -0,0 +1,53 @@ +/* XPM */ +static char * wl_folder_next_unsync_up_xpm[] = { +"32 32 18 1", +" c #BEFBBEFBBEFB s backgroundToolBarColor", +". c #000000000000", +"X c #8E38C30BFFFF", +"o c #59656595C71B", +"O c #965896589658", +"+ c #596569A6C71B", +"@ c #59656DB6CF3C", +"# c #596571C6CF3C", +"$ c #596575D6CF3C", +"% c #618579E7D75C", +"& c #61857DF7D75C", +"* c #61857DF7DF7D", +"= c #61858207DF7D", +"- c #69A68A28E79D", +"; c #61858617E79D", +": c #69A68E38EFBE", +"> c #69A69248EFBE", +", c #69A69658F7DE", +" ", +" ", +" ", +" ", +" ..... ", +" .Xoo.O ", +" .Xoo.O ", +" .X++.O ", +" .X@@.O ", +" .X##.O ", +" .X$$.O ", +" .X%%.O ", +" .X&&.O ", +" .X**.O ", +" ......X==...... ", +" .X-;;;;;;;;;.OO ", +" .X--------.OO ", +" .X::::::.OO ", +" .X>>>>.OO ", +" .X,,.OO ", +" .X.OO ", +" .OO ", +" OO ", +" ", +" . ", +" . . . ", +" .. . . . . ... ", +" . . . . . . . . ", +" . . . ... .. . ", +" . .. . . . . ", +" . . .. . . . ", +" "}; diff --git a/etc/icons/wl-folder-prev-entity-up.xpm b/etc/icons/wl-folder-prev-entity-up.xpm new file mode 100644 index 0000000..0d1895c --- /dev/null +++ b/etc/icons/wl-folder-prev-entity-up.xpm @@ -0,0 +1,53 @@ +/* XPM */ +static char * wl_folder_previous_unsync_up_xpm[] = { +"32 32 18 1", +" c #BEFBBEFBBEFB s backgroundToolBarColor", +". c #000000000000", +"X c #8E38C30BFFFF", +"o c #69A69658F7DE", +"O c #69A69248EFBE", +"+ c #69A68E38EFBE", +"@ c #69A68A28E79D", +"# c #61858617E79D", +"$ c #61858207DF7D", +"% c #965896589658", +"& c #61857DF7DF7D", +"* c #61857DF7D75C", +"= c #618579E7D75C", +"- c #596575D6CF3C", +"; c #596571C6CF3C", +": c #59656DB6CF3C", +"> c #596569A6C71B", +", c #59656595C71B", +" ", +" ", +" ", +" ", +" . ", +" .X. ", +" .Xoo. ", +" .XOOOO. ", +" .X++++++. ", +" .X@@@@@@@@. ", +" .X@#########. ", +" ......X$$...... ", +" %%%%.X&&.%%%%% ", +" .X**.% ", +" .X==.% ", +" .X--.% ", +" .X;;.% ", +" .X::.% ", +" .X>>.% ", +" .X,,.% ", +" .X,,.% ", +" .....% ", +" %%%%% ", +" ", +" ", +" ... ", +" . . . . . . . ", +" . . .. . . . . ", +" ... . ... . . ", +" . . . . . ", +" . . .. . ", +" "}; diff --git a/etc/icons/wl-folder-read-up.xpm b/etc/icons/wl-folder-read-up.xpm new file mode 100644 index 0000000..1277854 --- /dev/null +++ b/etc/icons/wl-folder-read-up.xpm @@ -0,0 +1,55 @@ +/* XPM */ +static char * wl_folder_jump_to_current_entity_up_xpm[] = { +"32 32 20 1", +" c #BEFBBEFBBEFB s backgroundToolBarColor", +". c #000000000000", +"X c #8E38C30BFFFF", +"o c #8617BEFBF7DE", +"O c #8617BAEAF7DE", +"+ c #8617B6DAF7DE", +"@ c #FFFFFFFFFFFF", +"# c #79E7AEBAEFBE", +"$ c #79E7AEBAF7DE", +"% c #79E7B2CAF7DE", +"& c #79E7A699EFBE", +"* c #79E7AAAAEFBE", +"= c #71C6A289EFBE", +"- c #71C69E79EFBE", +"; c #71C69A69E79D", +": c #69A69658E79D", +"> c #69A69248E79D", +", c #69A68A28E79D", +"< c #965896589658", +"1 c #AEBAAEBAAEBA", +" ", +" ", +" .... ", +" ..XXXX.. ", +" .XoO+++Oo. ", +" .Xo+@@#$%+o. ", +" .Xo+$@@&&*$+o. ", +" .XO%*=-;-=*%O. ", +" .X+$&-:>:-&$+. ", +" .X+#&;>,>;&#+. ", +" ..X$&-:>:-&$.. ", +" .<.%*=-;-=*.<. ", +" .1..*&&&..1.< ", +" .@@....11.<< ", +" ..@@@1..<< ", +" <.....<<< ", +" <..<<<<<< ", +" <..<<<< ", +" <..<< ", +" <..< ", +" <..<< ", +" @@.< ", +" <<<< ", +" <<<< ", +" < . ", +" ... . ", +" . . . .. ... ", +" . . . . . . . ", +" ... ... ... . . ", +" . . . . . . . ", +" . . .. .. . ... ", +" "}; diff --git a/etc/icons/wl-folder-select-entity-up.xpm b/etc/icons/wl-folder-select-entity-up.xpm new file mode 100644 index 0000000..2a4cd19 --- /dev/null +++ b/etc/icons/wl-folder-select-entity-up.xpm @@ -0,0 +1,55 @@ +/* XPM */ +static char * wl_folder_select_entity_up_xpm[] = { +"32 32 20 1", +" c #BEFBBEFBBEFB", +". c #000000000000", +"X c #8E38C30BFFFF", +"o c #8617BEFBF7DE", +"O c #8617BAEAF7DE", +"+ c #8617B6DAF7DE", +"@ c #FFFFFFFFFFFF", +"# c #79E7AEBAEFBE", +"$ c #79E7AEBAF7DE", +"% c #79E7B2CAF7DE", +"& c #79E7A699EFBE", +"* c #79E7AAAAEFBE", +"= c #71C6A289EFBE", +"- c #71C69E79EFBE", +"; c #71C69A69E79D", +": c #69A69658E79D", +"> c #69A69248E79D", +", c #69A68A28E79D", +"< c #965896589658", +"1 c #AEBAAEBAAEBA", +" ", +" ", +" .... ", +" ..XXXX.. ", +" .XoO+++Oo. ", +" .Xo+@@#$%+o. ", +" .Xo+$@@&&*$+o. ", +" .XO%*=-;-=*%O. ", +" .X+$&-:>:-&$+. ", +" .X+#&;>,>;&#+. ", +" ..X$&-:>:-&$.. ", +" .<.%*=-;-=*.<. ", +" .1..*&&&..1.< ", +" .@@....11.<< ", +" ..@@@1..<< ", +" <.....<<< ", +" <..<<<<<< ", +" <..<<<< ", +" <..<< ", +" <..< ", +" <..<< ", +" @@.< ", +" <<<< ", +" <<<< ", +" < ", +" .... ", +" . .. .. .... ", +" . . . . . . . . ", +" . . . . . . . . ", +" . . . . . . . . ", +" .... .. .. . . . ", +" "}; diff --git a/etc/icons/wl-folder-sync-current-entity-up.xpm b/etc/icons/wl-folder-sync-current-entity-up.xpm new file mode 100644 index 0000000..ab8002e --- /dev/null +++ b/etc/icons/wl-folder-sync-current-entity-up.xpm @@ -0,0 +1,55 @@ +/* XPM */ +static char * wl_folder_sync_current_entity_up_xpm[] = { +"32 32 20 1", +" c #CF3CCF3CCF3C s backgroundToolBarColor", +". c #000000000000", +"X c #FFFFE38DB6DA", +"o c #E79DCB2B9E79", +"O c #B6DAA6998617", +"+ c #CF3CBAEA9658", +"@ c #514471C6FFFF", +"# c #59656DB6EFBE", +"$ c #618569A6DF7D", +"% c #69A66595D75C", +"& c #79E76185C71B", +"* c #AEBAAAAAAEBA", +"= c #86175D75BEFB", +"- c #96585965AEBA", +"; c #9E7955559E79", +": c #A69951448E38", +"> c #C71BC30BC71B", +", c #AEBA4D348617", +"< c #BEFB492471C6", +"1 c #C71B492469A6", +" ", +" ", +" ", +" ............ ", +" ...XXXXXXXXXXXX... ", +" .XXXXXXXXXXXXXXXXXX. ", +" .XXXXXXXXXXXXXXXXXX. ", +" ....XXXXXXXXXXXX.... ", +" .ooo............OOO. ", +" .ooo++++++++++++OOO. ", +" .ooo++++++++++++OOO. ", +" .ooo++++++++++++OOO. ", +" .ooo+++++@@+++++OOO. ", +" .ooo++++####++++OOO. ", +" .ooo+++$$$$$$+++OOO. ", +" .ooo++%%%%%%%%++OOO. ", +" .ooo++++&&&&+++++OO. ", +" *...++++====++++...*** ", +" ****....----....******* ", +" *******;;;;************ ", +" **::::::::********* ", +" >>,,,,,,********* ", +" <<<< ", +" 11 ", +" ", +" ... ", +" . . . ... .. ", +" ... . . . . . ", +" . . . . . . ", +" . .. . . . ", +" ... . . . .. ", +" . "}; diff --git a/etc/icons/wl-folder-zoom-entity-up.xpm b/etc/icons/wl-folder-zoom-entity-up.xpm new file mode 100644 index 0000000..2688452 --- /dev/null +++ b/etc/icons/wl-folder-zoom-entity-up.xpm @@ -0,0 +1,55 @@ +/* XPM */ +static char * wl_folder_select_entity_up_xpm[] = { +"32 32 20 1", +" c #BEFBBEFBBEFB s backgroundToolBarColor", +". c #000000000000", +"X c #8E38C30BFFFF", +"o c #8617BEFBF7DE", +"O c #8617BAEAF7DE", +"+ c #8617B6DAF7DE", +"@ c #FFFFFFFFFFFF", +"# c #79E7AEBAEFBE", +"$ c #79E7AEBAF7DE", +"% c #79E7B2CAF7DE", +"& c #79E7A699EFBE", +"* c #79E7AAAAEFBE", +"= c #71C6A289EFBE", +"- c #71C69E79EFBE", +"; c #71C69A69E79D", +": c #69A69658E79D", +"> c #69A69248E79D", +", c #69A68A28E79D", +"< c #965896589658", +"1 c #AEBAAEBAAEBA", +" ", +" ", +" .... ", +" ..XXXX.. ", +" .XoO+++Oo. ", +" .Xo+@@#$%+o. ", +" .Xo+$@@&&*$+o. ", +" .XO%*=-;-=*%O. ", +" .X+$&-:>:-&$+. ", +" .X+#&;>,>;&#+. ", +" ..X$&-:>:-&$.. ", +" .<.%*=-;-=*.<. ", +" .1..*&&&..1.< ", +" .@@....11.<< ", +" ..@@@1..<< ", +" <.....<<< ", +" <..<<<<<< ", +" <..<<<< ", +" <..<< ", +" <..< ", +" <..<< ", +" @@.< ", +" <<<< ", +" <<<< ", +" < ", +" .... ", +" . .. .. .... ", +" . . . . . . . . ", +" . . . . . . . . ", +" . . . . . . . . ", +" .... .. .. . . . ", +" "}; diff --git a/etc/icons/wl-logo.xbm b/etc/icons/wl-logo.xbm new file mode 100644 index 0000000..d0d3218 --- /dev/null +++ b/etc/icons/wl-logo.xbm @@ -0,0 +1,622 @@ +#define wl-logo_width 464 +#define wl-logo_height 160 +static char wl-logo_bits[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xa2,0xa8, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2e,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x82,0x14,0x04,0x2a,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x7a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x28,0xa1,0xa2,0x80,0x02,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x80,0x77,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x24,0x85,0x08,0x10,0x2a,0x28,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x80,0x7a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x49,0x28,0xa5,0x8a,0x80,0x82,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x6d, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x40,0x24,0x45,0x48,0x40,0x2a,0x24,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x76,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x94,0x92, + 0x10,0x85,0x2a,0x80,0x08,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb4,0x6b,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x48,0x24,0xa5,0x28, + 0x80,0x2a,0x42,0x44,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6c,0x7d,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x22,0x49,0x12,0x82,0x2a,0x80, + 0x28,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x80,0xb7,0x6b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x55,0x92,0xa4,0x54,0x00,0x25,0x02,0x54, + 0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x40,0x6d,0x7d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x94,0x08,0x09,0x11,0x82,0xaa,0x88,0x90,0x00,0x10,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xa0,0xbb,0x6b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x51,0x52,0x52,0xa4,0x28,0x00,0x22,0x44,0x24,0x21,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x68,0x6d, + 0x7d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x8a,0x8a,0x24,0x09,0x85,0xaa,0x08,0x11,0x02,0x84,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0xb7,0x6b,0x00, + 0x00,0x00,0x00,0x00,0x40,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x29,0x29, + 0x89,0xa4,0x28,0x01,0xa2,0x84,0xa8,0x10,0x01,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6f,0x6d,0x7d,0x00,0x00,0x00, + 0x00,0x00,0xa0,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0xa4,0xa4,0x50,0x12, + 0x12,0xaa,0x08,0x50,0x00,0x82,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x40,0xb5,0xdb,0x76,0x00,0x00,0x00,0x00,0x00, + 0x58,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x94,0x12,0x49,0x0a,0x49,0xa1,0x00, + 0x42,0x05,0x92,0x20,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xc0,0xdf,0xb6,0x3b,0x00,0x00,0x00,0x00,0x00,0x6a,0x35, + 0x00,0x00,0x00,0x00,0x00,0x00,0x4a,0xaa,0x92,0xa2,0x20,0x0a,0xaa,0x28,0xa0, + 0x04,0x88,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x78,0xb5,0x6d,0x3d,0x00,0x00,0x00,0x00,0x00,0xad,0x6a,0x00,0x00, + 0x00,0x00,0x00,0x40,0x25,0x49,0x48,0x14,0x95,0x50,0x01,0x82,0x0a,0xa0,0x02, + 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xd6,0x6e,0xdb,0x36,0x00,0x00,0x00,0x00,0x00,0x55,0x6b,0x00,0x00,0x00,0x00, + 0x00,0x80,0xa8,0x24,0x95,0xa2,0x68,0x0f,0xa8,0x28,0xa0,0x0a,0x28,0x11,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x7a,0xdb, + 0xbd,0x3b,0x00,0x00,0x00,0x00,0xc0,0x6a,0xd5,0x00,0x00,0x00,0x00,0x00,0x50, + 0x95,0x92,0x42,0xfc,0x1f,0xc0,0x0f,0x82,0x0a,0x20,0x01,0x24,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0xd7,0x76,0x6b,0x1d, + 0x00,0x00,0x00,0x00,0x40,0xab,0xea,0x00,0x00,0x00,0x00,0x00,0x24,0x49,0x4a, + 0xe9,0x0f,0x00,0x00,0xe0,0x28,0x90,0x04,0x90,0x60,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0xbd,0xdb,0xb6,0x1f,0x00,0x00, + 0x00,0x00,0x50,0x55,0xd5,0x00,0x00,0x00,0x00,0x00,0x90,0x24,0x29,0x7e,0x00, + 0x00,0x00,0x00,0x86,0x42,0x50,0x05,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xd7,0xd7,0xb6,0x6d,0x1d,0x00,0x00,0x00,0x00, + 0xa0,0xda,0xf6,0x00,0x00,0x00,0x00,0x00,0xaa,0xaa,0xd4,0x07,0x00,0x00,0x00, + 0x00,0x30,0x10,0x02,0xa0,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0xba,0x7a,0x6f,0xb7,0x0f,0x00,0x00,0x00,0x00,0x70,0xab, + 0x6a,0x00,0x00,0x00,0x00,0x80,0x4a,0x92,0xfa,0x00,0x00,0x00,0x00,0x00,0x00, + 0x45,0x11,0x09,0x82,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0, + 0x01,0x5e,0xdf,0xd7,0xba,0xdb,0x0e,0x00,0x00,0x00,0x00,0x58,0x55,0x75,0x00, + 0x00,0x00,0x00,0x40,0x29,0x49,0x1e,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x44, + 0x20,0x20,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xfe,0xf5, + 0x6b,0xbd,0x6d,0x6d,0x07,0x00,0x00,0x00,0x00,0x56,0xad,0x75,0x00,0x00,0x00, + 0x00,0x50,0x4a,0xd5,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0x04,0x09, + 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xab,0x5e,0xbd,0x6b, + 0xb7,0xbb,0x07,0x00,0x00,0x00,0x00,0xaa,0x55,0x75,0x00,0x00,0x00,0x00,0x48, + 0xa5,0xf4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x42,0x41,0x80,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xfe,0xeb,0x6e,0xdd,0xdb,0xed, + 0x03,0x00,0x00,0x00,0x00,0xb5,0xb6,0x3a,0x00,0x00,0x00,0x00,0xa0,0x54,0x3e, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x08,0x14,0x25,0x06,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xab,0xbe,0xf5,0x77,0xbd,0xda,0x01,0x00, + 0x00,0x00,0x80,0x56,0xd5,0x3a,0x00,0x00,0x00,0x00,0x54,0x92,0x0f,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x82,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x80,0xfe,0xeb,0xaf,0xda,0xd6,0xf7,0x00,0x00,0x00,0x00, + 0x80,0x6a,0x55,0x1d,0x00,0x00,0x00,0x00,0x95,0xca,0x03,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x28,0x92,0x28,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xab,0xbe,0xda,0x6f,0x7b,0x7d,0x00,0x00,0x00,0x00,0xa0,0xad, + 0xaa,0x1e,0x00,0x00,0x00,0x00,0x55,0xf5,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x02,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xfe,0xd7,0xbf,0xba,0xad,0x3b,0x00,0x00,0x00,0x00,0x60,0xd5,0xb6,0x0e, + 0x00,0x00,0x00,0x80,0x92,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x50,0x49,0x88,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xab, + 0xfa,0x6a,0xd7,0xd7,0x1e,0x00,0x00,0x00,0x00,0xa0,0x5a,0x55,0x0f,0x00,0x00, + 0x00,0xa0,0x54,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10, + 0x20,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x5f,0xff, + 0xbb,0x7a,0x0f,0x00,0x00,0x00,0x00,0x58,0xab,0xaa,0x07,0x00,0x00,0x00,0x90, + 0x92,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x84,0x82,0x08, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xac,0xea,0x55,0xed,0xde, + 0x07,0x00,0x00,0x00,0x00,0xa8,0xd5,0xb6,0x03,0x00,0x00,0x00,0x48,0xd5,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x08,0x18,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf4,0x7f,0xbb,0xb7,0xeb,0x01,0x00, + 0x00,0x00,0x00,0x68,0x6d,0xd5,0x01,0x00,0x00,0x00,0xa4,0xf4,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x85,0x40,0x1a,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x5c,0xd5,0x6e,0x6d,0xfd,0x00,0x00,0x00,0x00, + 0x00,0xac,0xaa,0xea,0x00,0x00,0x00,0x00,0xa8,0x7a,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x12,0x18,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xf0,0xbf,0xdb,0xbb,0x3f,0x00,0x00,0x00,0x00,0x00,0xd6, + 0x56,0x7b,0x00,0x00,0x00,0x00,0x2a,0x1d,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x41,0x00,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xb0,0xea,0xbd,0x6e,0x0f,0x00,0x00,0x00,0x00,0x00,0x5a,0xb5,0x3a, + 0x00,0x00,0x00,0x00,0x55,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x08,0x49,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xc0,0x7f,0xeb,0xf5,0x03,0x00,0x00,0x00,0x00,0x00,0x6b,0xab,0x1d,0x00,0x00, + 0x00,0x40,0xa5,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x22,0x00,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xaa, + 0x5f,0xef,0x01,0x00,0x00,0x00,0x00,0x80,0x55,0xb5,0x0e,0x00,0x00,0x00,0x40, + 0xd5,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x24, + 0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xf5,0x7a, + 0x00,0x00,0x00,0x00,0x00,0x80,0xb6,0xad,0x07,0x00,0x00,0x00,0x50,0xe9,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x00,0x36,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd4,0xaf,0x3f,0x00,0x00, + 0x00,0x00,0x00,0xc0,0x5a,0xd5,0x03,0x00,0x00,0x00,0xa0,0x7a,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x49,0x39,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0x1e,0x00,0x00,0x00,0x00, + 0x00,0x40,0xd5,0xea,0x01,0x00,0x00,0x00,0x28,0x3d,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4a,0x00,0x35,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xd4,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x54,0x07,0x00,0x00,0x00,0x00,0x00,0x70, + 0x57,0xfd,0x00,0x00,0x00,0x00,0x54,0x1d,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x10,0xa4,0x2a,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x88,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xfa,0x07,0x00,0x00,0x00,0x00,0x00,0xa0,0x6a,0x3b, + 0x00,0x00,0x00,0x00,0x54,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x40,0x41,0x75,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xa2,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xdc,0x01,0x00,0x00,0x00,0x00,0x00,0xb0,0xb5,0x1e,0x00,0x00, + 0x00,0x00,0xaa,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x08,0xa4,0x6a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x94,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xeb,0x01,0x00,0x00,0x00,0x00,0x00,0xd8,0xae,0x0f,0x00,0x00,0x00,0x00, + 0xa5,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x42, + 0x50,0x75,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc2,0x01,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xfe, + 0x00,0x00,0x00,0x00,0x00,0x00,0x54,0xd5,0x03,0x00,0x00,0x00,0x80,0xea,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x42,0x75, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x94,0x01,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x7b,0x00,0x00, + 0x00,0x00,0x00,0x00,0xa8,0xf5,0x01,0x00,0x00,0x00,0x40,0xf5,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x58,0x35,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x40,0xc8,0x01,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x3e,0x00,0x00,0x00,0x00, + 0x00,0x00,0x6e,0xed,0x00,0x00,0x00,0x00,0x40,0x75,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x52,0x35,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x80,0xd2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x1f,0x00,0x00,0x00,0x00,0x00,0x00, + 0xb4,0x76,0x00,0x00,0x00,0x00,0xa0,0x3a,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x14,0xa8,0x3a,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x20,0xc4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xd0,0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0xab,0x75, + 0x00,0x00,0x00,0x00,0x50,0x1d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x40,0x56,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x80,0xd2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18, + 0x00,0x00,0x00,0xf8,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0xdd,0x3a,0x00,0x00, + 0x00,0x00,0xa8,0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xa9,0x3a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0xc8, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x1c,0x00,0x00, + 0x00,0xa8,0x03,0x00,0x00,0x00,0x00,0x00,0x80,0x6a,0x3d,0x00,0x00,0x00,0x00, + 0x50,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x28,0xaa,0x1a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xe5,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x0c,0x00,0x00,0x00,0xf4, + 0x03,0x00,0x00,0x00,0x00,0x00,0x80,0x56,0x1b,0x00,0x00,0x00,0x00,0xac,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x55, + 0x1d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x94,0x70,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x00,0x00,0x00,0xdc,0x01,0x00, + 0x00,0x00,0x00,0x00,0x40,0xb5,0x1d,0x00,0x00,0x00,0x00,0xa4,0x03,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x55,0x1d,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x75,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0xf6,0x00,0x00,0x00,0x00, + 0x00,0x00,0xa0,0xad,0x0e,0x00,0x00,0x00,0x00,0xda,0x01,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x84,0xaa,0x0e,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x48,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x92,0x07,0x00,0x00,0x00,0x7f,0x00,0x00,0x00,0x00,0x00,0x00, + 0xd0,0xd6,0x0e,0x00,0x00,0x00,0x00,0xea,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0xaa,0x0e,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x15,0x39,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x80,0x03,0x00,0x00,0x80,0x3a,0x00,0x00,0x00,0x00,0x00,0x00,0x54,0x6b, + 0x0f,0x00,0x00,0x00,0x80,0x75,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x48,0x55,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x40,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc4, + 0x01,0x00,0x00,0x80,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x6a,0x5d,0x07,0x00, + 0x00,0x00,0x40,0x75,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x50,0x55,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x95, + 0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xe0,0x00,0x00, + 0x00,0xc0,0x1d,0x00,0x00,0x00,0x00,0x00,0x00,0xbd,0xaa,0x07,0x00,0x00,0x00, + 0x80,0x3a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xa0,0x2a,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x48,0x06,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x60, + 0x0f,0x00,0x00,0x00,0x00,0x00,0x40,0xd5,0x6d,0x03,0x00,0x00,0x00,0x40,0x1d, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x54, + 0x95,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x92,0x07,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x32,0x00,0x00,0x00,0xb0,0x0f,0x00, + 0x00,0x00,0x00,0x00,0xa0,0xaf,0xb6,0x03,0x00,0x00,0x00,0x40,0x1d,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x95,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0xc9,0x03,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x80,0x01,0x00,0x00,0x38,0x00,0x00,0x00,0xd8,0x07,0x00,0x00,0x00, + 0x00,0x00,0xd8,0x76,0xd5,0x03,0x00,0x00,0x00,0xb0,0x0e,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0xc5,0x01,0x00,0x00, + 0x00,0x00,0xa0,0x00,0x00,0x00,0xd2,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xd0,0x01,0x00,0x00,0x1d,0x00,0x00,0x00,0xe8,0x03,0x00,0x00,0x00,0x00,0x00, + 0xe8,0xab,0xdb,0x01,0x00,0x00,0x00,0x40,0x07,0x00,0x00,0x38,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x54,0xc5,0x01,0x00,0x50,0x01,0x00, + 0xa8,0x01,0x00,0x40,0xe9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc4,0x00, + 0x00,0x20,0x0e,0x00,0x00,0x00,0xb8,0x03,0x00,0x00,0x00,0x00,0x00,0xde,0x5f, + 0xd5,0x01,0x00,0x00,0x00,0xb0,0x07,0x00,0x00,0x56,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x54,0xd1,0x00,0x00,0x8a,0x0a,0x00,0xe2,0x01, + 0x00,0x50,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x08, + 0x07,0x00,0x00,0x00,0xee,0x01,0x00,0x00,0x00,0x00,0x00,0xf5,0xea,0xee,0x01, + 0x00,0x00,0x00,0x94,0x03,0x00,0x00,0xfa,0x00,0x00,0x00,0x18,0x00,0x00,0x00, + 0x00,0x00,0x40,0x15,0x55,0xe1,0x00,0x00,0x69,0x1a,0x00,0xe8,0x00,0x00,0x80, + 0x3a,0x00,0x00,0x24,0x00,0x00,0x00,0x00,0x80,0x44,0x00,0x10,0x81,0x03,0x00, + 0x00,0x00,0xfd,0x00,0x00,0x00,0x00,0x00,0xc0,0x7b,0x55,0xd5,0x00,0x00,0x00, + 0x00,0xd4,0x03,0x00,0x00,0xd6,0x01,0x00,0x00,0x6a,0x00,0x00,0x00,0x00,0x00, + 0xe8,0x0f,0xaa,0x70,0x00,0xa0,0x94,0x1a,0x00,0x6b,0x00,0x00,0x50,0x1c,0x00, + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x90,0x00,0x00,0x04,0x00,0x00,0x00,0x00, + 0xef,0x00,0x00,0x00,0x00,0x00,0xa0,0x1e,0xdd,0xb6,0x00,0x00,0x00,0x00,0xd4, + 0x01,0x00,0xff,0xed,0x01,0x00,0x80,0xf6,0x00,0x00,0x00,0x00,0x00,0xfd,0x00, + 0x55,0x74,0x00,0xa0,0x57,0x1a,0x80,0x48,0x00,0x00,0x28,0x0f,0x00,0x40,0xd5, + 0x00,0x00,0x00,0x00,0x40,0x42,0x01,0x44,0x20,0x00,0x0f,0x00,0x80,0x7a,0x00, + 0x00,0x00,0x00,0x00,0x68,0x8f,0x6a,0xdb,0x01,0x00,0x00,0x00,0xea,0x00,0xf0, + 0x7a,0xf7,0x01,0x00,0x80,0x6d,0x00,0x2c,0x00,0x00,0xc0,0x1e,0x00,0x15,0x31, + 0x00,0xc8,0xa1,0x1a,0x40,0x25,0x01,0x00,0x80,0x07,0x00,0x00,0xe0,0x00,0x00, + 0x15,0x00,0x10,0x00,0x02,0x00,0x01,0xf2,0x03,0x00,0xc0,0x7f,0x00,0x00,0x00, + 0x00,0x00,0xb4,0x07,0x5b,0xd5,0x01,0x00,0x00,0x00,0xea,0x00,0xd4,0xc7,0xed, + 0x00,0x00,0x60,0x7b,0x00,0xd7,0x00,0x00,0xb0,0x07,0x00,0x15,0x38,0x00,0x64, + 0x50,0x1d,0x20,0x95,0x02,0x00,0xd4,0x03,0x00,0x40,0x75,0x00,0x40,0x30,0x00, + 0x00,0x29,0x06,0x70,0xf0,0x7f,0x00,0x00,0xa0,0x3a,0x00,0x00,0x00,0x00,0x00, + 0xdb,0x83,0xd6,0xb6,0x01,0x00,0x00,0x00,0x75,0x00,0xff,0x40,0x7b,0x00,0x00, + 0xb0,0x7d,0xc0,0xf5,0x00,0x00,0xd4,0x03,0x80,0x4a,0x1d,0x00,0x1d,0x90,0x0e, + 0xa0,0x52,0x18,0x00,0xe0,0x01,0x00,0x20,0x70,0x00,0x00,0x3a,0x00,0x40,0x80, + 0x04,0x00,0x34,0x00,0x00,0x00,0xe0,0x3f,0x00,0x00,0x00,0x00,0x80,0xf6,0x80, + 0x6d,0x5b,0x03,0x00,0x00,0x00,0x75,0xc0,0x7a,0x80,0x5d,0x00,0x00,0xd0,0x3a, + 0x40,0xad,0x01,0x00,0xea,0x01,0x00,0x05,0x0c,0x80,0x0e,0x50,0x07,0x20,0x49, + 0x35,0x00,0x74,0x00,0x00,0x48,0x3d,0x00,0xa0,0x18,0x00,0xc0,0x04,0x0c,0x80, + 0x38,0x00,0x00,0x00,0x50,0x1d,0x00,0x00,0x00,0x00,0x80,0x7d,0xc0,0xb6,0xaa, + 0x03,0x00,0x00,0x00,0x35,0x60,0x1f,0x00,0xeb,0x01,0x00,0x6c,0x1f,0xb0,0xd6, + 0x01,0x00,0xed,0x00,0xc0,0x22,0x0e,0x40,0x0e,0xa0,0x03,0x90,0x2a,0x35,0x00, + 0x3a,0x00,0x00,0x10,0x1e,0x00,0x10,0x1e,0x00,0x20,0x40,0x08,0x00,0x18,0x00, + 0x00,0x00,0xf8,0x1f,0x00,0x00,0x00,0x00,0xf0,0x3e,0x40,0x5b,0xdb,0x06,0x00, + 0x00,0x00,0x3d,0xd8,0x1d,0x80,0x5e,0x03,0x00,0xb8,0x1d,0x68,0xdb,0x01,0x00, + 0x75,0x00,0x40,0x09,0x07,0x40,0x07,0xd4,0x01,0xc0,0xa5,0x38,0x00,0x39,0x00, + 0x00,0xa2,0x07,0x00,0x88,0x0e,0x00,0x08,0x12,0x19,0x00,0x1d,0x00,0x00,0x00, + 0x6c,0x1d,0x00,0x00,0x00,0x00,0x50,0x0f,0x40,0xed,0xad,0x06,0x00,0x00,0xc0, + 0x1a,0x74,0x0f,0x00,0xb5,0x07,0x00,0xd6,0x0e,0xb4,0xad,0x01,0x80,0x75,0x00, + 0x40,0x81,0x03,0x40,0x03,0xf5,0x00,0x04,0x94,0x1e,0x00,0x1c,0x00,0x00,0xc8, + 0x03,0x00,0xa2,0x07,0x00,0x00,0x00,0x18,0x20,0x0c,0x00,0x00,0x00,0xd8,0x0f, + 0x00,0x00,0x00,0x00,0xde,0x07,0x80,0xab,0xea,0x0e,0x00,0x00,0x40,0x1d,0xde, + 0x07,0x80,0xed,0x06,0x00,0x6d,0x0f,0x72,0xf5,0x01,0xc0,0x3a,0x00,0xa0,0xa4, + 0x03,0xa0,0x43,0x3c,0x00,0x00,0x50,0x0e,0x80,0x0e,0x00,0x00,0xe2,0x00,0x00, + 0xc4,0x01,0x00,0x00,0x90,0x1c,0x00,0x0e,0x00,0x00,0x00,0xfe,0x0e,0x00,0x00, + 0x00,0x00,0xea,0x03,0x40,0xb5,0x36,0x0b,0x00,0x00,0x80,0x0e,0x74,0x07,0x40, + 0x5c,0x0f,0x00,0xdb,0x06,0xc8,0x96,0x01,0xa0,0x36,0x00,0x50,0x81,0x01,0x90, + 0xaa,0x0f,0x00,0x00,0x80,0x07,0x00,0x0d,0x00,0x00,0x74,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x1c,0x00,0x06,0x00,0x00,0x00,0x55,0x0f,0x00,0x00,0x00,0xc0, + 0xfb,0x01,0x80,0x5d,0xdb,0x1d,0x00,0x00,0xe0,0x0e,0xdf,0x07,0x40,0xf0,0x0d, + 0x80,0xb6,0x07,0x00,0xeb,0x01,0xa0,0x3a,0x00,0xa8,0xe8,0x00,0x50,0xff,0x00, + 0x00,0x00,0xb0,0x03,0x00,0x0c,0x00,0x00,0x71,0x00,0x00,0x75,0x00,0x00,0x00, + 0x40,0x0c,0x40,0x06,0x00,0x00,0x00,0xff,0x0d,0x00,0x00,0x00,0xa0,0x76,0x00, + 0xc0,0xea,0x55,0x15,0x00,0x00,0x00,0x8f,0x75,0x07,0x20,0xa8,0x0e,0x80,0x6d, + 0x07,0x80,0xb5,0x01,0xb0,0x35,0x00,0xa6,0xe2,0x00,0xc8,0x03,0x00,0x00,0x00, + 0xc0,0x01,0x80,0x0a,0x00,0x00,0x34,0x00,0x80,0x30,0x00,0x00,0x00,0x00,0x0e, + 0x10,0x06,0x00,0x00,0x80,0xb6,0x0f,0x00,0x00,0x00,0x68,0x3f,0x00,0x40,0xaf, + 0xb6,0x3a,0x00,0x00,0xe0,0x86,0xbe,0x07,0x10,0xdc,0x0f,0x80,0xb6,0x03,0x80, + 0x5e,0x01,0x50,0x6d,0x00,0xd1,0x72,0x00,0xa8,0x01,0x00,0x00,0x00,0xe8,0x00, + 0x40,0x12,0x00,0x80,0x32,0x00,0x20,0x34,0x00,0x00,0x00,0x40,0x0e,0x00,0x04, + 0x00,0x00,0xc0,0xef,0x0e,0x00,0x00,0x00,0xdc,0x0e,0x00,0x00,0xb5,0xda,0x6d, + 0x00,0x00,0x30,0x87,0xd7,0x06,0x0c,0xb4,0x0e,0xd0,0xdb,0x03,0x00,0xd5,0x03, + 0xd4,0x6a,0x80,0xaa,0x3a,0x00,0x50,0x03,0x00,0x40,0x00,0x68,0x00,0x08,0x29, + 0x00,0x40,0x60,0x00,0x00,0x31,0x00,0x00,0x00,0x00,0x07,0x80,0x0c,0x00,0x00, + 0x80,0xba,0x1d,0x00,0x00,0x00,0xeb,0x07,0x00,0x80,0x55,0xab,0x6a,0x00,0x00, + 0xc8,0xc3,0xfa,0x0f,0x15,0x7a,0x0f,0x44,0x6d,0x07,0x80,0x6b,0x03,0x52,0xab, + 0x69,0xa9,0x1a,0x00,0xa8,0x06,0x00,0x00,0x00,0x6a,0x00,0xa0,0x04,0x00,0x80, + 0x8a,0x00,0xa8,0x24,0x00,0x08,0x09,0x00,0x03,0x20,0x10,0x00,0x00,0xe0,0xef, + 0x1f,0x00,0x00,0x40,0xdd,0x03,0x00,0x00,0xde,0xb5,0xd6,0x00,0x00,0x50,0xc3, + 0x5f,0xf5,0x0b,0xd6,0x06,0x73,0xb7,0x15,0x00,0x5d,0x43,0x59,0xad,0xaa,0xa8, + 0x2a,0x00,0x91,0x0a,0x00,0xa8,0x00,0x68,0x80,0x5a,0xaa,0x04,0x20,0x51,0x00, + 0x00,0x10,0x80,0x44,0x18,0xa0,0x03,0x08,0x01,0x00,0x08,0x60,0xbb,0x3a,0x00, + 0x00,0xa0,0xf7,0x00,0x00,0x00,0xb3,0xae,0xb5,0x01,0x00,0xd0,0xa3,0xea,0x5f, + 0x07,0xba,0xcf,0x8c,0xda,0x0e,0x80,0xaa,0xad,0x6f,0xb5,0x6a,0x51,0xab,0xaa, + 0x56,0x29,0x00,0x42,0x40,0x65,0x20,0x0e,0x21,0x49,0x24,0x04,0x85,0x4e,0x45, + 0x90,0x01,0x12,0xc0,0x01,0x00,0x10,0x00,0x07,0xd0,0xee,0x3f,0x00,0x00,0x70, + 0x7d,0x00,0x00,0x00,0xdc,0x6a,0xad,0x01,0x00,0xac,0xe1,0xbf,0xea,0x83,0xef, + 0xba,0xe7,0xaf,0x07,0x80,0x6d,0xf5,0xab,0x55,0x75,0x54,0x55,0xd5,0x53,0xa5, + 0xaa,0x3c,0x80,0xaa,0x84,0x87,0x4a,0x22,0x5d,0xa9,0x20,0x2f,0x10,0xe5,0x90, + 0x30,0xc0,0x00,0x44,0x84,0x80,0x03,0xf0,0xbf,0x6a,0x00,0x00,0xbe,0x1f,0x00, + 0x00,0x00,0x54,0xb5,0x55,0x03,0x00,0xd4,0x41,0xd5,0xff,0x81,0x5a,0xef,0x41, + 0xf5,0x03,0x00,0x56,0xeb,0xa8,0x6a,0xbb,0x68,0x55,0xd5,0x59,0x55,0x49,0x1e, + 0x20,0x49,0xd5,0x43,0x28,0x49,0x0e,0x04,0x94,0x03,0x45,0x70,0x00,0x28,0x68, + 0x00,0x10,0x00,0xe8,0x01,0xa8,0xea,0xff,0x00,0x80,0x6a,0x0f,0x00,0x00,0x00, + 0xe8,0xae,0xb6,0x06,0x00,0xe8,0xe1,0x7f,0xf5,0x80,0xed,0xfa,0x60,0xdb,0x01, + 0x00,0xeb,0x7a,0xd0,0x56,0x1d,0x50,0x55,0xf5,0x40,0x55,0x55,0x0f,0x80,0x24, + 0xe9,0x01,0x45,0x92,0x47,0xa9,0xc2,0xa1,0x10,0x3d,0xa0,0x42,0x30,0x00,0x00, + 0x11,0x71,0x00,0xf8,0x7f,0x55,0x03,0xd0,0xdf,0x03,0x00,0x00,0x00,0xb0,0xd5, + 0xaa,0x0d,0x00,0xd4,0x40,0xd5,0x3f,0x40,0x77,0x3f,0xa0,0xed,0x00,0x00,0x5d, + 0x3d,0x50,0x5b,0x0f,0xa5,0xaa,0x7a,0x50,0x95,0xaa,0x07,0x50,0x95,0x74,0x80, + 0x12,0xc9,0x03,0x22,0xf0,0x00,0x44,0x0e,0x00,0x10,0x1d,0x00,0x40,0x00,0x3c, + 0x00,0xb0,0xd5,0xff,0x1d,0x7e,0xf5,0x01,0x00,0x00,0x00,0x50,0x6d,0x6d,0x0d, + 0x00,0xea,0xc0,0xff,0x1e,0xc0,0xad,0x1f,0xc0,0x76,0x00,0x00,0xaa,0x1f,0xb0, + 0xaa,0x57,0x50,0x55,0x3d,0xa0,0x54,0xd2,0x01,0x50,0x52,0x3a,0x00,0xa8,0xe4, + 0x80,0x88,0x7a,0x40,0x81,0x07,0x20,0x42,0x0e,0x00,0x00,0x49,0x0e,0x00,0x7c, + 0x7f,0x55,0xef,0xd5,0x7e,0x00,0x00,0x00,0x00,0xc0,0xb6,0xb6,0x1a,0x00,0xf4, + 0x80,0xaa,0x07,0x80,0xf6,0x07,0x80,0x3d,0x00,0x00,0xb6,0x07,0x40,0xed,0x83, + 0x7c,0xab,0x0e,0x40,0x53,0xf5,0x00,0x20,0xa9,0x1e,0x00,0x04,0x7a,0x00,0x44, + 0x1e,0x00,0xd4,0x03,0x80,0x88,0x07,0x00,0x00,0x80,0x07,0x00,0xd4,0xdb,0xff, + 0x5b,0xbb,0x3d,0x00,0x00,0x00,0x00,0x60,0xd5,0xd5,0x36,0x00,0x6b,0x00,0xfe, + 0x01,0x80,0xfb,0x01,0xc0,0x1e,0x00,0x00,0xec,0x03,0x80,0xf5,0x14,0x1c,0xd5, + 0x07,0x80,0x54,0x3d,0x00,0x40,0x45,0x0f,0x00,0x54,0x1f,0x00,0x92,0x0f,0x80, + 0xf2,0x00,0x00,0xf0,0x01,0x00,0x40,0xf0,0x01,0x00,0xfc,0x76,0xab,0xf6,0xee, + 0x0f,0x00,0x00,0x00,0x00,0x40,0x5b,0x56,0x2b,0x00,0x75,0x00,0x00,0x00,0x00, + 0x3e,0x00,0x80,0x0f,0x00,0x00,0xf8,0x00,0x00,0x3f,0x40,0x0f,0xfe,0x01,0x00, + 0xaa,0x0f,0x00,0x00,0xd5,0x03,0x00,0xe0,0x03,0x00,0xf8,0x01,0x00,0x3e,0x00, + 0x00,0x7e,0x00,0x00,0x00,0x7f,0x00,0x00,0xb4,0xdf,0xfe,0xbd,0xb7,0x07,0x00, + 0x00,0x00,0x00,0x80,0xad,0x5b,0x75,0x00,0x6a,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x07,0x00,0x00,0x00,0xf0,0x01, + 0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xec,0xfa,0x57,0xd7,0xfa,0x01,0x00,0x00,0x00, + 0x00,0x00,0xb5,0x6a,0xd5,0x00,0x7a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x80,0xc0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xbc,0x5f,0xfd,0xbd,0x7f,0x00,0x00,0x00,0x00,0x00,0x00, + 0x54,0x55,0xab,0x81,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xea,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xf4,0xea,0x57,0xef,0x3d,0x00,0x0c,0x03,0x00,0x00,0x00,0xab,0x55, + 0x55,0x03,0x3a,0x00,0x00,0x00,0x00,0x18,0x1c,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x40,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7c,0x00, + 0x00,0xc0,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xdc,0x7f,0xfd,0x75,0x0f,0x00,0x08,0xe1,0xef,0x1f,0x80,0x57,0xdb,0xed,0xf3, + 0x77,0x10,0xfe,0xf8,0x00,0x38,0x1c,0xfe,0x70,0xe0,0xc0,0x00,0x03,0x7f,0x20, + 0x7a,0x90,0x7f,0xfe,0xf8,0xc0,0x0f,0x03,0x0e,0x7f,0x00,0xc6,0x30,0x04,0x40, + 0x00,0x82,0xc0,0x80,0x83,0x83,0x3f,0x86,0x00,0x00,0x00,0x00,0x00,0xf4,0xd6, + 0x6f,0xef,0x03,0x00,0x98,0xa1,0x44,0x0b,0x80,0x51,0x67,0x3a,0x86,0x70,0x10, + 0x4a,0x28,0x01,0x28,0x06,0x4a,0xac,0x58,0xc1,0xc1,0x0d,0x4b,0x12,0xdb,0x10, + 0x2d,0x96,0x28,0x63,0x80,0x83,0x13,0x49,0x00,0x83,0x31,0x04,0x40,0x00,0xc2, + 0xe0,0xe0,0x46,0x8d,0x25,0x86,0x00,0x00,0x00,0x00,0x00,0xbc,0x7d,0xb5,0xfd, + 0x00,0x00,0x70,0x20,0x00,0x03,0x80,0xa4,0x55,0x0c,0x8a,0x74,0x10,0x02,0x08, + 0x01,0x28,0x1a,0x02,0x04,0x08,0x40,0x21,0x00,0x01,0x08,0x43,0x11,0x04,0x02, + 0x08,0x22,0x80,0xc2,0x00,0x01,0x00,0x01,0x51,0x04,0xc0,0x07,0xc6,0xa0,0x30, + 0x40,0x80,0x00,0x8a,0x00,0x00,0x00,0x00,0x00,0xd0,0xdb,0xff,0x3f,0x00,0x00, + 0x40,0xe0,0x03,0x01,0x40,0x8c,0x4a,0x4d,0x9b,0xd9,0x1f,0x3e,0xf8,0x01,0x58, + 0x0b,0x3e,0x78,0xf0,0x20,0x21,0x00,0x1f,0xc1,0x43,0x13,0x0c,0x3e,0xf8,0xe1, + 0x83,0x44,0x00,0x1f,0x00,0x01,0x91,0x04,0x40,0x05,0x24,0x21,0x11,0xc0,0x83, + 0x0f,0x92,0x00,0x00,0x00,0x00,0x00,0x70,0xf7,0xaa,0x0f,0x00,0x00,0x20,0x20, + 0x01,0x03,0xc0,0x0b,0x5b,0xaa,0xf6,0x58,0x00,0x12,0x88,0x40,0x48,0x19,0x02, + 0xa0,0x41,0xa3,0x22,0x0e,0x03,0xe8,0x43,0x14,0x0c,0x12,0x98,0x20,0xc0,0x44, + 0x00,0x0b,0x00,0x81,0x11,0x05,0x40,0x00,0xaa,0x30,0x11,0x00,0x8c,0x04,0xa2, + 0x00,0x00,0x00,0x00,0x00,0xe0,0xbd,0xff,0x01,0x00,0x00,0x20,0x20,0x00,0x03, + 0x60,0x10,0x69,0x4c,0xa2,0x59,0x10,0x02,0x88,0xa0,0x9a,0x18,0x02,0x00,0x01, + 0xb2,0x26,0x08,0x11,0x75,0x42,0x14,0x0c,0x06,0x88,0x61,0x40,0xcd,0x10,0x01, + 0x00,0x83,0x10,0x06,0x40,0x00,0x98,0x50,0x33,0x04,0x88,0x01,0xc2,0x00,0x00, + 0x00,0x00,0x00,0x80,0x6f,0x3f,0x00,0x00,0x00,0x20,0xe0,0x0f,0x03,0x20,0x10, + 0xd2,0xb2,0x93,0x5c,0x10,0xfe,0x08,0x29,0x99,0x08,0xfe,0xdc,0xb8,0x11,0xc4, + 0x0d,0x6f,0x3c,0x42,0x18,0x0c,0xfe,0x08,0x21,0x20,0x88,0x1f,0x7f,0x00,0xfc, + 0x10,0x06,0x40,0x1f,0x92,0x09,0xe2,0xc7,0x8d,0x3f,0x82,0x00,0x00,0x00,0x00, + 0x00,0x00,0xfe,0x03,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x2a,0x4a, + 0xd0,0x18,0x10,0x40,0x00,0x95,0x0a,0x10,0x50,0x40,0x80,0x00,0x00,0x00,0x41, + 0x0e,0x02,0x00,0x00,0x90,0x00,0x00,0x00,0x00,0x04,0x48,0x00,0x00,0x20,0x00, + 0x40,0x09,0x00,0x00,0x00,0x00,0x01,0x24,0x04,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0xaa,0x54,0x1c, + 0x00,0x00,0x00,0xa0,0x44,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x07,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x95,0xaa,0x0e,0x00,0x00, + 0x00,0xad,0x2a,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0xe1,0x01,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x6a,0x55,0x0d,0x00,0x00,0x80,0x52, + 0x92,0x14,0x00,0x00,0x00,0x00,0x00,0xa0,0x78,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x40,0xad,0x5a,0x0d,0x00,0x00,0x00,0x4a,0xa9,0x2a, + 0x00,0x00,0x00,0x00,0x00,0x14,0x3e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x55,0xab,0x0e,0x00,0x00,0x80,0x2a,0x95,0x64,0x00,0x00, + 0x00,0x00,0x80,0x42,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x6a,0x55,0x0d,0x00,0x00,0x00,0x55,0xa5,0x52,0x00,0x00,0x00,0x00, + 0x00,0xd0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xac,0xb5,0x0d,0x00,0x00,0x00,0xa4,0x54,0xaa,0x00,0x00,0x00,0x00,0xa0,0xfa, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0xaa, + 0x1a,0x00,0x00,0x00,0x95,0x4a,0x49,0x01,0x00,0x00,0x00,0x14,0x3d,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0xad,0x1a,0x00, + 0x00,0x00,0x54,0x29,0xa5,0x02,0x00,0x00,0x80,0xc2,0x0f,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x55,0x35,0x00,0x00,0x00, + 0x50,0xa5,0x54,0x0a,0x00,0x00,0x52,0xf4,0x01,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xda,0x6a,0x00,0x00,0x00,0x90,0x94, + 0x92,0x12,0x00,0x40,0x08,0x7d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x55,0x6b,0x00,0x00,0x00,0x40,0x55,0x4a,0x49, + 0x92,0x94,0xd2,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x56,0xd5,0x00,0x00,0x00,0x80,0x52,0xa9,0x54,0x49,0x22, + 0xf9,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xa8,0xda,0x00,0x00,0x00,0x00,0xae,0x4a,0x92,0x2a,0x55,0x1f,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xd8,0xaa,0x01,0x00,0x00,0x00,0x60,0xa5,0x4a,0xa4,0xf8,0x03,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0xd5, + 0x01,0x00,0x00,0x00,0x00,0xbc,0xa9,0xfa,0x1f,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x56,0x03,0x00, + 0x00,0x00,0x00,0x00,0xf8,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0xaa,0x03,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd0,0xaa,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x58,0x55,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x50,0xad,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xa8,0xb5,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50, + 0x55,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0xaa,0x0e, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x68,0x55,0x0d,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0xab,0x0a,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x5a,0x1d,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x50,0xd5,0x1a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x60,0x55,0x1d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xa0,0xaa,0x1a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x56, + 0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xaa,0x3a,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x55,0x35,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0xda,0x3a,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x80,0x55,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x80,0xaa,0x3a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x40,0x55,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xab,0x3a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x5a,0x35, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xaa,0x3a,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6b,0x35,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xaa,0x3a,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xaa,0x3a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x54,0x1d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x68,0x1d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0, + 0x1e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x0f,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; diff --git a/etc/icons/wl-logo.xpm b/etc/icons/wl-logo.xpm new file mode 100644 index 0000000..0d5b307 --- /dev/null +++ b/etc/icons/wl-logo.xpm @@ -0,0 +1,438 @@ +/* XPM */ +static char *wl-logo4[] = { +/* width height num_colors chars_per_pixel */ +" 491 176 255 2", +/* colors */ +".. c None", +".# c #030404", +".a c #506cc2", +".b c #1f4269", +".c c #ce9adc", +".d c #235bb4", +".e c #926474", +".f c #5c556a", +".g c #887dcc", +".h c #39414c", +".i c #0d263c", +".j c #836993", +".k c #ad81bc", +".l c #3d5684", +".m c #202624", +".n c #21508c", +".o c #ba758e", +".p c #61618f", +".q c #f1b9d4", +".r c #8073b4", +".s c #4462ac", +".t c #b78ed4", +".u c #143654", +".v c #2c4159", +".w c #db8dac", +".x c #474c5f", +".y c #6c73c4", +".z c #97719e", +".A c #3162bc", +".B c #615056", +".C c #17232b", +".D c #415c94", +".E c #7e6074", +".F c #6569a7", +".G c #dda7dc", +".H c #a787d2", +".I c #0d1515", +".J c #c37c9c", +".K c #273338", +".L c #2e4e7c", +".M c #1d497c", +".N c #315894", +".O c #5062a0", +".P c #c88cc4", +".Q c #51494c", +".R c #aa749c", +".S c #9f7cbd", +".T c #71607f", +".U c #e09fcc", +".V c #625b78", +".W c #3d4656", +".X c #8f6c94", +".Y c #505064", +".Z c #2a302e", +".0 c #b384bc", +".1 c #817acc", +".2 c #1e3445", +".3 c #2b476c", +".4 c #1f2b2e", +".5 c #121715", +".6 c #d89fdb", +".7 c #295eb6", +".8 c #ce819e", +".9 c #a278ab", +"#. c #4d5b89", +"## c #f4bfd6", +"#a c #eab4dc", +"#b c #445378", +"#c c #6771c4", +"#d c #6170c4", +"#e c #4a5677", +"#f c #2356a4", +"#g c #2c3b45", +"#h c #305590", +"#i c #5967ac", +"#j c #c996d7", +"#k c #ab6e84", +"#l c #454344", +"#m c #b886c1", +"#n c #5d6bb4", +"#o c #233f58", +"#p c #152d42", +"#q c #836fa4", +"#r c #7b79cc", +"#s c #26476d", +"#t c #9d82cc", +"#u c #6c5b71", +"#v c #2858a5", +"#w c #6a679d", +"#x c #eda9c6", +"#y c #33404c", +"#z c #7373c3", +"#A c #795b67", +"#B c #746aa4", +"#C c #0f1f2c", +"#D c #1a2d40", +"#E c #50609a", +"#F c #060e14", +"#G c #9582cc", +"#H c #79699c", +"#I c #294e7c", +"#J c #d082a0", +"#K c #4a68bc", +"#L c #c195d4", +"#M c #a073a0", +"#N c #273844", +"#O c #74668f", +"#P c #9479bc", +"#Q c #223d54", +"#R c #e79dbc", +"#S c #d39ad3", +"#T c #9f697c", +"#U c #8f7dcc", +"#V c #69618c", +"#W c #8f71a4", +"#X c #c191d4", +"#Y c #193d64", +"#Z c #435073", +"#0 c #3c66bc", +"#1 c #7b5b66", +"#2 c #e4a7d4", +"#3 c #0a1b2b", +"#4 c #ca84ac", +"#5 c #394e6f", +"#6 c #375da5", +"#7 c #5964a1", +"#8 c #ad7aac", +"#9 c #a57eb9", +"a. c #4b5985", +"a# c #f1b4ce", +"aa c #e295b4", +"ab c #d587a5", +"ac c #f1b8d4", +"ad c #b7738c", +"ae c #363d44", +"af c #282e2c", +"ag c #8d657c", +"ah c #181e1c", +"ai c #5d4f54", +"aj c #946e95", +"ak c #f7cbde", +"al c #88606e", +"am c #e6a1c4", +"an c #37475c", +"ao c #715760", +"ap c #e7b1dc", +"aq c #3b3d3c", +"ar c #14232c", +"as c #bb80ac", +"at c #3662bb", +"au c #c67b97", +"av c #f3b9d2", +"aw c #0c0f0e", +"ax c #1a467c", +"ay c #3f60ac", +"az c #5d5f8b", +"aA c #113254", +"aB c #c489c4", +"aC c #7470b4", +"aD c #2c5594", +"aE c #3b5484", +"aF c #b77a9f", +"aG c #eca7c4", +"aH c #645871", +"aI c #435784", +"aJ c #4a64ac", +"aK c #183654", +"aL c #1a201e", +"aM c #214a7d", +"aN c #ce90c4", +"aO c #223644", +"aP c #484546", +"aQ c #676db5", +"aR c #b18ad4", +"aS c #26446c", +"aT c #295292", +"aU c #385284", +"aV c #9a79b9", +"aW c #956576", +"aX c #855f6c", +"aY c #cd809e", +"aZ c #2e3537", +"a0 c #565d8b", +"a1 c #515675", +"a2 c #ae6f86", +"a3 c #21313c", +"a4 c #866c9c", +"a5 c #a26a7e", +"a6 c #5a5874", +"a7 c #3c5a94", +"a8 c #222826", +"a9 c #61649b", +"b. c #4166bc", +"b# c #153a64", +"ba c #2c445f", +"bb c #9a74a6", +"bc c #6a545c", +"bd c #1d4d8c", +"be c #305aa3", +"bf c #5165ab", +"bg c #c692d0", +"bh c #ae78a4", +"bi c #71638b", +"bj c #dfa4dc", +"bk c #3f495c", +"bl c #1e3954", +"bm c #504950", +"bn c #bd89c5", +"bo c #5c6ec4", +"bp c #274c7c", +"bq c #715e7c", +"br c #285bb4", +"bs c #324359", +"bt c #7675c6", +"bu c #785e74", +"bv c #716db1", +"bw c #8b75b4", +"bx c #f3bcd4", +"by c #354a67", +"bz c #12293c", +"bA c #3864bc", +"bB c #4b5372", +"bC c #7c6690", +"bD c #333736", +"bE c #d49fdc", +"bF c #1f282c", +"bG c #546fc4", +"bH c #d09ddc", +"bI c #9f697c", +"bJ c #c27994", +"bK c #8575ba", +"bL c #bb92d4", +"bM c #485064", +"bN c #19272c", +"bO c #475f9c", +"bP c #aa8ad4", +"bQ c #c880a1", +"bR c #29363c", +"bS c #315284", +"bT c #9d7ec0", +"bU c #535266", +"bV c #313634", +"bW c #304b6d", +"bX c #131816", +"bY c #daa3dc", +"bZ c #f6c8dc", +"b0 c #b7738c", +"b1 c #f0b1cc", +"b2 c #1b3144", +"b3 c #7e6da1", +"b4 c #d486a4", +"b5 c #ab6e84", +"b6 c #927fcc", +"b7 c #855f6c", +"b8 c #e7add9", +/* pixels */ +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"....................................................................................................................................................................................................................................................................................................................................................................................................................................................................aRaRaRaRaRaRaR.t.t.t..............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"..............................................................................................................................................b.b.#0.................................................................................................................................................................................................................................................................................................H.H.HbPaRaRaRaRaR.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"............................................................................................................................................b.#0b.ay.#.....................................................................................................................................................................................................................................................................................H.HaRaRaRaRaR.HaRaRaRaRaRaRaRaR.t.t.taR.t.t.t.t.t.t#X#X#X#X#X.t.t.t........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"..........................................................................................................................................#0b.b.b.#0#Faw.............................................................................................................................................................................................................................................................................H.H.H.HaR.H.HbPaRaRaRaRaRbP.t.taR.t.taR.t.t.t.t.t.t#X#X#X.t.t.t.t#X#X#X#X#X#X.t#X................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"........................................................................................................................................bAb.b.b.b.b.bz.#....................................................................................................................................................................................................................................................................#t#t.H.H.H.H.0.HaRbP.HbPaRbP.HaRaRaRbPaRaRaR.taRbn.tbn.t.t.t.t.t.t#X#X#X.t#X#X.t#X#Xbg#X#X#X.0............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"......................................................................................................................................#0b.#0b.b.b.b.bz.#................................................................................................................................................................................................................................................................#t.H.H.H.H.H.HbPbP.H.H.0bP.0.HaRaRaRaRaRaR.taR.taR.t.t.t.t.t.t.t.t.tbL.t.t.t#X#X#X#X#X#X#X#X#X#X#L#Lbg#9......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"..................................................................................................................................b.b.#0bAb.b.b.b.#K.b.#..........................................................................................................................................................................................................................................................#t.H.H.H.H.H#t.H.H.H.H.H.HbP.HbPaR.HaR.HaRaRaRaRaRaR.taR.taR.tbn.t.t.t.t.t.t#X#X.t.t.t#X.t#X#X#X#L#Xbgbg#L#j#LbgaV..................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"................................................................................................................................bAbAbAb.b.#0#0b.#0b.bp.#......................................................................................................................................................................................................................................................#t#t.H#t#t#t.H.H.H.H.H.H.HaRbP.HaR.HbPaRbPaRbPaRaRbP.taRaR.taR.t.t.t.t.t.t#X.t#X.t.t#X#X#X#X#X#X#X#X#X#j#X#Lbg#L#j#j#j#L#8..............................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"..............................................................................................................................b.#0b.bAb.bAb.#0b.b.b.bp.#................................................................................................................................................................................................................................................#G#t#t#t#t#t.H.H#t#t.H#t.H.H.H.H.HaR.HaR.HaR.0bPaRaRaRaRaRaRaRaR.t.taR.t.t.t.t.t.t.t.t#X.t.t#X.t#X.t#X#X#X#X#X#X#L#X#X#L#j#j#j#L.kbC..........................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"............................................................................................................................#0bAbAbAb.#0b.b.b.b.#0#K.b.#............................................................................................................................................................................................................................................b6#t#t#t#t.H#t.H#t#t.H.H.H.H.H.0.H.H.0.HaR.HaRbPbPaRaRbPaRaRaRbP.t.taRaR.t.t.t.t.t.t#X.t#X.t#X#X.t#X#X#XbL#X#X#X#L#X#X#j#j#j#L#j#j#j#j.caj........................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"........................................................................................................................bAbA.s#0b.#0bAb.bAb.b.b.b.#0bz.#........................................................................................................................................................................................................................................#t#tb6#t#t#t#t#t#t#t.H#t.H#t.H.H.H.H.H.H.H.HbP.H.HaR.H.H.0bPaRaR.taRaR.t.t.taRbnbn.t.t.t.t.t#X.t.t#X#X.t#X#XbL#X#X#X#X#X#X#X#X#Xbg#X#j#j#j#j#L.k.Y....................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"......................................................................................................................bAbAbA#0bAbAbAb.#0b.#0#0#0#0#Kbz.#......................................................................................................................................................................................................................................#t#G#t#t#t#G#t#t.H#t.H#t.H#t.H.H#t.H.H.HbP.H.H.HaRaRbPaRaRbPaRaRaRaRaRbPaRaRaR.t.t.t.t.t.t#X.t.t#X#X.t.t#X#X.t#X#X#X#X#j#j#j#j#j#j#j#j#j#j#L.c.c#j#ja6..................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"....................................................................................................................bAbAbAbA#0b.b.#0bAb.b.b.b.b.b.#0bz.#..................................................................................................................................................................................................................................#tb6b6#t#tb6#t#t#t#t#t#t#t#t.H.H#t.H#t.H.H.HbPaRbP.H.H.HbPaRaRaRaRbPaRaRbnbP.t.t.t.t.t.t.t.t.t.t.t.t.t#X#XbL.t#X#X#X#X#X#X#X#X#X#X#L#L#j#L#j#j#j#j.c#j#j.cbC................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"................................................................................................................atbAbAbA#0bAbAbAbAbAb.#0#0#0b.b.#0#K#3.#..............................................................................................................................................................................................................................b6bTb6#t#tb6#G#t#t#G#t#t.H#t.H.H#t#t.H.H.H.H.H.H.0.H.HbPaRaRaRbPbPbPaRaRaRbP.t.taRaRaR.t.t.t.t.t.t#X.t.t#X.t.t.t#X#X#X#X#X#X#X#X#X#L#j#X#j#jbg#j#j#j#j#j#j.c#j.cbb#g............................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"..............................................................................................................bA.AbAbAbAbAbAb.b.b.#0bAbAb.#0#0b.b.b..#.#..............................................................................................#d#d#c......................................................................................................................b6b6b6b6b6b6#tb6#tb6#t#t#t#t#t#t#t.H.H.H.H.H.H.H.H.H.H.H.0.H.H.H.0.H.0bPaRaR.tbPaRaR.t.taRaRbnaR.t.t.t#X#X.t#X#X#X#X#X.t#XbL#X#X#X#X#X#X#j#X#X#j#L#j#L#j#j.c#j#j#j.c#jasa3..........................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"...........................................................................................................AbAbAbAbAbA.sb.bAbAbAbAbAb.b.b.b.b.b.#0#K.#.#..........................................................................................#d#c#c#c#d.y.y.O..............................................................................................................b6b6b6#G#t#t#tb6#t#t#t#t#t#t#G.H#t#t#t#t#t#t.H.H.H.H.H.H.H.HbPbPbPbPaRbPaRaRbPbPbnbP.taRaR.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t#X.t#X#X#X#L#L#X#j#X#j#j#jbg#j#j#j#j#j#j.c.c#j.c.c#mbF........................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"......................................................................................................bAbA.AbAbAatbAbAbA#0bAbAb.b.#0#0bAb.b.#0b.b.bp.#.#......................................................................................bo#c#d#c#c#c#c#d.y#c.3........................................................................................................#Ub6b6b6b6b6b6b6#t#tb6#t#t#t#G#t#t#t#t#t.H.H.H#t#t.H.H.H.HbPbP.H.0.HbPbPaR.HbPaRaRaRaRaRaR.taR.t.t.tbn.t.t.t.t.t.t#X#X#X#X#X#X#X#X#X#X#X#j#X#L#X#L#L#j#X#j#j#j#j#j#j#j.c#j.c.c.cbbaw......................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"....................................................................................................at.A.AbA.AbAbAbAbAbAbA.s#0bAbAbA#0b.bA#0b.#0b.aK.#......................................................................................#c#c#d#d#d.y.y#c.y#c.y.y#C....................................................................................................b6b6b6b6b6b6b6b6#tb6b6#t#Gb6#t#t#t#G.H.H.H#t#t#t.H.0.H.H.H.0.H.H.HbPaR.HaRbPaRaRaRaRbP.tbP.taR.taR.t.t.t.t.t.t.t#X#X.t.t.t.t#X#X#XbL#X#X#X#X#X#X#j#X#X#j#j#j#j#j#j.c#j#j#j#S#j#j.c.cbC.5....................................................................................................................................................................................................................................................................................................................................................................................................................................................", +".................................................................................................A.AatbA.AbA.AbAbAbAbAbA#0bAbAb.b.bAb.b.bAb.b.#0b.#3.#....................................................................................#d#daQ#c#d#d#d#d#c.y#d.y.yaE.#..............................................................................................b6b6b6#Ub6b6b6#tb6b6#t#t#Gb6#tb6#t#t#t#t#t#t#t.H.H.H.H#G#t.H.H.H.H.0.H.HaR.H.0bP.0bPaRaRaRaRaRaRaR.taRaR.tbn.t.t.t.t.t.t#X#X#X.t#X.t#XbL#X#X#X#X#X#X#j#j#L#L#X#j#L#j#j#j#j#j#j.c.c#j.c.c.c.x....................................................................................................................................................................................................................................................................................................................................................................................................................................................", +".............................................................................................A.AatbAbA.AbAatbAbAbAbAbAbAbAbA#0bAbAb.#0#0b.b.b.b.b..#.#..................................................................................bo#d#d#d#d#c#c#d.y#d#c.y#c.y#i.#............................................................................................#U#Ub6b6b6b6b6b6b6#tb6b6b6b6#t#t#t#t#t#t#t#t#t.H#t#t#t.H.H.H.H.H.H.HbP.HaR#P.p.p.p.p#V.p#V.pbi.S.t.taR.t.t.t.t.t.t.t.t.t#X.t.t.t#X.t#X#X#X#X#X#X#L#j#j#X#X#X#j#j#j#j#j#L.c.c.c.c#j#j#S#j.c.c.cbN..................................................................................................................................................................................................................................................................................................................................................................................................................................................", +".........................................................................................A.A.AbA.A.AatatbAbA.AbA.AbAbAbAbAbAbAb.bAbAb.#0bAb.b.#0bp.#.#................................................................................#dbobo#dbo#d#d#c#d#c#c#c.y#c.y#c.#aw........................................................................................b6b6.g#Ub6b6b6b6#t#U#t#t#t#t#t#t#tb6#t#t#t#t#t#t#t.H.H#t.H.Haz.pbRbR.C.#.#.#.#.#aw..................awaw#g#Nbi#V.t.t.tbg.t.t#X#X.t#X#X.t#X#X#X#X#X#X#X#j#j#j#X#j#j#j#j#j#j#j#j#j.c.c.c#S.c#S.c.c#m.I................................................................................................................................................................................................................................................................................................................................................................................................................................................", +".....................................................................................7.A.A.A.A.A.A.AbAbA.A.AbAatbAbAbAbAb.bAb.bA#0b.bAb.b.#0b.b.#3.#................................................................................bobo#c#c#c#c#c#c#d#d.y.y.y#c.y.y.y.#.#.....................................................................................g.g.g#Ub6b6b6#Ub6b6b6#tb6b6b6b6b6b6#t#t#t#t#t#t.H#t.Hazbs#N.#.#.#.#...................................................xbkbi.t#X.t.t#X.t#X#X#X#X#X#X#X#X#X#X#X#X#j#L#L#j#j#j#j#j#j#j#j#j#j.c#j.c.c.c.c.Vaw..............................................................................................................................................................................................................................................................................................................................................................................................................................................", +".................................................................................A.A.A.7.A.A.A.A.A.A.AbAbAbAbAbAatbAbAbAbAbAbAbAbAb.bA#0bAb.b.#6.#.#..............................................................................bo#cbo#d#d#d#d#d#c#c#c#d#d.y#d#c.y#c.#.#...................................................................................g#Ub6b6#Ub6#Ub6b6b6b6b6b6b6#tb6#t#tb6#tb6#t#t#ta0anar.#.#.#.....................................................................Vbi.t#X.t#X.t.t#X#X#X#X#X#X#j#j#L#X#j#j#L#j#j#j#j#j#j.c.c#j#S#j.c#S.c.c.c.4..............................................................................................................................................................................................................................................................................................................................................................................................................................................", +"...........................................................................7.A.A.7.A.A.A.A.A.AbAbA.Aat.A.A.AbAbAbAbAbAbAb.bAb.b.b.bAb.b.b.#0b.aK.#aw..............................................................................#dbo#dbobo#d#d#c#d#d#d#d#c#c.y.y.y.l.#.#.................................................................................g.gb6.g.gb6#Ub6b6b6b6b6#U#tb6b6#tb6b6#t#GbKa0aO.#.#.#..................................................................................bC#W#X#X#X#X#X#X#L#L#L#X#X#X#jbg#j#j#j#L.c.c.c.c#j#j.c.c#S#j.c.c.cbE#M.#............................................................................................................................................................................................................................................................................................................................................................................................................................................", +".....................................................................7.7.7.7.7.A.7#6.A.7.A.A.A.A#6.AbAbAbA.A.AbAbAbAbAbAbAbAbAbAb.#0bAb.bAb.be.#.#..............................................................................bo#dbo#d#cboaQbo#c#c#c#c.y#d#c#c#c#c.3.#...............................................................................g.gb6.g#Ub6#Ub6b6b6#Ub6b6b6b6#tb6b6#t#t#ta0.C.#.#aw..............................................................................................#9#X#X#X#X#X#X#L#j#j#j#L#j#j#j#j#j#j#L#j.c.c#j#j.c#S.c#S.c#SbH.c.x.5..........................................................................................................................................................................................................................................................................................................................................................................................................................................", +".......................................d.d#v................brbr.7.7.7.7.7.7.A.7.A.7.A.A.A.A.A.A.AbA.A.A.AbAbAbAatbAbAbA#0bAbA#0bAbAb.#0b.#0aK.#aw............................................................................bGaQbo#cbobo#c#d#c#d#d#d.y#d.y.y.y.y.yar.#.............................................................................g.g#U.g.gb6.gb6#U#U#Ub6#Ub6b6b6b6b6b6#waO.#.#.#........................................................................................................#9#X#X#X#X#X#X#X#X#j#X#L#j#j#j#j#j#j#j#j.c.c.c.c.c.c.c.c.c.cbn.#..........................................................................................................................................................................................................................................................................................................................................................................................................................................", +".......................................d.d.d.d.d.d.d.7.7.7.7.7br.7.7.7.A.7.7at.A.A.A.A.A.A.AbA.AbA.AatbAatbA.AbAbAbAbAbAbAbAbAb.b.#0bAb.b.#h.#.#............................................................................#d#dbobo#d#d#d#d#d#d#c#d#d#d#d#d#d#d.y#i.#.#...........................................................................1.g.g.g.g.gb6.gb6b6b6b6b6#Ub6b6b6#t#b.C.#.#.5................................................................................................................#X#X#X#j#L#j#X#j#j#L#j#j#j#j#j#j#j#j#j#j.c.c.c#S.c#S.c.c.c.4aw........................................................................................................................................................................................................................................................................................................................................................................................................................................", +".........................................d.d.7.dbr.7br.d.d.7.7.7.7.7.7.7.A.7.7.7.A.7.A.A.A.A.A.A.AbAbA.AbA.AbAbAatbAbAbA#0b.bAbAbAbAb.#0#0#F.#.5..........................................................................bobobobobobobobo#d#d#c#d#c#c#c#c#c.y.y#c.3.#aw.........................................................................g#U.g.g.gb6.g.gb6#U#U#Ub6b6b6b6.rbs#F.#.#.........................................................................................................................t#X#X#X#X#j#Lbg#j#L#j#j.c.c#j.c.c.c.c#j#j.c.c.c.cbH#S#S.9.#........................................................................................................................................................................................................................................................................................................................................................................................................................................", +".........................................7.d.7.7.d.7.7.7br.7.7br.7.7.7.7.7.A.A.7.A.7.7.A.A.AbA.A.A.A.A.AbAbAbAbAatbAbAbAbAbAb.b.b.#0bAbAbz.#.#............................................................................bobo#dboaQ#d#dbobobo#c#d#d#c#c.y#d#c.y.y#F.#.........................................................................g.g.1.g#U.g#U#U.gb6b6b6#Ub6b6.rbs.#.#aw................................................................................................................................#X#j#X#X#j#X#j#j#L#j#j.c#L#j#j#j#S.c#j#j#S.c#S.c.c.c.c.I.5......................................................................................................................................................................................................................................................................................................................................................................................................................................", +".........................................d.d.d.d.7.d.d.7.7.d.7.7.7.7.7#6.A.7.7.A.7.A.A.7.A.A.A.A.A.AbAbA.A.A.AbAbAbAbAbAbA#0bAbAbAbAb..b.#.#............................................................................bGbobobG#d#dbobo#c#c#c#d#c#c#d.y#d#c.y#c.3.#.#.......................................................................1.g.g#U.g.g.gb6.g#U.g#U#Ub6aCbs.#.#aw......................................................................................................................................#X#j#j#L#j#j#j#j#L#j#j#j#L.c.c#j.c.c#S.c.c.cbHbH#SbE.Y.#......................................................................................................................................................................................................................................................................................................................................................................................................................................", +".........................................d.d.d.d.7.7.d.d.7br.7br.7.7.7.7.7#6.7.A.A.A.A.7.A.A.A#6bA.A.AbAbAbAbAbAatbAbAbAbAbAbAb.b.#0bp.#.#............................................................................bobobobobobo#d#dbo#d#dbo#d#d#d#d#c#c#c.y.y#F.#.......................................................................g.1.1.g.g.g.g.gb6.g#Ub6b6#Ubs.#.#aw............................................................................................................................................bL#X#j#X#X#j#j#j#j#j#S#j#j.c#j.c.c#j.c#S.c#S.c.c.cbb.#......................................................................................................................................................................................................................................................................................................................................................................................................................................", +"...........................................7.7.d.d.7.7.7.7.7.7.7.7.7.7.7.7.7.A.7.7.A.A.A.A.AbA.A.A.Aat.Aat.A.AbAbAbAbA.sbAbA#0bAbAaM.#.#.............................................................................aboboboboboboboaQ#dbo#d#c#d#c#c#c#d.y#d#c#Q.#.#.....................................................................1.1.g.g.g.g.g.g.g.gb6b6.gaUaw.#.#..................................................................................................................................................#j#L#j#j#j#j#j#j.c#j#j.c#j.c.c.c#S.c.c.c.cbH#SbEbE.I.5....................................................................................................................................................................................................................................................................................................................................................................................................................................", +"...........................................d.7.7.d.d.7.d.7br.7.7.7.7.7.A.A.7.A.A.7.A.A.A.A.A.A.A.AbAatbAbAbA.AbAaybAbAbA#0bAbAb.aK.#.#...............................................................................abobobobo#dbo#dbo#dbo#daQbo#d#d#c#d#c#d.D.#.#.....................................................................1.g.1.g.1.g.g.g.g.g.g.ga9.C.#.#........................................................................................................................................................#j#j#L#j#j#j#j#j.c#j.c#j#j#j.c.c.c.c#S.c.c.c.c#S#y.#....................................................................................................................................................................................................................................................................................................................................................................................................................................", +"...........................................d.d.d.d.7.d.7br.7.7.7.7.7.7.7.7.7.7#6.A.7.A.7.A.A.AbAbA.AbA.A.A.AbAbAbAbAbAbAbAbA#6bz.#.#..............................................................................bobobGbobG#dbobobo#dbo#c#d#d#c#c#c#d#c.y#iaw.#.5...................................................................1.g.1.g.1.g.1.1.g.g.gaCba.#.#.5............................................................................................................................................................#j#j#L#j#j#j#j#j#j#L.c#S.c.c.c#S.c.c.cbH#SbEbH.j.#....................................................................................................................................................................................................................................................................................................................................................................................................................................", +".............................................d.7.d.7br.7.7br.7.7.7.A.7.7.7.A.A.7.A.7.A.7.A.A.A.A.A.AatbAbAbA.AbAatbAbAbA.saT#F.#aw..............................................................................bGbobobobobobobGbobo#dbobo#d#d#d#d#c#d#d#db2.#aw...................................................................g.1.g.1.g.g.g.g.1.g.ga0aw.#aw..................................................................................................................................................................bg#j#L#j.c#j#j.c#j#j.c#L#j#j.c.c#S#S.c.c.cbE#m.#....................................................................................................................................................................................................................................................................................................................................................................................................................................", +".............................................7.d.7.d.7.dbr.7brbr.7.7.7.A.A.7.7.A.7.A.A.A.A.A.A.A.A.AbA.Aat.AbAbAbAbAbAbA.u.#.#.5.................................................................................abo.abobobobG#daQbobo#d#c#d#d#d#c#d#c#c#Q.#.#...................................................................1.1.1.1.g.1.1.g.g#U.gaO.#.#......................................................................................................................................................................#j#j#j#j#j#j.c#j.c.c#j#S#S#S.c#S.c.cbH#SbE#SbE.#aw..................................................................................................................................................................................................................................................................................................................................................................................................................................", +"...............................................d.7.d.7.7.7.7.7.7.7.7.7.7.7.7.7.A.A.A.A.A.A.A.AbA.A.AbAbAbAbA.AbAbAbAaT#F.#.#..................................................................................bo.abobGbobGaQbG#d#dbobobobobo#cbo#c#d#caE.#.#..................................................................#r.1.1.1.1.g.g.1.g.ga9aw.#.#..........................................................................................................................................................................#j#j#j.c#L#j#j#j.c.c.c.c#j.c.c#S.cbH.cbH.c.cbF.#..................................................................................................................................................................................................................................................................................................................................................................................................................................", +"...............................................7.d.7.d.dbr.7.7br.7.7.7.7#6.A.A#6.7.7.A.7.A.A.A.AbA.A.A.A.A.AbAbAbebz.#.#.5...................................................................................a.abobobobGbobGbobobo#d#d#d#c#cbo#c#d#daE.#.#...................................................................1.1#r.gbK.1.1.1#U.1#5.#.#.5..............................................................................................................................................................................#L#j#j#j#j#j.c#j#j.c.c.c.c.c.c.c.c#S.cbEbE#y.#..................................................................................................................................................................................................................................................................................................................................................................................................................................", +".................................................d.7.7.7br.7.7br.7.7.7.A.7.7.A.A.A.7.A.A.A.A.A.A.A.AbAbAbAbA.AaA.#.#aw......................................................................................bobGbGbobobo#dboboboboaQbobo#d#c#d#d#caE.#.#..................................................................bt.1.1.1#r.g.1.g.1aC.K.#.#..................................................................................................................................................................................#j#j#j.c.c#j.c.c#j#j.c.c.c#S.c#S.c#S.c#SbH#g.#..................................................................................................................................................................................................................................................................................................................................................................................................................................", +"...................................................7br.d.7br.7.7.7.7.7.7.7.7.7.7.7.A.A.A.A.A.A.AbAat.A.A.AaM#F.#.#.........................................................................................a.a.a#n.abGbGbobG#dbobobo#d#dbo#d#d#daE.#.#...................................................................1.1.1.1#r.g.1.g.1a9aw.#aw......................................................................................................................................................................................#L.c#j#j#j#L#j.c.c.c.c.c.c#S.cbHbHbEbH#S.X.#..................................................................................................................................................................................................................................................................................................................................................................................................................................", +".....................................................7.d.7.7.7br.7.7.7.7.7.A.A.A.A.A.A.7.A.A.A.AbA.Aat.N.I.#.#..........................................................................................bGbobobGbobo#nbGbobo#dbG#dbobo#dbobo#caU.#.#..................................................................#r.1#r.1.1.1.1.1.1a..#.#.5........................................................................................................................................................................................#j#j#j#j#j#S#j.c#j#j.c.c.c#S.c#S.c#SbH.c.j.#..................................................................................................................................................................................................................................................................................................................................................................................................................................", +".......................................................7brbr.7.7.7.7.7.A.A.7.7.7.7.7.A.A.A.A.A.A.A.A#Y.#.#aw.............................................................................................a.a.a#nbG.abGbobobGbo#dbobo#dbo#c#c.3.#.#..................................................................#rbK#rbK#r.1#r.g.1ba.#.#..............................................................................................................................................................................................#j#j.c.c#j.c#j#S#S.c.c.c.c.c.c#SbH#jaRb3.#...............................................................................................................................................................H.H................................................................................................................................................................................................................................................................", +"...........................................................d.7br.7.7.7.7.7#6.A.A.A.7.A.A.A.A.A.Abe#3.#.#..............................................................................................#nbGbGbG#nbGbo#nbGboboboboboaQ#dbo#d#p.#.#..................................................................bt#rbt#r.1.1.1.1.1a3.#.#.................................................................................................................................................................................................c#j#j#j#j.c.c.c#j.c#S.c#S.c.c.c#j.1btbt#C.5..........................................................................................................................................................aRaR.H.k.#............................................................................................................................................................................................................................................................", +"..............................................................bd#f.7.7.7.7.A.7.7.7.A.A.A.A.A.A.n#F.#aw.................................................................................................a.a.a.abGbobGbGbobobobobG#d#dbobf#C.#.#..................................................................bt.1#r.1.1bt#r.1aQar.#.#..................................................................................................................................................................................................#j#j#j.c.c#j#L.c.c.c.c.c.cbHbH#j.1btbtbtaI.#.........................................................................................................................................................HaRaRaRbP.#aw..........................................................................................................................................................................................................................................................", +"....................................................................bzbz.i.i#F#F#v.7.7.A.A.AaM.#.#.5................................................................................................bG.a#nbG.a.a#nbobGbobobo#dbobobo.D#F.#aw...................................................................1btbt.1#r.1.1.1bvaw.#aw......................................................................................................................................................................................................#j#j#j.c#S#j.c#j.c.c#S#S#S.c#UbtbtbtbtaI.#......................................................................................................................................................aR.HaRbPaRbP.#.#..........................................................................................................................................................................................................................................................", +"...............................................................................7.7.A.A#6at#v.#.#...................................................................................................a.a.abG.abobobGbGbobobGbobobobo.3.#.#.5....................................................................bt.1.1#rbK.1#raQ#F.#aw.........................................................................................................................................................................................................c#j#j#j#j.c.c#S.c.c.c.c.c#tbtbtbtbtbtbt.#.......................................................................................................................................................HaR.HaRaRaR.#.#..........................................................................................................................................................................................................................................................", +".............................................................................7at.A.A.A.7aM#F.#aw..................................................................................................#nbG.abo.a.abo#nbG.aaQbGbobobf#p.#.#......................................................................btbtbtbt#r#rbKaQaw.#aw..........................................................................................................................................................................................................#j#j#j.c#j#j.c#j.c.c.c#S#Xbtbtbtbtbtbtbt.#.#..................................................................................................................................................aR.HaR.HbP.0bP.#.#..........................................................................................................................................................................................................................................................", +".............................................................................A.7.7.7.A#v.#.#.....................................................................................................a.a.a.a.abGbG.abG.abobobobG.D#F.#aw......................................................................bt#r.1.1.1#rbtaQaw.#aw.............................................................................................................................................................................................................c.c#S#L.c.c.c#S.c.c.c.c#r#z#zbtbtbKbtbt.#.#.................................................................................................................................................H.HaR.HaR.HbPaR.#.#..........................................................................................................................................................................................................................................................", +"...........................................................................7.A.A.A.A#v#F.#aw.....................................................................................................a.a#n.a.a#nbGbobobGbGbobobl.#.#.5......................................................................#rbtbtbtbtbK#raQ#F.#aw..............................................................................................................................................................................................................#j#j#j#j#j#j.c.c.c.c#S#tbtbtbtbtbtbtbt#n.#.#................................................................................................................................................aR.HaRaRaRaR.HaR.#.#..........................................................................................................................................................................................................................................................", +".........................................................................7#6.7.7.A#f#F.#aw.....................................................................................................a.a.abG.a.abG.a.abGboboa7#F.#.#..........................................................................btbKbt#r#r#raQaw.#aw..................................................................................................................................................................................................................#j.c.c.c.c.c#j.c.cbLbtbtbtbtbtbtbtbtaI.#aw..............................................................................................................................................aR.HaR.H.HbPaRaRbP.#.#..........................................................................................................................................................................................................................................................", +".......................................................................A.7.A.A.7#v#F.#aw.......................................................................................................a.a.abobG.abobo#n.a#nbf.#.#.5..........................................................................btbt#rbtbtbtbv#F.#aw....................................................................................................................................................................................................................#j#j#j#L#j#S#j#j#S.gbtbt#z#zbtbtbtbtaI.#................................................................................................................................................bP.HaRaR.H.HaR.0.p.#.#..........................................................................................................................................................................................................................................................", +".......................................................................7.A.7.7.A.i.#aw......................................................................................................#i.a.a.a.a.a#n.a.abGbGbGbl.#aw..........................................................................btbt#rbtbt.1.1#F.#aw......................................................................................................................................................................................................................#j#j.c.c.c.c.c.c.H.y.y#zbtbtbtbtbtbt.v.#...............................................................................................................................................H.HaR.H.HaRaRbPbP.p.#................................................................................................................................................................................................bY..........................................................", +".....................................................................7.7.7.7.7.i.#.#.........................................................................................................a.a.a.a.abG.abG.abobGbo.#.#..........................................................................btbtbtbt.1btbt.2.#.#........................................................................................................................................................................................................................#j#j#j#j#j.c#S#Xbtbtbtbtbtbtbtbtbtbtb2.#.............................................................................................................................................H.0.HaRbP.HbP.HaR.HbR.#...........................................................................................................................................................................................G.G.G.G.G#S......................................................", +"...................................................................7.7.7.7.A#Y.#.#.........................................................................................................a#i.a.a.a#n.abo.abo.aboaS.#.#..........................................................................btbtbtbtbtbt.2.#.#...........................................................................................................................................................................................................................c#j.c.c.c.c.cb6.y.ybtbtbtbtbtbtbtbt.#.#............................................................................................................................................bP.H.H.H.0bP.0aRaRaRbN.#......................................................................................................................................................................................bY.Gbjbjbj.G#2.G.#aw..................................................", +".................................................................7.7.7.A.7ax.#.#...........................................................................................................a.a.a.a.a.a.a#n.abo.abo#F.#..........................................................................#zbtbtbtbtbKaI.#.#............................................................................................................................................................................................................................#j#j#j#j#j#j.tbtbt.y.y#zbtbtbtbtbtaI.#.#...........................................................................................................................................HbPbPbPbP.HbPbP.HbP#P.#.#....................................................................................................................................................................................bYbY.G.G.GbY.G.Gbq.#.#..................................................", +".................................................................7.7.7.7aD.#.#..........................................................................................................#K.a#K.a.a.a.a.abGbG.abo#s.#.#........................................................................btbtbtbtbtbta..#.#...............................................................................................................................................................................................................................c#j.c.c#S.c.1.y.ybtbtbt#zbtbtbtbt#C.#.............................................................................................................................................H.H.H.H.HaR.H.0aRaRbB.#aw..................................................................................................................................................................................bYbjbjbYbYbY.GbYbj.I.#....................................................", +"..............................................................br.7.7.7#v#F.#aw...........................................................................................................a.a#i.a.a.a.a.a.abo.a.a#F.#..........................................................................btbtbtbtbt#n#F.#................................................................................................................................................................................................................................#j#j#j#j.c.H#zbt#zbtbtbt#zbtbtbt#7.#.#...........................................................................................................................................H.H.H.H.H.HbPbPbP.HaRaw.#.....................................................................................................................................................................................GbYbY.G.Gbj.G.G.T.#.#....................................................", +".............................................................7.7.7.7.7#3.#aw...........................................................................................................a#K.a.a.a.a.abo.a#n.abobS.#.#........................................................................#zbt#zbtbtbtaw.#aw.................................................................................................................................................................................................................................c#j.c.c#X.ybt.ybt.ybtbtbtbtbtbt#C.#.5...........................................................................................................................................H.H.H.0bPaR.H.H.0aR#e.#.#..................................................................................................................................................................................bYbY.G.Gbjbj.GbjaN.#.#......................................................", +".............................................................7.7.7.7aA.#.#..........................................................................................................#K.a.a.a.a.a.a.a.abG.a.a#n#3.#........................................................................bt.ybt#zbtbtb2.#.#..................................................................................................................................................................................................................................#j#j#j#j#t.ybt.ybt.ybtbt#zbtbta9.#.#...........................................................................................................................................H.H.HbP.H.HaRbPbPbP#Paw.#..................................................................................................................................................................................bYbYbYbYbY.GbY.G.P.5.#aw......................................................", +"..........................................................br.7br.7ax.#.#...........................................................................................................a.a.a#K.a#i.a.a.abo.abobGa7.#.#.........................................................................ybtbtbtbtaI.#.#.....................................................................................................................................................................................................................................c#j.c#j.y.y.ybt.ybt.ybtbtbt.1#F.#.5.........................................................................................................................................H.H.H.H.H.H.H.H.H.H.H#N.#aw..................................................................................................................................................................................bYbYbYbj.GbY.GbY.h.#aw........................................................", +".........................................................7br.7.7#f.#.#........................................................................................................#K#K#K#K.a#K.a.a.a.a.a.a.a.abGbl.#.5......................................................................btbtbtbtbtaQ#F.#.......................................................................................................................................................................................................................................c#j#j.1#z.y.ybt#zbt.ybtbt#zb3.#.#...........................................................................................................................................H.H.H.H.HaR.HaRaRaR#V.#.#..................................................................................................................................................................................bYbYbYbYbY.Gbj.G.Y.#.#..........................................................", +".......................................................dbr.7.7br#F.#aw......................................................................................................#K#K.a.a.a.a.a.a.a.a.a.a#n.a.a.s.#.#.......................................................................y.y#z#zbtbt#C.#aw......................................................................................................................................................................................................................................#j#j.tbtbt#z#z.ybt#zbtbt#zaR#y.#.5.........................................................................................................................................H.H.H.H.0bP.HaR.H.Haz.#.#..................................................................................................................................................................................bYbYbjbY.GbYbY.G.X.#.#............................................................", +".......................................................7.7.7.7aA.#.#......................................................................................................#K.a#K#K#K#K.a.a.a.a.a.a.a.a#n.aaS.#aw......................................................................btbtbt#zbt#5.#.#......................................................................................................................................................................................................................................#j#j#j.1.ybt.y#z.ybtbt.ybtb6#m.#.#...........................................................................................................................................k.H.H.H.H.H.H.HaR#Paw.#....................................................................................................................................................................................bYbYbYbYbjbYbYaj.#.#..............................................................", +".....................................................d.dbrbr.n.#.#....................................................................................................#K#K#K#K#K.a#K#K.a#K#K.a.a.a.abGbG.a#F.#......................................................................bt.y.y.ybt#n.#.#........................................................................................................................................................................................................................................#j.c.t.y.y.y.ybtbt.y.ybtb6.c#u.#aw.........................................................................................................................................H.H.H.H.H.H.H.HbP#P.I.#aw...................................................................................................................................c.c#S..........................................bYbYbYbYbY.Gbj#8.#.#................................................................", +"...................................................7.7.7.7#f#F.#.5..................................................................................................#K#K#K#K#I#I#KbG#K.a.a.a#i.a.a.a.aboa7.#.#......................................................................btbtbtbt#z#C.#aw........................................................................................................................................................................................................................................#j#j.1.y.ybt.y.ybtbtbtb6bE.c.I.#........................................................................................b6.................................................H.H.H.H.0.H.H.0bwaw.#aw...................................................................................................................................c#S.cbE.Iaw......................................bYbYbYbYbY.G.P.I.#.5................................................................", +".................................................d.7.7.d.d.i.#aw................................................................................................b.#K#0#K#K#I.#bA#K#K.a.a.a#K.a.a.a#n.a.abl.#.5.....................................................................y.y.y#z.y#5.#.#..........................................................................................................................................................................................................................................#j.t.y.ybt.y.y#z.y#zb6.c.c.9.#.#......................................................................................b6b6b6#w...........................................H.H#t.H.H.H.HbP#P.I.#aw...................................................................................................................................c#SbHbH.V.#.#....................................bY.6bYbYbYbY.P.5.#aw..................................................................", +".................................................d.d.7.7bd.#.#................................................................................................#K#K#K#K#K#p.#aK.a.a#K#K.a.a.a#K.a.a.a.a.a#F.#......................................................................#z#zbtbt#i#F.#.................................................A.A.A......................................................................................................................................................................................#j.1.y.y.y.y.ybtbtb6.c.c.cbN.#.5.......................................1.1.g.g.1.1..................................b6b6b6bKaw.#........................................#t.H.H.H.H.H.Hbwaw.#aw.................................................................................................................................c.c.c.c.c#m.#.#......................................bYbYbYbYbYbY#3.#aw....................................................................", +"...............................................d.d.7brbr#F.#.5..............................................................................................#K#0#K#Kat#C.#.##K#K#K#K.a#K.a.a.a.a.a.a.a.s.#.#....................................................................bt.ybt.y.yb2.#aw.............................................A.A.AbAataM...................................................................................................................................................................................c.t.y.y.ybtbtbt.y#U.c#S.c.9.#.#...................................1.1.1.1.1.1.1.g.g.1aO..........................#Ub6b6bTaCaw.#aw.......................................H.H.H.H.H.H.Hbw.I.#aw........................................aR.......................................................................................c.c.c#S.c#S.j.#aw.......................6.6.6bY.6bE.6bYbY.6bYbYbY.h.#.#......................................................................", +".............................................d.7.d.7.db#.#.#............................................................................................#Kb.#Kb.#K#6#F.#aw..#K.a#K.a.a.a#K.a.a.a.a#n.a.L.#aw...................................................................ybt.ybtbt.O.#.#..............................................atat.AbAatat.#......................................................b.b.................................................................................................#d#d#d#d#c.yboaQ......#j.1.y.y.y.y.y.yb6#j.c.c.c.4.#.5...............................1#r.1.1.1.1.1.g.1.1.g.1a..#......................b6b6#Ub6b6bs.#aw......................................#t.H.H.H.H.H.H#Paw.#aw.......................................t.t.taR#q.................................................................................c#j#S.c#S.c.c.c.I......................bEbE.6bEbY.6bYbYbYbYbYbYbY#8.h#y................bj......................................................", +"...........................................d.7.d.7.d#f.#.#............................................................................................b.b.#0#K#Kbp.#.#aw..#K#K#K#K#K#K#K.a.a.a.a.a.abGbS.#.....................................................................y.y.y.y.y#C.#.5.............................................AbAbA.A.AbAbA.#.#................................................#0#K#K#Kb..#......................................................................................bo#d#c#c#n#5.5.#.#.#........#X.y.y.y.y.y.yb6.c.c.c.c#M.#.#............................bt.1.1.1#r.g.g.g.g.1.g.g.g.g#..#....................b6b6b6b6b6b6#Z.#.........................................H.H#t#t#t.H#Paw.#aw....................................aRaR.t.t.t.t.t.#.............................................................................c#S.c.c.c.c.c#S.c#m.I..................bEbYbYbY.6bEbYbEbY.6bYbYbYbYbYbYbYbYbY.G.G.G.G.GbjaN......................................................", +"...........................................d.7.d.7.7aA.#aw..........................................................................................b.#K#K#0#Kb#.#.#.......a#K#K.a#K.a.a#K.a#i.a.a.a.a.a.#...................................................................y.y.y#z#zbW.#.#...............................7.7.7.7.7.A.A.A.A.A.AbA.A.A.n.#.#............................................b.b.b.b.#K#Kbp.#aw..............................................................................bo#c#cbobf#N.#.#aw..............#jb6#z.y.y#z#z#U.c.c.c.cbHbF.#.5...........................1bKbt#b.K#oaQ.1.1.1.1.1.1.g.1a3.#..................#U#U#Ub6#Ub6b6b6a0........................................#t.H.H.H#tbw.I.#aw.....................................t.taR.t.t.tbn.S.#.#..............................#X#X#X#X..................................#j#j.c#j.c#S#S.c#S.c#S#mbF................bEbEbEbEbEbEbY.6bYbY.6.6bjbYbYbY.G.GbYbYbjbj.PbU.#.#aw....................................................", +".........................................d.d.d.d.d#f.#.#........................................................................................b.#0b.#0#K#6bz.#.#......#K#K#K#K.a#K.a.a.a#K.a.a.a.a#n.a#C.#.................................................................y.ybt.ybtaw.#.........................7.7.A.A.7beaS.4.#.#aK.A.A.AbA.AbAbA#3.#.5..........................................b.b.#K#0#Kb.b.#3.#....................#K#K.a.a#K..............................................bo#d#d#d.Oaw.#.#....................#j.y.y.y.y.yb6.c#j.c.c.cbb.#.#........................bt#r.1...#.#.5....bK.1.g.g.g.g.g.g.I.#................#Ub6b6b6b6b6b6b6b6b6b6#w...................................H.H.H.H.H#P.I.#aw....................................aRaRaR.taRaR.t.ta1.#aw............................#X#X#Xbgbg.k.#...............................c#S.c#S.c.c.c.cbH#S.cbH#maw................bEbEbYbYbYbEbYbY.6bYbYbYbYbYbYbYbYbYaFbq.4.#.#aw........................................................", +".......................................d.d.d.7.d.daA.#aw......................................................................................#0b.#K#0b.at#F.#aw........#K#K#K#K#K#K#K.a.a.a.a.a.a.a.a.aaS.#...............................................................y#z.ybt.ybW.#.#.....................7.7.7.7.n#3.#.#aw.......A.A.A.A.A.A.AaM.#.#..........................................b.#K#0#Kb.#K#K.N.#.#.................a.a.a.a.a#K.aaS.5........................................#dbobo#n#p.#.#........................#t#c#c#z.y#U#j.c#j#S.c.c.4.#bX.......................1bt#r...#aw.........1.1.1.1.1.1.g.v.#.#..............b6.g.gb6#Ub6b6b6b6b6b6b6b6b6.r..............................#t#t.H.Hbwaw.#aw....................................aRaR.taR.t.taR.t.Saw.#............................#X#X#L#L#Xbg#X.#aw..............................#j.c.c.c.c#S.cbHbH#SbH#S.jaw..................#y#y#ybhbEbYbYbY.X.X.Xbq.h.h.4.#.#.#.5..............................................................", +".....................................d.7.7.d.d.7#f.#.#....................................................................................#0b.b.b.b.b.bp.#.#aw..........#0.a.a#K.a#K.a#K.a.a.a.a.a.abo.a.s.#...............................................................y.y.y.y.y#F.#...................7.7.7.7#v.I.#.#.............A.AbA.A.A.AbA#Y.#..........................................b.#0b.b.b.#0b.b.#3.#.5..............#K#K#K#K#K.a.a.a.a.#....................................bo#dbo#d#i#F.#aw........................#j.1#z.y.y.1.c.c#j.c#j#j.V.#.#.......................1bt.1.5.#...............1.1.g.g.ga..#.#.................gb6b6#Ub6b6b6b6b6bTb6b6b6b6#G.r.K.........................H.H.H#taz.#.#aw.......................................t.taR.taR.t.t.S#g.#aw..........................#X#X#X#X#X#L#Xa6.#.#..........................#j#j.c#X#j.c.c.c.c.c.c.c#SbH#SbF........................bYbYbYbY#8.#.#................................................................................", +".....................................d.d.7.d.d.db#.#aw..................................................................................bAb.b.b.b.#Kbz.#.#.............a#K#K#K#K#K#K#K.a#K#K.a.a.a.a#n.a.a#Qaw.............................................................y.y.y.ybW.#.#...............7.7.7.7.A.M.#.#aw...............A.A.AbA.A.Aat.A.n........................................b.b.b.b.b.#K#K#K.b.#.#..............#K#K.a.a.a#K.a#K.a.a#p.#................................bobobobobf#F.#aw...........................t.y.y#cbt#X#j.c.c.c.c#m.I.#......................bt.1bt.C.#.................1.1.1.1a..#.#....................#Ub6b6#Ub6b6b6b6b6b6#tbTb6#G#GaOaw......................#t#t.Haz.#.#........................................aRaR.taR.tbn.t.S.I.#aw..........................#XbL#X#X#X#Xbg.k.I.#...........................c.c.....##m.c#S.c#S.cbEbH.cbHbH.j.#.....................6.6bE.6.6.4.#.5................................................................................", +"...................................d.d.d.d.7.d.d#3.#..................................................................................b.b.#0#0#0#6#3.#.#..............#K#0#K.a#KbG#K.a.a.a.a.a.a.a.abG.a.a.s.#...........................................................y.y.y.ybtaw.#...............7.7.7.7.7bd.#.#.....................AbA.AbA.AbAbAbAbeb2..................................#0#0b.#0#K#K#0b.b.#F.#..............#K#K.a#K#K#K.a.a.a.a.a#p.#..............................bobobo#d#d#Q.#aw..........................#jb6.y.y.y.t#j.c#j#j.c.cae.#aw....................bt#rbtan.#aw...............g.g.1.ga..#.#....................b6b6bK#Ub6#U#Ub6b6b6b6b6#Gb6b6bT.C.#....................#t.H.H#B.#.#........................................aRaRaRbP.taR.tbk.#.#aw..........................#X#X#X#X#X#Xbg#taw.#aw........................#j.......5.....c.c.c.c#S.c.cbE#S#S#m.#....................bYbYbYbY#8.#.#..................................................................................", +".................................d.d.d.d.d.7.d#f.#.#..............................................................................b.#0#0bAb.b.bp#F.#aw.................a.a#K.a#0.a#K#K.a.a.a#i.a.a.abG#n.a.ablaw........................................................#z.y.y.ybW.#.#...........7.7br.7.7.7.7#F.#.5.....................A.A.AbA.A.AatatbAbe#3................................b.b.b.b.#0b.b.#K.b.#.#............#K.a#K#K.a.a#K#K.a#K#K.abl.#............................bo#dboaQbobf.#.#............................#j#c#c.y.H#j#j.c.c#j.c.j.#.#......................bt.1#w.#.#...............1.1.1aC.K.#.#.....................g.g..aw.#az.r#Ub6b6b6b6b6b6b6#G#b.#.#....................#t#t.S#F.#.5......................................aRaRaRbnaRbP#qaw.#.#...............................t#X#X#X#X#X#9.5.#aw........................#j....aw..........#S.c.c.c#S.cbHbHbE.c.#aw................bEbEbEbYbY#y.#bX..................................................................................", +"...............................d.d.d.d.d.d.d.dax.#aw............................................................................#0bAb.b.b.b..b.#.#....................#K#0.a#K#K.a#K.a#K.a#K.a.a.a.a.abG.aboaJ.#.......................................................y.y#z#z.y#F.#...........d.7.7.7.7.7.7b#.#.#.........................A.A.A.AbAbAbA.Aat.baw............................b.b.#0#0b.b.#0#K#6.#.#............#K#Kb.#K.a#K#K.a.a.a.a.a.a.L.#..........................bGbobG#dbobo#s.#aw............................#t.y.ybt#j.c#j#j#j.cas.I.#......................bKbtbt#F.#............#r.1.1.1az.#.#aw.....................g..............bKb6b6b6b6b6#t#t#Z.#.#......................#G.Han.#aw........................................bP.tbPaRaRbk.#.#.5..............................bL#X#XbL#X#X#O.I.#aw........................#j....................#S.c#S.c#S.c#S.cbE.#.#.................6bYbYbEbY.#.#....................................................................................", +"...............................d.d.d.d.d.d.7.daA.#..........................................................................bA.s#0bAbAb.be#p.#.#......................#K#K#K#K#K#K#K.a#K.a.a.a.a.a.a.a.a.abG.ablaw.....................................................y.y.y.ybW.#.#.........7.d.d.7br.7.7.7.i.#........................at.A..bA.A.A.AbAbA.AbA#F..........................b.bAb.b.#0b.#K#0b..b.#aw..........#K.....##o#K.a#K#K#K.a.a.a.a#I.#..........................bobobo#dbGbo#p.#.............................H.y.y#c#t#j.c.c.c#j.c#g.#aw......................btbt#E.#.#......bt.1.1#r.1a9.#.#.#......................#U..................b6b6b6b6b6b6aO.#.#......................#t#t.H.#.#........................................aRaR.t.t.t#g.#.#.................................t#X.t#X#X#Xa6.#.#.....................................................cbHbHbEbHbE#Sbb.#.#................bEbEbY.6a4.#.#....................................................................................", +".............................d.d.d.d.d.d.d.d.d.i.#........................................................................bA#0#0bAb.b.aD#F.#aw.........................a#K#K.a#KbG#K.a.a.a.a.a.a.a#n.abo.a.abGbo#F...................................................y#c.y.y.y#C.#..........br.7.7.7.7.7.7.7.#.#.......................A.A....aT.AbAbA.A.AbAbA.i.#........................b.b.b.b.#0#Kb.b.#K#F.#..........#K....aw.....a#K.a.a.a.a.a#K.abS.#........................bobobobobo#dbob2.#..........................#Ubt#c.y.yaR#j#j#j#j.cbC.#.#......................bt#r#r.1btbt#r.1.1bKaCbM.5.#.#.5................................................b6b6b6b6aO.#.#.........................H#t#t.#.#........................................aRbPbPbPb3.#.#.................................t#X#X#X#X#X#g.#.#.........................................................c.c.c.c#SbHbq.#.5..............bY.6bYbEbY.Y.#......................................................................................", +"...........................d.d.d.d.d.d.d.d.d.d#3.#....................................................................bAbAbAbAb.bA#0.b.#.#.5..........................#K#K#K#K#0bG#K.a#K#K#K#i.a.a.a.a#n.a#n.a#nbS.#.................................................y#c.y#z#E.#.#.........7.7.7br.7br.7.7.7.#.#.......................A.........A.AbAbAbAatbA.i.#......................bAb.b.b.b.b.#0b.b.aD.#.#........................#K#K#K#K#K.a.a.a.L.#.......................abobobobobo#dbobl.#.........................y.g.g#c.y.y.H#j#j#j#j.0.#.#........................btbtbt#7.va3.2.#.#.#.#.5........................................................b6b6b6aO.#.#...........................H#t#tbs.#......................................aRaRaRbnbP#N.#.5..............................#X#X.t#X#X#X#O.#.#..........................................................#S#SbEbH.c.cbN.#................bYbEbY.6.6#y.#......................................................................................", +"..........................#f.d.d.d.d.d.7.d.d.7.i.#..................................................................bAbAbAbAbAbA#6bz.#.#..............................#0#K#K#K#K#K.a#K.a.a.a.a.a.a.a.abGbGbGbGbGbG#p.................................................y.y.y.yb2.#.5.......d.d.d.d.7.7.7.7.7br#F.#.....................A...........AbA.Aat.AbAat#3.#......................b.#0#0#0b.#0#0#Kb..b.#.5.........................a.a.a.a.a.a.a.abS.#......................bobGbobobobobobo.D.#......................#c#r#X#z.y.y.y#z#j#j.c.c.I.#aw......................btbKbtbta3.#.5..................................................................b6b6b6aO.#.#..........................#t#t.H.H.HaO......................................aRbPbPaR.tbR.#.................................t.t#XbLbLbL.I.#...............................................................c.c.cbE.9.#.#..............bEbE.6bEbYbY.Y.#......................................................................................", +".........................d.d.d.d.d.d.d.d.7.d.dax.#..............................................................atbAbAbAbA.s#0aM#F.#aw.................................a#K.a#K#K#K#K.a.a.a.a#K.a.a.a.a.a.a.a.a#nbGaJ.#.............................................y.y.y.y#i.#.#.........7.7.7.7br.7.7.7.7.7aA.#.................A.7..........at.AbAbAbAbAbAbA.#.#....................#0bAb.b.#0b.#K#0b.#Kbz.#..........................#K#K#K.a.a#K#K.a.a.#......................bobobGboboaQbobobobl.5..................#d.y#X#j#c#c#c.y.yb6#j#jae.#.#........................btbt.1bt.O.#....................................................................b6b6b3.#.#........................#t..#t#t#t#t.H.Hbs..................................bPaRaRaRaRaRb3.#..............................#X#XbL.t#X#X#X#F.#........................#j....................................#S#S.c#S.4.#bX...............6bYbEbEbE.6bh.#......................................................................................", +".......................d.d#f.d.d.d.d.d.7.d.d.d#f.#............................................................bAbAbAbAbA#0#0aA.#.#......................................#K#K.a#K#K#K#K#K.a.a.a.a.a.a.a#n.abobobG#nboaSaw..........................................#c.y#c.ybW.#aw.......d.7br.7.d.7.7.7.7.7br#f#F...............7.A............bA.A.A.A.A.AbA#v.#.#................b...b.b.bA#0b.b.#0b.#0b.bz.#...........................a.a.a#K#K.a.a.a.a#F.#.................abGbGbobobobG#d#d#d#d#d#Q..............#d#c#caR#L.H.y.y.y.y.y#c#U.V.#.#........................btbt#rbt#rbtaI.5.........................................g.g....................b6b6b6.C.#........................#t....#t#t#t.H#t#t.H#B................................aRaRaRaRbP.taR#V.5.........................t.t.t.t.t#X.t.tbL.x.#......................#L..........#j#j#j.......................cbHbE.j.#.#................bEbEbYbYbYbYbY.X.5...............................G....................................................", +"......................#f.d.d.d.d.d.d.d.d.d.7.d.d#3#F......................................................bAbAbA.AbAbAbAbe#3.#.#.........................................a#K#K#KbG#K.a#K#K.a.a.a.a.a.a.a.a.a.abG.abobo#3.........................................y#c.y#c.y#C.#.........d.7.d.7.7br.7.7.7.7.7.7#v#Y.........A.A.A...5.........AbAbAbAbAbA.AbAaM.#aw............#0bA....b.b.b.#0#0b.b.#K#0b.#6blb.........................#K#K.a.a.a.a#K.a.aaS.#............bobo..#nbGbobo#dbobGbobobobo#da7bf....#d#c#c#c#c.jbg#L#t#c.y.y.y.y.y.y#i#C........................bt..btbtbtbt.1btaI.K.....................................g.g....................b6b6b6b6.#.#....................bT#t....bz#t#t#t.H.H#t.H.H#t#U..........................aR.HaRbPaRaR.tbP.tb3.x.....................t.t#X#X#X#X#X#X.t#XbL#g..................#j#j.....5....#j#j#j.c.kaf...................c.cbn.I.#..................bEbEbEbEbEbYbEbY.Xae.........................Gbj......................................................", +".....................d.d.d#f.d.d.d.d.d.d.d.d.d.d#f.#...................................................AbA.AbAbAbAbAbA#Y.#.#aw............................................#K#K#K#K#K.a.a.a.a#i.a#n.abGbo.abobG#nbobGbGbf.#......................................#c.y.y.y#E.#.#.........d.d.7br.d.7br.7.7.7.7.7.7.7.7.7.7.A#6.7...#...........A.A.A.A.A.AbAbAaT.#..........bAbA....aw#s#0b.bAb.b.b.#0b.b.#Kb.b.#h..aw....................#K.a#K#K.a.a.a.a.a.abl.........abo.a....bo.abobGbobGaQbobo#d#dbo#c#d#c#c#d#d#d#nbs#L#j#j.1.y#c#c#c.y.y.y.y.y#7..................#zbt....btbtbK#rbt.1#rbt#7...............................1#U#U..aw................b6#U#Ub6b6ar.#................b6#t#t...5.#...H.H#t#t#t.H#t.H.H.H.H.HbT#t...............HaR.HaRaRaRaRaRaRaRaR.taR.k.H.............t.t.t...t.t.t.t#X#X#X#X#X#X#W............#X#j#j....aw....#j#j#j.c#j.c.Vaw...............c#S#S.4.#aw................bEbE.6.6bYbYbEbYbY.6bY#m................bYbY.G....aw....................................................", +"....................#f.d.d.d.d.d.d.d.d.d.d.7.d.dbrb#aw..............................................atatbA.A.AbAbAbebz.#.#.................................................a#K.a#K#K.a#K.a.a.a.a.a.a.abG.a.abGbGbo#nbGbobSaw.....................................y.y.y.y#Q.#bX.......7.7.d.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.A.i.#.#...........A.A.AbAbAbAat.A.AataA#Q..bAbAbAbA..aw.#....#0b.bAbAb.b.#0#K#0b.b.bp.#.#......................#K.a.a#K#K.a#K.a.a.a.a.a.a.a#n.a#na3.#awbobGbobobo#dbobobobo#dbobo#d#dbo#c#cbfar.k#X#X#j.1.y.y.y.y#c#c.y.ybt.y.y.y#c.y.y.y.ybtbt#z...5#ybtbtbt#rbtbtbKbt.1bt#zbt.....................g.g.g.....#..............b6#Ub6b6b6b6b6#w.#............#t#t#t#G#y.#.#....#t.H#t.H#t.H#t.H#t.H.H.H.H.H.H.H.H.HaRaRaRbP..#HbPaRaRbPaR.taRaR.taR.t.t.taRaR.t.t.t.tbn.5#g#X#X#X.t#X#XbL#X#X#X#X#X#X#Xbg#j#L#L.t.5.#.........c.c#j#j#j#j#j.#...............c.c.j.#.#..................bYbEbEbEbEbYbYbYbY.6.6bYbYbYbYbYbYbY.G.G.G.Gajaw.#......................................................", +"..................#f.d.d#f.d.d.d.d.d.d.7.d.d.7.d.d.d.i...........................................A.AbAbA.AbAbAbAaM#F.#aw....................................................#K#K#K.a#K.a#K.a.a.a.a.a.a.a.abG#n.a.abo.abobo#p..................................#c#c#c.y#c#F.#.........d.d.7.d.d.d.7br.7.7.7.7.7.7.A.7.A.A.i.#.#...........AbAatat.A.A.AbAbAbAbAbAbAbAbAbAbe.#.#aw....b.bAb.b.b.b.#0b.b.b.b.#I.#.#.........................a#K#K.a.a.a.a.a.a.a.a.a#n.abGbS#F.#aw..bGbobobobobG#d#dbo#dbo#d#c#d#c#c#dbf#Fbi#X#L#j#L.g#c#c.y#c.y.y.y.y.ybtbt.y#z#zbtbtbtbtbt.4.#aw..bt#rbtbt#r#r#r.1#r.1.1.1#r.1.1.1.1.1.1.1.1.g.g.g#b.#.#.................gb6b6b6b6b6b6b6aC#Bb6b6b6#t#tb6#G#Paw.#aw......#t#t.H#t.H#t.H.H.H#t.H.H.H.H.H.H.HbP.H.H.p.#.##HaRbPaRaRaRaRaRaRaR.taR.t.t.t.t.t.t.tbi.#.#.V.t.t.t#X.t#X.t#X#X#X#X#X#X#X#L#Xbg#g.#.#........#j#j#j#j.c.c.c.c.x.#...........cbH.c.#.#....................bEbYbY.6bY.6bEbEbYbYbYbYbYbYbYbYbYbYbjbj.P.5.#.#........................................................", +"...................d#f.d.d#f.d.d.d.d.d.d.d.d.7.d.7.dbr.i.....................................A.AbA.A.AbAatbA#var.#.#..........................................................#K#K#K.a.a.a#K.a.a.a.a#n.a.abGbobGbGbo.aboboaJ#F.................................y.y#c.y#E.#.#.........7.d.7.7.7.d.7.7.7.7.7.7.7.7.A.7#f#F.#.#.............AbA.A.AatbA.AatbAbAbAbAbAbAbebz.#.#........b.#0b.#0bAb.#0#0b.#KaM.#.#.............................a#K.a#K.a#K.a.a.a.abGbG.aaS.#.#......#nbGbobGaQbGbo#daQ#dbobobobo#dbo#i#Fa6bg#X#X#X#jb6.y#c.y.y.y.y.y.y.y.y#zbtbt.y#zbtbtbtb2.#.#....btbtbtbKbtbtbtbK#r.1bK.1.1#r.1.1.1.1.1.g.1.1aCar.#.#................b6#U#Ub6#Ub6b6b6b6b6b6b6b6b6b6#tb6bK#F.#aw........#t#t#t#t.H#t#t.H.H#t.H.H.H.H.0.H.HbPaRan.#.#....aRaRaRaRaR.t.taRaR.taR.t.t.taR.t.tbR.#.#....#X#X.t#X.t#X.t#X#X#X#X#X#X#Xbg.kbF.#.#..........#j#j#j#j#j#j#j#j.k.I.........c.c#Saw.#........................bEbEbEbYbYbYbYbYbY.6bYbYbYbYbjbjbY.G.X.#.#aw..........................................................", +"................#f.d.d#f.d.d.d.d.d.d.d.7.d.d.d.7.d.7.d.dax...............................A.A.A.A.A.Aat.AbA.M#F.#aw............................................................#KbG#K.a.a#K.a.a.a.a.a.abG#n.a.a.aboboboboboboa7aw..............................#c#c.y.y#Q.#.5.........d.7.7.7br.7.7br.7.7.7.7.7.7.7ax.#.#aw.............A.A.AbA.AbA.AbAbA.AbAatbAbAaM#F.#aw..........bAbA#0b.b.b.b.b.#0bp.#.#..............................#K.a#K.a.a.a.a.a.a.a.a.a#p.#.#........bGbobGbobobobobobobo#d#d#c#c#daE#F#y#j#L#j#j#j#L.H#c.y.y.y.y.y.y.y.y.y.y.y.ybtbt.y#n#F.#.#......bt.1btbt.1.1.1#r#r#r#rbt.1.1.1.1.1.1.g.1.ga9aw.#aw.................g#Ub6b6#Ub6b6b6b6b6b6bTb6bTb6#tb6az.#.#aw..........#t#t.H.H#t.H.H.H.H.H.H.H.H.HbPbP.0#P.C.#.#......aRaRbPaRbPaRbP.t.taR.taR.t.t.t.tbR.#.#.......t.t#X.t#X#X#X#X#X#X#X#L#j#X#O.I.#aw............#j#j.c#j#j.c.c.c.cas.V...c.c#S..aw.#..........................bEbY.6bE.6bEbEbYbYbYbYbYbYbY.G.G.P.h.#.#..............................................................", +".................d#f.d.d#f.d.d.d.d.d.d.d.d.d.d.7.d.7.7.d.7.d.n.....................7.A.7.A.A.A.A.A.AbA#v.i.#.#..................................................................#K#K#K.a.a#K.a.a.a.a.abGbGbobo.abGbobobobobobobl.5...........................y.y.y.y.y#C.#.............d.d.7.7.d.7.7br.7.7.A.7aD.i.#.#.................A.A.AbA.A.A.A.AbA.AbA.A.N#3.#.#..............b.bAbAb.b.b.b.#Kbp.#.#................................#K.a.a#K.a.a.a.a.a.a.O#F.#.#............#nbGbobobobo#dbobobobo#dbo.3.#bNbL#X#X#X#X#X#j#j.y#c#c#c#c#z.y.y.ybt.y.y.y.ybt#iaw.#aw..........#r#rbtbtbtbtbKbt.1.1bK#r#r.1.g.g.1.1.1#5.#.#.5..................b6.g.gb6b6b6b6b6b6b6b6#t#Gb6b6#t#Z.#.#................#t#t.H#t#t#t.H.H.H.H.H.H.H.H.Haz.I.#aw........bPaRaRaRaRbnaRbP.taR.tbnaR.t.S.I.#.#........#X.t#X#X#X#X#XbL#X#X#X#X#Xbk.#.#..................#j#j#j#j#j#j#j.c#j.c#j.c.c.f.#.#............................bEbY.6bYbYbYbE.6bY.6bYbYbYbYbYaj.I.#aw................................................................", +".................d.d#f.d.d#f.d.d.d.d.d.d.7.7.7.d.7.7br.7br.7br.7#vbr.........7.7.A.A.A.A.A.A#6.AbAbA.M#F.#aw.......................................................................a.a#K.a.a.a.a.a.a#n.a.a.a.abo#nbGbGbGbobo#d#d#C..........................#d#c#c#c#i.#.#.............d.7.d.d.7.7br.7.7.7.7b#.#.#aw...................A.A.A.A.AbAbAbA.AbAbe.u.#.#aw................bAb.b.b.#0#0#0bp.#.#...................................a#K#K.a.a.a.a.a.aaS.#.#aw..............bGbobobG#dbobo#d#d#d#dbfb2.#aw.t#X#X#X#j#j#j#L#L#Z.y.y.y.y.y.y.y.y.y.y#z#zbtaEaw.#aw..............btbt#r#r.1#r.1#r#r#r.1.1.1.1.1.1aC.C.#.#.......................gb6b6#Ub6#U#Ub6b6b6b6b6b6#t.raO.#.#....................#t#t.H.H.H#t.H#t.H.H.H.H#P#N.#.#..............aRaRbPbPaRbPbnaR.taR.t.t.f.#.#aw............#X.t.t.tbLbL#X#X#X#X#W.I.#.#....................#L.c.c#j.c.c.c#j.c#j.cbb.I.#.#................................bEbYbE.6.6bYbYbYbYbYbYbYaB.4.#.#....................................................................", +"...............d#f.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.7.d.7.7.7br.7.7.7.7.7.7.7.A.7.A.A.A.7.A.AbA.A#v.i.#.#............................................................................#K.a.a.a.a#nbG.a.a#n.abG.abG#n.abobobobobobobf#F.........................y.y.y.yaE.#aw...............7.7.7.d.7.7br.7b##F.#.#.......................A.A.A.A.A.A.AbA#vaA.#.#aw......................#0bAbAb.b.bp.#.#.......................................a.a#K#K#K.aa7#C.#.#....................bGbobo#dboboaQbobo#s#F.#bN.tbg#X#X#X#X#X#X.k#D.#aE.y.y#c#c.y#z.ybtbt.y.y.v.#.#....................btbtbtbt#rbt.1.1bK#r.1.1.1.1#5.#.#aw..........................#Ub6#Ub6b6#Ub6b6b6b6b6b6#w#F.#aw........................#t#t#t.H#t.H.H.H.Hbwan.#.#aw..................aR.t.t.t.tbP.t.t.t#qbN.#.#..................#X#X.t#X#X#XbL#9#g.#.#.5........................#j#j#j#j#j.c.c.c#m.x.#.#.5.....................................6bYbYbYbY.6bY.6bY.P.Y.#.#aw......................................................................", +"...............d.d#f.d#f.d#f.d.d.d.d.d.d.d.d.7.d.d.d.7.dbr.7.7.7.7.7.7.7.7.A#6.A.7.7.A.A.A.A.A#Y#F.#aw..............................................................................#K.a.a.a.abG.abGbo.abo.abo.abGbo#nbobobobobobobSaw.....................y#d#c#c#cb2.#....................bdaxaxb#bz.#.#.#.............................A.AbA.AbAbpbz.#.#aw..........................b.b.b.b.aK.#.#........................................#K#K.a.a.sbl.#.#.5........................bobGbobobGbf.3#F.#.#..bg#X#X#L#j#X#L#j.k.I.#aw.....y.y.y.y.y.y.y.ybW#F.#.#........................bt.1#rbK#rbK#r#r.1#r#r#5aw.#.#.................................gb6b6b6b6b6b6b6b6.rbs.#.#.5.............................Sbw#t.H.H.Haz#N.#.#aw.........................0aRaRaR.tbPbibN.#.#.5.......................t#X.t.t#qbk.#.#aw..............................#j#j.c.c#jbb#y.#.#aw...........................................cbEbEbYbYbY#8.h.#.#aw..........................................................................", +"..............#f.d.d.d.d.d.d.d#f.d.d.d.d.d.d.7.7.7.7.7.7.d.7.d.7.7.7.7.A.7.7.7.A.A.7.A.A.A.n.I.#.#.....................................................................................a.a.a.a.a.a.abG.abo.abobobGbobG#dbGbo#d#d#d#d#Q.....................y.y.y.y.y#F.#....................................................................bp#3.#.#.#..................................#0bp#3.#.#..............................................bW#C.#.#aw................................bWb2#F.#.#aw....#X#j#L#X#X#L#X#X.k.5.#aw........bf#b.laI.lb2.#.#.#................................#.aQ#r.1.1bva..K.#.#.#........................................b3b6b6b6#t.r#Z.I.#aw......................................aL.#.#.#.#..................................bU#g#g.#.#.#.................................x.5.#.#.5.......................................x.4.#.#.#.5..................................................aH#y#y.#.#.#.5..............................................................................", +"...............d#f.d#f.d#f.d.d.d.d.d.d.d.d.d.d.d.d.d.7.d.7.7.7.7.7.7.7.7.7.A.A.7#6.A.A#v.u.#.#.5.........................................................................................a#n.abG#nbG.abo.abobGbGbobGbobobo#dbobobobo#d#C..................#d.y.y.y#i.#.#....................................................................................................................aw..........................................................................................................#X#X#X#X#X#L#X#jbb.5.#aw..................................................................aw.#.#.#aw..................................................a1#NaO.#.#aw............................................................................................................................................................................................................................................................................................................................................", +"..............#f.d.d.d.d.d#f.d.d.d.d.d.7.d.d.7.7.7.d.7.7.d.7.7br.7.7.7.7.7.7.A.A.A.7#Y#F.#aw..............................................................................................bobo#dbobo.abobGbobobo#dbobo#dbo#d#d#d#dbo#d#i#F.................y.y.y.y.l.#.5...............................................................................................................................................................................................................................t#Xbg#j#j#X#j#L#O.#.#.5........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"..............#f.d#f.d#f.d.d.d.d.d.d.d.d.7.7.d.d.d.7.7.d.7.7br.A.7.7.7.A.7.7.7.7.n#3.#.#.....................................................................................................y.y#c#daQbG.abobobobo#dbobo#dboboboaQ#c#c#d#E.5.............y.ybt.y.y.2.#..............................................................................................................................................................................................................................#X#X#X#j#j.c.c#j.V.#.#............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"...............d.d.d.d.d#f.d.d.d.d.d.d.d.d.d.d.d.d.d.7brbr.7brbr.7.7.7.7.7.7.n#3.#.#.5.........................5aL........ahaL............................................................aLaf.1bt.ybobobobo#d#d#d#d#d#d#c#c#d.y#d#d.y.ybt#Zah...........1.1.g.1bt.4#F..........................................................................ah.m..........aLa8af...............................................................................................................................t#X#j#LaHbX.P.c.Wawaw......................................................................................................................................................................aL.ma8a8a8...............................................m.ZbDbDbDbVa8..................................................................................................................................................................................................................................................", +"...............d#f.d#f.d.d.d.d.d.d.d.d.d.d.d.7.7.7.7br.7.7.7.7.A.7.7.7.A#vaA.#.#.5..............................a8aa......a8#Rbx....ahaLaL.maLaLaL..ahahaL.m.m.m.maL....................a8aqaqaub6#r.y#dbo#bbsaQ.ybt.ybyaI.y.y#c.y#i#Zan#Z#i#g....bXahaZbM.YbM.x.p.5.5ah..........bX........bXaLaL.maLaLah......ahaLaL.maL......................bVbDao.........ZaqaW##......ahaLaL.maLaLah........ahahaL............ahahaL............ahah................ahah............bXahaLaLaLaLah.........t#X#X#X#jbba8b1bmahbXah..........bX....ahahaL.m.m.m.maL....ahahaLaLaLaLah......ahahaLaLaL............ahahaLaLahah........ahaL..............ahahaL........ahahaLaLaLaLah.....................m.B##a#abbcaq........ahah........ah.......................Zab.w.wababab##......ah..........ah............ahaL..............ahahaL..........ahaLaL..........ahahaLaLaLaLah......ahah........ah............................................................................................................................", +"..............#f.d.d.d#f.d#f.d.d.d.d.d.d.d.d.d.d.d.7.d.dbr.7br.7.7.7#faA.#.#aw..................................aPaP....bD#ka#......af.o.obJ.oadad##..#kad.QaibJ.oadbx..................af#k.oaobx.gbt#d#d#..Z#AbTbtbK.W.R#Sbt.yaza8bib0.Jbm#u.4....bJaYbVb5b4#J#JbcahaLbx........aqbx......a8.o.obJ.o.oadbx....af.o.obJ.obD....................afao.Qaa.....Zaq#Ta5bZ......af.o.obJ.o.oadbx..aLaLa5ad#Taq......ahaLa5ad#Taq..........aLaib7..........bX.m#Tadao.Z........a8#k.o.o.o.oaWa#..#X#X#XbL#X#X#j.RaZa#.Zaf...mbV........aqbx....a5ad.QaibJ.oad##..af#k.o.o.o.oaWa#....a8#k.o.o.o.B#1......ah#Tbxbx##bxaabx.....m#lbD##........ah.m#TadaWaf......a8#k.o.o.o.oaWa#................aL.ea#........aPbc.......Z.Z#k......aLbx....................aq##..................bXaa.......m.mad.........m#lbD##........ah.m#TadaWaf......ah...o.oai.Q......a8#k.o.o.o.oaWa#....af.Z#k......aLbx..........................................................................................................................", +"..............#f.d#f.d.d.d.d.d.d.d.d.d.d.7.d.7.d.7.d.7.7.7br.7.7bd#p.#.#aw........................................aPaW#lala#........a8##...................Qb7bx........................bD###R.B#R..bt.y#daz.zaqbIb6.g.x.Jbgbt.FafbnavbY#j.caq#4af.....6aqab#a.6as.Qaf.Zbx........#l##......a8bx.................mbx......#lau...................Zal.oaW....#lab#TaW##......a8bx..............aL#R##....aabx.....maa##....aaa#........af#RbD#R......aL..a###.....8a#.......m##..........bx#X#L#X#X.t.t#j#jbmbVbx......af#T#l......aq##.........Qb7bx.........m##.................m##......aobc.......m.o.................m#R.Bad.......maqa#bZ....aaa#.....m##.............................Za#............aq##....a8abbV.......Za#....................#la2ai.QaP.............Qao......afao.8.........m#R.Bad.......maqa#bZ....aaa#.....Qbx......#R##.....m##.................mab.Z.......Za#..........................................................................................................................", +"................#f.d.d#f.d.d.d.d.d.d.d.d.d.d.7.d.7.7.7.d.7.7bd#3.#.#.5..............................................aP.e##..........afaoaqbV.Z.............Z#1bZ......................afaWbZ..bc.e....bt.yaz.zaBaPbQ#G.fbQ#j.1#ebU#x.Hb6#U#UbU#T.9af..#taqabbj#t.Wah..bD#laP#laqaq.Q##......afaoaqbVbV..........a8aobVbDbDaqbx...................Zb7#xbcaa#l.Q##bcaW##.......ZaoaqbVbV...........mbD.ZbV..........a8bD.Z.Z..........a8aWbxaP#k......a8bx...................mbcbV.Z.Z....#jbg#XbL#X#X.t.kbFafbDbx......afbZaob7....aP##.........Z#1bZ........a8bcbVbVaf...........m.B.ZbDbDbVau##....a8.QaPafa8..........afa#...Q......a8##................a8bcbVbV.Z......................bVa#............aqaG....af##...Q....aqa#....................#la2a5aWaobx...........eai.o...Z..b7bJ........afa#...Q......a8##................afaq.ZbV..........a8bcbVbVaf...........m##...Q....aqa#..........................................................................................................................", +"..................#f.d.d#f.d.d.d.d.d.d.d.7.d.d.d.d.d.d#fb##F.#.#.5..................................................#l.wbZ...........Z.8auau#kbx..........afao##......................bV.Q.B#Abc.Baa....#c#Eaj#jbT.Q#8#u#J#S.ga6buacb6#U.g.gbUbI#2a0a.bTaq.wbj#tanah..aq########abaW##.......Z.8auau#kbx........a8auauaWb7##bx.......1.1.1......afb7ak.Bb7ai.w##aPalbZ.......Z.8auau#kbx...........waua5.Q.B.........wau#k.Q.B......afau#T..aq#R....a8bx....a8af.Z........a8albJauaY.wb8.c#L#X#XbL#Xa6#F.5.ZbDbx......a8##..aoao...Q##........afao##........a8albJbJbJab.........mbJbJbJaPaGbx.......m.o####aba#.......maoau..aq.o.....Z#R................a8albJbJbJab....................bVaG..........bVaPbx....af##..aW.Q..aPbx....................#l##bZbZ####..........al..aq..bV##aPau.......maoau..aq.o.....Z#R..................#RauauaobD......a8albJbJbJab........a8##..aW.Q..aPbx..........................................................................................................................", +".....................d.d#f.d.d.d.d.d.d.d.d.d.7.7#fax#3.#.#aw........................................................aq.w............bVbx..................afaobx....................a8#1bxbx####bJ#T......#.ajbg.gbbaq#Ab4#S#U.ra8amb6.g.gbKa8am#2#U.pb6bVabbYbT.4bX..bDbx.........Q##......bVbx................a8bx....aPau....b6#U.g.g.g.g#UbT.haobZ...Q.o##..aqb7##......bVbx........................auao##............auao##..a8.BabaWaW.Ba5....afau......##.e.o......a8bJ##..#aapbY#j#LbLbL#9.4.#.#....bVa#.......m##....#l.B.Q##........afaobx........a8bJbZ...............m##....bcal........a8.o...............mau.o#Tb7.Q....bVal........aL......a8bJbZ..........................#l.Q..........bV.obx....a8##....aoao.Qbx....................aq##..................al..aqbD..bZbVbJ......a8au.o#Tb7.Q....bVal........aL................#la#....afbJbZ...............mbx....ao#1.Qbx..........................................................................................................................", +"........................bd.d.d.d.d.d.d.d.daxaA#3.#.#aw...............................................................Zab.............Z.eaqbDbVa8.m.........m.B##.....................m##..........aq#R.......j.t#r.g.zbD.8#S.g.gb3ai.Vbia1.W.Xa#.H.1.1#U.Z.8.6b6.5.5...Zbx.........Q##......bVaWaqbDbVa8.m.......m##......#l#a.Hb6b6.1.1.g.gb6#tbUaX.q...QaGbZ..bVao##......bVaWaqbDbVa8.m....aL.Zaf..bV.Z..##...m.Z.Z..bV.Z..##...m##........bV#R....aiaqaf..bDbVab......a8.Q#A.EbuaH.x.c#j#Xa6.#.#aw.......Za#.......mbx.......Qal##.........m.B##.........m.Q.QbV.Za8a8......aL##......aqab......aLad............ah..##......aPad.....Baqafa8.ma8.o....a8.Q.Q.Z.Za8a8.....................ebDbDafaf.ZaWa#......aLbx......aoaPbx....................aq#Taqaq.Za8.m........#1....aob1...Z.o....aL..##......aPad.....Baqafa8.ma8.o.....mbV.Z..bVbVbx....a8.Q.QbV.Za8a8......aL##......aoaPbx..........................................................................................................................", +"............................aA.i.i.i.i.#.#.#.#.........................................................................8...............8aubJbJ.oadbx.........obx......................a#.............w......aX.Pbt#rbKbh.8#j.1.1.1#jaYbh.z#2ac#j#U#r#r.r#B.w#S.g.5aw....#R........alaa.........8aubJbJ.oadbx......aa......agab#G#U#U.g.1.1.g.g#P#HaY.q.t.kav.......o#R.........8aubJbJ.oad##....bxau.oa5#Ra#......a#au.oa5#Ra#......a#...........w......abbJad..bZa#.......f#Jaub4b4au#k.qbba3.#.#...........e#R........aa........au#R...........obx...........oau.obJ.oaWa#.......8........bJ........ab..............#R..........bJ......#RaubJaba#bx.......oaubJbJ.oaWa#....................#R.8.o.obxa#...........8........bJ.w.....................eabbJaubJ.o.oaa..............##....ab......#R..........bJ......#RaubJaba#bx.......w.oa2aubx##.......oau.obJ.oaWa#.......8........bJ.w..........................................................................................................................", +"................................................................................................................................................................................................................#d.ybtb6#j#jbtbtbtbt.1bgaNbg.1.1bt#z.ybt#t#jaRa.aw#F.......................................................H#S.tb6.g.1.g.g.1.gb6aR.6.6.H.H.H#P..........................................................................................................#X.cb8#a#a#ab8.UaY.5#FbX......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"..................................................................................................................................................................................................................bo.y#z#zbt#c.y.y.ybt.ybtbt#zbtbt.y.y.ybt.1#r#e.#........................................................#Ub6.g.g.g.1.g.g.g.g#Ub6bT#t#G#t#G#t#t#b...................................................................................................t.t#X#X#Xbg#j#j#VbFaw.5..........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"....................................................................................................................................................................................................................bo#d#c#d#d#d#c#c#c.y.y#c.y#c#c.y.y.y#z.y.yaI.#.......................................................1.1.1.g.1.1.g.1.g.1.1.g#Ub6b6b6b6b6b6b6b6an............................................................................................aR.t.t.t.t.tbL#X#W.Kaw.#..............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"......................................................................................................................................................................................................................#dbo#dbo#d#d#d#c#c#c#c#c.y#d#d#c.y.y.y.y#5.#.......................................................1.g.1.g.g.1.g.1#U#U.g.g.g.g.g.g#U#U#U#Ub6b6.I.......................................................................................t.t.t.t.taR.t.tbT.4.#.#bX................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"..........................................................................................................................................................................................................................bo#dbo#dbobobo#c#d#d#d#c#c.y#c#c#c.yb2.#.......................................................1.1.1.1.1.g.1.g.g.g.g.g.g.g#U#U.gb6b6b6b6b6a0.#.................................................................................HaRaRaRaRaRaR.t.Sbk.#.#.5....................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"............................................................................................................................................................................................................................#dbo#d#d#d#d#d#c#c#d#d#d.y.y.y#d#cb2.#......................................................bt.1.1.1.1.g.1.1.1.1.g.g.g.gb6b6.g.g.gb6#U#Ub6aO............................................................................aRaRaRaRaRaR.t.t.Sbk.#.#aw........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"..............................................................................................................................................................................................................................bobobo#dbo#d#dbo#c#c#d#d#d#c.y.y#i.#.........................................................1.1.1.1.1.1.1.g.g.g.g.g.g.g.g.g.gb6.gb6b6#U#Uar.......................................................................HaRaRaRbPaRaRaRb3bR.#.#aw............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"................................................................................................................................................................................................................................bobo#dbo#d#c#d#d#c#c#c.y#d#c#d#c.3aw.......................................................1.1.1.1.g.g#r.1.1.1.g.g.1.g.g#U.g.g.g.gb6b6#Ub6aO...............................................................HaRaRbPbPaRaRbPaR#qbN.#.#.5................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"..................................................................................................................................................................................................................................bobo#dbo#d#d#d#d#d#d#d#d.y.y.y.y#C.........................................................1.1.1#r.1.1.g.g.g.1.g.g.g.g.g#U#U#Ub6#U#Ub6b6#U#Z.......................................................H.H.HaR.H.H.HaRbP#PbU.I.#.#.5....................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"....................................................................................................................................................................................................................................bo#dbobo#c#d#d#c#c.y#d#d#d#c#cbO.#.........................................................1.1.1.g.1.1.1.g.1.g.1#U.g.gb6b6.gb6b6.g#Ub6b6b6aCa9..........................................#t#t.H.H.H.H.H.HaRaR.Hb3bR.#.#aw..........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"........................................................................................................................................................................................................................................#d#cboaQ#c#d#d#d#c#c.y.y.y#c#C.5.........................................................1.1.1.1.g.g.1.g.g#U.g.g.g.g.g.g.g#Ub6b6b6#Ub6b6b6bK.r............................#t#t#t.H.H.H.H.H.H.HbP.HaR#Pan.I.#.#.5..............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"..........................................................................................................................................................................................................................................#d#d#d#c#c#c#c#c#c#c#c.y.y#i.#............................................................aC.1.1.g.g.1.g.g.g.g.g#Ub6b6b6.g#U#Ub6#Ub6b6b6b6b6b6b6b6b6b6b6b6bT#G#t#t#t#t#t#t.H#t.H.H.H#t.H.H.H#PbB.C.#.#aw....................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"............................................................................................................................................................................................................................................#dbo#d#d#d.y.y#d.y.y#c#c.y#Qaw..............................................................az.1.1.g.g.g.g.g.g.g.g.g.gb6b6b6b6b6b6b6b6b6bTb6bTb6#t#t#t#t#G#t#t#t#t#t#t.H#t.H#t.H.H.Haz.Waw.#.#aw..........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"..............................................................................................................................................................................................................................................#d#c#d#d#d#d#c#c.y.y.y.y#E.#..................................................................a0#5bv.g.g.g.g.g.gb6.g.g.g#Ub6b6b6b6b6b6b6b6b6bTb6#G#G#tb6#t#t#t#t.H#t#t#t.H#B#b#N.#.#.#..................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"................................................................................................................................................................................................................................................#d#c#c#d.y#d.y#c#c.y#c.y#C.5........................................................................bs#5#.#U#U.gb6b6b6b6b6#Ub6b6b6b6#t#G#t#G#tb6#t#t#t#G#t#t#t#Baz#NbN.#.#.#.5........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"................................................................................................................................................................................................................................................#d#d#c#d#c#c.y.y#c.y#c.y#E.#..................................................................................araOaOa.a.a0a0#Ub6b6b6b6b6b6b6#t#wa0az#ZaOaO.I.#.#.#.5..................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"................................................................................................................................................................................................................................................#c#c#d#c.y#d#d#c.y.y.y#c.y#F.5...................................................................................................#.#.#.#.#.#.#.#.#.5..................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"................................................................................................................................................................................................................................................#d#c#d#d.y.y.y#d#c.y.y.y.ybW.#........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"................................................................................................................................................................................................................................................#c#d#c#c#d#d#c.y.y.y.y.y.y#i.#........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"................................................................................................................................................................................................................................................#c#d#d#c#c.y#d#c#c.y#c.y.y.y#Caw......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"................................................................................................................................................................................................................................................#c#c#c#c#c#d.y.y.y#c.y#c.y.yby.#......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"................................................................................................................................................................................................................................................#d#d#d.y#c#c#d#c.y.y.y#z.y.y#i.#......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"................................................................................................................................................................................................................................................#c#c#d#d#d#d.y.y#c.y.y.y.y.y.y#Caw....................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"................................................................................................................................................................................................................................................#d#c#c.y#c#c#c.y#c.y.y#c.y.y.y#Q.#....................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"................................................................................................................................................................................................................................................#c#d#d#d.y#d.y#c.y#c#c.y.y#z.yaI.#....................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"..................................................................................................................................................................................................................................................#c#d#d.y#d.y#d.y.y.y.y.y#z.y.y.#....................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"..................................................................................................................................................................................................................................................#d#c#c#d#c#c.y#c.y.y.y.y.y.y.y#C.#..................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"..................................................................................................................................................................................................................................................#d#d#c#c.y#d.y#c#c#c.y.y.y.y.yb2.#..................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"..................................................................................................................................................................................................................................................#c#c#d.y#c.y#c.y.y.y#c.y.y.y.yaE.#..................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"..................................................................................................................................................................................................................................................#d#d#c#d#d.y#d.y.y.y.y.y#z#z.y#E.#..................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"....................................................................................................................................................................................................................................................#c#d#c#c#c.y#c.y.y#c.y.y.y.y.y.#.5................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"....................................................................................................................................................................................................................................................#c.y#d.y#d.y#c.y.y#c.y.y#z.y.y.#.#................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"....................................................................................................................................................................................................................................................#d#d.y#c.y#c.y#c.y.y.y.y.y.y.y#C.#................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"....................................................................................................................................................................................................................................................#c#d#d#c.y#d.y.y.y#c.y.y#z#z.yb2.#................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"......................................................................................................................................................................................................................................................#c#c#d#c.y#c#c.y.y.y.y.y.y#zb2.#................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +".......................................................................................................................................................................................................................................................y.y#d#c.y.y#c.y.y.y.y.y.y.yb2.#................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"......................................................................................................................................................................................................................................................#d#d.y.y#c#c.y#z#c.y.y.y.y.yb2.#................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"........................................................................................................................................................................................................................................................#d#d.y.y.y#c.y.y.y.y.y#z.yb2.#................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"........................................................................................................................................................................................................................................................#c#c#d#c#c.y.y.y.y#z#z.y.yb2.#................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"...........................................................................................................................................................................................................................................................y.y.y.y.y#c.y.y.y.y#z.yb2.#................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"..........................................................................................................................................................................................................................................................#d#d#c#c#c#z#c.y.y.y.y.y#F.#................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +".............................................................................................................................................................................................................................................................y.y.y.y.y.y.y.y.y#z.y.#.#................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"............................................................................................................................................................................................................................................................#d#c#d.y.y.y.y#z.y.yaI.#.#................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"...............................................................................................................................................................................................................................................................y#c.y#c.y.y.y.y.y#C.#..................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +".................................................................................................................................................................................................................................................................y#c.y.y.y#z.y#..#.#..................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"...................................................................................................................................................................................................................................................................y.y.y.y.ybO#F.#.5..................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"......................................................................................................................................................................................................................................................................aIb2#C.#.#.5....................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................" +}; diff --git a/etc/icons/wl-message-extract-content-up.xpm b/etc/icons/wl-message-extract-content-up.xpm new file mode 100644 index 0000000..4e093d7 --- /dev/null +++ b/etc/icons/wl-message-extract-content-up.xpm @@ -0,0 +1,43 @@ +/* XPM */ +static char * wl_message_extract_content_up_xpm[] = { +"32 32 8 1", +" c #CF3CCF3CCF3C s backgroundToolBarColor", +". c #000000000000", +"X c #FFFFE38DB6DA", +"o c #E79DCB2B9E79", +"O c #B6DAA6998617", +"+ c #CF3CBAEA9658", +"@ c #514471C6FFFF", +"# c #AEBAAAAAAEBA", +" ", +" ", +" ", +" ............ ", +" ...XXXXXXXXXXXX... ", +" .XXXXXXXXXXXXXXXXXX. ", +" .XXXXXXXXXXXXXXXXXX. ", +" ....XXXXXXXXXXXX.... ", +" .ooo............OOO. ", +" .ooo++++++++++++OOO. ", +" .ooo+++++++@++++OOO. ", +" .ooo++++++@@++++OOO. ", +" .ooo+++++@@@@@@@@@O@@ @@ @@ ", +" .ooo++++@@@@@@@@@@O@@ @@ @@ ", +" .ooo++++@@@@@@@@@@O@@ @@ @@ ", +" .ooo+++++@@@@@@@@@O@@ @@ @@ ", +" .ooo++++++@@++++OOO. ", +" .ooo+++++++@++++OOO.## ", +" .ooo++++++++++++OO+.#### ", +" ...++++++++++++...##### ", +" ............####### ", +" ############## ", +" ", +" ", +" . . ", +" .... . . ", +" . . . .... ... .. ... ", +" ... . . . .. . . . ", +" . .. . . ... . . ", +" . . . . . . . . . ", +" .... . . . . .. . .. . ", +" "}; diff --git a/etc/icons/wl-message-next-content-up.xpm b/etc/icons/wl-message-next-content-up.xpm new file mode 100644 index 0000000..b4bd524 --- /dev/null +++ b/etc/icons/wl-message-next-content-up.xpm @@ -0,0 +1,53 @@ +/* XPM */ +static char * wl_folder_next_unsync_up_xpm[] = { +"32 32 18 1", +" c #BEFBBEFBBEFB s backgroundToolBarColor", +". c #000000000000", +"X c #8E38C30BFFFF", +"o c #59656595C71B", +"O c #965896589658", +"+ c #596569A6C71B", +"@ c #59656DB6CF3C", +"# c #596571C6CF3C", +"$ c #596575D6CF3C", +"% c #618579E7D75C", +"& c #61857DF7D75C", +"* c #61857DF7DF7D", +"= c #61858207DF7D", +"- c #69A68A28E79D", +"; c #61858617E79D", +": c #69A68E38EFBE", +"> c #69A69248EFBE", +", c #69A69658F7DE", +" ", +" ", +" ", +" ", +" ..... ", +" .Xoo.O ", +" .Xoo.O ", +" .X++.O ", +" .X@@.O ", +" .X##.O ", +" .X$$.O ", +" .X%%.O ", +" .X&&.O ", +" .X**.O ", +" ......X==...... ", +" .X-;;;;;;;;;.OO ", +" .X--------.OO ", +" .X::::::.OO ", +" .X>>>>.OO ", +" .X,,.OO ", +" .X.OO ", +" .OO ", +" OO ", +" ", +" . ", +" . . . ", +" .. . . . . ... ", +" . . . . . . . . ", +" . . . ... .. . ", +" . .. . . . . ", +" . . .. . . . ", +" "}; diff --git a/etc/icons/wl-message-play-content-up.xpm b/etc/icons/wl-message-play-content-up.xpm new file mode 100644 index 0000000..6e79248 --- /dev/null +++ b/etc/icons/wl-message-play-content-up.xpm @@ -0,0 +1,41 @@ +/* XPM */ +static char * wl_message_play_content_up_xpm[] = { +"32 32 6 1", +" c #CF3CCF3CCF3C s backgroundToolBarColor", +". c #000000000000", +"X c #BEFBBEFBBEFB", +"o c #69A669A669A6", +"O c #9E799A699E79", +"+ c #D75C5D755965", +" ", +" ", +" ", +" ", +" ............ ", +" .XXXXXXXXXXXo. ", +" .. .XOOOOOOOOOOo. ", +" .. .XOOOOOO........ ", +" .X..XOOOOOO.XXOOOO. ", +" .O..XOOOOOO.oooooo. ", +" .o..XOOOOOO........ ", +" .o..XOOOOOOOOOOo. ", +" .o..XOOOOOOOOOOo. ", +" .. .XOOOOOOOOOOo. ", +" .. .XOOOOOOOOOOo. ", +" .oooooooooooo. ", +" ............ + ", +" ++ ", +" ++ ++ ++ +++++++++ ", +" ++ ++ ++ ++++++++++ ", +" ++ ++ ++ ++++++++++ ", +" ++ ++ ++ +++++++++ ", +" ++ ", +" + ", +" . ", +" ... . ", +" . . . .. . . ", +" . . . . . . ", +" ... . ... . . ", +" . . . . .. ", +" . . .. . . ", +" . "}; diff --git a/etc/icons/wl-message-prev-content-up.xpm b/etc/icons/wl-message-prev-content-up.xpm new file mode 100644 index 0000000..0d1895c --- /dev/null +++ b/etc/icons/wl-message-prev-content-up.xpm @@ -0,0 +1,53 @@ +/* XPM */ +static char * wl_folder_previous_unsync_up_xpm[] = { +"32 32 18 1", +" c #BEFBBEFBBEFB s backgroundToolBarColor", +". c #000000000000", +"X c #8E38C30BFFFF", +"o c #69A69658F7DE", +"O c #69A69248EFBE", +"+ c #69A68E38EFBE", +"@ c #69A68A28E79D", +"# c #61858617E79D", +"$ c #61858207DF7D", +"% c #965896589658", +"& c #61857DF7DF7D", +"* c #61857DF7D75C", +"= c #618579E7D75C", +"- c #596575D6CF3C", +"; c #596571C6CF3C", +": c #59656DB6CF3C", +"> c #596569A6C71B", +", c #59656595C71B", +" ", +" ", +" ", +" ", +" . ", +" .X. ", +" .Xoo. ", +" .XOOOO. ", +" .X++++++. ", +" .X@@@@@@@@. ", +" .X@#########. ", +" ......X$$...... ", +" %%%%.X&&.%%%%% ", +" .X**.% ", +" .X==.% ", +" .X--.% ", +" .X;;.% ", +" .X::.% ", +" .X>>.% ", +" .X,,.% ", +" .X,,.% ", +" .....% ", +" %%%%% ", +" ", +" ", +" ... ", +" . . . . . . . ", +" . . .. . . . . ", +" ... . ... . . ", +" . . . . . ", +" . . .. . ", +" "}; diff --git a/etc/icons/wl-message-quit-up.xpm b/etc/icons/wl-message-quit-up.xpm new file mode 100644 index 0000000..7eb9182 --- /dev/null +++ b/etc/icons/wl-message-quit-up.xpm @@ -0,0 +1,42 @@ +/* XPM */ +static char * wl_folder_quit_up_xpm[] = { +"32 32 7 1", +" c #CF3CCF3CCF3C s backgroundToolBarColor", +". c #000000000000", +"X c #FFFFE38DB6DA", +"o c #CF3CBAEA9658", +"O c #AEBAB2CAAEBA", +"+ c #B6DA965869A6", +"@ c #69A68E38EFBE", +" ", +" ", +" ", +" ........... ", +" .XXooooooo.OO ", +" .X.......o.OO ", +" .o.++++X.o.OO ", +" .o.+oooX.o.OO ", +" @ .o.+oooX.o.OO ", +" @@ .o.+oooX.o.OO ", +" @@@@@@@@@ .o.XXXXX.o.OO ", +" @@@@@@@@@@ .o.......o.OO ", +" @@@@@@@@@@@.XXooooooo.OO ", +" @@@@@@@@@@O.XXooooooo.OO ", +" @@@@@@@@@OO.o.......o.OO ", +" OOOOOO@@OO .o.++++X.o.OO ", +" OOOOOO@OO .o.+oooX.o.OO ", +" OO .o.+oooX.o.OO ", +" O .o.+oooX.o.OO ", +" O .o.XXXXX.o.OO ", +" .o.......o.OO ", +" .ooooooooo.OO ", +" ...........OO ", +" OOOOOOOOOOOO ", +" . . ", +" .... . ", +" . . . . ... ", +" ... . . . . ", +" . .. . . ", +" . . . . . ", +" .... . . . . ", +" "}; diff --git a/etc/icons/wl-message-read-up.xpm b/etc/icons/wl-message-read-up.xpm new file mode 100644 index 0000000..1277854 --- /dev/null +++ b/etc/icons/wl-message-read-up.xpm @@ -0,0 +1,55 @@ +/* XPM */ +static char * wl_folder_jump_to_current_entity_up_xpm[] = { +"32 32 20 1", +" c #BEFBBEFBBEFB s backgroundToolBarColor", +". c #000000000000", +"X c #8E38C30BFFFF", +"o c #8617BEFBF7DE", +"O c #8617BAEAF7DE", +"+ c #8617B6DAF7DE", +"@ c #FFFFFFFFFFFF", +"# c #79E7AEBAEFBE", +"$ c #79E7AEBAF7DE", +"% c #79E7B2CAF7DE", +"& c #79E7A699EFBE", +"* c #79E7AAAAEFBE", +"= c #71C6A289EFBE", +"- c #71C69E79EFBE", +"; c #71C69A69E79D", +": c #69A69658E79D", +"> c #69A69248E79D", +", c #69A68A28E79D", +"< c #965896589658", +"1 c #AEBAAEBAAEBA", +" ", +" ", +" .... ", +" ..XXXX.. ", +" .XoO+++Oo. ", +" .Xo+@@#$%+o. ", +" .Xo+$@@&&*$+o. ", +" .XO%*=-;-=*%O. ", +" .X+$&-:>:-&$+. ", +" .X+#&;>,>;&#+. ", +" ..X$&-:>:-&$.. ", +" .<.%*=-;-=*.<. ", +" .1..*&&&..1.< ", +" .@@....11.<< ", +" ..@@@1..<< ", +" <.....<<< ", +" <..<<<<<< ", +" <..<<<< ", +" <..<< ", +" <..< ", +" <..<< ", +" @@.< ", +" <<<< ", +" <<<< ", +" < . ", +" ... . ", +" . . . .. ... ", +" . . . . . . . ", +" ... ... ... . . ", +" . . . . . . . ", +" . . .. .. . ... ", +" "}; diff --git a/etc/icons/wl-summary-delete-up.xpm b/etc/icons/wl-summary-delete-up.xpm new file mode 100644 index 0000000..59f7a90 --- /dev/null +++ b/etc/icons/wl-summary-delete-up.xpm @@ -0,0 +1,43 @@ +/* XPM */ +static char * wl_summary_delete_up_xpm[] = { +"32 32 8 1", +" c #BEFBBEFBBEFB s backgroundToolBarColor", +". c #000000000000", +"X c #E79DCB2B9E79", +"o c #69A68E38EFBE", +"O c #CF3CBAEA9658", +"+ c #FFFFFFFFFFFF", +"@ c #B6DAA6998617", +"# c #965896589658", +" ", +" .... ", +" .XXXX.. ", +" o .XOOOXX.. ", +" oo ..XOOOOOOO.. ", +" ooooooo .++.XOOOOOOOO. ", +" oooooooo .. ..@@@OOOO@. ", +" ooooooooo.+.++...@@@@@. ", +" oooooooo .++..++...... ", +" ooooooo ...++.+.+#... ", +" oo .XO.......@@. ", +" o .XOXOOO@O@@@. ", +" .XOXOOO@O@@@. ", +" .XOXOOO@O@@@. ", +" .XOXOOO@O@@@. ", +" .XOXOOO@O@@@. ", +" .XOXOOO@O@@@. ", +" .XOXOOO@O@@@. ", +" .XOXOOO@O@@@. ", +" .XOXOOO@O@@@. ", +" .XOXOOO@O@@@.## ", +" ..XOOO@O@..#### ", +" .......##### ", +" ######### ", +" . . ", +" .... . . ", +" . . . . . ... . ", +" . . . . . . . . . . ", +" . . ... . ... . ... ", +" . . . . . . . ", +" .... .. . .. . .. ", +" "}; diff --git a/etc/icons/wl-summary-exit-up.xpm b/etc/icons/wl-summary-exit-up.xpm new file mode 100644 index 0000000..7eb9182 --- /dev/null +++ b/etc/icons/wl-summary-exit-up.xpm @@ -0,0 +1,42 @@ +/* XPM */ +static char * wl_folder_quit_up_xpm[] = { +"32 32 7 1", +" c #CF3CCF3CCF3C s backgroundToolBarColor", +". c #000000000000", +"X c #FFFFE38DB6DA", +"o c #CF3CBAEA9658", +"O c #AEBAB2CAAEBA", +"+ c #B6DA965869A6", +"@ c #69A68E38EFBE", +" ", +" ", +" ", +" ........... ", +" .XXooooooo.OO ", +" .X.......o.OO ", +" .o.++++X.o.OO ", +" .o.+oooX.o.OO ", +" @ .o.+oooX.o.OO ", +" @@ .o.+oooX.o.OO ", +" @@@@@@@@@ .o.XXXXX.o.OO ", +" @@@@@@@@@@ .o.......o.OO ", +" @@@@@@@@@@@.XXooooooo.OO ", +" @@@@@@@@@@O.XXooooooo.OO ", +" @@@@@@@@@OO.o.......o.OO ", +" OOOOOO@@OO .o.++++X.o.OO ", +" OOOOOO@OO .o.+oooX.o.OO ", +" OO .o.+oooX.o.OO ", +" O .o.+oooX.o.OO ", +" O .o.XXXXX.o.OO ", +" .o.......o.OO ", +" .ooooooooo.OO ", +" ...........OO ", +" OOOOOOOOOOOO ", +" . . ", +" .... . ", +" . . . . ... ", +" ... . . . . ", +" . .. . . ", +" . . . . . ", +" .... . . . . ", +" "}; diff --git a/etc/icons/wl-summary-forward-up.xpm b/etc/icons/wl-summary-forward-up.xpm new file mode 100644 index 0000000..0a957d5 --- /dev/null +++ b/etc/icons/wl-summary-forward-up.xpm @@ -0,0 +1,41 @@ +/* XPM */ +static char * wl_summary_forward_up_xpm[] = { +"32 32 6 1", +" c #BEFBBEFBBEFB s backgroundToolBarColor", +". c #000000000000", +"X c #FFFFFFFFFFFF", +"o c #59656595C71B", +"O c #9E799A699E79", +"+ c #D75C38E34103", +" ", +" .................. ", +" .XXXXXXXXXXXXXXXX. ", +" .XooX XXXXXXXX.O ", +" .XooXXXXXXXXXXXXX.O ", +" .XXXX XXXXXXXX.O ", +" .XXXXXXXXXXXXXXXX.O + ", +" .XXXXXXXXXXXXXXXX.O++ ", +" .XXXXXXXXXXXXXXXX.+++++ ", +" .XXXXXXXXXXXXXXXX.O++ + ", +" .XXXXXXXXXXXXXXXX.O + + ", +" ..................O + ", +" OOOOOOOOOOOOOOOOOO + ", +" OOOOOOOOOO.................. ", +" .XXXXXXXXXXXXXXXX. ", +" .XooX XXXXXXXX.O", +" .XooXXXXXXXXXXXXX.O", +" .XXXX XXXXXXXX.O", +" .XXXXXXXXXXXXXXXX.O", +" .XXXXXXXXXXXXXXXX.O", +" .XXXXXXXXXXXXXXXX.O", +" .XXXXXXXXXXXXXXXX.O", +" .XXXXXXXXXXXXXXXX.O", +" ..................O", +" OOOOOOOOOOOOOOOO.O", +" .... OOOOOOOOOOOOOOOO.O", +" . .. . .. . . .. . . ... ", +" ... . . .. . . . . .. . . ", +" . . . . . . . ... . . . ", +" . . . . . . . . . . . ", +" . .. . . . .. .. ... ", +" "}; diff --git a/etc/icons/wl-summary-jump-to-current-message-up.xpm b/etc/icons/wl-summary-jump-to-current-message-up.xpm new file mode 100644 index 0000000..0c206ef --- /dev/null +++ b/etc/icons/wl-summary-jump-to-current-message-up.xpm @@ -0,0 +1,42 @@ +/* XPM */ +static char * wl_summary_jump_to_current_message_up_xpm[] = { +"32 32 7 1", +" c #CF3CCF3CCF3C s backgroundToolBarColor", +". c #000000000000", +"X c #EFBEFFFFC71B", +"o c #CF3CBAEA9658", +"O c #F7DEFFFFBEFB", +"+ c #AEBAB2CAAEBA", +"@ c #69A68E38EFBE", +" ", +" ", +" ............ ", +" .X.oOOOOOOOO.++ ", +" .X.oOOOOOOOOO.++ ", +" .XX.oOOOOOOOOO.++ ", +" .X...oOOOOOOOOO.++ ", +" ..ooooOO+O+++OO.++ ", +" .oOOOOOOOOOOOOO.++ ", +" .OOOOOOOOOOOOOO.++ ", +" @ .OO++OOOO++++OO.++ ", +" @@.OOOOOOOOOOOOOO.++ ", +" @@@@@@@OOOOOOOOOOOOOO.++ ", +" @@@@@@@@O+OO++OOO++OO.++ ", +" @@@@@@@@@OOOOOOOOOOOO.++ ", +" @@@@@@@@OOOOOOOOOOOOO.++ ", +" @@@@@@@OO++OO++O+++OO.++ ", +" @@.OOOOOOOOOOOOOO.++ ", +" @ .OOOOOOOOOOOOOO.++ ", +" .OOOOOOOOOOOOOO.++ ", +" .OOOOOOOOOOOOOO.++ ", +" .OOOOOOOOOOOOOO.++ ", +" ...............++ ", +" ++++++++++++++++ ", +" +++++++++.++++++ ", +" .... . ", +" . ... ... . . . ", +" ... . . . . . .. ", +" . . . . ... . ", +" . . . . . . ", +" .... . . . .. . ", +" "}; diff --git a/etc/icons/wl-summary-mark-as-important-up.xpm b/etc/icons/wl-summary-mark-as-important-up.xpm new file mode 100644 index 0000000..d4210b9 --- /dev/null +++ b/etc/icons/wl-summary-mark-as-important-up.xpm @@ -0,0 +1,43 @@ +/* XPM */ +static char * wl_summary_mark_as_important_up_xpm[] = { +"32 32 8 1", +" c #BEFBBEFBBEFB s backgroundToolBarColor", +". c #000000000000", +"X c #E79DCB2B9E79", +"o c #CF3CBAEA9658", +"O c #B6DAA6998617", +"+ c #FFFFFFFFFFFF", +"@ c #AEBAAEBAAEBA", +"# c #69A68E38EFBE", +" ", +" .................. ", +" ..XoooooooooooooooO. ", +" ..XoooooooooooooooO. ", +" ..Xoooooooooooooooo. ", +" .+.ooooooooooooooooO. ", +" .+.XoooooooooooooooO. ", +" .+.XoooooooooooooooO. ", +" .+.XooooooooooooooooO. ", +" .+.XoooooooooooooooO. ", +" .+.OOOOOOOOOOOOOOOOO. ", +" .+.................O. ", +" .+.@@@@@@@@@@@@@@@@.. ", +" .+@+++++++++++++++@. ", +" .++@++++++++++++++++. ", +" .+++...@+++++++++++++. ", +" # .+++++.@++++++++++++++. ", +" ## .+++++.@@++++++++++++++. ", +" # .+++++.@@@+++++++++++++. ", +" ## .#++.................. ", +" ####+. ", +" . ", +" ", +" ", +" . ", +" . . . ", +" .. .. .. . .. . ", +" . . . . .. .. ", +" . . . ... . .. ", +" . . . . . . . . ", +" . . . .. .. . . ", +" "}; diff --git a/etc/icons/wl-summary-next-page-up.xpm b/etc/icons/wl-summary-next-page-up.xpm new file mode 100644 index 0000000..b4bd524 --- /dev/null +++ b/etc/icons/wl-summary-next-page-up.xpm @@ -0,0 +1,53 @@ +/* XPM */ +static char * wl_folder_next_unsync_up_xpm[] = { +"32 32 18 1", +" c #BEFBBEFBBEFB s backgroundToolBarColor", +". c #000000000000", +"X c #8E38C30BFFFF", +"o c #59656595C71B", +"O c #965896589658", +"+ c #596569A6C71B", +"@ c #59656DB6CF3C", +"# c #596571C6CF3C", +"$ c #596575D6CF3C", +"% c #618579E7D75C", +"& c #61857DF7D75C", +"* c #61857DF7DF7D", +"= c #61858207DF7D", +"- c #69A68A28E79D", +"; c #61858617E79D", +": c #69A68E38EFBE", +"> c #69A69248EFBE", +", c #69A69658F7DE", +" ", +" ", +" ", +" ", +" ..... ", +" .Xoo.O ", +" .Xoo.O ", +" .X++.O ", +" .X@@.O ", +" .X##.O ", +" .X$$.O ", +" .X%%.O ", +" .X&&.O ", +" .X**.O ", +" ......X==...... ", +" .X-;;;;;;;;;.OO ", +" .X--------.OO ", +" .X::::::.OO ", +" .X>>>>.OO ", +" .X,,.OO ", +" .X.OO ", +" .OO ", +" OO ", +" ", +" . ", +" . . . ", +" .. . . . . ... ", +" . . . . . . . . ", +" . . . ... .. . ", +" . .. . . . . ", +" . . .. . . . ", +" "}; diff --git a/etc/icons/wl-summary-next-up.xpm b/etc/icons/wl-summary-next-up.xpm new file mode 100644 index 0000000..b4bd524 --- /dev/null +++ b/etc/icons/wl-summary-next-up.xpm @@ -0,0 +1,53 @@ +/* XPM */ +static char * wl_folder_next_unsync_up_xpm[] = { +"32 32 18 1", +" c #BEFBBEFBBEFB s backgroundToolBarColor", +". c #000000000000", +"X c #8E38C30BFFFF", +"o c #59656595C71B", +"O c #965896589658", +"+ c #596569A6C71B", +"@ c #59656DB6CF3C", +"# c #596571C6CF3C", +"$ c #596575D6CF3C", +"% c #618579E7D75C", +"& c #61857DF7D75C", +"* c #61857DF7DF7D", +"= c #61858207DF7D", +"- c #69A68A28E79D", +"; c #61858617E79D", +": c #69A68E38EFBE", +"> c #69A69248EFBE", +", c #69A69658F7DE", +" ", +" ", +" ", +" ", +" ..... ", +" .Xoo.O ", +" .Xoo.O ", +" .X++.O ", +" .X@@.O ", +" .X##.O ", +" .X$$.O ", +" .X%%.O ", +" .X&&.O ", +" .X**.O ", +" ......X==...... ", +" .X-;;;;;;;;;.OO ", +" .X--------.OO ", +" .X::::::.OO ", +" .X>>>>.OO ", +" .X,,.OO ", +" .X.OO ", +" .OO ", +" OO ", +" ", +" . ", +" . . . ", +" .. . . . . ... ", +" . . . . . . . . ", +" . . . ... .. . ", +" . .. . . . . ", +" . . .. . . . ", +" "}; diff --git a/etc/icons/wl-summary-prev-page-up.xpm b/etc/icons/wl-summary-prev-page-up.xpm new file mode 100644 index 0000000..0d1895c --- /dev/null +++ b/etc/icons/wl-summary-prev-page-up.xpm @@ -0,0 +1,53 @@ +/* XPM */ +static char * wl_folder_previous_unsync_up_xpm[] = { +"32 32 18 1", +" c #BEFBBEFBBEFB s backgroundToolBarColor", +". c #000000000000", +"X c #8E38C30BFFFF", +"o c #69A69658F7DE", +"O c #69A69248EFBE", +"+ c #69A68E38EFBE", +"@ c #69A68A28E79D", +"# c #61858617E79D", +"$ c #61858207DF7D", +"% c #965896589658", +"& c #61857DF7DF7D", +"* c #61857DF7D75C", +"= c #618579E7D75C", +"- c #596575D6CF3C", +"; c #596571C6CF3C", +": c #59656DB6CF3C", +"> c #596569A6C71B", +", c #59656595C71B", +" ", +" ", +" ", +" ", +" . ", +" .X. ", +" .Xoo. ", +" .XOOOO. ", +" .X++++++. ", +" .X@@@@@@@@. ", +" .X@#########. ", +" ......X$$...... ", +" %%%%.X&&.%%%%% ", +" .X**.% ", +" .X==.% ", +" .X--.% ", +" .X;;.% ", +" .X::.% ", +" .X>>.% ", +" .X,,.% ", +" .X,,.% ", +" .....% ", +" %%%%% ", +" ", +" ", +" ... ", +" . . . . . . . ", +" . . .. . . . . ", +" ... . ... . . ", +" . . . . . ", +" . . .. . ", +" "}; diff --git a/etc/icons/wl-summary-prev-up.xpm b/etc/icons/wl-summary-prev-up.xpm new file mode 100644 index 0000000..0d1895c --- /dev/null +++ b/etc/icons/wl-summary-prev-up.xpm @@ -0,0 +1,53 @@ +/* XPM */ +static char * wl_folder_previous_unsync_up_xpm[] = { +"32 32 18 1", +" c #BEFBBEFBBEFB s backgroundToolBarColor", +". c #000000000000", +"X c #8E38C30BFFFF", +"o c #69A69658F7DE", +"O c #69A69248EFBE", +"+ c #69A68E38EFBE", +"@ c #69A68A28E79D", +"# c #61858617E79D", +"$ c #61858207DF7D", +"% c #965896589658", +"& c #61857DF7DF7D", +"* c #61857DF7D75C", +"= c #618579E7D75C", +"- c #596575D6CF3C", +"; c #596571C6CF3C", +": c #59656DB6CF3C", +"> c #596569A6C71B", +", c #59656595C71B", +" ", +" ", +" ", +" ", +" . ", +" .X. ", +" .Xoo. ", +" .XOOOO. ", +" .X++++++. ", +" .X@@@@@@@@. ", +" .X@#########. ", +" ......X$$...... ", +" %%%%.X&&.%%%%% ", +" .X**.% ", +" .X==.% ", +" .X--.% ", +" .X;;.% ", +" .X::.% ", +" .X>>.% ", +" .X,,.% ", +" .X,,.% ", +" .....% ", +" %%%%% ", +" ", +" ", +" ... ", +" . . . . . . . ", +" . . .. . . . . ", +" ... . ... . . ", +" . . . . . ", +" . . .. . ", +" "}; diff --git a/etc/icons/wl-summary-read-up.xpm b/etc/icons/wl-summary-read-up.xpm new file mode 100644 index 0000000..1277854 --- /dev/null +++ b/etc/icons/wl-summary-read-up.xpm @@ -0,0 +1,55 @@ +/* XPM */ +static char * wl_folder_jump_to_current_entity_up_xpm[] = { +"32 32 20 1", +" c #BEFBBEFBBEFB s backgroundToolBarColor", +". c #000000000000", +"X c #8E38C30BFFFF", +"o c #8617BEFBF7DE", +"O c #8617BAEAF7DE", +"+ c #8617B6DAF7DE", +"@ c #FFFFFFFFFFFF", +"# c #79E7AEBAEFBE", +"$ c #79E7AEBAF7DE", +"% c #79E7B2CAF7DE", +"& c #79E7A699EFBE", +"* c #79E7AAAAEFBE", +"= c #71C6A289EFBE", +"- c #71C69E79EFBE", +"; c #71C69A69E79D", +": c #69A69658E79D", +"> c #69A69248E79D", +", c #69A68A28E79D", +"< c #965896589658", +"1 c #AEBAAEBAAEBA", +" ", +" ", +" .... ", +" ..XXXX.. ", +" .XoO+++Oo. ", +" .Xo+@@#$%+o. ", +" .Xo+$@@&&*$+o. ", +" .XO%*=-;-=*%O. ", +" .X+$&-:>:-&$+. ", +" .X+#&;>,>;&#+. ", +" ..X$&-:>:-&$.. ", +" .<.%*=-;-=*.<. ", +" .1..*&&&..1.< ", +" .@@....11.<< ", +" ..@@@1..<< ", +" <.....<<< ", +" <..<<<<<< ", +" <..<<<< ", +" <..<< ", +" <..< ", +" <..<< ", +" @@.< ", +" <<<< ", +" <<<< ", +" < . ", +" ... . ", +" . . . .. ... ", +" . . . . . . . ", +" ... ... ... . . ", +" . . . . . . . ", +" . . .. .. . ... ", +" "}; diff --git a/etc/icons/wl-summary-reply-up.xpm b/etc/icons/wl-summary-reply-up.xpm new file mode 100644 index 0000000..59ee885 --- /dev/null +++ b/etc/icons/wl-summary-reply-up.xpm @@ -0,0 +1,42 @@ +/* XPM */ +static char * wl_summary_reply_up_xpm[] = { +"32 32 7 1", +" c #BEFBBEFBBEFB s backgroundToolBarColor", +". c #000000000000", +"X c #EFBEFFFFC71B", +"o c #FFFFFFFFFFFF", +"O c #59656595C71B", +"+ c #9E799A699E79", +"@ c #79E7B2CAF7DE", +" ", +" ............... .", +" .XXXXXXXXXXXXX. ..", +" .XXXXXXXXXXXX..o.", +" ..............XXXXXXXXXXX..o. ", +" .oooooooooooo.XXXXXXXXXXX.oo. ", +" .oOOo ooo.XXXXXXXXXX..ooo. ", +" .oOOoooooooo.XXXXXXXXX.oooo. ", +" .oooo ooo.XXXXXXXX.oooo. ", +" .ooooooooooo.XXXXXXXX.oooo. ", +" .ooooooooooo.XXXXXXX.ooooo. ", +" .oooooooooooo.XXXXXX.oo.oo.+++", +" .oooooooooooo.XXXXXX.oo.o.X.++", +" .oooooooooooo.XXXXXX.oo.o.X.++", +" ..................XXXo.oo.XX.+", +" ++++++++++.OOOOO.XXX..o.XXX.+", +" ++++++++++.......XXXX..XXXX.+", +" .@@@.XXXXX.XXXX.++", +" .@o@@@.XXXX.XXX.+++", +" .@o@@@@@........++++", +" .OoOOOOO. . +++++ ", +" .OoOOOOO.+++++++ ", +" .OOOOOOO.++ ", +" .......+++ ", +" . ", +" ... . ", +" . . . ... . . . ", +" . . . . . . . . . ", +" ... ... . . . . . ", +" . . . . . . .. ", +" . . .. ... . . ", +" . . "}; diff --git a/etc/icons/wl-summary-reply-with-citation-up.xpm b/etc/icons/wl-summary-reply-with-citation-up.xpm new file mode 100644 index 0000000..771d731 --- /dev/null +++ b/etc/icons/wl-summary-reply-with-citation-up.xpm @@ -0,0 +1,42 @@ +/* XPM */ +static char * wl_summary_reply_with_citation_up_xpm[] = { +"32 32 7 1", +" c #BEFBBEFBBEFB s backgroundToolBarColor", +". c #000000000000", +"X c #EFBEFFFFC71B", +"o c #FFFFFFFFFFFF", +"O c #9E799A699E79", +"+ c #59656595C71B", +"@ c #79E7B2CAF7DE", +" ", +" ............... .", +" .XXXXXXXXXXXXX. ..", +" .XXXXXXXXXXXX..o.", +" ..............XOXOOOXXXXX..o. ", +" .oooooooooooo.XXXXXXXXXXX.oo. ", +" .o++o ooo.XXOXOOXXXX..ooo. ", +" .o++oooooooo.XXXXXXXXX.oooo. ", +" .oooo ooo.XXXXXXXX.oooo. ", +" .ooooooooooo.XXXXXXXX.oooo. ", +" .ooooooooooo.XXXXXXX.ooooo. ", +" .oooooooooooo.XXXXXX.oo.oo.OOO", +" .oooooooooooo.XXXXXX.oo.o.X.OO", +" .oooooooooooo.XXXXXX.oo.o.X.OO", +" ..................XXXo.oo.XX.O", +" OOOOOOOOOO.+++++.XXX..o.XXX.O", +" OOOOOOOOOO.......XXXX..XXXX.O", +" .@@@.XXXXX.XXXX.OO", +" .@o@@@.XXXX.XXX.OOO", +" .@o@@@@@........OOOO", +" .+o+++++. . OOOOO ", +" .+o+++++.OOOOOOO ", +" .+++++++.OO ", +" .......OOO ", +" . . ", +" ... . ", +" . . . . ... . ", +" . . . . . . ", +" .... . . . ... ", +" . . . . . . ", +" . ... . . .. ", +" "}; diff --git a/etc/icons/wl-summary-sync-force-update-up.xpm b/etc/icons/wl-summary-sync-force-update-up.xpm new file mode 100644 index 0000000..ab8002e --- /dev/null +++ b/etc/icons/wl-summary-sync-force-update-up.xpm @@ -0,0 +1,55 @@ +/* XPM */ +static char * wl_folder_sync_current_entity_up_xpm[] = { +"32 32 20 1", +" c #CF3CCF3CCF3C s backgroundToolBarColor", +". c #000000000000", +"X c #FFFFE38DB6DA", +"o c #E79DCB2B9E79", +"O c #B6DAA6998617", +"+ c #CF3CBAEA9658", +"@ c #514471C6FFFF", +"# c #59656DB6EFBE", +"$ c #618569A6DF7D", +"% c #69A66595D75C", +"& c #79E76185C71B", +"* c #AEBAAAAAAEBA", +"= c #86175D75BEFB", +"- c #96585965AEBA", +"; c #9E7955559E79", +": c #A69951448E38", +"> c #C71BC30BC71B", +", c #AEBA4D348617", +"< c #BEFB492471C6", +"1 c #C71B492469A6", +" ", +" ", +" ", +" ............ ", +" ...XXXXXXXXXXXX... ", +" .XXXXXXXXXXXXXXXXXX. ", +" .XXXXXXXXXXXXXXXXXX. ", +" ....XXXXXXXXXXXX.... ", +" .ooo............OOO. ", +" .ooo++++++++++++OOO. ", +" .ooo++++++++++++OOO. ", +" .ooo++++++++++++OOO. ", +" .ooo+++++@@+++++OOO. ", +" .ooo++++####++++OOO. ", +" .ooo+++$$$$$$+++OOO. ", +" .ooo++%%%%%%%%++OOO. ", +" .ooo++++&&&&+++++OO. ", +" *...++++====++++...*** ", +" ****....----....******* ", +" *******;;;;************ ", +" **::::::::********* ", +" >>,,,,,,********* ", +" <<<< ", +" 11 ", +" ", +" ... ", +" . . . ... .. ", +" ... . . . . . ", +" . . . . . . ", +" . .. . . . ", +" ... . . . .. ", +" . "}; diff --git a/etc/ja.Emacs b/etc/ja.Emacs new file mode 100644 index 0000000..34a5bc1 --- /dev/null +++ b/etc/ja.Emacs @@ -0,0 +1,100 @@ +Emacs*XlwMenu.folder.labelString: ¥Õ¥©¥ë¥À +Emacs*XlwMenu.enterCurrentFolder.labelString: ¥Õ¥©¥ë¥À¤Ø°ÜÆ° +Emacs*XlwMenu.prevFolder.labelString: Á°¤Î¥Õ¥©¥ë¥À +Emacs*XlwMenu.nextFolder.labelString: ¼¡¤Î¥Õ¥©¥ë¥À +Emacs*XlwMenu.checkCurrentFolder.labelString: ºÇ¿·¥á¥Ã¥»¡¼¥¸¤Î¥Á¥§¥Ã¥¯ +Emacs*XlwMenu.syncCurrentFolder.labelString: ¥µ¥Þ¥ê¤ò¹¹¿· +Emacs*XlwMenu.dropCurrentFolder.labelString: ̤Ʊ´ü¤ò¤Ê¤¯¤¹ +Emacs*XlwMenu.prefetchCurrentFolder.labelString: ¥×¥ê¥Õ¥§¥Ã¥Á +Emacs*XlwMenu.flushQueue.labelString: ¥­¥å¡¼¤Ë¤¢¤ë¥á¥Ã¥»¡¼¥¸¤òÁ÷¿® +Emacs*XlwMenu.addFolder.labelString: ¥Õ¥©¥ë¥À¤òÄɲà +Emacs*XlwMenu.addGroup.labelString: ¥°¥ë¡¼¥×¤òÄɲà +Emacs*XlwMenu.setPetname.labelString: ¤¢¤À̾¤ò¤Ä¤±¤ë +Emacs*XlwMenu.exit.labelString: ½ªÎ» +Emacs*XlwMenu.togglePlugStatus.labelString: ¥ª¥ó¥é¥¤¥ó/¥ª¥Õ¥é¥¤¥ó +Emacs*XlwMenu.changePlugStatus.labelString: ¥×¥é¥°¾õÂÖ´ÉÍý +Emacs*XlwMenu.saveCurrentStatus.labelString: ¸½ºß¤Î¾õÂÖ¤ò¥»¡¼¥Ö +Emacs*XlwMenu.markAsReadAllCurrentFolder.labelString: ¤¹¤Ù¤ÆÆɤó¤À¤³¤È¤Ë¤¹¤ë +Emacs*XlwMenu.expireCurrentFolder.labelString: Expire (¼«Æ°ºï½ü/¥¢¡¼¥«¥¤¥Ö) +Emacs*XlwMenu.folderManager.labelString: ¥Õ¥©¥ë¥ÀÊÔ½¸ +Emacs*XlwMenu.rename.labelString: ̾Á°Êѹ¹ +Emacs*XlwMenu.openAllUnreadFolder.labelString: Á´¤Æ¤Î̤ÆÉ¥Õ¥©¥ë¥À¤ò³«¤¯ +Emacs*XlwMenu.updateStatus.labelString: ¾õÂÖ¤ò¹¹¿· +Emacs*XlwMenu.emptyTrash.labelString: ¥´¥ßÈ¢¤ò¶õ¤Ë¤¹¤ë +Emacs*XlwMenu.emptyTrash.labelString: ¥´¥ßÈ¢¤ò¶õ¤Ë¤¹¤ë +Emacs*XlwMenu.unsubscribe.labelString: ¹ØÆɤò¤ä¤á¤ë(¥¢¥¯¥»¥¹·¿) +Emacs*XlwMenu.displayAll.labelString: ¤¹¤Ù¤Æɽ¼¨(¥¢¥¯¥»¥¹·¿) + +Emacs*XlwMenu.summary.labelString: ¥µ¥Þ¥ê +Emacs*XlwMenu.read.labelString: Æɤ߿ʤá¤ë +Emacs*XlwMenu.prevPage.labelString: Á°¤Î¥Ú¡¼¥¸ +Emacs*XlwMenu.nextPage.labelString: ¼¡¤Î¥Ú¡¼¥¸ +Emacs*XlwMenu.prev.labelString: Á°¤Î¥á¥Ã¥»¡¼¥¸ +Emacs*XlwMenu.next.labelString: ¼¡¤Î¥á¥Ã¥»¡¼¥¸ +Emacs*XlwMenu.up.labelString: Á°¤Î̤ÆÉ¥á¥Ã¥»¡¼¥¸ +Emacs*XlwMenu.down.labelString: ¼¡¤Î̤ÆÉ¥á¥Ã¥»¡¼¥¸ +Emacs*XlwMenu.parentMessage.labelString: ¿Æ¥á¥Ã¥»¡¼¥¸¤Ø°ÜÆ° +Emacs*XlwMenu.setDeleteMark.labelString: ºï½ü¥Þ¡¼¥¯¤ò¤Ä¤±¤ë +Emacs*XlwMenu.setRefileMark.labelString: ¥ê¥Õ¥¡¥¤¥ë¥Þ¡¼¥¯¤ò¤Ä¤±¤ë +Emacs*XlwMenu.setTargetMark.labelString: ¤Þ¤È¤á½èÍýÍÑ¥Þ¡¼¥¯¤ò¤Ä¤±¤ë +Emacs*XlwMenu.unmark.labelString: °ì»þ¥Þ¡¼¥¯¤ò¾Ã¤¹ +Emacs*XlwMenu.unmarkAll.labelString: ¤¹¤Ù¤Æ¤Î°ì»þ¥Þ¡¼¥¯¤ò¾Ã¤¹ +Emacs*XlwMenu.enterTheMessage.labelString: ¥á¥Ã¥»¡¼¥¸¤Ø°ÜÆ° +Emacs*XlwMenu.markAsImportant.labelString: ¤·¤ª¤ê(½ÅÍ×¥Þ¡¼¥¯¤ò¤Ä¤±¤ë) +Emacs*XlwMenu.markAsUnread.labelString: Æɤޤʤ«¤Ã¤¿¤³¤È¤Ë¤¹¤ë +Emacs*XlwMenu.cancelPostedNews.labelString: ¥Ë¥å¡¼¥¹µ­»ö¤ò¥­¥ã¥ó¥»¥ë¤¹¤ë +Emacs*XlwMenu.supersedesMessage.labelString: ¥Ë¥å¡¼¥¹µ­»ö¤ò¾å½ñ¤­¤¹¤ë +Emacs*XlwMenu.resendBouncedMail.labelString: ¥¨¥é¡¼¥á¡¼¥ë¤òºÆÁ÷¤¹¤ë +Emacs*XlwMenu.resendMessage.labelString: ºÆÁ÷¤¹¤ë +Emacs*XlwMenu.sync.labelString: Ʊ´ü¤ò¤È¤ë +Emacs*XlwMenu.execute.labelString: ¥ê¥Õ¥¡¥¤¥ë/¥³¥Ô¡¼/ºï½ü¥Þ¡¼¥¯¤ò¼Â¹Ô +Emacs*XlwMenu.goToOtherFolder.labelString: ¾¤Î¥Õ¥©¥ë¥À¤Ø°ÜÆ° +Emacs*XlwMenu.pick.labelString: ¸¡º÷¤·¤Æ¥Þ¡¼¥¯ +Emacs*XlwMenu.markAsReadAll.labelString: Á´ÉôÆɤó¤À¤³¤È¤Ë¤¹¤ë +Emacs*XlwMenu.stick.labelString: ¥¹¥Æ¥£¥Ã¥­¡¼¥µ¥Þ¥ê¤Ë¤¹¤ë +Emacs*XlwMenu.messageOperation.labelString: ¥á¥Ã¥»¡¼¥¸¤ÎÁàºî +Emacs*XlwMenu.threadOperation.labelString: ¥¹¥ì¥Ã¥É¤ÎÁàºî +Emacs*XlwMenu.regionOperation.labelString: ¥ê¡¼¥¸¥ç¥ó¤ÎÁàºî +Emacs*XlwMenu.markOperation.labelString: ¤Þ¤È¤á½èÍýÍÑ¥Þ¡¼¥¯¤ÎÁàºî +Emacs*XlwMenu.markAsRead.labelString: Æɤó¤À¤³¤È¤Ë¤¹¤ë +Emacs*XlwMenu.setCopyMark.labelString: ¥³¥Ô¡¼¥Þ¡¼¥¯¤òÉÕ¤±¤ë +Emacs*XlwMenu.toggleDisplayMessage.labelString: ¥á¥Ã¥»¡¼¥¸¤Îɽ¼¨¤ò¥È¥°¥ë +Emacs*XlwMenu.displayFolder.labelString: ¥Õ¥©¥ë¥À°ìÍ÷¤òɽ¼¨ +Emacs*XlwMenu.pipeMessage.labelString: ¥Ñ¥¤¥×¤¹¤ë +Emacs*XlwMenu.writingMessages.labelString: ¥á¥Ã¥»¡¼¥¸¤ò½ñ¤¯ +Emacs*XlwMenu.writeAMessage.labelString: ¥á¥Ã¥»¡¼¥¸¤ò½ñ¤¯ +Emacs*XlwMenu.reply.labelString: ÊÖ»ö¤ò½ñ¤¯ +Emacs*XlwMenu.replyWithCitation.labelString: °úÍѤ·¤ÆÊÖ»ö¤ò½ñ¤¯ +Emacs*XlwMenu.forward.labelString: žÁ÷¤¹¤ë +Emacs*XlwMenu.prefetch.labelString: ¥×¥ê¥Õ¥§¥Ã¥Á +Emacs*XlwMenu.printMessage.labelString: °õºþ¤¹¤ë +Emacs*XlwMenu.openOrClose.labelString: ¥¹¥ì¥Ã¥É¤ò³«ÊÄ +Emacs*XlwMenu.openAll.labelString: ¥¹¥ì¥Ã¥É¤òÁ´Éô³«¤¯ +Emacs*XlwMenu.closeAll.labelString: ¥¹¥ì¥Ã¥É¤òÁ´ÉôÊĤ¸¤ë +Emacs*XlwMenu.exitCurrentFolder.labelString: ¸½ºß¤Î¥µ¥Þ¥ê¤ò½ªÎ» +Emacs*XlwMenu.toggleThreading.labelString: ¥¹¥ì¥Ã¥Éɽ¼¨¤Î On/Off +Emacs*XlwMenu.sort.labelString: ¥½¡¼¥È +Emacs*XlwMenu.byNumber.labelString: ¥á¥Ã¥»¡¼¥¸ÈÖ¹æ¤Ç¥½¡¼¥È +Emacs*XlwMenu.byDate.labelString: ÆüÉÕ¤±¤Ç¥½¡¼¥È +Emacs*XlwMenu.byFrom.labelString: Á÷¿®¼Ô¤Ç¥½¡¼¥È +Emacs*XlwMenu.bySubject.labelString: ¥µ¥Ö¥¸¥§¥¯¥È¤Ç¥½¡¼¥È + +Emacs*XlwMenu.scoreOperation.labelString: ¥¹¥³¥¢Áàºî +Emacs*XlwMenu.switchCurrentScoreFile.labelString: ¥¹¥³¥¢¥Õ¥¡¥¤¥ë¤òÊѹ¹ +Emacs*XlwMenu.editCurrentScoreFile.labelString: ¸½ºß¤Î¥¹¥³¥¢¥Õ¥¡¥¤¥ë¤òÊÔ½¸ +Emacs*XlwMenu.editScoreFile.labelString: ¥¹¥³¥¢¥Õ¥¡¥¤¥ë¤òÊÔ½¸ +Emacs*XlwMenu.setMarkBelow.labelString: ÆÀÅÀ¤¬Ä㤤¥á¥Ã¥»¡¼¥¸¤Ë¥Þ¡¼¥¯ +Emacs*XlwMenu.setExpungeBelow.labelString: ÆÀÅÀ¤¬Ä㤤¥á¥Ã¥»¡¼¥¸¤ò¾Ã¤¹ +Emacs*XlwMenu.rescoreBuffer.labelString: ¥¹¥³¥¢É¾²Á¤ò¤ä¤êľ¤¹¡£ +Emacs*XlwMenu.increaseScore.labelString: ÆÀÅÀ¤ò¾å¤²¤ë +Emacs*XlwMenu.lowerScore.labelString: ÆÀÅÀ¤ò²¼¤²¤ë + +Emacs*XlwMenu.plugged.labelString: ¥×¥é¥°´ÉÍý +Emacs*XlwMenu.togglePlugged.labelString: ¥×¥é¥°¤Î¥ª¥ó/¥ª¥Õ +Emacs*XlwMenu.togglePlugged.labelString: ¥×¥é¥°¤Î¥ª¥ó/¥ª¥Õ +Emacs*XlwMenu.toggleAllPlugged.labelString: Á´¥×¥é¥°¤Î¥ª¥ó/¥ª¥Õ +Emacs*XlwMenu.toggleAllPlugged.labelString: Á´¥×¥é¥°¤Î¥ª¥ó/¥ª¥Õ +Emacs*XlwMenu.prevPort.labelString: ¾å¤Î¥Ý¡¼¥È¥Ø +Emacs*XlwMenu.nextPort.labelString: ²¼¤Î¥Ý¡¼¥È¤Ø +Emacs*XlwMenu.prevServer.labelString: ¾å¤Î¥µ¡¼¥Ð¥Ø +Emacs*XlwMenu.nextServer.labelString: ²¼¤Î¥µ¡¼¥Ð¥Ø diff --git a/samples/en/dot.addresses b/samples/en/dot.addresses new file mode 100644 index 0000000..891a3d7 --- /dev/null +++ b/samples/en/dot.addresses @@ -0,0 +1,15 @@ +# +# "~/.addresses" sample file. +# by Yuuichi Teranishi +# Time-stamp: <99/09/10 15:45:37 teranisi> +# +# Lines begin with '#' are comment. +# Empty lines are ignored. +# Format of each line: +# email-address "petname" "realname" +# petname is used for Summary displaying. +# realname is used for To: field. +# +teranisi@gohome.org "YT" "Yuuichi Teranishi" +foo@bar.com "Mr. Foo" "John Foo" +bar@foo.com "Mr. Bar" "Michael Bar" diff --git a/samples/en/dot.folders b/samples/en/dot.folders new file mode 100644 index 0000000..bfa1164 --- /dev/null +++ b/samples/en/dot.folders @@ -0,0 +1,72 @@ +# +# "~/.folders" sample file. +# by Yuuichi Teranishi +# Time-stamp: <99/09/10 15:49:11 teranisi> +# +# Lines begin with '#' are comment. +# Empty lines are ignored. +# + +%inbox ++trash ++draft +%#mh/Backup@my.imap.server.com +%#mh/spool/mm +# group definition +Emacsen{ + %#mh/spool/xemacs-beta + %#mh/spool/mew-dist + %#mh/spool/tm-ja + %#mh/spool/mule-win32 + -fj.news.reader.gnus@other.nntp.server.com +# multi folder +# following line defines multi folder of -fj.editor.xemacs,-fj.editor.mule, +# and -fj.editor.emacs. + *-fj.editor.xemacs,-fj.editor.mule,-fj.editor.emacs + -gnu.emacs.sources +} +UNIX{ +# You can define multi level group. + BSD { + %#mh/spool/freebsd-users-jp + -fj.os.bsd.freebsd + -japan.comp.freebsd + %#mh/spool/bsd-nomads + -fj.os.bsd.misc + } + Linux { + -fj.os.linux + -japan.comp.linux + } +-fj.kanji +-fj.lang.perl +-fj.unix +-fj.questions.unix +-fj.sys.sun +-fj.sys.j3100 +-comp.windows.x.i386unix +-fj.comp.x11 +} +Television{ +%#mh/spool/tvdrama +-fj.rec.tv +-japan.tv +-fj.rec.tv.cm +-japan.tv.cm +-fj.rec.idol +-fj.rec.music +} +My folders { +INBOXes { +%inbox@localhost +# +# access group +# If there is '/' in the end of line, +# all subfolders are added to group +# +%#mh/expire@localhost / +} +# following definition adds all MH subfolders to group. ++ / +%#mh@my.imap.server.com +} diff --git a/samples/en/dot.wl b/samples/en/dot.wl new file mode 100644 index 0000000..2d293aa --- /dev/null +++ b/samples/en/dot.wl @@ -0,0 +1,372 @@ +;;; -*- emacs-lisp -*- +;;; ~/.wl (setting file for Wanderlust) +;;; Last-Modified: 1999-11-07 +;;; + +;; Following must be included in ~/.emacs +;; for .emacs begin +(require 'mime-setup) +(autoload 'wl "wl" "Wanderlust" t) +(autoload 'wl-draft "wl-draft" "Write draft with Wanderlust." t) +;; for .emacs end + +;;; [[ Private Setting ]] + +;; Header From +;(setq wl-from "Your Name ") +;; Organization +;(setq wl-organization "") + +;;; [[ Basic Setting ]] + +;; A directory for message database. +(setq elmo-msgdb-dir "~/.elmo") + +;; Home directory for MH (localdir) +(setq elmo-localdir-folder-path "~/Mail") +;; Default IMAP4 server +(setq elmo-default-imap4-server "localhost") +;; Default POP server +(setq elmo-default-pop3-server "localhost") +;; Default NNTP server +(setq elmo-default-nntp-server "localhost") +;; NNTP server name for posting +(setq wl-nntp-posting-server elmo-default-nntp-server) +;; SMTP server +(setq wl-smtp-posting-server "localhost") + +;; Icon directory (XEmacs) +;; (No need if installed as XEmacs package.) +;(setq wl-icon-dir "~/work/wl/etc") + +;; If (system-name) does not return FQDN, +;; set following as a local domain name without hostname. +;; ((system-name) "." wl-local-domain is used as domain part of Message-ID +;; and an argument of HELO in SMTP. +;(setq wl-local-domain "localdomain") +;; Specific domain part for message-id. +;(setq wl-message-id-domain "localhost.localdomain") + +;(setq wl-default-folder "+inbox") ;; Default folder for + ;; wl-summary-goto-folder. +;(setq wl-default-spec "+") ;; Default string for + ;; folder name completion. + +;(setq wl-fcc "+outbox") ;; Folder Carbon Copy + +(setq wl-interactive-exit t) ;; Confirm at exit time. +(setq wl-interactive-send t) ;; Confirm at message sending time. + +(setq wl-auto-select-first t) ;; display first message automatically. +(setq wl-auto-select-next t) ;; goto next folder when exit from + ;; summary. +;(setq wl-summary-next-no-unread 'skip-no-unread) + ;; folder is skipped if there is no + ;; unread. + +(setq wl-summary-move-order 'unread) ;; jump to unread message in 'N' or 'P'. +(setq wl-thread-insert-opened t) ;; Create opened thread. + +;(setq wl-stay-folder-window t) ;; folder mode and summary mode is + ;; displayed at the same time. + +;; cache setting. +;; (messages in localdir, localnews, maildir are not cached.) +;(setq elmo-archive-use-cache nil) +;(setq elmo-nntp-use-cache nil) +;(setq elmo-imap4-use-cache t) +;(setq elmo-pop3-use-cache t) + +;; Enable disconnected operation in IMAP folder. +;(setq elmo-enable-disconnected-operation t) + +;; Store draft message in queue folder if message is sent in unplugged status. +(setq wl-draft-enable-queuing t) +;; when plug status is changed from unplugged to plugged, +;; queued message is flushed automatically. +(setq wl-auto-flush-queue t) + +;; offline at startup. +;(setq wl-plugged nil) +;; change plug status by server or port at startup. +;(add-hook 'wl-make-plugged-hook +; '(lambda () +; (elmo-set-plugged plugged(t/nil) server port) +; (elmo-set-plugged plugged(t/nil) server) +; )) + + +;; highlight setting (for light background) + +;; decide group folder color by number. +;(setq wl-highlight-group-folder-by-numbers nil) + +(setq wl-highlight-message-header-alist + '(("Subject[ \t]*:" . wl-highlight-message-subject-header-contents) + ("From[ \t]*:" . wl-highlight-message-from-header-contents) + ("\\(.*To\\|Cc\\|Newsgroups\\)[ \t]*:" . wl-highlight-message-important-header-contents) + ("\\(User-Agent\\|X-Mailer\\|X-Newsreader\\)[ \t]*:" . + wl-highlight-message-unimportant-header-contents) + )) +;; don't change color by citation level. +;(setq wl-highlight-citation-face-list +; '(wl-highlight-message-cited-text-1)) + +(defun my-wl-set-face (face spec) + (make-face face) + (cond ((fboundp 'face-spec-set) + (face-spec-set face spec)) + (t + (wl-declare-face face spec)))) + +;; header. +(my-wl-set-face 'wl-highlight-message-subject-header-contents + '((t (:foreground "blue" :bold t)))) +(my-wl-set-face 'wl-highlight-message-from-header-contents + '((t (:foreground "red" :bold t)))) +(my-wl-set-face 'wl-highlight-message-important-header-contents + '((t (:foreground "purple" :bold t)))) +(my-wl-set-face 'wl-highlight-message-unimportant-header-contents + '((t (:foreground "RoyalBlue" :bold t)))) +(my-wl-set-face 'wl-highlight-message-headers + '((t (:foreground "magenta3" :bold t)))) +(my-wl-set-face 'wl-highlight-message-header-contents + '((t (:foreground "brown" :bold nil)))) +(my-wl-set-face 'wl-highlight-message-signature + '((t (:foreground "blue")))) +;; citation. +(my-wl-set-face 'wl-highlight-message-citation-header + '((t (:foreground "DarkGreen")))) +(my-wl-set-face 'wl-highlight-message-cited-text-1 + '((t (:foreground "forest green")))) +(my-wl-set-face 'wl-highlight-message-cited-text-2 + '((t (:foreground "SaddleBrown")))) +(my-wl-set-face 'wl-highlight-message-cited-text-3 + '((t (:foreground "orchid3")))) +(my-wl-set-face 'wl-highlight-message-cited-text-4 + '((t (:foreground "purple1")))) +(my-wl-set-face 'wl-highlight-message-cited-text-5 + '((t (:foreground "MediumPurple1")))) +(my-wl-set-face 'wl-highlight-message-cited-text-6 + '((t (:foreground "PaleVioletRed")))) +(my-wl-set-face 'wl-highlight-message-cited-text-7 + '((t (:foreground "LightPink")))) +(my-wl-set-face 'wl-highlight-message-cited-text-8 + '((t (:foreground "salmon")))) +(my-wl-set-face 'wl-highlight-message-cited-text-9 + '((t (:foreground "SandyBrown")))) +(my-wl-set-face 'wl-highlight-message-cited-text-10 + '((t (:foreground "wheat")))) +;; summary. +(my-wl-set-face 'wl-highlight-summary-important-face + '((t (:foreground "purple")))) +(my-wl-set-face 'wl-highlight-summary-new-face + '((t (:foreground "tomato")))) +(my-wl-set-face 'wl-highlight-summary-unread-face + '((t (:foreground "RoyalBlue")))) +(my-wl-set-face 'wl-highlight-summary-deleted-face + '((t (:foreground "gray")))) +(my-wl-set-face 'wl-highlight-summary-refiled-face + '((t (:foreground "blue")))) +(my-wl-set-face 'wl-highlight-summary-temp-face + '((t (:foreground "salmon")))) +(my-wl-set-face 'wl-highlight-summary-displaying-face + '((t (:bold t :underline t)))) +;; (thread) +(my-wl-set-face 'wl-highlight-summary-thread-top-face + '((t (:foreground "green4")))) +(my-wl-set-face 'wl-highlight-summary-normal-face + '((t (:foreground "SeaGreen")))) +;; folder +(my-wl-set-face 'wl-highlight-folder-unknown-face + '((t (:foreground "RoyalBlue")))) +(my-wl-set-face 'wl-highlight-folder-killed-face + '((t (:foreground "gray50")))) +(my-wl-set-face 'wl-highlight-folder-unread-face + '((t (:foreground "brown")))) +(my-wl-set-face 'wl-highlight-folder-zero-face + '((t (:foreground "blue4")))) +(my-wl-set-face 'wl-highlight-folder-few-face + '((t (:foreground "tomato")))) +(my-wl-set-face 'wl-highlight-folder-many-face + '((t (:foreground "HotPink1")))) +;; group +(my-wl-set-face 'wl-highlight-folder-opened-face + '((t (:foreground "forest green")))) +(my-wl-set-face 'wl-highlight-folder-closed-face + '((t (:foreground "DarkOliveGreen4")))) +;; demo +(my-wl-set-face 'wl-highlight-demo-face + '((t (:foreground "blue2")))) + + +;;; [[ Special Setting ]] + +;; compress ~/elmo using jka-compr. +;(setq elmo-msgdb-overview-filename "overview.gz") +;(setq elmo-msgdb-number-filename "number.gz") +;(setq wl-summary-cache-file ".wl-summary-cache.gz") +;(setq wl-thread-top-file ".wl-thread-top.gz") + + +;; open unread group folder after checking. +(add-hook 'wl-folder-check-entity-hook + '(lambda () + (wl-folder-open-unread-folder entity) + )) + +;; User's mail addresses. +(setq wl-user-mail-address-list + (list (wl-address-header-extract-address wl-from) + ;;"e-mail2@bbb.com" ... + )) + +;; Change summary display function. + +;; get extra field values as overview information (only localdir folder). +(setq elmo-msgdb-extra-fields '("newsgroups" + "x-ml-name" + "x-mail-count" "x-ml-count" + "x-sequence" + "mailing-list")) + +;;; ML message displays ML name and ML sequence number in subject. +(setq wl-summary-subject-func 'my-wl-summary-subject-func-ml) +(defun my-wl-summary-subject-func-ml (subject-string) + (let ((folder wl-summary-buffer-folder-name) + (subj subject-string) (sequence) (ml-name) (ml-count)) + (setq sequence (elmo-msgdb-overview-entity-get-extra-field + entity "x-sequence") + ml-name (or (elmo-msgdb-overview-entity-get-extra-field + entity "x-ml-name") + (and sequence + (car (split-string sequence " ")))) + ml-count (or (elmo-msgdb-overview-entity-get-extra-field + entity "x-mail-count") + (elmo-msgdb-overview-entity-get-extra-field + entity "x-ml-count") + (and sequence + (cadr (split-string sequence " "))))) + (if (string-match + "^\\s(\\(.+\\)[ :]\\([0-9]+\\)\\s)[ \t]*" + subject-string) + (progn + (setq subj (substring subject-string (match-end 0))) + (if (not ml-name) (setq ml-name (match-string 1 subject-string))) + (if (not ml-count) (setq ml-count (match-string 2 subject-string))))) + (if (and ml-name ml-count) + (if (string= folder wl-default-folder) + (format "(%s %05d) %s" + (car (split-string ml-name " ")) + (string-to-int ml-count) + subj) + (format "#%05d %s" + (string-to-int ml-count) subj)) + subj))) + +;; imput asynchronously. +;; (utils/im-wl.el is needed to be installed. +;; Don't forget setting ~/.im/Config (Smtpservers). +;; note that wl-draft-enable-queuing is not valid.) +;(autoload 'wl-draft-send-with-imput-async "im-wl") +;(setq wl-draft-send-func 'wl-draft-send-with-imput-async) + + +;; template +(setq wl-template-alist + '(("default" + ("From" . wl-from) + ("Organization" . "~/.wl sample") + (body . "Hello, this is XXX \n")) ;; body + ("report" + ("To" . "boss@company.jp") + ("Subject" . "Report") + (top . "Sir, here is my report\n") ;; insert in top. +;; (file-bottom . "~/work/report.txt") ;; insert file in bottom + ) + )) +;; Change headers in draft sending time. +(setq wl-draft-config-alist + '((reply ;; see reply buffer + "^To: .*\\(test-notsend-wl@lists.airs.net\\)" + (template . "default")) ;; template + ("^To: .*\\(test-notsend-wl@lists.airs.net\\)" + wl-ml-draft-config-func ;; function + ("From" . wl-from) ;; variable + ("Organization" . "~/.wl sample")) ;; string + ("^Newsgroups: test.*" + ("Organization" . "organization for nntp.")) + )) +;; Change headers in draft preparation time. +; (add-hook 'wl-mail-setup-hook +; '(lambda () +; (unless wl-draft-reedit ;; don't apply when reedit. +; (wl-draft-config-exec wl-draft-config-alist)))) + +;; header value setting for mail reply. + +;; "a" (without-argument) reply to author (Reply-To or From). +;; if 'X-ML-Name' and 'Reply-To' exists, reply to 'Reply-To'. +; (setq wl-draft-reply-without-argument-list +; '((("X-ML-Name" "Reply-To") . (("Reply-To") nil nil)) +; ("X-ML-Name" . (("To" "Cc") nil nil)) +; ("Followup-To" . (nil nil ("Followup-To"))) +; ("Newsgroups" . (nil nil ("Newsgroups"))) +; ("Reply-To" . (("Reply-To") nil nil)) +; ("Mail-Reply-To" . (("Mail-Reply-To") nil nil)) +; ("From" . (("From") nil nil)))) +; +;; "C-u a" (with-argument) reply to all. +; (setq wl-draft-reply-with-argument-list +; '(("Followup-To" . (("From") nil ("Followup-To"))) +; ("Newsgroups" . (("From") nil ("Newsgroups"))) +; ("Mail-Followup-To" . (("Mail-Followup-To") nil ("Newsgroups"))) +; ("From" . (("From") ("To" "Cc") ("Newsgroups"))))) + + +;; X-Face (requires x-face (and x-face-mule)) + +(when (and window-system + (module-installed-p 'x-face)) + (cond (wl-on-xemacs ;; for XEmacs + (autoload 'x-face-xmas-wl-display-x-face "x-face" nil t) + (setq wl-highlight-x-face-func + 'x-face-xmas-wl-display-x-face)) + ((module-installed-p 'x-face-mule) ;; for Mule (GNU Emacs) + ;; after x-face-mule 0.20 + (setq wl-highlight-x-face-func + (function + (lambda (beg end) + (x-face-mule-x-face-decode-message-header beg end)))) + (setq x-face-mule-highlight-x-face-style 'xmas) + (require 'x-face-mule) + ))) + +;; rule for auto refile. +;(setq wl-refile-rule-alist +; '( +; ("x-ml-name" +; ("^Wanderlust" . "+wl") +; ("^Elisp" . "+elisp")) +; ("From" +; ("teranisi@isl.ntt.co.jp" . "+teranisi")))) + +;; Marks to skip auto-refile (default is "N" "U" "!"). +;; nil means all message is auto-refiled. +;(setq wl-summary-auto-refile-skip-marks nil) + +;; Scoring. +;; "all.SCORE" file is used regardless of wl-score-folder-alist. +; (setq wl-score-folder-alist +; '(("^-comp\\." +; "news.comp.SCORE" +; "news.SCORE") +; ("^-" +; "news.SCORE"))) +;; directory for storing score files. +; (setq wl-score-files-directory "~/.elmo/") + + +;;; +;;; end of file +;;; diff --git a/samples/ja/dot.addresses b/samples/ja/dot.addresses new file mode 100644 index 0000000..40c0d51 --- /dev/null +++ b/samples/ja/dot.addresses @@ -0,0 +1,13 @@ +# +# $B%"%I%l%9%U%!%$%k%5%s%W%k(B +# by Yuuichi Teranishi +# Time-stamp: <98/06/15 00:32:30 teranisi> +# +# '#' $B$G;O$^$k9T$O%3%a%s%H!#(B +# $B6u9T$OL5;k!#(B +# +# $B%a!<%k%"%I%l%9(B "$B$"$@L>(B" "$BK\L>(B" +# +teranisi@gohome.org "$B$F$i$K$7(B" "$B;{@>M50l(B" +foo@bar.com "$B$U!<$5$s(B" "Mr. Foo" +bar@foo.com "$B$P!<$5$s(B" "Mr. Bar" diff --git a/samples/ja/dot.folders b/samples/ja/dot.folders new file mode 100644 index 0000000..d3f722d --- /dev/null +++ b/samples/ja/dot.folders @@ -0,0 +1,73 @@ +# +# $B%U%)%k%@Dj5A%U%!%$%k%5%s%W%k(B +# by Yuuichi Teranishi +# Time-stamp: <98/10/02 18:31:06 teranisi> +# +# '#' $B$G;O$^$k9T$O%3%a%s%H!#(B +# $B6u9T$OL5;k!#(B +# +# $B8D!9$N%U%)%k%@$N=q<0$K$D$$$F$O(B info $B$r;2>H$N$3$H!#(B +# + +%inbox ++trash ++draft +%#mh/Backup@my.imap.server.com +%#mh/spool/mm +# $B%0%k!<%W$NDj5A(B +Emacsen{ + %#mh/spool/xemacs-beta + %#mh/spool/mew-dist + %#mh/spool/tm-ja + %#mh/spool/mule-win32 + -fj.news.reader.gnus@other.nntp.server.com +# $B%^%k%A%U%)%k%@(B($BJ#?t$N%U%)%k%@$r2>A[E*$K0l$D$K8+$($k$h$&$K$9$k%U%)%k%@(B) +# $BpJs$N@_Dj(B ]] + +;; From $B$N@_Dj(B +;(setq wl-from "Your Name ") +;; Organization $B$N@_Dj(B +;(setq wl-organization "") + +;;; [[ $B4pK\E*$J@_Dj(B ]] + +;; $B%a%C%;!<%8%G!<%?%Y!<%9$r:n$k%G%#%l%/%H%j(B +(setq elmo-msgdb-dir "~/.elmo") + +;; MH (localdir) $B$N%[!<%`(B +(setq elmo-localdir-folder-path "~/Mail") +;; IMAP4$B%5!<%P$N@_Dj(B +(setq elmo-default-imap4-server "localhost") +;; POP$B%5!<%P$N@_Dj(B +(setq elmo-default-pop3-server "localhost") +;; $B%K%e!<%9%5!<%P$N@_Dj(B +(setq elmo-default-nntp-server "localhost") +;; $BEj9F@h$N(B $B%K%e!<%9%5!<%P(B +(setq wl-nntp-posting-server elmo-default-nntp-server) +;; $B%a!<%k$rAw?.$9$k@h$N(B (SMTP)$B%5!<%P(B +(setq wl-smtp-posting-server "localhost") + +;; $B%"%$%3%s$rCV$/%G%#%l%/%H%j(B (XEmacs $B$N$_(B) +;; (XEmacs $B$N(B package $B$H$7$F%$%s%9%H!<%k$5$l$F$$$k>l9g!"I,MW$"$j$^$;$s(B) +;(setq wl-icon-dir "~/work/wl/etc") + +;; (system-name) $B$,(BFQDN$B$rJV$5$J$$>l9g!"(B +;; $B0J2<$r%[%9%HL>$r=|$$$?%I%a%$%sL>$r@_Dj$7$F$/$@$5$$!#(B +;; ((system-name) "." wl-local-domain $B$,(B Message-ID $B$N:n@.!"(B +;; SMTP $B$N(B HELO $B$K;HMQ(B $B$5$l$^$9!#(B) +;(setq wl-local-domain "localdomain") +;; Message-ID $B$N%I%a%$%s%Q!<%H$r6/@)E*$K;XDj(B +;(setq wl-message-id-domain "localhost.localdomain") + +;(setq wl-default-folder "+inbox") ;; wl-summary-goto-folder $B$N;~$KA*Br$9$k(B + ;; $B%G%U%)%k%H$N%U%)%k%@(B +;(setq wl-default-spec "+") ;; $B%U%)%k%@L>Jd40;~$K;HMQ$9$k(B + ;; $B%G%U%)%k%H$N%9%Z%C%/(B + +;(setq wl-fcc "+outbox") ;; Folder Carbon Copy + +(setq wl-interactive-exit t) ;; $B=*N;;~$K3NG'$9$k(B +(setq wl-interactive-send t) ;; $B%a!<%kAw?.;~$K$O3NG'$9$k(B + +(setq wl-auto-select-first t) ;; $B%5%^%j0\F08e$K@hF,%a%C%;!<%8$rI=<($9$k(B +(setq wl-auto-select-next t) ;; $B%5%^%jFb$N0\F0$GL$FI%a%C%;!<%8$,$J$$$H(B + ;; $Bl9g$OJXMx(B +(setq wl-summary-move-order 'unread) ;; $BL$FI%a%C%;!<%8$rM%@hE*$KFI$`(B +(setq wl-thread-insert-opened t) ;; thread$B:n@.;~$O>o$K(Bopen$B$K$9$k(B + +;(setq wl-stay-folder-window t) ;; $B%5%^%j$K0\F0$7$?$H$-$K%U%)%k%@%P%C%U%!(B + ;; $B$N1&$K%5%^%j$N%P%C%U%!$rI=<($9$k(B + +;; $B%U%)%k%@uBV$GAw?.$9$k$H!$%-%e!<(B(`wl-queue-folder')$B$K3JG<$9$k(B +(setq wl-draft-enable-queuing t) +;; unplugged $B$+$i(B plugged $B$KJQ$($k$H!$%-%e!<$K$"$k%a%C%;!<%8$rAw?.$9$k(B +(setq wl-auto-flush-queue t) + +;; $B5/F0;~$O%*%U%i%$%s>uBV$K$9$k(B +;(setq wl-plugged nil) +;; $B5/F0;~$K%]!<%H$4$H$N(Bplug$B>uBV$rJQ99$9$k(B +;(add-hook 'wl-make-plugged-hook +; '(lambda () +; ;; server,port$B$N(Bplug$B>uBV$r?75,DI2C$b$7$/$OJQ99$9$k(B +; (elmo-set-plugged plugged$BCM(B(t/nil) server port) +; ;; port $B$r>JN,$9$k$H(Bserver$B$NA4(Bport$B$,JQ99$5$l$k(B +; ;; (port $B$r>JN,$7$F?75,$NDI2C$O$G$-$J$$(B) +; (elmo-set-plugged plugged$BCM(B(t/nil) server) +; )) + + +;; highlight$B$N@_Dj(B ($BL@$k$$GX7J?'$N>l9g$G$9(B) + +;; $B%0%k!<%W$rL$FI?t$K$h$j?'J,$1$7$J$$!#3+JD>uBV$K$h$j?'J,$1$9$k!#(B +;(setq wl-highlight-group-folder-by-numbers nil) + +(setq wl-highlight-message-header-alist + '(("Subject[ \t]*:" . wl-highlight-message-subject-header-contents) + ("From[ \t]*:" . wl-highlight-message-from-header-contents) + ("\\(.*To\\|Cc\\|Newsgroups\\)[ \t]*:" . wl-highlight-message-important-header-contents) + ("\\(User-Agent\\|X-Mailer\\|X-Newsreader\\)[ \t]*:" . + wl-highlight-message-unimportant-header-contents) + )) +;; $B0zMQ%l%Y%k$G?'J,$1$7$J$$(B +;(setq wl-highlight-citation-face-list +; '(wl-highlight-message-cited-text-1)) + +(defun my-wl-set-face (face spec) + (make-face face) + (cond ((fboundp 'face-spec-set) + (face-spec-set face spec)) + (t + (wl-declare-face face spec)))) + +;; $B%a%C%;!<%8%X%C%@(B +(my-wl-set-face 'wl-highlight-message-subject-header-contents + '((t (:foreground "blue" :bold t)))) +(my-wl-set-face 'wl-highlight-message-from-header-contents + '((t (:foreground "red" :bold t)))) +(my-wl-set-face 'wl-highlight-message-important-header-contents + '((t (:foreground "purple" :bold t)))) +(my-wl-set-face 'wl-highlight-message-unimportant-header-contents + '((t (:foreground "RoyalBlue" :bold t)))) +(my-wl-set-face 'wl-highlight-message-headers + '((t (:foreground "magenta3" :bold t)))) +(my-wl-set-face 'wl-highlight-message-header-contents + '((t (:foreground "brown" :bold nil)))) +(my-wl-set-face 'wl-highlight-message-signature + '((t (:foreground "blue")))) +;; $B0zMQ(B +(my-wl-set-face 'wl-highlight-message-citation-header + '((t (:foreground "DarkGreen")))) +(my-wl-set-face 'wl-highlight-message-cited-text-1 + '((t (:foreground "forest green")))) +(my-wl-set-face 'wl-highlight-message-cited-text-2 + '((t (:foreground "SaddleBrown")))) +(my-wl-set-face 'wl-highlight-message-cited-text-3 + '((t (:foreground "orchid3")))) +(my-wl-set-face 'wl-highlight-message-cited-text-4 + '((t (:foreground "purple1")))) +(my-wl-set-face 'wl-highlight-message-cited-text-5 + '((t (:foreground "MediumPurple1")))) +(my-wl-set-face 'wl-highlight-message-cited-text-6 + '((t (:foreground "PaleVioletRed")))) +(my-wl-set-face 'wl-highlight-message-cited-text-7 + '((t (:foreground "LightPink")))) +(my-wl-set-face 'wl-highlight-message-cited-text-8 + '((t (:foreground "salmon")))) +(my-wl-set-face 'wl-highlight-message-cited-text-9 + '((t (:foreground "SandyBrown")))) +(my-wl-set-face 'wl-highlight-message-cited-text-10 + '((t (:foreground "wheat")))) +;; $B%5%^%j(B +(my-wl-set-face 'wl-highlight-summary-important-face + '((t (:foreground "purple")))) +(my-wl-set-face 'wl-highlight-summary-new-face + '((t (:foreground "tomato")))) +(my-wl-set-face 'wl-highlight-summary-unread-face + '((t (:foreground "RoyalBlue")))) +(my-wl-set-face 'wl-highlight-summary-deleted-face + '((t (:foreground "gray")))) +(my-wl-set-face 'wl-highlight-summary-refiled-face + '((t (:foreground "blue")))) +(my-wl-set-face 'wl-highlight-summary-temp-face + '((t (:foreground "salmon")))) +(my-wl-set-face 'wl-highlight-summary-displaying-face + '((t (:bold t :underline t)))) +;; ($B%9%l%C%I(B) +(my-wl-set-face 'wl-highlight-summary-thread-top-face + '((t (:foreground "green4")))) +(my-wl-set-face 'wl-highlight-summary-normal-face + '((t (:foreground "SeaGreen")))) +;; $B%U%)%k%@(B +(my-wl-set-face 'wl-highlight-folder-unknown-face + '((t (:foreground "RoyalBlue")))) +(my-wl-set-face 'wl-highlight-folder-killed-face + '((t (:foreground "gray50")))) +(my-wl-set-face 'wl-highlight-folder-unread-face + '((t (:foreground "brown")))) +(my-wl-set-face 'wl-highlight-folder-zero-face + '((t (:foreground "blue4")))) +(my-wl-set-face 'wl-highlight-folder-few-face + '((t (:foreground "tomato")))) +(my-wl-set-face 'wl-highlight-folder-many-face + '((t (:foreground "HotPink1")))) +;; $B%0%k!<%W(B +(my-wl-set-face 'wl-highlight-folder-opened-face + '((t (:foreground "forest green")))) +(my-wl-set-face 'wl-highlight-folder-closed-face + '((t (:foreground "DarkOliveGreen4")))) +;; $B%9%?!<%H%"%C%W%G%b(B +(my-wl-set-face 'wl-highlight-demo-face + '((t (:foreground "blue2")))) + + +;;; [[ $BFCpJs$r;}$D%U%#!<%k%I$r(Boverview$B>pJs$K(B +;; $BF~$l$k@_Dj(B($B$?$@$7!$(Blocal$B%U%)%k%@$N$_(B) +;; $B<+F0%j%U%!%$%k$KI,MW$J%U%#!<%k%I$b@_Dj(B +(setq elmo-msgdb-extra-fields '("newsgroups" + "x-ml-name" + "x-mail-count" "x-ml-count" + "x-sequence" + "mailing-list")) + +;;; ML $B$N%a%C%;!<%8$G$"$l$P!$%5%^%j$N(B Subject $BI=<($K(B +;;; ML$BL>(B $B$d(B ML$B$K$*$1$k%a%C%;!<%8HV9f$bI=<($9$k(B +(setq wl-summary-subject-func 'my-wl-summary-subject-func-ml) +(defun my-wl-summary-subject-func-ml (subject-string) + (let ((folder wl-summary-buffer-folder-name) + (subj subject-string) (sequence) (ml-name) (ml-count)) + (setq sequence (elmo-msgdb-overview-entity-get-extra-field + entity "x-sequence") + ml-name (or (elmo-msgdb-overview-entity-get-extra-field + entity "x-ml-name") + (and sequence + (car (split-string sequence " ")))) + ml-count (or (elmo-msgdb-overview-entity-get-extra-field + entity "x-mail-count") + (elmo-msgdb-overview-entity-get-extra-field + entity "x-ml-count") + (and sequence + (cadr (split-string sequence " "))))) + (if (string-match + "^\\s(\\(.+\\)[ :]\\([0-9]+\\)\\s)[ \t]*" + subject-string) + (progn + (setq subj (substring subject-string (match-end 0))) + (if (not ml-name) (setq ml-name (match-string 1 subject-string))) + (if (not ml-count) (setq ml-count (match-string 2 subject-string))))) + (if (and ml-name ml-count) + (if (string= folder wl-default-folder) + (format "(%s %05d) %s" + (car (split-string ml-name " ")) + (string-to-int ml-count) + subj) + (format "#%05d %s" + (string-to-int ml-count) subj)) + subj))) + +;; imput $B$K$h$jHsF14|$GAw?.$9$k(B +;; (utils/im-wl.el $B$r%$%s%9%H!<%k$7$F$*$/I,MW$,$"$j$^$9!#(B +;; $B$^$?!$(B~/.im/Config $B$N@_Dj(B(Smtpservers)$B$rK:$l$J$$$3$H$H!$(B +;; wl-draft-enable-queuing $B$N5!G=$,F/$+$J$/$J$k$3$H$KCm0U!#(B) +;(autoload 'wl-draft-send-with-imput-async "im-wl") +;(setq wl-draft-send-func 'wl-draft-send-with-imput-async) + +;; $B%F%s%W%l!<%H$N@_Dj(B +(setq wl-template-alist + '(("default" + ("From" . wl-from) + ("Organization" . "~/.wl sample") + (body . " $B!{!{$G$9!#(B\n")) ;; $BK\J8(B + ("report" + ("To" . "boss@company.jp") + ("Subject" . "$BJs9p(B") + (top . "$B:#=5$NJs9p$G$9!#(B\n") ;; $BK\J8@hF,$X$NA^F~(B +;; (file-bottom . "~/work/report.txt") ;; $BK\J8KvHx$X%U%!%$%k$NA^F~(B + ) + )) + +;; $B%I%i%U%H%P%C%U%!$NFbMF$K$h$j(B From $B$d(B Organization $B$J$I$N%X%C%@$r<+(B +;; $BF0E*$KJQ99$9$k(B +(setq wl-draft-config-alist + '((reply ;; $BJV?.85$N%P%C%U%!$r8+$k(B + "^To: .*\\(test-notsend-wl@lists.airs.net\\)" + (template . "default")) ;; $B%F%s%W%l!<%H(B + ("^To: .*\\(test-notsend-wl@lists.airs.net\\)" + wl-ml-draft-config-func ;; $B4X?t(B + ("From" . wl-from) ;; $BJQ?t(B + ("Organization" . "~/.wl sample")) ;; $BJ8;zNs(B + ("^Newsgroups: test.*" + ("Organization" . "$B%K%e!<%9Ej9F;~$NAH?%L>(B")) + )) +;; $B%I%i%U%H:n@.;~(B($BJV?.;~(B)$B$K!$<+F0E*$K%X%C%@$rJQ99$9$k(B +; (add-hook 'wl-mail-setup-hook +; '(lambda () +; (unless wl-draft-reedit ;; $B:FJT=8;~$OE,MQ$7$J$$(B +; (wl-draft-config-exec wl-draft-config-alist)))) + +;; $B%a!<%k$NJV?.;~$K08@h$rIU$1$kJ}?K$N@_Dj(B + +;; $B2<5-JQ?t$N(B alist $B$NMWAG(B +;; ('$BJV?.85$KB8:_$9$k%U%#!<%k%I(B' . +;; ('To$B%U%#!<%k%I(B' 'Cc$B%U%#!<%k%I(B' 'Newsgroups$B%U%#!<%k%I(B')) + +;; "a" (without-argument)$B$G$O(B Reply-To $B$d(B From $B$J$I$G;XDj$5$l$?M#0l?M(B +;; $B$^$?$OM#0l$D$NEj9F@h$KJV?.$9$k!#$^$?!$(BX-ML-Name $B$H(B Reply-To $B$,$D$$(B +;; $B$F$$$k$J$i(B Reply-To $B08$K$9$k!#(B +; (setq wl-draft-reply-without-argument-list +; '((("X-ML-Name" "Reply-To") . (("Reply-To") nil nil)) +; ("X-ML-Name" . (("To" "Cc") nil nil)) +; ("Followup-To" . (nil nil ("Followup-To"))) +; ("Newsgroups" . (nil nil ("Newsgroups"))) +; ("Reply-To" . (("Reply-To") nil nil)) +; ("Mail-Reply-To" . (("Mail-Reply-To") nil nil)) +; ("From" . (("From") nil nil)))) +; +;; "C-u a" (with-argument)$B$G$"$l$P4X78$9$kA4$F$N?M!&Ej9F@h$KJV?.$9$k!#(B +; (setq wl-draft-reply-with-argument-list +; '(("Followup-To" . (("From") nil ("Followup-To"))) +; ("Newsgroups" . (("From") nil ("Newsgroups"))) +; ("Mail-Followup-To" . (("Mail-Followup-To") nil ("Newsgroups"))) +; ("From" . (("From") ("To" "Cc") ("Newsgroups"))))) + + +;; X-Face $B$rI=<($9$k(B ($BMW(B x-face (and x-face-mule)) + +(when (and window-system + (module-installed-p 'x-face)) + (cond (wl-on-xemacs ;; for XEmacs + (autoload 'x-face-xmas-wl-display-x-face "x-face" nil t) + (setq wl-highlight-x-face-func + 'x-face-xmas-wl-display-x-face)) + ((module-installed-p 'x-face-mule) ;; for Mule (GNU Emacs) + ;; x-face-mule 0.20$B0J8e(B + (setq wl-highlight-x-face-func + (function + (lambda (beg end) + (x-face-mule-x-face-decode-message-header beg end)))) + (setq x-face-mule-highlight-x-face-style 'xmas) + (require 'x-face-mule) + ))) + +;; $B<+F0%j%U%!%$%k$N%k!<%k@_Dj(B +;(setq wl-refile-rule-alist +; '( +; ("x-ml-name" +; ("^Wanderlust" . "+wl") +; ("^Elisp" . "+elisp")) +; ("From" +; ("teranisi@isl.ntt.co.jp" . "+teranisi")))) + +;; $B<+F0%j%U%!%$%k$7$J$$1JB3%^!<%/$r@_Dj(B +;; $BI8=`$G$O(B "N" "U" "!" $B$K$J$C$F$*$j!"L$FI%a%C%;!<%8$r<+F0%j%U%!%$%k$7(B +;; $B$^$;$s!#(Bnil $B$G$9$Y$F$N%a%C%;!<%8$,BP>]$K$J$j$^$9!#(B +;(setq wl-summary-auto-refile-skip-marks nil) + +;; $B%9%3%"5!G=$N@_Dj(B +;; wl-score-folder-alist $B$N@_Dj$K4X$o$i$:I,$:(B "all.SCORE" $B$O;HMQ$5$l$k!#(B +; (setq wl-score-folder-alist +; '(("^-comp\\." +; "news.comp.SCORE" +; "news.SCORE") +; ("^-" +; "news.SCORE"))) +;; $B%9%3%"%U%!%$%k$rCV$/%G%#%l%/%H%j(B +; (setq wl-score-files-directory "~/.elmo/") + +;;; +;;; end of file +;;; diff --git a/utils/bbdb-wl.el b/utils/bbdb-wl.el new file mode 100644 index 0000000..8aa0354 --- /dev/null +++ b/utils/bbdb-wl.el @@ -0,0 +1,254 @@ +;; +;; bbdb setup. +;; +(eval-when-compile + (require 'mime-setup) + (require 'elmo-vars) + (require 'elmo-util) + (require 'bbdb) + (require 'wl-summary) + (require 'wl-message) + (require 'wl-draft) + (require 'wl-address) + (defvar bbdb-pop-up-elided-display nil) + (or (fboundp 'bbdb-extract-field-value-internal) + (defun bbdb-extract-field-value-internal (field)))) + +(defvar bbdb-wl-get-update-record-hook nil) + +(defun bbdb-wl-setup () + (require 'bbdb) + (add-hook 'wl-message-redisplay-hook 'bbdb-wl-get-update-record) + (add-hook 'wl-summary-exit-hook 'bbdb-wl-hide-bbdb-buffer) + (add-hook 'wl-message-window-deleted-hook 'bbdb-wl-hide-bbdb-buffer) + (add-hook 'wl-exit-hook 'bbdb-wl-exit) + (add-hook 'wl-summary-toggle-disp-off-hook 'bbdb-wl-hide-bbdb-buffer) + (add-hook 'wl-summary-toggle-disp-folder-on-hook 'bbdb-wl-hide-bbdb-buffer) + (add-hook 'wl-summary-toggle-disp-folder-off-hook 'bbdb-wl-hide-bbdb-buffer) + (add-hook 'wl-summary-toggle-disp-folder-message-resumed-hook + 'bbdb-wl-show-bbdb-buffer) + (add-hook 'wl-summary-mode-hook + (function + (lambda () + (define-key (current-local-map) ":" 'bbdb-wl-show-sender) + (define-key (current-local-map) ";" 'bbdb-wl-edit-notes)))) + (add-hook 'wl-summary-exit-hook 'bbdb-flush-all-caches) + (add-hook 'wl-summary-exec-hook 'bbdb-flush-all-caches) + (add-hook 'wl-mail-setup-hook + (function + (lambda () +; (local-set-key "\M-\t" 'bbdb-complete-name) + (define-key (current-local-map) "\M-\t" 'bbdb-complete-name) + )))) + +(defun bbdb-wl-exit () + (let (bbdb-buf) + (if (setq bbdb-buf (get-buffer bbdb-buffer-name)) + (kill-buffer bbdb-buf))) + (bbdb-save-db t)) + +(defun bbdb-wl-get-update-record () + (set-buffer (wl-message-get-original-buffer)) + (bbdb-wl-update-record) + (run-hooks 'bbdb-wl-get-update-record-hook)) + +(defun bbdb-wl-hide-bbdb-buffer () + (let (bbdb-buf bbdb-win) + (if (setq bbdb-buf (get-buffer bbdb-buffer-name)) + (if (setq bbdb-win (get-buffer-window bbdb-buf)) + (delete-window bbdb-win))))) + +(defun bbdb-wl-show-bbdb-buffer () + (save-selected-window + (if (get-buffer-window bbdb-buffer-name) + nil + (let ((mes-win (get-buffer-window + (save-excursion + (if (buffer-live-p wl-current-summary-buffer) + (set-buffer wl-current-summary-buffer)) + wl-message-buf-name))) + (cur-win (selected-window)) + (b (current-buffer))) + (and mes-win (select-window mes-win)) + (let ((size (min + (- (window-height mes-win) + window-min-height 1) + (- (window-height mes-win) + (max window-min-height + (1+ bbdb-pop-up-target-lines)))))) + (split-window mes-win (if (> size 0) size window-min-height))) + ;; goto the bottom of the two... + (select-window (next-window)) + ;; make it display *BBDB*... + (let ((pop-up-windows nil)) + (switch-to-buffer (get-buffer-create bbdb-buffer-name))))))) + +(defun bbdb-wl-from-func (string) + "A candidate for wl-summary-from-func..." + (let ((hit (bbdb-search-simple nil (wl-address-header-extract-address + string))) + first-name last-name from-str) + (if hit + (progn + (setq first-name (aref hit 0)) + (setq last-name (aref hit 1)) + (cond ((and (null first-name) + (null last-name)) + (setq from-str string)) + ((and first-name last-name) + (setq from-str (concat first-name " " last-name))) + ((or first-name last-name) + (setq from-str (or first-name last-name)))) + from-str) + string))) + +(defun bbdb-wl-update-record (&optional offer-to-create) + "Returns the record corresponding to the current WL message, +creating or modifying it as necessary. A record will be created if +bbdb/mail-auto-create-p is non-nil, or if OFFER-TO-CREATE is true and +the user confirms the creation." + (save-excursion + (if bbdb-use-pop-up + (bbdb-wl-pop-up-bbdb-buffer offer-to-create) + (let ((key + (save-excursion + (set-buffer + (save-excursion + (if (buffer-live-p wl-current-summary-buffer) + (set-buffer wl-current-summary-buffer)) + wl-message-buf-name)) + (intern (format + "%s-%d" + wl-current-summary-buffer + wl-message-buffer-cur-number))))) + (or (bbdb-message-cache-lookup key nil) + (and key + (let* ((from (or (std11-field-body "From") "")) + (addr (and from + (nth 1 (std11-extract-address-components + from))))) + (if (or (null from) + (null addr) + (string-match (bbdb-user-mail-names) addr)) + (setq from (or (std11-field-body "To") from))) + (with-temp-buffer ; to keep raw buffer unibyte. + (elmo-set-buffer-multibyte + default-enable-multibyte-characters) + (setq from (eword-decode-string + (decode-mime-charset-string + from + wl-mime-charset)))) + (if from + (bbdb-encache-message + key + (bbdb-annotate-message-sender + from t + (or (bbdb-invoke-hook-for-value + bbdb/mail-auto-create-p) + offer-to-create) + offer-to-create)))))))))) + +(defun bbdb-wl-annotate-sender (string) + "Add a line to the end of the Notes field of the BBDB record +corresponding to the sender of this message." + (interactive (list (if bbdb-readonly-p + (error "The Insidious Big Brother Database is read-only.") + (read-string "Comments: ")))) + (set-buffer (wl-message-get-original-buffer)) + (bbdb-annotate-notes (bbdb-wl-update-record t) string)) + +(defun bbdb-wl-edit-notes (&optional arg) + "Edit the notes field or (with a prefix arg) a user-defined field +of the BBDB record corresponding to the sender of this message." + (interactive "P") + (wl-summary-redisplay) + (set-buffer (wl-message-get-original-buffer)) + (let ((record (or (bbdb-wl-update-record t) (error "")))) + (bbdb-display-records (list record)) + (if arg + (bbdb-record-edit-property record nil t) + (bbdb-record-edit-notes record t)))) + +(defun bbdb-wl-show-sender () + "Display the contents of the BBDB for the sender of this message. +This buffer will be in bbdb-mode, with associated keybindings." + (interactive) + (wl-summary-redisplay) + (set-buffer (wl-message-get-original-buffer)) + (let ((record (bbdb-wl-update-record t)) + bbdb-win) + (if record + (progn + (bbdb-wl-pop-up-bbdb-buffer) + (bbdb-display-records (list record))) + (error "unperson")) + (setq bbdb-win (get-buffer-window (get-buffer bbdb-buffer-name))) + (and bbdb-win + (select-window bbdb-win)))) + + +(defun bbdb-wl-pop-up-bbdb-buffer (&optional offer-to-create) + "Make the *BBDB* buffer be displayed along with the WL window(s), +displaying the record corresponding to the sender of the current message." + (if (get-buffer-window bbdb-buffer-name) + nil + (let ((mes-win (get-buffer-window + (save-excursion + (if (buffer-live-p wl-current-summary-buffer) + (set-buffer wl-current-summary-buffer)) + wl-message-buf-name))) + (cur-win (selected-window)) + (b (current-buffer))) + (and mes-win + (select-window mes-win)) + (let ((size (min + (- (window-height mes-win) + window-min-height 1) + (- (window-height mes-win) + (max window-min-height + (1+ bbdb-pop-up-target-lines)))))) + (split-window mes-win (if (> size 0) size window-min-height))) + ;; goto the bottom of the two... + (select-window (next-window)) + ;; make it display *BBDB*... + (let ((pop-up-windows nil)) + (switch-to-buffer (get-buffer-create bbdb-buffer-name))) + ;; select the original window we were in... + (select-window cur-win) + ;; and make sure the current buffer is correct as well. + (set-buffer b))) + (let ((bbdb-gag-messages t) + (bbdb-use-pop-up nil) + (bbdb-electric-p nil)) + (let ((record (bbdb-wl-update-record offer-to-create)) + (bbdb-elided-display (bbdb-pop-up-elided-display)) + (b (current-buffer))) + (bbdb-display-records (if record (list record) nil)) + (set-buffer b) + record))) + +(defun bbdb-wl-send-mail-internal (&optional to subj records) + (unwind-protect + (wl-draft (wl-address-header-extract-address to) "" (or subj "")) + (condition-case nil (delete-other-windows) (error)))) + +;;; @ bbdb-extract-field-value -- stolen from tm-bbdb. +;;; +(and (not (fboundp 'bbdb-extract-field-value-internal)) + (not (fboundp 'tm:bbdb-extract-field-value)) ;; tm-bbdb +;; (not (fboundp 'PLEASE_REPLACE_WITH_SEMI-BASED_MIME-BBDB)) ;; mime-bbdb + (progn + ;; (require 'bbdb-hooks) ; not provided. + ;; (or (fboundp 'bbdb-extract-field-value) ; defined as autoload + (or (fboundp 'bbdb-header-start) + (load "bbdb-hooks")) + (fset 'bbdb-extract-field-value-internal + (symbol-function 'bbdb-extract-field-value)) + (defun bbdb-extract-field-value (field) + (let ((value (bbdb-extract-field-value-internal field))) + (and value + (eword-decode-string value)))) + )) + + +(provide 'bbdb-wl) diff --git a/utils/im-wl.el b/utils/im-wl.el new file mode 100644 index 0000000..947646c --- /dev/null +++ b/utils/im-wl.el @@ -0,0 +1,178 @@ +;;; +;;; im-wl -- IM/Nifty4U+ interface for Wanderlust. +;;; ...not completed. +;;; +;;; Copyright (C) 1998,1999 OKUNISHI Fujikazu +;;; Copyright (C) 1998,1999 Yuuichi Teranishi +;;; +;;; Time-stamp: <1999-09-10 22:58:45 fuji0924> +;;; Author: OKUNISHI Fujikazu +;;; Yuuichi Teranishi +;;; Keywords: mail, news, Wanderlust, IM, Nifty4U+ + +;;; This program is free software; you can redistribute it and/or modify +;;; it under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 2, or (at your option) +;;; any later version. +;;; +;;; This program is distributed in the hope that it will be useful, +;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Emacs; see the file COPYING. If not, write to the +;;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;;; Boston, MA 02111-1307, USA. +;;; + +;;; +;;; General settings: +;;; (autoload 'wl-draft-send-with-imput-async "im-wl") +;;; (setq wl-draft-send-func 'wl-draft-send-with-imput-async) +;;; +;;; for Nifty4U+ users: +;;; (add-hook 'wl-mail-setup-hook '(lambda () (require 'im-wl))) +;;; (setq wl-draft-config-alist +;;; '(("^Newsgroups: nifty\\..*" +;;; ;; to avoid header-encoding. +;;; ;; [cf. slrn-ja-0.9.4.6.jp4/doc/README.macros.euc] +;;; ;(eword-field-encoding-method-alist . '((t . iso-2022-jp-2))) +;;; (wl-draft-send-func . 'wl-draft-send-with-imput-async) +;;; (im-wl-dispatcher . '("~/nifty4u-plus/inews-nifty4u" "-h")) +;;; (im-wl-dispatcher-error-msg +;;; . (format "^%s :" (expand-file-name (car im-wl-dispatcher))))))) + +;;; Code: +;(require 'emu) + +;;; Variables: +(defvar im-wl-dispatcher + '("imput" "-h" "-watch" "--debug=no" "-verbose" "--Queuing=yes") + "Program to post an article and its arguments. +This is most commonly `imput(impost)' or `inews-nifty4u'.") + +(defvar im-wl-dispatcher-error-msg (format "^%s: ERROR:" (car im-wl-dispatcher)) + "Error message of dispatcher") + +(defvar im-wl-default-temp-file-name "~/.imput-temp" + "Default temporary file name (for async).") + +;; xxx for Emacs18/19.x +(or (boundp 'shell-command-switch) + (defvar shell-command-switch "-c")) + +;; Buffer local variables (For async). +(defvar im-wl-buffer-editing-buffer nil) +(defvar im-wl-buffer-sending-buffer nil) +(defvar im-wl-buffer-kill-when-done nil) +(make-variable-buffer-local 'im-wl-buffer-editing-buffer) +(make-variable-buffer-local 'im-wl-buffer-sending-buffer) +(make-variable-buffer-local 'im-wl-buffer-kill-when-done) + + +;;;###autoload +(defun wl-draft-send-with-imput-async (editing-buffer kill-when-done) + "Send the message in the current buffer with imput asynchronously." + (let (buffer-process process-connection-type watch-buffer + (sending-buffer (current-buffer)) + (error-msg-regexp im-wl-dispatcher-error-msg) + (msg (save-excursion + (set-buffer editing-buffer) + (or wl-draft-buffer-file-name + (setq wl-draft-buffer-file-name + (expand-file-name + im-wl-default-temp-file-name)))))) + ;; current buffer is raw buffer. + (save-excursion + (goto-char (point-max)) + ;; require one newline at the end. + (or (= (preceding-char) ?\n) + (insert ?\n)) + ;; Change header-delimiter to be what imput expects. + (let (delimline + (case-fold-search t)) + (save-restriction + (std11-narrow-to-header mail-header-separator) + ;; Insert Message-ID: 'cause wl-do-fcc() does not take care.. + (goto-char (point-min)) + (when (and wl-insert-message-id + (not (re-search-forward "^Message-ID[ \t]*:" nil t))) + (insert (concat "Message-ID: " + (wl-draft-make-message-id-string) "\n"))) + ;; Insert date field. + (goto-char (point-min)) + (or (re-search-forward "^Date[ \t]*:" nil t) + (wl-draft-insert-date-field))) + (run-hooks 'wl-mail-send-pre-hook) ;; X-PGP-Sig, Cancel-Lock + (goto-char (point-min)) + (re-search-forward + (concat "^" (regexp-quote mail-header-separator) "\n") nil t) + (replace-match "\n") + (forward-char -1) + (setq delimline (point-marker)) + ;; ignore any blank lines in the header + (goto-char (point-min)) + (while (and (re-search-forward "\n\n\n*" delimline t) + (< (point) delimline)) + (replace-match "\n")) + ;; Find and handle any FCC fields. + ;; 'cause imput can NOT handle `Fcc: %IMAP'. + (goto-char (point-min)) + (if (re-search-forward "^FCC:" delimline t) + (wl-draft-do-fcc delimline)))) + (set-buffer-modified-p t) + (as-binary-output-file + (write-region (point-min)(point-max) msg nil t)) + ;; The local variables must be binded to 'watch-buffer. + (set-buffer (setq watch-buffer (generate-new-buffer " *Wl Watch*"))) + (setq im-wl-buffer-sending-buffer sending-buffer) + (setq im-wl-buffer-editing-buffer editing-buffer) + (setq im-wl-buffer-kill-when-done kill-when-done) + (setq im-wl-dispatcher-error-msg error-msg-regexp) + ;; Variables specified in wl-draft-config-alist are buffer-local, so + ;; we have to run subprocess under the editing-buffer. + ;; The filter function can find 'watch-buffer by process-buffer(). + (set-buffer sending-buffer) + (setq buffer-process + ;; start-process-shell-command() is Emacs19/20's function. + (start-process + "DISPATCHER" watch-buffer + shell-file-name shell-command-switch + (format "%s < %s" + (mapconcat 'identity im-wl-dispatcher " ") msg))) + (set-process-sentinel buffer-process 'im-wl-watch-process-async) + (message "Sending a message in background") + (if kill-when-done + (wl-draft-hide editing-buffer)))) + +(defun im-wl-watch-process-async (process event) + (let ((process-buffer (process-buffer process)) + editing-buffer kill-when-done raw-buffer) + (set-buffer process-buffer) + (setq editing-buffer im-wl-buffer-editing-buffer) + (setq kill-when-done im-wl-buffer-kill-when-done) + (setq raw-buffer im-wl-buffer-sending-buffer) + (goto-char (point-min)) + (if (null (re-search-forward im-wl-dispatcher-error-msg nil t)) + (progn + ;; sent successfully. + (kill-buffer raw-buffer) + (kill-buffer process-buffer) + (if kill-when-done + (wl-draft-delete editing-buffer))) + (ding) + (message "Send failed") + (kill-buffer raw-buffer) + (switch-to-buffer editing-buffer) + (condition-case () + (progn + (split-window-vertically) + (select-window (next-window))) + (error)) ; ignore error. + (switch-to-buffer process-buffer) + (beginning-of-line)))) + +(provide 'im-wl) + +;;; im-wl.el ends here diff --git a/utils/rfc2368.el b/utils/rfc2368.el new file mode 100644 index 0000000..f66a5f6 --- /dev/null +++ b/utils/rfc2368.el @@ -0,0 +1,152 @@ +;;; rfc2368.el --- support for rfc 2368 + +;;; Copyright 1999 Sen Nagata + +;; Keywords: rfc 2368, mailto, mail +;; Version: 0.3 +;; License: GPL 2 + +;; This file is not a part of GNU Emacs. + +;;; Commentary: +;; +;; notes: +;; +;; -repeat after me: "the colon is not part of the header name..." +;; -if w3 becomes part of emacs, then it may make sense to have this +;; file depend on w3 -- the maintainer of w3 says merging w/ emacs +;; is planned! +;; +;; historical note: +;; +;; this is intended as a replacement for mailto.el +;; +;; acknowledgements: +;; +;; the functions that deal w/ unhexifying in this file were basically +;; taken from w3 -- i hope to replace them w/ something else soon OR +;; perhaps if w3 becomes a part of emacs soon, use the functions from w3. + +;;; History: +;; +;; 0.3: +;; +;; added the constant rfc2368-version +;; implemented first potential fix for a bug in rfc2368-mailto-regexp +;; implemented first potential fix for a bug in rfc2368-parse-mailto +;; (both bugs reported by Kenichi OKADA) +;; +;; 0.2: +;; +;; started to use checkdoc +;; +;; 0.1: +;; +;; initial implementation + +;;; Code: +(defconst rfc2368-version "rfc2368.el 0.3") + +;; only an approximation? +;; see rfc 1738 +(defconst rfc2368-mailto-regexp + "^\\(mailto:\\)\\([^?]+\\)*\\(\\?\\(.*\\)\\)*" + "Regular expression to match and aid in parsing a mailto url.") + +;; describes 'mailto:' +(defconst rfc2368-mailto-scheme-index 1 + "Describes the 'mailto:' portion of the url.") +;; i'm going to call this part the 'prequery' +(defconst rfc2368-mailto-prequery-index 2 + "Describes the portion of the url between 'mailto:' and '?'.") +;; i'm going to call this part the 'query' +(defconst rfc2368-mailto-query-index 4 + "Describes the portion of the url after '?'.") + +;; for dealing w/ unhexifying strings, my preferred approach is to use +;; a 'string-replace-match-using-function' which can perform a +;; string-replace-match and compute the replacement text based on a +;; passed function -- however, emacs doesn't seem to have such a +;; function yet :-( + +;; for the moment a rip-off of url-unhex (w3/url.el) +(defun rfc2368-unhexify-char (char) + "Unhexify CHAR -- e.g. %20 -> ." + (if (> char ?9) + (if (>= char ?a) + (+ 10 (- char ?a)) + (+ 10 (- char ?A))) + (- char ?0))) + +;; for the moment a rip-off of url-unhex-string (w3/url.el) (slightly modified) +(defun rfc2368-unhexify-string (string) + "Unhexify STRING -- e.g. 'hello%20there' -> 'hello there'." + (let ((case-fold-search t) + (result "")) + (while (string-match "%[0-9a-f][0-9a-f]" string) + (let* ((start (match-beginning 0)) + (hex-code (+ (* 16 + (rfc2368-unhexify-char (elt string (+ start 1)))) + (rfc2368-unhexify-char (elt string (+ start 2)))))) + (setq result (concat + result (substring string 0 start) + (char-to-string hex-code)) + string (substring string (match-end 0))))) + ;; it seems clearer to do things this way than to just return: + ;; (concat result string) + (setq result (concat result string)) + result)) + +(defun rfc2368-parse-mailto-url (mailto-url) + "Parse MAILTO-URL, and return an alist of header-name, header-value pairs. +MAILTO-URL should be a RFC 2368 (mailto) compliant url. A cons cell w/ a +key of 'Body' is a special case and is considered a header for this purpose. +The returned alist is intended for use w/ the `compose-mail' interface. +Note: make sure MAILTO-URL has been 'unhtmlized' (e.g. & -> &), before +calling this function." + (let ((case-fold-search t) + prequery query headers-alist) + + (if (string-match rfc2368-mailto-regexp mailto-url) + (progn + + (setq prequery + (match-string rfc2368-mailto-prequery-index mailto-url)) + + (setq query + (match-string rfc2368-mailto-query-index mailto-url)) + + ;; build alist of header name-value pairs + (if (not (null query)) + (setq headers-alist + (mapcar + (lambda (x) + (let* ((temp-list (split-string x "=")) + (header-name (car temp-list)) + (header-value (cadr temp-list))) + ;; return ("Header-Name" . "header-value") + (cons + (capitalize (rfc2368-unhexify-string header-name)) + (rfc2368-unhexify-string header-value)))) + (split-string query "&")))) + + ;; deal w/ multiple 'To' recipients + (if prequery + (progn + (if (assoc "To" headers-alist) + (let* ((our-cons-cell + (assoc "To" headers-alist)) + (our-cdr + (cdr our-cons-cell))) + (setcdr our-cons-cell (concat our-cdr ", " prequery))) + (setq headers-alist + (cons (cons "To" prequery) headers-alist))))) + + headers-alist) + + (error "Failed to match a mailto: url")) + )) + +(provide 'rfc2368) + +;;; rfc2368.el ends here diff --git a/utils/sasl/README.en b/utils/sasl/README.en new file mode 100644 index 0000000..ab8fad8 --- /dev/null +++ b/utils/sasl/README.en @@ -0,0 +1,17 @@ +README: SASL library for Emacs. +========================================================= + +How to compile elisp files: + + cd lisp + emacs --batch --no-init-file --no-site-file \ + --eval '(setq load-path (cons "." load-path))' \ + --funcall batch-byte-compile *.el + +How to compile DL modules (Emacs 20.3 and later with DL patch): + + cd src + gcc -shared -nostdlib -fPIC -I${EMACSSRCDIR}/src -o md5.so md5-dl.c -lcrypto + gcc -shared -nostdlib -fPIC -I${EMACSSRCDIR}/src -o sha1.so sha1-dl.c -lcrypto + + Current version of DL modules require libcrypto library from OpenSSL. diff --git a/utils/sasl/lisp/digest-md5.el b/utils/sasl/lisp/digest-md5.el new file mode 100644 index 0000000..e72c535 --- /dev/null +++ b/utils/sasl/lisp/digest-md5.el @@ -0,0 +1,144 @@ +;;; digest-md5.el --- Compute DIGEST-MD5. + +;; Copyright (C) 1999 Kenichi OKADA + +;; Author: Kenichi OKADA +;; Daiki Ueno +;; Keywords: DIGEST-MD5, HMAC-MD5, SASL, IMAP, POP, ACAP + +;; This file is part of FLIM (Faithful Library about Internet Message). + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 2, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; This program is implemented from draft-leach-digest-sasl-05.txt. +;; +;; It is caller's responsibility to base64-decode challenges and +;; base64-encode responses in IMAP4 AUTHENTICATE command. +;; +;; Passphrase should be longer than 16 bytes. (See RFC 2195) + +;; Examples. +;; +;; (digest-md5-parse-digest-challenge +;; "realm=\"elwood.innosoft.com\",nonce=\"OA6MG9tEQGm2hh\",qop=\"auth\",algorithm=md5-sess,charset=utf-8") +;; => (realm "elwood.innosoft.com" nonce "OA6MG9tEQGm2hh" qop "auth" algorithm md5-sess charset utf-8) + +;; (digest-md5-build-response-value +;; "chris" "elwood.innosoft.com" "secret" "OA6MG9tEQGm2hh" +;; "OA6MHXh6VqTrRk" 1 "imap/elwood.innosoft.com" "auth") +;; => "d388dad90d4bbd760a152321f2143af7" + +;;; Code: + +(require 'hmac-md5) +(require 'unique-id) + +(defvar digest-md5-challenge nil) + +(defvar digest-md5-parse-digest-challenge-syntax-table + (let ((table (make-syntax-table))) + (modify-syntax-entry ?= "." table) + (modify-syntax-entry ?, "." table) + table) + "A syntax table for parsing digest-challenge attributes.") + +;;;###autoload +(defun digest-md5-parse-digest-challenge (digest-challenge) + ;; return a property list of + ;; (realm nonce qop-options stale maxbuf charset + ;; algorithm cipher-opts auth-param). + (with-temp-buffer + (set-syntax-table digest-md5-parse-digest-challenge-syntax-table) + (insert digest-challenge) + (goto-char (point-min)) + (insert "(") + (while (progn (forward-sexp) (not (eobp))) + (delete-char 1) + (insert " ")) + (insert ")") + (condition-case nil + (setplist 'digest-md5-challenge (read (point-min-marker))) + (end-of-file + (error "Parse error in digest-challenge."))))) + +(defun digest-md5-digest-uri (serv-type host &optional serv-name) + (concat serv-type "/" host + (if (and serv-name + (null (string= host serv-name))) + (concat "/" serv-name)))) + +(defmacro digest-md5-cnonce () + ;; It is RECOMMENDED that it + ;; contain at least 64 bits of entropy. + '(concat (unique-id-m "") (unique-id-m ""))) + +(defmacro digest-md5-challenge (prop) + (list 'get ''digest-md5-challenge prop)) + +(defmacro digest-md5-build-response-value + (username realm passwd nonce cnonce nonce-count digest-uri qop) + `(encode-hex-string + (md5-binary + (concat + (encode-hex-string + (md5-binary (concat (md5-binary + (concat ,username + ":" ,realm + ":" ,passwd)) + ":" ,nonce + ":" ,cnonce + (let ((authzid (digest-md5-challenge 'authzid))) + (if authzid (concat ":" authzid) nil))))) + ":" ,nonce + ":" (format "%08x" ,nonce-count) ":" ,cnonce ":" ,qop ":" + (encode-hex-string + (md5-binary + (concat "AUTHENTICATE:" ,digest-uri + (if (string-equal "auth-int" ,qop) + ":00000000000000000000000000000000" + nil)))))))) + +;;;###autoload +(defun digest-md5-digest-response + (username realm passwd nonce cnonce nonce-count digest-uri + &optional charset qop maxbuf cipher authzid) + (concat + "username=\"" username "\"," + "realm=\"" realm "\"," + "nonce=\"" nonce "\"," + (format "nc=%08x," nonce-count) + "cnonce=\"" cnonce "\"," + "digest-uri=\"" digest-uri "\"," + "response=" + (digest-md5-build-response-value + username realm passwd nonce cnonce nonce-count digest-uri + (or qop "auth")) + "," + (mapconcat + #'identity + (delq nil + (mapcar (lambda (prop) + (if (digest-md5-challenge prop) + (format "%s=%s" + prop (digest-md5-challenge prop)))) + '(charset qop maxbuf cipher authzid))) + ","))) + +(provide 'digest-md5) + +;;; digest-md5.el ends here diff --git a/utils/sasl/lisp/hex-util.el b/utils/sasl/lisp/hex-util.el new file mode 100644 index 0000000..92a09ff --- /dev/null +++ b/utils/sasl/lisp/hex-util.el @@ -0,0 +1,73 @@ +;;; hex-util.el --- Functions to encode/decode hexadecimal string. + +;; Copyright (C) 1999 Shuhei KOBAYASHI + +;; Author: Shuhei KOBAYASHI +;; Keywords: data + +;; This file is part of FLIM (Faithful Library about Internet Message). + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 2, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;;; Code: + +(eval-when-compile + (defmacro hex-char-to-num (chr) + (` (let ((chr (, chr))) + (cond + ((and (<= ?a chr)(<= chr ?f)) (+ (- chr ?a) 10)) + ((and (<= ?A chr)(<= chr ?F)) (+ (- chr ?A) 10)) + ((and (<= ?0 chr)(<= chr ?9)) (- chr ?0)) + (t (error "Invalid hexadecimal digit `%c'" chr)))))) + (defmacro num-to-hex-char (num) + (` (aref "0123456789abcdef" (, num))))) + +(defun decode-hex-string (string) + "Decode hexadecimal STRING to octet string." + (let* ((len (length string)) + (dst (make-string (/ len 2) 0)) + (idx 0)(pos 0)) + (while (< pos len) +;;; logior and lsh are not byte-coded. +;;; (aset dst idx (logior (lsh (hex-char-to-num (aref string pos)) 4) +;;; (hex-char-to-num (aref string (1+ pos))))) + (aset dst idx (+ (* (hex-char-to-num (aref string pos)) 16) + (hex-char-to-num (aref string (1+ pos))))) + (setq idx (1+ idx) + pos (+ 2 pos))) + dst)) + +(defun encode-hex-string (string) + "Encode octet STRING to hexadecimal string." + (let* ((len (length string)) + (dst (make-string (* len 2) 0)) + (idx 0)(pos 0)) + (while (< pos len) +;;; logand and lsh are not byte-coded. +;;; (aset dst idx (num-to-hex-char (logand (lsh (aref string pos) -4) 15))) + (aset dst idx (num-to-hex-char (/ (aref string pos) 16))) + (setq idx (1+ idx)) +;;; (aset dst idx (num-to-hex-char (logand (aref string pos) 15))) + (aset dst idx (num-to-hex-char (% (aref string pos) 16))) + (setq idx (1+ idx) + pos (1+ pos))) + dst)) + +(provide 'hex-util) + +;;; hex-util.el ends here diff --git a/utils/sasl/lisp/hmac-def.el b/utils/sasl/lisp/hmac-def.el new file mode 100644 index 0000000..7525c89 --- /dev/null +++ b/utils/sasl/lisp/hmac-def.el @@ -0,0 +1,85 @@ +;;; hmac-def.el --- A macro for defining HMAC functions. + +;; Copyright (C) 1999 Shuhei KOBAYASHI + +;; Author: Shuhei KOBAYASHI +;; Keywords: HMAC, RFC 2104 + +;; This file is part of FLIM (Faithful Library about Internet Message). + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 2, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; This program is implemented from RFC 2104, +;; "HMAC: Keyed-Hashing for Message Authentication". + +;;; Code: + +(defmacro define-hmac-function (name H B L &optional bit) + "Define a function NAME(TEXT KEY) which computes HMAC with function H. + +HMAC function is H(KEY XOR opad, H(KEY XOR ipad, TEXT)): + +H is a cryptographic hash function, such as SHA1 and MD5, which takes +a string and return a digest of it (in binary form). +B is a byte-length of a block size of H. (B=64 for both SHA1 and MD5.) +L is a byte-length of hash outputs. (L=16 for MD5, L=20 for SHA1.) +If BIT is non-nil, truncate output to specified bits." + (` (defun (, name) (text key) + (, (concat "Compute " + (upcase (symbol-name name)) + " over TEXT with KEY.")) + (let ((key-xor-ipad (make-string (, B) ?\x36)) + (key-xor-opad (make-string (, B) ?\x5C)) + (len (length key)) + (pos 0)) + (unwind-protect + (progn + ;; if `key' is longer than the block size, apply hash function + ;; to `key' and use the result as a real `key'. + (if (> len (, B)) + (setq key ((, H) key) + len (, L))) + (while (< pos len) + (aset key-xor-ipad pos (logxor (aref key pos) ?\x36)) + (aset key-xor-opad pos (logxor (aref key pos) ?\x5C)) + (setq pos (1+ pos))) + (setq key-xor-ipad (unwind-protect + (concat key-xor-ipad text) + (fillarray key-xor-ipad 0)) + key-xor-ipad (unwind-protect + ((, H) key-xor-ipad) + (fillarray key-xor-ipad 0)) + key-xor-opad (unwind-protect + (concat key-xor-opad key-xor-ipad) + (fillarray key-xor-opad 0)) + key-xor-opad (unwind-protect + ((, H) key-xor-opad) + (fillarray key-xor-opad 0))) + ;; now `key-xor-opad' contains + ;; H(KEY XOR opad, H(KEY XOR ipad, TEXT)). + (, (if (and bit (< (/ bit 8) L)) + (` (substring key-xor-opad 0 (, (/ bit 8)))) + ;; return a copy of `key-xor-opad'. + (` (concat key-xor-opad))))) + ;; cleanup. + (fillarray key-xor-ipad 0) + (fillarray key-xor-opad 0)))))) + +(provide 'hmac-def) + +;;; hmac-def.el ends here diff --git a/utils/sasl/lisp/hmac-md5.el b/utils/sasl/lisp/hmac-md5.el new file mode 100644 index 0000000..9c936d0 --- /dev/null +++ b/utils/sasl/lisp/hmac-md5.el @@ -0,0 +1,95 @@ +;;; hmac-md5.el --- Compute HMAC-MD5. + +;; Copyright (C) 1999 Shuhei KOBAYASHI + +;; Author: Shuhei KOBAYASHI +;; Kenichi OKADA +;; Maintainer: Kenichi OKADA +;; Keywords: HMAC, RFC 2104, HMAC-MD5, MD5, KEYED-MD5, CRAM-MD5 + +;; This file is part of FLIM (Faithful Library about Internet Message). + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 2, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; Test cases from RFC 2202, "Test Cases for HMAC-MD5 and HMAC-SHA-1". +;; +;; (encode-hex-string (hmac-md5 "Hi There" (make-string 16 ?\x0b))) +;; => "9294727a3638bb1c13f48ef8158bfc9d" +;; +;; (encode-hex-string (hmac-md5 "what do ya want for nothing?" "Jefe")) +;; => "750c783e6ab0b503eaa86e310a5db738" +;; +;; (encode-hex-string (hmac-md5 (make-string 50 ?\xdd) (make-string 16 ?\xaa))) +;; => "56be34521d144c88dbb8c733f0e8b3f6" +;; +;; (encode-hex-string +;; (hmac-md5 +;; (make-string 50 ?\xcd) +;; (decode-hex-string "0102030405060708090a0b0c0d0e0f10111213141516171819"))) +;; => "697eaf0aca3a3aea3a75164746ffaa79" +;; +;; (encode-hex-string +;; (hmac-md5 "Test With Truncation" (make-string 16 ?\x0c))) +;; => "56461ef2342edc00f9bab995690efd4c" +;; (encode-hex-string +;; (hmac-md5-96 "Test With Truncation" (make-string 16 ?\x0c))) +;; => "56461ef2342edc00f9bab995" +;; +;; (encode-hex-string +;; (hmac-md5 +;; "Test Using Larger Than Block-Size Key - Hash Key First" +;; (make-string 80 ?\xaa))) +;; => "6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd" +;; +;; (encode-hex-string +;; (hmac-md5 +;; "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data" +;; (make-string 80 ?\xaa))) +;; => "6f630fad67cda0ee1fb1f562db3aa53e" + +;;; Code: + +(eval-when-compile (require 'hmac-def)) +(require 'hex-util) ; (decode-hex-string STRING) +(require 'md5) ; expects (md5 STRING) + +;; We cannot define this function in md5.el because recent XEmacs provides +;; built-in md5 function and provides feature 'md5 at startup. +(if (and (featurep 'xemacs) + (fboundp 'md5) + (subrp (symbol-function 'md5)) + (condition-case nil + ;; `md5' of XEmacs 21 takes 4th arg CODING (and 5th arg NOERROR). + (md5 "" nil nil 'binary) ; => "fb5d2156096fa1f254352f3cc3fada7e" + (error nil))) + ;; XEmacs 21. + (defun md5-binary (string &optional start end) + "Return the MD5 of STRING in binary form." + (decode-hex-string (md5 string start end 'binary))) + ;; not XEmacs 21 and not DL. + (if (not (fboundp 'md5-binary)) + (defun md5-binary (string) + "Return the MD5 of STRING in binary form." + (decode-hex-string (md5 string))))) + +(define-hmac-function hmac-md5 md5-binary 64 16) ; => (hmac-md5 TEXT KEY) +;; (define-hmac-function hmac-md5-96 md5-binary 64 16 96) + +(provide 'hmac-md5) + +;;; hmac-md5.el ends here diff --git a/utils/sasl/lisp/hmac-sha1.el b/utils/sasl/lisp/hmac-sha1.el new file mode 100644 index 0000000..6b2beea --- /dev/null +++ b/utils/sasl/lisp/hmac-sha1.el @@ -0,0 +1,80 @@ +;;; hmac-sha1.el --- Compute HMAC-SHA1. + +;; Copyright (C) 1999 Shuhei KOBAYASHI + +;; Author: Shuhei KOBAYASHI +;; Keywords: HMAC, RFC 2104, HMAC-SHA1, SHA1, Cancel-Lock + +;; This file is part of FLIM (Faithful Library about Internet Message). + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 2, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; Test cases from RFC 2202, "Test Cases for HMAC-MD5 and HMAC-SHA-1". +;; +;; (encode-hex-string (hmac-sha1 "Hi There" (make-string 20 ?\x0b))) +;; => "b617318655057264e28bc0b6fb378c8ef146be00" +;; +;; (encode-hex-string (hmac-sha1 "what do ya want for nothing?" "Jefe")) +;; => "effcdf6ae5eb2fa2d27416d5f184df9c259a7c79" +;; +;; (encode-hex-string (hmac-sha1 (make-string 50 ?\xdd) (make-string 20 ?\xaa))) +;; => "125d7342b9ac11cd91a39af48aa17b4f63f175d3" +;; +;; (encode-hex-string +;; (hmac-sha1 +;; (make-string 50 ?\xcd) +;; (decode-hex-string "0102030405060708090a0b0c0d0e0f10111213141516171819"))) +;; => "4c9007f4026250c6bc8414f9bf50c86c2d7235da" +;; +;; (encode-hex-string +;; (hmac-sha1 "Test With Truncation" (make-string 20 ?\x0c))) +;; => "4c1a03424b55e07fe7f27be1d58bb9324a9a5a04" +;; (encode-hex-string +;; (hmac-sha1-96 "Test With Truncation" (make-string 20 ?\x0c))) +;; => "4c1a03424b55e07fe7f27be1" +;; +;; (encode-hex-string +;; (hmac-sha1 +;; "Test Using Larger Than Block-Size Key - Hash Key First" +;; (make-string 80 ?\xaa))) +;; => "aa4ae5e15272d00e95705637ce8a3b55ed402112" +;; +;; (encode-hex-string +;; (hmac-sha1 +;; "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data" +;; (make-string 80 ?\xaa))) +;; => "e8e99d0f45237d786d6bbaa7965c7808bbff1a91" + +;;; Code: + +(eval-when-compile (require 'hmac-def)) +(require 'hex-util) ; (decode-hex-string STRING) +(require 'sha1) ; expects (sha1 STRING) + +;;; For consintency with hmac-md5.el, we define this function here. +(or (fboundp 'sha1-binary) + (defun sha1-binary (string) + "Return the SHA1 of STRING in binary form." + (decode-hex-string (sha1 string)))) + +(define-hmac-function hmac-sha1 sha1-binary 64 20) ; => (hmac-sha1 TEXT KEY) +;; (define-hmac-function hmac-sha1-96 sha1-binary 64 20 96) + +(provide 'hmac-sha1) + +;;; hmac-sha1.el ends here diff --git a/utils/sasl/lisp/md5-dl.el b/utils/sasl/lisp/md5-dl.el new file mode 100644 index 0000000..4bc12bf --- /dev/null +++ b/utils/sasl/lisp/md5-dl.el @@ -0,0 +1,66 @@ +;;; md5-dl.el --- MD5 Message Digest Algorithm using DL module. + +;; Copyright (C) 1999 Shuhei KOBAYASHI + +;; Author: Shuhei KOBAYASHI +;; Keywords: MD5, RFC 1321 + +;; This file is part of FLIM (Faithful Library about Internet Message). + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 2, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;;; Code: + +(defvar md5-dl-module + (if (and (fboundp 'md5-string) + (subrp (symbol-function 'md5-string))) + nil + (if (fboundp 'dynamic-link) + (let ((path (expand-file-name "md5.so" exec-directory))) + (and (file-exists-p path) + path))))) + +(defvar md5-dl-handle + (and (stringp md5-dl-module) + (file-exists-p md5-dl-module) + (dynamic-link md5-dl-module))) + +;;; md5-dl-module provides `md5-string'. +(dynamic-call "emacs_md5_init" md5-dl-handle) + +(defun md5-region (beg end) + (interactive "r") + (md5-string (buffer-substring-no-properties beg end))) + +;;; Note that XEmacs built-in version takes two more args: CODING and NOERROR. +;;;###autoload +(defun md5 (object &optional beg end) + "Return the MD5 (a secure message digest algorithm) of an object. +OBJECT is either a string or a buffer. +Optional arguments BEG and END denote buffer positions for computing the +hash of a portion of OBJECT." + (if (stringp object) + (md5-string object) + (save-excursion + (set-buffer object) + (md5-region (or beg (point-min)) (or end (point-max)))))) + +(provide 'md5-dl) +(provide 'md5) + +;;; md5-dl.el ends here. diff --git a/utils/sasl/lisp/md5-el.el b/utils/sasl/lisp/md5-el.el new file mode 100644 index 0000000..a339cec --- /dev/null +++ b/utils/sasl/lisp/md5-el.el @@ -0,0 +1,408 @@ +;;; md5.el -- MD5 Message Digest Algorithm +;;; Gareth Rees + +;; LCD Archive Entry: +;; md5|Gareth Rees|gdr11@cl.cam.ac.uk| +;; MD5 cryptographic message digest algorithm| +;; 13-Nov-95|1.0|~/misc/md5.el.Z| + +;;; Details: ------------------------------------------------------------------ + +;; This is a direct translation into Emacs LISP of the reference C +;; implementation of the MD5 Message-Digest Algorithm written by RSA +;; Data Security, Inc. +;; +;; The algorithm takes a message (that is, a string of bytes) and +;; computes a 16-byte checksum or "digest" for the message. This digest +;; is supposed to be cryptographically strong in the sense that if you +;; are given a 16-byte digest D, then there is no easier way to +;; construct a message whose digest is D than to exhaustively search the +;; space of messages. However, the robustness of the algorithm has not +;; been proven, and a similar algorithm (MD4) was shown to be unsound, +;; so treat with caution! +;; +;; The C algorithm uses 32-bit integers; because GNU Emacs +;; implementations provide 28-bit integers (with 24-bit integers on +;; versions prior to 19.29), the code represents a 32-bit integer as the +;; cons of two 16-bit integers. The most significant word is stored in +;; the car and the least significant in the cdr. The algorithm requires +;; at least 17 bits of integer representation in order to represent the +;; carry from a 16-bit addition. + +;;; Usage: -------------------------------------------------------------------- + +;; To compute the MD5 Message Digest for a message M (represented as a +;; string or as a vector of bytes), call +;; +;; (md5-encode M) +;; +;; which returns the message digest as a vector of 16 bytes. If you +;; need to supply the message in pieces M1, M2, ... Mn, then call +;; +;; (md5-init) +;; (md5-update M1) +;; (md5-update M2) +;; ... +;; (md5-update Mn) +;; (md5-final) + +;;; Copyright and licence: ---------------------------------------------------- + +;; Copyright (C) 1995, 1996, 1997 by Gareth Rees +;; Derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm +;; +;; md5.el is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published by the +;; Free Software Foundation; either version 2, or (at your option) any +;; later version. +;; +;; md5.el is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +;; for more details. +;; +;; The original copyright notice is given below, as required by the +;; licence for the original code. This code is distributed under *both* +;; RSA's original licence and the GNU General Public Licence. (There +;; should be no problems, as the former is more liberal than the +;; latter). + +;;; Original copyright notice: ------------------------------------------------ + +;; Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. +;; +;; License to copy and use this software is granted provided that it is +;; identified as the "RSA Data Security, Inc. MD5 Message- Digest +;; Algorithm" in all material mentioning or referencing this software or +;; this function. +;; +;; License is also granted to make and use derivative works provided +;; that such works are identified as "derived from the RSA Data +;; Security, Inc. MD5 Message-Digest Algorithm" in all material +;; mentioning or referencing the derived work. +;; +;; RSA Data Security, Inc. makes no representations concerning either +;; the merchantability of this software or the suitability of this +;; software for any particular purpose. It is provided "as is" without +;; express or implied warranty of any kind. +;; +;; These notices must be retained in any copies of any part of this +;; documentation and/or software. + +;;; Code: --------------------------------------------------------------------- + +(defvar md5-program "md5" + "*Program that reads a message on its standard input and writes an +MD5 digest on its output.") + +(defvar md5-maximum-internal-length 4096 + "*The maximum size of a piece of data that should use the MD5 routines +written in lisp. If a message exceeds this, it will be run through an +external filter for processing. Also see the `md5-program' variable. +This variable has no effect if you call the md5-init|update|final +functions - only used by the `md5' function's simpler interface.") + +(defvar md5-bits (make-vector 4 0) + "Number of bits handled, modulo 2^64. +Represented as four 16-bit numbers, least significant first.") +(defvar md5-buffer (make-vector 4 '(0 . 0)) + "Scratch buffer (four 32-bit integers).") +(defvar md5-input (make-vector 64 0) + "Input buffer (64 bytes).") + +(defun md5-unhex (x) + (if (> x ?9) + (if (>= x ?a) + (+ 10 (- x ?a)) + (+ 10 (- x ?A))) + (- x ?0))) + +(defun md5-encode (message) + "Encodes MESSAGE using the MD5 message digest algorithm. +MESSAGE must be a string or an array of bytes. +Returns a vector of 16 bytes containing the message digest." + (if (or (null md5-maximum-internal-length) + (<= (length message) md5-maximum-internal-length)) + (progn + (md5-init) + (md5-update message) + (md5-final)) + (save-excursion + (set-buffer (get-buffer-create " *md5-work*")) + (erase-buffer) + (insert message) + (call-process-region (point-min) (point-max) + md5-program + t (current-buffer)) + ;; MD5 digest is 32 chars long + ;; mddriver adds a newline to make neaten output for tty + ;; viewing, make sure we leave it behind. + (let ((data (buffer-substring (point-min) (+ (point-min) 32))) + (vec (make-vector 16 0)) + (ctr 0)) + (while (< ctr 16) + (aset vec ctr (+ (* 16 (md5-unhex (aref data (* ctr 2)))) + (md5-unhex (aref data (1+ (* ctr 2)))))) + (setq ctr (1+ ctr))))))) + +(defsubst md5-add (x y) + "Return 32-bit sum of 32-bit integers X and Y." + (let ((m (+ (car x) (car y))) + (l (+ (cdr x) (cdr y)))) + (cons (logand 65535 (+ m (lsh l -16))) (logand l 65535)))) + +;; FF, GG, HH and II are basic MD5 functions, providing transformations +;; for rounds 1, 2, 3 and 4 respectively. Each function follows this +;; pattern of computation (where ROTATE(x,y) means rotate 32-bit value x +;; by y bits to the left): +;; +;; FF(a,b,c,d,x,s,ac) = ROTATE(a + F(b,c,d) + x + ac,s) + b +;; +;; so we use the macro `md5-make-step' to construct each one. The +;; helper functions F, G, H and I operate on 16-bit numbers; the full +;; operation splits its inputs, operates on the halves separately and +;; then puts the results together. + +(defsubst md5-F (x y z) (logior (logand x y) (logand (lognot x) z))) +(defsubst md5-G (x y z) (logior (logand x z) (logand y (lognot z)))) +(defsubst md5-H (x y z) (logxor x y z)) +(defsubst md5-I (x y z) (logxor y (logior x (logand 65535 (lognot z))))) + +(defmacro md5-make-step (name func) + (` + (defun (, name) (a b c d x s ac) + (let* + ((m1 (+ (car a) ((, func) (car b) (car c) (car d)) (car x) (car ac))) + (l1 (+ (cdr a) ((, func) (cdr b) (cdr c) (cdr d)) (cdr x) (cdr ac))) + (m2 (logand 65535 (+ m1 (lsh l1 -16)))) + (l2 (logand 65535 l1)) + (m3 (logand 65535 (if (> s 15) + (+ (lsh m2 (- s 32)) (lsh l2 (- s 16))) + (+ (lsh m2 s) (lsh l2 (- s 16)))))) + (l3 (logand 65535 (if (> s 15) + (+ (lsh l2 (- s 32)) (lsh m2 (- s 16))) + (+ (lsh l2 s) (lsh m2 (- s 16))))))) + (md5-add (cons m3 l3) b))))) + +(md5-make-step md5-FF md5-F) +(md5-make-step md5-GG md5-G) +(md5-make-step md5-HH md5-H) +(md5-make-step md5-II md5-I) + +(defun md5-init () + "Initialise the state of the message-digest routines." + (aset md5-bits 0 0) + (aset md5-bits 1 0) + (aset md5-bits 2 0) + (aset md5-bits 3 0) + (aset md5-buffer 0 '(26437 . 8961)) + (aset md5-buffer 1 '(61389 . 43913)) + (aset md5-buffer 2 '(39098 . 56574)) + (aset md5-buffer 3 '( 4146 . 21622))) + +(defun md5-update (string) + "Update the current MD5 state with STRING (an array of bytes)." + (let ((len (length string)) + (i 0) + (j 0)) + (while (< i len) + ;; Compute number of bytes modulo 64 + (setq j (% (/ (aref md5-bits 0) 8) 64)) + + ;; Store this byte (truncating to 8 bits to be sure) + (aset md5-input j (logand 255 (aref string i))) + + ;; Update number of bits by 8 (modulo 2^64) + (let ((c 8) (k 0)) + (while (and (> c 0) (< k 4)) + (let ((b (aref md5-bits k))) + (aset md5-bits k (logand 65535 (+ b c))) + (setq c (if (> b (- 65535 c)) 1 0) + k (1+ k))))) + + ;; Increment number of bytes processed + (setq i (1+ i)) + + ;; When 64 bytes accumulated, pack them into sixteen 32-bit + ;; integers in the array `in' and then tranform them. + (if (= j 63) + (let ((in (make-vector 16 (cons 0 0))) + (k 0) + (kk 0)) + (while (< k 16) + (aset in k (md5-pack md5-input kk)) + (setq k (+ k 1) kk (+ kk 4))) + (md5-transform in)))))) + +(defun md5-pack (array i) + "Pack the four bytes at ARRAY reference I to I+3 into a 32-bit integer." + (cons (+ (lsh (aref array (+ i 3)) 8) (aref array (+ i 2))) + (+ (lsh (aref array (+ i 1)) 8) (aref array (+ i 0))))) + +(defun md5-byte (array n b) + "Unpack byte B (0 to 3) from Nth member of ARRAY of 32-bit integers." + (let ((e (aref array n))) + (cond ((eq b 0) (logand 255 (cdr e))) + ((eq b 1) (lsh (cdr e) -8)) + ((eq b 2) (logand 255 (car e))) + ((eq b 3) (lsh (car e) -8))))) + +(defun md5-final () + (let ((in (make-vector 16 (cons 0 0))) + (j 0) + (digest (make-vector 16 0)) + (padding)) + + ;; Save the number of bits in the message + (aset in 14 (cons (aref md5-bits 1) (aref md5-bits 0))) + (aset in 15 (cons (aref md5-bits 3) (aref md5-bits 2))) + + ;; Compute number of bytes modulo 64 + (setq j (% (/ (aref md5-bits 0) 8) 64)) + + ;; Pad out computation to 56 bytes modulo 64 + (setq padding (make-vector (if (< j 56) (- 56 j) (- 120 j)) 0)) + (aset padding 0 128) + (md5-update padding) + + ;; Append length in bits and transform + (let ((k 0) (kk 0)) + (while (< k 14) + (aset in k (md5-pack md5-input kk)) + (setq k (+ k 1) kk (+ kk 4)))) + (md5-transform in) + + ;; Store the results in the digest + (let ((k 0) (kk 0)) + (while (< k 4) + (aset digest (+ kk 0) (md5-byte md5-buffer k 0)) + (aset digest (+ kk 1) (md5-byte md5-buffer k 1)) + (aset digest (+ kk 2) (md5-byte md5-buffer k 2)) + (aset digest (+ kk 3) (md5-byte md5-buffer k 3)) + (setq k (+ k 1) kk (+ kk 4)))) + + ;; Return digest + digest)) + +;; It says in the RSA source, "Note that if the Mysterious Constants are +;; arranged backwards in little-endian order and decrypted with the DES +;; they produce OCCULT MESSAGES!" Security through obscurity? + +(defun md5-transform (in) + "Basic MD5 step. Transform md5-buffer based on array IN." + (let ((a (aref md5-buffer 0)) + (b (aref md5-buffer 1)) + (c (aref md5-buffer 2)) + (d (aref md5-buffer 3))) + (setq + a (md5-FF a b c d (aref in 0) 7 '(55146 . 42104)) + d (md5-FF d a b c (aref in 1) 12 '(59591 . 46934)) + c (md5-FF c d a b (aref in 2) 17 '( 9248 . 28891)) + b (md5-FF b c d a (aref in 3) 22 '(49597 . 52974)) + a (md5-FF a b c d (aref in 4) 7 '(62844 . 4015)) + d (md5-FF d a b c (aref in 5) 12 '(18311 . 50730)) + c (md5-FF c d a b (aref in 6) 17 '(43056 . 17939)) + b (md5-FF b c d a (aref in 7) 22 '(64838 . 38145)) + a (md5-FF a b c d (aref in 8) 7 '(27008 . 39128)) + d (md5-FF d a b c (aref in 9) 12 '(35652 . 63407)) + c (md5-FF c d a b (aref in 10) 17 '(65535 . 23473)) + b (md5-FF b c d a (aref in 11) 22 '(35164 . 55230)) + a (md5-FF a b c d (aref in 12) 7 '(27536 . 4386)) + d (md5-FF d a b c (aref in 13) 12 '(64920 . 29075)) + c (md5-FF c d a b (aref in 14) 17 '(42617 . 17294)) + b (md5-FF b c d a (aref in 15) 22 '(18868 . 2081)) + a (md5-GG a b c d (aref in 1) 5 '(63006 . 9570)) + d (md5-GG d a b c (aref in 6) 9 '(49216 . 45888)) + c (md5-GG c d a b (aref in 11) 14 '( 9822 . 23121)) + b (md5-GG b c d a (aref in 0) 20 '(59830 . 51114)) + a (md5-GG a b c d (aref in 5) 5 '(54831 . 4189)) + d (md5-GG d a b c (aref in 10) 9 '( 580 . 5203)) + c (md5-GG c d a b (aref in 15) 14 '(55457 . 59009)) + b (md5-GG b c d a (aref in 4) 20 '(59347 . 64456)) + a (md5-GG a b c d (aref in 9) 5 '( 8673 . 52710)) + d (md5-GG d a b c (aref in 14) 9 '(49975 . 2006)) + c (md5-GG c d a b (aref in 3) 14 '(62677 . 3463)) + b (md5-GG b c d a (aref in 8) 20 '(17754 . 5357)) + a (md5-GG a b c d (aref in 13) 5 '(43491 . 59653)) + d (md5-GG d a b c (aref in 2) 9 '(64751 . 41976)) + c (md5-GG c d a b (aref in 7) 14 '(26479 . 729)) + b (md5-GG b c d a (aref in 12) 20 '(36138 . 19594)) + a (md5-HH a b c d (aref in 5) 4 '(65530 . 14658)) + d (md5-HH d a b c (aref in 8) 11 '(34673 . 63105)) + c (md5-HH c d a b (aref in 11) 16 '(28061 . 24866)) + b (md5-HH b c d a (aref in 14) 23 '(64997 . 14348)) + a (md5-HH a b c d (aref in 1) 4 '(42174 . 59972)) + d (md5-HH d a b c (aref in 4) 11 '(19422 . 53161)) + c (md5-HH c d a b (aref in 7) 16 '(63163 . 19296)) + b (md5-HH b c d a (aref in 10) 23 '(48831 . 48240)) + a (md5-HH a b c d (aref in 13) 4 '(10395 . 32454)) + d (md5-HH d a b c (aref in 0) 11 '(60065 . 10234)) + c (md5-HH c d a b (aref in 3) 16 '(54511 . 12421)) + b (md5-HH b c d a (aref in 6) 23 '( 1160 . 7429)) + a (md5-HH a b c d (aref in 9) 4 '(55764 . 53305)) + d (md5-HH d a b c (aref in 12) 11 '(59099 . 39397)) + c (md5-HH c d a b (aref in 15) 16 '( 8098 . 31992)) + b (md5-HH b c d a (aref in 2) 23 '(50348 . 22117)) + a (md5-II a b c d (aref in 0) 6 '(62505 . 8772)) + d (md5-II d a b c (aref in 7) 10 '(17194 . 65431)) + c (md5-II c d a b (aref in 14) 15 '(43924 . 9127)) + b (md5-II b c d a (aref in 5) 21 '(64659 . 41017)) + a (md5-II a b c d (aref in 12) 6 '(25947 . 22979)) + d (md5-II d a b c (aref in 3) 10 '(36620 . 52370)) + c (md5-II c d a b (aref in 10) 15 '(65519 . 62589)) + b (md5-II b c d a (aref in 1) 21 '(34180 . 24017)) + a (md5-II a b c d (aref in 8) 6 '(28584 . 32335)) + d (md5-II d a b c (aref in 15) 10 '(65068 . 59104)) + c (md5-II c d a b (aref in 6) 15 '(41729 . 17172)) + b (md5-II b c d a (aref in 13) 21 '(19976 . 4513)) + a (md5-II a b c d (aref in 4) 6 '(63315 . 32386)) + d (md5-II d a b c (aref in 11) 10 '(48442 . 62005)) + c (md5-II c d a b (aref in 2) 15 '(10967 . 53947)) + b (md5-II b c d a (aref in 9) 21 '(60294 . 54161))) + + (aset md5-buffer 0 (md5-add (aref md5-buffer 0) a)) + (aset md5-buffer 1 (md5-add (aref md5-buffer 1) b)) + (aset md5-buffer 2 (md5-add (aref md5-buffer 2) c)) + (aset md5-buffer 3 (md5-add (aref md5-buffer 3) d)))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Here begins the merger with the XEmacs API and the md5.el from the URL +;;; package. Courtesy wmperry@cs.indiana.edu +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun md5 (object &optional start end) + "Return the MD5 (a secure message digest algorithm) of an object. +OBJECT is either a string or a buffer. +Optional arguments START and END denote buffer positions for computing the +hash of a portion of OBJECT." + (let ((buffer nil)) + (unwind-protect + (save-excursion + (setq buffer (generate-new-buffer " *md5-work*")) + (set-buffer buffer) + (cond + ((bufferp object) + (insert-buffer-substring object start end)) + ((stringp object) + (insert (if (or start end) + (substring object start end) + object))) + (t nil)) + (prog1 + (if (or (null md5-maximum-internal-length) + (<= (point-max) md5-maximum-internal-length)) + (mapconcat + (function (lambda (node) (format "%02x" node))) + (md5-encode (buffer-string)) + "") + (call-process-region (point-min) (point-max) + shell-file-name + t buffer nil + shell-command-switch md5-program) + ;; MD5 digest is 32 chars long + ;; mddriver adds a newline to make neaten output for tty + ;; viewing, make sure we leave it behind. + (buffer-substring (point-min) (+ (point-min) 32))) + (kill-buffer buffer))) + (and buffer (buffer-name buffer) (kill-buffer buffer) nil)))) + +(provide 'md5) diff --git a/utils/sasl/lisp/md5.el b/utils/sasl/lisp/md5.el new file mode 100644 index 0000000..634b2f0 --- /dev/null +++ b/utils/sasl/lisp/md5.el @@ -0,0 +1,65 @@ +;;; md5.el --- MD5 Message Digest Algorithm. + +;; Copyright (C) 1999 Shuhei KOBAYASHI + +;; Author: Shuhei KOBAYASHI +;; Keywords: MD5, RFC 1321 + +;; This file is part of FLIM (Faithful Library about Internet Message). + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 2, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; Examples from RFC 1321. +;; +;; (md5 "") +;; => d41d8cd98f00b204e9800998ecf8427e +;; +;; (md5 "a") +;; => 0cc175b9c0f1b6a831c399e269772661 +;; +;; (md5 "abc") +;; => 900150983cd24fb0d6963f7d28e17f72 +;; +;; (md5 "message digest") +;; => f96b697d7cb7938d525a2f31aaf161d0 +;; +;; (md5 "abcdefghijklmnopqrstuvwxyz") +;; => c3fcd3d76192e4007dfb496cca67e13b +;; +;; (md5 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") +;; => d174ab98d277d9f5a5611c2c9f419d9f +;; +;; (md5 "12345678901234567890123456789012345678901234567890123456789012345678901234567890") +;; => 57edf4a22be3c955ac49da2e2107b67a + +;;; Code: + +(cond + ((and (fboundp 'md5) + (subrp (symbol-function 'md5))) + ;; recent XEmacs has `md5' as a built-in function. + ;; (and 'md5 is already provided.) + ) + ((and (fboundp 'dynamic-link) + (file-exists-p (expand-file-name "md5.so" exec-directory))) + ;; Emacs with DL patch. + (require 'md5 "md5-dl")) + (t + (require 'md5 "md5-el"))) + +;;; md5.el ends here. diff --git a/utils/sasl/lisp/sasl.el b/utils/sasl/lisp/sasl.el new file mode 100644 index 0000000..3e78040 --- /dev/null +++ b/utils/sasl/lisp/sasl.el @@ -0,0 +1,156 @@ +;;; sasl.el --- basic functions for SASL + +;; Copyright (C) 1995, 1996, 1998, 1999 Free Software Foundation, Inc. + +;; Author: Kenichi OKADA +;; Keywords: SMTP, SASL, RFC2222 + +;; This file is part of FLIM (Faithful Library about Internet Message). + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 2, or (at +;; your option) any later version. + +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; Example. +;; +;; (base64-encode-string +;; (sasl-scram-md5-client-msg-2 +;; (base64-decode-string "dGVzdHNhbHQBAAAAaW1hcEBlbGVhbm9yLmlubm9zb2Z0LmNvbQBqaGNOWmxSdVBiemlGcCt2TFYrTkN3") +;; (base64-decode-string "AGNocmlzADx0NG40UGFiOUhCMEFtL1FMWEI3MmVnQGVsZWFub3IuaW5ub3NvZnQuY29tPg==") +;; (scram-md5-make-salted-pass +;; "secret stuff" "testsalt"))) +;; => "AQAAAMg9jU8CeB4KOfk7sUhSQPs=" +;; +;; (base64-encode-string +;; (scram-md5-make-server-msg-2 +;; (base64-decode-string "dGVzdHNhbHQBAAAAaW1hcEBlbGVhbm9yLmlubm9zb2Z0LmNvbQBqaGNOWmxSdVBiemlGcCt2TFYrTkN3") +;; (base64-decode-string "AGNocmlzADx0NG40UGFiOUhCMEFtL1FMWEI3MmVnQGVsZWFub3IuaW5ub3NvZnQuY29tPg==") +;; (scram-make-security-info nil t 0) +;; "testsalt" +;; (scram-md5-make-salted-pass +;; "secret stuff" "testsalt"))) +;; => "U0odqYw3B7XIIW0oSz65OQ==" + +;;; Code: + +(require 'hmac-md5) + +(eval-when-compile + (require 'scram-md5) + (require 'digest-md5)) + +(eval-and-compile + (autoload 'open-ssl-stream "ssl") + (autoload 'base64-decode-string "base64") + (autoload 'base64-encode-string "base64") + (autoload 'starttls-open-stream "starttls") + (autoload 'starttls-negotiate "starttls") + (autoload 'digest-md5-parse-digest-challenge "digest-md5") + (autoload 'digest-md5-digest-response "digest-md5") + (autoload 'scram-md5-make-salted-pass "scram-md5") + (autoload 'scram-md5-parse-server-msg-1 "scram-md5") + (autoload 'scram-md5-make-client-msg-1 "scram-md5")) + +;;; CRAM-MD5 +(defun sasl-cram-md5 (username passphrase challenge) + (let ((secure-word (copy-sequence passphrase))) + (setq secure-word (unwind-protect + (hmac-md5 challenge secure-word) + (fillarray secure-word 0)) + secure-word (unwind-protect + (encode-hex-string secure-word) + (fillarray secure-word 0)) + secure-word (unwind-protect + (concat username " " secure-word) + (fillarray secure-word 0))))) + +;;; PLAIN +(defun sasl-plain (authorid authenid passphrase) + (concat authorid "\0" authenid "\0" passphrase)) + +;;; SCRAM-MD5 +(eval-when-compile + (defvar sasl-scram-md5-client-security-info + (scram-make-security-info nil t 0))) + +(defun sasl-scram-md5-make-salted-pass (server-msg-1 passphrase) + (scram-md5-make-salted-pass + passphrase + (car + (scram-md5-parse-server-msg-1 server-msg-1)))) + +(defun sasl-scram-md5-client-msg-1 (authenticate-id &optional authorize-id) + (scram-md5-make-client-msg-1 authenticate-id authorize-id)) + +(defun sasl-scram-md5-client-msg-2 (server-msg-1 client-msg-1 salted-pass) + (let (client-proof client-key shared-key client-verifier) + (setq client-key + (scram-md5-make-client-key salted-pass)) + (setq client-verifier + (scram-md5-make-client-verifier client-key)) + (setq shared-key + (unwind-protect + (scram-md5-make-shared-key + server-msg-1 + client-msg-1 + sasl-scram-md5-client-security-info + client-verifier) + (fillarray client-verifier 0))) + (setq client-proof + (unwind-protect + (scram-md5-make-client-proof + client-key shared-key) + (fillarray client-key 0) + (fillarray shared-key 0))) + (unwind-protect + (scram-md5-make-client-msg-2 + sasl-scram-md5-client-security-info + client-proof) + (fillarray client-proof 0)))) + +(defun sasl-scram-md5-authenticate-server (server-msg-1 + server-msg-2 + client-msg-1 + salted-pass) + (string= server-msg-2 + (scram-md5-make-server-msg-2 + server-msg-1 + client-msg-1 + sasl-scram-md5-client-security-info + (car + (scram-md5-parse-server-msg-1 server-msg-1)) + salted-pass))) + +;;; DIGEST-MD5 + +(defvar sasl-digest-md5-nonce-count 1) + +(defun sasl-digest-md5-digest-response (digest-challenge username passwd + serv-type host &optional realm) + (digest-md5-parse-digest-challenge digest-challenge) + (digest-md5-digest-response + username + (or realm (digest-md5-challenge 'realm)) ;; need to check. + passwd + (digest-md5-challenge 'nonce) + (digest-md5-cnonce) + sasl-digest-md5-nonce-count + (digest-md5-digest-uri serv-type host) ;; MX host + )) + +(provide 'sasl) + +;;; sasl.el ends here \ No newline at end of file diff --git a/utils/sasl/lisp/scram-md5.el b/utils/sasl/lisp/scram-md5.el new file mode 100644 index 0000000..6891600 --- /dev/null +++ b/utils/sasl/lisp/scram-md5.el @@ -0,0 +1,154 @@ +;;; scram-md5.el --- Compute SCRAM-MD5. + +;; Copyright (C) 1999 Shuhei KOBAYASHI + +;; Author: Shuhei KOBAYASHI +;; Kenichi OKADA +;; Keywords: SCRAM-MD5, HMAC-MD5, SASL, IMAP, POP, ACAP + +;; This file is part of FLIM (Faithful Library about Internet Message). + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 2, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; This program is implemented from draft-newman-auth-scram-03.txt. +;; +;; It is caller's responsibility to base64-decode challenges and +;; base64-encode responses in IMAP4 AUTHENTICATE command. +;; +;; Passphrase should be longer than 16 bytes. (See RFC 2195) + +;; Examples. +;; +;; (scram-make-security-info nil t 0) +;; => "^A^@^@^@" + +;;; Code: + +(require 'hmac-md5) +(require 'unique-id) + +(defmacro scram-security-info-no-security-layer (security-info) + `(eq (logand (aref ,security-info 0) 1) 1)) +(defmacro scram-security-info-integrity-protection-layer (security-info) + `(eq (logand (aref ,security-info 0) 2) 2)) +(defmacro scram-security-info-buffer-size (security-info) + `(let ((ssecinfo ,security-info)) + (+ (lsh (aref ssecinfo 1) 16) + (lsh (aref ssecinfo 2) 8) + (aref ssecinfo 3)))) + +(defun scram-make-security-info (integrity-protection-layer + no-security-layer buffer-size) + (let ((csecinfo (make-string 4 0))) + (when integrity-protection-layer + (aset csecinfo 0 2)) + (if no-security-layer + (aset csecinfo 0 (logior (aref csecinfo 0) 1)) + (aset csecinfo 1 + (lsh (logand buffer-size (lsh 255 16)) -16)) + (aset csecinfo 2 + (lsh (logand buffer-size (lsh 255 8)) -8)) + (aset csecinfo 3 (logand buffer-size 255))) + csecinfo)) + +(defun scram-make-unique-nonce () ; 8*OCTET, globally unique. + ;; For example, concatenated string of process-identifier, system-clock, + ;; sequence-number, random-number, and domain-name. + (let (id) + (unwind-protect + (concat "<" + (setq id (unique-id-m ".sasl")) + "@" (system-name) ">") + (fillarray id 0)))) + +(defun scram-xor-string (str1 str2) + ;; (length str1) == (length str2) == (length dst) == 16 (in SCRAM-MD5) + (let* ((len (length str1)) + (dst (make-string len 0)) + (pos 0)) + (while (< pos len) + (aset dst pos (logxor (aref str1 pos) (aref str2 pos))) + (setq pos (1+ pos))) + dst)) + +(defun scram-md5-make-client-msg-1 (authenticate-id &optional authorize-id) + "Make an initial client message from AUTHENTICATE-ID and AUTHORIZE-ID. +If AUTHORIZE-ID is the same as AUTHENTICATE-ID, it may be omitted." + (let (nonce) + (unwind-protect + (concat authorize-id "\0" authenticate-id "\0" + (setq nonce (scram-make-unique-nonce))) + (fillarray nonce 0)))) + +(defun scram-md5-parse-server-msg-1 (server-msg-1) + "Parse SERVER-MSG-1 and return a list of (SALT SECURITY-INFO SERVICE-ID)." + (when (and (> (length server-msg-1) 16) + (eq (string-match "[^@]+@[^\0]+\0" server-msg-1 12) 12)) + (list (substring server-msg-1 0 8) ; salt + (substring server-msg-1 8 12) ; server-security-info + (substring server-msg-1 ; service-id + 12 (1- (match-end 0)))))) + +(defun scram-md5-make-salted-pass (passphrase salt) + (hmac-md5 salt passphrase)) + +(defun scram-md5-make-client-key (salted-pass) + (md5-binary salted-pass)) + +(defun scram-md5-make-client-verifier (client-key) + (md5-binary client-key)) + +(defun scram-md5-make-shared-key (server-msg-1 + client-msg-1 + client-security-info + client-verifier) + (let (buff) + (unwind-protect + (hmac-md5 + (setq buff + (concat server-msg-1 client-msg-1 client-security-info)) + client-verifier) + (fillarray buff 0)))) + +(defun scram-md5-make-client-proof (client-key shared-key) + (scram-xor-string client-key shared-key)) + +(defun scram-md5-make-client-msg-2 (client-security-info client-proof) + (concat client-security-info client-proof)) + +(defun scram-md5-make-server-msg-2 (server-msg-1 + client-msg-1 + client-security-info + salt salted-pass) + (let (buff server-salt) + (setq server-salt + (hmac-md5 salt salted-pass)) + (unwind-protect + (hmac-md5 + (setq buff + (concat + client-msg-1 + server-msg-1 + client-security-info)) + server-salt) + (fillarray server-salt 0) + (fillarray buff 0)))) + +(provide 'scram-md5) + +;;; scram-md5.el ends here diff --git a/utils/sasl/lisp/sha1-dl.el b/utils/sasl/lisp/sha1-dl.el new file mode 100644 index 0000000..06f51a2 --- /dev/null +++ b/utils/sasl/lisp/sha1-dl.el @@ -0,0 +1,56 @@ +;;; sha1-dl.el --- SHA1 Secure Hash Algorithm using DL module. + +;; Copyright (C) 1999 Shuhei KOBAYASHI + +;; Author: Shuhei KOBAYASHI +;; Keywords: SHA1, FIPS 180-1 + +;; This file is part of FLIM (Faithful Library about Internet Message). + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 2, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;;; Code: + +(provide 'sha1-dl) ; beware of circular dependency. +(eval-when-compile (require 'sha1)) ; sha1-dl-module. + +(defvar sha1-dl-handle + (and (stringp sha1-dl-module) + (file-exists-p sha1-dl-module) + (dynamic-link sha1-dl-module))) + +;;; sha1-dl-module provides `sha1-string' and `sha1-binary'. +(dynamic-call "emacs_sha1_init" sha1-dl-handle) + +(defun sha1-region (beg end) + (sha1-string (buffer-substring-no-properties beg end))) + +(defun sha1 (object &optional beg end) + "Return the SHA1 (Secure Hash Algorithm) of an object. +OBJECT is either a string or a buffer. +Optional arguments BEG and END denote buffer positions for computing the +hash of a portion of OBJECT." + (if (stringp object) + (sha1-string object) + (save-excursion + (set-buffer object) + (sha1-region (or beg (point-min)) (or end (point-max)))))) + +(provide 'sha1-dl) + +;;; sha1-dl.el ends here diff --git a/utils/sasl/lisp/sha1-el.el b/utils/sasl/lisp/sha1-el.el new file mode 100644 index 0000000..96d52a3 --- /dev/null +++ b/utils/sasl/lisp/sha1-el.el @@ -0,0 +1,408 @@ +;;; sha1-el.el --- SHA1 Secure Hash Algorithm in Emacs-Lisp. + +;; Copyright (C) 1999 Shuhei KOBAYASHI + +;; Author: Shuhei KOBAYASHI +;; Keywords: SHA1, FIPS 180-1 + +;; This file is part of FLIM (Faithful Library about Internet Message). + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 2, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; This program is implemented from the definition of SHA-1 in FIPS PUB +;; 180-1 (Federal Information Processing Standards Publication 180-1), +;; "Announcing the Standard for SECURE HASH STANDARD". +;; +;; EXCEPTION: +;; * Two optimizations taken from GnuPG/cipher/sha1.c. +;; +;; BUGS: +;; * It is assumed that length of input string is less than 2^29 bytes. +;; * It is caller's responsibility to make string (or region) unibyte. + +;;; Code: + +(require 'hex-util) + +;;; +;;; external SHA1 function. +;;; + +(defvar sha1-maximum-internal-length 500 + "*Maximum length of message to use lisp version of SHA1 function. +If message is longer than this, `sha1-program' is used instead. + +If this variable is set to 0, use extarnal program only. +If this variable is set to nil, use internal function only.") + +(defvar sha1-program '("openssl" "sha1") + "*Name of program to compute SHA1. +It must be a string \(program name\) or list of strings \(name and its args\).") + +(defun sha1-string-external (string) + ;; `with-temp-buffer' is new in v20, so we do not use it. + (save-excursion + (let (buffer) + (unwind-protect + (let (prog args) + (if (consp sha1-program) + (setq prog (car sha1-program) + args (cdr sha1-program)) + (setq prog sha1-program + args nil)) + (setq buffer (set-buffer + (generate-new-buffer " *sha1 external*"))) + (insert string) + (apply (function call-process-region) + (point-min)(point-max) + prog t t nil args) + ;; SHA1 is 40 bytes long in hexadecimal form. + (buffer-substring (point-min)(+ (point-min) 40))) + (and buffer + (buffer-name buffer) + (kill-buffer buffer)))))) + +(defun sha1-region-external (beg end) + (sha1-string-external (buffer-substring-no-properties beg end))) + +;;; +;;; internal SHA1 function. +;;; + +(eval-when-compile + ;; optional second arg of string-to-number is new in v20. + (defconst sha1-K0-high 23170) ; (string-to-number "5A82" 16) + (defconst sha1-K0-low 31129) ; (string-to-number "7999" 16) + (defconst sha1-K1-high 28377) ; (string-to-number "6ED9" 16) + (defconst sha1-K1-low 60321) ; (string-to-number "EBA1" 16) + (defconst sha1-K2-high 36635) ; (string-to-number "8F1B" 16) + (defconst sha1-K2-low 48348) ; (string-to-number "BCDC" 16) + (defconst sha1-K3-high 51810) ; (string-to-number "CA62" 16) + (defconst sha1-K3-low 49622) ; (string-to-number "C1D6" 16) + +;;; original definition of sha1-F0. +;;; (defmacro sha1-F0 (B C D) +;;; (` (logior (logand (, B) (, C)) +;;; (logand (lognot (, B)) (, D))))) +;;; a little optimization from GnuPG/cipher/sha1.c. + (defmacro sha1-F0 (B C D) + (` (logxor (, D) (logand (, B) (logxor (, C) (, D)))))) + (defmacro sha1-F1 (B C D) + (` (logxor (, B) (, C) (, D)))) +;;; original definition of sha1-F2. +;;; (defmacro sha1-F2 (B C D) +;;; (` (logior (logand (, B) (, C)) +;;; (logand (, B) (, D)) +;;; (logand (, C) (, D))))) +;;; a little optimization from GnuPG/cipher/sha1.c. + (defmacro sha1-F2 (B C D) + (` (logior (logand (, B) (, C)) + (logand (, D) (logior (, B) (, C)))))) + (defmacro sha1-F3 (B C D) + (` (logxor (, B) (, C) (, D)))) + + (defmacro sha1-S1 (W-high W-low) + (` (let ((W-high (, W-high)) + (W-low (, W-low))) + (setq S1W-high (+ (% (* W-high 2) 65536) + (/ W-low (, (/ 65536 2))))) + (setq S1W-low (+ (/ W-high (, (/ 65536 2))) + (% (* W-low 2) 65536)))))) + (defmacro sha1-S5 (A-high A-low) + (` (progn + (setq S5A-high (+ (% (* (, A-high) 32) 65536) + (/ (, A-low) (, (/ 65536 32))))) + (setq S5A-low (+ (/ (, A-high) (, (/ 65536 32))) + (% (* (, A-low) 32) 65536)))))) + (defmacro sha1-S30 (B-high B-low) + (` (progn + (setq S30B-high (+ (/ (, B-high) 4) + (* (% (, B-low) 4) (, (/ 65536 4))))) + (setq S30B-low (+ (/ (, B-low) 4) + (* (% (, B-high) 4) (, (/ 65536 4)))))))) + + (defmacro sha1-OP (round) + (` (progn + (sha1-S5 sha1-A-high sha1-A-low) + (sha1-S30 sha1-B-high sha1-B-low) + (setq sha1-A-low (+ ((, (intern (format "sha1-F%d" round))) + sha1-B-low sha1-C-low sha1-D-low) + sha1-E-low + (, (symbol-value + (intern (format "sha1-K%d-low" round)))) + (aref block-low idx) + (progn + (setq sha1-E-low sha1-D-low) + (setq sha1-D-low sha1-C-low) + (setq sha1-C-low S30B-low) + (setq sha1-B-low sha1-A-low) + S5A-low))) + (setq carry (/ sha1-A-low 65536)) + (setq sha1-A-low (% sha1-A-low 65536)) + (setq sha1-A-high (% (+ ((, (intern (format "sha1-F%d" round))) + sha1-B-high sha1-C-high sha1-D-high) + sha1-E-high + (, (symbol-value + (intern (format "sha1-K%d-high" round)))) + (aref block-high idx) + (progn + (setq sha1-E-high sha1-D-high) + (setq sha1-D-high sha1-C-high) + (setq sha1-C-high S30B-high) + (setq sha1-B-high sha1-A-high) + S5A-high) + carry) + 65536))))) + + (defmacro sha1-add-to-H (H X) + (` (progn + (setq (, (intern (format "sha1-%s-low" H))) + (+ (, (intern (format "sha1-%s-low" H))) + (, (intern (format "sha1-%s-low" X))))) + (setq carry (/ (, (intern (format "sha1-%s-low" H))) 65536)) + (setq (, (intern (format "sha1-%s-low" H))) + (% (, (intern (format "sha1-%s-low" H))) 65536)) + (setq (, (intern (format "sha1-%s-high" H))) + (% (+ (, (intern (format "sha1-%s-high" H))) + (, (intern (format "sha1-%s-high" X))) + carry) + 65536))))) + ) + +;;; buffers (H0 H1 H2 H3 H4). +(defvar sha1-H0-high) +(defvar sha1-H0-low) +(defvar sha1-H1-high) +(defvar sha1-H1-low) +(defvar sha1-H2-high) +(defvar sha1-H2-low) +(defvar sha1-H3-high) +(defvar sha1-H3-low) +(defvar sha1-H4-high) +(defvar sha1-H4-low) + +(defun sha1-block (block-high block-low) + (let (;; step (c) --- initialize buffers (A B C D E). + (sha1-A-high sha1-H0-high) (sha1-A-low sha1-H0-low) + (sha1-B-high sha1-H1-high) (sha1-B-low sha1-H1-low) + (sha1-C-high sha1-H2-high) (sha1-C-low sha1-H2-low) + (sha1-D-high sha1-H3-high) (sha1-D-low sha1-H3-low) + (sha1-E-high sha1-H4-high) (sha1-E-low sha1-H4-low) + (idx 16)) + ;; step (b). + (let (;; temporary variables used in sha1-S1 macro. + S1W-high S1W-low) + (while (< idx 80) + (sha1-S1 (logxor (aref block-high (- idx 3)) + (aref block-high (- idx 8)) + (aref block-high (- idx 14)) + (aref block-high (- idx 16))) + (logxor (aref block-low (- idx 3)) + (aref block-low (- idx 8)) + (aref block-low (- idx 14)) + (aref block-low (- idx 16)))) + (aset block-high idx S1W-high) + (aset block-low idx S1W-low) + (setq idx (1+ idx)))) + ;; step (d). + (setq idx 0) + (let (;; temporary variables used in sha1-OP macro. + S5A-high S5A-low S30B-high S30B-low carry) + (while (< idx 20) (sha1-OP 0) (setq idx (1+ idx))) + (while (< idx 40) (sha1-OP 1) (setq idx (1+ idx))) + (while (< idx 60) (sha1-OP 2) (setq idx (1+ idx))) + (while (< idx 80) (sha1-OP 3) (setq idx (1+ idx)))) + ;; step (e). + (let (;; temporary variables used in sha1-add-to-H macro. + carry) + (sha1-add-to-H H0 A) + (sha1-add-to-H H1 B) + (sha1-add-to-H H2 C) + (sha1-add-to-H H3 D) + (sha1-add-to-H H4 E)))) + +(defun sha1-binary (string) + "Return the SHA1 of STRING in binary form." + (let (;; prepare buffers for a block. byte-length of block is 64. + ;; input block is split into two vectors. + ;; + ;; input block: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ... + ;; block-high: +-0-+ +-1-+ +-2-+ +-3-+ + ;; block-low: +-0-+ +-1-+ +-2-+ +-3-+ + ;; + ;; length of each vector is 80, and elements of each vector are + ;; 16bit integers. elements 0x10-0x4F of each vector are + ;; assigned later in `sha1-block'. + (block-high (eval-when-compile (make-vector 80 nil))) + (block-low (eval-when-compile (make-vector 80 nil)))) + (unwind-protect + (let* (;; byte-length of input string. + (len (length string)) + (lim (* (/ len 64) 64)) + (rem (% len 4)) + (idx 0)(pos 0)) + ;; initialize buffers (H0 H1 H2 H3 H4). + (setq sha1-H0-high 26437 ; (string-to-number "6745" 16) + sha1-H0-low 8961 ; (string-to-number "2301" 16) + sha1-H1-high 61389 ; (string-to-number "EFCD" 16) + sha1-H1-low 43913 ; (string-to-number "AB89" 16) + sha1-H2-high 39098 ; (string-to-number "98BA" 16) + sha1-H2-low 56574 ; (string-to-number "DCFE" 16) + sha1-H3-high 4146 ; (string-to-number "1032" 16) + sha1-H3-low 21622 ; (string-to-number "5476" 16) + sha1-H4-high 50130 ; (string-to-number "C3D2" 16) + sha1-H4-low 57840) ; (string-to-number "E1F0" 16) + ;; loop for each 64 bytes block. + (while (< pos lim) + ;; step (a). + (setq idx 0) + (while (< idx 16) + (aset block-high idx (+ (* (aref string pos) 256) + (aref string (1+ pos)))) + (setq pos (+ pos 2)) + (aset block-low idx (+ (* (aref string pos) 256) + (aref string (1+ pos)))) + (setq pos (+ pos 2)) + (setq idx (1+ idx))) + (sha1-block block-high block-low)) + ;; last block. + (if (prog1 + (< (- len lim) 56) + (setq lim (- len rem)) + (setq idx 0) + (while (< pos lim) + (aset block-high idx (+ (* (aref string pos) 256) + (aref string (1+ pos)))) + (setq pos (+ pos 2)) + (aset block-low idx (+ (* (aref string pos) 256) + (aref string (1+ pos)))) + (setq pos (+ pos 2)) + (setq idx (1+ idx))) + ;; this is the last (at most) 32bit word. + (cond + ((= rem 3) + (aset block-high idx (+ (* (aref string pos) 256) + (aref string (1+ pos)))) + (setq pos (+ pos 2)) + (aset block-low idx (+ (* (aref string pos) 256) + 128))) + ((= rem 2) + (aset block-high idx (+ (* (aref string pos) 256) + (aref string (1+ pos)))) + (aset block-low idx 32768)) + ((= rem 1) + (aset block-high idx (+ (* (aref string pos) 256) + 128)) + (aset block-low idx 0)) + (t ;; (= rem 0) + (aset block-high idx 32768) + (aset block-low idx 0))) + (setq idx (1+ idx)) + (while (< idx 16) + (aset block-high idx 0) + (aset block-low idx 0) + (setq idx (1+ idx)))) + ;; last block has enough room to write the length of string. + (progn + ;; write bit length of string to last 4 bytes of the block. + (aset block-low 15 (* (% len 8192) 8)) + (setq len (/ len 8192)) + (aset block-high 15 (% len 65536)) + ;; XXX: It is not practical to compute SHA1 of + ;; such a huge message on emacs. + ;; (setq len (/ len 65536)) ; for 64bit emacs. + ;; (aset block-low 14 (% len 65536)) + ;; (aset block-high 14 (/ len 65536)) + (sha1-block block-high block-low)) + ;; need one more block. + (sha1-block block-high block-low) + (fillarray block-high 0) + (fillarray block-low 0) + ;; write bit length of string to last 4 bytes of the block. + (aset block-low 15 (* (% len 8192) 8)) + (setq len (/ len 8192)) + (aset block-high 15 (% len 65536)) + ;; XXX: It is not practical to compute SHA1 of + ;; such a huge message on emacs. + ;; (setq len (/ len 65536)) ; for 64bit emacs. + ;; (aset block-low 14 (% len 65536)) + ;; (aset block-high 14 (/ len 65536)) + (sha1-block block-high block-low)) + ;; make output string (in binary form). + (let ((result (make-string 20 0))) + (aset result 0 (/ sha1-H0-high 256)) + (aset result 1 (% sha1-H0-high 256)) + (aset result 2 (/ sha1-H0-low 256)) + (aset result 3 (% sha1-H0-low 256)) + (aset result 4 (/ sha1-H1-high 256)) + (aset result 5 (% sha1-H1-high 256)) + (aset result 6 (/ sha1-H1-low 256)) + (aset result 7 (% sha1-H1-low 256)) + (aset result 8 (/ sha1-H2-high 256)) + (aset result 9 (% sha1-H2-high 256)) + (aset result 10 (/ sha1-H2-low 256)) + (aset result 11 (% sha1-H2-low 256)) + (aset result 12 (/ sha1-H3-high 256)) + (aset result 13 (% sha1-H3-high 256)) + (aset result 14 (/ sha1-H3-low 256)) + (aset result 15 (% sha1-H3-low 256)) + (aset result 16 (/ sha1-H4-high 256)) + (aset result 17 (% sha1-H4-high 256)) + (aset result 18 (/ sha1-H4-low 256)) + (aset result 19 (% sha1-H4-low 256)) + result)) + ;; do not leave a copy of input string. + (fillarray block-high nil) + (fillarray block-low nil)))) + +(defun sha1-string-internal (string) + (encode-hex-string (sha1-binary string))) + +(defun sha1-region-internal (beg end) + (sha1-string-internal (buffer-substring-no-properties beg end))) + +;;; +;;; application interface. +;;; + +(defun sha1-region (beg end) + (if (and sha1-maximum-internal-length + (> (abs (- end beg)) sha1-maximum-internal-length)) + (sha1-region-external beg end) + (sha1-region-internal beg end))) + +(defun sha1-string (string) + (if (and sha1-maximum-internal-length + (> (length string) sha1-maximum-internal-length)) + (sha1-string-external string) + (sha1-string-internal string))) + +(defun sha1 (object &optional beg end) + "Return the SHA1 (Secure Hash Algorithm) of an object. +OBJECT is either a string or a buffer. +Optional arguments BEG and END denote buffer positions for computing the +hash of a portion of OBJECT." + (if (stringp object) + (sha1-string object) + (save-excursion + (set-buffer object) + (sha1-region (or beg (point-min)) (or end (point-max)))))) + +(provide 'sha1-el) + +;;; sha1-el.el ends here diff --git a/utils/sasl/lisp/sha1.el b/utils/sasl/lisp/sha1.el new file mode 100644 index 0000000..a7265b6 --- /dev/null +++ b/utils/sasl/lisp/sha1.el @@ -0,0 +1,77 @@ +;;; sha1.el --- SHA1 Secure Hash Algorithm. + +;; Copyright (C) 1999 Shuhei KOBAYASHI + +;; Author: Shuhei KOBAYASHI +;; Kenichi OKADA +;; Maintainer: Kenichi OKADA +;; Keywords: SHA1, FIPS 180-1 + +;; This file is part of FLIM (Faithful Library about Internet Message). + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 2, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; Examples from FIPS PUB 180-1. +;; +;; +;; (sha1 "abc") +;; => a9993e364706816aba3e25717850c26c9cd0d89d +;; +;; (sha1 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") +;; => 84983e441c3bd26ebaae4aa1f95129e5e54670f1 +;; +;; (sha1 (make-string 1000000 ?a)) +;; => 34aa973cd4c4daa4f61eeb2bdbad27316534016f + +;;; Code: + +(require 'hex-util) + +(eval-when-compile + (defun-maybe sha1-string (a))) + +(defvar sha1-dl-module + (if (and (fboundp 'sha1-string) + (subrp (symbol-function 'sha1-string))) + nil + (if (fboundp 'dynamic-link) + (let ((path (expand-file-name "sha1.so" exec-directory))) + (and (file-exists-p path) + path))))) + +(cond + (sha1-dl-module + ;; Emacs with DL patch. + (require 'sha1-dl)) + (t + (require 'sha1-el))) + +;; compatibility for another sha1.el by Keiichi Suzuki. +(defun sha1-encode (string) + (decode-hex-string + (sha1-string string))) +(defun sha1-encode-binary (string) + (decode-hex-string + (sha1-string string))) + +(make-obsolete 'sha1-encode "It's old API.") +(make-obsolete 'sha1-encode-binary "It's old API.") + +(provide 'sha1) + +;;; sha1.el ends here diff --git a/utils/sasl/lisp/unique-id.el b/utils/sasl/lisp/unique-id.el new file mode 100644 index 0000000..f80b2d4 --- /dev/null +++ b/utils/sasl/lisp/unique-id.el @@ -0,0 +1,92 @@ +;;; unique-id.el --- Compute DIGEST-MD5. + +;; Copyright (C) 1999 Kenichi OKADA + +;; Author: Katsumi Yamaoka + +;; This file is part of FLIM (Faithful Library about Internet Message). + +;;; Code: + +;;; Gnus 5.8.3: message.el + +(defvar unique-id-m-char nil) + +;; If you ever change this function, make sure the new version +;; cannot generate IDs that the old version could. +;; You might for example insert a "." somewhere (not next to another dot +;; or string boundary), or modify the suffix string (default to "fsf"). +(defun unique-id-m (&optional suffix) + ;; Don't use microseconds from (current-time), they may be unsupported. + ;; Instead we use this randomly inited counter. + (setq unique-id-m-char + (% (1+ (or unique-id-m-char (logand (random t) (1- (lsh 1 20))))) + ;; (current-time) returns 16-bit ints, + ;; and 2^16*25 just fits into 4 digits i base 36. + (* 25 25))) + (let ((tm (current-time))) + (concat + (if (memq system-type '(ms-dos emx vax-vms)) + (let ((user (downcase (user-login-name)))) + (while (string-match "[^a-z0-9_]" user) + (aset user (match-beginning 0) ?_)) + user) + (unique-id-m-number-base36 (user-uid) -1)) + (unique-id-m-number-base36 (+ (car tm) + (lsh (% unique-id-m-char 25) 16)) 4) + (unique-id-m-number-base36 (+ (nth 1 tm) + (lsh (/ unique-id-m-char 25) 16)) 4) + ;; Append the suffix, because while the generated ID is unique to + ;; the application, other applications might otherwise generate + ;; the same ID via another algorithm. + (or suffix ".fsf")))) + +(defun unique-id-m-number-base36 (num len) + (if (if (< len 0) + (<= num 0) + (= len 0)) + "" + (concat (unique-id-m-number-base36 (/ num 36) (1- len)) + (char-to-string (aref "zyxwvutsrqponmlkjihgfedcba9876543210" + (% num 36)))))) + + +;;; Wanderlust 1.0.3: wl-draft.el, wl-mule.el + +(defun unique-id-w-random-alphabet () + (let ((alphabet '(?A ?B ?C ?D ?E ?F ?G ?H ?I ?J ?K ?L ?M + ?N ?O ?P ?Q ?R ?S ?T ?U ?V ?W ?X ?Y ?Z))) + (nth (abs (% (random) 26)) alphabet))) + +(defun unique-id-w () + (let ((time (current-time))) + (format "%d.%d.%d.%d%c" + (car time) (nth 1 time) (nth 2 time) + (random 100000) + (unique-id-w-random-alphabet)))) + + +;;; VM 6.75: vm-misc.el + +(defun unique-id-v () + (let ((time (current-time))) + (format "%d.%d.%d.%d" + (car time) (nth 1 time) (nth 2 time) + (random 1000000)))) + + +;;; X-PGP-Sig 1.3.5.1 + +(defun unique-id-x (&optional length) + (let ((i (or length 16)) + s) + (while (> i 0) + (setq i (1- i) + s (concat s (char-to-string (+ (/ (* 94 (% (abs (random)) 100)) + 100) 33))))) + s)) + +(provide 'unique-id) + +;;; unique-id.el ends here + diff --git a/utils/sasl/src/md5-dl.c b/utils/sasl/src/md5-dl.c new file mode 100644 index 0000000..bdd17a1 --- /dev/null +++ b/utils/sasl/src/md5-dl.c @@ -0,0 +1,85 @@ +/* Dynamic loading module to compute MD5 for Emacs 20 with DL support. + + Copyright (C) 1999 Shuhei KOBAYASHI + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ + +/* + How to compile: (OpenSSL is required) + + gcc -shared -nostdlib -fPIC -I${EMACS}/src -o md5.so md5-dl.c -lcrypto + +*/ + +#include "config.h" +#include "lisp.h" + +/* for 20.2 (not tested) +#ifndef STRING_BYTES +#define STRING_BYTES(STR) ((STR)->size) +#define make_unibyte_string make_string +#endif +*/ + +#include + +static unsigned char to_hex[] = {'0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + +DEFUN ("md5-string", Fmd5_string, Smd5_string, 1, 1, 0, + "Return the MD5 of the STRING.") + (string) + Lisp_Object string; +{ + unsigned char *md; + unsigned char md_hex[MD5_DIGEST_LENGTH*2]; + int i, j; + + CHECK_STRING (string, 0); + + md = MD5 (XSTRING (string)->data, STRING_BYTES (XSTRING (string)), + (unsigned char *) 0); + + for (i = j = 0; i < MD5_DIGEST_LENGTH; i++, j++) + { + md_hex[j] = to_hex[(unsigned int)(md[i] / 16)]; + md_hex[++j] = to_hex[(unsigned int)(md[i] & 15)]; + } + + return make_unibyte_string (md_hex, sizeof(md_hex)); +} + +/* + * setting + */ +static struct Lisp_Subr *s_md5_string; + +void +emacs_md5_init () +{ + s_md5_string = (struct Lisp_Subr *) xmalloc (sizeof (struct Lisp_Subr)); + bcopy (&Smd5_string, s_md5_string, sizeof (struct Lisp_Subr)); + defsubr (s_md5_string); +} + +void +emacs_md5_fini () +{ + undefsubr (s_md5_string); + free (s_md5_string); +} diff --git a/utils/sasl/src/sha1-dl.c b/utils/sasl/src/sha1-dl.c new file mode 100644 index 0000000..045fef8 --- /dev/null +++ b/utils/sasl/src/sha1-dl.c @@ -0,0 +1,84 @@ +/* Dynamic loading module to compute SHA-1 for Emacs 20 with DL support. + + Copyright (C) 1999 Shuhei KOBAYASHI + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ + +/* + How to compile: (OpenSSL is required) + + gcc -shared -nostdlib -fPIC -I${EMACS}/src -o sha1.so sha1-dl.c -lcrypto + +*/ + +#include "config.h" +#include "lisp.h" + +/* for 20.2 (not tested) +#ifndef STRING_BYTES +#define STRING_BYTES(STR) ((STR)->size) +#define make_unibyte_string make_string +#endif +*/ + +#include + +static unsigned char to_hex[] = {'0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; +DEFUN ("sha1-string", Fsha1_string, Ssha1_string, 1, 1, 0, + "Return the SHA-1 of the STRING.") + (string) + Lisp_Object string; +{ + unsigned char *md; + unsigned char md_hex[SHA_DIGEST_LENGTH*2]; + int i, j; + + CHECK_STRING (string, 0); + + md = SHA1 (XSTRING (string)->data, STRING_BYTES (XSTRING (string)), + (unsigned char *) 0); + + for (i = j = 0; i < SHA_DIGEST_LENGTH; i++, j++) + { + md_hex[j] = to_hex[(unsigned int)(md[i] / 16)]; + md_hex[++j] = to_hex[(unsigned int)(md[i] & 15)]; + } + + return make_unibyte_string (md_hex, sizeof(md_hex)); +} + +/* + * setting + */ +static struct Lisp_Subr *s_sha1_string; + +void +emacs_sha1_init () +{ + s_sha1_string = (struct Lisp_Subr *) xmalloc (sizeof (struct Lisp_Subr)); + bcopy (&Ssha1_string, s_sha1_string, sizeof (struct Lisp_Subr)); + defsubr (s_sha1_string); +} + +void +emacs_sha1_fini () +{ + undefsubr (s_sha1_string); + free (s_sha1_string); +} diff --git a/utils/ssl.el b/utils/ssl.el new file mode 100644 index 0000000..f8a9998 --- /dev/null +++ b/utils/ssl.el @@ -0,0 +1,201 @@ +;;; ssl.el,v --- ssl functions for emacsen without them builtin +;; Author: wmperry +;; Created: 1999/10/14 12:44:18 +;; Version: 1.2 +;; Keywords: comm + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Copyright (c) 1995, 1996 by William M. Perry +;;; Copyright (c) 1996 - 1999 Free Software Foundation, Inc. +;;; +;;; This file is part of GNU Emacs. +;;; +;;; GNU Emacs is free software; you can redistribute it and/or modify +;;; it under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 2, or (at your option) +;;; any later version. +;;; +;;; GNU Emacs is distributed in the hope that it will be useful, +;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Emacs; see the file COPYING. If not, write to the +;;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;;; Boston, MA 02111-1307, USA. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(require 'cl) +(require 'base64) + +(eval-and-compile + (condition-case () + (require 'custom) + (error nil)) + (if (and (featurep 'custom) (fboundp 'custom-declare-variable)) + nil ;; We've got what we needed + ;; We have the old custom-library, hack around it! + (defmacro defgroup (&rest args) + nil) + (defmacro defcustom (var value doc &rest args) + (` (defvar (, var) (, value) (, doc)))))) + +(defgroup ssl nil + "Support for `Secure Sockets Layer' encryption." + :group 'comm) + +(defcustom ssl-certificate-directory "~/.w3/certs/" + "*Directory to store CA certificates in" + :group 'ssl + :type 'directory) + +(defcustom ssl-rehash-program-name "c_rehash" + "*Program to run after adding a cert to a directory . +Run with one argument, the directory name." + :group 'ssl + :type 'string) + +(defcustom ssl-view-certificate-program-name "x509" + "*The program to run to provide a human-readable view of a certificate." + :group 'ssl + :type 'string) + +(defcustom ssl-view-certificate-program-arguments '("-text" "-inform" "DER") + "*Arguments that should be passed to the certificate viewing program. +The certificate is piped to it. +Maybe a way of passing a file should be implemented" + :group 'ssl + :type 'list) + +(defcustom ssl-certificate-directory-style 'ssleay + "*Style of cert database to use, the only valid value right now is `ssleay'. +This means a directory of pem encoded certificates with hash symlinks." + :group 'ssl + :type '(choice (const :tag "SSLeay" :value ssleay) + (const :tag "OpenSSL" :value openssl))) + +(defcustom ssl-certificate-verification-policy 0 + "*How far up the certificate chain we should verify." + :group 'ssl + :type '(choice (const :tag "No verification" :value 0) + (const :tag "Verification required" :value 1) + (const :tag "Reject connection if verification fails" :value 3) + (const :tag "SSL_VERIFY_CLIENT_ONCE" :value 5))) + +(defcustom ssl-program-name "openssl" + "*The program to run in a subprocess to open an SSL connection." + :group 'ssl + :type 'string) + +(defcustom ssl-program-arguments + '("s_client" + "-quiet" + "-host" host + "-port" service + "-verify" (int-to-string ssl-certificate-verification-policy) + "-CApath" ssl-certificate-directory + ) + "*Arguments that should be passed to the program `ssl-program-name'. +This should be used if your SSL program needs command line switches to +specify any behaviour (certificate file locations, etc). +The special symbols 'host and 'port may be used in the list of arguments +and will be replaced with the hostname and service/port that will be connected +to." + :group 'ssl + :type 'list) + +(defun ssl-certificate-information (der) + "Return an assoc list of information about a certificate in DER format." + (let ((certificate (concat "-----BEGIN CERTIFICATE-----\n" + (base64-encode-string der) + "\n-----END CERTIFICATE-----\n")) + (exit-code 0)) + (save-excursion + (set-buffer (get-buffer-create " *openssl*")) + (erase-buffer) + (insert certificate) + (setq exit-code (condition-case () + (call-process-region (point-min) (point-max) + ssl-program-name + t (list (current-buffer) nil) t + "x509" + "-subject" ; Print the subject DN + "-issuer" ; Print the issuer DN + "-dates" ; Both before and after dates + "-serial" ; print out serial number + "-noout" ; Don't spit out the certificate + ) + (error -1))) + (if (/= exit-code 0) + nil + (let ((vals nil)) + (goto-char (point-min)) + (while (re-search-forward "^\\([^=\n\r]+\\)\\s *=\\s *\\(.*\\)" nil t) + (push (cons (match-string 1) (match-string 2)) vals)) + vals))))) + +(defun ssl-accept-ca-certificate () + "Ask if the user is willing to accept a new CA certificate. The buffer-name +should be the intended name of the certificate, and the buffer should probably +be in DER encoding" + ;; TODO, check if it is really new or if we already know it + (let* ((process-connection-type nil) + (tmpbuf (generate-new-buffer "X509 CA Certificate Information")) + (response (save-excursion + (and (eq 0 + (apply 'call-process-region + (point-min) (point-max) + ssl-view-certificate-program-name + nil tmpbuf t + ssl-view-certificate-program-arguments)) + (switch-to-buffer tmpbuf) + (goto-char (point-min)) + (or (recenter) t) + (yes-or-no-p + "Accept this CA to vouch for secure server identities? ") + (kill-buffer tmpbuf))))) + (if (not response) + nil + (if (not (file-directory-p ssl-certificate-directory)) + (make-directory ssl-certificate-directory)) + (case ssl-certificate-directory-style + (ssleay + (base64-encode-region (point-min) (point-max)) + (goto-char (point-min)) + (insert "-----BEGIN CERTIFICATE-----\n") + (goto-char (point-max)) + (insert "-----END CERTIFICATE-----\n") + (let ((f (expand-file-name + (concat (file-name-sans-extension (buffer-name)) ".pem") + ssl-certificate-directory))) + (write-file f) + (call-process ssl-rehash-program-name + nil nil nil + (expand-file-name ssl-certificate-directory)))))))) + +(defun open-ssl-stream (name buffer host service) + "Open a SSL connection for a service to a host. +Returns a subprocess-object to represent the connection. +Input and output work as for subprocesses; `delete-process' closes it. +Args are NAME BUFFER HOST SERVICE. +NAME is name for process. It is modified if necessary to make it unique. +BUFFER is the buffer (or buffer-name) to associate with the process. + Process output goes at end of that buffer, unless you specify + an output stream or filter function to handle the output. + BUFFER may be also nil, meaning that this process is not associated + with any buffer +Third arg is name of the host to connect to, or its IP address. +Fourth arg SERVICE is name of the service desired, or an integer +specifying a port number to connect to." + (if (integerp service) (setq service (int-to-string service))) + (let* ((process-connection-type nil) + (port service) + (proc (eval + (` + (start-process name buffer ssl-program-name + (,@ ssl-program-arguments)))))) + (process-kill-without-query proc) + proc)) + +(provide 'ssl) diff --git a/utils/wl-mailto.el b/utils/wl-mailto.el new file mode 100644 index 0000000..09fb0c6 --- /dev/null +++ b/utils/wl-mailto.el @@ -0,0 +1,130 @@ +;;; wl-mailto.el --- some mailto support for wanderlust + +;;; Copyright (C) 1999 Sen Nagata + +;; Author: Sen Nagata +;; Version: 0.5 +;; License: GPL 2 +;; Warning: not optimized at all + +;; This file is not a part of GNU Emacs. + +;;; Commentary: +;; +;; required elisp packages: +;; +;; -wl (>= 0.9.6?) +;; +;; -rfc2368.el +;; -thingatpt.el or browse-url.el +;; +;; installation: +;; +;; -put this file (and rfc2368.el) in an appropriate directory (so emacs +;; can find it) +;; +;; +;; -put: +;; +;; (add-hook 'wl-init-hook (lambda () (require 'wl-mailto))) +;; +;; in .emacs or .wl +;; +;; details: +;; +;; this package provides a number of interactive functions +;; (commands) for the user. each of the commands ultimately creates a +;; draft message based on some information. the names of the commands +;; and brief descriptions are: +;; +;; 1) wl-mailto-compose-message-from-mailto-url +;; make a draft message from a user-specified mailto: url +;; +;; 2) wl-mailto-compose-message-from-mailto-url-at-point +;; make a draft message from a mailto: url at point +;; +;; usage: +;; +;; -invoke wl +;; -try out the commands mentioned above in 'details' + +;;; History: +;; +;; 0.5 +;; +;; wl-user-agent functionality merged into wl-draft.el, so removed +;; dependency +;; +;; 1999-06-24: +;; +;; incorporated a patch from Kenichi OKADA for +;; wl-mailto-compose-message-from-mailto-url-at-point +;; +;; 1999-06-11: +;; +;; fixed a typo +;; +;; 0.4 +;; +;; 1999-06-01: +;; +;; checkdoc checking +;; xemacs compatibility +;; +;; 1999-05-31: +;; +;; rewrote to use rfc2368.el and wl-user-agent.el + +;;; Code: +(defconst wl-mailto-version "wl-mailto.el 0.5") + +;; how should we handle the dependecy on wl? +;; will this work? +(eval-when-compile + (require 'wl)) + +;; use rfc2368 support -- should be usable for things other than wl too +(require 'rfc2368) + +;; yucky compatibility stuff -- someone help me w/ this, please... +(if (and (string-match "^XEmacs \\([0-9.]+\\)" (emacs-version)) + (< (string-to-int (match-string 1 (emacs-version))) 21)) + ;; for xemacs versions less than 21, use browse-url.el + (progn + (require 'browse-url) + (fset 'wl-mailto-url-at-point + 'browse-url-url-at-point)) + ;; for everything else, use thingatpt.el + (progn + (require 'thingatpt) + (fset 'wl-mailto-url-at-point + (lambda () + (thing-at-point 'url))))) + +(defun wl-mailto-compose-message-from-mailto-url (url &optional dummy) + "Compose a message from URL (RFC 2368). +The optional second argument, DUMMY, exists to match the interface +provided by `browse-url-mail' (w3) -- DUMMY does not do anything." + (interactive "sURL: ") + (if (string-match rfc2368-mailto-regexp url) + (let* ((other-headers (rfc2368-parse-mailto-url url)) + (to (cdr (assoc-ignore-case "to" other-headers))) + (subject (cdr (assoc-ignore-case "subject" other-headers)))) + + (wl-user-agent-compose to subject other-headers)) + (message "Not a mailto: url."))) + +;; prepare a message from a mailto: url at point +(defun wl-mailto-compose-message-from-mailto-url-at-point () + "Draft a new message based on URL (RFC 2368) at point." + (interactive) + (let ((url (wl-mailto-url-at-point))) + (if (and url (string-match rfc2368-mailto-regexp url)) + (wl-mailto-compose-message-from-mailto-url url) + ;; tell the user that we didn't find a mailto: url at point + (message "No mailto: url detected at point.")))) + +;; since this will be used via 'require'... +(provide 'wl-mailto) + +;;; wl-mailto.el ends here diff --git a/wl/ChangeLog b/wl/ChangeLog new file mode 100644 index 0000000..7485720 --- /dev/null +++ b/wl/ChangeLog @@ -0,0 +1,31 @@ +2000-03-30 Yuuichi Teranishi + + * wl-demo.el (wl-title-logo): Refer wl-icon-dir. + + * wl-folder.el (wl-create-folder-entity-from-buffer): + Fixed problem when '}' character is contained in folder name. + + * wl-xmas.el (wl-make-modeline): Consider plugged status. + +2000-03-29 Daiki Ueno + + * wl-fldmgr.el (wl-fldmgr-add-completion-hashtb): New variable. + (wl-fldmgr-add-completion-all-completions): + Use wl-fldmgr-add-completion-hashtb. + +2000-03-28 Daiki Ueno + + * wl-fldmgr.el (wl-fldmgr-add-completion-all-completions, + wl-fldmgr-add-completion-subr): New functions. + * wl-folder.el (wl-folder-completion-func): New variable. + * wl-summary.el (wl-summary-read-folder): + Use wl-folder-completion-func. + + * wl-refile.el: Eliminate throw & catch. + + * wl.el (wl-plugged-sending-queue-status): Fixed. + +2000-03-27 Mikio Nakajima + + * wl-draft.el (wl-draft): Put category property on + mail-header-separator. diff --git a/wl/tm-wl.el b/wl/tm-wl.el new file mode 100644 index 0000000..885dd7e --- /dev/null +++ b/wl/tm-wl.el @@ -0,0 +1,285 @@ +;;; wl-mime.el -- tm implementations of MIME processing on Wanderlust. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <00/03/14 19:32:32 teranisi> + +;; This file is part of Wanderlust (Yet Another Message Interface on Emacsen). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; + +(autoload 'mime/editor-mode "tm-edit" nil t) +(autoload 'mime/edit-again "tm-edit" nil t) + +(eval-when-compile (require 'tm-edit)) + +(defalias 'wl-draft-editor-mode 'mime/editor-mode) + +(defun wl-draft-decode-message-in-buffer (&optional default-content-type) + (when default-content-type + (insert "Content-type: " default-content-type "\n") + (insert "\n")) + (mime-editor::edit-again 'code-conversion)) + +(defun wl-draft-yank-current-message-entity () + "Yank currently displayed message entity. +By setting following-method as yank-content." + (let ((wl-draft-buffer (current-buffer)) + (mime-viewer/following-method-alist + (list (cons 'wl-message-original-mode + (function wl-draft-yank-to-draft-buffer))))) + (if (get-buffer (wl-current-message-buffer)) + (save-excursion + (save-restriction + (set-buffer (wl-current-message-buffer)) + (setq mime::preview/mother-buffer nil) + (widen) + (mime-viewer/follow-content)))))) + +(defmacro wl-draft-enclose-digest-region (beg end) + (` (mime-editor/enclose-region "digest" (, beg) (, end)))) + +(defun wl-draft-preview-message () + (interactive) + (let ((mime-viewer/content-header-filter-hook 'wl-highlight-headers) + (mime-viewer/ignored-field-regexp "^:$") + (mime-editor/translate-buffer-hook + (append + (list 'wl-draft-config-exec) + mime-editor/translate-buffer-hook))) + (mime-editor/preview-message) + (let ((buffer-read-only nil)) + (let ((buffer-read-only nil)) + (when wl-highlight-body-too + (wl-highlight-body)) + (run-hooks 'wl-draft-preview-message-hook))))) + +(defmacro wl-draft-caesar-region (beg end) + (` (tm:caesar-region))) + +(defalias 'wl-draft-insert-message 'mime-editor/insert-message) + +(defalias 'wl-draft-insert-mail 'mime-editor/insert-mail) + +;;; Message + +(defun wl-message-decode-mode (outbuf inbuf) + (let ((mime-viewer/content-header-filter-hook 'wl-highlight-headers)) + (mime/viewer-mode nil nil nil inbuf outbuf))) + +(defun wl-message-decode-with-all-header (outbuf inbuf) + (let ((mime-viewer/ignored-field-regexp "^:$") + (mime-viewer/content-header-filter-hook 'wl-highlight-headers)) + (mime/viewer-mode nil nil nil inbuf outbuf))) + +(defun wl-message-delete-mime-out-buf () + (let (mime-out-buf mime-out-win) + (if (setq mime-out-buf (get-buffer mime/output-buffer-name)) + (if (setq mime-out-win (get-buffer-window mime-out-buf)) + (delete-window mime-out-win))))) + +(defun wl-message-request-partial (folder number msgdb) + (elmo-set-work-buf + (elmo-read-msg-no-cache folder number (current-buffer) msgdb) + (mime/parse-message nil nil))) + +(defalias 'wl-message-read 'mime-viewer/scroll-up-content) +(defalias 'wl-message-next-content 'mime-viewer/next-content) +(defalias 'wl-message-prev-content 'mime-viewer/previous-content) +(defalias 'wl-message-play-content 'mime-viewer/play-content) +(defalias 'wl-message-extract-content 'mime-viewer/extract-content) +(defalias 'wl-message-quit 'mime-viewer/quit) +(defalias 'wl-message-button-dispatcher 'tm:button-dispatcher) + +;;; Summary +(defun wl-summary-burst () + (interactive) + (let ((raw-buf (wl-message-get-original-buffer)) + (i 0) + target + children message-entity content-type) + (save-excursion + (setq target wl-summary-buffer-folder-name) + (while (not (elmo-folder-writable-p target)) + (setq target + (wl-summary-read-folder wl-default-folder "to extract to "))) + (wl-summary-set-message-buffer-or-redisplay) + (set-buffer raw-buf) + (setq children (mime::content-info/children mime::article/content-info)) + (message "Bursting...") + (while children + (setq content-type (mime::content-info/type (car children))) + (when (string= "message/rfc822" (downcase content-type)) + (message (format "Bursting...%s" (setq i (+ 1 i)))) + (setq message-entity + (car (mime::content-info/children (car children)))) + (save-restriction + (narrow-to-region (mime::content-info/point-min message-entity) + (mime::content-info/point-max message-entity)) + (elmo-append-msg target + (buffer-substring (point-min) (point-max)) + (std11-field-body "Message-ID")))) + (setq children (cdr children))) + (message "Bursting...done.")) + (if (elmo-folder-plugged-p target) + (elmo-commit target)) + (wl-summary-sync-update3))) + +;; internal variable. +(defvar wl-mime-save-dir nil "Last saved directory.") +;;; Yet another save method. +(defun wl-mime-save-content (beg end cal) + (goto-char beg) + (let* ((name + (save-restriction + (narrow-to-region beg end) + (mime-article/get-filename cal))) + (encoding (cdr (assq 'encoding cal))) + (filename (read-file-name "Save to file: " + (expand-file-name + (or name ".") + (or wl-mime-save-dir + wl-tmp-dir)))) + tmp-buf) + (while (file-directory-p filename) + (setq filename (read-file-name "Please set filename (not directory): " + filename))) + (if (file-exists-p filename) + (or (yes-or-no-p (format "File %s exists. Save anyway? " filename)) + (error "Not saved"))) + (setq wl-mime-save-dir (file-name-directory filename)) + (setq tmp-buf (generate-new-buffer (file-name-nondirectory filename))) + (re-search-forward "\n\n") + (append-to-buffer tmp-buf (match-end 0) end) + (save-excursion + (set-buffer tmp-buf) + (mime-decode-region (point-min)(point-max) encoding) + (as-binary-output-file (write-file filename)) + (kill-buffer tmp-buf)))) + +;;; Yet another combine method. +(defun wl-mime-combine-message/partial-pieces (beg end cal) + (interactive) + (let* (folder + (msgdb (save-excursion + (set-buffer wl-message-buffer-cur-summary-buffer) + (setq folder wl-summary-buffer-folder-name) + wl-summary-buffer-msgdb)) + (mime-viewer/content-header-filter-hook 'wl-highlight-headers) + (id (cdr (assoc "id" cal))) + (mother mime::article/preview-buffer) + (target (cdr (assq 'major-mode cal))) + (article-buffer (buffer-name (current-buffer))) + (subject-buf (eval (cdr (assq 'summary-buffer-exp cal)))) + subject-id overviews + (root-dir (expand-file-name + (concat "m-prts-" (user-login-name)) mime/tmp-dir)) + full-file) + (setq root-dir (concat root-dir "/" (replace-as-filename id))) + (setq full-file (concat root-dir "/FULL")) + (if (null target) + (error "%s is not supported. Sorry." target)) + (if (or (file-exists-p full-file) + (not (y-or-n-p "Merge partials?"))) + (mime-article/decode-message/partial beg end cal) + (message "Merging...") + (let (cinfo the-id parameters) + (setq subject-id + (eword-decode-string + (decode-mime-charset-string + (std11-field-body "Subject") + wl-summary-buffer-mime-charset))) + (if (string-match "[0-9\n]+" subject-id) + (setq subject-id (substring subject-id 0 (match-beginning 0)))) + (setq overviews (elmo-msgdb-get-overview msgdb)) + (catch 'tag + (while overviews + (when (string-match + (regexp-quote subject-id) + (elmo-msgdb-overview-entity-get-subject + (car overviews))) + (setq cinfo + (wl-message-request-partial + folder + (elmo-msgdb-overview-entity-get-number (car overviews)) + msgdb)) + (setq parameters (mime::content-info/parameters cinfo)) + (setq the-id (assoc-value "id" parameters)) + (if (string= the-id id) + (progn + (set-buffer elmo-work-buf-name) + (setq mime::article/preview-buffer + (get-buffer wl-message-buf-name)) + (mime-article/decode-message/partial + (point-min)(point-max) parameters) + (if (file-exists-p full-file) + (throw 'tag nil))))) + (setq overviews (cdr overviews))) + (message "Not all partials found.")))))) + +(defun wl-mime-setup () + (require 'tm-view) + (set-alist 'mime-viewer/quitting-method-alist + 'wl-message-original-mode 'wl-message-exit) + (set-alist 'mime-viewer/over-to-previous-method-alist + 'wl-message-original-mode 'wl-message-exit) + (set-alist 'mime-viewer/over-to-next-method-alist + 'wl-message-original-mode 'wl-message-exit) + (add-hook 'wl-summary-redisplay-hook 'wl-message-delete-mime-out-buf) + (add-hook 'wl-message-exit-hook 'wl-message-delete-mime-out-buf) + (set-atype 'mime/content-decoding-condition + '((type . "message/partial") + (method . wl-message-combine-message/partial-pieces) + (major-mode . wl-message-original-mode) + (summary-buffer-exp . wl-summary-buffer-name))) + (set-atype 'mime/content-decoding-condition + '((mode . "extract") + (method . wl-mime-save-content) + (major-mode . wl-message-original-mode)) + 'remove + '((method "tm-file" nil 'file 'type 'encoding 'mode 'name) + (mode . "extract")) + 'replacement) + (set-alist 'mime-viewer/following-method-alist + 'wl-message-original-mode + (function wl-message-follow-current-entity)) + + (set-alist 'mime-editor/message-inserter-alist + 'wl-draft-mode (function wl-draft-insert-current-message)) + (set-alist 'mime-editor/mail-inserter-alist + 'wl-draft-mode (function wl-draft-insert-get-message)) + (set-alist 'mime-editor/split-message-sender-alist + 'wl-draft-mode + (cdr (assq 'mail-mode + mime-editor/split-message-sender-alist))) + (setq mime-viewer/code-converter-alist + (append + (list (cons 'wl-message-original-mode 'mime-charset/decode-buffer)) + mime-viewer/code-converter-alist)) + (defvar-maybe mime::preview/mother-buffer nil)) + +(provide 'tm-wl) + +;;; tm-wl.el ends here diff --git a/wl/wl-address.el b/wl/wl-address.el new file mode 100644 index 0000000..50ef029 --- /dev/null +++ b/wl/wl-address.el @@ -0,0 +1,381 @@ +;;; wl-address.el -- Tiny address management for Wanderlust. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <2000-03-03 00:59:01 teranisi> + +;; This file is part of Wanderlust (Yet Another Message Interface on Emacsen). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; + +(require 'wl-util) +(require 'std11) + +(defvar wl-address-complete-header-regexp "^\\(To\\|From\\|Cc\\|Bcc\\|Mail-Followup-To\\|Reply-To\\|Return-Receipt-To\\):") +(defvar wl-newsgroups-complete-header-regexp "^\\(Newsgroups\\|Followup-To\\):") +(defvar wl-folder-complete-header-regexp "^\\(FCC\\):") +(defvar wl-address-list nil) +(defvar wl-address-completion-list nil) +(defvar wl-address-petname-hash nil) + +(defun wl-complete-field-to () + (interactive) + (let ((cl wl-address-completion-list)) + (if cl + (completing-read "To: " cl) + (read-string "To: ")))) + +(defun wl-complete-field-body-or-tab () + (interactive) + (let ((case-fold-search t) + epand-char skip-chars + completion-list) + (if (wl-draft-on-field-p) + (wl-complete-field) + (if (and + (< (point) + (save-excursion + (goto-char (point-min)) + (search-forward (concat "\n" mail-header-separator "\n") nil 0) + (point))) + (save-excursion + (beginning-of-line) + (while (and (looking-at "^[ \t]") + (not (= (point) (point-min)))) + (forward-line -1)) + (cond ((looking-at wl-address-complete-header-regexp) + (setq completion-list wl-address-completion-list) + (setq epand-char ?@)) + ((looking-at wl-folder-complete-header-regexp) + (setq completion-list wl-folder-entity-hashtb) + (setq skip-chars "^, ")) + ((looking-at wl-newsgroups-complete-header-regexp) + (setq completion-list wl-folder-newsgroups-hashtb))))) + (wl-complete-field-body completion-list + epand-char skip-chars) + (indent-for-tab-command))))) + +(defvar wl-completion-buf-name "*Completions*") + +(defvar wl-complete-candidates nil) + +(defun wl-complete-window-show (all) + (if (and (get-buffer-window wl-completion-buf-name) + (equal wl-complete-candidates all)) + (let ((win (get-buffer-window wl-completion-buf-name))) + (save-excursion + (set-buffer wl-completion-buf-name) + (if (pos-visible-in-window-p (point-max) win) + (set-window-start win 1) + (scroll-other-window)))) + (message "Making completion list...") + (setq wl-complete-candidates all) + (with-output-to-temp-buffer + wl-completion-buf-name + (display-completion-list all)) + (message "Making completion list... done"))) + +(defun wl-complete-window-delete () + (let (comp-buf comp-win) + (if (setq comp-buf (get-buffer wl-completion-buf-name)) + (if (setq comp-win (get-buffer-window comp-buf)) + (delete-window comp-win))))) + +(defun wl-complete-field () + (interactive) + (let* ((end (point)) + (start (save-excursion + (skip-chars-backward "_a-zA-Z0-9+@%.!\\-") + (point))) + (completion) + (pattern (buffer-substring start end)) + (cl wl-draft-field-completion-list)) + (if (null cl) + nil + (setq completion + (let ((completion-ignore-case t)) + (try-completion pattern cl))) + (cond ((eq completion t) + (let ((alias (assoc pattern cl))) + (if alias + (progn + (delete-region start end) + (insert (cdr alias)) + ; (wl-highlight-message (point-min)(point-max) t) + ))) + (wl-complete-window-delete)) + ((null completion) + (message "Can't find completion for \"%s\"" pattern) + (ding)) + ((not (string= pattern completion)) + (delete-region start end) + (insert completion) + (wl-complete-window-delete) + (wl-highlight-message (point-min)(point-max) t)) + (t + (let ((list (all-completions pattern cl))) + (wl-complete-window-show list))))))) + +(defun wl-complete-insert (start end pattern completion-list) + (let ((alias (and (consp completion-list) + (assoc pattern completion-list))) + comp-buf comp-win) + (if alias + (progn + (delete-region start end) + (insert (cdr alias)) + (if (setq comp-buf (get-buffer wl-completion-buf-name)) + (if (setq comp-win (get-buffer-window comp-buf)) + (delete-window comp-win))))))) + +(defun wl-complete-field-body (completion-list &optional epand-char skip-chars) + (interactive) + (let* ((end (point)) + (start (save-excursion +; (skip-chars-backward "_a-zA-Z0-9+@%.!\\-") + (skip-chars-backward (or skip-chars + "_a-zA-Z0-9+@%.!\\-/")) + (point))) + (completion) + (pattern (buffer-substring start end)) + (len (length pattern)) + (cl completion-list)) + (if (null cl) + nil + (setq completion (try-completion pattern cl)) + (cond ((eq completion t) + (wl-complete-insert start end pattern completion-list) + (wl-complete-window-delete) + (message "Sole completion")) + ((and epand-char + (> len 0) + (char-equal (aref pattern (1- len)) epand-char) + (assoc (substring pattern 0 (1- len)) cl)) + (wl-complete-insert + start end + (substring pattern 0 (1- len)) + cl)) + ((null completion) + (message "Can't find completion for \"%s\"" pattern) + (ding)) + ((not (string= pattern completion)) + (delete-region start end) + (insert completion)) + (t + (let ((list (sort (all-completions pattern cl) 'string<))) + (wl-complete-window-show list))))))) + +(defvar wl-address-init-func 'wl-local-address-init) + +(defun wl-address-init () + (funcall wl-address-init-func)) + +(defun wl-local-address-init () + (message "Updating addresses...") + (setq wl-address-list + (wl-address-make-address-list wl-address-file)) + (setq wl-address-completion-list + (wl-address-make-completion-list wl-address-list)) + (if (file-readable-p wl-alias-file) + (setq wl-address-completion-list + (append wl-address-completion-list + (wl-address-make-alist-from-alias-file wl-alias-file)))) + (setq wl-address-petname-hash (elmo-make-hash)) + (mapcar + (function + (lambda (x) + (elmo-set-hash-val (downcase (car x)) + (cadr x) + wl-address-petname-hash))) + wl-address-list) + (message "Updating addresses...done.")) + + +(defun wl-address-expand-aliases (alist nest-count) + (when (< nest-count 5) + (let (expn-str new-expn-str expn new-expn(n 0) (expanded nil)) + (while (setq expn-str (cdr (nth n alist))) + (setq new-expn-str nil) + (while (string-match "^[ \t]*\\([^,]+\\)" expn-str) + (setq expn (elmo-match-string 1 expn-str)) + (setq expn-str (wl-string-delete-match expn-str 0)) + (if (string-match "^[ \t,]+" expn-str) + (setq expn-str (wl-string-delete-match expn-str 0))) + (if (string-match "[ \t,]+$" expn) + (setq expn (wl-string-delete-match expn 0))) + (setq new-expn (cdr (assoc expn alist))) + (if new-expn + (setq expanded t)) + (setq new-expn-str (concat new-expn-str (and new-expn-str ", ") + (or new-expn expn)))) + (when new-expn-str + (setcdr (nth n alist) new-expn-str)) + (setq n (1+ n))) + (and expanded + (wl-address-expand-aliases alist (1+ nest-count)))))) + +(defun wl-address-make-alist-from-alias-file (file) + (elmo-set-work-buf + (let ((case-fold-search t) + alias expn alist) + (insert-file-contents file) + (while (re-search-forward ",$" nil t) + (end-of-line) + (forward-char 1) + (delete-backward-char 1)) + (goto-char (point-min)) + (while (re-search-forward "^\\([^#;\n][^:]+\\):[ \t]*\\(.*\\)$" nil t) + (setq alias (wl-match-buffer 1) + expn (wl-match-buffer 2)) + (setq alist (cons (cons alias expn) alist))) + (wl-address-expand-aliases alist 0) + (nreverse alist) ; return value + ))) + +(defun wl-address-make-address-list (path) + (if (and path (file-readable-p path)) + (elmo-set-work-buf + (let (ret + (coding-system-for-read wl-cs-autoconv)) + (insert-file-contents path) + (goto-char (point-min)) + (while (not (eobp)) + (if (looking-at + "^\\([^#\n][^ \t\n]+\\)[ \t]+\"\\(.*\\)\"[ \t]+\"\\(.*\\)\"[ \t]*.*$") + (setq ret + (wl-append-element + ret + (list (wl-match-buffer 1) + (wl-match-buffer 2) + (wl-match-buffer 3))))) + (forward-line)) + ret)))) + +(defsubst wl-address-get-petname (str) + (let ((addr (downcase (wl-address-header-extract-address str)))) + (or (elmo-get-hash-val addr wl-address-petname-hash) + str))) + +(defsubst wl-address-make-completion-list (address-list) + (mapcar '(lambda (entity) + (cons (nth 0 entity) + (concat (nth 2 entity) " <"(nth 0 entity)">"))) address-list)) + +(defsubst wl-address-user-mail-address-p (address) + "Judge whether ADDRESS is user's or not." + (member (downcase (wl-address-header-extract-address address)) + (or (mapcar 'downcase wl-user-mail-address-list) + (list (downcase + (wl-address-header-extract-address + wl-from)))))) + +(defsubst wl-address-header-extract-address (str) + "Extracts a real e-mail address from STR and returns it. +e.g. \"Mine Sakurai \" + -> \"m-sakura@ccs.mt.nec.co.jp\". +e.g. \"m-sakura@ccs.mt.nec.co.jp (Mine Sakurai)\" + -> \"m-sakura@ccs.mt.nec.co.jp\"." + (cond ((string-match ".*<\\([^>]*\\)>" str) ; .* to extract last <> + (wl-match-string 1 str)) + ((string-match "\\([^ \t\n]*@[^ \t\n]*\\)" str) + (wl-match-string 1 str)) + (t str))) + +(defsubst wl-address-header-extract-realname (str) + "Extracts a real name from STR and returns it. +e.g. \"Mr. bar \" + -> \"Mr. bar\"." + (cond ((string-match "\\(.*[^ \t]\\)[ \t]*<[^>]*>" str) + (wl-match-string 1 str)) + (t ""))) + +(defun wl-address-petname-delete (the-email) + "Delete petname in wl-address-file." + (let* ( (tmp-buf (get-buffer-create " *wl-petname-tmp*")) + (output-coding-system + (mime-charset-to-coding-system wl-mime-charset))) + (set-buffer tmp-buf) + (message "Deleting Petname...") + (erase-buffer) + (insert-file-contents wl-address-file) + (delete-matching-lines (concat "^[ \t]*" the-email)) + (write-region (point-min) (point-max) + wl-address-file nil 'no-msg) + (message "Deleting Petname...done") + (kill-buffer tmp-buf))) + + +(defun wl-address-petname-add-or-change (the-email + default-petname + default-realname + &optional change-petname) + "Add petname to wl-address-file, if not registerd. +If already registerd, change it." + (let (the-realname the-petname) + + ;; setup output "petname" + ;; if null petname'd, let default-petname be the petname. + (setq the-petname + (read-from-minibuffer (format "Petname: ") default-petname)) + (if (string= the-petname "") + (setq the-petname default-petname)) + + ;; setup output "realname" + (setq the-realname + (read-from-minibuffer (format "Real Name: ") default-realname)) +;; (if (string= the-realname "") +;; (setq the-realname default-petname)) + + ;; writing to ~/.address + (let ( (tmp-buf (get-buffer-create " *wl-petname-tmp*")) + (output-coding-system (mime-charset-to-coding-system wl-mime-charset))) + (set-buffer tmp-buf) + (message "Adding Petname...") + (erase-buffer) + (if (file-exists-p wl-address-file) + (insert-file-contents wl-address-file)) + (if (not change-petname) + ;; if only add + (progn + (goto-char (point-max)) + (if (and (> (buffer-size) 0) + (not (eq (char-after (1- (point-max))) ?\n))) + (insert "\n"))) + ;; if change + (if (re-search-forward (concat "^[ \t]*" the-email) nil t) + (delete-region (save-excursion (beginning-of-line) + (point)) + (save-excursion (end-of-line) + (+ 1 (point)))))) + (insert (format "%s\t\"%s\"\t\"%s\"\n" + the-email the-petname the-realname)) + (write-region (point-min) (point-max) + wl-address-file nil 'no-msg) + (message "Adding Petname...done") + (kill-buffer tmp-buf)))) + +(provide 'wl-address) + +;;; wl-address.el ends here diff --git a/wl/wl-demo.el b/wl/wl-demo.el new file mode 100644 index 0000000..52a3a0d --- /dev/null +++ b/wl/wl-demo.el @@ -0,0 +1,201 @@ +;;; wl-demo.el -- Opening demo on Wanderlust. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <2000-03-30 15:56:54 teranisi> + +;; This file is part of Wanderlust (Yet Another Message Interface on Emacsen). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; + +(require 'wl-vars) +(provide 'wl-demo) +(if (featurep 'xemacs) + (require 'wl-xmas)) + +(eval-when-compile + (defun-maybe device-on-window-system-p ()) + (defun-maybe glyph-height (a)) + (defun-maybe glyph-width (a)) + (defun-maybe make-extent (a b)) + (defun-maybe make-glyph (a)) + (defun-maybe set-extent-end-glyph (a b)) + (defun-maybe startup-center-spaces (a)) + (defun-maybe window-pixel-height ()) + (defun-maybe window-pixel-width ()) + (condition-case nil + (require 'bitmap) + (error nil)) + (defun-maybe bitmap-compose (a)) + (defun-maybe bitmap-decode-xbm (a)) + (defun-maybe bitmap-read-xbm-file (a)) + (unless (boundp ':data) + (set (make-local-variable ':data) nil)) + (unless (boundp ':type) + (set (make-local-variable ':type) nil)) + (condition-case nil + (require 'image) + (error nil)) + (defun-maybe frame-char-height ()) + (defun-maybe frame-char-width ()) + (defun-maybe image-type-available-p (a))) + +(static-condition-case nil + (progn + (insert-image '(image)) + (defalias 'wl-insert-image 'insert-image)) + (wrong-number-of-arguments + (defun wl-insert-image (image) + (insert-image image "x"))) + (void-function + (defun wl-insert-image (image)))) + +;; +;; demo ;-) +;; +(eval-when-compile + (cond ((or (featurep 'xemacs) (featurep 'image)) + (defmacro wl-title-logo () + (let ((file (expand-file-name "wl-logo.xpm" wl-icon-dir))) + (if (file-exists-p file) + (let ((buffer (generate-new-buffer " *wl-logo*")) + (coding-system-for-read 'binary) + buffer-file-format format-alist + insert-file-contents-post-hook + insert-file-contents-pre-hook) + (prog1 + (save-excursion + (set-buffer buffer) + (insert-file-contents file) + (buffer-string)) + (kill-buffer buffer))))))) + ((condition-case nil + (require 'bitmap) + (error nil)) + (defmacro wl-title-logo () + (let ((file (expand-file-name "wl-logo.xbm" wl-icon-dir))) + (if (file-exists-p file) + (condition-case nil + (bitmap-decode-xbm (bitmap-read-xbm-file file)) + (error (message "Bitmap Logo is not used."))))))) + (t + (defmacro wl-title-logo ())))) + +(defconst wl-title-logo + (cond ((or (and (featurep 'xemacs) + (featurep 'xpm) + (device-on-window-system-p)) + (and (eval-when-compile (featurep 'image)) + (image-type-available-p 'xpm))) + (wl-title-logo)) + ((and window-system + (condition-case nil + (require 'bitmap) + (error nil))) + (let ((cmp (wl-title-logo))) + (if cmp + (condition-case nil + (let ((len (length cmp)) + (bitmap (bitmap-compose (aref cmp 0))) + (i 1)) + (while (< i len) + (setq bitmap (concat bitmap "\n" + (bitmap-compose (aref cmp i))) + i (1+ i))) + bitmap) + (error nil))))))) + +(defun wl-demo () + (interactive) + (let ((demo-buf (get-buffer-create "*WL Demo*")) + logo-ext start) + (switch-to-buffer demo-buf) + (erase-buffer) + (if (and wl-demo-display-logo wl-title-logo) + (cond + ((featurep 'xemacs) + (let ((wl-logo (make-glyph (vector 'xpm :data wl-title-logo)))) + (insert-char ?\n (max 1 (/ (- (window-height) 6 + (/ (glyph-height wl-logo) + (/ (window-pixel-height) + (window-height)))) 2))) + (indent-to (startup-center-spaces wl-logo)) + (insert-char ?\ (max 0 (/ (- (window-width) + (/ (glyph-width wl-logo) + (/ (window-pixel-width) + (window-width)))) 2))) + (setq logo-ext (make-extent (point)(point))) + (set-extent-end-glyph logo-ext wl-logo))) + ((featurep 'image) + (let ((wl-logo (list 'image :type 'xpm :data wl-title-logo)) + pixel-width pixel-height) + (with-temp-buffer + (insert wl-title-logo) + (goto-char (point-min)) + (skip-syntax-forward "^\"") + (when (looking-at "\"[ \t]*\\([0-9]+\\)[ \t]*\\([0-9]+\\)") + (setq pixel-width (string-to-int (match-string 1)) + pixel-height (string-to-int (match-string 2))))) + (insert-char ?\n (max 1 (/ (- (window-height) 6 + (/ pixel-height + (frame-char-height))) 2))) + (insert-char ?\ (max 0 (/ (- (window-width) + (/ pixel-width + (frame-char-width))) 2))) + (wl-insert-image wl-logo) + (insert "\n"))) + (t + (insert wl-title-logo) + (indent-rigidly (point-min) (point-max) + (max 0 (/ (- (window-width) (current-column)) 2))) + (insert "\n") + (goto-char (point-min)) + (insert-char ?\n (max 0 (/ (- (window-height) + (count-lines (point) (point-max)) + 6) 2))) + (goto-char (point-max)))) + (insert-char ?\n (max 1 (- (/ (window-height) 3) 2)))) + (setq start (point)) + (insert "\n" (if (and wl-demo-display-logo wl-title-logo) + "" + (concat wl-appname "\n"))) + (let ((fill-column (window-width))) + (center-region start (point))) + (setq start (point)) + (put-text-property (point-min) (point) 'face 'wl-highlight-logo-face) + (insert (format "\nversion %s - \"%s\"\n\n" + wl-version wl-codename + )) + (insert "Copyright (C) 1998-2000 Yuuichi Teranishi ") + (put-text-property start (point-max) 'face 'wl-highlight-demo-face) + (let ((fill-column (window-width))) + (center-region start (point))) + (goto-char (point-min)) + (sit-for + (if (featurep 'lisp-float-type) (/ (float 5) (float 10)) 1)) + ;;(if (featurep 'xemacs) (delete-extent logo-ext)) + demo-buf)) + +;;; wl-demo.el ends here diff --git a/wl/wl-dnd.el b/wl/wl-dnd.el new file mode 100644 index 0000000..5578a7a --- /dev/null +++ b/wl/wl-dnd.el @@ -0,0 +1,103 @@ +;;; wl-dnd.el -- dragdrop support on Wanderlust. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <2000-02-18 19:14:53 teranisi> + +;; This file is part of Wanderlust (Yet Another Message Interface on Emacsen). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; + +(provide 'wl-dnd) + +(static-cond + ((featurep 'offix) + (defun start-drag (event what &optional typ) + (if (numberp typ) + (funcall (intern "offix-start-drag") event what typ) + (funcall (intern "offix-start-drag") event what)))) + ((featurep 'cde) + (defun start-drag (event what &optional typ) + (if (not typ) + (funcall (intern "cde-start-drag-internal") event nil + (list what)) + (funcall (intern "cde-start-drag-internal") event t what)))) + (t (defun start-drag (event what &optional typ)))) + +(defun wl-dnd-start-drag (event) + (interactive "@e") + (mouse-set-point event) + (start-drag event (concat + wl-summary-buffer-folder-name " " + (int-to-string (wl-summary-message-number))))) + +(defun wl-dnd-drop-func (event object text) + (interactive "@e") + (mouse-set-point event) + (beginning-of-line) + (when (looking-at "^[ ]*\\([^\\[].+\\):.*\n") + (let* ((src-spec (save-match-data + (split-string (nth 2 (car (cdr object))) + " "))) + (src-fld (nth 0 src-spec)) + (number (string-to-int (nth 1 src-spec))) + target) + (setq target + (wl-folder-get-folder-name-by-id (get-text-property + (point) + 'wl-folder-entity-id))) + (message "%s is dropped at %s." number + (buffer-substring (match-beginning 1) + (match-end 1))) + (set-buffer (wl-summary-get-buffer src-fld)) + (save-match-data + (wl-summary-jump-to-msg number)) + (wl-summary-refile target number) + (select-window (get-buffer-window (current-buffer))) + )) + t) + +(defun wl-dnd-default-drop-message (event object) + (message "Dropping here is meaningless.") + t) + +(defun wl-dnd-set-drop-target (beg end) + (let (ext substr) + (setq ext (make-extent beg end)) + (set-extent-property + ext + 'experimental-dragdrop-drop-functions + '((wl-dnd-drop-func t t (buffer-substring beg end)))))) +; (set-extent-property ext 'mouse-face 'highlight))) + +(defun wl-dnd-set-drag-starter (beg end) + (let (ext kmap) + (setq ext (make-extent beg end)) +; (set-extent-property ext 'mouse-face 'isearch) + (setq kmap (make-keymap)) + (define-key kmap [button1] 'wl-dnd-start-drag) + (set-extent-property ext 'keymap kmap))) + +;;; wl-dnd.el ends here diff --git a/wl/wl-draft.el b/wl/wl-draft.el new file mode 100644 index 0000000..b85bfc7 --- /dev/null +++ b/wl/wl-draft.el @@ -0,0 +1,1854 @@ +;;; wl-draft.el -- Message draft mode for Wanderlust. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <2000-03-22 19:12:26 teranisi> + +;; This file is part of Wanderlust (Yet Another Message Interface on Emacsen). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; + +(require 'sendmail) +(require 'wl-template) +(require 'emu) +(if (module-installed-p 'timezone) + (require 'timezone)) +(require 'std11) +(require 'wl-vars) + +(eval-when-compile + (require 'smtp) + (require 'elmo-pop3) + (mapcar + (function + (lambda (symbol) + (unless (boundp symbol) + (set (make-local-variable symbol) nil)))) + '(x-face-add-x-face-version-header + mail-reply-buffer + mail-from-style + smtp-authenticate-type + smtp-authenticate-user + smtp-authenticate-passphrase + smtp-connection-type + )) + (defun-maybe x-face-insert (a)) + (defun-maybe x-face-insert-version-header ()) + (defun-maybe wl-init (&optional a)) + (defun-maybe wl-draft-mode ())) + +(defvar wl-draft-buf-name "Draft") +(defvar wl-caesar-region-func nil) +(defvar wl-draft-cite-func 'wl-default-draft-cite) +(defvar wl-draft-buffer-file-name nil) +(defvar wl-draft-field-completion-list nil) +(defvar wl-draft-verbose-send t) +(defvar wl-draft-verbose-msg nil) +(defvar wl-draft-queue-flushing nil) +(defvar wl-draft-config-variables nil) +(defvar wl-draft-config-exec-flag t) +(defvar wl-draft-buffer-cur-summary-buffer nil) +(defvar wl-draft-clone-local-variable-regexp "^\\(wl\\|mime\\)") +(defvar wl-draft-sendlog-filename "sendlog") +(defvar wl-draft-queue-save-filename "qinfo") +(defvar wl-draft-config-save-filename "config") +(defvar wl-draft-queue-flush-send-func 'wl-draft-dispatch-message) +(defvar wl-sent-message-via nil) +(defvar wl-sent-message-modified nil) +(defvar wl-draft-fcc-list nil) +(defvar wl-draft-reedit nil) +(defvar wl-draft-reply-buffer nil) +(defvar wl-draft-forward nil) + +(defvar wl-draft-config-sub-func-alist + '((body . wl-draft-config-sub-body) + (top . wl-draft-config-sub-top) + (bottom . wl-draft-config-sub-bottom) + (header . wl-draft-config-sub-header) + (body-file . wl-draft-config-sub-body-file) + (top-file . wl-draft-config-sub-top-file) + (bottom-file . wl-draft-config-sub-bottom-file) + (header-file . wl-draft-config-sub-header-file) + (template . wl-draft-config-sub-template) + (x-face . wl-draft-config-sub-x-face))) + +(make-variable-buffer-local 'wl-draft-buffer-file-name) +(make-variable-buffer-local 'wl-draft-buffer-cur-summary-buffer) +(make-variable-buffer-local 'wl-draft-config-variables) +(make-variable-buffer-local 'wl-draft-config-exec-flag) +(make-variable-buffer-local 'wl-sent-message-via) +(make-variable-buffer-local 'wl-draft-fcc-list) +(make-variable-buffer-local 'wl-draft-reply-buffer) + +;;; SMTP binding by Daiki Ueno +(defvar wl-smtp-features + '(((smtp-authenticate-type + (if wl-smtp-authenticate-type + (intern (downcase (format "%s" wl-smtp-authenticate-type))))) + ((smtp-authenticate-user wl-smtp-posting-user) + ((smtp-authenticate-passphrase + (elmo-get-passwd + (format "%s@%s" + smtp-authenticate-user + smtp-server)))))) + (smtp-connection-type)) + "Additional SMTP features.") + +(eval-when-compile + (defun wl-smtp-parse-extension (exts parents) + (let (bindings binding feature) + (dolist (ext exts) + (setq feature (if (listp (car ext)) (caar ext) (car ext)) + binding + (` ((, feature) + (or (, (if (listp (car ext)) + (cadar ext) + (let ((wl-feature + (intern + (concat "wl-" (symbol-name feature))))) + (if (boundp wl-feature) + wl-feature)))) + (and (boundp '(, feature)) (, feature)))))) + (when parents + (setcdr binding (list (append '(and) parents (cdr binding))))) + (setq bindings + (nconc bindings (list binding) + (wl-smtp-parse-extension + (cdr ext) (cons feature parents))))) + bindings))) + +(defmacro wl-smtp-extension-bind (&rest body) + "Return a `let' form that binds all variables of SMTP extension. +After this is done, BODY will be executed in the scope +of the `let' form. + +The variables bound and their default values are described by +the `wl-smtp-features' variable." + (` (let* (, (wl-smtp-parse-extension wl-smtp-features nil)) + (,@ body)))) + +(defun wl-draft-insert-date-field () + (insert "Date: " (wl-make-date-string) "\n")) + +(defun wl-draft-insert-from-field () + ;; Put the "From:" field in unless for some odd reason + ;; they put one in themselves. + (let* ((login (or user-mail-address (user-login-name))) + (fullname (user-full-name))) + (cond ((eq mail-from-style 'angles) + (insert "From: " fullname) + (let ((fullname-start (+ (point-min) 6)) + (fullname-end (point-marker))) + (goto-char fullname-start) + ;; Look for a character that cannot appear unquoted + ;; according to RFC 822. + (if (re-search-forward "[^- !#-'*+/-9=?A-Z^-~]" + fullname-end 1) + (progn + ;; Quote fullname, escaping specials. + (goto-char fullname-start) + (insert "\"") + (while (re-search-forward "[\"\\]" + fullname-end 1) + (replace-match "\\\\\\&" t)) + (insert "\"")))) + (insert " <" login ">\n")) + ((eq mail-from-style 'parens) + (insert "From: " login " (") + (let ((fullname-start (point))) + (insert fullname) + (let ((fullname-end (point-marker))) + (goto-char fullname-start) + ;; RFC 822 says \ and nonmatching parentheses + ;; must be escaped in comments. + ;; Escape every instance of ()\ ... + (while (re-search-forward "[()\\]" fullname-end 1) + (replace-match "\\\\\\&" t)) + ;; ... then undo escaping of matching parentheses, + ;; including matching nested parentheses. + (goto-char fullname-start) + (while (re-search-forward + "\\(\\=\\|[^\\]\\(\\\\\\\\\\)*\\)\\\\(\\(\\([^\\]\\|\\\\\\\\\\)*\\)\\\\)" + fullname-end 1) + (replace-match "\\1(\\3)" t) + (goto-char fullname-start)))) + (insert ")\n")) + ((null mail-from-style) + (insert "From: " login "\n"))))) + +(defun wl-draft-insert-x-face-field () + "Insert x-face header." + (interactive) + (if (not (file-exists-p wl-x-face-file)) + (error "File %s does not exist" wl-x-face-file) + (beginning-of-buffer) + (search-forward mail-header-separator nil t) + (beginning-of-line) + (wl-draft-insert-x-face-field-here) + (run-hooks 'wl-draft-insert-x-face-field-hook) ; highlight it if you want. + )) + +(defun wl-draft-insert-x-face-field-here () + "insert x-face field at point." + (let ((x-face-string (elmo-get-file-string wl-x-face-file))) + (if (string-match "^[ \t]*" x-face-string) + (setq x-face-string (substring x-face-string (match-end 0)))) + (insert "X-Face: " x-face-string)) + (if (not (= (preceding-char) ?\n)) + (insert ?\n)) + (and (fboundp 'x-face-insert-version-header) ; x-face.el... + (boundp 'x-face-add-x-face-version-header) + x-face-add-x-face-version-header + (x-face-insert-version-header))) + +(defun wl-draft-setup () + (let ((field wl-draft-fields) + ret-val) + (while field + (setq ret-val (append ret-val + (list (cons (concat (car field) " ") + (concat (car field) " "))))) + (setq field (cdr field))) + (setq wl-draft-field-completion-list ret-val))) + +(defun wl-draft-make-mail-followup-to (recipients) + (if (elmo-list-member + (or wl-user-mail-address-list + (list (wl-address-header-extract-address wl-from))) + recipients) + (let ((rlist (elmo-list-delete + (or wl-user-mail-address-list + (list (wl-address-header-extract-address wl-from))) + (copy-sequence recipients)))) + (if (elmo-list-member rlist (mapcar 'downcase + wl-subscribed-mailing-list)) + rlist + (append rlist (list (wl-address-header-extract-address + wl-from))))) + recipients)) + +(defun wl-draft-delete-myself-from-cc (to cc) + (let ((myself (or wl-user-mail-address-list + (list (wl-address-header-extract-address wl-from))))) + (if wl-draft-always-delete-myself + (elmo-list-delete myself cc) + (if (elmo-list-member myself cc) + (if (elmo-list-member (append to cc) + (mapcar 'downcase wl-subscribed-mailing-list)) + ;; member list is contained in recipients. + (elmo-list-delete myself cc) + cc + ) + cc)))) + +(defun wl-draft-forward (original-subject summary-buf) + (wl-draft "" (concat "Forward: " original-subject) + nil nil nil nil nil nil nil nil summary-buf) + (goto-char (point-max)) + (wl-draft-insert-message) + (mail-position-on-field "To")) + +(defun wl-draft-reply (buf no-arg summary-buf) +; (save-excursion + (let ((r-list (if no-arg wl-draft-reply-without-argument-list + wl-draft-reply-with-argument-list)) + to mail-followup-to cc subject in-reply-to references newsgroups + from) + (set-buffer buf) + (if (wl-address-user-mail-address-p + (setq from + (wl-address-header-extract-address (std11-field-body "From")))) + (setq to (mapconcat 'identity (elmo-multiple-field-body "To") ",") + cc (mapconcat 'identity (elmo-multiple-field-body "Cc") ",") + newsgroups (or (std11-field-body "Newsgroups") "")) + (catch 'done + (while r-list + (when (let ((condition (car (car r-list)))) + (cond ((stringp condition) + (std11-field-body condition)) + ((listp condition) + (catch 'done + (while condition + (if (not (std11-field-body (car condition))) + (throw 'done nil)) + (setq condition (cdr condition))) + t)) + ((symbolp condition) + (funcall condition)))) + (let ((r-to-list (nth 0 (cdr (car r-list)))) + (r-cc-list (nth 1 (cdr (car r-list)))) + (r-ng-list (nth 2 (cdr (car r-list))))) + (when (and (member "Followup-To" r-ng-list) + (string= (std11-field-body "Followup-To") "poster")) + (setq r-to-list (cons "From" r-to-list)) + (setq r-ng-list (delete "Followup-To" (copy-sequence r-ng-list)))) + (setq to (wl-concat-list (cons to + (elmo-multiple-fields-body-list + r-to-list)) + ",")) + (setq cc (wl-concat-list (cons cc + (elmo-multiple-fields-body-list + r-cc-list)) + ",")) + (setq newsgroups (wl-concat-list (cons newsgroups + (std11-field-bodies + r-ng-list)) + ","))) + (throw 'done nil)) + (setq r-list (cdr r-list))) + (error "No match field: check your `wl-draft-reply-without-argument-list'"))) + (setq subject (std11-field-body "Subject")) + (with-temp-buffer ; to keep raw buffer unibyte. + (elmo-set-buffer-multibyte default-enable-multibyte-characters) + (setq subject (or (and subject + (eword-decode-string + (decode-mime-charset-string + subject + wl-mime-charset)))))) + (and subject wl-reply-subject-prefix + (let ((case-fold-search t)) + (not + (equal + (string-match (regexp-quote wl-reply-subject-prefix) + subject) + 0))) + (setq subject (concat wl-reply-subject-prefix subject))) + (and (setq in-reply-to (std11-field-body "Message-Id")) + (setq in-reply-to + (format "In your message of \"%s\"\n\t%s" + (or (std11-field-body "Date") "some time ago") + in-reply-to))) + (setq references (nconc + (std11-field-bodies '("References" "In-Reply-To")) + (list in-reply-to))) + (setq to (wl-parse-addresses to) + cc (wl-parse-addresses cc)) + (setq to (mapcar '(lambda (addr) + (wl-address-header-extract-address + addr)) to)) + (setq cc (mapcar '(lambda (addr) + (wl-address-header-extract-address + addr)) cc)) + ;; if subscribed mailing list is contained in cc or to + ;; and myself is contained in cc, + ;; delete myself from cc. + (setq cc (wl-draft-delete-myself-from-cc to cc)) + (if wl-insert-mail-followup-to + (progn + (setq mail-followup-to + (wl-draft-make-mail-followup-to (append to cc))) + (setq mail-followup-to (wl-delete-duplicates mail-followup-to + nil t)))) + (setq newsgroups (wl-parse newsgroups + "[ \t\f\r\n,]*\\([^ \t\f\r\n,]+\\)") + newsgroups (wl-delete-duplicates newsgroups) + newsgroups (if newsgroups (mapconcat 'identity newsgroups ","))) + (setq to (wl-delete-duplicates to nil t)) + (setq cc (wl-delete-duplicates + (append (wl-delete-duplicates cc nil t) + to (copy-sequence to)) + t t)) + (and to (setq to (mapconcat 'identity to ",\n\t"))) + (and cc (setq cc (mapconcat 'identity cc ",\n\t"))) + (and mail-followup-to (setq mail-followup-to + (mapconcat 'identity + mail-followup-to ",\n\t"))) + (and (null to) (setq to cc cc nil)) + (setq references (delq nil references) + references (mapconcat 'identity references " ") + references (wl-parse references "[^<]*\\(<[^>]+>\\)") + references (wl-delete-duplicates references) + references (if references + (mapconcat 'identity references "\n\t"))) + (wl-draft + to subject in-reply-to cc references newsgroups mail-followup-to + nil nil nil summary-buf) + (setq wl-draft-reply-buffer buf)) + (run-hooks 'wl-reply-hook)) + +(defun wl-draft-yank-from-mail-reply-buffer (decode-it) + (interactive) + (save-restriction + (current-buffer) + (narrow-to-region (point)(point)) + (insert + (save-excursion + (set-buffer mail-reply-buffer) + (if decode-it + (decode-mime-charset-region (point-min) (point-max) + wl-mime-charset)) + (buffer-substring-no-properties + (point-min) (point-max)))) + (goto-char (point-max)) + (push-mark) + (goto-char (point-min))) + (let ((beg (point))) + (cond (mail-citation-hook (run-hooks 'mail-citation-hook)) + (mail-yank-hooks (run-hooks 'mail-yank-hooks)) + (t (and wl-draft-cite-func + (funcall wl-draft-cite-func)))) ; default cite + (run-hooks 'wl-draft-cited-hook) + (if wl-highlight-body-too + (wl-highlight-body-region beg (point-max))))) + +(defun wl-draft-confirm () + (interactive) + (y-or-n-p (format "Send current draft as %s? " + (if (wl-message-mail-p) + (if (wl-message-news-p) "Mail and News" "Mail") + "News")))) + +(defun wl-message-news-p () + (std11-field-body "Newsgroups")) + +(defun wl-message-field-exists-p (field) + (let ((value (std11-field-body field))) + (and value + (not (string= value ""))))) + +(defun wl-message-mail-p () + (or (wl-message-field-exists-p "To") + (wl-message-field-exists-p "Cc") + (wl-message-field-exists-p "Bcc") + ;;(wl-message-field-exists-p "Fcc") ; This may be needed.. + )) + +(defun wl-draft-open-file (&optional file) + (interactive) ; "*fFile to edit: ") + (wl-draft-edit-string (elmo-get-file-string + (or file + (read-file-name "File to edit: " + (or wl-tmp-dir "~/")))))) + +(defun wl-draft-edit-string (string) + (let ((cur-buf (current-buffer)) + (tmp-buf (get-buffer-create " *wl-draft-edit-string*")) + to subject in-reply-to cc references newsgroups mail-followup-to + content-type + body-beg buffer-read-only + ) + (set-buffer tmp-buf) + (erase-buffer) + (insert string) + (setq to (std11-field-body "To")) + (setq to (and to + (eword-decode-string + (decode-mime-charset-string + to + wl-mime-charset)))) + (setq subject (std11-field-body "Subject")) + (setq subject (and subject + (eword-decode-string + (decode-mime-charset-string + subject + wl-mime-charset)))) + (setq in-reply-to (std11-field-body "In-Reply-To")) + (setq cc (std11-field-body "Cc")) + (setq cc (and cc + (eword-decode-string + (decode-mime-charset-string + cc + wl-mime-charset)))) + (setq references (std11-field-body "References")) + (setq newsgroups (std11-field-body "Newsgroups")) + (setq mail-followup-to (std11-field-body "Mail-Followup-To")) + (setq content-type (std11-field-body "Content-Type")) + (goto-char (point-min)) + (or (re-search-forward "\n\n" nil t) + (search-forward (concat mail-header-separator "\n") nil t)) + (unwind-protect + (set-buffer + (wl-draft to subject in-reply-to cc references newsgroups + mail-followup-to + content-type + (buffer-substring (point) (point-max)) + 'edit-again + )) + (and to (mail-position-on-field "To")) + (delete-other-windows) + (kill-buffer tmp-buf))) + (setq buffer-read-only nil) ;;?? + (run-hooks 'wl-mail-setup-hook)) + +(defun wl-draft-insert-current-message (dummy) + (interactive) + (let ((mail-reply-buffer (wl-message-get-original-buffer)) + mail-citation-hook mail-yank-hooks + wl-draft-cite-func) + (if (eq 0 + (save-excursion + (set-buffer mail-reply-buffer) + (buffer-size))) + (error "No current message") + (wl-draft-yank-from-mail-reply-buffer nil)))) + +(defun wl-draft-insert-get-message (dummy) + (let ((fld (completing-read + "Folder name: " + (if (memq 'read-folder wl-use-folder-petname) + (wl-folder-get-entity-with-petname) + wl-folder-entity-hashtb) + nil nil wl-default-spec + 'wl-read-folder-hist)) + (number (call-interactively + (function (lambda (num) + (interactive "nNumber: ") + num)))) + (mail-reply-buffer (get-buffer-create "*wl-draft-insert-get-message*")) + mail-citation-hook mail-yank-hooks + wl-draft-cite-func) + (unwind-protect + (progn + (save-excursion + (elmo-read-msg-with-cache fld number mail-reply-buffer nil)) + (wl-draft-yank-from-mail-reply-buffer nil)) + (kill-buffer mail-reply-buffer)))) + +;; +;; default body citation func +;; +(defun wl-default-draft-cite () + (let ((mail-yank-ignored-headers "[^:]+:") + (mail-yank-prefix "> ") + (summary-buf wl-current-summary-buffer) + (message-buf (get-buffer (wl-current-message-buffer))) + from date cite-title num entity) + (if (and summary-buf + (buffer-live-p summary-buf) + message-buf + (buffer-live-p message-buf)) + (progn + (save-excursion + (set-buffer summary-buf) + (setq num + (save-excursion + (set-buffer message-buf) + wl-message-buffer-cur-number)) + (setq entity (assoc (cdr (assq num + (elmo-msgdb-get-number-alist + wl-summary-buffer-msgdb))) + (elmo-msgdb-get-overview + wl-summary-buffer-msgdb))) + (setq from (elmo-msgdb-overview-entity-get-from entity)) + (setq date (elmo-msgdb-overview-entity-get-date entity))) + (setq cite-title (format "At %s,\n%s wrote:" + (or date "some time ago") + (wl-summary-from-func-internal + (or from "you")))))) + (and cite-title + (insert cite-title "\n")) + (mail-indent-citation))) + +(defvar wl-draft-buffer nil "Draft buffer to yank content") +(defun wl-draft-yank-to-draft-buffer (buffer) + "Yank BUFFER content to `wl-draft-buffer'." + (set-buffer wl-draft-buffer) + (let ((mail-reply-buffer buffer)) + (wl-draft-yank-from-mail-reply-buffer nil) + (kill-buffer buffer))) + +(defun wl-draft-yank-original (&optional arg) + "Yank original message." + (interactive "P") + (if arg + (let (buf mail-reply-buffer) + (elmo-set-work-buf + (yank) + (setq buf (current-buffer))) + (setq mail-reply-buffer buf) + (wl-draft-yank-from-mail-reply-buffer nil)) + (wl-draft-yank-current-message-entity))) + +(defun wl-draft-hide (editing-buffer) + "Hide the editing draft buffer if possible." + (interactive) + (when (and editing-buffer + (buffer-live-p editing-buffer)) + (set-buffer editing-buffer) + (let ((sum-buf wl-draft-buffer-cur-summary-buffer) + fld-buf sum-win fld-win) + (if (and wl-draft-use-frame + (> (length (visible-frame-list)) 1)) + ;; hide draft frame + (delete-frame) + ;; hide draft window + (or (one-window-p) + (delete-window))) + ;; stay folder window if required + (when wl-stay-folder-window + (if (setq fld-buf (get-buffer wl-folder-buffer-name)) + (if (setq fld-win (get-buffer-window fld-buf)) + (select-window fld-win) + (if wl-draft-resume-folder-window ;; resume folder window + (switch-to-buffer fld-buf))))) + (if (buffer-live-p sum-buf) + (if (setq sum-win (get-buffer-window sum-buf t)) + ;; if Summary is on the frame, select it. + (select-window sum-win) + ;; if summary is not on the frame, switch to it. + (if (and wl-stay-folder-window + (or wl-draft-resume-folder-window fld-win)) + (wl-folder-select-buffer sum-buf) + (switch-to-buffer sum-buf))))))) + +(defun wl-draft-delete (editing-buffer) + "kill the editing draft buffer and delete the file corresponds to it." + (save-excursion + (when editing-buffer + (set-buffer editing-buffer) + (if wl-draft-buffer-file-name + (progn + (if (file-exists-p wl-draft-buffer-file-name) + (delete-file wl-draft-buffer-file-name)) + (let ((msg (and wl-draft-buffer-file-name + (string-match "[0-9]+$" wl-draft-buffer-file-name) + (string-to-int + (elmo-match-string 0 wl-draft-buffer-file-name))))) + (wl-draft-config-info-operation msg 'delete)))) + (set-buffer-modified-p nil) ; force kill + (kill-buffer editing-buffer)))) + +(defun wl-draft-kill (&optional force-kill) + "Kill current draft buffer and quit editing." + (interactive "P") + (save-excursion + (when (and (or (eq major-mode 'wl-draft-mode) + (eq major-mode 'mail-mode)) + (or force-kill + (y-or-n-p "Kill Current Draft?"))) + (let ((cur-buf (current-buffer))) + (wl-draft-hide cur-buf) + (wl-draft-delete cur-buf))) + (message ""))) + +(defun wl-draft-fcc () + "Add a new FCC field, with file name completion." + (interactive) + (or (mail-position-on-field "fcc" t) ;Put new field after exiting FCC. + (mail-position-on-field "to")) + (insert "\nFCC: ")) + +;; function for wl-sent-message-via + +(defmacro wl-draft-sent-message-p (type) + (` (eq (nth 1 (assq (, type) wl-sent-message-via)) 'sent))) + +(defmacro wl-draft-set-sent-message (type result &optional server-port) + (` (let ((element (assq (, type) wl-sent-message-via))) + (if element + (unless (eq (nth 1 element) (, result)) + (setcdr element (list (, result) (, server-port))) + (setq wl-sent-message-modified t)) + (push (list (, type) (, result) (, server-port)) wl-sent-message-via) + (setq wl-sent-message-modified t))))) + +(defun wl-draft-sent-message-results () + (let ((results wl-sent-message-via) + unplugged-via sent-via) + (while results + (cond ((eq (nth 1 (car results)) 'unplugged) + (push (caar results) unplugged-via)) + ((eq (nth 1 (car results)) 'sent) + (push (caar results) sent-via))) + (setq results (cdr results))) + (list unplugged-via sent-via))) + +(defun wl-draft-write-sendlog (status proto server to id) + "Write send log file, if `wl-draft-sendlog' is non-nil." + (when wl-draft-sendlog + (save-excursion + (let* ((tmp-buf (get-buffer-create " *wl-draft-sendlog*")) + (filename (expand-file-name wl-draft-sendlog-filename + elmo-msgdb-dir)) + (filesize (nth 7 (file-attributes filename))) + (server (if server (concat " server=" server) "")) + (to (if to (cond + ((memq proto '(fcc queue)) + (format " folder=\"%s\"" to)) + ((eq proto 'nntp) + (format " ng=<%s>" to)) + (t + (concat " to=" + (mapconcat + 'identity + (mapcar '(lambda(x) (format "<%s>" x)) to) + ",")))) + "")) + (id (if id (concat " id=" id) "")) + (time (wl-sendlog-time))) + (set-buffer tmp-buf) + (erase-buffer) + (insert (format "%s proto=%s stat=%s%s%s%s\n" + time proto status server to id)) + (if (and wl-draft-sendlog-max-size filesize + (> filesize wl-draft-sendlog-max-size)) + (rename-file filename (concat filename ".old") t)) + (if (file-writable-p filename) + (write-region (point-min) (point-max) + filename t 'no-msg) + (message (format "%s is not writable." filename))) + (kill-buffer tmp-buf))))) + +(defun wl-draft-get-header-delimiter (&optional delete) + ;; If DELETE is non-nil, replace the header delimiter with a blank line + (let (delimline) + (goto-char (point-min)) + (when (re-search-forward + (concat "^" (regexp-quote mail-header-separator) "$\\|^$") nil t) + (replace-match "") + (if delete + (forward-char -1)) + (setq delimline (point-marker))) + delimline)) + +(defun wl-draft-send-mail-with-qmail () + "Pass the prepared message buffer to qmail-inject. +Refer to the documentation for the variable `send-mail-function' +to find out how to use this." + (if (and wl-draft-qmail-send-plugged + (not (elmo-plugged-p))) + (wl-draft-set-sent-message 'mail 'unplugged) + ;; send the message + (let ((id (std11-field-body "Message-ID")) + (to (std11-field-body "To"))) + (case + (as-binary-process + (apply + 'call-process-region 1 (point-max) wl-qmail-inject-program + nil nil nil + wl-qmail-inject-args)) + ;; qmail-inject doesn't say anything on it's stdout/stderr, + ;; we have to look at the retval instead + (0 (progn + (wl-draft-set-sent-message 'mail 'sent) + (wl-draft-write-sendlog 'ok 'qmail nil (list to) id))) + (1 (error "qmail-inject reported permanent failure")) + (111 (error "qmail-inject reported transient failure")) + ;; should never happen + (t (error "qmail-inject reported unknown failure")))))) + +;; +;; from Semi-gnus +;; +(defun wl-draft-send-mail-with-smtp () + "Send the prepared message buffer with SMTP." + (require 'smtp) + (let* ((errbuf (if mail-interactive + (generate-new-buffer " smtp errors") + 0)) + (case-fold-search t) + (default-case-fold-search t) + (sender (or wl-envelope-from + (wl-address-header-extract-address wl-from))) + (delimline (save-excursion + (goto-char (point-min)) + (re-search-forward + (concat "^" (regexp-quote mail-header-separator) + "$\\|^$") nil t) + (point-marker))) + (recipients (smtp-deduce-address-list (current-buffer) + (point-min) delimline)) + (smtp-server (or wl-smtp-posting-server + (if (functionp smtp-server) + (funcall smtp-server sender + recipients) + (or smtp-server "localhost")))) + (smtp-service (or wl-smtp-posting-port smtp-service)) + (smtp-local-domain (or smtp-local-domain wl-local-domain)) + (id (std11-field-body "message-id"))) + (if (not (elmo-plugged-p smtp-server smtp-service)) + (wl-draft-set-sent-message 'mail 'unplugged + (cons smtp-server smtp-service)) + (unwind-protect + (save-excursion + ;; Insert an extra newline if we need it to work around + ;; Sun's bug that swallows newlines. + (goto-char (1+ delimline)) + (if (eval mail-mailer-swallows-blank-line) + (newline)) + ;;(run-hooks 'wl-mail-send-pre-hook) + (if mail-interactive + (save-excursion + (set-buffer errbuf) + (erase-buffer))) + (wl-draft-delete-field "bcc" delimline) + (wl-draft-delete-field "resent-bcc" delimline) + (let (process-connection-type) + (as-binary-process + (when recipients + (wl-smtp-extension-bind + (let ((err (smtp-via-smtp sender recipients + (current-buffer)))) + (when (not (eq err t)) + (wl-draft-write-sendlog 'failed 'smtp smtp-server + recipients id) + (error "Sending failed; SMTP protocol error:%s" err)))) + (wl-draft-set-sent-message 'mail 'sent) + (wl-draft-write-sendlog + 'ok 'smtp smtp-server recipients id))))) + (if (bufferp errbuf) + (kill-buffer errbuf)))))) + +(defun wl-draft-send-mail-with-pop-before-smtp () + "Send the prepared message buffer with POP-before-SMTP." + (require 'elmo-pop3) + (condition-case () + (elmo-pop3-get-connection + (list 'pop3 + (or wl-pop-before-smtp-user + elmo-default-pop3-user) + (or wl-pop-before-smtp-authenticate-type + elmo-default-pop3-authenticate-type) + (or wl-pop-before-smtp-server + elmo-default-pop3-server) + (or wl-pop-before-smtp-port + elmo-default-pop3-port) + (or wl-pop-before-smtp-ssl + elmo-default-pop3-ssl))) + (error)) + (wl-draft-send-mail-with-smtp)) + +(defun wl-draft-insert-required-fields (&optional force-msgid) + ;; Insert Message-Id field... + (goto-char (point-min)) + (when (and (or force-msgid + wl-insert-message-id) + (not (re-search-forward "^Message-ID[ \t]*:" nil t))) + (insert (concat "Message-ID: " + (wl-draft-make-message-id-string) + "\n"))) + ;; Insert date field. + (goto-char (point-min)) + (or (re-search-forward "^Date[ \t]*:" nil t) + (wl-draft-insert-date-field)) + ;; Insert from field. + (goto-char (point-min)) + (or (re-search-forward "^From[ \t]*:" nil t) + (wl-draft-insert-from-field))) + +(defun wl-draft-normal-send-func (editing-buffer kill-when-done) + "Send the message in the current buffer. " + (save-restriction + (std11-narrow-to-header mail-header-separator) + (wl-draft-insert-required-fields) + ;; Delete null fields. + (goto-char (point-min)) + (while (re-search-forward "^[^ \t\n:]+:[ \t]*\n" nil t) + (replace-match "")) + ;; ignore any blank lines in the header + (while (re-search-forward "\n\n\n*" nil t) + (replace-match "\n"))) + (run-hooks 'wl-mail-send-pre-hook) ;; X-PGP-Sig, Cancel-Lock + (wl-draft-dispatch-message) + (when kill-when-done + ;; hide editing-buffer. + (wl-draft-hide editing-buffer) + ;; delete editing-buffer and its file. + (wl-draft-delete editing-buffer))) + +(defun wl-draft-dispatch-message (&optional mes-string) + "Send the message in the current buffer. Not modified the header fields." + (let (delimline) + (if (and wl-draft-verbose-send mes-string) + (message mes-string)) + ;; get fcc folders. + (setq delimline (wl-draft-get-header-delimiter t)) + (unless wl-draft-fcc-list + (setq wl-draft-fcc-list (wl-draft-get-fcc-list delimline))) + ;; + (setq wl-sent-message-modified nil) + (unwind-protect + (progn + (if (and (wl-message-mail-p) + (not (wl-draft-sent-message-p 'mail))) + (funcall wl-draft-send-mail-func)) + (if (and (wl-message-news-p) + (not (wl-draft-sent-message-p 'news)) + (not (wl-message-field-exists-p "Resent-to"))) + (funcall wl-draft-send-news-func))) + ;; + (let* ((status (wl-draft-sent-message-results)) + (unplugged-via (car status)) + (sent-via (nth 1 status))) + ;; If one sent, process fcc folder. + (when (and sent-via wl-draft-fcc-list) + (wl-draft-do-fcc (wl-draft-get-header-delimiter) wl-draft-fcc-list) + (setq wl-draft-fcc-list nil)) + ;; If one unplugged, append queue. + (when (and unplugged-via + wl-sent-message-modified) + (if wl-draft-enable-queuing + (wl-draft-queue-append wl-sent-message-via) + (error "Unplugged"))) + (when wl-draft-verbose-send + (if (and unplugged-via sent-via);; combined message + (progn + (setq wl-draft-verbose-msg + (format "Sending%s and Queuing%s..." + sent-via unplugged-via)) + (message (concat wl-draft-verbose-msg "done"))) + (if mes-string + (message (concat mes-string + (if sent-via "done." "failed."))))))))) + (not wl-sent-message-modified)) ;; return value + +(defun wl-draft-raw-send (&optional kill-when-done force-pre-hook mes-string) + "Force send current buffer as raw message." + (interactive) + (save-excursion + (let (wl-interactive-send +; wl-draft-verbose-send + (wl-mail-send-pre-hook (and force-pre-hook wl-mail-send-pre-hook)) +; wl-news-send-pre-hook + mail-send-hook + mail-send-actions) + (wl-draft-send kill-when-done mes-string)))) + +(defun wl-draft-clone-local-variables () + (let ((locals (buffer-local-variables)) + result) + (mapcar + (function + (lambda (local) + (when (and (consp local) + (car local) + (string-match + wl-draft-clone-local-variable-regexp + (symbol-name (car local)))) + (setq result (wl-append result (list (car local))))))) + locals) + result)) + +(defun wl-draft-send (&optional kill-when-done mes-string) + "Send current draft message. +If optional argument is non-nil, current draft buffer is killed" + (interactive) + (wl-draft-config-exec) + (run-hooks 'wl-draft-send-hook) + (when (or (not wl-interactive-send) + (y-or-n-p "Send current draft. OK?")) + (let ((send-mail-function 'wl-draft-raw-send) + (editing-buffer (current-buffer)) + (sending-buffer (wl-draft-generate-clone-buffer + " *wl-draft-sending-buffer*" + (append wl-draft-config-variables + (wl-draft-clone-local-variables)))) + (wl-draft-verbose-msg nil) + err) + (unwind-protect + (save-excursion (set-buffer sending-buffer) + (if (and (not (wl-message-mail-p)) + (not (wl-message-news-p))) + (error "No recipient is specified")) + (expand-abbrev) ; for mail-abbrevs + (run-hooks 'mail-send-hook) ; translate buffer + (if wl-draft-verbose-send + (message (or mes-string "Sending..."))) + (funcall wl-draft-send-func editing-buffer kill-when-done) + ;; Now perform actions on successful sending. + (while mail-send-actions + (condition-case () + (apply (car (car mail-send-actions)) + (cdr (car mail-send-actions))) + (error)) + (setq mail-send-actions (cdr mail-send-actions))) + (if (or (eq major-mode 'wl-draft-mode) + (eq major-mode 'mail-mode)) + (local-set-key "\C-c\C-s" 'wl-draft-send)) ; override + (if wl-draft-verbose-send + (message (concat (or wl-draft-verbose-msg + mes-string "Sending...") + "done.")))) + ;; kill sending buffer, anyway. + (and (buffer-live-p sending-buffer) + (kill-buffer sending-buffer)))))) + +(defun wl-draft-save () + "Save current draft." + (interactive) + (save-buffer) + (wl-draft-config-info-operation + (and (string-match "[0-9]+$" wl-draft-buffer-file-name) + (string-to-int + (elmo-match-string 0 wl-draft-buffer-file-name))) + 'save)) + +(defun wl-draft-mimic-kill-buffer () + "Kill the current (draft) buffer with query." + (interactive) + (let ((bufname (read-buffer (format "Kill buffer: (default %s) " + (buffer-name)))) + wl-draft-use-frame) + (if (or (not bufname) + (string-equal bufname "") + (string-equal bufname (buffer-name))) + (wl-draft-save-and-exit) + (kill-buffer bufname)))) + +(defun wl-draft-save-and-exit () + "Save current draft and exit current draft mode." + (interactive) + (wl-draft-save) + (let ((editing-buffer (current-buffer))) + (wl-draft-hide editing-buffer) + (kill-buffer editing-buffer))) + +(defun wl-draft-send-and-exit () + "Send current draft message and kill it." + (interactive) + (wl-draft-send t)) + +(defun wl-draft-send-from-toolbar () + (interactive) + (let ((wl-interactive-send t)) + (wl-draft-send-and-exit))) + +(defun wl-draft-delete-field (field &optional delimline) + (wl-draft-delete-fields (regexp-quote field) delimline)) + +(defun wl-draft-delete-fields (regexp &optional delimline) + (save-restriction + (unless delimline + (if (search-forward "\n\n" nil t) + (setq delimline (point)) + (setq delimline (point-max)))) + (narrow-to-region (point-min) delimline) + (goto-char (point-min)) + (let ((regexp (concat "^" regexp ":")) + (case-fold-search t) + last) + (while (not (eobp)) + (if (looking-at regexp) + (progn + (delete-region + (point) + (progn + (forward-line 1) + (if (re-search-forward "^[^ \t]" nil t) + (goto-char (match-beginning 0)) + (point-max))))) + (forward-line 1) + (if (re-search-forward "^[^ \t]" nil t) + (goto-char (match-beginning 0)) + (point-max))))))) + +(defun wl-draft-get-fcc-list (header-end) + (let (fcc-list + (case-fold-search t)) + (or (markerp header-end) (error "header-end must be a marker")) + (save-excursion + (goto-char (point-min)) + (while (re-search-forward "^FCC:[ \t]*" header-end t) + (setq fcc-list + (cons (buffer-substring-no-properties + (point) + (progn + (end-of-line) + (skip-chars-backward " \t") + (point))) + fcc-list)) + (save-match-data + (wl-folder-confirm-existence (eword-decode-string (car fcc-list)))) + (delete-region (match-beginning 0) + (progn (forward-line 1) (point))))) + fcc-list)) + +(defun wl-draft-do-fcc (header-end &optional fcc-list) + (let ((send-mail-buffer (current-buffer)) + (tembuf (generate-new-buffer " fcc output")) + (case-fold-search t) + beg end) + (or (markerp header-end) (error "header-end must be a marker")) + (save-excursion + (unless fcc-list + (setq fcc-list (wl-draft-get-fcc-list header-end))) + (set-buffer tembuf) + (erase-buffer) + ;; insert just the headers to avoid moving the gap more than + ;; necessary (the message body could be arbitrarily huge.) + (insert-buffer-substring send-mail-buffer 1 header-end) + (wl-draft-insert-required-fields t) + (goto-char (point-max)) + (insert-buffer-substring send-mail-buffer header-end) + (let ((id (std11-field-body "Message-ID")) + (elmo-enable-disconnected-operation t) + cache-saved) + (while fcc-list + (unless (or cache-saved + (elmo-folder-plugged-p (car fcc-list))) + (elmo-cache-save id nil nil nil) ;; for disconnected operation + (setq cache-saved t)) + (if (elmo-append-msg (eword-decode-string (car fcc-list)) + (buffer-substring + (point-min) (point-max)) + id) + (wl-draft-write-sendlog 'ok 'fcc nil (car fcc-list) id) + (wl-draft-write-sendlog 'failed 'fcc nil (car fcc-list) id)) + (setq fcc-list (cdr fcc-list))))) + (kill-buffer tembuf))) + +(defun wl-draft-on-field-p () + (if (< (point) + (save-excursion + (goto-char (point-min)) + (search-forward (concat "\n" mail-header-separator "\n") nil 0) + (point))) + (if (bolp) + (if (bobp) + t + (save-excursion + (forward-line -1) + (if (looking-at ".*,[ \t]?$") nil t))) + (let ((pos (point))) + (save-excursion + (beginning-of-line) + (if (looking-at "^[ \t]") + nil + (if (re-search-forward ":" pos t) nil t))))))) + +(defun wl-draft-random-alphabet () + (let ((alphabet '(?A ?B ?C ?D ?E ?F ?G ?H ?I ?J ?K ?L ?M ?N ?O ?P ?Q ?R ?S ?T ?U ?V ?W ?X ?Y ?Z))) + (nth (abs (% (random) 26)) alphabet))) + +;;;###autoload +(defun wl-draft (&optional to subject in-reply-to cc references newsgroups + mail-followup-to + content-type + body edit-again summary-buf) + "Write and send mail/news message with Wanderlust." + (interactive) + (unless (featurep 'wl) + (require 'wl)) + (unless wl-init + (wl-load-profile)) + (wl-init) ;; returns immediately if already initialized. + (if (interactive-p) + (setq summary-buf (wl-summary-get-buffer wl-summary-buffer-folder-name))) + (let ((draft-folder-spec (elmo-folder-get-spec wl-draft-folder)) + buf-name file-name num wl-demo change-major-mode-hook) + (if (not (eq (car draft-folder-spec) 'localdir)) + (error "%s folder cannot be used for draft folder" wl-draft-folder)) + (setq num (elmo-max-of-list (or (elmo-list-folder wl-draft-folder) '(0)))) + (setq num (+ 1 num)) + ;; To get unused buffer name. + (while (get-buffer (concat wl-draft-folder "/" (int-to-string num))) + (setq num (+ 1 num))) + (setq buf-name (find-file-noselect + (setq file-name + (elmo-get-msg-filename wl-draft-folder + num)))) + (if wl-draft-use-frame + (switch-to-buffer-other-frame buf-name) + (switch-to-buffer buf-name)) + (set-buffer buf-name) + (if (not (string-match (regexp-quote wl-draft-folder) + (buffer-name))) + (rename-buffer (concat wl-draft-folder "/" (int-to-string num)))) + (if (or (eq wl-draft-reply-buffer-style 'full) + (eq this-command 'wl-draft) + (eq this-command 'wl-summary-write) + (eq this-command 'wl-summary-write-current-newsgroup)) + (delete-other-windows)) + (auto-save-mode -1) + (wl-draft-mode) + (setq wl-sent-message-via nil) + (if (stringp wl-from) + (insert "From: " wl-from "\n")) + (and (or (interactive-p) + (eq this-command 'wl-summary-write) + to) + (insert "To: " (or to "") "\n")) + (and cc (insert "Cc: " (or cc "") "\n")) + (insert "Subject: " (or subject "") "\n") + (and newsgroups (insert "Newsgroups: " newsgroups "\n")) + (and mail-followup-to (insert "Mail-Followup-To: " mail-followup-to "\n")) + (and wl-insert-mail-reply-to + (insert "Mail-Reply-To: " + (wl-address-header-extract-address + wl-from) "\n")) + (and in-reply-to (insert "In-Reply-To: " in-reply-to "\n")) + (and references (insert "References: " references "\n")) + (insert (funcall wl-generate-mailer-string-func) + "\n") + (setq wl-draft-buffer-file-name file-name) + (if mail-default-reply-to + (insert "Reply-To: " mail-default-reply-to "\n")) + (if (or wl-bcc mail-self-blind) + (insert "Bcc: " (or wl-bcc (user-login-name)) "\n")) + (if wl-fcc + (insert "FCC: " wl-fcc "\n")) + (if wl-organization + (insert "Organization: " wl-organization "\n")) + (and wl-auto-insert-x-face + (file-exists-p wl-x-face-file) + (wl-draft-insert-x-face-field-here)) + (if mail-default-headers + (insert mail-default-headers)) + (if (not (= (preceding-char) ?\n)) + (insert ?\n)) + (if edit-again + (let (start) + (setq start (point)) + (when content-type + (insert "Content-type: " content-type "\n\n")) + (and body (insert body)) + (save-restriction + (narrow-to-region start (point)) + (and edit-again + (wl-draft-decode-message-in-buffer)) + (widen) + (goto-char start) + (put-text-property (point) + (progn + (insert mail-header-separator "\n") + (1- (point))) + 'category 'mail-header-separator))) + (put-text-property (point) + (progn + (insert mail-header-separator "\n") + (1- (point))) + 'category 'mail-header-separator) + (and body (insert body))) + (if wl-on-nemacs + (push-mark (point) t) + (push-mark (point) t t)) + (as-binary-output-file + (write-region (point-min)(point-max) wl-draft-buffer-file-name + nil t)) + (wl-draft-editor-mode) + (wl-draft-overload-functions) + (let (wl-highlight-x-face-func) + (wl-highlight-headers)) + (goto-char (point-min)) + (if (interactive-p) + (run-hooks 'wl-mail-setup-hook)) + (wl-user-agent-compose-internal) ;; user-agent + (cond ((eq this-command 'wl-summary-write-current-newsgroup) + (mail-position-on-field "Subject")) + ((and (interactive-p) (null to)) + (mail-position-on-field "To")) + (t + (goto-char (point-max)))) + (setq wl-draft-config-exec-flag t) + (setq wl-draft-buffer-cur-summary-buffer (or summary-buf + (get-buffer + wl-summary-buffer-name))) + buf-name)) + +(defun wl-draft-elmo-nntp-send () + (let ((elmo-nntp-post-pre-hook wl-news-send-pre-hook) + (elmo-default-nntp-user + (or wl-nntp-posting-user elmo-default-nntp-user)) + (elmo-default-nntp-server + (or wl-nntp-posting-server elmo-default-nntp-server)) + (elmo-default-nntp-port + (or wl-nntp-posting-port elmo-default-nntp-port)) + (elmo-default-nntp-ssl + (or wl-nntp-posting-ssl elmo-default-nntp-ssl))) + (if (not (elmo-plugged-p elmo-default-nntp-server elmo-default-nntp-port)) + (wl-draft-set-sent-message 'news 'unplugged + (cons elmo-default-nntp-server + elmo-default-nntp-port)) + (elmo-nntp-post elmo-default-nntp-server (current-buffer)) + (wl-draft-set-sent-message 'news 'sent) + (wl-draft-write-sendlog 'ok 'nntp elmo-default-nntp-server + (std11-field-body "Newsgroups") + (std11-field-body "Message-ID"))))) + +(defun wl-draft-generate-clone-buffer (name &optional local-variables) + "generate clone of current buffer named NAME." + (let ((editing-buffer (current-buffer))) + (save-excursion + (set-buffer (generate-new-buffer name)) + (erase-buffer) + (wl-draft-mode) + (wl-draft-editor-mode) + (insert-buffer editing-buffer) + (message "") + (when local-variables + (mapcar + (function + (lambda (var) + (make-local-variable var) + (set var (save-excursion + (set-buffer editing-buffer) + (symbol-value var))))) + local-variables)) + (current-buffer)))) + +(defun wl-draft-reedit (number) + (let ((draft-folder-spec (elmo-folder-get-spec wl-draft-folder)) + (wl-draft-reedit t) + buf-name file-name change-major-mode-hook) + (setq file-name (expand-file-name + (int-to-string number) + (expand-file-name + (nth 1 draft-folder-spec) + elmo-localdir-folder-path))) + (unless (file-exists-p file-name) + (error "File %s does not exist" file-name)) + (setq buf-name (find-file-noselect file-name)) + (if wl-draft-use-frame + (switch-to-buffer-other-frame buf-name) + (switch-to-buffer buf-name)) + (set-buffer buf-name) + (if (not (string-match (regexp-quote wl-draft-folder) + (buffer-name))) + (rename-buffer (concat wl-draft-folder "/" (buffer-name)))) + (auto-save-mode -1) + (wl-draft-mode) + (setq wl-sent-message-via nil) + (setq wl-draft-buffer-file-name file-name) + (wl-draft-config-info-operation number 'load) + (goto-char (point-min)) + (or (re-search-forward "\n\n" nil t) + (search-forward (concat mail-header-separator "\n") nil t)) + (if wl-on-nemacs + (push-mark (point) t) + (push-mark (point) t t)) + (write-region (point-min)(point-max) wl-draft-buffer-file-name + nil t) + (wl-draft-overload-functions) + (wl-draft-editor-mode) + (let (wl-highlight-x-face-func) + (wl-highlight-headers)) + (run-hooks 'wl-draft-reedit-hook) + (goto-char (point-max)) + buf-name + )) + +(defmacro wl-draft-body-goto-top () + (` (progn + (goto-char (point-min)) + (if (re-search-forward mail-header-separator nil t) + (forward-char 1) + (goto-char (point-max)))))) + +(defmacro wl-draft-body-goto-bottom () + (` (goto-char (point-max)))) + +(defmacro wl-draft-config-body-goto-header () + (` (progn + (goto-char (point-min)) + (if (re-search-forward mail-header-separator nil t) + (beginning-of-line) + (goto-char (point-max)))))) + +(defun wl-draft-config-sub-body (content) + (wl-draft-body-goto-top) + (delete-region (point) (point-max)) + (if content (insert (eval content)))) + +(defun wl-draft-config-sub-top (content) + (wl-draft-body-goto-top) + (if content (insert (eval content)))) + +(defun wl-draft-config-sub-bottom (content) + (wl-draft-body-goto-bottom) + (if content (insert (eval content)))) + +(defun wl-draft-config-sub-header (content) + (wl-draft-config-body-goto-header) + (if content (insert (concat (eval content) "\n")))) + +(defsubst wl-draft-config-sub-file (content) + (let ((coding-system-for-read wl-cs-autoconv) + (file (expand-file-name (eval content)))) + (if (file-exists-p file) + (insert-file-contents file) + (error "%s: no exists file" file)))) + +(defun wl-draft-config-sub-body-file (content) + (wl-draft-body-goto-top) + (delete-region (point) (point-max)) + (wl-draft-config-sub-file content)) + +(defun wl-draft-config-sub-top-file (content) + (wl-draft-body-goto-top) + (wl-draft-config-sub-file content)) + +(defun wl-draft-config-sub-bottom-file (content) + (wl-draft-body-goto-bottom) + (wl-draft-config-sub-file content)) + +(defun wl-draft-config-sub-header-file (content) + (wl-draft-config-body-goto-header) + (wl-draft-config-sub-file content)) + +(defun wl-draft-config-sub-template (content) + (setq wl-draft-config-variables + (wl-template-insert (eval content)))) + +(defun wl-draft-config-sub-x-face (content) + (if (and (string-match "\\.xbm\\(\\.gz\\)?$" content) + (fboundp 'x-face-insert)) ; x-face.el is installed. + (x-face-insert content) + (wl-draft-replace-field "X-Face" (elmo-get-file-string content t) t))) + +(defsubst wl-draft-config-sub-func (field content) + (let (func) + (if (setq func (assq field wl-draft-config-sub-func-alist)) + (let (wl-draft-config-variables) + (funcall (cdr func) content) + ;; for wl-draft-config-sub-template + (cons t wl-draft-config-variables))))) + +(defsubst wl-draft-config-exec-sub (clist) + (let (config local-variables) + (while clist + (setq config (car clist)) + (cond + ((consp config) + (let ((field (car config)) + (content (cdr config)) + ret-val) + (cond + ((stringp field) + (wl-draft-replace-field field (eval content) t)) + ((setq ret-val (wl-draft-config-sub-func field content)) + (if (cdr ret-val) ;; for wl-draft-config-sub-template + (wl-append local-variables (cdr ret-val)))) + ((boundp field) ;; variable + (make-local-variable field) + (set field (eval content)) + (wl-append local-variables (list field))) + (t + (error "%s: not variable" field))))) + ((or (functionp config) + (and (symbolp config) + (fboundp config))) + (funcall config)) + (t + (error "%s: not supported type" config))) + (setq clist (cdr clist))) + local-variables)) + +(defun wl-draft-prepared-config-exec (&optional config-alist reply-buf) + "Change headers in draft preparation time." + (interactive) + (unless wl-draft-reedit + (let ((config-alist + (or config-alist + (and (boundp 'wl-draft-prepared-config-alist) + wl-draft-prepared-config-alist) ;; For compatible. + wl-draft-config-alist))) + (if config-alist + (wl-draft-config-exec config-alist reply-buf))))) + +(defun wl-draft-config-exec (&optional config-alist reply-buf) + "Change headers in draft sending time." + (interactive) + (let ((case-fold-search t) + (alist (or config-alist wl-draft-config-alist)) + (reply-buf (or reply-buf (and (buffer-live-p wl-draft-reply-buffer) + wl-draft-reply-buffer))) + (local-variables wl-draft-config-variables) + key clist found) + (when (and (or (interactive-p) + wl-draft-config-exec-flag) + alist) + (save-excursion + (catch 'done + (while alist + (setq key (caar alist) + clist (cdar alist)) + (cond + ((eq key 'reply) + (when (and + reply-buf + (save-excursion + (set-buffer reply-buf) + (save-restriction + (std11-narrow-to-header) + (goto-char (point-min)) + (re-search-forward (car clist) nil t)))) + (wl-draft-config-exec-sub (cdr clist)) + (setq found t))) + ((stringp key) + (when (save-restriction + (std11-narrow-to-header mail-header-separator) + (goto-char (point-min)) + (re-search-forward key nil t)) + (wl-append local-variables + (wl-draft-config-exec-sub clist)) + (setq found t))) + ((eval key) + (wl-append local-variables + (wl-draft-config-exec-sub clist)) + (setq found t))) + (if (and found wl-draft-config-matchone) + (throw 'done t)) + (setq alist (cdr alist)))) + (if found + (setq wl-draft-config-exec-flag nil)) + (run-hooks 'wl-draft-config-exec-hook) + (put-text-property (point-min)(point-max) 'face nil) + (wl-highlight-message (point-min)(point-max) t) + (setq wl-draft-config-variables + (elmo-uniq-list local-variables)))))) + +(defun wl-draft-replace-field (field content &optional add) + (save-excursion + (save-restriction + (let ((case-fold-search t) + (inhibit-read-only t) ;; added by teranisi. + beg) + (std11-narrow-to-header mail-header-separator) + (goto-char (point-min)) + (if (re-search-forward (concat "^" (regexp-quote field) ":") nil t) + (if content + ;; replace field + (progn + (setq beg (point)) + (re-search-forward "^[^ \t]" nil 'move) + (beginning-of-line) + (skip-chars-backward "\n") + (delete-region beg (point)) + (insert " " content)) + ;; delete field + (save-excursion + (beginning-of-line) + (setq beg (point))) + (re-search-forward "^[^ \t]" nil 'move) + (beginning-of-line) + (delete-region beg (point))) + (when (and add content) + ;; add field + (goto-char (point-max)) + (insert (concat field ": " content "\n")))))))) + +(defun wl-draft-config-info-operation (msg operation) + (let* ((msgdb-dir (elmo-msgdb-expand-path wl-draft-folder)) + (filename + (expand-file-name + (format "%s-%d" wl-draft-config-save-filename msg) + msgdb-dir)) + element alist variable) + (cond + ((eq operation 'save) + (let ((variables (elmo-uniq-list wl-draft-config-variables))) + (while (setq variable (pop variables)) + (when (boundp variable) + (wl-append alist + (list (cons variable (eval variable)))))) + (elmo-object-save filename alist))) + ((eq operation 'load) + (setq alist (elmo-object-load filename)) + (while (setq element (pop alist)) + (set (make-local-variable (car element)) (cdr element)) + (wl-append wl-draft-config-variables (list (car element))))) + ((eq operation 'delete) + (if (file-exists-p filename) + (delete-file filename)))))) + +(defun wl-draft-queue-info-operation (msg operation + &optional add-sent-message-via) + (let* ((msgdb-dir (elmo-msgdb-expand-path wl-queue-folder)) + (filename + (expand-file-name + (format "%s-%d" wl-draft-queue-save-filename msg) + msgdb-dir)) + element alist variable) + (cond + ((eq operation 'save) + (let ((variables (elmo-uniq-list + (append wl-draft-queue-save-variables + wl-draft-config-variables + (list 'wl-draft-fcc-list))))) + (if add-sent-message-via + (push 'wl-sent-message-via variables)) + (while (setq variable (pop variables)) + (when (boundp variable) + (wl-append alist + (list (cons variable (eval variable)))))) + (elmo-object-save filename alist))) + ((eq operation 'load) + (setq alist (elmo-object-load filename)) + (while (setq element (pop alist)) + (set (make-local-variable (car element)) (cdr element)))) + ((eq operation 'get-sent-via) + (setq alist (elmo-object-load filename)) + (cdr (assq 'wl-sent-message-via alist))) + ((eq operation 'delete) + (if (file-exists-p filename) + (delete-file filename)))))) + +(defun wl-draft-queue-append (wl-sent-message-via) + (if wl-draft-verbose-send + (message "Queuing...")) + (let ((send-buffer (current-buffer)) + (message-id (std11-field-body "Message-ID"))) + (if (elmo-append-msg wl-queue-folder + (buffer-substring (point-min) (point-max)) + message-id) + (progn + (if message-id + (elmo-dop-lock-message message-id)) + (wl-draft-queue-info-operation + (car (elmo-max-of-folder wl-queue-folder)) + 'save wl-sent-message-via) + (wl-draft-write-sendlog 'ok 'queue nil wl-queue-folder message-id) + (when wl-draft-verbose-send + (setq wl-draft-verbose-msg "Queuing...") + (message "Queuing...done."))) + (wl-draft-write-sendlog 'failed 'queue nil wl-queue-folder message-id) + (error "Queuing failed")))) + +(defun wl-draft-queue-flush () + "Flush draft queue." + (interactive) + (let ((msgs2 (elmo-list-folder wl-queue-folder)) + (i 0) + (performed 0) + (wl-draft-queue-flushing t) + msgs failure len buffer msgid sent-via) + ;; get plugged send message + (while msgs2 + (setq sent-via (wl-draft-queue-info-operation (car msgs2) 'get-sent-via)) + (catch 'found + (while sent-via + (when (and (eq (nth 1 (car sent-via)) 'unplugged) + (elmo-plugged-p + (car (nth 2 (car sent-via))) + (cdr (nth 2 (car sent-via))))) + (wl-append msgs (list (car msgs2))) + (throw 'found t)) + (setq sent-via (cdr sent-via)))) + (setq msgs2 (cdr msgs2))) + (when (> (setq len (length msgs)) 0) + (if (elmo-y-or-n-p (format + "%d message(s) are in the sending queue. Send now?" + len) + (not elmo-dop-flush-confirm) t) + (progn + (save-excursion + (setq buffer (get-buffer-create " *wl-draft-queue-flush*")) + (set-buffer buffer) + (while msgs + ;; reset buffer local variables + (kill-all-local-variables) + (erase-buffer) + (setq i (+ 1 i) + failure nil) + (setq wl-sent-message-via nil) + (wl-draft-queue-info-operation (car msgs) 'load) + (elmo-read-msg-no-cache wl-queue-folder (car msgs) + (current-buffer)) + (condition-case err + (setq failure (funcall + wl-draft-queue-flush-send-func + (format "Sending (%d/%d)..." i len))) +;; (wl-draft-raw-send nil nil +;; (format "Sending (%d/%d)..." i len)) + (error + (elmo-display-error err t) + (setq failure t)) + (quit + (setq failure t))) + (unless failure + (elmo-delete-msgs wl-queue-folder (cons (car msgs) nil)) + (wl-draft-queue-info-operation (car msgs) 'delete) + (elmo-dop-unlock-message (std11-field-body "Message-ID")) + (setq performed (+ 1 performed))) + (setq msgs (cdr msgs))) + (kill-buffer buffer) + (message "%d message(s) are sent." performed))) + (message "%d message(s) are remained to be sent." len)) + len))) + +(defun wl-jump-to-draft-buffer (&optional arg) + "Jump to the draft if exists." + (interactive "P") + (if arg + (wl-jump-to-draft-folder) + (let ((bufs (buffer-list)) + (draft-regexp (concat + "^" (regexp-quote + (expand-file-name + (nth 1 (elmo-folder-get-spec wl-draft-folder)) + (expand-file-name + elmo-localdir-folder-path))))) + buf draft-bufs) + (while bufs + (if (and + (setq buf (buffer-file-name (car bufs))) + (string-match draft-regexp buf)) + (setq draft-bufs (cons (buffer-name (car bufs)) draft-bufs))) + (setq bufs (cdr bufs))) + (cond + ((null draft-bufs) + (message "No draft buffer exist.")) + (t + (setq draft-bufs + (sort draft-bufs (function (lambda (a b) (not (string< a b)))))) + (if (setq buf (cdr (member (buffer-name) draft-bufs))) + (setq buf (car buf)) + (setq buf (car draft-bufs))) + (switch-to-buffer buf)))))) + +(defun wl-jump-to-draft-folder () + (let ((msgs (reverse (elmo-list-folder wl-draft-folder))) + (mybuf (buffer-name)) + msg buf) + (if (not msgs) + (message "No draft message exist.") + (if (string-match (concat "^" wl-draft-folder "/") mybuf) + (setq msg (cadr (memq + (string-to-int (substring mybuf (match-end 0))) + msgs)))) + (or msg (setq msg (car msgs))) + (if (setq buf (get-buffer (format "%s/%d" wl-draft-folder msg))) + (switch-to-buffer buf) + (wl-draft-reedit msg))))) + +(defun wl-draft-highlight-and-recenter (&optional n) + (interactive "P") + (if wl-highlight-body-too + (let ((beg (point-min)) + (end (point-max))) + (put-text-property beg end 'face nil) + (wl-highlight-message beg end t))) + (recenter n)) + +;;;; user-agent support by Sen Nagata + +;; this appears to be necessarily global... +(defvar wl-user-agent-compose-p nil) +(defvar wl-user-agent-headers-and-body-alist nil) + +;; this should be a generic function for mail-mode -- i wish there was +;; something like it in sendmail.el +(defun wl-user-agent-insert-header (header-name header-value) + "Insert HEADER-NAME w/ value HEADER-VALUE into a message." + ;; it seems like overriding existing headers is acceptable -- should + ;; we provide an option? + + ;; plan was: unfold header (might be folded), remove existing value, insert + ;; new value + ;; wl doesn't seem to fold header lines yet anyway :-) + + (let ((kill-whole-line t) + end-of-line) + (mail-position-on-field (capitalize header-name)) + (setq end-of-line (point)) + (beginning-of-line) + (re-search-forward ":" end-of-line) + (insert (concat " " header-value "\n")) + (kill-line))) + +;; this should be a generic function for mail-mode -- i wish there was +;; something like it in sendmail.el +;; +;; ** haven't dealt w/ case where the body is already set ** +(defun wl-user-agent-insert-body (body-text) + "Insert a body of text, BODY-TEXT, into a message." + ;; code defensively... :-P + (goto-char (point-min)) + (search-forward mail-header-separator) + (forward-line 1) + (insert body-text)) + +;;;###autoload +(defun wl-user-agent-compose (&optional to subject other-headers continue + switch-function yank-action + send-actions) + "Support the `compose-mail' interface for wl. +Only support for TO, SUBJECT, and OTHER-HEADERS has been implemented. +Support for CONTINUE, YANK-ACTION, and SEND-ACTIONS has not +been implemented yet. Partial support for SWITCH-FUNCTION now supported." + + ;; protect these -- to and subject get bound at some point, so it looks + ;; to be necessary to protect the values used w/in + (let ((wl-user-agent-headers-and-body-alist other-headers) + (wl-draft-use-frame (eq switch-function 'switch-to-buffer-other-frame)) + (wl-draft-reply-buffer-style 'split)) + (when (eq switch-function 'switch-to-buffer-other-window) + (when (one-window-p t) + (if (window-minibuffer-p) (other-window 1)) + (split-window)) + (other-window 1)) + (if to + (if (wl-string-match-assoc "to" wl-user-agent-headers-and-body-alist + 'ignore-case) + (setcdr + (wl-string-match-assoc "to" wl-user-agent-headers-and-body-alist + 'ignore-case) + to) + (setq wl-user-agent-headers-and-body-alist + (cons (cons "to" to) + wl-user-agent-headers-and-body-alist)))) + (if subject + (if (wl-string-match-assoc "subject" + wl-user-agent-headers-and-body-alist + 'ignore-case) + (setcdr + (wl-string-match-assoc "subject" + wl-user-agent-headers-and-body-alist + 'ignore-case) + subject) + (setq wl-user-agent-headers-and-body-alist + (cons (cons "subject" subject) + wl-user-agent-headers-and-body-alist)))) + ;; i think this is what we want to use... + (unwind-protect + (progn + ;; tell the hook-function to do its stuff + (setq wl-user-agent-compose-p t) + ;; because to get the hooks working, wl-draft has to think it has + ;; been called interactively + (call-interactively 'wl-draft)) + (setq wl-user-agent-compose-p nil)))) + +(defun wl-user-agent-compose-internal () + "Manipulate headers and/or a body of a draft message." + ;; being called from wl-user-agent-compose? + (if wl-user-agent-compose-p + (progn + ;; insert headers + (let ((case-fold-search t)) + (mapcar + (lambda (x) + (let ((header-name (car x)) + (header-value (cdr x))) + ;; skip body + (if (not (string-match "^body$" header-name)) + (wl-user-agent-insert-header header-name header-value) + t))) + wl-user-agent-headers-and-body-alist)) + ;; highlight headers (from wl-draft in wl-draft.el) + (let (wl-highlight-x-face-func) + (wl-highlight-headers)) + ;; insert body + (if (wl-string-match-assoc "body" wl-user-agent-headers-and-body-alist + 'ignore-case) + (wl-user-agent-insert-body + (cdr (wl-string-match-assoc + "body" + wl-user-agent-headers-and-body-alist 'ignore-case))))) + t)) + +(provide 'wl-draft) + +;;; wl-draft.el ends here diff --git a/wl/wl-expire.el b/wl/wl-expire.el new file mode 100644 index 0000000..003c749 --- /dev/null +++ b/wl/wl-expire.el @@ -0,0 +1,729 @@ +;;; wl-expire.el -- Message expire modules for Wanderlust. + +;; Copyright 1998,1999,2000 Masahiro MURATA +;; Yuuichi Teranishi + +;; Author: Masahiro MURATA +;; Keywords: mail, net news +;; Time-stamp: <00/03/14 19:34:13 teranisi> + +;; This file is part of Wanderlust (Yet Another Message Interface on Emacsen). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +(require 'wl-summary) +(require 'wl-thread) +(require 'wl-folder) + +;;; Code: + +(eval-when-compile + (require 'wl-util) + (require 'elmo-archive)) + +;; Variables + +(defvar wl-expired-alist nil) +(defvar wl-expired-alist-file-name "expired-alist") +(defvar wl-expired-log-alist nil) +(defvar wl-expired-log-alist-file-name "expired-log") + +(defun wl-expired-alist-load () + (elmo-object-load (expand-file-name + wl-expired-alist-file-name + elmo-msgdb-dir))) + +(defun wl-expired-alist-save (&optional alist) + (elmo-object-save (expand-file-name + wl-expired-alist-file-name + elmo-msgdb-dir) + (or alist wl-expired-alist))) + +(defsubst wl-expire-msg-p (msg-num mark-alist) + (cond ((consp wl-summary-expire-reserve-marks) + (let ((mark (nth 1 (assq msg-num mark-alist)))) + (not (or (member mark wl-summary-expire-reserve-marks) + (and wl-summary-buffer-disp-msg + (eq msg-num wl-summary-buffer-current-msg)))))) + ((eq wl-summary-expire-reserve-marks 'all) + (not (or (assq msg-num mark-alist) + (and wl-summary-buffer-disp-msg + (eq msg-num wl-summary-buffer-current-msg))))) + ((eq wl-summary-expire-reserve-marks 'none) + t) + (t + (error "invalid marks: %s" wl-summary-expire-reserve-marks)))) + +(defmacro wl-expire-make-sortable-date (date) + (` (timezone-make-sortable-date + (aref (, date) 0) (aref (, date) 1) (aref (, date) 2) + (timezone-make-time-string + (aref (, date) 3) (aref (, date) 4) (aref (, date) 5))))) + +(defsubst wl-expire-date-p (key-datevec date) + (let ((datevec (condition-case nil + (timezone-fix-time date nil nil) + (error nil)))) + (and + datevec (> (aref datevec 1) 0) + (string< + (wl-expire-make-sortable-date datevec) + (wl-expire-make-sortable-date key-datevec))))) + +(defun wl-expire-delete-reserve-marked-msgs-from-list (msgs mark-alist) + (let ((dlist msgs)) + (while dlist + (unless (wl-expire-msg-p (car dlist) mark-alist) + (setq msgs (delq (car dlist) msgs))) + (setq dlist (cdr dlist))) + msgs)) + +(defun wl-expire-delete (folder delete-list msgdb &optional no-reserve-marks) + "Delete message for expire." + (unless no-reserve-marks + (setq delete-list + (wl-expire-delete-reserve-marked-msgs-from-list + delete-list (elmo-msgdb-get-mark-alist msgdb)))) + (when delete-list + (let ((mess + (format "Expiring (delete) %s msgs..." + (length delete-list)))) + (message "%s" mess) + (if (elmo-delete-msgs folder + delete-list + msgdb) + (progn + (elmo-msgdb-delete-msgs folder + delete-list + msgdb + t) + (wl-expire-append-log folder delete-list nil 'delete) + (message "%s" (concat mess "done"))) + (error (concat mess "failed!"))))) + (cons delete-list (length delete-list))) + +(defun wl-expire-refile (folder refile-list msgdb dst-folder + &optional no-reserve-marks preserve-number copy) + "Refile message for expire. If COPY is non-nil, copy message." + (when (not (string= folder dst-folder)) + (unless no-reserve-marks + (setq refile-list + (wl-expire-delete-reserve-marked-msgs-from-list + refile-list (elmo-msgdb-get-mark-alist msgdb)))) + (when refile-list + (let* ((doingmes (if copy + "Copying %s" + "Expiring (move %s)")) + (mess (format (concat doingmes " %s msgs...") + dst-folder (length refile-list)))) + (message "%s" mess) + (unless (or (elmo-folder-exists-p dst-folder) + (elmo-create-folder dst-folder)) + (error "%s: create folder failed" dst-folder)) + (if wl-expire-add-seen-list + (elmo-msgdb-add-msgs-to-seen-list + dst-folder + refile-list + msgdb + (concat wl-summary-important-mark + wl-summary-read-uncached-mark))) + (if (elmo-move-msgs folder + refile-list + dst-folder + msgdb + nil nil t + copy + preserve-number) + (progn + (wl-expire-append-log folder refile-list dst-folder (if copy 'copy 'move)) + (message "%s" (concat mess "done"))) + (error (concat mess "failed!"))))) + (cons refile-list (length refile-list)))) + +(defun wl-expire-refile-with-copy-reserve-msg + (folder refile-list msgdb dst-folder + &optional no-reserve-marks preserve-number copy) + "Refile message for expire. +If REFILE-LIST includes reserve mark message, so copy." + (when (not (string= folder dst-folder)) + (let ((msglist refile-list) + (mark-alist (elmo-msgdb-get-mark-alist msgdb)) + (number-alist (elmo-msgdb-get-number-alist msgdb)) + (ret-val t) + (copy-reserve-message) + (copy-len 0) + msg msg-id) + (message "Expiring (move %s) %s msgs..." + dst-folder (length refile-list)) + (unless (or (elmo-folder-exists-p dst-folder) + (elmo-create-folder dst-folder)) + (error "%s: create folder failed" dst-folder)) + (while (setq msg (wl-pop msglist)) + (unless (wl-expire-msg-p msg mark-alist) + (setq msg-id (cdr (assq msg number-alist))) + (if (assoc msg-id wl-expired-alist) + ;; reserve mark message already refiled or expired + (setq refile-list (delq msg refile-list)) + ;; reserve mark message not refiled + (wl-append wl-expired-alist (list (cons msg-id dst-folder))) + (setq copy-reserve-message t)))) + (when refile-list + (if wl-expire-add-seen-list + (elmo-msgdb-add-msgs-to-seen-list + dst-folder + refile-list + msgdb + (concat wl-summary-important-mark + wl-summary-read-uncached-mark))) + (unless + (setq ret-val + (elmo-move-msgs folder + refile-list + dst-folder + msgdb + nil nil t + copy-reserve-message + preserve-number)) + (error "expire: move msgs to %s failed" dst-folder)) + (wl-expire-append-log folder refile-list dst-folder + (if copy-reserve-message 'copy 'move)) + (setq copy-len (length refile-list)) + (when copy-reserve-message + (setq refile-list + (wl-expire-delete-reserve-marked-msgs-from-list + refile-list + mark-alist)) + (when refile-list + (if (setq ret-val + (elmo-delete-msgs folder + refile-list + msgdb)) + (progn + (elmo-msgdb-delete-msgs folder + refile-list + msgdb + t) + (wl-expire-append-log folder refile-list nil 'delete)))))) + (let ((mes (format "Expiring (move %s) %s msgs..." + dst-folder (length refile-list)))) + (if ret-val + (message (concat mes "done")) + (error (concat mes "failed!")))) + (cons refile-list copy-len)))) + +(defun wl-expire-archive-get-folder (src-folder &optional fmt) + "Get archive folder name from src-folder." + (let* ((spec (elmo-folder-get-spec src-folder)) + (fmt (or fmt wl-expire-archive-folder-name-fmt)) + (archive-spec (char-to-string + (car (rassq 'archive elmo-spec-alist)))) + dst-folder-base dst-folder-fmt prefix) + (cond ((eq (car spec) 'localdir) + (setq dst-folder-base (concat archive-spec (nth 1 spec)))) + ((stringp (nth 1 spec)) + (setq dst-folder-base + (elmo-concat-path (format "%s%s" archive-spec (car spec)) + (nth 1 spec)))) + (t + (setq dst-folder-base + (elmo-concat-path (format "%s%s" archive-spec (car spec)) + (elmo-replace-msgid-as-filename + src-folder))))) + (setq dst-folder-fmt (format fmt + dst-folder-base + wl-expire-archive-folder-type)) + (setq dst-folder-base (format "%s;%s" + dst-folder-base + wl-expire-archive-folder-type)) + (when (and wl-expire-archive-folder-prefix + (stringp (nth 1 spec))) + (cond ((eq wl-expire-archive-folder-prefix 'short) + (setq prefix (file-name-nondirectory (nth 1 spec)))) + (t + (setq prefix (nth 1 spec)))) + (setq dst-folder-fmt (concat dst-folder-fmt ";" prefix)) + (setq dst-folder-base (concat dst-folder-base ";" prefix))) + (cons dst-folder-base dst-folder-fmt))) + +(defsubst wl-expire-archive-get-max-number (dst-folder-base &optional regexp) + (let ((files (reverse (sort (elmo-list-folders dst-folder-base) + 'string<))) + (regexp (or regexp wl-expire-archive-folder-num-regexp)) + filenum in-folder) + (catch 'done + (while files + (when (string-match regexp (car files)) + (setq filenum (elmo-match-string 1 (car files))) + (setq in-folder (elmo-max-of-folder (car files))) + (throw 'done (cons in-folder filenum))) + (setq files (cdr files)))))) + +(defun wl-expire-archive-number-delete-old (dst-folder-base + preserve-number msgs mark-alist + &optional no-confirm regexp file) + (let ((len 0) (max-num 0) + folder-info dels) + (if (or (and file (setq folder-info + (cons (elmo-max-of-folder file) nil))) + (setq folder-info (wl-expire-archive-get-max-number dst-folder-base + regexp))) + (progn + (setq len (cdar folder-info)) + (when preserve-number + ;; delete small number than max number of dst-folder + (setq max-num (caar folder-info)) + (while (and msgs (>= max-num (car msgs))) + (wl-append dels (list (car msgs))) + (setq msgs (cdr msgs))) + (setq dels (wl-expire-delete-reserve-marked-msgs-from-list + dels mark-alist)) + (unless (and dels + (or (or no-confirm (not wl-expire-delete-oldmsg-confirm)) + (progn + (if (eq major-mode 'wl-summary-mode) + (wl-thread-jump-to-msg (car dels))) + (y-or-n-p (format "Delete old messages %s? " + dels))))) + (setq dels nil))) + (list msgs dels max-num (cdr folder-info) len)) + (list msgs dels 0 "0" 0)))) + +(defun wl-expire-archive-number1 (folder delete-list msgdb + &optional preserve-number no-delete) + "Standard function for `wl-summary-expire'. +Refile to archive folder followed message number." + (let* ((elmo-archive-treat-file t) ;; treat archive folder as a file. + (dst-folder-fmt (funcall + wl-expire-archive-get-folder-func folder)) + (dst-folder-base (car dst-folder-fmt)) + (dst-folder-fmt (cdr dst-folder-fmt)) + (refile-func (if no-delete + 'wl-expire-refile + 'wl-expire-refile-with-copy-reserve-msg)) + tmp dels dst-folder + prev-arcnum arcnum msg arcmsg-list + deleted-list ret-val) + (setq tmp (wl-expire-archive-number-delete-old + dst-folder-base preserve-number delete-list + (elmo-msgdb-get-mark-alist msgdb) + no-delete)) + (when (and (not no-delete) + (setq dels (nth 1 tmp))) + (wl-append deleted-list (car (wl-expire-delete folder dels msgdb)))) + (setq delete-list (car tmp)) + (catch 'done + (while t + (if (setq msg (wl-pop delete-list)) + (setq arcnum (/ msg wl-expire-archive-files)) + (setq arcnum nil)) + (when (and prev-arcnum + (not (eq arcnum prev-arcnum))) + (setq dst-folder (format dst-folder-fmt + (* prev-arcnum wl-expire-archive-files))) + (and (setq ret-val + (funcall + refile-func + folder arcmsg-list msgdb dst-folder t preserve-number + no-delete)) + (wl-append deleted-list (car ret-val))) + (setq arcmsg-list nil)) + (if (null msg) + (throw 'done t)) + (wl-append arcmsg-list (list msg)) + (setq prev-arcnum arcnum))) + deleted-list + )) + +(defun wl-expire-archive-number2 (folder delete-list msgdb + &optional preserve-number no-delete) + "Standard function for `wl-summary-expire'. +Refile to archive folder followed the number of message in one archive folder." + (let* ((elmo-archive-treat-file t) ;; treat archive folder as a file. + (dst-folder-fmt (funcall + wl-expire-archive-get-folder-func folder)) + (dst-folder-base (car dst-folder-fmt)) + (dst-folder-fmt (cdr dst-folder-fmt)) + (refile-func (if no-delete + 'wl-expire-refile + 'wl-expire-refile-with-copy-reserve-msg)) + (len 0) (filenum 0) + tmp dels dst-folder + arc-len msg arcmsg-list + deleted-list ret-val) + (setq tmp (wl-expire-archive-number-delete-old + dst-folder-base preserve-number delete-list + (elmo-msgdb-get-mark-alist msgdb) + no-delete)) + (when (and (not no-delete) + (setq dels (nth 1 tmp))) + (wl-append deleted-list (car (wl-expire-delete folder dels msgdb)))) + (setq delete-list (car tmp) + filenum (string-to-int (nth 3 tmp)) + len (nth 4 tmp) + arc-len len) + (catch 'done + (while t + (if (setq msg (wl-pop delete-list)) + (setq len (1+ len)) + (setq len (1+ wl-expire-archive-files))) + (when (> len wl-expire-archive-files) + (when arcmsg-list + (setq dst-folder (format dst-folder-fmt filenum)) + (and (setq ret-val + (funcall + refile-func + folder arcmsg-list msgdb dst-folder t preserve-number + no-delete)) + (wl-append deleted-list (car ret-val))) + (setq arc-len (+ arc-len (cdr ret-val)))) + (setq arcmsg-list nil) + (if (< arc-len wl-expire-archive-files) + (setq len (1+ arc-len)) + (setq filenum (+ filenum wl-expire-archive-files) + len (- len arc-len) ;; maybe 1 + arc-len (1- len) ;; maybe 0 + ))) + (if (null msg) + (throw 'done t)) + (wl-append arcmsg-list (list msg)))) + deleted-list + )) + +(defun wl-expire-archive-date (folder delete-list msgdb + &optional preserve-number no-delete) + "Standard function for `wl-summary-expire'. +Refile to archive folder followed message date." + (let* ((elmo-archive-treat-file t) ;; treat archive folder as a file. + (number-alist (elmo-msgdb-get-number-alist msgdb)) + (overview (elmo-msgdb-get-overview msgdb)) + (dst-folder-fmt (funcall + wl-expire-archive-get-folder-func + folder + wl-expire-archive-date-folder-name-fmt + )) + (dst-folder-base (car dst-folder-fmt)) + (dst-folder-fmt (cdr dst-folder-fmt)) + (refile-func (if no-delete + 'wl-expire-refile + 'wl-expire-refile-with-copy-reserve-msg)) + tmp dels dst-folder date time + msg arcmsg-alist arcmsg-list + deleted-list ret-val) + (setq tmp (wl-expire-archive-number-delete-old + dst-folder-base preserve-number delete-list + (elmo-msgdb-get-mark-alist msgdb) + no-delete + wl-expire-archive-date-folder-num-regexp)) + (when (and (not no-delete) + (setq dels (nth 1 tmp))) + (wl-append deleted-list (car (wl-expire-delete folder dels msgdb)))) + (setq delete-list (car tmp)) + (while (setq msg (wl-pop delete-list)) + (setq date (elmo-msgdb-overview-entity-get-date + (assoc (cdr (assq msg number-alist)) overview))) + (setq time + (condition-case nil + (timezone-fix-time date nil nil) + (error [0 0 0 0 0 0 0]))) + (if (= (aref time 1) 0) ;; if (month == 0) + (aset time 0 0)) ;; year = 0 + (setq dst-folder (format dst-folder-fmt + (aref time 0) ;; year + (aref time 1) ;; month + )) + (setq arcmsg-alist + (wl-append-assoc-list + dst-folder + msg + arcmsg-alist))) + (while arcmsg-alist + (setq dst-folder (caar arcmsg-alist)) + (setq arcmsg-list (cdar arcmsg-alist)) + (and (setq ret-val + (funcall + refile-func + folder arcmsg-list msgdb dst-folder t preserve-number + no-delete)) + (wl-append deleted-list (car ret-val))) + (setq arcmsg-alist (cdr arcmsg-alist))) + deleted-list + )) + +(defsubst wl-expire-folder-p (folder) + (wl-get-assoc-list-value wl-expire-alist folder)) + +(defun wl-summary-expire (&optional folder-name notsummary nolist) + (interactive) + (let ((folder (or folder-name wl-summary-buffer-folder-name)) + (alist wl-expire-alist) + expires) + (when (and (or (setq expires (wl-expire-folder-p folder)) + (progn (and (interactive-p) + (message "no match %s in wl-expire-alist" + folder)) + nil)) + (or (not (interactive-p)) + (y-or-n-p (format "Expire %s? " folder)))) + (let* ((msgdb (or wl-summary-buffer-msgdb + (elmo-msgdb-load folder))) + (number-alist (elmo-msgdb-get-number-alist msgdb)) + (mark-alist (elmo-msgdb-get-mark-alist msgdb)) + expval rm-type val-type value more args + delete-list) + (save-excursion + (setq expval (car expires) + rm-type (nth 1 expires) + args (cddr expires)) + (setq val-type (car expval) + value (nth 1 expval) + more (nth 2 expval)) + (run-hooks 'wl-summary-expire-pre-hook) + (cond + ((eq val-type nil)) + ((eq val-type 'number) + (let* ((msgs (if (not nolist) + (elmo-list-folder folder) + (mapcar 'car number-alist))) + (msglen (length msgs)) + (more (or more (1+ value))) + count) + (when (>= msglen more) + (setq count (- msglen value)) + (while (and msgs (> count 0)) + (when (assq (car msgs) number-alist) ;; don't expire new message + (wl-append delete-list (list (car msgs))) + (when (or (not wl-expire-number-with-reserve-marks) + (wl-expire-msg-p (car msgs) mark-alist)) + (setq count (1- count)))) + (setq msgs (cdr msgs)))))) + ((eq val-type 'date) + (let* ((overview (elmo-msgdb-get-overview msgdb)) + (key-date (elmo-date-get-offset-datevec + (timezone-fix-time (current-time-string) + (current-time-zone) nil) + value t))) + (while overview + (when (wl-expire-date-p + key-date + (elmo-msgdb-overview-entity-get-date + (car overview))) + (wl-append delete-list + (list (elmo-msgdb-overview-entity-get-number + (car overview))))) + (setq overview (cdr overview))))) + (t + (error "%s: not supported" val-type))) + (when delete-list + (or wl-expired-alist + (setq wl-expired-alist (wl-expired-alist-load))) + (setq delete-list + (cond ((eq rm-type nil) nil) + ((eq rm-type 'remove) + (car (wl-expire-delete folder delete-list msgdb))) + ((eq rm-type 'trash) + (car (wl-expire-refile folder delete-list msgdb wl-trash-folder))) + ((stringp rm-type) + (car (wl-expire-refile folder delete-list msgdb rm-type))) + ((fboundp rm-type) + (apply rm-type (append (list folder delete-list msgdb) + args))) + (t + (error "%s: invalid type" rm-type)))) + (when (and (not notsummary) delete-list) + (wl-summary-delete-messages-on-buffer delete-list) + (wl-summary-folder-info-update) + (wl-summary-set-message-modified) + (wl-summary-set-mark-modified) + (sit-for 0) + (set-buffer-modified-p nil)) + (wl-expired-alist-save)) + (run-hooks 'wl-summary-expire-hook) + (if delete-list + (message "Expiring %s is done" folder) + (and (interactive-p) + (message "No expire")))) + delete-list + )))) + +(defun wl-folder-expire-entity (entity) + (cond + ((consp entity) + (let ((flist (nth 2 entity))) + (while flist + (wl-folder-expire-entity (car flist)) + (setq flist (cdr flist))))) + ((stringp entity) + (when (wl-expire-folder-p entity) + (let ((update-msgdb (cond + ((consp wl-expire-folder-update-msgdb) + (wl-string-match-member + entity + wl-expire-folder-update-msgdb)) + (t + wl-expire-folder-update-msgdb))) + (wl-summary-highlight (if (or (wl-summary-sticky-p entity) + (wl-summary-always-sticky-folder-p + entity)) + wl-summary-highlight)) + wl-auto-select-first ret-val) + (save-window-excursion + (save-excursion + (and update-msgdb + (wl-summary-goto-folder-subr entity 'force-update nil)) + (setq ret-val (wl-summary-expire entity (not update-msgdb))) + (if update-msgdb + (wl-summary-save-status 'keep) + (if ret-val + (wl-folder-check-entity entity)))))))))) + +;; Command + +(defun wl-folder-expire-current-entity () + (interactive) + (let ((entity-name + (or (wl-folder-get-folder-name-by-id + (get-text-property (point) 'wl-folder-entity-id)) + (wl-folder-get-realname (wl-folder-folder-name))))) + (when (and entity-name + (or (not (interactive-p)) + (y-or-n-p (format "Expire %s? " entity-name)))) + (wl-folder-expire-entity + (wl-folder-search-entity-by-name entity-name + wl-folder-entity)) + (if (get-buffer wl-summary-buffer-name) + (kill-buffer wl-summary-buffer-name)) + (message "Expiring %s is done" entity-name)))) + +;;; Archive + +(defun wl-folder-archive-current-entity () + (interactive) + (let ((entity-name + (or (wl-folder-get-folder-name-by-id + (get-text-property (point) 'wl-folder-entity-id)) + (wl-folder-get-realname (wl-folder-folder-name))))) + (when (and entity-name + (or (not (interactive-p)) + (y-or-n-p (format "Archive %s? " entity-name)))) + (wl-folder-archive-entity + (wl-folder-search-entity-by-name entity-name + wl-folder-entity)) + (message "Archiving %s is done" entity-name)))) + +(defun wl-archive-number1 (folder archive-list msgdb) + (wl-expire-archive-number1 folder archive-list msgdb t t)) + +(defun wl-archive-number2 (folder archive-list msgdb) + (wl-expire-archive-number2 folder archive-list msgdb t t)) + +(defun wl-archive-date (folder archive-list msgdb) + (wl-expire-archive-date folder archive-list msgdb t t)) + +(defun wl-archive-folder (folder archive-list msgdb dst-folder) + (let* ((elmo-archive-treat-file t) ;; treat archive folder as a file. + copied-list ret-val) + (setq archive-list + (car (wl-expire-archive-number-delete-old + nil t archive-list + (elmo-msgdb-get-mark-alist msgdb) + t ;; no-confirm + nil dst-folder))) + (when archive-list + (and (setq ret-val + (wl-expire-refile + folder archive-list msgdb dst-folder t t t)) ;; copy!! + (wl-append copied-list ret-val))) + copied-list + )) + +(defun wl-summary-archive (&optional arg folder-name notsummary nolist) + (interactive "P") + (let* ((folder (or folder-name wl-summary-buffer-folder-name)) + (msgdb (or wl-summary-buffer-msgdb + (elmo-msgdb-load folder))) + (msgs (if (not nolist) + (elmo-list-folder folder) + (mapcar 'car (elmo-msgdb-get-number-alist msgdb)))) + (alist wl-archive-alist) + func dst-folder archive-list) + (if arg + (let ((wl-default-spec (char-to-string + (car (rassq 'archive elmo-spec-alist))))) + (setq dst-folder (wl-summary-read-folder + (concat wl-default-spec (substring folder 1)) + "for archive")))) + (run-hooks 'wl-summary-archive-pre-hook) + (if dst-folder + (wl-archive-folder folder msgs msgdb dst-folder) + (when (and (catch 'match + (while alist + (when (string-match (caar alist) folder) + (setq func (cadar alist)) + (throw 'match t)) + (setq alist (cdr alist))) + (and (interactive-p) + (message "No match %s in wl-archive-alist" folder)) + (throw 'match nil)) + (or (not (interactive-p)) + (y-or-n-p (format "Archive %s? " folder)))) + (setq archive-list + (funcall func folder msgs msgdb)) + (run-hooks 'wl-summary-archive-hook) + (if archive-list + (message "Archiving %s is done" folder) + (and (interactive-p) + (message "No archive"))))))) + +(defun wl-folder-archive-entity (entity) + (cond + ((consp entity) + (let ((flist (nth 2 entity))) + (while flist + (wl-folder-archive-entity (car flist)) + (setq flist (cdr flist))))) + ((stringp entity) + (wl-summary-archive nil entity t)))) + +;; append log + +(defun wl-expire-append-log (src-folder msgs dst-folder action) + (when wl-expire-use-log + (save-excursion + (let ((tmp-buf (get-buffer-create " *wl-expire work*")) + (filename (expand-file-name wl-expired-log-alist-file-name + elmo-msgdb-dir))) + (set-buffer tmp-buf) + (erase-buffer) + (if dst-folder + (insert (format "%s\t%s -> %s\t%s\n" + action + src-folder dst-folder msgs)) + (insert (format "%s\t%s\t%s\n" + action + src-folder msgs))) + (if (file-writable-p filename) + (write-region (point-min) (point-max) + filename t 'no-msg) + (message (format "%s is not writable." filename))) + (kill-buffer tmp-buf))))) + +(provide 'wl-expire) + +;;; wl-expire.el ends here diff --git a/wl/wl-fldmgr.el b/wl/wl-fldmgr.el new file mode 100644 index 0000000..d9f6c01 --- /dev/null +++ b/wl/wl-fldmgr.el @@ -0,0 +1,1388 @@ +;;; wl-fldmgr.el -- Folder manager for Wanderlust. + +;; Copyright 1998,1999,2000 Masahiro MURATA +;; Yuuichi Teranishi + +;; Author: Masahiro MURATA +;; Keywords: mail, net news +;; Time-stamp: <00/03/14 19:34:28 teranisi> + +;; This file is part of Wanderlust (Yet Another Message Interface on Emacsen). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; + +(require 'wl-folder) +(require 'wl-summary) +(require 'wl-highlight) +(eval-when-compile + (require 'wl-util)) + +;;; Global Variable + +(defvar wl-fldmgr-modified nil) +(defvar wl-fldmgr-modified-access-list nil) +(defvar wl-fldmgr-cut-entity-list nil) +(defvar wl-fldmgr-entity-list nil) +(defvar wl-fldmgr-group-insert-opened nil) + +(defconst wl-fldmgr-folders-header + "# +# Folder definition file +# This file is generated automatically by %s %s (%s). +# + +") + +(defconst wl-fldmgr-filter-completion-alist + '(("/last:") + ("/first:") + ("/since:") + ("/before:") + ("/from=") + ("/subject=") + ("/date=") + ("/to=") + ("/cc=") + ("/tocc=") + ("/body="))) + +;;; Initial setup + +(defvar wl-fldmgr-mode-map nil) +(if wl-fldmgr-mode-map + nil + (define-prefix-command 'wl-fldmgr-mode-map) + (define-key wl-fldmgr-mode-map "\C-s" 'wl-fldmgr-save-folders) + (define-key wl-fldmgr-mode-map "m" 'wl-fldmgr-make-multi) + (define-key wl-fldmgr-mode-map "g" 'wl-fldmgr-make-group) + (define-key wl-fldmgr-mode-map "A" 'wl-fldmgr-make-access-group) + (define-key wl-fldmgr-mode-map "f" 'wl-fldmgr-make-filter) + (define-key wl-fldmgr-mode-map "p" 'wl-fldmgr-set-petname) + (define-key wl-fldmgr-mode-map "a" 'wl-fldmgr-add) + (define-key wl-fldmgr-mode-map "d" 'wl-fldmgr-delete) + (define-key wl-fldmgr-mode-map "R" 'wl-fldmgr-rename) + (define-key wl-fldmgr-mode-map "c" 'wl-fldmgr-copy) + (define-key wl-fldmgr-mode-map "k" 'wl-fldmgr-cut) + (define-key wl-fldmgr-mode-map "W" 'wl-fldmgr-copy-region) + (define-key wl-fldmgr-mode-map "\C-w" 'wl-fldmgr-cut-region) + (define-key wl-fldmgr-mode-map "y" 'wl-fldmgr-yank) + (define-key wl-fldmgr-mode-map "s" 'wl-fldmgr-sort) + (define-key wl-fldmgr-mode-map "l" 'wl-fldmgr-access-display-normal) + (define-key wl-fldmgr-mode-map "L" 'wl-fldmgr-access-display-all) + (define-key wl-fldmgr-mode-map "q" 'wl-fldmgr-clear-cut-entity-list) + (define-key wl-fldmgr-mode-map "r" 'wl-fldmgr-reconst-entity-hashtb) + (define-key wl-fldmgr-mode-map "u" 'wl-fldmgr-unsubscribe) + (define-key wl-fldmgr-mode-map "U" 'wl-fldmgr-unsubscribe-region)) + +(add-hook 'wl-folder-mode-hook 'wl-fldmgr-init) + +(defun wl-fldmgr-init () + (setq wl-fldmgr-cut-entity-list nil) + (setq wl-fldmgr-modified nil) + (setq wl-fldmgr-modified-access-list nil)) + +(defun wl-fldmgr-exit () + (when (and wl-fldmgr-modified + (or (not wl-interactive-save-folders) + (y-or-n-p "Folder view was modified. Save current folders? "))) + (wl-fldmgr-save-folders))) + +;;; Macro and misc Function +;; + +(defmacro wl-fldmgr-delete-line () + (` (delete-region (save-excursion (beginning-of-line) + (point)) + (save-excursion (end-of-line) + (+ 1 (point)))))) + +(defmacro wl-fldmgr-make-indent (level) + (` (concat " " (make-string (* 2 (, level)) ? )))) + +(defmacro wl-fldmgr-get-entity-id (&optional entity) + (` (get-text-property (if (, entity) + 0 + (point)) + 'wl-folder-entity-id + (, entity)))) + +(defmacro wl-fldmgr-assign-id (entity &optional id) + (` (let ((entity-id (or (, id) wl-folder-entity-id))) + (put-text-property 0 (length (, entity)) + 'wl-folder-entity-id + entity-id + (, entity))))) + +(defsubst wl-fldmgr-read-string (str) + (if (string-match "\n" str) + (error "Not supported name: %s" str) + (elmo-string str))) + +(defsubst wl-fldmgr-add-modified-access-list (group) + (if (not (member group wl-fldmgr-modified-access-list)) + (wl-append wl-fldmgr-modified-access-list (list group)))) + +(defsubst wl-fldmgr-delete-modified-access-list (group) + (if (member group wl-fldmgr-modified-access-list) + (setq wl-fldmgr-modified-access-list + (delete group wl-fldmgr-modified-access-list)))) + +(defsubst wl-fldmgr-add-group (group) + (or (assoc group wl-folder-group-alist) + (wl-append wl-folder-group-alist + (list (cons group + wl-fldmgr-group-insert-opened))))) + +(defsubst wl-fldmgr-delete-group (group) + (wl-fldmgr-delete-modified-access-list group) + (setq wl-folder-group-alist + (delete (assoc group wl-folder-group-alist) + wl-folder-group-alist))) + +(defun wl-fldmgr-add-entity-hashtb (entities) + "update `wl-folder-entity-hashtb', `wl-folder-newsgroups-hashtb'. +return value is diffs '(new unread all)." + (let* ((new-diff 0) + (unread-diff 0) + (all-diff 0) + val entity entity-stack) + (setq wl-folder-newsgroups-hashtb + (or (wl-folder-create-newsgroups-hashtb entities t) + wl-folder-newsgroups-hashtb)) + (while entities + (setq entity (wl-pop entities)) + (cond + ((consp entity) + (wl-fldmgr-add-group (car entity)) + (and entities + (wl-push entities entity-stack)) + (setq entities (nth 2 entity))) + ((stringp entity) + (if (not (setq val (wl-folder-get-entity-info entity))) + (wl-folder-set-entity-info entity nil) + (setq new-diff (+ new-diff (or (nth 0 val) 0))) + (setq unread-diff (+ unread-diff (or (nth 1 val) 0))) + (setq all-diff (+ all-diff (or (nth 2 val) 0)))))) + (unless entities + (setq entities (wl-pop entity-stack)))) + (setq unread-diff (+ unread-diff new-diff)) + (list new-diff unread-diff all-diff))) + +(defun wl-fldmgr-delete-entity-hashtb (entities &optional clear) + "update `wl-folder-entity-hashtb'. +return value is diffs '(-new -unread -all)." + (let* ((new-diff 0) + (unread-diff 0) + (all-diff 0) + entity val + entity-stack) + (while entities + (setq entity (wl-pop entities)) + (cond + ((consp entity) + (wl-fldmgr-delete-group (car entity)) + (and entities + (wl-push entities entity-stack)) + (setq entities (nth 2 entity))) + ((stringp entity) + (when (setq val (wl-folder-get-entity-info entity)) + (setq new-diff (+ new-diff (or (nth 0 val) 0))) + (setq unread-diff (+ unread-diff (or (nth 1 val) 0))) + (setq all-diff (+ all-diff (or (nth 2 val) 0))) + (and clear (wl-folder-clear-entity-info entity))))) + (unless entities + (setq entities (wl-pop entity-stack)))) + (setq unread-diff (+ unread-diff new-diff)) + (list (- 0 new-diff) (- 0 unread-diff) (- 0 all-diff)))) + +;; return value +;; example: '(("Desktop" group) ("+ml" access) "+ml/wl") + +(defun wl-fldmgr-get-path (entity target-entity &optional group-target) + (let* ((target-id (wl-fldmgr-get-entity-id target-entity)) + (entities (list entity)) + entity-stack result-path) + (reverse + (catch 'done + (while entities + (setq entity (wl-pop entities)) + (cond + ((consp entity) + (if (and (string= target-entity (car entity)) + (eq target-id (wl-fldmgr-get-entity-id (car entity)))) + (throw 'done + (wl-push (if group-target + (car entity) + (list (car entity) (nth 1 entity))) + result-path)) + (wl-push (list (car entity) (nth 1 entity)) + result-path)) + (wl-push entities entity-stack) + (setq entities (nth 2 entity))) + ((stringp entity) + (if (and (string= target-entity entity) + (eq target-id (wl-fldmgr-get-entity-id entity))) + (throw 'done + (wl-push entity result-path))))) + (unless entities + (while (and entity-stack + (not entities)) + (setq result-path (cdr result-path)) + (setq entities (wl-pop entity-stack))))))))) + +;; (defun wl-fldmgr-get-previous-entity (entity key-id) +;; (cdr (wl-fldmgr-get-previous-entity-internal '(nil . nil) entity key-id))) +;; +;; (defun wl-fldmgr-get-previous-entity-internal (result entity key-id) +;; (cond +;; ((stringp entity) +;; (if (eq key-id (wl-fldmgr-get-entity-id entity)) +;; (cons t result) +;; (cons nil (cons entity entity)))) +;; ((consp entity) +;; (if (eq key-id (wl-fldmgr-get-entity-id (car entity))) +;; (cons t result) +;; (setcar result (car entity)) +;; (let ((flist (nth 2 entity)) +;; return found) +;; (while (and flist (not found)) +;; (if (car (setq return +;; (wl-fldmgr-get-previous-entity-internal +;; result (car flist) key-id))) +;; (setq found t)) +;; (setq result (cdr return)) +;; (setq flist (cdr flist))) +;; (cons found result)))))) + +;; path is get `wl-fldmgr-get-path-from-buffer'. +(defun wl-fldmgr-update-group (path diffs) + (save-excursion + (while (and path (consp (car path))) + (if (string= (caar path) wl-folder-desktop-name) ; update desktop + (progn + (goto-char (point-min)) + (wl-folder-update-diff-line diffs)) + ;; goto the path line. + (goto-char (point-min)) + (if (wl-folder-buffer-search-group + (wl-folder-get-petname (caar path))) + (wl-folder-update-diff-line diffs))) + (setq path (cdr path))))) + +;;; Function for wl-folder-entity +;; + +;; usage: +;; (wl-delete-entity '(("Desktop") ("ML") "+ml/wl") '("+ml/wl") wl-folder-entity) +;; (wl-delete-entity '(("Desktop") "ML") '("+inbox" "ML") wl-folder-entity) +;; (wl-delete-entity '(("Desktop") "ML") nil wl-folder-entity) + +(defun wl-delete-entity (key-path delete-list entity &optional clear) + (let (wl-fldmgr-entity-list) + (when (and (string= (caar key-path) (car entity)) + (wl-delete-entity-sub (cdr key-path) delete-list entity clear)) + ;; return value is non-nil (diffs) + (wl-fldmgr-delete-entity-hashtb wl-fldmgr-entity-list clear)))) + +(defun wl-delete-entity-sub (key-path delete-list entity clear) + (let ((flist (nth 2 entity)) + (key (car key-path)) + next) + (cond + ((consp key);; into group + (if (setq next (assoc (car key) flist)) + (wl-delete-entity-sub (cdr key-path) + delete-list + next + clear) + ;; not found + nil)) + ((stringp key) ;; delete entities + (if (not delete-list) + (setq delete-list (list key))) + (let* ((group (car entity)) + (access (eq (nth 1 entity) 'access)) + (unsubscribes (and access (nth 3 entity))) + (update t) + cut-entity is-group) + (catch 'done + (while delete-list + (setq key (car delete-list)) + (cond ((member key flist);; entity + (setq flist (delete key flist)) + (unless clear + (wl-push key wl-fldmgr-cut-entity-list)) + (wl-append wl-fldmgr-entity-list (list key)) + (setq is-group nil)) + ((setq cut-entity (assoc key flist));; group + (setq flist (delete cut-entity flist)) + (unless clear + (wl-push cut-entity wl-fldmgr-cut-entity-list)) + (wl-append wl-fldmgr-entity-list (list cut-entity)) + (setq is-group t)) + (t + ;; not found + (message "%s not found" key) + (setq update nil) + (throw 'done t))) + (when access + (if is-group + (wl-append unsubscribes + (list (list (elmo-string key) 'access nil))) + (wl-append unsubscribes (list (elmo-string key))))) + (setq delete-list (cdr delete-list)))) + (when update + (setcdr (cdr entity) (list flist unsubscribes)) + (when access + (wl-fldmgr-add-modified-access-list group)) + t + )))))) + +;; usage: +;; (wl-add-entity '(("Desktop") ("ML") "ml/wl") '("+ml/new") wl-folder-entity 12) +;; (wl-add-entity '(("Desktop") "ML") '("+ml/new") wl-folder-entity 10) + +(defun wl-add-entity (key-path new entity prev-entity-id &optional errmes) + (when (string= (caar key-path) (car entity)) + (mapcar + '(lambda (ent) + (wl-folder-entity-assign-id + ent + wl-folder-entity-id-name-hashtb + t)) + new) + (when (wl-add-entity-sub (cdr key-path) new entity errmes) + ;; return value is non-nil (diffs) + (wl-fldmgr-add-entity-hashtb new)))) + +(defun wl-add-entity-sub (key-path new entity &optional errmes) + (let ((flist (nth 2 entity)) + entry) + (catch 'success + (cond + ((consp (car key-path));; into group + (if (setq entry (assoc (caar key-path) flist)) + (if (not (wl-add-entity-sub (cdr key-path) + new + entry + errmes)) + (throw 'success nil)) + (and errmes (message "%s not found" (caar key-path))) + (throw 'success nil))) + (t;; insert entities + (let* ((new2 new) + (group (car entity)) + (access (eq (nth 1 entity) 'access)) + (unsubscribes (and access (nth 3 entity)))) + ;; check + (while new2 + (cond + ((stringp (car new2)) ;; folder + (cond + ((wl-string-member (car new2) flist) + (and errmes (message "%s: already exists" (car new2))) + (throw 'success nil)) + ((and access + (not (wl-string-member (car new2) unsubscribes))) + (and errmes (message "%s: not access group folder" (car new2))) + (throw 'success nil)))) + (t ;; group + (when (and access + (not (wl-string-assoc (caar new2) unsubscribes))) + (and errmes (message "%s: can't insert access group" + (caar new2))) + (throw 'success nil)))) + (setq new2 (cdr new2))) + ;; do it + (when access + ;; remove from unsubscribe + (mapcar + '(lambda (x) + (cond + ((consp x) + (setq unsubscribes + (delete (wl-string-assoc (car x) unsubscribes) + unsubscribes))) + (t + (setq unsubscribes (delete (elmo-string x) unsubscribes))))) + new) +;; (setq new2 new) +;; (while new2 +;; (setq unsubscribes (delete (elmo-string (car new2)) unsubscribes)) +;; (setq new2 (cdr new2))) + (setcdr (cddr entity) (list unsubscribes)) + (wl-fldmgr-add-modified-access-list group)) + (if (not key-path);; insert group top + (if (cddr entity) + (setcar (cddr entity) (append new flist)) + (setcdr (cdr entity) (list new))) + (let (akey) + (if (catch 'done + (while flist + (setq akey (car flist)) + (cond ((consp akey);; group + (if (equal (car key-path) (car akey)) + (throw 'done t))) + (t + (if (equal (car key-path) akey) + (throw 'done t)))) + (setq flist (cdr flist)))) + (setcdr flist (append new (cdr flist))) + (and errmes (message "%s not found" (car key-path))) + (throw 'success nil))))))) + (throw 'success t)))) + +;; return value is +;; (path indent-level (group . type) previous-entity-id target-entity) +;; previous-entity-id is (id-name-alist-prev-id . entity-alist-prev-id) +;; example: +;; '((("Desktop" group) ("ML" group) "+ml/wl") '(3 2) ("ML" . group) nil "+ml/wl") + +(defun wl-fldmgr-get-path-from-buffer (&optional prev) + (let ((indent-level 0) + (group-target t) + folder-path group-type previous-entity entity) + (save-excursion + (beginning-of-line) + (when prev +;; (wl-folder-next-entity-skip-invalid t) +;; (and (setq previous-entity +;; (wl-fldmgr-get-previous-entity wl-folder-entity +;; (wl-fldmgr-get-entity-id))) +;; ;; change entity to id +;; (setq previous-entity +;; (cons +;; (and (car previous-entity) +;; (wl-fldmgr-get-entity-id (car previous-entity))) +;; (and (cdr previous-entity) +;; (wl-fldmgr-get-entity-id (cdr previous-entity)))))) + (wl-folder-prev-entity-skip-invalid)) + (if (and prev + (looking-at wl-folder-group-regexp) + (string= (wl-match-buffer 2) "-")) + (setq group-target nil) + (if (and prev (bobp)) + (error "out of desktop group"))) + (setq folder-path (wl-fldmgr-get-path wl-folder-entity + (wl-folder-get-entity-from-buffer) + ;;(wl-fldmgr-get-entity-id) + group-target)) + (let ((fp folder-path)) + (while fp + (if (consp (car fp)) + (progn + (setq indent-level (1+ indent-level)) + (setq group-type (cons (caar fp) (nth 1 (car fp))))) + (setq entity (car fp))) + (setq fp (cdr fp)))) + (list folder-path indent-level group-type previous-entity entity)))) + +;;; Command +;; + +(defun wl-fldmgr-clear-cut-entity-list () + (interactive) + (setq wl-fldmgr-cut-entity-list nil) + (message "Cleared cut entity list")) + +(defun wl-fldmgr-reconst-entity-hashtb (&optional arg nomes) + (interactive "P") + (or nomes (message "Reconstructing entity alist...")) + (when (not arg) + (setq wl-folder-entity-id 0) + (wl-folder-entity-assign-id wl-folder-entity)) + (setq wl-folder-entity-hashtb + (wl-folder-create-entity-hashtb + wl-folder-entity + wl-folder-entity-hashtb + t)) + ;; reset property on buffer + (when (not arg) + (let ((inhibit-read-only t) + (cur-point (point))) + (erase-buffer) + (wl-folder-insert-entity " " wl-folder-entity) + (goto-char cur-point) + (set-buffer-modified-p nil))) + (or nomes (message "Reconstructing entity alist...done"))) + + +(defun wl-fldmgr-cut-region () + (interactive) + (let* ((p1 (region-beginning)) + (p2 (region-end)) + (r1 (progn + (goto-char p1) + (beginning-of-line) + (point))) + (r2 (progn + (goto-char p2) + (beginning-of-line) + (point))) + (from (min r1 r2)) + (to (max r1 r2)) + (count 0) + (errmes nil) + (cut-list nil) + name pre-indent indent) + (catch 'err + (save-excursion + (goto-char from) + (and (looking-at "^\\([ ]*\\)") + (setq pre-indent (wl-match-buffer 1))) + (while (< (point) to) + (and (looking-at "^\\([ ]*\\)") + (setq indent (wl-match-buffer 1))) + (cond ((= (length pre-indent) (length indent)) + (setq pre-indent indent) + (setq count (1+ count)) + (and (setq name (wl-folder-get-entity-from-buffer)) + (wl-append cut-list (list name))) + (forward-line 1)) + ((< (length pre-indent) (length indent)) + (wl-folder-goto-bottom-of-current-folder pre-indent) + (beginning-of-line)) + (t + (setq errmes "bad region") + (throw 'err t)))) + (unless (eq (point) to) + (setq errmes "bad region") + (throw 'err t))) + (save-excursion + (let ((count2 (length cut-list)) + tmp path ent diffs) + (goto-char from) + (save-excursion + (wl-folder-next-entity-skip-invalid t) + (setq tmp (wl-fldmgr-get-path-from-buffer))) + (setq path (car tmp)) + (setq diffs + (wl-delete-entity path cut-list wl-folder-entity)) + (catch 'done + (while (> count 0) + (setq ent (looking-at wl-folder-entity-regexp)) + (if (not (wl-fldmgr-cut (and ent tmp) + (and ent (pop cut-list)))) + (throw 'done nil)) + (setq count (1- count)))) + (if (> count2 0) + (wl-push count2 wl-fldmgr-cut-entity-list)) + (if diffs + (wl-fldmgr-update-group path diffs)) + t)) + (throw 'err nil)) + (if errmes + (message "%s" errmes)))) + +(defun wl-fldmgr-cut (&optional tmp entity clear) + (interactive) + (save-excursion + (beginning-of-line) + (let ((ret-val nil) + (inhibit-read-only t) + path diffs) + (if (bobp) + (message "Can't remove desktop group") + (or tmp (setq tmp (wl-fldmgr-get-path-from-buffer))) + (setq path (car tmp)) + (if (not path) + (if (not (eobp)) + (wl-fldmgr-delete-line)) ;; unsubscribe or removed folder + (if (not entity) + (setq diffs + (wl-delete-entity path nil wl-folder-entity clear))) + (setq wl-fldmgr-modified t) + ;; + (if (looking-at wl-folder-group-regexp) + ;; group + (let (beg end indent opened) + (setq indent (wl-match-buffer 1)) + (setq opened (wl-match-buffer 2)) + (if (string= opened "+") + (wl-fldmgr-delete-line) + (setq beg (point)) + (end-of-line) + (save-match-data + (setq end + (progn + (wl-folder-goto-bottom-of-current-folder indent) + (beginning-of-line) + (point)))) + (delete-region beg end))) + ;; entity + (wl-fldmgr-delete-line)) + (if diffs + (wl-fldmgr-update-group path diffs)) + (set-buffer-modified-p nil)) + (setq ret-val t)) + ret-val))) + +(defun wl-fldmgr-copy-region () + (interactive) + (let* ((p1 (region-beginning)) + (p2 (region-end)) + (r1 (progn + (goto-char p1) + (beginning-of-line) + (point))) + (r2 (progn + (goto-char p2) + (beginning-of-line) + (point))) + (from (min r1 r2)) + (to (max r1 r2)) + (errmes nil) + (cut-list nil) + (count 0) + name + pre-indent indent) + (catch 'err + (save-excursion + (goto-char from) + (when (bobp) + (setq errmes "can't copy desktop group") + (throw 'err t)) + (and (looking-at "^\\([ ]*\\)") + (setq pre-indent (wl-match-buffer 1))) + (while (< (point) to) + (and (looking-at "^\\([ ]*\\)") + (setq indent (wl-match-buffer 1))) + (if (looking-at wl-folder-group-regexp) + (progn + (setq errmes "can't copy group folder") + (throw 'err t))) + (cond ((= (length pre-indent) (length indent)) + (if (setq name (wl-folder-get-entity-from-buffer)) + (progn + (setq pre-indent indent) + (wl-push name cut-list))) + (forward-line 1)) + ((< (length pre-indent) (length indent)) + (wl-folder-goto-bottom-of-current-folder pre-indent) + (beginning-of-line)) + (t + (setq errmes "bad region") + (throw 'err t)))) + (unless (eq (point) to) + (setq errmes "bad region") + (throw 'err t))) + (catch 'done + (setq cut-list (reverse cut-list)) + (while cut-list + (setq name (pop cut-list)) + (unless (wl-fldmgr-copy name) + (throw 'done nil)) + (setq count (1+ count))) + (wl-push count wl-fldmgr-cut-entity-list) + (message "Copy %s folders" count) + (throw 'err nil))) + (if errmes + (message "%s" errmes)))) + +(defun wl-fldmgr-copy (&optional ename) + (interactive "P") + (save-excursion + (beginning-of-line) + (let ((ret-val nil)) + (if (and (not ename) + (looking-at wl-folder-group-regexp)) + (message "Can't copy group folder") + (let* ((name (or ename (wl-folder-get-entity-from-buffer))) + (entity (elmo-string name))) + (when name + (if (member entity wl-fldmgr-cut-entity-list) + (setq wl-fldmgr-cut-entity-list + (delete entity wl-fldmgr-cut-entity-list))) + (wl-push entity wl-fldmgr-cut-entity-list) + (or ename + (message "Copy: %s" name)) + (setq ret-val t)))) + ret-val))) + +(defun wl-fldmgr-yank () + (interactive) + (save-excursion + (beginning-of-line) + (if (bobp) + (message "Can't insert in the out of desktop group") + (let ((inhibit-read-only t) + (top (car wl-fldmgr-cut-entity-list)) + tmp indent path count new + access new-list diffs) + (if (not top) + (message "No cut buffer") + (setq tmp (wl-fldmgr-get-path-from-buffer t)) + (setq path (car tmp)) + (setq indent (wl-fldmgr-make-indent (nth 1 tmp))) + (if (numberp top) + (setq count (pop wl-fldmgr-cut-entity-list)) + (setq count 1)) + (if (catch 'err + (let ((count count) + (cut-list wl-fldmgr-cut-entity-list)) + ;; check insert entity + (while (> count 0) + (setq new (car cut-list)) + (wl-push new new-list) + (when (consp new);; group + (cond + (access + (message "Can't insert group in access") + (throw 'err t)) + ((wl-string-assoc (car new) wl-folder-group-alist) + (message "%s: group already exists" (car new)) + (throw 'err t)))) + (setq cut-list (cdr cut-list)) + (setq count (1- count)))) + (if (not (setq diffs + (wl-add-entity + path new-list wl-folder-entity (nth 3 tmp) t))) + (throw 'err t)) + (while (> count 0) + (setq new (pop wl-fldmgr-cut-entity-list)) + (save-excursion + (wl-folder-insert-entity indent new) + (setq wl-fldmgr-modified t)) + (setq count (1- count))) + (wl-fldmgr-update-group path diffs) + (set-buffer-modified-p nil)) + ;; error + (wl-push count wl-fldmgr-cut-entity-list))))))) + +(defvar wl-fldmgr-add-completion-hashtb (make-vector 7 0)) + +(defun wl-fldmgr-add-completion-all-completions (string) + (let ((table + (catch 'found + (mapatoms + (function + (lambda (atom) + (if (string-match (symbol-name atom) string) + (throw 'found (symbol-value atom))))) + wl-fldmgr-add-completion-hashtb))) + (pattern + (if (string-match "\\.$" + (car (elmo-network-get-spec + string nil nil nil))) + (substring string 0 (match-beginning 0)) + (concat string nil)))) + (or table + (setq table (elmo-list-folders pattern)) + (and table + (or (/= (length table) 1) + (elmo-folder-exists-p (car table)))) + (setq pattern + (if (string-match "\\.[^\\.]+$" string) + (substring string 0 (match-beginning 0)) + (char-to-string (aref string 0))) + table (elmo-list-folders pattern))) + (setq pattern (concat "^" (regexp-quote pattern))) + (unless (intern-soft pattern wl-fldmgr-add-completion-hashtb) + (set (intern pattern wl-fldmgr-add-completion-hashtb) table)) + table)) + +(defun wl-fldmgr-add-completion-subr (string predicate flag) + (let ((table + (if (string= string "") + (mapcar (function (lambda (spec) + (list (char-to-string (car spec))))) + elmo-spec-alist) + (when (assq (aref string 0) elmo-spec-alist) + (delq nil (mapcar + (function list) + (condition-case nil + (wl-fldmgr-add-completion-all-completions string) + (error nil)))))))) + (if (null flag) + (try-completion string table predicate) + (if (eq flag 'lambda) + (eq t (try-completion string table predicate)) + (if flag + (all-completions string table predicate)))))) + +(defun wl-fldmgr-add (&optional name) + (interactive) + (save-excursion + (beginning-of-line) + (let ((ret-val nil) + (inhibit-read-only t) + (wl-folder-completion-func (function wl-fldmgr-add-completion-subr)) + tmp indent path diffs) + (if (bobp) + (message "Can't insert in the out of desktop group") + (setq tmp (wl-fldmgr-get-path-from-buffer t)) + (setq path (car tmp)) + (setq indent (wl-fldmgr-make-indent (nth 1 tmp))) + (or name + (setq name (wl-fldmgr-read-string + (wl-summary-read-folder wl-default-folder "to add")))) + ;; maybe add elmo-plugged-alist. + (when (stringp name) + (elmo-folder-set-plugged name wl-plugged t)) + (when (setq diffs + (wl-add-entity + path (list name) wl-folder-entity (nth 3 tmp) t)) + (wl-folder-insert-entity indent name) + (wl-fldmgr-update-group path diffs) + (setq wl-fldmgr-modified t) + (set-buffer-modified-p nil) + (setq ret-val t))) + ret-val))) + +(defun wl-fldmgr-delete () + (interactive) + (save-excursion + (beginning-of-line) + (if (looking-at wl-folder-group-regexp) + (error "can't delete group folder")) + (let* ((inhibit-read-only t) + (tmp (wl-fldmgr-get-path-from-buffer)) + (entity (elmo-string (nth 4 tmp))) + (msgs (and (elmo-folder-exists-p entity) + (elmo-list-folder entity)))) + (when (yes-or-no-p (format "%sDo you really delete \"%s\"? " + (if (> (length msgs) 0) + (format "%d msg(s) exists. " (length msgs)) + "") + entity)) + (elmo-delete-folder entity) + (wl-fldmgr-cut tmp nil t))))) + +(defun wl-fldmgr-rename () + (interactive) + (save-excursion + (beginning-of-line) + (if (bobp) + (message "Can't rename desktop group") + (cond + ((looking-at wl-folder-group-regexp) ;; group + (let* ((indent (wl-match-buffer 1)) + (old-group (wl-folder-get-realname (wl-match-buffer 3))) + (group-entity (wl-folder-search-group-entity-by-name + old-group wl-folder-entity)) + group) + (if (eq (nth 1 group-entity) 'access) + (message "%s: can't rename access group folder" old-group) + (setq group (wl-fldmgr-read-string + (read-from-minibuffer "Rename: " old-group))) + (if (string-match "/$" group) + (message "Remove tail slash.") + (cond + ((or (string= group "") + (string= old-group group)) + nil) + (t + (if (wl-string-assoc group wl-folder-group-alist) + (message "%s: group already exists" group) + (let ((inhibit-read-only t) + (id (wl-fldmgr-get-entity-id + (car group-entity)))) + (wl-fldmgr-assign-id group id) + (setcar group-entity group) + (setcar (wl-string-assoc old-group wl-folder-group-alist) + group) + ;;(setcdr (assq id wl-folder-entity-id-name-alist) group) + (wl-folder-set-id-name id group) + (wl-fldmgr-delete-line) + (wl-folder-insert-entity + indent + group-entity t) + (setq wl-fldmgr-modified t) + (set-buffer-modified-p nil))))))))) + (t ;; folder + (let* ((tmp (wl-fldmgr-get-path-from-buffer)) + (old-folder (nth 4 tmp)) + new-folder) + (if (eq (cdr (nth 2 tmp)) 'access) + (error "can't rename access folder")) + (setq new-folder + (wl-fldmgr-read-string + (wl-summary-read-folder old-folder "to rename" t t old-folder))) + (if (or (wl-folder-entity-exists-p new-folder) + (file-exists-p (elmo-msgdb-expand-path new-folder))) + (error "already exists folder: %s" new-folder)) + (elmo-rename-folder old-folder new-folder) + (wl-folder-set-entity-info + new-folder + (wl-folder-get-entity-info old-folder)) + (when (wl-fldmgr-cut tmp nil t) + (wl-fldmgr-add new-folder)))))))) + +(defun wl-fldmgr-make-access-group () + (interactive) + (wl-fldmgr-make-group nil t)) + +(defun wl-fldmgr-make-group (&optional group-name access) + (interactive) + (save-excursion + (beginning-of-line) + (if (bobp) + (message "Can't insert in the out of desktop group") + (let ((inhibit-read-only t) + (type 'group) + group tmp indent path new prev-id flist diffs) + (setq tmp (wl-fldmgr-get-path-from-buffer t)) + (setq path (car tmp)) + (setq indent (wl-fldmgr-make-indent (nth 1 tmp))) + (setq prev-id (nth 3 tmp)) + (if (eq (cdr (nth 2 tmp)) 'access) + (message "Can't insert access group") + (setq group (or group-name + (wl-fldmgr-read-string + (read-from-minibuffer + (if access "Access Type Group: " "Group: "))))) + (when (or access (string-match "[\t ]*/$" group)) + (setq group (if access group + (substring group 0 (match-beginning 0)))) + (setq type 'access) + (setq flist (wl-create-access-folder-entity group))) + (if (string= group "") + nil + (if (wl-string-assoc group wl-folder-group-alist) + (message "%s: group already exists" group) + (setq new (append (list group type) flist)) + (when (setq diffs (wl-add-entity path + (list new) + wl-folder-entity + prev-id)) + (wl-folder-insert-entity indent new) + (wl-fldmgr-update-group path diffs) + (setq wl-fldmgr-modified t) + (set-buffer-modified-p nil))))))))) + +(defun wl-fldmgr-make-multi () + (interactive) + (if (not wl-fldmgr-cut-entity-list) + (message "No cut buffer") + (let ((cut-entity wl-fldmgr-cut-entity-list) + (new-entity "") + (first t) + status) + (setq status + (catch 'done + (while cut-entity + (cond + ((numberp (car cut-entity)) + nil) + ((consp (car cut-entity)) + (message "Can't make multi included group folder") + (throw 'done nil)) + (t + (let ((spec (elmo-folder-get-spec (car cut-entity))) + multi-fld) + (if (eq (car spec) 'multi) + (setq multi-fld + (substring (car cut-entity) 1))) + (setq new-entity + (format "%s%s%s" + (or multi-fld (car cut-entity)) + (if first "" ",") + new-entity)) + (setq first nil)))) + (setq cut-entity (cdr cut-entity))) + (throw 'done t))) + (when status + (setq new-entity (concat "*" new-entity)) + (wl-fldmgr-add new-entity))))) + +(defun wl-fldmgr-make-filter () + (interactive) + (save-excursion + (beginning-of-line) + (if (looking-at wl-folder-group-regexp) + (message "This folder is group") + (let ((tmp (wl-fldmgr-get-path-from-buffer))) + (if (eq (cdr (nth 2 tmp)) 'access) + (message "Tan't change access group") + (let* ((entity (nth 4 tmp)) + (old-entity entity) + old-filter + filter new-entity) + (unless entity (error "no folder")) + (when (string-match "^\\(\\(/[^/]+/\\)+\\)\\(.*\\)" entity) + (setq old-filter (substring entity + (match-beginning 1) + (match-end 1))) + (setq old-entity (substring entity + (match-beginning 3) + (match-end 3)))) + (setq filter (completing-read "Filter: " + wl-fldmgr-filter-completion-alist + nil nil + (or old-filter "/"))) + (unless (or (string= filter "") + (string-match "/$" filter)) + (setq filter (concat filter "/"))) + (setq new-entity (concat filter old-entity)) + (let ((entity new-entity) + spec) + ;; check filter syntax + (while (eq + (car (setq spec (elmo-folder-get-spec entity))) + 'filter) + (setq entity (nth 2 spec)))) + (wl-fldmgr-add new-entity))))))) + +(defun wl-fldmgr-sort () + (interactive) + (save-excursion + (beginning-of-line) + (let ((inhibit-read-only t) + entity flist indent opened) + (when (looking-at wl-folder-group-regexp) + (setq indent (wl-match-buffer 1)) + (setq opened (wl-match-buffer 2)) + (setq entity (wl-folder-search-group-entity-by-name + (wl-folder-get-realname (wl-match-buffer 3)) + wl-folder-entity)) + (message "Sorting...") + (setq flist (sort (nth 2 entity) wl-fldmgr-sort-func)) + (setcar (cddr entity) flist) + (wl-fldmgr-add-modified-access-list (car entity)) + (setq wl-fldmgr-modified t) + ;; + (when (string= opened "-") + (let (beg end) + (setq beg (point)) + (end-of-line) + (save-match-data + (setq end + (progn + (wl-folder-goto-bottom-of-current-folder indent) + (beginning-of-line) + (point)))) + (delete-region beg end) + (wl-folder-insert-entity indent entity))) + ;;(wl-fldmgr-reconst-entity-hashtb t t) + (message "Sorting...done") + (set-buffer-modified-p nil))))) + +(defun wl-fldmgr-sort-standard (x y) + (cond ((and (consp x) (not (consp y))) + wl-fldmgr-sort-group-first) + ((and (not (consp x)) (consp y)) + (not wl-fldmgr-sort-group-first)) + ((and (consp x) (consp y)) + (string-lessp (car x) (car y))) + (t + (string-lessp x y)))) + +(defun wl-fldmgr-subscribe-region () + (interactive) + (wl-fldmgr-unsubscribe-region -1)) + +(defun wl-fldmgr-unsubscribe-region (&optional arg) + (interactive "P") + (let* ((p1 (region-beginning)) + (p2 (region-end)) + (r1 (progn + (goto-char p1) + (beginning-of-line) + (point))) + (r2 (progn + (goto-char p2) + (beginning-of-line) + (point))) + (from (min r1 r2)) + (to (max r1 r2)) + (count 0)) + (goto-char from) + (while (< (point) to) + (setq count (1+ count)) + (forward-line)) + (goto-char from) + (message "Unsubscribe region...") + (while (and (> count 0) + (wl-fldmgr-unsubscribe (or arg 1) t)) + (setq count (1- count))) + (message "Unsubscribe region...done"))) + +(defun wl-fldmgr-subscribe () + (interactive) + (wl-fldmgr-unsubscribe -1)) + +(defun wl-fldmgr-unsubscribe (&optional arg force) + (interactive "P") + (let ((type (and arg (prefix-numeric-value arg))) + execed is-group) + (save-excursion + (beginning-of-line) + (let ((inhibit-read-only t) + folder + tmp indent beg) + (cond + ((looking-at (format "^[ ]*%s\\[[+-]\\]\\(.*\\)" wl-folder-unsubscribe-mark)) + (if (and type (> type 0)) + nil + (setq folder (list (wl-match-buffer 1) 'access nil)) + (if (wl-string-assoc (car folder) wl-folder-group-alist) + (message "%s: group already exists" (car folder)) + (wl-fldmgr-delete-line) + (when (wl-fldmgr-add folder) + (wl-folder-maybe-load-folder-list folder) +;; (wl-folder-search-group-entity-by-name (car folder) +;; wl-folder-entity)) + (setq execed t))))) + ((looking-at (format "^[ ]*%s\\(.*\\)" wl-folder-unsubscribe-mark)) + (if (and type (> type 0)) + nil + (setq folder (wl-match-buffer 1)) + (wl-fldmgr-delete-line) + (when (wl-fldmgr-add folder) + (setq execed t)))) + (t + (if (and type (< type 0)) + nil + (setq is-group (looking-at wl-folder-group-regexp)) + (setq tmp (wl-fldmgr-get-path-from-buffer)) + (setq indent (wl-fldmgr-make-indent (nth 1 tmp))) + (if (eq (cdr (nth 2 tmp)) 'access) + (when (wl-fldmgr-cut tmp) + (pop wl-fldmgr-cut-entity-list) ;; don't leave cut-list + (setq beg (point)) + (insert indent wl-folder-unsubscribe-mark + (if is-group + (concat "[+]" (nth 4 tmp)) + (nth 4 tmp)) + "\n") + (save-excursion (forward-line -1) + (wl-highlight-folder-current-line)) + (remove-text-properties beg (point) '(wl-folder-entity-id)) + (setq execed t)))))) + (set-buffer-modified-p nil))) + (if (or force execed) + (progn + (forward-line) + t)))) + +(defun wl-fldmgr-access-display-normal (&optional arg) + (interactive "P") + (wl-fldmgr-access-display-all (not arg))) + +(defun wl-fldmgr-access-display-all (&optional arg) + (interactive "P") + (let ((id (save-excursion + (wl-folder-prev-entity-skip-invalid t) + (wl-fldmgr-get-entity-id)))) + (save-excursion + (beginning-of-line) + (let ((inhibit-read-only t) + entity indent opened + unsubscribes beg) + (when (not (looking-at wl-folder-group-regexp)) + (wl-folder-goto-top-of-current-folder) + (looking-at wl-folder-group-regexp)) + (setq indent (wl-match-buffer 1)) + (setq opened (wl-match-buffer 2)) + (setq entity (wl-folder-search-group-entity-by-name + (wl-folder-get-realname (wl-match-buffer 3)) + wl-folder-entity)) + (when (eq (nth 1 entity) 'access) + (save-excursion + (if (string= opened "-") + (let (beg end) + (setq beg (point)) + (end-of-line) + (save-match-data + (setq end + (progn + (wl-folder-goto-bottom-of-current-folder indent) + (beginning-of-line) + (point)))) + (delete-region beg end)) + (wl-fldmgr-delete-line) + (setcdr (assoc (car entity) wl-folder-group-alist) t));; set open + (wl-folder-insert-entity indent entity)) + (when (not arg) + (setq unsubscribes (nth 3 entity)) + (forward-line) + (while unsubscribes + (setq beg (point)) + (insert indent " " wl-folder-unsubscribe-mark + (if (consp (car unsubscribes)) + (concat "[+]" (caar unsubscribes)) + (car unsubscribes)) + "\n") + (remove-text-properties beg (point) '(wl-folder-entity-id)) + (save-excursion (forward-line -1) + (wl-highlight-folder-current-line)) + (setq unsubscribes (cdr unsubscribes)))) + (set-buffer-modified-p nil)))) + (wl-folder-move-path id))) + +(defun wl-fldmgr-set-petname () + (interactive) + (save-excursion + (beginning-of-line) + (let* ((is-group (looking-at wl-folder-group-regexp)) + (name (wl-folder-get-entity-from-buffer)) + (searchname (wl-folder-get-petname name)) + (pentry (wl-string-assoc name wl-folder-petname-alist)) + (old-petname (or (cdr pentry) "")) + (change) + petname) + (unless name (error "no folder")) + (if (and is-group + (not (eq (nth 1 (wl-folder-search-group-entity-by-name + name wl-folder-entity)) + 'access))) + (message "Can't set petname. please rename.") + (setq petname (wl-fldmgr-read-string + (read-from-minibuffer "Petname: " old-petname))) + (cond + ((string= petname "") + (when pentry + (setq wl-folder-petname-alist + (delete pentry wl-folder-petname-alist)) + (setq change t))) + (t + (if (string= petname old-petname) + nil + (if (or (rassoc petname wl-folder-petname-alist) + (wl-string-assoc petname wl-folder-group-alist)) + (message "%s: already exists" petname) + (wl-folder-append-petname name petname) + (setq change t))))) + (when change + (let ((inhibit-read-only t) + indent) + (goto-char (point-min)) + (if is-group + (progn + (if (string= old-petname "") + (setq old-petname name)) + (while (wl-folder-buffer-search-group old-petname) + (beginning-of-line) + (and (looking-at "^\\([ ]*\\)") + (setq indent (wl-match-buffer 1))) + (wl-fldmgr-delete-line) + (wl-folder-insert-entity + indent + (wl-folder-search-group-entity-by-name + name wl-folder-entity) + t))) + (while (wl-folder-buffer-search-entity name searchname) + (save-excursion + (beginning-of-line) + (and (looking-at "^\\([ ]*\\)") + (setq indent (wl-match-buffer 1))) + (wl-fldmgr-delete-line)) + (wl-folder-insert-entity indent name))) + (setq wl-fldmgr-modified t) + (set-buffer-modified-p nil))))))) + +;;; Function for save folders +;; + +(defun wl-fldmgr-insert-folders-buffer (indent entities &optional pet-entities) + (let ((flist entities) + name petname) + (while flist + (setq name (car flist)) + (cond ((stringp name) + (if (setq petname (cdr (wl-string-assoc name wl-folder-petname-alist))) + (wl-append pet-entities (list name))) + (insert indent name + (if petname + (concat "\t\"" petname "\"") + "") + "\n")) + ((consp name) + (let ((group (wl-folder-get-realname (car name))) + (type (nth 1 name))) + (if (not (string= group (car name))) ; petname. + (wl-append pet-entities (list (car name)))) + (cond ((eq type 'group) + (insert indent group "{\n") + (setq pet-entities + (wl-fldmgr-insert-folders-buffer + (concat indent wl-fldmgr-folders-indent) + (nth 2 name) pet-entities)) + (insert indent "}\n")) + ((eq type 'access) + (insert indent group "/\n")))))) + (setq flist (cdr flist)))) + pet-entities) + +(defun wl-fldmgr-insert-petname-buffer (pet-entities) + (let ((alist wl-folder-petname-alist)) + (while alist + (if (wl-string-member (caar alist) pet-entities) + nil + (insert "=\t" (caar alist) "\t\"" (cdar alist) "\"\n")) + (setq alist (cdr alist))))) + +(defun wl-fldmgr-delete-disused-petname () + (let ((alist wl-folder-petname-alist)) + (while alist + (unless (wl-folder-search-entity-by-name (caar alist) wl-folder-entity) + (setq wl-folder-petname-alist + (delete (car alist) wl-folder-petname-alist))) + (setq alist (cdr alist))))) + +(defun wl-fldmgr-save-folders () + (interactive) + (let ((tmp-buf (get-buffer-create " *wl-fldmgr-tmp*")) + (access-list wl-fldmgr-modified-access-list) + entity + save-petname-entities) + (message "Saving folders...") + (set-buffer tmp-buf) + (erase-buffer) + (insert (format wl-fldmgr-folders-header + wl-appname wl-version wl-codename)) + (wl-fldmgr-delete-disused-petname) + (setq save-petname-entities + (wl-fldmgr-insert-folders-buffer "" (nth 2 wl-folder-entity))) + (insert "\n# petname definition (group, folder in access group)\n") + (wl-fldmgr-insert-petname-buffer save-petname-entities) + (insert "\n# end of file.\n") + (if (and wl-fldmgr-make-backup + (file-exists-p wl-folders-file)) + (rename-file wl-folders-file (concat wl-folders-file ".bak") t)) + (let ((output-coding-system (mime-charset-to-coding-system + wl-mime-charset))) + (write-region + (point-min) + (point-max) + wl-folders-file + nil + 'no-msg) + (set-file-modes wl-folders-file 384)) ; 600 + (kill-buffer tmp-buf) + (while access-list + (setq entity (wl-folder-search-group-entity-by-name + (car access-list) wl-folder-entity)) + (elmo-msgdb-flist-save + (car access-list) + (list + (wl-folder-make-save-access-list (nth 2 entity)) + (wl-folder-make-save-access-list (nth 3 entity)))) + (setq access-list (cdr access-list))) + (setq wl-fldmgr-modified nil) + (setq wl-fldmgr-modified-access-list nil) + (message "Saving folders...done"))) + +(provide 'wl-fldmgr) + +;;; wl-fldmgr.el ends here diff --git a/wl/wl-folder.el b/wl/wl-folder.el new file mode 100644 index 0000000..083e8e3 --- /dev/null +++ b/wl/wl-folder.el @@ -0,0 +1,2679 @@ +;;; wl-folder.el -- Folder mode for Wanderlust. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <00/03/25 16:30:59 teranisi> + +;; This file is part of Wanderlust (Yet Another Message Interface on Emacsen). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; + +(require 'elmo-vars) +(require 'elmo-util) +(require 'elmo2) +(require 'wl-vars) +(condition-case () + (require 'easymenu) ; needed here. + (error)) + +(eval-when-compile + (require 'cl) + (require 'wl-util) + (provide 'wl-folder) + (require 'wl) + (require 'elmo-nntp) + (if wl-use-semi + (require 'mmelmo)) + (unless (boundp ':file) + (set (make-local-variable ':file) nil)) + (defun-maybe mmelmo-cleanup-entity-buffers ())) + +(defvar wl-folder-buffer-name "Folder") +(defvar wl-folder-entity nil) ; desktop entity. +(defvar wl-folder-group-alist nil) ; opened or closed +(defvar wl-folder-entity-id nil) ; id +(defvar wl-folder-entity-hashtb nil) +(defvar wl-folder-entity-id-name-hashtb nil) +(defvar wl-folder-newsgroups-hashtb nil) +(defvar wl-folder-info-alist-modified nil) +(defvar wl-folder-completion-func nil) + +(defvar wl-folder-mode-map nil) + +(defvar wl-folder-opened-glyph nil) +(defvar wl-folder-closed-glyph nil) +(defvar wl-folder-nntp-glyph nil) +(defvar wl-folder-imap4-glyph nil) +(defvar wl-folder-pop3-glyph nil) +(defvar wl-folder-localdir-glyph nil) +(defvar wl-folder-localnews-glyph nil) +(defvar wl-folder-internal-glyph nil) +(defvar wl-folder-multi-glyph nil) +(defvar wl-folder-filter-glyph nil) +(defvar wl-folder-archive-glyph nil) +(defvar wl-folder-pipe-glyph nil) +(defvar wl-folder-maildir-glyph nil) +(defvar wl-folder-trash-empty-glyph nil) +(defvar wl-folder-trash-glyph nil) +(defvar wl-folder-draft-glyph nil) +(defvar wl-folder-queue-glyph nil) + +(defvar wl-folder-buffer-disp-summary nil) +(make-variable-buffer-local 'wl-folder-buffer-disp-summary) +(defvar wl-folder-buffer-cur-entity-id nil) +(make-variable-buffer-local 'wl-folder-buffer-cur-entity-id) +(defvar wl-folder-buffer-cur-path nil) +(make-variable-buffer-local 'wl-folder-buffer-cur-entity-id) +(defvar wl-folder-buffer-cur-point nil) +(make-variable-buffer-local 'wl-folder-buffer-cur-point) + +(defconst wl-folder-entity-regexp "^\\([ ]*\\)\\(\\[[\\+-]\\]\\)?\\([^\\[].+\\):[-*0-9]+/[-*0-9]+/[-*0-9]+") +(defconst wl-folder-group-regexp "^\\([ ]*\\)\\[\\([\\+-]\\)\\]\\(.+\\):[-0-9-]+/[0-9-]+/[0-9-]+\n") +;; 1:indent 2:opened 3:group-name +(defconst wl-folder-unsync-regexp ":[^0\\*][0-9]*/[0-9\\*-]+/[0-9\\*-]+$") + +(defvar wl-folder-mode-menu-spec + '("Folder" + ["Enter Current Folder" wl-folder-jump-to-current-entity t] + ["Prev Folder" wl-folder-prev-entity t] + ["Next Folder" wl-folder-next-entity t] + ["Check Current Folder" wl-folder-check-current-entity t] + ["Sync Current Folder" wl-folder-sync-current-entity t] + ["Drop Current Folder" wl-folder-drop-unsync-current-entity t] + ["Prefetch Current Folder" wl-folder-prefetch-current-entity t] + ["Mark as Read all Current Folder" wl-folder-mark-as-read-all-current-entity t] + ["Expire Current Folder" wl-folder-expire-current-entity t] + ["Empty trash" wl-folder-empty-trash t] + ["Flush queue" wl-folder-flush-queue t] + ["Open All" wl-folder-open-all t] + ["Open All Unread folder" wl-folder-open-all-unread-folder t] + ["Close All" wl-folder-close-all t] + ("Folder Manager" + ["Add folder" wl-fldmgr-add t] + ["Add group" wl-fldmgr-make-group t] + ["Copy" wl-fldmgr-copy t] + ["Cut" wl-fldmgr-cut t] + ["Paste" wl-fldmgr-yank t] + ["Set petname" wl-fldmgr-set-petname t] + ["Rename" wl-fldmgr-rename t] + ["Save" wl-fldmgr-save-folders t] + "----" + ["Unsubscribe" wl-fldmgr-unsubscribe t] + ["Display all" wl-fldmgr-access-display-all t]) + "----" + ["Write a message" wl-draft t] + "----" + ["Toggle Plug Status" wl-toggle-plugged t] + ["Change Plug Status" wl-plugged-change t] + "----" + ["Save Current Status" wl-save t] + ["Update Satus" wl-status-update t] + ["Exit" wl-exit t] + )) + +(if wl-on-xemacs + (defun wl-folder-setup-mouse () + (define-key wl-folder-mode-map 'button2 'wl-folder-click) + (define-key wl-folder-mode-map 'button4 'wl-folder-prev-entity) + (define-key wl-folder-mode-map 'button5 'wl-folder-next-entity) + (define-key wl-folder-mode-map [(shift button4)] + 'wl-folder-prev-unread) + (define-key wl-folder-mode-map [(shift button5)] + 'wl-folder-next-unread)) + (if wl-on-nemacs + (defun wl-folder-setup-mouse ()) + (defun wl-folder-setup-mouse () + (define-key wl-folder-mode-map [mouse-2] 'wl-folder-click) + (define-key wl-folder-mode-map [mouse-4] 'wl-folder-prev-entity) + (define-key wl-folder-mode-map [mouse-5] 'wl-folder-next-entity) + (define-key wl-folder-mode-map [S-mouse-4] 'wl-folder-prev-unread) + (define-key wl-folder-mode-map [S-mouse-5] 'wl-folder-next-unread)))) + +(if wl-folder-mode-map + nil + (setq wl-folder-mode-map (make-sparse-keymap)) + (define-key wl-folder-mode-map " " 'wl-folder-jump-to-current-entity) +; (define-key wl-folder-mode-map "\M- " 'wl-folder-open-close) + (define-key wl-folder-mode-map "/" 'wl-folder-open-close) + (define-key wl-folder-mode-map "\C-m" 'wl-folder-jump-to-current-entity) + (define-key wl-folder-mode-map "\M-\C-m" 'wl-folder-update-recursive-current-entity) + (define-key wl-folder-mode-map "rc" 'wl-folder-mark-as-read-all-region) + (define-key wl-folder-mode-map "c" 'wl-folder-mark-as-read-all-current-entity) + (define-key wl-folder-mode-map "g" 'wl-folder-goto-folder) + (define-key wl-folder-mode-map "j" 'wl-folder-jump-to-current-entity) + (define-key wl-folder-mode-map "w" 'wl-draft) + (define-key wl-folder-mode-map "W" 'wl-folder-write-current-newsgroup) + (define-key wl-folder-mode-map "\C-c\C-o" 'wl-jump-to-draft-buffer) + (define-key wl-folder-mode-map "rS" 'wl-folder-sync-region) + (define-key wl-folder-mode-map "S" 'wl-folder-sync-current-entity) + (define-key wl-folder-mode-map "rs" 'wl-folder-check-region) + (define-key wl-folder-mode-map "s" 'wl-folder-check-current-entity) + (define-key wl-folder-mode-map "I" 'wl-folder-prefetch-current-entity) + (define-key wl-folder-mode-map "D" 'wl-folder-drop-unsync-current-entity) + (define-key wl-folder-mode-map "p" 'wl-folder-prev-entity) + (define-key wl-folder-mode-map "n" 'wl-folder-next-entity) + (define-key wl-folder-mode-map "v" 'wl-folder-toggle-disp-summary) + (define-key wl-folder-mode-map "P" 'wl-folder-prev-unread) + (define-key wl-folder-mode-map "N" 'wl-folder-next-unread) + (define-key wl-folder-mode-map "J" 'wl-folder-jump-folder) + (define-key wl-folder-mode-map "f" 'wl-folder-goto-first-unread-folder) + (define-key wl-folder-mode-map "o" 'wl-folder-open-all-unread-folder) + (define-key wl-folder-mode-map "[" 'wl-folder-open-all) + (define-key wl-folder-mode-map "]" 'wl-folder-close-all) + (define-key wl-folder-mode-map "e" 'wl-folder-expire-current-entity) + (define-key wl-folder-mode-map "E" 'wl-folder-empty-trash) + (define-key wl-folder-mode-map "F" 'wl-folder-flush-queue) + (define-key wl-folder-mode-map "q" 'wl-exit) + (define-key wl-folder-mode-map "z" 'wl-folder-suspend) + (define-key wl-folder-mode-map "\M-t" 'wl-toggle-plugged) + (define-key wl-folder-mode-map "\C-t" 'wl-plugged-change) + (define-key wl-folder-mode-map "<" 'beginning-of-buffer) + (define-key wl-folder-mode-map ">" 'end-of-buffer) + ;; wl-fldmgr + (unless wl-on-nemacs + (define-key wl-folder-mode-map "m" 'wl-fldmgr-mode-map)) + (define-key wl-folder-mode-map "*" 'wl-fldmgr-make-multi) + (define-key wl-folder-mode-map "+" 'wl-fldmgr-make-group) + (define-key wl-folder-mode-map "|" 'wl-fldmgr-make-filter) + (define-key wl-folder-mode-map "\M-c" 'wl-fldmgr-copy) + (define-key wl-folder-mode-map "\M-w" 'wl-fldmgr-copy-region) + (define-key wl-folder-mode-map "\C-k" 'wl-fldmgr-cut) + (define-key wl-folder-mode-map "\C-w" 'wl-fldmgr-cut-region) + (define-key wl-folder-mode-map "\C-y" 'wl-fldmgr-yank) + (define-key wl-folder-mode-map "R" 'wl-fldmgr-rename) + (define-key wl-folder-mode-map "u" 'wl-fldmgr-unsubscribe) + (define-key wl-folder-mode-map "ru" 'wl-fldmgr-unsubscribe-region) + (define-key wl-folder-mode-map "U" 'wl-fldmgr-unsubscribe-region) + (define-key wl-folder-mode-map "l" 'wl-fldmgr-access-display-normal) + (define-key wl-folder-mode-map "L" 'wl-fldmgr-access-display-all) + (define-key wl-folder-mode-map "Z" 'wl-status-update) + (define-key wl-folder-mode-map "\C-x\C-s" 'wl-save) + (define-key wl-folder-mode-map "\M-s" 'wl-save) + (define-key wl-folder-mode-map "\C-xk" 'wl-folder-mimic-kill-buffer) + (wl-folder-setup-mouse) + (easy-menu-define + wl-folder-mode-menu + wl-folder-mode-map + "Menu used in Folder mode." + wl-folder-mode-menu-spec)) + +(defmacro wl-folder-unread-regex (group) + (` (concat "^[ ]*.+:[0-9\\*-]+/[^0\\*][0-9]*/[0-9\\*-]+$" + (if (, group) + "\\|^[ ]*\\[[+-]\\]" + "")))) + +(defmacro wl-folder-buffer-group-p () + (` (save-excursion (beginning-of-line) + (looking-at wl-folder-group-regexp)))) + +(defmacro wl-folder-folder-name () + (` (save-excursion + (beginning-of-line) + (if (or (looking-at "^[ ]*\\[[\\+-]\\]\\(.+\\):[-0-9\\*-]+/[0-9\\*-]+/[0-9\\*-]+\n") + (looking-at "^[ ]*\\([^\\[].+\\):.*\n")) + (wl-match-buffer 1))))) + +(defmacro wl-folder-entity-name () + (` (save-excursion + (beginning-of-line) + (if (looking-at "^[ ]*\\([^\\[].+\\):.*\n") + (wl-match-buffer 1))))) + +(defun wl-folder-buffer-search-group (group) + (re-search-forward + (concat + "^\\([ \t]*\\)\\[[\\+-]\\]" + (regexp-quote group) ":[-0-9-]+/[0-9-]+/[0-9-]+") nil t)) + +(defun wl-folder-buffer-search-entity (folder &optional searchname) + (let ((search (or searchname (wl-folder-get-petname folder)))) + (re-search-forward + (concat + "^[ \t]*" + (regexp-quote search) ":[-0-9\\*-]+/[0-9\\*-]+/[0-9\\*-]+") nil t))) + +(defsubst wl-folder-get-folder-name-by-id (entity-id &optional hashtb) + (and (numberp entity-id) + (elmo-get-hash-val (format "#%d" entity-id) + (or hashtb wl-folder-entity-id-name-hashtb)))) + +(defsubst wl-folder-set-id-name (entity-id entity &optional hashtb) + (and (numberp entity-id) + (elmo-set-hash-val (format "#%d" entity-id) + entity (or hashtb wl-folder-entity-id-name-hashtb)))) + +(defmacro wl-folder-get-entity-id (entity) + (` (or (get-text-property 0 + 'wl-folder-entity-id + (, entity)) + (, entity)))) ;; for nemacs + +(defmacro wl-folder-get-entity-from-buffer (&optional getid) + (` (let ((id (get-text-property (point) + 'wl-folder-entity-id))) + (if (not id) ;; for nemacs + (wl-folder-get-realname (wl-folder-folder-name)) + (if (, getid) + id + (wl-folder-get-folder-name-by-id id)))))) + +(defmacro wl-folder-entity-exists-p (entity &optional hashtb) + (` (let ((sym (intern-soft (, entity) + (or (, hashtb) wl-folder-entity-hashtb)))) + (and sym (boundp sym))))) + +(defmacro wl-folder-clear-entity-info (entity &optional hashtb) + (` (let ((sym (intern-soft (, entity) + (or (, hashtb) wl-folder-entity-hashtb)))) + (if (boundp sym) + (makunbound sym))))) + +(defmacro wl-folder-get-entity-info (entity &optional hashtb) + (` (elmo-get-hash-val (, entity) (or (, hashtb) wl-folder-entity-hashtb)))) + +(defmacro wl-folder-set-entity-info (entity value &optional hashtb) + (` (let* ((hashtb (or (, hashtb) wl-folder-entity-hashtb)) + (info (wl-folder-get-entity-info (, entity) hashtb))) + (elmo-set-hash-val (, entity) + (if (< (length (, value)) 4) + (append (, value) (list (nth 3 info))) + (, value)) + hashtb)))) + +(defun wl-folder-persistent-p (folder) + (or (elmo-get-hash-val folder wl-folder-entity-hashtb) ; on Folder mode. + (catch 'found + (let ((li wl-save-folder-list)) + (while li + (if (string-match (car li) folder) + (throw 'found t)) + (setq li (cdr li))))) + (not (catch 'found + (let ((li wl-no-save-folder-list)) + (while li + (if (string-match (car li) folder) + (throw 'found t)) + (setq li (cdr li)))))))) + +(defun wl-folder-prev-entity () + (interactive) + (forward-line -1)) + +(defun wl-folder-next-entity () + (interactive) + (forward-line 1)) + +(defun wl-folder-prev-entity-skip-invalid (&optional hereto) + "move to previous entity. skip unsubscribed or removed entity." + (interactive) + (if hereto + (end-of-line)) + (if (re-search-backward wl-folder-entity-regexp nil t) + (beginning-of-line) + (goto-char (point-min)))) + +(defun wl-folder-next-entity-skip-invalid (&optional hereto) + "move to next entity. skip unsubscribed or removed entity." + (interactive) + (beginning-of-line) + (if (not hereto) + (forward-line 1)) + (if (re-search-forward wl-folder-entity-regexp nil t) + (beginning-of-line) + (goto-char (point-max)))) + +(defun wl-folder-search-group-entity-by-name (name entity) + (wl-folder-search-entity-by-name name entity 'group)) + +(defun wl-folder-search-entity-by-name (name entity &optional type) + (let ((entities (list entity)) + entity-stack) + (catch 'done + (while entities + (setq entity (wl-pop entities)) + (cond + ((consp entity) + (if (and (not (eq type 'folder)) + (string= name (car entity))) + (throw 'done entity)) + (and entities + (wl-push entities entity-stack)) + (setq entities (nth 2 entity))) + ((and (not (eq type 'group)) + (stringp entity)) + (if (string= name entity) + (throw 'done entity)))) + (unless entities + (setq entities (wl-pop entity-stack))))))) + +(defun wl-folder-search-entity-list-by-name (name entity &optional get-id) + (let ((entities (list entity)) + entity-stack ret-val) + (while entities + (setq entity (wl-pop entities)) + (cond + ((consp entity) + (and entities + (wl-push entities entity-stack)) + (setq entities (nth 2 entity))) + ((stringp entity) + (if (string= name entity) + (wl-append ret-val (if get-id + (list (wl-folder-get-entity-id entity)) + (list entity)))))) + (unless entities + (setq entities (wl-pop entity-stack)))) + ret-val)) + +(defun wl-folder-get-prev-folder (id &optional unread) + (let ((name (if (stringp id) + id + (wl-folder-get-folder-name-by-id id))) + entity entity-stack last-entity finfo + (entities (list wl-folder-entity))) + (catch 'done + (while entities + (setq entity (wl-pop entities)) + (cond + ((consp entity) +;; (if (and (string= name (car entity)) +;; (eq id (wl-folder-get-entity-id (car entity)))) +;; (throw 'done last-entity)) + (and entities + (wl-push entities entity-stack)) + (setq entities (nth 2 entity))) + ((stringp entity) + (if (and (string= name entity) + ;; don't use eq, `id' is string on Nemacs. + (equal id (wl-folder-get-entity-id entity))) + (throw 'done last-entity)) + (if (or (not unread) + (and (setq finfo (wl-folder-get-entity-info entity)) + (and (nth 0 finfo)(nth 1 finfo)) + (> (+ (nth 0 finfo)(nth 1 finfo)) 0))) + (setq last-entity entity)))) + (unless entities + (setq entities (wl-pop entity-stack))))))) + +(defun wl-folder-get-next-folder (id &optional unread) + (let ((name (if (stringp id) + id + (wl-folder-get-folder-name-by-id id))) + entity entity-stack found finfo + (entities (list wl-folder-entity))) + (catch 'done + (while entities + (setq entity (wl-pop entities)) + (cond + ((consp entity) +;; (if (and (string= name (car entity)) +;; (eq id (wl-folder-get-entity-id (car entity)))) +;; (setq found t)) + (and entities + (wl-push entities entity-stack)) + (setq entities (nth 2 entity))) + ((stringp entity) + (if found + (when (or (not unread) + (and (setq finfo (wl-folder-get-entity-info entity)) + (and (nth 0 finfo)(nth 1 finfo)) + (> (+ (nth 0 finfo)(nth 1 finfo)) 0))) + (throw 'done entity)) + (if (and (string= name entity) + ;; don't use eq, `id' is string on Nemacs. + (equal id (wl-folder-get-entity-id entity))) + (setq found t))))) + (unless entities + (setq entities (wl-pop entity-stack))))))) + +(defun wl-folder-flush-queue () + "Flush queue." + (interactive) + (let ((cur-buf (current-buffer)) + (wl-auto-select-first nil) + (wl-plugged t) + emptied) + (if (not (elmo-list-folder wl-queue-folder)) + (error "No queue exists") + (if wl-stay-folder-window + (wl-folder-select-buffer + (wl-summary-get-buffer-create wl-queue-folder))) + (wl-summary-goto-folder-subr wl-queue-folder 'force-update nil) + (unwind-protect + (wl-draft-queue-flush) + (if wl-summary-cache-use (wl-summary-save-view-cache)) + (wl-summary-msgdb-save) + (if (get-buffer-window cur-buf) + (select-window (get-buffer-window cur-buf))) + (set-buffer cur-buf) + (if wl-stay-folder-window + (wl-folder-toggle-disp-summary 'off wl-queue-folder) + (switch-to-buffer cur-buf)))))) + +(defun wl-folder-empty-trash () + "Empty trash." + (interactive) + (let ((cur-buf (current-buffer)) + (wl-auto-select-first nil) + trash-buf emptied) + (if wl-stay-folder-window + (wl-folder-select-buffer + (wl-summary-get-buffer-create wl-trash-folder))) + (wl-summary-goto-folder-subr wl-trash-folder 'force-update nil nil t) + (setq trash-buf (current-buffer)) + (unwind-protect + (setq emptied (wl-summary-delete-all-msgs)) + (when emptied + (setq wl-thread-entities nil + wl-thread-entity-list nil) + (if wl-summary-cache-use (wl-summary-save-view-cache)) + (wl-summary-msgdb-save)) + (if (get-buffer-window cur-buf) + (select-window (get-buffer-window cur-buf))) + (set-buffer cur-buf) + (if emptied + (wl-folder-set-folder-updated wl-trash-folder '(0 0 0))) + (if wl-stay-folder-window + (wl-folder-toggle-disp-summary 'off wl-trash-folder) + (switch-to-buffer cur-buf)) + (and trash-buf + (kill-buffer trash-buf))))) + +(defun wl-folder-goto-top-of-current-folder () + (if (re-search-backward "^\\([ ]*\\)\\[\\([\\+-]\\)\\]\\(.+\\)\n" nil t) + (beginning-of-line) + (goto-char (point-min)))) + +(defun wl-folder-goto-bottom-of-current-folder (indent) + (if (catch 'done + (while (re-search-forward "^\\([ ]*\\)[^ ]" nil t) + (if (<= (length (wl-match-buffer 1)) + (length indent)) + (throw 'done nil))) + (throw 'done t)) + (goto-char (point-max)))) + +(defsubst wl-folder-update-group (entity diffs &optional is-group) + (let ((path (wl-folder-get-path + wl-folder-entity + (wl-folder-get-entity-id entity) + entity))) + (if (not is-group) + ;; delete itself from path + (setq path (delete (nth (- (length path) 1) path) path))) + (goto-char (point-min)) + (catch 'done + (while path + ;; goto the path line. + (if (or (eq (car path) 0) ; update desktop + (wl-folder-buffer-search-group + (wl-folder-get-petname + (if (stringp (car path)) + (car path) + (wl-folder-get-folder-name-by-id + (car path)))))) + ;; update it. + (wl-folder-update-diff-line diffs) + (throw 'done t)) + (setq path (cdr path)))))) + +(defun wl-folder-maybe-load-folder-list (entity) + (when (null (caddr entity)) + (setcdr (cdr entity) + (elmo-msgdb-flist-load (car entity))) + (when (cddr entity) + (let (diffs) + (save-excursion + (wl-folder-entity-assign-id entity + wl-folder-entity-id-name-hashtb + t) + (setq diffs (wl-fldmgr-add-entity-hashtb (list entity))) + (unless (equal diffs '(0 0 0)) + (wl-folder-update-group (car entity) diffs t))))))) + +(defsubst wl-folder-force-fetch-p (entity) + (cond + ((consp wl-force-fetch-folders) + (wl-string-match-member entity wl-force-fetch-folders)) + (t + wl-force-fetch-folders))) + +(defun wl-folder-jump-to-current-entity (&optional arg) + "Enter the current folder. If optional arg exists, update folder list. " + (interactive "P") + (beginning-of-line) + (let (entity beg end indent opened fname err fld-name) + (cond + ((looking-at wl-folder-group-regexp) + (save-excursion + (setq fname (wl-folder-get-realname (wl-match-buffer 3))) + (setq indent (wl-match-buffer 1)) + (setq opened (wl-match-buffer 2)) + (if (string= opened "+") + (progn + (setq entity (wl-folder-search-group-entity-by-name + fname + wl-folder-entity)) + (setq beg (point)) + (if arg + (wl-folder-update-recursive-current-entity entity) + ;; insert as opened + (setcdr (assoc (car entity) wl-folder-group-alist) t) + (if (eq 'access (cadr entity)) + (wl-folder-maybe-load-folder-list entity)) + (condition-case errobj + (progn + (if (or (wl-folder-force-fetch-p (car entity)) + (and + (eq 'access (cadr entity)) + (null (caddr entity)))) + (wl-folder-update-newest indent entity) + (wl-folder-insert-entity indent entity)) + (wl-highlight-folder-path wl-folder-buffer-cur-path)) + (quit + (setq err t) + (setcdr (assoc fname wl-folder-group-alist) nil)) + (error + (elmo-display-error errobj t) + (ding) + (setq err t) + (setcdr (assoc fname wl-folder-group-alist) nil))) + (if (not err) + (let ((buffer-read-only nil)) + (delete-region (save-excursion (beginning-of-line) + (point)) + (save-excursion (end-of-line) + (+ 1 (point)))))))) + (setq beg (point)) + (end-of-line) + (save-match-data + (setq end + (progn (wl-folder-goto-bottom-of-current-folder indent) + (beginning-of-line) + (point)))) + (setq entity (wl-folder-search-group-entity-by-name + fname + wl-folder-entity)) + (let ((buffer-read-only nil)) + (delete-region beg end)) + (setcdr (assoc (car entity) wl-folder-group-alist) nil) + (wl-folder-insert-entity indent entity) ; insert entity + (forward-line -1) + (wl-highlight-folder-path wl-folder-buffer-cur-path) +; (wl-delete-all-overlays) +; (wl-highlight-folder-current-line) + ))) + ((setq fld-name (wl-folder-entity-name)) + (if wl-on-nemacs + (progn + (wl-folder-set-current-entity-id + (wl-folder-get-entity-from-buffer)) + (setq fld-name (wl-folder-get-realname fld-name))) + (wl-folder-set-current-entity-id + (get-text-property (point) 'wl-folder-entity-id)) + (setq fld-name (wl-folder-get-folder-name-by-id + wl-folder-buffer-cur-entity-id))) + (let ((summary-buf (wl-summary-get-buffer-create fld-name arg)) + error-selecting) + (if wl-stay-folder-window + (wl-folder-select-buffer summary-buf) + (if (and summary-buf + (get-buffer-window summary-buf)) + (delete-window))) + (wl-summary-goto-folder-subr fld-name + (wl-summary-get-sync-range fld-name) + nil arg t))))) + (set-buffer-modified-p nil)) + +(defun wl-folder-close-entity (entity) + (let ((entities (list entity)) + entity-stack) + (while entities + (setq entity (wl-pop entities)) + (cond + ((consp entity) + (setcdr (assoc (car entity) wl-folder-group-alist) nil) + (and entities + (wl-push entities entity-stack)) + (setq entities (nth 2 entity)))) + (unless entities + (setq entities (wl-pop entity-stack)))))) + +(defun wl-folder-update-recursive-current-entity (&optional entity) + (interactive) + (when (wl-folder-buffer-group-p) + (cond + ((string= (wl-match-buffer 2) "+") + (save-excursion + (if entity () + (setq entity + (wl-folder-search-group-entity-by-name + (wl-folder-get-realname (wl-match-buffer 3)) + wl-folder-entity))) + (let ((inhibit-read-only t) + (entities (list entity)) + entity-stack err indent) + (while (and entities (not err)) + (setq entity (wl-pop entities)) + (cond + ((consp entity) + (wl-folder-close-entity entity) + (setcdr (assoc (car entity) wl-folder-group-alist) t) + (unless (wl-folder-buffer-search-group + (wl-folder-get-petname (car entity))) + (error "%s: not found group" (car entity))) + (setq indent (wl-match-buffer 1)) + (if (eq 'access (cadr entity)) + (wl-folder-maybe-load-folder-list entity)) + (beginning-of-line) + (setq err nil) + (save-excursion + (condition-case errobj + (wl-folder-update-newest indent entity) + (quit + (setq err t) + (setcdr (assoc (car entity) wl-folder-group-alist) nil)) + (error + (elmo-display-error errobj t) + (ding) + (setq err t) + (setcdr (assoc (car entity) wl-folder-group-alist) nil))) + (if (not err) + (delete-region (save-excursion (beginning-of-line) + (point)) + (save-excursion (end-of-line) + (+ 1 (point)))))) + ;; + (and entities + (wl-push entities entity-stack)) + (setq entities (nth 2 entity)))) + (unless entities + (setq entities (wl-pop entity-stack))))) + (set-buffer-modified-p nil))) + (t + (wl-folder-jump-to-current-entity))))) + +(defun wl-folder-no-auto-check-folder-p (folder) + (if (stringp folder) + (if (catch 'found + (let ((li wl-auto-check-folder-list)) + (while li + (if (string-match (car li) folder) + (throw 'found t)) + (setq li (cdr li))))) + nil + (catch 'found + (let ((li wl-auto-uncheck-folder-list)) + (while li + (if (string-match (car li) folder) + (throw 'found t)) ; no check! + (setq li (cdr li)))))))) + +(defsubst wl-folder-add-folder-info (pre-value value) + (list + (+ (or (nth 0 pre-value) 0) (or (nth 0 value) 0)) + (+ (or (nth 1 pre-value) 0) (or (nth 1 value) 0)) + (+ (or (nth 2 pre-value) 0) (or (nth 2 value) 0)))) + +(defun wl-folder-check-entity (entity &optional auto) + "Check unsync message number." + (let ((start-pos (point)) + ret-val) + (run-hooks 'wl-folder-check-entity-pre-hook) + (if (and (consp entity) ;; group entity + wl-folder-check-async) ;; very fast + (setq ret-val (wl-folder-check-entity-async entity auto)) + (save-excursion + (cond + ((consp entity) + (let ((flist (if auto + (elmo-delete-if + 'wl-folder-no-auto-check-folder-p + (nth 2 entity)) + (nth 2 entity))) + (wl-folder-check-entity-pre-hook nil) + (wl-folder-check-entity-hook nil) + new unread all) + (while flist + (setq ret-val + (wl-folder-add-folder-info + ret-val + (wl-folder-check-entity (car flist)))) + (setq flist (cdr flist))) + ;(wl-folder-buffer-search-entity (car entity)) + ;(wl-folder-update-line ret-val) + )) + ((and (stringp entity) + (elmo-folder-plugged-p entity)) + (message "Checking \"%s\"" entity) + (setq ret-val (wl-folder-check-one-entity entity)) + (goto-char start-pos) + (sit-for 0)) + (t + (message "Uncheck(unplugged) \"%s\"" entity))))) + (if ret-val + (message "Checking \"%s\" is done." + (if (consp entity) (car entity) entity))) + (run-hooks 'wl-folder-check-entity-hook) + ret-val)) + +;; All contained folders are imap4 and persistent flag, then +;; use server diff. +(defun wl-folder-use-server-diff-p (folder) + (let ((spec (elmo-folder-get-spec folder))) + (cond + ((eq (car spec) 'multi) + (let ((folders (cdr spec))) + (catch 'done + (while folders + (if (wl-folder-use-server-diff-p (car folders)) + (throw 'done t)) + (setq folders (cdr folders))) + nil))) + ((eq (car spec) 'filter) + (wl-folder-use-server-diff-p (nth 2 spec))) + ((eq (car spec) 'imap4) + (and wl-folder-use-server-diff + (elmo-imap4-use-flag-p spec))) + (t nil)))) + +(defun wl-folder-check-one-entity (entity) + (let* ((elmo-use-server-diff (wl-folder-use-server-diff-p entity)) + (nums (condition-case err + (if (wl-string-member entity wl-strict-diff-folders) + (elmo-strict-folder-diff entity) + (elmo-folder-diff entity)) + (error + ;; maybe not exist folder. + (if (not (elmo-folder-exists-p entity)) + (if (not (elmo-folder-creatable-p entity)) + (error "Folder %s is not found" entity) + (if (y-or-n-p + (format "Folder %s does not exist, create it?" + entity)) + (progn + (unless (elmo-create-folder entity) + (error "Create folder failed")) + ;; one more try. + (if (wl-string-member entity wl-strict-diff-folders) + (elmo-strict-folder-diff entity) + (elmo-folder-diff entity))) + (error "Folder is not created"))) + (signal (car err) (cdr err)))))) + unread unsync nomif) + (if (and (eq wl-folder-notify-deleted 'sync) + (car nums) + (or (> 0 (car nums)) (> 0 (cdr nums)))) + (progn + (wl-folder-sync-entity entity) + (setq nums (elmo-folder-diff entity))) + (unless wl-folder-notify-deleted + (setq unsync (if (and (car nums) (> 0 (car nums))) 0 (car nums))) + (setq nomif (if (and (car nums) (> 0 (cdr nums))) 0 (cdr nums))) + (setq nums (cons unsync nomif))) + (wl-folder-entity-hashtb-set wl-folder-entity-hashtb entity + (list (car nums) + (setq + unread + (or + ;; If server diff, All unreads are + ;; treated as unsync. + (if elmo-use-server-diff 0) + (elmo-folder-get-info-unread entity) + (wl-summary-count-unread + (elmo-msgdb-mark-load + (elmo-msgdb-expand-path entity)) + entity))) + (cdr nums)) + (current-buffer))) + (setq wl-folder-info-alist-modified t) + (sit-for 0) + (list (if wl-folder-notify-deleted + (car nums) + (max (or (car nums) 0))) unread (cdr nums)))) + +(defun wl-folder-check-entity-async (entity &optional auto) + (let ((elmo-nntp-groups-async t) + (elist (if auto + (elmo-delete-if + 'wl-folder-no-auto-check-folder-p + (wl-folder-get-entity-list entity)) + (wl-folder-get-entity-list entity))) + (nntp-connection-keys nil) + folder spec-list local-elist net-elist server + ret-val) + (while elist + (if (not (elmo-folder-plugged-p (car elist))) + (message "Uncheck \"%s\"" (car elist)) + (setq spec-list + (elmo-folder-get-primitive-spec-list (elmo-string (car elist)))) + (cond ((assq 'nntp spec-list) + (wl-append net-elist (list (car elist))) + (while spec-list + (when (eq (caar spec-list) 'nntp) + (when (not (string= server (nth 2 (car spec-list)))) + (setq server (nth 2 (car spec-list))) + (message "Checking on \"%s\"" server)) + (setq nntp-connection-keys + (elmo-nntp-get-folders-info-prepare + (car spec-list) + nntp-connection-keys))) + (setq spec-list (cdr spec-list)))) + (t + (wl-append local-elist (list (car elist)))))) + (setq elist (cdr elist))) + ;; check local entity at first + (while (setq folder (pop local-elist)) + (if (not (elmo-folder-plugged-p folder)) + (message "Uncheck \"%s\"" folder) + (message "Checking \"%s\"" folder) + (setq ret-val + (wl-folder-add-folder-info + ret-val + (wl-folder-check-one-entity folder))) + ;;(sit-for 0) + )) + ;; check network entity at last + (when net-elist + (elmo-nntp-get-folders-info nntp-connection-keys) + (while (setq folder (pop net-elist)) + (if (not (elmo-folder-plugged-p folder)) + (message "Uncheck \"%s\"" folder) + (message "Checking \"%s\"" folder) + (setq ret-val + (wl-folder-add-folder-info + ret-val + (wl-folder-check-one-entity folder))) + ;;(sit-for 0) + ))) + ret-val)) + +;; +(defun wl-folder-resume-entity-hashtb-by-finfo (entity-hashtb info-alist) + "Resume unread info for entity alist." + (let (info) + (while info-alist + (setq info (nth 1 (car info-alist))) + (wl-folder-set-entity-info (caar info-alist) + (list (nth 2 info)(nth 3 info)(nth 1 info)) + entity-hashtb) + (setq info-alist (cdr info-alist))))) + +(defun wl-folder-move-path (path) + (let ((fp (if (consp path) + path + ;; path is entity-id + (wl-folder-get-path wl-folder-entity path)))) + (goto-char (point-min)) + (while (and fp + (not (eobp))) + (when (equal (car fp) + (wl-folder-get-entity-from-buffer t)) + (setq fp (cdr fp)) + (setq wl-folder-buffer-cur-point (point))) + (forward-line 1)) + (and wl-folder-buffer-cur-point + (goto-char wl-folder-buffer-cur-point)))) + +(defun wl-folder-set-current-entity-id (entity-id) + (let ((buf (get-buffer wl-folder-buffer-name))) + (if buf + (save-excursion + (set-buffer buf) + (setq wl-folder-buffer-cur-entity-id entity-id) + (setq wl-folder-buffer-cur-path (wl-folder-get-path wl-folder-entity + entity-id)) + (wl-highlight-folder-path wl-folder-buffer-cur-path) + (and wl-folder-move-cur-folder + wl-folder-buffer-cur-point + (goto-char wl-folder-buffer-cur-point)))) + (if (eq (current-buffer) buf) + (and wl-folder-move-cur-folder + wl-folder-buffer-cur-point + (goto-char wl-folder-buffer-cur-point))))) + +(defun wl-folder-check-current-entity () + "Check folder at position. +If current line is group folder, check all sub entries." + (interactive) + (let* ((entity-name (wl-folder-get-entity-from-buffer)) + (group (wl-folder-buffer-group-p)) + (desktop (string= entity-name wl-folder-desktop-name))) + (when entity-name + (wl-folder-check-entity + (if group + (wl-folder-search-group-entity-by-name entity-name + wl-folder-entity) + entity-name) + desktop)))) + +(defun wl-folder-sync-entity (entity &optional unread-only) + "Synchronize the msgdb of ENTITY." + (cond + ((consp entity) + (let ((flist (nth 2 entity))) + (while flist + (wl-folder-sync-entity (car flist) unread-only) + (setq flist (cdr flist))))) + ((stringp entity) + (let ((nums (wl-folder-get-entity-info entity)) + (wl-summary-highlight (if (or (wl-summary-sticky-p entity) + (wl-summary-always-sticky-folder-p + entity)) + wl-summary-highlight)) + wl-auto-select-first new unread) + (setq new (or (car nums) 0)) + (setq unread (or (cadr nums) 0)) + (if (or (not unread-only) + (or (< 0 new) (< 0 unread))) + (save-window-excursion + (save-excursion + (wl-summary-goto-folder-subr entity + (wl-summary-get-sync-range entity) + nil nil nil t) + (wl-summary-exit)))))))) + +(defun wl-folder-sync-current-entity (&optional unread-only) + "Synchronize the folder at position. +If current line is group folder, check all subfolders." + (interactive "P") + (save-excursion + (let ((entity-name (wl-folder-get-entity-from-buffer)) + (group (wl-folder-buffer-group-p))) + (when (and entity-name + (y-or-n-p (format "Sync %s?" entity-name))) + (wl-folder-sync-entity + (if group + (wl-folder-search-group-entity-by-name entity-name + wl-folder-entity) + entity-name) + unread-only) + (message "Syncing %s is done!" entity-name))))) + +(defun wl-folder-mark-as-read-all-entity (entity) + "Mark as read all messages in the ENTITY" + (cond + ((consp entity) + (let ((flist (nth 2 entity))) + (while flist + (wl-folder-mark-as-read-all-entity (car flist)) + (setq flist (cdr flist))))) + ((stringp entity) + (let ((nums (wl-folder-get-entity-info entity)) + (wl-summary-highlight (if (or (wl-summary-sticky-p entity) + (wl-summary-always-sticky-folder-p + entity)) + wl-summary-highlight)) + wl-auto-select-first new unread) + (setq new (or (car nums) 0)) + (setq unread (or (cadr nums) 0)) + (if (or (< 0 new) (< 0 unread)) + (save-window-excursion + (save-excursion + (wl-summary-goto-folder-subr entity + (wl-summary-get-sync-range entity) + nil) + (wl-summary-mark-as-read-all) + (wl-summary-exit))) + (sit-for 0)))))) + +(defun wl-folder-mark-as-read-all-current-entity () + "Mark as read all messages in the folder at position. +If current line is group folder, all subfolders are marked." + (interactive) + (save-excursion + (let ((entity-name (wl-folder-get-entity-from-buffer)) + (group (wl-folder-buffer-group-p)) + summary-buf) + (when (and entity-name + (y-or-n-p (format "Mark all messages in %s as read?" entity-name))) + (wl-folder-mark-as-read-all-entity + (if group + (wl-folder-search-group-entity-by-name entity-name + wl-folder-entity) + entity-name)) + (message "All messages in %s are marked!" entity-name))))) + +(defun wl-folder-check-region (beg end) + (interactive "r") + (goto-char beg) + (beginning-of-line) + (setq beg (point)) + (goto-char end) + (beginning-of-line) + (setq end (point)) + (goto-char beg) + (let ((inhibit-read-only t) + entity) + (while (< (point) end) + ;; normal folder entity + (if (looking-at "^[\t ]*\\([^\\[]+\\):\\(.*\\)\n") + (save-excursion + (setq entity (wl-folder-get-entity-from-buffer)) + (if (not (elmo-folder-plugged-p entity)) + (message "Uncheck %s" entity) + (message "Checking %s" entity) + (wl-folder-check-one-entity entity) + (sit-for 0)))) + (forward-line 1))) + (message "")) + +(defun wl-folder-sync-region (beg end) + (interactive "r") + (goto-char beg) + (beginning-of-line) + (setq beg (point)) + (goto-char end) + (end-of-line) + (setq end (point)) + (goto-char beg) + (while (< (point) end) + ;; normal folder entity + (if (looking-at "^[\t ]*\\([^\\[]+\\):\\(.*\\)\n") + (save-excursion + (let ((inhibit-read-only t) + entity) + (setq entity (wl-folder-get-entity-from-buffer)) + (wl-folder-sync-entity entity) + (message "Syncing %s is done!" entity) + (sit-for 0)))) + (forward-line 1)) + (message "")) + +(defun wl-folder-mark-as-read-all-region (beg end) + (interactive "r") + (goto-char beg) + (beginning-of-line) + (setq beg (point)) + (goto-char end) + (end-of-line) + (setq end (point)) + (goto-char beg) + (while (< (point) end) + ;; normal folder entity + (if (looking-at "^[\t ]*\\([^\\[]+\\):\\(.*\\)\n") + (save-excursion + (let ((inhibit-read-only t) + entity) + (setq entity (wl-folder-get-entity-from-buffer)) + (wl-folder-mark-as-read-all-entity entity) + (message "All messages in %s are marked!" entity) + (sit-for 0)))) + (forward-line 1)) + (message "")) + +(defsubst wl-create-access-init-load-p (folder) + (let ((no-load-regexp (when (and + (not wl-folder-init-load-access-folders) + wl-folder-init-no-load-access-folders) + (mapconcat 'identity + wl-folder-init-no-load-access-folders + "\\|"))) + (load-regexp (and wl-folder-init-load-access-folders + (mapconcat 'identity + wl-folder-init-load-access-folders + "\\|")))) + (cond (load-regexp (string-match load-regexp folder)) + (t (not (and no-load-regexp + (string-match no-load-regexp folder))))))) + +(defun wl-create-access-folder-entity (name) + (let (flists flist) + (when (wl-create-access-init-load-p name) + (setq flists (elmo-msgdb-flist-load name)) ; load flist. + (setq flist (car flists)) + (while flist + (when (consp (car flist)) + (setcdr (cdar flist) + (wl-create-access-folder-entity (caar flist)))) + (setq flist (cdr flist))) + flists))) + +(defun wl-create-folder-entity-from-buffer () + "Create folder entity recursively." + (cond + ((looking-at "^[ \t]*$") ; blank line + (goto-char (+ 1(match-end 0))) + 'ignore) + ((looking-at "^#.*$") ; comment + (goto-char (+ 1 (match-end 0))) + 'ignore) + ((looking-at "^[\t ]*\\(.+\\)[\t ]*{[\t ]*$") ; group definition + (let (name entity flist) + (setq name (wl-match-buffer 1)) + (goto-char (+ 1 (match-end 0))) + (while (setq entity (wl-create-folder-entity-from-buffer)) + (unless (eq entity 'ignore) + (wl-append flist (list entity)))) + (if (looking-at "^[\t ]*}[\t ]*$") ; end of group + (progn + (goto-char (+ 1 (match-end 0))) + (if (wl-string-assoc name wl-folder-petname-alist) + (error "%s already defined as petname" name)) + (list name 'group flist)) + (error "Syntax error in folder definition")))) + ((looking-at "^[\t ]*\\([^\t \n]+\\)[\t ]*/$") ; access it! + (let (name) + (setq name (wl-match-buffer 1)) + (goto-char (+ 1 (match-end 0))) +; (condition-case () +; (unwind-protect +; (setq flist (elmo-list-folders name))) +; (error (message "Access to folder %s failed." name))) +;; (setq flist (elmo-msgdb-flist-load name)) ; load flist. +;; (setq unsublist (nth 1 flist)) +;; (setq flist (car flist)) +;; (list name 'access flist unsublist))) + (append (list name 'access) (wl-create-access-folder-entity name)))) + ;((looking-at "^[\t ]*\\([^\t \n}]+\\)[\t ]*\\(\"[^\"]*\"\\)?[\t ]*$") ; normal folder entity + ((looking-at "^[\t ]*=[ \t]+\\([^\n]+\\)$"); petname definition + (goto-char (+ 1 (match-end 0))) + (let ((rest (elmo-match-buffer 1)) + petname) + (when (string-match "\\(\"[^\"]*\"\\)[\t ]*$" rest) + (setq petname (elmo-delete-char ?\" (elmo-match-string 1 rest))) + (setq rest (substring rest 0 (match-beginning 0)))) + (when (string-match "^[\t ]*\\(.*[^\t ]+\\)[\t ]+$" rest) + (wl-folder-append-petname (elmo-match-string 1 rest) + petname)) + 'ignore)) + ((looking-at "^[ \t]*}[ \t]*$") ; end of group + nil) + ((looking-at "^.*$") ; normal folder entity + (goto-char (+ 1 (match-end 0))) + (let ((rest (elmo-match-buffer 0)) + realname petname) + (if (string-match "\\(\"[^\"]*\"\\)[\t ]*$" rest) + (progn + (setq petname (elmo-delete-char ?\" (elmo-match-string 1 rest))) + (setq rest (substring rest 0 (match-beginning 0))) + (when (string-match "^[\t ]*\\(.*[^\t ]+\\)[\t ]+$" rest) + (wl-folder-append-petname + (setq realname (elmo-match-string 1 rest)) + petname) + realname)) + (if (string-match "^[\t ]*\\(.+\\)$" rest) + (elmo-match-string 1 rest) + rest)))))) + +(defun wl-folder-create-folder-entity () + "Create folder entries." + (let ((tmp-buf (get-buffer-create " *wl-folder-tmp*")) + entity ret-val) + (condition-case () + (progn + (set-buffer tmp-buf) + (erase-buffer) + (insert-file-contents wl-folders-file) + (goto-char (point-min)) + (while (and (not (eobp)) + (setq entity (wl-create-folder-entity-from-buffer))) + (unless (eq entity 'ignore) + (wl-append ret-val (list entity)))) + (kill-buffer tmp-buf)) + (file-error nil)) + (setq ret-val (list wl-folder-desktop-name 'group ret-val)))) + +(defun wl-folder-entity-assign-id (entity &optional hashtb on-noid) + (let* ((hashtb (or hashtb + (setq wl-folder-entity-id-name-hashtb + (elmo-make-hash wl-folder-entity-id)))) + (entities (list entity)) + entity-stack) + (while entities + (setq entity (wl-pop entities)) + (cond + ((consp entity) + (when (not (and on-noid + (get-text-property 0 + 'wl-folder-entity-id + (car entity)))) + (put-text-property 0 (length (car entity)) + 'wl-folder-entity-id + wl-folder-entity-id + (car entity)) + (wl-folder-set-id-name wl-folder-entity-id + (car entity) hashtb)) + (and entities + (wl-push entities entity-stack)) + (setq entities (nth 2 entity))) + ((stringp entity) + (when (not (and on-noid + (get-text-property 0 + 'wl-folder-entity-id + entity))) + (put-text-property 0 (length entity) + 'wl-folder-entity-id + wl-folder-entity-id + entity) + (wl-folder-set-id-name wl-folder-entity-id + entity hashtb)))) + (setq wl-folder-entity-id (+ 1 wl-folder-entity-id)) + (unless entities + (setq entities (wl-pop entity-stack)))))) + +(defun wl-folder-click (e) + (interactive "e") + (mouse-set-point e) + (beginning-of-line) + (save-excursion + (wl-folder-jump-to-current-entity))) + +(defun wl-folder-select-buffer (buffer) + (let ((gbw (get-buffer-window buffer)) + ret-val) + (if gbw + (progn (select-window gbw) + (setq ret-val t)) + (condition-case () + (unwind-protect + (split-window-horizontally wl-folder-window-width) + (other-window 1)) + (error nil))) + (set-buffer buffer) + (switch-to-buffer buffer) + ret-val + )) + +(defun wl-folder-toggle-disp-summary (&optional arg folder) + (interactive) + (if (or (and folder (assoc folder wl-folder-group-alist)) + (and (interactive-p) (wl-folder-buffer-group-p))) + (error "This command is not available on Group")) + (beginning-of-line) + (let (wl-auto-select-first) + (cond + ((eq arg 'on) + (setq wl-folder-buffer-disp-summary t)) + ((eq arg 'off) + (setq wl-folder-buffer-disp-summary nil) + ;; hide wl-summary window. + (let ((cur-buf (current-buffer)) + (summary-buffer (wl-summary-get-buffer folder))) + (wl-folder-select-buffer summary-buffer) + (delete-window) + (select-window (get-buffer-window cur-buf)))) + (t + (setq wl-folder-buffer-disp-summary + (not wl-folder-buffer-disp-summary)) + (let ((cur-buf (current-buffer)) + folder-name) + (when (looking-at "^[ ]*\\([^\\[].+\\):.*\n") + (setq folder-name (wl-folder-get-entity-from-buffer)) + (if wl-folder-buffer-disp-summary + (progn + (wl-folder-select-buffer + (wl-summary-get-buffer-create folder-name)) + (unwind-protect + (wl-summary-goto-folder-subr folder-name 'no-sync nil) + (select-window (get-buffer-window cur-buf)))) + (wl-folder-select-buffer (wl-summary-get-buffer folder-name)) + (delete-window) + (select-window (get-buffer-window cur-buf))))))))) + +(defun wl-folder-prev-unsync () + "move cursor to the previous unsync folder." + (interactive) + (let (start-point) + (setq start-point (point)) + (beginning-of-line) + (if (re-search-backward wl-folder-unsync-regexp nil t) + (beginning-of-line) + (goto-char start-point) + (message "No more unsync folder")))) + +(defun wl-folder-next-unsync (&optional plugged) + "move cursor to the next unsync." + (interactive) + (let (start-point entity) + (setq start-point (point)) + (end-of-line) + (if (catch 'found + (while (re-search-forward wl-folder-unsync-regexp nil t) + (if (or (wl-folder-buffer-group-p) + (not plugged) + (setq entity + (wl-folder-get-realname + (wl-folder-folder-name))) + (elmo-folder-plugged-p entity)) + (throw 'found t)))) + (beginning-of-line) + (goto-char start-point) + (message "No more unsync folder")))) + +(defun wl-folder-prev-unread (&optional group) + "move cursor to the previous unread folder." + (interactive "P") + (let (start-point) + (setq start-point (point)) + (beginning-of-line) + (if (re-search-backward (wl-folder-unread-regex group) nil t) + (progn + (beginning-of-line) + (wl-folder-folder-name)) + (goto-char start-point) + (message "No more unread folder") + nil))) + +(defun wl-folder-next-unread (&optional group) + "move cursor to the next unread folder." + (interactive "P") + (let (start-point) + (setq start-point (point)) + (end-of-line) + (if (re-search-forward (wl-folder-unread-regex group) nil t) + (progn + (beginning-of-line) + (wl-folder-folder-name)) + (goto-char start-point) + (message "No more unread folder") + nil))) + +(defun wl-folder-mode () + "Major mode for Wanderlust Folder. +See info under Wanderlust for full documentation. + +Special commands: +\\{wl-folder-mode-map} + +Entering Folder mode calls the value of `wl-folder-mode-hook'." + (interactive) + (setq major-mode 'wl-folder-mode) + (setq mode-name "Folder") + (use-local-map wl-folder-mode-map) + (setq buffer-read-only t) + (setq inhibit-read-only nil) + (setq truncate-lines t) + (when wl-show-plug-status-on-modeline + (setq mode-line-format (wl-make-modeline))) + (easy-menu-add wl-folder-mode-menu) + (wl-xmas-setup-folder) + (run-hooks 'wl-folder-mode-hook)) + +(defun wl-folder-append-petname (realname petname) + (let (pentry) + ;; check group name. + (if (wl-folder-search-group-entity-by-name petname wl-folder-entity) + (error "%s already defined as group name" petname)) + (when (setq pentry (wl-string-assoc realname wl-folder-petname-alist)) + (setq wl-folder-petname-alist + (delete pentry wl-folder-petname-alist))) + (wl-append wl-folder-petname-alist + (list (cons realname petname))))) + +(defun wl-folder (&optional arg) + (interactive "P") + (let (initialize) +; (delete-other-windows) + (if (get-buffer wl-folder-buffer-name) + (switch-to-buffer wl-folder-buffer-name) + (switch-to-buffer (get-buffer-create wl-folder-buffer-name)) + (setq mode-line-buffer-identification '("Wanderlust: %12b")) + (wl-folder-mode) + (wl-folder-init) + (wl-folder-init-icons) + (set-buffer wl-folder-buffer-name) + (let ((inhibit-read-only t) + (buffer-read-only nil)) + (erase-buffer) + (setcdr (assoc (car wl-folder-entity) wl-folder-group-alist) t) + (save-excursion + (wl-folder-insert-entity " " wl-folder-entity))) + (set-buffer-modified-p nil) + (sit-for 0) + (setq initialize t)) + (if (not arg) + (progn + (run-hooks 'wl-auto-check-folder-pre-hook) + (cond + ((eq wl-auto-check-folder-name 'none)) + ((or (consp wl-auto-check-folder-name) + (stringp wl-auto-check-folder-name)) + (let ((folder-list (if (consp wl-auto-check-folder-name) + wl-auto-check-folder-name + (list wl-auto-check-folder-name))) + entity) + (while folder-list + (if (setq entity (wl-folder-search-entity-by-name + (car folder-list) + wl-folder-entity)) + (wl-folder-check-entity entity 'auto)) + (setq folder-list (cdr folder-list))))) + (t + (wl-folder-check-entity wl-folder-entity 'auto))) + (run-hooks 'wl-auto-check-folder-hook))) + initialize)) + +(defun wl-folder-set-folder-updated (name value) + (save-excursion + (let (buf) + (if (setq buf (get-buffer wl-folder-buffer-name)) + (wl-folder-entity-hashtb-set + wl-folder-entity-hashtb name value buf)) +;; (elmo-folder-set-info-hashtb (elmo-string name) +;; nil +;; (nth 2 value) +;; (nth 0 value) +;; (nth 1 value)) + (setq wl-folder-info-alist-modified t)))) + +(defun wl-folder-calc-finfo (entity) + ;; calcurate finfo without inserting. + (let ((entities (list entity)) + entity-stack + new unread all nums) + (while entities + (setq entity (wl-pop entities)) + (cond + ((consp entity) + (and entities + (wl-push entities entity-stack)) + (setq entities (nth 2 entity))) + ((stringp entity) + (setq nums (wl-folder-get-entity-info entity)) + (setq new (+ (or new 0) (or (nth 0 nums) 0))) + (setq unread (+ (or unread 0) + (or (and (nth 0 nums)(nth 1 nums) + (+ (nth 0 nums)(nth 1 nums))) 0))) + (setq all (+ (or all 0) (or (nth 2 nums) 0))))) + (unless entities + (setq entities (wl-pop entity-stack)))) + (list new unread all))) + +(defsubst wl-folder-make-save-access-list (list) + (mapcar '(lambda (x) + (cond + ((consp x) + (list (elmo-string (car x)) 'access)) + (t + (elmo-string x)))) + list)) + +(defun wl-folder-update-newest (indent entity) + (let (ret-val new unread all) + (cond + ((consp entity) + (let ((inhibit-read-only t) + (buffer-read-only nil) + (flist (nth 2 entity)) + (as-opened (cdr (assoc (car entity) wl-folder-group-alist))) + beg + ) + (setq beg (point)) + (if as-opened + (let (update-flist flist-unsub new-flist removed group-name-end) + (when (and (eq (cadr entity) 'access) + (elmo-folder-plugged-p (car entity))) + (message "Fetching folder entries...") + (when (setq new-flist + (elmo-list-folders + (elmo-string (car entity)) + (wl-string-member + (car entity) + wl-folder-hierarchy-access-folders))) + (setq update-flist + (wl-folder-update-access-group entity new-flist)) + (setq flist (nth 1 update-flist)) + (when (car update-flist) ;; diff + (setq flist-unsub (nth 2 update-flist)) + (setq removed (nth 3 update-flist)) + (elmo-msgdb-flist-save + (car entity) + (list + (wl-folder-make-save-access-list flist) + (wl-folder-make-save-access-list flist-unsub))) + (wl-folder-entity-assign-id + entity + wl-folder-entity-id-name-hashtb + t) + (setq wl-folder-entity-hashtb + (wl-folder-create-entity-hashtb + entity + wl-folder-entity-hashtb + t)) + (setq wl-folder-newsgroups-hashtb + (or + (wl-folder-create-newsgroups-hashtb + entity nil) + wl-folder-newsgroups-hashtb)))) + (message "Fetching folder entries...done.")) + (wl-folder-insert-entity indent entity)))))))) + +(defun wl-folder-insert-entity (indent entity &optional onlygroup) + (let (ret-val new unread all) + (cond + ((consp entity) + (let ((inhibit-read-only t) + (buffer-read-only nil) + (flist (nth 2 entity)) + (as-opened (cdr (assoc (car entity) wl-folder-group-alist))) + beg + ) +; (insert indent "[" (if as-opened "-" "+") "]" (car entity) "\n") +; (save-excursion (forward-line -1) +; (wl-highlight-folder-current-line)) + (setq beg (point)) + (if (and as-opened + (not onlygroup)) + (let (update-flist flist-unsub new-flist removed group-name-end) +; (when (and (eq (cadr entity) 'access) +; newest) +; (message "fetching folder entries...") +; (when (setq new-flist +; (elmo-list-folders +; (elmo-string (car entity)) +; (wl-string-member +; (car entity) +; wl-folder-hierarchy-access-folders) +; )) +; (setq update-flist +; (wl-folder-update-access-group entity new-flist)) +; (setq flist (nth 1 update-flist)) +; (when (car update-flist) ;; diff +; (setq flist-unsub (nth 2 update-flist)) +; (setq removed (nth 3 update-flist)) +; (elmo-msgdb-flist-save +; (car entity) +; (list +; (wl-folder-make-save-access-list flist) +; (wl-folder-make-save-access-list flist-unsub))) +; ;; +; ;; reconstruct wl-folder-entity-id-name-hashtb and +; ;; wl-folder-entity-hashtb +; ;; +; (wl-folder-entity-assign-id +; entity +; wl-folder-entity-id-name-hashtb +; t) +; (setq wl-folder-entity-hashtb +; (wl-folder-create-entity-hashtb +; entity +; wl-folder-entity-hashtb +; t)) +; (setq wl-folder-newsgroups-hashtb +; (or +; (wl-folder-create-newsgroups-hashtb +; entity nil) +; wl-folder-newsgroups-hashtb)))) +; (message "fetching folder entries...done.")) + (insert indent "[" (if as-opened "-" "+") "]" + (wl-folder-get-petname (car entity))) + (setq group-name-end (point)) + (insert ":0/0/0\n") + (put-text-property beg (point) 'wl-folder-entity-id + (get-text-property 0 'wl-folder-entity-id + (car entity))) + (when removed + (setq beg (point)) + (while removed + (insert indent " " + wl-folder-removed-mark + (if (listp (car removed)) + (concat "[+]" (caar removed)) + (car removed)) + "\n") + (save-excursion (forward-line -1) + (wl-highlight-folder-current-line)) + (setq removed (cdr removed))) + (remove-text-properties beg (point) '(wl-folder-entity-id))) + (let* ((len (length flist)) + (mes (> len 100)) + (i 0)) + (while flist + (setq ret-val + (wl-folder-insert-entity + (concat indent " ") (car flist))) + (setq new (+ (or new 0) (or (nth 0 ret-val) 0))) + (setq unread (+ (or unread 0) (or (nth 1 ret-val) 0))) + (setq all (+ (or all 0) (or (nth 2 ret-val) 0))) + (when mes + (setq i (1+ i)) + (and (zerop (% i 10)) + (elmo-display-progress + 'wl-folder-insert-entity "Inserting group %s..." + (/ (* i 100) len) (car entity)))) + (setq flist (cdr flist))) + (when mes (message ""))) + (save-excursion + (goto-char group-name-end) + (delete-region (point) (save-excursion (end-of-line) + (point))) + (insert (format ":%d/%d/%d" (or new 0) + (or unread 0) (or all 0))) + (setq ret-val (list new unread all)) + (wl-highlight-folder-current-line ret-val))) + (setq ret-val (wl-folder-calc-finfo entity)) + (insert indent "[" (if as-opened "-" "+") "]" + (wl-folder-get-petname (car entity)) + (format ":%d/%d/%d" + (or (nth 0 ret-val) 0) + (or (nth 1 ret-val) 0) + (or (nth 2 ret-val) 0)) + "\n") + (put-text-property beg (point) 'wl-folder-entity-id + (get-text-property 0 'wl-folder-entity-id + (car entity))) + (save-excursion (forward-line -1) + (wl-highlight-folder-current-line ret-val))))) + ((stringp entity) + (let* ((inhibit-read-only t) + (buffer-read-only nil) + (nums (wl-folder-get-entity-info entity)) + beg) + (setq beg (point)) + (insert indent (wl-folder-get-petname entity) + (format ":%s/%s/%s\n" + (or (setq new (nth 0 nums)) "*") + (or (setq unread (and (nth 0 nums)(nth 1 nums) + (+ (nth 0 nums)(nth 1 nums)))) + "*") + (or (setq all (nth 2 nums)) "*"))) + (put-text-property beg (point) 'wl-folder-entity-id + (get-text-property 0 'wl-folder-entity-id entity)) + (save-excursion (forward-line -1) + (wl-highlight-folder-current-line nums)) + (setq ret-val (list new unread all))))) + (set-buffer-modified-p nil) + ret-val)) + +(defun wl-folder-check-all () + (interactive) + (wl-folder-check-entity wl-folder-entity)) + +(defun wl-folder-entity-hashtb-set (entity-hashtb name value buffer) + (let (cur-val + (new-diff 0) + (unread-diff 0) + (all-diff 0) + diffs + entity-list) + (setq cur-val (wl-folder-get-entity-info name entity-hashtb)) + (setq new-diff (- (or (nth 0 value) 0) (or (nth 0 cur-val) 0))) + (setq unread-diff + (+ new-diff + (- (or (nth 1 value) 0) (or (nth 1 cur-val) 0)))) + (setq all-diff (- (or (nth 2 value) 0) (or (nth 2 cur-val) 0))) + (setq diffs (list new-diff unread-diff all-diff)) + (unless (and (nth 0 cur-val) + (equal diffs '(0 0 0))) + (wl-folder-set-entity-info name value entity-hashtb) + (save-match-data + (save-excursion + (set-buffer buffer) + (setq entity-list (wl-folder-search-entity-list-by-name + name wl-folder-entity)) + (while entity-list + (wl-folder-update-group (car entity-list) diffs) + (setq entity-list (cdr entity-list))) + (goto-char (point-min)) + (while (wl-folder-buffer-search-entity name) + (wl-folder-update-line value))))))) + +(defun wl-folder-update-unread (folder unread) + (save-window-excursion + (let ((buf (get-buffer wl-folder-buffer-name)) + cur-unread + (unread-diff 0) + ;;(fld (elmo-string folder)) + value newvalue entity-list) + ;; Update folder-info + ;;(elmo-folder-set-info-hashtb fld nil nil nil unread) + (setq cur-unread (or (nth 1 (wl-folder-get-entity-info folder)) 0)) + (setq unread-diff (- (or unread 0) cur-unread)) + (setq value (wl-folder-get-entity-info folder)) + + (setq newvalue (list (nth 0 value) + unread + (nth 2 value))) + (wl-folder-set-entity-info folder newvalue) + (setq wl-folder-info-alist-modified t) + (when (and buf + (not (eq unread-diff 0))) + (save-match-data + (save-excursion + (set-buffer buf) + (save-excursion + (setq entity-list (wl-folder-search-entity-list-by-name + folder wl-folder-entity)) + (while entity-list + (wl-folder-update-group (car entity-list) (list 0 + unread-diff + 0)) + (setq entity-list (cdr entity-list))) + (goto-char (point-min)) + (while (wl-folder-buffer-search-entity folder) + (wl-folder-update-line newvalue))))))))) + +(defun wl-folder-create-entity-hashtb (entity &optional hashtb reconst) + (let* ((hashtb (or hashtb (elmo-make-hash wl-folder-entity-id))) + (entities (list entity)) + entity-stack) + (while entities + (setq entity (wl-pop entities)) + (cond + ((consp entity) + (and entities + (wl-push entities entity-stack)) + (setq entities (nth 2 entity))) + ((stringp entity) + (when (not (and reconst + (wl-folder-get-entity-info entity))) + (wl-folder-set-entity-info entity + nil + hashtb)))) + (unless entities + (setq entities (wl-pop entity-stack)))) + hashtb)) + +;; Unsync number is reserved. +;; (defun wl-folder-reconstruct-entity-hashtb (entity &optional hashtb id-name) +;; (let* ((hashtb (or hashtb (elmo-make-hash wl-folder-entity-id))) +;; (entities (list entity)) +;; entity-stack) +;; (while entities +;; (setq entity (wl-pop entities)) +;; (cond +;; ((consp entity) +;; (if id-name +;; (wl-folder-set-id-name (wl-folder-get-entity-id (car entity)) +;; (car entity))) +;; (and entities +;; (wl-push entities entity-stack)) +;; (setq entities (nth 2 entity)) +;; ) +;; ((stringp entity) +;; (wl-folder-set-entity-info entity +;; (wl-folder-get-entity-info entity) +;; hashtb) +;; (if id-name +;; (wl-folder-set-id-name (wl-folder-get-entity-id entity) +;; entity)))) +;; (unless entities +;; (setq entities (wl-pop entity-stack)))) +;; hashtb)) + +(defun wl-folder-create-newsgroups-from-nntp-access2 (entity) + (let ((flist (nth 2 entity)) + folders) + (and + (setq folders + (delq + nil + (mapcar + '(lambda (fld) + (if (consp fld) + (wl-folder-create-newsgroups-from-nntp-access2 fld) + (nth 1 (elmo-folder-get-spec fld)))) + flist))) + (elmo-nntp-make-groups-hashtb folders 1024)) + nil)) + +(defun wl-folder-create-newsgroups-from-nntp-access (entity) + (let ((flist (nth 2 entity)) + folders) + (while flist + (wl-append folders + (cond + ((consp (car flist)) + (wl-folder-create-newsgroups-from-nntp-access (car flist))) + (t + (list (nth 1 (elmo-folder-get-spec (car flist))))))) + (setq flist (cdr flist))) + folders)) + +(defun wl-folder-create-newsgroups-hashtb (entity &optional is-list info) + (let ((entities (if is-list entity (list entity))) + entity-stack spec-list folders fld make-hashtb) + (and info (message "Creating newsgroups...")) + (while entities + (setq entity (wl-pop entities)) + (cond + ((consp entity) + (if (eq (nth 1 entity) 'access) + (when (eq (elmo-folder-get-type (car entity)) 'nntp) + (wl-append folders + (wl-folder-create-newsgroups-from-nntp-access entity)) + (setq make-hashtb t)) + (and entities + (wl-push entities entity-stack)) + (setq entities (nth 2 entity)))) + ((stringp entity) + (setq spec-list (elmo-folder-get-primitive-spec-list entity)) + (while spec-list + (when (and (eq (caar spec-list) 'nntp) + (setq fld (nth 1 (car spec-list)))) + (wl-append folders (list (elmo-string fld)))) + (setq spec-list (cdr spec-list))))) + (unless entities + (setq entities (wl-pop entity-stack)))) + (and info (message "Creating newsgroups...done")) + (if (or folders make-hashtb) + (elmo-nntp-make-groups-hashtb folders)))) + +(defun wl-folder-get-path (entity target-id &optional string) + (let* ((entities (list entity)) + entity-stack result-path) + (reverse + (catch 'done + (while entities + (setq entity (wl-pop entities)) + (cond + ((consp entity) + (if (and (or (not string) (string= string (car entity))) + ;; don't use eq, `id' is string on Nemacs. + (equal target-id (wl-folder-get-entity-id (car entity)))) + (throw 'done + (wl-push target-id result-path)) + (wl-push (wl-folder-get-entity-id (car entity)) result-path)) + (wl-push entities entity-stack) + (setq entities (nth 2 entity))) + ((stringp entity) + (if (and (or (not string) (string= string entity)) + ;; don't use eq, `id' is string on Nemacs. + (equal target-id (wl-folder-get-entity-id entity))) + (throw 'done + (wl-push target-id result-path))))) + (unless entities + (while (and entity-stack + (not entities)) + (setq result-path (cdr result-path)) + (setq entities (wl-pop entity-stack))))))))) + +(defun wl-folder-create-group-alist (entity) + (if (consp entity) + (let ((flist (nth 2 entity)) cur-alist append-alist) + (setq cur-alist (list (cons (car entity) nil))) + (while flist + (if (consp (car flist)) + (wl-append append-alist + (wl-folder-create-group-alist (car flist)))) + (setq flist (cdr flist))) + (append cur-alist append-alist)))) + +(defun wl-folder-init-info-hashtb () + (let ((info-alist (and wl-folder-info-save + (elmo-msgdb-finfo-load)))) + (elmo-folder-info-make-hashtb + info-alist + wl-folder-entity-hashtb))) +;; (wl-folder-resume-entity-hashtb-by-finfo +;; wl-folder-entity-hashtb +;; info-alist))) + +(defun wl-folder-cleanup-variables () + (setq wl-folder-entity nil + wl-folder-entity-hashtb nil + wl-folder-entity-id-name-hashtb nil + wl-folder-group-alist nil + wl-folder-petname-alist nil + wl-folder-newsgroups-hashtb nil + wl-fldmgr-cut-entity-list nil + wl-fldmgr-modified nil + wl-fldmgr-modified-access-list nil + wl-score-cache nil + )) + +(defun wl-make-plugged-alist () + (let ((entity-list (wl-folder-get-entity-list wl-folder-entity)) + (add (not wl-reset-plugged-alist))) + (while entity-list + (elmo-folder-set-plugged + (elmo-string (car entity-list)) wl-plugged add) + (setq entity-list (cdr entity-list))) + ;; smtp posting server + (when wl-smtp-posting-server + (elmo-set-plugged wl-plugged + wl-smtp-posting-server ; server + (or (and (boundp 'smtp-service) smtp-service) + "smtp") ; port + nil nil "smtp" add)) + ;; nntp posting server + (when wl-nntp-posting-server + (elmo-set-plugged wl-plugged + wl-nntp-posting-server + elmo-default-nntp-port + nil nil "nntp" add)) + (wl-plugged-init-icons) + ;; user setting + (run-hooks 'wl-make-plugged-hook))) + +(defvar wl-folder-init-func 'wl-local-folder-init) + +(defun wl-folder-init () + (interactive) + (funcall wl-folder-init-func)) + +(defun wl-local-folder-init () + (message "Initializing folder...") + (save-excursion + (let* ((entity (wl-folder-create-folder-entity)) + (inhibit-read-only t)) + (setq wl-folder-entity entity) + (setq wl-folder-entity-id 0) + (wl-folder-entity-assign-id wl-folder-entity) + (setq wl-folder-entity-hashtb + (wl-folder-create-entity-hashtb entity)) + (setq wl-folder-group-alist + (wl-folder-create-group-alist entity)) + (setq wl-folder-newsgroups-hashtb + (wl-folder-create-newsgroups-hashtb wl-folder-entity)) + (wl-folder-init-info-hashtb) + (setq wl-folder-buffer-cur-entity-id nil + wl-folder-buffer-cur-path nil + wl-folder-buffer-cur-point nil))) + (message "Initializing folder...done.")) + +(defun wl-folder-get-realname (petname) + (or (car + (wl-string-rassoc + petname + wl-folder-petname-alist)) + petname)) + +(defun wl-folder-get-petname (folder) + (or (cdr + (wl-string-assoc + folder + wl-folder-petname-alist)) + folder)) + +(defun wl-folder-get-entity-with-petname () + (let ((alist wl-folder-petname-alist) + (hashtb (copy-sequence wl-folder-entity-hashtb))) + (while alist + (wl-folder-set-entity-info (cdar alist) nil hashtb) + (setq alist (cdr alist))) + hashtb)) + +(defun wl-folder-update-diff-line (diffs) + (let ((inhibit-read-only t) + (buffer-read-only nil) + cur-new new-new + cur-unread new-unread + cur-all new-all + id) + (save-excursion + (beginning-of-line) + (setq id (get-text-property (point) 'wl-folder-entity-id)) + (when (looking-at "^[ ]*\\(.*\\):\\([0-9\\*-]*\\)/\\([0-9\\*-]*\\)/\\([0-9\\*]*\\)") + ;;(looking-at "^[ ]*\\([^\\[].+\\):\\([0-9\\*-]*/[0-9\\*-]*/[0-9\\*]*\\)") + (setq cur-new (string-to-int + (wl-match-buffer 2))) + (setq cur-unread (string-to-int + (wl-match-buffer 3))) + (setq cur-all (string-to-int + (wl-match-buffer 4))) + (delete-region (match-beginning 2) + (match-end 4)) + (goto-char (match-beginning 2)) + (insert (format "%s/%s/%s" + (setq new-new (+ cur-new (nth 0 diffs))) + (setq new-unread (+ cur-unread (nth 1 diffs))) + (setq new-all (+ cur-all (nth 2 diffs))))) + (put-text-property (match-beginning 2) (point) + 'wl-folder-entity-id id) + (if wl-use-highlight-mouse-line + (put-text-property (match-beginning 2) (point) + 'mouse-face 'highlight)) + (wl-highlight-folder-group-line (list new-new new-unread new-all)) + (setq buffer-read-only t) + (set-buffer-modified-p nil))))) + +(defun wl-folder-update-line (nums &optional is-group) + (let ((inhibit-read-only t) + (buffer-read-only nil) + id) + (save-excursion + (beginning-of-line) + (setq id (get-text-property (point) 'wl-folder-entity-id)) + (if (looking-at "^[ ]*\\(.*\\):\\([0-9\\*-]*/[0-9\\*-]*/[0-9\\*]*\\)") + ;;(looking-at "^[ ]*\\([^\\[].+\\):\\([0-9\\*-]*/[0-9\\*-]*/[0-9\\*]*\\)") + (progn + (delete-region (match-beginning 2) + (match-end 2)) + (goto-char (match-beginning 2)) + (insert (format "%s/%s/%s" + (or (nth 0 nums) "*") + (or (and (nth 0 nums)(nth 1 nums) + (+ (nth 0 nums)(nth 1 nums))) + "*") + (or (nth 2 nums) "*"))) + (put-text-property (match-beginning 2) (point) + 'wl-folder-entity-id id) + (if is-group + ;; update only colors + (wl-highlight-folder-group-line nums) + (wl-highlight-folder-current-line nums)) + (set-buffer-modified-p nil)))))) + +(defun wl-folder-goto-folder (&optional arg) + (interactive "P") + (wl-folder-goto-folder-subr nil arg)) + +(defun wl-folder-goto-folder-subr (&optional folder sticky) + (beginning-of-line) + (let (summary-buf fld-name entity id error-selecting) +;; (setq fld-name (wl-folder-get-entity-from-buffer)) +;; (if (or (null fld-name) +;; (assoc fld-name wl-folder-group-alist)) + (setq fld-name wl-default-folder) + (setq fld-name (or folder + (wl-summary-read-folder fld-name))) + (if (and (setq entity + (wl-folder-search-entity-by-name fld-name + wl-folder-entity + 'folder)) + (setq id (wl-folder-get-entity-id entity))) + (wl-folder-set-current-entity-id id)) + (setq summary-buf (wl-summary-get-buffer-create fld-name sticky)) + (if wl-stay-folder-window + (wl-folder-select-buffer summary-buf) + (if (and summary-buf + (get-buffer-window summary-buf)) + (delete-window))) + (wl-summary-goto-folder-subr fld-name + (wl-summary-get-sync-range fld-name) + nil sticky t))) + +(defun wl-folder-suspend () + (interactive) + (run-hooks 'wl-folder-suspend-hook) + (wl-folder-info-save) + (wl-crosspost-alist-save) + (wl-kill-buffers + (format "^\\(%s\\)$" + (mapconcat 'identity + (list (format "%s\\(:.*\\)?" + (default-value 'wl-message-buf-name)) + wl-original-buf-name) + "\\|"))) + (if (fboundp 'mmelmo-cleanup-entity-buffers) + (mmelmo-cleanup-entity-buffers)) + (bury-buffer wl-folder-buffer-name) + (delete-windows-on wl-folder-buffer-name t)) + +(defun wl-folder-info-save () + (when (and wl-folder-info-save + wl-folder-info-alist-modified) + (let ((entities (list wl-folder-entity)) + entity entity-stack info-alist info) + (while entities + (setq entity (wl-pop entities)) + (cond + ((consp entity) + (and entities + (wl-push entities entity-stack)) + (setq entities (nth 2 entity))) + ((stringp entity) + (when (and (setq info (elmo-folder-get-info entity)) + (not (equal info '(nil)))) + (wl-append info-alist (list (list (elmo-string entity) + (list (nth 3 info) ;; max + (nth 2 info) ;; length + (nth 0 info) ;; new + (nth 1 info)) ;; unread + )))))) + (unless entities + (setq entities (wl-pop entity-stack)))) + (elmo-msgdb-finfo-save info-alist) + (setq wl-folder-info-alist-modified nil)))) + +(defun wl-folder-goto-first-unread-folder (&optional arg) + (interactive "P") + (let ((entities (list wl-folder-entity)) + entity entity-stack ret-val + first-entity finfo) + (setq first-entity + (catch 'done + (while entities + (setq entity (wl-pop entities)) + (cond + ((consp entity) + (and entities + (wl-push entities entity-stack)) + (setq entities (nth 2 entity))) + ((stringp entity) + (if (and (setq finfo (wl-folder-get-entity-info entity)) + (and (nth 0 finfo)(nth 1 finfo)) + (> (+ (nth 0 finfo)(nth 1 finfo)) 0)) + (throw 'done entity)) + (wl-append ret-val (list entity)))) + (unless entities + (setq entities (wl-pop entity-stack)))))) + (if first-entity + (progn + (when arg + (wl-folder-jump-folder first-entity) + (sit-for 0)) + (wl-folder-goto-folder-subr first-entity)) + (message "No unread folder")))) + +(defun wl-folder-jump-folder (&optional fld-name noopen) + (interactive) + (if (not fld-name) + (setq fld-name (wl-summary-read-folder wl-default-folder))) + (goto-char (point-min)) + (if (not noopen) + (wl-folder-open-folder fld-name)) + (and (wl-folder-buffer-search-entity fld-name) + (beginning-of-line))) + +(defun wl-folder-get-entity-list (entity) + (let ((entities (list entity)) + entity-stack ret-val) + (while entities + (setq entity (wl-pop entities)) + (cond + ((consp entity) + (and entities + (wl-push entities entity-stack)) + (setq entities (nth 2 entity))) + ((stringp entity) + (wl-append ret-val (list entity)))) + (unless entities + (setq entities (wl-pop entity-stack)))) + ret-val)) + +(defun wl-folder-open-unread-folder (entity) + (save-excursion + (let ((alist (wl-folder-get-entity-list entity)) + (unread 0) + finfo path-list path id) + (while alist + (when (and (setq finfo (wl-folder-get-entity-info (car alist))) + (nth 0 finfo) (nth 1 finfo) + (> (+ (nth 0 finfo)(nth 1 finfo)) 0)) + (setq unread (+ unread (+ (nth 0 finfo)(nth 1 finfo)))) + (setq id (wl-folder-get-entity-id (car alist))) + (setq path (delete id (wl-folder-get-path + wl-folder-entity + id + (car alist)))) + (if (not (member path path-list)) + (wl-append path-list (list path)))) + (setq alist (cdr alist))) + (while path-list + (wl-folder-open-folder-sub (car path-list)) + (setq path-list (cdr path-list))) + (message "%s unread folder" + (if (> unread 0) unread "No"))))) + +(defun wl-folder-open-unread-current-entity () + (interactive) + (let ((entity-name (wl-folder-get-entity-from-buffer)) + (group (wl-folder-buffer-group-p))) + (when entity-name + (wl-folder-open-unread-folder + (if group + (wl-folder-search-group-entity-by-name entity-name + wl-folder-entity) + entity-name))))) + +(defun wl-folder-open-only-unread-folder () + (interactive) + (let ((id (progn + (wl-folder-prev-entity-skip-invalid t) + (wl-folder-get-entity-from-buffer t)))) + (wl-folder-open-all-unread-folder) + (save-excursion + (goto-char (point-max)) + (while (and (re-search-backward + "^[ ]*\\[[-]\\].+:0/0/[0-9-]+" nil t) + (not (bobp))) + (wl-folder-jump-to-current-entity) ;; close it + )) + (wl-folder-move-path id) + (recenter))) + +(defun wl-folder-open-all-unread-folder (&optional arg) + (interactive "P") + (let ((id (progn + (wl-folder-prev-entity-skip-invalid t) + (wl-folder-get-entity-from-buffer t)))) + (wl-folder-open-unread-folder wl-folder-entity) + (if (not arg) + (wl-folder-move-path id) + (goto-char (point-min)) + (wl-folder-next-unread t)))) + +(defun wl-folder-open-folder (&optional fld-name) + (interactive) + (if (not fld-name) + (setq fld-name (wl-summary-read-folder wl-default-folder))) + (let* ((id (wl-folder-get-entity-id + (wl-folder-search-entity-by-name fld-name wl-folder-entity + 'folder))) + (path (and id (wl-folder-get-path wl-folder-entity id)))) + (if path + (wl-folder-open-folder-sub path)))) + +(defun wl-folder-open-folder-sub (path) + (let ((inhibit-read-only t) + (buffer-read-only nil) + indent name entity + err) + (save-excursion + (goto-char (point-min)) + (while (and path + (wl-folder-buffer-search-group + (wl-folder-get-petname + (if (stringp (car path)) + (car path) + (wl-folder-get-folder-name-by-id + (car path)))))) + (beginning-of-line) + (setq path (cdr path)) + (if (and (looking-at wl-folder-group-regexp) + (string= "+" (wl-match-buffer 2)));; closed group + (save-excursion + (setq indent (wl-match-buffer 1)) + (setq name (wl-folder-get-realname (wl-match-buffer 3))) + (setq entity (wl-folder-search-group-entity-by-name + name + wl-folder-entity)) + ;; insert as opened + (setcdr (assoc (car entity) wl-folder-group-alist) t) + (if (eq 'access (cadr entity)) + (wl-folder-maybe-load-folder-list entity)) + (wl-folder-insert-entity indent entity) + (delete-region (save-excursion (beginning-of-line) + (point)) + (save-excursion (end-of-line) + (+ 1 (point))))))) + (set-buffer-modified-p nil)))) + +(defun wl-folder-open-all-pre () + (let ((entities (list wl-folder-entity)) + entity entity-stack group-entry) + (while entities + (setq entity (wl-pop entities)) + (cond + ((consp entity) + (unless (or (not (setq group-entry + (assoc (car entity) wl-folder-group-alist))) + (cdr group-entry)) + (setcdr group-entry t) + (when (eq 'access (cadr entity)) + (wl-folder-maybe-load-folder-list entity))) + (and entities + (wl-push entities entity-stack)) + (setq entities (nth 2 entity)))) + (unless entities + (setq entities (wl-pop entity-stack)))))) + +(defun wl-folder-open-all (&optional refresh) + (interactive "P") + (let* ((inhibit-read-only t) + (buffer-read-only nil) + (len (length wl-folder-group-alist)) + (i 0) + indent name entity) + (if refresh + (let ((id (progn + (wl-folder-prev-entity-skip-invalid t) + (wl-folder-get-entity-from-buffer t)))) + (mapcar '(lambda (x) + (setcdr x t)) + wl-folder-group-alist) + (erase-buffer) + (wl-folder-insert-entity " " wl-folder-entity) + (wl-folder-move-path id)) + (message "Opening all folders...") + (wl-folder-open-all-pre) + (save-excursion + (goto-char (point-min)) + (while (re-search-forward + "^\\([ ]*\\)\\[\\([+]\\)\\]\\(.+\\):[-0-9-]+/[0-9-]+/[0-9-]+\n" + nil t) + (setq indent (wl-match-buffer 1)) + (setq name (wl-folder-get-realname (wl-match-buffer 3))) + (setq entity (wl-folder-search-group-entity-by-name + name + wl-folder-entity)) + ;; insert as opened + (setcdr (assoc (car entity) wl-folder-group-alist) t) + (forward-line -1) + (wl-folder-insert-entity indent entity) + (delete-region (save-excursion (beginning-of-line) + (point)) + (save-excursion (end-of-line) + (+ 1 (point)))) + (setq i (1+ i)) + (and (zerop (% i 10)) + (elmo-display-progress + 'wl-folder-open-all "Opening all folders..." + (/ (* i 100) len)))))) + (message "Opening all folders...done") + (set-buffer-modified-p nil))) + +(defun wl-folder-close-all () + (interactive) + (let ((inhibit-read-only t) + (buffer-read-only nil) + (alist wl-folder-group-alist) + (id (progn + (wl-folder-prev-entity-skip-invalid t) + (wl-folder-get-entity-from-buffer t)))) + (while alist + (setcdr (car alist) nil) + (setq alist (cdr alist))) + (setcdr (assoc (car wl-folder-entity) wl-folder-group-alist) t) + (erase-buffer) + (wl-folder-insert-entity " " wl-folder-entity) + (wl-folder-move-path id) + (recenter) + (set-buffer-modified-p nil))) + +(defun wl-folder-open-close () + "open or close parent entity." + (interactive) + (save-excursion + (beginning-of-line) + (if (wl-folder-buffer-group-p) + ;; if group (whether opend or closed.) + (wl-folder-jump-to-current-entity) + ;; if folder + (let (indent) + (setq indent (save-excursion + (re-search-forward "\\([ ]*\\)." nil t) + (wl-match-buffer 1))) + (while (looking-at indent) + (forward-line -1))) + (wl-folder-jump-to-current-entity)))) + +(defsubst wl-folder-access-subscribe-p (group folder) + (let (subscr regexp match) + (if (setq subscr (wl-get-assoc-list-value + wl-folder-access-subscribe-alist + group)) + (progn + (setq regexp (mapconcat 'identity (cdr subscr) "\\|")) + (setq match (string-match regexp folder)) + (if (car subscr) + match + (not match))) + t))) + +(defun wl-folder-update-access-group (entity new-flist) + (let* ((flist (nth 2 entity)) + (unsubscribes (nth 3 entity)) + (len (+ (length flist) (length unsubscribes))) + (i 0) + diff new-unsubscribes removes + subscribed-list folder group entry) + ;; check subscribed groups + (while flist + (cond + ((listp (car flist)) ;; group + (setq group (elmo-string (caar flist))) + (cond + ((assoc group new-flist) ;; found in new-flist + (setq new-flist (delete (assoc group new-flist) + new-flist)) + (if (wl-folder-access-subscribe-p (car entity) group) + (wl-append subscribed-list (list (car flist))) + (wl-append new-unsubscribes (list (car flist))) + (setq diff t))) + (t + (setq wl-folder-group-alist + (delete (wl-string-assoc group wl-folder-group-alist) + wl-folder-group-alist)) + (wl-append removes (list (list group)))))) + (t ;; folder + (setq folder (elmo-string (car flist))) + (cond + ((member folder new-flist) ;; found in new-flist + (setq new-flist (delete folder new-flist)) + (if (wl-folder-access-subscribe-p (car entity) folder) + (wl-append subscribed-list (list (car flist))) + (wl-append new-unsubscribes (list folder)) + (setq diff t))) + (t + (wl-append removes (list folder)))))) + (setq i (1+ i)) + (and (zerop (% i 10)) + (elmo-display-progress + 'wl-folder-update-access-group "Updating access group..." + (/ (* i 100) len))) + (setq flist (cdr flist))) + ;; check unsubscribed groups + (while unsubscribes + (cond + ((listp (car unsubscribes)) + (when (setq entry (assoc (caar unsubscribes) new-flist)) + (setq new-flist (delete entry new-flist)) + (wl-append new-unsubscribes (list (car unsubscribes))))) + (t + (when (member (car unsubscribes) new-flist) + (setq new-flist (delete (car unsubscribes) new-flist)) + (wl-append new-unsubscribes (list (car unsubscribes)))))) + (setq i (1+ i)) + (and (zerop (% i 10)) + (elmo-display-progress + 'wl-folder-update-access-group "Updating access group..." + (/ (* i 100) len))) + (setq unsubscribes (cdr unsubscribes))) + ;; + (if (or new-flist removes) + (setq diff t)) + (setq new-flist + (mapcar '(lambda (x) + (cond ((consp x) (list (car x) 'access)) + (t x))) + new-flist)) + ;; check new groups + (let ((new-list new-flist)) + (while new-list + (if (not (wl-folder-access-subscribe-p + (car entity) + (if (listp (car new-list)) + (caar new-list) + (car new-list)))) + ;; auto unsubscribe + (progn + (wl-append new-unsubscribes (list (car new-list))) + (setq new-flist (delete (car new-list) new-flist))) + (cond + ((listp (car new-list)) + ;; check group exists + (if (wl-string-assoc (caar new-list) wl-folder-group-alist) + (progn + (message "%s: group already exists." (caar new-list)) + (sit-for 1) + (wl-append new-unsubscribes (list (car new-list))) + (setq new-flist (delete (car new-list) new-flist))) + (wl-append wl-folder-group-alist + (list (cons (caar new-list) nil))))))) + (setq new-list (cdr new-list)))) + (if new-flist + (message "%d new folder(s)." (length new-flist)) + (message "Updating access group...done")) + (wl-append new-flist subscribed-list) ;; new is first + (run-hooks 'wl-folder-update-access-group-hook) + (setcdr (cdr entity) (list new-flist new-unsubscribes)) + (list diff new-flist new-unsubscribes removes))) + +(defun wl-folder-prefetch-entity (entity) + "Prefetch all new messages in the ENTITY" + (cond + ((consp entity) + (let ((flist (nth 2 entity)) + (sum-done 0) + (sum-all 0) + result) + (while flist + (setq result (wl-folder-prefetch-entity (car flist))) + (setq sum-done (+ sum-done (car result))) + (setq sum-all (+ sum-all (cdr result))) + (setq flist (cdr flist))) + (message "Prefetched %d/%d message(s) in \"%s\"." + sum-done sum-all + (wl-folder-get-petname (car entity))) + (cons sum-done sum-all))) + ((stringp entity) + (let ((nums (wl-folder-get-entity-info entity)) + (wl-summary-highlight (if (or (wl-summary-sticky-p entity) + (wl-summary-always-sticky-folder-p + entity)) + wl-summary-highlight)) + wl-summary-exit-next-move + wl-auto-select-first ret-val + count) + (setq count (or (car nums) 0)) + (setq count (+ count (wl-folder-count-incorporates entity))) + (if (< 0 count) + (save-window-excursion + (save-excursion + (wl-summary-goto-folder-subr entity + (wl-summary-get-sync-range entity) + nil) + (setq ret-val (wl-summary-incorporate)) + (wl-summary-exit) + ret-val)) + (cons 0 0)))))) + +(defun wl-folder-count-incorporates (folder) + (let ((sum 0)) + (mapcar '(lambda (x) + (if (member (cadr x) + wl-summary-incorporate-marks) + (incf sum))) + (elmo-msgdb-mark-load (elmo-msgdb-expand-path folder))) + sum)) + +(defun wl-folder-prefetch-current-entity (&optional no-check) + "Prefetch all uncached messages in the folder at position. +If current line is group folder, all subfolders are prefetched." + (interactive "P") + (save-excursion + (let ((entity-name (wl-folder-get-entity-from-buffer)) + (group (wl-folder-buffer-group-p)) + wl-folder-check-entity-hook + summary-buf entity) + (when entity-name + (setq entity + (if group + (wl-folder-search-group-entity-by-name entity-name + wl-folder-entity) + entity-name)) + (if (not no-check) + (wl-folder-check-entity entity)) + (wl-folder-prefetch-entity entity))))) + +(defun wl-folder-drop-unsync-entity (entity) + "Drop all unsync messages in the ENTITY" + (cond + ((consp entity) + (let ((flist (nth 2 entity))) + (while flist + (wl-folder-drop-unsync-entity (car flist)) + (setq flist (cdr flist))))) + ((stringp entity) + (let ((nums (wl-folder-get-entity-info entity)) + wl-summary-highlight wl-auto-select-first new) + (setq new (or (car nums) 0)) + (if (< 0 new) + (save-window-excursion + (save-excursion + (wl-summary-goto-folder-subr entity 'no-sync nil) + (wl-summary-drop-unsync) + (wl-summary-exit)))))))) + +(defun wl-folder-drop-unsync-current-entity (&optional force-check) + "Drop all unsync messages in the folder at position. +If current line is group folder, all subfolders are dropped. +If optional arg exists, don't check any folders." + (interactive "P") + (save-excursion + (let ((entity-name (wl-folder-get-entity-from-buffer)) + (group (wl-folder-buffer-group-p)) + wl-folder-check-entity-hook + summary-buf entity) + (when (and entity-name + (y-or-n-p (format + "Drop all unsync messages in %s?" entity-name))) + (setq entity + (if group + (wl-folder-search-group-entity-by-name entity-name + wl-folder-entity) + entity-name)) + (if (null force-check) + (wl-folder-check-entity entity)) + (wl-folder-drop-unsync-entity entity) + (message "All unsync messages in %s are dropped!" entity-name))))) + +(defun wl-folder-write-current-newsgroup () + (interactive) + (wl-summary-write-current-newsgroup (wl-folder-entity-name))) + +(defun wl-folder-mimic-kill-buffer () + "Kill the current (Folder) buffer with query." + (interactive) + (let ((bufname (read-buffer (format "Kill buffer: (default %s) " + (buffer-name)))) + wl-interactive-exit) + (if (or (not bufname) + (string-equal bufname "") + (string-equal bufname (buffer-name))) + (wl-exit) + (kill-buffer bufname)))) + +(defun wl-folder-confirm-existence (fld &optional ignore-error) + (if (or (wl-folder-entity-exists-p fld) + (file-exists-p (elmo-msgdb-expand-path fld))) + () + (if ignore-error + (condition-case nil + (if (elmo-folder-exists-p fld) + () + (if (elmo-folder-creatable-p fld) + (if (y-or-n-p + (format "Folder %s does not exist, create it?" fld)) + (progn + (setq wl-folder-entity-hashtb + (wl-folder-create-entity-hashtb + fld + wl-folder-entity-hashtb)) + (elmo-create-folder fld))))) + (error)) + (if (elmo-folder-exists-p fld) + () + (if (not (elmo-folder-creatable-p fld)) + (error "Folder %s is not found" fld) + (if (y-or-n-p + (format "Folder %s does not exist, create it?" fld)) + (progn + (setq wl-folder-entity-hashtb + (wl-folder-create-entity-hashtb + fld + wl-folder-entity-hashtb)) + (unless (elmo-create-folder fld) + (error "Create folder failed"))) + (error "Folder is not created"))))))) + +(provide 'wl-folder) + +;;; wl-folder.el ends here diff --git a/wl/wl-highlight.el b/wl/wl-highlight.el new file mode 100644 index 0000000..b9f4c20 --- /dev/null +++ b/wl/wl-highlight.el @@ -0,0 +1,1224 @@ +;;; wl-highlight.el -- Hilight modules for Wanderlust. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <00/03/05 00:59:10 teranisi> + +;; This file is part of Wanderlust (Yet Another Message Interface on Emacsen). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; + +(if (and (featurep 'xemacs) + (featurep 'dragdrop)) + (require 'wl-dnd)) +(require 'wl-vars) +(provide 'wl-highlight) + +(eval-when-compile + (if wl-on-xemacs + (require 'wl-xmas) + (if wl-on-nemacs + (require 'wl-nemacs) + (require 'wl-mule))) + (defun-maybe extent-begin-glyph (a)) + (defun-maybe delete-extent (a)) + (defun-maybe make-extent (a b)) + (defun-maybe set-extent-begin-glyph (a b)) + (defun-maybe set-extent-end-glyph (a b)) + (defun-maybe extent-at (a b c d e)) + (defun-maybe wl-dnd-set-drop-target (a b)) + (defun-maybe wl-dnd-set-drag-starter (a b))) + +(put 'wl-defface 'lisp-indent-function 'defun) + +(defgroup wl-faces nil + "Wanderlust, Faces." + :prefix "wl-highlight-" + :group 'wl-highlight + :group 'wl) + +(defgroup wl-summary-faces nil + "Wanderlust, Faces of summary buffer." + :prefix "wl-highlight-" + :group 'wl-highlight + :group 'wl-summary) + +(defgroup wl-folder-faces nil + "Wanderlust, Faces of folder buffer." + :prefix "wl-highlight-" + :group 'wl-highlight + :group 'wl-folder) + +(defgroup wl-message-faces nil + "Wanderlust, Faces of message buffer." + :prefix "wl-highlight-" + :group 'wl-highlight) + +;; for message header and signature + +(wl-defface wl-highlight-message-headers + '( + (((type tty) + (background dark)) + (:foreground "cyan")) + (((class color) + (background dark)) + (:foreground "gray" :bold t)) + (((class color) + (background light)) + (:foreground "gray50" :bold t))) + "Face used for displaying header names." + :group 'wl-message-faces + :group 'wl-faces) + +(wl-defface wl-highlight-message-header-contents + '( + (((type tty) + (background dark)) + (:foreground "green")) + (((class color) + (background dark)) + (:foreground "LightSkyBlue" :bold t)) + (((class color) + (background light)) + (:foreground "purple" :bold t))) + "Face used for displaying header content." + :group 'wl-message-faces + :group 'wl-faces) + +(wl-defface wl-highlight-message-important-header-contents + '( + (((type tty) + (background dark)) + (:foreground "yellow")) + (((class color) + (background dark)) + (:foreground "yellow" :bold t)) + (((class color) + (background light)) + (:foreground "brown" :bold t))) + "Face used for displaying contents of special headers." + :group 'wl-message-faces + :group 'wl-faces) + +(wl-defface wl-highlight-message-important-header-contents2 + '( + (((type tty) + (background dark)) + (:foreground "red")) + (((class color) + (background dark)) + (:foreground "orange" :bold t)) + (((class color) + (background light)) + (:foreground "DarkSlateBlue" :bold t))) + "Face used for displaying contents of special headers." + :group 'wl-message-faces + :group 'wl-faces) + +(wl-defface wl-highlight-message-citation-header + '( + (((type tty) + (background dark)) + (:foreground "cyan")) + (((class color) + (background dark)) + (:foreground "SkyBlue")) + (((class color) + (background light)) + (:foreground "DarkGreen"))) + "Face used for displaying header of quoted texts." + :group 'wl-message-faces + :group 'wl-faces) + +(wl-defface wl-highlight-message-unimportant-header-contents + '( + (((type tty) + (background dark)) + (:foreground "green")) + (((class color) + (background dark)) + (:foreground "GreenYellow" :bold t)) + (((class color) + (background light)) + (:foreground "DarkGreen" :bold t))) + "Face used for displaying contents of unimportant headers." + :group 'wl-message-faces + :group 'wl-faces) + +(wl-defface wl-highlight-message-signature + '((((class color) + (background dark)) + (:foreground "khaki")) + (((class color) + (background light)) + (:foreground "DarkSlateBlue"))) + "Face used for displaying signature." + :group 'wl-message-faces + :group 'wl-faces) + +;; for draft + +(wl-defface wl-highlight-header-separator-face + '( + (((type tty) + (background dark)) + (:foreground "black" :background "yellow")) + (((class color)) + (:foreground "Black" :background "DarkKhaki"))) + "Face used for displaying header separator." + :group 'wl-draft + :group 'wl-faces) + +;; important messages + +(wl-defface wl-highlight-summary-important-face + '( + (((type tty) + (background dark)) + (:foreground "magenta")) + (((class color) + (background dark)) + (:foreground "orange")) + (((class color) + (background light)) + (:foreground "purple"))) + "Face used for displaying important messages." + :group 'wl-summary-faces + :group 'wl-faces) + +(wl-defface wl-highlight-summary-new-face + '( + (((type tty) + (background dark)) + (:foreground "red")) + (((class color) + (background dark)) + (:foreground "tomato")) + (((class color) + (background light)) + (:foreground "tomato"))) + "Face used for displaying new messages." + :group 'wl-summary-faces + :group 'wl-faces) + +(wl-defface wl-highlight-summary-displaying-face + '((t + (:underline t :bold t))) + "Face used for displaying message." + :group 'wl-summary-faces + :group 'wl-faces) + +(wl-defface wl-highlight-thread-indent-face + '((t + (:foreground "gray40"))) + "Face used for displaying indented thread." + :group 'wl-summary-faces + :group 'wl-faces) + +;; unimportant messages + +(wl-defface wl-highlight-summary-unread-face + '( + (((type tty) + (background dark)) + (:foreground "cyan")) + (((class color) + (background dark)) + (:foreground "LightSkyBlue")) + (((class color) + (background light)) + (:foreground "RoyalBlue"))) + "Face used for displaying unread messages." + :group 'wl-summary-faces + :group 'wl-faces) + +(wl-defface wl-highlight-summary-deleted-face + '( + (((type tty) + (background dark)) + (:foreground "blue")) + (((class color) + (background dark)) + (:foreground "gray")) + (((class color) + (background light)) + (:foreground "DarkKhaki"))) + "Face used for displaying messages mark as deleted." + :group 'wl-summary-faces + :group 'wl-faces) + +(wl-defface wl-highlight-summary-refiled-face + '( + (((type tty) + (background dark)) + (:foreground "blue")) + (((class color) + (background dark)) + (:foreground "blue")) + (((class color) + (background light)) + (:foreground "firebrick"))) + "Face used for displaying messages mark as refiled." + :group 'wl-summary-faces + :group 'wl-faces) + +(wl-defface wl-highlight-summary-copied-face + '( + (((type tty) + (background dark)) + (:foreground "blue")) + (((class color) + (background dark)) + (:foreground "cyan")) + (((class color) + (background light)) + (:foreground "blue"))) + "Face used for displaying messages mark as copied." + :group 'wl-summary-faces + :group 'wl-faces) + +;; obsolete. +(wl-defface wl-highlight-summary-temp-face + '( + (((type tty) + (background dark)) + (:foreground "gold")) + (((class color)) + (:foreground "HotPink1"))) + "Face used for displaying messages mark as temp." + :group 'wl-summary-faces + :group 'wl-faces) + +(wl-defface wl-highlight-summary-target-face + '( + (((type tty) + (background dark)) + (:foreground "gold")) + (((class color)) + (:foreground "HotPink1"))) + "Face used for displaying messages mark as target." + :group 'wl-summary-faces + :group 'wl-faces) + +(wl-defface wl-highlight-summary-low-read-face + '( + (((type tty) + (background dark)) + (:foreground "yellow" :italic t)) + (((class color) + (background dark)) + (:foreground "PaleGreen" :italic t)) + (((class color) + (background light)) + (:foreground "Green3" :italic t))) + "Face used for displaying low interest read messages." + :group 'wl-summary-faces + :group 'wl-faces) + +(wl-defface wl-highlight-summary-high-read-face + '( + (((type tty)) + (:bold t)) + (((class color) + (background dark)) + (:foreground "PaleGreen" :bold t)) + (((class color) + (background light)) + (:foreground "SeaGreen" :bold t))) + "Face used for displaying high interest read messages." + :group 'wl-summary-faces + :group 'wl-faces) + +(wl-defface wl-highlight-summary-low-unread-face + '( + (((type tty) + (background dark)) + (:foreground "cyan" :italic t)) + (((class color) + (background dark)) + (:foreground "LightSkyBlue" :italic t)) + (((class color) + (background light)) + (:foreground "RoyalBlue" :italic t))) + "Face used for displaying low interest unread messages." + :group 'wl-summary-faces + :group 'wl-faces) + +(wl-defface wl-highlight-summary-high-unread-face + '( + (((type tty)) + (:foreground "red" :bold t)) + (((class color) + (background dark)) + (:foreground "tomato" :bold t)) + (((class color) + (background light)) + (:foreground "tomato" :bold t))) + "Face used for displaying high interest unread messages." + :group 'wl-summary-faces + :group 'wl-faces) + +;; ordinary messages + +(wl-defface wl-highlight-summary-thread-top-face + '( + (((type tty) + (background dark)) + (:foreground "green")) + (((class color) + (background dark)) + (:foreground "GreenYellow")) + (((class color) + (background light)) + (:foreground "green4"))) + "Face used for displaying top thread message." + :group 'wl-summary-faces + :group 'wl-faces) + +(wl-defface wl-highlight-summary-normal-face + '( + (((type tty) + (background dark)) + (:foreground "yellow")) + (((class color) + (background dark)) + (:foreground "PaleGreen")) + (((class color) + (background light)) + (:foreground "SeaGreen"))) + "Face used for displaying normal message." + :group 'wl-summary-faces + :group 'wl-faces) + +;; folder + +(wl-defface wl-highlight-folder-unknown-face + '( + (((type tty) + (background dark)) + (:foreground "cyan")) + (((class color) + (background dark)) + (:foreground "pink")) + (((class color) + (background light)) + (:foreground "RoyalBlue"))) + "Face used for displaying unread folder." + :group 'wl-folder-faces + :group 'wl-faces) + +(wl-defface wl-highlight-folder-killed-face + '( + (((type tty) + (background dark)) + (:foreground "gray")) + (((class color)) + (:foreground "gray50"))) + "Face used for displaying killed folder." + :group 'wl-folder-faces + :group 'wl-faces) + +(wl-defface wl-highlight-folder-zero-face + '( + (((type tty) + (background dark)) + (:foreground "green")) + (((class color) + (background dark)) + (:foreground "SkyBlue")) + (((class color) + (background light)) + (:foreground "BlueViolet"))) + "Face used for displaying folder needs no sync." + :group 'wl-folder-faces + :group 'wl-faces) + +(wl-defface wl-highlight-folder-few-face + '( + (((type tty) + (background dark)) + (:foreground "yellow")) + (((class color) + (background dark)) + (:foreground "orange")) + (((class color) + (background light)) + (:foreground "OrangeRed3"))) + "Face used for displaying folder contains few unsync messages." + :group 'wl-folder-faces + :group 'wl-faces) + +(wl-defface wl-highlight-folder-many-face + '( + (((type tty) + (background dark)) + (:foreground "red")) + (((class color) + (background dark)) + (:foreground "HotPink1")) + (((class color) + (background light)) + (:foreground "tomato"))) + "Face used for displaying folder contains many unsync messages." + :group 'wl-folder-faces + :group 'wl-faces) + +(wl-defface wl-highlight-folder-unread-face + '( + (((type tty) + (background dark)) + (:foreground "magenta")) + (((class color) + (background dark)) + (:foreground "gold")) + (((class color) + (background light)) + (:foreground "MediumVioletRed"))) + "Face used for displaying unread folder." + :group 'wl-folder-faces + :group 'wl-faces) + +(wl-defface wl-highlight-folder-opened-face + '( + (((type tty) + (background dark)) + (:foreground "blue")) + (((class color) + (background dark)) + (:foreground "PaleGreen")) + (((class color) + (background light)) + (:foreground "ForestGreen"))) + "Face used for displaying opened group folder." + :group 'wl-folder-faces + :group 'wl-faces) + +(wl-defface wl-highlight-folder-closed-face + '( + (((type tty) + (background dark)) + (:foreground "cyan")) + (((class color) + (background dark)) + (:foreground "GreenYellow")) + (((class color) + (background light)) + (:foreground "DarkOliveGreen4"))) + "Face used for displaying closed group folder." + :group 'wl-folder-faces + :group 'wl-faces) + +(wl-defface wl-highlight-folder-path-face + '((t + (:bold t :underline t))) + "Face used for displaying path." + :group 'wl-folder-faces + :group 'wl-faces) + +(wl-defface wl-highlight-demo-face + '( + (((type tty) + (background dark)) + (:foreground "green")) + (((class color) + (background dark)) + (:foreground "GreenYellow")) + (((class color) + (background light)) + (:foreground "blue2"))) + "Face used for displaying demo." + :group 'wl-faces) + +(wl-defface wl-highlight-logo-face + '( + (((type tty) + (background dark)) + (:foreground "cyan")) + (((class color) + (background dark)) + (:foreground "SkyBlue")) + (((class color) + (background light)) + (:foreground "SteelBlue"))) + "Face used for displaying demo." + :group 'wl-faces) + +(wl-defface wl-highlight-refile-destination-face + '((((class color) + (background dark)) + (:foreground "pink")) + (((class color) + (background light)) + (:foreground "red"))) + "Face used for displaying refile destination." + :group 'wl-summary-faces + :group 'wl-faces) + +;; cited face + +(wl-defface wl-highlight-message-cited-text-1 + '( + (((type tty) + (background dark)) + (:foreground "magenta")) + (((class color) + (background dark)) + (:foreground "HotPink1")) + (((class color) + (background light)) + (:foreground "ForestGreen"))) + "Face used for displaying quoted text from other messages." + :group 'wl-message-faces + :group 'wl-faces) + +(wl-defface wl-highlight-message-cited-text-2 + '( + (((type tty) + (background dark)) + (:foreground "blue")) + (((class color)) + (:foreground "violet"))) + "Face used for displaying quoted text from other messages." + :group 'wl-message-faces + :group 'wl-faces) + +(wl-defface wl-highlight-message-cited-text-3 + '( + (((type tty) + (background dark)) + (:foreground "cyan")) + (((class color)) + (:foreground "orchid3"))) + "Face used for displaying quoted text from other messages." + :group 'wl-message-faces + :group 'wl-faces) + +(wl-defface wl-highlight-message-cited-text-4 + '( + (((type tty) + (background dark)) + (:foreground "green")) + (((class color)) + (:foreground "purple1"))) + "Face used for displaying quoted text from other messages." + :group 'wl-message-faces + :group 'wl-faces) + +(wl-defface wl-highlight-message-cited-text-5 + '( + (((type tty) + (background dark)) + (:foreground "yellow")) + (((class color)) + (:foreground "MediumPurple1"))) + "Face used for displaying quoted text from other messages." + :group 'wl-message-faces + :group 'wl-faces) + +(wl-defface wl-highlight-message-cited-text-6 + '( + (((type tty) + (background dark)) + (:foreground "red")) + (((class color)) + (:foreground "PaleVioletRed"))) + "Face used for displaying quoted text from other messages." + :group 'wl-message-faces + :group 'wl-faces) + +(wl-defface wl-highlight-message-cited-text-7 + '( + (((type tty) + (background dark)) + (:foreground "magenta")) + (((class color)) + (:foreground "LightPink"))) + "Face used for displaying quoted text from other messages." + :group 'wl-message-faces + :group 'wl-faces) + +(wl-defface wl-highlight-message-cited-text-8 + '( + (((type tty) + (background dark)) + (:foreground "blue")) + (((class color)) + (:foreground "salmon"))) + "Face used for displaying quoted text from other messages." + :group 'wl-message-faces + :group 'wl-faces) + +(wl-defface wl-highlight-message-cited-text-9 + '( + (((type tty) + (background dark)) + (:foreground "cyan")) + (((class color)) + (:foreground "SandyBrown"))) + "Face used for displaying quoted text from other messages." + :group 'wl-message-faces + :group 'wl-faces) + +(wl-defface wl-highlight-message-cited-text-10 + '( + (((type tty) + (background dark)) + (:foreground "green")) + (((class color)) + (:foreground "wheat"))) + "Face used for displaying quoted text from other messages." + :group 'wl-message-faces + :group 'wl-faces) + +(defvar wl-highlight-folder-opened-regexp " *\\(\\[\\-\\]\\)") +(defvar wl-highlight-folder-closed-regexp " *\\(\\[\\+\\]\\)") +(defvar wl-highlight-folder-leaf-regexp "[ ]*\\([-%\\+]\\)\\(.*\\):.*$") + +(defvar wl-highlight-summary-unread-regexp " *[0-9]+[^0-9]\\(!\\|U\\)") +(defvar wl-highlight-summary-important-regexp " *[0-9]+[^0-9]\\$") +(defvar wl-highlight-summary-new-regexp " *[0-9]+[^0-9]N") +(defvar wl-highlight-summary-deleted-regexp " *[0-9]+D") +(defvar wl-highlight-summary-refiled-regexp " *[0-9]+o") +(defvar wl-highlight-summary-copied-regexp " *[0-9]+O") +(defvar wl-highlight-summary-target-regexp " *[0-9]+\\*") +;(defvar wl-highlight-summary-thread-top-regexp " *[0-9]+[^0-9][^0-9]../..\(.*\)..:.. \\[") + +(defvar wl-highlight-citation-face-list + '(wl-highlight-message-cited-text-1 + wl-highlight-message-cited-text-2 + wl-highlight-message-cited-text-3 + wl-highlight-message-cited-text-4 + wl-highlight-message-cited-text-5 + wl-highlight-message-cited-text-6 + wl-highlight-message-cited-text-7 + wl-highlight-message-cited-text-8 + wl-highlight-message-cited-text-9 + wl-highlight-message-cited-text-10)) + +(defmacro defun-hilit (name &rest everything-else) + "Define a function for highlight. Nemacs implementation is set as empty." + (if wl-on-nemacs + (` (defun (, name) nil nil)) + (` (defun (, name) (,@ everything-else))))) + +(defmacro defun-hilit2 (name &rest everything-else) + "Define a function for highlight w/o nemacs." + (if wl-on-nemacs + () ; noop + (` (defun (, name) (,@ everything-else))))) + +(defun-hilit wl-highlight-summary-displaying () + (interactive) + (wl-delete-all-overlays) + (let (bol eol ov) + (save-excursion + (beginning-of-line) + (setq bol (point)) + (save-excursion (end-of-line) (setq eol (point))) + (setq ov (make-overlay bol eol)) + (overlay-put ov 'face 'wl-highlight-summary-displaying-face)))) + +(defun-hilit2 wl-highlight-folder-group-line (numbers) + (if wl-highlight-group-folder-by-numbers + (let (fsymbol bol eol) + (beginning-of-line) + (setq bol (point)) + (save-excursion (end-of-line) (setq eol (point))) + (setq fsymbol + (let ((unsync (nth 0 numbers)) + (unread (nth 1 numbers))) + (cond ((and unsync (eq unsync 0)) + (if (and unread (> unread 0)) + 'wl-highlight-folder-unread-face + 'wl-highlight-folder-zero-face)) + ((and unsync + (>= unsync wl-folder-many-unsync-threshold)) + 'wl-highlight-folder-many-face) + (t + 'wl-highlight-folder-few-face)))) + (put-text-property bol eol 'face fsymbol)) + (let ((highlights (list "opened" "closed")) + fregexp fsymbol bol eol matched type extent num type) + (beginning-of-line) + (setq bol (point)) + (save-excursion (end-of-line) (setq eol (point))) + (catch 'highlighted + (while highlights + (setq fregexp (symbol-value + (intern (format "wl-highlight-folder-%s-regexp" + (car highlights))))) + (setq fsymbol (intern (format "wl-highlight-folder-%s-face" + (car highlights)))) + (when (looking-at fregexp) + (put-text-property bol eol 'face fsymbol) + (setq matched t) + (throw 'highlighted nil)) + (setq highlights (cdr highlights))))))) + +(defun-hilit2 wl-highlight-summary-line-string (line mark temp-mark indent) + (let (fsymbol) + (cond ((and (string= temp-mark "+") + (member mark (list wl-summary-unread-cached-mark + wl-summary-unread-uncached-mark + wl-summary-new-mark))) + (setq fsymbol 'wl-highlight-summary-high-unread-face)) + ((and (string= temp-mark "-") + (member mark (list wl-summary-unread-cached-mark + wl-summary-unread-uncached-mark + wl-summary-new-mark))) + (setq fsymbol 'wl-highlight-summary-low-unread-face)) + ((string= temp-mark "o") + (setq fsymbol 'wl-highlight-summary-refiled-face)) + ((string= temp-mark "O") + (setq fsymbol 'wl-highlight-summary-copied-face)) + ((string= temp-mark "D") + (setq fsymbol 'wl-highlight-summary-deleted-face)) + ((string= temp-mark "*") + (setq fsymbol 'wl-highlight-summary-temp-face)) + ((string= mark wl-summary-new-mark) + (setq fsymbol 'wl-highlight-summary-new-face)) + ((member mark (list wl-summary-unread-cached-mark + wl-summary-unread-uncached-mark)) + (setq fsymbol 'wl-highlight-summary-unread-face)) + ((or (string= mark wl-summary-important-mark)) + (setq fsymbol 'wl-highlight-summary-important-face)) + ((string= temp-mark "-") + (setq fsymbol 'wl-highlight-summary-low-read-face)) + ((string= temp-mark "+") + (setq fsymbol 'wl-highlight-summary-high-read-face)) + (t (if (= 0 (length indent)) + (setq fsymbol 'wl-highlight-summary-thread-top-face) + (setq fsymbol 'wl-highlight-summary-normal-face)))) + (put-text-property 0 (length line) 'face fsymbol line)) + (if wl-use-highlight-mouse-line + (put-text-property 0 (length line) 'mouse-face 'highlight line))) + +(defun-hilit2 wl-highlight-summary-current-line (&optional smark regexp temp-too) + (interactive) + (save-excursion + (let ((inhibit-read-only t) + (case-fold-search nil) temp-mark status-mark + (sregexp (concat + "^" + wl-summary-buffer-number-regexp + "\\(.\\)\\(.\\)../..\(.*\)..:.. \\(" + wl-highlight-thread-indent-string-regexp + "\\)\\[")) + fregexp fsymbol bol eol matched thread-top looked-at) + (beginning-of-line) + (setq bol (point)) + (save-excursion (end-of-line) (setq eol (point))) + (if smark + (setq status-mark smark) + (setq looked-at (looking-at sregexp)) + (setq status-mark (buffer-substring (match-beginning 2) + (match-end 2)))) + (when temp-too + (unless looked-at + (setq looked-at (looking-at sregexp))) + (when looked-at + (setq temp-mark (buffer-substring (match-beginning 1) + (match-end 1))) + (cond + ((string= temp-mark "*") + (setq fsymbol 'wl-highlight-summary-temp-face)) + ((string= temp-mark "D") + (setq fsymbol 'wl-highlight-summary-deleted-face)) + ((string= temp-mark "O") + (setq fsymbol 'wl-highlight-summary-copied-face)) + ((string= temp-mark "o") + (setq fsymbol 'wl-highlight-summary-refiled-face))))) + (if (not fsymbol) + (cond + ((and (string= temp-mark "+") + (member status-mark (list wl-summary-unread-cached-mark + wl-summary-unread-uncached-mark + wl-summary-new-mark))) + (setq fsymbol 'wl-highlight-summary-high-unread-face)) + ((and (string= temp-mark "-") + (member status-mark (list wl-summary-unread-cached-mark + wl-summary-unread-uncached-mark + wl-summary-new-mark))) + (setq fsymbol 'wl-highlight-summary-low-unread-face)) + ((string= status-mark wl-summary-new-mark) + (setq fsymbol 'wl-highlight-summary-new-face)) + ((member status-mark (list wl-summary-unread-cached-mark + wl-summary-unread-uncached-mark)) + (setq fsymbol 'wl-highlight-summary-unread-face)) + ((string= status-mark wl-summary-important-mark) + (setq fsymbol 'wl-highlight-summary-important-face)) + ;; score mark + ((string= temp-mark "-") + (setq fsymbol 'wl-highlight-summary-low-read-face)) + ((string= temp-mark "+") + (setq fsymbol 'wl-highlight-summary-high-read-face)) + ;; + (t (if (and looked-at + (string= (buffer-substring + (match-beginning 3) + (match-end 3)) "")) + (setq fsymbol 'wl-highlight-summary-thread-top-face) + (setq fsymbol 'wl-highlight-summary-normal-face))))) + (put-text-property bol eol 'face fsymbol) + (if wl-use-highlight-mouse-line + (put-text-property bol;(1- (match-end 0)) + eol 'mouse-face 'highlight)) +; (put-text-property (match-beginning 3) (match-end 3) +; 'face 'wl-highlight-thread-indent-face) + ;; Dnd stuff. + (if wl-use-dnd + (wl-dnd-set-drag-starter bol eol))))) + +(defun-hilit2 wl-highlight-folder (start end) + "Highlight folder between start and end. +Faces used: + wl-highlight-folder-unknown-face unread messages + wl-highlight-folder-zero-face folder needs no sync + wl-highlight-folder-few-face folder contains few unsync messages + wl-highlight-folder-many-face folder contains many unsync messages + wl-highlight-folder-opened-face opened group folder + wl-highlight-folder-closed-face closed group folder + +Variables used: + wl-highlight-folder-opened-regexp matches opened group folder + wl-highlight-folder-closed-regexp matches closed group folder +" + (interactive "r") + (if (< end start) + (let ((s start)) (setq start end end s))) + (let* ((lines (count-lines start end)) + (real-end end) + gc-message) + (save-excursion + (save-restriction + (widen) + (narrow-to-region start end) + (save-restriction + (goto-char start) + (while (not (eobp)) + (wl-highlight-folder-current-line) + (forward-line 1))))))) + +(if (not wl-on-nemacs) + (defsubst wl-delete-all-overlays () + (mapcar (lambda (x) + (delete-overlay x)) + (overlays-in (point-min) (point-max))))) + +(defun-hilit2 wl-highlight-folder-path (folder-path) + "Highlight current folder path...overlay" + (save-excursion + (wl-delete-all-overlays) + (let ((fp folder-path) ov) + (goto-char (point-min)) + (while (and fp + (not (eobp))) + (beginning-of-line) + (or (looking-at "^[ ]*\\[[\\+-]\\]\\(.+\\):.*\n") + (looking-at "^[ ]*\\([^ \\[].+\\):.*\n")) + (when (equal + (get-text-property (point) 'wl-folder-entity-id) + (car fp)) + (setq fp (cdr fp)) + (setq ov (make-overlay + (match-beginning 1) + (match-end 1))) + (setq wl-folder-buffer-cur-point (point)) + (overlay-put ov 'face 'wl-highlight-folder-path-face)) + (forward-line 1))))) + +(defun-hilit2 wl-highlight-refile-destination-string (string) + (put-text-property 0 (length string) 'face + 'wl-highlight-refile-destination-face + string)) + +(defun-hilit wl-highlight-summary-all () + "For evaluation" + (interactive) + (wl-highlight-summary (point-min)(point-max))) + +(defun-hilit2 wl-highlight-summary (start end) + "Highlight summary between start and end. +Faces used: + wl-highlight-summary-unread-face unread messages + wl-highlight-summary-important-face important messages + wl-highlight-summary-deleted-face messages mark as deleted + wl-highlight-summary-refiled-face messages mark as refiled + wl-highlight-summary-copied-face messages mark as copied + wl-highlight-summary-new-face new messages + +Variables used: + wl-highlight-summary-unread-regexp matches unread messages + wl-highlight-summary-important-regexp matches important messages + wl-highlight-summary-deleted-regexp matches messages mark as deleted + wl-highlight-summary-refiled-regexp matches messages mark as refiled + wl-highlight-summary-copied-regexp matches messages mark as copied + wl-highlight-summary-new-regexp matches new messages + +If HACK-SIG is true,then we search backward from END for something that +looks like the beginning of a signature block, and don't consider that a +part of the message (this is because signatures are often incorrectly +interpreted as cited text.)" + (if (< end start) + (let ((s start)) (setq start end end s))) + (let* ((lines (count-lines start end)) + (too-big (and wl-highlight-max-summary-lines + (> lines wl-highlight-max-summary-lines))) + (real-end end) + gc-message + e p hend i percent) + (save-excursion + (save-restriction + (widen) + (narrow-to-region start end) + (if (not too-big) + (save-restriction + (goto-char start) + (setq i 0) + (while (not (eobp)) + (wl-highlight-summary-current-line nil nil wl-summary-scored) + (setq i (+ i 1)) + (setq percent (/ (* i 100) lines)) + (if (eq (% percent 5) 0) + (elmo-display-progress + 'wl-highlight-summary "Highlighting..." + percent)) + (forward-line 1)) + (message "Highlighting...done."))))))) + +(defun wl-highlight-headers () + (let ((beg (point-min)) + (end (or (save-excursion (re-search-forward "^$" nil t)) + (point-max)))) + (wl-highlight-message beg end nil) + (and wl-highlight-x-face-func + (funcall wl-highlight-x-face-func beg end)) + (run-hooks 'wl-highlight-headers-hook))) + +(defun wl-highlight-body-all () + (wl-highlight-message (point-min) (point-max) t t)) + +(defun-hilit wl-highlight-body () + (let ((beg (or (save-excursion (goto-char (point-min)) + (re-search-forward "^$" nil t)) + (point-min))) + (end (point-max))) + (wl-highlight-message beg end t))) + +(defun-hilit2 wl-highlight-body-region (beg end) + (wl-highlight-message beg end t t)) + +(defun wl-highlight-signature-search-simple (beg end) + "Search signature area in the body message between beg and end. +Returns start point of signature." + (save-excursion + (goto-char end) + (if (re-search-backward "\n--+ *\n" beg t) + (if (eq (char-after (point)) ?\n) + (1+ (point)) + (point)) + end))) + +(defun wl-highlight-signature-search (beg end) + "Search signature area in the body message between beg and end. +Returns start point of signature." + (save-excursion + (goto-char end) + (or + ;; look for legal signature separator (check at first for fasten) + (re-search-backward "\n-- \n" beg t) + + ;; look for dual separator + (save-excursion + (and + (re-search-backward "^[^A-Za-z0-9> \t\n]+ *$" beg t) + (> (- (match-end 0) (match-beginning 0)) 10);; "10" is a magic number. + (re-search-backward + (concat "^" + (regexp-quote (buffer-substring (match-beginning 0) (match-end 0))) + "$") beg t))) + + ;; look for user specified signature-separator + (if (stringp wl-highlight-signature-separator) + (re-search-backward wl-highlight-signature-separator nil t);; case one string + (let ((sep wl-highlight-signature-separator)) ;; case list + (while (and sep + (not (re-search-backward (car sep) beg t))) + (setq sep (cdr sep))) + (point))) ;; if no separator found, returns end. + ))) + +(defun-hilit2 wl-highlight-message (start end hack-sig &optional body-only) + "Highlight message headers between start and end. +Faces used: + wl-highlight-message-headers the part before the colon + wl-highlight-message-header-contents the part after the colon + wl-highlight-message-important-header-contents contents of \"special\" + headers + wl-highlight-message-important-header-contents2 contents of \"special\" + headers + wl-highlight-message-unimportant-header-contents contents of unimportant + headers + wl-highlight-message-cited-text quoted text from other + messages + wl-highlight-message-citation-header header of quoted texts + wl-highlight-message-signature signature + +Variables used: + wl-highlight-important-header-regexp what makes a \"special\" header + wl-highlight-important-header2-regexp what makes a \"special\" header + wl-highlight-unimportant-header-regexp what makes a \"special\" header + wl-highlight-citation-prefix-regexp matches lines of quoted text + wl-highlight-citation-header-regexp matches headers for quoted text + +If HACK-SIG is true,then we search backward from END for something that +looks like the beginning of a signature block, and don't consider that a +part of the message (this is because signatures are often incorrectly +interpreted as cited text.)" + (if (< end start) + (let ((s start)) (setq start end end s))) + (let* ((too-big (and wl-highlight-max-message-size + (> (- end start) + wl-highlight-max-message-size))) + (real-end end) + current beg + e p hend) + (save-excursion + (save-restriction + (widen) + ;; take off signature + (if (and hack-sig (not too-big)) + (setq end (funcall wl-highlight-signature-search-func + (- end wl-max-signature-size) end))) + (if hack-sig + (put-text-property end (point-max) + 'face 'wl-highlight-message-signature)) + (narrow-to-region start end) + + (save-restriction + ;; narrow down to just the headers... + (goto-char start) + ;; If this search fails then the narrowing performed above + ;; is sufficient + (if (re-search-forward (format + "^$\\|%s" + (regexp-quote mail-header-separator)) nil t) + (narrow-to-region (point-min) (point))) + (goto-char start) + (while (and (not body-only) + (not (eobp))) + (cond + ((looking-at "^\\([^ \t\n:]+[ \t]*:\\) *\\(.*\\(\n[ \t].*\\)*\n\\)") + (setq hend (match-end 0)) + (put-text-property (match-beginning 1) (match-end 1) + 'face 'wl-highlight-message-headers) + (setq p (match-end 1)) + (cond + ((catch 'match + (let ((regexp-alist wl-highlight-message-header-alist)) + (while regexp-alist + (when (save-match-data + (looking-at (caar regexp-alist))) + (put-text-property + (match-beginning 2) (match-end 2) + 'face + (cdar regexp-alist)) + (throw 'match t)) + (setq regexp-alist (cdr regexp-alist))) + (throw 'match nil)))) + (t + (put-text-property + (match-beginning 2) (match-end 2) + 'face 'wl-highlight-message-header-contents))) + (goto-char hend)) + ((looking-at mail-header-separator) + (put-text-property (match-beginning 0) (match-end 0) + 'face 'wl-highlight-header-separator-face) + (goto-char (match-end 0))) + ;; ignore non-header field name lines + (t (forward-line 1))))) + ;; now do the body, unless it's too big.... + (if too-big + nil + (let (prefix prefix-face-alist pair end) + (while (not (eobp)) + (cond + ((null wl-highlight-force-citation-header-regexp) + nil) + ((looking-at wl-highlight-force-citation-header-regexp) + (setq current 'wl-highlight-message-citation-header) + (setq end (match-end 0))) + ((null wl-highlight-citation-prefix-regexp) + nil) + ((looking-at wl-highlight-citation-prefix-regexp) + (setq prefix (buffer-substring (point) + (match-end 0))) + (setq pair (assoc prefix prefix-face-alist)) + (unless pair + (setq prefix-face-alist + (append prefix-face-alist + (list + (setq pair + (cons + prefix + (nth + (% (length prefix-face-alist) + (length + wl-highlight-citation-face-list)) + wl-highlight-citation-face-list))))))) + (unless wl-highlight-highlight-citation-too + (goto-char (match-end 0))) + (setq current (cdr pair))) + ((null wl-highlight-citation-header-regexp) + nil) + ((looking-at wl-highlight-citation-header-regexp) + (setq current 'wl-highlight-message-citation-header) + (setq end (match-end 0))) + (t (setq current nil))) + (cond (current + (setq p (point)) + (forward-line 1) ; this is to put the \n in the face too + (let ();(inhibit-read-only t)) + (put-text-property p (or end (point)) + 'face current) + (setq end nil)) + (forward-char -1))) + (forward-line 1))) + (run-hooks 'wl-highlight-message-hook)))))) + + +;; highlight-mouse-line for folder mode + +(defun wl-highlight-folder-mouse-line () + (interactive) + (let* ((end (save-excursion (end-of-line) (point))) + (beg (progn + (re-search-forward "[^ ]" end t) + (1- (point)))) + (inhibit-read-only t)) + (put-text-property beg end 'mouse-face 'highlight))) + +;;; wl-highlight.el ends here diff --git a/wl/wl-message.el b/wl/wl-message.el new file mode 100644 index 0000000..37bb7ba --- /dev/null +++ b/wl/wl-message.el @@ -0,0 +1,615 @@ +;;; wl-message.el -- Message displaying modules for Wanderlust. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <2000-03-17 10:19:41 teranisi> + +;; This file is part of Wanderlust (Yet Another Message Interface on Emacsen). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; + +(require 'wl-vars) +(require 'wl-highlight) + +(eval-when-compile + (if wl-use-semi + (progn + (require 'wl-mime) + (require 'mime-view) + (require 'mmelmo-imap4)) + (require 'tm-wl)) + (mapcar + (function + (lambda (symbol) + (unless (boundp symbol) + (set (make-local-variable symbol) nil)))) + '(mime-view-ignored-field-list mmelmo-imap4-skipped-parts)) + (defun-maybe event-window (a)) + (defun-maybe posn-window (a)) + (defun-maybe event-start (a)) + (defun-maybe mime-open-entity (a b))) + +(defvar wl-original-buf-name "*Message*") +(defvar wl-message-buf-name "Message") +(defvar wl-message-buffer-cur-summary-buffer nil) +(defvar wl-message-buffer-cur-folder nil) +(defvar wl-message-buffer-cur-number nil) + +(defvar wl-original-buffer-cur-folder nil) +(defvar wl-original-buffer-cur-number nil) +(defvar wl-original-buffer-cur-msgdb nil) + +(mapcar + (function make-variable-buffer-local) + (list 'wl-message-buffer-cur-folder + 'wl-message-buffer-cur-number)) + +(provide 'wl-message) + +(defvar wl-fixed-window-configuration nil) + +(defun wl-message-buffer-window () + (let* ((mes-buf (concat "^" (default-value 'wl-message-buf-name))) + (start-win (selected-window)) + (cur-win start-win)) + (catch 'found + (while (progn + (setq cur-win (next-window cur-win)) + (if (string-match mes-buf (buffer-name (window-buffer cur-win))) + (throw 'found cur-win)) + (not (eq cur-win start-win))))))) + +(defun wl-select-buffer (buffer) + (let ((gbw (or (get-buffer-window buffer) + (wl-message-buffer-window))) + (sum (car wl-message-window-size)) + (mes (cdr wl-message-window-size)) + whi) + (when (and gbw + (not (eq (save-excursion (set-buffer (window-buffer gbw)) + wl-message-buffer-cur-summary-buffer) + (current-buffer)))) + (delete-window gbw) + (run-hooks 'wl-message-window-deleted-hook) + (setq gbw nil)) + (if gbw + (select-window gbw) +; (if (or (null mes) +; wl-stay-folder-window) +; (delete-other-windows)) + (when wl-fixed-window-configuration + (delete-other-windows) + (and wl-stay-folder-window + (wl-summary-toggle-disp-folder))) + (setq whi (1- (window-height))) + (if mes + (progn + (let ((total (+ sum mes))) + (setq sum (max window-min-height (/ (* whi sum) total))) + (setq mes (max window-min-height (/ (* whi mes) total)))) + (if (< whi (+ sum mes)) + (enlarge-window (- (+ sum mes) whi))))) + (split-window (get-buffer-window (current-buffer)) sum) + (other-window 1)) + (switch-to-buffer buffer))) + +;; +;; called by wl-summary-mode buffer +;; +(defvar wl-message-func-called-hook nil) + +(defun wl-message-scroll-down (amount) + (let ((view-message-buffer (get-buffer-create wl-message-buf-name)) + (cur-buf (current-buffer))) + (wl-select-buffer view-message-buffer) + (if (bobp) + () + (scroll-down)) + (select-window (get-buffer-window cur-buf)))) + +(defun wl-message-scroll-up (amount) + (let ((view-message-buffer (get-buffer-create wl-message-buf-name)) + (cur-buf (current-buffer))) + (wl-select-buffer view-message-buffer) + (save-excursion + (save-restriction + (widen) + (forward-page 1) + (if (pos-visible-in-window-p (point)) + (wl-message-narrow-to-page 1)))) ;Go to next page. + (if (eobp) + () + (scroll-up)) + (select-window (get-buffer-window cur-buf)))) + +(defun wl-message-follow-current-entity (buffer) + "Follow to current message" + (wl-draft-reply (wl-message-get-original-buffer) + 'to-all wl-message-buffer-cur-summary-buffer) + (let ((mail-reply-buffer buffer)) + (wl-draft-yank-from-mail-reply-buffer nil))) + +(defun wl-message-original-mode () + (setq major-mode 'wl-message-original-mode) + (setq mode-name "Original") + (setq buffer-read-only t) + (if (fboundp 'set-buffer-file-coding-system) + (set-buffer-file-coding-system wl-cs-noconv))) + +(defun wl-message-mode () + (interactive) + (setq major-mode 'wl-message-mode) + (setq buffer-read-only t) + (setq mode-name "Message")) + +(defun wl-message-get-buffer-create () + (let ((buf-name wl-message-buf-name)) + (or (get-buffer buf-name) + (save-excursion + (set-buffer (get-buffer-create buf-name)) + (wl-message-mode) + (run-hooks 'wl-message-buffer-created-hook) + (get-buffer buf-name))))) + +(defun wl-message-original-get-buffer-create () + (or (get-buffer wl-original-buf-name) + (save-excursion + (set-buffer (get-buffer-create wl-original-buf-name)) + (wl-message-original-mode) + (get-buffer wl-original-buf-name)))) + +(defun wl-message-exit () + (interactive) + (let (summary-buf summary-win) + (if (setq summary-buf wl-message-buffer-cur-summary-buffer) + (if (setq summary-win (get-buffer-window summary-buf)) + (select-window summary-win) + (switch-to-buffer summary-buf) + (wl-select-buffer wl-message-buf-name) + (select-window (get-buffer-window summary-buf)))) + (run-hooks 'wl-message-exit-hook))) + +(defun wl-message-decode (outbuf inbuf flag) + (cond + ((eq flag 'all-header) + (save-excursion + (set-buffer inbuf) + (let ((buffer-read-only nil)) + (decode-mime-charset-region (point-min) + (save-excursion + (goto-char (point-min)) + (re-search-forward "^$" nil t) + (point)) + wl-mime-charset))) + (wl-message-decode-with-all-header outbuf inbuf)) + ((eq flag 'no-mime) + (save-excursion + (set-buffer inbuf) + (let ((buffer-read-only nil)) + (save-excursion + (set-buffer outbuf) + (elmo-set-buffer-multibyte nil)) + (copy-to-buffer outbuf (point-min) (point-max)) + (set-buffer outbuf) + (local-set-key "q" 'wl-message-exit) + (local-set-key "p" 'wl-message-exit) + (local-set-key "n" 'wl-message-exit) + (elmo-set-buffer-multibyte default-enable-multibyte-characters) + ;;(decode-mime-charset-region (point-min) (point-max) wl-mime-charset) + ;; we can call decode-coding-region() directly, because multibyte flag is t. + (decode-coding-region (point-min) (point-max) wl-cs-autoconv) + (wl-highlight-message (point-min) + (save-excursion + (goto-char (point-min)) + (re-search-forward "^$" nil t)) nil)))) + (t ; normal + (save-excursion + (set-buffer inbuf) + (let ((buffer-read-only nil)) + (decode-mime-charset-region (point-min) + (save-excursion + (goto-char (point-min)) + (re-search-forward "^$" nil t) + (point)) + wl-mime-charset))) + (wl-message-decode-mode outbuf inbuf)))) + +(defun wl-message-prev-page (&optional lines) + "Scroll down this message. Returns non-nil if top of message" + (interactive) + (let ((cur-buf (current-buffer)) + (view-message-buffer (get-buffer-create wl-message-buf-name)) + ret-val) + (wl-select-buffer view-message-buffer) + (move-to-window-line 0) + (if (and wl-break-pages + (bobp) + (not (save-restriction (widen) (bobp)))) + (progn + (wl-message-narrow-to-page -1) + (goto-char (point-max)) + (recenter -1)) + (if (not (bobp)) + (scroll-down lines) + (setq ret-val t))) + (select-window (get-buffer-window cur-buf)) + ret-val)) + +(static-if (fboundp 'luna-make-entity) + (defsubst wl-message-make-mime-entity (backend number backend folder msgdb) + (luna-make-entity (mm-expand-class-name 'elmo) + :location (get-buffer-create + (concat mmelmo-entity-buffer-name "0")) + :imap (eq backend 'elmo-imap4) + :folder folder + :number number + :msgdb msgdb :size 0)) + (defsubst wl-message-make-mime-entity (backend number backend folder msgdb) + (mime-open-entity backend (list folder number msgdb nil)))) + +(defun wl-message-next-page (&optional lines) + "Scroll up this message. Returns non-nil if bottom of message" + (interactive) + (let ((cur-buf (current-buffer)) + (view-message-buffer (get-buffer-create wl-message-buf-name)) + ret-val) + (wl-select-buffer view-message-buffer) + (move-to-window-line -1) + (if (save-excursion + (end-of-line) + (and (pos-visible-in-window-p) + (eobp))) + (if (or (null wl-break-pages) + (save-excursion + (save-restriction + (widen) (forward-line) (eobp)))) + (setq ret-val t) + (wl-message-narrow-to-page 1) + (setq ret-val nil)) + (condition-case () + (scroll-up lines) + (end-of-buffer + (goto-char (point-max)))) + (setq ret-val nil)) + (select-window (get-buffer-window cur-buf)) + ret-val + )) + +(defun wl-message-narrow-to-page (&optional arg) + (interactive "P") + (setq arg (if arg (prefix-numeric-value arg) 0)) + (save-excursion + (condition-case () + (forward-page -1) ; Beginning of current page. + (beginning-of-buffer + (goto-char (point-min)))) + (forward-char 1) ; for compatibility with emacs-19.28 and emacs-19.29 + (widen) + (cond + ((> arg 0) (forward-page arg)) + ((< arg 0) (forward-page (1- arg)))) + (forward-page) + (if wl-break-pages + (narrow-to-region (point) + (progn + (forward-page -1) + (if (and (eolp) (not (bobp))) + (forward-line)) + (point)))) )) + +(defun wl-message-toggle-disp-summary () + (interactive) + (let ((summary-buf (get-buffer wl-message-buffer-cur-summary-buffer)) + summary-win) + (if (and summary-buf + (buffer-live-p summary-buf)) + (if (setq summary-win (get-buffer-window summary-buf)) + (delete-window summary-win) + (switch-to-buffer summary-buf) + (wl-select-buffer wl-message-buf-name)) + (wl-summary-goto-folder-subr wl-message-buffer-cur-folder 'no-sync + nil nil t) + ; no summary-buf + (let ((sum-buf (current-buffer))) + (wl-select-buffer wl-message-buf-name) + (setq wl-message-buffer-cur-summary-buffer sum-buf))))) + +(defun wl-message-normal-get-original-buffer () + (let (ret-val) + (if (setq ret-val (get-buffer wl-original-buf-name)) + ret-val + (set-buffer (setq ret-val + (get-buffer-create wl-original-buf-name))) + (wl-message-original-mode) + ret-val))) + + +(if wl-use-semi + (defalias 'wl-message-get-original-buffer + 'mmelmo-get-original-buffer) + (defalias 'wl-message-get-original-buffer + 'wl-message-normal-get-original-buffer)) + +(defvar wl-message-redisplay-func 'wl-normal-message-redisplay) +(defvar wl-message-cache-used nil) ;whether cache is used or not. + +(defun wl-message-redisplay (folder number flag msgdb &optional force-reload) + (let ((default-mime-charset wl-mime-charset) + (buffer-read-only nil)) + (setq wl-message-cache-used nil) + (if wl-message-redisplay-func + (funcall wl-message-redisplay-func + folder number flag msgdb force-reload)))) + +;; nil means don't fetch all. +(defun wl-message-decide-backend (folder number message-id size) + (let ((dont-do-that (and + (not (setq wl-message-cache-used + (or + (elmo-buffer-cache-hit + (list folder number message-id)) + (elmo-cache-exists-p message-id + folder number)))) + (integerp size) + (not (elmo-local-file-p folder number)) + wl-fetch-confirm-threshold + (>= size wl-fetch-confirm-threshold) + (not (y-or-n-p + (format "Fetch entire message? (%dbytes)" + size)))))) + (message "") + (cond ((and dont-do-that + (eq (elmo-folder-number-get-type folder number) 'imap4) + (not (and (elmo-use-cache-p folder number) + (elmo-cache-exists-p message-id folder number)))) + 'elmo-imap4) + (t (if (not dont-do-that) 'elmo))))) + +(defmacro wl-message-original-buffer-folder () + wl-original-buffer-cur-folder) + +(defmacro wl-message-original-buffer-number () + wl-original-buffer-cur-number) + +(defun wl-message-set-original-buffer-information (folder number) + (when (or (not (string= folder (or wl-original-buffer-cur-folder ""))) + (not (eq number (or wl-original-buffer-cur-number 0)))) + (setq wl-original-buffer-cur-folder folder) + (setq wl-original-buffer-cur-number number))) + +;; Works on FLIM-1.9.0/SEMI-1.8.2 or later (maybe). +(defun wl-mmelmo-message-redisplay (folder number flag msgdb + &optional force-reload) + (let* ((cur-buf (current-buffer)) + (view-message-buffer (wl-message-get-buffer-create)) + (message-id (cdr (assq number + (elmo-msgdb-get-number-alist msgdb)))) + (size (elmo-msgdb-overview-entity-get-size + (assoc message-id + (elmo-msgdb-get-overview msgdb)))) + (backend (wl-message-decide-backend folder number message-id size)) + cur-entity ret-val header-end real-fld-num summary-win) + (require 'mmelmo) + (wl-select-buffer view-message-buffer) + (set-buffer view-message-buffer) + (unwind-protect + (progn + (setq wl-message-buffer-cur-summary-buffer cur-buf) + (setq wl-message-buffer-cur-folder folder) + (setq wl-message-buffer-cur-number number) + (setq buffer-read-only nil) + (erase-buffer) + (if backend + (let (mime-display-header-hook ;; bind to nil... + (mime-view-ignored-field-list + (if (eq flag 'all-header) + nil + mime-view-ignored-field-list)) + (mmelmo-force-reload force-reload) + (mmelmo-imap4-threshold wl-fetch-confirm-threshold)) + (setq real-fld-num (elmo-get-real-folder-number + folder number)) + (setq cur-entity + (wl-message-make-mime-entity + backend + (if (eq backend 'elmo-imap4) + (cdr real-fld-num) + number) + backend + (if (eq backend 'elmo-imap4) + (car real-fld-num) + folder) + msgdb)) + (setq mmelmo-imap4-skipped-parts nil) + ;;; mime-display-message sets buffer-read-only variable as t. + ;;; which makes buffer read-only status confused... + (wl-mime-display-message cur-entity view-message-buffer + nil nil 'mmelmo-original-mode) + (if mmelmo-imap4-skipped-parts + (progn + (message "Skipped fetching of %s." + (mapconcat + (lambda (x) + (format "[%s]" x)) + mmelmo-imap4-skipped-parts ",")))) + (if (and (eq backend 'elmo-imap4) + (null mmelmo-imap4-skipped-parts)) + (message "No required part was skipped.")) + (setq ret-val (not (eq backend 'elmo-imap4)))) + (message "Skipped fetching.") + (setq ret-val nil))) + (setq buffer-read-only nil) + (wl-message-set-original-buffer-information folder number) + (wl-message-overload-functions) + ;; highlight body + (when wl-highlight-body-too + (wl-highlight-body)) + (condition-case () + (wl-message-narrow-to-page) + (error nil));; ignore errors. + (setq mode-line-buffer-identification + (format "Wanderlust: << %s / %s >>" + (if (memq 'modeline wl-use-folder-petname) + (wl-folder-get-petname folder) + folder) number)) + (goto-char (point-min)) + (unwind-protect + (save-excursion + (run-hooks 'wl-message-redisplay-hook)) + ;; go back to summary mode + (set-buffer-modified-p nil) + (setq buffer-read-only t) + (set-buffer cur-buf) + (setq summary-win (get-buffer-window cur-buf)) + (if (window-live-p summary-win) + (select-window summary-win)))) + ret-val + )) + +(defun wl-normal-message-redisplay (folder number flag msgdb + &optional force-reload) + (interactive) + (let* ((cur-buf (current-buffer)) + (original-message-buffer (wl-message-get-original-buffer)) + (view-message-buffer (wl-message-get-buffer-create)) + (message-id (cdr (assq number + (elmo-msgdb-get-number-alist msgdb)))) + (size (elmo-msgdb-overview-entity-get-size + (assoc message-id + (elmo-msgdb-get-overview msgdb)))) + header-end ret-val summary-win + ) + (wl-select-buffer view-message-buffer) + (unwind-protect + (progn + (setq wl-message-buffer-cur-summary-buffer cur-buf) + (setq wl-message-buffer-cur-folder folder) + (setq wl-message-buffer-cur-number number) + (setq buffer-read-only nil) + (erase-buffer) + (if (or (eq (elmo-folder-number-get-type folder number) 'localdir) + (not (and (integerp size) + wl-fetch-confirm-threshold + (>= size wl-fetch-confirm-threshold) + (not (elmo-cache-exists-p message-id + folder number)) + (not (y-or-n-p + (format "Fetch entire message? (%dbytes)" + size)))))) + (progn + (save-excursion + (set-buffer original-message-buffer) + (let ((buffer-read-only nil)) + (elmo-read-msg-with-buffer-cache + folder number original-message-buffer msgdb force-reload))) + ;; decode MIME message. + (wl-message-decode + view-message-buffer + original-message-buffer flag) + (setq ret-val t)) + (save-excursion + (set-buffer view-message-buffer) + (insert "\n\n")))) + (setq buffer-read-only nil) + (wl-message-set-original-buffer-information folder number) + (wl-message-overload-functions) + ;; highlight body + (and wl-highlight-body-too (wl-highlight-body)) + (condition-case () + (wl-message-narrow-to-page) + (error nil)) ; ignore errors. + (setq mode-line-buffer-identification + (format "Wanderlust: << %s / %s >>" + (if (memq 'modeline wl-use-folder-petname) + (wl-folder-get-petname folder) + folder) + number)) + (goto-char (point-min)) + (unwind-protect + (run-hooks 'wl-message-redisplay-hook) + ;; go back to summary mode + (set-buffer-modified-p nil) + (setq buffer-read-only t) + (set-buffer cur-buf) + (setq summary-win (get-buffer-window cur-buf)) + (if (window-live-p summary-win) + (select-window summary-win))) + ret-val + ))) + +(defun wl-message-refer-article-or-url (e) + "Read article specified by message-id around point. If failed, + attempt to execute button-dispatcher." + (interactive "e") + (let ((window (get-buffer-window (current-buffer))) + mouse-window point beg end msg-id) + (unwind-protect + (progn + (mouse-set-point e) + (setq mouse-window (get-buffer-window (current-buffer))) + (setq point (point)) + (setq beg (save-excursion (beginning-of-line) (point))) + (setq end (save-excursion (end-of-line) (point))) + (search-forward ">" end t) ;Move point to end of "<....>". + (if (and (re-search-backward "\\(<[^<> \t\n]+@[^<> \t\n]+>\\)" + beg t) + (not (string-match "mailto:" + (setq msg-id (wl-match-buffer 1))))) + (progn + (goto-char point) + (switch-to-buffer-other-window + wl-message-buffer-cur-summary-buffer) + (if (wl-summary-jump-to-msg-by-message-id msg-id) + (wl-summary-redisplay))) + (wl-message-button-dispatcher e))) + (if (eq mouse-window (get-buffer-window (current-buffer))) + (select-window window))))) + +(defun wl-message-uu-substring (buf outbuf &optional first last) + (save-excursion + (set-buffer buf) + (search-forward "\n\n") + (let ((sp (point)) + ep filename case-fold-search) + (if first + (progn + (re-search-forward "^begin[ \t]+[0-9]+[ \t]+\\([^ ].*\\)" nil t) + (setq filename (buffer-substring (match-beginning 1)(match-end 1)))) + (re-search-forward "^M.*$" nil t)) ; uuencoded string + (beginning-of-line) + (setq sp (point)) + (goto-char (point-max)) + (if last + (re-search-backward "^end" sp t) + (re-search-backward "^M.*$" sp t)) ; uuencoded string + (forward-line 1) + (setq ep (point)) + (set-buffer outbuf) + (goto-char (point-max)) + (insert-buffer-substring buf sp ep) + (set-buffer buf) + filename))) + +;;; wl-message.el ends here diff --git a/wl/wl-mime.el b/wl/wl-mime.el new file mode 100644 index 0000000..f1fb91b --- /dev/null +++ b/wl/wl-mime.el @@ -0,0 +1,369 @@ +;;; wl-mime.el -- SEMI implementations of MIME processing on Wanderlust. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <2000-03-23 15:53:53 teranisi> + +;; This file is part of Wanderlust (Yet Another Message Interface on Emacsen). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; + +(require 'mime-view) +(require 'mime-edit) +(require 'mime-play) +(require 'mmelmo) + +(eval-when-compile + (defun-maybe Meadow-version ()) + (mapcar + (function + (lambda (symbol) + (unless (boundp symbol) + (set (make-local-variable symbol) nil)))) + '(xemacs-betaname + xemacs-codename + enable-multibyte-characters + mule-version))) + +;;; Draft + +(defalias 'wl-draft-editor-mode 'mime-edit-mode) + +(defalias 'wl-draft-decode-message-in-buffer + 'mime-edit-decode-message-in-buffer) + +(defun wl-draft-yank-current-message-entity () + "Yank currently displayed message entity. +By setting following-method as yank-content." + (let ((wl-draft-buffer (current-buffer)) + (mime-view-following-method-alist + (list (cons 'mmelmo-original-mode + (function wl-draft-yank-to-draft-buffer)))) + (mime-preview-following-method-alist + (list (cons 'mmelmo-original-mode + (function wl-draft-yank-to-draft-buffer))))) + (if (get-buffer (wl-current-message-buffer)) + (save-excursion + (save-restriction + (set-buffer (wl-current-message-buffer)) + (widen) + (mime-preview-follow-current-entity)))))) + +(defalias 'wl-draft-enclose-digest-region 'mime-edit-enclose-digest-region) + +;; SEMI 1.13.5 or later. +;; (mime-display-message +;; MESSAGE &optional +;; PREVIEW-BUFFER MOTHER DEFAULT-KEYMAP-OR-FUNCTION ORIGINAL-MAJOR-MODE) +;; SEMI 1.13.4 or earlier. +;; (mime-display-message +;; MESSAGE &optional +;; PREVIEW-BUFFER MOTHER DEFAULT-KEYMAP-OR-FUNCTION) +(static-if (or (and mime-user-interface-product + (eq (nth 0 (aref mime-user-interface-product 1)) 1) + (>= (nth 1 (aref mime-user-interface-product 1)) 14)) + (and mime-user-interface-product + (eq (nth 0 (aref mime-user-interface-product 1)) 1) + (eq (nth 1 (aref mime-user-interface-product 1)) 13) + (>= (nth 2 (aref mime-user-interface-product 1)) 5))) + ;; Has original-major-mode optional argument. + (defalias 'wl-mime-display-message 'mime-display-message) + (defmacro wl-mime-display-message (message &optional + preview-buffer mother + default-keymap-or-function + original-major-mode) + (` (mime-display-message (, message) (, preview-buffer) (, mother) + (, default-keymap-or-function)))) + ;; User agent field of XEmacs has problem on SEMI 1.13.4 or earlier. + (setq mime-edit-user-agent-value + (concat + (mime-product-name mime-user-interface-product) "/" + (mapconcat + #'number-to-string + (mime-product-version mime-user-interface-product) ".") + " (" (mime-product-code-name mime-user-interface-product) + ") " (mime-product-name mime-library-product) + "/" (mapconcat #'number-to-string + (mime-product-version mime-library-product) ".") + " (" (mime-product-code-name mime-library-product) ") " + (if (featurep 'xemacs) + (concat + (if (featurep 'mule) "MULE") + " XEmacs" + (if (string-match "\\s +\\((\\|\\\"\\)" emacs-version) + (concat "/" (substring emacs-version 0 + (match-beginning 0)) + (if (and (boundp 'xemacs-betaname) + ;; It does not exist in XEmacs + ;; versions prior to 20.3. + xemacs-betaname) + (concat " " xemacs-betaname) + "") + " (" xemacs-codename ") (" + system-configuration ")") + " (" emacs-version ")")) + (let ((ver (if (string-match "\\.[0-9]+$" emacs-version) + (substring emacs-version 0 (match-beginning 0)) + emacs-version))) + (if (featurep 'mule) + (if (boundp 'enable-multibyte-characters) + (concat "Emacs/" ver + " (" system-configuration ")" + (if enable-multibyte-characters + (concat " MULE/" mule-version) + " (with unibyte mode)") + (if (featurep 'meadow) + (let ((mver (Meadow-version))) + (if (string-match "^Meadow-" mver) + (concat " Meadow/" + (substring mver + (match-end 0))))))) + (concat "MULE/" mule-version + " (based on Emacs " ver ")")) + (concat "Emacs/" ver " (" system-configuration ")"))))))) + +;; FLIM 1.12.7 +;; (mime-read-field FIELD-NAME &optional ENTITY) +;; FLIM 1.13.2 or later +;; (mime-entity-read-field ENTITY FIELD-NAME) +(static-if (fboundp 'mime-entity-read-field) + (defalias 'wl-mime-entity-read-field 'mime-entity-read-field) + (defmacro wl-mime-entity-read-field (entity field-name) + (` (mime-read-field (, field-name) (, entity))))) + +(defun wl-draft-preview-message () + (interactive) + (let ((mime-display-header-hook 'wl-highlight-headers) + mime-view-ignored-field-list ; all header. + (mime-edit-translate-buffer-hook (append + (list 'wl-draft-config-exec) + mime-edit-translate-buffer-hook))) + (mime-edit-preview-message) + (let ((buffer-read-only nil)) + (when wl-highlight-body-too + (wl-highlight-body)) + (run-hooks 'wl-draft-preview-message-hook)))) + +(defalias 'wl-draft-caesar-region 'mule-caesar-region) + +(defalias 'wl-draft-insert-message 'mime-edit-insert-message) + +(defalias 'wl-draft-insert-mail 'mime-edit-insert-mail) + +;;; Message + +(defun wl-message-decode-mode (outbuf inbuf) + (let ((mime-view-content-header-filter-hook 'wl-highlight-headers) + (mime-display-header-hook 'wl-highlight-headers)) + (mime-view-mode nil nil nil inbuf outbuf))) + +(defun wl-message-decode-with-all-header (outbuf inbuf) + (let ((mime-view-ignored-field-regexp "^:$") + (mime-view-content-header-filter-hook 'wl-highlight-headers) + (mime-display-header-hook 'wl-highlight-headers) + mime-view-ignored-field-list) + (mime-view-mode nil nil nil inbuf outbuf))) + +(defun wl-message-delete-mime-out-buf () + (let (mime-out-buf mime-out-win) + (if (setq mime-out-buf (get-buffer mime-echo-buffer-name)) + (if (setq mime-out-win (get-buffer-window mime-out-buf)) + (delete-window mime-out-win))))) + +(defun wl-message-request-partial (folder number msgdb) + (elmo-set-work-buf + (elmo-read-msg-no-cache folder number (current-buffer) msgdb) + (mime-parse-buffer nil))); 'mime-buffer-entity))) + +(defalias 'wl-message-read 'mime-preview-scroll-up-entity) +(defalias 'wl-message-next-content 'mime-preview-move-to-next) +(defalias 'wl-message-prev-content 'mime-preview-move-to-previous) +(defalias 'wl-message-play-content 'mime-preview-play-current-entity) +(defalias 'wl-message-extract-content 'mime-preview-extract-current-entity) +(defalias 'wl-message-quit 'mime-preview-quit) +(defalias 'wl-message-button-dispatcher 'mime-button-dispatcher) + +;;; Summary +(defun wl-summary-burst () + (interactive) + (let ((raw-buf (wl-message-get-original-buffer)) + (i 0) + target + children message-entity content-type) + (save-excursion + (setq target wl-summary-buffer-folder-name) + (while (not (elmo-folder-writable-p target)) + (setq target + (wl-summary-read-folder wl-default-folder "to extract to"))) + (wl-summary-set-message-buffer-or-redisplay) + (save-excursion + (set-buffer (get-buffer wl-message-buf-name)) + (setq message-entity (get-text-property (point-min) 'mime-view-entity))) + (set-buffer raw-buf) + (setq children (mime-entity-children message-entity)) + (message "Bursting...") + (while children + (setq content-type (mime-entity-content-type (car children))) + (when (and (eq (cdr (assq 'type content-type)) 'message) + (eq (cdr (assq 'subtype content-type)) 'rfc822)) + (message (format "Bursting...%s" (setq i (+ 1 i)))) + (setq message-entity + (car (mime-entity-children (car children)))) + (save-restriction + (narrow-to-region (mime-entity-point-min message-entity) + (mime-entity-point-max message-entity)) + (elmo-append-msg target + ;;(mime-entity-content (car children)))) + (buffer-substring (point-min) (point-max)) + (std11-field-body "Message-ID")))) + (setq children (cdr children))) + (message "Bursting...done.")) + (if (elmo-folder-plugged-p target) + (elmo-commit target)) + (wl-summary-sync-update3))) + + +;; internal variable. +(defvar wl-mime-save-dir nil "Last saved directory.") +;;; Yet another save method. +(defun wl-mime-save-content (entity situation) + (let ((filename (read-file-name "Save to file: " + (expand-file-name + (or (mime-entity-safe-filename entity) + ".") + (or wl-mime-save-dir + wl-tmp-dir))))) + (while (file-directory-p filename) + (setq filename (read-file-name "Please set filename (not directory): " + filename))) + (if (file-exists-p filename) + (or (yes-or-no-p (format "File %s exists. Save anyway? " filename)) + (error "Not saved"))) + (setq wl-mime-save-dir (file-name-directory filename)) + (mime-write-entity-content entity filename))) + +;;; Yet another combine method. +(defun wl-mime-combine-message/partial-pieces (entity situation) + "Internal method for wl to combine message/partial messages +automatically." + (interactive) + (let* ((msgdb (save-excursion + (set-buffer wl-message-buffer-cur-summary-buffer) + wl-summary-buffer-msgdb)) + (mime-display-header-hook 'wl-highlight-headers) + (folder wl-message-buffer-cur-folder) + (id (or (cdr (assoc "id" situation)) "")) + (mother (current-buffer)) + subject-id overviews + (root-dir (expand-file-name + (concat "m-prts-" (user-login-name)) + temporary-file-directory)) + full-file) + (setq root-dir (concat root-dir "/" (replace-as-filename id))) + (setq full-file (concat root-dir "/FULL")) + (if (or (file-exists-p full-file) + (not (y-or-n-p "Merge partials?"))) + (with-current-buffer mother + (mime-store-message/partial-piece entity situation)) + (setq subject-id + (eword-decode-string + (decode-mime-charset-string + (wl-mime-entity-read-field entity 'Subject) + wl-summary-buffer-mime-charset))) + (if (string-match "[0-9\n]+" subject-id) + (setq subject-id (substring subject-id 0 (match-beginning 0)))) + (setq overviews (elmo-msgdb-get-overview msgdb)) + (catch 'tag + (while overviews + (when (string-match + (regexp-quote subject-id) + (elmo-msgdb-overview-entity-get-subject (car overviews))) + (let* ((message + ;; request message at the cursor in Subject buffer. + (wl-message-request-partial + folder + (elmo-msgdb-overview-entity-get-number (car overviews)) + msgdb)) + (situation (mime-entity-situation message)) + (the-id (or (cdr (assoc "id" situation)) ""))) + (when (string= (downcase the-id) + (downcase id)) + (with-current-buffer mother + (mime-store-message/partial-piece message situation)) + (if (file-exists-p full-file) + (throw 'tag nil))))) + (setq overviews (cdr overviews))) + (message "Not all partials found."))))) + +;;; Setup methods. +(defun wl-mime-setup () + (set-alist 'mime-preview-quitting-method-alist + 'mmelmo-original-mode 'wl-message-exit) + (set-alist 'mime-view-over-to-previous-method-alist + 'mmelmo-original-mode 'wl-message-exit) + (set-alist 'mime-view-over-to-next-method-alist + 'mmelmo-original-mode 'wl-message-exit) + (set-alist 'mime-preview-over-to-previous-method-alist + 'mmelmo-original-mode 'wl-message-exit) + (set-alist 'mime-preview-over-to-next-method-alist + 'mmelmo-original-mode 'wl-message-exit) + (add-hook 'wl-summary-redisplay-hook 'wl-message-delete-mime-out-buf) + (add-hook 'wl-message-exit-hook 'wl-message-delete-mime-out-buf) + + (ctree-set-calist-strictly + 'mime-acting-condition + '((type . message) (subtype . partial) + (method . wl-mime-combine-message/partial-pieces) + (request-partial-message-method . wl-message-request-partial) + (major-mode . mmelmo-original-mode))) + (ctree-set-calist-strictly + 'mime-acting-condition + '((mode . "extract") + (major-mode . mmelmo-original-mode) + (method . wl-mime-save-content))) + (set-alist 'mime-preview-following-method-alist + 'mmelmo-original-mode + (function wl-message-follow-current-entity)) + (set-alist 'mime-view-following-method-alist + 'mmelmo-original-mode + (function wl-message-follow-current-entity)) + (set-alist 'mime-edit-message-inserter-alist + 'wl-draft-mode (function wl-draft-insert-current-message)) + (set-alist 'mime-edit-mail-inserter-alist + 'wl-draft-mode (function wl-draft-insert-get-message)) + (set-alist 'mime-edit-split-message-sender-alist + 'wl-draft-mode + (cdr (assq 'mail-mode mime-edit-split-message-sender-alist))) + (set-alist 'mime-raw-representation-type-alist + 'mmelmo-original-mode 'binary) + ;; Sort and highlight header fields. + (setq mmelmo-sort-field-list wl-message-sort-field-list) + (add-hook 'mmelmo-header-inserted-hook 'wl-highlight-headers) + (add-hook 'mmelmo-entity-content-inserted-hook 'wl-highlight-body)) + + +(provide 'wl-mime) + +;;; wl-mime.el ends here diff --git a/wl/wl-mule.el b/wl/wl-mule.el new file mode 100644 index 0000000..e4e85cf --- /dev/null +++ b/wl/wl-mule.el @@ -0,0 +1,299 @@ +;;; wl-mule.el -- Wanderlust modules for Mule compatible Emacsen. +;; (Mule2.3@19.28, Mule2.3@19.34, Emacs 20.x) + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <2000-03-22 15:57:29 teranisi> + +;; This file is part of Wanderlust (Yet Another Message Interface on Emacsen). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; + +(eval-when-compile + (require 'wl-folder) + (require 'wl-summary) + (require 'wl-draft) + (require 'wl-message) + (require 'wl-highlight) + (require 'wl-vars) + (defvar-maybe wl-draft-mode-map (make-sparse-keymap))) + +(defun wl-draft-mode-setup () + (require 'derived) + (define-derived-mode wl-draft-mode mail-mode "Draft" + "draft mode for Wanderlust derived from mail mode. +See info under Wanderlust for full documentation. + +Special commands: +\\{wl-draft-mode-map}")) + +;; Common implementations. +(defun wl-highlight-folder-current-line (&optional numbers) + "Highlight current folder line." + (interactive) + (save-excursion + (let ((highlights (list "opened" "closed")) + (inhibit-read-only t) + (fld-name (wl-folder-get-folder-name-by-id + (get-text-property (point) 'wl-folder-entity-id))) + fregexp fsymbol bol eol matched type extent num type) + (beginning-of-line) + (setq bol (point)) + (save-excursion (end-of-line) (setq eol (point))) + (if (and numbers (nth 0 numbers) (nth 1 numbers)) + (progn + (setq fsymbol + (let ((unsync (nth 0 numbers)) + (unread (nth 1 numbers))) + (cond ((and unsync (eq unsync 0)) + (if (and unread (> unread 0)) + 'wl-highlight-folder-unread-face + 'wl-highlight-folder-zero-face)) + ((and unsync + (>= unsync wl-folder-many-unsync-threshold)) + 'wl-highlight-folder-many-face) + (t + 'wl-highlight-folder-few-face)))) + (put-text-property bol eol 'face fsymbol) + (setq matched t))) + (catch 'highlighted + (while highlights + (setq fregexp (symbol-value + (intern (format "wl-highlight-folder-%s-regexp" + (car highlights))))) + (if (not wl-highlight-group-folder-by-numbers) + (setq fsymbol (intern (format "wl-highlight-folder-%s-face" + (car highlights))))) + (when (looking-at fregexp) + (put-text-property bol eol 'face fsymbol) + (setq matched t) + (throw 'highlighted nil)) + (setq highlights (cdr highlights)))) + (if (not matched) + (if (looking-at (format "^[ ]*\\(%s\\|%s\\)" + wl-folder-unsubscribe-mark + wl-folder-removed-mark)) + (put-text-property bol eol 'face + 'wl-highlight-folder-killed-face) + (put-text-property bol eol 'face + 'wl-highlight-folder-unknown-face))) + (if wl-use-highlight-mouse-line + (wl-highlight-folder-mouse-line))))) + +(defun wl-highlight-plugged-current-line ()) +(defun wl-plugged-set-folder-icon (folder string) + string) + +(defun wl-folder-init-icons ()) ; dummy. +(defun wl-plugged-init-icons ()) ; dummy. + +(defun wl-xmas-setup-folder ()) ; dummy +(defun wl-xmas-setup-summary ()) +(defun wl-xmas-setup-draft-toolbar ()) + +(defun wl-message-overload-functions () + (local-set-key "l" 'wl-message-toggle-disp-summary) + (local-set-key [mouse-2] 'wl-message-refer-article-or-url) + (local-set-key [mouse-4] 'wl-message-wheel-down) + (local-set-key [mouse-5] 'wl-message-wheel-up) + (local-set-key [S-mouse-4] 'wl-message-wheel-down) + (local-set-key [S-mouse-5] 'wl-message-wheel-up)) + +(defun wl-message-wheel-up (event) + (interactive "e") + (if (string-match wl-message-buf-name (buffer-name)) + (wl-message-next-page) + (let ((cur-buf (current-buffer)) + proceed) + (save-selected-window + (select-window (posn-window (event-start event))) + (set-buffer cur-buf) + (setq proceed (wl-message-next-page))) + (if proceed + (if (memq 'shift (event-modifiers event)) + (wl-summary-down t) + (wl-summary-next t)))))) + +(defun wl-message-wheel-down (event) + (interactive "e") + (if (string-match wl-message-buf-name (buffer-name)) + (wl-message-prev-page) + (let ((cur-buf (current-buffer)) + proceed) + (save-selected-window + (select-window (posn-window (event-start event))) + (set-buffer cur-buf) + (setq proceed (wl-message-prev-page))) + (if proceed + (if (memq 'shift (event-modifiers event)) + (wl-summary-up t) + (wl-summary-prev t)))))) + +(defun wl-draft-key-setup () + (define-key wl-draft-mode-map "\C-c\C-y" 'wl-draft-yank-original) + (define-key wl-draft-mode-map "\C-c\C-a" 'wl-draft-insert-x-face-field) + (define-key wl-draft-mode-map "\C-c\C-s" 'wl-draft-send) + (define-key wl-draft-mode-map "\C-c\C-c" 'wl-draft-send-and-exit) + (define-key wl-draft-mode-map "\C-c\C-z" 'wl-draft-save-and-exit) + (define-key wl-draft-mode-map "\C-c\C-k" 'wl-draft-kill) + (define-key wl-draft-mode-map "\C-l" 'wl-draft-highlight-and-recenter) + (define-key wl-draft-mode-map "\C-i" 'wl-complete-field-body-or-tab) + (define-key wl-draft-mode-map "\C-c\C-r" 'wl-draft-caesar-region) + (define-key wl-draft-mode-map "\M-t" 'wl-toggle-plugged) + (define-key wl-draft-mode-map "\C-c\C-o" 'wl-jump-to-draft-buffer) + (define-key wl-draft-mode-map "\C-c\C-e" 'wl-draft-config-exec) + (define-key wl-draft-mode-map "\C-c\C-j" 'wl-template-select) + (define-key wl-draft-mode-map "\C-c\C-p" 'wl-draft-preview-message) + (define-key wl-draft-mode-map "\C-x\C-s" 'wl-draft-save) + (define-key wl-draft-mode-map "\C-xk" 'wl-draft-mimic-kill-buffer)) + +(defun wl-draft-overload-menubar () + (local-set-key [menu-bar mail send] + '("Send Message" . wl-draft-send-and-exit)) + (local-set-key [menu-bar mail send-stay] + '("Send, Keep Editing" . wl-draft-send)) + (local-set-key [menu-bar mail cancel] + '("Kill Current Draft" . wl-draft-kill)) + (local-set-key [menu-bar mail yank] + '("Cite Message" . wl-draft-yank-original)) + (local-set-key [menu-bar mail signature] + '("Insert Signature" . insert-signature)) + (local-set-key [menu-bar headers fcc] + '("FCC" . wl-draft-fcc))) + +(defun wl-draft-overload-functions () + (setq mode-line-buffer-identification + (format "Wanderlust: %s" (buffer-name))) + (local-set-key "\C-c\C-s" 'wl-draft-send) ; override + (wl-draft-overload-menubar) + (when wl-show-plug-status-on-modeline + (setq mode-line-format (wl-make-modeline)))) + +(defalias 'wl-make-modeline 'wl-make-modeline-subr) + +;; for "ja-mule-canna-2.3.mini" on PocketBSD +(defun-maybe make-face (a)) + +(eval-when-compile + (require 'static)) +(static-cond + ((and (fboundp 'defface) + (not (featurep 'tinycustom))) + (defalias 'wl-defface 'defface) + (eval-when-compile + (defun wl-face-spec-set-match-display (display frame)) + (defun wl-frame-parameter (frame property &optional default)) + (defun wl-get-frame-properties (&optional frame)))) + (t + (defmacro wl-defface (face spec doc &rest args) + (nconc (list 'wl-declare-face (list 'quote face) spec))) + + (defun wl-declare-face (face spec) + (make-face face) + (while spec + (let* ((entry (car spec)) + (display (nth 0 entry)) + (atts (nth 1 entry))) + (setq spec (cdr spec)) + (when (wl-face-spec-set-match-display display nil) + (apply 'wl-face-attributes-set face nil atts))))) + + (defconst wl-face-attributes + '((:bold set-face-bold-p) + (:italic set-face-italic-p) + (:underline set-face-underline-p) + (:foreground set-face-foreground) + (:background set-face-background) + (:stipple set-face-stipple))) + + (defun wl-face-attributes-set (face frame &rest atts) + "For FACE on FRAME set the attributes [KEYWORD VALUE].... +Each keyword should be listed in `custom-face-attributes'. + +If FRAME is nil, set the default face." + (while atts + (let* ((name (nth 0 atts)) + (value (nth 1 atts)) + (fun (nth 1 (assq name wl-face-attributes)))) + (setq atts (cdr (cdr atts))) + (condition-case nil + (funcall fun face value frame) + (error nil))))) + + (defun wl-frame-parameter (frame property &optional default) + "Return FRAME's value for property PROPERTY." + (or (cdr (assq property (frame-parameters frame))) + default)) + + (eval-when-compile + (defun-maybe x-display-grayscale-p ())) + + (defun wl-get-frame-properties (&optional frame) + "Return a plist with the frame properties of FRAME used by custom." + (list (cons 'type window-system) + (cons 'class (or (wl-frame-parameter frame 'display-type) + (when window-system + (cond ((x-display-color-p) + 'color) + ((and (fboundp 'x-display-grayscale-p) + (x-display-grayscale-p)) + 'grayscale) + (t 'mono))))) + (cons 'background (or (wl-frame-parameter frame 'background-mode) + wl-highlight-background-mode)))) + + (defun wl-face-spec-set-match-display (display frame) + "Non-nil iff DISPLAY matches FRAME. +If FRAME is nil, the current FRAME is used." + ;; This is a kludge to get started, we really should use specifiers! + (if (eq display t) + t + (let* ((props (wl-get-frame-properties frame)) + (type (cdr (assq 'type props))) + (class (cdr (assq 'class props))) + (background (cdr (assq 'background props))) + (match t) + (entries display) + entry req options) + (while (and entries match) + (setq entry (car entries) + entries (cdr entries) + req (car entry) + options (cdr entry) + match (cond ((eq req 'type) + (memq type options)) + ((eq req 'class) + (memq class options)) + ((eq req 'background) + (memq background options)) + (t + (message (format "\ +Warning: Unknown req `%S' with options `%S'" req options)) + nil)))) + match))))) + +(provide 'wl-mule) + +;;; wl-mule.el ends here diff --git a/wl/wl-nemacs.el b/wl/wl-nemacs.el new file mode 100644 index 0000000..4a28f3e --- /dev/null +++ b/wl/wl-nemacs.el @@ -0,0 +1,172 @@ +;;; wl-nemacs.el -- Wanderlust modules for Nemacs. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <2000-03-22 15:57:31 teranisi> + +;; This file is part of Wanderlust (Yet Another Message Interface on Emacsen). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; + +(defun wl-xmas-setup-folder ()) ; dummy +(defun wl-xmas-setup-summary ()) +(defun wl-xmas-setup-draft-toolbar ()) + +(defun wl-summary-setup-mouse ()) +(defun wl-message-overload-functions () + (local-set-key "l" 'wl-message-toggle-disp-summary)) + +(defun wl-message-wheel-up (event) + (interactive "e")) +(defun wl-message-wheel-down (event) + (interactive "e")) + +(defun wl-highlight-folder-current-line (&optional numbers)) +(defun wl-highlight-folder-path (folder-path)) +(defun wl-highlight-summary (start end)) +(defun wl-highlight-folder-group-line (numbers)) +(defun wl-highlight-summary-line-string (line mark indent before-indent)) +(defun wl-highlight-body-region (beg end)) +(defun wl-highlight-message (start end hack-sig &optional body-only)) +(defun wl-delete-all-overlays ()) +(defun wl-highlight-summary-current-line (&optional smark regexp temp-too)) + +(defun wl-highlight-plugged-current-line ()) +(defun wl-plugged-set-folder-icon (folder string) + string) + +(defun wl-folder-init-icons ()) ; dummy. +(defun wl-plugged-init-icons ()) ; dummy. + +(defmacro wl-defface (face spec doc &rest args) + (` (defvar (, face) (, spec) (, doc)))) + +(defsubst elmo-archive-call-process (prog args &optional output) + (apply 'call-process prog nil output nil args) + 0) + +(defun wl-draft-mode-setup () + (defalias 'wl-draft-mode 'mail-mode)) +(defun wl-draft-key-setup ()) + +;; ??? +(defvar mime-article/kanji-code-alist + (list (cons t (mime-charset-to-coding-system default-mime-charset)))) + +(defun wl-draft-overload-functions () + (setq mode-line-buffer-identification + (format "Wanderlust: %s" (buffer-name))) + (local-set-key "\C-c\C-y" 'wl-draft-yank-original) + (local-set-key "\C-c\C-s" 'wl-draft-send) + (local-set-key "\C-c\C-a" 'wl-draft-insert-x-face-field) + (local-set-key "\C-c\C-c" 'wl-draft-send-and-exit) + (local-set-key "\C-c\C-z" 'wl-draft-save-and-exit) + (local-set-key "\C-c\C-k" 'wl-draft-kill) + (local-set-key "\C-l" 'wl-draft-highlight-and-recenter) + (local-set-key "\C-i" 'wl-complete-field-body-or-tab) + (local-set-key "\C-c\C-r" 'wl-draft-caesar-region) + (local-set-key "\M-t" 'wl-toggle-plugged) + (local-set-key "\C-c\C-o" 'wl-jump-to-draft-buffer) + (local-set-key "\C-c\C-j" 'wl-template-select) + (local-set-key "\C-c\C-p" 'wl-draft-preview-message) + (local-set-key "\C-x\C-s" 'wl-draft-save) + (local-set-key "\C-xk" 'wl-draft-mimic-kill-buffer) + (when wl-show-plug-status-on-modeline + (set (make-variable-buffer-local 'mode-line-format) (wl-make-modeline)))) + +(defalias 'wl-make-modeline 'wl-make-modeline-subr) + +;;; Emulations. + +(defvar-maybe user-mail-address nil) +(defvar-maybe mail-send-actions nil) +(defvar-maybe mail-default-headers nil) +(defvar-maybe mail-citation-hook nil) +(defvar-maybe mail-yank-hooks nil) +(defvar-maybe mail-mailer-swallows-blank-line nil) + +(defvar mail-send-actions nil) + +(defun-maybe mail-indent-citation () + "Modify text just inserted from a message to be cited. +The inserted text should be the region. +When this function returns, the region is again around the modified text. + +Normally, indent each nonblank line `mail-indentation-spaces' spaces. +However, if `mail-yank-prefix' is non-nil, insert that prefix on each line." + (let ((start (point))) + (mail-yank-clear-headers start (mark t)) + (if (null mail-yank-prefix) + (indent-rigidly start (mark t) mail-indentation-spaces) + (save-excursion + (goto-char start) + (while (< (point) (mark t)) + (insert mail-yank-prefix) + (forward-line 1)))))) + +(defun-maybe mail-yank-clear-headers (start end) + (save-excursion + (goto-char start) + (if (search-forward "\n\n" end t) + (save-restriction + (narrow-to-region start (point)) + (goto-char start) + (while (let ((case-fold-search t)) + (re-search-forward mail-yank-ignored-headers nil t)) + (beginning-of-line) + (delete-region (point) + (progn (re-search-forward "\n[^ \t]") + (forward-char -1) + (point)))))))) + +(defun-maybe find-file-name-handler (filename operation)) + +(defun-maybe read-event () + (setq unread-command-events + (if (fboundp 'read-char-exclusive) + (read-char-exclusive) + ;; XXX Emacs18.59 does not have read-char-exclusive(). + (read-char)))) + +(defmacro easy-menu-define (a b c d) + (` (defvar (, a) nil (, c)))) +(defmacro easy-menu-add (a) + (` nil)) + +(defun copy-face (a b)) +(defun make-face (a)) +(defun set-face-foreground (a b)) +(defun set-face-background (a b)) +(defun set-face-underline-p (a b)) +(defun set-face-font (a b)) + +;;; XXX cl's member() brings evil upon MIME-View. +;; cl is always called after poe-18, so `(require 'poe-18)' is +;; a dead duck... We MUST re-load it certainly. +(load-library "poe-18") + +(provide 'wl-nemacs) + +;;; wl-nemacs.el ends here diff --git a/wl/wl-refile.el b/wl/wl-refile.el new file mode 100644 index 0000000..836fe54 --- /dev/null +++ b/wl/wl-refile.el @@ -0,0 +1,204 @@ +;;; wl-refile.el -- Refile modules for Wanderlust. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <00/03/23 19:07:28 teranisi> + +;; This file is part of Wanderlust (Yet Another Message Interface on Emacsen). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; + +(require 'wl-vars) +(require 'wl-util) +(provide 'wl-refile) + + +(defvar wl-refile-alist nil) +(defvar wl-refile-alist-file-name "refile-alist") +;; should be renamed to "refile-from-alist" +(defvar wl-refile-msgid-alist nil) +(defvar wl-refile-msgid-alist-file-name "refile-msgid-alist") + +(defvar wl-refile-alist-max-length 1000) + +(defun wl-refile-alist-setup () + (setq wl-refile-alist + (elmo-object-load + (expand-file-name wl-refile-alist-file-name + elmo-msgdb-dir))) + (setq wl-refile-msgid-alist + (elmo-object-load + (expand-file-name wl-refile-msgid-alist-file-name + elmo-msgdb-dir)))) + +(defun wl-refile-alist-save (file-name alist) + (save-excursion + (let ((filename (expand-file-name file-name + elmo-msgdb-dir)) + (tmp-buffer (get-buffer-create " *wl-refile-alist-tmp*"))) + (set-buffer tmp-buffer) + (erase-buffer) + (if (> (length alist) wl-refile-alist-max-length) + (setcdr (nthcdr (1- wl-refile-alist-max-length) alist) nil)) + (prin1 alist tmp-buffer) + (princ "\n" tmp-buffer) + (if (file-writable-p filename) + (write-region (point-min) (point-max) + filename nil 'no-msg) + (message (format "%s is not writable." filename))) + (kill-buffer tmp-buffer)))) + +(defun wl-refile-learn (entity dst) + (let (tocc-list from key hit ml) + (setq dst (elmo-string dst)) + (setq tocc-list + (mapcar (function + (lambda (entity) + (downcase (wl-address-header-extract-address entity)))) + (wl-parse-addresses + (concat + (elmo-msgdb-overview-entity-get-to entity) "," + (elmo-msgdb-overview-entity-get-cc entity))))) + (while tocc-list + (if (wl-string-member + (car tocc-list) + (mapcar (function downcase) wl-subscribed-mailing-list)) + (setq ml (car tocc-list) + tocc-list nil) + (setq tocc-list (cdr tocc-list)))) + (if ml + (setq key ml) ; subscribed entity!! + (or (wl-address-user-mail-address-p + (setq from + (downcase + (wl-address-header-extract-address + (elmo-msgdb-overview-entity-get-from + entity))))) + (setq key from))) + (if (not ml) + (wl-refile-msgid-learn entity dst)) + (if key + (if (setq hit (assoc key wl-refile-alist)) + (setcdr hit dst) + (setq wl-refile-alist + (nconc wl-refile-alist (list (cons key dst)))))))) + +(defun wl-refile-msgid-learn (entity dst) + (let ((key (elmo-msgdb-overview-entity-get-id entity)) + hit) + (setq dst (elmo-string dst)) + (if key + (if (setq hit (assoc key wl-refile-msgid-alist)) + (setcdr hit dst) + (setq wl-refile-msgid-alist (cons (cons key dst) + wl-refile-msgid-alist)))))) + +;; +;; refile guess +;; +(defvar wl-refile-guess-func-list + '(wl-refile-guess-by-rule + wl-refile-guess-by-msgid + wl-refile-guess-by-history) + "*Functions in this list are used for guessing refile destination folder.") + +(defun wl-refile-guess (entity) + (let ((flist wl-refile-guess-func-list) guess) + (while flist + (if (setq guess (funcall (car flist) entity)) + (setq flist nil) + (setq flist (cdr flist)))) + guess)) + +(defun wl-refile-guess-by-rule (entity) + (let ((rules wl-refile-rule-alist) + (rule-set) (field) (field-cont)) + (catch 'found + (while rules + (setq rule-set (cdr (car rules)) + field (car (car rules))) + (cond ((string-match field "From") + (setq field-cont + (elmo-msgdb-overview-entity-get-from entity))) + ((string-match field "Subject") + (setq field-cont + (elmo-msgdb-overview-entity-get-subject entity))) + ((string-match field "To") + (setq field-cont + (elmo-msgdb-overview-entity-get-to entity))) + ((string-match field "Cc") + (setq field-cont + (elmo-msgdb-overview-entity-get-cc entity))) + (t + (setq field-cont + (elmo-msgdb-overview-entity-get-extra-field + entity (downcase field))))) + (if field-cont + (while rule-set + (if (string-match (car (car rule-set)) field-cont) + (throw 'found (cdr (car rule-set))) + (setq rule-set (cdr rule-set))))) + (setq rules (cdr rules)))))) + +(defun wl-refile-guess-by-history (entity) + (let ((tocc-list + (mapcar (function + (lambda (entity) + (downcase (wl-address-header-extract-address entity)))) + (wl-parse-addresses + (concat + (elmo-msgdb-overview-entity-get-to entity) "," + (elmo-msgdb-overview-entity-get-cc entity))))) + ret-val) + (setq tocc-list (elmo-list-delete + (or wl-user-mail-address-list + (list (wl-address-header-extract-address wl-from))) + tocc-list)) + (while tocc-list + (if (setq ret-val (cdr (assoc (car tocc-list) wl-refile-alist))) + (setq tocc-list nil) + (setq tocc-list (cdr tocc-list)))) + (or ret-val + (wl-refile-guess-by-from entity)))) + +(defun wl-refile-get-account-part-from-address (address) + (if (string-match "\\([^@]+\\)@[^@]+" address) + (wl-match-string 1 address) + address)) + +(defun wl-refile-guess-by-from (entity) + (let ((from + (downcase (wl-address-header-extract-address + (elmo-msgdb-overview-entity-get-from entity))))) + ;; search from alist + (or (cdr (assoc from wl-refile-alist)) + (format "%s/%s" wl-refile-default-from-folder + (wl-refile-get-account-part-from-address from))))) + +(defun wl-refile-guess-by-msgid (entity) + (cdr (assoc (elmo-msgdb-overview-entity-get-references entity) + wl-refile-msgid-alist))) + +;;; wl-refile.el ends here diff --git a/wl/wl-score.el b/wl/wl-score.el new file mode 100644 index 0000000..69aca75 --- /dev/null +++ b/wl/wl-score.el @@ -0,0 +1,1499 @@ +;;; wl-score.el -- Scoring in Wanderlust. + +;; Copyright 1998,1999,2000 Masahiro MURATA +;; Yuuichi Teranishi + +;; Author: Masahiro MURATA +;; Keywords: mail, net news +;; Time-stamp: <00/03/14 19:35:28 teranisi> + +;; This file is part of Wanderlust (Yet Another Message Interface on Emacsen). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; Original codes are gnus-score.el and score-mode.el + +;;; Code: +;; + + +(require 'wl-vars) +(require 'wl-util) +(eval-when-compile + (provide 'elmo-msgdb)) + +(defvar wl-score-edit-header-char + '((?a "from" nil string) + (?s "subject" nil string) + (?i "message-id" nil string) + (?r "references" "message-id" string) + (?x "xref" nil string) + (?e "extra" nil string) + (?l "lines" nil number) + (?d "date" nil date) + (?f "followup" nil string) + (?t "thread" "message-id" string))) + +(defvar wl-score-edit-type-char + '((?s s "substring" string) + (?e e "exact string" string) + (?f f "fuzzy string" string) + (?r r "regexp string" string) + (?b before "before date" date) + (?a after "after date" date) + (?n at "this date" date) + (?< < "less than number" number) + (?> > "greater than number" number) + (?= = "equal to number" number))) + +(defvar wl-score-edit-perm-char + '((?t temp "temporary") + (?p perm "permanent") + (?i now "immediate"))) + +;;; Global Variable + +(defconst wl-score-header-index + ;; Name to function alist. + '(("number" wl-score-integer elmo-msgdb-overview-entity-get-number) ;;0 + ("subject" wl-score-string 3 charset) + ("from" wl-score-string 2 charset) + ("date" wl-score-date elmo-msgdb-overview-entity-get-date) ;;4 + ("message-id" wl-score-string elmo-msgdb-overview-entity-get-id) + ("references" wl-score-string 1) + ("to" wl-score-string 5) + ("cc" wl-score-string 6) + ("chars" wl-score-integer elmo-msgdb-overview-entity-get-size) ;;7 + ("lines" wl-score-integer wl-score-overview-entity-get-lines) + ("xref" wl-score-string wl-score-overview-entity-get-xref) + ("extra" wl-score-extra wl-score-overview-entity-get-extra mime) + ("followup" wl-score-followup 2 charset) + ("thread" wl-score-thread 1))) + +(defvar wl-score-auto-make-followup-entry nil) +(defvar wl-score-debug nil) +(defvar wl-score-trace nil) + +(defvar wl-score-alist nil) +(defvar wl-score-index nil) +(defvar wl-score-cache nil) +(defvar wl-scores-messages nil) +(defvar wl-current-score-file nil) +(defvar wl-score-make-followup nil) +(defvar wl-score-stop-add-entry nil) + +(defvar wl-prev-winconf nil) +(defvar wl-score-help-winconf nil) +(defvar wl-score-header-buffer-list nil) +(defvar wl-score-alike-hashtb nil) + +(defvar wl-score-edit-exit-func nil + "Function run on exit from the score buffer.") + +(mapcar + (function make-variable-buffer-local) + (list 'wl-current-score-file + 'wl-score-alist)) + +;; Utility functions + +(defun wl-score-simplify-buffer-fuzzy () + "Simplify string in the buffer fuzzily. +The string in the accessible portion of the current buffer is simplified. +It is assumed to be a single-line subject. +Whitespace is generally cleaned up, and miscellaneous leading/trailing +matter is removed. Additional things can be deleted by setting +wl-score-simplify-fuzzy-regexp." + (let ((case-fold-search t) + (modified-tick)) + (elmo-buffer-replace "\t" " ") + (while (not (eq modified-tick (buffer-modified-tick))) + (setq modified-tick (buffer-modified-tick)) + (cond + ((listp wl-score-simplify-fuzzy-regexp) + (mapcar 'elmo-buffer-replace + wl-score-simplify-fuzzy-regexp)) + (wl-score-simplify-fuzzy-regexp + (elmo-buffer-replace + wl-score-simplify-fuzzy-regexp))) + (elmo-buffer-replace "^ *\\[[-+?*!][-+?*!]\\] *") + (elmo-buffer-replace + "^ *\\(re\\|fw\\|fwd\\|forward\\)[[{(^0-9]*[])}]?[:;] *") + (elmo-buffer-replace "^[[].*:\\( .*\\)[]]$" "\\1")) + (elmo-buffer-replace " *[[{(][^()\n]*[]})] *$") + (elmo-buffer-replace " +" " ") + (elmo-buffer-replace " $") + (elmo-buffer-replace "^ +"))) + +(defun wl-score-simplify-string-fuzzy (string) + "Simplify a string fuzzily. +See `wl-score-simplify-buffer-fuzzy' for details." + (elmo-set-work-buf + (let ((case-fold-search t)) + (insert string) + (wl-score-simplify-buffer-fuzzy) + (buffer-string)))) + +(defun wl-score-simplify-subject (subject) + (elmo-set-work-buf + (let ((case-fold-search t)) + (insert subject) + (cond + ((listp wl-score-simplify-fuzzy-regexp) + (mapcar 'elmo-buffer-replace + wl-score-simplify-fuzzy-regexp)) + (wl-score-simplify-fuzzy-regexp + (elmo-buffer-replace + wl-score-simplify-fuzzy-regexp))) + (elmo-buffer-replace + "^[ \t]*\\(re\\|was\\|fw\\|fwd\\|forward\\)[:;][ \t]*") + (buffer-string)))) + +;; + +(defun wl-score-overview-entity-get-lines (entity) + (let ((lines + (elmo-msgdb-overview-entity-get-extra-field entity "lines"))) + (and lines + (string-to-int lines)))) + +(defun wl-score-overview-entity-get-xref (entity) + (or (elmo-msgdb-overview-entity-get-extra-field entity "xref") + "")) + +(defun wl-score-overview-entity-get-extra (entity header &optional decode) + (let ((extra (elmo-msgdb-overview-entity-get-extra-field entity header))) + (if (and extra decode) + (eword-decode-string + (decode-mime-charset-string extra elmo-mime-charset)) + (or extra "")))) + +(defun wl-string> (s1 s2) + (not (or (string< s1 s2) + (string= s1 s2)))) + +(defmacro wl-score-ov-entity-get-by-index (entity index) + (` (aref (cdr (, entity)) (, index)))) + +(defsubst wl-score-ov-entity-get (entity index &optional extra decode) + (let ((str (cond ((integerp index) + (wl-score-ov-entity-get-by-index entity index)) + (extra + (funcall index entity extra decode)) + (t + (funcall index entity))))) + (if (and decode (not extra)) + (decode-mime-charset-string str elmo-mime-charset) + str))) + +(defun wl-score-string-index< (a1 a2) + (string-lessp (wl-score-ov-entity-get-by-index (car a1) wl-score-index) + (wl-score-ov-entity-get-by-index (car a2) wl-score-index))) + +(defun wl-score-string-func< (a1 a2) + (string-lessp (funcall wl-score-index (car a1)) + (funcall wl-score-index (car a2)))) + +(defun wl-score-string-sort (messages index) + (let ((func (cond ((integerp index) + 'wl-score-string-index<) + (t + 'wl-score-string-func<)))) + (sort messages func))) + +(defsubst wl-score-get (symbol &optional alist) + ;; Get SYMBOL's definition in ALIST. + (cdr (assoc symbol + (or alist + wl-score-alist)))) + +(defun wl-score-set (symbol value &optional alist warn) + ;; Set SYMBOL to VALUE in ALIST. + (let* ((alist (or alist wl-score-alist)) + (entry (assoc symbol alist))) + (cond ((wl-score-get 'read-only alist) + ;; This is a read-only score file, so we do nothing. + (when warn + (message "Note: read-only score file; entry discarded"))) + (entry + (setcdr entry value)) + ((null alist) + (error "Empty alist")) + (t + (setcdr alist + (cons (cons symbol value) (cdr alist))))))) + +(defun wl-score-cache-clean () + (interactive) + (setq wl-score-cache nil)) + +(defun wl-score-load-score-alist (file) + "Read score FILE." + (let (alist) + (if (not (file-readable-p file)) + (setq wl-score-alist nil) + (with-temp-buffer + (wl-as-mime-charset wl-score-mode-mime-charset + (insert-file-contents file)) + (goto-char (point-min)) + ;; Only do the loading if the score file isn't empty. + (when (save-excursion (re-search-forward "[()0-9a-zA-Z]" nil t)) + (setq alist + (condition-case () + (read (current-buffer)) + (error "Problem with score file %s" file)))) + (cond + ((and alist + (atom alist)) + (error "Invalid syntax with score file %s" file)) + (t + (setq wl-score-alist alist))))))) + +(defun wl-score-save () + ;; Save all score information. + (let ((cache wl-score-cache) + entry score file dir) + (with-temp-buffer + (setq wl-score-alist nil) + (while cache + (setq entry (pop cache) + file (car entry) + score (cdr entry)) + (unless (or (not (equal (wl-score-get 'touched score) '(t))) + (wl-score-get 'read-only score) + (and (file-exists-p file) + (not (file-writable-p file)))) + (setq score (setcdr entry (wl-delete-alist 'touched score))) + (erase-buffer) + (let (emacs-lisp-mode-hook + (lisp-mode-syntax-table wl-score-mode-syntax-table)) + (pp score (current-buffer))) + (setq dir (file-name-directory file)) + (if (file-directory-p dir) + (); ok. + (if (file-exists-p dir) + (error "File %s already exists" dir) + (elmo-make-directory dir))) + ;; If the score file is empty, we delete it. + (if (zerop (buffer-size)) + (when (file-exists-p file) ; added by teranisi. + (delete-file file)) + ;; There are scores, so we write the file. + (when (file-writable-p file) + (wl-as-mime-charset wl-score-mode-mime-charset + (write-region (point-min) (point-max) + file nil 'no-msg))))))))) + +(defun wl-score-remove-from-cache (file) + (setq wl-score-cache + (delq (assoc file wl-score-cache) wl-score-cache))) + +(defun wl-score-load-file (file) + (let* ((file (expand-file-name + (or (and (string-match + (concat "^" (regexp-quote + (expand-file-name + wl-score-files-dir))) + (expand-file-name file)) + file) + (expand-file-name + file + (file-name-as-directory wl-score-files-dir))))) + (cached (assoc file wl-score-cache)) + alist) + (if cached + ;; The score file was already loaded. + (setq alist (cdr cached)) + ;; We load the score file. + (setq wl-score-alist nil) + (setq alist (wl-score-load-score-alist file)) + (unless (assq 'touched alist) + (wl-push (list 'touched nil) alist)) + (wl-push (cons file alist) wl-score-cache)) + (let ((a alist)) + (while a + ;; Downcase all header names. + (cond + ((stringp (caar a)) + (setcar (car a) (downcase (caar a))))) + (pop a))) + (setq wl-current-score-file file) + (setq wl-score-alist alist))) + +(defun wl-score-guess-like-gnus (folder) + (let* (score-list + (spec (elmo-folder-get-spec folder)) + (method (symbol-name (car spec))) + (fld-name (car (cdr spec)))) + (when (stringp fld-name) + (while (string-match "[\\/:,;*?\"<>|]" fld-name) + (setq fld-name (replace-match "." t nil fld-name))) + (setq score-list (list (concat method "@" fld-name ".SCORE"))) + (while (string-match "[\\/.][^\\/.]*$" fld-name) + (setq fld-name (substring fld-name 0 (match-beginning 0))) + (wl-append score-list (list (concat method "@" fld-name + ".all.SCORE")))) + score-list))) + +(defun wl-score-get-score-files (score-alist folder) + (let ((files (wl-get-assoc-list-value + score-alist folder + (if (not wl-score-folder-alist-matchone) 'all-list))) + fl f) + (while (setq f (wl-pop files)) + (wl-append + fl + (cond ((functionp f) + (funcall f folder)) + ((and (symbolp f) (eq f 'guess)) + (wl-score-guess-like-gnus folder)) + (t + (list f))))) + fl)) + +(defun wl-score-get-score-alist (&optional folder) + (interactive) + (let* ((fld (or folder wl-summary-buffer-folder-name)) + (score-alist (reverse + (wl-score-get-score-files wl-score-folder-alist fld))) + alist scores) + (setq wl-current-score-file nil) + (unless (and wl-score-default-file + (member wl-score-default-file score-alist)) + (wl-push wl-score-default-file score-alist)) + (while score-alist + (setq alist + (cond ((stringp (car score-alist)) ;; file + (wl-score-load-file (car score-alist))) + ((consp (car score-alist)) ;; alist + (car score-alist)) + ((boundp (car score-alist)) ;; variable + (symbol-value (car score-alist))) + (t + (error "Void variable: %s" (car score-alist))))) + (let ((mark (car (wl-score-get 'mark alist))) + (expunge (car (wl-score-get 'expunge alist))) + (mark-and-expunge (car (wl-score-get 'mark-and-expunge alist))) + (temp (car (wl-score-get 'temp alist))) + (important (car (wl-score-get 'important alist)))) + (setq wl-summary-important-above + (or important wl-summary-important-above)) + (setq wl-summary-temp-above + (or temp wl-summary-temp-above)) + (setq wl-summary-mark-below + (or mark mark-and-expunge wl-summary-mark-below)) + (setq wl-summary-expunge-below + (or expunge mark-and-expunge wl-summary-expunge-below))) + (wl-append scores (list alist)) + (setq score-alist (cdr score-alist))) + scores)) + +(defun wl-score-headers (scores &optional msgdb force-msgs not-add) + (let* ((elmo-mime-charset wl-summary-buffer-mime-charset) + (now (wl-day-number (current-time-string))) + (expire (and wl-score-expiry-days + (- now wl-score-expiry-days))) + (overview (elmo-msgdb-get-overview + (or msgdb wl-summary-buffer-msgdb))) + (mark-alist (elmo-msgdb-get-mark-alist + (or msgdb wl-summary-buffer-msgdb))) + (wl-score-stop-add-entry not-add) + entries + news new num entry ov header) + (setq wl-scores-messages nil) + (message "Scoring...") + + ;; Create messages, an alist of the form `(OVERVIEW . SCORE)'. + (while (setq ov (pop overview)) + (when (and (not (assq + (setq num + (elmo-msgdb-overview-entity-get-number ov)) + wl-summary-scored)) + (or (memq num force-msgs) + (member (cadr (assq num mark-alist)) + wl-summary-score-marks))) + (setq wl-scores-messages + (cons (cons ov (or wl-summary-default-score 0)) + wl-scores-messages)))) + + (save-excursion + (setq news scores) + (while news + (setq scores news + news nil) + ;; Run each header through the score process. + (setq entries wl-score-header-index) + (while entries + (setq entry (pop entries) + header (car entry)) + (if (> (length wl-scores-messages) 500) + (message "Scoring...\"%s\"" header)) + (when (< 0 (apply 'max (mapcar + (lambda (score) + (length (wl-score-get header score))) + scores))) + ;; Call the scoring function for this type of "header". + (when (setq new (funcall (nth 1 entry) scores header now expire)) + (wl-push new news)))))) + + ;; Add messages to `wl-summary-scored'. + (let (entry num score) + (while wl-scores-messages + (when (or (/= wl-summary-default-score + (cdar wl-scores-messages))) + (setq num (elmo-msgdb-overview-entity-get-number + (caar wl-scores-messages)) + score (cdar wl-scores-messages)) + (if (setq entry (assq num wl-summary-scored)) + (setcdr entry (+ score (cdr entry))) + (wl-push (cons num score) + wl-summary-scored))) + (setq wl-scores-messages (cdr wl-scores-messages)))) + (message "Scoring...done") + ;; Remove buffers. + (mapcar '(lambda (x) (elmo-kill-buffer x)) + wl-score-header-buffer-list) + (setq wl-score-header-buffer-list nil))) + +(defun wl-score-integer (scores header now expire) + (let ((wl-score-index (nth 2 (assoc header wl-score-header-index))) + entries alist) + + ;; Find matches. + (while scores + (setq alist (car scores) + scores (cdr scores) + entries (assoc header alist)) + (while (cdr entries) ;First entry is the header index. + (let* ((rest (cdr entries)) + (kill (car rest)) + (match (nth 0 kill)) + (type (or (nth 3 kill) '>)) + (score (or (nth 1 kill) wl-score-interactive-default-score)) + (date (nth 2 kill)) + (found nil) + (match-func (if (memq type '(> < <= >= =)) + type + (error "Invalid match type: %s" type))) + (messages wl-scores-messages)) + (while messages + (when (funcall match-func + (or (wl-score-ov-entity-get + (caar messages) wl-score-index) + 0) + match) + (setq found t) + (setcdr (car messages) (+ score (cdar messages)))) + (setq messages (cdr messages))) + ;; Update expire date + (cond ((null date)) ;Permanent entry. + ((and found wl-score-update-entry-dates) ;Match, update date. + (wl-score-set 'touched '(t) alist) + (setcar (nthcdr 2 kill) now)) + ((and expire (< date expire)) ;Old entry, remove. + (wl-score-set 'touched '(t) alist) + (setcdr entries (cdr rest)) + (setq rest entries))) + (setq entries rest))))) + nil) + +(defun wl-score-date (scores header now expire) + (let ((wl-score-index (nth 2 (assoc header wl-score-header-index))) + entries alist match match-func message) + ;; Find matches. + (while scores + (setq alist (car scores) + scores (cdr scores) + entries (assoc header alist)) + (while (cdr entries) ;First entry is the header index. + (let* ((rest (cdr entries)) + (kill (car rest)) + (type (or (nth 3 kill) 'before)) + (score (or (nth 1 kill) wl-score-interactive-default-score)) + (date (nth 2 kill)) + (found nil) + (messages wl-scores-messages) + l) + (cond + ((eq type 'after) + (setq match-func 'string< + match (wl-date-iso8601 (nth 0 kill)))) + ((eq type 'before) + (setq match-func 'wl-string> + match (wl-date-iso8601 (nth 0 kill)))) + ((eq type 'at) + (setq match-func 'string= + match (wl-date-iso8601 (nth 0 kill)))) + ((eq type 'regexp) + (setq match-func 'string-match + match (nth 0 kill))) + (t (error "Invalid match type: %s" type))) + (while (setq message (pop messages)) + (when (and + (setq l (wl-score-ov-entity-get + (car message) wl-score-index)) + (funcall match-func match (wl-date-iso8601 l))) + (setq found t) + (setcdr message (+ score (cdr message))))) + ;; Update expire date + (cond ((null date)) ;Permanent entry. + ((and found wl-score-update-entry-dates) ;Match, update date. + (wl-score-set 'touched '(t) alist) + (setcar (nthcdr 2 kill) now)) + ((and expire (< date expire)) ;Old entry, remove. + (wl-score-set 'touched '(t) alist) + (setcdr entries (cdr rest)) + (setq rest entries))) + (setq entries rest))))) + nil) + +(defsubst wl-score-lines () + (save-excursion + (beginning-of-line) + (count-lines 1 (point)))) + +(defun wl-score-extra (scores header now expire) + (let ((score-list scores) + entries alist extra extras) + (while score-list + (setq alist (pop score-list) + entries (assoc header alist)) + (while (cdr entries) + (setq extra (nth 4 (cadr entries))) + (unless (member extra extras) + (wl-push extra extras)) + (setq entries (cdr entries)))) + (while extras + (wl-score-string scores header now expire (car extras)) + (setq extras (cdr extras))) + nil)) + +(defmacro wl-score-put-alike () + (` (elmo-set-hash-val (format "#%d" (wl-score-lines)) + alike + wl-score-alike-hashtb))) +;;(push (cons (wl-score-lines) alike) wl-score-alike-alist) +;;(put-text-property (1- (point)) (point) 'messages alike) + +(defmacro wl-score-get-alike () + (` (elmo-get-hash-val (format "#%d" (wl-score-lines)) + wl-score-alike-hashtb))) +;;(cdr (assq (wl-score-lines) wl-score-alike-alist)) +;;(get-text-property (point) 'messages))) + +(defun wl-score-insert-header (header messages &optional extra-header) + (let ((mime-decode (nth 3 (assoc header wl-score-header-index))) + (buffer-name (concat "*Score-Headers-" header + (if extra-header + (concat "-" extra-header) + "") + "*")) + buf) + (if (setq buf (get-buffer buffer-name)) + (set-buffer buf) + (set-buffer (setq buf (get-buffer-create buffer-name))) + (wl-append wl-score-header-buffer-list (list buf)) + (buffer-disable-undo (current-buffer)) + (make-local-variable 'wl-score-alike-hashtb) + (setq wl-score-alike-hashtb (elmo-make-hash (* (length messages) 2))) + (when mime-decode + (elmo-set-buffer-multibyte default-enable-multibyte-characters)) + (let (art last this alike) + (while (setq art (pop messages)) + (setq this (wl-score-ov-entity-get (car art) + wl-score-index + extra-header)) + (and this (setq this (std11-unfold-string this))) + (if (equal last this) + ;; O(N*H) cons-cells used here, where H is the number of + ;; headers. + (wl-push art alike) + (when last + (wl-score-put-alike) + (insert last ?\n)) + (setq alike (list art) + last this))) + (when last + (wl-score-put-alike) + (insert last ?\n)) + (when mime-decode + (decode-mime-charset-region (point-min) (point-max) + elmo-mime-charset) + (when (eq mime-decode 'mime) + (eword-decode-region (point-min) (point-max)))))))) + +(defun wl-score-string (scores header now expire &optional extra-header) + ;; Insert the unique message headers in the buffer. + (let ((wl-score-index (nth 2 (assoc header wl-score-header-index))) + entries alist messages + fuzzies kill) + (when (integerp wl-score-index) + (setq wl-scores-messages + (wl-score-string-sort wl-scores-messages wl-score-index))) + (setq messages wl-scores-messages) + + (wl-score-insert-header header messages extra-header) + + ;; Go through all the score alists and pick out the entries + ;; for this header. + (while scores + (setq alist (pop scores) + entries (assoc header alist)) + (while (cdr entries) ;First entry is the header index. + (let* ((kill (cadr entries)) + (type (or (nth 3 kill) 's)) + (score (or (nth 1 kill) wl-score-interactive-default-score)) + (date (nth 2 kill)) + (extra (nth 4 kill)) ; non-standard header; string. + (mt (aref (symbol-name type) 0)) + (case-fold-search (not (memq mt '(?R ?S ?E ?F)))) + (dmt (downcase mt)) + (match (nth 0 kill)) + (search-func + (cond ((= dmt ?r) 're-search-forward) + ((memq dmt '(?e ?s ?f)) 'search-forward) + ((= dmt ?w) nil) + (t (error "Invalid match type: %s" type)))) + arts art found) + (if (and extra-header + (or (not extra) + (not (string= extra-header extra)))) + (setq entries (cdr entries)) + (cond + ;; Fuzzy matches. We save these for later. + ((= dmt ?f) + (wl-push (cons entries alist) fuzzies) + (setq entries (cdr entries))) + (t + ;; Regexp, substring and exact matching. + (goto-char (point-min)) + (when (and (not (= dmt ?e)) + (string= match "")) + (setq match "\n")) + (while (and (not (eobp)) + (funcall search-func match nil t)) + (when (or (not (= dmt ?e)) + ;; Is it really exact? + (and (eolp) + (= (save-excursion (forward-line 0) (point)) + (match-beginning 0)))) + ;;(end-of-line) + (setq found (setq arts (wl-score-get-alike))) + ;; Found a match, update scores. + (while (setq art (pop arts)) + (setcdr art (+ score (cdr art))))) + (forward-line 1)) + ;; Update expiry date + (cond + ;; Permanent entry. + ((null date) + (setq entries (cdr entries))) + ;; We have a match, so we update the date. + ((and found wl-score-update-entry-dates) + (wl-score-set 'touched '(t) alist) + (setcar (nthcdr 2 kill) now) + (setq entries (cdr entries))) + ;; This entry has expired, so we remove it. + ((and expire (< date expire)) + (wl-score-set 'touched '(t) alist) + (setcdr entries (cddr entries))) + ;; No match; go to next entry. + (t + (setq entries (cdr entries)))))))))) + + ;; Find fuzzy matches. + (when fuzzies + ;; Simplify the entire buffer for easy matching. + (wl-score-simplify-buffer-fuzzy) + (while (setq kill (cadaar fuzzies)) + (let* ((match (nth 0 kill)) + (type (nth 3 kill)) + (score (or (nth 1 kill) wl-score-interactive-default-score)) + (date (nth 2 kill)) + (mt (aref (symbol-name type) 0)) + (case-fold-search (not (= mt ?F))) + arts art found) + (goto-char (point-min)) + (while (and (not (eobp)) + (search-forward match nil t)) + (when (and (eolp) + (= (save-excursion (forward-line 0) (point)) + (match-beginning 0))) + (setq found (setq arts (wl-score-get-alike))) + (while (setq art (pop arts)) + (setcdr art (+ score (cdr art))))) + (forward-line 1)) + ;; Update expiry date + (cond + ;; Permanent. + ((null date)) + ;; Match, update date. + ((and found wl-score-update-entry-dates) + (wl-score-set 'touched '(t) (cdar fuzzies)) + (setcar (nthcdr 2 kill) now)) + ;; Old entry, remove. + ((and expire (< date expire)) + (wl-score-set 'touched '(t) (cdar fuzzies)) + (setcdr (caar fuzzies) (cddaar fuzzies)))) + (setq fuzzies (cdr fuzzies))))) + nil)) + +(defun wl-score-thread (scores header now expire) + (wl-score-followup scores header now expire t)) + +(defun wl-score-followup (scores header now expire &optional thread) + ;; Insert the unique message headers in the buffer. + (let ((wl-score-index (nth 2 (assoc header wl-score-header-index))) + (all-scores scores) + entries alist messages + new news) + (when (integerp wl-score-index) + (setq wl-scores-messages + (wl-score-string-sort wl-scores-messages wl-score-index))) + (setq messages wl-scores-messages) + + (wl-score-insert-header (if thread "references" "from") messages) + + ;; Find matches. + (while scores + (setq alist (car scores) + scores (cdr scores) + entries (assoc header alist)) + (while (cdr entries) ;First entry is the header index. + (let* ((rest (cdr entries)) + (kill (car rest)) + (match (nth 0 kill)) + (type (or (nth 3 kill) 's)) + (score (or (nth 1 kill) wl-score-interactive-default-score)) + (date (nth 2 kill)) + (found nil) + (mt (aref (symbol-name type) 0)) + (case-fold-search (not (memq mt '(?R ?S ?E ?F)))) + (dmt (downcase mt)) + (search-func + (cond ((= dmt ?r) 're-search-forward) + ((memq dmt '(?e ?s ?f)) 'search-forward) + (t (error "Invalid match type: %s" type)))) + arts art day) + (goto-char (point-min)) + (while (funcall search-func match nil t) + (when (or (not (= dmt ?e)) + (and (eolp) + (= (progn (beginning-of-line) (point)) + (match-beginning 0)))) + ;;(end-of-line) + (setq found (setq arts (wl-score-get-alike))) + ;; Found a match, update scores. + (while (setq art (pop arts)) + (setq day nil) + (when (or (not wl-score-make-followup) + (and wl-score-update-entry-dates + expire + (< expire + (setq day + (wl-day-number + (elmo-msgdb-overview-entity-get-date + (car art))))))) + (when (setq new (wl-score-add-followups + (car art) score all-scores alist thread + day)) + (when thread + (unless wl-score-stop-add-entry + (wl-append rest (list new))) + (setcdr art (+ score (cdr art)))) + (wl-push new news)))) + (forward-line 1))) + ;; Update expire date + (cond ((null date)) ;Permanent entry. + ((and found wl-score-update-entry-dates) ;Match, update date. + (wl-score-set 'touched '(t) alist) + (setcar (nthcdr 2 kill) now)) + ((and expire (< date expire)) ;Old entry, remove. + (wl-score-set 'touched '(t) alist) + (setcdr entries (cdr rest)) + (setq rest entries))) + (setq entries rest)))) + (when (and news (not thread)) + (list (cons "references" news))))) + +(defun wl-score-add-followups (header score scores alist &optional thread day) + (let* ((id (car header)) + (scores (car scores)) + entry dont) + (when id + ;; Don't enter a score if there already is one. + (while (setq entry (pop scores)) + (and (member (car entry) '("thread" "references")) + (memq (nth 3 (cadr entry)) '(s nil)) + (assoc id entry) + (setq dont t))) + (unless dont + (let ((entry (list id score + (or day (wl-day-number (current-time-string))) 's))) + (unless (or thread wl-score-stop-add-entry) + (wl-score-update-score-entry "references" entry alist)) + (wl-score-set 'touched '(t) alist) + entry))))) + +(defun wl-score-flush-cache () + "Flush the cache of score files." + (interactive) + (wl-score-save) + (setq wl-score-cache nil + wl-score-alist nil) + (message "The score cache is now flushed")) + +(defun wl-score-set-mark-below (score) + "Automatically mark messages with score below SCORE as read." + (interactive + (list (or (and current-prefix-arg (prefix-numeric-value current-prefix-arg)) + (string-to-int (read-string "Mark below: "))))) + (setq score (or score wl-summary-default-score 0)) + (wl-score-set 'mark (list score)) + (wl-score-set 'touched '(t)) + (setq wl-summary-mark-below score) + (wl-summary-score-update-all-lines t)) + +(defun wl-score-set-expunge-below (score) + "Automatically expunge messages with score below SCORE." + (interactive + (list (or (and current-prefix-arg (prefix-numeric-value current-prefix-arg)) + (string-to-int (read-string "Expunge below: "))))) + (setq score (or score wl-summary-default-score 0)) + (wl-score-set 'expunge (list score)) + (wl-score-set 'touched '(t))) + +(defun wl-score-change-score-file (file) + "Change current score alist." + (interactive + (list (read-file-name "Change to score file: " wl-score-files-dir))) + (wl-score-load-file file)) + +(defun wl-score-default (level) + (if level (prefix-numeric-value level) + wl-score-interactive-default-score)) + +(defun wl-summary-lower-score (&optional score) + (interactive "P") + (wl-summary-increase-score score t)) + +(defun wl-summary-increase-score (&optional score lower) + (interactive "P") + (if (wl-summary-message-number) + (let* ((rscore (if lower + (- (wl-score-default score)) + (wl-score-default score))) + (increase (> rscore 0)) + lscore entry list match type) + (setq entry (wl-score-get-header-entry nil rscore)) + (setq list (nth 1 entry)) + (setq match (car list)) + (setq type (nth 3 list)) + (cond ((memq type '(r R s S nil)) + (when (and match (string= (car entry) "subject")) + (setq match (wl-score-simplify-subject match)))) + ((memq type '(f F)) + (setq match (wl-score-simplify-string-fuzzy match)))) + (setq match (read-string + (format "Match on %s, %s: " + (car entry) + (if increase "raise" "lower")) + (if (numberp match) + (int-to-string match) + match))) + ;; transform from string to int. + (when (eq (nth 1 (assoc (car entry) wl-score-header-index)) + 'wl-score-integer) + (setq match (string-to-int match))) + ;; set score + (if score + (setq lscore rscore) + (setq lscore (nth 1 list)) + (setq lscore + (abs (if lscore + lscore + wl-score-interactive-default-score))) + (setq lscore (if lower (- lscore) lscore))) + (setcar (cdr list) + (if (eq lscore wl-score-interactive-default-score) + nil + lscore)) + ;; update score file + (setcar list match) + (unless (eq (nth 2 list) 'now) + (let ((alist (if wl-current-score-file + (cdr (assoc wl-current-score-file wl-score-cache)) + wl-score-alist))) + (wl-score-update-score-entry (car entry) list alist) + (wl-score-set 'touched '(t) alist))) + (wl-summary-score-effect (car entry) list (eq (nth 2 list) 'now))))) + +(defun wl-score-get-latest-msgs () + (let* ((now (wl-day-number (current-time-string))) + (expire (and wl-score-expiry-days + (- now wl-score-expiry-days))) + (roverview (reverse (elmo-msgdb-get-overview + wl-summary-buffer-msgdb))) + msgs) + (if (not expire) + (mapcar 'car (elmo-msgdb-get-number-alist + wl-summary-buffer-msgdb)) ;; all messages + (catch 'break + (while roverview + (if (< (wl-day-number + (elmo-msgdb-overview-entity-get-date (car roverview))) + expire) + (throw 'break t)) + (wl-push (elmo-msgdb-overview-entity-get-number (car roverview)) + msgs) + (setq roverview (cdr roverview)))) + msgs))) + +(defsubst wl-score-get-overview () + (let ((num (wl-summary-message-number))) + (if num + (assoc (cdr (assq num (elmo-msgdb-get-number-alist + wl-summary-buffer-msgdb))) + (elmo-msgdb-get-overview wl-summary-buffer-msgdb))))) + +(defun wl-score-get-header (header &optional extra) + (let ((index (nth 2 (assoc header wl-score-header-index))) + (decode (nth 3 (assoc header wl-score-header-index)))) + (if index + (wl-score-ov-entity-get (wl-score-get-overview) index extra decode)))) + +(defun wl-score-kill-help-buffer () + (when (get-buffer "*Score Help*") + (kill-buffer "*Score Help*") + (when wl-score-help-winconf + (set-window-configuration wl-score-help-winconf)))) + +(defun wl-score-insert-help (string alist idx) + (setq wl-score-help-winconf (current-window-configuration)) + (let ((cur-win (selected-window)) + mes-win) + (save-excursion + (set-buffer (get-buffer-create "*Score Help*")) + (buffer-disable-undo (current-buffer)) + (delete-windows-on (current-buffer)) + (erase-buffer) + (insert string ":\n\n") + (let ((max -1) + (list alist) + (i 0) + n width pad format) + ;; find the longest string to display + (while list + (setq n (length (nth idx (car list)))) + (unless (> max n) + (setq max n)) + (setq list (cdr list))) + (setq max (+ max 4)) ; %c, `:', SPACE, a SPACE at end + (setq n (/ (1- (window-width)) max)) ; items per line + (setq width (/ (1- (window-width)) n)) ; width of each item + ;; insert `n' items, each in a field of width `width' + (while alist + (unless (< i n) + (setq i 0) + (delete-char -1) ; the `\n' takes a char + (insert "\n")) + (setq pad (- width 3)) + (setq format (concat "%c: %-" (int-to-string pad) "s")) + (insert (format format (caar alist) (nth idx (car alist)))) + (setq alist (cdr alist)) + (setq i (1+ i)) + (set-buffer-modified-p nil))) + (when (and (get-buffer wl-message-buf-name) + (setq mes-win (get-buffer-window + (get-buffer wl-message-buf-name)))) + (select-window mes-win) + (unless (eq (next-window) cur-win) + (delete-window (next-window)))) + (split-window) + (pop-to-buffer "*Score Help*") + (let ((window-min-height 1)) + (shrink-window-if-larger-than-buffer)) + (select-window cur-win)))) + +(defun wl-score-get-header-entry (&optional match-func increase) + (let (hchar tchar pchar + header score perm type extra hentry entry) + (unwind-protect + (progn + ;; read the header to score. + (while (not hchar) + (message "%s header (%s?): " + (if increase + (if (> increase 0) "Increase" "Lower") + "Set") + (mapconcat (lambda (s) (char-to-string (car s))) + wl-score-edit-header-char "")) + (setq hchar (read-char)) + (when (or (= hchar ??) (= hchar ?\C-h)) + (setq hchar nil) + (wl-score-insert-help "Match on header" + wl-score-edit-header-char 1))) + (wl-score-kill-help-buffer) + (unless (setq hentry (assq (downcase hchar) + wl-score-edit-header-char)) + (error "Invalid header type")) + + (message "") + (setq entry (assoc (setq header (nth 1 hentry)) + wl-score-header-default-entry)) + (setq score (nth 1 entry) + perm (nth 2 entry) + type (nth 3 entry)) + + ;; read extra header. + (when (equal header "extra") + (setq extra + (completing-read + "Set extra header: " + (mapcar 'list + elmo-msgdb-extra-fields)))) + + ;; read the type. + (unless type + (let ((valid-types + (delq nil + (mapcar (lambda (s) + (if (eq (nth 3 hentry) + (nth 3 s)) + s nil)) + (copy-sequence + wl-score-edit-type-char))))) + (while (not tchar) + (message "Set header '%s' with match type (%s?): " + header + (mapconcat (lambda (s) (char-to-string (car s))) + valid-types "")) + (setq tchar (read-char)) + (when (or (= tchar ??) (= tchar ?\C-h)) + (setq tchar nil) + (wl-score-insert-help "Match type" valid-types 2))) + (wl-score-kill-help-buffer) + (unless (setq type (nth 1 (assq (downcase tchar) valid-types))) + (error "Invalid match type")) + (message ""))) + + ;; read the permanence. + (unless perm + (while (not pchar) + (message "Set permanence (%s?): " + (mapconcat (lambda (s) (char-to-string (car s))) + wl-score-edit-perm-char "")) + (setq pchar (read-char)) + (when (or (= pchar ??) (= pchar ?\C-h)) + (setq pchar nil) + (wl-score-insert-help "Match permanence" + wl-score-edit-perm-char 2))) + (wl-score-kill-help-buffer) + (unless (setq perm (nth 1 (assq (downcase pchar) + wl-score-edit-perm-char))) + (error "Invalid match duration")) + (message "")) + + ;; read the score. + (unless (or score increase) + (setq score (string-to-int (read-string "Set score: ")))) + (message ""))) + + (let* ((match-header (or (nth 2 hentry) header)) + (match (if match-func + (funcall match-func match-header extra) + (wl-score-get-header match-header extra))) + (match (cond ((memq type '(r R regexp Regexp)) + (regexp-quote match)) + ((eq (nth 1 (assoc (car entry) wl-score-header-index)) + 'wl-score-integer) + match) + (t + (or match "")))) + (perm (cond ((eq perm 'perm) + nil) + ((eq perm 'temp) + (wl-day-number (current-time-string))) + ((eq perm 'now) + perm))) + (new (list match score perm type extra))) + (list header new)))) + +(defun wl-score-update-score-entries (header entries &optional alist) + (while entries + (wl-score-update-score-entry header (car entries) alist) + (setq entries (cdr entries))) + (wl-score-set 'touched '(t) alist)) + +(defun wl-score-update-score-entry (header new &optional alist) + (let ((old (wl-score-get header alist)) + (match (nth 0 new)) + elem) + (if (and old + (setq elem (assoc match old)) + (eq (nth 3 elem) (nth 3 new)) + (or (and (numberp (nth 2 elem)) (numberp (nth 2 new))) + (and (not (nth 2 elem)) (not (nth 2 new))))) + (setcar (cdr elem) (+ (or (nth 1 elem) + wl-score-interactive-default-score) + (or (nth 1 new) + wl-score-interactive-default-score))) + (wl-score-set header (if old (cons new old) (list new)) alist t)))) + +;; functions for summary mode + +(defun wl-summary-score-effect (header entry &optional now) + (let ((scores (list (list (list header entry))))) + (setq wl-summary-scored nil) + (cond ((string= header "followup") + (if wl-score-auto-make-followup-entry + (let ((wl-score-make-followup t)) + (wl-score-headers scores nil (wl-score-get-latest-msgs))) + (wl-score-headers scores nil + (if (eq wl-summary-buffer-view 'thread) + (wl-thread-get-children-msgs + (wl-summary-message-number)) + (list (wl-summary-message-number))))) + (unless now + (wl-score-update-score-entries + "references" + (cdr (assoc "references" (car scores)))))) + ((string= header "thread") + (wl-score-headers scores nil + (if (eq wl-summary-buffer-view 'thread) + (wl-thread-get-children-msgs + (wl-summary-message-number)) + (list (wl-summary-message-number)))) + (unless now + (wl-score-update-score-entries header + ;; remove parent + (cdr (cdaar scores))))) + (t + (wl-score-headers scores nil + (list (wl-summary-message-number))))) + (wl-summary-score-update-all-lines t))) + +(defun wl-summary-rescore-msgs (number-alist) + (mapcar + 'car + (nthcdr + (max (- (length number-alist) + wl-summary-rescore-partial-threshold) + 0) + number-alist))) + +(defun wl-summary-rescore (&optional arg) + "Redo the entire scoring process in the current summary." + (interactive "P") + (let (number-alist expunged) + (wl-score-save) + (setq wl-score-cache nil) + (setq wl-summary-scored nil) + (setq number-alist (elmo-msgdb-get-number-alist wl-summary-buffer-msgdb)) + (wl-summary-score-headers nil wl-summary-buffer-msgdb + (unless arg + (wl-summary-rescore-msgs number-alist))) + (setq expunged (wl-summary-score-update-all-lines t)) + (if expunged + (message "%d message(s) are expunged by scoring." (length expunged))) + (set-buffer-modified-p nil))) + +;; optional argument force-msgs is added by teranisi. +(defun wl-summary-score-headers (&optional folder msgdb force-msgs not-add) + "Do scoring if scoring is required." + (let ((scores (wl-score-get-score-alist + (or folder wl-summary-buffer-folder-name)))) + (when scores + (wl-score-headers scores msgdb force-msgs not-add)))) + +(defun wl-summary-score-update-all-lines (&optional update) + (let* ((alist wl-summary-scored) + (count (length alist)) + (folder wl-summary-buffer-folder-name) + (i 0) + (update-unread nil) + num score dels visible score-mark mark-alist) + (save-excursion + (message "Updating score...") + (while alist + (setq num (caar alist) + score (cdar alist)) + (when wl-score-debug + (message "Scored %d with %d" score num) + (wl-push (list (elmo-string wl-summary-buffer-folder-name) num score) + wl-score-trace)) + (setq score-mark (wl-summary-get-score-mark num)) + (and (setq visible (wl-summary-jump-to-msg num)) + (wl-summary-set-score-mark score-mark)) + (cond ((and wl-summary-expunge-below + (< score wl-summary-expunge-below)) + (wl-push num dels)) + ((< score wl-summary-mark-below) + (if visible + (wl-summary-mark-as-read + t nil nil nil (elmo-use-cache-p folder num));; opened + (setq update-unread t) + (wl-thread-msg-mark-as-read num)));; closed + ((and wl-summary-important-above + (> score wl-summary-important-above)) + (if (wl-thread-jump-to-msg num);; force open + (wl-summary-mark-as-important num " "))) + ((and wl-summary-temp-above + (> score wl-summary-temp-above)) + (if visible + (wl-summary-mark-line "*")) + (setq wl-summary-buffer-target-mark-list + (cons num wl-summary-buffer-target-mark-list)))) + (setq i (1+ i)) + (and (zerop (% i 10)) + (message "Updating score...%d%%" (/ (* i 100) count))) + (setq alist (cdr alist))) + (when dels +; (elmo-msgdb-delete-msgs wl-summary-buffer-folder-name +; dels wl-summary-buffer-msgdb t) + ;; mark as read. + (setq mark-alist (elmo-msgdb-get-mark-alist wl-summary-buffer-msgdb)) + (mapcar (function (lambda (x) + (setq mark-alist + (elmo-msgdb-mark-set mark-alist x nil)))) + dels) + (elmo-mark-as-read wl-summary-buffer-folder-name + dels wl-summary-buffer-msgdb) + (elmo-msgdb-set-mark-alist wl-summary-buffer-msgdb mark-alist) + (wl-summary-delete-messages-on-buffer dels)) + (when (and update update-unread) + (let ((num-db (elmo-msgdb-get-number-alist + wl-summary-buffer-msgdb)) + (mark-alist (elmo-msgdb-get-mark-alist + wl-summary-buffer-msgdb))) + ;; Update Folder mode + (wl-folder-set-folder-updated wl-summary-buffer-folder-name + (list 0 + (wl-summary-count-unread + mark-alist) + (length num-db))) + (wl-summary-update-modeline))) + (message "Updating score...done.") + dels))) + +(defun wl-score-edit-done () + (let ((bufnam (buffer-file-name (current-buffer))) + (winconf wl-prev-winconf)) + (when winconf + (set-window-configuration winconf)) + (wl-score-remove-from-cache bufnam) + (wl-score-load-file bufnam))) + +(defun wl-score-edit-current-scores (file) + "Edit the current score alist." + (interactive (list wl-current-score-file)) + (if file + (wl-score-edit-file file) + (call-interactively 'wl-score-edit-file))) + +(defun wl-score-edit-file (file) + "Edit a score file." + (interactive + (list (read-file-name "Edit score file: " wl-score-files-dir))) + (when (wl-collect-summary) + (wl-score-save)) + (let ((winconf (current-window-configuration)) + (edit-buffer (wl-as-mime-charset wl-score-mode-mime-charset + (find-file-noselect file))) + (sum-buf (current-buffer))) + (if (string-match (concat "^" wl-summary-buffer-name) (buffer-name)) + (let ((cur-buf (current-buffer)) + (view-message-buffer (get-buffer wl-message-buf-name))) + (when view-message-buffer + (wl-select-buffer view-message-buffer) + (delete-window) + (select-window (get-buffer-window cur-buf))) + (wl-select-buffer edit-buffer)) + (switch-to-buffer edit-buffer)) + (wl-score-mode) + (setq wl-score-edit-exit-func 'wl-score-edit-done) + (setq wl-score-edit-summary-buffer sum-buf) + (make-local-variable 'wl-prev-winconf) + (setq wl-prev-winconf winconf)) + (message + (substitute-command-keys + "\\\\[wl-score-edit-exit] to save edits"))) + +;; score-mode + +(defvar wl-score-edit-summary-buffer nil) + +(defvar wl-score-mode-syntax-table + (let ((table (copy-syntax-table lisp-mode-syntax-table))) + (modify-syntax-entry ?| "w" table) + table) + "Syntax table used in score-mode buffers.") + +(defvar wl-score-mode-map nil) +(defvar wl-score-mode-menu-spec + '("Score" + ["Exit" wl-score-edit-exit t] + ["Insert date" wl-score-edit-insert-date t] + ["Format" wl-score-pretty-print t])) + +(unless wl-score-mode-map + (setq wl-score-mode-map (copy-keymap emacs-lisp-mode-map)) + (define-key wl-score-mode-map "\C-c\C-k" 'wl-score-edit-kill) + (define-key wl-score-mode-map "\C-c\C-c" 'wl-score-edit-exit) + (define-key wl-score-mode-map "\C-c\C-p" 'wl-score-pretty-print) + (define-key wl-score-mode-map "\C-c\C-d" 'wl-score-edit-insert-date) + (define-key wl-score-mode-map "\C-c\C-s" 'wl-score-edit-insert-header) + (define-key wl-score-mode-map "\C-c\C-e" 'wl-score-edit-insert-header-entry) + + (unless (boundp 'wl-score-menu) + (easy-menu-define + wl-score-menu wl-score-mode-map "Menu used in score mode." + wl-score-mode-menu-spec))) + +(defun wl-score-mode () + "Mode for editing Wanderlust score files. +This mode is an extended emacs-lisp mode. + +Special commands; +\\{wl-score-mode-map} +Entering Score mode calls the value of `wl-score-mode-hook'." + (interactive) + (kill-all-local-variables) + (use-local-map wl-score-mode-map) + (set-syntax-table wl-score-mode-syntax-table) + (setq major-mode 'wl-score-mode) + (setq mode-name "Score") + (lisp-mode-variables nil) + (make-local-variable 'wl-score-edit-exit-func) + (make-local-variable 'wl-score-edit-summary-buffer) + (run-hooks 'emacs-lisp-mode-hook 'wl-score-mode-hook)) + +(defun wl-score-edit-insert-date () + "Insert date in numerical format." + (interactive) + (princ (wl-day-number (current-time-string)) (current-buffer))) + +(defun wl-score-pretty-print () + "Format the current score file." + (interactive) + (goto-char (point-min)) + (let ((form (read (current-buffer)))) + (erase-buffer) + (let ((emacs-lisp-mode-syntax-table wl-score-mode-syntax-table)) + (pp form (current-buffer)))) + (goto-char (point-min))) + +(defun wl-score-edit-exit () + "Stop editing the score file." + (interactive) + (unless (file-exists-p (file-name-directory (buffer-file-name))) + (elmo-make-directory (file-name-directory (buffer-file-name)))) + (if (zerop (buffer-size)) + (progn + (set-buffer-modified-p nil) + (and (file-exists-p (buffer-file-name)) + (delete-file (buffer-file-name)))) + (wl-as-mime-charset wl-score-mode-mime-charset + (save-buffer))) + (let ((buf (current-buffer))) + (when wl-score-edit-exit-func + (funcall wl-score-edit-exit-func)) + (kill-buffer buf))) + +(defun wl-score-edit-kill () + "Cancel editing the score file." + (interactive) + (let ((buf (current-buffer))) + (set-buffer-modified-p nil) + (when wl-score-edit-exit-func + (funcall wl-score-edit-exit-func)) + (kill-buffer buf))) + +(defun wl-score-edit-get-summary-buf () + (let ((summary-buf (and wl-score-edit-summary-buffer + (get-buffer wl-score-edit-summary-buffer)))) + (if (and summary-buf + (buffer-live-p summary-buf)) + summary-buf + (if (and (setq summary-buf (window-buffer (previous-window))) + (string-match (concat "^" wl-summary-buffer-name) + (buffer-name summary-buf))) + summary-buf)))) + +(defun wl-score-edit-get-header (header &optional extra) + (let ((sum-buf (wl-score-edit-get-summary-buf)) + (index (nth 2 (assoc header wl-score-header-index)))) + (when (and sum-buf index) + (save-excursion + (set-buffer sum-buf) + (wl-score-get-header header extra))))) + +(defun wl-score-edit-insert-number () + (interactive) + (let ((sum-buf (wl-score-edit-get-summary-buf)) + num) + (when sum-buf + (if (setq num (save-excursion + (set-buffer sum-buf) + (wl-summary-message-number))) + (prin1 num (current-buffer)))))) + +(defun wl-score-edit-insert-header () + (interactive) + (let (hchar entry) + (unwind-protect + (progn + (while (not hchar) + (message "Insert header (%s?): " + (mapconcat (lambda (s) (char-to-string (car s))) + wl-score-edit-header-char "")) + (setq hchar (read-char)) + (when (or (= hchar ??) (= hchar ?\C-h)) + (setq hchar nil) + (wl-score-insert-help "Match on header" + wl-score-edit-header-char 1))) + (wl-score-kill-help-buffer) + (unless (setq entry (assq (downcase hchar) + wl-score-edit-header-char)) + (error "Invalid match type"))) + (message "") + (let* ((header (nth 1 entry)) + (value (wl-score-edit-get-header header))) + (and value (prin1 value (current-buffer))))))) + +(defun wl-score-edit-insert-header-entry () + (interactive) + (let (form entry) + (goto-char (point-min)) + (setq form (and (not (zerop (buffer-size))) + (condition-case () + (read (current-buffer)) + (error "Invalid syntax")))) + (setq entry (wl-score-get-header-entry 'wl-score-edit-get-header)) + (unless (eq (nth 2 (nth 1 entry)) 'now) + (if form + (wl-score-update-score-entry (car entry) (nth 1 entry) form) + (setq form (list entry))) + (erase-buffer) + (let ((emacs-lisp-mode-syntax-table wl-score-mode-syntax-table)) + (pp form (current-buffer))) + (goto-char (point-min))))) + +(provide 'wl-score) + +;;; wl-score.el ends here diff --git a/wl/wl-summary.el b/wl/wl-summary.el new file mode 100644 index 0000000..b62d9c5 --- /dev/null +++ b/wl/wl-summary.el @@ -0,0 +1,5872 @@ +;;; wl-summary.el -- Summary mode for Wanderlust. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <00/03/22 01:00:41 teranisi> + +;; This file is part of Wanderlust (Yet Another Message Interface on Emacsen). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; + +(require 'elmo2) +(require 'elmo-multi) +(require 'wl-message) +(require 'wl-vars) +(require 'wl-highlight) +(require 'wl-refile) +(require 'wl-util) +(condition-case () + (progn + (require 'timezone) + (require 'easymenu)) + (error)) +(require 'elmo-date) + +(condition-case nil + (require 'ps-print) + (error)) + +(eval-when-compile + (require 'cl) + (condition-case () (require 'timer) (error nil)) + (mapcar + (function + (lambda (symbol) + (unless (boundp symbol) + (set (make-local-variable symbol) nil)))) + '(dragdrop-drop-functions scrollbar-height mail-reply-buffer)) + (defun-maybe ps-print-buffer-with-faces (a)) + (defun-maybe elmo-database-msgid-put (a b c)) + (defun-maybe elmo-database-close ()) + (defun-maybe elmo-database-msgid-get (a)) + (defun-maybe run-with-idle-timer (secs repeat function &rest args))) + +(defvar wl-summary-buffer-name "Summary") +(defvar wl-summary-mode-map nil) +(defvar wl-current-summary-buffer nil) + +(defvar wl-summary-buffer-msgdb nil) +(defvar wl-summary-buffer-folder-name nil) +(defvar wl-summary-buffer-disp-msg nil) +(defvar wl-summary-buffer-disp-folder nil) +(defvar wl-summary-buffer-refile-list nil) +(defvar wl-summary-buffer-delete-list nil) +(defvar wl-summary-buffer-last-displayed-msg nil) +(defvar wl-summary-buffer-current-msg nil) +(defvar wl-summary-buffer-unread-status " (0 new/0 unread)") +(defvar wl-summary-buffer-unread-count 0) +(defvar wl-summary-buffer-new-count 0) +(defvar wl-summary-buffer-mime-charset nil) +(defvar wl-summary-buffer-weekday-name-lang nil) +(defvar wl-summary-buffer-thread-indent-set-alist nil) +(defvar wl-summary-buffer-message-redisplay-func nil) +(defvar wl-summary-buffer-view 'thread) +(defvar wl-summary-buffer-message-modified nil) +(defvar wl-summary-buffer-mark-modified nil) +(defvar wl-summary-buffer-number-column nil) +(defvar wl-summary-buffer-number-regexp nil) +(defvar wl-summary-buffer-persistent nil) +(defvar wl-summary-buffer-thread-nodes nil) +(defvar wl-summary-buffer-target-mark-list nil) +(defvar wl-summary-buffer-copy-list nil) +(defvar wl-summary-buffer-prev-refile-destination nil) +(defvar wl-summary-buffer-prev-copy-destination nil) +(defvar wl-thread-indent-level-internal nil) +(defvar wl-thread-have-younger-brother-str-internal nil) +(defvar wl-thread-youngest-child-str-internal nil) +(defvar wl-thread-vertical-str-internal nil) +(defvar wl-thread-horizontal-str-internal nil) +(defvar wl-thread-space-str-internal nil) +(defvar wl-summary-last-visited-folder nil) +(defvar wl-read-folder-hist nil) +(defvar wl-summary-scored nil) +(defvar wl-crosspost-alist-modified nil) + +(defvar wl-summary-message-regexp "^ *\\([0-9]+\\)") + +(defvar wl-summary-shell-command-last "") + +(defvar wl-ps-preprint-hook nil) +(defvar wl-ps-print-hook nil) + +(mapcar + (function make-variable-buffer-local) + (list 'wl-summary-buffer-msgdb + 'wl-summary-buffer-disp-msg + 'wl-summary-buffer-disp-folder + 'wl-summary-buffer-refile-list + 'wl-summary-buffer-copy-list + 'wl-summary-buffer-target-mark-list + 'wl-summary-buffer-delete-list + 'wl-summary-buffer-folder-name + 'wl-summary-buffer-last-displayed-msg + 'wl-summary-buffer-unread-status + 'wl-summary-buffer-unread-count + 'wl-summary-buffer-new-count + 'wl-summary-buffer-mime-charset + 'wl-summary-buffer-weekday-name-lang + 'wl-summary-buffer-thread-indent-set + 'wl-summary-buffer-message-redisplay-func + 'wl-summary-buffer-view + 'wl-summary-buffer-message-modified + 'wl-summary-buffer-mark-modified + 'wl-summary-buffer-number-column + 'wl-summary-buffer-number-regexp + 'wl-summary-buffer-persistent + 'wl-summary-buffer-thread-nodes + 'wl-summary-buffer-prev-refile-destination + 'wl-summary-scored + 'wl-summary-default-score + 'wl-summary-move-direction-downward + 'wl-summary-important-above + 'wl-summary-temp-above + 'wl-summary-mark-below + 'wl-summary-expunge-below + 'wl-thread-indent-level-internal + 'wl-thread-have-younger-brother-str-internal + 'wl-thread-youngest-child-str-internal + 'wl-thread-vertical-str-internal + 'wl-thread-horizontal-str-internal + 'wl-thread-space-str-internal)) + +;; internal functions (dummy) +(unless (fboundp 'wl-summary-append-message-func-internal) + (defun wl-summary-append-message-func-internal (entity overview + mark-alist update))) +(unless (fboundp 'wl-summary-from-func-internal) + (defun wl-summary-from-func-internal (from) + from)) +(unless (fboundp 'wl-summary-subject-func-internal) + (defun wl-summary-subject-func-internal (subject) + subject)) +(unless (fboundp 'wl-summary-subject-filter-func-internal) + (defun wl-summary-subject-filter-func-internal (subject) + subject)) + +(defmacro wl-summary-sticky-buffer-name (folder) + (` (concat wl-summary-buffer-name ":" (, folder)))) + +(defun wl-summary-default-subject (subject-string) + (if (string-match "^[ \t]*\\[[^:]+[,: ][0-9]+\\][ \t]*" subject-string) + (substring subject-string (match-end 0)) + subject-string)) + +(eval-when-compile (defvar-maybe entity nil)) ; silence byte compiler. +(defun wl-summary-default-from (from) + (let (retval tos ng) + (unless + (and (eq major-mode 'wl-summary-mode) + (stringp wl-summary-showto-folder-regexp) + (string-match wl-summary-showto-folder-regexp + wl-summary-buffer-folder-name) + (wl-address-user-mail-address-p from) + (cond + ((and (setq tos (elmo-msgdb-overview-entity-get-to entity)) + (not (string= "" tos))) + (setq retval + (concat "To:" + (mapconcat + (function + (lambda (to) + (eword-decode-string + (if wl-use-petname + (wl-address-get-petname to) + (car + (std11-extract-address-components to)))))) + (wl-parse-addresses tos) + ",")))) + ((setq ng (elmo-msgdb-overview-entity-get-extra-field + entity "newsgroups")) + (setq retval (concat "Ng:" ng))))) + (if wl-use-petname + (setq retval (wl-address-get-petname from)) + (setq retval from))) + retval)) + +(defun wl-summary-simple-from (string) + (if wl-use-petname + (wl-address-get-petname string) + string)) + +(defvar wl-summary-mode-menu-spec + '("Summary" + ["Read" wl-summary-read t] + ["Prev page" wl-summary-prev-page t] + ["Next page" wl-summary-next-page t] + ["Top" wl-summary-display-top t] + ["Bottom" wl-summary-display-bottom t] + ["Prev" wl-summary-prev t] + ["Next" wl-summary-next t] + ["Up" wl-summary-up t] + ["Down" wl-summary-down t] + ["Parent message" wl-summary-jump-to-parent-message t] + "----" + ["Sync" wl-summary-sync t] + ["Execute" wl-summary-exec t] + ["Go to other folder" wl-summary-goto-folder t] + ["Pick" wl-summary-pick t] + ["Mark as read all" wl-summary-mark-as-read-all t] + ["Unmark all" wl-summary-unmark-all t] + ["Toggle display message" wl-summary-toggle-disp-msg t] + ["Display folder" wl-summary-toggle-disp-folder t] + ["Toggle threading" wl-summary-toggle-thread t] + ["Stick" wl-summary-stick t] + ("Sort" + ["By Number" wl-summary-sort-by-number t] + ["By Date" wl-summary-sort-by-date t] + ["By From" wl-summary-sort-by-from t] + ["By Subject" wl-summary-sort-by-subject t]) + "----" + ("Message Operation" + ["Mark as read" wl-summary-mark-as-read t] + ["Mark as important" wl-summary-mark-as-important t] + ["Mark as unread" wl-summary-mark-as-unread t] + ["Set delete mark" wl-summary-delete t] + ["Set refile mark" wl-summary-refile t] + ["Set copy mark" wl-summary-copy t] + ["Prefetch" wl-summary-prefetch t] + ["Set target mark" wl-summary-target-mark t] + ["Unmark" wl-summary-unmark t] + ["Save" wl-summary-save t] + ["Cancel posted news" wl-summary-cancel-message t] + ["Supersedes message" wl-summary-supersedes-message t] + ["Resend bounced mail" wl-summary-resend-bounced-mail t] + ["Resend message" wl-summary-resend-message t] + ["Enter the message" wl-summary-jump-to-current-message t] + ["Pipe message" wl-summary-pipe-message t] + ["Print message" wl-summary-print-message t]) + ("Thread Operation" + ["Open or Close" wl-thread-open-close (eq wl-summary-buffer-view 'thread)] + ["Open all" wl-thread-open-all (eq wl-summary-buffer-view 'thread)] + ["Close all" wl-thread-close-all (eq wl-summary-buffer-view 'thread)] + ["Mark as read" wl-thread-mark-as-read (eq wl-summary-buffer-view 'thread)] + ["Mark as important" wl-thread-mark-as-important (eq wl-summary-buffer-view 'thread)] + ["Mark as unread" wl-thread-mark-as-unread (eq wl-summary-buffer-view 'thread)] + ["Set delete mark" wl-thread-delete (eq wl-summary-buffer-view 'thread)] + ["Set refile mark" wl-thread-refile (eq wl-summary-buffer-view 'thread)] + ["Set copy mark" wl-thread-copy (eq wl-summary-buffer-view 'thread)] + ["Prefetch" wl-thread-prefetch (eq wl-summary-buffer-view 'thread)] + ["Set target mark" wl-thread-target-mark (eq wl-summary-buffer-view 'thread)] + ["Unmark" wl-thread-unmark (eq wl-summary-buffer-view 'thread)] + ["Save" wl-thread-save (eq wl-summary-buffer-view 'thread)] + ["Execute" wl-thread-exec (eq wl-summary-buffer-view 'thread)]) + ("Region Operation" + ["Mark as read" wl-summary-mark-as-read-region t] + ["Mark as important" wl-summary-mark-as-important-region t] + ["Mark as unread" wl-summary-mark-as-unread-region t] + ["Set delete mark" wl-summary-delete-region t] + ["Set refile mark" wl-summary-refile-region t] + ["Set copy mark" wl-summary-copy-region t] + ["Prefetch" wl-summary-prefetch-region t] + ["Set target mark" wl-summary-target-mark-region t] + ["Unmark" wl-summary-unmark-region t] + ["Save" wl-summary-save-region t] + ["Execute" wl-summary-exec-region t]) + ("Mark Operation" + ["Mark as read" wl-summary-target-mark-mark-as-read t] + ["Mark as important" wl-summary-target-mark-mark-as-important t] + ["Mark as unread" wl-summary-target-mark-mark-as-unread t] + ["Set delete mark" wl-summary-target-mark-delete t] + ["Set refile mark" wl-summary-target-mark-refile t] + ["Set copy mark" wl-summary-target-mark-copy t] + ["Prefetch" wl-summary-target-mark-prefetch t] + ["Save" wl-summary-target-mark-save t] + ["Reply with citation" wl-summary-target-mark-reply-with-citation t] + ["Forward" wl-summary-target-mark-forward t] + ["uudecode" wl-summary-target-mark-uudecode t]) + ("Score Operation" + ["Switch current score file" wl-score-change-score-file t] + ["Edit current score file" wl-score-edit-current-scores t] + ["Edit score file" wl-score-edit-file t] + ["Set mark below" wl-score-set-mark-below t] + ["Set expunge below" wl-score-set-expunge-below t] + ["Rescore buffer" wl-summary-rescore t] + ["Increase score" wl-summary-increase-score t] + ["Lower score" wl-summary-lower-score t]) + "----" + ("Writing Messages" + ["Write a message" wl-summary-write t] + ["Reply" wl-summary-reply t] + ["Reply with citation" wl-summary-reply-with-citation t] + ["Forward" wl-summary-forward t]) + "----" + ["Toggle Plug Status" wl-toggle-plugged t] + ["Change Plug Status" wl-plugged-change t] + "----" + ["Exit Current Folder" wl-summary-exit t])) + +(if wl-on-xemacs + (defun wl-summary-setup-mouse () + (define-key wl-summary-mode-map 'button4 'wl-summary-prev) + (define-key wl-summary-mode-map 'button5 'wl-summary-next) + (define-key wl-summary-mode-map [(shift button4)] + 'wl-summary-up) + (define-key wl-summary-mode-map [(shift button5)] + 'wl-summary-down) + (define-key wl-summary-mode-map 'button2 'wl-summary-click)) + (if wl-on-nemacs + (defun wl-summary-setup-mouse ()) + (defun wl-summary-setup-mouse () + (define-key wl-summary-mode-map [mouse-4] 'wl-summary-prev) + (define-key wl-summary-mode-map [mouse-5] 'wl-summary-next) + (define-key wl-summary-mode-map [S-mouse-4] 'wl-summary-up) + (define-key wl-summary-mode-map [S-mouse-5] 'wl-summary-down) + (define-key wl-summary-mode-map [mouse-2] 'wl-summary-click)))) + +(if wl-summary-mode-map + () + (setq wl-summary-mode-map (make-sparse-keymap)) + (define-key wl-summary-mode-map " " 'wl-summary-read) + (define-key wl-summary-mode-map "." 'wl-summary-redisplay) + (define-key wl-summary-mode-map "<" 'wl-summary-display-top) + (define-key wl-summary-mode-map ">" 'wl-summary-display-bottom) + (define-key wl-summary-mode-map "\177" 'wl-summary-prev-page) + (unless wl-on-nemacs + (define-key wl-summary-mode-map [backspace] 'wl-summary-prev-page)) + (define-key wl-summary-mode-map "\r" 'wl-summary-next-line-content) + (define-key wl-summary-mode-map "\C-m" 'wl-summary-next-line-content) + (define-key wl-summary-mode-map "/" 'wl-thread-open-close) + (define-key wl-summary-mode-map "[" 'wl-thread-open-all) + (define-key wl-summary-mode-map "]" 'wl-thread-close-all) + (define-key wl-summary-mode-map "-" 'wl-summary-prev-line-content) + (define-key wl-summary-mode-map "\e\r" 'wl-summary-prev-line-content) + (define-key wl-summary-mode-map "g" 'wl-summary-goto-folder) + (define-key wl-summary-mode-map "c" 'wl-summary-mark-as-read-all) + (define-key wl-summary-mode-map "D" 'wl-summary-drop-unsync) + + (define-key wl-summary-mode-map "a" 'wl-summary-reply) + (define-key wl-summary-mode-map "A" 'wl-summary-reply-with-citation) + (define-key wl-summary-mode-map "C" 'wl-summary-cancel-message) + (define-key wl-summary-mode-map "E" 'wl-summary-reedit) + (define-key wl-summary-mode-map "\eE" 'wl-summary-resend-bounced-mail) + (define-key wl-summary-mode-map "f" 'wl-summary-forward) + (define-key wl-summary-mode-map "$" 'wl-summary-mark-as-important) + (define-key wl-summary-mode-map "@" 'wl-summary-edit-addresses) + + (define-key wl-summary-mode-map "y" 'wl-summary-save) + (define-key wl-summary-mode-map "n" 'wl-summary-next) + (define-key wl-summary-mode-map "p" 'wl-summary-prev) + (define-key wl-summary-mode-map "N" 'wl-summary-down) + (define-key wl-summary-mode-map "P" 'wl-summary-up) +; (define-key wl-summary-mode-map "w" 'wl-draft) + (define-key wl-summary-mode-map "w" 'wl-summary-write) + (define-key wl-summary-mode-map "W" 'wl-summary-write-current-newsgroup) +; (define-key wl-summary-mode-map "e" 'wl-draft-open-file) + (define-key wl-summary-mode-map "e" 'wl-summary-save) + (define-key wl-summary-mode-map "\C-c\C-o" 'wl-jump-to-draft-buffer) + (define-key wl-summary-mode-map "H" 'wl-summary-redisplay-all-header) + (define-key wl-summary-mode-map "M" 'wl-summary-redisplay-no-mime) + (define-key wl-summary-mode-map "B" 'wl-summary-burst) + (define-key wl-summary-mode-map "Z" 'wl-status-update) + (define-key wl-summary-mode-map "#" 'wl-summary-print-message) + (define-key wl-summary-mode-map "|" 'wl-summary-pipe-message) + (define-key wl-summary-mode-map "q" 'wl-summary-exit) + (define-key wl-summary-mode-map "Q" 'wl-summary-force-exit) + + (define-key wl-summary-mode-map "j" 'wl-summary-jump-to-current-message) + (define-key wl-summary-mode-map "J" 'wl-thread-jump-to-msg) + (define-key wl-summary-mode-map "I" 'wl-summary-incorporate) + (define-key wl-summary-mode-map "\M-j" 'wl-summary-jump-to-msg-by-message-id) + (define-key wl-summary-mode-map "^" 'wl-summary-jump-to-parent-message) + (define-key wl-summary-mode-map "!" 'wl-summary-mark-as-unread) + + (define-key wl-summary-mode-map "s" 'wl-summary-sync) + (define-key wl-summary-mode-map "S" 'wl-summary-sort) + (define-key wl-summary-mode-map "\M-s" 'wl-summary-stick) + (define-key wl-summary-mode-map "T" 'wl-summary-toggle-thread) + + (define-key wl-summary-mode-map "l" 'wl-summary-toggle-disp-folder) + (define-key wl-summary-mode-map "v" 'wl-summary-toggle-disp-msg) + (define-key wl-summary-mode-map "V" 'wl-summary-virtual) + + (define-key wl-summary-mode-map "\C-i" 'wl-summary-goto-last-displayed-msg) + (define-key wl-summary-mode-map "?" 'wl-summary-pick) + (define-key wl-summary-mode-map "\ee" 'wl-summary-expire) + + ;; line commands + (define-key wl-summary-mode-map "R" 'wl-summary-mark-as-read) + (define-key wl-summary-mode-map "i" 'wl-summary-prefetch) + (define-key wl-summary-mode-map "x" 'wl-summary-exec) + (define-key wl-summary-mode-map "*" 'wl-summary-target-mark) + (define-key wl-summary-mode-map "o" 'wl-summary-refile) + (define-key wl-summary-mode-map "O" 'wl-summary-copy) + (define-key wl-summary-mode-map "\M-o" 'wl-summary-refile-prev-destination) +; (define-key wl-summary-mode-map "\M-O" 'wl-summary-copy-prev-destination) + (define-key wl-summary-mode-map "\C-o" 'wl-summary-auto-refile) + (define-key wl-summary-mode-map "d" 'wl-summary-delete) + (define-key wl-summary-mode-map "u" 'wl-summary-unmark) + (define-key wl-summary-mode-map "U" 'wl-summary-unmark-all) + + ;; thread commands + (define-key wl-summary-mode-map "t" (make-sparse-keymap)) + (define-key wl-summary-mode-map "tR" 'wl-thread-mark-as-read) + (define-key wl-summary-mode-map "ti" 'wl-thread-prefetch) + (define-key wl-summary-mode-map "tx" 'wl-thread-exec) + (define-key wl-summary-mode-map "t*" 'wl-thread-target-mark) + (define-key wl-summary-mode-map "to" 'wl-thread-refile) + (define-key wl-summary-mode-map "tO" 'wl-thread-copy) + (define-key wl-summary-mode-map "td" 'wl-thread-delete) + (define-key wl-summary-mode-map "tu" 'wl-thread-unmark) + (define-key wl-summary-mode-map "t!" 'wl-thread-mark-as-unread) + (define-key wl-summary-mode-map "t$" 'wl-thread-mark-as-important) + (define-key wl-summary-mode-map "ty" 'wl-thread-save) + + ;; target-mark commands + (define-key wl-summary-mode-map "m" (make-sparse-keymap)) + (define-key wl-summary-mode-map "mi" 'wl-summary-target-mark-prefetch) + (define-key wl-summary-mode-map "mR" 'wl-summary-target-mark-mark-as-read) + (define-key wl-summary-mode-map "mo" 'wl-summary-target-mark-refile) + (define-key wl-summary-mode-map "mO" 'wl-summary-target-mark-copy) + (define-key wl-summary-mode-map "md" 'wl-summary-target-mark-delete) + (define-key wl-summary-mode-map "my" 'wl-summary-target-mark-save) + (define-key wl-summary-mode-map "m!" 'wl-summary-target-mark-mark-as-unread) + (define-key wl-summary-mode-map "m$" 'wl-summary-target-mark-mark-as-important) + (define-key wl-summary-mode-map "mu" 'wl-summary-delete-all-temp-marks) + (define-key wl-summary-mode-map "mU" 'wl-summary-target-mark-uudecode) + (define-key wl-summary-mode-map "ma" 'wl-summary-target-mark-all) + (define-key wl-summary-mode-map "mt" 'wl-summary-target-mark-thread) + (define-key wl-summary-mode-map "mA" 'wl-summary-target-mark-reply-with-citation) + (define-key wl-summary-mode-map "mf" 'wl-summary-target-mark-forward) + (define-key wl-summary-mode-map "m?" 'wl-summary-target-mark-pick) + + ;; region commands + (define-key wl-summary-mode-map "r" (make-sparse-keymap)) + (define-key wl-summary-mode-map "rR" 'wl-summary-mark-as-read-region) + (define-key wl-summary-mode-map "ri" 'wl-summary-prefetch-region) + (define-key wl-summary-mode-map "rx" 'wl-summary-exec-region) + (define-key wl-summary-mode-map "mr" 'wl-summary-target-mark-region) + (define-key wl-summary-mode-map "r*" 'wl-summary-target-mark-region) + (define-key wl-summary-mode-map "ro" 'wl-summary-refile-region) + (define-key wl-summary-mode-map "rO" 'wl-summary-copy-region) + (define-key wl-summary-mode-map "rd" 'wl-summary-delete-region) + (define-key wl-summary-mode-map "ru" 'wl-summary-unmark-region) + (define-key wl-summary-mode-map "r!" 'wl-summary-mark-as-unread-region) + (define-key wl-summary-mode-map "r$" 'wl-summary-mark-as-important-region) + (define-key wl-summary-mode-map "ry" 'wl-summary-save-region) + + ;; score commands + (define-key wl-summary-mode-map "K" 'wl-summary-increase-score) + (define-key wl-summary-mode-map "L" 'wl-summary-lower-score) + (define-key wl-summary-mode-map "h" (make-sparse-keymap)) + (define-key wl-summary-mode-map "hR" 'wl-summary-rescore) + (define-key wl-summary-mode-map "hc" 'wl-score-change-score-file) + (define-key wl-summary-mode-map "he" 'wl-score-edit-current-scores) + (define-key wl-summary-mode-map "hf" 'wl-score-edit-file) + (define-key wl-summary-mode-map "hF" 'wl-score-flush-cache) + (define-key wl-summary-mode-map "hm" 'wl-score-set-mark-below) + (define-key wl-summary-mode-map "hx" 'wl-score-set-expunge-below) + + (define-key wl-summary-mode-map "\M-t" 'wl-toggle-plugged) + (define-key wl-summary-mode-map "\C-t" 'wl-plugged-change) + ;; + (wl-summary-setup-mouse) + (easy-menu-define + wl-summary-mode-menu + wl-summary-mode-map + "Menu used in Summary mode." + wl-summary-mode-menu-spec)) + +(defun wl-status-update () + (interactive) + (wl-address-init)) + +(defun wl-summary-display-top () + (interactive) + (goto-char (point-min)) + (if wl-summary-buffer-disp-msg + (wl-summary-redisplay))) + +(defun wl-summary-display-bottom () + (interactive) + (goto-char (point-max)) + (forward-line -1) + (if wl-summary-buffer-disp-msg + (wl-summary-redisplay))) + +(defun wl-summary-collect-unread (mark-alist &optional folder) + (let (mark ret-val) + (while mark-alist + (setq mark (cadr (car mark-alist))) + (and mark + (or (string= mark wl-summary-new-mark) + (string= mark wl-summary-unread-uncached-mark) + (string= mark wl-summary-unread-cached-mark)) + (setq ret-val (cons (car (car mark-alist)) ret-val))) + (setq mark-alist (cdr mark-alist))) + ret-val)) + +(defun wl-summary-count-unread (mark-alist &optional folder) + (let ((new 0) + (unread 0) + mark) + (while mark-alist + (setq mark (cadr (car mark-alist))) + (and mark + (cond + ((string= mark wl-summary-new-mark) + (setq new (+ 1 new))) + ((or (string= mark wl-summary-unread-uncached-mark) + (string= mark wl-summary-unread-cached-mark)) + (setq unread (+ 1 unread))))) + (setq mark-alist (cdr mark-alist))) + (if (eq major-mode 'wl-summary-mode) + (setq wl-summary-buffer-new-count new + wl-summary-buffer-unread-count unread)) + (+ new unread))) + +(defun wl-summary-make-modeline () + "Create new modeline format for Wanderlust" + (let* ((duplicated (copy-sequence mode-line-format)) + (cur-entry duplicated) + return-modeline) + (if (memq 'wl-plug-state-indicator mode-line-format) + duplicated + (catch 'done + (while cur-entry + (if (or (and (symbolp (car cur-entry)) + (eq 'mode-line-buffer-identification + (car cur-entry))) + (and (consp (car cur-entry)) + (or + (eq 'modeline-buffer-identification + (car (car cur-entry))) + (eq 'modeline-buffer-identification + (cdr (car cur-entry)))))) + (progn + (setq return-modeline (append return-modeline + (list + 'wl-plug-state-indicator + (car cur-entry) + 'wl-summary-buffer-unread-status) + (cdr cur-entry))) + (throw 'done return-modeline)) + (setq return-modeline (append return-modeline + (list (car cur-entry))))) + (setq cur-entry (cdr cur-entry))))))) + +(defun wl-summary-reedit (&optional arg) + "Re-edit current message. +If optional argument is non-nil, Supersedes message" + (interactive "P") + (if arg + (wl-summary-supersedes-message) + (if (string= wl-summary-buffer-folder-name wl-draft-folder) + (if (wl-summary-message-number) + (unwind-protect + (wl-draft-reedit (wl-summary-message-number)) + (if (wl-message-news-p) + (mail-position-on-field "Newsgroups") + (mail-position-on-field "To")) + (delete-other-windows))) + (save-excursion + (let ((mmelmo-force-fetch-entire-message t)) + (wl-summary-set-message-buffer-or-redisplay) + (set-buffer (wl-message-get-original-buffer)) + (wl-draft-edit-string (buffer-substring (point-min) + (point-max)))))))) + +(defun wl-summary-resend-bounced-mail () + "Re-mail the current message. +This only makes sense if the current message is a bounce message which +contains some mail you have written but has been bounced back to +you." + (interactive) + (save-excursion + (let ((mmelmo-force-fetch-entire-message t)) + (wl-summary-set-message-buffer-or-redisplay) + (set-buffer (wl-message-get-original-buffer)) + (goto-char (point-min)) + (let ((case-fold-search nil)) + (cond + ((and + (re-search-forward + (concat "^\\($\\|[Cc]ontent-[Tt]ype:[ \t]+multipart/report\\)") nil t) + (not (bolp)) + (re-search-forward "boundary=\"\\([^\"]+\\)\"" nil t)) + (let ((boundary (buffer-substring (match-beginning 1) (match-end 1))) + start) + (cond + ((and (setq start (re-search-forward + (concat "^--" boundary "\n" + "[Cc]ontent-[Tt]ype:[ \t]+" + "\\(message/rfc822\\|text/rfc822-headers\\)\n" + "\\(.+\n\\)*\n") nil t)) + (re-search-forward + (concat "\n\\(--" boundary "\\)--\n") nil t)) + (wl-draft-edit-string (buffer-substring start (match-beginning 1)))) + (t + (message "Seems no message/rfc822 part."))))) + ((let ((case-fold-search t)) + (re-search-forward wl-rejected-letter-start nil t)) + (skip-chars-forward " \t\n") + (wl-draft-edit-string (buffer-substring (point) (point-max)))) + (t + (message "Does not appear to be a rejected letter."))))))) + +(defun wl-summary-resend-message (address) + "Resend the current message to ADDRESS." + (interactive "sResend message to: ") + (if (or (null address) (string-match "^[ \t]*$" address)) + (message "No address specified.") + (message "Resending message to %s..." address) + (save-excursion + (let ((mmelmo-force-fetch-entire-message t)) + (wl-summary-set-message-buffer-or-redisplay) + ;; We first set up a normal mail buffer. + (set-buffer (get-buffer-create " *wl-draft-resend*")) + (buffer-disable-undo (current-buffer)) + (erase-buffer) + (setq wl-sent-message-via nil) + ;; Insert our usual headers. + (wl-draft-insert-from-field) + (wl-draft-insert-date-field) + (insert "to: " address "\n") + (goto-char (point-min)) + ;; Rename them all to "Resent-*". + (while (re-search-forward "^[A-Za-z]" nil t) + (forward-char -1) + (insert "Resent-")) + (widen) + (forward-line) + (delete-region (point) (point-max)) + (let ((beg (point))) + ;; Insert the message to be resent. + (insert-buffer-substring (wl-message-get-original-buffer)) + (goto-char (point-min)) + (search-forward "\n\n") + (forward-char -1) + (save-restriction + (narrow-to-region beg (point)) + (wl-draft-delete-fields wl-ignored-resent-headers) + (goto-char (point-max))) + (insert mail-header-separator) + ;; Rename all old ("Previous-")Resent headers. + (while (re-search-backward "^\\(Previous-\\)*Resent-" beg t) + (beginning-of-line) + (insert "Previous-")) + ;; Quote any "From " lines at the beginning. + (goto-char beg) + (when (looking-at "From ") + (replace-match "X-From-Line: "))) + ;; Send it. + (wl-draft-dispatch-message) + (kill-buffer (current-buffer))) + (message "Resending message to %s...done" address)))) + +(defun wl-summary-msgdb-load-async (folder) + "Loading msgdb and selecting folder is executed asynchronously in IMAP4. +Returns nil if selecting folder was in failure." + (if (and (elmo-folder-plugged-p folder) + (eq (elmo-folder-get-type folder) 'imap4)) + (let* ((spec (elmo-folder-get-spec folder)) + (connection (elmo-imap4-get-connection spec)) + (process (elmo-imap4-connection-get-process connection)) + msgdb response) + (save-excursion + (unwind-protect + (progn + (elmo-imap4-send-command (process-buffer process) + process + (format "select \"%s\"" + (elmo-imap4-spec-folder + spec))) + (setq msgdb (elmo-msgdb-load (elmo-string folder))) + (setq response (elmo-imap4-read-response + (process-buffer process) + process))) + (if (null response) + (progn + (setcar (cddr connection) nil) + (error "Select folder failed")) + (setcar (cddr connection) (elmo-imap4-spec-folder spec)))) + (if response msgdb))) + (elmo-msgdb-load (elmo-string folder)))) + +(defun wl-summary-buffer-set-folder (folder) + (setq wl-summary-buffer-folder-name folder) + (when (wl-summary-sticky-p) + (make-local-variable 'wl-message-buf-name) + (setq wl-message-buf-name (format "%s:%s" wl-message-buf-name folder))) + (setq wl-summary-buffer-mime-charset (or (wl-get-assoc-list-value + wl-folder-mime-charset-alist + folder) + wl-mime-charset)) + (setq wl-summary-buffer-weekday-name-lang + (or (wl-get-assoc-list-value + wl-folder-weekday-name-lang-alist + folder) + wl-summary-weekday-name-lang)) + (setq wl-summary-buffer-thread-indent-set + (wl-get-assoc-list-value + wl-folder-thread-indent-set-alist + folder)) + (setq wl-summary-buffer-persistent (wl-folder-persistent-p folder)) + (setq + wl-thread-indent-level-internal + (or (nth 0 wl-summary-buffer-thread-indent-set) + wl-thread-indent-level) + wl-thread-have-younger-brother-str-internal + (or (nth 1 wl-summary-buffer-thread-indent-set) + wl-thread-have-younger-brother-str) + wl-thread-youngest-child-str-internal + (or (nth 2 wl-summary-buffer-thread-indent-set) + wl-thread-youngest-child-str) + wl-thread-vertical-str-internal + (or (nth 3 wl-summary-buffer-thread-indent-set) + wl-thread-vertical-str) + wl-thread-horizontal-str-internal + (or (nth 4 wl-summary-buffer-thread-indent-set) + wl-thread-horizontal-str) + wl-thread-space-str-internal + (or (nth 5 wl-summary-buffer-thread-indent-set) + wl-thread-space-str)) + (setq wl-thread-indent-regexp + (concat + (regexp-quote wl-thread-have-younger-brother-str-internal) "\\|" + (regexp-quote wl-thread-youngest-child-str-internal) "\\|" + (regexp-quote wl-thread-vertical-str-internal) "\\|" + (regexp-quote wl-thread-horizontal-str-internal) "\\|" + (regexp-quote wl-thread-space-str-internal))) + (run-hooks 'wl-summary-buffer-set-folder-hook)) + +(defun wl-summary-mode () + "Major mode for reading threaded messages. +The keys that are defined for this mode are:\\ + +SPC Read messages. +DEL Back-scroll this message. +. Force to display this message. +RET Make this message scroll up with one line. +M-RET - Make this message scroll down with one line. + +C-n Go to the next line. +C-p Go to the previous line. +n Move to below then display. +N Move to next unread. +p Move to above then display. +P Move to previous unread. +s Sync current folder. +t Same as 's' but force update. +g Go to the folder which you input. +w Write a message. A new draft is prepared. +a Answer to this message. A new draft is prepared in Draft mode. +f Forward this message to a third person. A new draft is prepared in + Draft mode and this message is automatically attached. +v Toggle \"Summary and Folder view\". + You can quickly put the delete marks since the next message is not + displayed. +i Prefetch message if uncached. +o Put the refile mark('o') on this message. +! Mark current message as unread. +$ Toggle mark current message as important. +d Put the delete mark('D') on this message. +c Check all messages as read. +* Put the temporal mark('*') on this message. +u Cancel the mark on this message. +x Process marked messages. + +mo Put the refile mark onto all messages marked with '*'. + This is very convenient to refile all messages picked by '?'. +md Put the delete mark onto all messages marked with '*'. +mi Prefetch all messages marked with '*'. +mu Unmark all target-marked messages. +mt Put the '*' mark onto all messages which belong to th current thread. +ma Put the '*' mark onto all messages. +? Pick messages according to a pick pattern which you input, + then put the '*' mark onto them. +q Goto folder mode. +" + (interactive) + (setq major-mode 'wl-summary-mode) + (setq mode-name "Summary") + (use-local-map wl-summary-mode-map) + (setq wl-summary-buffer-refile-list nil) + (setq wl-summary-buffer-target-mark-list nil) + (setq wl-summary-buffer-delete-list nil) + (setq wl-summary-scored nil) + (setq wl-summary-buffer-disp-msg nil) +;; (setq default-directory (or wl-tmp-dir (expand-file-name "~/"))) + (setq buffer-read-only t) + (setq truncate-lines t) +; (make-local-variable 'tab-width) +; (setq tab-width 1) + (buffer-disable-undo (current-buffer)) + (if wl-use-semi + (setq wl-summary-buffer-message-redisplay-func + 'wl-mmelmo-message-redisplay) + (setq wl-summary-buffer-message-redisplay-func + 'wl-normal-message-redisplay)) + (wl-xmas-setup-summary) ; setup toolbar, dnd, etc. + (when wl-show-plug-status-on-modeline + (setq mode-line-format (wl-summary-make-modeline))) + (easy-menu-add wl-summary-mode-menu) + (run-hooks 'wl-summary-mode-hook)) + +(defun wl-summary-overview-entity-compare-by-date (x y) + "Compare entity by date" + (condition-case nil + (string< + (timezone-make-date-sortable + (elmo-msgdb-overview-entity-get-date x)) + (timezone-make-date-sortable + (elmo-msgdb-overview-entity-get-date y))) + (error))) ;; ignore error. + +(defun wl-summary-overview-entity-compare-by-number (x y) + "Compare entity by number" + (< + (elmo-msgdb-overview-entity-get-number x) + (elmo-msgdb-overview-entity-get-number y))) + +(defun wl-summary-overview-entity-compare-by-from (x y) + "Compare entity by from" + (string< + (wl-address-header-extract-address + (or (elmo-msgdb-overview-entity-get-from-no-decode x) + wl-summary-no-from-message)) + (wl-address-header-extract-address + (or (elmo-msgdb-overview-entity-get-from-no-decode y) + wl-summary-no-from-message)))) + +(defun wl-summary-overview-entity-compare-by-subject (x y) + "Compare entity by subject" + (string< (elmo-msgdb-overview-entity-get-subject-no-decode x) + (elmo-msgdb-overview-entity-get-subject-no-decode y))) + +(defun wl-summary-sort-by-date () + (interactive) + (wl-summary-rescan "date")) +(defun wl-summary-sort-by-number () + (interactive) + (wl-summary-rescan "number")) +(defun wl-summary-sort-by-subject () + (interactive) + (wl-summary-rescan "subject")) +(defun wl-summary-sort-by-from () + (interactive) + (wl-summary-rescan "from")) + +(defun wl-summary-rescan (&optional sort-by) + "Rescan current folder without updating." + (interactive) + (let* ((cur-buf (current-buffer)) + (msgdb wl-summary-buffer-msgdb) + (overview (elmo-msgdb-get-overview msgdb)) + (number-alist (elmo-msgdb-get-number-alist msgdb)) + (mark-alist (elmo-msgdb-get-mark-alist msgdb)) + (elmo-mime-charset wl-summary-buffer-mime-charset) + i percent num + gc-message entity + curp + (inhibit-read-only t) + (buffer-read-only nil) + expunged) + (fset 'wl-summary-append-message-func-internal + (wl-summary-get-append-message-func)) + (erase-buffer) + (message "Re-scanning...") + (setq i 0) + (setq num (length overview)) + (when sort-by + (message "Sorting by %s..." sort-by) + (setq overview + (sort overview + (intern (format "wl-summary-overview-entity-compare-by-%s" + sort-by)))) + (message "Sorting by %s...done" sort-by) + (elmo-msgdb-set-overview wl-summary-buffer-msgdb + overview)) + (setq curp overview) + (set-buffer cur-buf) + (setq wl-thread-entity-hashtb (elmo-make-hash (* (length overview) 2))) + (setq wl-thread-entity-list nil) + (setq wl-thread-entities nil) + (setq wl-summary-buffer-target-mark-list nil) + (setq wl-summary-buffer-refile-list nil) + (setq wl-summary-buffer-delete-list nil) + (message "Constructing summary structure..." percent) + (while curp + (setq entity (car curp)) + (wl-summary-append-message-func-internal entity overview mark-alist + nil) + (setq curp (cdr curp)) + (setq i (+ i 1)) + (elmo-display-progress + 'wl-summary-rescan "Constructing summary structure..." + (/ (* i 100) num))) + (message "Constructing summary structure...done." percent) + (set-buffer cur-buf) + (when (eq wl-summary-buffer-view 'thread) + (message "Inserting thread...") + (wl-thread-insert-top) + (message "Inserting thread...done.")) + (when wl-use-scoring + (setq wl-summary-scored nil) + (wl-summary-score-headers nil msgdb + (wl-summary-rescore-msgs number-alist) + t) + (setq expunged (wl-summary-score-update-all-lines)) + (if expunged + (message "%d message(s) are expunged by scoring." (length expunged)))) + (wl-summary-set-message-modified) + (wl-summary-count-unread mark-alist) + (wl-summary-update-modeline) + (goto-char (point-max)) + (forward-line -1) + (set-buffer-modified-p nil))) + +(defun wl-summary-next-folder-or-exit (&optional next-entity upward) + (if (and next-entity + wl-auto-select-next) + (let (retval) + (wl-summary-toggle-disp-msg 'off) + (unwind-protect + (setq retval + (wl-summary-goto-folder-subr next-entity + 'force-update + nil + nil ; not sticky + t ; interactive! + )) + (wl-folder-set-current-entity-id (wl-folder-get-entity-id next-entity)) + (if (and (eq retval 'more-next) + (memq wl-auto-select-next '(unread skip-no-unread)) + (memq this-command wl-summary-next-no-unread-command)) + (if upward + (wl-summary-up + t (eq wl-auto-select-next 'skip-no-unread)) + (goto-char (point-max)) + (forward-line -1) + (wl-summary-down + t (eq wl-auto-select-next 'skip-no-unread)))))) + (wl-summary-exit))) + +(defun wl-summary-entity-info-msg (entity finfo) + (or (and entity + (concat + (elmo-replace-in-string + (if (memq 'ask-folder wl-use-folder-petname) + (wl-folder-get-petname entity) + entity) + "%" "%%") + (if (null (car finfo)) + " (? new/? unread)" + (format + " (%d new/%d unread)" + (nth 0 finfo) + (+ (nth 0 finfo) + (nth 1 finfo)))))) + "folder mode")) + +(defun wl-summary-set-message-modified () + (setq wl-summary-buffer-message-modified t)) +(defun wl-summary-message-modified-p () + wl-summary-buffer-message-modified) +(defun wl-summary-set-mark-modified () + (setq wl-summary-buffer-mark-modified t)) +(defun wl-summary-mark-modified-p () + wl-summary-buffer-mark-modified) + +(defun wl-summary-msgdb-save () + "Save msgdb if modified." + (when wl-summary-buffer-msgdb + (save-excursion + (let (path) + (when (wl-summary-message-modified-p) + (setq path (elmo-msgdb-expand-path wl-summary-buffer-folder-name)) + (elmo-msgdb-overview-save + path + (elmo-msgdb-get-overview wl-summary-buffer-msgdb)) + (elmo-msgdb-number-save + path + (elmo-msgdb-get-number-alist wl-summary-buffer-msgdb)) + (elmo-folder-set-info-max-by-numdb + (elmo-string wl-summary-buffer-folder-name) + (elmo-msgdb-get-number-alist + wl-summary-buffer-msgdb)) + (setq wl-summary-buffer-message-modified nil)) + (when (wl-summary-mark-modified-p) + (or path + (setq path (elmo-msgdb-expand-path + wl-summary-buffer-folder-name))) + (elmo-msgdb-mark-save + path + (elmo-msgdb-get-mark-alist wl-summary-buffer-msgdb)) +;; (elmo-folder-set-info-hashtb +;; (elmo-string wl-summary-buffer-folder-name) +;; nil nil +;; 0 +;; (+ wl-summary-buffer-new-count wl-summary-buffer-unread-count)) +;; (setq wl-folder-info-alist-modified t) + (setq wl-summary-buffer-mark-modified nil)))))) + +(defsubst wl-summary-cleanup-temp-marks (&optional sticky) + (if (or wl-summary-buffer-refile-list + wl-summary-buffer-copy-list + wl-summary-buffer-delete-list) + (if (y-or-n-p "Marks remain to be executed. Execute them?") + (progn + (wl-summary-exec) + (if (or wl-summary-buffer-refile-list + wl-summary-buffer-copy-list + wl-summary-buffer-delete-list) + (error "Some execution was failed"))) + ;; delete temp-marks + (message "") + (wl-summary-delete-all-refile-marks) + (wl-summary-delete-all-copy-marks) + (wl-summary-delete-all-delete-marks))) + (if wl-summary-buffer-target-mark-list + (progn + (wl-summary-delete-all-target-marks) + (setq wl-summary-buffer-target-mark-list nil))) + (wl-summary-delete-all-temp-marks-on-buffer sticky) + (setq wl-summary-scored nil)) + +;; a subroutine for wl-summary-exit/wl-save-status +(defun wl-summary-save-status (&optional sticky) + ;; already in summary buffer. + (when wl-summary-buffer-persistent + ;; save the current summary buffer view. + (if (and wl-summary-cache-use + (or (wl-summary-message-modified-p) + (wl-summary-mark-modified-p))) + (wl-summary-save-view-cache sticky)) + ;; save msgdb ... + (wl-summary-msgdb-save))) + +(defun wl-summary-force-exit () + "Exit current summary. Buffer is deleted even the buffer is sticky" + (interactive) + (wl-summary-exit 'force-exit)) + +(defun wl-summary-exit (&optional force-exit) + "Exit current summary. if FORCE-EXIT, exits even the summary is sticky." + (interactive "P") + (let ((summary-buf (current-buffer)) + (sticky (wl-summary-sticky-p)) + (message-buf (get-buffer wl-message-buf-name)) + summary-win + message-buf message-win + folder-buf folder-win) + (wl-summary-cleanup-temp-marks sticky) + (unwind-protect + ;; save summary status + (progn + (wl-summary-save-status sticky) + ;(wl-summary-msgdb-save) + (if wl-use-scoring + (wl-score-save))) + ;; for sticky summary + (wl-delete-all-overlays) + (setq wl-summary-buffer-disp-msg nil) + ;; delete message window if displayed. + (if (setq message-buf (get-buffer wl-message-buf-name)) + (if (setq message-win (get-buffer-window message-buf)) + (delete-window message-win))) + (if (setq folder-buf (get-buffer wl-folder-buffer-name)) + (if (setq folder-win (get-buffer-window folder-buf)) + ;; folder win is already displayed. + (select-window folder-win) + ;; folder win is not displayed. + (switch-to-buffer folder-buf)) + ;; currently no folder buffer + (wl-folder)) + (and wl-folder-move-cur-folder + wl-folder-buffer-cur-point + (goto-char wl-folder-buffer-cur-point)) + (setq wl-folder-buffer-cur-path nil) + (setq wl-folder-buffer-cur-entity-id nil) + (wl-delete-all-overlays) + (if wl-summary-exit-next-move + (wl-folder-next-unsync t) + (beginning-of-line)) + (if (setq summary-win (get-buffer-window summary-buf)) + (delete-window summary-win)) + (if (or force-exit + (not sticky)) + (progn + (set-buffer summary-buf) + (and (get-buffer wl-message-buf-name) + (kill-buffer wl-message-buf-name)) + ;; kill buffers of mime-view-caesar + (wl-kill-buffers + (format "^%s-([0-9 ]+)$" (regexp-quote wl-message-buf-name))) + (kill-buffer summary-buf))) + (run-hooks 'wl-summary-exit-hook)))) + +(defun wl-summary-sync-force-update (&optional unset-cursor) + (interactive) + (let ((msgdb-dir (elmo-msgdb-expand-path wl-summary-buffer-folder-name)) + ret-val seen-list) + (unwind-protect + (progn + (setq seen-list (elmo-msgdb-seen-load msgdb-dir)) + (setq ret-val (wl-summary-sync-update3 seen-list unset-cursor)) + (elmo-msgdb-seen-save msgdb-dir nil)) + (set-buffer (current-buffer))) + (if (interactive-p) + (message "%s" ret-val)) + ret-val)) + +(defun wl-summary-sync (&optional unset-cursor force-range) + (interactive) + (let* ((folder wl-summary-buffer-folder-name) + (inhibit-read-only t) + (buffer-read-only nil) + (msgdb-dir (elmo-msgdb-expand-path + folder)) + (range (or force-range (wl-summary-input-range folder))) + mes seen-list) + (cond ((string= range "all") + ;; initialize buffer local databases. + (unless (elmo-folder-plugged-p folder) ; forbidden + (error "Unplugged")) + (wl-summary-cleanup-temp-marks) + (setq seen-list + (nconc + (elmo-msgdb-mark-alist-to-seen-list + (elmo-msgdb-get-number-alist + wl-summary-buffer-msgdb) + (elmo-msgdb-get-mark-alist + wl-summary-buffer-msgdb) + (concat wl-summary-important-mark + wl-summary-read-uncached-mark)) + (elmo-msgdb-seen-load msgdb-dir))) + (setq wl-thread-entity-hashtb (elmo-make-hash + (* (length (elmo-msgdb-get-number-alist + wl-summary-buffer-msgdb)) 2))) + (setq wl-summary-buffer-msgdb '(nil nil nil nil)) + (setq wl-thread-entity-list nil) + (setq wl-thread-entities nil) + (setq wl-summary-buffer-target-mark-list nil) + (setq wl-summary-buffer-refile-list nil) + (setq wl-summary-buffer-copy-list nil) + (setq wl-summary-buffer-delete-list nil) + (wl-summary-buffer-number-column-detect nil) + (setq mes (wl-summary-sync-update3 seen-list unset-cursor)) + (elmo-msgdb-seen-save msgdb-dir nil) ; delete all seen. + (if mes (message "%s" mes))) +; (wl-summary-sync-all folder t)) + ((string= range "rescan") + (let ((msg (wl-summary-message-number))) + (wl-summary-rescan) + (and msg (wl-summary-jump-to-msg msg)))) + ((string= range "rescan-noscore") + (let ((msg (wl-summary-message-number)) + wl-use-scoring) + (wl-summary-rescan) + (and msg (wl-summary-jump-to-msg msg)))) + ((or (string-match "last:" range) + (string-match "first:" range)) + (wl-summary-goto-folder-subr (concat "/" range "/" folder) + 'force-update nil nil t)) + ((string= range "no-sync") + ;; do nothing. + ) + (t + (setq seen-list (elmo-msgdb-seen-load msgdb-dir)) + (setq mes (wl-summary-sync-update3 seen-list unset-cursor)) + (elmo-msgdb-seen-save msgdb-dir nil) ; delete all seen. + (if mes (message "%s" mes)))))) + +(defvar wl-summary-edit-addresses-candidate-fields + ;; First element becomes default. + '("from" "to" "cc")) + +(defun wl-summary-edit-addresses-collect-candidate-fields (mime-charset) + (let ((fields wl-summary-edit-addresses-candidate-fields) + body candidates components) + (while fields + (setq body + (mapconcat 'identity (elmo-multiple-field-body (car fields)) + ",")) + (setq body (wl-parse-addresses body)) + (if body (setq candidates (append candidates body))) + (setq fields (cdr fields))) + (setq candidates (elmo-uniq-list candidates)) + (elmo-set-work-buf + (elmo-set-buffer-multibyte default-enable-multibyte-characters) + (mapcar (function + (lambda (x) + (setq components (std11-extract-address-components x)) + (cons (nth 1 components) + (and (car components) + (eword-decode-string + (decode-mime-charset-string + (car components) + mime-charset)))))) + candidates)))) + +(defun wl-summary-edit-addresses-subr (the-email name-in-addr) + ;; returns nil if there's no change. + (if (elmo-get-hash-val (downcase the-email) wl-address-petname-hash) + (let (char) + (message (format "'%s' already exists. (e)dit/(d)elete/(c)ancel?" + the-email)) + (while (not (or (eq (setq char (read-char)) ?\r) + (eq char ?\n) + (eq char ? ) + (eq char ?e) + (eq char ?c) + (eq char ?d))) + (message + "Please answer `e' or `d' or `c'. (e)dit/(d)elete/(c)ancel?")) + (cond + ((or (eq char ?e) + (eq char ?\n) + (eq char ?\r) + (eq char ? )) + ;; Change Addresses + (wl-address-petname-add-or-change + the-email + (elmo-get-hash-val the-email wl-address-petname-hash) + (wl-address-header-extract-realname + (cdr (assoc (downcase the-email) + wl-address-completion-list))) t) + "edited") + ((eq char ?d) + ;; Delete Addresses + (if (y-or-n-p (format "Delete '%s'? " + the-email)) + (progn + (wl-address-petname-delete the-email) + "deleted") + (message "") + nil)) + (t (message "") + nil))) + ;; Add Petname + (wl-address-petname-add-or-change + the-email name-in-addr name-in-addr) + "added")) + +(defun wl-summary-edit-addresses (&optional addr-str) + "Edit address book interactively. +Optional argument ADDR-STR is used as a target address if specified." + (interactive (if current-prefix-arg + (list (read-from-minibuffer "Target address: ")))) + (save-excursion + (wl-summary-set-message-buffer-or-redisplay)) + (let* ((charset wl-summary-buffer-mime-charset) + (candidates + (with-current-buffer (wl-message-get-original-buffer) + (wl-summary-edit-addresses-collect-candidate-fields + charset))) + address pair result) + (if addr-str + (setq address addr-str) + (when candidates + (setq address (car (car candidates))) + (setq address + (completing-read + (format "Target address (%s): " address) + (mapcar + (function (lambda (x) (cons (car x) (car x)))) + candidates) + nil nil nil nil address)))) + (when address + (setq pair (assoc address candidates)) + (unless pair + (setq pair (cons address nil))) + (when (setq result (wl-summary-edit-addresses-subr (car pair) (cdr pair))) + ;; update alias + (wl-status-update) + (setq address (assoc (car pair) wl-address-list)) + (if address + (message "%s, %s, <%s> is %s." + (nth 2 address) + (nth 1 address) + (nth 0 address) + result))) + ;; i'd like to update summary-buffer, but... + ;;(wl-summary-rescan) + (run-hooks 'wl-summary-edit-addresses-hook)))) + +(defun wl-summary-incorporate (&optional arg) + "Check and prefetch all uncached messages. +If optional argument is non-nil, checking is omitted." + (interactive "P") + (unless arg + (wl-summary-sync-force-update)) + (wl-summary-prefetch-region (point-min) (point-max) + wl-summary-incorporate-marks)) + +(defun wl-summary-prefetch-msg (number) + "Returns status-mark. if skipped, returns nil." + ;; prefetching procedure. + (save-excursion + (let* ((msgdb wl-summary-buffer-msgdb) + (mark-alist (elmo-msgdb-get-mark-alist msgdb)) + (number-alist (elmo-msgdb-get-number-alist msgdb)) + (message-id (cdr (assq number number-alist))) + (ov (assoc message-id + (elmo-msgdb-get-overview msgdb))) + (entity ov) + (size (elmo-msgdb-overview-entity-get-size ov)) + (inhibit-read-only t) + (buffer-read-only nil) + (force-read (and size + (or (null wl-prefetch-threshold) + (< size wl-prefetch-threshold)))) + mark new-mark) + (unwind-protect + (progn + (when (and size (not force-read) wl-prefetch-confirm) + (setq force-read + (save-restriction + (widen) + (y-or-n-p + (format + "Message from %s has %d bytes. Prefetch it?" + (concat + "[ " + (save-match-data + (wl-set-string-width + wl-from-width + (wl-summary-from-func-internal + (eword-decode-string + (elmo-delete-char + ?\" + (or + (elmo-msgdb-overview-entity-get-from ov) + "??")))))) " ]") + size)))) + (message "")); flush. + (setq mark (cadr (assq number mark-alist))) + (if force-read + (save-excursion + (save-match-data + (if (and (null (elmo-folder-plugged-p + wl-summary-buffer-folder-name)) + elmo-enable-disconnected-operation) + (progn ;; append-queue for offline + (elmo-dop-prefetch-msgs + wl-summary-buffer-folder-name (list number)) + (setq new-mark + (cond + ((string= mark + wl-summary-unread-uncached-mark) + wl-summary-unread-cached-mark) + ((string= mark wl-summary-new-mark) + (setq wl-summary-buffer-new-count + (- wl-summary-buffer-new-count 1)) + (setq wl-summary-buffer-unread-count + (+ wl-summary-buffer-unread-count 1)) + wl-summary-unread-cached-mark) + ((or (null mark) + (string= mark wl-summary-read-uncached-mark)) + (setq wl-summary-buffer-unread-count + (+ wl-summary-buffer-unread-count 1)) + wl-summary-unread-cached-mark) + (t mark)))) + ;; online + (elmo-prefetch-msg wl-summary-buffer-folder-name + number + (wl-message-get-original-buffer) + msgdb) + (setq new-mark + (cond + ((string= mark + wl-summary-unread-uncached-mark) + wl-summary-unread-cached-mark) + ((string= mark wl-summary-new-mark) + (setq wl-summary-buffer-new-count + (- wl-summary-buffer-new-count 1)) + (setq wl-summary-buffer-unread-count + (+ wl-summary-buffer-unread-count 1)) + wl-summary-unread-cached-mark) + ((string= mark wl-summary-read-uncached-mark) + nil) + (t mark)))) + (setq mark-alist (elmo-msgdb-mark-set + mark-alist number new-mark)) + (or new-mark (setq new-mark " ")) + (elmo-msgdb-set-mark-alist msgdb mark-alist) + (wl-summary-set-mark-modified) + (wl-summary-update-modeline) + (wl-folder-update-unread + wl-summary-buffer-folder-name + (+ wl-summary-buffer-unread-count + wl-summary-buffer-new-count))) + new-mark))))))) + +;(defvar wl-summary-message-uncached-marks +; (list wl-summary-new-mark +; wl-summary-unread-uncached-mark +; wl-summary-read-uncached-mark)) + +(defun wl-summary-prefetch-region (beg end &optional prefetch-marks) + (interactive "r") + (let ((count 0) + targets + mark length + entity msg + start-pos) + (save-excursion + (setq start-pos (point)) + (save-restriction + (narrow-to-region beg end) + ;; collect prefetch targets. + (message "Collecting marks...") + (goto-char (point-min)) + (while (not (eobp)) + (beginning-of-line) + (when (looking-at "^ *\\([0-9]+\\)[^0-9]\\([^0-9]\\)") + (setq mark (wl-match-buffer 2)) + (setq msg (string-to-int (wl-match-buffer 1))) + (if (or (and (null prefetch-marks) + msg + (null (elmo-cache-exists-p + (cdr (assq msg + (elmo-msgdb-get-number-alist + wl-summary-buffer-msgdb)))))) + (member mark prefetch-marks)) + (setq targets (nconc targets (list msg)))) + (setq entity (wl-thread-get-entity msg)) + (if (or (not (eq wl-summary-buffer-view 'thread)) + (wl-thread-entity-get-opened entity)) + (); opened. no hidden children. + ;; hidden children!! + (setq targets (nconc + targets + (wl-thread-get-children-msgs-uncached + msg prefetch-marks))))) + (forward-line 1)) + (setq length (length targets)) + (message "Prefetching...") + (while targets + (setq mark (if (not (wl-thread-entity-parent-invisible-p + (wl-thread-get-entity (car targets)))) + (progn + (wl-summary-jump-to-msg (car targets)) + (wl-summary-prefetch)) + (wl-summary-prefetch-msg (car targets)))) + (if (if prefetch-marks + (string= mark wl-summary-unread-cached-mark) + (or (string= mark wl-summary-unread-cached-mark) + (string= mark " "))) + (message "Prefetching... %d/%d message(s)" + (setq count (+ 1 count)) length)) + ;; redisplay! + (save-excursion + (save-restriction + (widen) + (goto-char start-pos) + (sit-for 0))) + (setq targets (cdr targets))) + (message "Prefetched %d/%d message(s)" count length) + (cons count length))))) + +(defun wl-summary-prefetch () + "Prefetch current message." + (interactive) + (save-excursion + (save-match-data + (beginning-of-line) + (when (looking-at "^ *\\([0-9]+\\)[^0-9]\\([^0-9]\\)") + (goto-char (match-beginning 2)) + (let ((inhibit-read-only t) + (buffer-read-only nil) + mark) + (setq mark (wl-summary-prefetch-msg + (string-to-int (wl-match-buffer 1)))) + (when mark + (delete-region (match-beginning 2) + (match-end 2)) + (insert mark) + (if wl-summary-highlight + (wl-highlight-summary-current-line))) + (set-buffer-modified-p nil) + mark))))) + +(defun wl-summary-delete-all-status-marks-on-buffer () + (interactive) + (save-excursion + (goto-char (point-min)) + (let ((inhibit-read-only t) + (buffer-read-only nil) + (case-fold-search nil)) + (while (re-search-forward + (concat "^" wl-summary-buffer-number-regexp ".\\(.\\)") nil t) + (delete-region (match-beginning 1) (match-end 1)) + (insert " "))))) + +(defun wl-summary-delete-copy-marks-on-buffer (cpys) + (mapcar (function + (lambda (x) + (wl-summary-unmark x))) + cpys)) + +(defun wl-summary-delete-all-refile-marks () + (mapcar (function + (lambda (x) + (wl-summary-unmark (car x)))) wl-summary-buffer-refile-list)) + +(defun wl-summary-delete-all-copy-marks () + (mapcar (function + (lambda (x) + (wl-summary-unmark (car x)))) wl-summary-buffer-copy-list)) + +(defun wl-summary-delete-all-delete-marks () + (mapcar 'wl-summary-unmark wl-summary-buffer-delete-list)) + +(defun wl-summary-delete-all-target-marks () + (mapcar 'wl-summary-unmark wl-summary-buffer-target-mark-list)) + +(defun wl-summary-delete-all-temp-marks-on-buffer (&optional sticky) + ;; for summary view cache saving. + (interactive) + (save-excursion + (goto-char (point-min)) + (let ((inhibit-read-only t) + (buffer-read-only nil) + (case-fold-search nil) + (regexp (concat "^" wl-summary-buffer-number-regexp "\\([^ ]\\)" ))) + (while (re-search-forward regexp nil t) + (delete-region (match-beginning 1) (match-end 1)) + (insert " ") + (if (and sticky wl-summary-highlight) + (wl-highlight-summary-current-line)))))) + +(defun wl-summary-delete-all-marks (mark-alist mark) + "Delete all MARKs in MARK-ALIST" + (let ((malist mark-alist) + (ret-val mark-alist) + entity) + (while malist + (setq entity (car malist)) + (if (string= (cadr entity) mark) + ;; delete this entity + (setq ret-val (delete entity ret-val))) + (setq malist (cdr malist))) + ret-val)) + +;; Does not work correctly... +(defun wl-summary-mark-as-read-region (beg end) + (interactive "r") + (save-excursion + (save-restriction + (narrow-to-region beg end);(save-excursion (goto-char end) + ; (end-of-line) (point))) + (goto-char (point-min)) + (if (eq wl-summary-buffer-view 'thread) + (progn + (while (not (eobp)) + (let* ((number (wl-summary-message-number)) + (entity (wl-thread-get-entity number)) + children) + (if (wl-thread-entity-get-opened entity) + ;; opened...mark line. + ;; Crossposts are not processed + (wl-summary-mark-as-read t) + ;; closed + (wl-summary-mark-as-read t) ; mark itself. + (setq children (wl-thread-get-children-msgs number)) + (while children + (wl-thread-msg-mark-as-read (car children)) + (setq children (cdr children)))) + (forward-line 1)))) + (while (not (eobp)) + (wl-summary-mark-as-read t) + (forward-line 1))))) + (wl-summary-count-unread (elmo-msgdb-get-mark-alist wl-summary-buffer-msgdb)) + (wl-summary-update-modeline)) + +(defun wl-summary-mark-as-unread-region (beg end) + (interactive "r") + (save-excursion + (save-restriction + (narrow-to-region beg end);(save-excursion (goto-char end) + ; (end-of-line) (point))) + (goto-char (point-min)) + (if (eq wl-summary-buffer-view 'thread) + (progn + (while (not (eobp)) + (let* ((number (wl-summary-message-number)) + (entity (wl-thread-get-entity number)) + children) + (if (wl-thread-entity-get-opened entity) + ;; opened...mark line. + ;; Crossposts are not processed + (wl-summary-mark-as-unread) + ;; closed + (wl-summary-mark-as-unread) ; mark itself. + (setq children + (delq number (wl-thread-get-children-msgs number))) + (while children + (wl-thread-msg-mark-as-unread (car children)) + (setq children (cdr children)))) + (forward-line 1)))) + (while (not (eobp)) + (wl-summary-mark-as-unread) + (forward-line 1))))) + (wl-summary-count-unread (elmo-msgdb-get-mark-alist wl-summary-buffer-msgdb)) + (wl-summary-update-modeline)) + +(defun wl-summary-mark-as-important-region (beg end) + (interactive "r") + (save-excursion + (save-restriction + (narrow-to-region beg end);(save-excursion (goto-char end) + ; (end-of-line) (point))) + (goto-char (point-min)) + (if (eq wl-summary-buffer-view 'thread) + (progn + (while (not (eobp)) + (let* ((number (wl-summary-message-number)) + (entity (wl-thread-get-entity number)) + children) + (if (wl-thread-entity-get-opened entity) + ;; opened...mark line. + ;; Crossposts are not processed + (wl-summary-mark-as-important) + ;; closed + (wl-summary-mark-as-important) ; mark itself. + (setq children + (delq number (wl-thread-get-children-msgs number))) + (while children + (wl-thread-msg-mark-as-important (car children)) + (setq children (cdr children)))) + (forward-line 1)))) + (while (not (eobp)) + (wl-summary-mark-as-important) + (forward-line 1))))) + (wl-summary-count-unread (elmo-msgdb-get-mark-alist wl-summary-buffer-msgdb)) + (wl-summary-update-modeline)) + +(defun wl-summary-mark-as-read-all () + (interactive) + (if (or (not (interactive-p)) + (y-or-n-p "Mark all messages as read?")) + (let* ((folder wl-summary-buffer-folder-name) + (cur-buf (current-buffer)) + (msgdb wl-summary-buffer-msgdb) + ;;(number-alist (elmo-msgdb-get-number-alist msgdb)) + (mark-alist (elmo-msgdb-get-mark-alist msgdb)) + (malist mark-alist) + (inhibit-read-only t) + (buffer-read-only nil) + (case-fold-search nil) + msg mark) + (message "Setting all msgs as read...") + (elmo-mark-as-read folder (wl-summary-collect-unread mark-alist) + msgdb) + (save-excursion + (goto-char (point-min)) + (while (re-search-forward "^ *\\([0-9]+\\)[^0-9]\\([^0-9 ]\\)" nil t) + (setq msg (string-to-int (wl-match-buffer 1))) + (setq mark (wl-match-buffer 2)) + (when (and (not (string= mark wl-summary-important-mark)) + (not (string= mark wl-summary-read-uncached-mark))) + (delete-region (match-beginning 2) (match-end 2)) + (if (or (not (elmo-use-cache-p folder msg)) + (string= mark wl-summary-unread-cached-mark)) + (progn + (insert " ") + (setq mark-alist + (elmo-msgdb-mark-set + mark-alist + msg ;(cdr (assq msg number-alist)) + nil))) + ;; New mark and unread-uncached mark + (insert wl-summary-read-uncached-mark) + (setq mark-alist + (elmo-msgdb-mark-set mark-alist + msg + ; (cdr (assq msg number-alist)) + wl-summary-read-uncached-mark))) + (if wl-summary-highlight + (wl-highlight-summary-current-line nil nil t))))) + (setq mark-alist (wl-summary-set-as-read-mark-alist mark-alist)) + (wl-summary-set-mark-modified) + (set-buffer cur-buf); why is this needed??? + (elmo-msgdb-set-mark-alist msgdb mark-alist) + (wl-folder-update-unread wl-summary-buffer-folder-name 0) + (setq wl-summary-buffer-unread-count 0) + (setq wl-summary-buffer-new-count 0) + (wl-summary-update-modeline) + (message "Setting all msgs as read...done.") + (set-buffer-modified-p nil)))) + +(defun wl-summary-delete-cache () + "Delete cache of current message." + (interactive) + (save-excursion + (let* ((inhibit-read-only t) + (buffer-read-only nil) + (folder wl-summary-buffer-folder-name) + (msgdb wl-summary-buffer-msgdb) + (mark-alist (elmo-msgdb-get-mark-alist msgdb)) + (number-alist (elmo-msgdb-get-number-alist msgdb)) + (case-fold-search nil) + mark number unread new-mark) +; (re-search-backward "^ *[0-9]+..[0-9]+/[0-9]+" nil t) ; set cursor line + (beginning-of-line) + (when (looking-at "^ *\\([0-9]+\\)[^0-9]\\([^0-9]\\)") + (progn + (setq mark (wl-match-buffer 2)) + (cond + ((or (string= mark wl-summary-new-mark) + (string= mark wl-summary-unread-uncached-mark) + (string= mark wl-summary-important-mark)) + ;; noop + ) + ((string= mark wl-summary-unread-cached-mark) + (setq new-mark wl-summary-unread-uncached-mark)) + (t + (setq new-mark wl-summary-read-uncached-mark))) + (when new-mark + (setq number (string-to-int (wl-match-buffer 1))) + (delete-region (match-beginning 2) (match-end 2)) + (goto-char (match-beginning 2)) + (insert new-mark) + (elmo-cache-delete (cdr (assq number number-alist)) + wl-summary-buffer-folder-name + number) + (setq mark-alist + (elmo-msgdb-mark-set mark-alist number new-mark)) + (elmo-msgdb-set-mark-alist msgdb mark-alist) + (wl-summary-set-mark-modified) + (if wl-summary-highlight + (wl-highlight-summary-current-line nil nil t)) + (set-buffer-modified-p nil))))))) + +(defun wl-summary-resume-cache-status () + "Resume the cache status of all messages in the current folder." + (interactive) + (let* ((folder wl-summary-buffer-folder-name) + (cur-buf (current-buffer)) + (msgdb wl-summary-buffer-msgdb) + (number-alist (elmo-msgdb-get-number-alist msgdb)) + (mark-alist (elmo-msgdb-get-mark-alist msgdb)) + (inhibit-read-only t) + (buffer-read-only nil) + (case-fold-search nil) + msg mark msgid set-mark) + (message "Resuming cache status...") + (save-excursion + (goto-char (point-min)) + (while (re-search-forward "^ *\\([0-9]+\\)[^0-9]\\([^0-9]\\)" nil t) + (setq msg (string-to-int + (wl-match-buffer 1))) + (setq mark (wl-match-buffer 2)) + (setq msgid (cdr (assq msg number-alist))) + (setq set-mark nil) + (if (elmo-cache-exists-p msgid folder msg) + (if (or + (string= mark wl-summary-unread-uncached-mark) ; U -> ! + (string= mark wl-summary-new-mark) ; N -> ! + ) + (setq set-mark wl-summary-unread-cached-mark) + (if (string= mark wl-summary-read-uncached-mark) ; u -> ' ' + (setq set-mark " "))) + (if (string= mark " ") + (setq set-mark wl-summary-read-uncached-mark) ;' ' -> u + (if (string= mark wl-summary-unread-cached-mark) + (setq set-mark wl-summary-unread-uncached-mark) ; ! -> U + ))) + (when set-mark + (delete-region (match-beginning 2) (match-end 2)) + (insert set-mark) + (setq mark-alist + (elmo-msgdb-mark-set + mark-alist msg ; msgid + (if (string= set-mark " ") nil set-mark))) + (if wl-summary-highlight + (wl-highlight-summary-current-line)))) + (wl-summary-set-mark-modified) + (set-buffer cur-buf); why is this needed??? + (elmo-msgdb-set-mark-alist msgdb mark-alist) + (wl-summary-count-unread mark-alist) + (wl-summary-update-modeline) + (message "Resuming cache status...done.") + (set-buffer-modified-p nil)))) + +(defun wl-summary-resume-marks-and-highlight () + (let* ((msgdb wl-summary-buffer-msgdb) + (mark-alist (elmo-msgdb-get-mark-alist msgdb)) + ;;(number-alist (elmo-msgdb-get-number-alist msgdb)) + (count (count-lines (point-min)(point-max))) + (i 0) + msg-num percent smark) + (save-excursion + (goto-char (point-min)) + (message "Resuming all marks...") + (while (not (eobp)) + (setq msg-num (wl-summary-message-number)) + (setq smark (car (cdr (assq msg-num mark-alist)))) + (if (looking-at (format "^ *%s \\( \\)" msg-num)) + (progn + (goto-char (match-end 1)) + (delete-region (match-beginning 1) (match-end 1)) + (insert (or smark " ")))) + (wl-highlight-summary-current-line smark) + (setq i (+ i 1)) + (setq percent (/ (* i 100) count)) + (elmo-display-progress + 'wl-summary-resume-marks-and-highlight "Resuming all marks..." + percent) + (forward-line 1))) + (message "Resuming all marks...done."))) + +(defun wl-summary-resume-marks () + (let* ((msgdb wl-summary-buffer-msgdb) + (mark-alist (elmo-msgdb-get-mark-alist msgdb)) + (number-alist (elmo-msgdb-get-number-alist msgdb)) + (count (length mark-alist)) + (i 0) + entity msg-num percent) + (save-excursion + (message "Resuming all marks...") + (while mark-alist + (setq entity (car mark-alist)) + (if (setq msg-num (car (rassoc (car entity) number-alist))) + (progn ;(goto-char (point-min)) + (if (re-search-forward (format "^ *%s \\( \\)" msg-num) nil t) + (progn + (delete-region (match-beginning 1) (match-end 1)) + (insert (or (cadr entity) + " "))) + (if (re-search-backward (format "^ *%s \\( \\)" msg-num) nil t) + (progn + (goto-char (match-end 1)) + (delete-region (match-beginning 1) (match-end 1)) + (insert (or (cadr entity) + " "))))))) + (setq i (+ i 1)) + (setq percent (/ (* i 100) count)) + (elmo-display-progress + 'wl-summary-resume-marks "Resuming all marks..." + percent) + (setq mark-alist (cdr mark-alist))) + (message "Resuming all marks...done.")))) + +(defun wl-summary-delete-messages-on-buffer (msgs &optional deleting-info) + (interactive) + (save-excursion + (let ((inhibit-read-only t) + (buffer-read-only nil) + (msgs2 msgs) + (len (length msgs)) + (i 0) + update-list) + (while msgs + (if (eq wl-summary-buffer-view 'thread) + (progn + (setq update-list + (wl-append update-list + (wl-thread-delete-message (car msgs)))) + (setq update-list (and update-list + (delete (car msgs) update-list)))) + (goto-char (point-min)) + (if (re-search-forward (format "^ *%d[^0-9]\\([^0-9]\\).*$" + (car msgs)) nil t) + (progn + (delete-region (match-beginning 0) (match-end 0)) + (delete-char 1) ; delete '\n' + ))) + (when deleting-info + (setq i (1+ i)) + (and (zerop (% i 10)) + (elmo-display-progress + 'wl-summary-delete-messages-on-buffer "Deleting..." + (/ (* i 100) len)))) + (setq msgs (cdr msgs))) + (if (eq wl-summary-buffer-view 'thread) + (wl-thread-update-line-msgs (elmo-uniq-list update-list))) + (wl-thread-cleanup-symbols msgs2) + (wl-summary-count-unread + (elmo-msgdb-get-mark-alist wl-summary-buffer-msgdb)) + (wl-summary-update-modeline) + (wl-folder-update-unread + wl-summary-buffer-folder-name + (+ wl-summary-buffer-unread-count wl-summary-buffer-new-count))))) + +(defun wl-summary-set-as-read-mark-alist (mark-alist) + (let ((marks (list (cons wl-summary-unread-cached-mark + nil) + (cons wl-summary-unread-uncached-mark + wl-summary-read-uncached-mark) + (cons wl-summary-new-mark + wl-summary-read-uncached-mark))) + (ret-val mark-alist) + entity pair) + (while mark-alist + (setq entity (car mark-alist)) + (when (setq pair (assoc (cadr entity) marks)) + (if (elmo-use-cache-p wl-summary-buffer-folder-name + (caar mark-alist)) + (if (cdr pair) + (setcar (cdr entity) (cdr pair)) + (setq ret-val (delete entity ret-val))) + (setq ret-val (delete entity ret-val)))) + (setq mark-alist (cdr mark-alist))) + ret-val)) + +(defun wl-summary-set-status-marks (mark-alist before after) + "Set the BEFORE marks to AFTER" + (let ((ret-val mark-alist) + entity) + (while mark-alist + (setq entity (car mark-alist)) + (when (string= (cadr entity) before) + (if after + (setcar (cdr entity) after) + (setq ret-val (delete entity ret-val)))) + (setq mark-alist (cdr mark-alist))) + ret-val)) + +(defun wl-summary-set-status-marks-on-buffer (before after) + "Set the MARKS marks on buffer" + (interactive) + (save-excursion + (goto-char (point-min)) + (let ((inhibit-read-only t) + (buffer-read-only nil) + (regexp (concat "^" wl-summary-buffer-number-regexp ".\\(\\%s\\)"))) + (while (re-search-forward + (format regexp (regexp-quote before)) nil t) + (delete-region (match-beginning 1) (match-end 1)) + (insert after) + (if wl-summary-highlight + (wl-highlight-summary-current-line)))))) + +(defun wl-summary-get-delete-folder (folder) + (if (string= folder wl-trash-folder) + 'null + (let* ((type (or (wl-get-assoc-list-value wl-delete-folder-alist folder) + 'trash))) + (cond ((stringp type) + type) + ((or (equal type 'remove) (equal type 'null)) + 'null) + (t;; (equal type 'trash) + wl-trash-folder))))) + +(defun wl-summary-delete-important-msgs-from-list (delete-list + mark-alist) + (let ((dlist delete-list)) + (while dlist + (if (string= wl-summary-important-mark + (car (cdr (assq (car dlist) mark-alist)))) + (setq delete-list (delete (car dlist) delete-list))) + (setq dlist (cdr dlist))) + delete-list)) + +(defun wl-summary-delete-canceled-msgs-from-list (delete-list msgdb) + (let ((dlist delete-list)) + (while dlist + (if (null (cdr (assq (car dlist) (cadr msgdb)))) + (setq delete-list (delete (car dlist) delete-list))) + (setq dlist (cdr dlist))) + delete-list)) + +(defun wl-summary-get-append-message-func () + (if (eq wl-summary-buffer-view 'thread) + 'wl-summary-insert-thread-entity +; 'wl-summary-insert-thread + 'wl-summary-insert-summary)) + +(defun wl-summary-sort () + (interactive) + (let ((sort-by (let ((input-range-list '("number" "date" "subject" "from")) + (default "date") + in) + (setq in + (completing-read + (format "Sort by (%s): " default) + (mapcar + (function (lambda (x) (cons x x))) + input-range-list))) + (if (string= in "") + default + in)))) + (if (not (member sort-by '("number" "date" "subject" "from"))) + (error "Sort by %s is not implemented" sort-by)) + (wl-summary-rescan sort-by))) + +(defun wl-summary-sync-marks () + "Update marks in summary." + (interactive) + (let ((plugged (elmo-folder-plugged-p wl-summary-buffer-folder-name)) + mark-alist unread-marks msgs mark importants unreads + importants-in-db unreads-in-db has-imap4 diff diffs + mes) + ;; synchronize marks. + (when (not (eq (elmo-folder-get-type + wl-summary-buffer-folder-name) + 'internal)) + (message "Updating marks...") + (setq unread-marks (list wl-summary-unread-cached-mark + wl-summary-unread-uncached-mark + wl-summary-new-mark) + mark-alist (elmo-msgdb-get-mark-alist wl-summary-buffer-msgdb) + importants (elmo-list-folder-important + wl-summary-buffer-folder-name + (elmo-msgdb-get-overview wl-summary-buffer-msgdb)) + has-imap4 (elmo-folder-contains-type + wl-summary-buffer-folder-name 'imap4) + unreads (if (and has-imap4 plugged) + (elmo-list-folder-unread + wl-summary-buffer-folder-name + mark-alist unread-marks))) + (while mark-alist + (if (string= (cadr (car mark-alist)) + wl-summary-important-mark) + (setq importants-in-db (cons (car (car mark-alist)) + importants-in-db)) + (if (member (cadr (car mark-alist)) unread-marks) + (setq unreads-in-db (cons (car (car mark-alist)) + unreads-in-db)))) + (setq mark-alist (cdr mark-alist))) + (setq diff (elmo-list-diff importants importants-in-db)) + (setq diffs (cadr diff)) ; important-deletes + (setq mes (format "Updated (-%d" (length diffs))) + (while diffs + (wl-summary-mark-as-important (car diffs) + wl-summary-important-mark + 'no-server) + (setq diffs (cdr diffs))) + (setq diffs (car diff)) ; important-appends + (setq mes (concat mes (format "/+%d) important," (length diffs)))) + (while diffs + (wl-summary-mark-as-important (car diffs) " " 'no-server) + (setq diffs (cdr diffs))) + (when (and has-imap4 plugged) + (setq diff (elmo-list-diff unreads unreads-in-db)) + (setq diffs (cadr diff)) + (setq mes (concat mes (format "(-%d" (length diffs)))) + (while diffs + (wl-summary-mark-as-read t 'no-server nil (car diffs) 'no-cache) + (setq diffs (cdr diffs))) + (setq diffs (car diff)) ; unread-appends + (setq mes (concat mes (format "/+%d) unread mark(s)." (length diffs)))) + (while diffs + (wl-summary-mark-as-unread (car diffs) 'no-server 'no-modeline) + (setq diffs (cdr diffs)))) + (if (interactive-p) (message mes))))) + +(defun wl-summary-confirm-appends (appends) + (condition-case nil + (let ((len (length appends)) + in) + (if (> len wl-summary-update-confirm-threshold) + (if (y-or-n-p (format "Too many messages(%d). Continue?" len)) + appends + (setq in wl-summary-update-confirm-threshold) + (catch 'end + (while t + (setq in (read-from-minibuffer "Update number: " + (int-to-string in)) + in (string-to-int in)) + (if (y-or-n-p (format "%d messages are disappeared. OK?" + (- len in))) + (throw 'end in)))) + (nthcdr (max (- len in) 0) appends)) + appends)) + (quit nil) + (error nil))) ; + +(defun wl-summary-sync-update3 (&optional seen-list unset-cursor) + "Update the summary view." + (interactive) + (let* ((folder wl-summary-buffer-folder-name) + (cur-buf (current-buffer)) + (msgdb wl-summary-buffer-msgdb) + (number-alist (elmo-msgdb-get-number-alist msgdb)) + (mark-alist (elmo-msgdb-get-mark-alist msgdb)) + (overview (elmo-msgdb-get-overview msgdb)) + ;;(location (elmo-msgdb-get-location msgdb)) + (case-fold-search nil) + (elmo-mime-charset wl-summary-buffer-mime-charset) + (inhibit-read-only t) + (buffer-read-only nil) + diff append-list delete-list + i percent num result + gc-message + in-folder + in-db curp + overview-append + entity ret-val crossed crossed2 sync-all + top-num update-top-list mark + expunged msgs unreads importants) + ;(setq seen-list nil) ;for debug. + (fset 'wl-summary-append-message-func-internal + (wl-summary-get-append-message-func)) + ;; Flush pending append operations (disconnected operation). + (setq seen-list + (wl-summary-flush-pending-append-operations seen-list)) + (goto-char (point-max)) + (message "Checking folder diff...") + (setq in-folder (elmo-list-folder folder)) + (setq in-db (sort (mapcar 'car number-alist) '<)) + (when (or (eq msgdb nil) ; trick for unplugged... + (equal msgdb '(nil nil nil nil))) + (setq sync-all t) + (wl-summary-set-message-modified) + (wl-summary-set-mark-modified) + (erase-buffer)) + (setq diff (if (eq (elmo-folder-get-type folder) 'multi) + (elmo-multi-list-bigger-diff in-folder in-db) + (elmo-list-bigger-diff in-folder in-db))) + (setq append-list (car diff)) + (setq delete-list (cadr diff)) + (message "Checking folder diff...done.") + ;; Don't delete important-marked msgs other than 'internal. + (unless (eq (elmo-folder-get-type folder) 'internal) + (setq delete-list + (wl-summary-delete-important-msgs-from-list delete-list + mark-alist))) + (if (and (elmo-folder-contains-type folder 'nntp) + (elmo-nntp-max-number-precedes-list-active-p)) + ;; XXX this does not work correctly in rare case. + (setq delete-list + (wl-summary-delete-canceled-msgs-from-list delete-list + msgdb))) + (if (or (equal diff '(nil nil)) + (equal diff '(nil)) + (and (eq (length delete-list) 0) + (eq (length append-list) 0))) + (progn + ;; For max-number update... + (if (and (elmo-folder-contains-type folder 'nntp) + (elmo-nntp-max-number-precedes-list-active-p) + (elmo-update-number folder msgdb)) + (wl-summary-set-message-modified) + (setq ret-val (format "No update is needed for \"%s\"" folder)))) + (when delete-list + (message "Deleting...") + (elmo-msgdb-delete-msgs folder delete-list msgdb t) ; reserve cache. + ;;(set-buffer cur-buf) + (wl-summary-delete-messages-on-buffer delete-list t) + (message "Deleting...done.")) + ;;(set-buffer cur-buf) + ;; Change "New" marks to "Uncached Unread" marks. + (wl-summary-set-status-marks mark-alist + wl-summary-new-mark + wl-summary-unread-uncached-mark) + (wl-summary-set-status-marks-on-buffer + wl-summary-new-mark + wl-summary-unread-uncached-mark) + ;; Confirm appended message number. + (setq append-list (wl-summary-confirm-appends append-list)) + (setq num (length append-list)) + (if append-list + (progn + (setq i 0) + (setq result (elmo-msgdb-create + folder + append-list + wl-summary-new-mark + wl-summary-unread-cached-mark ; ! + wl-summary-read-uncached-mark ; u ;; XXXX + wl-summary-important-mark + seen-list)) + ;; delete duplicated messages. + (when (elmo-folder-contains-multi folder) + (setq crossed (elmo-multi-delete-crossposts + msgdb result)) + (setq result (cdr crossed)) + (setq crossed (car crossed))) + (setq overview-append (car result)) + (setq msgdb (elmo-msgdb-append msgdb result)) + ;; set these value for append-message-func + (setq overview (elmo-msgdb-get-overview msgdb)) + (setq number-alist (elmo-msgdb-get-number-alist msgdb)) + (setq mark-alist (elmo-msgdb-get-mark-alist msgdb)) + ;; (setq location (elmo-msgdb-get-location msgdb)) + (setq curp overview-append) + (setq num (length curp)) + (while curp + (setq entity (car curp)) + (setq top-num + (wl-summary-append-message-func-internal + entity overview mark-alist + (not sync-all))) + (when top-num + (wl-append update-top-list (list top-num))) + (if elmo-use-database + (elmo-database-msgid-put + (car entity) folder + (elmo-msgdb-overview-entity-get-number entity))) + (setq curp (cdr curp)) + (setq i (+ i 1)) + (setq percent (/ (* i 100) num)) + (elmo-display-progress + 'wl-summary-sync-update3 "Updating thread..." + percent)) + (setq update-top-list + (elmo-uniq-list update-top-list)) + (when (and (eq wl-summary-buffer-view 'thread) + update-top-list ) + (message "Updating indent...") + (wl-thread-update-indent-string-thread update-top-list) + (message "Updating indent...done.")) + (message "Updating thread...done.") + ;;(set-buffer cur-buf) + )) + (wl-summary-set-message-modified) + (wl-summary-set-mark-modified) + (setq wl-summary-buffer-msgdb msgdb) + (when (and sync-all (eq wl-summary-buffer-view 'thread)) + (message "Inserting thread...") + (setq wl-thread-entity-cur 0) + (wl-thread-insert-top) + (message "Inserting thread...done.")) + (if elmo-use-database + (elmo-database-close)) + (run-hooks 'wl-summary-sync-updated-hook) + (setq ret-val (format "Updated (-%d/+%d) message(s)" + (length delete-list) num))) + ;; synchronize marks. + (if wl-summary-auto-sync-marks + (wl-summary-sync-marks)) + ;; scoring + (when wl-use-scoring + (setq wl-summary-scored nil) + (wl-summary-score-headers nil msgdb + (and sync-all + (wl-summary-rescore-msgs number-alist)) + sync-all) + (setq expunged (wl-summary-score-update-all-lines)) + (if expunged + (setq ret-val (concat ret-val + (format " (%d expunged)" + (length expunged)))))) + ;; crosspost + (setq crossed2 (wl-summary-update-crosspost)) + (if (or crossed crossed2) + (let ((crosses (+ (or crossed 0) + (or crossed2 0)))) + (setq ret-val + (if ret-val + (concat ret-val + (format " (%d crosspost)" crosses)) + (format "%d crosspost message(s)" crosses)))) + (and ret-val + (setq ret-val (concat ret-val ".")))) + ;; Update Folder mode + (wl-folder-set-folder-updated folder (list 0 + (wl-summary-count-unread + (elmo-msgdb-get-mark-alist + msgdb)) + (length in-folder))) + (wl-summary-update-modeline) + ;; + (unless unset-cursor + (goto-char (point-min)) + (if (not (wl-summary-cursor-down t)) + (progn + (goto-char (point-max)) + (forward-line -1)) + (if (and wl-summary-highlight + (not (get-text-property (point) 'face))) + (save-excursion + (forward-line (- 0 + (or + wl-summary-partial-highlight-above-lines + wl-summary-highlight-partial-threshold))) + (wl-highlight-summary (point) (point-max)))))) + (wl-delete-all-overlays) + (set-buffer-modified-p nil) + ret-val)) + +(defun wl-summary-set-score-mark (mark) + (save-excursion + (beginning-of-line) + (let ((inhibit-read-only t) + (buffer-read-only nil) + msg-num + cur-mark) + (when (looking-at "^ *\\([0-9]+\\)\\([^0-9]\\)") + (setq msg-num (string-to-int (wl-match-buffer 1))) + (setq cur-mark (wl-match-buffer 2)) + (when (member cur-mark (list " " + wl-summary-score-below-mark + wl-summary-score-over-mark)) + (goto-char (match-end 1)) + (delete-region (match-beginning 2) (match-end 2)) + (insert mark) + (if wl-summary-highlight + (wl-highlight-summary-current-line nil nil t)) + (set-buffer-modified-p nil)))))) + +(defun wl-summary-get-score-mark (msg-num) + (let ((score (cdr (assq msg-num wl-summary-scored)))) + (if score + (cond ((< score wl-summary-default-score) + "-") + ((> score wl-summary-default-score) + "+"))))) + +(defun wl-summary-update-modeline () + (setq wl-summary-buffer-unread-status + (format " {%s}(%d new/%d unread)" + (if (eq wl-summary-buffer-view 'thread) + "T" "S") + wl-summary-buffer-new-count + (+ wl-summary-buffer-new-count + wl-summary-buffer-unread-count)))) + +(defsubst wl-summary-jump-to-msg (&optional number) + (interactive) + (let ((num (or number + (string-to-int + (read-from-minibuffer "Jump to Message(No.): "))))) + (setq num (int-to-string num)) + (if (re-search-forward (concat "^[ \t]*" num "[^0-9]") nil t) + (progn + (beginning-of-line) + t) + (if (re-search-backward (concat "^[ \t]*" num "[^0-9]") nil t) + (progn + (beginning-of-line) + t) + nil)))) + +(defun wl-summary-highlight-msgs (msgs) + (save-excursion + (let ((len (length msgs)) + i) + (message "Hilighting...") + (setq i 0) + (while msgs + (setq i (+ i 1)) + (elmo-display-progress + 'wl-summary-highlight-msgs "Highlighting..." + (/ (* i 100) len)) + (if (wl-summary-jump-to-msg (car msgs)) + (wl-highlight-summary-current-line)) + (setq msgs (cdr msgs))) + (message "Highlighting...done.")))) + +(defun wl-summary-message-number () + (save-excursion + (beginning-of-line) + (if (looking-at "^ *\\([0-9]+\\)") + (string-to-int (wl-match-buffer 1)) + nil))) + +(defun wl-summary-move (src dsts-msgs) + (let* ((dsts (car dsts-msgs)) ; (+foo +bar) +;; (msgs (cdr dsts-msgs)) ; (1 2 3) +;; (msgdb wl-summary-buffer-msgdb) +;; result) + ) + (while dsts + (setq dsts (cdr dsts))))) + +(defun wl-summary-flush-pending-append-operations (&optional seen-list) + "Execute append operations that are done while offline status." + (when (and (elmo-folder-plugged-p wl-summary-buffer-folder-name) + elmo-enable-disconnected-operation) + (let* ((resumed-list (elmo-dop-append-list-load + wl-summary-buffer-folder-name t)) + (append-list (elmo-dop-append-list-load + wl-summary-buffer-folder-name)) + (appends (append resumed-list append-list)) + (number-alist (elmo-msgdb-get-number-alist wl-summary-buffer-msgdb)) + dels pair) + (when appends + (while appends + (if (setq pair (rassoc (car appends) number-alist)) + (setq dels (append dels (list (car pair))))) + (setq appends (cdr appends))) + (when dels + (setq seen-list + (elmo-msgdb-add-msgs-to-seen-list-subr + dels + wl-summary-buffer-msgdb + (concat wl-summary-important-mark + wl-summary-read-uncached-mark) + seen-list)) + (message "Resuming summary status...") + (elmo-msgdb-delete-msgs wl-summary-buffer-folder-name + dels wl-summary-buffer-msgdb t) + (wl-summary-delete-messages-on-buffer dels) + (message "Resuming summary status...done.")) + ;; delete resume-file + (elmo-dop-append-list-save wl-summary-buffer-folder-name nil t) + (when append-list + (elmo-dop-flush-pending-append-operations + wl-summary-buffer-folder-name append-list))))) + seen-list) + +(defun wl-summary-delete-all-msgs () + (interactive) + (let ((cur-buf (current-buffer)) + (dels (elmo-list-folder wl-summary-buffer-folder-name))) + (set-buffer cur-buf) + (if (null dels) + (message "No message to delete.") + (if (y-or-n-p (format "%s has %d message(s). Delete all?" + wl-summary-buffer-folder-name + (length dels))) + (progn + (message "Deleting...") + (elmo-delete-msgs wl-summary-buffer-folder-name dels + wl-summary-buffer-msgdb) + (elmo-msgdb-delete-msgs wl-summary-buffer-folder-name + dels wl-summary-buffer-msgdb) + ;;(elmo-msgdb-save wl-summary-buffer-folder-name nil) + (wl-summary-set-message-modified) + (wl-summary-set-mark-modified) + (wl-folder-set-folder-updated wl-summary-buffer-folder-name + (list 0 0 0)) + ;; for thread. + ;; (setq wl-thread-top-entity '(nil t nil nil)) + (setq wl-summary-buffer-unread-count 0) + (setq wl-summary-buffer-new-count 0) + (wl-summary-update-modeline) + (set-buffer cur-buf) + (let ((inhibit-read-only t) + (buffer-read-only nil)) + (erase-buffer)) + ;; (if wl-summary-cache-use (wl-summary-save-view-cache)) + (message "Deleting...done.") + t) + nil)))) + +(defun wl-summary-toggle-thread (&optional arg) + "Toggle thread status (T)hread and (S)equencial." + (interactive "P") + (when (or arg + (y-or-n-p (format "Toggle threading? (y=%s): " + (if (eq wl-summary-buffer-view 'thread) + "\"off\"" "\"on\"")))) + (if (eq wl-summary-buffer-view 'thread) + (setq wl-summary-buffer-view 'sequence) + (setq wl-summary-buffer-view 'thread)) + (wl-summary-update-modeline) + (force-mode-line-update) + (wl-summary-rescan))) + +(defun wl-summary-load-file-object (filename) + "Load lisp object from dir." + (save-excursion + (let ((tmp-buffer (get-buffer-create " *wl-summary-load-file-object*")) + insert-file-contents-pre-hook ; To avoid autoconv-xmas... + insert-file-contents-post-hook + ret-val) + (if (not (file-readable-p filename)) + () + (set-buffer tmp-buffer) + (as-binary-input-file (insert-file-contents filename)) + (setq ret-val + (condition-case nil + (read (current-buffer)) + (error (error "reading failed"))))) + (kill-buffer tmp-buffer) + ret-val))) + +(defun wl-summary-goto-folder (&optional arg) + (interactive "P") + (wl-summary-goto-folder-subr nil nil nil arg t)) + +(defun wl-summary-goto-last-visited-folder () + (interactive) + (let ((entity + (wl-folder-search-entity-by-name wl-summary-last-visited-folder + wl-folder-entity + 'folder))) + (if entity (wl-folder-set-current-entity-id + (wl-folder-get-entity-id entity)))) + (wl-summary-goto-folder-subr wl-summary-last-visited-folder nil nil nil t)) + +(defun wl-summary-sticky-p (&optional fld) + (if fld + (get-buffer (wl-summary-sticky-buffer-name fld)) + (not (string= wl-summary-buffer-name (buffer-name))))) + +(defmacro wl-summary-always-sticky-folder-p (fld) + (` (wl-string-match-member (, fld) wl-summary-always-sticky-folder-list))) + +(defun wl-summary-stick (&optional force) + "Make current summary buffer sticky." + (interactive "P") + (if (wl-summary-sticky-p) + (message "Current summary buffer is already sticky.") + (when (or force (y-or-n-p "Stick current summary buffer?")) + (wl-summary-toggle-disp-msg 'off) + (wl-summary-switch-to-clone-buffer + (wl-summary-sticky-buffer-name + wl-summary-buffer-folder-name)) +;;; ???hang up +; (rename-buffer (wl-summary-sticky-buffer-name +; wl-summary-buffer-folder-name))) + (message "Folder `%s' is now sticky." wl-summary-buffer-folder-name)))) + +(defun wl-summary-switch-to-clone-buffer (buffer-name) + (let ((cur-buf (current-buffer)) + (msg (wl-summary-message-number)) + (buf (get-buffer-create buffer-name)) + (folder wl-summary-buffer-folder-name) + (copy-variables + (append '(wl-summary-buffer-view + wl-summary-buffer-refile-list + wl-summary-buffer-delete-list + wl-summary-buffer-copy-list + wl-summary-buffer-target-mark-list + wl-summary-buffer-msgdb + wl-summary-buffer-number-column + wl-summary-buffer-number-regexp + wl-summary-buffer-message-modified + wl-summary-buffer-mark-modified) + (and (eq wl-summary-buffer-view 'thread) + '(wl-thread-entity-hashtb + wl-thread-entities + wl-thread-entity-list)) + (and wl-use-scoring + '(wl-summary-scored + wl-summary-default-score + wl-summary-important-above + wl-summary-temp-above + wl-summary-mark-below + wl-summary-expunge-below)) + (and (featurep 'wl-score) + '(wl-current-score-file + wl-score-alist))))) + (set-buffer buf) + (wl-summary-buffer-set-folder folder) + (wl-summary-mode) + (let ((buffer-read-only nil)) + (insert-buffer cur-buf)) + (set-buffer-modified-p nil) + (mapcar + (function + (lambda (var) + (set var (save-excursion + (set-buffer cur-buf) + (symbol-value var))))) + copy-variables) + (switch-to-buffer buf) + (kill-buffer cur-buf) + (setq mode-line-buffer-identification + (format "Wanderlust: %s" + (if (memq 'modeline wl-use-folder-petname) + (wl-folder-get-petname folder) + folder))) + (wl-summary-count-unread + (elmo-msgdb-get-mark-alist wl-summary-buffer-msgdb)) + (wl-summary-update-modeline) + (if msg + (if (eq wl-summary-buffer-view 'thread) + (wl-thread-jump-to-msg msg) + (wl-summary-jump-to-msg msg)) + (goto-char (point-max)) + (beginning-of-line)))) + +(defun wl-summary-get-buffer (folder) + (or (and folder + (get-buffer (wl-summary-sticky-buffer-name folder))) + (get-buffer wl-summary-buffer-name))) + +(defun wl-summary-get-buffer-create (folder &optional force-sticky) + (if force-sticky + (get-buffer-create + (wl-summary-sticky-buffer-name folder)) + (or (get-buffer (wl-summary-sticky-buffer-name folder)) + (get-buffer-create wl-summary-buffer-name)))) + +(defun wl-summary-disp-msg (folder disp-msg) + (let (disp mes-win) + (if (and disp-msg + wl-summary-buffer-disp-msg) + (let ((view-message-buffer (get-buffer wl-message-buf-name)) + (number (wl-summary-message-number)) + cur-folder cur-number sel-win) + (when view-message-buffer + (save-excursion + (set-buffer view-message-buffer) + (setq cur-folder wl-message-buffer-cur-folder + cur-number wl-message-buffer-cur-number)) + (when (and (string= folder cur-folder) + (eq number cur-number)) + (setq sel-win (selected-window)) + (wl-select-buffer view-message-buffer) + (select-window sel-win) + (setq disp t))))) + (if (not disp) + (setq wl-summary-buffer-disp-msg nil)) + (when (and (not disp) + (setq mes-win (wl-message-buffer-window))) + (delete-window mes-win) + (run-hooks 'wl-summary-toggle-disp-off-hook)))) + +(defun wl-summary-goto-folder-subr (&optional folder scan-type other-window + sticky interactive scoring) + "Display target folder on summary" + (interactive) + (let* ((keep-cursor (memq this-command + wl-summary-keep-cursor-command)) + (fld (or folder (wl-summary-read-folder wl-default-folder))) + (cur-fld wl-summary-buffer-folder-name) + buf mes hilit reuse-buf + retval entity) + (if (string= fld "") + (setq fld wl-default-folder)) + (when (and (not (string= cur-fld fld)) ; folder is moved. + (eq major-mode 'wl-summary-mode)) ; called in summary. + (setq wl-summary-last-visited-folder wl-summary-buffer-folder-name) + (wl-summary-cleanup-temp-marks (wl-summary-sticky-p)) + (wl-summary-save-status 'keep)) ;; keep current buffer, anyway. + (setq buf (wl-summary-get-buffer-create fld sticky)) + (setq reuse-buf + (save-excursion + (set-buffer buf) + (string= fld wl-summary-buffer-folder-name))) + (unwind-protect + (if reuse-buf + (if interactive + (switch-to-buffer buf) + (set-buffer buf)) + (if other-window + (delete-other-windows)) + (set-buffer buf) + (wl-summary-buffer-set-folder fld) + (unless (eq major-mode 'wl-summary-mode) + (wl-summary-mode)) + (setq wl-summary-buffer-disp-msg nil) + (setq wl-summary-buffer-last-displayed-msg nil) + (setq wl-summary-buffer-current-msg nil) + (let ((case-fold-search nil) + (inhibit-read-only t) + (buffer-read-only nil)) + (erase-buffer) + (setq mode-line-buffer-identification + (format "Wanderlust: %s" + (if (memq 'modeline wl-use-folder-petname) + (wl-folder-get-petname fld) + fld))) + ;; resume summary cache + (if wl-summary-cache-use + (let* ((dir (elmo-msgdb-expand-path fld)) + (cache (expand-file-name wl-summary-cache-file dir)) + (view (expand-file-name wl-summary-view-file dir))) + (when (file-exists-p cache) + (as-binary-input-file + (insert-file-contents cache)) + (elmo-set-buffer-multibyte + default-enable-multibyte-characters) + (decode-mime-charset-region + (point-min)(point-max) + wl-summary-buffer-mime-charset)) + (when (file-exists-p view) + (setq wl-summary-buffer-view + (wl-summary-load-file-object view))) + (if (eq wl-summary-buffer-view 'thread) + (wl-thread-resume-entity fld)))) + ;; Load msgdb + (setq wl-summary-buffer-msgdb nil) ; new msgdb + (setq wl-summary-buffer-msgdb + (wl-summary-msgdb-load-async fld)) + (if (null wl-summary-buffer-msgdb) + (setq wl-summary-buffer-msgdb + (elmo-msgdb-load (elmo-string fld)))) + (wl-summary-count-unread + (elmo-msgdb-get-mark-alist wl-summary-buffer-msgdb)) + (wl-summary-update-modeline))) + (wl-summary-buffer-number-column-detect t) + (wl-summary-disp-msg fld (and reuse-buf keep-cursor)) + (unless (and reuse-buf keep-cursor) + (setq hilit wl-summary-highlight) + (unwind-protect + (let ((wl-summary-highlight (if reuse-buf wl-summary-highlight)) + (wl-use-scoring + (if (or scoring interactive) wl-use-scoring))) + (if (and (not scan-type) + interactive + (not wl-ask-range)) + (setq scan-type (wl-summary-get-sync-range fld))) + (cond + ((eq scan-type nil) + (wl-summary-sync 'unset-cursor)) + ((eq scan-type 'all) + (wl-summary-sync 'unset-cursor "all")) + ((eq scan-type 'no-sync)) + ((or (eq scan-type 'force-update) + (eq scan-type 'update)) + (setq mes (wl-summary-sync-force-update 'unset-cursor))))) + (if interactive + (switch-to-buffer buf) + (set-buffer buf)) + ;; stick always-sticky-folder + (when (wl-summary-always-sticky-folder-p fld) + (or (wl-summary-sticky-p) (wl-summary-stick t))) + (run-hooks 'wl-summary-prepared-pre-hook) + (set-buffer-modified-p nil) + (goto-char (point-min)) + (if (wl-summary-cursor-down t) + (let ((unreadp (wl-thread-next-mark-p + (wl-thread-entity-get-mark + (wl-summary-message-number)) + wl-summary-move-order))) + (cond ((and wl-auto-select-first unreadp) + (setq retval 'disp-msg)) + ((not unreadp) + (setq retval 'more-next)))) + (goto-char (point-max)) + (if (elmo-folder-plugged-p folder) + (forward-line -1) + (wl-summary-prev)) + (setq retval 'more-next)) + (setq wl-summary-highlight hilit) + (if (and wl-summary-highlight + (not reuse-buf)) + (if (and wl-summary-highlight-partial-threshold + (> (count-lines (point-min) (point-max)) + wl-summary-highlight-partial-threshold)) + (save-excursion + (forward-line (- + 0 + wl-summary-partial-highlight-above-lines)) + (wl-highlight-summary (point) (point-max))) + (wl-highlight-summary (point-min) (point-max)))) + (if (null wl-summary-buffer-msgdb) ;; one more try. + (setq wl-summary-buffer-msgdb + (elmo-msgdb-load (elmo-string fld)))) + (if (eq retval 'disp-msg) + (wl-summary-redisplay)) + (if mes (message "%s" mes)) + (if (and interactive wl-summary-recenter) + (recenter (/ (- (window-height) 2) 2)))))) + ;; set current entity-id + (if (and (not folder) + (setq entity + (wl-folder-search-entity-by-name fld + wl-folder-entity + 'folder))) + ;; entity-id is unknown. + (wl-folder-set-current-entity-id + (wl-folder-get-entity-id entity))) + (unwind-protect + (run-hooks 'wl-summary-prepared-hook) + (set-buffer-modified-p nil)) + retval)) + +(defun wl-summary-summary-line-already-exists-p (parent-number buffer) + "returns the depth." + (set-buffer buffer) + (goto-char (point-max)) + (let ((depth 0)) + (when (re-search-backward (format "^ *%s..../..\(.*\)..:.. " + parent-number) nil t) + (goto-char (match-end 0)) + (while (string-match wl-thread-indent-regexp + (char-to-string + (char-after (point)))) + (setq depth (+ 1 depth)) + (forward-char)) + (/ depth wl-thread-indent-level-internal)))) + +(defun wl-summary-goto-bottom-of-current-thread () + (if (re-search-forward (concat "^" wl-summary-buffer-number-regexp + "..../..\(.*\)..:.. \\[") nil t) + () + (goto-char (point-max)))) + +(defun wl-summary-goto-top-of-current-thread () + (wl-summary-jump-to-msg + (wl-thread-entity-get-number + (wl-thread-entity-get-top-entity (wl-thread-get-entity + (wl-summary-message-number)))))) + +(defun wl-summary-goto-bottom-of-sub-thread (&optional depth) + (interactive) + (let ((depth (or depth + (wl-thread-get-depth-of-current-line)))) + (forward-line 1) + (while (and (not (eobp)) + (>= (wl-thread-get-depth-of-current-line) + depth)) + (forward-line 1)) + (beginning-of-line))) + +(defun wl-summary-insert-line (line) + "Insert LINE in the Summary." + (if wl-use-highlight-mouse-line + ;; remove 'mouse-face of current line. + (put-text-property + (save-excursion (beginning-of-line)(point)) + (save-excursion (end-of-line)(point)) + 'mouse-face nil)) + (insert line "\n") + (if wl-use-highlight-mouse-line + ;; remove 'mouse-face of current line. + (put-text-property + (save-excursion (beginning-of-line)(point)) + (save-excursion (end-of-line)(point)) + 'mouse-face nil)) + (condition-case nil ; it's dangerous, so ignore error. + (run-hooks 'wl-summary-line-inserted-hook) + (error (ding) + (message "Error in wl-summary-line-inserted-hook")))) + +(defun wl-summary-insert-summary (entity database mark-alist dummy) + (let ((overview-entity entity) + summary-line msg) + (setq msg (elmo-msgdb-overview-entity-get-number entity)) + (when (setq summary-line + (wl-summary-overview-create-summary-line + msg entity nil 0 mark-alist)) + (let ((inhibit-read-only t) + buffer-read-only) + (goto-char (point-max)) + (wl-summary-insert-line summary-line))))) + +(defun wl-summary-default-subject-filter (subject) + (let ((case-fold-search t)) + (setq subject (elmo-replace-in-string subject "[ \t]*\\(re\\|was\\):" "")) + (setq subject (elmo-replace-in-string subject "[ \t]" "")) + (elmo-replace-in-string subject "^\\[.*\\]" ""))) + +(defun wl-summary-subject-equal (subject1 subject2) + (string= (wl-summary-subject-filter-func-internal subject1) + (wl-summary-subject-filter-func-internal subject2))) + +(defun wl-summary-insert-thread-entity (entity overview mark-alist update) + (let* ((this-id (elmo-msgdb-overview-entity-get-id entity)) + (parent-entity + (elmo-msgdb-overview-get-parent-entity entity overview));; temp + ;;(parent-id (elmo-msgdb-overview-entity-get-id parent-entity)) + (parent-number (elmo-msgdb-overview-entity-get-number parent-entity)) + msg) + (if (and parent-number + wl-summary-divide-thread-when-subject-changed + (not (wl-summary-subject-equal + (or (elmo-msgdb-overview-entity-get-subject + entity) "") + (or (elmo-msgdb-overview-entity-get-subject + parent-entity) "")))) + (setq parent-number nil)) + (setq msg (elmo-msgdb-overview-entity-get-number entity)) + (wl-thread-insert-message entity overview mark-alist + msg parent-number update))) + +(defun wl-summary-update-thread (entity + overview + mark-alist + thr-entity + parent-entity) + (let* ((depth 0) + (this-id (elmo-msgdb-overview-entity-get-id entity)) + (overview-entity entity) + (parent-id (elmo-msgdb-overview-entity-get-id parent-entity)) + (parent-number (elmo-msgdb-overview-entity-get-number parent-entity)) + summary-line msg subject-differ) + (cond + ((or (not parent-id) + (string= this-id parent-id)) + (goto-char (point-max)) + (beginning-of-line)) + ;; parent already exists in buffer. + ((setq depth (or (wl-summary-summary-line-already-exists-p + parent-number (current-buffer)) -1)) + (setq depth (+ 1 depth)) + (wl-thread-goto-bottom-of-sub-thread))) + (if (and (elmo-msgdb-overview-entity-get-number entity)) + (if (setq summary-line + (wl-summary-overview-create-summary-line + (elmo-msgdb-overview-entity-get-number entity) + entity parent-entity depth mark-alist nil nil + thr-entity)) + (let ((inhibit-read-only t) + (buffer-read-only nil)) + (wl-summary-insert-line summary-line)))))) + +(defun wl-summary-mark-as-unread (&optional number + no-server-update + no-modeline-update) + (interactive) + (save-excursion + (let* (eol + (inhibit-read-only t) + (buffer-read-only nil) + (folder wl-summary-buffer-folder-name) + (msgdb wl-summary-buffer-msgdb) + (mark-alist (elmo-msgdb-get-mark-alist msgdb)) + ;;(number-alist (elmo-msgdb-get-number-alist msgdb)) + new-mark visible mark) + (if number + (progn + (setq visible (wl-summary-jump-to-msg number)) + (unless (setq mark (cadr (assq number mark-alist))) + (setq mark " "))) + ;; interactive + (setq visible t)) + (end-of-line) + (setq eol (point)) + (re-search-backward (concat "^" wl-summary-buffer-number-regexp + "..../..")) ; set cursor line + (beginning-of-line) + (if (or (and (not visible) + ;; already exists in msgdb. + (assq number (elmo-msgdb-get-number-alist msgdb))) + (re-search-forward + (format (concat "^ *\\(" + (if number (int-to-string number) + "[0-9]+") + "\\)[^0-9]\\(%s\\|%s\\)") + wl-summary-read-uncached-mark + " ") eol t)) + (progn + (setq number (or number (string-to-int (wl-match-buffer 1)))) + (setq mark (or mark (elmo-match-buffer 2))) + (save-match-data + (setq new-mark (if (string= mark + wl-summary-read-uncached-mark) + wl-summary-unread-uncached-mark + (if (elmo-use-cache-p folder number) + wl-summary-unread-mark + wl-summary-unread-uncached-mark)))) + ;; server side mark + (unless no-server-update + (elmo-mark-as-unread folder (list number) + msgdb)) + (when visible + (delete-region (match-beginning 2) (match-end 2)) + (insert new-mark)) + (setq mark-alist + (elmo-msgdb-mark-set mark-alist + number + new-mark)) + (elmo-msgdb-set-mark-alist msgdb mark-alist) + (unless no-modeline-update + (setq wl-summary-buffer-unread-count + (+ 1 wl-summary-buffer-unread-count)) + (wl-summary-update-modeline) + (wl-folder-update-unread + folder + (+ wl-summary-buffer-unread-count + wl-summary-buffer-new-count))) + (wl-summary-set-mark-modified) + (if (and visible wl-summary-highlight) + (wl-highlight-summary-current-line)))))) + (set-buffer-modified-p nil)) + +(defun wl-summary-delete (&optional number) + "Mark Delete mark 'D'. +If optional argument NUMBER is specified, mark message specified by NUMBER." + (interactive) + (let* ((buffer-num (wl-summary-message-number)) + (msg-num (or number buffer-num)) + mark) + (catch 'done + (when (null msg-num) + (if (interactive-p) + (message "No message.")) + (throw 'done nil)) + (when (setq mark (wl-summary-get-mark msg-num)) + (when (wl-summary-reserve-temp-mark-p mark) + (if (interactive-p) + (error "Already marked as `%s'" mark)) + (throw 'done nil)) + (wl-summary-unmark msg-num)) + (if (or (interactive-p) + (eq number buffer-num)) + (wl-summary-mark-line "D")) + (setq wl-summary-buffer-delete-list + (cons msg-num wl-summary-buffer-delete-list)) + (if (interactive-p) + (if (eq wl-summary-move-direction-downward nil) + (wl-summary-prev) + (wl-summary-next))) + msg-num))) + +(defun wl-summary-remove-destination () + (save-excursion + (let ((inhibit-read-only t) + (buffer-read-only nil) + (buf (current-buffer)) + sol eol rs re) + (beginning-of-line) + (setq sol (point)) + (end-of-line) + (setq eol (point)) + (setq rs (next-single-property-change sol 'wl-summary-destination + buf eol)) + (setq re (next-single-property-change rs 'wl-summary-destination + buf eol)) + (put-text-property rs re 'wl-summary-destination nil) + (put-text-property rs re 'invisible nil) + (goto-char re) + (delete-char (- eol re))))) + +(defun wl-summary-check-mark (msg mark) + (let ((check-func (cond ((string= mark "o") + 'wl-summary-msg-marked-as-refiled) + ((string= mark "O") + 'wl-summary-msg-marked-as-copied) + ((string= mark "D") + 'wl-summary-msg-marked-as-deleted) + ((string= mark "*") + 'wl-summary-msg-marked-as-target)))) + (if check-func + (funcall check-func msg)))) + +(defun wl-summary-mark-collect (mark &optional begin end) + (save-excursion + (save-restriction + (let (msglist) + (narrow-to-region (or begin (point-min)) + (or end (point-max))) + (goto-char (point-min)) + ;; for thread... + (if (eq wl-summary-buffer-view 'thread) + (progn + (while (not (eobp)) + (let* ((number (wl-summary-message-number)) + (entity (wl-thread-get-entity number)) + result) + ;; opened...only myself is checked. + (if (wl-summary-check-mark number mark) + (wl-append msglist (list number))) + (unless (wl-thread-entity-get-opened entity) + ;; closed...children is also checked. + (if (setq result (wl-thread-get-children-msgs-with-mark + number + mark)) + (wl-append msglist result))) + (forward-line 1))) + (elmo-uniq-list msglist)) + (let* ((case-fold-search nil) + (re (format (concat wl-summary-message-regexp "%s") + (regexp-quote mark)))) + (while (re-search-forward re nil t) + (setq msglist (cons (wl-summary-message-number) msglist))) + (nreverse msglist))))))) + +(defun wl-summary-exec () + (interactive) + (wl-summary-exec-subr (mapcar 'car wl-summary-buffer-refile-list) + (reverse wl-summary-buffer-delete-list) + (mapcar 'car wl-summary-buffer-copy-list))) + +(defun wl-summary-exec-region (beg end) + (interactive "r") + (message "Collecting marks ...") + (save-excursion + (goto-char beg) + (beginning-of-line) + (setq beg (point)) + (goto-char (1- end)) + (forward-line) + (setq end (point)) + (wl-summary-exec-subr (wl-summary-mark-collect "o" beg end) + (wl-summary-mark-collect "D" beg end) + (wl-summary-mark-collect "O" beg end)))) + +(defun wl-summary-exec-subr (msgs dels cpys) + (save-excursion + (let* ((del-fld (wl-summary-get-delete-folder + wl-summary-buffer-folder-name)) + (start (point)) + dst tmp msg msgs2 cpys2 + msg-dst dst-msgs len + refile-failures + copy-failures + succeeds result executed) + (if (not (or msgs dels cpys)) + (message "No marks") + (message "Executing ...") + (setq msgs (append msgs dels)) + (setq msgs2 msgs) + (while dels + (when (not (assq (car dels) wl-summary-buffer-refile-list)) + (wl-append wl-summary-buffer-refile-list + (list (cons (car dels) del-fld))) + (setq wl-summary-buffer-delete-list + (delete (car dels) wl-summary-buffer-delete-list))) + (setq dels (cdr dels))) + (setq len (length msgs2)) + ;; begin refile... + (while msgs + (setq msg (car msgs)) + (setq msgs (cdr msgs)) + (setq msg-dst (assq msg wl-summary-buffer-refile-list)) + (setq dst (cdr msg-dst)) + (if dst + (if (setq tmp (assoc dst dst-msgs)) + (setq dst-msgs (cons (append tmp (list msg)) + (delete tmp dst-msgs))) + (setq dst-msgs (cons (list dst msg) dst-msgs))))) + (setq refile-failures 0) + (goto-char start) ; avoid moving cursor to the bottom line. + (setq executed 0) + (while dst-msgs + ;;(elmo-msgdb-add-msgs-to-seen-list + ;; (car (car dst-msgs)) ;dst-folder + ;; (cdr (car dst-msgs)) ;msgs + ;; wl-summary-buffer-msgdb + ;; (concat wl-summary-important-mark + ;; wl-summary-read-uncached-mark)) + (setq result nil) + (condition-case nil + (setq result (elmo-move-msgs wl-summary-buffer-folder-name + (cdr (car dst-msgs)) + (car (car dst-msgs)) + wl-summary-buffer-msgdb + len executed (cdr dst-msgs) + nil ; no-delete + nil ; same-number + (list wl-summary-unread-cached-mark + wl-summary-unread-uncached-mark + wl-summary-new-mark))) + (error nil)) + (if result ; succeeded. + (progn + ;; update buffer. + (wl-summary-delete-messages-on-buffer + (cdr (car dst-msgs))) + ;; update refile-alist. + (mapcar + (function + (lambda (x) + (setq wl-summary-buffer-refile-list + (delq (assq x wl-summary-buffer-refile-list) + wl-summary-buffer-refile-list)))) + (cdr (car dst-msgs)))) + (setq refile-failures + (+ refile-failures (length (cdr (car dst-msgs)))))) + (setq executed (+ executed (length (cdr (car dst-msgs))))) + (setq dst-msgs (cdr dst-msgs))) + ;; end refile + ;; begin cOpy... + (setq cpys2 cpys) + (setq len (length cpys2)) + (while cpys + (setq msg (car cpys)) + (setq cpys (cdr cpys)) + (setq msg-dst (assq msg wl-summary-buffer-copy-list)) + (setq dst (cdr msg-dst)) + (if dst + (if (setq tmp (assoc dst dst-msgs)) + (setq dst-msgs (cons (append tmp (list msg)) + (delete tmp dst-msgs))) + (setq dst-msgs (cons (list dst msg) dst-msgs))))) + (setq copy-failures 0) + (setq executed 0) + (while dst-msgs + ;;(elmo-msgdb-add-msgs-to-seen-list + ;;(car (car dst-msgs)) ;dst-folder + ;;(cdr (car dst-msgs)) ;msgs + ;;wl-summary-buffer-msgdb + ;;(concat wl-summary-important-mark + ;;wl-summary-read-uncached-mark)) + (setq result nil) + (condition-case nil + (setq result (elmo-move-msgs wl-summary-buffer-folder-name + (cdr (car dst-msgs)) + (car (car dst-msgs)) + wl-summary-buffer-msgdb + len executed + (cdr dst-msgs) + t ; t is no-delete (copy) + nil ; same number + (list + wl-summary-unread-cached-mark + wl-summary-unread-uncached-mark + wl-summary-new-mark))) + (error nil)) + (if result ; succeeded. + (progn + ;; update buffer. + (wl-summary-delete-copy-marks-on-buffer (cdr (car dst-msgs))) + ;; update copy-alist + (mapcar + (function + (lambda (x) + (setq wl-summary-buffer-copy-list + (delq (assq x wl-summary-buffer-copy-list) + wl-summary-buffer-copy-list)))) + (cdr (car dst-msgs)))) + (setq copy-failures + (+ copy-failures (length (cdr (car dst-msgs)))))) + (setq executed (+ executed (length (cdr (car dst-msgs))))) + (setq dst-msgs (cdr dst-msgs))) + ;; end cOpy + (wl-summary-folder-info-update) + (wl-summary-set-message-modified) + (wl-summary-set-mark-modified) + (run-hooks 'wl-summary-exec-hook) + (set-buffer-modified-p nil) + (message (concat "Executing ... done" + (if (> refile-failures 0) + (format " (%d refiling failed)" refile-failures) + "") + (if (> copy-failures 0) + (format " (%d copying failed)" copy-failures) + "") + ".")))))) + +(defun wl-summary-read-folder (default &optional purpose ignore-error + no-create init) + (let ((fld (completing-read + (format "Folder name %s(%s): " (or purpose "") + default) + (or wl-folder-completion-func + (if (memq 'read-folder wl-use-folder-petname) + (wl-folder-get-entity-with-petname) + wl-folder-entity-hashtb)) + nil nil (or init wl-default-spec) + 'wl-read-folder-hist))) + (setq fld (elmo-string (wl-folder-get-realname fld))) + (if (string-match "\n" fld) + (error "Not supported folder name: %s" fld)) + (if (or (string= fld wl-default-spec) + (string= fld "")) + (setq fld default)) + (unless no-create + (wl-folder-confirm-existence fld ignore-error)) + fld)) + +(defun wl-summary-print-destination (msg-num folder) + "Print refile destination on line." + (wl-summary-remove-destination) + (let ((inhibit-read-only t) + (buffer-read-only nil) + len rs re c) + (setq len (string-width folder)) + (if (< len 1) () + (end-of-line) + (setq re (point)) + (setq c 0) + (while (< c len) + (forward-char -1) + (setq c (+ c (char-width (following-char))))) + (setq rs (point)) + (put-text-property rs re 'invisible t) + (put-text-property rs re 'wl-summary-destination t) + (goto-char re) + (wl-highlight-refile-destination-string folder) + (insert folder) + (set-buffer-modified-p nil)))) + +;; override. +(when wl-on-nemacs + (defun wl-summary-print-destination (msg-num &optional folder)) + (defun wl-summary-remove-destination ())) + +(defsubst wl-summary-get-mark (number) + "Returns a temporal mark of message specified by NUMBER." + (or (and (memq number wl-summary-buffer-delete-list) "D") + (and (assq number wl-summary-buffer-copy-list) "O") + (and (assq number wl-summary-buffer-refile-list) "o") + (and (assq number wl-summary-buffer-target-mark-list) "*"))) + +(defsubst wl-summary-reserve-temp-mark-p (mark) + "Returns t if temporal MARK should be reserved." + (member mark wl-summary-reserve-mark-list)) + +(defun wl-summary-refile (&optional dst number) + "Put refile mark on current line message. +If optional argument DST is specified, put mark without asking +destination folder. +If optional argument NUMBER is specified, mark message specified by NUMBER. + +If folder is read-only, message should be copied. +See `wl-refile-policy-alist' for more details." + (interactive) + (let ((policy (wl-get-assoc-list-value wl-refile-policy-alist + wl-summary-buffer-folder-name))) + (cond ((eq policy 'copy) + (if (interactive-p) + (call-interactively 'wl-summary-copy) + (wl-summary-copy dst number))) + (t + (wl-summary-refile-subr "refile" (interactive-p) dst number))))) + +(defun wl-summary-copy (&optional dst number) + "Put refile mark on current line message. +If optional argument DST is specified, put mark without asking +destination folder. +If optional argument NUMBER is specified, mark message specified by NUMBER." + (interactive) + (wl-summary-refile-subr "copy" (interactive-p) dst number)) + +(defun wl-summary-refile-subr (copy-or-refile interactive &optional dst number) + (interactive) + (let* ((buffer-num (wl-summary-message-number)) + (msg-num (or number buffer-num)) + (msgid (and msg-num + (cdr (assq msg-num + (elmo-msgdb-get-number-alist + wl-summary-buffer-msgdb))))) + (entity (and msg-num + (elmo-msgdb-overview-get-entity-by-number + (elmo-msgdb-get-overview wl-summary-buffer-msgdb) + msg-num))) + (variable + (intern (format "wl-summary-buffer-%s-list" copy-or-refile))) + folder mark already tmp-folder) + (catch 'done + (when (null entity) + ;; msgdb is empty? + (if interactive + (message "Cannot refile.")) + (throw 'done nil)) + (when (null msg-num) + (if interactive + (message "No message.")) + (throw 'done nil)) + (when (setq mark (wl-summary-get-mark msg-num)) + (when (wl-summary-reserve-temp-mark-p mark) + (if interactive + (error "Already marked as `%s'" mark)) + (throw 'done nil))) + (setq folder (and msg-num + (or dst (wl-summary-read-folder + (or (wl-refile-guess entity) wl-trash-folder) + (format "for %s" copy-or-refile))))) + ;; Cache folder hack by okada@opaopa.org + (if (and (eq (car (elmo-folder-get-spec folder)) 'cache) + (not (string= folder + (setq tmp-folder + (concat "'cache/" + (elmo-cache-get-path-subr + (elmo-msgid-to-cache msgid))))))) + (progn + (setq folder tmp-folder) + (message "Force refile to %s." folder))) + (if (string= folder wl-summary-buffer-folder-name) + (error "Same folder")) + (if (and + (not (elmo-folder-plugged-p folder)) + (or (null msgid) + (not (elmo-cache-exists-p msgid)))) + (error "Unplugged (no cache or msgid)")) + (if (or (string= folder wl-queue-folder) + (string= folder wl-draft-folder)) + (error "Don't %s messages to %s" copy-or-refile folder)) + ;; learn for refile. + (if (string= "refile" copy-or-refile) + (wl-refile-learn entity folder)) + (wl-summary-unmark msg-num) + (set variable (append + (symbol-value variable) + (list (cons msg-num folder)))) + (when (or interactive + (eq number buffer-num)) + (wl-summary-mark-line (if (string= "refile" copy-or-refile) + "o" "O")) + ;; print refile destination + (wl-summary-print-destination msg-num folder)) + (if interactive + (if (eq wl-summary-move-direction-downward nil) + (wl-summary-prev) + (wl-summary-next))) + (run-hooks (intern (format "wl-summary-%s-hook" copy-or-refile))) + (setq wl-summary-buffer-prev-refile-destination folder) + msg-num))) + +(defun wl-summary-refile-prev-destination () + "Refile message to previously refiled destination" + (interactive) + (wl-summary-refile wl-summary-buffer-prev-refile-destination + (wl-summary-message-number)) + (if (eq wl-summary-move-direction-downward nil) + (wl-summary-prev) + (wl-summary-next))) + +(defun wl-summary-copy-prev-destination () + "Refile message to previously refiled destination" + (interactive) + (wl-summary-copy wl-summary-buffer-prev-copy-destination + (wl-summary-message-number)) + (if (eq wl-summary-move-direction-downward nil) + (wl-summary-prev) + (wl-summary-next))) + +(defsubst wl-summary-no-auto-refile-message-p (msg mark-alist) + (member (cadr (assq msg mark-alist)) wl-summary-auto-refile-skip-marks)) + +(defun wl-summary-auto-refile-check-refile-rule-alist () + (when wl-refile-rule-alist + (message "Checking destination folders...") + (let ((ralist wl-refile-rule-alist) + pairs dsts) + (while ralist + (setq pairs (cdr (car ralist))) + (while pairs + (if (not (member (cdr (car pairs)) dsts)) + (setq dsts (cons (cdr (car pairs)) dsts))) + (setq pairs (cdr pairs))) + (setq ralist (cdr ralist))) + (mapcar + 'wl-folder-confirm-existence + dsts)) + (message "Checking destination folders...done."))) + +(defun wl-summary-auto-refile (&optional open-all) + "Set refile mark automatically according to wl-refile-guess-by-rule." + (interactive "P") + (wl-summary-auto-refile-check-refile-rule-alist) + (message "Marking...") + (save-excursion + (if (and (eq wl-summary-buffer-view 'thread) + open-all) + (wl-thread-open-all)) + (let* ((spec wl-summary-buffer-folder-name) + (overview (elmo-msgdb-get-overview + wl-summary-buffer-msgdb)) + (mark-alist (elmo-msgdb-get-mark-alist + wl-summary-buffer-msgdb)) + (count 0) + number dst thr-entity) + (goto-line 1) + (while (not (eobp)) + (setq number (wl-summary-message-number)) + (when (and (not (wl-summary-no-auto-refile-message-p number + mark-alist)) + (setq dst + (wl-refile-guess-by-rule + (elmo-msgdb-overview-get-entity-by-number + overview number))) + (not (equal dst spec))) + ;(wl-folder-confirm-existence dst) + (if (wl-summary-refile dst number) + (incf count)) + (message "Marking...%d message(s)." count)) + (if (eq wl-summary-buffer-view 'thread) + ;; process invisible children. + (if (not (wl-thread-entity-get-opened + (setq thr-entity (wl-thread-get-entity number)))) + (mapcar + (function + (lambda (x) + (when (and (setq dst + (wl-refile-guess-by-rule + (elmo-msgdb-overview-get-entity-by-number + overview x))) + (not (equal dst spec))) + (if (wl-summary-refile dst x) + (incf count)) + (message "Marking...%d message(s)." count)))) + (elmo-delete-if + (function (lambda (x) + (wl-summary-no-auto-refile-message-p + x + mark-alist))) + (wl-thread-entity-get-descendant thr-entity))))) + (forward-line)) + (if (eq count 0) + (message "No message was marked.") + (message "Marked %d message(s)." count))))) + +(defun wl-summary-unmark (&optional number) + "Unmark marks (temporary, refile, copy, delete)of current line. +If optional argument NUMBER is specified, unmark message specified by NUMBER." + (interactive) + (save-excursion + (beginning-of-line) + (let ((inhibit-read-only t) + (buffer-read-only nil) + visible + msg-num + cur-mark + score-mark) + (if number + (setq visible (wl-summary-jump-to-msg number)) + (setq visible t)) + ;; Delete mark on buffer. + (when (and visible + (looking-at "^ *\\([0-9]+\\)\\([^0-9]\\)")) + (goto-char (match-end 2)) + (or number + (setq number (string-to-int (wl-match-buffer 1)))) + (setq cur-mark (wl-match-buffer 2)) + (if (string= cur-mark " ") + () + (delete-region (match-beginning 2) (match-end 2)) + (if (setq score-mark (wl-summary-get-score-mark number)) + (insert score-mark) + (insert " "))) + (if (or (string= cur-mark "o") + (string= cur-mark "O")) + (wl-summary-remove-destination)) + (if wl-summary-highlight + (wl-highlight-summary-current-line nil nil score-mark)) + (set-buffer-modified-p nil)) + ;; Remove from temporary mark structure. + (and number + (wl-summary-delete-mark number))))) + +(defun wl-summary-msg-marked-as-target (msg) + (if (memq msg wl-summary-buffer-target-mark-list) + t)) + +(defun wl-summary-msg-marked-as-copied (msg) + (assq msg wl-summary-buffer-copy-list)) + +(defun wl-summary-msg-marked-as-deleted (msg) + (if (memq msg wl-summary-buffer-delete-list) + t)) + +(defun wl-summary-msg-marked-as-refiled (msg) + (assq msg wl-summary-buffer-refile-list)) + +(defun wl-summary-target-mark (&optional number) + "Put target mark '*' on current message. +If optional argument NUMBER is specified, mark message specified by NUMBER." + (interactive) + (let* ((buffer-num (wl-summary-message-number)) + (msg-num (or number buffer-num)) + mark) + (catch 'done + (when (null msg-num) + (if (interactive-p) + (message "No message.")) + (throw 'done nil)) + (when (setq mark (wl-summary-get-mark msg-num)) + (when (wl-summary-reserve-temp-mark-p mark) + (if (interactive-p) + (error "Already marked as `%s'" mark)) + (throw 'done nil)) + (wl-summary-unmark msg-num)) + (if (or (interactive-p) + (eq number buffer-num)) + (wl-summary-mark-line "*")) + (setq wl-summary-buffer-target-mark-list + (cons msg-num wl-summary-buffer-target-mark-list)) + (if (interactive-p) + (if (eq wl-summary-move-direction-downward nil) + (wl-summary-prev) + (wl-summary-next))) + msg-num))) + + +(defun wl-summary-refile-region (beg end) + "Put copy mark on messages in the region specified by BEG and END." + (interactive "r") + (wl-summary-refile-region-subr "refile" beg end)) + +(defun wl-summary-copy-region (beg end) + "Put copy mark on messages in the region specified by BEG and END." + (interactive "r") + (wl-summary-refile-region-subr "copy" beg end)) + +(defun wl-summary-refile-region-subr (copy-or-refile beg end) + (save-excursion + (save-restriction + (goto-char beg) + ;; guess by first msg + (let* ((msgid (cdr (assq (wl-summary-message-number) + (elmo-msgdb-get-number-alist + wl-summary-buffer-msgdb)))) + (function (intern (format "wl-summary-%s" copy-or-refile))) + (entity (assoc msgid (elmo-msgdb-get-overview + wl-summary-buffer-msgdb))) + folder) + (if entity + (setq folder (wl-summary-read-folder (wl-refile-guess entity) + (format "for %s" + copy-or-refile)))) + (narrow-to-region beg end) + (if (eq wl-summary-buffer-view 'thread) + (progn + (while (not (eobp)) + (let* ((number (wl-summary-message-number)) + (entity (wl-thread-get-entity number)) + children) + (if (wl-thread-entity-get-opened entity) + ;; opened...refile line. + (funcall function folder number) + ;; closed + (mapcar + (function + (lambda (x) + (funcall function folder x))) + (wl-thread-get-children-msgs number))) + (forward-line 1)))) + (while (not (eobp)) + (funcall function folder (wl-summary-message-number)) + (forward-line 1))))))) + +(defun wl-summary-unmark-region (beg end) + (interactive "r") + (save-excursion + (save-restriction + (narrow-to-region beg end) + (goto-char (point-min)) + (if (eq wl-summary-buffer-view 'thread) + (progn + (while (not (eobp)) + (let* ((number (wl-summary-message-number)) + (entity (wl-thread-get-entity number))) + (if (wl-thread-entity-get-opened entity) + ;; opened...unmark line. + (wl-summary-unmark) + ;; closed + (mapcar + 'wl-summary-unmark + (wl-thread-get-children-msgs number)))) + (forward-line 1))) + (while (not (eobp)) + (wl-summary-unmark) + (forward-line 1)))))) + +(defun wl-summary-mark-region-subr (function beg end) + (save-excursion + (save-restriction + (narrow-to-region beg end) + (goto-char (point-min)) + (if (eq wl-summary-buffer-view 'thread) + (progn + (while (not (eobp)) + (let* ((number (wl-summary-message-number)) + (entity (wl-thread-get-entity number)) + (wl-summary-move-direction-downward t)) + (if (wl-thread-entity-get-opened entity) + ;; opened...delete line. + (funcall function number) + ;; closed + (mapcar + function + (wl-thread-get-children-msgs number))) + (forward-line 1)))) + (while (not (eobp)) + (funcall function (wl-summary-message-number)) + (forward-line 1)))))) + +(defun wl-summary-delete-region (beg end) + (interactive "r") + (wl-summary-mark-region-subr 'wl-summary-delete beg end)) + +(defun wl-summary-target-mark-region (beg end) + (interactive "r") + (wl-summary-mark-region-subr 'wl-summary-target-mark beg end)) + +(defun wl-summary-target-mark-all () + (interactive) + (wl-summary-target-mark-region (point-min) (point-max)) + (setq wl-summary-buffer-target-mark-list + (mapcar 'car + (elmo-msgdb-get-number-alist wl-summary-buffer-msgdb)))) + +(defun wl-summary-delete-all-mark (mark) + (goto-char (point-min)) + (let ((case-fold-search nil)) + (while (re-search-forward (format "^ *[0-9]+%s" + (regexp-quote mark)) nil t) + (wl-summary-unmark)) + (cond ((string= mark "*") + (setq wl-summary-buffer-target-mark-list nil)) + ((string= mark "D") + (setq wl-summary-buffer-delete-list nil)) + ((string= mark "O") + (setq wl-summary-buffer-copy-list nil)) + ((string= mark "o") + (setq wl-summary-buffer-refile-list nil))))) + +(defun wl-summary-unmark-all () + "Unmark all according to what you input." + (interactive) + (let ((unmarks (string-to-char-list (read-from-minibuffer "Unmark: "))) + cur-mark) + (save-excursion + (while unmarks + (setq cur-mark (char-to-string (car unmarks))) + (wl-summary-delete-all-mark cur-mark) + (setq unmarks (cdr unmarks)))))) + +(defun wl-summary-target-mark-thread () + (interactive) + (let (beg end) + (end-of-line) + (wl-summary-goto-top-of-current-thread) + (wl-thread-force-open) + (setq beg (point)) + (end-of-line) + (wl-summary-goto-bottom-of-current-thread) +; (forward-line -1) + (beginning-of-line) + (setq end (point)) + (wl-summary-target-mark-region beg end))) + +(defun wl-summary-target-mark-msgs (msgs) + (while msgs + (if (eq wl-summary-buffer-view 'thread) + (wl-thread-jump-to-msg (car msgs)) + (wl-summary-jump-to-msg (car msgs))) + (wl-summary-target-mark (wl-summary-message-number)) + (setq msgs (cdr msgs)))) + +(defun wl-summary-pick (&optional from-list delete-marks) + (interactive) + (save-excursion + (let* ((completion-ignore-case t) + (field (completing-read + (format "Field name (%s): " wl-summary-pick-field-default) + (mapcar 'list + (append '("From" "Subject" "Date" + "To" "Cc" "Body" "Since" "Before") + elmo-msgdb-extra-fields)))) + (field (if (string= field "") + (setq field wl-summary-pick-field-default) + field)) + (value (if (string-match field "Since\\|Before") + (completing-read "Value: " + (mapcar (function + (lambda (x) + (list (format "%s" (car x))))) + elmo-date-descriptions)) + (read-from-minibuffer "Value: "))) + (overview (elmo-msgdb-get-overview wl-summary-buffer-msgdb)) + (number-alist (elmo-msgdb-get-number-alist wl-summary-buffer-msgdb)) + (elmo-search-mime-charset wl-search-mime-charset) + server-side-search + result get-func sum) + (if delete-marks + (let ((mlist wl-summary-buffer-target-mark-list)) + (while mlist + (when (wl-summary-jump-to-msg (car mlist)) + (wl-summary-unmark)) + (setq mlist (cdr mlist))) + (setq wl-summary-buffer-target-mark-list nil))) + (setq field (downcase field)) + (cond + ((string-match field "from") + (setq get-func 'elmo-msgdb-overview-entity-get-from)) + ((string-match field "subject") + (setq get-func 'elmo-msgdb-overview-entity-get-subject)) + ((string-match field "date") + (setq get-func 'elmo-msgdb-overview-entity-get-date)) + ((string-match field "to") + (setq get-func 'elmo-msgdb-overview-entity-get-to)) + ((string-match field "cc") + (setq get-func 'elmo-msgdb-overview-entity-get-cc)) + ((string-match field "since") + (setq server-side-search (vector 'date "since" value))) + ((string-match field "before") + (setq server-side-search (vector 'date "before" value))) + ((string-match field "body") + (setq server-side-search (vector 'match "body" value))) + ((member field elmo-msgdb-extra-fields) + (setq get-func + (lambda (entity) + (elmo-msgdb-overview-entity-get-extra-field entity field)))) + (t + (error "Pick by %s is not supported" field))) + (unwind-protect + (if server-side-search + (progn + (message "Searching...") + (let ((elmo-mime-charset wl-summary-buffer-mime-charset)) + (setq result (elmo-search wl-summary-buffer-folder-name + (list server-side-search)))) + (if from-list + (setq result (elmo-list-filter from-list result))) + (message "%d message(s) are picked." (length result))) + (setq sum 0) + (message "Searching...") + (while overview + (when (and (string-match value + (or + (funcall get-func (car overview)) + "")) + (or (not from-list) + (memq + (elmo-msgdb-overview-entity-get-number + (car overview)) from-list))) + (setq result + (append result + (list + (elmo-msgdb-overview-entity-get-number + (car overview))))) + (message "Picked %d message(s)." (setq sum (+ sum 1)))) + (setq overview (cdr overview))) + (message "%d message(s) are picked." sum)) + (if (null result) + (message "No message was picked.") + (wl-summary-target-mark-msgs result)))))) + +(defun wl-summary-unvirtual () + "Exit from current virtual folder." + (interactive) + (if (eq 'filter + (elmo-folder-get-type wl-summary-buffer-folder-name)) + (wl-summary-goto-folder-subr (nth 2 (elmo-folder-get-spec + wl-summary-buffer-folder-name)) + 'update nil nil t) + (error "This folder is not filtered"))) + +(defun wl-summary-virtual (&optional arg) + "Goto virtual folder." + (interactive "P") + (if arg + (wl-summary-unvirtual) + (let* ((completion-ignore-case t) + (field (completing-read (format "Field name (%s): " + wl-summary-pick-field-default) + '(("From" . "From") + ("Subject" . "Subject") + ("To" . "To") + ("Cc" . "Cc") + ("Body" . "Body") + ("Since" . "Since") + ("Before" . "Before")))) + (value (read-from-minibuffer "Value: "))) + (if (string= field "") + (setq field wl-summary-pick-field-default)) + (wl-summary-goto-folder-subr (concat "/" (downcase field) "=" value "/" + wl-summary-buffer-folder-name) + 'update nil nil t)))) + +(defun wl-summary-delete-all-temp-marks () + (interactive) + (save-excursion + (goto-char (point-min)) + (message "Unmarking...") + (while (not (eobp)) + (wl-summary-unmark) + (forward-line)) + (message "Unmarking...done.") + (setq wl-summary-buffer-target-mark-list nil) + (setq wl-summary-buffer-delete-list nil) + (setq wl-summary-buffer-refile-list nil) + (setq wl-summary-buffer-copy-list nil))) + +(defun wl-summary-delete-mark (number) + "Delete temporary mark of the message specified by NUMBER." + (cond + ((memq number wl-summary-buffer-target-mark-list) + (setq wl-summary-buffer-target-mark-list + (delq number wl-summary-buffer-target-mark-list))) + ((memq number wl-summary-buffer-delete-list) + (setq wl-summary-buffer-delete-list + (delq number wl-summary-buffer-delete-list))) + (t + (let (pair) + (cond + ((setq pair (assq number wl-summary-buffer-copy-list)) + (setq wl-summary-buffer-copy-list + (delq pair wl-summary-buffer-copy-list))) + ((setq pair (assq number wl-summary-buffer-refile-list)) + (setq wl-summary-buffer-refile-list + (delq pair wl-summary-buffer-refile-list)))))))) + +(defun wl-summary-mark-line (mark) + "Put MARK on current line. Returns message number." + (save-excursion + (beginning-of-line) + (let ((inhibit-read-only t) + (buffer-read-only nil) + msg-num + cur-mark) + (when (looking-at "^ *\\([0-9]+\\)\\([^0-9]\\)") + (setq msg-num (string-to-int (wl-match-buffer 1))) + (setq cur-mark (wl-match-buffer 2)) + (goto-char (match-end 1)) + (delete-region (match-beginning 2) (match-end 2)) + ;(wl-summary-delete-mark msg-num) + (insert mark) + (if wl-summary-highlight + (wl-highlight-summary-current-line nil nil t)) + (set-buffer-modified-p nil) + msg-num)))) + +(defun wl-summary-target-mark-delete () + (interactive) + (save-excursion + (goto-char (point-min)) + (let ((regexp (concat "^" wl-summary-buffer-number-regexp "\\(\\*\\)")) + number mlist) + (while (re-search-forward regexp nil t) + (let (wl-summary-buffer-disp-msg) + (when (setq number (wl-summary-message-number)) + (wl-summary-delete number) + (setq wl-summary-buffer-target-mark-list + (delq number wl-summary-buffer-target-mark-list))))) + (setq mlist wl-summary-buffer-target-mark-list) + (while mlist + (wl-append wl-summary-buffer-delete-list (list (car mlist))) + (setq wl-summary-buffer-target-mark-list + (delq (car mlist) wl-summary-buffer-target-mark-list)) + (setq mlist (cdr mlist)))))) + +(defun wl-summary-target-mark-prefetch () + (interactive) + (save-excursion + (let* ((mlist (nreverse wl-summary-buffer-target-mark-list)) + (inhibit-read-only t) + (buffer-read-only nil) + (count 0) + (length (length mlist)) + (pos (point)) + skipped + new-mark) + (while mlist + (setq new-mark (wl-summary-prefetch-msg (car mlist))) + (if new-mark + (progn + (message "Prefetching... %d/%d message(s)" + (setq count (+ 1 count)) length) + (when (wl-summary-jump-to-msg (car mlist)) + (wl-summary-unmark) + (when new-mark + (when (looking-at "^ *[0-9]+[^0-9]\\([^0-9]\\)") + (delete-region (match-beginning 1) (match-end 1))) + (goto-char (match-beginning 1)) + (insert new-mark) + (if wl-summary-highlight + (wl-highlight-summary-current-line)) + (save-excursion + (goto-char pos) + (sit-for 0))))) + (setq skipped (cons (car mlist) skipped))) + (setq mlist (cdr mlist))) + (setq wl-summary-buffer-target-mark-list skipped) + (message "Prefetching... %d/%d message(s)." count length) + (set-buffer-modified-p nil)))) + +(defun wl-summary-target-mark-refile-subr (copy-or-refile) + (let ((variable + (intern (format "wl-summary-buffer-%s-list" copy-or-refile))) + (function + (intern (format "wl-summary-%s" copy-or-refile))) + regexp number msgid entity folder mlist) + (save-excursion + (goto-char (point-min)) + (setq regexp (concat "^" wl-summary-buffer-number-regexp "\\(\\*\\)")) + ;; guess by first mark + (when (re-search-forward regexp nil t) + (setq msgid (cdr (assq (setq number (wl-summary-message-number)) + (elmo-msgdb-get-number-alist + wl-summary-buffer-msgdb))) + entity (assoc msgid + (elmo-msgdb-get-overview + wl-summary-buffer-msgdb))) + (if (null entity) + (error "Cannot %s" copy-or-refile)) + (funcall function + (setq folder (wl-summary-read-folder + (wl-refile-guess entity) + (format "for %s" copy-or-refile))) + number) + (if number + (setq wl-summary-buffer-target-mark-list + (delq number wl-summary-buffer-target-mark-list))) + (while (re-search-forward regexp nil t) + (let (wl-summary-buffer-disp-msg) + (when (setq number (wl-summary-message-number)) + (funcall function folder number) + (setq wl-summary-buffer-target-mark-list + (delq number wl-summary-buffer-target-mark-list))))) + ;; process invisible messages. + (setq mlist wl-summary-buffer-target-mark-list) + (while mlist + (set variable + (append (symbol-value variable) + (list (cons (car mlist) folder)))) + (setq wl-summary-buffer-target-mark-list + (delq (car mlist) wl-summary-buffer-target-mark-list)) + (setq mlist (cdr mlist))))))) + +(defun wl-summary-target-mark-copy () + (interactive) + (wl-summary-target-mark-refile-subr "copy")) + +(defun wl-summary-target-mark-refile () + (interactive) + (wl-summary-target-mark-refile-subr "refile")) + +(defun wl-summary-target-mark-mark-as-read () + (interactive) + (save-excursion + (goto-char (point-min)) + (let ((regexp (concat "^" wl-summary-buffer-number-regexp "\\(\\*\\)")) + (inhibit-read-only t) + (buffer-read-only nil) + number mlist) + (while (re-search-forward regexp nil t) + (let (wl-summary-buffer-disp-msg) + ;; delete target-mark from buffer. + (delete-region (match-beginning 1) (match-end 1)) + (insert " ") + (setq number (wl-summary-mark-as-read t)) + (if wl-summary-highlight + (wl-highlight-summary-current-line)) + (if number + (setq wl-summary-buffer-target-mark-list + (delq number wl-summary-buffer-target-mark-list))))) + (setq mlist wl-summary-buffer-target-mark-list) + (while mlist + (wl-thread-msg-mark-as-read (car mlist)) + (setq wl-summary-buffer-target-mark-list + (delq (car mlist) wl-summary-buffer-target-mark-list)) + (setq mlist (cdr mlist))) + (wl-summary-count-unread + (elmo-msgdb-get-mark-alist wl-summary-buffer-msgdb)) + (wl-summary-update-modeline)))) + +(defun wl-summary-target-mark-mark-as-unread () + (interactive) + (save-excursion + (goto-char (point-min)) + (let ((regexp (concat "^" wl-summary-buffer-number-regexp "\\(\\*\\)")) + (inhibit-read-only t) + (buffer-read-only nil) + number mlist) + (while (re-search-forward regexp nil t) + (let (wl-summary-buffer-disp-msg) + ;; delete target-mark from buffer. + (delete-region (match-beginning 1) (match-end 1)) + (insert " ") + (setq number (wl-summary-mark-as-unread)) + (if wl-summary-highlight + (wl-highlight-summary-current-line)) + (if number + (setq wl-summary-buffer-target-mark-list + (delq number wl-summary-buffer-target-mark-list))))) + (setq mlist wl-summary-buffer-target-mark-list) + (while mlist + (wl-summary-mark-as-unread (car mlist)) + (wl-thread-msg-mark-as-unread (car mlist)) + (setq wl-summary-buffer-target-mark-list + (delq (car mlist) wl-summary-buffer-target-mark-list)) + (setq mlist (cdr mlist))) + (wl-summary-count-unread + (elmo-msgdb-get-mark-alist wl-summary-buffer-msgdb)) + (wl-summary-update-modeline)))) + +(defun wl-summary-target-mark-mark-as-important () + (interactive) + (save-excursion + (goto-char (point-min)) + (let ((regexp (concat "^" wl-summary-buffer-number-regexp "\\(\\*\\)")) + (inhibit-read-only t) + (buffer-read-only nil) + number mlist) + (while (re-search-forward regexp nil t) + (let (wl-summary-buffer-disp-msg) + ;; delete target-mark from buffer. + (delete-region (match-beginning 1) (match-end 1)) + (insert " ") + (setq number (wl-summary-mark-as-important)) + (if wl-summary-highlight + (wl-highlight-summary-current-line)) + (if number + (setq wl-summary-buffer-target-mark-list + (delq number wl-summary-buffer-target-mark-list))))) + (setq mlist wl-summary-buffer-target-mark-list) + (while mlist + (wl-summary-mark-as-important (car mlist)) + (wl-thread-msg-mark-as-important (car mlist)) + (setq wl-summary-buffer-target-mark-list + (delq (car mlist) wl-summary-buffer-target-mark-list)) + (setq mlist (cdr mlist))) + (wl-summary-count-unread + (elmo-msgdb-get-mark-alist wl-summary-buffer-msgdb)) + (wl-summary-update-modeline)))) + +(defun wl-summary-target-mark-save () + (interactive) + (save-excursion + (goto-char (point-min)) + (let ((wl-save-dir + (wl-read-directory-name "Save to directory: " wl-tmp-dir)) + (regexp (concat "^" wl-summary-buffer-number-regexp "\\(\\*\\)")) + number mlist) + (if (null (file-exists-p wl-save-dir)) + (make-directory wl-save-dir)) + (while (re-search-forward regexp nil t) + (let (wl-summary-buffer-disp-msg) + (setq number (wl-summary-save t wl-save-dir)) + (wl-summary-unmark) + (if number + (setq wl-summary-buffer-target-mark-list + (delq number wl-summary-buffer-target-mark-list)))))))) + +(defun wl-summary-target-mark-pick () + (interactive) + (wl-summary-pick wl-summary-buffer-target-mark-list 'delete)) + +(defun wl-summary-mark-as-read (&optional notcrosses + leave-server-side-mark-untouched + displayed + number + no-cache) + (interactive) + (save-excursion + (let* (eol + (inhibit-read-only t) + (buffer-read-only nil) + (folder wl-summary-buffer-folder-name) + (msgdb wl-summary-buffer-msgdb) + (mark-alist (elmo-msgdb-get-mark-alist msgdb)) + ;;(number-alist (elmo-msgdb-get-number-alist msgdb)) + (case-fold-search nil) + mark unread visible uncached new-mark) + (if number + (progn + (setq visible (wl-summary-jump-to-msg number)) + (setq mark (cadr (assq number mark-alist)))) + (setq visible t)) + (beginning-of-line) + (if (or (not visible) + (looking-at + (format "^ *\\([0-9]+\\)[^0-9]\\(%s\\|%s\\|%s\\|%s\\).*$" + (regexp-quote wl-summary-read-uncached-mark) + (regexp-quote wl-summary-unread-uncached-mark) + (regexp-quote wl-summary-unread-cached-mark) + (regexp-quote wl-summary-new-mark)))) + (progn + (setq mark (or mark (wl-match-buffer 2))) + (when mark + (cond + ((string= mark wl-summary-new-mark) ; N + (setq wl-summary-buffer-new-count + (- wl-summary-buffer-new-count 1)) + (setq uncached t) + (setq unread t)) + ((string= mark wl-summary-unread-uncached-mark) ; U + (setq wl-summary-buffer-unread-count + (- wl-summary-buffer-unread-count 1)) + (setq uncached t) + (setq unread t)) + ((string= mark wl-summary-unread-cached-mark) ; ! + (setq wl-summary-buffer-unread-count + (- wl-summary-buffer-unread-count 1)) + (setq unread t)) + (t + ;; no need to mark server. + (setq leave-server-side-mark-untouched t))) + (wl-summary-update-modeline) + (wl-folder-update-unread + folder + (+ wl-summary-buffer-unread-count + wl-summary-buffer-new-count))) + (setq number (or number (string-to-int (wl-match-buffer 1)))) + ;; set server side mark... + (setq new-mark (if (and uncached no-cache) + wl-summary-read-uncached-mark + nil)) + (if (not leave-server-side-mark-untouched) + (elmo-mark-as-read folder + (list number) msgdb)) + (when visible + (goto-char (match-end 2)) + (delete-region (match-beginning 2) (match-end 2)) + (insert (or new-mark " "))) + (setq mark-alist + (elmo-msgdb-mark-set mark-alist number new-mark)) + (elmo-msgdb-set-mark-alist msgdb mark-alist) + (wl-summary-set-mark-modified) + (if (and visible wl-summary-highlight) + (wl-highlight-summary-current-line nil nil t)) + (if (not notcrosses) + (wl-summary-set-crosspost nil (and wl-summary-buffer-disp-msg + (interactive-p)))))) + (set-buffer-modified-p nil) + (if unread + (run-hooks 'wl-summary-unread-message-hook)) + number ;return value + ))) + +(defun wl-summary-mark-as-important (&optional number + mark + no-server-update) + (interactive) + (if (eq (elmo-folder-get-type wl-summary-buffer-folder-name) + 'internal) + (error "Cannot process mark in this folder")) + (save-excursion + (let* (eol + (inhibit-read-only t) + (buffer-read-only nil) + (folder wl-summary-buffer-folder-name) + (msgdb wl-summary-buffer-msgdb) + (mark-alist (elmo-msgdb-get-mark-alist msgdb)) + (number-alist (elmo-msgdb-get-number-alist msgdb)) + message-id visible) + (if number + (progn + (setq visible (wl-summary-jump-to-msg number)) + (setq mark (or mark (cadr (assq number mark-alist))))) + (setq visible t)) + (end-of-line) + (setq eol (point)) + (if visible + (re-search-backward (concat "^" wl-summary-buffer-number-regexp + "..../..") nil t)) ; set cursor line + (beginning-of-line) + (if (re-search-forward "^ *\\([0-9]+\\)[^0-9]\\([^0-9]\\)" eol t) + (progn + (setq number (or number (string-to-int (wl-match-buffer 1)))) + (setq mark (or mark (wl-match-buffer 2))) + (setq message-id (cdr (assq number number-alist))) + (if (string= mark wl-summary-important-mark) + (progn + ;; server side mark + (unless no-server-update + (elmo-unmark-important folder (list number) msgdb) + (elmo-msgdb-global-mark-delete message-id)) + (when visible + (delete-region (match-beginning 2) (match-end 2)) + (insert " ")) + (setq mark-alist + (elmo-msgdb-mark-set mark-alist + number + nil))) + ;; server side mark + (unless no-server-update + (elmo-mark-as-important folder (list number) msgdb)) + (when visible + (delete-region (match-beginning 2) (match-end 2)) + (insert wl-summary-important-mark)) + (setq mark-alist + (elmo-msgdb-mark-set mark-alist + (string-to-int (wl-match-buffer 1)) + wl-summary-important-mark)) + ;; Force cache message!! + (save-match-data + (unless (elmo-cache-exists-p message-id) + (elmo-force-cache-msg folder number message-id + (elmo-msgdb-get-location msgdb)))) + (unless no-server-update + (elmo-msgdb-global-mark-set message-id + wl-summary-important-mark))) + (elmo-msgdb-set-mark-alist msgdb mark-alist) + (wl-summary-set-mark-modified))) + (if (and visible wl-summary-highlight) + (wl-highlight-summary-current-line nil nil t)))) + (set-buffer-modified-p nil) + number) + +(defsubst wl-summary-format-date (date-string) + (condition-case nil + (let ((datevec (timezone-fix-time date-string nil + wl-summary-fix-timezone))) + (format "%02d/%02d(%s)%02d:%02d" + (aref datevec 1) + (aref datevec 2) + (elmo-date-get-week (aref datevec 0) + (aref datevec 1) + (aref datevec 2)) + (aref datevec 3) + (aref datevec 4))) + (error "??/??(??)??:??"))) + +(defun wl-summary-overview-create-summary-line (msg + entity + parent-entity + depth + mark-alist + &optional + children-num + temp-mark thr-entity + subject-differ) + (let ((wl-mime-charset wl-summary-buffer-mime-charset) + (elmo-mime-charset wl-summary-buffer-mime-charset) + no-parent before-indent + from subject parent-raw-subject parent-subject + mark line + (elmo-lang wl-summary-buffer-weekday-name-lang) + (children-num (if children-num (int-to-string children-num))) + (thr-str "")) + (if thr-entity + (setq thr-str (wl-thread-make-indent-string thr-entity))) + (if (string= thr-str "") + (setq no-parent t)) ; no parent + (if (and wl-summary-width + wl-summary-indent-length-limit + (< wl-summary-indent-length-limit + (string-width thr-str))) + (setq thr-str (wl-set-string-width + wl-summary-indent-length-limit + thr-str))) + (setq from + (wl-set-string-width + (if children-num + (- wl-from-width (length children-num) 2) + wl-from-width) + (elmo-delete-char ?\n + (wl-summary-from-func-internal + (elmo-msgdb-overview-entity-get-from entity))))) + (setq subject + (elmo-delete-char ?\n + (or (elmo-msgdb-overview-entity-get-subject + entity) + wl-summary-no-subject-message))) + (setq parent-raw-subject + (elmo-msgdb-overview-entity-get-subject parent-entity)) + (setq parent-subject + (if parent-raw-subject + (elmo-delete-char ?\n parent-raw-subject))) + (setq mark (or (cadr (assq msg mark-alist)) " ")) + (setq line + (concat + (setq before-indent + (format (concat "%" + (int-to-string + wl-summary-buffer-number-column) + "s%s%s%s %s") + msg + (or temp-mark " ") + mark + (wl-summary-format-date + (elmo-msgdb-overview-entity-get-date entity)) + (if thr-str thr-str ""))) + (format "[%s ] %s" + (if children-num + (concat "+" children-num ": " from) + (concat " " from)) + (if (or no-parent + (null parent-subject) + (not (wl-summary-subject-equal + subject parent-subject))) + (wl-summary-subject-func-internal subject) "")))) + (if wl-summary-width (setq line + (wl-set-string-width + (- wl-summary-width 1) line))) + (if wl-summary-highlight + (wl-highlight-summary-line-string line + mark + temp-mark + thr-str)) + line)) + +(defsubst wl-summary-buffer-number-column-detect (update) + (let (end) + (save-excursion + (setq wl-summary-buffer-number-column + (or + (if (and update + (setq end (if (re-search-forward "^ *[0-9]+[^0-9]" nil t) + (point)))) + (- end (progn (beginning-of-line) (point)) 1)) + (wl-get-assoc-list-value wl-summary-number-column-alist + wl-summary-buffer-folder-name) + wl-summary-default-number-column)) + (setq wl-summary-buffer-number-regexp + (wl-repeat-string "." wl-summary-buffer-number-column))))) + +(defsubst wl-summary-proc-wday (wday-str year month mday) + (save-match-data + (if (string-match "\\([A-Z][a-z][a-z]\\).*" wday-str) + (wl-match-string 1 wday-str) + (elmo-date-get-week year month mday)))) + +(defmacro wl-summary-cursor-move-regex () + (` (let ((mark-alist + (if (elmo-folder-plugged-p wl-summary-buffer-folder-name) + (cond ((eq wl-summary-move-order 'new) + (list + (list + wl-summary-new-mark) + (list + wl-summary-unread-uncached-mark + wl-summary-unread-cached-mark + wl-summary-important-mark))) + ((eq wl-summary-move-order 'unread) + (list + (list + wl-summary-unread-uncached-mark + wl-summary-unread-cached-mark + wl-summary-new-mark) + (list + wl-summary-important-mark))) + (t + (list + (list + wl-summary-unread-uncached-mark + wl-summary-unread-cached-mark + wl-summary-new-mark + wl-summary-important-mark)))) + (cond ((eq wl-summary-move-order 'unread) + (list + (list + wl-summary-unread-cached-mark) + (list + wl-summary-important-mark))) + (t + (list + (list + wl-summary-unread-cached-mark + wl-summary-important-mark))))))) + (mapcar + (function + (lambda (mark-list) + (concat wl-summary-message-regexp + ".\\(" + (mapconcat 'regexp-quote + mark-list + "\\|") + "\\)\\|" + wl-summary-message-regexp "\\*"))) + mark-alist)))) + +;; +;; Goto unread or important +;; +(defun wl-summary-cursor-up (&optional hereto) + (interactive "P") + (if (and (not wl-summary-buffer-target-mark-list) + (eq wl-summary-buffer-view 'thread)) + (progn + (if (eobp) + (forward-line -1)) + (wl-thread-jump-to-prev-unread hereto)) + (if hereto + (end-of-line) + (beginning-of-line)) + (let ((case-fold-search nil) + regex-list) + (setq regex-list (wl-summary-cursor-move-regex)) + (catch 'done + (while regex-list + (when (re-search-backward + (car regex-list) + nil t nil) + (beginning-of-line) + (throw 'done t)) + (setq regex-list (cdr regex-list))) + (beginning-of-line) + (throw 'done nil))))) + +;; +;; Goto unread or important +;; returns t if next message exists in this folder. +(defun wl-summary-cursor-down (&optional hereto) + (interactive "P") + (if (and (null wl-summary-buffer-target-mark-list) + (eq wl-summary-buffer-view 'thread)) + (wl-thread-jump-to-next-unread hereto) + (if hereto + (beginning-of-line) + (end-of-line)) + (let ((case-fold-search nil) + regex-list) + (setq regex-list (wl-summary-cursor-move-regex)) + (catch 'done + (while regex-list + (when (re-search-forward + (car regex-list) + nil t nil) + (beginning-of-line) + (throw 'done t)) + (setq regex-list (cdr regex-list))) + (beginning-of-line) + (throw 'done nil))))) + +(defun wl-summary-save-view-cache (&optional keep-current-buffer) + (save-excursion + (let* ((dir (elmo-msgdb-expand-path wl-summary-buffer-folder-name)) + (cache (expand-file-name wl-summary-cache-file dir)) + (view (expand-file-name wl-summary-view-file dir)) + ;;(coding-system-for-write wl-cs-cache) + ;;(output-coding-system wl-cs-cache) + (save-view wl-summary-buffer-view) + (tmp-buffer(get-buffer-create " *wl-summary-save-view-cache*")) + charset) + (if (file-directory-p dir) + (); ok. + (if (file-exists-p dir) + (error "File %s already exists" dir) + (elmo-make-directory dir))) + (if (eq save-view 'thread) + (wl-thread-save-entity dir)) + (unwind-protect + (progn + (when (file-writable-p cache) + (if keep-current-buffer + (progn + (save-excursion + (set-buffer tmp-buffer) + (erase-buffer)) + (setq charset wl-summary-buffer-mime-charset) + (copy-to-buffer tmp-buffer (point-min) (point-max)) + (save-excursion + (set-buffer tmp-buffer) + (widen) + (encode-mime-charset-region + (point-min) (point-max) charset) + (as-binary-output-file + (write-region (point-min) + (point-max) cache nil 'no-msg)))) + (let (buffer-read-only) + (widen) + (encode-mime-charset-region (point-min) (point-max) + wl-summary-buffer-mime-charset) + (as-binary-output-file + (write-region (point-min) (point-max) cache nil 'no-msg))))) + (when (file-writable-p view) ; 'thread or 'sequence + (save-excursion + (set-buffer tmp-buffer) + (erase-buffer) + (prin1 save-view tmp-buffer) + (princ "\n" tmp-buffer) + (write-region (point-min) (point-max) view nil 'no-msg)))) + ;; kill tmp buffer. + (kill-buffer tmp-buffer))))) + +(defsubst wl-summary-get-sync-range (folder) + (intern (or (and + (elmo-folder-plugged-p folder) + (wl-get-assoc-list-value + wl-folder-sync-range-alist + folder)) + wl-default-sync-range))) + +;; redefined for wl-summary-sync-update +(defun wl-summary-input-range (folder) + "returns update or all or rescan." + ;; for the case when parts are expanded in the bottom of the folder + (let ((input-range-list '("update" "all" "rescan" "first:" "last:" + "no-sync" "rescan-noscore")) + (default (or (wl-get-assoc-list-value + wl-folder-sync-range-alist + folder) + wl-default-sync-range)) + range) + (setq range + (completing-read (format "Range (%s): " default) + (mapcar + (function (lambda (x) (cons x x))) + input-range-list))) + (if (string= range "") + default + range))) + +(defun wl-summary-toggle-disp-folder (&optional arg) + (interactive) + (let (fld-buf fld-win + (view-message-buffer (wl-message-get-buffer-create)) + (cur-buf (current-buffer)) + (summary-win (get-buffer-window (current-buffer)))) + (cond + ((eq arg 'on) + (setq wl-summary-buffer-disp-folder t) + ;; hide your folder window + (if (setq fld-buf (get-buffer wl-folder-buffer-name)) + (if (setq fld-win (get-buffer-window fld-buf)) + (delete-window fld-win)))) + ((eq arg 'off) + (setq wl-summary-buffer-disp-folder nil) + ;; hide your wl-message window! + (wl-select-buffer view-message-buffer) + (delete-window) + (select-window (get-buffer-window cur-buf)) + ;; display wl-folder window!! + (if (setq fld-buf (get-buffer wl-folder-buffer-name)) + (if (setq fld-win (get-buffer-window fld-buf)) + ;; folder win is already displayed. + (select-window fld-win) + ;; folder win is not displayed. + (switch-to-buffer fld-buf)) + ;; no folder buf + (wl-folder)) + ;; temporarily delete summary-win. + (if summary-win + (delete-window summary-win)) + (split-window-horizontally wl-folder-window-width) + (other-window 1) + (switch-to-buffer cur-buf)) + (t + (if (setq fld-buf (get-buffer wl-folder-buffer-name)) + (if (setq fld-win (get-buffer-window fld-buf)) + (setq wl-summary-buffer-disp-folder nil) + (setq wl-summary-buffer-disp-folder t))) + (if (not wl-summary-buffer-disp-folder) + ;; hide message window + (let ((mes-win (get-buffer-window view-message-buffer)) + (wl-stay-folder-window t)) + (if mes-win (delete-window mes-win)) + ;; hide your folder window + (if (setq fld-buf (get-buffer wl-folder-buffer-name)) + (if (setq fld-win (get-buffer-window fld-buf)) + (progn + (delete-window (get-buffer-window cur-buf)) + (select-window fld-win) + (switch-to-buffer cur-buf)))) + (run-hooks 'wl-summary-toggle-disp-folder-off-hook) + ;; resume message window. + (when mes-win + (wl-select-buffer view-message-buffer) + (run-hooks 'wl-summary-toggle-disp-folder-message-resumed-hook) + (select-window (get-buffer-window cur-buf))) + ) + (save-excursion + ;; hide message window + (let ((mes-win (get-buffer-window view-message-buffer)) + (wl-stay-folder-window t)) + (if mes-win (delete-window mes-win)) + (select-window (get-buffer-window cur-buf)) + ;; display wl-folder window!! + (if (setq fld-buf (get-buffer wl-folder-buffer-name)) + (if (setq fld-win (get-buffer-window fld-buf)) + ;; folder win is already displayed. + (select-window fld-win) + ;; folder win is not displayed...occupy all. + (switch-to-buffer fld-buf)) + ;; no folder buf + (wl-folder)) + (split-window-horizontally wl-folder-window-width) + (other-window 1) + (switch-to-buffer cur-buf) + ;; resume message window. + (run-hooks 'wl-summary-toggle-disp-folder-on-hook) + (when mes-win + (wl-select-buffer view-message-buffer) + (run-hooks 'wl-summary-toggle-disp-folder-message-resumed-hook) + (select-window (get-buffer-window cur-buf)))) + ))))) + (run-hooks 'wl-summary-toggle-disp-folder-hook)) + +(defun wl-summary-toggle-disp-msg (&optional arg) + (interactive) + (let (fld-buf fld-win + (view-message-buffer (wl-message-get-buffer-create)) + (cur-buf (current-buffer)) + summary-win) + (cond + ((eq arg 'on) + (setq wl-summary-buffer-disp-msg t) + ;; hide your folder window + (if (and (not wl-stay-folder-window) + (setq fld-buf (get-buffer wl-folder-buffer-name))) + (if (setq fld-win (get-buffer-window fld-buf)) + (delete-window fld-win)))) + ((eq arg 'off) + (wl-delete-all-overlays) + (setq wl-summary-buffer-disp-msg nil) + (save-excursion + (wl-select-buffer view-message-buffer) + (delete-window) + (and (get-buffer-window cur-buf) + (select-window (get-buffer-window cur-buf))) + (run-hooks 'wl-summary-toggle-disp-off-hook))) + (t + (if (get-buffer-window view-message-buffer) ; already displayed + (setq wl-summary-buffer-disp-msg nil) + (setq wl-summary-buffer-disp-msg t)) + (if wl-summary-buffer-disp-msg + (progn + (wl-summary-redisplay) + ;; hide your folder window +;; (setq fld-buf (get-buffer wl-folder-buffer-name)) +;; (if (setq fld-win (get-buffer-window fld-buf)) +;; (delete-window fld-win))) + (run-hooks 'wl-summary-toggle-disp-on-hook)) + (wl-delete-all-overlays) + (save-excursion + (wl-select-buffer view-message-buffer) + (delete-window) + (select-window (get-buffer-window cur-buf)) + (run-hooks 'wl-summary-toggle-disp-off-hook)) + ;;(switch-to-buffer cur-buf) + ))))) + +(defun wl-summary-next-line-content () + (interactive) + (let ((cur-buf (current-buffer))) + (wl-summary-toggle-disp-msg 'on) + (when (wl-summary-set-message-buffer-or-redisplay 'ignore-original) + (set-buffer cur-buf) + (wl-message-next-page 1)))) + +(defun wl-summary-prev-line-content () + (interactive) + (let ((cur-buf (current-buffer))) + (wl-summary-toggle-disp-msg 'on) + (when (wl-summary-set-message-buffer-or-redisplay 'ignore-original) + (set-buffer cur-buf) + (wl-message-prev-page 1)))) + +(defun wl-summary-next-page () + (interactive) + (wl-message-next-page)) + +(defun wl-summary-prev-page () + (interactive) + (wl-message-prev-page)) + +(defsubst wl-summary-no-mime-p (folder) + (wl-string-match-member folder wl-summary-no-mime-folder-list)) + +(defun wl-summary-set-message-buffer-or-redisplay (&optional ignore-original) + ;; if current message is not displayed, display it. + ;; return t if exists. + (let ((folder wl-summary-buffer-folder-name) + (number (wl-summary-message-number)) + cur-folder cur-number message-last-pos + (view-message-buffer (wl-message-get-buffer-create))) + (save-excursion + (set-buffer view-message-buffer) + (setq cur-folder wl-message-buffer-cur-folder) + (setq cur-number wl-message-buffer-cur-number)) + (if (and (not ignore-original) + (not + (and (eq number (wl-message-original-buffer-number)) + (string= folder (wl-message-original-buffer-folder))))) + (progn + (if (wl-summary-no-mime-p folder) + (wl-summary-redisplay-no-mime folder number) + (wl-summary-redisplay-internal folder number)) + nil) + (if (and (string= folder (or cur-folder "")) + (eq number (or cur-number 0))) + (progn + (set-buffer view-message-buffer) + t) + (if (wl-summary-no-mime-p folder) + (wl-summary-redisplay-no-mime folder number) + (wl-summary-redisplay-internal folder number)) + nil)))) + +(defun wl-summary-target-mark-forward (&optional arg) + (interactive "P") + (let ((mlist (nreverse wl-summary-buffer-target-mark-list)) + (summary-buf (current-buffer)) + (wl-draft-forward t) + start-point + draft-buf) + (wl-summary-jump-to-msg (car mlist)) + (wl-summary-forward t) + (setq start-point (point)) + (setq draft-buf (current-buffer)) + (setq mlist (cdr mlist)) + (save-window-excursion + (when mlist + (while mlist + (set-buffer summary-buf) + (wl-summary-jump-to-msg (car mlist)) + (wl-summary-redisplay) + (set-buffer draft-buf) + (goto-char (point-max)) + (wl-draft-insert-message) + (setq mlist (cdr mlist))) + (wl-draft-body-goto-top) + (wl-draft-enclose-digest-region (point) (point-max))) + (goto-char start-point) + (save-excursion + (set-buffer summary-buf) + (wl-summary-delete-all-temp-marks))) + (run-hooks 'wl-mail-setup-hook))) + +(defun wl-summary-target-mark-reply-with-citation (&optional arg) + (interactive "P") + (let ((mlist (nreverse wl-summary-buffer-target-mark-list)) + (summary-buf (current-buffer)) + change-major-mode-hook + start-point + draft-buf) + (wl-summary-jump-to-msg (car mlist)) + (wl-summary-reply arg t) + (goto-char (point-max)) + (setq start-point (point)) + (setq draft-buf (current-buffer)) + (save-window-excursion + (while mlist + (set-buffer summary-buf) + (wl-summary-jump-to-msg (car mlist)) + (wl-summary-redisplay) + (set-buffer draft-buf) + (goto-char (point-max)) + (wl-draft-yank-original) + (setq mlist (cdr mlist))) + (goto-char start-point) + (save-excursion + (set-buffer summary-buf) + (wl-summary-delete-all-temp-marks))) + (run-hooks 'wl-mail-setup-hook))) + +(defun wl-summary-reply-with-citation (&optional arg) + (interactive "P") + (unwind-protect + (wl-summary-reply arg t) + (goto-char (point-max)) + (wl-draft-yank-original) + (run-hooks 'wl-mail-setup-hook))) + +(defun wl-summary-jump-to-msg-by-message-id (&optional id) + (interactive) + (let* ((original (wl-summary-message-number)) + (msgid (elmo-string (or id (read-from-minibuffer "Message-ID: ")))) + (number-alist (elmo-msgdb-get-number-alist wl-summary-buffer-msgdb)) + msg otherfld schar + (errmsg + (format "No message with id \"%s\" in the folder." msgid))) + (if (setq msg (car (rassoc msgid number-alist))) + ;;(wl-summary-jump-to-msg-internal + ;;wl-summary-buffer-folder-name msg 'no-sync) + (progn + (wl-thread-jump-to-msg msg) + t) + ;; for XEmacs! + (if (and elmo-use-database + (setq errmsg + (format + "No message with id \"%s\" in the database." msgid)) + (setq otherfld (elmo-database-msgid-get msgid))) + (if (cdr (wl-summary-jump-to-msg-internal + (car otherfld) (nth 1 otherfld) 'no-sync)) + t ; succeed. + ;; Back to original. + (wl-summary-jump-to-msg-internal + wl-summary-buffer-folder-name original 'no-sync)) + (cond ((eq wl-summary-search-via-nntp 'confirm) + (message "Search message in nntp server \"%s\" ?" + elmo-default-nntp-server) + (setq schar (read-char)) + (cond ((eq schar ?y) + (wl-summary-jump-to-msg-by-message-id-via-nntp msgid)) + ((eq schar ?s) + (wl-summary-jump-to-msg-by-message-id-via-nntp + msgid + (read-from-minibuffer "NNTP Server: "))) + (t + (message errmsg) + nil))) + (wl-summary-search-via-nntp + (wl-summary-jump-to-msg-by-message-id-via-nntp msgid)) + (t + (message errmsg) + nil)))))) + +(defun wl-summary-jump-to-msg-by-message-id-via-nntp (&optional id server-spec) + (interactive) + (let* ((msgid (elmo-string (or id (read-from-minibuffer "Message-ID: ")))) + newsgroups folder ret + user server port ssl spec) + (if server-spec + (if (string-match "^-" server-spec) + (setq spec (elmo-nntp-get-spec server-spec) + user (nth 2 spec) + server (nth 3 spec) + port (nth 4 spec) + ssl (nth 5 spec)) + (setq server server-spec))) + (when (setq ret (elmo-nntp-get-newsgroup-by-msgid + msgid + (or server elmo-default-nntp-server) + (or user elmo-default-nntp-user) + (or port elmo-default-nntp-port) + (or ssl elmo-default-nntp-ssl))) + (setq newsgroups (wl-parse-newsgroups ret)) + (setq folder (concat "-" (car newsgroups) + (elmo-nntp-folder-postfix user server port ssl))) + (catch 'found + (while newsgroups + (if (wl-folder-entity-exists-p (car newsgroups) + wl-folder-newsgroups-hashtb) + (throw 'found + (setq folder (concat "-" (car newsgroups) + (elmo-nntp-folder-postfix user server port ssl))))) + (setq newsgroups (cdr newsgroups))))) + (if ret + (wl-summary-jump-to-msg-internal folder nil 'update msgid) + (message "No message id \"%s\" in nntp server \"%s\"." + msgid (or server elmo-default-nntp-server)) + nil))) + +(defun wl-summary-jump-to-msg-internal (folder msg scan-type &optional msgid) + (let (wl-auto-select-first entity) + (if (or (string= folder wl-summary-buffer-folder-name) + (y-or-n-p + (format + "Message was found in the folder \"%s\". Jump to it? " + folder))) + (progn + (unwind-protect + (wl-summary-goto-folder-subr + folder scan-type nil nil t) + (if msgid + (setq msg + (car (rassoc msgid + (elmo-msgdb-get-number-alist + wl-summary-buffer-msgdb))))) + (setq entity (wl-folder-search-entity-by-name folder + wl-folder-entity + 'folder)) + (if entity + (wl-folder-set-current-entity-id + (wl-folder-get-entity-id entity)))) + (if (null msg) + (message "Message was not found currently in this folder.") + (setq msg (and (wl-thread-jump-to-msg msg) msg))) + (cons folder msg))))) + +(defun wl-summary-jump-to-parent-message (arg) + (interactive "P") + (let ((cur-buf (current-buffer)) + (regexp "\\(<[^<>]*>\\)[ \t]*$") + (i -1) ;; xxx + msg-id ref-list ref irt) + (wl-summary-set-message-buffer-or-redisplay) + (set-buffer (wl-message-get-original-buffer)) + (message "Searching parent message...") + (setq ref (std11-field-body "References") + irt (std11-field-body "In-Reply-To")) + (cond + ((and arg (not (numberp arg)) ref (not (string= ref "")) + (string-match regexp ref)) + ;; The first message of the thread. + (setq msg-id (wl-match-string 1 ref))) + ;; "In-Reply-To:" has only one msg-id. + ((and irt (not (string= irt "")) + (string-match regexp irt)) + (setq msg-id (wl-match-string 1 irt))) + ((and (or (null arg) (numberp arg)) ref (not (string= ref "")) + (string-match regexp ref)) + ;; "^" searching parent, "C-u 2 ^" looking for grandparent. + (while (string-match regexp ref) + (setq ref-list + (append (list + (wl-match-string 1 ref)) + ref-list)) + (setq ref (substring ref (match-end 0))) + (setq i (1+ i))) + (setq msg-id + (if (null arg) (nth 0 ref-list) ;; previous + (if (<= arg i) (nth (1- arg) ref-list) + (nth i ref-list)))))) + (set-buffer cur-buf) + (cond ((null msg-id) + (message "No parent message!") + nil) + ((wl-summary-jump-to-msg-by-message-id msg-id) + (wl-summary-redisplay) + (message "Searching parent message...done.") + t) + (t ; failed. + (message "Parent message was not found.") + nil)))) + +(defun wl-summary-reply (&optional arg without-setup-hook) + "Reply to current message. Default is \"wide\" reply. +Reply to author if invoked with argument." + (interactive "P") + (let ((folder wl-summary-buffer-folder-name) + (number (wl-summary-message-number)) + (summary-buf (current-buffer)) + mes-buf) + (wl-summary-redisplay-internal folder number) + (wl-select-buffer (get-buffer (setq mes-buf (wl-current-message-buffer)))) + (set-buffer mes-buf) + (goto-char (point-min)) + (or wl-draft-use-frame + (split-window-vertically)) + (other-window 1) + (when (setq mes-buf (wl-message-get-original-buffer)) + (wl-draft-reply mes-buf (not arg) summary-buf) + (unless without-setup-hook + (run-hooks 'wl-mail-setup-hook))))) + +(defun wl-summary-write () + "Write a new draft from Summary." + (interactive) + (wl-draft nil nil nil nil nil + nil nil nil nil nil (current-buffer)) + (run-hooks 'wl-mail-setup-hook) + (mail-position-on-field "To")) + +(defun wl-summary-write-current-newsgroup (&optional folder) + (interactive) + (let* ((folder (or folder wl-summary-buffer-folder-name)) + (flist (elmo-folder-get-primitive-folder-list folder)) + newsgroups fld ret) + (while (setq fld (car flist)) + (if (setq ret + (cond ((eq 'nntp (elmo-folder-get-type fld)) + (nth 1 (elmo-folder-get-spec fld))) + ((eq 'localnews (elmo-folder-get-type fld)) + (elmo-replace-in-string + (nth 1 (elmo-folder-get-spec fld)) "/" "\\.")))) + (setq newsgroups (cond (newsgroups + (concat newsgroups "," ret)) + (t ret)))) + (setq flist (cdr flist))) + (if newsgroups + (progn + (wl-draft nil nil nil nil nil newsgroups) + (run-hooks 'wl-mail-setup-hook)) + (error "%s is not newsgroup" folder)))) + +(defun wl-summary-forward (&optional without-setup-hook) + (interactive) + (let ((folder wl-summary-buffer-folder-name) + (number (wl-summary-message-number)) + (summary-buf (current-buffer)) + (wl-draft-forward t) + entity subject num) + (wl-summary-redisplay-internal folder number) + (wl-select-buffer (get-buffer wl-message-buf-name)) + (or wl-draft-use-frame + (split-window-vertically)) + (other-window 1) + ;; get original subject. + (if summary-buf + (save-excursion + (set-buffer summary-buf) + (setq num (wl-summary-message-number)) + (setq entity (assoc (cdr (assq num + (elmo-msgdb-get-number-alist + wl-summary-buffer-msgdb))) + (elmo-msgdb-get-overview + wl-summary-buffer-msgdb))) + (and entity + (setq subject + (or (elmo-msgdb-overview-entity-get-subject entity) + ""))))) + (wl-draft-forward subject summary-buf) + (unless without-setup-hook + (run-hooks 'wl-mail-setup-hook)))) + +(defun wl-summary-click (e) + (interactive "e") + (mouse-set-point e) + (wl-summary-read)) + +(defun wl-summary-read () + (interactive) + (let ((folder wl-summary-buffer-folder-name) + (number (wl-summary-message-number)) + cur-folder cur-number message-last-pos + (view-message-buffer (get-buffer-create wl-message-buf-name)) + (sticky-buf-name (and (wl-summary-sticky-p) wl-message-buf-name)) + (summary-buf-name (buffer-name))) + (save-excursion + (set-buffer view-message-buffer) + (when (and sticky-buf-name + (not (wl-local-variable-p 'wl-message-buf-name + (current-buffer)))) + (make-local-variable 'wl-message-buf-name) + (setq wl-message-buf-name sticky-buf-name) + (make-local-variable 'wl-message-buffer-cur-summary-buffer) + (setq wl-message-buffer-cur-summary-buffer summary-buf-name)) + (setq cur-folder wl-message-buffer-cur-folder) + (setq cur-number wl-message-buffer-cur-number)) + (wl-summary-toggle-disp-msg 'on) + (if (and (string= folder cur-folder) + (eq number cur-number)) + (progn + (if (wl-summary-next-page) + (wl-summary-down t))) +; (wl-summary-scroll-up-content))) + (if (wl-summary-no-mime-p folder) + (wl-summary-redisplay-no-mime folder number) + (wl-summary-redisplay-internal folder number))))) + +(defun wl-summary-move-cached-regex (skip-marks) + (if (eq wl-summary-move-order 'unread) + (list + (format "^%s[^%s]\\(%s\\)" + wl-summary-buffer-number-regexp + skip-marks + (regexp-quote wl-summary-unread-cached-mark)) + (format "^%s[^%s]\\(%s\\| \\)" + wl-summary-buffer-number-regexp + skip-marks + (regexp-quote wl-summary-important-mark))) + (list + (format "^%s[^%s]\\(%s\\|%s\\| \\)" + wl-summary-buffer-number-regexp + skip-marks + (regexp-quote wl-summary-unread-cached-mark) + (regexp-quote wl-summary-important-mark))))) + +(defun wl-summary-prev (&optional interactive) + (interactive) + (if wl-summary-move-direction-toggle + (setq wl-summary-move-direction-downward nil)) + (let ((type (elmo-folder-get-type wl-summary-buffer-folder-name)) + (skip-mark-regexp (mapconcat + 'regexp-quote + wl-summary-skip-mark-list "")) + goto-next regex-list regex next-entity finfo) + (beginning-of-line) + (if (elmo-folder-plugged-p wl-summary-buffer-folder-name) + (progn + (setq regex (format "^%s[^%s]" + wl-summary-buffer-number-regexp + skip-mark-regexp)) + (unless (re-search-backward regex nil t) + (setq goto-next t))) + (setq regex-list (wl-summary-move-cached-regex skip-mark-regexp)) + (catch 'done + (while regex-list + (if (re-search-backward (car regex-list) nil t) + (throw 'done t)) + (setq regex-list (cdr regex-list))) + (setq goto-next t))) + (beginning-of-line) + (if (not goto-next) + (progn + (if wl-summary-buffer-disp-msg + (wl-summary-redisplay))) + (if (or interactive (interactive-p)) + (progn + (when wl-auto-select-next + (setq next-entity (wl-summary-get-prev-folder)) + (if next-entity + (setq finfo (wl-folder-get-entity-info next-entity)))) + (wl-ask-folder + '(lambda () (wl-summary-next-folder-or-exit next-entity)) + (format + "No more messages. Type SPC to go to %s." + (wl-summary-entity-info-msg next-entity finfo)))))))) + +(defun wl-summary-next (&optional interactive) + (interactive) + (if wl-summary-move-direction-toggle + (setq wl-summary-move-direction-downward t)) + (let ((type (elmo-folder-get-type wl-summary-buffer-folder-name)) + (skip-mark-regexp (mapconcat + 'regexp-quote + wl-summary-skip-mark-list "")) + goto-next regex regex-list next-entity finfo) + (end-of-line) + (if (elmo-folder-plugged-p wl-summary-buffer-folder-name) + (progn + (setq regex (format "^%s[^%s]" + wl-summary-buffer-number-regexp + skip-mark-regexp)) + (unless (re-search-forward regex nil t) + (forward-line 1) + (setq goto-next t))) + (setq regex-list (wl-summary-move-cached-regex skip-mark-regexp)) + (catch 'done + (while regex-list + (if (re-search-forward (car regex-list) nil t) + (throw 'done t)) + (setq regex-list (cdr regex-list))) + (setq goto-next t))) + (beginning-of-line) + (if (not goto-next) + (if wl-summary-buffer-disp-msg + (wl-summary-redisplay)) + (if (or interactive (interactive-p)) + (progn + (when wl-auto-select-next + (setq next-entity (wl-summary-get-next-folder)) + (if next-entity + (setq finfo (wl-folder-get-entity-info next-entity)))) + (wl-ask-folder + '(lambda () (wl-summary-next-folder-or-exit next-entity)) + (format + "No more messages. Type SPC to go to %s." + (wl-summary-entity-info-msg next-entity finfo)))))))) + +(defun wl-summary-up (&optional interactive skip-no-unread) + (interactive) + (if wl-summary-move-direction-toggle + (setq wl-summary-move-direction-downward nil)) + (if (wl-summary-cursor-up) + (if wl-summary-buffer-disp-msg + (wl-summary-redisplay)) + (if (or interactive + (interactive-p)) + (let (next-entity finfo) + (when wl-auto-select-next + (progn + (setq next-entity (wl-summary-get-prev-unread-folder)) + (if next-entity + (setq finfo (wl-folder-get-entity-info next-entity))))) + (if (and skip-no-unread + (eq wl-auto-select-next 'skip-no-unread)) + (wl-summary-next-folder-or-exit next-entity t) + (wl-ask-folder + '(lambda () (wl-summary-next-folder-or-exit next-entity t)) + (format + "No more unread messages. Type SPC to go to %s." + (wl-summary-entity-info-msg next-entity finfo)))))))) + +(defun wl-summary-get-prev-folder () + (let ((folder-buf (get-buffer wl-folder-buffer-name)) + last-entity cur-id) + (when folder-buf + (setq cur-id (save-excursion (set-buffer folder-buf) + wl-folder-buffer-cur-entity-id)) + (wl-folder-get-prev-folder cur-id)))) + +(defun wl-summary-get-next-folder () + (let ((folder-buf (get-buffer wl-folder-buffer-name)) + cur-id) + (when folder-buf + (setq cur-id (save-excursion (set-buffer folder-buf) + wl-folder-buffer-cur-entity-id)) + (wl-folder-get-next-folder cur-id)))) + +(defun wl-summary-get-next-unread-folder () + (let ((folder-buf (get-buffer wl-folder-buffer-name)) + cur-id) + (when folder-buf + (setq cur-id (save-excursion (set-buffer folder-buf) + wl-folder-buffer-cur-entity-id)) + (wl-folder-get-next-folder cur-id 'unread)))) + +(defun wl-summary-get-prev-unread-folder () + (let ((folder-buf (get-buffer wl-folder-buffer-name)) + cur-id) + (when folder-buf + (setq cur-id (save-excursion (set-buffer folder-buf) + wl-folder-buffer-cur-entity-id)) + (wl-folder-get-prev-folder cur-id 'unread)))) + +(defun wl-summary-down (&optional interactive skip-no-unread) + (interactive) + (if wl-summary-move-direction-toggle + (setq wl-summary-move-direction-downward t)) + (if (wl-summary-cursor-down) + (if wl-summary-buffer-disp-msg + (wl-summary-redisplay)) + (if (or interactive + (interactive-p)) + (let (next-entity finfo) + (when wl-auto-select-next + (setq next-entity (wl-summary-get-next-unread-folder)) + (if next-entity + (setq finfo (wl-folder-get-entity-info next-entity)))) + (if (and skip-no-unread + (eq wl-auto-select-next 'skip-no-unread)) + (wl-summary-next-folder-or-exit next-entity) + (wl-ask-folder + '(lambda () (wl-summary-next-folder-or-exit next-entity)) + (format + "No more unread messages. Type SPC to go to %s." + (wl-summary-entity-info-msg next-entity finfo)))))))) + +(defun wl-summary-goto-last-displayed-msg () + (interactive) + (unless wl-summary-buffer-last-displayed-msg + (setq wl-summary-buffer-last-displayed-msg + wl-summary-buffer-current-msg)) + (if wl-summary-buffer-last-displayed-msg + (progn + (wl-summary-jump-to-msg wl-summary-buffer-last-displayed-msg) + (if wl-summary-buffer-disp-msg + (wl-summary-redisplay))) + (message "No last message."))) + +(defun wl-summary-redisplay (&optional arg) + (interactive "P") + (if (and (not arg) + (wl-summary-no-mime-p wl-summary-buffer-folder-name)) + (wl-summary-redisplay-no-mime) + (wl-summary-redisplay-internal nil nil arg))) + +(defsubst wl-summary-redisplay-internal (&optional folder number force-reload) + (interactive) + (let* ((msgdb wl-summary-buffer-msgdb) + (fld (or folder wl-summary-buffer-folder-name)) + (num (or number (wl-summary-message-number))) + (wl-mime-charset wl-summary-buffer-mime-charset) + (default-mime-charset wl-summary-buffer-mime-charset) + (wl-message-redisplay-func + wl-summary-buffer-message-redisplay-func) + fld-buf fld-win thr-entity) + (if (and wl-thread-open-reading-thread + (eq wl-summary-buffer-view 'thread) + (not (wl-thread-entity-get-opened + (setq thr-entity (wl-thread-get-entity + num)))) + (wl-thread-entity-get-children thr-entity)) + (wl-thread-force-open)) + (if num + (progn + (setq wl-summary-buffer-disp-msg t) + (setq wl-summary-buffer-last-displayed-msg + wl-summary-buffer-current-msg) + ;; hide folder window + (if (and (not wl-stay-folder-window) + (setq fld-buf (get-buffer wl-folder-buffer-name))) + (if (setq fld-win (get-buffer-window fld-buf)) + (delete-window fld-win))) + (setq wl-current-summary-buffer (current-buffer)) + (if (wl-message-redisplay fld num 'mime msgdb force-reload) + (wl-summary-mark-as-read nil + ;; cached, then change server-mark. + (if wl-message-cache-used + nil + ;; plugged, then leave server-mark. + (if (elmo-folder-plugged-p + wl-summary-buffer-folder-name) + 'leave)) + t) ;; displayed + ) + (setq wl-summary-buffer-current-msg num) + (if wl-summary-recenter + (recenter (/ (- (window-height) 2) 2))) + (wl-highlight-summary-displaying) + (wl-cache-prefetch-next fld num (current-buffer)) + (run-hooks 'wl-summary-redisplay-hook)) + (message "No message to display.")))) + +(defun wl-summary-redisplay-no-mime (&optional folder number) + (interactive) + (let* ((msgdb wl-summary-buffer-msgdb) + (fld (or folder wl-summary-buffer-folder-name)) + (num (or number (wl-summary-message-number))) + (wl-mime-charset wl-summary-buffer-mime-charset) + (default-mime-charset wl-summary-buffer-mime-charset) + wl-break-pages) + (if num + (progn + (setq wl-summary-buffer-disp-msg t) + (setq wl-current-summary-buffer (current-buffer)) + (wl-normal-message-redisplay fld num 'no-mime msgdb) + (wl-summary-mark-as-read nil nil t) + (setq wl-summary-buffer-current-msg num) + (if wl-summary-recenter + (recenter (/ (- (window-height) 2) 2))) + (wl-highlight-summary-displaying) + (run-hooks 'wl-summary-redisplay-hook)) + (message "No message to display.") + (wl-ask-folder 'wl-summary-exit + "No more messages. Type SPC to go to folder mode.")))) + +(defun wl-summary-redisplay-all-header (&optional folder number) + (interactive) + (let* ((msgdb wl-summary-buffer-msgdb) + (fld (or folder wl-summary-buffer-folder-name)) + (num (or number (wl-summary-message-number))) + (wl-mime-charset wl-summary-buffer-mime-charset) + (default-mime-charset wl-summary-buffer-mime-charset) + (wl-message-redisplay-func wl-summary-buffer-message-redisplay-func)) + (if num + (progn + (if (wl-message-redisplay fld num 'all-header msgdb); t if displayed. + (wl-summary-mark-as-read nil nil t)) + (run-hooks 'wl-summary-redisplay-hook)) + (message "No message to display.")))) + +(defun wl-summary-jump-to-current-message () + (interactive) + (let (message-buf message-win) + (if (setq message-buf (get-buffer wl-message-buf-name)) + (if (setq message-win (get-buffer-window message-buf)) + (select-window message-win) + (wl-select-buffer (get-buffer wl-message-buf-name))) + (wl-summary-redisplay) + (wl-select-buffer (get-buffer wl-message-buf-name))) + (goto-char (point-min)))) + +(defun wl-summary-cancel-message () + "Cancel an article on news." + (interactive) + (let ((summary-buf (current-buffer)) + message-buf) + (wl-summary-set-message-buffer-or-redisplay) + (if (setq message-buf (wl-message-get-original-buffer)) + (set-buffer message-buf)) + (unless (wl-message-news-p) + (error "This is not a news article; canceling is impossible")) + (when (yes-or-no-p "Do you really want to cancel this article? ") + (let (from newsgroups message-id distribution buf) + (save-excursion + (setq from (std11-field-body "from") + newsgroups (std11-field-body "newsgroups") + message-id (std11-field-body "message-id") + distribution (std11-field-body "distribution")) + ;; Make sure that this article was written by the user. + (unless (wl-address-user-mail-address-p + (wl-address-header-extract-address + (car (wl-parse-addresses from)))) + (error "This article is not yours")) + ;; Make control message. + (setq buf (set-buffer (get-buffer-create " *message cancel*"))) + (setq wl-draft-buffer-cur-summary-buffer summary-buf) + (buffer-disable-undo (current-buffer)) + (erase-buffer) + (insert "Newsgroups: " newsgroups "\n" + "From: " (wl-address-header-extract-address + wl-from) "\n" + "Subject: cmsg cancel " message-id "\n" + "Control: cancel " message-id "\n" + (if distribution + (concat "Distribution: " distribution "\n") + "") + mail-header-separator "\n" + wl-summary-cancel-message) + (message "Canceling your message...") + (wl-draft-raw-send t t) ; kill when done, force-pre-hooks. + (message "Canceling your message...done")))))) + +(defun wl-summary-supersedes-message () + "Supersede current message." + (interactive) + (let ((summary-buf (current-buffer)) + (mmelmo-force-fetch-entire-message t) + message-buf from) + (wl-summary-set-message-buffer-or-redisplay) + (if (setq message-buf (wl-message-get-original-buffer)) + (set-buffer message-buf)) + (unless (wl-message-news-p) + (error "This is not a news article; supersedes is impossible")) + (save-excursion + (setq from (std11-field-body "from")) + ;; Make sure that this article was written by the user. + (unless (wl-address-user-mail-address-p + (wl-address-header-extract-address + (car (wl-parse-addresses from)))) + (error "This article is not yours")) + (let* ((message-id (std11-field-body "message-id")) + (followup-to (std11-field-body "followup-to")) + (mail-default-headers + (concat mail-default-headers + "Supersedes: " message-id "\n" + (and followup-to + (concat "Followup-To: " followup-to "\n"))))) + (set-buffer (wl-message-get-original-buffer)) + (wl-draft-edit-string (buffer-substring (point-min) (point-max))))))) + +(defun wl-summary-save (&optional arg wl-save-dir) + (interactive) + (let ((filename) + (num (wl-summary-message-number)) + (mmelmo-force-fetch-entire-message t)) + (if (null wl-save-dir) + (setq wl-save-dir wl-tmp-dir)) + (if num + (save-excursion + (setq filename (expand-file-name + (int-to-string num) + wl-save-dir)) + (if (null (and arg + (null (file-exists-p filename)))) + (setq filename + (read-file-name "Save to file: " filename))) + + (wl-summary-set-message-buffer-or-redisplay) + (set-buffer (wl-message-get-original-buffer)) + (if (and (null arg) (file-exists-p filename)) + (if (y-or-n-p "file already exists. override it?") + (write-region (point-min) (point-max) filename)) + (write-region (point-min) (point-max) filename))) + (message "No message to save.")) + num)) + +(defun wl-summary-save-region (beg end) + (interactive "r") + (save-excursion + (save-restriction + (narrow-to-region beg end) + (goto-char (point-min)) + (let ((wl-save-dir + (wl-read-directory-name "Save to directory: " wl-tmp-dir))) + (if (null (file-exists-p wl-save-dir)) + (make-directory wl-save-dir)) + (if (eq wl-summary-buffer-view 'thread) + (progn + (while (not (eobp)) + (let* ((number (wl-summary-message-number)) + (entity (wl-thread-get-entity number))) + (if (wl-thread-entity-get-opened entity) + (wl-summary-save t wl-save-dir) + ;; closed + (wl-summary-save t wl-save-dir)) + (forward-line 1)))) + (while (not (eobp)) + (wl-summary-save t wl-save-dir) + (forward-line 1))))))) + +;; mew-summary-pipe-message() +(defun wl-summary-pipe-message (prefix command) + "Send this message via pipe." + (interactive + (list current-prefix-arg + (read-string "Shell command on message: " wl-summary-shell-command-last))) + (if (y-or-n-p "Send this message to pipe? ") + (save-excursion + (wl-summary-set-message-buffer-or-redisplay) + (set-buffer (wl-message-get-original-buffer)) + (if (string= command "") + (setq command wl-summary-shell-command-last)) + (goto-char (point-min)) ; perhaps this line won't be necessary + (if prefix + (search-forward "\n\n")) + (shell-command-on-region (point) (point-max) command nil) + (setq wl-summary-shell-command-last command)))) + +(defun wl-summary-print-message (&optional arg) + (interactive "P") + (save-excursion + (wl-summary-set-message-buffer-or-redisplay) + (if (or (not (interactive-p)) + (y-or-n-p "Print ok?")) + (progn + (let* ((message-buffer (get-buffer wl-message-buf-name)) + ;; (summary-buffer (get-buffer wl-summary-buffer-name)) + (buffer (generate-new-buffer " *print*"))) + (set-buffer message-buffer) + (copy-to-buffer buffer (point-min) (point-max)) + (set-buffer buffer) + (funcall wl-print-buffer-func) + (kill-buffer buffer))) + (message "")))) + +(defun wl-summary-print-message-with-ps-print (&optional filename) + (interactive (list (ps-print-preprint current-prefix-arg))) + (if (or (not (interactive-p)) + (y-or-n-p "Print ok?")) + (let ((summary-buffer (current-buffer)) + wl-break-pages) + (save-excursion + ;;(wl-summary-set-message-buffer-or-redisplay) + (wl-summary-redisplay-internal) + (let* ((message-buffer (get-buffer wl-message-buf-name)) + (buffer (generate-new-buffer " *print*")) + (entity (progn + (set-buffer summary-buffer) + (assoc (cdr (assq + (wl-summary-message-number) + (elmo-msgdb-get-number-alist + wl-summary-buffer-msgdb))) + (elmo-msgdb-get-overview + wl-summary-buffer-msgdb)))) + (wl-ps-subject + (and entity + (or (elmo-msgdb-overview-entity-get-subject entity) + ""))) + (wl-ps-from + (and entity + (or (elmo-msgdb-overview-entity-get-from entity) ""))) + (wl-ps-date + (and entity + (or (elmo-msgdb-overview-entity-get-date entity) "")))) + (run-hooks 'wl-ps-preprint-hook) + (set-buffer message-buffer) + (copy-to-buffer buffer (point-min) (point-max)) + (set-buffer buffer) + (unwind-protect + (let ((ps-left-header + (list (concat "(" wl-ps-subject ")") + (concat "(" wl-ps-from ")"))) + (ps-right-header + (list "/pagenumberstring load" + (concat "(" wl-ps-date ")")))) + (run-hooks 'wl-ps-print-hook) + (funcall wl-ps-print-buffer-func filename)) + (kill-buffer buffer))))) + (message ""))) + +(if (featurep 'ps-print) ; ps-print is available. + (fset 'wl-summary-print-message 'wl-summary-print-message-with-ps-print)) + +(defun wl-summary-folder-info-update () + (let ((folder (elmo-string wl-summary-buffer-folder-name)) + (num-db (elmo-msgdb-get-number-alist + wl-summary-buffer-msgdb))) + (wl-folder-set-folder-updated folder + (list 0 + (+ wl-summary-buffer-unread-count + wl-summary-buffer-new-count) + (length num-db))))) + +(defun wl-summary-get-newsgroups () + (let ((spec-list (elmo-folder-get-primitive-spec-list + (elmo-string wl-summary-buffer-folder-name))) + ng-list) + (while spec-list + (when (eq (caar spec-list) 'nntp) + (wl-append ng-list (list (nth 1 (car spec-list))))) + (setq spec-list (cdr spec-list))) + ng-list)) + +(defun wl-summary-set-crosspost (&optional type redisplay) + (let* ((number (wl-summary-message-number)) + (spec (elmo-folder-number-get-spec wl-summary-buffer-folder-name + number)) + (folder (nth 1 spec)) + message-buf newsgroups) + (when (eq (car spec) 'nntp) + (if redisplay + (wl-summary-redisplay)) + (save-excursion + (if (setq message-buf (wl-message-get-original-buffer)) + (set-buffer message-buf)) + (setq newsgroups (std11-field-body "newsgroups"))) + (when newsgroups + (let* ((msgdb wl-summary-buffer-msgdb) + (num-db (elmo-msgdb-get-number-alist msgdb)) + (ng-list (wl-summary-get-newsgroups)) ;; for multi folder + crosspost-folders) + (when (setq crosspost-folders + (elmo-delete-lists ng-list + (wl-parse-newsgroups newsgroups t))) + (elmo-crosspost-message-set (cdr (assq number num-db)) ;;message-id + crosspost-folders + type) ;;not used + (setq wl-crosspost-alist-modified t))))))) + +(defun wl-summary-is-crosspost-folder (spec-list fld-list) + (let (fld flds) + (while spec-list + (if (and (eq (caar spec-list) 'nntp) + (member (setq fld (nth 1 (car spec-list))) fld-list)) + (wl-append flds (list fld))) + (setq spec-list (cdr spec-list))) + flds)) + +(defun wl-summary-update-crosspost () + (let* ((msgdb wl-summary-buffer-msgdb) + (number-alist (elmo-msgdb-get-number-alist msgdb)) + (mark-alist (elmo-msgdb-get-mark-alist msgdb)) + (spec-list (elmo-folder-get-primitive-spec-list + (elmo-string wl-summary-buffer-folder-name))) + (alist elmo-crosspost-message-alist) + (crossed 0) + mark ngs num) + (when (assq 'nntp spec-list) + (while alist + (when (setq ngs + (wl-summary-is-crosspost-folder + spec-list + (nth 1 (car alist)))) + (when (setq num (car (rassoc (caar alist) number-alist))) + (if (and (setq mark (cadr (assq num mark-alist))) + (member mark (list wl-summary-new-mark + wl-summary-unread-uncached-mark + wl-summary-unread-cached-mark))) + (setq crossed (1+ crossed))) + (if (wl-summary-jump-to-msg num) + (wl-summary-mark-as-read t);; opened + (wl-thread-msg-mark-as-read num)));; closed + ;; delete if message does't exists. + (elmo-crosspost-message-delete (caar alist) ngs) + (setq wl-crosspost-alist-modified t)) + (setq alist (cdr alist)))) + (if (> crossed 0) + crossed))) + +(defun wl-crosspost-alist-load () + (setq elmo-crosspost-message-alist (elmo-crosspost-alist-load)) + (setq wl-crosspost-alist-modified nil)) + +(defun wl-crosspost-alist-save () + (when wl-crosspost-alist-modified + ;; delete non-exists newsgroups + (let ((alist elmo-crosspost-message-alist) + newsgroups) + (while alist + (setq newsgroups + (elmo-delete-if + '(lambda (x) + (not (intern-soft x wl-folder-newsgroups-hashtb))) + (nth 1 (car alist)))) + (if newsgroups + (setcar (cdar alist) newsgroups) + (setq elmo-crosspost-message-alist + (delete (car alist) elmo-crosspost-message-alist))) + (setq alist (cdr alist))) + (elmo-crosspost-alist-save elmo-crosspost-message-alist) + (setq wl-crosspost-alist-modified nil)))) + +(defun wl-summary-pack-number (&optional arg) + (interactive "P") + (setq wl-summary-buffer-msgdb + (elmo-pack-number + wl-summary-buffer-folder-name wl-summary-buffer-msgdb arg)) + (wl-summary-rescan)) + +(defun wl-summary-target-mark-uudecode () + (interactive) + (let ((mlist (reverse wl-summary-buffer-target-mark-list)) + (summary-buf (current-buffer)) + (tmp-buf (get-buffer-create "*WL UUENCODE*")) + orig-buf i k filename rc errmsg) + (setq i 1) + (setq k (length mlist)) + (set-buffer tmp-buf) + (erase-buffer) + (save-window-excursion + (while mlist + (set-buffer summary-buf) + (wl-summary-jump-to-msg (car mlist)) + (wl-summary-redisplay) + (set-buffer (setq orig-buf (wl-message-get-original-buffer))) + (goto-char (point-min)) + (cond ((= i 1) ; first + (setq filename (wl-message-uu-substring + orig-buf tmp-buf t + (= i k)))) + ((< i k) + (wl-message-uu-substring orig-buf tmp-buf)) + (t ; last + (wl-message-uu-substring orig-buf tmp-buf nil t))) + (setq i (1+ i)) + (setq mlist (cdr mlist))) + (set-buffer tmp-buf) + (message "Exec %s..." wl-prog-uudecode) + (unwind-protect + (let ((decode-dir wl-tmp-dir)) + (if (not wl-prog-uudecode-no-stdout-option) + (setq filename (read-file-name "Save to file: " + (expand-file-name + (elmo-safe-filename filename) + wl-tmp-dir))) + (setq decode-dir + (wl-read-directory-name "Save to directory: " + wl-tmp-dir)) + (setq filename (expand-file-name filename decode-dir))) + (if (file-exists-p filename) + (or (yes-or-no-p (format "File %s exists. Save anyway? " + filename)) + (error ""))) + (elmo-bind-directory + decode-dir + (setq rc + (as-binary-process + (apply 'call-process-region (point-min) (point-max) + wl-prog-uudecode t (current-buffer) nil + wl-prog-uudecode-arg)))) + (when (not (= 0 rc)) + (setq errmsg (buffer-substring (point-min)(point-max))) + (error "uudecode error: %s" errmsg)) + (if (not wl-prog-uudecode-no-stdout-option) + (let (file-name-handler-alist) ;; void jka-compr + (as-binary-output-file + (write-region (point-min) (point-max) + filename nil 'no-msg)))) + (save-excursion + (set-buffer summary-buf) + (wl-summary-delete-all-temp-marks)) + (if (file-exists-p filename) + (message "Saved as %s" filename))) + (kill-buffer tmp-buf))))) + +(defun wl-summary-drop-unsync () + "Drop all unsync messages." + (interactive) + (if (elmo-folder-pipe-p wl-summary-buffer-folder-name) + (error "You cannot drop unsync messages in this folder")) + (if (or (not (interactive-p)) + (y-or-n-p "Drop all unsync messages?")) + (let* ((folder-list (elmo-folder-get-primitive-folder-list + wl-summary-buffer-folder-name)) + (is-multi (elmo-multi-p wl-summary-buffer-folder-name)) + (sum 0) + (multi-num 0) + pair) + (message "Dropping...") + (while folder-list + (setq pair (elmo-max-of-folder (car folder-list))) + (when is-multi ;; dirty hack... + (incf multi-num) + (setcar pair (+ (* multi-num elmo-multi-divide-number) + (car pair)))) + (elmo-msgdb-set-number-alist + wl-summary-buffer-msgdb + (nconc + (elmo-msgdb-get-number-alist wl-summary-buffer-msgdb) + (list (cons (car pair) nil)))) + (setq sum (+ sum (cdr pair))) + (setq folder-list (cdr folder-list))) + (wl-summary-set-message-modified) + (wl-folder-set-folder-updated wl-summary-buffer-folder-name + (list 0 + (+ wl-summary-buffer-unread-count + wl-summary-buffer-new-count) + sum)) + (message "Dropping...done.")))) + +(defun wl-summary-default-get-next-msg (msg) + (let (next) + (if (and (not wl-summary-buffer-target-mark-list) + (eq wl-summary-buffer-view 'thread) + (if (eq wl-summary-move-direction-downward nil) + (setq next (wl-thread-get-prev-unread msg)) + (setq next (wl-thread-get-next-unread msg)))) + next + (save-excursion + (wl-summary-jump-to-msg msg) + (let (wl-summary-buffer-disp-msg) + (if (eq wl-summary-move-direction-downward nil) + (unless (wl-summary-cursor-up) + (wl-summary-prev)) + (unless (wl-summary-cursor-down) + (wl-summary-next))) + (wl-summary-message-number)))))) + +(defsubst wl-cache-prefetch-p (fld &optional num) + (cond ((and num wl-cache-prefetch-folder-type-list) + (memq + (elmo-folder-number-get-type fld num) + wl-cache-prefetch-folder-type-list)) + (wl-cache-prefetch-folder-type-list + (let ((list wl-cache-prefetch-folder-type-list) + type) + (catch 'done + (while (setq type (pop list)) + (if (elmo-folder-contains-type fld type) + (throw 'done t)))))) + ((consp wl-cache-prefetch-folder-list) + (wl-string-match-member fld wl-cache-prefetch-folder-list)) + (t + wl-cache-prefetch-folder-list))) + +(defconst wl-cache-prefetch-idle-time + (if (featurep 'lisp-float-type) (/ (float 1) (float 10)) 1)) + +(defun wl-cache-prefetch-next (fld msg &optional summary) + (if (wl-cache-prefetch-p fld) + (if (not elmo-use-buffer-cache) + ;; (message "`elmo-use-buffer-cache' is nil, cache prefetch is disable.") + (save-excursion + (set-buffer (or summary (get-buffer wl-summary-buffer-name))) + (let ((next (funcall wl-cache-prefetch-get-next-func msg))) + (when (and next + (wl-cache-prefetch-p fld next)) + (if (not (fboundp 'run-with-idle-timer)) + (when (sit-for wl-cache-prefetch-idle-time) + (wl-cache-prefetch-message fld next summary)) + (run-with-idle-timer + wl-cache-prefetch-idle-time + nil + 'wl-cache-prefetch-message fld next summary) + (sit-for 0)))))))) + +(defvar wl-cache-prefetch-debug nil) +(defun wl-cache-prefetch-message (folder msg summary &optional next) + (when (buffer-live-p summary) + (save-excursion + (set-buffer summary) + (when (string= folder wl-summary-buffer-folder-name) + (unless next + (setq next msg)) + (let* ((msgdb wl-summary-buffer-msgdb) + (message-id (cdr (assq next + (elmo-msgdb-get-number-alist msgdb))))) + (if (not (elmo-buffer-cache-hit (list folder next message-id))) + (let* ((size (elmo-msgdb-overview-entity-get-size + (assoc message-id + (elmo-msgdb-get-overview msgdb))))) + (when (or (elmo-local-file-p folder next) + (not (and (integerp size) + wl-cache-prefetch-threshold + (>= size wl-cache-prefetch-threshold) + (not (elmo-cache-exists-p message-id + folder next))))) + (if wl-cache-prefetch-debug + (message "Reading %d..." msg)) + (elmo-buffer-cache-message folder next msgdb) + (if wl-cache-prefetch-debug + (message "Reading %d... done" msg)))))))))) + +(provide 'wl-summary) + +;;; wl-summary.el ends here diff --git a/wl/wl-template.el b/wl/wl-template.el new file mode 100644 index 0000000..78d49f5 --- /dev/null +++ b/wl/wl-template.el @@ -0,0 +1,194 @@ +;;; wl-template.el -- Draft template feature for Wanderlust. + +;; Copyright 1998,1999,2000 Masahiro MURATA +;; Yuuichi Teranishi + +;; Author: Masahiro MURATA +;; Keywords: mail, net news +;; Time-stamp: <2000-03-03 13:18:35 teranisi> + +;; This file is part of Wanderlust (Yet Another Message Interface on Emacsen). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: + +;;; Code: +;; + +;; Variables + +(defvar wl-template-default-name "default") +(defvar wl-template-buffer-name "*WL-Template*") +(defvar wl-template-mode-map nil) + +(defvar wl-template nil) +(defvar wl-template-cur-num 0) +(defvar wl-template-max-num 0) +(defvar wl-template-draft-buffer nil) + +;;; Code + +(if wl-template-mode-map + nil + (setq wl-template-mode-map (make-sparse-keymap)) + (define-key wl-template-mode-map "p" 'wl-template-prev) + (define-key wl-template-mode-map "n" 'wl-template-next) + (define-key wl-template-mode-map "q" 'wl-template-abort) + (define-key wl-template-mode-map "\r" 'wl-template-set) + (define-key wl-template-mode-map "\n" 'wl-template-set)) + +(defun wl-template-apply (name) + (let (template) + (when name + (if (string= name "") + (setq name wl-template-default-name)) + (when (setq template (cdr (assoc name wl-template-alist))) + (save-excursion + (setq wl-draft-config-variables + (elmo-uniq-list + (nconc wl-draft-config-variables + (save-excursion + (wl-draft-config-exec-sub template))))) + ;; rehighlight + (if wl-highlight-body-too + (let ((beg (point-min)) + (end (point-max))) + (put-text-property beg end 'face nil) + (wl-highlight-message beg end t)))))))) + +(defun wl-template-mode () + "Major mode for Wanderlust template. +See info under Wanderlust for full documentation. + +\\{wl-template-mode} + +Enterring WL-Template mode calls the value of `wl-template-mode-hook'." + (kill-all-local-variables) + (setq mode-name "Wl-Template" + major-mode 'wl-template-mode) + (use-local-map wl-template-mode-map) + (setq buffer-read-only t) + (run-hooks 'wl-template-mode-hook)) + +(defun wl-template-select () + (interactive) + (if (not wl-template-visible-select) + (wl-template-apply + (completing-read (format "Template (%s): " wl-template-default-name) + wl-template-alist)) + (let* ((begin wl-template-default-name) + (work wl-template-alist)) + (if (and begin (cdr (assoc begin wl-template-alist))) + (while (not (string= (car (car work)) begin)) + (setq wl-template-cur-num (1+ wl-template-cur-num)) + (setq work (cdr work)))) + (setq wl-template nil + wl-template-cur-num 0 + wl-template-max-num (length wl-template-alist)) + (setq wl-template-draft-buffer (current-buffer)) + (if (get-buffer-window wl-template-buffer-name) + (select-window (get-buffer-window wl-template-buffer-name)) + (let* ((cur-win (selected-window)) + (size (min + (- (window-height cur-win) + window-min-height 1) + (- (window-height cur-win) + (max window-min-height + (1+ wl-template-buffer-lines)))))) + (split-window cur-win (if (> size 0) size window-min-height)) + ;; goto the bottom of the two... + (select-window (next-window)) + ;; make it display... + (let ((pop-up-windows nil)) + (switch-to-buffer (get-buffer-create wl-template-buffer-name))))) + (set-buffer wl-template-buffer-name) + (wl-template-mode) + (wl-template-show)))) + +(defun wl-template-show (&optional arg) + "Show reference INDEX in wl-template-alist." + (save-excursion + (set-buffer wl-template-buffer-name) + (let ((buffer-read-only nil) + (mail-header-separator "--header separater--")) + (erase-buffer) + (goto-char (point-min)) + (wl-template-insert + (setq wl-template (car (nth wl-template-cur-num wl-template-alist))) + mail-header-separator) + (wl-highlight-message (point-min) (point-max) t) + (and wl-highlight-x-face-func + (funcall + wl-highlight-x-face-func + (point-min) (re-search-forward mail-header-separator nil t))) + (setq mode-line-process (concat ":" wl-template)) + (set-buffer-modified-p nil)))) + +(defun wl-template-next () + "Display next reference in other buffer." + (interactive) + (if (eq wl-template-max-num + (setq wl-template-cur-num (1+ wl-template-cur-num))) + (setq wl-template-cur-num 0)) + (wl-template-show)) + +(defun wl-template-prev () + "Display previous reference in other buffer." + (interactive) + (setq wl-template-cur-num (if (eq wl-template-cur-num 0) + (1- wl-template-max-num) + (1- wl-template-cur-num))) + (wl-template-show)) + +(defun wl-template-abort () + "Exit from electric reference mode without inserting reference." + (interactive) + (setq wl-template nil) + (delete-window) + (kill-buffer wl-template-buffer-name) + (when (buffer-live-p wl-template-draft-buffer) + (set-buffer wl-template-draft-buffer) + (let ((win (get-buffer-window wl-template-draft-buffer))) + (if win (select-window win))))) + +(defun wl-template-set () + "Exit from electric reference mode and insert selected reference." + (interactive) + (if (and wl-template-confirm + (not (y-or-n-p "Are you sure ? "))) + (message "") + (delete-window) + (kill-buffer wl-template-buffer-name) + (when (buffer-live-p wl-template-draft-buffer) + (set-buffer wl-template-draft-buffer) + (wl-template-apply wl-template) + (let ((win (get-buffer-window wl-template-draft-buffer))) + (if win (select-window win)))))) + +(defun wl-template-insert (name &optional mail-header) + (let ((template (cdr (assoc name wl-template-alist))) + (mail-header-separator (or mail-header + mail-header-separator))) + (when template + (if mail-header + (insert mail-header-separator "\n")) + (wl-draft-config-exec-sub template)))) + +(provide 'wl-template) + +;;; wl-template.el ends here diff --git a/wl/wl-thread.el b/wl/wl-thread.el new file mode 100644 index 0000000..ac11584 --- /dev/null +++ b/wl/wl-thread.el @@ -0,0 +1,1427 @@ +;;; wl-thread.el -- Thread display modules for Wanderlust. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <00/03/13 16:10:25 teranisi> + +;; This file is part of Wanderlust (Yet Another Message Interface on Emacsen). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; + +(require 'wl-summary) +(require 'wl-highlight) + +;; buffer local variables. +;(defvar wl-thread-top-entity '(nil t nil nil)) ; top entity +(defvar wl-thread-tops nil) ; top number list (number) +(defvar wl-thread-entities nil) +(defvar wl-thread-entity-list nil) ; entity list +(defvar wl-thread-entity-hashtb nil) ; obarray +(defvar wl-thread-indent-regexp nil) + +(mapcar + (function make-variable-buffer-local) + (list 'wl-thread-entity-hashtb + 'wl-thread-entities ; -> ".wl-thread-entity" + 'wl-thread-entity-list ; -> ".wl-thread-entity-list" + 'wl-thread-entity-cur + 'wl-thread-indent-regexp)) + +;;; global flag +(defvar wl-thread-insert-force-opened nil) + +;;;;;; each entity is (number opened-or-not children parent) ;;;;;;; + +(defun wl-meaning-of-mark (mark) + (if (not (elmo-folder-plugged-p wl-summary-buffer-folder-name)) + (cond + ((string= mark wl-summary-unread-cached-mark) + 'unread) + ((string= mark wl-summary-important-mark) + 'important)) + (cond + ((string= mark wl-summary-new-mark) + 'new) + ((or (string= mark wl-summary-unread-uncached-mark) + (string= mark wl-summary-unread-cached-mark)) + 'unread) + ((string= mark wl-summary-important-mark) + 'important)))) + +(defun wl-thread-next-mark-p (mark next) + (cond ((not (elmo-folder-plugged-p wl-summary-buffer-folder-name)) + (or (string= mark wl-summary-unread-cached-mark) + (string= mark wl-summary-important-mark))) + ((eq next 'new) + (string= mark wl-summary-new-mark)) + ((eq next 'unread) + (or (string= mark wl-summary-unread-uncached-mark) + (string= mark wl-summary-unread-cached-mark) + (string= mark wl-summary-new-mark))) + (t + (or (string= mark wl-summary-unread-uncached-mark) + (string= mark wl-summary-unread-cached-mark) + (string= mark wl-summary-new-mark) + (string= mark wl-summary-important-mark))))) + +(defun wl-thread-next-failure-mark-p (mark next) + (cond ((not (elmo-folder-plugged-p wl-summary-buffer-folder-name)) + (string= mark wl-summary-unread-cached-mark)) + ((or (eq next 'new) + (eq next 'unread)) + (or (string= mark wl-summary-unread-uncached-mark) + (string= mark wl-summary-unread-cached-mark) + (string= mark wl-summary-new-mark) + (string= mark wl-summary-important-mark))) + (t t))) + +(defun wl-thread-resume-entity (fld) + (let (entities top-list) + (setq entities (wl-summary-load-file-object + (expand-file-name wl-thread-entity-file + (elmo-msgdb-expand-path fld)))) + (setq top-list + (wl-summary-load-file-object + (expand-file-name wl-thread-entity-list-file + (elmo-msgdb-expand-path fld)))) + (current-buffer) + (message "Resuming thread structure...") + ;; set obarray value. + (setq wl-thread-entity-hashtb (elmo-make-hash (* (length entities) 2))) + (mapcar + '(lambda (x) + (elmo-set-hash-val (format "#%d" (car x)) + x + wl-thread-entity-hashtb)) + entities) + ;; set buffer local variables. + (setq wl-thread-entities entities) + (setq wl-thread-entity-list top-list) + (message "Resuming thread structure...done."))) + +(defun wl-thread-save-entity (dir) + (wl-thread-save-entities dir) + (wl-thread-save-top-list dir)) + +(defun wl-thread-save-top-list (dir) + (let ((top-file (expand-file-name wl-thread-entity-list-file dir)) + (entity wl-thread-entity-list) + (tmp-buffer (get-buffer-create " *wl-thread-save-top-list*"))) + (save-excursion + (set-buffer tmp-buffer) + (erase-buffer) + (when (file-writable-p top-file) + (prin1 entity tmp-buffer) + (princ "\n" tmp-buffer) + (write-region (point-min) (point-max) top-file nil 'no-msg) + (kill-buffer tmp-buffer))))) + +(defun wl-thread-save-entities (dir) + (let ((top-file (expand-file-name wl-thread-entity-file dir)) + (entities wl-thread-entities) + (tmp-buffer (get-buffer-create " *wl-thread-save-entities*"))) + (save-excursion + (set-buffer tmp-buffer) + (erase-buffer) + (when (file-writable-p top-file) + (prin1 entities tmp-buffer) + (princ "\n" tmp-buffer) + (write-region (point-min) (point-max) top-file nil 'no-msg) + (kill-buffer tmp-buffer))))) + +(defsubst wl-thread-entity-get-number (entity) + (nth 0 entity)) +(defsubst wl-thread-entity-get-opened (entity) + (nth 1 entity)) +(defsubst wl-thread-entity-get-children (entity) + (nth 2 entity)) +(defsubst wl-thread-entity-get-parent (entity) + (nth 3 entity)) + +(defsubst wl-thread-create-entity (num parent &optional opened) + (list num (or opened wl-thread-insert-opened) nil parent)) + +(defsubst wl-thread-get-entity (num) + (and num + (boundp (intern (format "#%d" num) wl-thread-entity-hashtb)) + (elmo-get-hash-val (format "#%d" num) wl-thread-entity-hashtb))) + +(defsubst wl-thread-entity-set-parent (entity parent) + (setcar (cdddr entity) parent) + entity) + +(defsubst wl-thread-entity-set-children (entity children) + (setcar (cddr entity) children)) + +(defsubst wl-thread-entity-insert-as-top (entity) + (when (and entity + (car entity)) + (setq wl-thread-entity-list (append wl-thread-entity-list + (list (car entity)))) + (setq wl-thread-entities (cons entity wl-thread-entities)) + (elmo-set-hash-val (format "#%d" (car entity)) entity + wl-thread-entity-hashtb))) + +(defsubst wl-thread-entity-insert-as-children (to entity) + (let ((children (nth 2 to))) + (setcar (cddr to) (wl-append children + (list (car entity)))) + (setq wl-thread-entities (cons entity wl-thread-entities)) + (elmo-set-hash-val (format "#%d" (car entity)) entity + wl-thread-entity-hashtb))) + +(defsubst wl-thread-entity-set-opened (entity opened) + (setcar (cdr entity) opened)) + +(defsubst wl-thread-entity-get-children-num (entity) + (let (children + ret-val msgs-stack + (msgs (list (car entity)))) + (while msgs + (setq msgs (cdr msgs)) + (setq children (wl-thread-entity-get-children entity)) + (if (null children) + (while (and (null msgs) msgs-stack) + (setq msgs (wl-pop msgs-stack))) + (setq ret-val (+ (or ret-val 0) (length children))) + (wl-push msgs msgs-stack) + (setq msgs children)) + (setq entity (wl-thread-get-entity (car msgs)))) + ret-val)) + +(defsubst wl-thread-entity-get-descendant (entity) + (let (children + ret-val msgs-stack + (msgs (list (car entity)))) + (while msgs + (setq msgs (cdr msgs)) + (setq children (wl-thread-entity-get-children entity)) + (if (null children) + (while (and (null msgs) msgs-stack) + (setq msgs (wl-pop msgs-stack))) + (setq ret-val (append ret-val (copy-sequence children))) + (wl-push msgs msgs-stack) + (setq msgs children)) + (setq entity (wl-thread-get-entity (car msgs)))) + ret-val)) + +(defsubst wl-thread-entity-get-parent-entity (entity) + (wl-thread-get-entity (wl-thread-entity-get-parent entity))) + +(defun wl-thread-entity-get-top-entity (entity) + (let ((cur-entity entity) + p-num) + (while (setq p-num (wl-thread-entity-get-parent cur-entity)) + (setq cur-entity (wl-thread-get-entity p-num))) + cur-entity)) + +(defun wl-thread-entity-parent-invisible-p (entity) + "If parent of ENTITY is invisible, the top invisible ancestor entity of +ENTITY is returned." + (let ((cur-entity entity) + ret-val) + (catch 'done + (while (setq cur-entity (wl-thread-entity-get-parent-entity + cur-entity)) + (if (null (wl-thread-entity-get-number cur-entity)) + ;; top!! + (progn + ;;(setq ret-val nil) + (throw 'done nil)) + (when (not (wl-thread-entity-get-opened cur-entity)) + ;; not opened!! + (setq ret-val cur-entity))))) + ;; top of closed entity in the path. + ret-val)) + +(defun wl-thread-entity-get-mark (number) + (let ((mark-alist (elmo-msgdb-get-mark-alist wl-summary-buffer-msgdb)) + mark) + (setq mark (cadr (assq number mark-alist))) + (if (string= mark wl-summary-read-uncached-mark) + () + mark))) + +(defun wl-thread-meaning-alist-get-result (meaning-alist) + (let ((malist meaning-alist) + ret-val) + (catch 'done + (while malist + (if (setq ret-val (cdr (car malist))) + (throw 'done ret-val)) + (setq malist (cdr malist)))))) + +(defun wl-thread-entity-check-prev-mark (entity prev-marks) + "Check prev mark. Result is stored in PREV-MARK." + (let ((msgs (list (car entity))) + (succeed-list (car prev-marks)) + (failure-list (cdr prev-marks)) + msgs-stack children + mark meaning success failure parents) + (catch 'done + (while msgs + (if (and (not (memq (car msgs) parents)) + (setq children (reverse (wl-thread-entity-get-children entity)))) + (progn + (wl-append parents (list (car msgs))) + (wl-push msgs msgs-stack) + (setq msgs children)) + (if (setq mark (wl-thread-entity-get-mark (car entity))) + (if (setq meaning (wl-meaning-of-mark mark)) + (if (setq success (assq meaning succeed-list)) + (progn + (setcdr success entity) + (throw 'done nil)) + (setq failure (assq meaning failure-list)) + (unless (cdr failure) + (setcdr (assq meaning failure-list) entity))))) + (setq msgs (cdr msgs))) + (unless msgs + (while (and (null msgs) msgs-stack) + (setq msgs (wl-pop msgs-stack)))) + (setq entity (wl-thread-get-entity (car msgs))))))) + +(defun wl-thread-entity-check-next-mark (entity next-marks) + "Check next mark. Result is stored in NEXT-MARK." + (let ((msgs (list (car entity))) + (succeed-list (car next-marks)) + (failure-list (cdr next-marks)) + msgs-stack children + mark meaning success failure) + (catch 'done + (while msgs + (if (setq mark (wl-thread-entity-get-mark (car entity))) + (if (setq meaning (wl-meaning-of-mark mark)) + (if (setq success (assq meaning succeed-list)) + (progn + (setcdr success entity) + (throw 'done nil)) + (setq failure (assq meaning failure-list)) + (unless (cdr failure) + (setcdr (assq meaning failure-list) entity))))) + (setq msgs (cdr msgs)) + (setq children (wl-thread-entity-get-children entity)) + (if children + (progn + (wl-push msgs msgs-stack) + (setq msgs children)) + (unless msgs + (while (and (null msgs) msgs-stack) + (setq msgs (wl-pop msgs-stack))))) + (setq entity (wl-thread-get-entity (car msgs))))))) + +(defun wl-thread-entity-get-older-brothers (entity &optional parent) + (let* ((parent (or parent + (wl-thread-entity-get-parent-entity entity))) + (brothers (wl-thread-entity-get-children parent)) + ret-val) + (if parent + brothers + (setq brothers wl-thread-entity-list)) + (catch 'done + (while brothers + (if (not (eq (wl-thread-entity-get-number entity) + (car brothers))) + (wl-append ret-val (list (car brothers))) + (throw 'done ret-val)) + (setq brothers (cdr brothers)))))) + +(defun wl-thread-entity-get-younger-brothers (entity &optional parent) + (let* ((parent (or parent + (wl-thread-entity-get-parent-entity entity))) + (brothers (wl-thread-entity-get-children parent))) + (if parent + (cdr (memq (wl-thread-entity-get-number entity) + brothers)) + ;; top!! + (cdr (memq (car entity) wl-thread-entity-list))))) + +(defun wl-thread-entity-check-prev-mark-from-older-brother (entity prev-marks) + (let* (older-brother parent) + (catch 'done + (while entity + (setq older-brother + (reverse (wl-thread-entity-get-older-brothers entity))) + ;; check itself + (let ((succeed-list (car prev-marks)) + (failure-list (cdr prev-marks)) + mark meaning success failure) + (if (setq mark (wl-thread-entity-get-mark (car entity))) + (if (setq meaning (wl-meaning-of-mark mark)) + (if (setq success (assq meaning succeed-list)) + (progn + (setcdr success entity) + (throw 'done nil)) + (setq failure (assq meaning failure-list)) + (unless (cdr failure) + (setcdr (assq meaning failure-list) entity)))))) + ;; check older brothers + (while older-brother + (wl-thread-entity-check-prev-mark (wl-thread-get-entity + (car older-brother)) + prev-marks) + (if (wl-thread-meaning-alist-get-result + (car prev-marks)) + (throw 'done nil)) + (setq older-brother (cdr older-brother))) + (setq entity (wl-thread-entity-get-parent-entity entity)))))) + +(defun wl-thread-entity-get-prev-marked-entity (entity prev-marks) + (let ((older-brothers (reverse + (wl-thread-entity-get-older-brothers entity))) + marked) + (or (catch 'done + (while older-brothers + (wl-thread-entity-check-prev-mark + (wl-thread-get-entity (car older-brothers)) prev-marks) + (if (setq marked + (wl-thread-meaning-alist-get-result + (car prev-marks))) + (throw 'done marked)) + (setq older-brothers (cdr older-brothers)))) + (wl-thread-entity-check-prev-mark-from-older-brother + (wl-thread-entity-get-parent-entity entity) prev-marks) + (if (setq marked + (wl-thread-meaning-alist-get-result + (car prev-marks))) + marked + (if (setq marked + (wl-thread-meaning-alist-get-result + (cdr prev-marks))) + marked))))) + +(defun wl-thread-get-prev-unread (msg &optional hereto) + (let ((cur-entity (wl-thread-get-entity msg)) + (prev-marks (cond ((eq wl-summary-move-order 'new) + (cons (list (cons 'new nil)) + (list (cons 'unread nil) + (cons 'important nil)))) + ((eq wl-summary-move-order 'unread) + (cons (list (cons 'unread nil) + (cons 'new nil)) + (list (cons 'important nil)))) + (t + (cons (list (cons 'unread nil) + (cons 'new nil) + (cons 'important nil)) + nil)))) + mark ret-val) + (if hereto + (when (wl-thread-next-mark-p (setq mark + (wl-thread-entity-get-mark + (car cur-entity))) + (caaar prev-marks)) + ;;(setq mark (cons cur-entity + ;;(wl-thread-entity-get-mark cur-entity))) + (setq ret-val msg))) + (when (and (not ret-val) + (or (setq cur-entity + (wl-thread-entity-get-prev-marked-entity + cur-entity prev-marks)) + (and hereto mark))) + (if (and hereto + (catch 'done + (let ((success-list (car prev-marks))) + (while success-list + (if (cdr (car success-list)) + (throw 'done nil)) + (setq success-list (cdr success-list))) + t)) + (wl-thread-next-failure-mark-p mark (caaar prev-marks))) + (setq ret-val msg) + (when cur-entity + (setq ret-val (car cur-entity))))) + ret-val)) + +(defun wl-thread-jump-to-prev-unread (&optional hereto) + "If prev unread is a children of a closed message, +the closed parent will be opened." + (interactive "P") + (let ((msg (wl-thread-get-prev-unread + (wl-summary-message-number) hereto))) + (when msg + (wl-thread-entity-force-open (wl-thread-get-entity msg)) + (wl-summary-jump-to-msg msg) + t))) + +(defun wl-thread-jump-to-msg (&optional number) + (interactive) + (let ((num (or number + (string-to-int + (read-from-minibuffer "Jump to Message(No.): "))))) + (wl-thread-entity-force-open (wl-thread-get-entity num)) + (wl-summary-jump-to-msg num))) + +(defun wl-thread-get-next-unread (msg &optional hereto) + (let ((cur-entity (wl-thread-get-entity msg)) + (next-marks (cond ((not (elmo-folder-plugged-p + wl-summary-buffer-folder-name)) + (cons (list (cons 'unread nil)) + (list (cons 'important nil)))) + ((eq wl-summary-move-order 'new) + (cons (list (cons 'new nil)) + (list (cons 'unread nil) + (cons 'important nil)))) + ((eq wl-summary-move-order 'unread) + (cons (list (cons 'unread nil) + (cons 'new nil)) + (list (cons 'important nil)))) + (t + (cons (list (cons 'unread nil) + (cons 'new nil) + (cons 'important nil)) + nil)))) + mark ret-val) + (if hereto + (when (wl-thread-next-mark-p (setq mark + (wl-thread-entity-get-mark + (car cur-entity))) + (caaar next-marks)) + (setq ret-val msg))) + (when (and (not ret-val) + (or (setq cur-entity + (wl-thread-entity-get-next-marked-entity + cur-entity next-marks)) + (and hereto mark))) + (if (and hereto + ;; all success-list is nil + (catch 'done + (let ((success-list (car next-marks))) + (while success-list + (if (cdr (car success-list)) + (throw 'done nil)) + (setq success-list (cdr success-list))) + t)) + (wl-thread-next-failure-mark-p mark (caaar next-marks))) + (setq ret-val msg) + (when cur-entity + (setq ret-val (car cur-entity))))) + ret-val)) + +(defun wl-thread-jump-to-next-unread (&optional hereto) + "If next unread is a children of a closed message, +the closed parent will be opened." + (interactive "P") + (let ((msg (wl-thread-get-next-unread + (wl-summary-message-number) hereto))) + (when msg + (wl-thread-entity-force-open (wl-thread-get-entity msg)) + (wl-summary-jump-to-msg msg) + t))) + +(defun wl-thread-close-all () + "Close all top threads." + (interactive) + (message "Closing all threads...") + (let ((entities wl-thread-entity-list) + (cur 0) + (len (length wl-thread-entity-list))) + (while entities + (when (and (wl-thread-entity-get-opened (wl-thread-get-entity + (car entities))) + (wl-thread-entity-get-children (wl-thread-get-entity + (car entities)))) + (wl-summary-jump-to-msg (car entities)) + (wl-thread-open-close) + (setq cur (1+ cur)) + (elmo-display-progress + 'wl-thread-close-all "Closing all threads..." + (/ (* cur 100) len))) + (setq entities (cdr entities)))) + (message "Closing all threads...done.") + (goto-char (point-max))) + +(defun wl-thread-open-all () + "Open all threads." + (interactive) + (message "Opening all threads...") + (let ((entities wl-thread-entity-list) + (cur 0) + (len (length wl-thread-entity-list))) + (while entities + (if (not (wl-thread-entity-get-opened (wl-thread-get-entity + (car entities)))) + (wl-thread-entity-force-open (wl-thread-get-entity + (car entities)))) + (setq cur (1+ cur)) + (elmo-display-progress + 'wl-thread-open-all "Opening all threads..." + (/ (* cur 100) len)) + (setq entities (cdr entities)))) + (message "Opening all threads...done.") + (goto-char (point-max))) + +(defun wl-thread-open-all-unread () + (interactive) + (let ((mark-alist (elmo-msgdb-get-mark-alist wl-summary-buffer-msgdb)) + mark) + (while mark-alist + (if (setq mark (nth 1 (car mark-alist))) + (if (or (string= mark wl-summary-unread-uncached-mark) + (string= mark wl-summary-unread-cached-mark) + (string= mark wl-summary-new-mark) + (string= mark wl-summary-important-mark)) + (wl-thread-entity-force-open (wl-thread-get-entity + (nth 0 (car mark-alist)))))) + (setq mark-alist (cdr mark-alist))))) + +;;; a subroutine for wl-thread-entity-get-next-marked-entity. +(defun wl-thread-entity-check-next-mark-from-younger-brother + (entity next-marks) + (let* (parent younger-brother) + (catch 'done + (while entity + (setq parent (wl-thread-entity-get-parent-entity entity) + younger-brother + (wl-thread-entity-get-younger-brothers entity parent)) + ;; check my brother! + (while younger-brother + (wl-thread-entity-check-next-mark + (wl-thread-get-entity (car younger-brother)) + next-marks) + (if (wl-thread-meaning-alist-get-result + (car next-marks)) + (throw 'done nil)) + (setq younger-brother (cdr younger-brother))) + (setq entity parent))))) + +(defun wl-thread-entity-get-next-marked-entity (entity next-marks) + (let ((children (wl-thread-entity-get-children entity)) + marked) + (or (catch 'done + (while children + (wl-thread-entity-check-next-mark + (wl-thread-get-entity (car children)) next-marks) + (if (setq marked + (wl-thread-meaning-alist-get-result + (car next-marks))) + (throw 'done marked)) + (setq children (cdr children)))) + ;; check younger brother + (wl-thread-entity-check-next-mark-from-younger-brother + entity next-marks) + (if (setq marked + (wl-thread-meaning-alist-get-result + (car next-marks))) + marked + (if (setq marked + (wl-thread-meaning-alist-get-result + (cdr next-marks))) + marked))))) + +(defun wl-thread-update-line-msgs (msgs) + (wl-delete-all-overlays) + (while msgs + (setq msgs + (wl-thread-update-line-on-buffer (car msgs) nil msgs)))) + +(defsubst wl-thread-update-line-on-buffer-sub (entity &optional msg parent-msg) + (let ((number-alist (elmo-msgdb-get-number-alist wl-summary-buffer-msgdb)) + (overview (elmo-msgdb-get-overview wl-summary-buffer-msgdb)) + (mark-alist (elmo-msgdb-get-mark-alist wl-summary-buffer-msgdb)) + (buffer-read-only nil) + (inhibit-read-only t) + ;;(parent-msg parent-msg) + overview-entity + temp-mark + children-num + summary-line) + (if (memq msg wl-summary-buffer-delete-list) + (setq temp-mark "D")) + (if (memq msg wl-summary-buffer-target-mark-list) + (setq temp-mark "*")) + (if (assq msg wl-summary-buffer-refile-list) + (setq temp-mark "o")) + (if (assq msg wl-summary-buffer-copy-list) + (setq temp-mark "O")) + (unless temp-mark + (setq temp-mark (wl-summary-get-score-mark msg))) + ;(setq parent-entity (wl-thread-entity-get-parent-entity entity)) + (unless parent-msg + (setq parent-msg (wl-thread-entity-get-parent entity))) + ;;(setq children (wl-thread-entity-get-children entity)) + (setq children-num (wl-thread-entity-get-children-num entity)) + (setq overview-entity + (elmo-msgdb-search-overview-entity msg + number-alist overview)) + ;;(wl-delete-all-overlays) + (when overview-entity + (setq summary-line + (wl-summary-overview-create-summary-line + msg + overview-entity + (assoc ; parent-entity + (cdr (assq parent-msg + number-alist)) overview) + nil + mark-alist + (if wl-thread-insert-force-opened + nil + (if (not (wl-thread-entity-get-opened entity)) + (or children-num))) + temp-mark entity)) + (wl-summary-insert-line summary-line)))) + +(defun wl-thread-update-line-on-buffer (&optional msg parent-msg updates) + (interactive) + (let ((msgs (list (or msg (wl-summary-message-number)))) + entity children msgs-stack) + (while msgs + (setq msg (wl-pop msgs)) + (setq updates (and updates (delete msg updates))) + (when (wl-thread-delete-line-from-buffer msg) + (setq entity (wl-thread-get-entity msg)) + (wl-thread-update-line-on-buffer-sub entity msg parent-msg) + ;; + (setq children (wl-thread-entity-get-children entity)) + (if children + ;; update children + (when (wl-thread-entity-get-opened entity) + (wl-push msgs msgs-stack) + (setq parent-msg msg + msgs children)) + (unless msgs + (while (and (null msgs) msgs-stack) + (setq msgs (wl-pop msgs-stack))) + (when msgs + (setq parent-msg + (wl-thread-entity-get-number + (wl-thread-entity-get-parent-entity + (wl-thread-get-entity (car msgs)))))))))) + updates)) + +(defun wl-thread-delete-line-from-buffer (msg) + "Simply delete msg line." + (let (beg) + (if (wl-summary-jump-to-msg msg) + (progn + (setq beg (point)) + (forward-line 1) + (delete-region beg (point)) + t) + nil))) + +(defun wl-thread-cleanup-symbols (msgs) + (let (sym) + (while msgs + ;; free symbol. + (when (boundp (setq sym (intern (format "#%d" (car msgs)) + wl-thread-entity-hashtb))) + ;; delete entity. + (setq wl-thread-entities + (delq (wl-thread-get-entity (car msgs)) + wl-thread-entities)) + (makunbound sym)) + (setq msgs (cdr msgs))))) + +(defun wl-thread-delete-message (msg &optional update) + "Delete MSG from entity and buffer." + (save-excursion + (let* ((entity (wl-thread-get-entity msg)) + children children2 + older-brothers younger-brothers ;;brothers + parent num) + (when entity + (setq parent (wl-thread-entity-get-parent-entity entity)) + (if parent + (progn + ;; has parent. + ;;(setq brothers (wl-thread-entity-get-children parent)) + (setq older-brothers (wl-thread-entity-get-older-brothers + entity parent)) + (setq younger-brothers (wl-thread-entity-get-younger-brothers + entity parent)) + ;; + (setq children (wl-thread-entity-get-children entity)) + (mapcar '(lambda (x) + (wl-thread-entity-set-parent + (wl-thread-get-entity x) + (wl-thread-entity-get-number parent))) + children) + (wl-thread-entity-set-children + parent + (append + (append + older-brothers + children) + younger-brothers))) + ;; top...children becomes top. + (mapcar '(lambda (x) + (wl-thread-entity-set-parent (wl-thread-get-entity x) + nil)) + (setq children (wl-thread-entity-get-children entity))) + ;; delete myself from top list. + (setq older-brothers (wl-thread-entity-get-older-brothers + entity nil)) + (setq younger-brothers (wl-thread-entity-get-younger-brothers + entity nil)) + (setq wl-thread-entity-list + (append (append older-brothers children) + younger-brothers)))) + + ;; delete myself from buffer. + (unless (wl-thread-delete-line-from-buffer msg) + ;; jump to suitable point. + ;; just upon the oldest younger-brother of my top. + (let ((younger-bros (wl-thread-entity-get-younger-brothers + (wl-thread-entity-get-top-entity entity) + nil))) + (if younger-bros + (wl-summary-jump-to-msg (car younger-bros)) + (goto-char (point-max)))) ; no younger brothers. + ) + ;; insert children if thread is closed. + (when (not (wl-thread-entity-get-opened entity)) + (setq children2 children) + (while children2 + (wl-thread-insert-entity 0 ; no mean now... + (wl-thread-get-entity + (car children2)) + entity nil) + (setq children2 (cdr children2)))) + (if update + ;; modify buffer. + (progn + (if parent + ;; update parent on buffer. + (progn + (setq num (wl-thread-entity-get-number parent)) + (when num + (wl-thread-update-line-on-buffer num))) + ;; update children lines on buffer. + (mapcar '(lambda (x) + (wl-thread-update-line-on-buffer + x + (wl-thread-entity-get-number parent))) + children))) + ;; don't update buffer + (if parent + ;; return parent number + (list (wl-thread-entity-get-number parent)) + children)) + ;; update the indent string +; (wl-summary-goto-top-of-current-thread) +; (setq beg (point)) +; (wl-thread-goto-bottom-of-sub-thread) +; (wl-thread-update-indent-string-region beg (point))) + ))) + + +(defun wl-thread-insert-message (overview-entity overview mark-alist + msg parent-msg &optional update) + "Insert MSG to the entity. +When optional argument UPDATE is non-nil, +Message is inserted to the summary buffer." + (let ((parent (wl-thread-get-entity parent-msg)) + child-entity invisible-top) +;; Update the thread view...not implemented yet. +; (when force-insert +; (if parent +; (wl-thread-entity-force-open parent)) + (if parent + ;; insert as children. + (wl-thread-entity-insert-as-children + parent + (setq child-entity (wl-thread-create-entity msg (nth 0 parent)))) + ;; insert as top message. + (wl-thread-entity-insert-as-top + (wl-thread-create-entity msg nil))) + (if update + (if (not (setq invisible-top + (wl-thread-entity-parent-invisible-p child-entity))) + ;; visible. + (progn + (wl-summary-update-thread + overview-entity + overview + mark-alist + child-entity + (elmo-msgdb-overview-get-entity-by-number overview parent-msg)) + (when parent + ;; use thread structure. + (wl-thread-entity-get-number + (wl-thread-entity-get-top-entity parent)))); return value; +;; (setq beg (point)) +;; (wl-thread-goto-bottom-of-sub-thread) +;; (wl-thread-update-indent-string-region beg (point))) + ;; currently invisible.. update closed line. + (wl-thread-update-children-number invisible-top) + nil)))) + +(defun wl-thread-update-indent-string-thread (top-list) + (let (beg) + (while top-list + (wl-summary-jump-to-msg (car top-list)) + (setq beg (point)) + (wl-thread-goto-bottom-of-sub-thread) + (wl-thread-update-indent-string-region beg (point)) + (setq top-list (cdr top-list))))) + +(defun wl-thread-update-children-number (entity) + "Update the children number." + (save-excursion + (wl-summary-jump-to-msg (wl-thread-entity-get-number entity)) + (beginning-of-line) + (let ((text-prop (get-text-property (point) 'face)) + from from-end beg str) + (cond + ((looking-at (concat "^" wl-summary-buffer-number-regexp + "..../..\(.*\)..:.. [" + wl-thread-indent-regexp + "]*\\[\\+\\([0-9]+\\):")) + (delete-region (match-beginning 1)(match-end 1)) + (goto-char (match-beginning 1)) + (setq str (format "%s" (wl-thread-entity-get-children-num entity))) + (if wl-summary-highlight + (put-text-property 0 (length str) 'face text-prop str)) + (insert str)) + ((looking-at (concat "^" wl-summary-buffer-number-regexp + "..../..\(.*\)..:.. [" + wl-thread-indent-regexp + "]*\\[")) + (goto-char (match-end 0)) + (setq beg (current-column)) + (setq from-end (save-excursion + (move-to-column (+ 1 beg wl-from-width)) + (point))) + (setq from (buffer-substring (match-end 0) from-end)) + (delete-region (match-end 0) from-end) + (setq str (wl-set-string-width + (1+ wl-from-width) + (format + "+%s:%s" + (wl-thread-entity-get-children-num + entity) + from))) + (if wl-summary-highlight + (put-text-property 0 (length str) 'face text-prop str)) + (insert str) + (condition-case nil ; it's dangerous, so ignore error. + (run-hooks 'wl-thread-update-children-number-hook) + (error + (ding) + (message "Error in wl-thread-update-children-number-hook.")))))))) + +;; +;; Thread oriented commands. +;; +(defun wl-thread-call-region-func (func &optional arg) + (save-excursion + (if arg + (wl-summary-goto-top-of-current-thread) + (beginning-of-line)) + (let ((beg (point))) + (wl-thread-goto-bottom-of-sub-thread) + (funcall func beg (point))))) + +(defun wl-thread-prefetch (&optional arg) + (interactive "P") + (wl-thread-call-region-func 'wl-summary-prefetch-region arg)) + +(defun wl-thread-msg-mark-as-read (msg) + "Set mark as read for invisible MSG. Modeline is not changed." + (let* ((msgdb wl-summary-buffer-msgdb) + (mark-alist (elmo-msgdb-get-mark-alist msgdb)) + cur-mark) + (setq cur-mark (cadr (assq msg mark-alist))) + (cond ((or (string= cur-mark wl-summary-new-mark) + (string= cur-mark wl-summary-unread-uncached-mark)) + ;; N,U -> u or " " + (setq mark-alist + (elmo-msgdb-mark-set mark-alist + msg + (if (elmo-use-cache-p + wl-summary-buffer-folder-name + msg) + wl-summary-read-uncached-mark))) + (elmo-msgdb-set-mark-alist msgdb mark-alist) + (wl-summary-set-mark-modified)) + ((string= cur-mark wl-summary-unread-cached-mark) + ;; "!" -> " " + (setq mark-alist (elmo-msgdb-mark-set mark-alist msg nil)) + (elmo-msgdb-set-mark-alist msgdb mark-alist) + (wl-summary-set-mark-modified))))) + +(defun wl-thread-msg-mark-as-unread (msg) + "Set mark as unread for invisible MSG. Modeline is not changed." + (let* ((msgdb wl-summary-buffer-msgdb) + (mark-alist (elmo-msgdb-get-mark-alist msgdb)) + cur-mark) + (setq cur-mark (cadr (assq msg mark-alist))) + (cond ((string= cur-mark wl-summary-read-uncached-mark) + ;; u -> U + (setq mark-alist + (elmo-msgdb-mark-set mark-alist + msg + wl-summary-unread-uncached-mark)) + (elmo-msgdb-set-mark-alist msgdb mark-alist) + (wl-summary-set-mark-modified)) + ((null cur-mark) + ;; " " -> "!" + (setq mark-alist (elmo-msgdb-mark-set mark-alist msg + wl-summary-unread-cached-mark)) + (elmo-msgdb-set-mark-alist msgdb mark-alist) + (wl-summary-set-mark-modified))))) + +(defun wl-thread-msg-mark-as-important (msg) + "Set mark as important for invisible MSG. Modeline is not changed." + (let* ((msgdb wl-summary-buffer-msgdb) + (mark-alist (elmo-msgdb-get-mark-alist msgdb)) + cur-mark) + (setq cur-mark (cadr (assq msg mark-alist))) + (setq mark-alist + (elmo-msgdb-mark-set mark-alist + msg + (if (string= cur-mark wl-summary-important-mark) + nil + wl-summary-important-mark))) + (elmo-msgdb-set-mark-alist msgdb mark-alist) + (wl-summary-set-mark-modified))) + +(defun wl-thread-mark-as-read (&optional arg) + (interactive "P") + (wl-thread-call-region-func 'wl-summary-mark-as-read-region arg)) + +(defun wl-thread-mark-as-unread (&optional arg) + (interactive "P") + (wl-thread-call-region-func 'wl-summary-mark-as-unread-region arg)) + +(defun wl-thread-mark-as-important (&optional arg) + (interactive "P") + (wl-thread-call-region-func 'wl-summary-mark-as-important-region arg)) + +(defun wl-thread-copy (&optional arg) + (interactive "P") + (wl-thread-call-region-func 'wl-summary-copy-region arg)) + +(defun wl-thread-refile (&optional arg) + (interactive "P") + (condition-case err + (progn + (wl-thread-call-region-func 'wl-summary-refile-region arg) + (if arg + (wl-summary-goto-top-of-current-thread)) + (wl-thread-goto-bottom-of-sub-thread)) + (error + (elmo-display-error err t) + nil))) + +(defun wl-thread-delete (&optional arg) + (interactive "P") + (wl-thread-call-region-func 'wl-summary-delete-region arg) + (if arg + (wl-summary-goto-top-of-current-thread)) + (if (not wl-summary-move-direction-downward) + (wl-summary-prev) + (wl-thread-goto-bottom-of-sub-thread) + (if wl-summary-buffer-disp-msg + (wl-summary-redisplay)))) + +(defun wl-thread-target-mark (&optional arg) + (interactive "P") + (wl-thread-call-region-func 'wl-summary-target-mark-region arg)) + +(defun wl-thread-unmark (&optional arg) + (interactive "P") + (wl-thread-call-region-func 'wl-summary-unmark-region arg)) + +(defun wl-thread-exec (&optional arg) + (interactive "P") + (wl-thread-call-region-func 'wl-summary-exec-region arg)) + +(defun wl-thread-save (&optional arg) + (interactive "P") + (wl-thread-call-region-func 'wl-summary-save-region arg)) + +(defun wl-thread-force-open (&optional msg-num) + "force open current folder" + (if msg-num + (wl-summary-jump-to-msg msg-num)) + (let ((wl-thread-insert-force-opened t)) + (wl-thread-open-close))) + +(defun wl-thread-entity-force-open (entity) + (let ((wl-thread-insert-force-opened t) + notopen) + (if (null (wl-thread-entity-get-parent entity)) + ;; top!! + (if (and (not (wl-thread-entity-get-opened entity)) + (wl-thread-entity-get-children entity)) + (wl-thread-force-open (wl-thread-entity-get-number entity))) + (if (setq notopen (wl-thread-entity-parent-invisible-p entity)) + (wl-thread-force-open (wl-thread-entity-get-number notopen)))))) + +(defun wl-thread-insert-top () + (let ((elist wl-thread-entity-list) + (len (length wl-thread-entity-list)) + (cur 0)) + (wl-delete-all-overlays) + (while elist + (wl-thread-insert-entity + 0 + (wl-thread-get-entity (car elist)) + nil + len) + (setq cur (1+ cur)) + (elmo-display-progress + 'wl-thread-insert-top "Inserting thread..." + (/ (* cur 100) len)) + (setq elist (cdr elist))))) + +(defsubst wl-thread-insert-entity-sub (indent entity parent-entity all) + (let ((number-alist (elmo-msgdb-get-number-alist wl-summary-buffer-msgdb)) + (overview (elmo-msgdb-get-overview wl-summary-buffer-msgdb)) + (mark-alist (elmo-msgdb-get-mark-alist wl-summary-buffer-msgdb)) + msg-num + overview-entity + temp-mark + children-num + summary-line + score) + (when (setq msg-num (wl-thread-entity-get-number entity)) + (unless all ; all...means no temp-mark. + (cond ((memq msg-num wl-summary-buffer-delete-list) + (setq temp-mark "D")) + ((memq msg-num wl-summary-buffer-target-mark-list) + (setq temp-mark "*")) + ((assq msg-num wl-summary-buffer-refile-list) + (setq temp-mark "o")) + ((assq msg-num wl-summary-buffer-copy-list) + (setq temp-mark "O")))) + (unless temp-mark + (setq temp-mark (wl-summary-get-score-mark msg-num))) + (setq children-num (wl-thread-entity-get-children-num entity)) + (setq overview-entity + (elmo-msgdb-search-overview-entity + (nth 0 entity) number-alist overview)) + ;;(wl-delete-all-overlays) + (when overview-entity + (setq summary-line + (wl-summary-overview-create-summary-line + msg-num + overview-entity + (assoc ; parent-entity + (cdr (assq (nth 0 parent-entity) + number-alist)) overview) + (1+ indent) + mark-alist + (if wl-thread-insert-force-opened + nil + (if (not (wl-thread-entity-get-opened entity)) + (or children-num))) + temp-mark entity)) + (wl-summary-insert-line summary-line))))) + +(defun wl-thread-insert-entity (indent entity parent-entity all) + "Insert thread entity in current buffer." + (let ((msgs (list (car entity))) + children msgs-stack) + (while msgs + (wl-thread-insert-entity-sub indent entity parent-entity all) + (setq msgs (cdr msgs)) + (setq children (nth 2 entity)) + (if children + ;; insert children + (when (or wl-thread-insert-force-opened + (wl-thread-entity-get-opened entity)) + (wl-thread-entity-set-opened entity t) + (wl-push msgs msgs-stack) + (setq msgs children + indent (1+ indent) + parent-entity entity))) + (unless msgs + (while (and (null msgs) msgs-stack) + (setq msgs (wl-pop msgs-stack)) + (setq indent (1- indent))) + (when msgs + (setq entity (wl-thread-get-entity (car msgs))) + (setq parent-entity (wl-thread-entity-get-parent-entity entity)))) + (setq entity (wl-thread-get-entity (car msgs)))))) + +(defun wl-thread-descendant-p (mynumber number) + (let ((cur (wl-thread-get-entity number)) + num) + (catch 'done + (while cur + (setq cur (wl-thread-entity-get-parent-entity cur)) + (if (null (setq num (wl-thread-entity-get-number cur))) ; top! + (throw 'done nil)) + (if (and num + (eq mynumber (wl-thread-entity-get-number cur))) + (throw 'done t))) + nil))) + +; (defun wl-thread-goto-bottom-of-sub-thread () +; (interactive) +; (let ((depth (wl-thread-get-depth-of-current-line))) +; (forward-line 1) +; (while (and (not (eobp)) +; (> (wl-thread-get-depth-of-current-line) +; depth)) +; (forward-line 1)) +; (beginning-of-line))) + +(defun wl-thread-goto-bottom-of-sub-thread (&optional msg) + (interactive) + (let ((mynumber (or msg (wl-summary-message-number)))) + (forward-line 1) + (while (wl-thread-descendant-p mynumber (wl-summary-message-number)) + (forward-line 1)) + (beginning-of-line))) + +(defun wl-thread-remove-destination-region (beg end) + (save-excursion + (save-restriction + (narrow-to-region beg end) + (goto-char (point-min)) + (while (not (eobp)) + (let ((num (wl-summary-message-number))) + (if (assq num wl-summary-buffer-refile-list) + (wl-summary-remove-destination))) + (forward-line 1))))) + +(defun wl-thread-print-destination-region (beg end) + (if (or wl-summary-buffer-refile-list + wl-summary-buffer-copy-list) + (save-excursion + (save-restriction + (narrow-to-region beg end) + (goto-char (point-min)) + (while (not (eobp)) + (let ((num (wl-summary-message-number)) + pair) + (if (or (setq pair (assq num wl-summary-buffer-refile-list)) + (setq pair (assq num wl-summary-buffer-copy-list))) + (wl-summary-print-destination (car pair) (cdr pair)))) + (forward-line 1)))))) + +(defsubst wl-thread-get-children-msgs (msg) + (let ((msgs (list msg)) + msgs-stack children + ret-val) + (while msgs + (wl-append ret-val (list (car msgs))) + (setq children (wl-thread-entity-get-children + (wl-thread-get-entity (car msgs)))) + (setq msgs (cdr msgs)) + (if (null children) + (while (and (null msgs) msgs-stack) + (setq msgs (wl-pop msgs-stack))) + (wl-push msgs msgs-stack) + (setq msgs children))) + ret-val)) + +(defun wl-thread-get-children-msgs-uncached (msg &optional uncached-marks) + (let ((children-msgs (wl-thread-get-children-msgs msg)) + (mark-alist (elmo-msgdb-get-mark-alist wl-summary-buffer-msgdb)) + (number-alist (elmo-msgdb-get-number-alist wl-summary-buffer-msgdb)) + mark + uncached-list) + (while children-msgs + (if (and (not (eq msg (car children-msgs))) ; except itself + (or (and uncached-marks + (setq mark (cadr (assq (car children-msgs) + mark-alist))) + (member mark uncached-marks)) + (and (not uncached-marks) + (null (elmo-cache-exists-p + (cdr (assq (car children-msgs) + number-alist))))))) + (wl-append uncached-list (list (car children-msgs)))) + (setq children-msgs (cdr children-msgs))) + uncached-list)) + +(defun wl-thread-get-children-msgs-with-mark (msg mark) + (let ((children-msgs (wl-thread-get-children-msgs msg)) + (check-func (cond ((string= mark "o") + 'wl-summary-msg-marked-as-refiled) + ((string= mark "O") + 'wl-summary-msg-marked-as-copied) + ((string= mark "D") + 'wl-summary-msg-marked-as-deleted) + ((string= mark "*") + 'wl-summary-msg-marked-as-target))) + ret-val) + (while children-msgs + (if (funcall check-func (car children-msgs)) + (wl-append ret-val (list (car children-msgs)))) + (setq children-msgs (cdr children-msgs))) + ret-val)) + +(defun wl-thread-close (entity) + (let (depth beg) + (wl-thread-entity-set-opened entity nil) + (setq depth (wl-thread-get-depth-of-current-line)) + (beginning-of-line) + (setq beg (point)) + (wl-thread-goto-bottom-of-sub-thread) + (wl-thread-remove-destination-region beg + (point)) + (forward-char -1) ;; needed for mouse-face. + (delete-region beg (point)) + (wl-thread-insert-entity (- depth 1) + entity + (wl-thread-get-entity + (nth 3 entity)) + nil) + (delete-char 1) ; delete '\n' + (wl-thread-print-destination-region beg (point)))) + +(defun wl-thread-open (entity) + (let (depth beg) + (beginning-of-line) + (setq beg (point)) + (setq depth (wl-thread-get-depth-of-current-line)) + (end-of-line) + (delete-region beg (point)) + (wl-thread-entity-set-opened entity t) + (wl-thread-insert-entity depth ;(- depth 1) + entity + (wl-thread-get-entity + (nth 3 entity)) nil) + (delete-char 1) ; delete '\n' + (wl-thread-print-destination-region beg (point)))) + +(defun wl-thread-open-close (&optional force-open) + (interactive "P") + (when (eq wl-summary-buffer-view 'thread) + ;(if (equal wl-thread-top-entity '(nil t nil nil)) + ;(error "There's no thread structure.")) + (save-excursion + (let ((inhibit-read-only t) + (buffer-read-only nil) + (wl-thread-insert-force-opened + (or wl-thread-insert-force-opened + force-open)) + msg entity beg depth parent) + (setq msg (wl-summary-message-number)) + (setq entity (wl-thread-get-entity msg)) + (if (wl-thread-entity-get-opened entity) + ;; if already opened, close its child! + (if (wl-thread-entity-get-children entity) + (wl-thread-close entity) + ;; opened, but has no children, close its parent! + (when (setq parent (wl-thread-entity-get-parent entity)) + (wl-summary-jump-to-msg parent) + (wl-thread-close + (wl-thread-get-entity (wl-summary-message-number))))) + ;; if closed (or it is just a thread bottom message) + ;; has children, open it! + (if (wl-thread-entity-get-children entity) + (wl-thread-open entity) + ;; closed, and has no children, close its parent! + (setq msg (or (wl-thread-entity-get-parent entity) + (wl-thread-entity-get-number entity))) + (when msg + (wl-summary-jump-to-msg msg) + (wl-thread-close + (wl-thread-get-entity (wl-summary-message-number))))))) + (wl-summary-set-message-modified) + (set-buffer-modified-p nil)))) + + +(defun wl-thread-get-depth-of-current-line () + (interactive) + (save-excursion + (beginning-of-line) + (let ((depth 0)) + (if (re-search-forward (concat "^" wl-summary-buffer-number-regexp + "..../..\(.*\)..:.. ") + nil t) + (while (string-match wl-thread-indent-regexp + (char-to-string + (char-after (point)))) + (setq depth (1+ depth)) + (forward-char))) + (/ depth wl-thread-indent-level-internal)))) + +(defun wl-thread-update-indent-string-region (beg end) + (interactive "r") + (save-excursion + (goto-char beg) + (while (< (point) end) + (wl-thread-update-indent-string) + (forward-line 1)))) + +(defsubst wl-thread-make-indent-string (entity) + (let ((cur entity) + (ret-val "") + (space-str (wl-repeat-string wl-thread-space-str-internal + (- wl-thread-indent-level-internal 1))) + parent) + (when (wl-thread-entity-get-number + (setq parent (wl-thread-entity-get-parent-entity cur))) + (if (wl-thread-entity-get-younger-brothers cur) + (setq ret-val wl-thread-have-younger-brother-str-internal) + (setq ret-val wl-thread-youngest-child-str-internal)) + (setq ret-val (concat ret-val + (wl-repeat-string + wl-thread-horizontal-str-internal + (- wl-thread-indent-level-internal 1)))) + (setq cur parent) + (while (wl-thread-entity-get-number + (wl-thread-entity-get-parent-entity cur)) + (if (wl-thread-entity-get-younger-brothers cur) + (setq ret-val (concat wl-thread-vertical-str-internal + space-str + ret-val)) + (setq ret-val (concat wl-thread-space-str-internal + space-str + ret-val))) + (setq cur (wl-thread-entity-get-parent-entity cur)))) + ret-val)) + +(defun wl-thread-update-indent-string () + "Update indent string of current line." + (interactive) + (save-excursion + (beginning-of-line) + (let ((inhibit-read-only t) + (buffer-read-only nil) + thr-str) + (when (looking-at (concat "^ *\\([0-9]+\\)" + "..../..\(.*\)..:.. \\(" + wl-highlight-thread-indent-string-regexp + "\\)\\[")) + (goto-char (match-beginning 2)) + (delete-region (match-beginning 2) + (match-end 2)) + (setq thr-str + (wl-thread-make-indent-string + (wl-thread-get-entity (string-to-int (wl-match-buffer 1))))) + (if (and wl-summary-width + wl-summary-indent-length-limit + (< wl-summary-indent-length-limit + (string-width thr-str))) + (setq thr-str (wl-set-string-width + wl-summary-indent-length-limit + thr-str))) + (insert thr-str) + (if wl-summary-highlight + (wl-highlight-summary-current-line)))))) + +(provide 'wl-thread) + +;;; wl-thread.el ends here diff --git a/wl/wl-util.el b/wl/wl-util.el new file mode 100644 index 0000000..0102e10 --- /dev/null +++ b/wl/wl-util.el @@ -0,0 +1,820 @@ +;;; wl-util.el -- Utility modules for Wanderlust. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <2000-03-22 15:56:12 teranisi> + +;; This file is part of Wanderlust (Yet Another Message Interface on Emacsen). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; + +(provide 'wl-util) +(eval-when-compile + (provide 'elmo-util)) + +(condition-case () + (require 'tm-edit) + (error)) +(condition-case () + (require 'pp) + (error)) +(eval-when-compile + (mapcar + (function + (lambda (symbol) + (unless (boundp symbol) + (set (make-local-variable symbol) nil)))) + '(mule-version + nemacs-version + emacs-beta-version + xemacs-codename + mime-edit-insert-user-agent-field + mime-edit-user-agent-value + mime-editor/version + mime-editor/codename)) + (require 'time-stamp) + (defun-maybe read-event ()) + (defun-maybe next-command-event ()) + (defun-maybe event-to-character (a)) + (defun-maybe key-press-event-p (a)) + (defun-maybe button-press-event-p (a)) + (defun-maybe set-process-kanji-code (a b)) + (defun-maybe set-process-coding-system (a b c)) + (defun-maybe dispatch-event (a))) + +(defalias 'wl-set-work-buf 'elmo-set-work-buf) +(make-obsolete 'wl-set-work-buf 'elmo-set-work-buf) + +(defmacro wl-append (val func) + (list 'if val + (list 'nconc val func) + (list 'setq val func))) + +(defun wl-parse (string regexp &optional matchn) + (or matchn (setq matchn 1)) + (let (list) + (store-match-data nil) + (while (string-match regexp string (match-end 0)) + (setq list (cons (substring string (match-beginning matchn) + (match-end matchn)) list))) + (nreverse list))) + +(defun wl-delete-duplicates (list &optional all hack-addresses) + "Delete duplicate equivalent strings from the list. +If ALL is t, then if there is more than one occurrence of a string in the list, + then all occurrences of it are removed instead of just the subsequent ones. +If HACK-ADDRESSES is t, then the strings are considered to be mail addresses, + and only the address part is compared (so that \"Name \" and \"foo\" + would be considered to be equivalent.)" + (let ((hashtable (make-vector 29 0)) + (new-list nil) + sym-string sym) + (fillarray hashtable 0) + (while list + (setq sym-string + (if hack-addresses + (wl-address-header-extract-address (car list)) + (car list)) + sym-string (or sym-string "-unparseable-garbage-") + sym (intern sym-string hashtable)) + (if (boundp sym) + (and all (setcar (symbol-value sym) nil)) + (setq new-list (cons (car list) new-list)) + (set sym new-list)) + (setq list (cdr list))) + (delq nil (nreverse new-list)))) + +;; string utils. +(defalias 'wl-string-member 'elmo-string-member) +(defalias 'wl-string-match-member 'elmo-string-match-member) +(defalias 'wl-string-delete-match 'elmo-string-delete-match) +(defalias 'wl-string-match-assoc 'elmo-string-match-assoc) +(defalias 'wl-string-assoc 'elmo-string-assoc) +(defalias 'wl-string-rassoc 'elmo-string-rassoc) + +(defun wl-parse-addresses (string) + (if (null string) + () + (elmo-set-work-buf + ;;(unwind-protect + (let (list start s char) + (insert string) + (goto-char (point-min)) + (skip-chars-forward "\t\f\n\r ") + (setq start (point)) + (while (not (eobp)) + (skip-chars-forward "^\"\\,(") + (setq char (following-char)) + (cond ((= char ?\\) + (forward-char 1) + (if (not (eobp)) + (forward-char 1))) + ((= char ?,) + (setq s (buffer-substring start (point))) + (if (or (null (string-match "^[\t\f\n\r ]+$" s)) + (not (string= s ""))) + (setq list (cons s list))) + (skip-chars-forward ",\t\f\n\r ") + (setq start (point))) + ((= char ?\") + (re-search-forward "[^\\]\"" nil 0)) + ((= char ?\() + (let ((parens 1)) + (forward-char 1) + (while (and (not (eobp)) (not (zerop parens))) + (re-search-forward "[()]" nil 0) + (cond ((or (eobp) + (= (char-after (- (point) 2)) ?\\))) + ((= (preceding-char) ?\() + (setq parens (1+ parens))) + (t + (setq parens (1- parens))))))))) + (setq s (buffer-substring start (point))) + (if (and (null (string-match "^[\t\f\n\r ]+$" s)) + (not (string= s ""))) + (setq list (cons s list))) + (nreverse list)) ; jwz: fixed order + ))) + +(defun wl-version (&optional with-codename) + (format "%s %s%s" wl-appname wl-version + (if with-codename + (format " - \"%s\"" wl-codename) ""))) + +(defun wl-version-show () + (interactive) + (message "%s" (wl-version t))) + +;; from gnus +(defun wl-extended-emacs-version (&optional with-codename) + "Stringified Emacs version" + (interactive) + (cond + ((string-match "^\\([0-9]+\\.[0-9]+\\)\\.[.0-9]+$" emacs-version) + (concat "Emacs " (wl-match-string 1 emacs-version) + (and (boundp 'mule-version)(concat "/Mule " mule-version)))) + ((string-match "\\([A-Z]*[Mm][Aa][Cc][Ss]\\)[^(]*\\(\\((beta.*)\\|'\\)\\)?" + emacs-version) + (concat (wl-match-string 1 emacs-version) + (format " %d.%d" emacs-major-version emacs-minor-version) + (if (and (boundp 'emacs-beta-version) + emacs-beta-version) + (format "b%d" emacs-beta-version)) + (if with-codename + (if (boundp 'xemacs-codename) + (concat " - \"" xemacs-codename "\""))))) + (t emacs-version))) + +(defun wl-extended-emacs-version2 (&optional delimiter with-codename) + "Stringified Emacs version" + (interactive) + (cond + ((and (boundp 'mule-version) + mule-version + (string-match "\\([0-9]+\.[0-9]+\\)\\(.*$\\)" mule-version)) + (format "Mule%s%s@%d.%d%s" + (or delimiter " ") + (wl-match-string 1 mule-version) + emacs-major-version + emacs-minor-version + (if with-codename + (wl-match-string 2 mule-version) + ""))) + ((string-match "^\\([0-9]+\\.[0-9]+\\)\\.[.0-9]+$" emacs-version) + (if (boundp 'nemacs-version) + (concat "Nemacs" (or delimiter " ") + nemacs-version + "@" + (substring emacs-version + (match-beginning 1) + (match-end 1))) + (concat "Emacs" (or delimiter " ") + (wl-match-string 1 emacs-version)))) + ((string-match "\\([A-Z]*[Mm][Aa][Cc][Ss]\\)[^(]*\\(\\((beta.*)\\|'\\)\\)?" + emacs-version) + (concat (wl-match-string 1 emacs-version) + (or delimiter " ") + (format "%d.%d" emacs-major-version emacs-minor-version) + (if (and (boundp 'emacs-beta-version) + emacs-beta-version) + (format "b%d" emacs-beta-version)) + (if (and with-codename + (boundp 'xemacs-codename) + xemacs-codename) + (format " (%s)" xemacs-codename)))) + (t emacs-version))) + +(defun wl-extended-emacs-version3 (&optional delimiter with-codename) + "Stringified Emacs version" + (interactive) + (cond + ((and (boundp 'mule-version) + mule-version + (string-match "\\([0-9]+\.[0-9]+\\)\\(.*$\\)" mule-version)) + (format "Emacs%s%d.%d Mule%s%s%s" + (or delimiter " ") + emacs-major-version + emacs-minor-version + (or delimiter " ") + (wl-match-string 1 mule-version) + (if with-codename + (wl-match-string 2 mule-version) + ""))) + ((string-match "^\\([0-9]+\\.[0-9]+\\)\\.[.0-9]+$" emacs-version) + (if (boundp 'nemacs-version) + (let ((nemacs-codename-assoc '(("3.3.2" . " (FUJIMUSUME)") + ("3.3.1" . " (HINAMATSURI)") + ("3.2.3" . " (YUMENO-AWAYUKI)")))) + (format "Emacs%s%s Nemacs%s%s%s" + (or delimiter " ") + (wl-match-string 1 emacs-version) + (or delimiter " ") + nemacs-version + (or (and with-codename + (cdr (assoc nemacs-version + nemacs-codename-assoc))) + ""))) + (concat "Emacs" (or delimiter " ") + (wl-match-string 1 emacs-version)))) + ((string-match "\\([A-Z]*[Mm][Aa][Cc][Ss]\\)[^(]*\\(\\((beta.*)\\|'\\)\\)?" + emacs-version) + (concat (wl-match-string 1 emacs-version) + (or delimiter " ") + (format "%d.%d" emacs-major-version emacs-minor-version) + (if (and (boundp 'emacs-beta-version) + emacs-beta-version) + (format "b%d" emacs-beta-version)) + (if (and with-codename + (boundp 'xemacs-codename) + xemacs-codename) + (format " (%s)" xemacs-codename)))) + (t emacs-version))) + +(defun wl-append-element (list element) + (if element + (append list (list element)) + list)) + +(defun wl-read-event-char () + "Get the next event." + (let ((event (read-event))) + ;; should be gnus-characterp, but this can't be called in XEmacs anyway + (cons (and (numberp event) event) event))) + +(defun wl-xmas-read-event-char () + "Get the next event." + (let ((event (next-command-event))) + (sit-for 0) + ;; We junk all non-key events. Is this naughty? + (while (not (or (key-press-event-p event) + (button-press-event-p event))) + (dispatch-event event) + (setq event (next-command-event))) + (cons (and (key-press-event-p event) + (event-to-character event)) + event))) + +(if running-xemacs + (fset 'wl-read-event-char 'wl-xmas-read-event-char)) + +(defmacro wl-push (v l) + (list 'setq l (list 'cons v l))) + +(defmacro wl-pop (l) + (list 'car (list 'prog1 l (list 'setq l (list 'cdr l))))) + +(defun wl-ask-folder (func mes-string) + (let* (key keve + (cmd (if (featurep 'xemacs) + (event-to-character last-command-event) + (string-to-char (format "%s" (this-command-keys)))))) + (message mes-string) + (setq key (car (setq keve (wl-read-event-char)))) + (if (or (equal key ?\ ) + (and cmd + (equal key cmd))) + (progn + (message "") + (funcall func)) + (wl-push (cdr keve) unread-command-events)))) + +;(defalias 'wl-make-hash 'elmo-make-hash) +;(make-obsolete 'wl-make-hash 'elmo-make-hash) + +;(defalias 'wl-get-hash-val 'elmo-get-hash-val) +;(make-obsolete 'wl-get-hash-val 'elmo-get-hash-val) + +;(defalias 'wl-set-hash-val 'elmo-set-hash-val) +;(make-obsolete 'wl-set-hash-val 'elmo-set-hash-val) + +(defsubst wl-set-string-width (width string) + (elmo-set-work-buf + (elmo-set-buffer-multibyte default-enable-multibyte-characters) + (insert string) + (if (> (current-column) width) + (if (> (move-to-column width) width) + (progn + (condition-case nil ; ignore error + (backward-char 1) + (error)) + (concat (buffer-substring (point-min) (point)) " ")) + (buffer-substring (point-min) (point))) + (if (= (current-column) width) + string + (concat string + (format (format "%%%ds" + (- width (current-column))) + " ")))))) + +(defun wl-display-bytes (num) + (let (result remain) + (cond + ((> (setq result (/ num 1000000)) 0) + (setq remain (% num 1000000)) + (if (> remain 400000) + (setq result (+ 1 result))) + (format "%dM" result)) + ((> (setq result (/ num 1000)) 0) + (setq remain (% num 1000)) + (if (> remain 400) + (setq result (+ 1 result))) + (format "%dK" result)) + (t (format "%dB" result))))) + +(defun wl-generate-user-agent-string () + "A candidate of wl-generate-mailer-string-func. +Insert User-Agent field instead of X-Mailer field." + (let ((mime-user-agent (and (boundp 'mime-edit-insert-user-agent-field) + mime-edit-insert-user-agent-field + mime-edit-user-agent-value))) + (if mime-user-agent + (concat "User-Agent: " + wl-appname "/" wl-version + " (" wl-codename ") " + mime-user-agent) + (if (and (boundp 'mime-editor/version) + mime-editor/version) + (concat "User-Agent: " + wl-appname "/" wl-version + " (" wl-codename ") " + "tm/" mime-editor/version + (if (and (boundp 'mime-editor/codename) + mime-editor/codename) + (concat " (" mime-editor/codename ")")) + (if (and (boundp 'mime-library-product) + mime-library-product) + (concat " " (aref mime-library-product 0) + "/" + (mapconcat 'int-to-string + (aref mime-library-product 1) + ".") + " (" (aref mime-library-product 2) ")")) + (condition-case nil + (progn + (require 'apel-ver) + (concat " " (apel-version))) + (file-error nil)) + " " (wl-extended-emacs-version3 "/" t)) + (concat "User-Agent: " wl-appname "/" wl-version " (" wl-codename ") " + (wl-extended-emacs-version3 "/" t)))))) + +(defun wl-make-modeline-subr () + (let* ((duplicated (copy-sequence mode-line-format)) + (cur-entry duplicated) + return-modeline) + (if (memq 'wl-plug-state-indicator mode-line-format) + duplicated + (catch 'done + (while cur-entry + (if (or (and (symbolp (car cur-entry)) + (eq 'mode-line-buffer-identification + (car cur-entry))) + (and (consp (car cur-entry)) + (or + (eq 'modeline-buffer-identification + (car (car cur-entry))) + (eq 'modeline-buffer-identification + (cdr (car cur-entry)))))) + (progn + (setq return-modeline (append return-modeline + (list 'wl-plug-state-indicator) + cur-entry)) + (throw 'done return-modeline)) + (setq return-modeline (append return-modeline + (list (car cur-entry))))) + (setq cur-entry (cdr cur-entry))))))) + +(defalias 'wl-display-error 'elmo-display-error) +(make-obsolete 'wl-display-error 'elmo-display-error) + +(defun wl-get-assoc-list-value (assoc-list folder &optional match) + (catch 'found + (let ((alist assoc-list) + value pair) + (while alist + (setq pair (car alist)) + (if (string-match (car pair) folder) + (cond ((eq match 'all) + (setq value (append value (list (cdr pair))))) + ((eq match 'all-list) + (setq value (append value (cdr pair)))) + ((not match) + (throw 'found (cdr pair))))) + (setq alist (cdr alist))) + value))) + +(defmacro wl-match-string (pos string) + "Substring POSth matched string." + (` (substring (, string) (match-beginning (, pos)) (match-end (, pos))))) + +(defmacro wl-match-buffer (pos) + "Substring POSth matched from the current buffer." + (` (buffer-substring-no-properties + (match-beginning (, pos)) (match-end (, pos))))) + +(put 'wl-as-coding-system 'lisp-indent-function 1) +(put 'wl-as-mime-charset 'lisp-indent-function 1) + +(eval-and-compile + (if wl-on-mule3 + (defmacro wl-as-coding-system (coding-system &rest body) + (` (let ((coding-system-for-read (, coding-system)) + (coding-system-for-write (, coding-system))) + (,@ body)))) + (if wl-on-mule + (defmacro wl-as-coding-system (coding-system &rest body) + (` (let ((file-coding-system-for-read (, coding-system)) + (file-coding-system (, coding-system))) + (,@ body)))) + (if wl-on-nemacs + (defmacro wl-as-coding-system (coding-system &rest body) + (` (let ((default-kanji-fileio-code (, coding-system)) + (kanji-fileio-code (, coding-system)) + kanji-expected-code) + (,@ body)))))))) + +(defmacro wl-as-mime-charset (mime-charset &rest body) + (` (wl-as-coding-system (mime-charset-to-coding-system (, mime-charset)) + (,@ body)))) + +(defalias 'wl-string 'elmo-string) +(make-obsolete 'wl-string 'elmo-string) + +(defun wl-parse-newsgroups (string &optional subscribe-only) + (let* ((nglist (wl-parse string "[ \t\f\r\n,]*\\([^ \t\f\r\n,]+\\)")) + spec ret-val) + (if (not subscribe-only) + nglist + (while nglist + (if (intern-soft (car nglist) wl-folder-newsgroups-hashtb) + (wl-append ret-val (list (car nglist)))) + (setq nglist (cdr nglist))) + ret-val))) + +;; Check if active region exists or not. +(if (boundp 'mark-active) + (defmacro wl-region-exists-p () + 'mark-active) + (if (fboundp 'region-exists-p) + (defmacro wl-region-exists-p () + (list 'region-exists-p)))) + +(if (not (fboundp 'overlays-in)) + (defun overlays-in (beg end) + "Return a list of the overlays that overlap the region BEG ... END. +Overlap means that at least one character is contained within the overlay +and also contained within the specified region. +Empty overlays are included in the result if they are located at BEG +or between BEG and END." + (let ((ovls (overlay-lists)) + tmp retval) + (if (< end beg) + (setq tmp end + end beg + beg tmp)) + (setq ovls (nconc (car ovls) (cdr ovls))) + (while ovls + (setq tmp (car ovls) + ovls (cdr ovls)) + (if (or (and (<= (overlay-start tmp) end) + (>= (overlay-start tmp) beg)) + (and (<= (overlay-end tmp) end) + (>= (overlay-end tmp) beg))) + (setq retval (cons tmp retval)))) + retval))) + +(defsubst wl-repeat-string (str times) + (let ((loop times) + ret-val) + (while (> loop 0) + (setq ret-val (concat ret-val str)) + (setq loop (- loop 1))) + ret-val)) + +(defun wl-list-diff (list1 list2) + "Return a list of elements of LIST1 that do not appear in LIST2." + (let ((list1 (copy-sequence list1))) + (while list2 + (setq list1 (delq (car list2) list1)) + (setq list2 (cdr list2))) + list1)) + +(defun wl-append-assoc-list (item value alist) + "make assoc list '((item1 value1-1 value1-2 ...)) (item2 value2-1 ...)))" + (let ((entry (assoc item alist))) + (if entry + (progn + (when (not (member value (cdr entry))) + (nconc entry (list value))) + alist) + (append alist + (list (list item value)))))) + +(defun wl-delete-alist (key alist) + "Delete all entries in ALIST that have a key eq to KEY." + (let (entry) + (while (setq entry (assq key alist)) + (setq alist (delq entry alist))) + alist)) + +(eval-when-compile + (require 'static)) +(static-unless (fboundp 'pp) + (defvar pp-escape-newlines t) + (defun pp (object &optional stream) + "Output the pretty-printed representation of OBJECT, any Lisp object. +Quoting characters are printed when needed to make output that `read' +can handle, whenever this is possible. +Output stream is STREAM, or value of `standard-output' (which see)." + (princ (pp-to-string object) (or stream standard-output))) + + (defun pp-to-string (object) + "Return a string containing the pretty-printed representation of OBJECT, +any Lisp object. Quoting characters are used when needed to make output +that `read' can handle, whenever this is possible." + (save-excursion + (set-buffer (generate-new-buffer " pp-to-string")) + (unwind-protect + (progn + (lisp-mode-variables t) + (let ((print-escape-newlines pp-escape-newlines)) + (prin1 object (current-buffer))) + (goto-char (point-min)) + (while (not (eobp)) + (cond + ((looking-at "\\s(\\|#\\s(") + (while (looking-at "\\s(\\|#\\s(") + (forward-char 1))) + ((and (looking-at "\\(quote[ \t]+\\)\\([^.)]\\)") + (> (match-beginning 1) 1) + (= ?\( (char-after (1- (match-beginning 1)))) + ;; Make sure this is a two-element list. + (save-excursion + (goto-char (match-beginning 2)) + (forward-sexp) + ;; Avoid mucking with match-data; does this test work? + (char-equal ?\) (char-after (point))))) + ;; -1 gets the paren preceding the quote as well. + (delete-region (1- (match-beginning 1)) (match-end 1)) + (insert "'") + (forward-sexp 1) + (if (looking-at "[ \t]*\)") + (delete-region (match-beginning 0) (match-end 0)) + (error "Malformed quote")) + (backward-sexp 1)) + ((condition-case err-var + (prog1 t (down-list 1)) + (error nil)) + (backward-char 1) + (skip-chars-backward " \t") + (delete-region + (point) + (progn (skip-chars-forward " \t") (point))) + (if (not (char-equal ?' (char-after (1- (point))))) + (insert ?\n))) + ((condition-case err-var + (prog1 t (up-list 1)) + (error nil)) + (while (looking-at "\\s)") + (forward-char 1)) + (skip-chars-backward " \t") + (delete-region + (point) + (progn (skip-chars-forward " \t") (point))) + (if (not (char-equal ?' (char-after (1- (point))))) + (insert ?\n))) + (t (goto-char (point-max))))) + (goto-char (point-min)) + (indent-sexp) + (buffer-string)) + (kill-buffer (current-buffer)))))) + +(defsubst wl-get-date-iso8601 (date) + (or (get-text-property 0 'wl-date date) + (let* ((d1 (timezone-fix-time date nil nil)) + (time (format "%04d%02d%02dT%02d%02d%02d" + (aref d1 0) (aref d1 1) (aref d1 2) + (aref d1 3) (aref d1 4) (aref d1 5)))) + (put-text-property 0 1 'wl-date time date) + time))) + +(defun wl-make-date-string () + (let ((s (current-time-string))) + (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]" + s) + (concat (wl-match-string 1 s) ", " + (timezone-make-date-arpa-standard s (current-time-zone))))) + +(defun wl-date-iso8601 (date) + "Convert the DATE to YYMMDDTHHMMSS." + (condition-case () + (wl-get-date-iso8601 date) + (error ""))) + +(defun wl-day-number (date) + (let ((dat (mapcar '(lambda (s) (and s (string-to-int s)) ) + (timezone-parse-date date)))) + (timezone-absolute-from-gregorian + (nth 1 dat) (nth 2 dat) (car dat)))) + +(defun wl-url-news (url &rest args) + (interactive "sURL: ") + (if (string-match "^news:\\(.*\\)$" url) + (wl-summary-goto-folder-subr + (concat "-" (elmo-match-string 1 url)) nil nil nil t) + (message "Not a news: url."))) + +(defun wl-url-nntp (url &rest args) + (interactive "sURL: ") + (let (folder fld-name server port msg) + (if (string-match + "^nntp://\\([^:/]*\\):?\\([0-9]*\\)/\\([^/]*\\)/\\([0-9]*\\).*$" url) + (progn + (if (eq (length (setq fld-name + (elmo-match-string 3 url))) 0) + (setq fld-name nil)) + (if (eq (length (setq port + (elmo-match-string 2 url))) 0) + (setq port (int-to-string elmo-default-nntp-port))) + (if (eq (length (setq server + (elmo-match-string 1 url))) 0) + (setq server elmo-default-nntp-server)) + (setq folder (concat "-" fld-name "@" server ":" port)) + (if (eq (length (setq msg + (elmo-match-string 4 url))) 0) + (wl-summary-goto-folder-subr + folder nil nil nil t) + (wl-summary-goto-folder-subr + folder 'update nil nil t) + (goto-char (point-min)) + (re-search-forward (concat "^ *" msg) nil t) + (wl-summary-redisplay))) + (message "Not a nntp: url.")))) + +(defmacro wl-concat-list (list separator) + (` (mapconcat 'identity (delete "" (delq nil (, list))) (, separator)))) + +(defmacro wl-current-message-buffer () + (` (save-excursion + (if (buffer-live-p wl-current-summary-buffer) + (set-buffer wl-current-summary-buffer)) + wl-message-buf-name))) + +(defmacro wl-kill-buffers (regexp) + (` (mapcar (function + (lambda (x) + (if (and (buffer-name x) + (string-match (, regexp) (buffer-name x))) + (and (get-buffer x) + (kill-buffer x))))) + (buffer-list)))) + +(defun wl-sendlog-time () + (static-if (fboundp 'format-time-string) + (format-time-string "%Y/%m/%d %T") + (let ((date (current-time-string))) + (format "%s/%02d/%02d %s" + (substring date -4) + (cdr (assoc (upcase (substring date 4 7)) + timezone-months-assoc)) + (string-to-int (substring date 8 10)) + (substring date 11 19))))) + +(defun wl-collect-summary () + (let (result) + (mapcar + (function (lambda (x) + (if (and (string-match "^Summary" + (buffer-name x)) + (save-excursion + (set-buffer x) + (equal major-mode 'wl-summary-mode))) + (setq result (nconc result (list x)))))) + (buffer-list)) + result)) + +(static-if (fboundp 'read-directory-name) + (defalias 'wl-read-directory-name 'read-directory-name) + (defun wl-read-directory-name (prompt dir) + (let ((dir (read-file-name prompt dir))) + (unless (file-directory-p dir) + (error "%s is not directory" dir)) + dir))) + +;; local variable check. +(static-if (fboundp 'local-variable-p) + (defalias 'wl-local-variable-p 'local-variable-p) + (defmacro wl-local-variable-p (symbol &optional buffer) + (` (if (assq (, symbol) (buffer-local-variables (, buffer))) + t)))) + +(defun wl-number-base36 (num len) + (if (if (< len 0) + (<= num 0) + (= len 0)) + "" + (concat (wl-number-base36 (/ num 36) (1- len)) + (char-to-string (aref "zyxwvutsrqponmlkjihgfedcba9876543210" + (% num 36)))))) + +(defvar wl-unique-id-char nil) + +(defun wl-unique-id () + ;; Don't use microseconds from (current-time), they may be unsupported. + ;; Instead we use this randomly inited counter. + (setq wl-unique-id-char + (% (1+ (or wl-unique-id-char (logand (random t) (1- (lsh 1 20))))) + ;; (current-time) returns 16-bit ints, + ;; and 2^16*25 just fits into 4 digits i base 36. + (* 25 25))) + (let ((tm (static-if (fboundp 'current-time) + (current-time) + (let* ((cts (split-string (current-time-string) "[ :]")) + (m (cdr (assoc (nth 1 cts) + '(("Jan" . "01") ("Feb" . "02") + ("Mar" . "03") ("Apr" . "04") + ("May" . "05") ("Jun" . "06") + ("Jul" . "07") ("Aug" . "08") + ("Sep" . "09") ("Oct" . "10") + ("Nov" . "11") ("Dec" . "12")))))) + (list (string-to-int (concat (nth 6 cts) m + (substring (nth 2 cts) 0 1))) + (string-to-int (concat (substring (nth 2 cts) 1) + (nth 4 cts) (nth 5 cts) + (nth 6 cts)))))))) + (concat + (if (memq system-type '(ms-dos emx vax-vms)) + (let ((user (downcase (user-login-name)))) + (while (string-match "[^a-z0-9_]" user) + (aset user (match-beginning 0) ?_)) + user) + (wl-number-base36 (user-uid) -1)) + (wl-number-base36 (+ (car tm) + (lsh (% wl-unique-id-char 25) 16)) 4) + (wl-number-base36 (+ (nth 1 tm) + (lsh (/ wl-unique-id-char 25) 16)) 4) + ;; Append the name of the message interface, because while the + ;; generated ID is unique to this newsreader, other newsreaders + ;; might otherwise generate the same ID via another algorithm. + ".wl"))) + +(defun wl-draft-make-message-id-string () + (concat "<" (wl-unique-id) "@" + (or wl-message-id-domain + (if wl-local-domain + (concat (system-name) "." wl-local-domain) + (system-name))) + ">")) + +;;; Profile loading. +(defvar wl-load-profile-func 'wl-local-load-profile) +(defun wl-local-load-profile () + (message "Initializing ...") + (load wl-init-file 'noerror 'nomessage)) + +(defun wl-load-profile () + (funcall wl-load-profile-func)) + +;;; wl-util.el ends here diff --git a/wl/wl-vars.el b/wl/wl-vars.el new file mode 100644 index 0000000..3146152 --- /dev/null +++ b/wl/wl-vars.el @@ -0,0 +1,1949 @@ +;;; wl-vars.el -- Variable definitions for Wanderlust. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <00/03/25 00:19:06 teranisi> + +;; This file is part of Wanderlust (Yet Another Message Interface on Emacsen). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; + +(require 'elmo-vars) + +(if (module-installed-p 'custom) + (require 'custom)) + +(defconst wl-appname "Wanderlust") +(defconst wl-version elmo-version) ; equals to ELMO version. +(defconst wl-codename "Purple Rain") + +;;; Customizable Variables + +(defgroup wl nil + "Wanderlust, a news and mail reading software." + :tag "Wanderlust" + :link '(custom-manual "(wl-ja)Top") + :group 'news + :group 'mail) + +(defgroup wl-pref nil + "Wanderlust, Preferences." + :prefix "wl-" + :group 'wl) + +(defgroup wl-folder nil + "Wanderlust, folder buffer." + :prefix "wl-" + :group 'wl) + +(defgroup wl-summary nil + "Wanderlust, summary buffer." + :prefix "wl-" + :group 'wl) + +(defgroup wl-summary-marks nil + "Wanderlust, marks used in summary buffers." + :prefix "wl-summary-" + :group 'wl-summary) + +(defgroup wl-expire nil + "Wanderlust, Expiring and archiving." + :prefix "wl-" + :group 'wl) + +(defgroup wl-score nil + "Wanderlust, Score file handling." + :prefix "wl-" + :group 'wl) + +(defgroup wl-highlight nil + "Wanderlust, Highlights." + :prefix "wl-" + :group 'wl) + +(defgroup wl-draft nil + "Wanderlust, draft mode." + :prefix "wl-" + :group 'wl) + +;;; Emacsen +(defconst wl-on-emacs20 (> emacs-major-version 19)) + +(defconst wl-on-xemacs (featurep 'xemacs)) + +(defconst wl-on-nemacs (fboundp 'nemacs-version)) + +(defconst wl-on-mule (featurep 'mule)) + +(defconst wl-on-mule3 + (and wl-on-mule (or wl-on-xemacs wl-on-emacs20))) + +(require 'elmo-vars) + +(eval-when-compile + (defun-maybe locate-data-directory (a))) + +(defvar wl-cs-noconv + (cond (wl-on-mule3 'binary) + (wl-on-mule '*noconv*) + (wl-on-nemacs 0) + (t nil))) + +(defvar wl-cs-autoconv + (cond (wl-on-mule3 'undecided) + (wl-on-mule '*autoconv*) + (wl-on-nemacs 2) ; junet... + (t nil))) + +(defvar wl-cs-local + (cond (wl-on-mule3 'junet) + (wl-on-mule '*junet*) + (wl-on-nemacs 2) + (t nil))) + +(defvar wl-cs-cache wl-cs-local) + +(defvar wl-use-semi (module-installed-p 'mime-view) ; If nil, use tm. + "*Use SEMI or not") + +(defcustom wl-from (if (boundp 'user-mail-address) + user-mail-address) + "*From string used in draft." + :type 'string + :group 'wl) + +(defcustom wl-user-mail-address-list nil + "*A list of user's mail addresses. +This list is used to judge whether an address is user's or not. +You should set this variable if you use multiple e-mail addresses. +If you don't have multiple e-mail addresses, you don't have to set this." + :type '(repeat string) + :group 'wl) + +(defcustom wl-organization nil + "Organization name." + :type '(choice (const :tag "none" nil) + string) + :group 'wl) + +(defcustom wl-tmp-dir "~/tmp/" + "*Default temporary directory to save message, part." + :type 'directory + :group 'wl) + +(defcustom wl-icon-dir (if (fboundp 'locate-data-directory) + (locate-data-directory "wl")) + "*Icon directory (XEmacs)." + :type '(choice (const :tag "none" nil) + string) + :group 'wl) + +(defcustom wl-summary-from-func 'wl-summary-default-from + "*A function for displaying sender (From: field) information." + :type 'function + :group 'wl-summary) + +(defcustom wl-summary-subject-func 'wl-summary-default-subject + "*A function for displaying subject." + :type 'function + :group 'wl-summary) + +(defcustom wl-summary-subject-filter-func 'wl-summary-default-subject-filter + "*A filter function for comparing subjects." + :type 'function + :group 'wl-summary) + +(defcustom wl-summary-update-confirm-threshold 500 + "*Confirm updating summary if message number is larger than this value." + :type 'integer + :group 'wl-summary) + +;; Important folders +(defcustom wl-default-folder "%inbox" + "*Default folder used in wl-summary-goto-folder." + :type 'string + :group 'wl) +(defcustom wl-draft-folder "+draft" + "*Draft folder" + :type 'string + :group 'wl) +(defcustom wl-trash-folder "+trash" + "*Trash folder" + :type 'string + :group 'wl) +(defcustom wl-queue-folder "+queue" + "*Queue folder" + :type 'string + :group 'wl) + +(defcustom wl-default-spec "%" + "*Default spec" + :type 'string + :group 'wl) + +(defcustom wl-insert-mail-followup-to nil + "*Insert Mail-Followup-To: field if non-nil." + :type 'boolean + :group 'wl-draft) + +(defcustom wl-insert-mail-reply-to nil + "*Insert Mail-Reply-To: field if non-nil." + :type 'boolean + :group 'wl-draft) + +(defcustom wl-insert-message-id t + "*Insert Message-ID: field if non-nil." + :type 'boolean + :group 'wl-draft) + +(defcustom wl-auto-insert-x-face t + "*Insert X-Face: field automatically" + :type 'boolean + :group 'wl-draft) + +(defcustom wl-x-face-file "~/.xface" + "*If file exists and `wl-auto-insert-x-face' is non-nil, +X-Face field is inserted using its contents." + :type 'file + :group 'wl-draft) + +(defcustom wl-subscribed-mailing-list nil + "*Subscribed mailing list. You had better set this variable +if you set wl-insert-mail-followup-to as t." + :type '(repeat string) + :group 'wl-pref) + +(defcustom wl-demo t + "*Display demo at start time." + :type 'boolean + :group 'wl-pref) + +(defcustom wl-envelope-from nil + "*Envelope From used in SMTP. +If nil, wl-from is used." + :type '(choice (const :tag "Same as 'From' field." nil) + string) + :group 'wl) + +(defcustom wl-smtp-connection-type nil + "*SMTP connection type. +If nil, default smtp connection type is used." + :type '(choice (const :tag "default" nil) + (const :tag "Use STARTTLS" starttls) + symbol) + :group 'wl) + +(defcustom wl-smtp-posting-user nil + "*SMTP authentication user. " + :type '(choice (const :tag "none" nil) + string) + :group 'wl) + +(defcustom wl-smtp-posting-server nil + "*SMTP server name to send mail (wl-draft-send-mail-with-smtp)." + :type 'string + :group 'wl) + +(defcustom wl-smtp-posting-port nil + "*SMTP port number in `wl-smtp-posting-server'. +If nil, default SMTP port number(25) is used." + :type '(choice (const :tag "Default (25)" nil) + integer) + :group 'wl) + +(defcustom wl-smtp-authenticate-type nil + "*SMTP Authentication type. +If nil, don't authenticate." + :type '(choice (const :tag "none" nil) + (const :tag "PLAIN" "plain") + (const :tag "CRAM-MD5" "cram-md5") + (const :tag "LOGIN" "login") + (string :tag "Other")) + :group 'wl) + +(defcustom wl-pop-before-smtp-user nil + "*POP3 user name to send mail using POP-before-SMTP. +If nil, elmo-default-pop3-user is used. +To use POP-before-SMTP, +(setq wl-draft-send-mail-func 'wl-draft-send-mail-with-pop-before-smtp)" + :type '(choice (const :tag "none" nil) + string) + :group 'wl) + +(defcustom wl-pop-before-smtp-server nil + "*POP3 server for POP-before-SMTP. +If nil, elmo-default-pop3-server is used." + :type '(choice (const :tag "none" nil) + string) + :group 'wl) + +(defcustom wl-pop-before-smtp-port nil + "*POP3 port for POP-before-SMTP. +If nil, elmo-default-pop3-port is used." + :type '(choice (const :tag "none" nil) + integer string) + :group 'wl) + +(defcustom wl-pop-before-smtp-ssl nil + "*Non-nil forces using SSL by default for POP-before-SMTP. +If nil, elmo-default-pop3-ssl is used." + :type 'boolean + :group 'wl) + +(defcustom wl-pop-before-smtp-authenticate-type nil + "*Default Authentication type for POP-before-SMTP +If nil, elmo-default-pop3-authenticate-type is used." + :type '(choice (const :tag "none" nil) + (const :tag "APOP" "apop") + (const :tag "POP3" "user")) + :group 'wl) + +(defcustom wl-nntp-posting-server nil + "*NNTP server name to post news. +If nil, elmo-default-nntp-server is used." + :type '(choice (const :tag "none" nil) + string) + :group 'wl) +(defcustom wl-nntp-posting-user nil + "*NNTP user name to post news for authinfo. +If nil, elmo-default-nntp-user is used. +If nil, don't authenticate." + :type '(choice (const :tag "none" nil) + string) + :group 'wl) +(defcustom wl-nntp-posting-port nil + "*NNTP port to post news. +If nil, elmo-default-nntp-port is used." + :type '(choice (const :tag "none" nil) + integer string) + :group 'wl) +(defcustom wl-nntp-posting-ssl nil + "*Non-nil forces using SSL to post news. +If nil, elmo-default-nntp-ssl is used." + :type 'boolean + :group 'wl) + +(defcustom wl-fetch-confirm-threshold 30000 + "*Confirm fetching if message size is larger than this value." + :type 'integer + :group 'wl-pref) + +(defcustom wl-prefetch-confirm t + "*Confirm prefetching if message size is larger than `wl-prefetch-threshold'." + :type 'boolean + :group 'wl-pref) + +(defcustom wl-prefetch-threshold 30000 + "*Maximum size of message prefetched without confirmation. +If nil, all messages prefetched regardless of its size. +If message size is larger than this value, confirm prefetching +when `wl-prefetch-confirm' is non-nil." + :type '(choice (integer :tag "Threshold (bytes)") + (const :tag "No limitation" nil)) + :group 'wl-pref) + +(defcustom wl-cache-prefetch-threshold 30000 + "*Quit forward cache prefetching if message size is larger than this value." + :type 'integer + :group 'wl-pref) + +(defcustom wl-thread-insert-opened nil + "*Non-nil forces to insert thread as opened in updating." + :type 'boolean + :group 'wl-summary) + +(defcustom wl-thread-open-reading-thread t + "*Non-nil forces to open reading thread." + :type 'boolean + :group 'wl-summary) + +;;;; Hooks +(defvar wl-folder-mode-hook nil + "A hook called when wanderlust folder mode is started.") +(defvar wl-summary-toggle-disp-on-hook nil + "A hook called when message is toggled.") +(defvar wl-summary-toggle-disp-off-hook nil + "A hook called when message is disappeared.") +(defvar wl-summary-toggle-disp-folder-on-hook nil + "A hook called when folder is toggled.") +(defvar wl-summary-toggle-disp-folder-off-hook nil + "A hook called when folder is disappeared.") +(defvar wl-summary-toggle-disp-folder-message-resumed-hook nil + "A hook called when message window is resumed when folder is toggled.") +(defvar wl-summary-mode-hook nil + "A hook called when summary mode is started.") +(defvar wl-summary-prepared-pre-hook nil + "A hook called before the summary buffer has been generated.") +(defvar wl-summary-prepared-hook nil + "A hook called after the summary buffer has been generated.") +(defvar wl-summary-sync-updated-hook nil + "A hook called when update summary buffer.") +(defvar wl-summary-unread-message-hook nil + "A hook called when unread message is displayed.") +(defvar wl-summary-edit-addresses-hook nil + "A hook called when address book is edited.") +(defvar wl-summary-divide-thread-when-subject-changed nil + "Divide thread when subject is changed.") +(defvar wl-init-hook nil + "A hook called when initialization is finished.") +(defvar wl-hook nil + "A hook called when Wanderlust is invoked.") +(defvar wl-reply-hook nil + "A hook called when replied.") +(defvar wl-mail-setup-hook nil + "A hook called when Draft is prepared.") +(defvar wl-draft-reedit-hook nil + "A hook called when Draft is re-edited.") +(defvar wl-draft-send-hook nil + "A hook called on the draft editing buffer before sending process starts.") +(defvar wl-mail-send-pre-hook nil + "A hook called just before the mail sending process starts.") +(defvar wl-news-send-pre-hook nil + "A hook called just before the news sending process starts.") +(defvar wl-message-buffer-created-hook nil + "A hook called when Message buffer is prepared.") +(defvar wl-message-redisplay-hook nil + "A hook called when Message is displayed.") +(defvar wl-message-exit-hook nil + "A hook called when quit message.") +(defvar wl-summary-exit-hook nil + "A hook called when exit summary mode.") +(defvar wl-highlight-headers-hook nil + "A hook called when header is highlighted.") +(defvar wl-highlight-message-hook nil + "A hook called when message is highlighted.") +(defvar wl-exit-hook nil + "A hook called when exit wanderlust.") +(defvar wl-folder-suspend-hook nil + "A hook called when suspend wanderlust.") +(defvar wl-auto-check-folder-pre-hook nil + "A hook called before auto check folders.") +(defvar wl-auto-check-folder-hook nil + "A hook called when auto check folders.") +(defvar wl-folder-check-entity-pre-hook nil + "A hook called before check entity.") +(defvar wl-folder-check-entity-hook nil + "A hook called when check entity.") +(defvar wl-draft-config-exec-hook nil + "A hook called when execute header-config on draft.") +(defvar wl-summary-expire-pre-hook nil + "A hook called before expire.") +(defvar wl-summary-expire-hook nil + "A hook called when expired.") +(defvar wl-summary-archive-pre-hook nil + "A hook called before archive.") +(defvar wl-summary-archive-hook nil + "A hook called when archived.") +(defvar wl-summary-line-inserted-hook nil + "A hook called when summary line is inserted.") +(defvar wl-thread-update-children-number-hook nil + "A hook called when children number is updated.") +(defvar wl-folder-update-access-group-hook nil + "A hook called when update access group folder.") +(defvar wl-draft-cited-hook nil + "A hook called after a message is cited.") +(defvar wl-draft-insert-x-face-field-hook nil + "A hook called after a x-face field is inserted.") +(defvar wl-template-mode-hook nil + "A hook called when template mode is started.") +(defvar wl-score-mode-hook nil + "A hook called when score mode is started.") +(defvar wl-make-plugged-hook nil + "A hook called when make plugged alist.") +(defvar wl-plugged-exit-hook nil + "A hook called when exit plugged mode.") + +;;;; functions for draft +(defcustom wl-draft-send-func 'wl-draft-normal-send-func + "A function to send message." + :type 'function + :group 'wl-draft) + +(defcustom wl-draft-send-news-func 'wl-draft-elmo-nntp-send + "A function to send news." + :type 'function + :group 'wl-draft) + +(defcustom wl-draft-send-mail-func 'wl-draft-send-mail-with-smtp + "A function to send mail. +Prepared candidates are 'wl-draft-send-mail-with-smtp, +'wl-draft-send-mail-with-qmail and 'wl-draft-send-mail-with-pop-before-smtp." + :type '(radio (function-item wl-draft-send-mail-with-smtp) + (function-item wl-draft-send-mail-with-qmail) + (function-item wl-draft-send-mail-with-pop-before-smtp) + (function :tag "Other")) + :group 'wl-draft) + +(defcustom wl-draft-reply-with-argument-list + '(("Reply-To" . (("Reply-To") nil nil)) + ("Mail-Reply-To" . (("Mail-Reply-To") nil nil)) + ("From" . (("From") nil nil))) + "Alist of cons cell of +('field-name' . ('fields for To' 'fields for Cc' 'fields for Newsgroups')) +If car of each cons cell exists in original message, +cdr of each cons cell is used for draft message. +Default is for 'reply-to-author'." + :type '(repeat (cons (choice (string :tag "Field Name") + (repeat (string :tag "Field Name"))) + (list (repeat :tag "Fields For To" string) + (repeat :tag "Fields For Cc" string) + (repeat :tag "Fields For Newsgroups" string)))) + :group 'wl-draft) + +(defcustom wl-draft-reply-without-argument-list + '(("Followup-To" . (nil nil ("Followup-To"))) + ("Mail-Followup-To" . (("Mail-Followup-To") nil ("Newsgroups"))) + ("From" . (("From") ("To" "Cc") ("Newsgroups")))) + "Alist of cons cell of +('field-name' . ('fields for To' 'fields for Cc' 'fields for Newsgroups')) +'field-name' is a string. +'fields for ***' is a list of strings. +If car of each cons cell exists in original message, +cdr of each cons cell is used for draft message. +Default is for 'reply-to-all'." + :type '(repeat (cons (choice (string :tag "Field Name") + (repeat (string :tag "Field Name"))) + (list (repeat :tag "Fields For To" string) + (repeat :tag "Fields For Cc" string) + (repeat :tag "Fields For Newsgroups" string)))) + :group 'wl-draft) + +(defcustom wl-draft-always-delete-myself nil + "*Always delete myself from reciepient if non-nil." + :type 'boolean + :group 'wl-draft) + +(defcustom wl-draft-resume-folder-window t + "*Resume folder window in wl-draft-hide" + :type 'boolean + :group 'wl-draft) + +(defcustom wl-draft-use-frame nil + "*Raise new frame when composing draft." + :type 'boolean + :group 'wl-draft) + +(defcustom wl-draft-qmail-send-plugged nil + "*Send mail when plugged is on, in the `wl-draft-send-mail-with-qmail'." + :type 'boolean + :group 'wl-draft) + +;;;; +(defcustom wl-init-file "~/.wl" + "*User customization setting file." + :type 'file + :group 'wl) + +(defcustom wl-folders-file "~/.folders" + "*Folders file" + :type 'file + :group 'wl) + +(defcustom wl-address-file "~/.addresses" + "*Addresses file" + :type 'file + :group 'wl) + +(defcustom wl-alias-file "~/.im/Aliases" + "*Alias file for completion" + :type 'file + :group 'wl) + +(defcustom wl-folder-info-save t + "If non-nil, save elmo-folder-info-alist." + :type 'boolean + :group 'wl-folder) + +(defcustom wl-summary-unread-mark "!" + "Mark for unread message." + :type '(string :tag "Mark") + :group 'wl-summary-marks) +(defcustom wl-summary-important-mark "$" + "Mark for important message." + :type '(string :tag "Mark") + :group 'wl-summary-marks) +(defcustom wl-summary-new-mark "N" + "Mark for new message." + :type '(string :tag "Mark") + :group 'wl-summary-marks) +(defcustom wl-summary-unread-uncached-mark "U" + "Mark for unread and uncached message." + :type '(string :tag "Mark") + :group 'wl-summary-marks) +(defcustom wl-summary-unread-cached-mark "!" + "Mark for unread but already cached message." + :type '(string :tag "Mark") + :group 'wl-summary-marks) +(defcustom wl-summary-read-uncached-mark "u" + "Mark for read but uncached message." + :type '(string :tag "Mark") + :group 'wl-summary-marks) +(defcustom wl-summary-score-over-mark "+" + "Score mark used for messages with high scores." + :type '(string :tag "Mark") + :group 'wl-summary-marks) +(defcustom wl-summary-score-below-mark "-" + "Score mark used for messages with low scores." + :type '(string :tag "Mark") + :group 'wl-summary-marks) + +(defcustom wl-summary-no-mime-folder-list + (list (concat "^" (regexp-quote wl-draft-folder) "$")) + "*All folders that match this list don't analysis mime." + :type '(repeat string) + :group 'wl-summary) + +(defcustom wl-summary-fix-timezone "JST" + "Non-nil forces to fix timezone of summary date." + :type 'string + :group 'wl-summary) + +(defcustom wl-summary-default-score 0 + "*Default message score level. +All scores generated by the score files will be added to this score. +If this variable is nil, scoring will be disabled." + :type '(choice (const :tag "disable" nil) + integer) + :group 'wl-score) + +(defcustom wl-summary-important-above nil + "*Mark all messages with a score above this variable as important. +This variable is local to the summary buffers." + :type '(choice (const :tag "off" nil) + integer) + :group 'wl-score) + +(defcustom wl-summary-temp-above nil + "*Mark all messages with a score above this variable as temp. +This variable is local to the summary buffers." + :type '(choice (const :tag "off" nil) + integer) + :group 'wl-score) + +(defcustom wl-summary-mark-below 0 + "*Mark all messages with a score below this variable as read. +This variable is local to each summary buffer and usually set by the +score file." + :type 'integer + :group 'wl-score) + +(defcustom wl-summary-expunge-below nil + "All messages that have a score less than this variable will be expunged. +This variable is local to the summary buffers." + :type '(choice (const :tag "off" nil) + integer) + :group 'wl-score) + +(defcustom wl-summary-score-marks + (list wl-summary-new-mark) + "Persistent marks to scoring." + :type '(repeat (string :tag "Mark")) + :group 'wl-score) + +(defcustom wl-use-scoring (not wl-on-nemacs) + "*If non-nil, enable scoring." + :type 'boolean + :group 'wl-pref) + +(defcustom wl-summary-rescore-partial-threshold 200 + "*Summary is not scored entirely if there are messages more than this value +in sync-all or rescan." + :type 'integer + :group 'wl-score) + +(defcustom wl-score-files-dir (concat elmo-msgdb-dir elmo-path-sep) + "*Name of the directory where score files will be stored (default \"~/.elmo\")." + :type 'directory + :group 'wl) + +(defcustom wl-score-interactive-default-score 1000 + "*Scoring commands will raise/lower the score with this number as the default." + :type 'integer + :group 'wl-score) + +(defcustom wl-score-expiry-days 7 + "*Number of days before unused score file entries are expired. +If this variable is nil, no score file entries will be expired." + :type '(choice (const :tag "never" nil) + number) + :group 'wl-score) + +(defcustom wl-score-update-entry-dates t + "*In non-nil, update matching score entry dates. +If this variable is nil, then score entries that provide matches +will be expired along with non-matching score entries." + :type 'boolean + :group 'wl-score) + +(defcustom wl-score-folder-alist nil + "*Alist of folder regexp and score file." + :type '(repeat (list (regexp :tag "Folder Regexp") + (repeat :inline t + (choice file + (symbol :tag "Variable"))))) + :group 'wl-score) + +(defcustom wl-score-folder-alist-matchone t + "*If non-nil, getting only one element of `wl-score-folder-alist'." + :type 'boolean + :group 'wl-score) + +(defcustom wl-score-default-file "all.SCORE" + "*Default score file name." + :type 'file + :group 'wl-score) + +(defcustom wl-score-simplify-fuzzy-regexp + '("^[ \t]*\\[[^:]+[,: ][0-9]+\\][ \t]*") + "*Strings to be removed when doing fuzzy matches. +This can either be a regular expression or list of regular expressions." + :type '(repeat regexp) + :group 'wl-score) + +(defcustom wl-score-header-default-entry + '(("number" -1000 perm =) + ("subject" -1000 nil nil) + ("from" -1000 perm s) + ("message-id" -1000 temp e) + ("references" -1000 perm e) + ("to" -1000 perm s) + ("cc" -1000 perm s) + ("date" -1000 temp nil) + ("xref" -1000 perm s) + ("extra" -1000 perm s) + ("chars" -1000 perm >) + ("lines" -1000 perm >) + ("followup" -1000 perm s) + ("thread" -1000 temp s)) + "*Default entry when insert score entry." + :type '(repeat (list (string :tag "Header") + (choice (integer :tag "Score") + (const :tag "Ask" nil)) + (choice (const :tag "Permanent" perm) + (const :tag "Temporary" temp) + (const :tag "Ask" nil)) + (choice (const :tag "Regexp string" r) + (const :tag "Substring" s) + (const :tag "fuzzy string" f) + (const :tag "Exact string" e) + (const :tag "REGEXP STRING" R) + (const :tag "SUBSTRING" S) + (const :tag "FUZZY STRING" F) + (const :tag "EXACT STRING" E) + (const :tag "less than" <) + (const :tag "less equal" <=) + (const :tag "greater than" >) + (const :tag "greater equal" >=) + (const :tag "equal" =) + (const :tag "Ask" nil)))) + :group 'wl-score) + +(defcustom wl-score-mode-mime-charset 'x-ctext + "*MIME Charset for score file." + :type 'symbol + :group 'wl-score) + +(defcustom wl-draft-fields + '("To:" "Cc:" "Bcc:" "FCC:" "Distribution:" "Organization:" + "Newsgroups:" "Followup-To:" "Mail-Followup-To:" "From:" "Reply-To:") + "Fields used in draft mode." + :type '(repeat (string :tag "Field")) + :group 'wl-draft) + +(defcustom wl-draft-config-alist nil + "Alist of configuration field on draft. +ex. +'((\"^To: .*wl@lists.airs.net\" + (\"From\" . wl-from2) + (\"Organization\" . wl-organization2)) + (\"^To: .*hogehoge@\" + (\"From\" . \"Anonymous \") + wl-my-draft-config-func-hoge))" + :type '(repeat (list (sexp :tag "Match") + (repeat + :inline t + (choice (cons (sexp :tag "Field(Variable)") + (sexp :tag "Value")) + (sexp :tag "Function"))))) + :group 'wl-draft) + +(defcustom wl-draft-config-matchone nil + "*If non-nil, applied only one element of `wl-draft-config-alist'." + :type 'boolean + :group 'wl-draft) + +(defcustom wl-template-alist nil + "Alist of template." + :type '(repeat (list (string :tag "Name") + (repeat + :inline t + (choice (cons (sexp :tag "Field(Variable)") + (sexp :tag "Value")) + (sexp :tag "Function"))))) + :group 'wl-draft) + +(defcustom wl-template-visible-select t + "*If non-nil, select template with visible." + :type 'boolean + :group 'wl-draft) + +(defcustom wl-template-confirm nil + "*If non-nil, require your confirmation when selected template." + :type 'boolean + :group 'wl-draft) + +(defcustom wl-template-buffer-lines 7 + "*Lines of template buffer." + :type 'integer + :group 'wl-draft) + +;; queued sending. +(defcustom wl-draft-enable-queuing t + "*Non-nil enables queued sending." + :type 'boolean + :group 'wl-draft + :group 'wl-pref) + +(defcustom wl-auto-flush-queue t + "*If non-nil, sending queue is flushed when network status is toggled." + :type 'boolean + :group 'wl-draft + :group 'wl-pref) + +(defcustom wl-draft-reply-buffer-style 'split + "'split or 'full" + :type '(radio (const split) + (const full)) + :group 'wl-draft) + +(defcustom wl-draft-queue-save-variables + '(wl-envelope-from + wl-smtp-posting-server smtp-service + wl-nntp-posting-server elmo-default-nntp-port) + "*Saving variables in queue info." + :type '(repeat (sexp :tag "Variable")) + :group 'wl-draft) + +(defcustom wl-draft-sendlog t + "*Keep send state in log if non-nil." + :type 'boolean + :group 'wl-draft) + +(defcustom wl-draft-sendlog-max-size 20000 + "*Max file size of sendlog." + :type 'integer + :group 'wl-draft) + +(defcustom wl-summary-default-number-column 5 + "number of columns in summary buffer." + :type 'integer + :group 'wl-summary) + +(defcustom wl-summary-number-column-alist '(("\\*.*" . 6)) + "Alist of folder and its number column. +If no matches, 'wl-summary-default-number-column' is used. +ex. +'((\"^%inbox@qmail-maildir\" . 9) + (\"^-.*@news-server\" . 6))" + :type '(repeat (cons (regexp :tag "Folder Regexp") integer)) + :group 'wl-summary) + +(defcustom wl-summary-highlight t + "Non-nil forces Summary buffer to be highlighted." + :type 'boolean + :group 'wl-summary + :group 'wl-highlight) + +(defcustom wl-summary-highlight-partial-threshold 1000 + "Summary is not highlighted entirely +if there are lines more than this value." + :type 'integer + :group 'wl-summary + :group 'wl-highlight) + +(defcustom wl-summary-partial-highlight-above-lines 30 + "If Summary has lines more than wl-summary-highlight-partial-threshold, +Summary lines are highlighted partialy above current position." + :type 'integer + :group 'wl-summary + :group 'wl-highlight) + +(defcustom wl-summary-cache-use t + "Non-nil forces wl-summary to use cache file." + :type 'boolean + :group 'wl-summary) + +(defcustom wl-summary-auto-sync-marks t + "Non-nil forces to synchronize unread/important marks." + :type 'boolean + :group 'wl-summary) + +(defcustom wl-summary-cache-file ".wl-summary-cache" + "*Cache file for summary mode contents." + :type 'file + :group 'wl-summary) +(defcustom wl-summary-view-file ".wl-summary-view" + "*current summary view." + :type 'file + :group 'wl-summary) +(defcustom wl-thread-top-file ".wl-thread-top" + "*current thread top entity... obsolete." + :type 'file + :group 'wl-summary) +(defcustom wl-thread-entity-file ".wl-thread-entity" + "*thread entities." + :type 'file + :group 'wl-summary) +(defcustom wl-thread-entity-list-file ".wl-thread-entity-list" + "*thread top entity list." + :type 'file + :group 'wl-summary) + +(defcustom wl-print-buffer-func 'lpr-buffer + "A function to print current buffer." + :type 'function + :group 'wl-pref) + +(defcustom wl-ps-print-buffer-func + (if window-system 'ps-print-buffer-with-faces 'ps-print-buffer) + "A function to print current buffer with ps-print." + :type 'function + :group 'wl-pref) + +;;;; Preferences +(defcustom wl-use-petname t + "*Display petname in summary and default citation title." + :type 'boolean + :group 'wl-pref) + +(defcustom wl-use-folder-petname + '(modeline) + "*List of situation using folder petname. Allowed situations are: + + modeline : displayed on modeline. + ask-folder : displayed on minibuffer when ask folder. + read-folder : can used for completion at `wl-summary-read-folder'." + :type '(set (const modeline) + (const ask-folder) + (const read-folder)) + :group 'wl-summary + :group 'wl-pref) + +(defcustom wl-folder-petname-alist nil + "A list of (realname . petname)" + :type '(repeat (cons (string :tag "Realname") (string :tag "Petname"))) + :group 'wl-folder) + +(defcustom wl-summary-weekday-name-lang "ja" + "*Language to display week day." + :type '(choice (const "ja") + (const "en") + (const "fr") + (const "de") + (string :tag "Other")) + :group 'wl-summary + :group 'wl-pref) + +(defcustom wl-local-domain nil + "*Domain part of this client (without hostname). +Set this if (system-name) does not return FQDN." + :type '(choice (const :tag "Use System Name" nil) + string) + :group 'wl-pref) + +(defcustom wl-message-id-domain nil + "*Specific domain part of Message-ID." + :type '(choice (const :tag "Use System Name" nil) + string) + :group 'wl-pref) + +(defcustom wl-break-pages t + "*Break Pages at ^L." + :type 'boolean + :group 'wl-pref) + +(defcustom wl-message-scroll-amount 5 + "*Scroll amount by SPC key." + :type 'integer + :group 'wl-pref) + +(defcustom wl-message-window-size '(1 . 4) + "*Size of summary and message window. cons cell of (Summary : Message)." + :type '(cons integer integer) + :group 'wl-pref) + +(defcustom wl-message-sort-field-list '("Return-Path" "Received" "^To" "^Cc" + "Newsgroups" "Subject" "^From") + "*Sort order of header fields. Each elements are regexp of field name. +(Not valid on tm.)" + :type '(repeat (string :tag "Field Regexp")) + :group 'wl-pref) + +(defcustom wl-folder-window-width 20 + "*Width of folder window." + :type 'integer + :group 'wl-folder + :group 'wl-pref) + +(defcustom wl-summary-recenter t + "*Recenter on redisplay" + :type 'boolean + :group 'wl-summary + :group 'wl-pref) + +(defcustom wl-stay-folder-window nil + "*Stay folder window when folder is selected if non-nil." + :type 'boolean + :group 'wl-pref) + +(defcustom wl-reply-subject-prefix "Re: " + "*Prefix of the subject of the replied message." + :type 'string + :group 'wl-draft + :group 'wl-pref) + +(defcustom wl-folder-many-unsync-threshold 70 + "*Folders which contains messages more than this number are highlighted +with wl-highlight-folder-many-face." + :type 'integer + :group 'wl-folder + :group 'wl-pref) + +(defcustom wl-fcc nil + "*Folder Carbon Copy." + :type '(choice (const :tag "disable" nil) + string) + :group 'wl-draft + :group 'wl-pref) + +(defcustom wl-bcc nil + "*Blind Carbon Copy." + :type '(choice (const :tag "disable" nil) + string) + :group 'wl-draft + :group 'wl-pref) + +(defcustom wl-folder-desktop-name "Desktop" + "*An implicit name of the folder top entity." + :type 'string + :group 'wl-folder + :group 'wl-pref) + +(defcustom wl-summary-indent-length-limit 46 + "*Limit of indent length for thread." + :type 'integer + :group 'wl-summary + :group 'wl-pref) + +(defcustom wl-summary-no-from-message "nobody@nowhere?" + "*A string displayed in summary when no from field exists." + :type 'string + :group 'wl-summary) + +(defcustom wl-summary-no-subject-message "(WL:No Subject in original.)" + "*A string displayed in summary when no subject field exists." + :type 'string + :group 'wl-summary) + +(defcustom wl-summary-cancel-message "I'd like to cancel my message." + "*The body content of a cancel message." + :type 'string + :group 'wl-summary) + +(defcustom wl-summary-width 80 + "*Set summary line width if non nil." + :type 'integer + :group 'wl-summary + :group 'wl-pref) + +(defcustom wl-summary-pick-field-default "Body" + "*Default field for pick." + :type '(radio (const "From") + (const "Subject") + (const "Date") + (const "To") + (const "Cc") + (const "Body") + (const "Since") + (const "Before") + (string :tag "Other")) + :group 'wl-summary) + +(defcustom wl-from-width 17 + "*From width in summary." + :type 'integer + :group 'wl-summary + :group 'wl-pref) + +(defcustom wl-mime-charset (if wl-on-nemacs + 'iso-2022-jp + 'x-ctext) + "*MIME Charset for summary and message." + :type 'symbol + :group 'wl-summary + :group 'wl-pref) + +(defcustom wl-generate-mailer-string-func 'wl-generate-user-agent-string + "A function to create X-Mailer field string ." + :type 'function + :group 'wl-draft) + +(defcustom wl-highlight-background-mode (if (boundp 'hilit-background-mode) + (or hilit-background-mode 'dark) + 'dark) + "*Background mode of highlight (for Old Emacsen). 'dark or 'light" + :type '(radio (const dark) + (const light)) + :group 'wl-highlight) + +(defcustom wl-highlight-x-face-func nil + "A function to display X-Face." + :type 'function + :group 'wl-highlight) + +(defcustom wl-qmail-inject-program "/var/qmail/bin/qmail-inject" + "Location of the qmail-inject program." + :type '(string :tag "Program") + :group 'wl-draft) + +(defcustom wl-qmail-inject-args nil + "Arguments passed to qmail-inject programs. +This should be a list of strings, one string for each argument. + +For e.g., if you wish to set the envelope sender address so that bounces +go to the right place or to deal with listserv's usage of that address, you +might set this variable to '(\"-f\" \"you@some.where\")." + :type '(repeat (string :tag "Argument")) + :group 'wl-draft) + +(defcustom wl-rejected-letter-start + "^[\t ]*-+[\t ]+\\(original\\|\\(\\(the \\)?unsent\\)\\) message\\( follows\\)?[\t ]+-+[\t ]*$" + "Regexp specifying the beginning of the wrapper around a returned letter. + This wrapper is generated by the mail system when rejecting a letter." + :type 'regexp + :group 'wl-draft) + +(defcustom wl-ignored-resent-headers "\\(return-receipt\\|[bdf]cc\\)" + "*All headers that match this regexp will be deleted when resending a message." + :type 'regexp + :group 'wl-draft) + +(defcustom wl-refile-default-from-folder "+from" + "*Folder name to refile by `wl-refile-guess-by-from'." + :type '(string :tag "Folder") + :group 'wl-pref) + +(defcustom wl-summary-auto-refile-skip-marks + (list wl-summary-new-mark + wl-summary-unread-uncached-mark + wl-summary-unread-cached-mark) + "Persistent marks to skip auto-refiling." + :type '(repeat (string :tag "Mark")) + :group 'wl-summary) + +(defcustom wl-summary-reserve-mark-list + (list "o" "O" "D") + "If a message is already marked as temporal marks in this list, +the message is not marked by any mark command." + :type '(repeat (string :tag "Temp-Mark")) + :group 'wl-summary) + +(defcustom wl-summary-skip-mark-list + (list "D") + "If a message is already marked as temporal marks in this list, +the message is skipped at cursor move." + :type '(repeat (string :tag "Temp-Mark")) + :group 'wl-summary) + +(defcustom wl-summary-incorporate-marks + (list wl-summary-new-mark + wl-summary-unread-uncached-mark) + "Persistent marks to prefetch at `wl-summary-incorporate'" + :type '(repeat (string :tag "Mark")) + :group 'wl-summary) + +(defcustom wl-refile-rule-alist nil + "Refile rule alist. +e.x. +'( + (\"From\" + (\"teranisi@isl.ntt.co.jp\" . \"+teranisi\")) + (\"x-ml-name\" + (\"^Wanderlust\" . \"+wl\") + (\"^Elips\" . \"+elips\")))" + :type '(repeat (list (string :tag "Field") + (repeat :inline t + (cons (regexp :tag "Value") + (string :tag "Folder"))))) + :group 'wl-pref) + +(defcustom wl-strict-diff-folders nil + "Folders in this list are checked its unsync message number strictly." + :type '(repeat (string :tag "Folder")) + :group 'wl-folder) + +(defcustom wl-folder-use-server-diff t + "Checked unread message number on IMAP4 server. +Only IMAP4 folders have an effect." + :type 'boolean + :group 'wl-folder) + +(defcustom wl-force-fetch-folders nil + "Non-nil forces to fetch subfolders when user opened an 'access' folder." + :type '(choice (const :tag "off" nil) + (const :menu-tag "on" t) + (repeat (regexp :tag "Folder Regexp"))) + :group 'wl-folder) + +(defcustom wl-auto-check-folder-name nil + "*The folder specified by this variable will be automatically checked +at start time." + :type '(choice (string :tag "Folder") + (repeat (string :tag "Folder")) + (const none)) + :group 'wl-folder) + +(defcustom wl-auto-uncheck-folder-list '("\\$.*") + "All folders that match this list won't be checked when group is +automatically checked (or desktop is checked). +This value is preceded by wl-auto-check-folder-list. +Each elements are regexp of folder name." + :type '(repeat (regexp :tag "Folder Regexp")) + :group 'wl-folder) + +(defcustom wl-auto-check-folder-list nil + "All folders that match this list are checked when group is +automatically checked (or desktop is checked). +This value precedes wl-auto-uncheck-folder-list. +Each elements are regexp of folder name." + :type '(repeat (regexp :tag "Folder Regexp")) + :group 'wl-folder) + +(defcustom wl-interactive-send nil + "*If non-nil, require your confirmation when sending draft message." + :type 'boolean + :group 'wl-pref) + +(defcustom wl-interactive-exit t + "*If non-nil, require your confirmation when exiting WL." + :type 'boolean + :group 'wl-pref) + +(defcustom wl-summary-move-order 'unread + "*The order of priority when move in summary mode. +If this variable is `unread', precede \"U\", \"!\", \"N\" mark. +If this variable is `new', precede \"N\" mark." + :type '(radio (const new) + (const unread)) + :group 'wl-summary) + +(defvar wl-summary-move-direction-downward t) + +(defcustom wl-summary-move-direction-toggle t + "*If non-nil, search direction for the next message will be determined +depends on previous search direction. +It uses wl-summary-move-direction-downward as a direction flag." + :type 'boolean + :group 'wl-summary) + +(defcustom wl-auto-select-first nil + "*If non-nil, display selected first message when enter summary." + :type 'boolean + :group 'wl-pref) + +(defcustom wl-auto-select-next nil + "*If non-nil, offer to go to the next folder from the end of the previous. +If the value is the symbol `unread', go to the next folder +that no unread message exists. If the value is the symbol `skip-no-unread', +skip the folder that no unread message exists. + +See also variable `wl-summary-next-no-unread-command'." + :type '(radio (const :tag "off" nil) + (const :tag "on" t) + (const unread) + (const skip-no-unread)) + :group 'wl-pref) + +(defcustom wl-cache-prefetch-folder-type-list '(imap4 nntp) + "*All folder types that match this list prefetch next message, +and reserved buffer cache." + :type '(set (const localdir) + (const localnews) + (const imap4) + (const nntp) + (const pop3) + (const archive) + (const internal)) + :group 'wl-pref) + +(defcustom wl-cache-prefetch-folder-list nil + "*All folders that match this list prefetch next message, +and reserved buffer cache. +e.x. +'(\"^[-%]\")" + :type '(repeat (regexp :tag "Folder Regexp")) + :group 'wl-pref) + +(defcustom wl-cache-prefetch-get-next-func 'wl-summary-default-get-next-msg + "*A function to get message number when prefetch next message." + :type 'function + :group 'wl-pref) + +;; obsolete +;(defvar wl-no-cache-folder-list '("^\\$.*") +; "All folders that match this list won't be cached when reading messages. +;Each elements are regexp of folder name.") + +(defcustom wl-summary-always-sticky-folder-list nil + "All folders that match this list has sticky summary. +Each elements are regexp of folder name." + :type '(repeat (regexp :tag "Folder Regexp")) + :group 'wl-pref) + +(defcustom wl-no-save-folder-list '("^/.*$") + "All folders that match this list won't save its msgdb. +Each elements are regexp of folder name." + :type '(repeat (regexp :tag "Folder Regexp")) + :group 'wl-pref) + +(defcustom wl-save-folder-list nil + "All folders that match this list save its msgdb. +Each elements are regexp of folder name." + :type '(repeat (regexp :tag "Folder Regexp")) + :group 'wl-pref) + +(defcustom wl-search-mime-charset 'iso-2022-jp + "*MIME Charset for searching message." + :type 'symbol + :group 'wl-pref) + +(defcustom wl-folder-mime-charset-alist + '(("^-alt\\.chinese" . big5) + ("^-relcom\\." . koi8-r) + ("^-tw\\." . big5) + ("^-han\\." . euc-kr)) + "Charset alist. If no match, wl-mime-charset is used." + :type '(repeat (cons (regexp :tag "Folder Regexp") (symbol :tag "Charset"))) + :group 'wl-summary + :group 'wl-pref) + +(defcustom wl-folder-weekday-name-lang-alist + '(("^-alt\\.chinese" . "en") + ("^-relcom\\." . "en") + ("^-tw\\." . "en") + ("^-han\\." . "en")) + "Weekday name lang alist. If no match, wl-summary-weekday-name-lang +is used. +e.x. +'((\"xemacs-beta$\" . \"en\") + (\"^-fj\" . \"ja\"))" + :type '(repeat (cons (regexp :tag "Folder Regexp") + (choice (const "ja") + (const "en") + (const "fr") + (const "de") + (string :tag "Other")))) + :group 'wl-pref) + +(defcustom wl-folder-thread-indent-set-alist + '(("^-alt\\.chinese" . (2 "+" "+" "|" "-" " ")) + ("^-relcom\\." . (2 "+" "+" "|" "-" " ")) + ("^-tw\\." . (2 "+" "+" "|" "-" " ")) + ("^-han\\." . (2 "+" "+" "|" "-" " "))) + "Thread indent set alist. +If no match, following indent set is used. +(wl-thread-indent-level + wl-thread-have-younger-brother-str + wl-thread-youngest-child-str + wl-thread-vertical-str + wl-thread-horizontal-str + wl-thread-space-str) +e.x. +'((\"xemacs-beta$\" . (2 \"+\" \"+\" \"|\" \"-\" \" \")))" + :type '(repeat (cons (regexp :tag "Folder Regexp") + (group (integer :tag "Indent") + (string :tag "Yonger Brother") + (string :tag "Yonger Child") + (string :tag "Vertical") + (string :tag "Horizontal") + (string :tag "Space")))) + :group 'wl-pref) + +(defcustom wl-folder-sync-range-alist + (list (cons "^&.*$" "all") + (cons (concat "^" (regexp-quote wl-draft-folder) "$\\|^" + (regexp-quote wl-queue-folder) "$") + "all")) + "*Default sync range alist. If no matches, `wl-default-sync-range' is used." + :type '(repeat (cons (regexp :tag "Folder Regexp") + (choice (const "update") + (const "all") + (const "rescan") + (const "first:") + (const "last:") + (const "no-sync") + (const :tag "none" nil)))) + :group 'wl-pref) + +(defcustom wl-default-sync-range "update" + "*Default sync range." + :type '(choice (const "update") + (const "all") + (const "rescan") + (const "first:") + (const "last:") + (const "no-sync") + (const :tag "none" nil)) + :group 'wl-pref) + +(defcustom wl-ask-range t + "*If non-nil, ask for a range for summary synchronization. +If nil, always use default." + :type 'boolean + :group 'wl-pref) + +(defcustom wl-folder-move-cur-folder nil + "*Non-nil, move to current folder on folder-mode when goto folder." + :type 'boolean + :group 'wl-folder) + +(defcustom wl-folder-check-async (not wl-on-nemacs) + "*Check the folder asynchronous." + :type 'boolean + :group 'wl-folder) + +(defcustom wl-folder-notify-deleted nil + "*Non-nil, display negative number on folder-mode when message is deleted +in folder. If the value is 'sync, msgdb would be synchronized." + :type '(choice (const :tag "off" nil) + (const :tag "on" t) + (const sync)) + :group 'wl-folder) + +(defcustom wl-summary-exit-next-move t + "*Non-nil, move to next-unsync or next-entity when exit summary." + :type 'boolean + :group 'wl-summary) + +(defcustom wl-summary-next-no-unread-command + '(wl-summary-read wl-summary-down wl-summary-up) + "*Command list available when the value of `wl-auto-select-next' is 'unread +or 'skip-no-unread." + :type '(repeat function) + :group 'wl-summary) + +(defcustom wl-summary-search-via-nntp 'confirm + "*Non-nil, search message via nntp after `wl-summary-jump-to-msg-by-message-id'. If the value is 'confirm, confirm before search." + :type 'boolean + :group 'wl-summary) + +(defcustom wl-summary-keep-cursor-command + '(wl-summary-goto-folder wl-summary-goto-last-visited-folder) + "*Command list to keep cursor position when folder is changed to +already existing summary." + :type '(repeat function) + :group 'wl-summary) + +(defcustom wl-summary-showto-folder-regexp nil + "Regexp specifying the folder that shows the To (or Newsgroups) field as + Sender information in summary mode." + :type 'regexp + :group 'wl-summary) + +(defcustom wl-folder-removed-mark "#" + "Mark for removed folder." + :type 'string + :group 'wl-folder) + +(defcustom wl-folder-unsubscribe-mark "#" + "Mark for unsubscribe folder." + :type 'string + :group 'wl-folder) + +(defcustom wl-delete-folder-alist '(("^-" . remove)) + "*Alist of folder and delete policy. +Each element is (folder-regexp . policy). + +The policy is one of the followings: +'remove or +'null : remove message. +string : refile to the specified folder. +'trash or +otherwise : refile to the `wl-trash-folder'. +ex. +'((\"^%\" . \"%#mh/trash\") + (\"^-\" . remove) + (\"^\\\\+\" . trash))" + :type '(repeat (cons (regexp :tag "Folder Regexp") + (choice :tag "Policy" + (const remove) + (const :tag "remove(null)" null) + (const trash) + (const :tag "trash(other)" trash) + (string :tag "Folder")))) + :group 'wl-folder) + +(defcustom wl-refile-policy-alist '(("^[-=']" . copy) + (".*" . move)) + "*List of refile policy. Each element is (FOLDER-REGEXP . POLICY). +POLICY is copy or move." + :type '(repeat (cons (regexp :tag "Folder Regexp") + (choice (const copy) + (const move)))) + :group 'wl-summary + :group 'wl-pref) + +(defcustom wl-folder-hierarchy-access-folders '("-" "-alt") + "*Access group folders to make hierarchy structure." + :type '(repeat (string :tag "Folder")) + :group 'wl-folder) + +(defcustom wl-folder-init-load-access-folders nil + "*Access group folders to load folder list on `wl-folder-init'. +If this variable is non-nil, +`wl-folder-init-no-load-access-folders' will be ignored." + :type '(repeat (regexp :tag "Folder Regexp")) + :group 'wl-folder) + +(defcustom wl-folder-init-no-load-access-folders nil + "*Access group folders to not load folder list on `wl-folder-init'. +If `wl-folder-init-load-access-folders' is non-nil, +this variable will be ignored." + :type '(repeat (regexp :tag "Folder Regexp")) + :group 'wl-folder) + +(defcustom wl-folder-access-subscribe-alist nil + "*Subscribe folders to fetching folder entries. +Each element is (group-regexp (subscribe folder-regexp ...)). +If subscribe is non-nil, subscribe when match folder-regexp. +If subscribe is nil, unsubscribe when match folder-regexp. + +ex. +'((\"^-fj$\" . (t \"^-fj\\\\.\\\\(editor\\\\|mail\\\\|net\\\\|news\\\\)\")) + (\"^-comp$\" . (t \"^-comp\\\\.unix\" \"^-comp\\\\.sys\")) + (\"^-$\" . (nil \"^-alt\" \"^-rec\")))" + :type '(repeat (cons (regexp :tag "Folder Regexp") + (list (boolean :tag "Subscribed") + (repeat :inline t + (regexp :tag "Folder Regexp"))))) + :group 'wl-folder) + +;;; For Folder Manager + +(defcustom wl-interactive-save-folders t + "*Non-nil require your confirmation when save folders." + :type 'boolean + :group 'wl-folder) + +(defcustom wl-fldmgr-make-backup t + "*Non-nil make backup file when save folders." + :type 'boolean + :group 'wl-folder) + +(defcustom wl-fldmgr-folders-indent "\t" + "*Indent string for folders file." + :type 'string + :group 'wl-folder) + +(defcustom wl-fldmgr-sort-func 'wl-fldmgr-sort-standard + "*A function to sort folder." + :type 'function + :group 'wl-folder) + +(defcustom wl-fldmgr-sort-group-first t + "*Non-nil Group folder is first when sort." + :type 'function + :group 'wl-folder) + +;;; For Expire and Archive + +(defcustom wl-expire-alist nil + "Alist to decide a policy for expire. +Each element is (folder-regexp (number or date) policy). + +The policy is one of the followings: +'remove : remove messsage. +'trash : refile wl-trash-folder. +string : refile string folder. +function : call function. + +ex. +'((\"^\\\\+ml/wl$\" (number 500 510) wl-expire-archive-number1 t) + (\"^\\\\+ml/\" (number 300 305) wl-expire-archive-number2) + (\"^\\\\+outbox$\" (number 300) \"$outbox;lha\") + (\"^\\\\(\\\\+tmp\\\\|\\\\+trash\\\\)$\" (date 7) remove) + (\"^\\\\+misc$\" (date 14) trash))" + :type '(repeat (choice (list :tag "No-match" + (regexp :tag "Folder Regexp") + (const nil)) + (list :tag "Match" + (regexp :tag "Folder Regexp") + (list (radio :value number + (const number) + (const date)) + (list :inline t + integer + (repeat :inline t integer))) + (choice :tag "Policy" + :value remove + (const remove) + (const trash) + (string :tag "folder") + function) + (repeat :inline t + :tag "Arg for function" + sexp)))) + :group 'wl-expire) + +(defcustom wl-archive-alist '((".*" wl-archive-number1)) + "Alist to decide a policy for archive. +Each element is (folder-regexp policy(function)). + +ex. +'((\"\\\\+work$\" wl-archive-date) + (\"\\\\+ml/\" wl-archive-number1) + (\".*\" wl-archive-number2))" + :type '(repeat (list (regexp :tag "Folder Regexp") + function + (repeat :inline t + (sexp :tag "Argument")))) + :group 'wl-expire) + +(defcustom wl-summary-expire-reserve-marks + (list wl-summary-important-mark + wl-summary-new-mark + wl-summary-unread-mark + wl-summary-unread-uncached-mark + wl-summary-unread-cached-mark) + "Permanent marks of reserved message when expire. +Don't reserve temporary mark message. + +ex. +'all : reserved all permanent marks. +'none : not reserve permanent marks. +list : reserved specified permanent marks." + :type '(repeat (string :tag "Mark")) + :group 'wl-expire) + +(defcustom wl-expire-number-with-reserve-marks nil + "If non-nil, include reserve message when expire by number." + :type 'boolean + :group 'wl-expire) + +(defcustom wl-expire-add-seen-list t + "*If non-nil, add seen message list when refile message at expire." + :type 'boolean + :group 'wl-expire) + +(defcustom wl-expire-use-log nil + "*If non-nil, write a log when expired." + :type 'boolean + :group 'wl-expire) + +(defcustom wl-expire-folder-update-msgdb t + "*Non-nil update summary msgdb when expire on folder mode." + :type 'boolean + :group 'wl-expire) + +;; for wl-expire-archive-{number1|number2} +(defcustom wl-expire-archive-files 100 + "*The number of one archive folder." + :type 'integer + :group 'wl-expire) + +;; for wl-expire-archive-{number1|number2|date} +(defcustom wl-expire-archive-get-folder-func + 'wl-expire-archive-get-folder + "*A function to get archive folder name." + :type 'function + :group 'wl-expire) + +(defcustom wl-expire-delete-oldmsg-confirm t + "*If non-nil, require your confirmation when delete old message." + :type 'boolean + :group 'wl-expire) + +;; for wl-expire-archive-get-folder +(defcustom wl-expire-archive-folder-type 'zip + "*Archiver type of archive folder." + :type '(radio (const zip) + (const lha) + (const zoo) + (const rar) + (const tar) + (const tgz) + (symbol :tag "Other")) + :group 'wl-expire) + +(defcustom wl-expire-archive-folder-name-fmt "%s-%%05d;%s" ;; $folder-00100;zip + "*A format string for archive folder name." + :type 'string + :group 'wl-expire) + +(defcustom wl-expire-archive-folder-num-regexp "-\\([0-9]+\\);" + "*A regexp string for archive folder name." + :type 'string + :group 'wl-expire) + +(defcustom wl-expire-archive-date-folder-name-fmt "%s-%%04d%%02d;%s" + ;; $folder-199812;zip + "*A format string for archive date folder name." + :type 'string + :group 'wl-expire) + +(defcustom wl-expire-archive-date-folder-num-regexp "-\\([0-9]+\\);" + "*A regexp string for archive date folder name." + :type 'string + :group 'wl-expire) + +(defcustom wl-expire-archive-folder-prefix nil + "*Prefix for archive folder." + :type '(radio (const :tag "nothing" nil) + (const :tag "full" t) + (const short)) + :group 'wl-expire) + +;;;; Highlights. + +;; highilght about summary +(defcustom wl-highlight-max-summary-lines 10000 + "*If the summary is larger than this lines, don't highlight it." + :type 'integer + :group 'wl-highlight) + +;; highilght about draft and message +(defcustom wl-highlight-body-too t + "*In addition to header, highlight the body too. if non nil." + :type 'boolean + :group 'wl-highlight) + +(defcustom wl-highlight-message-header-alist + '(("Subject[ \t]*:" . wl-highlight-message-important-header-contents) + ("From[ \t]*:\\|To[ \t]*:" . wl-highlight-message-important-header-contents2) + ("X-[^ \t]*:\\|User-Agent[ \t]*:" . wl-highlight-message-unimportant-header-contents)) + "" + :type '(repeat (cons regexp face)) + :group 'wl-highlight) + +(defcustom wl-highlight-citation-prefix-regexp + "^[>|:} ]*[>|:}]\\([^ \n>]*>\\)?\\|^[^ <\n>]*>" + "All lines that match this regexp will be highlighted with + `wl-highlight-message-cited-text-*' face." + :type 'regexp + :group 'wl-highlight) + +(defcustom wl-highlight-highlight-citation-too nil + "*Whether the whole citation line should go in the + `wl-highlight-citation-face' face. +If nil, the text matched by `wl-highlight-citation-prefix-regexp' is in the +default face, and the remainder of the line is in the +wl-highlight-message-cited-text face." + :type 'boolean + :group 'wl-highlight) + +(defcustom wl-highlight-force-citation-header-regexp + "^>>>.*$\\|^[ \t]*<[^>]*>[ \t]*$" + "*The pattern to match the prolog of a cited block. +Text in the body of a message which matches this will be displayed in +the `wl-highlight-message-headers' face." + :type 'regexp + :group 'wl-highlight) + +(defcustom wl-highlight-citation-header-regexp + (concat "In article.*$\\|In message.*$\\|In the message.*$\\|" + "^At[^\n]+\n[^\n]+wrote:\n\\|" + "^.*\\(writes\\|wrote\\|said\\):\n") + "*The pattern to match the prolog of a cited block. +Text in the body of a message which matches this will be displayed in +the `wl-highlight-message-headers' face." + :type 'regexp + :group 'wl-highlight) + +(defcustom wl-highlight-max-message-size 10000 + "*If the message body is larger than this many chars, don't highlight it. +This is to prevent us from wasting time trying to fontify things like +uuencoded files and large digests. If this is nil, all messages will +be highlighted." + :type 'integer + :group 'wl-highlight) + +;; highilght about signature (of draft and message) +(defcustom wl-highlight-signature-separator + '("\n--+\n" "\n\n--+.*\n*\\'") + "List of regexps matching signature separator. +It will be verified from head to tail looking for a separator. +Verification will be done from the end of the buffer. +No need to specify \"^-- $\" in this list, +because it is verified by default. +This variable can also be a regex. " + :type '(repeat regexp) + :group 'wl-highlight) + +(defcustom wl-max-signature-size 400 + "*If the signature is larger than this chars, don't treat it as a signature." + :type 'integer + :group 'wl-highlight) + +;; highilght about mouse +(defcustom wl-use-highlight-mouse-line (and wl-on-xemacs window-system) + "*Highlight mouse line, if non nil." + :type 'boolean + :group 'wl-highlight) + +;; highilght about folder +(defcustom wl-highlight-folder-with-icon + (and (featurep 'xemacs) + (featurep 'xpm)) + "*Highlight folder with icon(XEmacs)." + :type 'boolean + :group 'wl-highlight) +(defcustom wl-highlight-group-folder-by-numbers t + "*Highlight group folder by numbers." + :type 'boolean + :group 'wl-highlight) + +(defcustom wl-highlight-signature-search-func 'wl-highlight-signature-search + "Function to search signature area in the message body." + :type 'function + :group 'wl-highlight) + +(defcustom wl-use-dnd (and wl-on-xemacs + (featurep 'dragdrop)) + "If Non-nil, support dragdrop feature in XEmacs." + :type 'boolean + :group 'wl-pref) + +(defcustom wl-reset-plugged-alist t + "*If non-nil, reset `elmo-plugged-alist' when startup." + :type 'boolean + :group 'wl-pref) + +(defcustom wl-demo-display-logo (or (and (featurep 'xemacs) + (featurep 'xpm)) + (and (module-installed-p 'image) + (image-type-available-p 'xpm)) + (module-installed-p 'bitmap)) + "If non-nil, display image (or bitmap) logo in th Wanderlust opening demo." + :type 'boolean + :group 'wl-pref) + +;;; Internal variables +(defvar wl-init nil) + +;; For disconnected operations. +(defvar wl-plugged-hook nil) +(defvar wl-unplugged-hook nil) +(defvar wl-plugged t) + +(defvar wl-plug-state-indicator-on " [ON] ") +(defvar wl-plug-state-indicator-off " [--] ") +(defvar wl-plug-state-indicator wl-plug-state-indicator-on) + +(defvar wl-show-plug-status-on-modeline t) + +;; Advanced thread view. +(defvar wl-thread-indent-level 1 + "*Indent level for thread.") +(defvar wl-thread-have-younger-brother-str "$B(2(B" + "*A string for thread branch line. It should contain one character.") +(defvar wl-thread-youngest-child-str "$B(1(B" + "*A string for thread branch line. It should contain one character.") +(defvar wl-thread-vertical-str "$B(-(B" + "*A string for thread branch line. It should contain one character.") +(defvar wl-thread-horizontal-str "$B(,(B" + "*A string for thread branch line. It should contain one character.") +(defvar wl-thread-space-str "$B!!(B" + "*A string for thread branch line. It should contain one character.") + +(defvar wl-highlight-thread-indent-string-regexp "[^\\[]*" + "* A regexp string for thread indent...for highlight.") + +;; folder icons. filename relative to wl-icon-dir +(defvar wl-opened-group-folder-icon "opened.xpm" + "*Icon file for opened group folder.") +(defvar wl-closed-group-folder-icon "closed.xpm" + "*Icon file for closed group folder.") +(defvar wl-nntp-folder-icon "news.xpm" + "*Icon file for nntp folder.") +(defvar wl-imap-folder-icon "imap.xpm" + "*Icon file for imap folder.") +(defvar wl-pop-folder-icon "pop.xpm" + "*Icon file for pop folder.") +(defvar wl-localdir-folder-icon "local.xpm" + "*Icon file for localdir folder.") +(defvar wl-localnews-folder-icon "localnews.xpm" + "*Icon file for localnews folder.") +(defvar wl-internal-folder-icon "internal.xpm" + "*Icon file for internal folder.") +(defvar wl-multi-folder-icon "multi.xpm" + "*Icon file for multi folder.") +(defvar wl-filter-folder-icon "filter.xpm" + "*Icon file for filter folder.") +(defvar wl-archive-folder-icon "archive.xpm" + "*Icon file for archive folder.") +(defvar wl-pipe-folder-icon "pipe.xpm" + "*Icon file for pipe folder.") +(defvar wl-maildir-folder-icon "maildir.xpm" + "*Icon file for maildir folder.") +(defvar wl-empty-trash-folder-icon "trash-e.xpm" + "*Icon file for emptied trash folder.") +(defvar wl-trash-folder-icon "trash.xpm" + "*Icon file for trash folder.") +(defvar wl-draft-folder-icon "draft.xpm" + "*Icon file for draft folder.") +(defvar wl-queue-folder-icon "queue.xpm" + "*Icon file for queue folder.") +(defvar wl-plugged-icon "plugged.xpm" + "*Icon file for plugged state.") +(defvar wl-unplugged-icon "unplugged.xpm" + "*Icon file for unplugged state.") +(defvar wl-prog-uudecode "uudecode" + "*uudecode program name") +(defvar wl-prog-uudecode-arg '("-p") ;; outout is stdout. + "*arguments for uudecode program") +(defvar wl-prog-uudecode-no-stdout-option nil + "*If non-nil, uudecode program don't have option for output to stdout.") + +;; Obsolete variables. for compatibility. +(defvar wl-address-filename wl-address-file) +(make-obsolete-variable 'wl-address-filename 'wl-address-file) +(defvar wl-score-default-file-name wl-score-default-file) +(make-obsolete-variable 'wl-score-default-file-name 'wl-score-default-file) +(defvar wl-draft-prepared-config-alist nil) +(make-obsolete-variable 'wl-draft-prepared-config-alist 'wl-draft-config-alist) +(defvar wl-score-files-directory wl-score-files-dir) +(make-obsolete-variable 'wl-score-files-directory 'wl-score-files-dir) + +;; plug +(defvar wl-plugged-plug-on "ON") +(defvar wl-plugged-plug-off "--") +(defvar wl-plugged-auto-off "**") +(defvar wl-plugged-server-indent 2) +(defvar wl-plugged-port-indent 4) +(defvar wl-plugged-queue-status-column 25) + +(provide 'wl-vars) + +;;; wl-vars.el ends here diff --git a/wl/wl-xmas.el b/wl/wl-xmas.el new file mode 100644 index 0000000..9ad923f --- /dev/null +++ b/wl/wl-xmas.el @@ -0,0 +1,463 @@ +;;; wl-xmas.el -- Wanderlust modules for XEmacsen. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <00/03/24 14:44:00 teranisi> + +;; This file is part of Wanderlust (Yet Another Message Interface on Emacsen). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; + +(eval-when-compile + (require 'wl-folder) + (require 'wl-summary) + (require 'wl-draft) + (require 'wl-message) + (require 'wl-highlight) + (defvar-maybe wl-draft-mode-map (make-sparse-keymap))) + +(defun wl-xmas-setup-toolbar (bar) + (let ((dir wl-icon-dir) + icon up down disabled name) + (when dir + (while bar + (setq icon (aref (car bar) 0) + name (symbol-name icon) + bar (cdr bar)) + (when (not (boundp icon)) + (setq up (concat dir elmo-path-sep name "-up.xpm")) + (setq down (concat dir elmo-path-sep name "-down.xpm")) + (setq disabled (concat dir elmo-path-sep name "-disabled.xpm")) + (if (not (file-exists-p up)) + (setq bar nil + dir nil) + (set icon (toolbar-make-button-list + up (and (file-exists-p down) down) + (and (file-exists-p disabled) disabled))))))) + dir)) + +(defvar wl-use-toolbar (if (featurep 'toolbar) 'default-toolbar nil)) +(defvar wl-plugged-glyph nil) +(defvar wl-unplugged-glyph nil) + +(defvar wl-folder-toolbar + '([wl-folder-jump-to-current-entity + wl-folder-jump-to-current-entity t "Enter Current Folder"] + [wl-folder-next-entity + wl-folder-next-entity t "Next Folder"] + [wl-folder-prev-entity + wl-folder-prev-entity t "Previous Folder"] + [wl-folder-check-current-entity + wl-folder-check-current-entity t "Check Current Folder"] +; [wl-draft +; wl-draft t "Write a New Message"] + [wl-folder-sync-current-entity + wl-folder-sync-current-entity t "Sync Current Folder"] + [wl-draft + wl-draft t "Write a New Message"] + [wl-folder-empty-trash + wl-folder-empty-trash t "Empty Trash"] + [wl-exit + wl-exit t "Quit Wanderlust"] + ) + "The Folder buffer toolbar.") + +(defvar wl-summary-toolbar + '([wl-summary-read + wl-summary-read t "Read Messages"] + [wl-summary-next + wl-summary-next t "Next Message"] + [wl-summary-prev + wl-summary-prev t "Previous Message"] + [wl-summary-jump-to-current-message + wl-summary-jump-to-current-message t "Jump to Current Message"] + [wl-summary-sync-force-update + wl-summary-sync-force-update t "Sync Current Folder"] + [wl-summary-delete + wl-summary-delete t "Delete Current Message"] + [wl-summary-mark-as-important + wl-summary-mark-as-important t "Mark Current Message as Important"] + [wl-draft + wl-draft t "Write a New Message"] + [wl-summary-reply + wl-summary-reply t "Reply to Current Message" ] + [wl-summary-reply-with-citation + wl-summary-reply-with-citation t "Reply to Current Message with Citation"] + [wl-summary-forward + wl-summary-forward t "Forward Current Message"] + [wl-summary-exit + wl-summary-exit t "Exit Current Summary"] + ) + "The Summary buffer toolbar.") + +(defvar wl-message-toolbar + '([wl-message-read + wl-message-read t "Read Contents"] + [wl-message-next-content + wl-message-next-content t "Next Content"] + [wl-message-prev-content + wl-message-prev-content t "Previous Content"] + [wl-message-quit + wl-message-quit t "Back to Summary"] + [wl-message-play-content + wl-message-play-content t "Play Content"] + [wl-message-extract-content + wl-message-extract-content t "Extract Content"] + ) + "The Message buffer toolbar.") + +(defalias 'wl-draft-insert-signature 'insert-signature) ;; for draft toolbar. + +(defvar wl-draft-toolbar + '([wl-draft-send-from-toolbar + wl-draft-send-from-toolbar t "Send Current Draft"] + [wl-draft-yank-original + wl-draft-yank-original t "Yank Displaying Message"] + [wl-draft-insert-signature + wl-draft-insert-signature t "Insert Signature"] + [wl-draft-kill + wl-draft-kill t "Kill Current Draft"] + ) + "The Draft buffer toolbar.") + +(defun wl-xmas-setup-folder-toolbar () + (and wl-use-toolbar + (wl-xmas-setup-toolbar wl-folder-toolbar) + (set-specifier (symbol-value wl-use-toolbar) + (cons (current-buffer) wl-folder-toolbar)))) + +(defun wl-xmas-setup-summary-toolbar () + (and wl-use-toolbar + (wl-xmas-setup-toolbar wl-summary-toolbar) + (set-specifier (symbol-value wl-use-toolbar) + (cons (current-buffer) wl-summary-toolbar)))) + +(defun wl-xmas-setup-message-toolbar () + (and wl-use-toolbar + (wl-xmas-setup-toolbar wl-message-toolbar) + (set-specifier (symbol-value wl-use-toolbar) + (cons (current-buffer) wl-message-toolbar)))) + +(defun wl-xmas-setup-draft-toolbar () + (and wl-use-toolbar + (wl-xmas-setup-toolbar wl-draft-toolbar) + (set-specifier (symbol-value wl-use-toolbar) + (cons (current-buffer) wl-draft-toolbar)))) + +;; XEmacs implementations. +(defun wl-highlight-folder-current-line (&optional numbers) + (interactive) + (save-excursion + (let ((highlights (list "opened" "closed")) + (inhibit-read-only t) + (fld-name (wl-folder-get-folder-name-by-id + (get-text-property (point) 'wl-folder-entity-id))) + fregexp fsymbol bol eol matched type extent num type glyph) + (setq eol (progn (end-of-line) (point)) + bol (progn (beginning-of-line) (point))) + (when (and fld-name (looking-at "[ \t]+\\([^ \t]+\\)")) + (if (and (setq extent (extent-at (match-beginning 1) nil nil nil 'at)) + (extent-begin-glyph extent)) + (delete-extent extent)) + (setq extent (make-extent (match-beginning 1) (match-beginning 1))) + (cond + ((string= fld-name wl-trash-folder) ;; set trash folder icon + (setq num (nth 2 numbers)) ;; number of messages + (set-extent-begin-glyph extent + (if (or (null num) + (eq num 0)) + wl-folder-trash-empty-glyph + wl-folder-trash-glyph))) + ((string= fld-name wl-draft-folder) ;; set draft folder icon + (set-extent-begin-glyph extent wl-folder-draft-glyph)) + ((string= fld-name wl-queue-folder) + (set-extent-begin-glyph extent wl-folder-queue-glyph)) + ((and (setq type (elmo-folder-get-type fld-name)) + (or numbers ;; XXX dirty...!! + (not (assoc fld-name wl-folder-group-alist)))) + ;; not group folder. + (set-extent-begin-glyph extent + (symbol-value + (intern (format "wl-folder-%s-glyph" + type))))))) + (when (and numbers (nth 0 numbers) (nth 1 numbers)) + (setq fsymbol + (let ((unsync (nth 0 numbers)) + (unread (nth 1 numbers))) + (cond ((and unsync (eq unsync 0)) + (if (and unread (> unread 0)) + 'wl-highlight-folder-unread-face + 'wl-highlight-folder-zero-face)) + ((and unsync + (>= unsync wl-folder-many-unsync-threshold)) + 'wl-highlight-folder-many-face) + (t + 'wl-highlight-folder-few-face)))) + (put-text-property bol eol 'face nil) + (put-text-property bol eol 'face fsymbol) + (setq matched t)) + (while highlights + (setq fregexp (symbol-value + (intern (format "wl-highlight-folder-%s-regexp" + (car highlights))))) + (if (not wl-highlight-group-folder-by-numbers) + (setq fsymbol (intern (format "wl-highlight-folder-%s-face" + (car highlights))))) + (when (looking-at fregexp) + (setq extent (make-extent (match-beginning 1) (match-end 1)) + glyph (intern (format "wl-folder-%s-glyph" + (car highlights)))) + (if (null (symbol-value glyph)) + (set glyph (wl-xmas-make-icon-glyph + (extent-string extent) + (symbol-value + (cdr (assq glyph wl-folder-toggle-icon-list)))))) + (setq glyph (symbol-value glyph)) + (set-extent-property extent 'end-open t) + (set-extent-property extent 'start-closed t) + (set-extent-property extent 'invisible t) + (set-extent-end-glyph extent glyph) + (put-text-property bol eol 'face nil) + (put-text-property bol eol 'face fsymbol) + (setq matched t highlights nil)) + (setq highlights (cdr highlights))) + (when (not matched) + (put-text-property bol eol 'face nil) + (if (looking-at (format "^[ ]*\\(%s\\|%s\\)" + wl-folder-unsubscribe-mark + wl-folder-removed-mark)) + (put-text-property bol eol 'face + 'wl-highlight-folder-killed-face) + (put-text-property bol eol 'face + 'wl-highlight-folder-unknown-face))) + (if wl-use-highlight-mouse-line + (wl-highlight-folder-mouse-line)) + (if (and (featurep 'dragdrop) wl-use-dnd) + (wl-dnd-set-drop-target bol eol))))) + +(defun wl-highlight-plugged-current-line () + (interactive) + (save-excursion + (let ((inhibit-read-only t) + extent switch) + (beginning-of-line) + (when (looking-at "[ \t]*\\(\\[\\([^]]+\\)\\]\\)") + (setq switch (elmo-match-buffer 2)) + (if (and (setq extent (extent-at (match-end 1) nil nil nil 'at)) + (extent-end-glyph extent)) + (delete-extent extent)) + (setq extent (make-extent (match-beginning 1) (match-end 1))) + (set-extent-property extent 'end-open t) + (set-extent-property extent 'start-closed t) + (set-extent-property extent 'invisible t) + (set-extent-end-glyph extent (if (string= switch wl-plugged-plug-on) + wl-plugged-glyph + wl-unplugged-glyph)))))) + +(defun wl-plugged-set-folder-icon (folder string) + (let ((string (copy-sequence string)) + (len (length string)) + type) + (if (string= folder wl-queue-folder) + (put-text-property 0 len 'begin-glyph wl-folder-queue-glyph string) + (if (setq type (elmo-folder-get-type folder)) + (put-text-property 0 len + 'begin-glyph + (symbol-value + (intern (format "wl-folder-%s-glyph" type))) + string))) + string)) + +(defvar wl-folder-internal-icon-list + ;; alist of (glyph . icon-file) + '((wl-folder-nntp-glyph . wl-nntp-folder-icon) + (wl-folder-imap4-glyph . wl-imap-folder-icon) + (wl-folder-pop3-glyph . wl-pop-folder-icon) + (wl-folder-localdir-glyph . wl-localdir-folder-icon) + (wl-folder-localnews-glyph . wl-localnews-folder-icon) + (wl-folder-internal-glyph . wl-internal-folder-icon) + (wl-folder-multi-glyph . wl-multi-folder-icon) + (wl-folder-filter-glyph . wl-filter-folder-icon) + (wl-folder-archive-glyph . wl-archive-folder-icon) + (wl-folder-pipe-glyph . wl-pipe-folder-icon) + (wl-folder-maildir-glyph . wl-maildir-folder-icon) + (wl-folder-trash-empty-glyph . wl-empty-trash-folder-icon) + (wl-folder-draft-glyph . wl-draft-folder-icon) + (wl-folder-queue-glyph . wl-queue-folder-icon) + (wl-folder-trash-glyph . wl-trash-folder-icon))) + +(defvar wl-folder-toggle-icon-list + '((wl-folder-opened-glyph . wl-opened-group-folder-icon) + (wl-folder-closed-glyph . wl-closed-group-folder-icon))) + +(defun wl-xmas-make-icon-glyph (icon-string icon-file &optional locale tag-set) + (let ((glyph (make-glyph (vector 'string :data icon-string)))) + (if wl-highlight-folder-with-icon + (set-glyph-image glyph + (vector 'xpm :file (expand-file-name + icon-file wl-icon-dir)) + locale tag-set 'prepend)) + glyph)) + +(defun wl-folder-init-icons () + (mapcar + (lambda (x) + (if (null (symbol-value (car x))) + (set (car x) (wl-xmas-make-icon-glyph "" (symbol-value (cdr x)))))) + wl-folder-internal-icon-list)) + +(defun wl-plugged-init-icons () + (if (null wl-plugged-glyph) + (setq wl-plugged-glyph + (wl-xmas-make-icon-glyph + (concat "[" wl-plugged-plug-on "]") + wl-plugged-icon))) + (if (null wl-unplugged-glyph) + (setq wl-unplugged-glyph + (wl-xmas-make-icon-glyph + (concat "[" wl-plugged-plug-off "]") + wl-unplugged-icon)))) + +(defun wl-make-modeline () + "Make modeline for Wanderlust" + (wl-plugged-init-icons) + (let ((extent (make-extent nil nil)) + (toggle-keymap (make-sparse-keymap))) + (define-key toggle-keymap 'button2 (make-modeline-command-wrapper + 'wl-toggle-plugged)) + (set-extent-keymap extent toggle-keymap) + (set-extent-property extent 'help-echo "button2 toggles plugged status") + (setq wl-plug-state-indicator-on (cons extent wl-plugged-glyph)) + (setq wl-plug-state-indicator-off (cons extent wl-unplugged-glyph)) + (setq wl-plug-state-indicator (if wl-plugged + wl-plug-state-indicator-on + wl-plug-state-indicator-off))) + (wl-make-modeline-subr)) + +(defun wl-make-date-string () + (let ((s (current-time-string))) + (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]" + s) + (concat (wl-match-string 1 s) ", " + (timezone-make-date-arpa-standard s (current-time-zone))))) + + +(defun wl-xmas-setup-folder () + (and (featurep 'scrollbar) + (set-specifier scrollbar-height (cons (current-buffer) 0))) + (wl-xmas-setup-folder-toolbar)) + +(defun wl-xmas-setup-summary () + (make-local-variable 'dragdrop-drop-functions) + (setq dragdrop-drop-functions '((wl-dnd-default-drop-message t t))) + (and (featurep 'scrollbar) + (set-specifier scrollbar-height (cons (current-buffer) 0))) + (wl-xmas-setup-summary-toolbar)) + +(defun wl-message-overload-functions () + (wl-xmas-setup-message-toolbar) + (local-set-key "l" 'wl-message-toggle-disp-summary) + (local-set-key 'button2 'wl-message-refer-article-or-url) + (local-set-key 'button4 'wl-message-wheel-down) + (local-set-key 'button5 'wl-message-wheel-up) + (local-set-key [(shift button4)] 'wl-message-wheel-down) + (local-set-key [(shift button5)] 'wl-message-wheel-up)) + +(defun wl-message-wheel-up (event) + (interactive "e") + (let ((cur-buf (current-buffer)) + proceed) + (save-selected-window + (select-window (event-window event)) + (set-buffer cur-buf) + (setq proceed (wl-message-next-page))) + (if proceed + (if (memq 'shift (event-modifiers event)) + (wl-summary-down t) + (wl-summary-next t))))) + +(defun wl-message-wheel-down (event) + (interactive "e") + (let ((cur-buf (current-buffer)) + proceed) + (save-selected-window + (select-window (event-window event)) + (set-buffer cur-buf) + (setq proceed (wl-message-prev-page))) + (if proceed + (if (memq 'shift (event-modifiers event)) + (wl-summary-up t) + (wl-summary-prev t))))) + +(defun wl-draft-overload-menubar () + (add-menu-item '("Mail") "Send, Keep Editing" + 'wl-draft-send t "Send Mail") + (add-menu-item '("Mail") "Send Message" + 'wl-draft-send-and-exit t "Send and Exit") + (delete-menu-item '("Mail" "Send Mail")) + (delete-menu-item '("Mail" "Send and Exit")) + ) + +(defun wl-draft-mode-setup () + (require 'derived) + (define-derived-mode wl-draft-mode mail-mode "Draft" + "draft mode for Wanderlust derived from mail mode. +See info under Wanderlust for full documentation. + +Special commands: +\\{wl-draft-mode-map}")) + +(defun wl-draft-key-setup () + (define-key wl-draft-mode-map "\C-c\C-y" 'wl-draft-yank-original) + (define-key wl-draft-mode-map "\C-c\C-s" 'wl-draft-send) + (define-key wl-draft-mode-map "\C-c\C-a" 'wl-draft-insert-x-face-field) + (define-key wl-draft-mode-map "\C-c\C-c" 'wl-draft-send-and-exit) + (define-key wl-draft-mode-map "\C-c\C-z" 'wl-draft-save-and-exit) + (define-key wl-draft-mode-map "\C-c\C-k" 'wl-draft-kill) + (define-key wl-draft-mode-map "\C-l" 'wl-draft-highlight-and-recenter) + (define-key wl-draft-mode-map "\C-i" 'wl-complete-field-body-or-tab) + (define-key wl-draft-mode-map "\C-c\C-r" 'wl-draft-caesar-region) + (define-key wl-draft-mode-map "\M-t" 'wl-toggle-plugged) + (define-key wl-draft-mode-map "\C-c\C-o" 'wl-jump-to-draft-buffer) + (define-key wl-draft-mode-map "\C-c\C-e" 'wl-draft-config-exec) + (define-key wl-draft-mode-map "\C-c\C-j" 'wl-template-select) + (define-key wl-draft-mode-map "\C-c\C-p" 'wl-draft-preview-message) + (define-key wl-draft-mode-map "\C-x\C-s" 'wl-draft-save) + (define-key wl-draft-mode-map "\C-xk" 'wl-draft-mimic-kill-buffer)) + +(defun wl-draft-overload-functions () + (setq mode-line-buffer-identification + (format "Wanderlust: %s" (buffer-name))) + (local-set-key "\C-c\C-s" 'wl-draft-send) ; override + (wl-xmas-setup-draft-toolbar) + (wl-draft-overload-menubar) + (when wl-show-plug-status-on-modeline + (setq mode-line-format (wl-make-modeline)))) + +(defalias 'wl-defface 'defface) + +(provide 'wl-xmas) + +;;; wl-xmas.el ends here diff --git a/wl/wl.el b/wl/wl.el new file mode 100644 index 0000000..3efc943 --- /dev/null +++ b/wl/wl.el @@ -0,0 +1,811 @@ +;;; wl.el -- Wanderlust bootstrap. + +;; Copyright 1998,1999,2000 Yuuichi Teranishi + +;; Author: Yuuichi Teranishi +;; Keywords: mail, net news +;; Time-stamp: <00/03/22 15:44:44 teranisi> + +;; This file is part of Wanderlust (Yet Another Message Interface on Emacsen). + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; + +;;; Commentary: +;; + +;;; Code: +;; + +(require 'elmo2) +;; from x-face.el +(unless (and (fboundp 'defgroup) + (fboundp 'defcustom)) + (require 'backquote) + (defmacro defgroup (&rest args)) + (defmacro defcustom (symbol value &optional doc &rest args) + (let ((doc (concat "*" (or doc "")))) + (` (defvar (, symbol) (, value) (, doc)))))) + +(require 'wl-vars) +(require 'wl-util) + +(if wl-on-xemacs + (require 'wl-xmas) + (if wl-on-nemacs + (require 'wl-nemacs) + (require 'wl-mule))) + +(provide 'wl) ; circular dependency +(require 'wl-folder) +(require 'wl-summary) +(require 'wl-thread) +(require 'wl-address) + +(wl-draft-mode-setup) +(require 'wl-draft) +(wl-draft-key-setup) + +(require 'wl-demo) +(require 'wl-highlight) + +(eval-when-compile + (require 'smtp) + (require 'wl-score) + (unless wl-on-nemacs + (require 'wl-fldmgr)) + (if wl-use-semi + (require 'wl-mime) + (require 'tm-wl))) + +(defun wl-plugged-init (&optional make-alist) + (setq elmo-plugged wl-plugged) + (if wl-reset-plugged-alist + (elmo-set-plugged elmo-plugged)) + (when make-alist + (wl-make-plugged-alist)) + ;; Plug status. + (setq elmo-plugged (setq wl-plugged (elmo-plugged-p))) + (setq wl-plug-state-indicator + (if wl-plugged + wl-plug-state-indicator-on + wl-plug-state-indicator-off)) + (force-mode-line-update t)) + +(defun wl-toggle-plugged (&optional arg queue-flush-only) + (interactive) + (elmo-quit) ; Disconnect current connection. + (unless queue-flush-only + (cond + ((eq arg 'on) + (setq wl-plugged t)) + ((eq arg 'off) + (setq wl-plugged nil)) + (t (setq wl-plugged (null wl-plugged)))) + (elmo-set-plugged wl-plugged)) + (setq elmo-plugged wl-plugged) + (save-excursion + (mapcar + (function + (lambda (x) + (set-buffer x) + (wl-summary-msgdb-save) + ;; msgdb is saved, but cache is not saved yet. + (wl-summary-set-message-modified))) + (wl-collect-summary))) + (if wl-plugged + (progn + ;; flush queue!! + (setq wl-plug-state-indicator wl-plug-state-indicator-on) + (elmo-dop-queue-flush) + (if (and wl-draft-enable-queuing + wl-auto-flush-queue) + (wl-draft-queue-flush)) + (when (and (eq major-mode 'wl-summary-mode) + (elmo-folder-plugged-p wl-summary-buffer-folder-name)) + (let* ((msgdb-dir (elmo-msgdb-expand-path + wl-summary-buffer-folder-name)) + (seen-list (elmo-msgdb-seen-load msgdb-dir))) + (setq seen-list + (wl-summary-flush-pending-append-operations seen-list)) + (elmo-msgdb-seen-save msgdb-dir seen-list))) + (run-hooks 'wl-plugged-hook)) + (setq wl-plug-state-indicator wl-plug-state-indicator-off) + (run-hooks 'wl-unplugged-hook)) + (force-mode-line-update t)) + +;;; wl-plugged-mode + +(defvar wl-plugged-port-label-alist + (list (cons elmo-default-nntp-port "nntp") + (cons elmo-default-imap4-port "imap4") + (cons elmo-default-pop3-port "pop3"))) + ;;(cons elmo-pop-before-smtp-port "pop3") + +(defconst wl-plugged-switch-variables + '(("Queuing" . wl-draft-enable-queuing) + ("AutoFlushQueue" . wl-auto-flush-queue) + ("DisconnectedOperation" . elmo-enable-disconnected-operation))) + +(defvar wl-plugged-buf-name "Plugged") +(defvar wl-plugged-mode-map nil) +(defvar wl-plugged-alist nil) +(defvar wl-plugged-switch nil) +(defvar wl-plugged-winconf nil) +(defvar wl-plugged-sending-queue-alist nil) +(defvar wl-plugged-dop-queue-alist nil) +(defvar wl-plugged-alist-modified nil) + +(defvar wl-plugged-glyph nil) +(defvar wl-unplugged-glyph nil) + +(defvar wl-plugged-mode-menu-spec + '("Plugged" + ["Toggle plugged" wl-plugged-toggle t] + ["Toggle All plugged" wl-plugged-toggle-all t] + ["Prev Port" wl-plugged-move-to-previous t] + ["Next Port" wl-plugged-move-to-next t] + ["Prev Server" wl-plugged-move-to-previous-server t] + ["Next Server" wl-plugged-move-to-next-server t] + ["Flush queue" wl-plugged-flush-queue t] + "----" + ["Exit" wl-plugged-exit t])) + +(eval-and-compile + (if wl-on-xemacs + (defun wl-plugged-setup-mouse () + (define-key wl-plugged-mode-map 'button2 'wl-plugged-click)) + (if wl-on-nemacs + (defun wl-plugged-setup-mouse ()) + (defun wl-plugged-setup-mouse () + (define-key wl-plugged-mode-map [mouse-2] 'wl-plugged-click))))) + +(unless wl-plugged-mode-map + (setq wl-plugged-mode-map (make-sparse-keymap)) + (define-key wl-plugged-mode-map " " 'wl-plugged-toggle) + (define-key wl-plugged-mode-map "\C-m" 'wl-plugged-toggle) + (define-key wl-plugged-mode-map "\M-t" 'wl-plugged-toggle-all) + (define-key wl-plugged-mode-map "q" 'wl-plugged-exit) + (define-key wl-plugged-mode-map "\C-t" 'wl-plugged-exit) + (define-key wl-plugged-mode-map "F" 'wl-plugged-flush-queue) + (define-key wl-plugged-mode-map "P" 'wl-plugged-move-to-previous-server) + (define-key wl-plugged-mode-map "N" 'wl-plugged-move-to-next-server) + (define-key wl-plugged-mode-map "p" 'wl-plugged-move-to-previous) + (define-key wl-plugged-mode-map "n" 'wl-plugged-move-to-next) + (define-key wl-plugged-mode-map "\e\t" 'wl-plugged-move-to-previous) + (define-key wl-plugged-mode-map "\t" 'wl-plugged-move-to-next) + (wl-plugged-setup-mouse) + (easy-menu-define + wl-plugged-mode-menu + wl-plugged-mode-map + "Menu used in Plugged mode." + wl-plugged-mode-menu-spec)) + +(defun wl-plugged-mode () + "Mode for setting Wanderlust plugged. +See info under Wanderlust for full documentation. + +Special commands: +\\{wl-plugged-mode-map} + +Entering Plugged mode calls the value of `wl-plugged-mode-hook'." + (interactive) + (kill-all-local-variables) + (use-local-map wl-plugged-mode-map) + (setq major-mode 'wl-plugged-mode) + (setq mode-name "Plugged") + (easy-menu-add wl-plugged-mode-menu) + (when wl-show-plug-status-on-modeline + (setq mode-line-format (wl-make-modeline))) + (setq wl-plugged-switch wl-plugged) + (setq wl-plugged-alist-modified nil) + (setq buffer-read-only t) + (run-hooks 'wl-plugged-mode-hook)) + +(defmacro wl-plugged-string (plugged &optional time) + (` (if (, time) wl-plugged-auto-off + (if (, plugged) wl-plugged-plug-on wl-plugged-plug-off)))) + +(defmacro wl-plugged-server-indent () + (` (make-string wl-plugged-server-indent ? ))) + +(defun wl-plugged-set-variables () + (setq wl-plugged-sending-queue-alist + (wl-plugged-sending-queue-info)) + (setq wl-plugged-dop-queue-alist + (wl-plugged-dop-queue-info)) + (setq wl-plugged-alist + (sort (copy-sequence elmo-plugged-alist) + '(lambda (a b) + (string< (caar a) (caar b)))))) + +(defun wl-plugged-sending-queue-info () + ;; sending queue status + (let (alist msgs sent-via server port) + (setq msgs (elmo-list-folder wl-queue-folder)) + (while msgs + (setq sent-via (wl-draft-queue-info-operation (car msgs) 'get-sent-via)) + (while sent-via + (when (eq (nth 1 (car sent-via)) 'unplugged) + (setq server (car (nth 2 (car sent-via))) + port (cdr (nth 2 (car sent-via)))) + (elmo-plugged-p server port) ;; add elmo-plugged-alist if nothing. + (setq alist + (wl-append-assoc-list + (cons server port) + (car msgs) + alist))) + (setq sent-via (cdr sent-via))) + (setq msgs (cdr msgs))) + alist)) + +(defun wl-plugged-sending-queue-status (qinfo) + ;; sending queue status + (let ((len (length (cdr qinfo)))) + (concat (wl-plugged-set-folder-icon + wl-queue-folder + (wl-folder-get-petname wl-queue-folder)) + (if (> len 1) + (format ": %d msgs (" len) + (format ": %d msg (" len)) + (mapconcat (function int-to-string) (cdr qinfo) ",") + ")"))) + +(defun wl-plugged-dop-queue-info () + ;; dop queue status + (let* ((count 0) + elmo-dop-queue dop-queue last alist server-info + ope operation) + (elmo-dop-queue-load) + (elmo-dop-queue-merge) + (setq dop-queue (sort elmo-dop-queue '(lambda (a b) + (string< (car a) (car b))))) + (wl-append dop-queue (list nil)) ;; terminate(dummy) + (setq last (caar dop-queue)) ;; first + (while dop-queue + (setq ope (cons (nth 1 (car dop-queue)) + (length (nth 2 (car dop-queue))))) + (if (string= last (caar dop-queue)) + (wl-append operation (list ope)) + ;;(setq count (1+ count)) + (when (and last (setq server-info (elmo-folder-portinfo last))) + (setq alist + (wl-append-assoc-list + (cons (car server-info) (nth 1 server-info)) ;; server port + (cons last operation) + alist))) + (setq last (caar dop-queue) + operation (list ope))) + (setq dop-queue (cdr dop-queue))) + alist)) + +(defun wl-plugged-dop-queue-status (qinfo &optional column) + ;; dop queue status + (let ((operations (cdr qinfo)) + (column (or column wl-plugged-queue-status-column))) + (mapconcat + '(lambda (folder-ope) + (concat (wl-plugged-set-folder-icon + (car folder-ope) + (wl-folder-get-petname (car folder-ope))) + "(" + (mapconcat + '(lambda (ope) + (if (> (cdr ope) 0) + (format "%s:%d" (car ope) (cdr ope)) + (format "%s" (car ope)))) + (cdr folder-ope) ",") + ")")) + operations + (concat "\n" (wl-set-string-width column ""))))) + +(defun wl-plugged-drawing (plugged-alist) + (let ((buffer-read-only nil) + (alist plugged-alist) + (vars wl-plugged-switch-variables) + last server port label plugged time + line len qinfo column) + (erase-buffer) + (while vars + (insert (format "%s:[%s]%s" + (caar vars) + (wl-plugged-string (symbol-value (cdar vars))) + (if (cdr vars) " " ""))) + (setq vars (cdr vars))) + (insert "\n") + (let ((elmo-plugged wl-plugged-switch)) + (setq line (format "[%s](wl-plugged)" + (wl-plugged-string (elmo-plugged-p)))) + ;; sending queue status + (when (setq qinfo (assoc (cons nil nil) wl-plugged-sending-queue-alist)) + (setq line (concat + (wl-set-string-width wl-plugged-queue-status-column line) + (wl-plugged-sending-queue-status qinfo)))) + (insert line "\n")) + (while alist + (setq server (caaar alist) + port (cdaar alist) + label (nth 1 (car alist)) + plugged (nth 2 (car alist)) + time (nth 3 (car alist))) + (unless (string= last server) + ;; server plug + (insert (format "%s[%s]%s\n" + (wl-plugged-server-indent) + (wl-plugged-string + (elmo-plugged-p server nil plugged-alist)) + server)) + (setq last server)) + ;; port plug + (setq line + (format "%s[%s]%s" + (make-string wl-plugged-port-indent ? ) + (wl-plugged-string plugged time) + (cond + ((stringp port) + port) + (t + (format "%s(%d)" + (or label + (cdr (assq port wl-plugged-port-label-alist)) + "") + port))))) + (setq column (max (if line (1+ (string-width line)) 0) + wl-plugged-queue-status-column)) + (cond + ;; sending queue status + ((setq qinfo (assoc (cons server port) wl-plugged-sending-queue-alist)) + (setq line + (concat + (wl-set-string-width column line) + (wl-plugged-sending-queue-status qinfo)))) + ;; dop queue status + ((setq qinfo (assoc (cons server port) wl-plugged-dop-queue-alist)) + (setq line + (concat + (wl-set-string-width column line) + (wl-plugged-dop-queue-status qinfo column))))) + (insert line "\n") + (setq alist (cdr alist))) + (delete-region (1- (point-max)) (point-max)) ;; delete line at the end. + (goto-char (point-min)) + (while (not (eobp)) + (wl-highlight-plugged-current-line) + (forward-line 1))) + (set-buffer-modified-p nil) + (count-lines (point-min) (point-max))) + +(defun wl-plugged-redrawing-switch (indent switch &optional time) + (beginning-of-line) + (when (re-search-forward + (format "^%s\\[\\([^]]+\\)\\]" (make-string indent ? ))) + (goto-char (match-beginning 1)) + (delete-region (match-beginning 1) (match-end 1)) + (insert (wl-plugged-string switch time)) + (wl-highlight-plugged-current-line) + (forward-line 1))) + +(defun wl-plugged-redrawing (plugged-alist) + (let ((buffer-read-only nil) + (alist plugged-alist) + last server port plugged time) + (goto-char (point-min)) + (wl-plugged-redrawing-switch 0 (elmo-plugged-p)) + (while alist + (setq server (caaar alist) + port (cdaar alist) + plugged (nth 2 (car alist)) + time (nth 3 (car alist))) + (unless (string= last server) + ;; server plug + (wl-plugged-redrawing-switch + wl-plugged-server-indent + (elmo-plugged-p server nil plugged-alist)) + (setq last server)) + ;; port plug + (wl-plugged-redrawing-switch + wl-plugged-port-indent plugged time) + (setq alist (cdr alist)))) + (set-buffer-modified-p nil)) + +(defun wl-plugged-change () + (interactive) + (if (not elmo-plugged-alist) + (message "No plugged info") + (setq wl-plugged-winconf (current-window-configuration)) + (let* ((cur-win (selected-window)) + (max-lines (if (eq major-mode 'wl-summary-mode) + (/ (frame-height) 2) + (window-height))) + window-lines lines) + (save-excursion + (set-buffer (get-buffer-create wl-plugged-buf-name)) + (wl-plugged-mode) + (buffer-disable-undo (current-buffer)) + (delete-windows-on (current-buffer)) + (wl-plugged-set-variables) + (setq lines (wl-plugged-drawing wl-plugged-alist))) + (select-window cur-win) + (setq window-lines (min max-lines (max lines window-min-height))) + (when (> (- (window-height) window-lines) window-min-height) + (split-window cur-win (- (window-height) window-lines))) + (switch-to-buffer wl-plugged-buf-name) + (condition-case nil + (progn + (enlarge-window (- window-lines (window-height))) + (when (fboundp 'pos-visible-in-window-p) + (goto-char (point-min)) + (while (and (<= (window-height) max-lines) + (not (pos-visible-in-window-p (1- (point-max))))) + (enlarge-window 2)))) + (error)) + (goto-char (point-min)) + (forward-line 1) + (wl-plugged-move-to-next)))) ;; goto first entry + +(defsubst wl-plugged-get-server () + (save-excursion + (end-of-line) + (wl-plugged-move-to-previous-server) + (beginning-of-line) + (when (looking-at (format "^%s\\[[^]]+\\]\\(.*\\)" + (wl-plugged-server-indent))) + (elmo-match-buffer 1)))) + +(defun wl-plugged-toggle () + (interactive) + (let ((cur-point (point))) + (save-excursion + (beginning-of-line) + (cond + ;; swtich variable + ((bobp) + (let (variable switch name) + (goto-char cur-point) + (when (and (not (bobp)) + (not (eq (char-before) ? ))) + (if (re-search-backward " [^ ]+" nil t) + (forward-char 1) + (re-search-backward "^[^ ]+" nil t))) + (when (looking-at "\\([^ :[]+\\):?\\[\\([^]]+\\)\\]") + (setq name (elmo-match-buffer 1)) + (setq switch (not (string= (elmo-match-buffer 2) wl-plugged-plug-on))) + (when (setq variable (cdr (assoc name wl-plugged-switch-variables))) + (set variable switch)) + (goto-char (match-beginning 2)) + (let ((buffer-read-only nil)) + (delete-region (match-beginning 2) (match-end 2)) + (insert (wl-plugged-string switch)) + (set-buffer-modified-p nil))))) + ;; swtich plug + ((looking-at "^\\( *\\)\\[\\([^]]+\\)\\]\\([^ \n]*\\)") + (let* ((indent (length (elmo-match-buffer 1))) + (switch (elmo-match-buffer 2)) + (name (elmo-match-buffer 3)) + (plugged (not (string= switch wl-plugged-plug-on))) + (alist wl-plugged-alist) + server port) + (cond + ((eq indent wl-plugged-port-indent) ;; toggle port plug + (cond + ((string-match "\\([^([]*\\)(\\([^)[]+\\))" name) + (setq port (string-to-int (elmo-match-string 2 name)))) + (t + (setq port name))) + (setq server (wl-plugged-get-server)) + (elmo-set-plugged plugged server port nil alist)) + ((eq indent wl-plugged-server-indent) ;; toggle server plug + (elmo-set-plugged plugged name nil nil alist)) + ((eq indent 0) ;; toggle all plug + (elmo-set-plugged plugged nil nil nil alist))) + ;; redraw + (wl-plugged-redrawing wl-plugged-alist) + ;; change wl-plug-state-indicator + (let ((elmo-plugged wl-plugged-switch)) + (setq wl-plugged-switch (elmo-plugged-p)) + (setq wl-plug-state-indicator + (if wl-plugged-switch + wl-plug-state-indicator-on + wl-plug-state-indicator-off)) + (force-mode-line-update t)))))) + (setq wl-plugged-alist-modified t) + (goto-char cur-point))) + +(defun wl-plugged-click (e) + (interactive "e") + (mouse-set-point e) + (wl-plugged-toggle)) + +(defun wl-plugged-toggle-all () + (interactive) + (let ((cur-point (point))) + (setq wl-plugged-switch (not wl-plugged-switch)) + (elmo-set-plugged wl-plugged-switch nil nil nil wl-plugged-alist) + (wl-plugged-redrawing wl-plugged-alist) + (goto-char cur-point) + (setq wl-plugged-alist-modified t) + ;; change wl-plug-state-indicator + (setq wl-plug-state-indicator + (if wl-plugged-switch + wl-plug-state-indicator-on + wl-plug-state-indicator-off)) + (force-mode-line-update t))) + +(defun wl-plugged-exit () + (interactive) + (setq ;;elmo-plugged-alist wl-plugged-alist + wl-plugged wl-plugged-switch + wl-plugged-alist nil + wl-plugged-sending-queue-alist nil + wl-plugged-dop-queue-alist nil) + (run-hooks 'wl-plugged-exit-hook) + (when wl-plugged-alist-modified + (wl-toggle-plugged (if wl-plugged 'on 'off) t)) + (kill-buffer (current-buffer)) + (if wl-plugged-winconf + (set-window-configuration wl-plugged-winconf))) + +(defun wl-plugged-flush-queue () + (interactive) + (let ((cur-point (point)) + (dop-status (elmo-dop-queue-flush)) + (send-status (wl-draft-queue-flush))) + (unless (or dop-status send-status) + (message "No processing queue.")) + (wl-plugged-set-variables) + (wl-plugged-drawing wl-plugged-alist) + (goto-char cur-point))) + +(defun wl-plugged-move-to-next () + (interactive) + (when (re-search-forward "\\[\\([^]]+\\)\\]" nil t) + (let ((pos (match-beginning 1))) + (if (invisible-p pos) + (goto-char (next-visible-point pos)) + (goto-char pos))))) + +(defun wl-plugged-move-to-previous () + (interactive) + (if (eq (char-before) ?\]) (forward-char -1)) + (when (re-search-backward "\\[\\([^]]+\\)\\]" nil t) + (let ((pos (match-beginning 1))) + (if (invisible-p pos) + (goto-char (next-visible-point pos)) + (goto-char pos))))) + +(defun wl-plugged-move-to-next-server () + (interactive) + (let ((regexp + (format "^%s\\[\\([^]]+\\)\\]" (wl-plugged-server-indent))) + point) + (save-excursion + (end-of-line) + (if (re-search-forward regexp nil t) + (setq point (match-beginning 1)))) + (if point (goto-char point)))) + +(defun wl-plugged-move-to-previous-server () + (interactive) + (let ((regexp + (format "^%s\\[\\([^]]+\\)\\]" (wl-plugged-server-indent)))) + (if (re-search-backward regexp nil t) + (goto-char (match-beginning 1))))) + +;;; end of wl-plugged-mode + +(defun wl-save () + "Save summary and folder status." + (interactive) + (wl-save-status 'keep-summary)) + +(defun wl-save-status (&optional keep-summary) + (message "Saving summary and folder status...") + (let (summary-buf) + (save-excursion + (let ((summaries (wl-collect-summary))) + (mapcar + (function + (lambda (x) + (set-buffer x) + (unless keep-summary + (wl-summary-cleanup-temp-marks)) + (wl-summary-save-status keep-summary) + (unless keep-summary + (kill-buffer x)))) + summaries)))) + (wl-refile-alist-save + wl-refile-alist-file-name wl-refile-alist) + (wl-refile-alist-save + wl-refile-msgid-alist-file-name wl-refile-msgid-alist) + (wl-folder-info-save) + (and (featurep 'wl-fldmgr) (wl-fldmgr-exit)) + (wl-crosspost-alist-save) + (message "Saving summary and folder status...done.")) + +(defun wl-exit () + (interactive) + (when (or (not wl-interactive-exit) + (y-or-n-p "Quit Wanderlust?")) + (elmo-quit) + (run-hooks 'wl-exit-hook) + (wl-save-status) + (wl-folder-cleanup-variables) + (elmo-cleanup-variables) + (wl-kill-buffers + (format "^\\(%s\\)$" + (mapconcat 'identity + (list (format "%s\\(:.*\\)?" + (default-value 'wl-message-buf-name)) + wl-original-buf-name + wl-folder-buffer-name) + "\\|"))) + (elmo-buffer-cache-clean-up) + (if (fboundp 'mmelmo-cleanup-entity-buffers) + (mmelmo-cleanup-entity-buffers)) + (setq wl-init nil) + (unless wl-on-nemacs + (remove-hook 'kill-emacs-hook 'wl-save-status)) + t) + (message "") ;; empty minibuffer. + ) + +(defun wl-init (&optional arg) + (when (not wl-init) + (setq elmo-plugged wl-plugged) + (let (succeed demo-buf) + (if wl-demo + (setq demo-buf (wl-demo))) + (unless wl-on-nemacs + (add-hook 'kill-emacs-hook 'wl-save-status)) + (unwind-protect + (progn + (wl-address-init) + (wl-draft-setup) + (wl-refile-alist-setup) + (wl-crosspost-alist-load) + (if wl-use-semi + (progn + (require 'wl-mime) + (setq elmo-use-semi t)) + (require 'tm-wl) + (setq elmo-use-semi nil)) + ;; defined above. + (wl-mime-setup) + (fset 'wl-summary-from-func-internal + (symbol-value 'wl-summary-from-func)) + (fset 'wl-summary-subject-func-internal + (symbol-value 'wl-summary-subject-func)) + (fset 'wl-summary-subject-filter-func-internal + (symbol-value 'wl-summary-subject-filter-func)) + (setq elmo-no-from wl-summary-no-from-message) + (setq elmo-no-subject wl-summary-no-subject-message) + (setq succeed t) + (progn + (message "Checking environment...") + (wl-check-environment arg) + (message "Checking environment...done."))) + (if demo-buf + (kill-buffer demo-buf)) + (if succeed + (setq wl-init t)) + (run-hooks 'wl-init-hook))))) + +(defun wl-check-environment (no-check-folder) + (unless (featurep 'mime-setup) + (require 'mime-setup)) + (unless wl-from + (error "Please set `wl-from'")) + (unless (string-match "[^.]\\.[^.]" (or wl-message-id-domain + (if wl-local-domain + (concat (system-name) + "." wl-local-domain) + (system-name)))) + (error "Please set `wl-local-domain' to get valid FQDN")) + (when (not no-check-folder) + (if (not (eq (elmo-folder-get-type wl-draft-folder) 'localdir)) + (error "%s is not allowed for draft folder" wl-draft-folder)) + (unless (elmo-folder-exists-p wl-draft-folder) + (if (y-or-n-p + (format "Draft Folder %s does not exist, create it?" + wl-draft-folder)) + (elmo-create-folder wl-draft-folder) + (error "Draft Folder is not created"))) + (if (and wl-draft-enable-queuing + (not (elmo-folder-exists-p wl-queue-folder))) + (if (y-or-n-p + (format "Queue Folder %s does not exist, create it?" + wl-queue-folder)) + (elmo-create-folder wl-queue-folder) + (error "Queue Folder is not created"))) + (unless (elmo-folder-exists-p wl-trash-folder) + (if (y-or-n-p + (format "Trash Folder %s does not exist, create it?" + wl-trash-folder)) + (elmo-create-folder wl-trash-folder) + (error "Trash Folder is not created"))) + (unless (elmo-folder-exists-p elmo-lost+found-folder) + (elmo-create-folder elmo-lost+found-folder))) + (unless (file-exists-p wl-tmp-dir) + (if (y-or-n-p + (format "Temp directory (to save multipart) %s does not exist, create it now?" + wl-tmp-dir)) + (make-directory wl-tmp-dir) + (error "Temp directory is not created")))) + +;;;###autoload +(defun wl (&optional arg) + "Start Wanderlust -- Yet Another Message Interface On Emacsen. +If prefix argument is specified, folder checkings are skipped." + (interactive "P") + (unless wl-init + (wl-load-profile)) + (unwind-protect + (wl-init arg) + (let ((make (wl-folder arg))) + (wl-plugged-init make))) + (run-hooks 'wl-hook)) + +;; Define some autoload functions WL might use. +(eval-and-compile + ;; This little mapcar goes through the list below and marks the + ;; symbols in question as autoloaded functions. + (mapcar + (function + (lambda (package) + (let ((interactive (nth 1 (memq ':interactive package)))) + (mapcar + (function + (lambda (function) + (let (keymap) + (when (consp function) + (setq keymap (car (memq 'keymap function))) + (setq function (car function))) + (autoload function (car package) nil interactive keymap)))) + (if (eq (nth 1 package) ':interactive) + (cdddr package) + (cdr package)))))) + '(("wl-fldmgr" :interactive t + wl-fldmgr-access-display-all wl-fldmgr-access-display-normal + wl-fldmgr-add wl-fldmgr-clear-cut-entity-list wl-fldmgr-copy + wl-fldmgr-copy-region wl-fldmgr-cut wl-fldmgr-cut-region + wl-fldmgr-make-access-group wl-fldmgr-make-filter + wl-fldmgr-make-group wl-fldmgr-make-multi + wl-fldmgr-reconst-entity-hashtb wl-fldmgr-rename wl-fldmgr-delete + wl-fldmgr-save-folders wl-fldmgr-set-petname wl-fldmgr-sort + wl-fldmgr-subscribe wl-fldmgr-subscribe-region + wl-fldmgr-unsubscribe wl-fldmgr-unsubscribe-region wl-fldmgr-yank ) + ("wl-fldmgr" + (wl-fldmgr-mode-map keymap) + wl-fldmgr-add-entity-hashtb) + ("wl-expire" :interactive t + wl-folder-archive-current-entity + wl-folder-expire-current-entity wl-summary-archive + wl-summary-expire ) + ("wl-score" + wl-score-save wl-summary-rescore-msgs wl-summary-score-headers + wl-summary-score-update-all-lines ) + ("wl-score" :interactive t + wl-score-change-score-file wl-score-edit-current-scores + wl-score-edit-file wl-score-flush-cache wl-summary-rescore + wl-score-set-mark-below wl-score-set-expunge-below + wl-summary-increase-score wl-summary-lower-score )))) + +;; for backward compatibility +(defalias 'wl-summary-from-func-petname 'wl-summary-default-from) + +(provide 'wl) + +;;; wl.el ends here -- 1.7.10.4