From: teranisi Date: Mon, 3 Apr 2000 06:59:08 +0000 (+0000) Subject: Import 1.x. X-Git-Tag: start X-Git-Url: http://git.chise.org/gitweb/?a=commitdiff_plain;h=1e366a559be4aec4ad4d3cf3e954b8e62a20d2f3;p=elisp%2Fwanderlust.git Import 1.x. --- 1e366a559be4aec4ad4d3cf3e954b8e62a20d2f3 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