aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBill Wohler2003-04-25 05:52:00 +0000
committerBill Wohler2003-04-25 05:52:00 +0000
commit924df20809a550b7e93fd1a051945db4e8898dfb (patch)
tree29f13e7595917617fb50ffa06ae0059e8a4ab97a
parent0b325c12a2332c696fdc87478d418d43e013ee22 (diff)
downloademacs-924df20809a550b7e93fd1a051945db4e8898dfb.tar.gz
emacs-924df20809a550b7e93fd1a051945db4e8898dfb.zip
Upgraded to MH-E version 7.3.
See etc/MH-E-NEWS and lisp/mh-e/ChangeLog for details.
-rw-r--r--etc/ChangeLog5
-rw-r--r--etc/MH-E-NEWS257
-rw-r--r--etc/NEWS2
-rw-r--r--lisp/mh-e/ChangeLog1569
-rw-r--r--lisp/mh-e/mh-alias.el97
-rw-r--r--lisp/mh-e/mh-comp.el271
-rw-r--r--lisp/mh-e/mh-customize.el1651
-rw-r--r--lisp/mh-e/mh-e.el411
-rw-r--r--lisp/mh-e/mh-funcs.el178
-rw-r--r--lisp/mh-e/mh-identity.el22
-rw-r--r--lisp/mh-e/mh-inc.el104
-rw-r--r--lisp/mh-e/mh-index.el176
-rw-r--r--lisp/mh-e/mh-junk.el416
-rw-r--r--lisp/mh-e/mh-loaddefs.el268
-rw-r--r--lisp/mh-e/mh-mime.el243
-rw-r--r--lisp/mh-e/mh-pick.el10
-rw-r--r--lisp/mh-e/mh-seq.el286
-rw-r--r--lisp/mh-e/mh-speed.el47
-rw-r--r--lisp/mh-e/mh-utils.el561
-rw-r--r--lisp/mh-e/mh-xemacs-compat.el42
-rw-r--r--lisp/mh-e/mh-xemacs-icons.el1306
-rw-r--r--lisp/toolbar/highlight.pbm3
-rw-r--r--lisp/toolbar/highlight.xpm33
23 files changed, 6399 insertions, 1559 deletions
diff --git a/etc/ChangeLog b/etc/ChangeLog
index d0779958023..473193ae47f 100644
--- a/etc/ChangeLog
+++ b/etc/ChangeLog
@@ -1,3 +1,8 @@
12003-04-24 Bill Wohler <wohler@newt.com>
2
3 * MH-E-NEWS: Upgraded to MH-E version 7.3.
4
5
12003-04-03 Kenichi Handa <handa@etlken2> 62003-04-03 Kenichi Handa <handa@etlken2>
2 7
3 * HELLO: Fix the malayalam line. 8 * HELLO: Fix the malayalam line.
diff --git a/etc/MH-E-NEWS b/etc/MH-E-NEWS
index 4e0cf683ab5..e794989fb59 100644
--- a/etc/MH-E-NEWS
+++ b/etc/MH-E-NEWS
@@ -1,3 +1,260 @@
1Copyright (C) 2003 Free Software Foundation, Inc.
2
3Copying and distribution of this file, with or without modification,
4are permitted in any medium without royalty provided the copyright
5notice and this notice are preserved.
6
7
8* Changes in MH-E 7.3
9
10** New Features in MH-E 7.3
11
12*** Unified function arguments
13
14Any function with MSG-OR-SEQ in its docstring uses the displayed
15message by default for this argument. However, if a prefix argument is
16provided, then the user is prompted for a message sequence. If the
17variable `transient-mark-mode' is non-nil and the mark is active, then
18the function operates on the messages in the selected region. In a
19program, MSG-OR-SEQ can be a message number, a list of message
20numbers, a region in a cons cell, or a sequence.
21
22*** MH-Index view of unseen messages
23
24Use "F n (mh-index-new-messages)" or Folder -> View New Messages menu
25item to display messages in the `mh-unseen-seq' sequence in folders
26specified by `mh-index-new-messages-folders'. With a prefix argument,
27enter a space-separated list of folders, or nothing to search all
28folders.
29
30Like other MH-Index folders, use "v (mh-index-visit-folder)" if you
31wish to visit the original folder with the unseen message. This is
32usually not necessary since the original message is annotated if you
33reply, deleted if you delete the message, or refiled if you refile the
34message (closes SF #701756).
35
36*** Spam software support
37
38MH-E now supports several spam filters including Bogofilter,
39SpamProbe, and SpamAssassin. Spam that is mistakenly considered to be
40good mail can be reclassified as spam with "J b (mh-junk-blacklist)".
41Conversely, good mail that is accidently considered to be spam can be
42reclassified with "J w (mh-junk-whitelist)" (closes SF #669518).
43
44If a message is blacklisted, and `mh-junk-mail-folder' is a string,
45then the message is refiled to that folder. If this variable is nil,
46the message is deleted. If a message is whitelisted, then the message
47is refiled to `mh-inbox'.
48
49To change the spam program being used, customize `mh-junk-program'.
50This should only be necessary if you have multiple filters on your
51system and MH-E picked the wrong one. These customization variables
52are found in the new customization group `mh-junk'.
53
54The documentation for the following functions describes what setup is
55needed for the different spam fighting programs:
56
57 - `mh-bogofilter-blacklist'
58 - `mh-spamprobe-blacklist'
59 - `mh-spamassassin-blacklist'
60
61*** Relative folder specification @ supported
62
63You can now use the relative folder marker @ in folder names (closes
64SF #666774).
65
66*** Marking messages
67
68Messages can now be highlighted with "' (mh-toggle-tick)", Sequence ->
69Toggle Tick Mark menu item or the "Toggle tick mark" button. These
70messages are added to the "tick" sequence, although this sequence can
71be changed in `mh-tick-seq'. The highlighting effect can be modified
72by customizing `mh-folder-tick-face' (closes SF #623367).
73
74There is also a new keybinding "/ ' (mh-narrow-to-tick)" and menu item
75Sequence -> Narrow to Tick Sequence to narrow the view to the
76highlighted messages.
77
78*** mh-default-folder-list now takes recipients
79
80If you wish to file a message based upon the recipient of a message
81(such as a mailing list), you can now indicate that when filling out
82the address in the `mh-default-folder-list' customization variable.
83
84*** Face header field supported
85
86In addition to the X-Face header field, the Face header field, which
87can display color images, is now supported. As a bonus, the external
88xface-e21 library is no longer required.
89
90*** X-Image-URL support
91
92Images specified in X-Image-URL header fields are now supported.
93See the customization variable `mh-fetch-x-image-url' to enable this
94support.
95
96*** Fcc completion
97
98Folders in Fcc fields in message drafts can now be completed with
99M-TAB.
100
101** New Variables in MH-E 7.3
102
103Variables that have been added to MH-E that have not been discussed
104elsewhere are listed here.
105
106*** mh-auto-fields-list
107
108Alist of addresses for which header lines are automatically inserted.
109When a regular expression matches in the To or cc fields of a message,
110the corresponding header field is automatically inserted in the
111message header. It also allows the automatic setting of an identity
112(using `mh-insert-identity') to set an alternate identity when sending
113messages to a certain person or mailing list.
114
115Since this is a more general use of `mh-insert-mail-followup-to-flag'
116and `mh-insert-mail-followup-to-list', these variables have been removed.
117
118*** mh-show-xface-face
119
120Face for displaying the X-Face image.
121
122*** mh-xemacs-toolbar-position
123
124This customization variable allows the user to place the toolbar on
125the four edges of the frame.
126
127*** mh-xemacs-use-toolbar-flag
128
129This customization variable is used to enable or disable the toolbar
130under XEmacs.
131
132** Variables Deleted in MH-E 7.3
133
134Variables that have been removed from MH-E that have not been
135discussed elsewhere are listed here.
136
137*** mh-decode-content-transfer-encoded-message-flag
138
139No longer needed since the external program mimencode is no longer
140used.
141
142*** mh-index-show-hook
143
144This hook was never used, so it was removed.
145
146*** mh-tool-bar-reply-3-buttons-flag
147
148Obsolete. This functionality is present `mh-tool-bar-folder-buttons'.
149
150** Bug Fixes in MH-E 7.3
151
152*** Can't refile message
153
154Messages with invalid addresses were causing errors in ali which
155prevented the refiling of messages. The ali error is now shown in the
156"*MH-E Log*" buffer and refiling suggests the last folder used (closes
157SF #680388).
158
159*** Empty body triggers duped header
160
161If the body was empty the header would be treated like the body and
162was therefore displayed twice. This has been fixed (closes SF
163#681162).
164
165*** mml or mhl directives not always processed
166
167The mml and mhl directives used to create body parts were not
168processed if one re-edited a draft, or if they added the directives
169manually. The directives are now always processed upon sending the
170letter. You may still, of course, use "C-c C-m m (mh-mml-to-mime)" or
171"C-c C-e (mh-edit-mhn)" to manually create the MIME body parts from
172the directives and then send the draft.
173
174*** mh-alias-grab-from-field fails
175
176MH-E was adding aliases with angle brackets around the address when
177there wasn't a phrase (usually, the user's name), to go with it. This
178caused ali to fail which caused problems in MH-E. This is probably a
179bug in ali, but MH-E no longer inserts angle brackets around the
180address unless there is a phrase, which avoids the problem (closes SF
181#690216).
182
183*** XEmacs fixes
184
185MH-E is now fully supported under XEmacs and compiles without any
186warnings.
187
188In particular, the following now work under XEmacs:
189
190- X-Face, Face, and X-Image-URL header fields
191- MH-E logo in mode line
192- Emphasis (bold, italics, etc.)
193- Smilies
194- Toolbar
195
196*** Indexed folders should respect mh-show-threads-flag
197
198Indexed folders are now threaded if `mh-show-threads-flag' is non-nil
199(closes SF #709667).
200
201*** Threading index view loses folder info
202
203This has been fixed (closes SF #709672).
204
205*** No undo information when re-editing drafts
206
207Undo is turned on in the draft buffer when using "e (mh-edit-again)"
208(closes SF #712777).
209
210*** Forwarded base64 encoded messages are incorrectly displayed
211
212This has been fixed (closes SF #681518).
213
214*** Append to *MH-E Log* buffer
215
216The last 100 lines of log messages are kept in the *MH-E Log* buffer.
217Previously, the buffer was erased every time it was written (closes SF
218#685476). In addition, many of the MH-E commands now send their output
219into this buffer instead of a plethora of other special-purpose
220buffers.
221
222*** mh-inc-folder complains if no mail and no current message
223
224The function `mh-inc-folder' no longer calls `mh-show' if point is not
225on a valid scan line. This keeps `mh-inc-folder' from complaining
226(closes SF #678115).
227
228*** Folder normalization strips leading slash
229
230Leading "/" characters in folder names entered by the user were being
231lost. This has been fixed (closes SF #676890).
232
233*** Print header doesn't show message
234
235When printing a sequence, the header simply indicated that a sequence,
236but not which one, was being printed and did not show the message
237number. This has been fixed. If more than one message is printed, a
238page of the scan lines is printed and its header indicates the
239sequence or message range. The pages with the actual messages all set
240the header to the folder and message displayed on that page.
241
242*** Aliases constantly reloaded
243
244Empty lists are now handled properly (closes SF #693859).
245
246*** Remove RCS keywords
247
248Removed RCS keywords per Emacs conventions (closes SF #680731).
249
250*** Replace mimencode
251
252MH-E was enhanced to decode message based on charset and
253Content-Transfer-Encoding. This eliminates the need for the external
254program mimencode (closes SF #674857).
255
256
257
1* Changes in MH-E 7.2 258* Changes in MH-E 7.2
2 259
3This release includes the new features of filing hints, hierarchical 260This release includes the new features of filing hints, hierarchical
diff --git a/etc/NEWS b/etc/NEWS
index 3015f622c46..85174557a5c 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -100,7 +100,7 @@ You can now put the init files .emacs and .emacs_SHELL under
100 100
101** MH-E changes. 101** MH-E changes.
102 102
103Upgraded to MH-E version 7.2. There have been major changes since 103Upgraded to MH-E version 7.3. There have been major changes since
104version 5.0.2; see MH-E-NEWS for details. 104version 5.0.2; see MH-E-NEWS for details.
105 105
106+++ 106+++
diff --git a/lisp/mh-e/ChangeLog b/lisp/mh-e/ChangeLog
index 79d82a4d531..c41a2532551 100644
--- a/lisp/mh-e/ChangeLog
+++ b/lisp/mh-e/ChangeLog
@@ -1,3 +1,1561 @@
12003-04-24 Bill Wohler <wohler@newt.com>
2
3 * Released MH-E version 7.3.
4
5 * MH-E-NEWS, README: Updated for release 7.3.
6
7 * mh-e.el (Version, mh-version): Updated for release 7.3.
8
92003-04-24 Satyaki Das <satyakid@stanford.edu>
10
11 * mh-xemacs-compat.el (mh-utils): Require mh-utils at compile
12 time, since the mh-do-in-xemacs macro is used.
13
14 * mh-inc.el (cl): Require cl at compile time since we are using
15 the loop and setf macros.
16
172003-04-24 Satyaki Das <satyakid@stanford.edu>
18
19 * mh-unit.el (mh-files): Fix the list of files to check.
20
212003-04-24 Bill Wohler <wohler@newt.com>
22
23 * ChangeLog: Appended copyright to end of file.
24
25 * Makefile: Added copyright and license.
26
27 * README: Added copyright.
28
29 * import-emacs: Changed copyright from Newt Software to Bill
30 Wohler and use license from mh-e.el, except that this file is
31 a part of MH-E, not GNU Emacs.
32
33 * mh-alias.el: Updated copyright so that it doesn't wrap upon
34 advice from Richard Stallman who said to use two-digit years when
35 they are surrounded by 4-digit years that are in the same century
36 and to break up copyrights on multiple lines.
37 * mh-comp.el: Ditto.
38 * mh-e.el: Ditto.
39 * mh-funcs.el: Ditto.
40 * mh-identity.el: Ditto.
41 * mh-mime.el: Ditto.
42 * mh-seq.el: Ditto.
43 * mh-utils.el: Ditto.
44 * mh-xemacs-compat.el: Ditto.
45
46 * mh-unit.el: New file. Unit tests for MH-E. This version merely
47 runs checkdoc and lm-verify which is useful before releasing the
48 software. It can and should be expanded to do real unit tests.
49
502003-04-22 Mark D Baushke <mdb@gnu.org>
51
52 * mh-alias.el: Update Copyright.
53 * mh-comp.el: Ditto.
54 * mh-customize.el: Ditto.
55 * mh-e.el: Ditto.
56 * mh-funcs.el: Ditto.
57 * mh-identity.el: Ditto.
58 * mh-index.el: Ditto.
59 * mh-mime.el: Ditto.
60 * mh-pick.el: Ditto.
61 * mh-seq.el: Ditto.
62 * mh-speed.el: Ditto.
63 * mh-utils.el: Ditto.
64 * mh-xemacs-compat.el: Ditto.
65
662003-04-22 Satyaki Das <satyaki@theforce.stanford.edu>
67
68 * mh-utils.el (mh-normalize-folder-name): Make the completion
69 code work properly with XEmacs. This change is neeeded since
70 split-string behaves differently in XEmacs than it does in GNU
71 Emacs.
72 (mh-exec-cmd-error): Add a comment, so that we change it later on.
73
742003-04-18 Steve Youngs <youngs@xemacs.org>
75
76 * mh-xemacs-icons.el (mh-xemacs-icons): Provide 'mh-xemacs-icons'
77 not 'mh-xemacs-toolbar'.
78
79 * mh-xemacs-compat.el (mh-xemacs-toolbar): Remove require, it's
80 now called 'mh-xemacs-icons' and it is required from
81 'mh-customize'.
82
83 * mh-customize.el: Require 'mh-xemacs-icons' instead of
84 'mh-xemacs-toolbar'.
85
862003-04-17 Peter S Galbraith <psg@debian.org>
87
88 * mh-xemacs-icons.el: New file (renamed from mh-xemacs-toolbar.el).
89 Holds XEmacs icons.
90
91 * mh-xemacs-toolbar.el: Deleted.
92
93 * Makefile: Incorporate the file renaming.
94
952003-04-15 Bill Wohler <wohler@newt.com>
96
97 * mh-comp.el (mh-forward): Pass a list of messages into
98 mh-compose-and-send-mail instead of msg-or-seq.
99 (mh-annotate-msg): The previous version called
100 mh-iterate-on-msg-or-seq in the letter buffer. The new version
101 simply adds the ability to operate on message lists. Thanks to
102 Satyaki for the fix and suggestion for passing a list from
103 mh-forward.
104
1052003-04-14 Bill Wohler <wohler@newt.com>
106
107 * mh-comp.el (mh-annotate-msg): Updated to handle msg-or-seq for
108 mh-forward was passing a msg-or-seq to mh-compose-and-send-mail
109 which in turn passed the msg-or-seq to mh-annotate-msg. In
110 particular, forwarding a region failed. Note that the msgs
111 argument in much of mh-comp.el should really be converted to
112 msg-or-seq accordingly. But not now, unless something is broken as
113 was the case here. We can revamp after the release.
114
1152003-04-13 Bill Wohler <wohler@newt.com>
116
117 * mh-funcs.el (mh-kill-folder): Added space after prompt to give
118 the (yes or no) bit a little elbow room.
119
120 * mh-xemacs-toolbar.el: Removing a copyright is a no-no.
121 Reinstated Steve's copyright.
122
1232003-04-12 Satyaki Das <satyaki@theforce.stanford.edu>
124
125 * mh-utils.el (mh-do-in-gnu-emacs, mh-do-in-xemacs): Add
126 indentation hooks for the macros.
127
1282003-04-11 Bill Wohler <wohler@newt.com>
129
130 * mh-alias.el, mh-comp.el, mh-customize.el, mh-funcs.el,
131 mh-identity.el, mh-inc.el, mh-index.el, mh-junk.el, mh-utils.el:
132 Merged in changes from CVS GNU Emacs. These included the removal
133 of trailing whitespace.
134
135 * mh-customize.el: The "anti-entropy" check-in. Moved groups
136 around slightly to reflect commentary. Moved defcustoms around
137 to preserve alphabetization. Big diff, little content.
138 (mh-xemacs-use-toolbar-flag): Doc fix.
139 (mh-xemacs-toolbar-position): Fixed typo in docstring.
140 (mh-default-folder-list): Updated docstring to reflect new Check
141 Recipient tag. Also, set type of Address to regexp.
142 (mh-x-mailer-string): Moved to mh-comp.el where it is used.
143
144 * mh-comp.el (mh-x-mailer-string): Moved here from customize.el.
145 Not quite sure how it got to mh-customize.el in the first place.
146
147 * mh-e.el (mh-folder-folder-menu): Added Folder -> View New
148 Messages menu item.
149
150 * mh-utils.el (mh-show-folder-menu): Ditto.
151
152 * mh-inc.el: Added Change Log comment (lm-verify fix).
153
154 * mh-index.el (mh-index-search): Added documentation about prefix
155 argument for users, in addition to documentation for programmers.
156
157 * mh-mime.el (mh-edit-mhn, mh-edit-mhn, mh-mml-to-mime): Docstring
158 fixes germaine to the change whereby we now check for MIME
159 directives before sending.
160
161 * mh-xemacs-toolbar.el: Fixed copyright. Added Change Log comment
162 (lm-verify fix). Added standard MH-E local variables. Removed
163 time-stamp stuff.
164
1652003-04-11 Satyaki Das <satyaki@theforce.stanford.edu>
166
167 * mh-seq.el (mh-iterate-on-msg-or-seq): Add a missed comma.
168
1692003-04-10 Satyaki Das <satyaki@theforce.stanford.edu>
170
171 * mh-index.el (mh-index-visit-folder): Prompt before reusing
172 existing folder buffer.
173
174 * mh-xemacs-toolbar.el (require): Require mh-utils at compile
175 time to avoid compilation error when doing "make bootstrap" in
176 CVS Emacs.
177
178 * mh-inc.el (mh-inc-spool-list): Declare it so that a compile
179 time warning is avoided when doing "make bootstrap" in CVS Emacs.
180
1812003-04-10 Peter S Galbraith <psg@debian.org>
182
183 * mh-inc.el (mh-inc-spool-generator): Changed to a defun instead
184 of a defmacro, applying Satyaki's patch.
185 (mh-inc-spool-def-key): same.
186 (mh-inc-spool-make): same.
187
188 * mh-utils.el: define-key "I" in mh-show-mode-map for
189 mh-inc-spool-map.
190
191 * mh-comp.el (mh-modify-header-field): Remove debug message.
192
1932003-04-10 Peter S Galbraith <psg@debian.org>
194
195 * mh-inc.el (mh-inc-spool-map-help): Default to nil.
196 (mh-inc-spool-map): Make "?" key display message when
197 `mh-inc-spool-map-help' is nil (instead of mh-inc-spool-map-help
198 containing the message).
199
200 * mh-e.el: require mh-inc.el
201 * mh-e.el: define-key "I" in mh-folder-mode-map for mh-inc-spool-map.
202 (mh-help-messages): Add help string for "I" key.
203
2042003-04-09 Peter S Galbraith <psg@debian.org>
205
206 * mh-inc.el: New file. New feature to `inc' mail from various
207 spool files into different folders.
208
209 * mh-loaddefs.el: Regenerate for mh-inc's mh-inc-spool-list-set.
210
211 * Makefile (MH-E-IMG): Add highlight icon.
212 (MH-E-SRC): Add mh-inc.el file.
213
214 * mh-customize.el (mh-inc-spool-list): New variable for new
215 feature to `inc' mail from various spool files into different
216 folders.
217
2182003-04-09 Satyaki Das <satyaki@theforce.stanford.edu>
219
220 * mh-utils.el (mh-mail-delivery-buffer): Add a defconst for
221 mh-mail-delivery-buffer.
222
223 * mh-comp.el (mh-send-letter): Use mh-mail-delivery-buffer.
224
225 * mh-mime.el (mh-small-image-p): Add mh-funcall-if-exists to
226 avoid compiler warning in GNU Emacs.
227
2282003-04-08 Satyaki Das <satyaki@theforce.stanford.edu>
229
230 * mh-mime.el (mh-small-image-p): Make the function slightly more
231 error-resistant in XEmacs.
232
233 * mh-seq.el (mh-narrow-to-seq, mh-widen): Update tool-bar-map in
234 the show buffer if needed. This allows us to display the widen
235 button in the show buffer only when the folder is narrowed.
236
237 * mh-customize.el (mh-tool-bar-define): Changed so that a
238 separate tool-bar-map is used in show-mode when folder is
239 narrowed to a sequence.
240
2412003-04-08 Satyaki Das <satyaki@theforce.stanford.edu>
242
243 * mh-seq.el (mh-iterate-on-msg-or-seq): Reinstate the use of
244 make-symbol since using gensym causes compiler warnings in CVS
245 Emacs.
246
2472003-04-08 Bill Wohler <wohler@newt.com>
248
249 * mh-comp.el (mh-forward): Function didn't handle a region of
250 messages. Use new function mh-msg-or-seq-to-msg-list to get a list
251 of messages in all circumstances. Also, use mh-coalesce-msg-list
252 on message list before submitting to forw since this should always
253 be done when calling a program to reduce the chance of exceeding
254 command-line limits.
255
256 * mh-seq.el (mh-iterate-on-msg-or-seq): Backed out previous
257 change. A nil msg-or-seq should mean no messages, and Satyaki is
258 going to use gensym instead of make-symbol.
259 (mh-msg-or-seq-to-msg-list): New function to convert a msg-or-seq
260 to a list of message numbers.
261
262 * mh-e.el (mh-coalesce-msg-list): Touched up the docstring a
263 little.
264
265 * mh-funcs.el (mh-print-msg): Can now print regions, message
266 lists, sequences and, of course, single messages. This version
267 works a little differently from the old version. Instead of
268 calling mhl | lpr once on all messages, mhl | lpr is called once
269 per message in order to put each message's number in the header.
270 Thanks to Satyaki for some code and ideas.
271
272 * mh-seq.el (mh-iterate-on-msg-or-seq): The argument msg-or-seq
273 can now be nil which means the current message. Make local symbols
274 so that local variables don't step on user's symbols (the msgs
275 symbol got me).
276
2772003-04-06 Bill Wohler <wohler@newt.com>
278
279 * mh-comp.el (mh-forward): Updated docstrings to indicate that a
280 list of messages is acceptable as well.
281
282 * mh-e.el (mh-delete-msg, mh-delete-msg-no-motion, mh-refile-msg)
283 (mh-undo, mh-notate-user-sequences, mh-delete-msg-from-seq): Ditto.
284
285 * mh-funcs.el (mh-copy-msg, mh-print-msg): Ditto.
286
287 * mh-junk.el (mh-junk-blacklist, mh-junk-whitelist): Ditto.
288
289 * mh-seq.el (mh-put-msg-in-seq, mh-iterate-on-msg-or-seq)
290 (mh-interactive-msg-or-seq): Ditto.
291
2922003-04-06 Satyaki Das <satyaki@theforce.stanford.edu>
293
294 * mh-junk.el (mh-junk-blacklist, mh-junk-whitelist): Call
295 mh-refile-a-msg and mh-delete-a-msg with nil as the message
296 number since that is more efficient.
297
298 * mh-seq.el (mh-iterate-on-msg-or-seq): Extended so that it will
299 handle lists of messages numbers as well.
300 (mh-put-msg-in-seq): Use mh-iterate-on-msg-or-seq to simplify the
301 function.
302
303 * mh-funcs.el (mh-copy-msg): Same as above.
304
305 * mh-e.el (mh-refile-msg): Make it more efficient. Using nil in
306 mh-refile-a-msg avoids needing to re-search-forward to that
307 message.
308 (mh-undo): Fix typo in interactive spec.
309 (mh-notate-user-sequences): Generalize the function to take a
310 msg-or-seq as argument.
311 (mh-delete-msg-from-seq): Extend the function so that it is now
312 able to subtract messages belonging in one sequence from another.
313 (mh-undo): Unify the region and sequence handling. The message
314 number branch of the function does extra stuff, so we can't merge
315 that in.
316
3172003-04-06 Bill Wohler <wohler@newt.com>
318
319 * mh-comp.el (mh-forward): Use mh-interactive-msg-or-seq. Inserted
320 consistent verbiage in docstring for msg-or-seq.
321 (mh-reply): Don't mention default in opening line in all
322 docstrings.
323
324 * mh-e.el (mh-delete-msg, mh-refile-msg)
325 (mh-undo, mh-delete-msg-from-seq): Use mh-interactive-msg-or-seq.
326 Inserted consistent verbiage in docstring for msg-or-seq. In
327 mh-delete-msg-from-seq, renamed msg-or-region to msg-or-seq.
328
329 * mh-funcs.el (mh-copy-msg, mh-print-msg): Use
330 mh-interactive-msg-or-seq. Inserted consistent verbiage in
331 docstring for msg-or-seq.
332
333 * mh-junk.el (mh-junk-blacklist, mh-junk-whitelist): Inserted
334 consistent verbiage in docstring for msg-or-seq.
335
336 * mh-seq.el (mh-msg-is-in-seq): Don't mention default in opening
337 line in all docstrings.
338 (mh-put-msg-in-seq): Use mh-interactive-msg-or-seq. Inserted
339 consistent verbiage in docstring for msg-or-seq.
340
341 * mh-e.el (mh-delete-msg, mh-delete-msg-no-motion, mh-refile-msg):
342 Rewritten to use new mh-interactive-msg-or-seq function and
343 mh-iterate-on-msg-or-seq macro. mh-delete-msg-no-motion gained the
344 ability to operate on regions.
345
346 * mh-junk.el (mh-junk-blacklist, mh-junk-whitelist): Rewritten to
347 use new mh-interactive-msg-or-seq function and
348 mh-iterate-on-msg-or-seq macro thereby gaining the ability to
349 operate on sequences or regions.
350
351 * mh-seq.el (mh-iterate-on-msg-or-seq): New macro to execute code
352 on a message, a region of messages, or a sequence. This macro
353 should be in all functions that operate on messages to provide a
354 uniform interface.
355 (mh-interactive-msg-or-seq): New function used in interactive
356 calls to obtain a message number, region, or sequence. This
357 function should be in all functions that operate on messages to
358 provide a uniform interface.
359
360 * mh-utils.el (with-mh-folder-updating, mh-in-show-buffer): Use
361 'defun lisp-indent-hook property instead of 1 to fix indentation
362 of these macros.
363
3642003-04-05 Peter S Galbraith <psg@debian.org>
365
366 * mh-loaddefs.el: Regenerated.
367 * mh-funcs.el (mh-ephem-message): autoload.
368
3692003-04-04 Peter S Galbraith <psg@debian.org>
370
371 * mh-e.el (mh-folder-from-address): Minor Fix. Wrong ending of
372 `when' block.
373
3742003-04-04 Satyaki Das <satyaki@theforce.stanford.edu>
375
376 * mh-mime.el (mh-mml-directive-present-p): The regexp has been
377 modified to recognize directives to encrypt/sign messages.
378
3792003-04-03 Mark D. Baushke <mdb@gnu.org>
380
381 * mh-e.el (mh-folder-from-address): E-mail messages missing the
382 To: field, but which have a Cc: field should also be handled.
383
3842003-04-03 Bill Wohler <wohler@newt.com>
385
386 * mh-e.el (mh-inc-folder): Modified the prompt text to read
387 better.
388
389 * mh-comp.el (mh-forward): Deleted local variable `compose'.
390 Deleted obsolete setting of mh-{mmh|mml}-compose-insert-flag.
391 (mh-letter-menu): Use mh-{mmh|mml}-directive-present-p instead of
392 obsolete. mh-{mmh|mml}-compose-insert-flag.
393 (mh-letter-mode): Deleted obsolete setting of
394 mh-{mmh|mml}-compose-insert-flag.
395 (mh-send-letter): This function now automatically runs the
396 directive-to-MIME conversion if any directives are detected,
397 rather than relying on the unreliable
398 mh-{mmh|mml}-compose-insert-flag variables. Updated docstring
399 accordingly.
400
401 * mh-identity.el (mh-insert-identity): Use
402 mh-{mmh|mml}-directive-present-p instead of obsolete.
403 mh-{mmh|mml}-compose-insert-flag.
404
405 * mh-loaddefs.el: Regenerated.
406
407 * mh-mime.el (mh-mhn-compose-type, mh-mhn-compose-external-type)
408 (mh-mhn-compose-forw, mh-edit-mhn, mh-mml-to-mime)
409 (mh-mml-forward-message, mh-mml-attach-file)
410 (mh-mml-secure-message-sign-pgpmime)
411 (mh-mml-secure-message-encrypt-pgpmime): Deleted obsolete setting
412 of mh-{mmh|mml}-compose-insert-flag.
413 (mh-mml-directive-present-p): Checkdoc fix.
414
415 * mh-utils.el (mh-mhn-compose-insert-flag,
416 mh-mml-compose-insert-flag): Deleted. Replaced by
417 mh-{mhn|mml}-directive-present-p.
418
4192003-04-03 Mark D. Baushke <mdb@gnu.org>
420
421 * mh-e.el (mh-folder-from-address): Fix minor problem with To:
422 address processing.
423
424 * mh-e.el (mh-folder-from-address): Bugfix match ?+ character not
425 a "?+" string.
426
4272003-04-03 Peter S Galbraith <psg@debian.org>
428
429 * mh-e.el (mh-inc-folder): Add second optional argument for the
430 folder to inc new mail into instead of mh-inbox.
431
4322003-04-03 Peter S Galbraith <psg@debian.org>
433
434 * mh-e.el (mh-folder-from-address): The first match found in
435 `mh-default-folder-list' is used.
436
437 * mh-customize.el (mh-default-folder-list): Tweak docs
438
4392003-04-03 Satyaki Das <satyaki@theforce.stanford.edu>
440
441 * mh-loaddefs.el: Regenerated.
442
443 * mh-mime.el (mh-mhn-directive-present-p): New function to test if
444 a MHN directive is present in the current buffer.
445 (mh-mml-directive-present-p): New function to test if a MML
446 directive is present in the current buffer.
447
448 * mh-comp.el (mh-letter-mode): Originally this function checked if
449 a #forw directive was present and set mh-mhn-compose-insert-flag
450 to t. The modification generalizes this test so that one of the
451 variables mh-{mml|mhn}-compose-insert-flag will get set if we have
452 any sort of MHN or MML directive is already present.
453
454 * mh-seq.el (tool-bar-map): Add a defvar to avoid compiler
455 warnings in CVS version of GNU Emacs.
456
457 * mh-utils.el (tool-bar-map): Same as above.
458
459 * mh-e.el (tool-bar-map): same as above.
460
4612003-04-02 Satyaki Das <satyaki@theforce.stanford.edu>
462
463 * mh-xemacs-toolbar.el (mh-xemacs-toolbar-toggle-tick-icon):
464 Change color to match mh-folder-tick-face.
465
466 * highlight.xpm: Same as above.
467
4682003-04-02 Peter S Galbraith <psg@debian.org>
469
470 * mh-e.el (mh-folder-from-address): Check `mh-default-folder-list'
471 for cases against the recipient instead of the originator.
472
473 * mh-customize.el (mh-default-folder-list): Add extra boolean flag
474 to conditionally check the recipient address instead of the
475 originator.
476
4772003-04-02 Peter S Galbraith <psg@debian.org>
478
479 * mh-customize.el (mh-folder-tick-face): Change tick highlight
480 face to a background yellow-green, as suggested by Bill.
481
4822003-04-01 Peter S Galbraith <psg@debian.org>
483
484 * highlight.xpm: New icon for mh-toggle-tick.
485
486 * mh-xemacs-toolbar.el (mh-xemacs-icon-map): Add tool-bar entry
487 for mh-toggle-tick.
488 (mh-xemacs-toolbar-toggle-tick-icon): New constant.
489
490 * mh-customize.el: Add tool-bar entry for mh-toggle-tick.
491
4922003-03-31 Satyaki Das <satyaki@theforce.stanford.edu>
493
494 * mh-loaddefs.el: Regenerated.
495
496 * mh-utils.el (mh-show-narrow-to-tick, mh-show-limit-map)
497 (mh-show-sequence-menu): Add new interactive function
498 mh-show-narrow-to-tick callable from the show buffer and arrange
499 for a key binding and a menu entry.
500
501 * mh-seq.el (mh-narrow-to-tick): New interactive function that
502 narrows to the tick sequence.
503
504 * mh-e.el (mh-folder-sequence-menu, mh-limit-map): Arrange for a
505 key binding and a menu entry for mh-narrow-to-tick.
506
507 * mh-comp.el (mh-letter-mode): Enable undo since we could be
508 reusing a show buffer where undo is disabled (closes SF #712777).
509
5102003-03-31 Peter S Galbraith <psg@debian.org>
511
512 * mh-e.el (mh-folder-sequence-menu): Add entry for mh-toggle-tick.
513
514 * mh-utils.el (mh-show-sequence-menu): Add entry for
515 mh-show-toggle-tick.
516
5172003-03-28 Satyaki Das <satyaki@theforce.stanford.edu>
518
519 * mh-seq.el (mh-delete-seq): If the tick sequence is killed with
520 "S k" then the highlighting wasn't getting removed. The change
521 fixes this.
522
5232003-03-27 Satyaki Das <satyaki@theforce.stanford.edu>
524
525 * mh-e.el (mh-notate-user-sequences): Extend it so that only the
526 messages in a part of the folder are notated.
527 (mh-delete-msg-from-seq): Extend it so that it will delete all
528 messages in the marked region.
529 (mh-delete-a-msg-from-seq): New function that deletes a single
530 message from a sequence.
531 (mh-clear-text-properties): If there is a ticked unseen message
532 and the message is removed from the unseen list with "S d" then
533 unticking the message doesn't change the highlight. This change
534 fixes this.
535
5362003-03-27 Peter S Galbraith <psg@debian.org>
537
538 * mh-xemacs-toolbar.el (mh-xemacs-toolbar-*-icon): Use original
539 24x24 icons, changing background only.
540
5412003-03-27 Satyaki Das <satyaki@theforce.stanford.edu>
542
543 * mh-junk.el (mh-spamassassin-identify-spammers): Remove unused
544 variable buffer-exists.
545 (mh-spamassassin-identify-spammers): Remove unused variable user.
546
547 * mh-customize.el (mh-junk-choose): Tweak it to remove XEmacs
548 compiler warning.
549
5502003-03-26 Satyaki Das <satyaki@theforce.stanford.edu>
551
552 * mh-seq.el (mh-thread-print-scan-lines): Handling of a boundary
553 condition when messages from the last source folder had been
554 removed was incorrect. This caused a folder header to appear
555 without any messages listed under it. This change fixes this.
556 (mh-thread-forget-message): Remove the entry from the scan line
557 table as well. This is needed for proper display of threaded view
558 of index folders.
559
5602003-03-26 Bill Wohler <wohler@newt.com>
561
562 * Makefile, README, import-emacs, mh-alias.el, mh-comp.el,
563 mh-customize.el, mh-e.el, mh-funcs.el, mh-identity.el,
564 mh-index.el, mh-loaddefs.el, mh-mime.el, mh-pick.el, mh-seq.el,
565 mh-speed.el, mh-utils.el, mh-xemacs-compat.el,
566 mh-xemacs-toolbar.el: Removed RCS keywords per Emacs conventions
567 (closes SF #680731).
568
569
5702003-03-26 Satyaki Das <satyaki@theforce.stanford.edu>
571
572 * mh-index.el: Fix commentary to mention that mairix is supported
573 as well.
574
575 * mh-loaddefs.el: Regenerated.
576
577 * mh-utils.el (mh-show-junk-blacklist, mh-show-junk-whitelist):
578 Interactive functions callable from the show buffer.
579 (mh-show-junk-map): Key bindings in show mode.
580
581 * mh-e.el (mh-junk-map): Key bindings to call spam program.
582 (mh-help-messages): Update help text.
583
584 * mh-customize.el (mh-junk): New customization group for spam
585 program interface.
586 (mh-junk-choice, mh-junk-function-alist, mh-junk-choose):
587 Functions and variables that decide which junk program is used.
588 (mh-junk-program, mh-junk-mail-folder): User customizable
589 variables that control the choice of spam program and the action
590 performed on received spam.
591
592 * Makefile (MH-E-SRC): Add mh-junk.el.
593
5942003-03-26 Satyaki Das <satyaki@theforce.stanford.edu>
595
596 * mh-loaddefs.el: Regenerated.
597
598 * mh-utils.el (mh-show-toggle-tick, mh-show-mode-map): New
599 interactive function callable from the show buffer and a key
600 binding for it.
601
602 * mh-seq.el (mh-delete-seq): Remove highlight from tick sequence.
603 (mh-put-msg-in-seq): Disable adding messages to tick sequence.
604 (mh-widen): Reset mh-tick-seq-changed-when-narrowed-flag.
605 (mh-tick-add-overlay, mh-tick-remove-overlay, mh-notate-tick)
606 (mh-toggle-tick): New functions to highlight/unhighlight tick
607 sequence and the interactive function that is used to toggle
608 tick.
609
610 * mh-e.el (mh-tick-seq-changed-when-narrowed-flag): New variable
611 that remembers if we are narrowed to the tick sequence. In that
612 case the highlighting isn't shown, since it adds no extra info.
613 (mh-folder-mode): Initialize mh-tick-seq-changed-when-narrowed-flag.
614 (mh-notate-user-sequences): Notate the tick sequence.
615 (mh-internal-seq): Treat mh-tick-seq like an internal sequence.
616 (mh-delete-msg-from-seq): Don't allow deletion from tick sequence.
617 (mh-folder-mode-map): Add key binding for "'"
618
619 * mh-customize.el (mh-tick-seq, mh-folder-tick-face): New
620 customizable variables that contain the name of the tick sequence
621 and the face to use to highlight it.
622
6232003-03-25 Satyaki Das <satyaki@theforce.stanford.edu>
624
625 * mh-loaddefs.el: Regenerated.
626
627 * mh-seq.el (mh-thread-print-scan-lines): New function which
628 prints out thread tree. It maintains the original folder info if
629 the folder was created by index search (closes SF #709672).
630 (mh-copy-seq-to-eob, mh-thread-inc, mh-thread-folder): Use
631 factored out function mh-thread-print-scan-lines.
632 (mh-toggle-threads): Since threading is allowed in index folders
633 there can be lines in the folder which aren't valid message scan
634 lines. So it is OK for mh-get-msg-num to fail once in a while.
635
636 * mh-index.el (mh-index-update-maps): Make the parsing of messages
637 that need to annotated with the X-MHE-Checksum header more robust.
638 If the search yielded no results then an error was being produced.
639 (mh-index-search): Enable automatic threading of index folders if
640 mh-show-threads-flag is non-nil (closes SF #709667).
641 (mh-index-next-folder): Relax error checking since index folder
642 can be threaded while the source folder info is visible.
643 (mh-index-group-by-folder): New function that is used in
644 mh-thread-folder to keep source folder info visible during
645 threading.
646
6472003-03-25 Bill Wohler <wohler@newt.com>
648
649 * mh-loaddefs.el: Regenerated.
650
651 * mh-customize.el (mh-index-new-messages-folders): New variable
652 that controls which folders "F n (mh-index-new-messages)"
653 accesses. Was mh-flists-search-folders.
654
655 * mh-index.el (mh-flists-search-folders): Still used internally,
656 but users now use new option mh-index-new-messages-folders.
657 Removed documentation since to avoid duplication with
658 mh-index-new-messages-folders.
659 (mh-flists-recursive-search-flag): Deleted. Use
660 mh-recursive-folders-flag instead.
661 (mh-flists-execute): Updated docs to specify which global
662 variables are used. Use mh-recursive-folders-flag instead of
663 mh-flists-recursive-search-flag.
664 (mh-index-new-messages): Edited doc, and refer to new option
665 mh-index-new-messages-folders. Ditto within code. Don't need to
666 prepend + to folder name as flists does that for us. Use
667
6682003-03-24 Satyaki Das <satyaki@theforce.stanford.edu>
669
670 * mh-e.el (mh-refile-msg): Add optional argument that controls
671 whether mh-last-destination-folder is updated or not.
672
6732003-03-22 Satyaki Das <satyaki@theforce.stanford.edu>
674
675 * mh-customize.el (mh-tool-bar-define): Fix a problem in the
676 XEmacs version which caused the show mode toolbar to have the
677 buttons in the reverse order. Also the add-hooks are no longer
678 needed since mh-toolbar-init is called in the appropriate modes.
679
680 * mh-comp.el (mh-letter-mode): Call mh-toolbar-init in XEmacs to
681 initialize toolbar.
682
683 * mh-utils.el (mh-show-mode): Same as above.
684
685 * mh-e.el (mh-folder-mode): Same as above.
686
6872003-03-21 Satyaki Das <satyaki@theforce.stanford.edu>
688
689 * mh-utils.el (mh-exec-cmd-env-daemon): New function which
690 executes a command asynchronously with its own environment.
691
692 * mh-comp.el (mh-redistribute): The function has been modified so
693 that /bin/sh isn't used to run send. It has also been refactored
694 so that the same code isn't repeated.
695
6962003-03-21 Bill Wohler <wohler@newt.com>
697
698 * mh-customize.el (mh-invisible-header-fields): Added X-Bogosity
699 for bogofilter.
700
7012003-03-21 Satyaki Das <satyaki@theforce.stanford.edu>
702
703 * mh-loaddefs.el: Regenerated.
704
705 * mh-xemacs-toolbar.el: Remove the code since that gets generated
706 when mh-tool-bar-define is expanded.
707 (mh-xemacs-icon-map): A alist to map GNU Emacs icon names to the
708 actual icons to be used in XEmacs. This is used in
709 mh-tool-bar-define.
710
711 * mh-customize.el (mh-toolbar): Use this group in XEmacs as well.
712 (mh-tool-bar-item-*): All these constants have been removed since
713 they aren't needed in the new scheme.
714 (mh-tool-bar-reply-3-buttons-flag): This variable has been
715 removed.
716 (mh-tool-bar-search-function): This is now used in XEmacs as well.
717 (mh-tool-bar-folder-set, mh-tool-bar-folder-buttons-set)
718 (mh-tool-bar-letter-buttons-set, mh-tool-bar-show-set)
719 (mh-tool-bar-letter-set): These functions aren't defined at the
720 top level any more.
721 (mh-tool-bar-reply-generator): A macro to generate the required
722 functions for the three reply buttons.
723 (mh-tool-bar-search, mh-tool-bar-customize)
724 (mh-tool-bar-folder-help, mh-tool-bar-letter-help)
725 (mh-tool-bar-reply-from, mh-show-tool-bar-reply-from)
726 (mh-tool-bar-reply-to, mh-show-tool-bar-reply-to)
727 (mh-tool-bar-reply-all, mh-show-tool-bar-reply-all): New
728 interactive functions that are called when tool bar buttons are
729 clicked.
730 (mh-xemacs-use-toolbar-flag, mh-xemacs-toolbar-position):
731 Additional customizable variables that are present only for
732 XEmacs.
733 (mh-tool-bar-define): A macro that generates the required code
734 for GNU Emacs and XEmacs tool bar.
735 (mh-tool-bar-define): Define the MH-E tool bar.
736
7372003-03-17 Satyaki Das <satyaki@theforce.stanford.edu>
738
739 * mh-seq.el (mh-notate-cur): Notate current message only if it
740 hasn't been marked for deletion or refiling.
741
7422003-03-15 Bill Wohler <wohler@newt.com>
743
744 * mh-customize.el (mh-invisible-header-fields): Added
745 X-Spam-Checker-Version.
746 (mh-auto-fields-list): checkdoc fix.
747
7482003-03-12 Satyaki Das <satyaki@theforce.stanford.edu>
749
750 * mh-index.el (mh-index-new-messages): If the destination folder
751 where the unseen messages are supposed to be copied to was
752 already present, but MH-E doesn't have it open, then a new folder
753 was being created. The change fixes this.
754 (mh-index-update-unseen, mh-flists-recursive-search-flag): Fix
755 checkdoc warnings.
756
757 * mh-loaddefs.el: Regenerated.
758
7592003-03-11 Satyaki Das <satyaki@theforce.stanford.edu>
760
761 * mh-index.el (mh-flists-results-folder): Subfolder under
762 +mhe-index where the results of the flists call is put.
763 (mh-index-generate-pretty-name): Make sure that normal index
764 searching will never use the folder reserved for the flists
765 results.
766 (mh-index-search): Add an extra parameter that marks all the
767 messages in the index folder to the unseen sequence.
768 (mh-index-update-unseen): Function to keep unseen sequence of
769 index folder synced with the actual folders from where the
770 messages were copied. This works only if the unseen messages are
771 displayed with mh-show. Killing the unseen sequence in the index
772 folder or adding/removing messages to it doesn't change the
773 unseen sequence in the source folders yet.
774 (mh-flists-search-folders): Variable that decides the folders on
775 which flists is run.
776 (mh-flists-recursive-search-flag): If non-nil, flists is passed
777 the -recurse option.
778 (mh-flists-execute): Function which uses /bin/sh to execute
779 flists and then print out the list of message files that match.
780 (mh-index-new-messages): New interactive function which searches
781 for messages in the unseen sequence (closes SF #701756).
782
783 * mh-utils.el (mh-show-folder-map): Add binding for
784 mh-index-new-messages.
785 (mh-show-msg): Update the unseen sequence in the source folder.
786
787 * mh-e.el (mh-folder-font-lock-unseen): The function assumes that
788 the end of buffer is reached when there isn't a valid scan line
789 on the current line. This doesn't work in the index folder since
790 we have lines containing the folder name and empty lines in
791 between the actual scan lines. The modification removes this
792 assumption.
793 (mh-folder-map): Add key binding for "Fn"
794
795 * mh-seq.el (mh-iterate-on-messages-in-region): If the point is
796 not at the beginning of the line, then the first message in the
797 region would be missed. The fix avoids this.
798
799 * mh-mime.el (mh-inline-vcard-p): Don't try to inline vcards if
800 we don't have the right libraries.
801
8022003-03-10 Satyaki Das <satyaki@theforce.stanford.edu>
803
804 * mh-e.el (mh-next-undeleted-msg, mh-previous-undeleted-msg)
805 (mh-next-msg): Add optional argument wait-after-complaining-flag.
806 If non-nil and there are no undeleted messages after (or before)
807 the current one, then pause for a second after printing out the
808 message.
809 (mh-refile-or-write-again): Modify call to mh-next-msg to use the
810 wait-after-complaining-flag.
811
8122003-03-10 Satyaki Das <satyaki@theforce.stanford.edu>
813
814 * mh-e.el (mh-refile-or-write-again): If mh-next-msg fails to find
815 a message to go to it prints out a diagnostic, which overwrites
816 the diagnostic about the folder the message was refiled to. The
817 change fixes this.
818
8192003-03-09 Satyaki Das <satyaki@theforce.stanford.edu>
820
821 * mh-seq.el (mh-widen, mh-narrow-to-seq): Update
822 mh-narrowed-to-seq before notating sequences. This is a bit
823 helpful for mh-tick.el.
824 (mh-put-msg-in-seq): Fix a minor bug. No internal sequence should
825 be notated -- the original code was doing the right thing only for
826 the "unseen" sequence.
827
828 * mh-index.el (mh-index-choose): Add autoload cookie for
829 mh-index-choose. This is needed for GNU Emacs 20.5.
830
831 * mh-loaddefs.el: Regenerated.
832
8332003-03-09 Bill Wohler <wohler@newt.com>
834
835 * mh-mime.el (mh-display-smileys): This function originally had a
836 test to see if font-lock-maximum-size was bound, but this was
837 recently removed. The test was put in for a reason; if
838 font-lock-maximum-size isn't bound, void-variable errors would
839 ensue. I put the bound test back in.
840
8412003-03-08 Steve Youngs <youngs@xemacs.org>
842
843 * mh-mime.el (mh-mime-security-button-map): Use 'mh-push-button'
844 in XEmacs as well.
845
8462003-03-07 Satyaki Das <satyaki@theforce.stanford.edu>
847
848 * mh-xemacs-toolbar.el: Declare a whole bunch of stuff for GNU
849 Emacs, so that we don't get so many compiler warnings. Also
850 surround calls to set-specifier and toolbar-make-button-list with
851 mh-funcall-if-exists. Maybe GNU Emacs shouldn't try to compile
852 this file in the first place.
853
854 * mh-xemacs-compat.el (mh-modeline-glyph): Declare it within
855 mh-do-in-xemacs to avoid compiler warning in GNU Emacs.
856 (mh-xemacs-push-button): Removed.
857
858 * mh-mime.el (mh-mime-button-map): Use the generalized
859 mh-push-button function.
860 (mh-push-button): Enhance it so that it works on XEmacs too.
861
8622003-03-08 Steve Youngs <youngs@xemacs.org>
863
864 * mh-xemacs-compat.el (mh-modeline-logo): New constant holding the
865 modeline image.
866 (mh-modeline-glyph): Use it.
867
8682003-03-08 Steve Youngs <youngs@xemacs.org>
869
870 * mh-xemacs-toolbar.el: New file that defines and displays a
871 toolbar in XEmacs.
872
873 * mh-xemacs-compat.el (mh-xemacs-toolbar): Require it here.
874
875 * Makefile (MH-E-SRC): Add mh-xemacs-toolbar.el.
876
877 * mh-customize.el (mh-toolbar):
878 (mh-tool-bar-letter-buttons):
879 (mh-tool-bar-letter-buttons-set):
880 (mh-tool-bar-folder-buttons):
881 (mh-tool-bar-folder-buttons-set):
882 (mh-tool-bar-search-function):
883 (mh-tool-bar-reply-3-buttons-flag):
884 (mh-tool-bar-item-inc):
885 (mh-tool-bar-item-save-mime):
886 (mh-tool-bar-item-prev-msg):
887 (mh-tool-bar-item-page-msg):
888 (mh-tool-bar-item-next-msg):
889 (mh-tool-bar-item-delete):
890 (mh-tool-bar-item-refile):
891 (mh-tool-bar-item-undo):
892 (mh-tool-bar-item-perform):
893 (mh-tool-bar-item-toggle-show):
894 (mh-tool-bar-item-reply-from):
895 (mh-tool-bar-item-reply-to):
896 (mh-tool-bar-item-reply-all):
897 (mh-tool-bar-item-reply):
898 (mh-tool-bar-item-alias):
899 (mh-tool-bar-item-compose):
900 (mh-tool-bar-item-rescan):
901 (mh-tool-bar-item-repack):
902 (mh-tool-bar-item-search):
903 (mh-tool-bar-item-visit):
904 (mh-tool-bar-item-prefs):
905 (mh-tool-bar-item-help):
906 (mh-tool-bar-item-widen):
907 (mh-tool-bar-item-send):
908 (mh-tool-bar-item-attach):
909 (mh-tool-bar-item-spell):
910 (mh-tool-bar-item-save):
911 (mh-tool-bar-item-undo-op):
912 (mh-tool-bar-item-kill):
913 (mh-tool-bar-item-copy):
914 (mh-tool-bar-item-paste):
915 (mh-tool-bar-item-kill-draft):
916 (mh-tool-bar-item-comp-prefs):
917 The MH-E toolbar for XEmacs is defined differently from the
918 GNU/Emacs version, so only define these if we're in GNU/Emacs.
919 XEmacs doesn't need to see them and it's always good to cut down
920 on pollution.
921
9222003-03-08 Steve Youngs <youngs@xemacs.org>
923
924 * mh-mime.el (mh-mime-button-map): Bind the 2nd mouse button to
925 `mh-xemacs-push-button' in XEmacs.
926 (mh-mime-security-button-map): Ditto.
927
928 * mh-xemacs-compat.el: Shush the byte-compiler.
929 (mh-xemacs-push-button): New function to make MIME buttons work in
930 XEmacs.
931
9322003-03-08 Steve Youngs <youngs@xemacs.org>
933
934 * mh-mime.el (mh-display-emphasis): Don't test
935 `font-lock-maximum-size' to see if it is bound, just test for a
936 non-nil value. This variable can have a nil value which makes it
937 bound and dividing nil by 8 throws an error.
938 This fixes a bug in MH-E under XEmacs when
939 `font-lock-maximum-size' is nil that prevented article emphasis
940 and smiley display which in turn was causing the "Flush changes in
941 article x y/n" errors.
942 (mh-display-smileys): Ditto.
943
9442003-03-08 Steve Youngs <youngs@xemacs.org>
945
946 * mh-utils.el (mh-logo-display): Display logo in XEmacs as well.
947
948 * mh-xemacs-compat.el (mh-modeline-glyph): New. The MH-E modeline
949 logo for XEmacs.
950
9512003-03-06 Satyaki Das <satyaki@theforce.stanford.edu>
952
953 * mh-utils.el (mh-allow-root-folder-flag): New global variable
954 that decides if "+" is an acceptable folder name.
955 (mh-folder-completion-function): Refine the test for existing
956 folders to take mh-allow-root-folder-flag into account.
957 (mh-folder-completing-read, mh-prompt-for-folder): Use the
958 allow-root-folder-flag argument of mh-prompt-for-folder and add a
959 similar argument to mh-folder-completing-read.
960 (mh-exec-cmd-error): Make the function nicer by using
961 process-environment to pass the environment variable assignments.
962
9632003-03-05 Satyaki Das <satyaki@theforce.stanford.edu>
964
965 * mh-mime.el (mh-push-button): Preserve point in the show buffer
966 if the mouse is used to expand/contract a button.
967
968 * mh-customize.el (mh-x-face-file): Mention X-Image-URL in
969 documentation.
970
971 * mh-comp.el (mh-insert-x-face): Modified to allow insertion of
972 X-Image-URL header field.
973
9742003-03-04 Satyaki Das <satyaki@theforce.stanford.edu>
975
976 * mh-utils.el (mh-face-display-function): Modified to facilitate
977 display of X-Image-URL images.
978 (mh-find-path): Initialize X-Image-URL cache directory.
979 (mh-x-image-url-cache-canonicalize, mh-x-image-url-fetch-image)
980 (mh-x-image-scale-and-display, mh-x-image-url-display)
981 (mh-x-image-display): New functions for X-Image-URL image display
982 and cache management.
983
984 * mh-customize.el (mh-show-use-xface-flag): Add info about
985 requirements for X-Image-URL display.
986 (mh-fetch-x-image-url): New customizable variable that controls
987 fetching of X-Image-URL.
988
9892003-03-04 Satyaki Das <satyaki@theforce.stanford.edu>
990
991 * mh-utils.el (mh-make-local-hook): New macro which works around
992 API changes in add-hook. Version of GNU Emacs before 21.1 and
993 XEmacs require a call to make-local-hook and just the LOCAL
994 argument of add-hook is not sufficient.
995 (mh-show-mode): Make kill-buffer-hook buffer local.
996
997 * mh-e.el (mh-folder-mode): Same as above.
998
999 * mh-comp.el (mh-compose-and-send-mail): Same as above.
1000
10012003-03-02 Satyaki Das <satyaki@theforce.stanford.edu>
1002
1003 * mh-mime.el (mh-push-button): Clicking on a MIME button used to
1004 cause the window with the show buffer to be selected. With this
1005 change the selected window doesn't change.
1006
10072003-03-01 Satyaki Das <satyaki@theforce.stanford.edu>
1008
1009 * mh-speed.el (mh-speed-flists): Avoid a potential race condition.
1010 When flists is called manually, or when an unseen message is read,
1011 mh-speed-partial-line was not reinitialized.
1012
1013 * mh-e.el (mh-visit-folder): If mh-visit-folder is used to visit
1014 the folder currently being visited (effectively doing a rescan)
1015 then mh-previous-window-config is erroneously set. The change
1016 fixes this.
1017
1018 * mh-customize.el (mh-index-show-hook): Remove unused variable.
1019
10202003-02-28 Satyaki Das <satyaki@theforce.stanford.edu>
1021
1022 * mh-e.el (mh-scan-folder): Call mh-reset-threads-and-narrowing
1023 only after the user has replied to question. This avoids premature
1024 clearing of the folder.
1025 (mh-rescan-folder, mh-visit-folder): Remove calls to
1026 mh-reset-threads-and-narrowing since it is now called in
1027 mh-scan-folder anyway.
1028
1029 * mh-funcs.el (mh-sort-folder): Same as above.
1030
10312003-02-26 Satyaki Das <satyaki@theforce.stanford.edu>
1032
1033 * mh-alias.el (mh-alias-alist): Change initial value to a symbol,
1034 so that it is different from the empty list, which could also
1035 mean that there are no aliases.
1036 (mh-alias-reload-maybe): Change test so that empty alist of
1037 aliases is properly handled (closes SF #693859).
1038
10392003-02-25 Satyaki Das <satyaki@theforce.stanford.edu>
1040
1041 * mh-mime.el (mh-decode-message-header): The message header could
1042 be encoded, for instance the author's name could contain
1043 characters not in ASCII. This function will decode such header
1044 fields.
1045 (mh-mm-inline-message): Use mh-decode-message-header.
1046
1047 * mh-utils.el (mh-display-msg): Use mh-decode-message-header.
1048 (mh-message-number-width): Use mh-scan-prog instead of "scan".
1049
1050 * mh-loaddefs.el: Regenerated.
1051
10522003-02-24 Satyaki Das <satyaki@theforce.stanford.edu>
1053
1054 * mh-utils.el (mh-truncate-log-buffer): Refine it so that the
1055 function will do the right thing even if called from a buffer
1056 other than mh-log-buffer.
1057
10582003-02-22 Peter S Galbraith <psg@debian.org>
1059
1060 * mh-alias.el (mh-alias-add-alias): Really fix SF #690216.
1061 This functions needs to strip brackets on standalone addresses as
1062 well.
1063
10642003-02-21 Satyaki Das <satyaki@theforce.stanford.edu>
1065
1066 * mh-xemacs-compat.el (replace-regexp-in-string): Remove the
1067 definition since it isn't used any more.
1068
10692003-02-20 Peter S Galbraith <psg@debian.org>
1070
1071 * mh-alias.el (mh-alias-which-file-has-alias): Bug fix. Needed to
1072 specify `noerror' on search.
1073
1074 * mh-alias.el (mh-alias-suggest-alias): Add condition for input
1075 string being an email address in brackets. We need to strip out
1076 the brackets. (closes SF #690216)
1077
10782003-02-20 Satyaki Das <satyaki@theforce.stanford.edu>
1079
1080 * mh-pick.el (mh-search-folder): The function was setting the
1081 global value of the variables mh-current-folder and
1082 mh-previous-window-config. This can lead to problems in code which
1083 assumes that these variables are nil when we aren't in a folder
1084 buffer. So make the variables local before setting them.
1085
10862003-02-19 Satyaki Das <satyaki@theforce.stanford.edu>
1087
1088 * mh-mime.el (mh-mime-display): All the MIME display code has been
1089 wrapped in a condition-case so that if something goes wrong, the
1090 raw message will be displayed.
1091
1092 * mh-funcs.el (mh-undo-folder): Comment out call to sit-for that
1093 seems unnecessary.
1094
1095 * mh-e.el (mh-scan-folder): Messages marked for deletion or
1096 refiling weren't getting annotated properly. The change fixes
1097 this.
1098 (mh-process-or-undo-commands): Change prompt to reflect what
1099 really happens in the code.
1100
11012003-02-18 Satyaki Das <satyaki@theforce.stanford.edu>
1102
1103 * mh-comp.el (mh-folder-expand-at-point): The function
1104 mail-abbrev-complete-alias often returns nil. This had the
1105 unfortunate consequence of always causing an error. The change
1106 fixes this.
1107
1108 * mh-alias.el (mh-alias-canonicalize-suggestion): New function
1109 which obviates the our need replace-regexp-in-string.
1110 (mh-alias-suggest-alias): Use mh-alias-canonicalize-suggestion to
1111 eliminate calls to replace-regexp-in-string. This avoids problems
1112 in Emacs20.
1113
1114 * mh-utils.el (mh-notate): Handle the case when nil is passed as
1115 notation gracefully.
1116 (mh-speed-flists-active-p): New function that returns non-nil if
1117 flists is being used in the speedbar to update message counts.
1118
1119 * mh-seq.el (mh-put-msg-in-seq): Fix a bug which made it
1120 impossible to add messages to the unseen sequence. Also adding
1121 messages to the unseen sequence will now update the speedbar
1122 message counts immediately.
1123
1124 * mh-e.el (mh-get-new-mail, mh-process-commands)
1125 (mh-undefine-sequence): Update speedbar message counts, if the
1126 speedbar is active and is displaying message counts.
1127 (mh-delete-msg-from-seq): In addition to updating message counts,
1128 unhighlight the message so that interactively removing messages
1129 from the unseen sequence makes the bold highlight of unseen
1130 messages in the scan buffer go away.
1131 (mh-clear-text-properties): New function that removes all text
1132 properties from the current scan line.
1133
11342003-02-15 Satyaki Das <satyaki@theforce.stanford.edu>
1135
1136 * mh-utils.el (mh-face-display-function): Wrap call of
1137 insert-image in mh-funcall-if-exists. This avoids a compiler
1138 warning in Emacs20.
1139
1140 * mh-speed.el (mh-speed-flists): Weaken test a bit to avoid
1141 compiler warning in Emacs20.
1142 (mh-speedbar-change-expand-button-char): Wrap call of
1143 speedbar-insert-image-button-maybe in mh-funcall-if-exists. This
1144 function isn't present in the speedbar that ships with Emacs20, so
1145 calling it there causes an error.
1146
1147 * mh-seq.el (mh-msg-is-in-seq): Adjust loop call a bit to avoid
1148 compiler warning in XEmacs. The XEmacs compiler should be improved
1149 so that such spurious warnings from builtin macros are suppressed.
1150
1151 * mh-index.el (mh-index-search): Same as above.
1152
1153 * mh-e.el (tool-bar-mode): The declaration is needed for Emacs20
1154 too.
1155
1156 * mh-comp.el (mailabbrev): Try loading it any way. Some day XEmacs
1157 will get it and then MH-E will just use it.
1158 (tool-bar-mode, tool-bar-map): These declarations are needed for
1159 Emacs20 too.
1160 (mh-mail-abbrev-make-syntax-table, mh-folder-expand-at-point):
1161 Remove mh-mail-abbrev-make-syntax-table since mh-funcall-if-exists
1162 can be used instead.
1163
1164 * mh-alias.el (require): Avoid autoloading functions that may not
1165 be defined.
1166 (mh-read-address, mh-alias-letter-expand-alias): Rewrite using
1167 mh-funcall-if-exists.
1168
11692003-02-15 Satyaki Das <satyaki@theforce.stanford.edu>
1170
1171 * mh-loaddefs.el: Regenerated.
1172
1173 * mh-speed.el (mh-folder-speedbar-buttons, mh-speed-add-buttons)
1174 (mh-speed-toggle): Reuse markers instead of creating more of them.
1175 (mh-speed-flists-folder, mh-speed-flists): Add optional folder
1176 argument to mh-speed-flists so that message counts are updated
1177 only for that one folder.
1178 (mh-speed-parse-flists-output): If no change in counts then avoid
1179 consing.
1180
1181 * mh-index.el (mh-index-execute): Rewritten to use a temporary
1182 buffer that is not left behind.
1183
1184 * mh-funcs.el (mh-store-buffer): Use mh-log-buffer instead of the
1185 special purpose *Store Output* buffer.
1186
11872003-02-14 Satyaki Das <satyaki@theforce.stanford.edu>
1188
1189 * mh-customize.el (mh-show-xface-face): Make it always be black
1190 foreground on a white background (the reverse of that can make
1191 some X-Face images look creepy).
1192
1193 * mh-utils.el (mh-truncate-log-buffer): Modify the function to
1194 return the current size of mh-log-buffer. Also we are now a bit
1195 more careful in adding separators between consecutive messages.
1196 (mh-exec-cmd): Fix a bug where the the log buffer would be
1197 displayed even if no error happened in the current command but
1198 the log buffer had messages from a previous error.
1199
1200 * mh-mime.el (mh-mime-save-parts): Use mh-log-buffer to show
1201 error messages.
1202
1203 * mh-alias.el (mh-alias-local-users): Add a space between parens.
1204
12052003-02-14 Steve Youngs <youngs@xemacs.org>
1206
1207 * mh-utils.el (mh-face-display-function): Call
1208 `x-face-xmas-wl-display-x-face' using `mh-funcall-if-exists'.
1209
1210 * mh-xemacs-compat.el (replace-regexp-in-string): New.
1211
12122003-02-13 Satyaki Das <satyaki@theforce.stanford.edu>
1213
1214 * mh-utils.el (mh-log-buffer-lines): New variable that keeps
1215 track of the number of lines to keep in mh-log-buffer.
1216 (mh-truncate-log-buffer): New function that is used to make sure
1217 that the log buffer doesn't grow to unbounded size.
1218 (mh-exec-cmd, mh-exec-cmd-daemon, mh-handle-process-error): Use
1219 mh-truncate-log-buffer instead of erase-buffer to keep some
1220 number of previous log messages around (closes SF #685476).
1221
12222003-02-13 Satyaki Das <satyaki@theforce.stanford.edu>
1223
1224 * mh-e.el (tool-bar-mode): Declare it in XEmacs.
1225 (mh-folder-mode): Use mh-funcall-if-exists to call hl-line-mode.
1226
1227 * mh-utils.el (mh-funcall-if-exists): New macro that calls a
1228 function only if it exists.
1229 (mh-logo-display, mh-defun-show-buffer): Use mh-funcall-if-exists
1230 to call the functions find-image and deactivate-mark.
1231
1232 * mh-mime.el (mh-mime-cleanup, mh-small-image-p)
1233 (mh-mm-display-part): Use mh-funcall-if-exists to call the
1234 functions image-size and remove-images.
1235
1236 * mh-comp.el (tool-bar-map, tool-bar-mode): Declare the variables
1237 in XEmacs.
1238 (mh-folder-expand-at-point): Use mh-funcall-if-exists to call
1239 mail-abbrev-complete-alias if it exists.
1240
1241 * mh-alias.el (mh-read-address): Use mh-funcall-if-exists for
1242 future extensibility.
1243
12442003-02-13 Satyaki Das <satyaki@theforce.stanford.edu>
1245
1246 * mh-utils.el (mh-logo-display): The function find-image is
1247 present only in GNU Emacs.
1248 (mh-defun-show-buffer): The function deactivate-mark is present
1249 only in GNU Emacs.
1250 (default-enable-multibyte-characters): Declare it in XEmacs to
1251 avoid compiler warning.
1252 (mh-face-display-function): Avoid inserting space if there isn't
1253 any Face or X-Face header field to display.
1254
1255 * mh-seq.el (mh-thread-last-ancestor): Move declaration of
1256 variable before its first use to silence XEmacs warning.
1257
1258 * mh-mime.el (default-enable-multibyte-characters, dots, type):
1259 Declare these in XEmacs to remove compiler warnings in XEmacs.
1260 (mh-mime-cleanup, mh-mm-display-part): Call remove-images only in
1261 GNU Emacs.
1262 (mh-small-image-p): Call image-size only in GNU Emacs.
1263
1264 * mh-index.el (mh-mairix-next-result): Fix a bug where a quote
1265 was missing.
1266 (mh-swish++-regexp-builder): Remove the unused binding meta.
1267
1268 * mh-e.el (mh-folder-size): Pass on an extra value to remove
1269 XEmacs warning.
1270 (mh-folder-mode): Surround calls to hl-line-mode and
1271 tool-bar-mode with mh-do-in-gnu-emacs since these functions
1272 aren't present in XEmacs.
1273
1274 * mh-customize.el (mh-tool-bar-show-set, mh-tool-bar-letter-set)
1275 (mh-tool-bar-folder-set): These functions call tool-bar-*
1276 functions which are present only in GNU Emacs. So surround them
1277 with mh-do-in-gnu-emacs.
1278
1279 * mh-comp.el (mh-letter-mode, mh-folder-expand-at-point): Only
1280 call these functions in GNU Emacs.
1281 (mail-abbrevs): Declare it in XEmacs.
1282
1283 * mh-alias.el (mh-read-address): Call completing-read-multiple
1284 only in GNU Emacs.
1285 (mail-abbrevs): Declare it in XEmacs.
1286 (mh-alias-add-alias-to-file): Remove unused code.
1287
12882003-02-14 Ville Skytt <scop@xemacs.org>
1289
1290 * mh-comp.el: Add autoloaded auto-mode-alist association.
1291
12922003-02-13 Satyaki Das <satyaki@theforce.stanford.edu>
1293
1294 * mh-utils.el (mh-face-display-function): Make the XEmacs part a
1295 little simpler.
1296
12972003-02-14 Steve Youngs <youngs@xemacs.org>
1298
1299 * mh-customize.el (mh-show-xface-face): XEmacs doesn't have the
1300 ':inherit' keyword for defface, rewrite with sane defaults.
1301
1302 * mh-utils.el (mh-face-display-function): Fix bug that was
1303 corrupting xface images when displayed with XEmacs' internal
1304 xface image support. Also make XEmacs honour 'mh-show-xface-face'
1305 when using internal xface image support.
1306
13072003-02-12 Peter S Galbraith <psg@debian.org>
1308
1309 * mh-comp.el (mh-modify-header-field): New function. To header
1310 FIELD add VALUE. If OVERWRITE-FLAG is non-nil then the old value,
1311 if present, is discarded. This is more flexible than before.
1312 (mh-insert-auto-fields): Use it. This and the new function are a
1313 courtesy of Satyaki. Thanks!
1314
1315 * mh-customize.el (mh-auto-fields-list): Doc tweaks suggested by
1316 Bill.
1317
13182003-02-12 Satyaki Das <satyaki@theforce.stanford.edu>
1319
1320 * mh-comp.el (mh-folder-expand-at-point): Tweak the error
1321 message. Completion in the Fcc header field is only supported in
1322 GNU Emacs 21.
1323
13242003-02-12 Peter S Galbraith <psg@debian.org>
1325
1326 * mh-customize.el (mh-auto-fields-list): Reorder after
1327 `mh-identity-list' since it needs it to be defined. Move to
1328 mh-identity customization group.
1329
13302003-02-11 Peter S Galbraith <psg@debian.org>
1331
1332 * mh-customize.el (mh-insert-mail-followup-to-flag): Removed.
1333 Obsolete.
1334 (mh-insert-mail-followup-to-list): Removed. Obsolete. Use
1335 `mh-auto-fields-list' instead, which is a more general solution.
1336 (mh-auto-fields-list): New defcustom. Alist of addresses for
1337 which header lines are automatically inserted. Replaces
1338 `mh-insert-mail-followup-to-list'.
1339
1340 * mh-comp.el (mh-insert-mail-followup-to): Removed. Obsolete.
1341 (mh-insert-auto-fields): New function. Insert custom fields if To
1342 or Cc match `mh-auto-fields-list', replacing
1343 mh-insert-mail-followup-to with a more general solution.
1344 (mh-compose-and-send-mail): Call mh-insert-auto-fields instead of
1345 mh-insert-mail-followup-to. Also don't call mh-insert-identity to
1346 insert default setting if mh-insert-auto-fields inserted an
1347 identity.
1348
13492003-02-11 Satyaki Das <satyaki@theforce.stanford.edu>
1350
1351 * mh-utils.el (mh-show-xface-function): Try to load the external
1352 x-face library only if XEmacs doesn't have xface support.
1353 (mh-face-display-function): Renamed. Also handle various
1354 permutations of x-face and xface support in XEmacs better.
1355
1356 * mh-customize.el (mh-show-use-xface-flag): Any emacs whose
1357 major version is greater than or equal to 21 supports display of
1358 X-Face and Face header fields.
1359
13602003-02-11 Satyaki Das <satyaki@theforce.stanford.edu>
1361
1362 * mh-utils.el (mh-do-in-gnu-emacs, mh-do-in-xemacs): Macros that
1363 execute code only in GNU Emacs and XEmacs respectively.
1364 (mh-emacs21-face-display-function): Refactor to make it slightly
1365 nicer. Get rid of compiler warnings in GNU Emacs by using the
1366 above macros. Also check for presence of xface feature (in XEmacs
1367 specific code) before trying to display X-Face header field image.
1368
13692003-02-11 Steve Youngs <youngs@xemacs.org>
1370
1371 * mh-customize.el (mh-show-use-xface-flag): If using XEmacs and
1372 can't find the external x-face pkg still enable X-Face images if
1373 feature 'xface is present.
1374 Update the doc string.
1375
1376 * mh-utils.el (mh-emacs21-face-display-function): Make it work in
1377 XEmacs.
1378 (mh-show-xface-function): If using XEmacs without xface support,
1379 use x-face.el pkg. If using XEmacs with xface support, or Emacs
1380 21, use mh-emacs21-face-display-function.
1381
13822003-02-11 Mark D. Baushke <mdb@gnu.org>
1383
1384 * mh-customize.el (mh-invisible-header-fields): Add
1385 "X-Notes-Item:" which is generated by Lotus Notes Domino. See
1386 URL<http://www-12.lotus.com/ldd/doc/domino_notes/Rnext/help6_admin.nsf
1387 /f4b82fbb75e942a6852566ac0037f284/5eda03c647f879c285256c1d00396051
1388 ?OpenDocument&Highlight=0,x-notes-item> for details on how Domino
1389 users may disable (restore the default) generation of these headers.
1390
13912003-02-10 Satyaki Das <satyaki@theforce.stanford.edu>
1392
1393 * mh-comp.el (mh-folder-expand-at-point): Add function doc string
1394 and produce a nicer error message for Emacs versions that lack
1395 mail-abbrev-complete-alias.
1396
1397 * mh-utils.el (mh-handle-process-error): Check doc fix.
1398
1399 * mh-e.el (mh-folder-from-address): Same as above.
1400
14012003-02-10 Peter S Galbraith <psg@debian.org>
1402
1403 * mh-comp.el: require mailabbrev, except in XEmacs.
1404 (mh-mail-abbrev-make-syntax-table): New defmacro to call
1405 mail-abbrev-make-syntax-table introduced in Emacs21.
1406 (mh-folder-expand-at-point): Handle nested folders.
1407 All of the above was written by Satyaki. I just applied the patch
1408 and tested.
1409
14102003-02-09 Satyaki Das <satyaki@theforce.stanford.edu>
1411
1412 * mh-comp.el: Fixes to keep the byte compiler happy.
1413
1414 * mh-customize.el (mh-invisible-header-fields): Modified to
1415 remove space after ":" in header field names.
1416
14172003-02-09 Peter S Galbraith <psg@mixed.dyndns.org>
1418
1419 * mh-comp.el (mh-letter-complete): Add completion for fcc lines.
1420 (mh-folder-expand-at-point): Do completion at point for folder
1421 name. Like `mh-alias-letter-expand-alias' for aliases, it doesn't
1422 work on XEmacs because it relies on `mail-abbrev-complete-alias'
1423 to do completion. Maybe Steve could update XEmacs' mailabbrev.el?
1424
14252003-02-09 Peter S Galbraith <psg@debian.org>
1426
1427 * mh-customize.el (mh-invisible-header-fields): Remove trailing
1428 space in "X-Face: " and "Face: " entries since those line often
1429 break there.
1430
14312003-02-08 Satyaki Das <satyaki@theforce.stanford.edu>
1432
1433 * mh-utils.el (mh-emacs21-face-display-function): Use
1434 mh-show-xface-face to colorize X-Face image.
1435
1436 * mh-customize.el (mh-invisible-header-fields): Add extra headers
1437 to ignore.
1438 (mh-show-xface-face): Allow customization of the X-Face colors.
1439
14402003-02-07 Satyaki Das <satyaki@theforce.stanford.edu>
1441
1442 * mh-utils.el (mh-uncompface-executable, mh-uncompface): Remember
1443 the path of the uncompface executable so that we don't need to
1444 search for it every time.
1445 (mh-emacs21-face-display-function): If more than one X-Face (or
1446 Face) header field was present then the fields would get
1447 concatenated, leading to garbled output. The change only displays
1448 the first image.
1449
1450 * mh-customize.el (mh-x-face-file): Change documentation since it
1451 can now be used to insert a Face header field.
1452
1453 * mh-comp.el (mh-insert-x-face): Generalized to allow insertion
1454 of Face header field.
1455
14562003-02-06 Bill Wohler <wohler@newt.com>
1457
1458 * mh-utils.el (mh-emacs21-face-display-function): Updated
1459 docstring. It is a common mistake to refer to a header field as a
1460 header. The term header refers to the entire header while the term
1461 header field refers to a single field.
1462
1463 * mh-customize.el (mh-show-use-xface-flag): Ditto.
1464
14652003-02-06 Satyaki Das <satyaki@theforce.stanford.edu>
1466
1467 * mh-utils.el (mh-show-xface-function): Modified to use
1468 mh-emacs21-face-display-function if we are running GNU Emacs 21.
1469 (mh-face-to-png): New function to convert a Face header to a png
1470 image.
1471 (mh-uncompface): New function which converts an X-Face header to
1472 a pbm image.
1473 (mh-icontopbm): New function that does the job of icontopbm.
1474 (mh-emacs21-face-display-function): New function that displays
1475 Face/X-Face image in GNU Emacs 21.
1476 (mh-show-xface): Modified to test if we are running in X.
1477 Otherwise face display is suppressed.
1478
1479 * mh-customize.el (mh-show-use-xface-flag): Tweak it, now that
1480 MH-E supports face display natively on Emacs 21. Also remove the
1481 check for window-system since it doesn't belong in a customizable
1482 variable.
1483
14842003-02-06 Satyaki Das <satyaki@theforce.stanford.edu>
1485
1486 * mh-utils.el (sendmail): Require it so that XEmacs can find
1487 rfc822-goto-eoh.
1488 (mh-mail-header-end): A substitute for mail-header-end that
1489 doesn't widen the buffer. This is essential to avoid problems when
1490 dealing with nested messages.
1491 (mh-in-header-p, mh-letter-header-font-lock)
1492 (mh-header-field-font-lock, mh-show-font-lock-fontify-region)
1493 (mh-show-unquote-From): Use mh-mail-header-end instead of
1494 mail-header-end.
1495
1496 * mh-mime.el (mh-decode-message-body): same as above (closes SF
1497 #681518).
1498
1499 * mh-comp.el (mh-yank-cur-msg): same as above.
1500
15012003-02-05 Satyaki Das <satyaki@theforce.stanford.edu>
1502
1503 * mh-utils.el (mh-display-msg): Call mh-show-mode before invisible
1504 headers are cleaned. This means that any surviving X-Face header
1505 can be removed unconditionally in mh-clean-msg-header.
1506 (mh-clean-msg-header): Since the function is now called with a
1507 read-only buffer, make the buffer temporarily writable.
1508
1509 * mh-mime.el (mh-mm-inline-message): Do X-Face display before
1510 invisible headers are removed.
1511
1512 * mh-customize.el (mh-invisible-headers): Simplified since the
1513 X-Face header isn't treated specially any more.
1514 (mh-invisible-header-fields): Add Face: and X-Face: to list of
1515 invisible headers.
1516
1517 * mh-mime.el (mh-mime-display): If body is empty the headers would
1518 be treated like the body. The change fixes this (closes SF #681162).
1519 (mh-mime-display): This change really fixes the above problem.
1520
15212003-02-04 Satyaki Das <satyaki@theforce.stanford.edu>
1522
1523 * mh-utils.el (mh-current-folder-name): Global variable that
1524 keeps track of current folder.
1525 (mh-normalize-folder-name): Substitute @ with
1526 mh-current-folder-name (closes SF #666774).
1527 (mh-prompt-for-folder): Bind mh-current-folder-name. Also
1528 invalidate cache if we are visiting a folder that wasn't found in
1529 the sub-folder cache. This is an indication that folders may have
1530 been created outside of MH-E and so the cache may be stale.
1531
15322003-02-03 Satyaki Das <satyaki@theforce.stanford.edu>
1533
1534 * mh-utils.el (mh-decode-content-transfer-encoded-message): Removed.
1535 (mh-display-msg): Remove the use of the above function.
1536 (mh-normalize-folder-name): Leading "/" characters were being
1537 lost. The change fixes this (closes SF #676890).
1538
1539 * mh-mime.el (mh-decode-message-body): New function, factored out
1540 from mh-mime-display and enhanced, to decode message based on
1541 charset and content-transfer-encoding. This eliminates the need
1542 for the external mimencode (closes SF #674857).
1543 (mh-mime-display): Use mh-decode-message-body.
1544
1545 * mh-e.el (mh-header-display): Don't need the binding since the
1546 variable isn't present any more.
1547 (mh-inc-folder): Avoid calling mh-show if point is not on a valid
1548 scan line (closes SF #678115).
1549
1550 * mh-customize.el
1551 (mh-decode-content-transfer-encoded-message-flag): Removed.
1552
15532003-02-03 Bill Wohler <wohler@newt.com>
1554
1555 * import-emacs: MH-E now has its own directory in Emacs.
1556
1557 * mh-e.el: (mh-version): Set to 7.2+cvs.
1558
12003-02-03 Bill Wohler <wohler@newt.com> 15592003-02-03 Bill Wohler <wohler@newt.com>
2 1560
3 * Released MH-E version 7.2. 1561 * Released MH-E version 7.2.
@@ -4061,7 +5619,7 @@
4061 Non-fatal depencencies on the mm-decode, mm-uu and mm-view 5619 Non-fatal depencencies on the mm-decode, mm-uu and mm-view
4062 libraries. 5620 libraries.
4063 5621
40642002-07-15 Satyaki Das <satyaki@theforce.stanford.edu> 56222002-07-15 Satyaki Das <satyaki@theforce.stanford.edu>
4065 5623
4066 * mh-utils.el (mh-require, mh-autoload): Remove these macros. 5624 * mh-utils.el (mh-require, mh-autoload): Remove these macros.
4067 (mh-decode-mime): Initialized to t iff the mm-decode library is 5625 (mh-decode-mime): Initialized to t iff the mm-decode library is
@@ -4674,7 +6232,7 @@
4674 (mh-filter-out-non-text): New function to filter out attachments 6232 (mh-filter-out-non-text): New function to filter out attachments
4675 from message being yanked. 6233 from message being yanked.
4676 6234
46772002-05-20 Bill Wohler <Bill.Wohler@openwave.com> 62352002-05-20 Bill Wohler <Bill.Wohler@openwave.com>
4678 6236
4679 * mh-utils.el (mh-invisible-headers-show-xface): First sentence of 6237 * mh-utils.el (mh-invisible-headers-show-xface): First sentence of
4680 docstring was not entirely on first line so was truncated in 6238 docstring was not entirely on first line so was truncated in
@@ -6017,3 +7575,10 @@
6017 (install): $MH-E-SRC is copied to $(EMACS_HOME)/lisp/mail, not 7575 (install): $MH-E-SRC is copied to $(EMACS_HOME)/lisp/mail, not
6018 $(EMACS_HOME)/src. 7576 $(EMACS_HOME)/src.
6019 (dist): Leave release in current directory. 7577 (dist): Leave release in current directory.
7578
7579
7580Copyright (C) 2003 Free Software Foundation, Inc.
7581
7582Copying and distribution of this file, with or without modification,
7583are permitted in any medium without royalty provided the copyright
7584notice and this notice are preserved.
diff --git a/lisp/mh-e/mh-alias.el b/lisp/mh-e/mh-alias.el
index 5c56ab8b2af..7978fbdc32f 100644
--- a/lisp/mh-e/mh-alias.el
+++ b/lisp/mh-e/mh-alias.el
@@ -1,6 +1,7 @@
1;;; mh-alias.el --- MH-E mail alias completion and expansion 1;;; mh-alias.el --- MH-E mail alias completion and expansion
2;; 2;;
3;; Copyright (C) 1994, 1995, 1996, 1997, 2001, 2002 Free Software Foundation, Inc. 3;; Copyright (C) 1994, 95, 96, 1997,
4;; 2001, 02, 2003 Free Software Foundation, Inc.
4 5
5;; Author: Peter S. Galbraith <psg@debian.org> 6;; Author: Peter S. Galbraith <psg@debian.org>
6;; Maintainer: Bill Wohler <wohler@newt.com> 7;; Maintainer: Bill Wohler <wohler@newt.com>
@@ -93,8 +94,6 @@
93 94
94;;; Change Log: 95;;; Change Log:
95 96
96;; $Id: mh-alias.el,v 1.2 2003/02/03 20:55:30 wohler Exp $
97
98;;; Code: 97;;; Code:
99 98
100(require 'mh-e) 99(require 'mh-e)
@@ -103,10 +102,12 @@
103(eval-when-compile (defvar mail-abbrev-syntax-table)) 102(eval-when-compile (defvar mail-abbrev-syntax-table))
104 103
105;;; Autoloads 104;;; Autoloads
106(autoload 'mail-abbrev-complete-alias "mailabbrev") 105(eval-when (compile load eval)
107(autoload 'multi-prompt "multi-prompt") 106 (ignore-errors
107 (require 'mailabbrev)
108 (require 'multi-prompt)))
108 109
109(defvar mh-alias-alist nil 110(defvar mh-alias-alist 'not-read
110 "Alist of MH aliases.") 111 "Alist of MH aliases.")
111(defvar mh-alias-blind-alist nil 112(defvar mh-alias-blind-alist nil
112 "Alist of MH aliases that are blind lists.") 113 "Alist of MH aliases that are blind lists.")
@@ -180,7 +181,7 @@ If ARG is non-nil, filenames listed in `mh-alias-system-aliases' are appended."
180 (insert-file-contents "/etc/passwd"))) 181 (insert-file-contents "/etc/passwd")))
181 ((stringp mh-alias-local-users) 182 ((stringp mh-alias-local-users)
182 (insert mh-alias-local-users "\n") 183 (insert mh-alias-local-users "\n")
183 (shell-command-on-region (point-min)(point-max) mh-alias-local-users t) 184 (shell-command-on-region (point-min) (point-max) mh-alias-local-users t)
184 (goto-char (point-min)))) 185 (goto-char (point-min))))
185 (while (< (point) (point-max)) 186 (while (< (point) (point-max))
186 (cond 187 (cond
@@ -241,7 +242,7 @@ If ARG is non-nil, filenames listed in `mh-alias-system-aliases' are appended."
241 242
242(defun mh-alias-reload-maybe () 243(defun mh-alias-reload-maybe ()
243 "Load new MH aliases." 244 "Load new MH aliases."
244 (if (or (not mh-alias-alist) ; Doesn't exist, so create it. 245 (if (or (eq mh-alias-alist 'not-read) ; Doesn't exist, so create it.
245 (mh-alias-tstamp nil)) ; Out of date, so recreate it. 246 (mh-alias-tstamp nil)) ; Out of date, so recreate it.
246 (mh-alias-reload))) 247 (mh-alias-reload)))
247 248
@@ -253,12 +254,16 @@ If ARG is non-nil, filenames listed in `mh-alias-system-aliases' are appended."
253ALIAS must be a string for a single alias. 254ALIAS must be a string for a single alias.
254If USER is t, then assume ALIAS is an address and call ali -user. 255If USER is t, then assume ALIAS is an address and call ali -user.
255ali returns the string unchanged if not defined. The same is done here." 256ali returns the string unchanged if not defined. The same is done here."
256 (save-excursion 257 (condition-case err
257 (let ((user-arg (if user "-user" "-nouser"))) 258 (save-excursion
258 (mh-exec-cmd-quiet t "ali" user-arg "-nolist" alias)) 259 (let ((user-arg (if user "-user" "-nouser")))
259 (goto-char (point-max)) 260 (mh-exec-cmd-quiet t "ali" user-arg "-nolist" alias))
260 (if (looking-at "^$") (delete-backward-char 1)) 261 (goto-char (point-max))
261 (buffer-substring (point-min)(point-max)))) 262 (if (looking-at "^$") (delete-backward-char 1))
263 (buffer-substring (point-min)(point-max)))
264 (error (progn
265 (message (error-message-string err))
266 alias))))
262 267
263(defun mh-alias-expand (alias) 268(defun mh-alias-expand (alias)
264 "Return expansion for ALIAS. 269 "Return expansion for ALIAS.
@@ -280,15 +285,14 @@ Blind aliases or users from /etc/passwd are not expanded."
280 (let* ((minibuffer-local-completion-map mh-alias-read-address-map) 285 (let* ((minibuffer-local-completion-map mh-alias-read-address-map)
281 (completion-ignore-case mh-alias-completion-ignore-case-flag) 286 (completion-ignore-case mh-alias-completion-ignore-case-flag)
282 (the-answer 287 (the-answer
283 (or (cond 288 (cond ((fboundp 'completing-read-multiple)
284 ((fboundp 'completing-read-multiple) 289 (mh-funcall-if-exists
285 (completing-read-multiple prompt mh-alias-alist nil nil)) 290 completing-read-multiple prompt mh-alias-alist nil nil))
286 ((featurep 'multi-prompt) 291 ((featurep 'multi-prompt)
287 (multi-prompt "," nil prompt mh-alias-alist nil nil)) 292 (mh-funcall-if-exists
288 (t 293 multi-prompt "," nil prompt mh-alias-alist nil nil))
289 (split-string 294 (t (split-string
290 (completing-read prompt mh-alias-alist nil nil) 295 (completing-read prompt mh-alias-alist nil nil) ",")))))
291 ","))))))
292 (if (not mh-alias-expand-aliases-flag) 296 (if (not mh-alias-expand-aliases-flag)
293 (mapconcat 'identity the-answer ", ") 297 (mapconcat 'identity the-answer ", ")
294 ;; Loop over all elements, checking if in passwd aliast or blind first 298 ;; Loop over all elements, checking if in passwd aliast or blind first
@@ -325,12 +329,14 @@ Blind aliases or users from /etc/passwd are not expanded."
325 (message "No alias for %s" the-name)))))) 329 (message "No alias for %s" the-name))))))
326 (self-insert-command 1)) 330 (self-insert-command 1))
327 331
332(mh-do-in-xemacs (defvar mail-abbrevs))
333
328;;;###mh-autoload 334;;;###mh-autoload
329(defun mh-alias-letter-expand-alias () 335(defun mh-alias-letter-expand-alias ()
330 "Expand mail alias before point." 336 "Expand mail alias before point."
331 (mh-alias-reload-maybe) 337 (mh-alias-reload-maybe)
332 (let ((mail-abbrevs mh-alias-alist)) 338 (let ((mail-abbrevs mh-alias-alist))
333 (mail-abbrev-complete-alias)) 339 (mh-funcall-if-exists mail-abbrev-complete-alias))
334 (when mh-alias-expand-aliases-flag 340 (when mh-alias-expand-aliases-flag
335 (let* ((end (point)) 341 (let* ((end (point))
336 (syntax-table (syntax-table)) 342 (syntax-table (syntax-table))
@@ -350,6 +356,9 @@ Blind aliases or users from /etc/passwd are not expanded."
350(defun mh-alias-suggest-alias (string) 356(defun mh-alias-suggest-alias (string)
351 "Suggest an alias for STRING." 357 "Suggest an alias for STRING."
352 (cond 358 (cond
359 ((string-match "^<\\(.*\\)>$" string)
360 ;; <somename@foo.bar> -> recurse, stripping brackets.
361 (mh-alias-suggest-alias (match-string 1 string)))
353 ((string-match "^\\sw+$" string) 362 ((string-match "^\\sw+$" string)
354 ;; One word -> downcase it. 363 ;; One word -> downcase it.
355 (downcase string)) 364 (downcase string))
@@ -389,9 +398,25 @@ Blind aliases or users from /etc/passwd are not expanded."
389 (format "%s %s" (match-string 2 string) (match-string 1 string)))) 398 (format "%s %s" (match-string 2 string) (match-string 1 string))))
390 (t 399 (t
391 ;; Output string, with spaces replaced by dots. 400 ;; Output string, with spaces replaced by dots.
392 (downcase (replace-regexp-in-string 401 (mh-alias-canonicalize-suggestion string))))
393 "\\.\\.+" "." 402
394 (replace-regexp-in-string " +" "." string)))))) 403(defun mh-alias-canonicalize-suggestion (string)
404 "Process STRING to replace spacess by periods.
405First all spaces are replaced by periods. Then every run of consecutive periods
406are replaced with a single period. Finally the string is converted to lower
407case."
408 (with-temp-buffer
409 (insert string)
410 ;; Replace spaces with periods
411 (goto-char (point-min))
412 (replace-regexp " +" ".")
413 ;; Replace consecutive periods with a single period
414 (goto-char (point-min))
415 (replace-regexp "\\.\\.+" ".")
416 ;; Convert to lower case
417 (downcase-region (point-min) (point-max))
418 ;; Whew! all done...
419 (buffer-string)))
395 420
396(defun mh-alias-which-file-has-alias (alias file-list) 421(defun mh-alias-which-file-has-alias (alias file-list)
397 "Return the name of writable file which defines ALIAS from list FILE-LIST." 422 "Return the name of writable file which defines ALIAS from list FILE-LIST."
@@ -403,7 +428,7 @@ Blind aliases or users from /etc/passwd are not expanded."
403 (erase-buffer) 428 (erase-buffer)
404 (when (file-writable-p (car file-list)) 429 (when (file-writable-p (car file-list))
405 (insert-file-contents (car file-list)) 430 (insert-file-contents (car file-list))
406 (if (re-search-forward (concat "^" (regexp-quote alias) ":")) 431 (if (re-search-forward (concat "^" (regexp-quote alias) ":") nil t)
407 (setq found (car file-list) 432 (setq found (car file-list)
408 the-list nil) 433 the-list nil)
409 (setq the-list (cdr the-list))))) 434 (setq the-list (cdr the-list)))))
@@ -470,14 +495,18 @@ Set `mh-alias-insert-file' or set AliasFile in your .mh_profile file"))
470 495
471;;;###mh-autoload 496;;;###mh-autoload
472(defun mh-alias-from-has-no-alias-p () 497(defun mh-alias-from-has-no-alias-p ()
473 "Return t is From has no current alias set." 498 "Return t is From has no current alias set.
499In the exceptional situation where there isn't a From header in the message the
500function returns nil."
474 (mh-alias-reload-maybe) 501 (mh-alias-reload-maybe)
475 (save-excursion 502 (save-excursion
476 (if (not (mh-folder-line-matches-show-buffer-p)) 503 (if (not (mh-folder-line-matches-show-buffer-p))
477 nil ;No corresponding show buffer 504 nil ;No corresponding show buffer
478 (if (eq major-mode 'mh-folder-mode) 505 (if (eq major-mode 'mh-folder-mode)
479 (set-buffer mh-show-buffer)) 506 (set-buffer mh-show-buffer))
480 (not (mh-alias-address-to-alias (mh-extract-from-header-value)))))) 507 (let ((from-header (mh-extract-from-header-value)))
508 (and from-header
509 (not (mh-alias-address-to-alias from-header)))))))
481 510
482(defun mh-alias-add-alias-to-file (alias address &optional file) 511(defun mh-alias-add-alias-to-file (alias address &optional file)
483 "Add ALIAS for ADDRESS in alias FILE without alias check or prompts. 512 "Add ALIAS for ADDRESS in alias FILE without alias check or prompts.
@@ -491,7 +520,6 @@ after it."
491 (goto-char (point-min)) 520 (goto-char (point-min))
492 (let ((alias-search (concat alias ":")) 521 (let ((alias-search (concat alias ":"))
493 (letter) 522 (letter)
494 (here (point))
495 (case-fold-search t)) 523 (case-fold-search t))
496 (cond 524 (cond
497 ;; Search for exact match (if we had the same alias before) 525 ;; Search for exact match (if we had the same alias before)
@@ -538,7 +566,11 @@ If the alias is already is use, `mh-alias-add-alias-to-file' will prompt."
538 (interactive "P\nP") 566 (interactive "P\nP")
539 (mh-alias-reload-maybe) 567 (mh-alias-reload-maybe)
540 (setq alias (completing-read "Alias: " mh-alias-alist nil nil alias)) 568 (setq alias (completing-read "Alias: " mh-alias-alist nil nil alias))
569 (if (and address (string-match "^<\\(.*\\)>$" address))
570 (setq address (match-string 1 address)))
541 (setq address (read-string "Address: " address)) 571 (setq address (read-string "Address: " address))
572 (if (string-match "^<\\(.*\\)>$" address)
573 (setq address (match-string 1 address)))
542 (let ((address-alias (mh-alias-address-to-alias address)) 574 (let ((address-alias (mh-alias-address-to-alias address))
543 (alias-address (mh-alias-expand alias))) 575 (alias-address (mh-alias-expand alias)))
544 (if (string-equal alias-address alias) 576 (if (string-equal alias-address alias)
@@ -571,7 +603,8 @@ already has an alias."
571 (insert-file-contents (mh-msg-filename (mh-get-msg-num t)))) 603 (insert-file-contents (mh-msg-filename (mh-get-msg-num t))))
572 ((eq major-mode 'mh-folder-mode) 604 ((eq major-mode 'mh-folder-mode)
573 (error "Cursor not pointing to a message"))) 605 (error "Cursor not pointing to a message")))
574 (let* ((address (mh-extract-from-header-value)) 606 (let* ((address (or (mh-extract-from-header-value)
607 (error "Message has no From: header")))
575 (alias (mh-alias-suggest-alias address))) 608 (alias (mh-alias-suggest-alias address)))
576 (mh-alias-add-alias alias address)))) 609 (mh-alias-add-alias alias address))))
577 610
diff --git a/lisp/mh-e/mh-comp.el b/lisp/mh-e/mh-comp.el
index d6b4f9754b6..b3b588e72a5 100644
--- a/lisp/mh-e/mh-comp.el
+++ b/lisp/mh-e/mh-comp.el
@@ -1,6 +1,7 @@
1;;; mh-comp.el --- MH-E functions for composing messages 1;;; mh-comp.el --- MH-E functions for composing messages
2 2
3;; Copyright (C) 1993,1995,1997,2000,2001,2002 Free Software Foundation, Inc. 3;; Copyright (C) 1993, 95, 1997,
4;; 2000, 01, 02, 2003 Free Software Foundation, Inc.
4 5
5;; Author: Bill Wohler <wohler@newt.com> 6;; Author: Bill Wohler <wohler@newt.com>
6;; Maintainer: Bill Wohler <wohler@newt.com> 7;; Maintainer: Bill Wohler <wohler@newt.com>
@@ -30,14 +31,14 @@
30 31
31;;; Change Log: 32;;; Change Log:
32 33
33;; $Id: mh-comp.el,v 1.2 2003/02/03 20:55:30 wohler Exp $
34
35;;; Code: 34;;; Code:
36 35
37(require 'mh-e) 36(require 'mh-e)
38(require 'gnus-util) 37(require 'gnus-util)
39(require 'easymenu) 38(require 'easymenu)
40(require 'cl) 39(require 'cl)
40(eval-when (compile load eval)
41 (ignore-errors (require 'mailabbrev)))
41 42
42;; Shush the byte-compiler 43;; Shush the byte-compiler
43(defvar adaptive-fill-first-line-regexp) 44(defvar adaptive-fill-first-line-regexp)
@@ -309,27 +310,21 @@ See also documentation for `\\[mh-send]' function."
309 310
310;;;###mh-autoload 311;;;###mh-autoload
311(defun mh-forward (to cc &optional msg-or-seq) 312(defun mh-forward (to cc &optional msg-or-seq)
312 "Forward one or more messages to the recipients TO and CC. 313 "Forward messages to the recipients TO and CC.
313 314Use optional MSG-OR-SEQ argument to specify a message or sequence to forward.
314Use the optional MSG-OR-SEQ to specify a message or sequence to forward. 315Default is the displayed message.
316If optional prefix argument is provided, then prompt for the message sequence.
317If variable `transient-mark-mode' is non-nil and the mark is active, then the
318selected region is forwarded.
319In a program, MSG-OR-SEQ can be a message number, a list of message numbers, a
320region in a cons cell, or a sequence.
315 321
316Default is the displayed message. If optional prefix argument is given then
317prompt for the message sequence. If variable `transient-mark-mode' is non-nil
318and the mark is active, then the selected region is forwarded.
319See also documentation for `\\[mh-send]' function." 322See also documentation for `\\[mh-send]' function."
320 (interactive (list (mh-read-address "To: ") 323 (interactive (list (mh-read-address "To: ")
321 (mh-read-address "Cc: ") 324 (mh-read-address "Cc: ")
322 (cond 325 (mh-interactive-msg-or-seq "Forward")))
323 ((mh-mark-active-p t)
324 (mh-region-to-msg-list (region-beginning) (region-end)))
325 (current-prefix-arg
326 (mh-read-seq-default "Forward" t))
327 (t
328 (mh-get-msg-num t)))))
329 (let* ((folder mh-current-folder) 326 (let* ((folder mh-current-folder)
330 (msgs (cond ((numberp msg-or-seq) (list msg-or-seq)) 327 (msgs (mh-msg-or-seq-to-msg-list msg-or-seq))
331 ((listp msg-or-seq) msg-or-seq)
332 (t (mh-seq-to-msgs msg-or-seq))))
333 (config (current-window-configuration)) 328 (config (current-window-configuration))
334 (fwd-msg-file (mh-msg-filename (car msgs) folder)) 329 (fwd-msg-file (mh-msg-filename (car msgs) folder))
335 ;; forw always leaves file in "draft" since it doesn't have -draft 330 ;; forw always leaves file in "draft" since it doesn't have -draft
@@ -337,7 +332,8 @@ See also documentation for `\\[mh-send]' function."
337 (draft (cond ((or (not (file-exists-p draft-name)) 332 (draft (cond ((or (not (file-exists-p draft-name))
338 (y-or-n-p "The file 'draft' exists. Discard it? ")) 333 (y-or-n-p "The file 'draft' exists. Discard it? "))
339 (mh-exec-cmd "forw" "-build" (if mh-nmh-flag "-mime") 334 (mh-exec-cmd "forw" "-build" (if mh-nmh-flag "-mime")
340 mh-current-folder msgs) 335 mh-current-folder
336 (mh-coalesce-msg-list msgs))
341 (prog1 337 (prog1
342 (mh-read-draft "" draft-name t) 338 (mh-read-draft "" draft-name t)
343 (mh-insert-fields "To:" to "Cc:" cc) 339 (mh-insert-fields "To:" to "Cc:" cc)
@@ -353,14 +349,12 @@ See also documentation for `\\[mh-send]' function."
353 (setq orig-from (mh-get-header-field "From:")) 349 (setq orig-from (mh-get-header-field "From:"))
354 (setq orig-subject (mh-get-header-field "Subject:"))) 350 (setq orig-subject (mh-get-header-field "Subject:")))
355 (let ((forw-subject 351 (let ((forw-subject
356 (mh-forwarded-letter-subject orig-from orig-subject)) 352 (mh-forwarded-letter-subject orig-from orig-subject)))
357 (compose))
358 (mh-insert-fields "Subject:" forw-subject) 353 (mh-insert-fields "Subject:" forw-subject)
359 (goto-char (point-min)) 354 (goto-char (point-min))
360 ;; If using MML, translate mhn 355 ;; If using MML, translate mhn
361 (if (equal mh-compose-insertion 'gnus) 356 (if (equal mh-compose-insertion 'gnus)
362 (save-excursion 357 (save-excursion
363 (setq compose t)
364 (re-search-forward (format "^\\(%s\\)?$" 358 (re-search-forward (format "^\\(%s\\)?$"
365 mh-mail-header-separator)) 359 mh-mail-header-separator))
366 (while 360 (while
@@ -386,12 +380,10 @@ See also documentation for `\\[mh-send]' function."
386 (forward-line 1)) 380 (forward-line 1))
387 (delete-other-windows) 381 (delete-other-windows)
388 (mh-add-msgs-to-seq msgs 'forwarded t) 382 (mh-add-msgs-to-seq msgs 'forwarded t)
389 (mh-compose-and-send-mail draft "" folder msg-or-seq 383 (mh-compose-and-send-mail draft "" folder msgs
390 to forw-subject cc 384 to forw-subject cc
391 mh-note-forw "Forwarded:" 385 mh-note-forw "Forwarded:"
392 config) 386 config)
393 (if compose
394 (setq mh-mml-compose-insert-flag t))
395 (mh-letter-mode-message))))) 387 (mh-letter-mode-message)))))
396 388
397(defun mh-forwarded-letter-subject (from subject) 389(defun mh-forwarded-letter-subject (from subject)
@@ -439,38 +431,27 @@ setting of the variable `mh-redist-full-contents'. See its documentation."
439 (mh-goto-header-end 0) 431 (mh-goto-header-end 0)
440 (insert "Resent-To: " to "\n") 432 (insert "Resent-To: " to "\n")
441 (if (not (equal cc "")) (insert "Resent-cc: " cc "\n")) 433 (if (not (equal cc "")) (insert "Resent-cc: " cc "\n"))
442 (mh-clean-msg-header (point-min) 434 (mh-clean-msg-header
443 "^Message-Id:\\|^Received:\\|^Return-Path:\\|^Sender:\\|^Date:\\|^From:" 435 (point-min)
444 nil) 436 "^Message-Id:\\|^Received:\\|^Return-Path:\\|^Sender:\\|^Date:\\|^From:"
437 nil)
445 (save-buffer) 438 (save-buffer)
446 (message "Redistributing...") 439 (message "Redistributing...")
447 (if (not mh-redist-background) 440 (let ((env "mhdist=1"))
448 (if mh-redist-full-contents 441 ;; Setup environment...
449 (call-process "/bin/sh" nil 0 nil "-c" 442 (setq env (concat env " mhaltmsg=" (if mh-redist-full-contents
450 (format "mhdist=1 mhaltmsg=%s %s -push %s" 443 buffer-file-name
451 buffer-file-name 444 (mh-msg-filename msg folder))))
452 (expand-file-name mh-send-prog mh-progs) 445 (unless mh-redist-full-contents
453 buffer-file-name)) 446 (setq env (concat env " mhannotate=1")))
454 (call-process "/bin/sh" nil 0 nil "-c" 447 ;; Redistribute...
455 (format 448 (if mh-redist-background
456 "mhdist=1 mhaltmsg=%s mhannotate=1 %s -push %s" 449 (mh-exec-cmd-env-daemon env mh-send-prog nil buffer-file-name)
457 (mh-msg-filename msg folder) 450 (mh-exec-cmd-error env mh-send-prog "-push" buffer-file-name))
458 (expand-file-name mh-send-prog mh-progs) 451 ;; Annotate...
459 buffer-file-name)))) 452 (mh-annotate-msg msg folder mh-note-dist
460 (mh-annotate-msg msg folder mh-note-dist 453 "-component" "Resent:"
461 "-component" "Resent:" 454 "-text" (format "\"%s %s\"" to cc)))
462 "-text" (format "\"%s %s\"" to cc))
463 (if mh-redist-background
464 (mh-exec-cmd-daemon "/bin/sh" nil "-c"
465 (format "mhdist=1 mhaltmsg=%s %s %s %s"
466 (if mh-redist-full-contents
467 buffer-file-name
468 (mh-msg-filename msg folder))
469 (if mh-redist-full-contents
470 ""
471 "mhannotate=1")
472 (mh-expand-file-name "send" mh-progs)
473 buffer-file-name)))
474 (kill-buffer draft) 455 (kill-buffer draft)
475 (message "Redistributing...done")))) 456 (message "Redistributing...done"))))
476 457
@@ -501,7 +482,8 @@ Optional argument BUFFER can be used to specify the buffer."
501 482
502;;;###mh-autoload 483;;;###mh-autoload
503(defun mh-reply (message &optional reply-to includep) 484(defun mh-reply (message &optional reply-to includep)
504 "Reply to MESSAGE (default: current message). 485 "Reply to MESSAGE.
486Default is the displayed message.
505If the optional argument REPLY-TO is not given, prompts for type of addresses 487If the optional argument REPLY-TO is not given, prompts for type of addresses
506to reply to: 488to reply to:
507 from sender only, 489 from sender only,
@@ -706,14 +688,15 @@ reused."
706 (buffer-substring (point-min) (1- (point-max))))) 688 (buffer-substring (point-min) (1- (point-max)))))
707 689
708(defun mh-annotate-msg (msg buffer note &rest args) 690(defun mh-annotate-msg (msg buffer note &rest args)
709 "Mark MSG in BUFFER with character NOTE and annotate message with ARGS." 691 "Mark MSG in BUFFER with character NOTE and annotate message with ARGS.
710 (apply 'mh-exec-cmd "anno" buffer msg args) 692MSG can be a message number, a list of message numbers, or a sequence."
693 (apply 'mh-exec-cmd "anno" buffer
694 (if (listp msg) (append msg args) (cons msg args)))
711 (save-excursion 695 (save-excursion
712 (cond ((get-buffer buffer) ; Buffer may be deleted 696 (cond ((get-buffer buffer) ; Buffer may be deleted
713 (set-buffer buffer) 697 (set-buffer buffer)
714 (if (numberp msg) 698 (mh-iterate-on-msg-or-seq nil msg
715 (mh-notate msg note (1+ mh-cmd-note)) 699 (mh-notate nil note (1+ mh-cmd-note)))))))
716 (mh-notate-seq msg note (1+ mh-cmd-note)))))))
717 700
718(defun mh-insert-fields (&rest name-values) 701(defun mh-insert-fields (&rest name-values)
719 "Insert the NAME-VALUES pairs in the current buffer. 702 "Insert the NAME-VALUES pairs in the current buffer.
@@ -776,7 +759,7 @@ Returns t if found, nil if not."
776 "Extract From: string from header." 759 "Extract From: string from header."
777 (save-excursion 760 (save-excursion
778 (if (not (mh-goto-header-field "From:")) 761 (if (not (mh-goto-header-field "From:"))
779 (error "No From header line found") 762 nil
780 (skip-chars-forward " \t") 763 (skip-chars-forward " \t")
781 (buffer-substring-no-properties 764 (buffer-substring-no-properties
782 (point) (progn (mh-header-field-end)(point)))))) 765 (point) (progn (mh-header-field-end)(point))))))
@@ -812,9 +795,9 @@ Returns t if found, nil if not."
812 ;; The next two will have to be merged. But I also need to make sure the 795 ;; The next two will have to be merged. But I also need to make sure the
813 ;; user can't mix directives of both types. 796 ;; user can't mix directives of both types.
814 ["Pull in All Compositions (mhn)" 797 ["Pull in All Compositions (mhn)"
815 mh-edit-mhn mh-mhn-compose-insert-flag] 798 mh-edit-mhn (mh-mhn-directive-present-p)]
816 ["Pull in All Compositions (gnus)" 799 ["Pull in All Compositions (gnus)"
817 mh-mml-to-mime mh-mml-compose-insert-flag] 800 mh-mml-to-mime (mh-mml-directive-present-p)]
818 ["Revert to Non-MIME Edit (mhn)" 801 ["Revert to Non-MIME Edit (mhn)"
819 mh-revert-mhn-edit (equal mh-compose-insertion 'mhn)] 802 mh-revert-mhn-edit (equal mh-compose-insertion 'mhn)]
820 ["Kill This Draft" mh-fully-kill-draft t])))) 803 ["Kill This Draft" mh-fully-kill-draft t]))))
@@ -857,6 +840,11 @@ work better in MH-Letter mode."
857 (mail-mode-fill-paragraph arg) 840 (mail-mode-fill-paragraph arg)
858 (fill-paragraph arg)))) 841 (fill-paragraph arg))))
859 842
843;; Avoid compiler warnings in XEmacs and Emacs 20
844(eval-when-compile
845 (defvar tool-bar-mode)
846 (defvar tool-bar-map))
847
860;;;###autoload 848;;;###autoload
861(define-derived-mode mh-letter-mode text-mode "MH-Letter" 849(define-derived-mode mh-letter-mode text-mode "MH-Letter"
862 "Mode for composing letters in MH-E.\\<mh-letter-mode-map> 850 "Mode for composing letters in MH-E.\\<mh-letter-mode-map>
@@ -918,8 +906,11 @@ When a message is composed, the hooks `text-mode-hook' and
918 (setq paragraph-separate paragraph-start) 906 (setq paragraph-separate paragraph-start)
919 ;; --- End of code from sendmail.el --- 907 ;; --- End of code from sendmail.el ---
920 908
909 ;; Enable undo since a show-mode buffer might have been reused.
910 (buffer-enable-undo)
921 (if (and (boundp 'tool-bar-mode) tool-bar-mode) 911 (if (and (boundp 'tool-bar-mode) tool-bar-mode)
922 (set (make-local-variable 'tool-bar-map) mh-letter-tool-bar-map)) 912 (set (make-local-variable 'tool-bar-map) mh-letter-tool-bar-map))
913 (mh-funcall-if-exists mh-toolbar-init :letter)
923 (make-local-variable 'font-lock-defaults) 914 (make-local-variable 'font-lock-defaults)
924 (cond 915 (cond
925 ((or (equal mh-highlight-citation-p 'font-lock) 916 ((or (equal mh-highlight-citation-p 'font-lock)
@@ -933,16 +924,6 @@ When a message is composed, the hooks `text-mode-hook' and
933 ;; ...or the header only 924 ;; ...or the header only
934 (setq font-lock-defaults '(mh-show-font-lock-keywords t)))) 925 (setq font-lock-defaults '(mh-show-font-lock-keywords t))))
935 (easy-menu-add mh-letter-menu) 926 (easy-menu-add mh-letter-menu)
936 ;; See if a "forw: -mime" message containing a MIME composition.
937 ;; Mode clears local vars, so can't do this in mh-forward.
938 (save-excursion
939 (goto-char (point-min))
940 (when (and (re-search-forward
941 (format "^\\(%s\\)?$" mail-header-separator) nil t)
942 (= 0 (forward-line 1))
943 (looking-at "^#forw"))
944 (require 'mh-mime) ;Need mh-mhn-compose-insert-flag local var
945 (setq mh-mhn-compose-insert-flag t)))
946 (setq fill-column mh-letter-fill-column) 927 (setq fill-column mh-letter-fill-column)
947 ;; If text-mode-hook turned on auto-fill, tune it for messages 928 ;; If text-mode-hook turned on auto-fill, tune it for messages
948 (when auto-fill-function 929 (when auto-fill-function
@@ -1055,16 +1036,25 @@ called, with no arguments, before the signature is actually inserted."
1055;;; Routines to compose and send a letter. 1036;;; Routines to compose and send a letter.
1056 1037
1057(defun mh-insert-x-face () 1038(defun mh-insert-x-face ()
1058 "Append X-Face field to header. 1039 "Append X-Face, Face or X-Image-URL field to header.
1059If the field already exists, this function does nothing." 1040If the field already exists, this function does nothing."
1060 (when (and (file-exists-p mh-x-face-file) 1041 (when (and (file-exists-p mh-x-face-file)
1061 (file-readable-p mh-x-face-file)) 1042 (file-readable-p mh-x-face-file))
1062 (save-excursion 1043 (save-excursion
1063 (when (null (mh-position-on-field "X-Face")) 1044 (unless (or (mh-position-on-field "X-Face")
1064 (insert "X-Face: ") 1045 (mh-position-on-field "Face")
1065 (goto-char (+ (point) (cadr (insert-file-contents mh-x-face-file)))) 1046 (mh-position-on-field "X-Image-URL"))
1066 (if (not (looking-at "^")) 1047 (save-excursion
1067 (insert "\n")))))) 1048 (goto-char (+ (point) (cadr (insert-file-contents mh-x-face-file))))
1049 (if (not (looking-at "^"))
1050 (insert "\n")))
1051 (unless (looking-at "\\(X-Face\\|Face\\|X-Image-URL\\): ")
1052 (insert "X-Face: "))))))
1053
1054(defvar mh-x-mailer-string nil
1055 "*String containing the contents of the X-Mailer header field.
1056If nil, this variable is initialized to show the version of MH-E, Emacs, and
1057MH the first time a message is composed.")
1068 1058
1069(defun mh-insert-x-mailer () 1059(defun mh-insert-x-mailer ()
1070 "Append an X-Mailer field to the header. 1060 "Append an X-Mailer field to the header.
@@ -1116,21 +1106,39 @@ The versions of MH-E, Emacs, and MH are shown."
1116 (setq fields (cdr fields)))) 1106 (setq fields (cdr fields))))
1117 search-result))) 1107 search-result)))
1118 1108
1119(defun mh-insert-mail-followup-to () 1109(defun mh-insert-auto-fields ()
1120 "Insert Mail-Followup-To: if To or Cc match `mh-insert-mail-followup-to-list'." 1110 "Insert custom fields if To or Cc match `mh-auto-fields-list'."
1121 (save-excursion 1111 (save-excursion
1122 (if (and (or (mh-goto-header-field "To:")(mh-goto-header-field "cc:")) 1112 (when (and (or (mh-goto-header-field "To:")(mh-goto-header-field "cc:")))
1123 (not (mh-goto-header-field "Mail-Followup-To: "))) 1113 (let ((list mh-auto-fields-list))
1124 (let ((list mh-insert-mail-followup-to-list)) 1114 (while list
1125 (while list 1115 (let ((regexp (nth 0 (car list)))
1126 (let ((regexp (nth 0 (car list))) 1116 (entries (nth 1 (car list))))
1127 (entry (nth 1 (car list)))) 1117 (when (mh-regexp-in-field-p regexp "To:" "cc:")
1128 (when (mh-regexp-in-field-p regexp "To:" "cc:") 1118 (let ((entry-list entries))
1129 (if (mh-goto-header-field "Mail-Followup-To: ") 1119 (while entry-list
1130 (insert entry ", ") 1120 (let ((field (caar entry-list))
1131 (mh-goto-header-end 0) 1121 (value (cdar entry-list)))
1132 (insert "Mail-Followup-To: " entry "\n"))) 1122 (cond
1133 (setq list (cdr list)))))))) 1123 ((equal "identity" field)
1124 (when (assoc value mh-identity-list)
1125 (mh-insert-identity value)))
1126 (t
1127 (mh-modify-header-field field value
1128 (equal field "From")))))
1129 (setq entry-list (cdr entry-list))))))
1130 (setq list (cdr list)))))))
1131
1132(defun mh-modify-header-field (field value &optional overwrite-flag)
1133 "To header FIELD add VALUE.
1134If OVERWRITE-FLAG is non-nil then the old value, if present, is discarded."
1135 (cond ((mh-goto-header-field (concat field ":"))
1136 (insert value)
1137 (if overwrite-flag
1138 (delete-region (point) (line-end-position))
1139 (insert ", ")))
1140 (t (mh-goto-header-end 0)
1141 (insert field ": " value "\n"))))
1134 1142
1135(defun mh-compose-and-send-mail (draft send-args 1143(defun mh-compose-and-send-mail (draft send-args
1136 sent-from-folder sent-from-msg 1144 sent-from-folder sent-from-msg
@@ -1149,12 +1157,13 @@ message. In that case, the ANNOTATE-FIELD is used to build a string
1149for `mh-annotate-msg'. 1157for `mh-annotate-msg'.
1150CONFIG is the window configuration to restore after sending the letter." 1158CONFIG is the window configuration to restore after sending the letter."
1151 (pop-to-buffer draft) 1159 (pop-to-buffer draft)
1152 (if mh-insert-mail-followup-to-flag (mh-insert-mail-followup-to)) 1160 (mh-insert-auto-fields)
1153 (mh-letter-mode) 1161 (mh-letter-mode)
1154 1162
1155 ;; mh-identity support 1163 ;; mh-identity support
1156 (if (and (boundp 'mh-identity-default) 1164 (if (and (boundp 'mh-identity-default)
1157 mh-identity-default) 1165 mh-identity-default
1166 (not mh-identity-local))
1158 (mh-insert-identity mh-identity-default)) 1167 (mh-insert-identity mh-identity-default))
1159 (when (and (boundp 'mh-identity-list) 1168 (when (and (boundp 'mh-identity-list)
1160 mh-identity-list) 1169 mh-identity-list)
@@ -1169,6 +1178,7 @@ CONFIG is the window configuration to restore after sending the letter."
1169 (setq mh-previous-window-config config) 1178 (setq mh-previous-window-config config)
1170 (setq mode-line-buffer-identification (list " {%b}")) 1179 (setq mode-line-buffer-identification (list " {%b}"))
1171 (mh-logo-display) 1180 (mh-logo-display)
1181 (mh-make-local-hook 'kill-buffer-hook)
1172 (add-hook 'kill-buffer-hook 'mh-tidy-draft-buffer nil t) 1182 (add-hook 'kill-buffer-hook 'mh-tidy-draft-buffer nil t)
1173 (if (and (boundp 'mh-compose-letter-function) 1183 (if (and (boundp 'mh-compose-letter-function)
1174 mh-compose-letter-function) 1184 mh-compose-letter-function)
@@ -1193,19 +1203,16 @@ This should be the last function called when composing the draft."
1193If optional prefix argument ARG is provided, monitor delivery. 1203If optional prefix argument ARG is provided, monitor delivery.
1194The value of `mh-before-send-letter-hook' is a list of functions to be called, 1204The value of `mh-before-send-letter-hook' is a list of functions to be called,
1195with no arguments, before doing anything. 1205with no arguments, before doing anything.
1196Run `\\[mh-edit-mhn]' if variable `mh-mhn-compose-insert-flag' is set. 1206Run `\\[mh-edit-mhn]' if mhn directives are present; otherwise
1197Run `\\[mh-mml-to-mime]' if variable `mh-mml-compose-insert-flag' is set. 1207run `\\[mh-mml-to-mime]' if mml directives are present.
1198Insert X-Mailer field if variable `mh-insert-x-mailer-flag' is set. 1208Insert X-Mailer field if variable `mh-insert-x-mailer-flag' is set.
1199Insert X-Face field if the file specified by `mh-x-face-file' exists." 1209Insert X-Face field if the file specified by `mh-x-face-file' exists."
1200 (interactive "P") 1210 (interactive "P")
1201 (run-hooks 'mh-before-send-letter-hook) 1211 (run-hooks 'mh-before-send-letter-hook)
1202 (cond 1212 (cond ((mh-mhn-directive-present-p)
1203 ((and (boundp 'mh-mhn-compose-insert-flag) 1213 (mh-edit-mhn))
1204 mh-mhn-compose-insert-flag) 1214 ((mh-mml-directive-present-p)
1205 (mh-edit-mhn)) 1215 (mh-mml-to-mime)))
1206 ((and (boundp 'mh-mml-compose-insert-flag)
1207 mh-mml-compose-insert-flag)
1208 (mh-mml-to-mime)))
1209 (if mh-insert-x-mailer-flag (mh-insert-x-mailer)) 1216 (if mh-insert-x-mailer-flag (mh-insert-x-mailer))
1210 (mh-insert-x-face) 1217 (mh-insert-x-face)
1211 (save-buffer) 1218 (save-buffer)
@@ -1232,7 +1239,7 @@ Insert X-Face field if the file specified by `mh-x-face-file' exists."
1232 (mh-goto-header-field "Content-Type:")) 1239 (mh-goto-header-field "Content-Type:"))
1233 (setq mh-send-args (format "-mime %s" mh-send-args))) 1240 (setq mh-send-args (format "-mime %s" mh-send-args)))
1234 (cond (arg 1241 (cond (arg
1235 (pop-to-buffer "MH mail delivery") 1242 (pop-to-buffer mh-mail-delivery-buffer)
1236 (erase-buffer) 1243 (erase-buffer)
1237 (mh-exec-cmd-output mh-send-prog t "-watch" "-nopush" 1244 (mh-exec-cmd-output mh-send-prog t "-watch" "-nopush"
1238 "-nodraftfolder" mh-send-args file-name) 1245 "-nodraftfolder" mh-send-args file-name)
@@ -1339,7 +1346,7 @@ yanked message will be deleted."
1339 (eq t mh-yank-from-start-of-msg))) 1346 (eq t mh-yank-from-start-of-msg)))
1340 ;; supercite needs the full header 1347 ;; supercite needs the full header
1341 (concat 1348 (concat
1342 (buffer-substring (point-min) (mail-header-end)) 1349 (buffer-substring (point-min) (mh-mail-header-end))
1343 "\n" 1350 "\n"
1344 (buffer-substring (region-beginning) (region-end)))) 1351 (buffer-substring (region-beginning) (region-end))))
1345 (yank-region 1352 (yank-region
@@ -1472,6 +1479,33 @@ This is useful in breaking up paragraphs in replies."
1472 (insert " ")) 1479 (insert " "))
1473 (forward-line -1)))) 1480 (forward-line -1))))
1474 1481
1482(mh-do-in-xemacs (defvar mail-abbrevs))
1483
1484(defun mh-folder-expand-at-point ()
1485 "Do folder name completion in Fcc header field."
1486 (let* ((end (point))
1487 (syntax-table (syntax-table))
1488 (beg (unwind-protect
1489 (save-excursion
1490 (mh-funcall-if-exists mail-abbrev-make-syntax-table)
1491 (set-syntax-table mail-abbrev-syntax-table)
1492 (backward-word 1)
1493 (point))
1494 (set-syntax-table syntax-table)))
1495 (folder (buffer-substring beg end))
1496 (leading-plus (and (> (length folder) 0) (equal (aref folder 0) ?+)))
1497 (last-slash (mh-search-from-end ?/ folder))
1498 (prefix (and last-slash (substring folder 0 last-slash)))
1499 (mail-abbrevs
1500 (mapcar #'(lambda (x)
1501 (list (cond (prefix (format "%s/%s" prefix x))
1502 (leading-plus (format "+%s" x))
1503 (t x))))
1504 (mh-folder-completion-function folder nil t))))
1505 (if (fboundp 'mail-abbrev-complete-alias)
1506 (mh-funcall-if-exists mail-abbrev-complete-alias)
1507 (error "Fcc completion not supported in your version of Emacs"))))
1508
1475;;;###mh-autoload 1509;;;###mh-autoload
1476(defun mh-letter-complete (arg) 1510(defun mh-letter-complete (arg)
1477 "Perform completion on header field or word preceding point. 1511 "Perform completion on header field or word preceding point.
@@ -1480,12 +1514,19 @@ by the function designated by `mh-letter-complete-function' elsewhere,
1480passing the prefix ARG if any." 1514passing the prefix ARG if any."
1481 (interactive "P") 1515 (interactive "P")
1482 (let ((case-fold-search t)) 1516 (let ((case-fold-search t))
1483 (if (and (mh-in-header-p) 1517 (cond
1484 (save-excursion 1518 ((and (mh-in-header-p)
1485 (mh-header-field-beginning) 1519 (save-excursion
1486 (looking-at "^.*\\(to\\|cc\\|from\\):"))) 1520 (mh-header-field-beginning)
1487 (mh-alias-letter-expand-alias) 1521 (looking-at "^fcc:")))
1488 (funcall mh-letter-complete-function arg)))) 1522 (mh-folder-expand-at-point))
1523 ((and (mh-in-header-p)
1524 (save-excursion
1525 (mh-header-field-beginning)
1526 (looking-at "^.*\\(to\\|cc\\|from\\):")))
1527 (mh-alias-letter-expand-alias))
1528 (t
1529 (funcall mh-letter-complete-function arg)))))
1489 1530
1490;;; Build the letter-mode keymap: 1531;;; Build the letter-mode keymap:
1491;;; If this changes, modify mh-letter-mode-help-messages accordingly, above. 1532;;; If this changes, modify mh-letter-mode-help-messages accordingly, above.
@@ -1532,6 +1573,8 @@ passing the prefix ARG if any."
1532 1573
1533;; "C-c /" prefix is used in mh-letter-mode by pgp.el and mailcrypt.el. 1574;; "C-c /" prefix is used in mh-letter-mode by pgp.el and mailcrypt.el.
1534 1575
1576;;;###autoload(add-to-list 'auto-mode-alist '("/drafts/[0-9]+\\'" . mh-letter-mode))
1577
1535(provide 'mh-comp) 1578(provide 'mh-comp)
1536 1579
1537;;; Local Variables: 1580;;; Local Variables:
diff --git a/lisp/mh-e/mh-customize.el b/lisp/mh-e/mh-customize.el
index 566fbf60a7c..12f024eefec 100644
--- a/lisp/mh-e/mh-customize.el
+++ b/lisp/mh-e/mh-customize.el
@@ -1,6 +1,6 @@
1;;; mh-customize.el --- MH-E customization 1;;; mh-customize.el --- MH-E customization
2 2
3;; Copyright (C) 2002 Free Software Foundation, Inc. 3;; Copyright (C) 2002, 2003 Free Software Foundation, Inc.
4 4
5;; Author: Bill Wohler <wohler@newt.com> 5;; Author: Bill Wohler <wohler@newt.com>
6;; Maintainer: Bill Wohler <wohler@newt.com> 6;; Maintainer: Bill Wohler <wohler@newt.com>
@@ -26,9 +26,9 @@
26 26
27;;; Commentary: 27;;; Commentary:
28 28
29;; All of the defgroups, defcustoms, and deffaces in MH-E are found here. This 29;; All of the defgroups, defcustoms, and deffaces in MH-E are found
30;; makes it possible to customize modules that aren't loaded yet. It also 30;; here. This makes it possible to customize modules that aren't loaded
31;; makes it easier to organize the customization groups. 31;; yet. It also makes it easier to organize the customization groups.
32 32
33;; This file contains the following sections: 33;; This file contains the following sections:
34;; 34;;
@@ -55,8 +55,6 @@
55 55
56;;; Change Log: 56;;; Change Log:
57 57
58;; $Id: mh-customize.el,v 1.2 2003/02/03 20:55:30 wohler Exp $
59
60;;; Code: 58;;; Code:
61(provide 'mh-customize) 59(provide 'mh-customize)
62(require 'mh-e) 60(require 'mh-e)
@@ -95,12 +93,31 @@ are removed."
95 :link '(custom-manual "(mh-e)Customizing Moving Mail") 93 :link '(custom-manual "(mh-e)Customizing Moving Mail")
96 :group 'mh) 94 :group 'mh)
97 95
96(defgroup mh-index nil
97 "Indexed searching."
98 :link '(custom-manual "(mh-e)Customizing mh-e")
99 :prefix "mh-"
100 :group 'mh)
101
102(defgroup mh-junk nil
103 "Spam handling."
104 :link '(custom-manual "(mh-e)Customizing mh-e")
105 :prefix "mh-junk-"
106 :group 'mh)
107
98(defgroup mh-show nil 108(defgroup mh-show nil
99 "Message display." 109 "Message display."
100 :prefix "mh-" 110 :prefix "mh-"
101 :link '(custom-manual "(mh-e)Customizing Reading") 111 :link '(custom-manual "(mh-e)Customizing Reading")
102 :group 'mh) 112 :group 'mh)
103 113
114(defgroup mh-faces nil
115 "Faces used in MH-E."
116 :link '(custom-manual "(mh-e)Customizing mh-e")
117 :prefix "mh-"
118 :group 'faces
119 :group 'mh)
120
104(defgroup mh-letter nil 121(defgroup mh-letter nil
105 "Composing messages." 122 "Composing messages."
106 :prefix "mh-" 123 :prefix "mh-"
@@ -113,25 +130,12 @@ are removed."
113 :prefix "mh-alias-" 130 :prefix "mh-alias-"
114 :group 'mh) 131 :group 'mh)
115 132
116(defgroup mh-index nil
117 "Indexed searching."
118 :link '(custom-manual "(mh-e)Customizing mh-e")
119 :prefix "mh-"
120 :group 'mh)
121
122(defgroup mh-identity nil 133(defgroup mh-identity nil
123 "Multiple personalities." 134 "Multiple personalities."
124 :link '(custom-manual "(mh-e)Customizing mh-e") 135 :link '(custom-manual "(mh-e)Customizing mh-e")
125 :prefix "mh-" 136 :prefix "mh-"
126 :group 'mh) 137 :group 'mh)
127 138
128(defgroup mh-faces nil
129 "Faces used in MH-E."
130 :link '(custom-manual "(mh-e)Customizing mh-e")
131 :prefix "mh-"
132 :group 'faces
133 :group 'mh)
134
135(defgroup mh-hooks nil 139(defgroup mh-hooks nil
136 "MH-E hooks." 140 "MH-E hooks."
137 :link '(custom-manual "(mh-e)Customizing mh-e") 141 :link '(custom-manual "(mh-e)Customizing mh-e")
@@ -174,52 +178,6 @@ are removed."
174 178
175;;; Toolbar configuration (:group 'mh-toolbar) 179;;; Toolbar configuration (:group 'mh-toolbar)
176 180
177(defconst mh-tool-bar-item-inc "Incorporate new mail in Inbox")
178(defconst mh-tool-bar-item-save-mime "Save MIME parts")
179(defconst mh-tool-bar-item-prev-msg "Previous message")
180(defconst mh-tool-bar-item-page-msg "Page this message")
181(defconst mh-tool-bar-item-next-msg "Next message")
182(defconst mh-tool-bar-item-delete "Mark for deletion")
183(defconst mh-tool-bar-item-refile "Refile this message")
184(defconst mh-tool-bar-item-undo "Undo this mark")
185(defconst mh-tool-bar-item-perform "Perform moves and deletes")
186(defconst mh-tool-bar-item-toggle-show "Toggle showing message")
187(defconst mh-tool-bar-item-reply-from "Reply to \"from\"")
188(defconst mh-tool-bar-item-reply-to "Reply to \"to\"")
189(defconst mh-tool-bar-item-reply-all "Reply to \"all\"")
190(defconst mh-tool-bar-item-reply "Reply to this message")
191(defconst mh-tool-bar-item-alias "Grab From alias")
192(defconst mh-tool-bar-item-compose "Compose new message")
193(defconst mh-tool-bar-item-rescan "Rescan this folder")
194(defconst mh-tool-bar-item-repack "Repack this folder")
195(defconst mh-tool-bar-item-search "Search")
196(defconst mh-tool-bar-item-visit "Visit other folder")
197(defconst mh-tool-bar-item-prefs "MH-E preferences")
198(defconst mh-tool-bar-item-help "Help")
199(defconst mh-tool-bar-item-widen "Widen from this sequence")
200
201(defconst mh-tool-bar-item-send "Send this letter")
202(defconst mh-tool-bar-item-attach "Insert attachment")
203(defconst mh-tool-bar-item-spell "Check spelling")
204(defconst mh-tool-bar-item-save "Save current buffer to its file")
205(defconst mh-tool-bar-item-undo-op "Undo last operation")
206(defconst mh-tool-bar-item-kill
207 "Cut (kill) text in region between mark and current position")
208(defconst mh-tool-bar-item-copy
209 "Copy text in region between mark and current position")
210(defconst mh-tool-bar-item-paste
211 "Paste (yank) text cut or copied earlier")
212(defconst mh-tool-bar-item-kill-draft "Kill this draft")
213(defconst mh-tool-bar-item-comp-prefs "MH-E composition preferences")
214
215(defcustom mh-tool-bar-reply-3-buttons-flag nil
216 "*Non-nil means use three buttons for reply commands in tool-bar.
217If you have room on your tool-bar because you are using a large font, you
218may set this variable to expand the single reply button into three buttons
219that won't lead to minibuffer prompt about who to reply to."
220 :type 'boolean
221 :group 'mh-toolbar)
222
223(defcustom mh-tool-bar-search-function 'mh-search-folder 181(defcustom mh-tool-bar-search-function 'mh-search-folder
224 "*Function called by the tool-bar search button. 182 "*Function called by the tool-bar search button.
225See `mh-search-folder' and `mh-index-search' for details." 183See `mh-search-folder' and `mh-index-search' for details."
@@ -228,389 +186,393 @@ See `mh-search-folder' and `mh-index-search' for details."
228 (function :tag "Other function")) 186 (function :tag "Other function"))
229 :group 'mh-toolbar) 187 :group 'mh-toolbar)
230 188
231(eval-when-compile (defvar tool-bar-map)) 189;; Functions called from the tool bar
232(defvar mh-show-tool-bar-map nil) 190(defun mh-tool-bar-search (&optional arg)
233(defun mh-tool-bar-show-set () 191 "Interactively call `mh-tool-bar-search-function'.
234 "Construct toolbar for `mh-show-mode'." 192Optional argument ARG is not used."
235 (when (fboundp 'tool-bar-add-item) 193 (interactive "P")
236 (setq 194 (call-interactively mh-tool-bar-search-function))
237 mh-show-tool-bar-map 195
238 (let ((tool-bar-map (make-sparse-keymap))) 196(defun mh-tool-bar-customize ()
239 (if (member mh-tool-bar-item-inc mh-tool-bar-folder-buttons) 197 "Call `mh-customize' from the toolbar."
240 (tool-bar-add-item "mail" 'mh-inc-folder 'mh-showtoolbar-inc-folder 198 (interactive)
241 :help mh-tool-bar-item-inc)) 199 (mh-customize t))
242 (if (member mh-tool-bar-item-save-mime mh-tool-bar-folder-buttons) 200
243 (tool-bar-add-item "attach" 'mh-mime-save-parts 201(defun mh-tool-bar-folder-help ()
244 'mh-showtoolbar-mime-save-parts 202 "Visit \"(mh-e)Top\"."
245 :help mh-tool-bar-item-save-mime)) 203 (interactive)
246 (if (member mh-tool-bar-item-prev-msg mh-tool-bar-folder-buttons) 204 (Info-goto-node "(mh-e)Top")
247 (tool-bar-add-item "left_arrow" 'mh-show-previous-undeleted-msg 205 (delete-other-windows))
248 'mh-showtoolbar-prev 206
249 :help mh-tool-bar-item-prev-msg)) 207(defun mh-tool-bar-letter-help ()
250 (if (member mh-tool-bar-item-page-msg mh-tool-bar-folder-buttons) 208 "Visit \"(mh-e)Draft Editing\"."
251 (tool-bar-add-item "page-down" 'mh-show-page-msg 'mh-showtoolbar-page 209 (interactive)
252 :help mh-tool-bar-item-page-msg)) 210 (Info-goto-node "(mh-e)Draft Editing")
253 (if (member mh-tool-bar-item-next-msg mh-tool-bar-folder-buttons) 211 (delete-other-windows))
254 (tool-bar-add-item "right_arrow" 'mh-show-next-undeleted-msg 212
255 'mh-showtoolbar-next 213(defmacro mh-tool-bar-reply-generator (function recipient folder-buffer-flag)
256 :help mh-tool-bar-item-next-msg)) 214 "Generate FUNCTION that replies to RECIPIENT.
257 (if (member mh-tool-bar-item-delete mh-tool-bar-folder-buttons) 215If FOLDER-BUFFER-FLAG is nil then the function generated
258 (tool-bar-add-item "close" 'mh-show-delete-msg 216When INCLUDE-FLAG is non-nil, include message body being replied to."
259 'mh-showtoolbar-delete 217 `(defun ,function (&optional arg)
260 :help mh-tool-bar-item-delete)) 218 ,(format "Reply to \"%s\".\nWhen ARG is non-nil include message in reply."
261 (if (member mh-tool-bar-item-refile mh-tool-bar-folder-buttons) 219 recipient)
262 (tool-bar-add-item "refile" 'mh-show-refile-msg 220 (interactive "P")
263 'mh-showtoolbar-refile 221 ,(if folder-buffer-flag nil '(set-buffer mh-show-folder-buffer))
264 :help mh-tool-bar-item-refile)) 222 (mh-reply (mh-get-msg-num nil) ,recipient arg)))
265 (if (member mh-tool-bar-item-undo mh-tool-bar-folder-buttons) 223
266 (tool-bar-add-item "undo" 'mh-show-undo 'mh-showtoolbar-undo 224(mh-tool-bar-reply-generator mh-tool-bar-reply-from "from" t)
267 :help mh-tool-bar-item-undo)) 225(mh-tool-bar-reply-generator mh-show-tool-bar-reply-from "from" nil)
268 (if (member mh-tool-bar-item-perform mh-tool-bar-folder-buttons) 226(mh-tool-bar-reply-generator mh-tool-bar-reply-to "to" t)
269 (tool-bar-add-item "execute" 'mh-show-execute-commands 227(mh-tool-bar-reply-generator mh-show-tool-bar-reply-to "to" nil)
270 'mh-showtoolbar-exec 228(mh-tool-bar-reply-generator mh-tool-bar-reply-all "all" t)
271 :help mh-tool-bar-item-perform)) 229(mh-tool-bar-reply-generator mh-show-tool-bar-reply-all "all" nil)
272 (if (member mh-tool-bar-item-toggle-show mh-tool-bar-folder-buttons) 230
273 (tool-bar-add-item "show" 'mh-show-toggle-showing 231;; XEmacs has a couple of extra customizations...
274 'mh-showtoolbar-toggle-show 232(mh-do-in-xemacs
275 :help mh-tool-bar-item-toggle-show)) 233 (require 'mh-xemacs-icons)
276 (if (member mh-tool-bar-item-reply-from mh-tool-bar-folder-buttons) 234 (defcustom mh-xemacs-use-toolbar-flag (if (and (featurep 'toolbar)
277 (tool-bar-add-item "reply-from" 235 (featurep 'xpm)
278 (lambda (&optional arg) 236 (device-on-window-system-p))
279 (interactive "P") 237 t
280 (set-buffer mh-show-folder-buffer) 238 nil)
281 (mh-reply (mh-get-msg-num nil) "from" arg)) 239 "*If non-nil, use toolbar.
282 'mh-showtoolbar-reply-from 240
283 :help mh-tool-bar-item-reply-from)) 241This will default to t if you are in an environment that supports
284 (if (member mh-tool-bar-item-reply-to mh-tool-bar-folder-buttons) 242toolbars and xpm."
285 (tool-bar-add-item "reply-to" 243 :type 'boolean
286 (lambda (&optional arg) 244 :group 'mh-toolbar)
287 (interactive "P") 245
288 (set-buffer mh-show-folder-buffer) 246 (defcustom mh-xemacs-toolbar-position (if mh-xemacs-use-toolbar-flag
289 (mh-reply (mh-get-msg-num nil) "to" arg)) 247 'default
290 'mh-showtoolbar-reply-to 248 nil)
291 :help mh-tool-bar-item-reply-to)) 249 "*Where to put the toolbar.
292 (if (member mh-tool-bar-item-reply-all mh-tool-bar-folder-buttons) 250
293 (tool-bar-add-item "reply-all" 251Valid non-nil values are \"default\", \"top\", \"bottom\", \"left\",
294 (lambda (&optional arg) 252\"right\". These match the four edges of the frame, with \"default\"
295 (interactive "P") 253meaning \"use the same position as the default-toolbar\".
296 (set-buffer mh-show-folder-buffer) 254
297 (mh-reply (mh-get-msg-num nil) "all" arg)) 255A nil value means do not use a toolbar.
298 'mh-showtoolbar-reply-all 256
299 :help mh-tool-bar-item-reply-all)) 257If this variable is set to anything other than \"default\" and the
300 (if (member mh-tool-bar-item-reply mh-tool-bar-folder-buttons) 258default-toolbar has a different positional setting from the value of
301 (tool-bar-add-item "mail/reply2" 'mh-show-reply 259this variable, then two toolbars will be displayed. The MH-E toolbar
302 'mh-showtoolbar-reply 260and the default-toolbar."
303 :help mh-tool-bar-item-reply)) 261 :type '(radio (const :tag "Same position as the \"default-toolbar\""
304 (if (member mh-tool-bar-item-alias mh-tool-bar-folder-buttons) 262 :value default)
305 (tool-bar-add-item "alias" 'mh-alias-grab-from-field 263 (const :tag "Along the top edge of the frame"
306 'mh-showtoolbar-alias 264 :value top)
307 :help mh-tool-bar-item-alias 265 (const :tag "Along the bottom edge of the frame"
308 :enable '(mh-alias-from-has-no-alias-p))) 266 :value bottom)
309 (if (member mh-tool-bar-item-compose mh-tool-bar-folder-buttons) 267 (const :tag "Along the left edge of the frame"
310 (tool-bar-add-item "mail_compose" 'mh-send 'mh-showtoolbar-compose 268 :value left)
311 :help mh-tool-bar-item-compose)) 269 (const :tag "Along the right edge of the frame"
312 (if (member mh-tool-bar-item-rescan mh-tool-bar-folder-buttons) 270 :value right)
313 (tool-bar-add-item "rescan" 'mh-show-rescan-folder 271 (const :tag "Don't use a toolbar" nil))
314 'mh-showtoolbar-rescan 272 :group 'mh-toolbar))
315 :help mh-tool-bar-item-rescan)) 273
316 (if (member mh-tool-bar-item-repack mh-tool-bar-folder-buttons) 274(defmacro mh-tool-bar-define (defaults &rest buttons)
317 (tool-bar-add-item "repack" 'mh-show-pack-folder 275 "Define a tool bar for MH-E.
318 'mh-showtoolbar-pack 276DEFAULTS is the list of buttons that are present by default. It is a list of
319 :help mh-tool-bar-item-repack)) 277lists where the sublists are of the following form:
320 (if (member mh-tool-bar-item-search mh-tool-bar-folder-buttons) 278
321 (tool-bar-add-item "search" 279 (:KEYWORD FUNC1 FUNC2 FUNC3 ...)
322 (lambda (&optional arg) 280
323 (interactive "P") 281Here :KEYWORD is one of :folder or :letter. If it is :folder then the default
324 (call-interactively 282buttons in the folder and show mode buffers are being specified. If it is
325 mh-tool-bar-search-function)) 283:letter then the default buttons in the letter mode are listed. FUNC1, FUNC2,
326 'mh-showtoolbar-search 284FUNC3, ... are the names of the functions that the buttons would execute.
327 :help mh-tool-bar-item-search)) 285
328 (if (member mh-tool-bar-item-visit mh-tool-bar-folder-buttons) 286Each element of BUTTONS is a list of four things:
329 (tool-bar-add-item "fld_open" 'mh-visit-folder 287
330 'mh-showtoolbar-visit 288 (FUNCTION MODES ICON DOC)
331 :help mh-tool-bar-item-visit)) 289
332 (if (member mh-tool-bar-item-prefs mh-tool-bar-folder-buttons) 290where,
333 (tool-bar-add-item "preferences" (lambda () 291
334 (interactive) 292 FUNCTION is the name of the function that will be executed when the button
335 (mh-customize t)) 293 is clicked.
336 'mh-showtoolbar-customize 294
337 :help mh-tool-bar-item-prefs)) 295 MODES is a list of symbols. List elements must be from `folder', `letter' and
338 (if (member mh-tool-bar-item-help mh-tool-bar-folder-buttons) 296 `sequence'. If `folder' is present then the button is available in the
339 (tool-bar-add-item "help" (lambda () 297 folder and show buffer. If the name of FUNCTION is of the form \"mh-foo\",
340 (interactive) 298 where foo is some arbitrary string, then we check if the function
341 (Info-goto-node "(mh-e)Top") 299 `mh-show-foo' exists. If it exists then that function is used in the show
342 (delete-other-windows)) 300 buffer. Otherwise the original function `mh-foo' is used in the show buffer
343 'mh-showtoolbar-help 301 as well. Presence of `sequence' is handled similar to the above. The only
344 :help mh-tool-bar-item-help)) 302 difference is that the button is shown only when the folder is narrowed to a
345 tool-bar-map)))) 303 sequence. If `letter' is present in MODES, then the button is available
346 304 during draft editing and runs FUNCTION when clicked.
347(defvar mh-letter-tool-bar-map nil) 305
348;;;###mh-autoload 306 ICON is the icon that is drawn in the button.
349(defun mh-tool-bar-letter-set () 307
350 "Construct toolbar for `mh-letter-mode'." 308 DOC is the documentation for the button. It is used in tool-tips and in
351 (when (fboundp 'tool-bar-add-item) 309 providing other help to the user. GNU Emacs uses only the first line of the
352 (setq 310 string. So the DOC should be formatted such that the first line is useful and
353 mh-letter-tool-bar-map 311 complete without the rest of the string."
354 (let ((tool-bar-map (make-sparse-keymap))) 312 ;; The following variable names have been carefully chosen to make code
355 (if (member mh-tool-bar-item-send mh-tool-bar-letter-buttons) 313 ;; generation easier. Modifying the names should be done carefully.
356 (tool-bar-add-item "mail_send" 'mh-send-letter 314 (let (folder-buttons folder-docs folder-button-setter sequence-button-setter
357 'mh-lettertoolbar-send 315 show-buttons show-button-setter show-seq-button-setter
358 :help mh-tool-bar-item-send)) 316 letter-buttons letter-docs letter-button-setter
359 (if (member mh-tool-bar-item-attach mh-tool-bar-letter-buttons) 317 folder-defaults letter-defaults
360 (tool-bar-add-item "attach" 'mh-compose-insertion 318 folder-vectors show-vectors letter-vectors)
361 'mh-lettertoolbar-compose 319 (dolist (x defaults)
362 :help mh-tool-bar-item-attach)) 320 (cond ((eq (car x) :folder) (setq folder-defaults (cdr x)))
363 (if (member mh-tool-bar-item-spell mh-tool-bar-letter-buttons) 321 ((eq (car x) :letter) (setq letter-defaults (cdr x)))))
364 (tool-bar-add-item "spell" 'ispell-message 'mh-lettertoolbar-ispell 322 (dolist (button buttons)
365 :help mh-tool-bar-item-spell)) 323 (unless (and (listp button) (equal (length button) 4))
366 (if (member mh-tool-bar-item-save mh-tool-bar-letter-buttons) 324 (error "Incorrect MH-E tool-bar button specification: %s" button))
367 (tool-bar-add-item-from-menu 'save-buffer "save")) 325 (let* ((name (nth 0 button))
368 (if (member mh-tool-bar-item-undo-op mh-tool-bar-letter-buttons) 326 (name-str (symbol-name name))
369 (tool-bar-add-item-from-menu 'undo "undo")) 327 (icon (nth 2 button))
370 (if (member mh-tool-bar-item-kill mh-tool-bar-letter-buttons) 328 (xemacs-icon (mh-do-in-xemacs
371 (tool-bar-add-item-from-menu 'kill-region "cut")) 329 (cdr (assoc (intern icon) mh-xemacs-icon-map))))
372 (if (member mh-tool-bar-item-copy mh-tool-bar-letter-buttons) 330 (full-doc (nth 3 button))
373 (tool-bar-add-item-from-menu 'menu-bar-kill-ring-save "copy")) 331 (doc (if (string-match "\\(.*\\)\n" full-doc)
374 (if (member mh-tool-bar-item-paste mh-tool-bar-letter-buttons) 332 (match-string 1 full-doc)
375 (tool-bar-add-item-from-menu 'yank "paste")) 333 full-doc))
376 (if (member mh-tool-bar-item-kill-draft mh-tool-bar-letter-buttons) 334 (modes (nth 1 button))
377 (tool-bar-add-item "close" 'mh-fully-kill-draft 335 functions show-sym)
378 'mh-lettertoolbar-kill 336 (when (memq 'letter modes) (setq functions `(:letter ,name)))
379 :help mh-tool-bar-item-kill-draft)) 337 (when (or (memq 'folder modes) (memq 'sequence modes))
380 (if (member mh-tool-bar-item-comp-prefs mh-tool-bar-letter-buttons) 338 (setq functions
381 (tool-bar-add-item "preferences" (lambda () 339 (append `(,(if (memq 'folder modes) :folder :sequence) ,name)
382 (interactive) 340 functions))
383 (mh-customize t)) 341 (setq show-sym
384 'mh-lettertoolbar-customize 342 (if (string-match "^mh-\\(.*\\)$" name-str)
385 :help mh-tool-bar-item-comp-prefs)) 343 (intern (concat "mh-show-" (match-string 1 name-str)))
386 (if (member mh-tool-bar-item-help mh-tool-bar-letter-buttons) 344 name))
387 (tool-bar-add-item "help" (lambda () 345 (setq functions
388 (interactive) 346 (append `(,(if (memq 'folder modes) :show :show-seq)
389 (Info-goto-node "(mh-e)Draft Editing") 347 ,(if (fboundp show-sym) show-sym name))
390 (delete-other-windows)) 348 functions)))
391 'mh-lettertoolbar-help 349 (do ((functions functions (cddr functions)))
392 :help mh-tool-bar-item-help)) 350 ((null functions))
393 tool-bar-map)))) 351 (let* ((type (car functions))
394 352 (function (cadr functions))
395(defvar mh-folder-tool-bar-map nil) 353 (type1 (substring (symbol-name type) 1))
396(defvar mh-folder-seq-tool-bar-map nil 354 (vector-list (cond ((eq type :show) 'show-vectors)
397 "Tool-bar to use when narrowed to a sequence in MH-Folder buffers.") 355 ((eq type :show-seq) 'show-vectors)
398;;;###mh-autoload 356 ((eq type :letter) 'letter-vectors)
399(defun mh-tool-bar-folder-set () 357 (t 'folder-vectors)))
400 "Construct toolbar for `mh-folder-mode'." 358 (list (cond ((eq type :letter) 'mh-tool-bar-letter-buttons)
401 (when (fboundp 'tool-bar-add-item) 359 (t 'mh-tool-bar-folder-buttons)))
402 (setq 360 (key (intern (concat "mh-" type1 "toolbar-" name-str)))
403 mh-folder-tool-bar-map 361 (setter (intern (concat type1 "-button-setter")))
404 (let ((tool-bar-map (make-sparse-keymap))) 362 (mbuttons (cond ((eq type :letter) 'letter-buttons)
405 (if (member mh-tool-bar-item-inc mh-tool-bar-folder-buttons) 363 ((eq type :show) 'show-buttons)
406 (tool-bar-add-item "mail" 'mh-inc-folder 364 ((eq type :show-seq) 'show-buttons)
407 'mh-foldertoolbar-inc-folder 365 (t 'folder-buttons)))
408 :help mh-tool-bar-item-inc)) 366 (docs (cond ((eq mbuttons 'letter-buttons) 'letter-docs)
409 (if (member mh-tool-bar-item-save-mime mh-tool-bar-folder-buttons) 367 ((eq mbuttons 'folder-buttons) 'folder-docs))))
410 (tool-bar-add-item "attach" 'mh-mime-save-parts 368 (add-to-list vector-list `[,xemacs-icon ,function t ,full-doc])
411 'mh-foldertoolbar-mime-save-parts 369 (add-to-list
412 :help mh-tool-bar-item-save-mime)) 370 setter `(when (member ',name ,list)
413 (if (member mh-tool-bar-item-prev-msg mh-tool-bar-folder-buttons) 371 (mh-funcall-if-exists
414 (tool-bar-add-item "left_arrow" 'mh-previous-undeleted-msg 372 tool-bar-add-item ,icon ',function ',key :help ,doc)))
415 'mh-foldertoolbar-prev 373 (add-to-list mbuttons name)
416 :help mh-tool-bar-item-prev-msg)) 374 (if docs (add-to-list docs doc))))))
417 (if (member mh-tool-bar-item-page-msg mh-tool-bar-folder-buttons) 375 (setq folder-buttons (nreverse folder-buttons)
418 (tool-bar-add-item "page-down" 'mh-page-msg 'mh-foldertoolbar-page 376 letter-buttons (nreverse letter-buttons)
419 :help mh-tool-bar-item-page-msg)) 377 show-buttons (nreverse show-buttons)
420 (if (member mh-tool-bar-item-next-msg mh-tool-bar-folder-buttons) 378 letter-docs (nreverse letter-docs)
421 (tool-bar-add-item "right_arrow" 'mh-next-undeleted-msg 379 folder-docs (nreverse folder-docs)
422 'mh-foldertoolbar-next 380 folder-vectors (nreverse folder-vectors)
423 :help mh-tool-bar-item-next-msg)) 381 show-vectors (nreverse show-vectors)
424 (if (member mh-tool-bar-item-delete mh-tool-bar-folder-buttons) 382 letter-vectors (nreverse letter-vectors))
425 (tool-bar-add-item "close" 'mh-delete-msg 'mh-foldertoolbar-delete 383 (dolist (x folder-defaults)
426 :help mh-tool-bar-item-delete)) 384 (unless (memq x folder-buttons)
427 (if (member mh-tool-bar-item-refile mh-tool-bar-folder-buttons) 385 (error "Folder defaults contains unknown button '%s'" x)))
428 (tool-bar-add-item "refile" 'mh-refile-msg 'mh-foldertoolbar-refile 386 (dolist (x letter-defaults)
429 :help mh-tool-bar-item-refile)) 387 (unless (memq x letter-buttons)
430 (if (member mh-tool-bar-item-undo mh-tool-bar-folder-buttons) 388 (error "Letter defaults contains unknown button '%s'" x)))
431 (tool-bar-add-item "undo" 'mh-undo 'mh-foldertoolbar-undo 389 `(eval-when (compile load eval)
432 :help mh-tool-bar-item-undo)) 390 (defvar mh-folder-tool-bar-map nil)
433 (if (member mh-tool-bar-item-perform mh-tool-bar-folder-buttons) 391 (defvar mh-folder-seq-tool-bar-map nil)
434 (tool-bar-add-item "execute" 'mh-execute-commands 392 (defvar mh-show-tool-bar-map nil)
435 'mh-foldertoolbar-exec 393 (defvar mh-show-seq-tool-bar-map nil)
436 :help mh-tool-bar-item-perform)) 394 (defvar mh-letter-tool-bar-map nil)
437 (if (member mh-tool-bar-item-toggle-show mh-tool-bar-folder-buttons) 395 ;; GNU Emacs tool bar specific code
438 (tool-bar-add-item "show" 'mh-toggle-showing 396 (mh-do-in-gnu-emacs
439 'mh-foldertoolbar-toggle-show 397 ;; Custom setter functions
440 :help mh-tool-bar-item-toggle-show)) 398 (defun mh-tool-bar-folder-buttons-set (symbol value)
441 (if (member mh-tool-bar-item-reply-from mh-tool-bar-folder-buttons) 399 "Construct toolbar for `mh-folder-mode' and `mh-show-mode'."
442 (tool-bar-add-item "reply-from" 400 (set-default symbol value)
443 (lambda (&optional arg) 401 (setq mh-folder-tool-bar-map
444 (interactive "P") 402 (let ((tool-bar-map (make-sparse-keymap)))
445 (mh-reply (mh-get-msg-num nil) "from" arg)) 403 ,@(nreverse folder-button-setter)
446 'mh-foldertoolbar-reply-from 404 tool-bar-map))
447 :help mh-tool-bar-item-reply-from)) 405 (setq mh-show-tool-bar-map
448 (if (member mh-tool-bar-item-reply-to mh-tool-bar-folder-buttons) 406 (let ((tool-bar-map (make-sparse-keymap)))
449 (tool-bar-add-item "reply-to" 407 ,@(nreverse show-button-setter)
450 (lambda (&optional arg) 408 tool-bar-map))
451 (interactive "P") 409 (setq mh-show-seq-tool-bar-map
452 (mh-reply (mh-get-msg-num nil) "to" arg)) 410 (let ((tool-bar-map (copy-keymap mh-show-tool-bar-map)))
453 'mh-foldertoolbar-reply-to 411 ,@(nreverse show-seq-button-setter)
454 :help mh-tool-bar-item-reply-to)) 412 tool-bar-map))
455 (if (member mh-tool-bar-item-reply-all mh-tool-bar-folder-buttons) 413 (setq mh-folder-seq-tool-bar-map
456 (tool-bar-add-item "reply-all" 414 (let ((tool-bar-map (copy-keymap mh-folder-tool-bar-map)))
457 (lambda (&optional arg) 415 ,@(nreverse sequence-button-setter)
458 (interactive "P") 416 tool-bar-map)))
459 (mh-reply (mh-get-msg-num nil) "all" arg)) 417 (defun mh-tool-bar-letter-buttons-set (symbol value)
460 'mh-foldertoolbar-reply-all 418 "Construct toolbar for `mh-letter-mode'."
461 :help mh-tool-bar-item-reply-all)) 419 (set-default symbol value)
462 (if (member mh-tool-bar-item-reply mh-tool-bar-folder-buttons) 420 (setq mh-letter-tool-bar-map
463 (tool-bar-add-item "mail/reply2" 'mh-reply 421 (let ((tool-bar-map (make-sparse-keymap)))
464 'mh-foldertoolbar-reply 422 ,@(nreverse letter-button-setter)
465 :help mh-tool-bar-item-reply)) 423 tool-bar-map))))
466 (if (member mh-tool-bar-item-alias mh-tool-bar-folder-buttons) 424 ;; XEmacs specific code
467 (tool-bar-add-item "alias" 'mh-alias-grab-from-field 425 (mh-do-in-xemacs
468 'mh-foldertoolbar-alias 426 (defvar mh-toolbar-folder-vector-map
469 :help mh-tool-bar-item-alias 427 ',(loop for button in folder-buttons
470 :enable '(mh-alias-from-has-no-alias-p))) 428 for vector in folder-vectors
471 (if (member mh-tool-bar-item-compose mh-tool-bar-folder-buttons) 429 collect (cons button vector)))
472 (tool-bar-add-item "mail_compose" 'mh-send 'mh-foldertoolbar-compose 430 (defvar mh-toolbar-show-vector-map
473 :help mh-tool-bar-item-compose)) 431 ',(loop for button in show-buttons
474 (if (member mh-tool-bar-item-rescan mh-tool-bar-folder-buttons) 432 for vector in show-vectors
475 (tool-bar-add-item "rescan" 'mh-rescan-folder 433 collect (cons button vector)))
476 'mh-foldertoolbar-rescan 434 (defvar mh-toolbar-letter-vector-map
477 :help mh-tool-bar-item-rescan)) 435 ',(loop for button in letter-buttons
478 (if (member mh-tool-bar-item-repack mh-tool-bar-folder-buttons) 436 for vector in letter-vectors
479 (tool-bar-add-item "repack" 'mh-pack-folder 'mh-foldertoolbar-pack 437 collect (cons button vector)))
480 :help mh-tool-bar-item-repack)) 438 (defvar mh-toolbar-folder-buttons nil)
481 (if (member mh-tool-bar-item-search mh-tool-bar-folder-buttons) 439 (defvar mh-toolbar-show-buttons nil)
482 (tool-bar-add-item "search" 440 (defvar mh-toolbar-letter-buttons nil)
483 (lambda (&optional arg) 441 ;; Custom setter functions
484 (interactive "P") 442 (defun mh-tool-bar-letter-buttons-set (symbol value)
485 (call-interactively 443 (set-default symbol value)
486 mh-tool-bar-search-function)) 444 (setq mh-toolbar-letter-buttons
487 'mh-foldertoolbar-search 445 (loop for b in value
488 :help mh-tool-bar-item-search)) 446 collect (cdr (assoc b mh-toolbar-letter-vector-map)))))
489 (if (member mh-tool-bar-item-visit mh-tool-bar-folder-buttons) 447 (defun mh-tool-bar-folder-buttons-set (symbol value)
490 (tool-bar-add-item "fld_open" 'mh-visit-folder 448 (set-default symbol value)
491 'mh-foldertoolbar-visit 449 (setq mh-toolbar-folder-buttons
492 :help mh-tool-bar-item-visit)) 450 (loop for b in value
493 (if (member mh-tool-bar-item-prefs mh-tool-bar-folder-buttons) 451 collect (cdr (assoc b mh-toolbar-folder-vector-map))))
494 (tool-bar-add-item "preferences" (lambda () 452 (setq mh-toolbar-show-buttons
495 (interactive) 453 (loop for b in value
496 (mh-customize t)) 454 collect (cdr (assoc b mh-toolbar-show-vector-map)))))
497 'mh-foldertoolbar-customize 455 ;; Initialize toolbar
498 :help mh-tool-bar-item-prefs)) 456 (defun mh-toolbar-init (mode)
499 (if (member mh-tool-bar-item-help mh-tool-bar-folder-buttons) 457 "Install toolbar in MODE."
500 (tool-bar-add-item "help" (lambda () 458 (let ((toolbar (cond ((eq mode :folder) mh-toolbar-folder-buttons)
501 (interactive) 459 ((eq mode :letter) mh-toolbar-letter-buttons)
502 (Info-goto-node "(mh-e)Top") 460 ((eq mode :show) mh-toolbar-show-buttons)))
503 (delete-other-windows)) 461 (height 37)
504 'mh-foldertoolbar-help 462 (width 40)
505 :help mh-tool-bar-item-help)) 463 (buffer (current-buffer)))
506 tool-bar-map)) 464 (when (and mh-xemacs-toolbar-position mh-xemacs-use-toolbar-flag)
507 465 (cond
508 (setq mh-folder-seq-tool-bar-map 466 ((eq mh-xemacs-toolbar-position 'top)
509 (let ((tool-bar-map (copy-keymap mh-folder-tool-bar-map))) 467 (set-specifier top-toolbar (cons buffer toolbar))
510 (if (member mh-tool-bar-item-widen mh-tool-bar-folder-buttons) 468 (set-specifier top-toolbar-visible-p t)
511 (tool-bar-add-item "widen" 'mh-widen 'mh-foldertoolbar-widen 469 (set-specifier top-toolbar-height height))
512 :help mh-tool-bar-item-widen)) 470 ((eq mh-xemacs-toolbar-position 'bottom)
513 tool-bar-map)))) 471 (set-specifier bottom-toolbar (cons buffer toolbar))
514 472 (set-specifier bottom-toolbar-visible-p t)
515(defun mh-tool-bar-folder-buttons-set (symbol value) 473 (set-specifier bottom-toolbar-height height))
516 "Update the `mh-tool-bar-folder-buttons' variable, and rebuild the tool-bar. 474 ((eq mh-xemacs-toolbar-position 'left)
517Sets the default for SYMBOL (e.g. `mh-tool-bar-folder-buttons') to VALUE (as 475 (set-specifier left-toolbar (cons buffer toolbar))
518set in customization). This is called after 'customize is used to alter 476 (set-specifier left-toolbar-visible-p t)
519`mh-tool-bar-folder-buttons'." 477 (set-specifier left-toolbar-width width))
520 (set-default symbol value) 478 ((eq mh-xemacs-toolbar-position 'right)
521 (mh-tool-bar-show-set) 479 (set-specifier right-toolbar (cons buffer toolbar))
522 (mh-tool-bar-folder-set)) 480 (set-specifier right-toolbar-visible-p t)
523 481 (set-specifier right-toolbar-width width))
524(custom-declare-variable 482 (t (set-specifier default-toolbar (cons buffer toolbar))))))))
525 'mh-tool-bar-folder-buttons 483 ;; Declare customizable toolbars
526 '(append 484 (custom-declare-variable
527 (list mh-tool-bar-item-inc 485 'mh-tool-bar-folder-buttons
528 mh-tool-bar-item-save-mime 486 '(list ,@(mapcar (lambda (x) `(quote ,x)) folder-defaults))
529 mh-tool-bar-item-prev-msg 487 "Choose buttons to include in MH-E folder/show toolbar."
530 mh-tool-bar-item-page-msg 488 :group 'mh-toolbar :set 'mh-tool-bar-folder-buttons-set
531 mh-tool-bar-item-next-msg 489 :type '(set ,@(loop for x in folder-buttons
532 mh-tool-bar-item-delete 490 for y in folder-docs
533 mh-tool-bar-item-refile 491 collect `(const :tag ,y ,x))))
534 mh-tool-bar-item-undo 492 (custom-declare-variable
535 mh-tool-bar-item-perform 493 'mh-tool-bar-letter-buttons
536;;; mh-tool-bar-item-toggle-show 494 '(list ,@(mapcar (lambda (x) `(quote ,x)) letter-defaults))
537 ) 495 "Choose buttons to include in MH-E letter toolbar."
538 (if mh-tool-bar-reply-3-buttons-flag 496 :group 'mh-toolbar :set 'mh-tool-bar-letter-buttons-set
539 (list mh-tool-bar-item-reply-from 497 :type '(set ,@(loop for x in letter-buttons
540 mh-tool-bar-item-reply-to 498 for y in letter-docs
541 mh-tool-bar-item-reply-all) 499 collect `(const :tag ,y ,x)))))))
542 (list mh-tool-bar-item-reply)) 500
543 (list mh-tool-bar-item-alias 501(mh-tool-bar-define
544 mh-tool-bar-item-compose 502 ((:folder mh-inc-folder mh-mime-save-parts mh-previous-undeleted-msg
545 mh-tool-bar-item-rescan 503 mh-page-msg mh-next-undeleted-msg mh-delete-msg mh-refile-msg
546;;; mh-tool-bar-item-repack 504 mh-undo mh-execute-commands mh-toggle-tick mh-reply
547 mh-tool-bar-item-search 505 mh-alias-grab-from-field mh-send mh-rescan-folder
548 mh-tool-bar-item-visit 506 mh-tool-bar-search mh-visit-folder
549 mh-tool-bar-item-prefs 507 mh-tool-bar-customize mh-tool-bar-folder-help mh-widen)
550 mh-tool-bar-item-help 508 (:letter mh-send-letter mh-compose-insertion ispell-message save-buffer
551 mh-tool-bar-item-widen)) 509 undo kill-region menu-bar-kill-ring-save yank mh-fully-kill-draft
552 "Buttons to include in MH-E folder/show toolbar." 510 mh-tool-bar-customize mh-tool-bar-letter-help))
553 :group 'mh-toolbar 511 ;; Folder/Show buffer buttons
554 :set 'mh-tool-bar-folder-buttons-set 512 (mh-inc-folder (folder) "mail"
555 :type `(set (const ,mh-tool-bar-item-inc) 513 "Incorporate new mail in Inbox
556 (const ,mh-tool-bar-item-save-mime) 514This button runs `mh-inc-folder' which drags any
557 (const ,mh-tool-bar-item-prev-msg) 515new mail into your Inbox folder.")
558 (const ,mh-tool-bar-item-page-msg) 516 (mh-mime-save-parts (folder) "attach"
559 (const ,mh-tool-bar-item-next-msg) 517 "Save MIME parts from this message
560 (const ,mh-tool-bar-item-delete) 518This button runs `mh-mime-save-parts' which saves a message's
561 (const ,mh-tool-bar-item-refile) 519different parts into separate files.")
562 (const ,mh-tool-bar-item-undo) 520 (mh-previous-undeleted-msg (folder) "left_arrow"
563 (const ,mh-tool-bar-item-perform) 521 "Go to the previous undeleted message
564 (const ,mh-tool-bar-item-toggle-show) 522This button runs `mh-previous-undeleted-msg'")
565 (const ,mh-tool-bar-item-reply-from) 523 (mh-page-msg (folder) "page-down"
566 (const ,mh-tool-bar-item-reply-to) 524 "Page the current message forwards\nThis button runs `mh-page-msg'")
567 (const ,mh-tool-bar-item-reply-all) 525 (mh-next-undeleted-msg (folder) "right_arrow"
568 (const ,mh-tool-bar-item-reply) 526 "Go to the next undeleted message\nThe button runs `mh-next-undeleted-msg'")
569 (const ,mh-tool-bar-item-alias) 527 (mh-delete-msg (folder) "close"
570 (const ,mh-tool-bar-item-compose) 528 "Mark this message for deletion\nThis button runs `mh-delete-msg'")
571 (const ,mh-tool-bar-item-rescan) 529 (mh-refile-msg (folder) "refile"
572 (const ,mh-tool-bar-item-repack) 530 "Refile this message\nThis button runs `mh-refile-msg'")
573 (const ,mh-tool-bar-item-search) 531 (mh-undo (folder) "undo" "Undo last operation\nThis button runs `undo'")
574 (const ,mh-tool-bar-item-visit) 532 (mh-execute-commands (folder) "execute"
575 (const ,mh-tool-bar-item-prefs) 533 "Perform moves and deletes\nThis button runs `mh-execute-commands'")
576 (const ,mh-tool-bar-item-help) 534 (mh-toggle-tick (folder) "highlight"
577 (const ,mh-tool-bar-item-widen))) 535 "Toggle tick mark\nThis button runs `mh-toggle-tick'")
578 536 (mh-toggle-showing (folder) "show"
579(defun mh-tool-bar-letter-buttons-set (symbol value) 537 "Toggle showing message\nThis button runs `mh-toggle-showing'")
580 "Update the `mh-tool-bar-letter-buttons' variable, and rebuild the tool-bar. 538 (mh-tool-bar-reply-from (folder) "reply-from" "Reply to \"from\"")
581Sets the default for SYMBOL (e.g. `mh-tool-bar-letter-buttons') to VALUE (as 539 (mh-tool-bar-reply-to (folder) "reply-to" "Reply to \"to\"")
582set in customization). This is called after 'customize is used to alter 540 (mh-tool-bar-reply-all (folder) "reply-all" "Reply to \"all\"")
583`mh-tool-bar-letter-buttons'." 541 (mh-reply (folder) "mail/reply2"
584 (set-default symbol value) 542 "Reply to this message\nThis button runs `mh-reply'")
585 (mh-tool-bar-letter-set)) 543 (mh-alias-grab-from-field (folder) "alias"
586 544 "Grab From alias\nThis button runs `mh-alias-grab-from-field'")
587(custom-declare-variable 545 (mh-send (folder) "mail_compose"
588 'mh-tool-bar-letter-buttons 546 "Compose new message\nThis button runs `mh-send'")
589 '(list mh-tool-bar-item-send 547 (mh-rescan-folder (folder) "rescan"
590 mh-tool-bar-item-attach 548 "Rescan this folder\nThis button runs `mh-rescan-folder'")
591 mh-tool-bar-item-spell 549 (mh-pack-folder (folder) "repack"
592 mh-tool-bar-item-save 550 "Repack this folder\nThis button runs `mh-pack-folder'")
593 mh-tool-bar-item-undo-op 551 (mh-tool-bar-search (folder) "search"
594 mh-tool-bar-item-kill 552 "Search\nThis button runs `mh-tool-bar-search-function'")
595 mh-tool-bar-item-copy 553 (mh-visit-folder (folder) "fld_open"
596 mh-tool-bar-item-paste 554 "Visit other folder\nThis button runs `mh-visit-folder'")
597 mh-tool-bar-item-kill-draft 555 ;; Letter buffer buttons
598 mh-tool-bar-item-comp-prefs 556 (mh-send-letter (letter) "mail_send" "Send this letter")
599 mh-tool-bar-item-help) 557 (mh-compose-insertion (letter) "attach" "Insert attachment")
600 "Buttons to include in MH-E letter toolbar." 558 (ispell-message (letter) "spell" "Check spelling")
601 :group 'mh-toolbar 559 (save-buffer (letter) "save" "Save current buffer to its file")
602 :set 'mh-tool-bar-letter-buttons-set 560 (undo (letter) "undo" "Undo last operation")
603 :type `(set (const ,mh-tool-bar-item-send) 561 (kill-region (letter) "cut"
604 (const ,mh-tool-bar-item-attach) 562 "Cut (kill) text in region between mark and current position")
605 (const ,mh-tool-bar-item-spell) 563 (menu-bar-kill-ring-save (letter) "copy"
606 (const ,mh-tool-bar-item-save) 564 "Copy text in region between mark and current position")
607 (const ,mh-tool-bar-item-undo-op) 565 (yank (letter) "paste" "Paste (yank) text cut or copied earlier")
608 (const ,mh-tool-bar-item-kill) 566 (mh-fully-kill-draft (letter) "close" "Kill this draft")
609 (const ,mh-tool-bar-item-copy) 567 ;; Common buttons
610 (const ,mh-tool-bar-item-paste) 568 (mh-tool-bar-customize (folder letter) "preferences" "MH-E Preferences")
611 (const ,mh-tool-bar-item-kill-draft) 569 (mh-tool-bar-folder-help (folder) "help"
612 (const ,mh-tool-bar-item-comp-prefs) 570 "Help! (general help)\nThis button runs `Info-goto-node'")
613 (const ,mh-tool-bar-item-help))) 571 (mh-tool-bar-letter-help (letter) "help"
572 "Help! (general help)\nThis button runs `Info-goto-node'")
573 ;; Folder narrowed to sequence buttons
574 (mh-widen (sequence) "widen"
575 "Widen from the sequence\nThis button runs `mh-widen'"))
614 576
615 577
616 578
@@ -660,12 +622,16 @@ If you prefer fixed-width message numbers, set this variable to nil and call
660(defcustom mh-default-folder-list nil 622(defcustom mh-default-folder-list nil
661 "*Alist of addresses and folders. 623 "*Alist of addresses and folders.
662When refiling messages, these folders are the default that is provided if the 624When refiling messages, these folders are the default that is provided if the
663sender has the associated address. You do not need to list your aliases here 625sender (or recipient if the Check Recipient checkbox has been selected) has
664as that lookup is already performed. 626the associated address, a regexp. The first entry to match will be used, so
627order them according to the wanted priority. You do not need to list your
628aliases here as that lookup is already performed.
629
665See `mh-prompt-for-refile-folder' and `mh-folder-from-address' for more 630See `mh-prompt-for-refile-folder' and `mh-folder-from-address' for more
666information." 631information."
667 :type '(repeat (list (string :tag "Address") 632 :type '(repeat (list (regexp :tag "Address")
668 (string :tag "Folder"))) 633 (string :tag "Folder")
634 (boolean :tag "Check Recipient")))
669 :group 'mh-folder) 635 :group 'mh-folder)
670 636
671(defcustom mh-default-folder-must-exist-flag t 637(defcustom mh-default-folder-must-exist-flag t
@@ -695,6 +661,44 @@ the `mh-progs' directory unless it is an absolute pathname."
695 :type 'string 661 :type 'string
696 :group 'mh-folder) 662 :group 'mh-folder)
697 663
664
665(defcustom mh-inc-spool-list nil
666 "*Alist of alternate spool files, corresponding folders and keybindings.
667Here's an example. Suppose you have subscribed to the MH-E devel mailing
668list. You could filter its mail into a separate spool file named
669~/mail/mh-e using Procmail and a .procmailrc entry like:
670
671MAILDIR=$HOME/mail #you'd better make sure it exists
672:0:
673* ^From mh-e-devel-admin@lists.sourceforge.net
674mh-e
675
676If you wanted to incorporate that spool file into an MH folder called
677mh-e by pressing \"I m\" in folder-mode or by `M-x mh-inc-spool-mh-e',
678you would setup `mh-inc-spool-list' with an entry:
679
680 Spool file: ~/mail/mh-e
681 Folder: mh-e
682 Key binding: m
683
684Then, you could also install `xbuffy' and configure an extra mailbox like so:
685
686box ~/mail/mh-e
687 title mh-e
688 origMode
689 polltime 10
690 headertime 0
691 command gnudoit -q '(mh-inc-spool-mh-e)'
692
693Note that the entry above uses the gnuserv package to communicate the
694command `mh-inc-spool-mh-e' to Emacs. It will incorporate the spool file
695when clicking the xbuffy box with the middle mouse button."
696 :type '(repeat (list (file :tag "Spool file")
697 (string :tag "Folder")
698 (character :tag "Key binding")))
699 :set 'mh-inc-spool-list-set
700 :group 'mh-folder)
701
698(defcustom mh-lpr-command-format "lpr -J '%s'" 702(defcustom mh-lpr-command-format "lpr -J '%s'"
699 "*Format for Unix command that prints a message. 703 "*Format for Unix command that prints a message.
700The string should be a Unix command line, with the string '%s' where 704The string should be a Unix command line, with the string '%s' where
@@ -712,12 +716,6 @@ If t, prompt always"
712 directory) 716 directory)
713 :group 'mh-folder) 717 :group 'mh-folder)
714 718
715(defcustom mh-recenter-summary-flag nil
716 "*Non-nil means to recenter the summary window.
717Recenter the summary window when the show window is toggled off if non-nil."
718 :type 'boolean
719 :group 'mh-folder)
720
721(defcustom mh-print-background-flag nil 719(defcustom mh-print-background-flag nil
722 "*Non-nil means messages should be printed in the background. 720 "*Non-nil means messages should be printed in the background.
723WARNING: do not delete the messages until printing is finished; 721WARNING: do not delete the messages until printing is finished;
@@ -725,6 +723,12 @@ otherwise, your output may be truncated."
725 :type 'boolean 723 :type 'boolean
726 :group 'mh-folder) 724 :group 'mh-folder)
727 725
726(defcustom mh-recenter-summary-flag nil
727 "*Non-nil means to recenter the summary window.
728Recenter the summary window when the show window is toggled off if non-nil."
729 :type 'boolean
730 :group 'mh-folder)
731
728(defcustom mh-recursive-folders-flag nil 732(defcustom mh-recursive-folders-flag nil
729 "*Non-nil means that commands which operate on folders do so recursively." 733 "*Non-nil means that commands which operate on folders do so recursively."
730 :type 'boolean 734 :type 'boolean
@@ -769,6 +773,12 @@ A directory name string, or nil to use current directory."
769 directory) 773 directory)
770 :group 'mh-folder) 774 :group 'mh-folder)
771 775
776(defcustom mh-tick-seq 'tick
777 "The name of the MH tick sequence."
778 :type '(choice (const :tag "Disable ticking" nil)
779 symbol)
780 :group 'mh-folder)
781
772(defcustom mh-update-sequences-after-mh-show-flag t 782(defcustom mh-update-sequences-after-mh-show-flag t
773 "*Non-nil means `mh-update-sequence' is called from `mh-show-mode'. 783 "*Non-nil means `mh-update-sequence' is called from `mh-show-mode'.
774If set, `mh-update-sequence' is run every time a message is shown, telling 784If set, `mh-update-sequence' is run every time a message is shown, telling
@@ -779,6 +789,86 @@ display MIME content using \"M-! mhshow RET\""
779 789
780 790
781 791
792;;; Indexed searching (:group 'mh-index)
793
794(defcustom mh-index-new-messages-folders t
795 "Folders searched for `mh-unseen-seq'.
796If t, then `mh-inbox' is searched. If nil, all the top level folders are
797searched. Otherwise the list of folders specified as strings are searched.
798See also `mh-recursive-folders-flag'."
799 :group 'mh-index
800 :type '(choice (const :tag "Inbox" t)
801 (const :tag "All" nil)
802 (repeat :tag "Choose folders" (string :tag "Folder"))))
803
804(defcustom mh-index-program nil
805 "Indexing program that MH-E shall use.
806The possible choices are swish++, swish-e, mairix, namazu, glimpse, pick and
807grep. By default this variable is nil which means that the programs are tried
808in order and the first one found is used.
809
810More information about setting up an indexing program to use with MH-E can be
811found in the documentation of `mh-index-search'."
812 :type '(choice (const :tag "Auto-detect" nil)
813 (const :tag "swish++" swish++)
814 (const :tag "swish-e" swish)
815 (const :tag "mairix" mairix)
816 (const :tag "namazu" namazu)
817 (const :tag "glimpse" glimpse)
818 (const :tag "pick" pick)
819 (const :tag "grep" grep))
820 :group 'mh-index)
821
822
823
824;;; Spam Handling (:group 'mh-junk)
825
826;; Spam fighting program chosen
827(defvar mh-junk-choice nil)
828
829;; Available spam filter interfaces
830(defvar mh-junk-function-alist
831 '((bogofilter mh-bogofilter-blacklist mh-bogofilter-whitelist)
832 (spamprobe mh-spamprobe-blacklist mh-spamprobe-whitelist)
833 (spamassassin mh-spamassassin-blacklist mh-spamassassin-whitelist))
834 "Available choices of spam programs to use.
835This is an alist. For each element there are functions that blacklist a message
836as spam and whitelist a message incorrectly classified as spam.")
837
838(defun mh-junk-choose (symbol value)
839 "Choose spam program to use.
840The function is always called with SYMBOL bound to `mh-junk-program' and VALUE
841bound to the new value of `mh-junk-program'. The function sets the variable
842`mh-junk-choice' in addition to `mh-junk-program'."
843 (set symbol value)
844 (setq mh-junk-choice
845 (or value
846 (loop for element in mh-junk-function-alist
847 until (executable-find (symbol-name (car element)))
848 finally return (car element)))))
849
850;; User customizable variables
851(defcustom mh-junk-mail-folder nil
852 "Folder to put spam mail in.
853If nil then the spam is deleted."
854 :type '(choice (const :tag "Delete spam" nil)
855 (string :tag "Spam folder"))
856 :group 'mh-junk)
857
858(defcustom mh-junk-program nil
859 "Spam program that MH-E shall use.
860The possible choices are bogofilter, spamprobe, and spamassassin. By default
861this variable is nil which means that the programs are tried in order and the
862first one found is used."
863 :type '(choice (const :tag "auto-detect" nil)
864 (const :tag "bogofilter" bogofilter)
865 (const :tag "spamprobe" spamprobe)
866 (const :tag "spamassassin" spamassassin))
867 :set 'mh-junk-choose
868 :group 'mh-junk)
869
870
871
782;;; Message display (:group 'mh-show) 872;;; Message display (:group 'mh-show)
783 873
784(defcustom mh-bury-show-buffer-flag t 874(defcustom mh-bury-show-buffer-flag t
@@ -798,21 +888,6 @@ what is removed."
798 :type 'boolean 888 :type 'boolean
799 :group 'mh-show) 889 :group 'mh-show)
800 890
801(defcustom mh-decode-content-transfer-encoded-message-flag
802 (and (fboundp 'executable-find) (executable-find "mimencode") t)
803 "Non-nil means decode messages with `mimencode', if necessary.
804
805Messages which are encoded as quoted-printable or base64 are translated into
8068-bit characters by the `mimencode' command.
807
808This variable is initialized to t if `mimencode' is available.
809
810The `mimencode' program is part of the metamail package. The source can be
811obtained from
812 ftp://thumper.bellcore.com/pub/nsb/"
813 :type 'boolean
814 :group 'mh-show)
815
816(defcustom mh-display-buttons-for-inline-parts-flag nil 891(defcustom mh-display-buttons-for-inline-parts-flag nil
817 "*Non-nil means display buttons for all inline MIME parts. 892 "*Non-nil means display buttons for all inline MIME parts.
818If non-nil, buttons are displayed for all MIME parts. Inline parts start off 893If non-nil, buttons are displayed for all MIME parts. Inline parts start off
@@ -830,6 +905,24 @@ question."
830 :type 'boolean 905 :type 'boolean
831 :group 'mh-show) 906 :group 'mh-show)
832 907
908(defcustom mh-fetch-x-image-url nil
909 "Control fetching of X-Image-URL header field image.
910This setting only has effect if `mh-show-use-xface-flag' is non-nil.
911
912If set to t, the image is fetched.
913
914If set to 'ask, the user is prompted before the image is fetched. MH-E will
915remember your reply and will either use the already fetched image the next time
916the same URL is encountered or silently skip it if you didn't fetch it the
917first time.
918
919If set to nil, the default, images are not fetched and only displayed if they
920are already present in the cache."
921 :type '(choice (const :tag "Always fetch" t)
922 (const :tag "Ask before fetching" ask)
923 (const :tag "Never fetch" nil))
924 :group 'mh-show)
925
833(defcustom mh-graphical-smileys-flag t 926(defcustom mh-graphical-smileys-flag t
834 "*Non-nil means graphical smileys are displayed. 927 "*Non-nil means graphical smileys are displayed.
835Non-nil means that small graphics will be used in the show buffer instead of 928Non-nil means that small graphics will be used in the show buffer instead of
@@ -854,6 +947,177 @@ The gnus method uses a different color for each indentation."
854 (const :tag "Don't fontify" nil)) 947 (const :tag "Don't fontify" nil))
855 :group 'mh-show) 948 :group 'mh-show)
856 949
950(defvar mh-invisible-headers nil
951 "*Regexp matching lines in a message header that are not to be shown.
952Use the function `mh-invisible-headers' to generate this variable.
953If `mh-visible-headers' is non-nil, it is used instead to specify what
954to keep.")
955
956(defun mh-invisible-headers ()
957 "Make or remake the variable `mh-invisible-headers'.
958Done using `mh-invisible-header-fields' as input."
959 (setq mh-invisible-headers
960 (concat
961 "^"
962 (let ((max-specpdl-size 1000) ;workaround for insufficient default
963 (fields mh-invisible-header-fields))
964 (regexp-opt fields t)))))
965
966(defun mh-invisible-header-fields-set (symbol value)
967 "Update `mh-invisible-header-fields'.
968The function is called with SYMBOL bound to `mh-invisible-header-fields' and
969VALUE is the the list of headers that are invisible. As a side effect, the
970variable `mh-invisible-fields' is set."
971 (set-default symbol value)
972 (mh-invisible-headers))
973
974;; Keep fields alphabetized. Mention source, if known.
975(defcustom mh-invisible-header-fields
976 '("Approved:"
977 "Autoforwarded:"
978 "Bestservhost:"
979 "Cancel-Lock:" ; NNTP posts
980 "Content-" ; RFC 2045
981 "Delivered-To:" ; Egroups/yahoogroups mailing list manager
982 "Delivery-Date:" ; MH
983 "Delivery:"
984 "Encoding:"
985 "Errors-To:"
986 "Face:" ; Gnus Face header
987 "Forwarded:" ; MH
988 "From " ; sendmail
989 "Importance:" ; MS Outlook
990 "In-Reply-To:" ; MH
991 "Lines:"
992 "List-" ; Mailman mailing list manager
993 "List-" ; Unknown mailing list managers
994 "List-Subscribe:" ; Unknown mailing list managers
995 "List-Unsubscribe:" ; Unknown mailing list managers
996 "Mail-from:" ; MH
997 "Mailing-List:" ; Egroups/yahoogroups mailing list manager
998 "Message-Id:" ; RFC 822
999 "Mime-Version" ; RFC 2045
1000 "NNTP-" ; News
1001 "Old-Return-Path:"
1002 "Original-Encoded-Information-Types:" ; X400
1003 "Original-Lines:" ; mail to news
1004 "Original-Newsgroups:" ; mail to news
1005 "Original-NNTP-" ; mail to news
1006 "Original-Path:" ; mail to news
1007 "Original-Received:" ; mail to news
1008 "Original-To:" ; mail to news
1009 "Original-X-" ; mail to news
1010 "P1-Content-Type:" ; X400
1011 "P1-Message-Id:" ; X400
1012 "P1-Recipient:" ; X400
1013 "Path:"
1014 "Precedence:"
1015 "Prev-Resent" ; MH
1016 "Priority:"
1017 "Received:" ; RFC 822
1018 "References:"
1019 "Remailed-" ; MH
1020 "Replied:" ; MH
1021 "Resent" ; MH
1022 "Return-Path:" ; RFC 822
1023 "Sensitivity:" ; MS Outlook
1024 "Status:" ; sendmail
1025 "Ua-Content-Id:" ; X400
1026 "User-Agent:"
1027 "Via:" ; MH
1028 "X-Abuse-Info:"
1029 "X-Accept-Language:"
1030 "X-Accept-Language:" ; Netscape/Mozilla
1031 "X-Ack:"
1032 "X-Apparently-From:" ; MS Outlook
1033 "X-Apparently-To:" ; Egroups/yahoogroups mailing list manager
1034 "X-Authentication-Warning:" ; sendmail
1035 "X-Beenthere:" ; Mailman mailing list manager
1036 "X-Bogosity:" ; bogofilter
1037 "X-Complaints-To:"
1038 "X-Cron-Env:"
1039 "X-Delivered"
1040 "X-Envelope-Sender:"
1041 "X-Envelope-To:"
1042 "X-Face:"
1043 "X-Folder:" ; Spam
1044 "X-From-Line"
1045 "X-Gnus-Mail-Source:" ; gnus
1046 "X-Habeas-SWE-1:" ; Spam
1047 "X-Habeas-SWE-2:" ; Spam
1048 "X-Habeas-SWE-3:" ; Spam
1049 "X-Habeas-SWE-4:" ; Spam
1050 "X-Habeas-SWE-5:" ; Spam
1051 "X-Habeas-SWE-6:" ; Spam
1052 "X-Habeas-SWE-7:" ; Spam
1053 "X-Habeas-SWE-8:" ; Spam
1054 "X-Habeas-SWE-9:" ; Spam
1055 "X-Info:" ; NTMail
1056 "X-Juno-" ; Juno
1057 "X-List-Host:" ; Unknown mailing list managers
1058 "X-List-Subscribe:" ; Unknown mailing list managers
1059 "X-List-Unsubscribe:" ; Unknown mailing list managers
1060 "X-Listserver:" ; Unknown mailing list managers
1061 "X-Loop:" ; Unknown mailing list managers
1062 "X-MIME-Autoconverted:" ; sendmail
1063 "X-MIMETrack:"
1064 "X-MS-TNEF-Correlator:" ; MS Outlook
1065 "X-Mailing-List:" ; Unknown mailing list managers
1066 "X-Mailman-Version:" ; Mailman mailing list manager
1067 "X-Majordomo:" ; Majordomo mailing list manager
1068 "X-Message-Id"
1069 "X-MHE-Checksum" ; Checksum added during index search
1070 "X-MimeOLE:" ; MS Outlook
1071 "X-Mozilla-Status:" ; Netscape/Mozilla
1072 "X-Msmail-" ; MS Outlook
1073 "X-News:" ; News
1074 "X-No-Archive:"
1075 "X-Notes-Item:" ; Lotus Notes Domino structured header
1076 "X-Orcl-Content-Type:"
1077 "X-Original-Complaints-To:"
1078 "X-Original-Date:" ; SourceForge mailing list manager
1079 "X-Original-Trace:"
1080 "X-OriginalArrivalTime:" ; Hotmail
1081 "X-Originating-IP:" ; Hotmail
1082 "X-Priority:" ; MS Outlook
1083 "X-Qotd-" ; User added
1084 "X-Received-Date:"
1085 "X-Received:"
1086 "X-Request-"
1087 "X-SBClass:" ; Spam
1088 "X-SBNote:" ; Spam
1089 "X-SBPass:" ; Spam
1090 "X-SBRule:" ; Spam
1091 "X-Scanned-By"
1092 "X-Sender:"
1093 "X-Server-Date:"
1094 "X-Server-Uuid:"
1095 "X-Sieve:" ; Sieve filtering
1096 "X-Spam-Checker-Version:" ; Spamassassin
1097 "X-Spam-Level:" ; Spamassassin
1098 "X-Spam-Score:" ; Spamassassin
1099 "X-Spam-Status:" ; Spamassassin
1100 "X-SpamBouncer:" ; Spam
1101 "X-Trace:"
1102 "X-UIDL:"
1103 "X-UserInfo1:"
1104 "X-VSMLoop:" ; NTMail
1105 "X-Vms-To:"
1106 "X-Wss-Id:" ; Worldtalk gateways
1107 "X-eGroups-" ; Egroups/yahoogroups mailing list manager
1108 "X-pgp:"
1109 "X-submission-address:"
1110 "X400-" ; X400
1111 "Xref:")
1112"*List of header fields that are not to be shown.
1113Regexps are not allowed. Unique fields should have a \":\" suffix; otherwise,
1114the element can be used to render invisible an entire class of fields that
1115start with the same prefix.
1116This variable is ignored if `mh-visible-headers' is set."
1117 :type '(repeat (string :tag "Header field"))
1118 :set 'mh-invisible-header-fields-set
1119 :group 'mh-show)
1120
857(defcustom mh-max-inline-image-height nil 1121(defcustom mh-max-inline-image-height nil
858 "*Maximum inline image height if Content-Disposition is not present. 1122 "*Maximum inline image height if Content-Disposition is not present.
859If nil, image will be displayed if its height is smaller than the height of 1123If nil, image will be displayed if its height is smaller than the height of
@@ -884,25 +1148,40 @@ The `goto-addr' module is used."
884 :type 'boolean 1148 :type 'boolean
885 :group 'mh-show) 1149 :group 'mh-show)
886 1150
887(defcustom mh-show-use-xface-flag 1151(defcustom mh-show-use-xface-flag (>= emacs-major-version 21)
888 (and window-system 1152 "*Non-nil means display face images in `mh-show-mode'.
889 (not (null (cond 1153This flag controls the display of three kinds of faces.
890 (mh-xemacs-flag 1154
891 (locate-library "x-face")) 1155The first is the traditional X-Face header field. For GNU Emacs 21
892 ((>= emacs-major-version 21) 1156and above, the `uncompface' binary is required to be in the execute
893 (locate-library "x-face-e21")) 1157PATH for the display of X-Face images. It can be obtained from
894 (t ;Emacs20 1158ftp://ftp.cs.indiana.edu/pub/faces/compface/compface.tar.Z.
895 nil)))) 1159
896 (not (null (and (fboundp 'executable-find) 1160If the XEmacs you are using has internal support for X-Face images, then MH-E
897 (executable-find 1161will display X-Face images in XEmacs \"out of the box\". Even if you don't have
898 "uncompface"))))) 1162X-Face support compiled into your XEmacs, you can still see the X-Face images
899 "*Non-nil means display faces in `mh-show-mode' with external x-face package. 1163in MH-E with the aid of an external x-face package and `uncompface'. It is
900It is available from ftp://ftp.jpl.org/pub/elisp/. Download it and put its 1164available from ftp://ftp.jpl.org/pub/elisp/. Download it, put its files in the
901files in the Emacs `load-path' and MH-E will invoke it automatically for you if 1165`load-path' and MH-E will invoke it automatically.
902this variable is non-nil. 1166
903 1167Second, MH-E supports the display of the Gnus-specific Face
904The `uncompface' binary is also required to be in the execute PATH. It can 1168header field in GNU Emacs >= 21 and XEmacs. No external packages
905be obtained from: ftp://ftp.cs.indiana.edu/pub/faces/compface/compface.tar.Z" 1169are required. More information about the Face header can be found
1170at: http://quimby.gnus.org/circus/face/.
1171
1172Finally, MH-E can also display images from the X-Image-URL header field. The
1173display of the images requires the `wget' program, available from
1174http://www.gnu.org/software/wget/wget.html, to fetch the image and the
1175`convert' program from the ImageMagick suite, available from
1176http://www.imagemagick.org/. Of the three header fields this is the most
1177efficient in terms of network usage since the image doesn't need to be
1178transmitted with every single mail. However its display needs the recipient to
1179fetch a URL and this can be misused. So it is disabled by default. It can be
1180enabled by customizing `mh-fetch-x-image-url'. Setting that to ask for
1181confirmation before fetching seems like a good choice.
1182
1183Versions of GNU Emacs prior to 21.1 don't support the display of
1184inline images. So face images are not displayed in these versions."
906 :type 'boolean 1185 :type 'boolean
907 :group 'mh-show) 1186 :group 'mh-show)
908 1187
@@ -932,163 +1211,6 @@ the message continues to conform to RFC 822 and MH-E can parse the headers."
932 :group 'mh-show) 1211 :group 'mh-show)
933(put 'mhl-formfile 'info-file "mh-e") 1212(put 'mhl-formfile 'info-file "mh-e")
934 1213
935(defvar mh-invisible-headers nil
936 "*Regexp matching lines in a message header that are not to be shown.
937If `mh-visible-headers' is non-nil, it is used instead to specify what
938to keep.")
939
940(defun mh-invisible-headers ()
941 "Make or remake the variable `mh-invisible-headers'.
942Done using `mh-invisible-header-fields' as input."
943 (setq mh-invisible-headers
944 (concat
945 "^"
946 (let ((max-specpdl-size 1000) ;workaround for insufficient default
947 (fields (append (if (not mh-show-use-xface-flag)
948 '("X-Face: "))
949 mh-invisible-header-fields)))
950 (regexp-opt fields t)))))
951
952(defun mh-invisible-header-fields-set (symbol value)
953 "Update `mh-invisible-header-fields'.
954The function is called with SYMBOL bound to `mh-invisible-header-fields' and
955VALUE is the the list of headers that are invisible. As a side effect, the
956variable `mh-invisible-fields' is set."
957 (set-default symbol value)
958 (mh-invisible-headers))
959
960;; Keep fields alphabetized. Mention source, if known.
961(defcustom mh-invisible-header-fields
962 '("Autoforwarded: "
963 "Bestservhost: "
964 "Content-" ; RFC 2045
965 "Delivered-To: " ; Egroups/yahoogroups mailing list manager
966 "Delivery-Date: " ; MH
967 "Delivery: "
968 "Encoding: "
969 "Errors-To: "
970 "Forwarded: " ; MH
971 "From " ; sendmail
972 "Importance: " ; MS Outlook
973 "In-Reply-To: " ; MH
974 "Lines: "
975 "List-" ; Mailman mailing list manager
976 "List-" ; Unknown mailing list managers
977 "List-Subscribe: " ; Unknown mailing list managers
978 "List-Unsubscribe: " ; Unknown mailing list managers
979 "Mail-from: " ; MH
980 "Mailing-List: " ; Egroups/yahoogroups mailing list manager
981 "Message-Id: " ; RFC 822
982 "Mime-Version" ; RFC 2045
983 "NNTP-" ; News
984 "Old-Return-Path: "
985 "Original-Encoded-Information-Types: " ; X400
986 "P1-Content-Type: " ; X400
987 "P1-Message-Id: " ; X400
988 "P1-Recipient: " ; X400
989 "Path: "
990 "Precedence: "
991 "Prev-Resent" ; MH
992 "Priority: "
993 "Received: " ; RFC 822
994 "References: "
995 "Remailed-" ; MH
996 "Replied: " ; MH
997 "Resent" ; MH
998 "Return-Path: " ; RFC 822
999 "Sensitivity: " ; MS Outlook
1000 "Status: " ; sendmail
1001 "Ua-Content-Id: " ; X400
1002 "User-Agent: "
1003 "Via: " ; MH
1004 "X-Abuse-Info: "
1005 "X-Accept-Language: "
1006 "X-Accept-Language: " ; Netscape/Mozilla
1007 "X-Ack: "
1008 "X-Apparently-From: " ; MS Outlook
1009 "X-Apparently-To: " ; Egroups/yahoogroups mailing list manager
1010 "X-Authentication-Warning: " ; sendmail
1011 "X-Beenthere: " ; Mailman mailing list manager
1012 "X-Complaints-To: "
1013 "X-Cron-Env: "
1014 "X-Delivered"
1015 "X-Envelope-Sender: "
1016 "X-Envelope-To: "
1017 "X-Folder: " ; Spam
1018 "X-From-Line"
1019 "X-Gnus-Mail-Source: " ; gnus
1020 "X-Habeas-SWE-1: " ; Spam
1021 "X-Habeas-SWE-2: " ; Spam
1022 "X-Habeas-SWE-3: " ; Spam
1023 "X-Habeas-SWE-4: " ; Spam
1024 "X-Habeas-SWE-5: " ; Spam
1025 "X-Habeas-SWE-6: " ; Spam
1026 "X-Habeas-SWE-7: " ; Spam
1027 "X-Habeas-SWE-8: " ; Spam
1028 "X-Habeas-SWE-9: " ; Spam
1029 "X-Info: " ; NTMail
1030 "X-Juno-" ; Juno
1031 "X-List-Host: " ; Unknown mailing list managers
1032 "X-List-Subscribe: " ; Unknown mailing list managers
1033 "X-List-Unsubscribe: " ; Unknown mailing list managers
1034 "X-Listserver: " ; Unknown mailing list managers
1035 "X-Loop: " ; Unknown mailing list managers
1036 "X-MIME-Autoconverted: " ; sendmail
1037 "X-MIMETrack: "
1038 "X-MS-TNEF-Correlator: " ; MS Outlook
1039 "X-Mailing-List: " ; Unknown mailing list managers
1040 "X-Mailman-Version: " ; Mailman mailing list manager
1041 "X-Message-Id"
1042 "X-MHE-Checksum" ; Checksum added during index search
1043 "X-MimeOLE: " ; MS Outlook
1044 "X-Mozilla-Status: " ; Netscape/Mozilla
1045 "X-Msmail-" ; MS Outlook
1046 "X-News: " ; News
1047 "X-No-Archive: "
1048 "X-Orcl-Content-Type: "
1049 "X-Original-Complaints-To: "
1050 "X-Original-Date: " ; SourceForge mailing list manager
1051 "X-Original-Trace: "
1052 "X-OriginalArrivalTime: " ; Hotmail
1053 "X-Originating-IP: " ; Hotmail
1054 "X-Priority: " ; MS Outlook
1055 "X-Qotd-" ; User added
1056 "X-Received-Date: "
1057 "X-Received: "
1058 "X-Request-"
1059 "X-SBClass: " ; Spam
1060 "X-SBNote: " ; Spam
1061 "X-SBPass: " ; Spam
1062 "X-SBRule: " ; Spam
1063 "X-Scanned-By"
1064 "X-Sender: "
1065 "X-Server-Date: "
1066 "X-Server-Uuid: "
1067 "X-Sieve: " ; Sieve filtering
1068 "X-Spam-Level: " ; Spam
1069 "X-Spam-Score: " ; Spam
1070 "X-Spam-Status: " ; Spam
1071 "X-SpamBouncer: " ; Spam
1072 "X-Trace: "
1073 "X-UIDL: "
1074 "X-UserInfo1: "
1075 "X-VSMLoop: " ; NTMail
1076 "X-Vms-To: "
1077 "X-Wss-Id: " ; Worldtalk gateways
1078 "X-eGroups-" ; Egroups/yahoogroups mailing list manager
1079 "X-pgp: "
1080 "X-submission-address: "
1081 "X400-" ; X400
1082 "Xref: ")
1083"*List of header fields that are not to be shown.
1084Regexps are not allowed. Unique fields should have a \": \" suffix; otherwise,
1085the element can be used to render invisible an entire class of fields that
1086start with the same prefix.
1087This variable is ignored if `mh-visible-headers' is set."
1088 :type '(repeat (string :tag "Header field"))
1089 :set 'mh-invisible-header-fields-set
1090 :group 'mh-show)
1091
1092 1214
1093 1215
1094;;; Composing messages (:group 'mh-letter) 1216;;; Composing messages (:group 'mh-letter)
@@ -1134,42 +1256,16 @@ by \\[mh-insert-letter] or \\[mh-yank-cur-msg]."
1134 :type 'string 1256 :type 'string
1135 :group 'mh-letter) 1257 :group 'mh-letter)
1136 1258
1137(defcustom mh-insert-mail-followup-to-flag t
1138 "Non-nil means maybe append a Mail-Followup-To field to the header.
1139The insertion is done if the To: or Cc: fields matches an entry in
1140`mh-insert-mail-followup-to-list'."
1141 :type 'boolean
1142 :group 'mh-letter)
1143
1144(defcustom mh-insert-mail-followup-to-list nil
1145 "Alist of addresses for which a Mail-Followup-To field is inserted.
1146Each element has the form (REGEXP ADDRESS).
1147When the REGEXP appears in the To or cc fields of a message, the corresponding
1148ADDRESS is inserted in a Mail-Followup-To field.
1149
1150Here's a customization example:
1151
1152 regexp: mh-e-users@lists.s\\\\(ourceforge\\\\|f\\\\).net
1153 address: mh-e-users@lists.sourceforge.net
1154
1155This corresponds to:
1156
1157 (setq mh-insert-mail-followup-to-list
1158 '((\"mh-e-users@lists.s\\\\(ourceforge\\\\|f\\\\).net\"
1159 \"mh-e-users@lists.sourceforge.net\")))
1160
1161While it might be tempting to add a descriptive name to the mailing list
1162address, consider that this field will appear in other people's outgoing
1163mail in their To: field. It might be best to keep it simple."
1164 :type '(repeat (list (string :tag "Regexp")
1165 (string :tag "Address")))
1166 :group 'mh-letter)
1167
1168(defcustom mh-insert-x-mailer-flag t 1259(defcustom mh-insert-x-mailer-flag t
1169 "*Non-nil means append an X-Mailer field to the header." 1260 "*Non-nil means append an X-Mailer field to the header."
1170 :type 'boolean 1261 :type 'boolean
1171 :group 'mh-letter) 1262 :group 'mh-letter)
1172 1263
1264(defcustom mh-letter-complete-function 'ispell-complete-word
1265 "*Function to call when completing outside of fields specific to aliases."
1266 :type '(choice function (const nil))
1267 :group 'mh-letter)
1268
1173(defcustom mh-letter-fill-column 72 1269(defcustom mh-letter-fill-column 72
1174 "*Fill column to use in `mh-letter-mode'. 1270 "*Fill column to use in `mh-letter-mode'.
1175This is usually less than in other text modes because email messages get 1271This is usually less than in other text modes because email messages get
@@ -1207,16 +1303,28 @@ Inserted into message by \\<mh-letter-mode-map>\\[mh-insert-signature]."
1207 :group 'mh-letter) 1303 :group 'mh-letter)
1208 1304
1209(defcustom mh-x-face-file "~/.face" 1305(defcustom mh-x-face-file "~/.face"
1210 "*File name containing the encoded X-Face string to insert in outgoing mail. 1306 "*File containing X-Face or Face header field to insert in outgoing mail.
1211If nil, or the file does not exist, nothing is added to message headers." 1307
1308If the file starts with either of the strings \"X-Face: \", \"Face: \" or
1309\"X-Image-URL: \" then it is assumed to contain the whole field and is added to
1310the message header verbatim. Otherwise it is assumed that the file contains the
1311value of the X-Face header field.
1312
1313X-Face header fields can be generated using `compface', which can be obtained
1314from ftp://ftp.cs.indiana.edu/pub/faces/compface/compface.tar.Z. The \"Online
1315X-Face Convertor\" at http://www.dairiki.org/xface/ is a useful resource for
1316quick conversion of images into X-Face header fields.
1317
1318There is a `make-face' script that converts a jpeg image to a Face header
1319field at http://quimby.gnus.org/circus/face/make-face.
1320
1321The URL of any image can be used for the X-Image-URL field and no processing
1322of the image is required.
1323
1324If nil, or the file does not exist, nothing is added to the message header."
1212 :type 'file 1325 :type 'file
1213 :group 'mh-letter) 1326 :group 'mh-letter)
1214 1327
1215(defvar mh-x-mailer-string nil
1216 "*String containing the contents of the X-Mailer header field.
1217If nil, this variable is initialized to show the version of MH-E, Emacs, and
1218MH the first time a message is composed.")
1219
1220(defcustom mh-yank-from-start-of-msg 'attribution 1328(defcustom mh-yank-from-start-of-msg 'attribution
1221 "*Controls which part of a message is yanked by \\<mh-letter-mode-map>\\[mh-yank-cur-msg]. 1329 "*Controls which part of a message is yanked by \\<mh-letter-mode-map>\\[mh-yank-cur-msg].
1222If t, include the entire message, with full headers. This is historically 1330If t, include the entire message, with full headers. This is historically
@@ -1260,39 +1368,24 @@ to the yanked region."
1260 (const :tag "Entire message with headers" t)) 1368 (const :tag "Entire message with headers" t))
1261 :group 'mh-letter) 1369 :group 'mh-letter)
1262 1370
1263(defcustom mh-letter-complete-function 'ispell-complete-word
1264 "*Function to call when completing outside of fields specific to aliases."
1265 :type '(choice function (const nil))
1266 :group 'mh-letter)
1267
1268 1371
1269 1372
1270;;; Alias handling (:group 'mh-alias) 1373;;; Alias handling (:group 'mh-alias)
1271 1374
1272(defcustom mh-alias-system-aliases
1273 '("/etc/nmh/MailAliases" "/usr/lib/mh/MailAliases" "/etc/passwd")
1274 "*A list of system files from which to cull aliases.
1275If these files are modified, they are automatically reread. This list need
1276include only system aliases and the passwd file, since personal alias files
1277listed in your \"AliasFile\" MH profile component are automatically included.
1278You can update the alias list manually using \\[mh-alias-reload]."
1279 :group 'mh-alias
1280 :type '(choice (file) (repeat file)))
1281
1282(defcustom mh-alias-expand-aliases-flag nil
1283 "*Non-nil means to expand aliases entered in the minibuffer.
1284In other words, aliases entered in the minibuffer will be expanded to the full
1285address in the message draft. By default, this expansion is not performed."
1286 :group 'mh-alias
1287 :type 'boolean)
1288
1289(defcustom mh-alias-completion-ignore-case-flag t 1375(defcustom mh-alias-completion-ignore-case-flag t
1290 "*Non-nil means don't consider case significant in MH alias completion. 1376 "*Non-nil means don't consider case significant in MH alias completion.
1291This is the default in plain MH, so it is the default here as well. It 1377This is the default in plain MH, so it is the default here as well. It
1292can be useful to set this to t if, for example, you use lowercase 1378can be useful to set this to t if, for example, you use lowercase
1293aliases for people and uppercase for mailing lists." 1379aliases for people and uppercase for mailing lists."
1294 :group 'mh-alias 1380 :type 'boolean
1295 :type 'boolean) 1381 :group 'mh-alias)
1382
1383(defcustom mh-alias-expand-aliases-flag nil
1384 "*Non-nil means to expand aliases entered in the minibuffer.
1385In other words, aliases entered in the minibuffer will be expanded to the full
1386address in the message draft. By default, this expansion is not performed."
1387 :type 'boolean
1388 :group 'mh-alias)
1296 1389
1297(defcustom mh-alias-flash-on-comma t 1390(defcustom mh-alias-flash-on-comma t
1298 "*Specify whether to flash or warn on translation. 1391 "*Specify whether to flash or warn on translation.
@@ -1301,31 +1394,20 @@ variable to the following values has the listed effects:
1301t Flash alias translation but don't warn if there is no translation. 1394t Flash alias translation but don't warn if there is no translation.
13021 Flash alias translation and warn if there is no translation. 13951 Flash alias translation and warn if there is no translation.
1303nil Do not flash alias translation nor warn if there is no translation." 1396nil Do not flash alias translation nor warn if there is no translation."
1304 :group 'mh-alias
1305 :type '(choice (const :tag "Flash but don't warn if no translation" t) 1397 :type '(choice (const :tag "Flash but don't warn if no translation" t)
1306 (const :tag "Flash and warn if no translation" 1) 1398 (const :tag "Flash and warn if no translation" 1)
1307 (const :tag "Don't flash nor warn if no translation" nil))) 1399 (const :tag "Don't flash nor warn if no translation" nil))
1308 1400 :group 'mh-alias)
1309(defcustom mh-alias-local-users t
1310 "*If t, local users are completed in MH-E To: and Cc: prompts.
1311
1312Users with a userid greater than some magic number (usually 200) are available
1313for completion.
1314
1315If you set this variable to a string, it will be executed to generate a
1316password file. A value of \"ypcat passwd\" is helpful if NIS is in use."
1317 :group 'mh-alias
1318 :type '(choice (boolean) (string)))
1319 1401
1320(defcustom mh-alias-insert-file nil 1402(defcustom mh-alias-insert-file nil
1321 "*Filename to use to store new MH-E aliases. 1403 "*Filename to use to store new MH-E aliases.
1322This variable can also be a list of filenames, in which case MH-E will prompt 1404This variable can also be a list of filenames, in which case MH-E will prompt
1323for one of them. If nil, the default, then MH-E will use the first file found 1405for one of them. If nil, the default, then MH-E will use the first file found
1324in the \"AliasFile\" component of the MH profile." 1406in the \"AliasFile\" component of the MH profile."
1325 :group 'mh-alias
1326 :type '(choice (const :tag "Use AliasFile MH profile component" nil) 1407 :type '(choice (const :tag "Use AliasFile MH profile component" nil)
1327 (file :tag "Alias file") 1408 (file :tag "Alias file")
1328 (repeat :tag "List of alias files" file))) 1409 (repeat :tag "List of alias files" file))
1410 :group 'mh-alias)
1329 1411
1330(defcustom mh-alias-insertion-location 'sorted 1412(defcustom mh-alias-insertion-location 'sorted
1331 "Specifies where new aliases are entered in alias files. 1413 "Specifies where new aliases are entered in alias files.
@@ -1335,32 +1417,80 @@ Options are sorted alphabetically, at the top of the file or at the bottom."
1335 (const :tag "At the bottom of file" bottom)) 1417 (const :tag "At the bottom of file" bottom))
1336 :group 'mh-alias) 1418 :group 'mh-alias)
1337 1419
1338 1420(defcustom mh-alias-local-users t
1421 "*If t, local users are completed in MH-E To: and Cc: prompts.
1339 1422
1340;;; Indexed searching (:group 'mh-index) 1423Users with a userid greater than some magic number (usually 200) are available
1424for completion.
1341 1425
1342(defcustom mh-index-program nil 1426If you set this variable to a string, it will be executed to generate a
1343 "Indexing program that MH-E shall use. 1427password file. A value of \"ypcat passwd\" is helpful if NIS is in use."
1344The possible choices are swish++, swish-e, mairix, namazu, glimpse, pick and 1428 :type '(choice (boolean) (string))
1345grep. By default this variable is nil which means that the programs are tried 1429 :group 'mh-alias)
1346in order and the first one found is used.
1347 1430
1348More information about setting up an indexing program to use with MH-E can be 1431(defcustom mh-alias-system-aliases
1349found in the documentation of `mh-index-search'." 1432 '("/etc/nmh/MailAliases" "/usr/lib/mh/MailAliases" "/etc/passwd")
1350 :type '(choice (const :tag "Auto-detect" nil) 1433 "*A list of system files from which to cull aliases.
1351 (const :tag "swish++" swish++) 1434If these files are modified, they are automatically reread. This list need
1352 (const :tag "swish-e" swish) 1435include only system aliases and the passwd file, since personal alias files
1353 (const :tag "mairix" mairix) 1436listed in your \"AliasFile\" MH profile component are automatically included.
1354 (const :tag "namazu" namazu) 1437You can update the alias list manually using \\[mh-alias-reload]."
1355 (const :tag "glimpse" glimpse) 1438 :type '(choice (file) (repeat file))
1356 (const :tag "pick" pick) 1439 :group 'mh-alias)
1357 (const :tag "grep" grep))
1358 :group 'mh-index)
1359 1440
1360 1441
1361 1442
1362;;; Multiple personalities (:group 'mh-identity) 1443;;; Multiple personalities (:group 'mh-identity)
1363 1444
1445(defvar mh-identity-list ())
1446
1447(defcustom mh-auto-fields-list nil
1448 "Alist of addresses for which header lines are automatically inserted.
1449Each element has the form (REGEXP ((KEYWORD VALUE) (KEYWORD VALUE)).
1450When the REGEXP appears in the To or cc fields of a message, the corresponding
1451KEYWORD header field is insert with its VALUE in the message header.
1452
1453There is one special case for KEYWORD, that of \"identity\", which means to
1454insert that identity using `mh-insert-identity'.
1455
1456The common KEYWORD cases of \"Mail-Followup-To\" and \"fcc\" are also
1457prompted for in the customization interface."
1458 :type `(repeat
1459 (list :tag ""
1460 (string :tag "Regular expression to match")
1461 (repeat :tag "At least one pair from below"
1462 (choice
1463 (cons :tag "Identity entry"
1464 (const "identity")
1465 ,(append
1466 '(radio)
1467 (mapcar (function (lambda (arg) `(const ,arg)))
1468 (mapcar 'car mh-identity-list))))
1469 (cons :tag "fcc field"
1470 (const "fcc")
1471 (string :tag "Value"))
1472 (cons :tag "Mail-Followup-To field"
1473 (const "Mail-Followup-To")
1474 (string :tag "Value"))
1475 (cons :tag "Other field and value pair"
1476 (string :tag "Field")
1477 (string :tag "Value"))))))
1478 :group 'mh-identity)
1479
1480(defcustom mh-identity-default nil
1481 "Default identity to use when `mh-letter-mode' is called."
1482 ;; Dynamically render :type corresponding to `mh-identity-list' entries,
1483 ;; e.g.:
1484 ;; :type '(radio (const :tag "none" nil)
1485 ;; (const "home")
1486 ;; (const "work"))
1487 :type (append
1488 '(radio)
1489 (cons '(const :tag "None" nil)
1490 (mapcar (function (lambda (arg) `(const ,arg)))
1491 (mapcar 'car mh-identity-list))))
1492 :group 'mh-identity)
1493
1364(defcustom mh-identity-list nil 1494(defcustom mh-identity-list nil
1365 "*List holding MH-E identity. 1495 "*List holding MH-E identity.
1366Omit the colon and trailing space from the field names. 1496Omit the colon and trailing space from the field names.
@@ -1408,20 +1538,6 @@ This would produce the equivalent of:
1408 :set 'mh-identity-list-set 1538 :set 'mh-identity-list-set
1409 :group 'mh-identity) 1539 :group 'mh-identity)
1410 1540
1411(defcustom mh-identity-default nil
1412 "Default identity to use when `mh-letter-mode' is called."
1413 ;; Dynamically render :type corresponding to `mh-identity-list' entries,
1414 ;; e.g.:
1415 ;; :type '(radio (const :tag "none" nil)
1416 ;; (const "home")
1417 ;; (const "work"))
1418 :type (append
1419 '(radio)
1420 (cons '(const :tag "None" nil)
1421 (mapcar (function (lambda (arg) `(const ,arg)))
1422 (mapcar 'car mh-identity-list))))
1423 :group 'mh-identity)
1424
1425 1541
1426 1542
1427;;; Hooks (:group 'mh-hooks + group where hook defined) 1543;;; Hooks (:group 'mh-hooks + group where hook defined)
@@ -1481,12 +1597,6 @@ current folder, `mh-current-folder'."
1481 :group 'mh-hooks 1597 :group 'mh-hooks
1482 :group 'mh-folder) 1598 :group 'mh-folder)
1483 1599
1484(defcustom mh-index-show-hook nil
1485 "Invoked after the message has been displayed."
1486 :type 'hook
1487 :group 'mh-hooks
1488 :group 'mh-index)
1489
1490(defcustom mh-letter-insert-signature-hook nil 1600(defcustom mh-letter-insert-signature-hook nil
1491 "Invoked at the beginning of the \\<mh-letter-mode-map>\\[mh-insert-signature] command. 1601 "Invoked at the beginning of the \\<mh-letter-mode-map>\\[mh-insert-signature] command.
1492Can be used to determine which signature file to use based on message content. 1602Can be used to determine which signature file to use based on message content.
@@ -1685,6 +1795,13 @@ will be removed from the unseen sequence."
1685 "Face for highlighting subject text in MH-Folder buffers." 1795 "Face for highlighting subject text in MH-Folder buffers."
1686 :group 'mh-folder-faces) 1796 :group 'mh-folder-faces)
1687 1797
1798(defface mh-folder-tick-face
1799 '((((class color) (background dark)) (:background "#dddf7e"))
1800 (((class color) (background light)) (:background "#dddf7e"))
1801 (t (:underline t)))
1802 "Face used to show ticked messages."
1803 :group 'mh-folder-faces)
1804
1688(defvar mh-folder-address-face 'mh-folder-address-face 1805(defvar mh-folder-address-face 'mh-folder-address-face
1689 "Face for highlighting the address in MH-Folder buffers.") 1806 "Face for highlighting the address in MH-Folder buffers.")
1690(copy-face 'mh-folder-subject-face 'mh-folder-address-face) 1807(copy-face 'mh-folder-subject-face 'mh-folder-address-face)
@@ -1774,6 +1891,12 @@ will be removed from the unseen sequence."
1774 "Face for highlighting the From: header field." 1891 "Face for highlighting the From: header field."
1775 :group 'mh-show-faces) 1892 :group 'mh-show-faces)
1776 1893
1894(defface mh-show-xface-face
1895 '((t (:foreground "black" :background "white")))
1896 "Face for displaying the X-Face image.
1897The background and foreground is used in the image."
1898 :group 'mh-show-faces)
1899
1777(defvar mh-show-subject-face 'mh-show-subject-face 1900(defvar mh-show-subject-face 'mh-show-subject-face
1778 "Face for highlighting the Subject header field.") 1901 "Face for highlighting the Subject header field.")
1779(copy-face 'mh-folder-subject-face 'mh-show-subject-face) 1902(copy-face 'mh-folder-subject-face 'mh-show-subject-face)
diff --git a/lisp/mh-e/mh-e.el b/lisp/mh-e/mh-e.el
index c51d6aa4b8e..ea3a202fe6d 100644
--- a/lisp/mh-e/mh-e.el
+++ b/lisp/mh-e/mh-e.el
@@ -1,10 +1,11 @@
1;;; mh-e.el --- GNU Emacs interface to the MH mail system 1;;; mh-e.el --- GNU Emacs interface to the MH mail system
2 2
3;; Copyright (C) 1985,86,87,88,90,92,93,94,95,97,2000,2001,2002 Free Software Foundation, Inc. 3;; Copyright (C) 1985, 86, 87, 88, 90, 92, 93, 94, 95, 97, 1999,
4;; 2000, 01, 02, 2003 Free Software Foundation, Inc.
4 5
5;; Author: Bill Wohler <wohler@newt.com> 6;; Author: Bill Wohler <wohler@newt.com>
6;; Maintainer: Bill Wohler <wohler@newt.com> 7;; Maintainer: Bill Wohler <wohler@newt.com>
7;; Version: 7.2 8;; Version: 7.3
8;; Keywords: mail 9;; Keywords: mail
9 10
10;; This file is part of GNU Emacs. 11;; This file is part of GNU Emacs.
@@ -79,8 +80,6 @@
79;; Maintenance picked up by Bill Wohler <wohler@newt.com> and the 80;; Maintenance picked up by Bill Wohler <wohler@newt.com> and the
80;; SourceForge Crew <http://mh-e.sourceforge.net/>. 2001. 81;; SourceForge Crew <http://mh-e.sourceforge.net/>. 2001.
81 82
82;; $Id: mh-e.el,v 1.262 2003/02/03 19:11:43 wohler Exp $
83
84;;; Code: 83;;; Code:
85 84
86(require 'cl) 85(require 'cl)
@@ -92,6 +91,7 @@
92 (> 50 recursive-load-depth-limit)) 91 (> 50 recursive-load-depth-limit))
93 (setq recursive-load-depth-limit 50))) 92 (setq recursive-load-depth-limit 50)))
94 93
94(require 'mh-inc)
95(require 'mh-utils) 95(require 'mh-utils)
96(require 'gnus-util) 96(require 'gnus-util)
97(require 'easymenu) 97(require 'easymenu)
@@ -102,7 +102,7 @@
102(defvar font-lock-auto-fontify) 102(defvar font-lock-auto-fontify)
103(defvar font-lock-defaults) 103(defvar font-lock-defaults)
104 104
105(defconst mh-version "7.2" "Version number of MH-E.") 105(defconst mh-version "7.3" "Version number of MH-E.")
106 106
107;;; Autoloads 107;;; Autoloads
108(autoload 'Info-goto-node "info") 108(autoload 'Info-goto-node "info")
@@ -413,7 +413,7 @@ is done highlighting.")
413 (cond 413 (cond
414 ((not mh-folder-unseen-seq-cache) 414 ((not mh-folder-unseen-seq-cache)
415 nil) 415 nil)
416 ((not cur-msg) ;Presumably at end of buffer 416 ((>= (point) limit) ;Presumably at end of buffer
417 (setq mh-folder-unseen-seq-cache nil) 417 (setq mh-folder-unseen-seq-cache nil)
418 nil) 418 nil)
419 ((member cur-msg mh-folder-unseen-seq-cache) 419 ((member cur-msg mh-folder-unseen-seq-cache)
@@ -432,8 +432,7 @@ is done highlighting.")
432 ;; Examine how we must have exited the loop... 432 ;; Examine how we must have exited the loop...
433 (let ((cur-msg (mh-get-msg-num nil))) 433 (let ((cur-msg (mh-get-msg-num nil)))
434 (cond 434 (cond
435 ((or (not cur-msg) 435 ((or (<= limit (point))
436 (<= limit (point))
437 (not (member cur-msg mh-folder-unseen-seq-cache))) 436 (not (member cur-msg mh-folder-unseen-seq-cache)))
438 (setq mh-folder-unseen-seq-cache nil) 437 (setq mh-folder-unseen-seq-cache nil)
439 nil) 438 nil)
@@ -468,6 +467,10 @@ is done highlighting.")
468(defvar mh-narrowed-to-seq nil) ;Sequence display is narrowed to or 467(defvar mh-narrowed-to-seq nil) ;Sequence display is narrowed to or
469 ;nil if not narrowed. 468 ;nil if not narrowed.
470 469
470(defvar mh-tick-seq-changed-when-narrowed-flag nil)
471 ;Has tick sequence changed while the
472 ;folder was narrowed to it?
473
471(defvar mh-view-ops ()) ;Stack of ops that change the folder 474(defvar mh-view-ops ()) ;Stack of ops that change the folder
472 ;view (such as narrowing or threading). 475 ;view (such as narrowing or threading).
473 476
@@ -535,34 +538,27 @@ the Emacs front end to the MH mail system."
535 538
536(defun mh-delete-msg (msg-or-seq) 539(defun mh-delete-msg (msg-or-seq)
537 "Mark the specified MSG-OR-SEQ for subsequent deletion and move to the next. 540 "Mark the specified MSG-OR-SEQ for subsequent deletion and move to the next.
538 541Default is the displayed message.
539Default is the displayed message. If optional prefix argument is given then 542If optional prefix argument is provided, then prompt for the message sequence.
540prompt for the message sequence. If variable `transient-mark-mode' is non-nil 543If variable `transient-mark-mode' is non-nil and the mark is active, then the
541and the mark is active, then the selected region is marked for deletion." 544selected region is marked for deletion.
542 (interactive (list (cond 545In a program, MSG-OR-SEQ can be a message number, a list of message numbers, a
543 ((mh-mark-active-p t) 546region in a cons cell, or a sequence."
544 (cons (region-beginning) (region-end))) 547 (interactive (list (mh-interactive-msg-or-seq "Delete")))
545 (current-prefix-arg
546 (mh-read-seq-default "Delete" t))
547 (t
548 (cons (line-beginning-position) (line-end-position))))))
549 (mh-delete-msg-no-motion msg-or-seq) 548 (mh-delete-msg-no-motion msg-or-seq)
550 (mh-next-msg)) 549 (mh-next-msg))
551 550
552(defun mh-delete-msg-no-motion (msg-or-seq) 551(defun mh-delete-msg-no-motion (msg-or-seq)
553 "Mark the specified MSG-OR-SEQ for subsequent deletion. 552 "Mark the specified MSG-OR-SEQ for subsequent deletion.
554Default is the displayed message. If optional prefix argument is provided, 553Default is the displayed message.
555then prompt for the message sequence." 554If optional prefix argument is provided, then prompt for the message sequence.
556 (interactive (list (if current-prefix-arg 555If variable `transient-mark-mode' is non-nil and the mark is active, then the
557 (mh-read-seq-default "Delete" t) 556selected region is marked for deletion.
558 (mh-get-msg-num t)))) 557In a program, MSG-OR-SEQ can be a message number, a list of message numbers, a
559 (cond ((numberp msg-or-seq) 558region in a cons cell, or a sequence."
560 (mh-delete-a-msg msg-or-seq)) 559 (interactive (list (mh-interactive-msg-or-seq "Delete")))
561 ((and (consp msg-or-seq) 560 (mh-iterate-on-msg-or-seq () msg-or-seq
562 (numberp (car msg-or-seq)) (numberp (cdr msg-or-seq))) 561 (mh-delete-a-msg nil)))
563 (mh-iterate-on-messages-in-region () (car msg-or-seq) (cdr msg-or-seq)
564 (mh-delete-a-msg nil)))
565 (t (mh-map-to-seq-msgs 'mh-delete-a-msg msg-or-seq))))
566 562
567(defun mh-execute-commands () 563(defun mh-execute-commands ()
568 "Process outstanding delete and refile requests." 564 "Process outstanding delete and refile requests."
@@ -593,7 +589,6 @@ Type \"\\[mh-show]\" to show the message normally again."
593 (mh-invalidate-show-buffer)) 589 (mh-invalidate-show-buffer))
594 (let ((mh-decode-mime-flag nil) 590 (let ((mh-decode-mime-flag nil)
595 (mhl-formfile nil) 591 (mhl-formfile nil)
596 (mh-decode-content-transfer-encoded-message-flag nil)
597 (mh-clean-message-header-flag nil)) 592 (mh-clean-message-header-flag nil))
598 (mh-show-msg nil) 593 (mh-show-msg nil)
599 (mh-in-show-buffer (mh-show-buffer) 594 (mh-in-show-buffer (mh-show-buffer)
@@ -601,28 +596,31 @@ Type \"\\[mh-show]\" to show the message normally again."
601 (mh-recenter 0)) 596 (mh-recenter 0))
602 (setq mh-showing-with-headers t))) 597 (setq mh-showing-with-headers t)))
603 598
604(defun mh-inc-folder (&optional maildrop-name) 599(defun mh-inc-folder (&optional maildrop-name folder)
605 "Inc(orporate)s new mail into the Inbox folder. 600 "Inc(orporate)s new mail into the Inbox folder.
606Optional argument MAILDROP-NAME specifies an alternate maildrop from the 601Optional argument MAILDROP-NAME specifies an alternate maildrop from the
607default. If the prefix argument is given, incorporates mail into the current 602default. The optional argument FOLDER specifies where to incorporate mail
608folder, otherwise uses the folder named by `mh-inbox'. 603instead of the default named by `mh-inbox'.
609The value of `mh-inc-folder-hook' is a list of functions to be called, with no 604The value of `mh-inc-folder-hook' is a list of functions to be called, with no
610arguments, after incorporating new mail. 605arguments, after incorporating new mail.
611Do not call this function from outside MH-E; use \\[mh-rmail] instead." 606Do not call this function from outside MH-E; use \\[mh-rmail] instead."
612 (interactive (list (if current-prefix-arg 607 (interactive (list (if current-prefix-arg
613 (expand-file-name 608 (expand-file-name
614 (read-file-name "inc mail from file: " 609 (read-file-name "inc mail from file: "
615 mh-user-path))))) 610 mh-user-path)))
611 (if current-prefix-arg
612 (mh-prompt-for-folder "inc mail into" mh-inbox t))))
613 (if (not folder)
614 (setq folder mh-inbox))
616 (let ((threading-needed-flag nil)) 615 (let ((threading-needed-flag nil))
617 (let ((config (current-window-configuration))) 616 (let ((config (current-window-configuration)))
618 (if (not maildrop-name) 617 (cond ((not (get-buffer folder))
619 (cond ((not (get-buffer mh-inbox)) 618 (mh-make-folder folder)
620 (mh-make-folder mh-inbox) 619 (setq threading-needed-flag mh-show-threads-flag)
621 (setq threading-needed-flag mh-show-threads-flag) 620 (setq mh-previous-window-config config))
622 (setq mh-previous-window-config config)) 621 ((not (eq (current-buffer) (get-buffer folder)))
623 ((not (eq (current-buffer) (get-buffer mh-inbox))) 622 (switch-to-buffer folder)
624 (switch-to-buffer mh-inbox) 623 (setq mh-previous-window-config config))))
625 (setq mh-previous-window-config config)))))
626 (mh-get-new-mail maildrop-name) 624 (mh-get-new-mail maildrop-name)
627 (when (and threading-needed-flag 625 (when (and threading-needed-flag
628 (save-excursion 626 (save-excursion
@@ -632,7 +630,8 @@ Do not call this function from outside MH-E; use \\[mh-rmail] instead."
632 (and (message "Not threading since the number of messages exceeds `mh-large-folder'") 630 (and (message "Not threading since the number of messages exceeds `mh-large-folder'")
633 nil)))) 631 nil))))
634 (mh-toggle-threads)) 632 (mh-toggle-threads))
635 (if mh-showing-mode (mh-show)) 633 (beginning-of-line)
634 (if (and mh-showing-mode (looking-at mh-scan-valid-regexp)) (mh-show))
636 (run-hooks 'mh-inc-folder-hook))) 635 (run-hooks 'mh-inc-folder-hook)))
637 636
638(defun mh-last-msg () 637(defun mh-last-msg ()
@@ -643,8 +642,10 @@ Do not call this function from outside MH-E; use \\[mh-rmail] instead."
643 (forward-line -1)) 642 (forward-line -1))
644 (mh-recenter nil)) 643 (mh-recenter nil))
645 644
646(defun mh-next-undeleted-msg (&optional arg) 645(defun mh-next-undeleted-msg (&optional arg wait-after-complaining-flag)
647 "Move to the next undeleted message ARG in window." 646 "Move to the next undeleted message ARG in window.
647If optional argument WAIT-AFTER-COMPLAINING-FLAG is non-nil and we are at the
648last undeleted message then pause for a second after printing message."
648 (interactive "p") 649 (interactive "p")
649 (setq mh-next-direction 'forward) 650 (setq mh-next-direction 'forward)
650 (forward-line 1) 651 (forward-line 1)
@@ -652,38 +653,73 @@ Do not call this function from outside MH-E; use \\[mh-rmail] instead."
652 (beginning-of-line) 653 (beginning-of-line)
653 (mh-maybe-show)) 654 (mh-maybe-show))
654 (t (forward-line -1) 655 (t (forward-line -1)
655 (message "No more undeleted messages")))) 656 (message "No more undeleted messages")
657 (if wait-after-complaining-flag (sit-for 1)))))
656 658
657(defun mh-folder-from-address () 659(defun mh-folder-from-address ()
658 "Determine folder name from address in From field. 660 "Determine folder name from address in From field.
659Takes the address in the From: header field, and returns one of: 661Takes the address in the From: header field, and returns one of:
660 662
661 a) The folder name associated with the address in the alist 663 a) The folder name associated with the address in the alist
662 `mh-default-folder-list'. 664 `mh-default-folder-list'. If the `Check Recipient' boolean
665 is set, then the `mh-default-folder-list' addresses are
666 checked against the recipient instead of the originator
667 (making possible to use this feature for mailing lists).
668 The first match found in `mh-default-folder-list' is used.
663 669
664 b) The address' corresponding alias from the user's personal 670 b) The address' corresponding alias from the user's personal
665 aliases file prefixed by `mh-default-folder-prefix'. 671 aliases file prefixed by `mh-default-folder-prefix'.
666 672
667Returns nil if the address was not found in either place or if the variable 673Returns nil if the address was not found in either place or if the variable
668`mh-default-folder-must-exist-flag' is nil and the folder does not exist." 674`mh-default-folder-must-exist-flag' is nil and the folder does not exist."
669 ;; Is address in mh-default-folder-list? 675 ;; Loop for all entries in mh-default-folder-list
670 (let* ((address 676 (save-excursion
671 (nth 1 (mail-extract-address-components 677 (let ((folder-name
672 (mh-extract-from-header-value)))) 678 (car
673 (folder-name 679 (delq nil
674 (nth 1 (assoc-ignore-case address mh-default-folder-list)))) 680 (mapcar
675 681 (lambda (list)
676 ;; If not, is there an alias for the address? 682 (let ((address-regexp (nth 0 list))
677 (if (not folder-name) 683 (folder (nth 1 list))
678 (let* ((alias (mh-alias-address-to-alias address))) 684 (to-flag (nth 2 list)))
679 (setq folder-name 685 (when (or
680 (and alias (concat "+" mh-default-folder-prefix alias))))) 686 (mh-goto-header-field (if to-flag "To:" "From:"))
681 687 ; if the To: field is missing, try Cc:
682 ;; If mh-default-folder-must-exist-flag set, check that folder exists. 688 (and to-flag (mh-goto-header-field "cc:")))
683 (if (and folder-name 689 (let ((endfield (save-excursion
684 (or (not mh-default-folder-must-exist-flag) 690 (mh-header-field-end)(point))))
685 (file-exists-p (mh-expand-file-name folder-name)))) 691 (if (re-search-forward address-regexp endfield t)
686 folder-name))) 692 folder
693 (when to-flag ;Try Cc: as well
694 (mh-goto-header-field "cc:")
695 (let ((endfield (save-excursion
696 (mh-header-field-end)(point))))
697 (when (re-search-forward
698 address-regexp endfield t)
699 folder))))))))
700 mh-default-folder-list)))))
701
702 ;; Make sure a result from `mh-default-folder-list' begins with "+"
703 ;; since 'mh-expand-file-name below depends on it
704 (when (and folder-name (not (eq (aref folder-name 0) ?+)))
705 (setq folder-name (concat "+" folder-name)))
706
707 ;; If not, is there an alias for the address?
708 (when (not folder-name)
709 (let* ((from-header (mh-extract-from-header-value))
710 (address (and from-header
711 (nth 1 (mail-extract-address-components
712 from-header))))
713 (alias (and address (mh-alias-address-to-alias address))))
714 (when alias
715 (setq folder-name
716 (and alias (concat "+" mh-default-folder-prefix alias))))))
717
718 ;; If mh-default-folder-must-exist-flag set, check that folder exists.
719 (if (and folder-name
720 (or (not mh-default-folder-must-exist-flag)
721 (file-exists-p (mh-expand-file-name folder-name))))
722 folder-name))))
687 723
688(defun mh-prompt-for-refile-folder () 724(defun mh-prompt-for-refile-folder ()
689 "Prompt the user for a folder in which the message should be filed. 725 "Prompt the user for a folder in which the message should be filed.
@@ -710,29 +746,26 @@ Otherwise, a default folder name is generated by `mh-folder-from-address'."
710 ""))) 746 "")))
711 t)) 747 t))
712 748
713(defun mh-refile-msg (msg-or-seq folder) 749(defun mh-refile-msg (msg-or-seq folder
714 "Refile MSG-OR-SEQ (default: displayed message) into FOLDER. 750 &optional dont-update-last-destination-flag)
715If optional prefix argument provided, then prompt for message sequence. 751 "Refile MSG-OR-SEQ into FOLDER.
752Default is the displayed message.
753If optional prefix argument is provided, then prompt for the message sequence.
716If variable `transient-mark-mode' is non-nil and the mark is active, then the 754If variable `transient-mark-mode' is non-nil and the mark is active, then the
717selected region is marked for refiling." 755selected region is marked for refiling.
718 (interactive 756In a program, MSG-OR-SEQ can be a message number, a list of message numbers, a
719 (list (cond 757region in a cons cell, or a sequence.
720 ((mh-mark-active-p t) 758
721 (cons (region-beginning) (region-end))) 759If optional argument DONT-UPDATE-LAST-DESTINATION-FLAG is non-nil then the
722 (current-prefix-arg 760variables `mh-last-destination' and `mh-last-destination-folder' are not
723 (mh-read-seq-default "Refile" t)) 761updated."
724 (t 762 (interactive (list (mh-interactive-msg-or-seq "Refile")
725 (cons (line-beginning-position) (line-end-position)))) 763 (intern (mh-prompt-for-refile-folder))))
726 (intern (mh-prompt-for-refile-folder)))) 764 (unless dont-update-last-destination-flag
727 (setq mh-last-destination (cons 'refile folder) 765 (setq mh-last-destination (cons 'refile folder)
728 mh-last-destination-folder mh-last-destination) 766 mh-last-destination-folder mh-last-destination))
729 (cond ((numberp msg-or-seq) 767 (mh-iterate-on-msg-or-seq () msg-or-seq
730 (mh-refile-a-msg msg-or-seq folder)) 768 (mh-refile-a-msg nil folder))
731 ((and (consp msg-or-seq)
732 (numberp (car msg-or-seq)) (numberp (cdr msg-or-seq)))
733 (mh-iterate-on-messages-in-region () (car msg-or-seq) (cdr msg-or-seq)
734 (mh-refile-a-msg nil folder)))
735 (t (mh-map-to-seq-msgs 'mh-refile-a-msg msg-or-seq folder)))
736 (mh-next-msg)) 769 (mh-next-msg))
737 770
738(defun mh-refile-or-write-again (message) 771(defun mh-refile-or-write-again (message)
@@ -742,13 +775,16 @@ refile or write command."
742 (interactive (list (mh-get-msg-num t))) 775 (interactive (list (mh-get-msg-num t)))
743 (if (null mh-last-destination) 776 (if (null mh-last-destination)
744 (error "No previous refile or write")) 777 (error "No previous refile or write"))
745 (cond ((eq (car mh-last-destination) 'refile) 778 (let (output)
746 (mh-refile-a-msg message (cdr mh-last-destination)) 779 (setq output
747 (message "Destination folder: %s" (cdr mh-last-destination))) 780 (cond ((eq (car mh-last-destination) 'refile)
748 (t 781 (mh-refile-a-msg message (cdr mh-last-destination))
749 (apply 'mh-write-msg-to-file message (cdr mh-last-destination)) 782 (format "Destination folder: %s" (cdr mh-last-destination)))
750 (message "Destination: %s" (cdr mh-last-destination)))) 783 (t
751 (mh-next-msg)) 784 (apply 'mh-write-msg-to-file message (cdr mh-last-destination))
785 (format "Destination: %s" (cdr mh-last-destination)))))
786 (mh-next-msg (interactive-p))
787 (message output)))
752 788
753(defun mh-quit () 789(defun mh-quit ()
754 "Quit the current MH-E folder. 790 "Quit the current MH-E folder.
@@ -809,14 +845,17 @@ Scrolls ARG lines or a full screen if no argument is supplied."
809 (mh-in-show-buffer (mh-show-buffer) 845 (mh-in-show-buffer (mh-show-buffer)
810 (scroll-down arg))) 846 (scroll-down arg)))
811 847
812(defun mh-previous-undeleted-msg (&optional arg) 848(defun mh-previous-undeleted-msg (&optional arg wait-after-complaining-flag)
813 "Move to the previous undeleted message ARG in window." 849 "Move to the previous undeleted message ARG in window.
850If optional argument WAIT-AFTER-COMPLAINING-FLAG is non-nil and we are at the
851first undeleted message then pause for a second after printing message."
814 (interactive "p") 852 (interactive "p")
815 (setq mh-next-direction 'backward) 853 (setq mh-next-direction 'backward)
816 (beginning-of-line) 854 (beginning-of-line)
817 (cond ((re-search-backward mh-scan-good-msg-regexp nil t arg) 855 (cond ((re-search-backward mh-scan-good-msg-regexp nil t arg)
818 (mh-maybe-show)) 856 (mh-maybe-show))
819 (t (message "No previous undeleted message")))) 857 (t (message "No previous undeleted message")
858 (if wait-after-complaining-flag (sit-for 1)))))
820 859
821(defun mh-previous-unread-msg (&optional count) 860(defun mh-previous-unread-msg (&optional count)
822 "Move to previous unread message. 861 "Move to previous unread message.
@@ -994,7 +1033,6 @@ refiles aren't carried out."
994 nil))) 1033 nil)))
995 (setq mh-next-direction 'forward) 1034 (setq mh-next-direction 'forward)
996 (let ((threaded-flag (memq 'unthread mh-view-ops))) 1035 (let ((threaded-flag (memq 'unthread mh-view-ops)))
997 (mh-reset-threads-and-narrowing)
998 (mh-scan-folder mh-current-folder (or range "all") dont-exec-pending) 1036 (mh-scan-folder mh-current-folder (or range "all") dont-exec-pending)
999 (cond (threaded-flag (mh-toggle-threads)) 1037 (cond (threaded-flag (mh-toggle-threads))
1000 (mh-index-data (mh-index-insert-folder-headers))))) 1038 (mh-index-data (mh-index-insert-folder-headers)))))
@@ -1040,14 +1078,10 @@ Otherwise send the entire message including the headers."
1040Default is the displayed message. 1078Default is the displayed message.
1041If optional prefix argument is provided, then prompt for the message sequence. 1079If optional prefix argument is provided, then prompt for the message sequence.
1042If variable `transient-mark-mode' is non-nil and the mark is active, then the 1080If variable `transient-mark-mode' is non-nil and the mark is active, then the
1043selected region is unmarked." 1081selected region is unmarked.
1044 (interactive (list (cond 1082In a program, MSG-OR-SEQ can be a message number, a list of message numbers, a
1045 ((mh-mark-active-p t) 1083region in a cons cell, or a sequence."
1046 (cons (region-beginning) (region-end))) 1084 (interactive (list (mh-interactive-msg-or-seq "Undo")))
1047 (current-prefix-arg
1048 (mh-read-seq-default "Undo" t))
1049 (t
1050 (mh-get-msg-num t)))))
1051 (cond ((numberp msg-or-seq) 1085 (cond ((numberp msg-or-seq)
1052 (let ((original-position (point))) 1086 (let ((original-position (point)))
1053 (beginning-of-line) 1087 (beginning-of-line)
@@ -1064,12 +1098,8 @@ selected region is unmarked."
1064 (mh-maybe-show)) 1098 (mh-maybe-show))
1065 (goto-char original-position) 1099 (goto-char original-position)
1066 (error "Nothing to undo")))) 1100 (error "Nothing to undo"))))
1067 ((and (consp msg-or-seq) 1101 (t (mh-iterate-on-msg-or-seq () msg-or-seq
1068 (numberp (car msg-or-seq)) (numberp (cdr msg-or-seq))) 1102 (mh-undo-msg nil))))
1069 (mh-iterate-on-messages-in-region () (car msg-or-seq) (cdr msg-or-seq)
1070 (mh-undo-msg nil)))
1071 (t
1072 (mh-map-to-seq-msgs 'mh-undo-msg msg-or-seq)))
1073 (if (not (mh-outstanding-commands-p)) 1103 (if (not (mh-outstanding-commands-p))
1074 (mh-set-folder-modified-p nil))) 1104 (mh-set-folder-modified-p nil)))
1075 1105
@@ -1176,10 +1206,10 @@ used to avoid problems in corner cases involving folders whose names end with a
1176 (call-process (expand-file-name "flist" mh-progs) nil t nil 1206 (call-process (expand-file-name "flist" mh-progs) nil t nil
1177 "-norecurse" folder "-sequence" (symbol-name mh-unseen-seq)) 1207 "-norecurse" folder "-sequence" (symbol-name mh-unseen-seq))
1178 (goto-char (point-min)) 1208 (goto-char (point-min))
1179 (multiple-value-bind (folder1 unseen total) 1209 (multiple-value-bind (folder unseen total)
1180 (mh-parse-flist-output-line 1210 (mh-parse-flist-output-line
1181 (buffer-substring (point) (line-end-position))) 1211 (buffer-substring (point) (line-end-position)))
1182 (values total unseen)))) 1212 (values total unseen folder))))
1183 1213
1184(defun mh-visit-folder (folder &optional range index-data) 1214(defun mh-visit-folder (folder &optional range index-data)
1185 "Visit FOLDER and display RANGE of messages. 1215 "Visit FOLDER and display RANGE of messages.
@@ -1197,12 +1227,12 @@ regardless of the size of the `mh-large-folder' variable."
1197 (list folder-name 1227 (list folder-name
1198 (mh-read-msg-range folder-name current-prefix-arg)))) 1228 (mh-read-msg-range folder-name current-prefix-arg))))
1199 (let ((config (current-window-configuration)) 1229 (let ((config (current-window-configuration))
1230 (current-buffer (current-buffer))
1200 (threaded-view-flag mh-show-threads-flag)) 1231 (threaded-view-flag mh-show-threads-flag))
1201 (save-excursion 1232 (save-excursion
1202 (when (get-buffer folder) 1233 (when (get-buffer folder)
1203 (set-buffer folder) 1234 (set-buffer folder)
1204 (setq threaded-view-flag (memq 'unthread mh-view-ops)) 1235 (setq threaded-view-flag (memq 'unthread mh-view-ops))))
1205 (mh-reset-threads-and-narrowing)))
1206 (when index-data 1236 (when index-data
1207 (mh-make-folder folder) 1237 (mh-make-folder folder)
1208 (setq mh-index-data (car index-data) 1238 (setq mh-index-data (car index-data)
@@ -1221,7 +1251,8 @@ regardless of the size of the `mh-large-folder' variable."
1221 (mh-index-data 1251 (mh-index-data
1222 (mh-index-insert-folder-headers))) 1252 (mh-index-insert-folder-headers)))
1223 (unless mh-showing-mode (delete-other-windows)) 1253 (unless mh-showing-mode (delete-other-windows))
1224 (setq mh-previous-window-config config)) 1254 (unless (eq current-buffer (current-buffer))
1255 (setq mh-previous-window-config config)))
1225 nil) 1256 nil)
1226 1257
1227;;;###mh-autoload 1258;;;###mh-autoload
@@ -1305,11 +1336,14 @@ arguments, after the message has been refiled."
1305 (mh-notate nil mh-note-refiled mh-cmd-note) 1336 (mh-notate nil mh-note-refiled mh-cmd-note)
1306 (run-hooks 'mh-refile-msg-hook))))) 1337 (run-hooks 'mh-refile-msg-hook)))))
1307 1338
1308(defun mh-next-msg () 1339(defun mh-next-msg (&optional wait-after-complaining-flag)
1309 "Move backward or forward to the next undeleted message in the buffer." 1340 "Move backward or forward to the next undeleted message in the buffer.
1341If optional argument WAIT-AFTER-COMPLAINING-FLAG is non-nil and we are at the
1342last message, then wait for a second after telling the user that there aren't
1343any more unread messages."
1310 (if (eq mh-next-direction 'forward) 1344 (if (eq mh-next-direction 'forward)
1311 (mh-next-undeleted-msg 1) 1345 (mh-next-undeleted-msg 1 wait-after-complaining-flag)
1312 (mh-previous-undeleted-msg 1))) 1346 (mh-previous-undeleted-msg 1 wait-after-complaining-flag)))
1313 1347
1314(defun mh-next-unread-msg (&optional count) 1348(defun mh-next-unread-msg (&optional count)
1315 "Move to next unread message. 1349 "Move to next unread message.
@@ -1406,7 +1440,10 @@ Make it the current folder."
1406 ["Widen from Sequence" mh-widen mh-narrowed-to-seq] 1440 ["Widen from Sequence" mh-widen mh-narrowed-to-seq]
1407 "--" 1441 "--"
1408 ["Narrow to Subject Sequence" mh-narrow-to-subject t] 1442 ["Narrow to Subject Sequence" mh-narrow-to-subject t]
1443 ["Narrow to Tick Sequence" mh-narrow-to-tick
1444 (and mh-tick-seq (mh-seq-msgs (mh-find-seq mh-tick-seq)))]
1409 ["Delete Rest of Same Subject" mh-delete-subject t] 1445 ["Delete Rest of Same Subject" mh-delete-subject t]
1446 ["Toggle Tick Mark" mh-toggle-tick t]
1410 "--" 1447 "--"
1411 ["Push State Out to MH" mh-update-sequences t])) 1448 ["Push State Out to MH" mh-update-sequences t]))
1412 1449
@@ -1459,6 +1496,7 @@ Make it the current folder."
1459 "--" 1496 "--"
1460 ["List Folders" mh-list-folders t] 1497 ["List Folders" mh-list-folders t]
1461 ["Visit a Folder..." mh-visit-folder t] 1498 ["Visit a Folder..." mh-visit-folder t]
1499 ["View New Messages" mh-index-new-messages t]
1462 ["Search a Folder..." mh-search-folder t] 1500 ["Search a Folder..." mh-search-folder t]
1463 ["Indexed Search..." mh-index-search t] 1501 ["Indexed Search..." mh-index-search t]
1464 "--" 1502 "--"
@@ -1474,6 +1512,9 @@ Make it the current folder."
1474 (set-specifier horizontal-scrollbar-visible-p nil 1512 (set-specifier horizontal-scrollbar-visible-p nil
1475 (cons (current-buffer) nil))))) 1513 (cons (current-buffer) nil)))))
1476 1514
1515;; Avoid compiler warnings in XEmacs and GNU Emacs 20
1516(eval-when-compile (defvar tool-bar-mode))
1517
1477(defmacro mh-write-file-functions-compat () 1518(defmacro mh-write-file-functions-compat ()
1478 "Return `write-file-functions' if it exists. 1519 "Return `write-file-functions' if it exists.
1479Otherwise return `local-write-file-hooks'. This macro exists purely for 1520Otherwise return `local-write-file-hooks'. This macro exists purely for
@@ -1483,6 +1524,9 @@ is used in previous versions and XEmacs."
1483 ''write-file-functions ;Emacs 21.4 1524 ''write-file-functions ;Emacs 21.4
1484 ''local-write-file-hooks)) ;<Emacs 21.4, XEmacs 1525 ''local-write-file-hooks)) ;<Emacs 21.4, XEmacs
1485 1526
1527;; Avoid compiler warning
1528(defvar tool-bar-map)
1529
1486(define-derived-mode mh-folder-mode fundamental-mode "MH-Folder" 1530(define-derived-mode mh-folder-mode fundamental-mode "MH-Folder"
1487 "Major MH-E mode for \"editing\" an MH folder scan listing.\\<mh-folder-mode-map> 1531 "Major MH-E mode for \"editing\" an MH folder scan listing.\\<mh-folder-mode-map>
1488 1532
@@ -1519,6 +1563,8 @@ When a folder is visited, the hook `mh-folder-mode-hook' is run.
1519 'mh-seen-list nil ; List of displayed messages 1563 'mh-seen-list nil ; List of displayed messages
1520 'mh-next-direction 'forward ; Direction to move to next message 1564 'mh-next-direction 'forward ; Direction to move to next message
1521 'mh-narrowed-to-seq nil ; Sequence display is narrowed to 1565 'mh-narrowed-to-seq nil ; Sequence display is narrowed to
1566 'mh-tick-seq-changed-when-narrowed-flag nil
1567 ; Tick seq changed while narrowed
1522 'mh-view-ops () ; Stack that keeps track of the order 1568 'mh-view-ops () ; Stack that keeps track of the order
1523 ; in which narrowing/threading has been 1569 ; in which narrowing/threading has been
1524 ; carried out. 1570 ; carried out.
@@ -1537,11 +1583,11 @@ When a folder is visited, the hook `mh-folder-mode-hook' is run.
1537 (setq truncate-lines t) 1583 (setq truncate-lines t)
1538 (auto-save-mode -1) 1584 (auto-save-mode -1)
1539 (setq buffer-offer-save t) 1585 (setq buffer-offer-save t)
1586 (mh-make-local-hook (mh-write-file-functions-compat))
1540 (add-hook (mh-write-file-functions-compat) 'mh-execute-commands nil t) 1587 (add-hook (mh-write-file-functions-compat) 'mh-execute-commands nil t)
1541 (make-local-variable 'revert-buffer-function) 1588 (make-local-variable 'revert-buffer-function)
1542 (make-local-variable 'hl-line-mode) ; avoid pollution 1589 (make-local-variable 'hl-line-mode) ; avoid pollution
1543 (if (fboundp 'hl-line-mode) 1590 (mh-funcall-if-exists hl-line-mode 1)
1544 (hl-line-mode 1))
1545 (setq revert-buffer-function 'mh-undo-folder) 1591 (setq revert-buffer-function 'mh-undo-folder)
1546 (or (assq 'mh-showing-mode minor-mode-alist) 1592 (or (assq 'mh-showing-mode minor-mode-alist)
1547 (setq minor-mode-alist 1593 (setq minor-mode-alist
@@ -1551,6 +1597,7 @@ When a folder is visited, the hook `mh-folder-mode-hook' is run.
1551 (easy-menu-add mh-folder-folder-menu) 1597 (easy-menu-add mh-folder-folder-menu)
1552 (if (and (boundp 'tool-bar-mode) tool-bar-mode) 1598 (if (and (boundp 'tool-bar-mode) tool-bar-mode)
1553 (set (make-local-variable 'tool-bar-map) mh-folder-tool-bar-map)) 1599 (set (make-local-variable 'tool-bar-map) mh-folder-tool-bar-map))
1600 (mh-funcall-if-exists mh-toolbar-init :folder)
1554 (if (and mh-xemacs-flag 1601 (if (and mh-xemacs-flag
1555 font-lock-auto-fontify) 1602 font-lock-auto-fontify)
1556 (turn-on-font-lock))) ; Force font-lock in XEmacs. 1603 (turn-on-font-lock))) ; Force font-lock in XEmacs.
@@ -1570,7 +1617,9 @@ Return in the folder's buffer."
1570 (cond ((null (get-buffer folder)) 1617 (cond ((null (get-buffer folder))
1571 (mh-make-folder folder)) 1618 (mh-make-folder folder))
1572 (t 1619 (t
1573 (or dont-exec-pending (mh-process-or-undo-commands folder)) 1620 (unless dont-exec-pending
1621 (mh-process-or-undo-commands folder)
1622 (mh-reset-threads-and-narrowing))
1574 (switch-to-buffer folder))) 1623 (switch-to-buffer folder)))
1575 (mh-regenerate-headers range) 1624 (mh-regenerate-headers range)
1576 (if (zerop (buffer-size)) 1625 (if (zerop (buffer-size))
@@ -1578,7 +1627,7 @@ Return in the folder's buffer."
1578 (message "Folder %s is empty" folder) 1627 (message "Folder %s is empty" folder)
1579 (message "No messages in %s, range %s" folder range)) 1628 (message "No messages in %s, range %s" folder range))
1580 (mh-goto-cur-msg)) 1629 (mh-goto-cur-msg))
1581 (when dont-exec-pending 1630 (when (mh-outstanding-commands-p)
1582 (mh-notate-deleted-and-refiled))) 1631 (mh-notate-deleted-and-refiled)))
1583 1632
1584(defun mh-set-cmd-note (width) 1633(defun mh-set-cmd-note (width)
@@ -1742,6 +1791,8 @@ Return in the current buffer."
1742 (if new-mail-flag 1791 (if new-mail-flag
1743 (progn 1792 (progn
1744 (mh-make-folder-mode-line) 1793 (mh-make-folder-mode-line)
1794 (when (mh-speed-flists-active-p)
1795 (mh-speed-flists t mh-current-folder))
1745 (when (memq 'unthread mh-view-ops) 1796 (when (memq 'unthread mh-view-ops)
1746 (mh-thread-inc folder start-of-inc)) 1797 (mh-thread-inc folder start-of-inc))
1747 (mh-goto-cur-msg)) 1798 (mh-goto-cur-msg))
@@ -1861,8 +1912,9 @@ Called by functions like `mh-sort-folder', so also invalidate show buffer."
1861 (if (mh-outstanding-commands-p) 1912 (if (mh-outstanding-commands-p)
1862 (if (or mh-do-not-confirm-flag 1913 (if (or mh-do-not-confirm-flag
1863 (y-or-n-p 1914 (y-or-n-p
1864 "Process outstanding deletes and refiles (or lose them)? ")) 1915 "Process outstanding deletes and refiles? "))
1865 (mh-process-commands folder) 1916 (mh-process-commands folder)
1917 (set-buffer folder)
1866 (mh-undo-folder))) 1918 (mh-undo-folder)))
1867 (mh-update-unseen) 1919 (mh-update-unseen)
1868 (mh-invalidate-show-buffer)) 1920 (mh-invalidate-show-buffer))
@@ -1914,6 +1966,8 @@ with no arguments, before the commands are processed."
1914 1966
1915 ;; Redraw folder buffer if needed 1967 ;; Redraw folder buffer if needed
1916 (when (and redraw-needed-flag) 1968 (when (and redraw-needed-flag)
1969 (when (mh-speed-flists-active-p)
1970 (mh-speed-flists t mh-current-folder))
1917 (cond ((memq 'unthread mh-view-ops) (mh-thread-inc folder (point-max))) 1971 (cond ((memq 'unthread mh-view-ops) (mh-thread-inc folder (point-max)))
1918 (mh-index-data (mh-index-insert-folder-headers))))) 1972 (mh-index-data (mh-index-insert-folder-headers)))))
1919 1973
@@ -1962,10 +2016,10 @@ with no arguments, after the unseen sequence is updated."
1962 (or mh-delete-list mh-refile-list)) 2016 (or mh-delete-list mh-refile-list))
1963 2017
1964(defun mh-coalesce-msg-list (messages) 2018(defun mh-coalesce-msg-list (messages)
1965 "Give a list of MESSAGES, return a list of message number ranges. 2019 "Given a list of MESSAGES, return a list of message number ranges.
1966Sort of the opposite of `mh-read-msg-list', which expands ranges. 2020This is the inverse of `mh-read-msg-list', which expands ranges.
1967Message lists passed to MH programs go through this so 2021Message lists passed to MH programs should be processed by this function
1968command line arguments won't exceed system limits." 2022to avoid exceeding system command line argument limits."
1969 (let ((msgs (sort (copy-sequence messages) 'mh-greaterp)) 2023 (let ((msgs (sort (copy-sequence messages) 'mh-greaterp))
1970 (range-high nil) 2024 (range-high nil)
1971 (prev -1) 2025 (prev -1)
@@ -2059,44 +2113,84 @@ Expands ranges into set of individual numbers."
2059 (setq msgs (cons num msgs))))) 2113 (setq msgs (cons num msgs)))))
2060 msgs)) 2114 msgs))
2061 2115
2062(defun mh-notate-user-sequences () 2116(defun mh-notate-user-sequences (&optional msg-or-seq)
2063 "Mark the scan listing of all messages in user-defined sequences." 2117 "Mark user-defined sequences in the messages specified by MSG-OR-SEQ.
2118The optional argument MSG-OR-SEQ can be a message number, a list of message
2119numbers, a sequence, a region in a cons cell, or nil in which case all
2120messages in the folder buffer are notated."
2121 (unless msg-or-seq
2122 (setq msg-or-seq (cons (point-min) (point-max))))
2064 (let ((seqs mh-seq-list) 2123 (let ((seqs mh-seq-list)
2065 (msg-hash (make-hash-table))) 2124 (msg-hash (make-hash-table))
2125 (tick-msgs (and mh-tick-seq (mh-seq-msgs (mh-find-seq mh-tick-seq)))))
2066 (dolist (seq seqs) 2126 (dolist (seq seqs)
2067 (unless (mh-internal-seq (mh-seq-name seq)) 2127 (unless (mh-internal-seq (mh-seq-name seq))
2068 (dolist (msg (mh-seq-msgs seq)) 2128 (dolist (msg (mh-seq-msgs seq))
2069 (setf (gethash msg msg-hash) t)))) 2129 (setf (gethash msg msg-hash) t))))
2070 (mh-iterate-on-messages-in-region msg (point-min) (point-max) 2130 (mh-iterate-on-msg-or-seq msg msg-or-seq
2071 (when (gethash msg msg-hash) 2131 (when (gethash msg msg-hash)
2072 (mh-notate nil mh-note-seq (1+ mh-cmd-note)))))) 2132 (mh-notate nil mh-note-seq (1+ mh-cmd-note)))
2133 (mh-notate-tick msg tick-msgs))))
2073 2134
2074(defun mh-internal-seq (name) 2135(defun mh-internal-seq (name)
2075 "Return non-nil if NAME is the name of an internal MH-E sequence." 2136 "Return non-nil if NAME is the name of an internal MH-E sequence."
2076 (or (memq name '(answered cur deleted forwarded printed)) 2137 (or (memq name '(answered cur deleted forwarded printed))
2077 (eq name mh-unseen-seq) 2138 (eq name mh-unseen-seq)
2139 (and mh-tick-seq (eq name mh-tick-seq))
2078 (eq name mh-previous-seq) 2140 (eq name mh-previous-seq)
2079 (mh-folder-name-p name))) 2141 (mh-folder-name-p name)))
2080 2142
2081(defun mh-delete-msg-from-seq (message sequence &optional internal-flag) 2143(defun mh-delete-msg-from-seq (msg-or-seq sequence &optional internal-flag)
2082 "Delete MESSAGE from SEQUENCE. 2144 "Delete MSG-OR-SEQ from SEQUENCE.
2083MESSAGE defaults to displayed message. From Lisp, optional third arg 2145Default value of MSG-OR-SEQ is the displayed message.
2084INTERNAL-FLAG non-nil means do not inform MH of the change." 2146If optional prefix argument is provided, then prompt for the message sequence.
2085 (interactive (list (mh-get-msg-num t) 2147If variable `transient-mark-mode' is non-nil and the mark is active, then the
2148selected region is deleted from SEQUENCE..
2149In a program, MSG-OR-SEQ can be a message number, a list of message numbers, a
2150region in a cons cell, or a sequence; optional third arg INTERNAL-FLAG non-nil
2151means do not inform MH of the change."
2152 (interactive (list (mh-interactive-msg-or-seq "Delete")
2086 (mh-read-seq-default "Delete from" t) 2153 (mh-read-seq-default "Delete from" t)
2087 nil)) 2154 nil))
2088 (let ((entry (mh-find-seq sequence))) 2155 (let ((entry (mh-find-seq sequence)))
2089 (cond (entry 2156 (when entry
2090 (mh-notate-if-in-one-seq message ? (1+ mh-cmd-note) sequence) 2157 (mh-iterate-on-msg-or-seq msg msg-or-seq
2091 (if (not internal-flag) 2158 (when (memq msg (mh-seq-msgs entry))
2092 (mh-undefine-sequence sequence (list message))) 2159 (mh-notate nil ? (1+ mh-cmd-note)))
2093 (setcdr entry (delq message (mh-seq-msgs entry))))))) 2160 (mh-delete-a-msg-from-seq msg sequence internal-flag)
2161 (mh-clear-text-properties nil))
2162 (mh-notate-user-sequences msg-or-seq)
2163 (when (and (eq sequence mh-unseen-seq) (mh-speed-flists-active-p))
2164 (mh-speed-flists t mh-current-folder)))))
2165
2166(defun mh-delete-a-msg-from-seq (msg sequence internal-flag)
2167 "Delete MSG from SEQUENCE.
2168If INTERNAL-FLAG is non-nil, then do not inform MH of the change."
2169 (let ((entry (mh-find-seq sequence)))
2170 (when (and entry (memq msg (mh-seq-msgs entry)))
2171 (if (not internal-flag)
2172 (mh-undefine-sequence sequence (list msg)))
2173 (setcdr entry (delq msg (mh-seq-msgs entry))))))
2174
2175(defun mh-clear-text-properties (message)
2176 "Clear all text properties (except mh-tick) from the scan line for MESSAGE."
2177 (save-excursion
2178 (with-mh-folder-updating (t)
2179 (when (or (not message) (mh-goto-msg message t t))
2180 (beginning-of-line)
2181 (let ((tick-property (get-text-property (point) 'mh-tick)))
2182 (set-text-properties (point) (line-end-position) nil)
2183 (when tick-property
2184 (add-text-properties (point) (line-end-position)
2185 `(mh-tick ,tick-property))))))))
2094 2186
2095(defun mh-undefine-sequence (seq msgs) 2187(defun mh-undefine-sequence (seq msgs)
2096 "Remove from the SEQ the list of MSGS." 2188 "Remove from the SEQ the list of MSGS."
2097 (mh-exec-cmd "mark" mh-current-folder "-delete" 2189 (prog1 (mh-exec-cmd "mark" mh-current-folder "-delete"
2098 "-sequence" (symbol-name seq) 2190 "-sequence" (symbol-name seq)
2099 (mh-coalesce-msg-list msgs))) 2191 (mh-coalesce-msg-list msgs))
2192 (when (and (eq seq mh-unseen-seq) (mh-speed-flists-active-p))
2193 (mh-speed-flists t mh-current-folder))))
2100 2194
2101(defun mh-define-sequence (seq msgs) 2195(defun mh-define-sequence (seq msgs)
2102 "Define the SEQ to contain the list of MSGS. 2196 "Define the SEQ to contain the list of MSGS.
@@ -2181,6 +2275,7 @@ range."
2181(gnus-define-keys mh-folder-mode-map 2275(gnus-define-keys mh-folder-mode-map
2182 " " mh-page-msg 2276 " " mh-page-msg
2183 "!" mh-refile-or-write-again 2277 "!" mh-refile-or-write-again
2278 "'" mh-toggle-tick
2184 "," mh-header-display 2279 "," mh-header-display
2185 "." mh-alt-show 2280 "." mh-alt-show
2186 ">" mh-write-msg-to-file 2281 ">" mh-write-msg-to-file
@@ -2227,6 +2322,7 @@ range."
2227 "i" mh-index-search 2322 "i" mh-index-search
2228 "k" mh-kill-folder 2323 "k" mh-kill-folder
2229 "l" mh-list-folders 2324 "l" mh-list-folders
2325 "n" mh-index-new-messages
2230 "o" mh-alt-visit-folder 2326 "o" mh-alt-visit-folder
2231 "p" mh-pack-folder 2327 "p" mh-pack-folder
2232 "r" mh-rescan-folder 2328 "r" mh-rescan-folder
@@ -2234,6 +2330,13 @@ range."
2234 "u" mh-undo-folder 2330 "u" mh-undo-folder
2235 "v" mh-visit-folder) 2331 "v" mh-visit-folder)
2236 2332
2333(define-key mh-folder-mode-map "I" mh-inc-spool-map)
2334
2335(gnus-define-keys (mh-junk-map "J" mh-folder-mode-map)
2336 "?" mh-prefix-help
2337 "b" mh-junk-blacklist
2338 "w" mh-junk-whitelist)
2339
2237(gnus-define-keys (mh-sequence-map "S" mh-folder-mode-map) 2340(gnus-define-keys (mh-sequence-map "S" mh-folder-mode-map)
2238 "?" mh-prefix-help 2341 "?" mh-prefix-help
2239 "d" mh-delete-msg-from-seq 2342 "d" mh-delete-msg-from-seq
@@ -2254,6 +2357,7 @@ range."
2254 "o" mh-thread-refile) 2357 "o" mh-thread-refile)
2255 2358
2256(gnus-define-keys (mh-limit-map "/" mh-folder-mode-map) 2359(gnus-define-keys (mh-limit-map "/" mh-folder-mode-map)
2360 "'" mh-narrow-to-tick
2257 "?" mh-prefix-help 2361 "?" mh-prefix-help
2258 "s" mh-narrow-to-subject 2362 "s" mh-narrow-to-subject
2259 "w" mh-widen) 2363 "w" mh-widen)
@@ -2304,8 +2408,8 @@ range."
2304 '((nil "[i]nc, [.]show, [,]show all, [n]ext, [p]revious,\n" 2408 '((nil "[i]nc, [.]show, [,]show all, [n]ext, [p]revious,\n"
2305 "[d]elete, [o]refile, e[x]ecute,\n" 2409 "[d]elete, [o]refile, e[x]ecute,\n"
2306 "[s]end, [r]eply.\n" 2410 "[s]end, [r]eply.\n"
2307 "Prefix characters:\n [F]older, [S]equence, MIME [K]eys, " 2411 "Prefix characters:\n [F]older, [S]equence, [J]unk, MIME [K]eys,"
2308 "[T]hread, / Limit, e[X]tract, [D]igest.") 2412 "\n [T]hread, / Limit, e[X]tract, [D]igest, [I]nc spools.")
2309 2413
2310 (?F "[l]ist, [v]isit folder;\n" 2414 (?F "[l]ist, [v]isit folder;\n"
2311 "[t]hread; [s]earch; [i]ndexed search;\n" 2415 "[t]hread; [s]earch; [i]ndexed search;\n"
@@ -2318,7 +2422,8 @@ range."
2318 (?X "un[s]har, [u]udecode message") 2422 (?X "un[s]har, [u]udecode message")
2319 (?D "[b]urst digest") 2423 (?D "[b]urst digest")
2320 (?K "[v]iew, [i]nline, [o]utput/save MIME part; save [a]ll parts; \n" 2424 (?K "[v]iew, [i]nline, [o]utput/save MIME part; save [a]ll parts; \n"
2321 "[TAB] next; [SHIFT-TAB] previous")) 2425 "[TAB] next; [SHIFT-TAB] previous")
2426 (?J "[b]lacklist, [w]hitelist message"))
2322 "Key binding cheat sheet. 2427 "Key binding cheat sheet.
2323 2428
2324This is an associative array which is used to show the most common commands. 2429This is an associative array which is used to show the most common commands.
diff --git a/lisp/mh-e/mh-funcs.el b/lisp/mh-e/mh-funcs.el
index fe4afd8955b..d6928a28e86 100644
--- a/lisp/mh-e/mh-funcs.el
+++ b/lisp/mh-e/mh-funcs.el
@@ -1,6 +1,6 @@
1;;; mh-funcs.el --- MH-E functions not everyone will use right away 1;;; mh-funcs.el --- MH-E functions not everyone will use right away
2 2
3;; Copyright (C) 1993, 1995, 2001, 2002 Free Software Foundation, Inc. 3;; Copyright (C) 1993, 1995, 2001, 02, 2003 Free Software Foundation, Inc.
4 4
5;; Author: Bill Wohler <wohler@newt.com> 5;; Author: Bill Wohler <wohler@newt.com>
6;; Maintainer: Bill Wohler <wohler@newt.com> 6;; Maintainer: Bill Wohler <wohler@newt.com>
@@ -32,8 +32,6 @@
32 32
33;;; Change Log: 33;;; Change Log:
34 34
35;; $Id: mh-funcs.el,v 1.2 2003/02/03 20:55:30 wohler Exp $
36
37;;; Code: 35;;; Code:
38 36
39(require 'mh-e) 37(require 'mh-e)
@@ -76,33 +74,21 @@ digest are inserted into the folder after that message."
76;;;###mh-autoload 74;;;###mh-autoload
77(defun mh-copy-msg (msg-or-seq folder) 75(defun mh-copy-msg (msg-or-seq folder)
78 "Copy the specified MSG-OR-SEQ to another FOLDER without deleting them. 76 "Copy the specified MSG-OR-SEQ to another FOLDER without deleting them.
79Default is the displayed message. If optional prefix argument is provided, 77Default is the displayed message.
80then prompt for the message sequence." 78If optional prefix argument is provided, then prompt for the message sequence.
81 (interactive (list (cond 79If variable `transient-mark-mode' is non-nil and the mark is active, then the
82 ((mh-mark-active-p t) 80selected region is copied.
83 (cons (region-beginning) (region-end))) 81In a program, MSG-OR-SEQ can be a message number, a list of message numbers, a
84 (current-prefix-arg 82region in a cons cell, or a sequence."
85 (mh-read-seq-default "Copy" t)) 83 (interactive (list (mh-interactive-msg-or-seq "Copy")
86 (t
87 (cons (line-beginning-position) (line-end-position))))
88 (mh-prompt-for-folder "Copy to" "" t))) 84 (mh-prompt-for-folder "Copy to" "" t)))
89 (let ((msg-list (cond ((numberp msg-or-seq) (list msg-or-seq)) 85 (let ((msg-list (let ((result ()))
90 ((symbolp msg-or-seq) (mh-seq-to-msgs msg-or-seq)) 86 (mh-iterate-on-msg-or-seq msg msg-or-seq
91 ((and (consp msg-or-seq) (numberp (car msg-or-seq)) 87 (mh-notate nil mh-note-copied mh-cmd-note)
92 (numberp (cdr msg-or-seq))) 88 (push msg result))
93 (let ((result ())) 89 result)))
94 (mh-iterate-on-messages-in-region msg
95 (car msg-or-seq) (cdr msg-or-seq)
96 (mh-notate nil mh-note-copied mh-cmd-note)
97 (push msg result))
98 result))
99 (t msg-or-seq))))
100 (mh-exec-cmd "refile" (mh-coalesce-msg-list msg-list) 90 (mh-exec-cmd "refile" (mh-coalesce-msg-list msg-list)
101 "-link" "-src" mh-current-folder folder) 91 "-link" "-src" mh-current-folder folder)))
102 (cond ((numberp msg-or-seq)
103 (mh-notate msg-or-seq mh-note-copied mh-cmd-note))
104 ((symbolp msg-or-seq)
105 (mh-notate-seq msg-or-seq mh-note-copied mh-cmd-note)))))
106 92
107;;;###mh-autoload 93;;;###mh-autoload
108(defun mh-kill-folder () 94(defun mh-kill-folder ()
@@ -111,7 +97,7 @@ Removes all of the messages (files) within the specified current folder,
111and then removes the folder (directory) itself." 97and then removes the folder (directory) itself."
112 (interactive) 98 (interactive)
113 (if (or mh-index-data 99 (if (or mh-index-data
114 (yes-or-no-p (format "Remove folder %s (and all included messages)?" 100 (yes-or-no-p (format "Remove folder %s (and all included messages)? "
115 mh-current-folder))) 101 mh-current-folder)))
116 (let ((folder mh-current-folder) 102 (let ((folder mh-current-folder)
117 (window-config mh-previous-window-config)) 103 (window-config mh-previous-window-config))
@@ -246,57 +232,60 @@ Otherwise just send the message's body without the headers."
246 232
247;;;###mh-autoload 233;;;###mh-autoload
248(defun mh-print-msg (msg-or-seq) 234(defun mh-print-msg (msg-or-seq)
249 "Print MSG-OR-SEQ (default: displayed message) on printer. 235 "Print MSG-OR-SEQ on printer.
250If optional prefix argument provided, then prompt for the message sequence. 236Default is the displayed message.
237If optional prefix argument is provided, then prompt for the message sequence.
238If variable `transient-mark-mode' is non-nil and the mark is active, then the
239selected region is printed.
240In a program, MSG-OR-SEQ can be a message number, a list of message numbers, a
241region in a cons cell, or a sequence.
242
251The variable `mh-lpr-command-format' is used to generate the print command. 243The variable `mh-lpr-command-format' is used to generate the print command.
252The messages are formatted by mhl. See the variable `mhl-formfile'." 244The messages are formatted by mhl. See the variable `mhl-formfile'."
253 (interactive (list (if current-prefix-arg 245 (interactive (list (mh-interactive-msg-or-seq "Print")))
254 (reverse (mh-seq-to-msgs 246 (message "Printing...")
255 (mh-read-seq-default "Print" t))) 247 (let (msgs)
256 (mh-get-msg-num t)))) 248 ;; Gather message numbers and add them to "printed" sequence.
257 (if (numberp msg-or-seq) 249 (mh-iterate-on-msg-or-seq msg msg-or-seq
258 (message "Printing message...") 250 (mh-add-msgs-to-seq msg 'printed t)
259 (message "Printing sequence...")) 251 (mh-notate nil mh-note-printed mh-cmd-note)
260 (let ((print-command 252 (push msg msgs))
261 (if (numberp msg-or-seq) 253 (setq msgs (nreverse msgs))
262 (format "%s -nobell -clear %s %s | %s" 254 ;; Print scan listing if we have more than one message.
263 (expand-file-name "mhl" mh-lib-progs) 255 (if (> (length msgs) 1)
264 (mh-msg-filename msg-or-seq) 256 (let* ((msgs-string
265 (if (stringp mhl-formfile) 257 (mapconcat 'identity (mh-list-to-string
266 (format "-form %s" mhl-formfile) 258 (mh-coalesce-msg-list msgs)) " "))
267 "") 259 (lpr-command
268 (format mh-lpr-command-format 260 (format mh-lpr-command-format
269 (if (numberp msg-or-seq) 261 (cond ((listp msg-or-seq)
270 (format "%s/%d" mh-current-folder 262 (format "Folder: %s, Messages: %s"
271 msg-or-seq) 263 mh-current-folder msgs-string))
272 (format "Sequence from %s" mh-current-folder)))) 264 ((symbolp msg-or-seq)
273 (format "(scan -clear %s ; %s -nobell -clear %s %s) | %s" 265 (format "Folder: %s, Sequence: %s"
274 (mapconcat (function (lambda (msg) msg)) msg-or-seq " ") 266 mh-current-folder msg-or-seq)))))
275 (expand-file-name "mhl" mh-lib-progs) 267 (scan-command
276 (if (stringp mhl-formfile) 268 (format "scan %s | %s" msgs-string lpr-command)))
277 (format "-form %s" mhl-formfile) 269 (if mh-print-background-flag
278 "") 270 (mh-exec-cmd-daemon shell-file-name nil "-c" scan-command)
279 (mh-msg-filenames msg-or-seq) 271 (call-process shell-file-name nil nil nil "-c" scan-command))))
280 (format mh-lpr-command-format 272 ;; Print the messages
281 (if (numberp msg-or-seq) 273 (dolist (msg msgs)
282 (format "%s/%d" mh-current-folder 274 (let* ((mhl-command (format "%s %s %s"
283 msg-or-seq) 275 (expand-file-name "mhl" mh-lib-progs)
284 (format "Sequence from %s" 276 (if mhl-formfile
285 mh-current-folder))))))) 277 (format " -form %s" mhl-formfile)
286 (if mh-print-background-flag 278 "")
287 (mh-exec-cmd-daemon shell-file-name nil "-c" print-command) 279 (mh-msg-filename msg)))
288 (call-process shell-file-name nil nil nil "-c" print-command)) 280 (lpr-command
289 (if (numberp msg-or-seq) 281 (format mh-lpr-command-format
290 (mh-notate msg-or-seq mh-note-printed mh-cmd-note) 282 (format "%s/%s" mh-current-folder msg)))
291 (mh-notate-seq msg-or-seq mh-note-printed mh-cmd-note)) 283 (print-command
292 (mh-add-msgs-to-seq msg-or-seq 'printed t) 284 (format "%s | %s" mhl-command lpr-command)))
293 (if (numberp msg-or-seq) 285 (if mh-print-background-flag
294 (message "Printing message...done") 286 (mh-exec-cmd-daemon shell-file-name nil "-c" print-command)
295 (message "Printing sequence...done")))) 287 (call-process shell-file-name nil nil nil "-c" print-command)))))
296 288 (message "Printing...done"))
297(defun mh-msg-filenames (msgs &optional folder)
298 "Return a list of file names for MSGS in FOLDER (default current folder)."
299 (mapconcat (function (lambda (msg) (mh-msg-filename msg folder))) msgs " "))
300 289
301;;;###mh-autoload 290;;;###mh-autoload
302(defun mh-sort-folder (&optional extra-args) 291(defun mh-sort-folder (&optional extra-args)
@@ -314,7 +303,6 @@ argument EXTRA-ARGS is given."
314 (when mh-index-data 303 (when mh-index-data
315 (mh-index-update-maps mh-current-folder)) 304 (mh-index-update-maps mh-current-folder))
316 (message "Sorting folder...done") 305 (message "Sorting folder...done")
317 (mh-reset-threads-and-narrowing)
318 (mh-scan-folder mh-current-folder "all") 306 (mh-scan-folder mh-current-folder "all")
319 (cond (threaded-flag (mh-toggle-threads)) 307 (cond (threaded-flag (mh-toggle-threads))
320 (mh-index-data (mh-index-insert-folder-headers))))) 308 (mh-index-data (mh-index-insert-folder-headers)))))
@@ -334,7 +322,9 @@ Argument IGNORE is deprecated."
334 (mh-unmark-all-headers t))) 322 (mh-unmark-all-headers t)))
335 (t 323 (t
336 (message "Commands not undone.") 324 (message "Commands not undone.")
337 (sit-for 2)))) 325 ;; Remove by 2003-06-30 if nothing seems amiss. XXX
326 ;; (sit-for 2)
327 )))
338 328
339;;;###mh-autoload 329;;;###mh-autoload
340(defun mh-store-msg (directory) 330(defun mh-store-msg (directory)
@@ -378,9 +368,9 @@ Default directory is the last directory used, or initially the value of
378 (if (looking-at "^[#:]....+\n\\( ?\n\\)?end$") 368 (if (looking-at "^[#:]....+\n\\( ?\n\\)?end$")
379 nil ;most likely end of a uuencode 369 nil ;most likely end of a uuencode
380 (point)))))) 370 (point))))))
381 (log-buffer (get-buffer-create "*Store Output*"))
382 (command "sh") 371 (command "sh")
383 (uudecode-filename "(unknown filename)")) 372 (uudecode-filename "(unknown filename)")
373 log-begin)
384 (if (not sh-start) 374 (if (not sh-start)
385 (save-excursion 375 (save-excursion
386 (goto-char (point-min)) 376 (goto-char (point-min))
@@ -389,31 +379,33 @@ Default directory is the last directory used, or initially the value of
389 (buffer-substring (point) 379 (buffer-substring (point)
390 (progn (end-of-line) (point))))))) 380 (progn (end-of-line) (point)))))))
391 (save-excursion 381 (save-excursion
392 (set-buffer log-buffer) 382 (set-buffer (get-buffer-create mh-log-buffer))
393 (erase-buffer) 383 (setq log-begin (mh-truncate-log-buffer))
394 (if (not (file-directory-p store-directory)) 384 (if (not (file-directory-p store-directory))
395 (progn 385 (progn
396 (insert "mkdir " directory "\n") 386 (insert "mkdir " directory "\n")
397 (call-process "mkdir" nil log-buffer t store-directory))) 387 (call-process "mkdir" nil mh-log-buffer t store-directory)))
398 (insert "cd " directory "\n") 388 (insert "cd " directory "\n")
399 (setq mh-store-default-directory directory) 389 (setq mh-store-default-directory directory)
400 (if (not sh-start) 390 (if (not sh-start)
401 (progn 391 (progn
402 (setq command "uudecode") 392 (setq command "uudecode")
403 (insert uudecode-filename " being uudecoded...\n")))) 393 (insert uudecode-filename " being uudecoded...\n"))))
404 (set-window-start (display-buffer log-buffer) 0) ;watch progress 394 (set-window-start (display-buffer mh-log-buffer) log-begin) ;watch progress
405 (let (value) 395 (let ((default-directory (file-name-as-directory store-directory)))
406 (let ((default-directory (file-name-as-directory store-directory))) 396 (if (equal (call-process-region sh-start (point-max) command
407 (setq value (call-process-region sh-start (point-max) command 397 nil mh-log-buffer t)
408 nil log-buffer t))) 398 0)
409 (set-buffer log-buffer) 399 (save-excursion
410 (mh-handle-process-error command value)) 400 (set-buffer mh-log-buffer)
411 (insert "\n(mh-store finished)\n"))) 401 (insert "\n(mh-store finished)\n"))
402 (error "Error occurred during execution of %s" command)))))
412 403
413 404
414 405
415;;; Help Functions 406;;; Help Functions
416 407
408;;;###mh-autoload
417(defun mh-ephem-message (string) 409(defun mh-ephem-message (string)
418 "Display STRING in the minibuffer momentarily." 410 "Display STRING in the minibuffer momentarily."
419 (message "%s" string) 411 (message "%s" string)
diff --git a/lisp/mh-e/mh-identity.el b/lisp/mh-e/mh-identity.el
index 43abedab5ce..9b9a879407e 100644
--- a/lisp/mh-e/mh-identity.el
+++ b/lisp/mh-e/mh-identity.el
@@ -1,6 +1,6 @@
1;;; mh-identity.el --- Multiple Identify support for MH-E. 1;;; mh-identity.el --- Multiple identify support for MH-E.
2 2
3;; Copyright (C) 2002 Free Software Foundation, Inc. 3;; Copyright (C) 2002, 2003 Free Software Foundation, Inc.
4 4
5;; Author: Peter S. Galbraith <psg@debian.org> 5;; Author: Peter S. Galbraith <psg@debian.org>
6;; Maintainer: Bill Wohler <wohler@newt.com> 6;; Maintainer: Bill Wohler <wohler@newt.com>
@@ -37,8 +37,6 @@
37 37
38;;; Change Log: 38;;; Change Log:
39 39
40;; $Id: mh-identity.el,v 1.2 2003/02/03 20:55:30 wohler Exp $
41
42;;; Code: 40;;; Code:
43 41
44 42
@@ -169,11 +167,9 @@ Edit the `mh-identity-list' variable to define identity."
169 (cond 167 (cond
170 ;; If MIME composition done, insert signature at the end as 168 ;; If MIME composition done, insert signature at the end as
171 ;; an inline MIME part. 169 ;; an inline MIME part.
172 ((and (boundp 'mh-mhn-compose-insert-flag) 170 ((mh-mhn-directive-present-p)
173 mh-mhn-compose-insert-flag)
174 (insert "#\n" "Content-Description: Signature\n")) 171 (insert "#\n" "Content-Description: Signature\n"))
175 ((and (boundp 'mh-mml-compose-insert-flag) 172 ((mh-mml-directive-present-p)
176 mh-mml-compose-insert-flag)
177 (mml-insert-tag 'part 'type "text/plain" 173 (mml-insert-tag 'part 'type "text/plain"
178 'disposition "inline" 174 'disposition "inline"
179 'description "Signature"))) 175 'description "Signature")))
@@ -182,12 +178,10 @@ Edit the `mh-identity-list' variable to define identity."
182 (funcall value)) 178 (funcall value))
183 (goto-char (point-min)) 179 (goto-char (point-min))
184 (when (not (re-search-forward "^--" nil t)) 180 (when (not (re-search-forward "^--" nil t))
185 (if (and (boundp 'mh-mhn-compose-insert-flag) 181 (cond ((mh-mhn-directive-present-p)
186 mh-mhn-compose-insert-flag) 182 (forward-line 2))
187 (forward-line 2)) 183 ((mh-mml-directive-present-p)
188 (if (and (boundp 'mh-mml-compose-insert-flag) 184 (forward-line 1)))
189 mh-mml-compose-insert-flag)
190 (forward-line 1))
191 (insert "-- \n")) 185 (insert "-- \n"))
192 (set (make-local-variable 'mh-identity-signature-end) 186 (set (make-local-variable 'mh-identity-signature-end)
193 (make-marker)) 187 (make-marker))
diff --git a/lisp/mh-e/mh-inc.el b/lisp/mh-e/mh-inc.el
new file mode 100644
index 00000000000..e1b35f31061
--- /dev/null
+++ b/lisp/mh-e/mh-inc.el
@@ -0,0 +1,104 @@
1;;; mh-inc.el --- MH-E `inc' and separate mail spool handling
2;;
3;; Copyright (C) 2003 Free Software Foundation, Inc.
4
5;; Author: Peter S. Galbraith <psg@debian.org>
6;; Maintainer: Bill Wohler <wohler@newt.com>
7;; Keywords: mail
8;; See: mh-e.el
9
10;; This file is part of GNU Emacs.
11
12;; GNU Emacs is free software; you can redistribute it and/or modify
13;; it under the terms of the GNU General Public License as published by
14;; the Free Software Foundation; either version 2, or (at your option)
15;; any later version.
16
17;; GNU Emacs is distributed in the hope that it will be useful,
18;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20;; GNU General Public License for more details.
21
22;; You should have received a copy of the GNU General Public License
23;; along with GNU Emacs; see the file COPYING. If not, write to the
24;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
25;; Boston, MA 02111-1307, USA.
26
27;;; Commentary:
28
29;; Support for inc. In addition to reading from the system mailbox, inc can
30;; also be used to incorporate mail from multiple spool files into separate
31;; folders. See `C-h v mh-inc-spool-list'.
32
33;;; Change Log:
34
35;;; Code:
36
37(eval-when-compile (require 'cl))
38
39(defvar mh-inc-spool-map (make-sparse-keymap)
40 "Keymap for MH-E's mh-inc-spool commands.")
41
42(defvar mh-inc-spool-map-help nil
43 "Help text to for `mh-inc-spool-map'.")
44
45(define-key mh-inc-spool-map "?"
46 '(lambda ()
47 (interactive)
48 (if mh-inc-spool-map-help
49 (mh-ephem-message (substring mh-inc-spool-map-help 0 -1))
50 (mh-ephem-message
51 "There are no keys defined yet. Customize `mh-inc-spool-list'"))))
52
53(defun mh-inc-spool-generator (folder spool)
54 "Create a command to inc into FOLDER from SPOOL file."
55 (let ((folder1 (make-symbol "folder"))
56 (spool1 (make-symbol "spool")))
57 (set folder1 folder)
58 (set spool1 spool)
59 (setf (symbol-function (intern (concat "mh-inc-spool-" folder)))
60 `(lambda ()
61 ,(format "Inc spool file %s into folder %s" spool folder)
62 (interactive)
63 (mh-inc-folder ,spool1 (concat "+" ,folder1))))))
64
65(defun mh-inc-spool-def-key (key folder)
66 "Define a KEY in `mh-inc-spool-map' to inc FOLDER and collect help string."
67 (when (not (= 0 key))
68 (define-key mh-inc-spool-map (format "%c" key)
69 (intern (concat "mh-inc-spool-" folder)))
70 (setq mh-inc-spool-map-help (concat mh-inc-spool-map-help "["
71 (char-to-string key)
72 "] inc " folder " folder\n"))))
73
74;; Avoid compiler warning
75(eval-when-compile (defvar mh-inc-spool-list))
76
77(defun mh-inc-spool-make ()
78 "Make all commands and defines keys for contents of `mh-inc-spool-list'."
79 (when mh-inc-spool-list
80 (setq mh-inc-spool-map-help nil)
81 (loop for elem in mh-inc-spool-list
82 do (let ((spool (nth 0 elem))
83 (folder (nth 1 elem))
84 (key (nth 2 elem)))
85 (progn
86 (mh-inc-spool-generator folder spool)
87 (mh-inc-spool-def-key key folder))))))
88
89;;;###mh-autoload
90(defun mh-inc-spool-list-set (symbol value)
91 "Set-default SYMBOL to VALUE to update the `mh-inc-spool-list' variable.
92Also rebuilds the user commands.
93This is called after 'customize is used to alter `mh-inc-spool-list'."
94 (set-default symbol value)
95 (mh-inc-spool-make))
96
97(provide 'mh-inc)
98
99;;; Local Variables:
100;;; indent-tabs-mode: nil
101;;; sentence-end-double-space: nil
102;;; End:
103
104;;; mh-inc.el ends here
diff --git a/lisp/mh-e/mh-index.el b/lisp/mh-e/mh-index.el
index a9da26953de..1d136469ec9 100644
--- a/lisp/mh-e/mh-index.el
+++ b/lisp/mh-e/mh-index.el
@@ -1,6 +1,6 @@
1;;; mh-index -- MH-E interface to indexing programs 1;;; mh-index -- MH-E interface to indexing programs
2 2
3;; Copyright (C) 2002 Free Software Foundation, Inc. 3;; Copyright (C) 2002, 2003 Free Software Foundation, Inc.
4 4
5;; Author: Satyaki Das <satyaki@theforce.stanford.edu> 5;; Author: Satyaki Das <satyaki@theforce.stanford.edu>
6;; Maintainer: Bill Wohler <wohler@newt.com> 6;; Maintainer: Bill Wohler <wohler@newt.com>
@@ -29,6 +29,7 @@
29;;; (1) The following search engines are supported: 29;;; (1) The following search engines are supported:
30;;; swish++ 30;;; swish++
31;;; swish-e 31;;; swish-e
32;;; mairix
32;;; namazu 33;;; namazu
33;;; glimpse 34;;; glimpse
34;;; grep 35;;; grep
@@ -40,8 +41,6 @@
40 41
41;;; Change Log: 42;;; Change Log:
42 43
43;; $Id: mh-index.el,v 1.2 2003/02/03 20:55:30 wohler Exp $
44
45;;; Code: 44;;; Code:
46 45
47(require 'cl) 46(require 'cl)
@@ -165,21 +164,22 @@ The current buffer contains a list of strings, one on each line. The function
165will execute CMD with ARGS and pass the first `mh-index-max-cmdline-args' 164will execute CMD with ARGS and pass the first `mh-index-max-cmdline-args'
166strings to it. This is repeated till all the strings have been used." 165strings to it. This is repeated till all the strings have been used."
167 (goto-char (point-min)) 166 (goto-char (point-min))
168 (let ((out (get-buffer-create " *mh-xargs-output*"))) 167 (let ((current-buffer (current-buffer)))
169 (save-excursion 168 (with-temp-buffer
170 (set-buffer out) 169 (let ((out (current-buffer)))
171 (erase-buffer)) 170 (set-buffer current-buffer)
172 (while (not (eobp)) 171 (while (not (eobp))
173 (let ((arg-list (reverse args)) 172 (let ((arg-list (reverse args))
174 (count 0)) 173 (count 0))
175 (while (and (not (eobp)) (< count mh-index-max-cmdline-args)) 174 (while (and (not (eobp)) (< count mh-index-max-cmdline-args))
176 (push (buffer-substring-no-properties (point) (line-end-position)) 175 (push (buffer-substring-no-properties (point) (line-end-position))
177 arg-list) 176 arg-list)
178 (incf count) 177 (incf count)
179 (forward-line)) 178 (forward-line))
180 (apply #'call-process cmd nil (list out nil) nil (nreverse arg-list)))) 179 (apply #'call-process cmd nil (list out nil) nil
181 (erase-buffer) 180 (nreverse arg-list))))
182 (insert-buffer-substring out))) 181 (erase-buffer)
182 (insert-buffer-substring out)))))
183 183
184 184
185 185
@@ -230,7 +230,8 @@ checksum -> (origin-folder, origin-index) map is updated too."
230 (point) (line-end-position))) 230 (point) (line-end-position)))
231 (forward-line) 231 (forward-line)
232 (save-excursion 232 (save-excursion
233 (cond ((eolp) 233 (cond ((not (string-match "^[0-9]*$" msg)))
234 ((eolp)
234 ;; need to compute checksum 235 ;; need to compute checksum
235 (set-buffer mh-checksum-buffer) 236 (set-buffer mh-checksum-buffer)
236 (insert mh-user-path (substring folder 1) "/" msg "\n")) 237 (insert mh-user-path (substring folder 1) "/" msg "\n"))
@@ -260,6 +261,9 @@ checksum -> (origin-folder, origin-index) map is updated too."
260 (mh-index-update-single-msg msg checksum origin-map))) 261 (mh-index-update-single-msg msg checksum origin-map)))
261 (forward-line)))))) 262 (forward-line))))))
262 263
264(defvar mh-flists-results-folder "new"
265 "Subfolder for `mh-index-folder' where flists output is placed.")
266
263(defun mh-index-generate-pretty-name (string) 267(defun mh-index-generate-pretty-name (string)
264 "Given STRING generate a name which is suitable for use as a folder name. 268 "Given STRING generate a name which is suitable for use as a folder name.
265White space from the beginning and end are removed. All spaces in the name are 269White space from the beginning and end are removed. All spaces in the name are
@@ -288,19 +292,24 @@ they are concatenated to construct the base name."
288 (subst-char-in-region (point-min) (point-max) ?\n ?_ t) 292 (subst-char-in-region (point-min) (point-max) ?\n ?_ t)
289 (subst-char-in-region (point-min) (point-max) ?\r ?_ t) 293 (subst-char-in-region (point-min) (point-max) ?\r ?_ t)
290 (subst-char-in-region (point-min) (point-max) ?/ ?$ t) 294 (subst-char-in-region (point-min) (point-max) ?/ ?$ t)
291 (truncate-string-to-width (buffer-substring (point-min) (point-max)) 20))) 295 (let ((out (truncate-string-to-width (buffer-string) 20)))
296 (cond ((eq mh-indexer 'flists) mh-flists-results-folder)
297 ((equal out mh-flists-results-folder) (concat out "1"))
298 (t out)))))
292 299
293;;;###mh-autoload 300;;;###mh-autoload
294(defun* mh-index-search (redo-search-flag folder search-regexp 301(defun* mh-index-search (redo-search-flag folder search-regexp
295 &optional window-config) 302 &optional window-config unseen-flag)
296 "Perform an indexed search in an MH mail folder. 303 "Perform an indexed search in an MH mail folder.
304Use a prefix argument to repeat the search, as in REDO-SEARCH-FLAG below.
297 305
298If REDO-SEARCH-FLAG is non-nil and the current folder buffer was generated by a 306If REDO-SEARCH-FLAG is non-nil and the current folder buffer was generated by a
299index search, then the search is repeated. Otherwise, FOLDER is searched with 307index search, then the search is repeated. Otherwise, FOLDER is searched with
300SEARCH-REGEXP and the results are presented in an MH-E folder. If FOLDER is 308SEARCH-REGEXP and the results are presented in an MH-E folder. If FOLDER is
301\"+\" then mail in all folders are searched. Optional argument WINDOW-CONFIG 309\"+\" then mail in all folders are searched. Optional argument WINDOW-CONFIG
302stores the window configuration that will be restored after the user quits the 310stores the window configuration that will be restored after the user quits the
303folder containing the index search results. 311folder containing the index search results. If optional argument UNSEEN-FLAG
312is non-nil, then all the messages are marked as unseen.
304 313
305Four indexing programs are supported; if none of these are present, then grep 314Four indexing programs are supported; if none of these are present, then grep
306is used. This function picks the first program that is available on your 315is used. This function picks the first program that is available on your
@@ -381,7 +390,7 @@ This has the effect of renaming already present X-MHE-Checksum headers."
381 (message "Processing %s output... " mh-indexer) 390 (message "Processing %s output... " mh-indexer)
382 (goto-char (point-min)) 391 (goto-char (point-min))
383 (loop for next-result = (funcall mh-index-next-result-function) 392 (loop for next-result = (funcall mh-index-next-result-function)
384 when (null next-result) return nil 393 while next-result
385 do (unless (eq next-result 'error) 394 do (unless (eq next-result 'error)
386 (unless (gethash (car next-result) folder-results-map) 395 (unless (gethash (car next-result) folder-results-map)
387 (setf (gethash (car next-result) folder-results-map) 396 (setf (gethash (car next-result) folder-results-map)
@@ -403,9 +412,13 @@ This has the effect of renaming already present X-MHE-Checksum headers."
403 (cons folder msg))))) 412 (cons folder msg)))))
404 folder-results-map) 413 folder-results-map)
405 414
415 ;; Mark messages as unseen (if needed)
416 (when (and unseen-flag (> result-count 0))
417 (mh-exec-cmd "mark" index-folder "all"
418 "-sequence" (symbol-name mh-unseen-seq) "-add"))
419
406 ;; Generate scan lines for the hits. 420 ;; Generate scan lines for the hits.
407 (let ((mh-show-threads-flag nil)) 421 (mh-visit-folder index-folder () (list folder-results-map origin-map))
408 (mh-visit-folder index-folder () (list folder-results-map origin-map)))
409 422
410 (goto-char (point-min)) 423 (goto-char (point-min))
411 (forward-line) 424 (forward-line)
@@ -548,9 +561,8 @@ The function is only applicable to folders displaying index search results.
548With non-nil optional argument BACKWARD-FLAG, jump to the previous group of 561With non-nil optional argument BACKWARD-FLAG, jump to the previous group of
549results." 562results."
550 (interactive "P") 563 (interactive "P")
551 (if (or (null mh-index-data) 564 (if (null mh-index-data)
552 (memq 'unthread mh-view-ops)) 565 (message "Only applicable in an MH-E index search buffer")
553 (message "Only applicable in an unthreaded MH-E index search buffer")
554 (let ((point (point))) 566 (let ((point (point)))
555 (forward-line (if backward-flag -1 1)) 567 (forward-line (if backward-flag -1 1))
556 (cond ((if backward-flag 568 (cond ((if backward-flag
@@ -628,6 +640,22 @@ we find a new folder name."
628 (set-buffer-modified-p old-buffer-modified-flag))) 640 (set-buffer-modified-p old-buffer-modified-flag)))
629 641
630;;;###mh-autoload 642;;;###mh-autoload
643(defun mh-index-group-by-folder ()
644 "Partition the messages based on source folder.
645Returns an alist with the the folder names in the car and the cdr being the
646list of messages originally from that folder."
647 (save-excursion
648 (goto-char (point-min))
649 (let ((result-table (make-hash-table)))
650 (loop for msg being hash-keys of mh-index-msg-checksum-map
651 do (push msg (gethash (car (gethash
652 (gethash msg mh-index-msg-checksum-map)
653 mh-index-checksum-origin-map))
654 result-table)))
655 (loop for x being the hash-keys of result-table
656 collect (cons x (nreverse (gethash x result-table)))))))
657
658;;;###mh-autoload
631(defun mh-index-delete-folder-headers () 659(defun mh-index-delete-folder-headers ()
632 "Delete the folder headers." 660 "Delete the folder headers."
633 (let ((cur-msg (mh-get-msg-num nil)) 661 (let ((cur-msg (mh-get-msg-num nil))
@@ -662,9 +690,28 @@ we find a new folder name."
662 (when (not folder) 690 (when (not folder)
663 (setq folder (car (gethash (gethash msg mh-index-msg-checksum-map) 691 (setq folder (car (gethash (gethash msg mh-index-msg-checksum-map)
664 mh-index-checksum-origin-map)))) 692 mh-index-checksum-origin-map))))
665 (mh-visit-folder 693 (when (or (not (get-buffer folder))
666 folder (loop for x being the hash-keys of (gethash folder mh-index-data) 694 (y-or-n-p (format "Reuse buffer displaying %s? " folder)))
667 when (mh-msg-exists-p x folder) collect x)))) 695 (mh-visit-folder
696 folder (loop for x being the hash-keys of (gethash folder mh-index-data)
697 when (mh-msg-exists-p x folder) collect x)))))
698
699;;;###mh-autoload
700(defun mh-index-update-unseen (msg)
701 "Remove counterpart of MSG in source folder from `mh-unseen-seq'.
702Also `mh-update-unseen' is called in the original folder, if we have it open."
703 (let* ((checksum (gethash msg mh-index-msg-checksum-map))
704 (folder-msg-pair (gethash checksum mh-index-checksum-origin-map))
705 (orig-folder (car folder-msg-pair))
706 (orig-msg (cdr folder-msg-pair)))
707 (when (mh-index-match-checksum orig-msg orig-folder checksum)
708 (when (get-buffer orig-folder)
709 (save-excursion
710 (set-buffer orig-folder)
711 (unless (member orig-msg mh-seen-list) (push orig-msg mh-seen-list))
712 (mh-update-unseen)))
713 (mh-exec-cmd-daemon "mark" #'ignore orig-folder (format "%s" orig-msg)
714 "-sequence" (symbol-name mh-unseen-seq) "-del"))))
668 715
669(defun mh-index-match-checksum (msg folder checksum) 716(defun mh-index-match-checksum (msg folder checksum)
670 "Check if MSG in FOLDER has X-MHE-Checksum header value of CHECKSUM." 717 "Check if MSG in FOLDER has X-MHE-Checksum header value of CHECKSUM."
@@ -918,7 +965,7 @@ FOLDER-PATH is the directory in which SEARCH-REGEXP-LIST is used to search."
918 (when (or (eobp) (and (bolp) (eolp))) 965 (when (or (eobp) (and (bolp) (eolp)))
919 (return nil)) 966 (return nil))
920 (unless (eq (char-after) ?/) 967 (unless (eq (char-after) ?/)
921 (return error)) 968 (return 'error))
922 (let ((start (point)) 969 (let ((start (point))
923 end msg-start) 970 end msg-start)
924 (setq end (line-end-position)) 971 (setq end (line-end-position))
@@ -1000,6 +1047,68 @@ REGEXP-LIST is an alist of fields and values."
1000 1047
1001 1048
1002 1049
1050;; Interface to unseen messages script
1051
1052(defvar mh-flists-search-folders)
1053
1054(defun mh-flists-execute (&rest args)
1055 "Search for unseen messages in `mh-flists-search-folders'.
1056If `mh-recursive-folders-flag' is t, then the folders are searched
1057recursively. All parameters ARGS are ignored."
1058 (set-buffer (get-buffer-create mh-index-temp-buffer))
1059 (erase-buffer)
1060 (unless (executable-find "sh")
1061 (error "Didn't find sh"))
1062 (with-temp-buffer
1063 (let ((unseen (symbol-name mh-unseen-seq)))
1064 (insert "for folder in `flists "
1065 (cond ((eq mh-flists-search-folders t) mh-inbox)
1066 ((eq mh-flists-search-folders nil) "")
1067 ((listp mh-flists-search-folders)
1068 (loop for folder in mh-flists-search-folders
1069 concat (concat " " folder))))
1070 (if mh-recursive-folders-flag " -recurse" "")
1071 " -sequence " unseen " -noshowzero -fast` ; do\n"
1072 "mhpath \"+$folder\" " unseen "\n" "done\n"))
1073 (call-process-region
1074 (point-min) (point-max) "sh" nil (get-buffer mh-index-temp-buffer))))
1075
1076;;;###mh-autoload
1077(defun mh-index-new-messages (folders)
1078 "Display new messages.
1079All messages in the `mh-unseen-seq' sequence from FOLDERS are displayed.
1080By default the folders specified by `mh-index-new-messages-folders' are
1081searched. With a prefix argument, enter a space-separated list of folders, or
1082nothing to search all folders."
1083 (interactive
1084 (list (if current-prefix-arg
1085 (split-string (read-string "Folders to search: "))
1086 mh-index-new-messages-folders)))
1087 (let* ((mh-flists-search-folders folders)
1088 (mh-indexer 'flists)
1089 (mh-index-execute-search-function 'mh-flists-execute)
1090 (mh-index-next-result-function 'mh-mairix-next-result)
1091 (mh-mairix-folder mh-user-path)
1092 (mh-index-regexp-builder nil)
1093 (new-folder (format "%s/%s" mh-index-folder mh-flists-results-folder))
1094 (window-config (if (equal new-folder mh-current-folder)
1095 mh-previous-window-config
1096 (current-window-configuration)))
1097 (redo-flag nil))
1098 (cond ((buffer-live-p (get-buffer new-folder))
1099 ;; The destination folder is being visited. Trick `mh-index-search'
1100 ;; into thinking that the folder was the result of a previous search.
1101 (set-buffer new-folder)
1102 (setq mh-index-previous-search (list "+" mh-flists-results-folder))
1103 (setq redo-flag t))
1104 ((mh-folder-exists-p new-folder)
1105 ;; Folder exists but we don't have it open. That means they are
1106 ;; stale results from a old flists search. Clear it out.
1107 (mh-exec-cmd-quiet nil "rmf" new-folder)))
1108 (mh-index-search redo-flag "+" mh-flists-results-folder window-config t)))
1109
1110
1111
1003;; Swish interface 1112;; Swish interface
1004 1113
1005(defvar mh-swish-binary (executable-find "swish-e")) 1114(defvar mh-swish-binary (executable-find "swish-e"))
@@ -1163,7 +1272,7 @@ FOLDER-PATH is the directory in which SEARCH-REGEXP is used to search."
1163(defun mh-swish++-regexp-builder (regexp-list) 1272(defun mh-swish++-regexp-builder (regexp-list)
1164 "Generate query for swish++. 1273 "Generate query for swish++.
1165REGEXP-LIST is an alist of fields and values." 1274REGEXP-LIST is an alist of fields and values."
1166 (let ((regexp "") meta) 1275 (let ((regexp ""))
1167 (dolist (elem regexp-list) 1276 (dolist (elem regexp-list)
1168 (when (cdr elem) 1277 (when (cdr elem)
1169 (setq regexp (concat regexp " and " 1278 (setq regexp (concat regexp " and "
@@ -1264,6 +1373,7 @@ FOLDER-PATH is the directory in which SEARCH-REGEXP is used to search."
1264 1373
1265 1374
1266 1375
1376;;;###mh-autoload
1267(defun mh-index-choose () 1377(defun mh-index-choose ()
1268 "Choose an indexing function. 1378 "Choose an indexing function.
1269The side-effects of this function are that the variables `mh-indexer', 1379The side-effects of this function are that the variables `mh-indexer',
diff --git a/lisp/mh-e/mh-junk.el b/lisp/mh-e/mh-junk.el
new file mode 100644
index 00000000000..30840c5032a
--- /dev/null
+++ b/lisp/mh-e/mh-junk.el
@@ -0,0 +1,416 @@
1;;; mh-junk.el --- Interface to anti-spam measures
2
3;; Copyright (C) 2003 Free Software Foundation, Inc.
4
5;; Author: Satyaki Das <satyaki@theforce.stanford.edu>,
6;; Bill Wohler <wohler@newt.com>
7;; Maintainer: Bill Wohler <wohler@newt.com>
8;; Keywords: mail, spam
9
10;; This file is part of GNU Emacs.
11
12;; GNU Emacs is free software; you can redistribute it and/or modify
13;; it under the terms of the GNU General Public License as published by
14;; the Free Software Foundation; either version 2, or (at your option)
15;; any later version.
16
17;; GNU Emacs is distributed in the hope that it will be useful,
18;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20;; GNU General Public License for more details.
21
22;; You should have received a copy of the GNU General Public License
23;; along with GNU Emacs; see the file COPYING. If not, write to the
24;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
25;; Boston, MA 02111-1307, USA.
26
27;;; Commentary:
28
29;; Spam handling in MH-E.
30
31;;; Change Log:
32
33;;; Code:
34
35(require 'mh-e)
36
37;; Interactive functions callable from the folder buffer
38;;;###mh-autoload
39(defun mh-junk-blacklist (msg-or-seq)
40 "Blacklist MSG-OR-SEQ as spam.
41Default is the displayed message.
42If optional prefix argument is provided, then prompt for the message sequence.
43If variable `transient-mark-mode' is non-nil and the mark is active, then the
44selected region is blacklisted.
45In a program, MSG-OR-SEQ can be a message number, a list of message numbers, a
46region in a cons cell, or a sequence.
47
48First the appropriate function is called depending on the value of
49`mh-junk-choice'. Then if `mh-junk-mail-folder' is a string then the message is
50refiled to that folder. If nil, the message is deleted.
51
52To change the spam program being used, customize `mh-junk-program'. Directly
53setting `mh-junk-choice' is not recommended.
54
55The documentation for the following functions describes what setup is needed
56for the different spam fighting programs:
57
58 - `mh-bogofilter-blacklist'
59 - `mh-spamprobe-blacklist'
60 - `mh-spamassassin-blacklist'"
61 (interactive (list (mh-interactive-msg-or-seq "Blacklist")))
62 (let ((blacklist-func (nth 1 (assoc mh-junk-choice mh-junk-function-alist))))
63 (unless blacklist-func
64 (error "Customize `mh-junk-program' appropriately"))
65 (let ((dest (cond ((null mh-junk-mail-folder) nil)
66 ((equal mh-junk-mail-folder "") "+")
67 ((eq (aref mh-junk-mail-folder 0) ?+)
68 mh-junk-mail-folder)
69 ((eq (aref mh-junk-mail-folder 0) ?@)
70 (concat mh-current-folder "/"
71 (substring mh-junk-mail-folder 1)))
72 (t (concat "+" mh-junk-mail-folder)))))
73 (mh-iterate-on-msg-or-seq msg msg-or-seq
74 (funcall (symbol-function blacklist-func) msg)
75 (if dest
76 (mh-refile-a-msg nil (intern dest))
77 (mh-delete-a-msg nil)))
78 (mh-next-msg))))
79
80;;;###mh-autoload
81(defun mh-junk-whitelist (msg-or-seq)
82 "Whitelist MSG-OR-SEQ incorrectly classified as spam.
83Default is the displayed message.
84If optional prefix argument is provided, then prompt for the message sequence.
85If variable `transient-mark-mode' is non-nil and the mark is active, then the
86selected region is whitelisted.
87In a program, MSG-OR-SEQ can be a message number, a list of message numbers, a
88region in a cons cell, or a sequence.
89
90First the appropriate function is called depending on the value of
91`mh-junk-choice'. Then the message is refiled to `mh-inbox'.
92
93To change the spam program being used, customize `mh-junk-program'. Directly
94setting `mh-junk-choice' is not recommended."
95 (interactive (list (mh-interactive-msg-or-seq "Whitelist")))
96 (let ((whitelist-func (nth 2 (assoc mh-junk-choice mh-junk-function-alist))))
97 (unless whitelist-func
98 (error "Customize `mh-junk-program' appropriately"))
99 (mh-iterate-on-msg-or-seq msg msg-or-seq
100 (funcall (symbol-function whitelist-func) msg)
101 (mh-refile-a-msg nil (intern mh-inbox)))
102 (mh-next-msg)))
103
104
105
106;; Bogofilter Interface
107
108(defvar mh-bogofilter-executable (executable-find "bogofilter"))
109
110(defun mh-bogofilter-blacklist (msg)
111 "Classify MSG as spam.
112Tell bogofilter that the message is spam.
113
114Bogofilter is a Bayesian spam filtering program. Get it from your local
115distribution or from:
116 http://bogofilter.sourceforge.net/
117
118You first need to teach bogofilter. This is done by running
119
120 bogofilter -n < good-message
121
122on every good message, and
123
124 bogofilter -s < spam-message
125
126on every spam message. Most Bayesian filters need 1000 to 5000 of each to
127start doing a good job.
128
129To use bogofilter, add the following .procmailrc recipes which you can also
130find in the bogofilter man page:
131
132 # Bogofilter
133 :0fw
134 | bogofilter -u -e -p
135
136 :0
137 * ^X-Bogosity: Yes, tests=bogofilter
138 $SPAM
139
140Bogofilter continues to feed the messages it classifies back into its
141database. Occasionally it misses, and those messages need to be reclassified.
142MH-E can do this for you. Use \\[mh-junk-blacklist] to reclassify messges in
143your +inbox as spam, and \\[mh-junk-whitelist] to reclassify messages in your
144spambox as good messages."
145 (unless mh-bogofilter-executable
146 (error "Couldn't find the bogofilter executable"))
147 (let ((msg-file (mh-msg-filename msg mh-current-folder)))
148 (call-process mh-bogofilter-executable msg-file 0 nil "-Ns")))
149
150(defun mh-bogofilter-whitelist (msg)
151 "Reinstate incorrectly filtered MSG.
152Train bogofilter to think of the message as non-spam."
153 (unless mh-bogofilter-executable
154 (error "Couldn't find the bogofilter executable"))
155 (let ((msg-file (mh-msg-filename msg mh-current-folder)))
156 (call-process mh-bogofilter-executable msg-file 0 nil "-Sn")))
157
158
159
160;; Spamprobe Interface
161
162(defvar mh-spamprobe-executable (executable-find "spamprobe"))
163
164(defun mh-spamprobe-blacklist (msg)
165 "Classify MSG as spam.
166Tell spamprobe that the message is spam.
167
168Spamprobe is a Bayesian spam filtering program. More info about the program can
169be found at:
170 http://spamprobe.sourceforge.net
171
172Here is a procmail recipe to stores incoming spam mail into the folder +spam
173and good mail in /home/user/Mail/mdrop/mbox. This recipe is provided as an
174example in the spamprobe man page.
175
176 PATH=/bin:/usr/bin:/usr/local/bin
177 DEFAULT=/home/user/Mail/mdrop/mbox
178 SPAM=/home/user/Mail/spam/.
179
180 # Spamprobe filtering
181 :0
182 SCORE=| spamprobe receive
183 :0 wf
184 | formail -I \"X-SpamProbe: $SCORE\"
185 :0 a:
186 *^X-SpamProbe: SPAM
187 $SPAM
188
189Occasionally some good mail gets misclassified as spam. You can use
190\\[mh-junk-whitelist] to reclassify that as good mail."
191 (unless mh-spamprobe-executable
192 (error "Couldn't find the spamprobe executable"))
193 (let ((msg-file (mh-msg-filename msg mh-current-folder)))
194 (call-process mh-spamprobe-executable msg-file 0 nil "spam")))
195
196(defun mh-spamprobe-whitelist (msg)
197 "Reinstate incorrectly filtered MSG.
198Train spamprobe to think of the message as non-spam."
199 (unless mh-spamprobe-executable
200 (error "Couldn't find the spamprobe executable"))
201 (let ((msg-file (mh-msg-filename msg mh-current-folder)))
202 (call-process mh-spamprobe-executable msg-file 0 nil "good")))
203
204
205
206;; Spamassassin Interface
207
208(defvar mh-spamassassin-executable (executable-find "spamassassin"))
209(defvar mh-sa-learn-executable (executable-find "sa-learn"))
210
211(defun mh-spamassassin-blacklist (msg)
212 "Blacklist MSG.
213This is done by sending the message to Razor and by appending the sender to
214~/.spamassassin/user_prefs in a blacklist_from rule. If sa-learn is available,
215the message is also recategorized as spam.
216
217Spamassassin is an excellent spam filter. For more information, see:
218 http://spamassassin.org/.
219
220I ran \"spamassassin -t\" on every mail message in my archive and ran an
221analysis in Gnumeric to find that the standard deviation of good mail
222scored under 5 (coincidentally, the spamassassin default for \"spam\").
223
224Furthermore, I observed that there weren't any messages with a score of 8
225or more that were interesting, so I added a couple of points to be
226conservative and send any message with a score of 10 or more down the
227drain. You might want to use a score of 12 or 13 to be really conservative.
228I have found that this really decreases the amount of junk to review.
229
230Messages with a score of 5-9 are set aside for later review. The major
231weakness of rules-based filters is a plethora of false positives\; I catch one
232or two legitimate messages in here a week, so it is worthwhile to check.
233
234You might choose to do this analysis yourself to pick a good score for
235deleting spam sight unseen, or you might pick a score out of a hat, or you
236might choose to be very conservative and not delete any messages at all.
237
238Based upon this discussion, here is what the associated ~/.procmailrc
239entries look like. These rules appear before my list filters so that spam
240sent to mailing lists gets pruned too.
241
242 #
243 # Spam
244 #
245 :0fw
246 | spamc
247
248 # Anything with a spam level of 10 or more is junked immediately.
249 :0:
250 * ^X-Spam-Level: ..........
251 /dev/null
252
253 :0
254 * ^X-Spam-Status: Yes
255 $SPAM
256
257If you don't use \"spamc\", use \"spamassassin -P -a\".
258
259A handful of spam does find its way into +inbox. In this case, use
260\\[mh-junk-blacklist] to add a \"blacklist_from\" line to
261~/spamassassin/user_prefs, delete the message, and send the message to the
262Razor, so that others might not see this spam.
263
264Over time, you see some patterns in the blacklisted addresses and can
265replace several lines with wildcards. For example, it is clear that High
266Speed Media is the biggest bunch of jerks on the Net. Here are some of the
267entries I have for them, and the list continues to grow.
268
269 blacklist_from *@*-hsm-*.com
270 blacklist_from *@*182*643*.com
271 blacklist_from *@*antarhsm*.com
272 blacklist_from *@*h*speed*
273 blacklist_from *@*hsm*182*.com
274 blacklist_from *@*hsm*643*.com
275 blacklist_from *@*hsmridi2983cslt227.com
276 blacklist_from *@*list*hsm*.com
277 blacklist_from *@h*s*media*
278 blacklist_from *@hsmdrct.com
279 blacklist_from *@hsmridi2983csltsite.com
280
281The function `mh-spamassassin-identify-spammers' is provided that shows the
282frequency counts of the host and domain names in your blacklist_from
283entries. This can be helpful when editing the blacklist_from entries.
284
285In versions of spamassassin (2.50 and on) that support a Bayesian classifier,
286\\[mh-junk-blacklist] uses the sa-learn program to recategorize the message as
287spam. Neither MH-E, nor spamassassin, rebuilds the database after adding
288words, so you will need to run \"sa-learn --rebuild\" periodically. This can
289be done by adding the following to your crontab:
290
291 0 * * * * sa-learn --rebuild > /dev/null 2>&1"
292 (unless mh-spamassassin-executable
293 (error "Couldn't find the spamassassin executable"))
294 (let ((current-folder mh-current-folder)
295 (msg-file (mh-msg-filename msg mh-current-folder))
296 (sender))
297 (save-excursion
298 (message "Giving this message the Razor...")
299 (mh-truncate-log-buffer)
300 (call-process mh-spamassassin-executable msg-file mh-log-buffer nil
301 "--report" "--remove-from-whitelist")
302 (when mh-sa-learn-executable
303 (message "Recategorizing this message as spam...")
304 (call-process mh-sa-learn-executable msg-file mh-log-buffer nil
305 "--single" "--spam" "--local --no-rebuild"))
306 (message "Blacklisting address...")
307 (set-buffer (get-buffer-create mh-temp-buffer))
308 (erase-buffer)
309 (call-process (expand-file-name mh-scan-prog mh-progs) nil t nil
310 (format "%s" msg) current-folder
311 "-format" "%<(mymbox{from})%|%(addr{from})%>")
312 (goto-char (point-min))
313 (if (search-forward-regexp "^\\(.+\\)$" nil t)
314 (progn
315 (setq sender (match-string 0))
316 (mh-spamassassin-add-rule "blacklist_from" sender)
317 (message "Blacklisting address...done"))
318 (message "Blacklisting address...not done (from my address)")))))
319
320(defun mh-spamassassin-whitelist (msg)
321 "Whitelist MSG.
322Add a whitelist_from rule to the ~/.spamassassin/user_prefs file. If sa-learn
323is available, then the message is recategorized as ham."
324 (unless mh-spamassassin-executable
325 (error "Couldn't find the spamassassin executable"))
326 (let ((msg-file (mh-msg-filename msg mh-current-folder))
327 (show-buffer (get-buffer mh-show-buffer))
328 from)
329 (save-excursion
330 (set-buffer (get-buffer-create mh-temp-buffer))
331 (erase-buffer)
332 (message "Removing spamassassin markup from message...")
333 (call-process mh-spamassassin-executable msg-file mh-temp-buffer nil
334 "--remove-markup")
335 (if show-buffer
336 (kill-buffer show-buffer))
337 (write-file msg-file)
338 (when mh-sa-learn-executable
339 (message "Recategorizing this message as ham...")
340 (call-process mh-sa-learn-executable msg-file mh-temp-buffer nil
341 "--single" "--ham" "--local --no-rebuild"))
342 (message "Whitelisting address...")
343 (setq from (car (ietf-drums-parse-address (mh-get-header-field "From:"))))
344 (kill-buffer nil)
345 (unless (equal from "")
346 (mh-spamassassin-add-rule "whitelist_from" from))
347 (message "Whitelisting address...done"))))
348
349(defun mh-spamassassin-add-rule (rule body)
350 "Add a new rule to ~/.spamassassin/user_prefs.
351The name of the rule is RULE and its body is BODY."
352 (save-window-excursion
353 (let* ((line (format "%s\t%s\n" rule body))
354 (case-fold-search t)
355 (file (expand-file-name "~/.spamassassin/user_prefs"))
356 (buffer-exists (find-buffer-visiting file)))
357 (find-file file)
358 (if (not (search-forward (format "\n%s" line) nil t))
359 (progn
360 (goto-char (point-max))
361 (insert (if (bolp) "" "\n") line)
362 (save-buffer)))
363 (if (not buffer-exists)
364 (kill-buffer nil)))))
365
366(defun mh-spamassassin-identify-spammers ()
367 "Identifies spammers who are repeat offenders.
368
369For each blacklist_from entry from the last blank line of
370~/.spamassassin/user_prefs to the end of the file, a list of host and domain
371names along with their frequency counts is displayed. This information can be
372used to replace multiple blacklist_from entries with a single wildcard entry
373such as:
374
375 blacklist_from *@*amazingoffersdirect2u.com"
376 (interactive)
377 (let* ((file (expand-file-name "~/.spamassassin/user_prefs"))
378 (domains (make-hash-table :test 'equal)))
379 (find-file file)
380 ;; Only consider entries between last blank line and end of file.
381 (goto-char (1- (point-max)))
382 (search-backward-regexp "^$")
383 ;; Perform frequency count.
384 (save-excursion
385 (while (search-forward-regexp "^blacklist_from\\s-*\\(.*\\)@\\(.*\\)$"
386 nil t)
387 (let ((host (match-string 2))
388 value)
389 ;; Remove top-level-domain from hostname.
390 (setq host (cdr (reverse (split-string host "\\."))))
391 ;; Add counts for each host and domain part.
392 (while host
393 (setq value (gethash (car host) domains))
394 (puthash (car host) (1+ (if (not value) 0 value)) domains)
395 (setq host (cdr host))))))
396
397 ;; Output
398 (delete-other-windows)
399 (pop-to-buffer (get-buffer-create "*MH-E Spammer Frequencies*"))
400 (erase-buffer)
401 (maphash '(lambda (key value) ""
402 (if (> value 2)
403 (insert (format "%s %s\n" key value))))
404 domains)
405 (sort-numeric-fields 2 (point-min) (point-max))
406 (reverse-region (point-min) (point-max))
407 (goto-char (point-min))))
408
409(provide 'mh-junk)
410
411;;; Local Variables:
412;;; indent-tabs-mode: nil
413;;; sentence-end-double-space: nil
414;;; End:
415
416;;; mh-junk.el ends here
diff --git a/lisp/mh-e/mh-loaddefs.el b/lisp/mh-e/mh-loaddefs.el
index 9646df03ad1..effdbdbc8b3 100644
--- a/lisp/mh-e/mh-loaddefs.el
+++ b/lisp/mh-e/mh-loaddefs.el
@@ -5,7 +5,6 @@
5;;; Keywords: mail 5;;; Keywords: mail
6;;; Commentary: 6;;; Commentary:
7;;; Change Log: 7;;; Change Log:
8;; $Id: mh-loaddefs.el,v 1.36 2003/02/03 19:15:13 wohler Exp $
9;;; Code: 8;;; Code:
10 9
11;;;### (autoloads (mh-letter-complete mh-open-line mh-fully-kill-draft 10;;;### (autoloads (mh-letter-complete mh-open-line mh-fully-kill-draft
@@ -13,7 +12,7 @@
13;;;;;; mh-insert-signature mh-to-fcc mh-to-field mh-fill-paragraph-function 12;;;;;; mh-insert-signature mh-to-fcc mh-to-field mh-fill-paragraph-function
14;;;;;; mh-send-other-window mh-send mh-reply mh-redistribute mh-forward 13;;;;;; mh-send-other-window mh-send mh-reply mh-redistribute mh-forward
15;;;;;; mh-extract-rejected-mail mh-edit-again) "mh-comp" "mh-comp.el" 14;;;;;; mh-extract-rejected-mail mh-edit-again) "mh-comp" "mh-comp.el"
16;;;;;; (15924 43423)) 15;;;;;; (16039 39609))
17;;; Generated autoloads from mh-comp.el 16;;; Generated autoloads from mh-comp.el
18 17
19(autoload (quote mh-edit-again) "mh-comp" "\ 18(autoload (quote mh-edit-again) "mh-comp" "\
@@ -29,13 +28,15 @@ gives the headers to clean out of the original message.
29See also documentation for `\\[mh-send]' function." t nil) 28See also documentation for `\\[mh-send]' function." t nil)
30 29
31(autoload (quote mh-forward) "mh-comp" "\ 30(autoload (quote mh-forward) "mh-comp" "\
32Forward one or more messages to the recipients TO and CC. 31Forward messages to the recipients TO and CC.
32Use optional MSG-OR-SEQ argument to specify a message or sequence to forward.
33Default is the displayed message.
34If optional prefix argument is provided, then prompt for the message sequence.
35If variable `transient-mark-mode' is non-nil and the mark is active, then the
36selected region is forwarded.
37In a program, MSG-OR-SEQ can be a message number, a list of message numbers, a
38region in a cons cell, or a sequence.
33 39
34Use the optional MSG-OR-SEQ to specify a message or sequence to forward.
35
36Default is the displayed message. If optional prefix argument is given then
37prompt for the message sequence. If variable `transient-mark-mode' is non-nil
38and the mark is active, then the selected region is forwarded.
39See also documentation for `\\[mh-send]' function." t nil) 40See also documentation for `\\[mh-send]' function." t nil)
40 41
41(autoload (quote mh-redistribute) "mh-comp" "\ 42(autoload (quote mh-redistribute) "mh-comp" "\
@@ -45,7 +46,8 @@ Depending on how your copy of MH was compiled, you may need to change the
45setting of the variable `mh-redist-full-contents'. See its documentation." t nil) 46setting of the variable `mh-redist-full-contents'. See its documentation." t nil)
46 47
47(autoload (quote mh-reply) "mh-comp" "\ 48(autoload (quote mh-reply) "mh-comp" "\
48Reply to MESSAGE (default: current message). 49Reply to MESSAGE.
50Default is the displayed message.
49If the optional argument REPLY-TO is not given, prompts for type of addresses 51If the optional argument REPLY-TO is not given, prompts for type of addresses
50to reply to: 52to reply to:
51 from sender only, 53 from sender only,
@@ -107,8 +109,8 @@ Send the draft letter in the current buffer.
107If optional prefix argument ARG is provided, monitor delivery. 109If optional prefix argument ARG is provided, monitor delivery.
108The value of `mh-before-send-letter-hook' is a list of functions to be called, 110The value of `mh-before-send-letter-hook' is a list of functions to be called,
109with no arguments, before doing anything. 111with no arguments, before doing anything.
110Run `\\[mh-edit-mhn]' if variable `mh-mhn-compose-insert-flag' is set. 112Run `\\[mh-edit-mhn]' if mhn directives are present; otherwise
111Run `\\[mh-mml-to-mime]' if variable `mh-mml-compose-insert-flag' is set. 113run `\\[mh-mml-to-mime]' if mml directives are present.
112Insert X-Mailer field if variable `mh-insert-x-mailer-flag' is set. 114Insert X-Mailer field if variable `mh-insert-x-mailer-flag' is set.
113Insert X-Face field if the file specified by `mh-x-face-file' exists." t nil) 115Insert X-Face field if the file specified by `mh-x-face-file' exists." t nil)
114 116
@@ -149,8 +151,8 @@ passing the prefix ARG if any." t nil)
149 151
150;;;*** 152;;;***
151 153
152;;;### (autoloads (mh-tool-bar-folder-set mh-tool-bar-letter-set 154;;;### (autoloads (mh-customize) "mh-customize" "mh-customize.el"
153;;;;;; mh-customize) "mh-customize" "mh-customize.el" (15933 21842)) 155;;;;;; (16038 15647))
154;;; Generated autoloads from mh-customize.el 156;;; Generated autoloads from mh-customize.el
155 157
156(autoload (quote mh-customize) "mh-customize" "\ 158(autoload (quote mh-customize) "mh-customize" "\
@@ -158,16 +160,10 @@ Customize MH-E variables.
158With optional argument DELETE-OTHER-WINDOWS-FLAG, other windows in the frame 160With optional argument DELETE-OTHER-WINDOWS-FLAG, other windows in the frame
159are removed." t nil) 161are removed." t nil)
160 162
161(autoload (quote mh-tool-bar-letter-set) "mh-customize" "\
162Construct toolbar for `mh-letter-mode'." nil nil)
163
164(autoload (quote mh-tool-bar-folder-set) "mh-customize" "\
165Construct toolbar for `mh-folder-mode'." nil nil)
166
167;;;*** 163;;;***
168 164
169;;;### (autoloads (mh-goto-cur-msg mh-update-sequences mh-folder-line-matches-show-buffer-p) 165;;;### (autoloads (mh-goto-cur-msg mh-update-sequences mh-folder-line-matches-show-buffer-p)
170;;;;;; "mh-e" "mh-e.el" (15934 48879)) 166;;;;;; "mh-e" "mh-e.el" (16040 30321))
171;;; Generated autoloads from mh-e.el 167;;; Generated autoloads from mh-e.el
172 168
173(autoload (quote mh-folder-line-matches-show-buffer-p) "mh-e" "\ 169(autoload (quote mh-folder-line-matches-show-buffer-p) "mh-e" "\
@@ -186,11 +182,11 @@ recenter the folder buffer." nil nil)
186 182
187;;;*** 183;;;***
188 184
189;;;### (autoloads (mh-prefix-help mh-help mh-store-buffer mh-store-msg 185;;;### (autoloads (mh-prefix-help mh-help mh-ephem-message mh-store-buffer
190;;;;;; mh-undo-folder mh-sort-folder mh-print-msg mh-page-digest-backwards 186;;;;;; mh-store-msg mh-undo-folder mh-sort-folder mh-print-msg mh-page-digest-backwards
191;;;;;; mh-page-digest mh-pipe-msg mh-pack-folder mh-list-folders 187;;;;;; mh-page-digest mh-pipe-msg mh-pack-folder mh-list-folders
192;;;;;; mh-kill-folder mh-copy-msg mh-burst-digest) "mh-funcs" "mh-funcs.el" 188;;;;;; mh-kill-folder mh-copy-msg mh-burst-digest) "mh-funcs" "mh-funcs.el"
193;;;;;; (15923 15465)) 189;;;;;; (16039 39632))
194;;; Generated autoloads from mh-funcs.el 190;;; Generated autoloads from mh-funcs.el
195 191
196(autoload (quote mh-burst-digest) "mh-funcs" "\ 192(autoload (quote mh-burst-digest) "mh-funcs" "\
@@ -200,8 +196,12 @@ digest are inserted into the folder after that message." t nil)
200 196
201(autoload (quote mh-copy-msg) "mh-funcs" "\ 197(autoload (quote mh-copy-msg) "mh-funcs" "\
202Copy the specified MSG-OR-SEQ to another FOLDER without deleting them. 198Copy the specified MSG-OR-SEQ to another FOLDER without deleting them.
203Default is the displayed message. If optional prefix argument is provided, 199Default is the displayed message.
204then prompt for the message sequence." t nil) 200If optional prefix argument is provided, then prompt for the message sequence.
201If variable `transient-mark-mode' is non-nil and the mark is active, then the
202selected region is copied.
203In a program, MSG-OR-SEQ can be a message number, a list of message numbers, a
204region in a cons cell, or a sequence." t nil)
205 205
206(autoload (quote mh-kill-folder) "mh-funcs" "\ 206(autoload (quote mh-kill-folder) "mh-funcs" "\
207Remove the current folder and all included messages. 207Remove the current folder and all included messages.
@@ -229,8 +229,14 @@ Advance displayed message to next digested message." t nil)
229Back up displayed message to previous digested message." t nil) 229Back up displayed message to previous digested message." t nil)
230 230
231(autoload (quote mh-print-msg) "mh-funcs" "\ 231(autoload (quote mh-print-msg) "mh-funcs" "\
232Print MSG-OR-SEQ (default: displayed message) on printer. 232Print MSG-OR-SEQ on printer.
233If optional prefix argument provided, then prompt for the message sequence. 233Default is the displayed message.
234If optional prefix argument is provided, then prompt for the message sequence.
235If variable `transient-mark-mode' is non-nil and the mark is active, then the
236selected region is printed.
237In a program, MSG-OR-SEQ can be a message number, a list of message numbers, a
238region in a cons cell, or a sequence.
239
234The variable `mh-lpr-command-format' is used to generate the print command. 240The variable `mh-lpr-command-format' is used to generate the print command.
235The messages are formatted by mhl. See the variable `mhl-formfile'." t nil) 241The messages are formatted by mhl. See the variable `mhl-formfile'." t nil)
236 242
@@ -256,6 +262,9 @@ The buffer can contain a shar file or uuencoded file.
256Default directory is the last directory used, or initially the value of 262Default directory is the last directory used, or initially the value of
257`mh-store-default-directory' or the current directory." t nil) 263`mh-store-default-directory' or the current directory." t nil)
258 264
265(autoload (quote mh-ephem-message) "mh-funcs" "\
266Display STRING in the minibuffer momentarily." nil nil)
267
259(autoload (quote mh-help) "mh-funcs" "\ 268(autoload (quote mh-help) "mh-funcs" "\
260Display cheat sheet for the MH-Folder commands in minibuffer." t nil) 269Display cheat sheet for the MH-Folder commands in minibuffer." t nil)
261 270
@@ -265,7 +274,7 @@ Display cheat sheet for the commands of the current prefix in minibuffer." t nil
265;;;*** 274;;;***
266 275
267;;;### (autoloads (mh-insert-identity mh-identity-list-set mh-identity-make-menu) 276;;;### (autoloads (mh-insert-identity mh-identity-list-set mh-identity-make-menu)
268;;;;;; "mh-identity" "mh-identity.el" (15900 46388)) 277;;;;;; "mh-identity" "mh-identity.el" (16039 39644))
269;;; Generated autoloads from mh-identity.el 278;;; Generated autoloads from mh-identity.el
270 279
271(autoload (quote mh-identity-make-menu) "mh-identity" "\ 280(autoload (quote mh-identity-make-menu) "mh-identity" "\
@@ -283,12 +292,24 @@ Edit the `mh-identity-list' variable to define identity." t nil)
283 292
284;;;*** 293;;;***
285 294
286;;;### (autoloads (mh-namazu-execute-search mh-swish++-execute-search 295;;;### (autoloads (mh-inc-spool-list-set) "mh-inc" "mh-inc.el" (16040
287;;;;;; mh-swish-execute-search mh-glimpse-execute-search mh-index-execute-commands 296;;;;;; 51164))
288;;;;;; mh-index-visit-folder mh-index-delete-folder-headers mh-index-insert-folder-headers 297;;; Generated autoloads from mh-inc.el
298
299(autoload (quote mh-inc-spool-list-set) "mh-inc" "\
300Set-default SYMBOL to VALUE to update the `mh-inc-spool-list' variable.
301Also rebuilds the user commands.
302This is called after 'customize is used to alter `mh-inc-spool-list'." nil nil)
303
304;;;***
305
306;;;### (autoloads (mh-index-choose mh-namazu-execute-search mh-swish++-execute-search
307;;;;;; mh-swish-execute-search mh-index-new-messages mh-glimpse-execute-search
308;;;;;; mh-index-execute-commands mh-index-update-unseen mh-index-visit-folder
309;;;;;; mh-index-delete-folder-headers mh-index-group-by-folder mh-index-insert-folder-headers
289;;;;;; mh-index-previous-folder mh-index-next-folder mh-index-parse-search-regexp 310;;;;;; mh-index-previous-folder mh-index-next-folder mh-index-parse-search-regexp
290;;;;;; mh-index-do-search mh-index-search mh-index-update-maps) 311;;;;;; mh-index-do-search mh-index-search mh-index-update-maps)
291;;;;;; "mh-index" "mh-index.el" (15924 45743)) 312;;;;;; "mh-index" "mh-index.el" (16038 15647))
292;;; Generated autoloads from mh-index.el 313;;; Generated autoloads from mh-index.el
293 314
294(autoload (quote mh-index-update-maps) "mh-index" "\ 315(autoload (quote mh-index-update-maps) "mh-index" "\
@@ -300,13 +321,15 @@ checksum -> (origin-folder, origin-index) map is updated too." nil nil)
300 321
301(autoload (quote mh-index-search) "mh-index" "\ 322(autoload (quote mh-index-search) "mh-index" "\
302Perform an indexed search in an MH mail folder. 323Perform an indexed search in an MH mail folder.
324Use a prefix argument to repeat the search, as in REDO-SEARCH-FLAG below.
303 325
304If REDO-SEARCH-FLAG is non-nil and the current folder buffer was generated by a 326If REDO-SEARCH-FLAG is non-nil and the current folder buffer was generated by a
305index search, then the search is repeated. Otherwise, FOLDER is searched with 327index search, then the search is repeated. Otherwise, FOLDER is searched with
306SEARCH-REGEXP and the results are presented in an MH-E folder. If FOLDER is 328SEARCH-REGEXP and the results are presented in an MH-E folder. If FOLDER is
307\"+\" then mail in all folders are searched. Optional argument WINDOW-CONFIG 329\"+\" then mail in all folders are searched. Optional argument WINDOW-CONFIG
308stores the window configuration that will be restored after the user quits the 330stores the window configuration that will be restored after the user quits the
309folder containing the index search results. 331folder containing the index search results. If optional argument UNSEEN-FLAG
332is non-nil, then all the messages are marked as unseen.
310 333
311Four indexing programs are supported; if none of these are present, then grep 334Four indexing programs are supported; if none of these are present, then grep
312is used. This function picks the first program that is available on your 335is used. This function picks the first program that is available on your
@@ -358,12 +381,21 @@ Jump to the previous folder marker." t nil)
358(autoload (quote mh-index-insert-folder-headers) "mh-index" "\ 381(autoload (quote mh-index-insert-folder-headers) "mh-index" "\
359Annotate the search results with original folder names." nil nil) 382Annotate the search results with original folder names." nil nil)
360 383
384(autoload (quote mh-index-group-by-folder) "mh-index" "\
385Partition the messages based on source folder.
386Returns an alist with the the folder names in the car and the cdr being the
387list of messages originally from that folder." nil nil)
388
361(autoload (quote mh-index-delete-folder-headers) "mh-index" "\ 389(autoload (quote mh-index-delete-folder-headers) "mh-index" "\
362Delete the folder headers." nil nil) 390Delete the folder headers." nil nil)
363 391
364(autoload (quote mh-index-visit-folder) "mh-index" "\ 392(autoload (quote mh-index-visit-folder) "mh-index" "\
365Visit original folder from where the message at point was found." t nil) 393Visit original folder from where the message at point was found." t nil)
366 394
395(autoload (quote mh-index-update-unseen) "mh-index" "\
396Remove counterpart of MSG in source folder from `mh-unseen-seq'.
397Also `mh-update-unseen' is called in the original folder, if we have it open." nil nil)
398
367(autoload (quote mh-index-execute-commands) "mh-index" "\ 399(autoload (quote mh-index-execute-commands) "mh-index" "\
368Delete/refile the actual messages. 400Delete/refile the actual messages.
369The copies in the searched folder are then deleted/refiled to get the desired 401The copies in the searched folder are then deleted/refiled to get the desired
@@ -403,6 +435,13 @@ daily from cron:
403 435
404FOLDER-PATH is the directory in which SEARCH-REGEXP is used to search." nil nil) 436FOLDER-PATH is the directory in which SEARCH-REGEXP is used to search." nil nil)
405 437
438(autoload (quote mh-index-new-messages) "mh-index" "\
439Display new messages.
440All messages in the `mh-unseen-seq' sequence from FOLDERS are displayed.
441By default the folders specified by `mh-index-new-messages-folders' are
442searched. With a prefix argument, enter a space-separated list of folders, or
443nothing to search all folders." t nil)
444
406(autoload (quote mh-swish-execute-search) "mh-index" "\ 445(autoload (quote mh-swish-execute-search) "mh-index" "\
407Execute swish-e and read the results. 446Execute swish-e and read the results.
408 447
@@ -515,16 +554,69 @@ daily from cron:
515 554
516FOLDER-PATH is the directory in which SEARCH-REGEXP is used to search." nil nil) 555FOLDER-PATH is the directory in which SEARCH-REGEXP is used to search." nil nil)
517 556
557(autoload (quote mh-index-choose) "mh-index" "\
558Choose an indexing function.
559The side-effects of this function are that the variables `mh-indexer',
560`mh-index-execute-search-function', and `mh-index-next-result-function' are
561set according to the first indexer in `mh-indexer-choices' present on the
562system." nil nil)
563
564;;;***
565
566;;;### (autoloads (mh-junk-whitelist mh-junk-blacklist) "mh-junk"
567;;;;;; "mh-junk.el" (16023 25085))
568;;; Generated autoloads from mh-junk.el
569
570(autoload (quote mh-junk-blacklist) "mh-junk" "\
571Blacklist MSG-OR-SEQ as spam.
572Default is the displayed message.
573If optional prefix argument is provided, then prompt for the message sequence.
574If variable `transient-mark-mode' is non-nil and the mark is active, then the
575selected region is blacklisted.
576In a program, MSG-OR-SEQ can be a message number, a list of message numbers, a
577region in a cons cell, or a sequence.
578
579First the appropriate function is called depending on the value of
580`mh-junk-choice'. Then if `mh-junk-mail-folder' is a string then the message is
581refiled to that folder. If nil, the message is deleted.
582
583To change the spam program being used, customize `mh-junk-program'. Directly
584setting `mh-junk-choice' is not recommended.
585
586The documentation for the following functions describes what setup is needed
587for the different spam fighting programs:
588
589 - `mh-bogofilter-blacklist'
590 - `mh-spamprobe-blacklist'
591 - `mh-spamassassin-blacklist'" t nil)
592
593(autoload (quote mh-junk-whitelist) "mh-junk" "\
594Whitelist MSG-OR-SEQ incorrectly classified as spam.
595Default is the displayed message.
596If optional prefix argument is provided, then prompt for the message sequence.
597If variable `transient-mark-mode' is non-nil and the mark is active, then the
598selected region is whitelisted.
599In a program, MSG-OR-SEQ can be a message number, a list of message numbers, a
600region in a cons cell, or a sequence.
601
602First the appropriate function is called depending on the value of
603`mh-junk-choice'. Then the message is refiled to `mh-inbox'.
604
605To change the spam program being used, customize `mh-junk-program'. Directly
606setting `mh-junk-choice' is not recommended." t nil)
607
518;;;*** 608;;;***
519 609
520;;;### (autoloads (mh-mime-inline-part mh-mime-save-part mh-push-button 610;;;### (autoloads (mh-mime-inline-part mh-mime-save-part mh-push-button
521;;;;;; mh-press-button mh-mime-display mh-mime-save-parts mh-display-emphasis 611;;;;;; mh-press-button mh-mime-display mh-decode-message-header
522;;;;;; mh-display-smileys mh-add-missing-mime-version-header mh-destroy-postponed-handles 612;;;;;; mh-mime-save-parts mh-display-emphasis mh-display-smileys
523;;;;;; mh-mime-cleanup mh-mml-secure-message-encrypt-pgpmime mh-mml-secure-message-sign-pgpmime 613;;;;;; mh-add-missing-mime-version-header mh-destroy-postponed-handles
524;;;;;; mh-mml-attach-file mh-mml-forward-message mh-mml-to-mime 614;;;;;; mh-mime-cleanup mh-mml-directive-present-p mh-mml-secure-message-encrypt-pgpmime
525;;;;;; mh-revert-mhn-edit mh-edit-mhn mh-mhn-compose-forw mh-mhn-compose-external-compressed-tar 615;;;;;; mh-mml-secure-message-sign-pgpmime mh-mml-attach-file mh-mml-forward-message
616;;;;;; mh-mml-to-mime mh-mhn-directive-present-p mh-revert-mhn-edit
617;;;;;; mh-edit-mhn mh-mhn-compose-forw mh-mhn-compose-external-compressed-tar
526;;;;;; mh-mhn-compose-anon-ftp mh-mhn-compose-insertion mh-compose-forward 618;;;;;; mh-mhn-compose-anon-ftp mh-mhn-compose-insertion mh-compose-forward
527;;;;;; mh-compose-insertion) "mh-mime" "mh-mime.el" (15923 15465)) 619;;;;;; mh-compose-insertion) "mh-mime" "mh-mime.el" (16039 39680))
528;;; Generated autoloads from mh-mime.el 620;;; Generated autoloads from mh-mime.el
529 621
530(autoload (quote mh-compose-insertion) "mh-mime" "\ 622(autoload (quote mh-compose-insertion) "mh-mime" "\
@@ -591,7 +683,8 @@ Process the current draft with the mhn program, which, using directives
591already inserted in the draft, fills in all the MIME components and header 683already inserted in the draft, fills in all the MIME components and header
592fields. 684fields.
593 685
594This step should be done last just before sending the message. 686This step is performed automatically when sending the message, but this
687function may be called manually before sending the draft as well.
595 688
596The `\\[mh-revert-mhn-edit]' command undoes this command. The arguments in the 689The `\\[mh-revert-mhn-edit]' command undoes this command. The arguments in the
597list `mh-mhn-args' are passed to mhn if this function is passed an optional 690list `mh-mhn-args' are passed to mhn if this function is passed an optional
@@ -602,8 +695,7 @@ components in a message, see \\[mh-mhn-compose-insertion] (generic insertion
602from a file), \\[mh-mhn-compose-anon-ftp] (external reference to file via 695from a file), \\[mh-mhn-compose-anon-ftp] (external reference to file via
603anonymous ftp), \\[mh-mhn-compose-external-compressed-tar] (reference to 696anonymous ftp), \\[mh-mhn-compose-external-compressed-tar] (reference to
604compressed tar file via anonymous ftp), and \\[mh-mhn-compose-forw] (forward 697compressed tar file via anonymous ftp), and \\[mh-mhn-compose-forw] (forward
605message). If these helper functions are used, `mh-edit-mhn' is run 698message).
606automatically when the draft is sent.
607 699
608The value of `mh-edit-mhn-hook' is a list of functions to be called, with no 700The value of `mh-edit-mhn-hook' is a list of functions to be called, with no
609arguments, after performing the conversion. 701arguments, after performing the conversion.
@@ -614,8 +706,13 @@ The mhn program is part of MH version 6.8 or later." t nil)
614Undo the effect of \\[mh-edit-mhn] by reverting to the backup file. 706Undo the effect of \\[mh-edit-mhn] by reverting to the backup file.
615Optional non-nil argument NOCONFIRM means don't ask for confirmation." t nil) 707Optional non-nil argument NOCONFIRM means don't ask for confirmation." t nil)
616 708
709(autoload (quote mh-mhn-directive-present-p) "mh-mime" "\
710Check if the current buffer has text which might be a MHN directive." nil nil)
711
617(autoload (quote mh-mml-to-mime) "mh-mime" "\ 712(autoload (quote mh-mml-to-mime) "mh-mime" "\
618Compose MIME message from mml directives." t nil) 713Compose MIME message from mml directives.
714This step is performed automatically when sending the message, but this
715function may be called manually before sending the draft as well." t nil)
619 716
620(autoload (quote mh-mml-forward-message) "mh-mime" "\ 717(autoload (quote mh-mml-forward-message) "mh-mime" "\
621Forward a message as attachment. 718Forward a message as attachment.
@@ -640,6 +737,9 @@ Add directive to encrypt/sign the entire message." t nil)
640Add directive to encrypt and sign the entire message. 737Add directive to encrypt and sign the entire message.
641If called with a prefix argument DONTSIGN, only encrypt (do NOT sign)." t nil) 738If called with a prefix argument DONTSIGN, only encrypt (do NOT sign)." t nil)
642 739
740(autoload (quote mh-mml-directive-present-p) "mh-mime" "\
741Check if the current buffer has text which may be an MML directive." nil nil)
742
643(autoload (quote mh-mime-cleanup) "mh-mime" "\ 743(autoload (quote mh-mime-cleanup) "mh-mime" "\
644Free the decoded MIME parts." nil nil) 744Free the decoded MIME parts." nil nil)
645 745
@@ -663,6 +763,9 @@ If ARG, prompt for directory, else use that specified by the variable
663mh_profile directives, since this function calls on mhstore or mhn to do the 763mh_profile directives, since this function calls on mhstore or mhn to do the
664actual storing." t nil) 764actual storing." t nil)
665 765
766(autoload (quote mh-decode-message-header) "mh-mime" "\
767Decode RFC2047 encoded message header fields." nil nil)
768
666(autoload (quote mh-mime-display) "mh-mime" "\ 769(autoload (quote mh-mime-display) "mh-mime" "\
667Display (and possibly decode) MIME handles. 770Display (and possibly decode) MIME handles.
668Optional argument, PRE-DISSECTED-HANDLES is a list of MIME handles. If 771Optional argument, PRE-DISSECTED-HANDLES is a list of MIME handles. If
@@ -689,7 +792,7 @@ Toggle display of the raw MIME part." t nil)
689;;;*** 792;;;***
690 793
691;;;### (autoloads (mh-do-search mh-pick-do-search mh-do-pick-search 794;;;### (autoloads (mh-do-search mh-pick-do-search mh-do-pick-search
692;;;;;; mh-search-folder) "mh-pick" "mh-pick.el" (15924 45743)) 795;;;;;; mh-search-folder) "mh-pick" "mh-pick.el" (16037 44490))
693;;; Generated autoloads from mh-pick.el 796;;; Generated autoloads from mh-pick.el
694 797
695(autoload (quote mh-search-folder) "mh-pick" "\ 798(autoload (quote mh-search-folder) "mh-pick" "\
@@ -719,14 +822,16 @@ indexing program specified in `mh-index-program' is used." t nil)
719 822
720;;;*** 823;;;***
721 824
722;;;### (autoloads (mh-thread-refile mh-thread-delete mh-thread-ancestor 825;;;### (autoloads (mh-narrow-to-tick mh-toggle-tick mh-notate-tick
723;;;;;; mh-thread-previous-sibling mh-thread-next-sibling mh-thread-forget-message 826;;;;;; mh-thread-refile mh-thread-delete mh-thread-ancestor mh-thread-previous-sibling
724;;;;;; mh-toggle-threads mh-thread-add-spaces mh-thread-inc mh-delete-subject-or-thread 827;;;;;; mh-thread-next-sibling mh-thread-forget-message mh-toggle-threads
828;;;;;; mh-thread-add-spaces mh-thread-inc mh-delete-subject-or-thread
725;;;;;; mh-delete-subject mh-narrow-to-subject mh-region-to-msg-list 829;;;;;; mh-delete-subject mh-narrow-to-subject mh-region-to-msg-list
830;;;;;; mh-interactive-msg-or-seq mh-msg-or-seq-to-msg-list mh-iterate-on-msg-or-seq
726;;;;;; mh-iterate-on-messages-in-region mh-add-to-sequence mh-notate-cur 831;;;;;; mh-iterate-on-messages-in-region mh-add-to-sequence mh-notate-cur
727;;;;;; mh-notate-seq mh-map-to-seq-msgs mh-rename-seq mh-widen mh-put-msg-in-seq 832;;;;;; mh-notate-seq mh-map-to-seq-msgs mh-rename-seq mh-widen mh-put-msg-in-seq
728;;;;;; mh-narrow-to-seq mh-msg-is-in-seq mh-list-sequences mh-delete-seq) 833;;;;;; mh-narrow-to-seq mh-msg-is-in-seq mh-list-sequences mh-delete-seq)
729;;;;;; "mh-seq" "mh-seq.el" (15923 15465)) 834;;;;;; "mh-seq" "mh-seq.el" (16039 39691))
730;;; Generated autoloads from mh-seq.el 835;;; Generated autoloads from mh-seq.el
731 836
732(autoload (quote mh-delete-seq) "mh-seq" "\ 837(autoload (quote mh-delete-seq) "mh-seq" "\
@@ -736,17 +841,21 @@ Delete the SEQUENCE." t nil)
736List the sequences defined in the folder being visited." t nil) 841List the sequences defined in the folder being visited." t nil)
737 842
738(autoload (quote mh-msg-is-in-seq) "mh-seq" "\ 843(autoload (quote mh-msg-is-in-seq) "mh-seq" "\
739Display the sequences that contain MESSAGE (default: current message)." t nil) 844Display the sequences that contain MESSAGE.
845Default is the displayed message." t nil)
740 846
741(autoload (quote mh-narrow-to-seq) "mh-seq" "\ 847(autoload (quote mh-narrow-to-seq) "mh-seq" "\
742Restrict display of this folder to just messages in SEQUENCE. 848Restrict display of this folder to just messages in SEQUENCE.
743Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command." t nil) 849Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command." t nil)
744 850
745(autoload (quote mh-put-msg-in-seq) "mh-seq" "\ 851(autoload (quote mh-put-msg-in-seq) "mh-seq" "\
746Add MSG-OR-SEQ (default: displayed message) to SEQUENCE. 852Add MSG-OR-SEQ to SEQUENCE.
747If optional prefix argument provided, then prompt for the message sequence. 853Default is the displayed message.
748If variable `transient-mark-mode' is non-nil and the mark is active, then 854If optional prefix argument is provided, then prompt for the message sequence.
749the selected region is added to the sequence." t nil) 855If variable `transient-mark-mode' is non-nil and the mark is active, then the
856selected region is added to the sequence.
857In a program, MSG-OR-SEQ can be a message number, a list of message numbers, a
858region in a cons cell, or a sequence." t nil)
750 859
751(autoload (quote mh-widen) "mh-seq" "\ 860(autoload (quote mh-widen) "mh-seq" "\
752Remove restrictions from current folder, thereby showing all messages." t nil) 861Remove restrictions from current folder, thereby showing all messages." t nil)
@@ -779,6 +888,34 @@ till END. In each step BODY is executed.
779 888
780If VAR is nil then the loop is executed without any binding." nil (quote macro)) 889If VAR is nil then the loop is executed without any binding." nil (quote macro))
781 890
891(autoload (quote mh-iterate-on-msg-or-seq) "mh-seq" "\
892Iterate an operation over a region or sequence.
893
894VAR is bound to each message in turn in a loop over MSG-OR-SEQ, which can be a
895message number, a list of message numbers, a sequence, or a region in a cons
896cell. In each iteration, BODY is executed.
897
898The parameter MSG-OR-SEQ is usually created with `mh-interactive-msg-or-seq'
899in order to provide a uniform interface to MH-E functions." nil (quote macro))
900
901(autoload (quote mh-msg-or-seq-to-msg-list) "mh-seq" "\
902Return a list of messages for MSG-OR-SEQ.
903MSG-OR-SEQ can be a message number, a list of message numbers, a sequence, or
904a region in a cons cell." nil nil)
905
906(autoload (quote mh-interactive-msg-or-seq) "mh-seq" "\
907Return interactive specification for message, sequence, or region.
908By convention, the name of this argument is msg-or-seq.
909
910If variable `transient-mark-mode' is non-nil and the mark is active, then this
911function returns a cons-cell of the region.
912If optional prefix argument provided, then prompt for message sequence with
913SEQUENCE-PROMPT and return sequence.
914Otherwise, the message number at point is returned.
915
916This function is usually used with `mh-iterate-on-msg-or-seq' in order to
917provide a uniform interface to MH-E functions." nil nil)
918
782(autoload (quote mh-region-to-msg-list) "mh-seq" "\ 919(autoload (quote mh-region-to-msg-list) "mh-seq" "\
783Return a list of messages within the region between BEGIN and END." nil nil) 920Return a list of messages within the region between BEGIN and END." nil nil)
784 921
@@ -829,11 +966,23 @@ Mark current message and all its children for subsequent deletion." t nil)
829(autoload (quote mh-thread-refile) "mh-seq" "\ 966(autoload (quote mh-thread-refile) "mh-seq" "\
830Mark current message and all its children for refiling to FOLDER." t nil) 967Mark current message and all its children for refiling to FOLDER." t nil)
831 968
969(autoload (quote mh-notate-tick) "mh-seq" "\
970Highlight current line if MSG is in TICKED-MSGS.
971If optional argument IGNORE-NARROWING is non-nil then highlighting is carried
972out even if folder is narrowed to `mh-tick-seq'." nil nil)
973
974(autoload (quote mh-toggle-tick) "mh-seq" "\
975Toggle tick mark of all messages in region BEGIN to END." t nil)
976
977(autoload (quote mh-narrow-to-tick) "mh-seq" "\
978Restrict display of this folder to just messages in `mh-tick-seq'.
979Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command." t nil)
980
832;;;*** 981;;;***
833 982
834;;;### (autoloads (mh-speed-add-folder mh-speed-invalidate-map mh-speed-flists 983;;;### (autoloads (mh-speed-add-folder mh-speed-invalidate-map mh-speed-flists
835;;;;;; mh-speed-view mh-speed-toggle mh-folder-speedbar-buttons) 984;;;;;; mh-speed-view mh-speed-toggle mh-folder-speedbar-buttons)
836;;;;;; "mh-speed" "mh-speed.el" (15933 21584)) 985;;;;;; "mh-speed" "mh-speed.el" (16037 44491))
837;;; Generated autoloads from mh-speed.el 986;;; Generated autoloads from mh-speed.el
838 987
839(autoload (quote mh-folder-speedbar-buttons) "mh-speed" "\ 988(autoload (quote mh-folder-speedbar-buttons) "mh-speed" "\
@@ -854,7 +1003,8 @@ Optional ARGS are ignored." t nil)
854 1003
855(autoload (quote mh-speed-flists) "mh-speed" "\ 1004(autoload (quote mh-speed-flists) "mh-speed" "\
856Execute flists -recurse and update message counts. 1005Execute flists -recurse and update message counts.
857If FORCE is non-nil the timer is reset." t nil) 1006If FORCE is non-nil the timer is reset. If FOLDER is non-nil then flists is run
1007only for that one folder." t nil)
858 1008
859(autoload (quote mh-speed-invalidate-map) "mh-speed" "\ 1009(autoload (quote mh-speed-invalidate-map) "mh-speed" "\
860Remove FOLDER from various optimization caches." t nil) 1010Remove FOLDER from various optimization caches." t nil)
@@ -866,7 +1016,7 @@ The function invalidates the latest ancestor that is present." nil nil)
866;;;*** 1016;;;***
867 1017
868;;;### (autoloads (mh-get-msg-num mh-goto-address-find-address-at-point) 1018;;;### (autoloads (mh-get-msg-num mh-goto-address-find-address-at-point)
869;;;;;; "mh-utils" "mh-utils.el" (15924 47279)) 1019;;;;;; "mh-utils" "mh-utils.el" (16039 40655))
870;;; Generated autoloads from mh-utils.el 1020;;; Generated autoloads from mh-utils.el
871 1021
872(autoload (quote mh-goto-address-find-address-at-point) "mh-utils" "\ 1022(autoload (quote mh-goto-address-find-address-at-point) "mh-utils" "\
@@ -885,7 +1035,7 @@ not pointing to a message." nil nil)
885;;;;;; mh-alias-add-alias mh-alias-from-has-no-alias-p mh-alias-address-to-alias 1035;;;;;; mh-alias-add-alias mh-alias-from-has-no-alias-p mh-alias-address-to-alias
886;;;;;; mh-alias-letter-expand-alias mh-alias-minibuffer-confirm-address 1036;;;;;; mh-alias-letter-expand-alias mh-alias-minibuffer-confirm-address
887;;;;;; mh-read-address mh-alias-reload) "mh-alias" "mh-alias.el" 1037;;;;;; mh-read-address mh-alias-reload) "mh-alias" "mh-alias.el"
888;;;;;; (15924 45743)) 1038;;;;;; (16039 39579))
889;;; Generated autoloads from mh-alias.el 1039;;; Generated autoloads from mh-alias.el
890 1040
891(autoload (quote mh-alias-reload) "mh-alias" "\ 1041(autoload (quote mh-alias-reload) "mh-alias" "\
@@ -904,7 +1054,9 @@ Expand mail alias before point." nil nil)
904Return the ADDRESS alias if defined, or nil." nil nil) 1054Return the ADDRESS alias if defined, or nil." nil nil)
905 1055
906(autoload (quote mh-alias-from-has-no-alias-p) "mh-alias" "\ 1056(autoload (quote mh-alias-from-has-no-alias-p) "mh-alias" "\
907Return t is From has no current alias set." nil nil) 1057Return t is From has no current alias set.
1058In the exceptional situation where there isn't a From header in the message the
1059function returns nil." nil nil)
908 1060
909(autoload (quote mh-alias-add-alias) "mh-alias" "\ 1061(autoload (quote mh-alias-add-alias) "mh-alias" "\
910*Add ALIAS for ADDRESS in personal alias file. 1062*Add ALIAS for ADDRESS in personal alias file.
diff --git a/lisp/mh-e/mh-mime.el b/lisp/mh-e/mh-mime.el
index a14a548e2c4..76bda78b70e 100644
--- a/lisp/mh-e/mh-mime.el
+++ b/lisp/mh-e/mh-mime.el
@@ -1,6 +1,6 @@
1;;; mh-mime.el --- MH-E support for composing MIME messages 1;;; mh-mime.el --- MH-E support for composing MIME messages
2 2
3;; Copyright (C) 1993, 1995, 2001, 2002 Free Software Foundation, Inc. 3;; Copyright (C) 1993, 1995, 2001, 02, 2003 Free Software Foundation, Inc.
4 4
5;; Author: Bill Wohler <wohler@newt.com> 5;; Author: Bill Wohler <wohler@newt.com>
6;; Maintainer: Bill Wohler <wohler@newt.com> 6;; Maintainer: Bill Wohler <wohler@newt.com>
@@ -32,8 +32,6 @@
32 32
33;;; Change Log: 33;;; Change Log:
34 34
35;; $Id: mh-mime.el,v 1.100 2003/01/25 19:18:51 satyaki Exp $
36
37;;; Code: 35;;; Code:
38 36
39(require 'cl) 37(require 'cl)
@@ -58,6 +56,7 @@
58(autoload 'mml-insert-empty-tag "mml") 56(autoload 'mml-insert-empty-tag "mml")
59(autoload 'mml-to-mime "mml") 57(autoload 'mml-to-mime "mml")
60(autoload 'mml-attach-file "mml") 58(autoload 'mml-attach-file "mml")
59(autoload 'rfc2047-decode-region "rfc2047")
61 60
62;;;###mh-autoload 61;;;###mh-autoload
63(defun mh-compose-insertion (&optional inline) 62(defun mh-compose-insertion (&optional inline)
@@ -235,7 +234,6 @@ See also \\[mh-edit-mhn]."
235The file specified by FILENAME is encoded as TYPE. An optional DESCRIPTION is 234The file specified by FILENAME is encoded as TYPE. An optional DESCRIPTION is
236used as the Content-Description field, optional set of ATTRIBUTES and an 235used as the Content-Description field, optional set of ATTRIBUTES and an
237optional COMMENT can also be included." 236optional COMMENT can also be included."
238 (setq mh-mhn-compose-insert-flag t)
239 (beginning-of-line) 237 (beginning-of-line)
240 (insert "#" type) 238 (insert "#" type)
241 (and attributes 239 (and attributes
@@ -306,7 +304,6 @@ DESCRIPTION, a line of text for the Content-description header, ATTRIBUTES,
306EXTRA-PARAMS, and COMMENT. 304EXTRA-PARAMS, and COMMENT.
307 305
308See also \\[mh-edit-mhn]." 306See also \\[mh-edit-mhn]."
309 (setq mh-mhn-compose-insert-flag t)
310 (beginning-of-line) 307 (beginning-of-line)
311 (insert "#@" type) 308 (insert "#@" type)
312 (and attributes 309 (and attributes
@@ -341,7 +338,6 @@ See also \\[mh-edit-mhn]."
341 (if mh-sent-from-msg 338 (if mh-sent-from-msg
342 (format " [%d]" mh-sent-from-msg) 339 (format " [%d]" mh-sent-from-msg)
343 ""))))) 340 "")))))
344 (setq mh-mhn-compose-insert-flag t)
345 (beginning-of-line) 341 (beginning-of-line)
346 (insert "#forw [") 342 (insert "#forw [")
347 (and description 343 (and description
@@ -368,7 +364,8 @@ Process the current draft with the mhn program, which, using directives
368already inserted in the draft, fills in all the MIME components and header 364already inserted in the draft, fills in all the MIME components and header
369fields. 365fields.
370 366
371This step should be done last just before sending the message. 367This step is performed automatically when sending the message, but this
368function may be called manually before sending the draft as well.
372 369
373The `\\[mh-revert-mhn-edit]' command undoes this command. The arguments in the 370The `\\[mh-revert-mhn-edit]' command undoes this command. The arguments in the
374list `mh-mhn-args' are passed to mhn if this function is passed an optional 371list `mh-mhn-args' are passed to mhn if this function is passed an optional
@@ -379,8 +376,7 @@ components in a message, see \\[mh-mhn-compose-insertion] (generic insertion
379from a file), \\[mh-mhn-compose-anon-ftp] (external reference to file via 376from a file), \\[mh-mhn-compose-anon-ftp] (external reference to file via
380anonymous ftp), \\[mh-mhn-compose-external-compressed-tar] \ \(reference to 377anonymous ftp), \\[mh-mhn-compose-external-compressed-tar] \ \(reference to
381compressed tar file via anonymous ftp), and \\[mh-mhn-compose-forw] (forward 378compressed tar file via anonymous ftp), and \\[mh-mhn-compose-forw] (forward
382message). If these helper functions are used, `mh-edit-mhn' is run 379message).
383automatically when the draft is sent.
384 380
385The value of `mh-edit-mhn-hook' is a list of functions to be called, with no 381The value of `mh-edit-mhn-hook' is a list of functions to be called, with no
386arguments, after performing the conversion. 382arguments, after performing the conversion.
@@ -396,7 +392,6 @@ The mhn program is part of MH version 6.8 or later."
396 (t 392 (t
397 (mh-exec-cmd-error (format "mhdraft=%s" buffer-file-name) 393 (mh-exec-cmd-error (format "mhdraft=%s" buffer-file-name)
398 "mhn" (if extra-args mh-mhn-args) buffer-file-name))) 394 "mhn" (if extra-args mh-mhn-args) buffer-file-name)))
399 (setq mh-mhn-compose-insert-flag nil)
400 (revert-buffer t t) 395 (revert-buffer t t)
401 (message "mhn editing...done") 396 (message "mhn editing...done")
402 (run-hooks 'mh-edit-mhn-hook)) 397 (run-hooks 'mh-edit-mhn-hook))
@@ -429,18 +424,35 @@ Optional non-nil argument NOCONFIRM means don't ask for confirmation."
429 (insert-file-contents backup-file)) 424 (insert-file-contents backup-file))
430 (after-find-file nil))) 425 (after-find-file nil)))
431 426
427;;;###mh-autoload
428(defun mh-mhn-directive-present-p ()
429 "Check if the current buffer has text which might be a MHN directive."
430 (save-excursion
431 (block 'search-for-mhn-directive
432 (goto-char (point-min))
433 (while (re-search-forward "^#" nil t)
434 (let ((s (buffer-substring-no-properties (point) (line-end-position))))
435 (cond ((equal s ""))
436 ((string-match "^forw[ \t\n]+" s)
437 (return-from 'search-for-mhn-directive t))
438 (t (let ((first-token (car (split-string s "[ \t;@]"))))
439 (when (string-match mh-media-type-regexp first-token)
440 (return-from 'search-for-mhn-directive t)))))))
441 nil)))
442
432 443
433 444
434;;; MIME composition functions 445;;; MIME composition functions
435 446
436;;;###mh-autoload 447;;;###mh-autoload
437(defun mh-mml-to-mime () 448(defun mh-mml-to-mime ()
438 "Compose MIME message from mml directives." 449 "Compose MIME message from mml directives.
450This step is performed automatically when sending the message, but this
451function may be called manually before sending the draft as well."
439 (interactive) 452 (interactive)
440 (when mh-gnus-pgp-support-flag ;; This is only needed for PGP 453 (when mh-gnus-pgp-support-flag ;; This is only needed for PGP
441 (message-options-set-recipient)) 454 (message-options-set-recipient))
442 (mml-to-mime) 455 (mml-to-mime))
443 (setq mh-mml-compose-insert-flag nil))
444 456
445;;;###mh-autoload 457;;;###mh-autoload
446(defun mh-mml-forward-message (description folder message) 458(defun mh-mml-forward-message (description folder message)
@@ -460,8 +472,7 @@ number."
460 (mml-attach-file (format "%s%s/%d" 472 (mml-attach-file (format "%s%s/%d"
461 mh-user-path (substring folder 1) msg) 473 mh-user-path (substring folder 1) msg)
462 "message/rfc822" 474 "message/rfc822"
463 description)) 475 description)))
464 (setq mh-mml-compose-insert-flag t))
465 (t (error "The message number, %s is not a integer!" msg))))) 476 (t (error "The message number, %s is not a integer!" msg)))))
466 477
467;;;###mh-autoload 478;;;###mh-autoload
@@ -488,8 +499,7 @@ automatically."
488 nil t nil nil 499 nil t nil nil
489 "attachment")))) 500 "attachment"))))
490 (mml-insert-empty-tag 'part 'type type 'filename file 501 (mml-insert-empty-tag 'part 'type type 'filename file
491 'disposition dispos 'description description) 502 'disposition dispos 'description description)))
492 (setq mh-mml-compose-insert-flag t)))
493 503
494;;;###mh-autoload 504;;;###mh-autoload
495(defun mh-mml-secure-message-sign-pgpmime () 505(defun mh-mml-secure-message-sign-pgpmime ()
@@ -497,8 +507,7 @@ automatically."
497 (interactive) 507 (interactive)
498 (if (not mh-gnus-pgp-support-flag) 508 (if (not mh-gnus-pgp-support-flag)
499 (error "Sorry. Your version of gnus does not support PGP/GPG") 509 (error "Sorry. Your version of gnus does not support PGP/GPG")
500 (mml-secure-message-sign-pgpmime) 510 (mml-secure-message-sign-pgpmime)))
501 (setq mh-mml-compose-insert-flag t)))
502 511
503;;;###mh-autoload 512;;;###mh-autoload
504(defun mh-mml-secure-message-encrypt-pgpmime (&optional dontsign) 513(defun mh-mml-secure-message-encrypt-pgpmime (&optional dontsign)
@@ -507,8 +516,16 @@ If called with a prefix argument DONTSIGN, only encrypt (do NOT sign)."
507 (interactive "P") 516 (interactive "P")
508 (if (not mh-gnus-pgp-support-flag) 517 (if (not mh-gnus-pgp-support-flag)
509 (error "Sorry. Your version of gnus does not support PGP/GPG") 518 (error "Sorry. Your version of gnus does not support PGP/GPG")
510 (mml-secure-message-encrypt-pgpmime dontsign) 519 (mml-secure-message-encrypt-pgpmime dontsign)))
511 (setq mh-mml-compose-insert-flag t))) 520
521;;;###mh-autoload
522(defun mh-mml-directive-present-p ()
523 "Check if the current buffer has text which may be an MML directive."
524 (save-excursion
525 (goto-char (point-min))
526 (re-search-forward
527 "\\(<#part\\(.\\|\n\\)*>[ \n\t]*<#/part>\\|^<#secure.+>$\\)"
528 nil t)))
512 529
513 530
514 531
@@ -547,6 +564,8 @@ BODY."
547(mh-defun-compat mm-handle-multipart-ctl-parameter (handle parameter) 564(mh-defun-compat mm-handle-multipart-ctl-parameter (handle parameter)
548 (get-text-property 0 parameter (car handle))) 565 (get-text-property 0 parameter (car handle)))
549 566
567(mh-do-in-xemacs (defvar default-enable-multibyte-characters))
568
550;; Copy of original function in mm-decode.el 569;; Copy of original function in mm-decode.el
551(mh-defun-compat mm-readable-p (handle) 570(mh-defun-compat mm-readable-p (handle)
552 "Say whether the content of HANDLE is readable." 571 "Say whether the content of HANDLE is readable."
@@ -610,8 +629,7 @@ BODY."
610 "Free the decoded MIME parts." 629 "Free the decoded MIME parts."
611 (let ((mime-data (gethash (current-buffer) mh-globals-hash))) 630 (let ((mime-data (gethash (current-buffer) mh-globals-hash)))
612 ;; This is for Emacs, what about XEmacs? 631 ;; This is for Emacs, what about XEmacs?
613 (cond ((fboundp 'remove-images) 632 (mh-funcall-if-exists remove-images (point-min) (point-max))
614 (remove-images (point-min) (point-max))))
615 (when mime-data 633 (when mime-data
616 (mm-destroy-parts (mh-mime-handles mime-data)) 634 (mm-destroy-parts (mh-mime-handles mime-data))
617 (remhash (current-buffer) mh-globals-hash)))) 635 (remhash (current-buffer) mh-globals-hash))))
@@ -662,6 +680,7 @@ I have seen this only in spam, so maybe we shouldn't fix this ;-)"
662 (when (and mh-graphical-smileys-flag 680 (when (and mh-graphical-smileys-flag
663 (fboundp 'smiley-region) 681 (fboundp 'smiley-region)
664 (boundp 'font-lock-maximum-size) 682 (boundp 'font-lock-maximum-size)
683 font-lock-maximum-size
665 (>= (/ font-lock-maximum-size 8) (buffer-size))) 684 (>= (/ font-lock-maximum-size 8) (buffer-size)))
666 (smiley-region (point-min) (point-max)))) 685 (smiley-region (point-min) (point-max))))
667 686
@@ -669,8 +688,8 @@ I have seen this only in spam, so maybe we shouldn't fix this ;-)"
669(defun mh-display-emphasis () 688(defun mh-display-emphasis ()
670 "Function to display graphical emphasis." 689 "Function to display graphical emphasis."
671 (when (and mh-graphical-emphasis-flag 690 (when (and mh-graphical-emphasis-flag
672 (boundp 'font-lock-maximum-size) 691 (if font-lock-maximum-size
673 (>= (/ font-lock-maximum-size 8) (buffer-size))) 692 (>= (/ font-lock-maximum-size 8) (buffer-size))))
674 (flet ((article-goto-body ())) ; shadow this function to do nothing 693 (flet ((article-goto-body ())) ; shadow this function to do nothing
675 (save-excursion 694 (save-excursion
676 (goto-char (point-min)) 695 (goto-char (point-min))
@@ -685,7 +704,10 @@ I have seen this only in spam, so maybe we shouldn't fix this ;-)"
685 (unless (>= (string-to-number emacs-version) 21) 704 (unless (>= (string-to-number emacs-version) 21)
686 ;; XEmacs doesn't care. 705 ;; XEmacs doesn't care.
687 (set-keymap-parent map mh-show-mode-map)) 706 (set-keymap-parent map mh-show-mode-map))
688 (define-key map [mouse-2] 'mh-push-button) 707 (mh-do-in-gnu-emacs
708 (define-key map [mouse-2] 'mh-push-button))
709 (mh-do-in-xemacs
710 (define-key map '(button2) 'mh-push-button))
689 (dolist (c mh-mime-button-commands) 711 (dolist (c mh-mime-button-commands)
690 (define-key map (cadr c) (car c))) 712 (define-key map (cadr c) (car c)))
691 map)) 713 map))
@@ -708,7 +730,10 @@ I have seen this only in spam, so maybe we shouldn't fix this ;-)"
708 (unless (>= (string-to-number emacs-version) 21) 730 (unless (>= (string-to-number emacs-version) 21)
709 (set-keymap-parent map mh-show-mode-map)) 731 (set-keymap-parent map mh-show-mode-map))
710 (define-key map "\r" 'mh-press-button) 732 (define-key map "\r" 'mh-press-button)
711 (define-key map [mouse-2] 'mh-push-button) 733 (mh-do-in-gnu-emacs
734 (define-key map [mouse-2] 'mh-push-button))
735 (mh-do-in-xemacs
736 (define-key map '(button2) 'mh-push-button))
712 map)) 737 map))
713 738
714(defvar mh-mime-save-parts-directory nil 739(defvar mh-mime-save-parts-directory nil
@@ -755,22 +780,46 @@ actual storing."
755 (if (equal nil mh-mime-save-parts-default-directory) 780 (if (equal nil mh-mime-save-parts-default-directory)
756 (setq mh-mime-save-parts-directory directory)) 781 (setq mh-mime-save-parts-directory directory))
757 (save-excursion 782 (save-excursion
758 (set-buffer (get-buffer-create " *mh-store*")) 783 (set-buffer (get-buffer-create mh-log-buffer))
759 (cd directory) 784 (cd directory)
760 (setq mh-mime-save-parts-directory directory) 785 (setq mh-mime-save-parts-directory directory)
761 (erase-buffer) 786 (let ((initial-size (mh-truncate-log-buffer)))
762 (apply 'call-process 787 (apply 'call-process
763 (expand-file-name command mh-progs) nil t nil 788 (expand-file-name command mh-progs) nil t nil
764 (mh-list-to-string (list folder msg "-auto"))) 789 (mh-list-to-string (list folder msg "-auto")))
765 (if (> (buffer-size) 0) 790 (if (> (buffer-size) initial-size)
766 (save-window-excursion 791 (save-window-excursion
767 (switch-to-buffer-other-window " *mh-store*") 792 (switch-to-buffer-other-window mh-log-buffer)
768 (sit-for 3))))))) 793 (sit-for 3))))))))
769 794
770;; Avoid errors if gnus-sum isn't loaded yet... 795;; Avoid errors if gnus-sum isn't loaded yet...
771(defvar gnus-newsgroup-charset nil) 796(defvar gnus-newsgroup-charset nil)
772(defvar gnus-newsgroup-name nil) 797(defvar gnus-newsgroup-name nil)
773 798
799(defun mh-decode-message-body ()
800 "Decode message based on charset.
801If message has been encoded for transfer take that into account."
802 (let* ((ct (ignore-errors (mail-header-parse-content-type
803 (message-fetch-field "Content-Type" t))))
804 (charset (mail-content-type-get ct 'charset))
805 (cte (message-fetch-field "Content-Transfer-Encoding")))
806 (when (stringp cte) (setq cte (mail-header-strip cte)))
807 (when (or (not ct) (equal (car ct) "text/plain"))
808 (save-restriction
809 (narrow-to-region (min (1+ (mh-mail-header-end)) (point-max))
810 (point-max))
811 (mm-decode-body charset
812 (and cte (intern (downcase
813 (gnus-strip-whitespace cte))))
814 (car ct))))))
815
816;;;###mh-autoload
817(defun mh-decode-message-header ()
818 "Decode RFC2047 encoded message header fields."
819 (when mh-decode-mime-flag
820 (let ((buffer-read-only nil))
821 (rfc2047-decode-region (point-min) (mh-mail-header-end)))))
822
774;;;###mh-autoload 823;;;###mh-autoload
775(defun mh-mime-display (&optional pre-dissected-handles) 824(defun mh-mime-display (&optional pre-dissected-handles)
776 "Display (and possibly decode) MIME handles. 825 "Display (and possibly decode) MIME handles.
@@ -778,36 +827,43 @@ Optional argument, PRE-DISSECTED-HANDLES is a list of MIME handles. If
778present they are displayed otherwise the buffer is parsed and then 827present they are displayed otherwise the buffer is parsed and then
779displayed." 828displayed."
780 (let ((handles ()) 829 (let ((handles ())
781 (folder mh-show-folder-buffer)) 830 (folder mh-show-folder-buffer)
831 (raw-message-data (buffer-string)))
782 (flet ((mm-handle-set-external-undisplayer 832 (flet ((mm-handle-set-external-undisplayer
783 (handle function) 833 (handle function)
784 (mh-handle-set-external-undisplayer folder handle function))) 834 (mh-handle-set-external-undisplayer folder handle function)))
785 ;; If needed dissect the current buffer 835 (goto-char (point-min))
786 (if pre-dissected-handles 836 (unless (search-forward "\n\n" nil t)
787 (setq handles pre-dissected-handles) 837 (goto-char (point-max))
788 (setq handles (or (mm-dissect-buffer nil) (mm-uu-dissect))) 838 (insert "\n\n"))
789 (setf (mh-mime-handles (mh-buffer-data)) 839
790 (mm-merge-handles handles (mh-mime-handles (mh-buffer-data)))) 840 (condition-case err
791 841 (progn
792 ;; Use charset to decode body... 842 ;; If needed dissect the current buffer
793 (unless handles 843 (if pre-dissected-handles
794 (let* ((ct (ignore-errors 844 (setq handles pre-dissected-handles)
795 (mail-header-parse-content-type 845 (setq handles (or (mm-dissect-buffer nil) (mm-uu-dissect)))
796 (message-fetch-field "Content-Type" t)))) 846 (setf (mh-mime-handles (mh-buffer-data))
797 (charset (mail-content-type-get ct 'charset))) 847 (mm-merge-handles handles
798 (when (stringp charset) 848 (mh-mime-handles (mh-buffer-data))))
799 (mm-decode-body charset))))) 849 (unless handles (mh-decode-message-body)))
800 850
801 (when (and handles (or (not (stringp (car handles))) (cdr handles))) 851 (when (and handles
802 ;; Goto start of message body 852 (or (not (stringp (car handles))) (cdr handles)))
803 (goto-char (point-min)) 853 ;; Goto start of message body
804 (or (search-forward "\n\n" nil t) (goto-char (point-max))) 854 (goto-char (point-min))
855 (or (search-forward "\n\n" nil t) (goto-char (point-max)))
805 856
806 ;; Delete the body 857 ;; Delete the body
807 (delete-region (point) (point-max)) 858 (delete-region (point) (point-max))
808 859
809 ;; Display the MIME handles 860 ;; Display the MIME handles
810 (mh-mime-display-part handles))))) 861 (mh-mime-display-part handles)))
862 (error
863 (message "Please report this error. The error message is:\n %s"
864 (error-message-string err))
865 (delete-region (point-min) (point-max))
866 (insert raw-message-data))))))
811 867
812(defun mh-mime-display-part (handle) 868(defun mh-mime-display-part (handle)
813 "Decides the viewer to call based on the type of HANDLE." 869 "Decides the viewer to call based on the type of HANDLE."
@@ -868,7 +924,8 @@ This is only useful if a Content-Disposition header is not present."
868 (let* ((image (mm-get-image handle))) 924 (let* ((image (mm-get-image handle)))
869 (cond ((fboundp 'glyph-width) 925 (cond ((fboundp 'glyph-width)
870 ;; XEmacs -- totally untested, copied from gnus 926 ;; XEmacs -- totally untested, copied from gnus
871 (and (< (glyph-width image) 927 (and (mh-funcall-if-exists glyphp image)
928 (< (glyph-width image)
872 (or mh-max-inline-image-width 929 (or mh-max-inline-image-width
873 (window-pixel-width))) 930 (window-pixel-width)))
874 (< (glyph-height image) 931 (< (glyph-height image)
@@ -876,8 +933,9 @@ This is only useful if a Content-Disposition header is not present."
876 (window-pixel-height))))) 933 (window-pixel-height)))))
877 ((fboundp 'image-size) 934 ((fboundp 'image-size)
878 ;; Emacs21 -- copied from gnus 935 ;; Emacs21 -- copied from gnus
879 (let ((size (image-size image))) 936 (let ((size (mh-funcall-if-exists image-size image)))
880 (and (< (cdr size) 937 (and size
938 (< (cdr size)
881 (or mh-max-inline-image-height 939 (or mh-max-inline-image-height
882 (1- (window-height)))) 940 (1- (window-height))))
883 (< (car size) 941 (< (car size)
@@ -889,7 +947,8 @@ This is only useful if a Content-Disposition header is not present."
889(defun mh-inline-vcard-p (handle) 947(defun mh-inline-vcard-p (handle)
890 "Decide if HANDLE is a vcard that must be displayed inline." 948 "Decide if HANDLE is a vcard that must be displayed inline."
891 (let ((type (mm-handle-type handle))) 949 (let ((type (mm-handle-type handle)))
892 (and (consp type) 950 (and (or (featurep 'vcard) (fboundp 'vcard-pretty-print))
951 (consp type)
893 (equal (car type) "text/x-vcard") 952 (equal (car type) "text/x-vcard")
894 (save-excursion 953 (save-excursion
895 (save-restriction 954 (save-restriction
@@ -933,6 +992,10 @@ This is only useful if a Content-Disposition header is not present."
933 (mh-mm-display-part handle))) 992 (mh-mm-display-part handle)))
934 (goto-char (point-max))))) 993 (goto-char (point-max)))))
935 994
995(mh-do-in-xemacs
996 (defvar dots)
997 (defvar type))
998
936(defun mh-insert-mime-button (handle index displayed) 999(defun mh-insert-mime-button (handle index displayed)
937 "Insert MIME button for HANDLE. 1000 "Insert MIME button for HANDLE.
938INDEX is the part number that will be DISPLAYED. It is also used by commands 1001INDEX is the part number that will be DISPLAYED. It is also used by commands
@@ -999,9 +1062,9 @@ like \"K v\" which operate on individual MIME parts."
999 (progn 1062 (progn
1000 ;; Delete the button and displayed part (if any) 1063 ;; Delete the button and displayed part (if any)
1001 (let ((region (get-text-property point 'mh-region))) 1064 (let ((region (get-text-property point 'mh-region)))
1002 (when region 1065 (when (and region (fboundp 'remove-images))
1003 (when (fboundp 'remove-images) 1066 (mh-funcall-if-exists
1004 (remove-images (car region) (cdr region)))) 1067 remove-images (car region) (cdr region)))
1005 (mm-display-part handle) 1068 (mm-display-part handle)
1006 (when region 1069 (when region
1007 (delete-region (car region) (cdr region)))) 1070 (delete-region (car region) (cdr region))))
@@ -1067,20 +1130,33 @@ If the MIME part is visible then it is removed. Otherwise the part is
1067displayed. This function is called when the mouse is used to click the MIME 1130displayed. This function is called when the mouse is used to click the MIME
1068button." 1131button."
1069 (interactive "e") 1132 (interactive "e")
1070 (set-buffer (window-buffer (posn-window (event-start event)))) 1133 (save-excursion
1071 (select-window (posn-window (event-start event))) 1134 (let* ((event-window
1072 (let* ((pos (posn-point (event-start event))) 1135 (or (mh-funcall-if-exists posn-window (event-start event));GNU Emacs
1073 (folder mh-show-folder-buffer) 1136 (mh-funcall-if-exists event-window event))) ;XEmacs
1074 (mm-inline-media-tests mh-mm-inline-media-tests) 1137 (event-position
1075 (data (get-text-property pos 'mh-data)) 1138 (or (mh-funcall-if-exists posn-point (event-start event)) ;GNU Emacs
1076 (function (get-text-property pos 'mh-callback)) 1139 (mh-funcall-if-exists event-closest-point event))) ;XEmacs
1077 (buffer-read-only nil)) 1140 (original-window (selected-window))
1078 (flet ((mm-handle-set-external-undisplayer 1141 (original-position (progn
1079 (handle function) 1142 (set-buffer (window-buffer event-window))
1080 (mh-handle-set-external-undisplayer folder handle function))) 1143 (set-marker (make-marker) (point))))
1081 (goto-char pos) 1144 (folder mh-show-folder-buffer)
1082 (unwind-protect (and function (funcall function data)) 1145 (mm-inline-media-tests mh-mm-inline-media-tests)
1083 (set-buffer-modified-p nil))))) 1146 (data (get-text-property event-position 'mh-data))
1147 (function (get-text-property event-position 'mh-callback))
1148 (buffer-read-only nil))
1149 (unwind-protect
1150 (progn
1151 (select-window event-window)
1152 (flet ((mm-handle-set-external-undisplayer (handle func)
1153 (mh-handle-set-external-undisplayer folder handle func)))
1154 (goto-char event-position)
1155 (and function (funcall function data))))
1156 (set-buffer-modified-p nil)
1157 (goto-char original-position)
1158 (set-marker original-position nil)
1159 (select-window original-window)))))
1084 1160
1085;;;###mh-autoload 1161;;;###mh-autoload
1086(defun mh-mime-save-part () 1162(defun mh-mime-save-part ()
@@ -1242,6 +1318,7 @@ message multiple times."
1242 handles)))) 1318 handles))))
1243 1319
1244 (goto-char (point-min)) 1320 (goto-char (point-min))
1321 (mh-show-xface)
1245 (cond (clean-message-header 1322 (cond (clean-message-header
1246 (mh-clean-msg-header (point-min) 1323 (mh-clean-msg-header (point-min)
1247 invisible-headers 1324 invisible-headers
@@ -1249,7 +1326,7 @@ message multiple times."
1249 (goto-char (point-min))) 1326 (goto-char (point-min)))
1250 (t 1327 (t
1251 (mh-start-of-uncleaned-message))) 1328 (mh-start-of-uncleaned-message)))
1252 (mh-show-xface) 1329 (mh-decode-message-header)
1253 (mh-show-addr) 1330 (mh-show-addr)
1254 ;; The other highlighting types don't need anything special 1331 ;; The other highlighting types don't need anything special
1255 (when (eq mh-highlight-citation-p 'gnus) 1332 (when (eq mh-highlight-citation-p 'gnus)
diff --git a/lisp/mh-e/mh-pick.el b/lisp/mh-e/mh-pick.el
index 3367392343b..f9a30e75bc2 100644
--- a/lisp/mh-e/mh-pick.el
+++ b/lisp/mh-e/mh-pick.el
@@ -1,6 +1,6 @@
1;;; mh-pick.el --- make a search pattern and search for a message in MH-E 1;;; mh-pick.el --- make a search pattern and search for a message in MH-E
2 2
3;; Copyright (C) 1993, 1995, 2001 Free Software Foundation, Inc. 3;; Copyright (C) 1993, 1995, 2001, 2003 Free Software Foundation, Inc.
4 4
5;; Author: Bill Wohler <wohler@newt.com> 5;; Author: Bill Wohler <wohler@newt.com>
6;; Maintainer: Bill Wohler <wohler@newt.com> 6;; Maintainer: Bill Wohler <wohler@newt.com>
@@ -30,8 +30,6 @@
30 30
31;;; Change Log: 31;;; Change Log:
32 32
33;; $Id: mh-pick.el,v 1.30 2003/01/27 04:16:47 wohler Exp $
34
35;;; Code: 33;;; Code:
36 34
37(require 'mh-e) 35(require 'mh-e)
@@ -62,9 +60,9 @@ the search folder is dismissed."
62 (mh-make-pick-template) 60 (mh-make-pick-template)
63 (message "")) 61 (message ""))
64 (setq mh-searching-function 'mh-pick-do-search 62 (setq mh-searching-function 'mh-pick-do-search
65 mh-searching-folder pick-folder 63 mh-searching-folder pick-folder)
66 mh-current-folder folder 64 (mh-make-local-vars 'mh-current-folder folder
67 mh-previous-window-config window-config) 65 'mh-previous-window-config window-config)
68 (message "%s" (substitute-command-keys 66 (message "%s" (substitute-command-keys
69 (concat "Type \\[mh-do-search] to search messages, " 67 (concat "Type \\[mh-do-search] to search messages, "
70 "\\[mh-help] for help."))))) 68 "\\[mh-help] for help.")))))
diff --git a/lisp/mh-e/mh-seq.el b/lisp/mh-e/mh-seq.el
index f00afa84f86..f5356509256 100644
--- a/lisp/mh-e/mh-seq.el
+++ b/lisp/mh-e/mh-seq.el
@@ -1,6 +1,6 @@
1;;; mh-seq.el --- MH-E sequences support 1;;; mh-seq.el --- MH-E sequences support
2 2
3;; Copyright (C) 1993, 1995, 2001, 2002 Free Software Foundation, Inc. 3;; Copyright (C) 1993, 1995, 2001, 02, 2003 Free Software Foundation, Inc.
4 4
5;; Author: Bill Wohler <wohler@newt.com> 5;; Author: Bill Wohler <wohler@newt.com>
6;; Maintainer: Bill Wohler <wohler@newt.com> 6;; Maintainer: Bill Wohler <wohler@newt.com>
@@ -68,8 +68,6 @@
68 68
69;;; Change Log: 69;;; Change Log:
70 70
71;; $Id: mh-seq.el,v 1.101 2003/01/26 00:57:35 jchonig Exp $
72
73;;; Code: 71;;; Code:
74 72
75(require 'cl) 73(require 'cl)
@@ -146,8 +144,10 @@ redone to get the new thread tree. This makes incremental threading easier.")
146 (mh-undefine-sequence sequence '("all")) 144 (mh-undefine-sequence sequence '("all"))
147 (mh-delete-seq-locally sequence) 145 (mh-delete-seq-locally sequence)
148 (mh-iterate-on-messages-in-region msg (point-min) (point-max) 146 (mh-iterate-on-messages-in-region msg (point-min) (point-max)
149 (when (and (member msg msg-list) (not (mh-seq-containing-msg msg nil))) 147 (cond ((and mh-tick-seq (eq sequence mh-tick-seq))
150 (mh-notate nil ? (1+ mh-cmd-note)))))) 148 (mh-notate-tick msg ()))
149 ((and (member msg msg-list) (not (mh-seq-containing-msg msg nil)))
150 (mh-notate nil ? (1+ mh-cmd-note)))))))
151 151
152;; Avoid compiler warnings 152;; Avoid compiler warnings
153(defvar view-exit-action) 153(defvar view-exit-action)
@@ -195,10 +195,12 @@ redone to get the new thread tree. This makes incremental threading easier.")
195 195
196;;;###mh-autoload 196;;;###mh-autoload
197(defun mh-msg-is-in-seq (message) 197(defun mh-msg-is-in-seq (message)
198 "Display the sequences that contain MESSAGE (default: current message)." 198 "Display the sequences that contain MESSAGE.
199Default is the displayed message."
199 (interactive (list (mh-get-msg-num t))) 200 (interactive (list (mh-get-msg-num t)))
200 (let* ((dest-folder (loop for seq in mh-refile-list 201 (let* ((dest-folder (loop for seq in mh-refile-list
201 when (member message (cdr seq)) return (car seq))) 202 until (member message (cdr seq))
203 finally return (car seq)))
202 (deleted-flag (unless dest-folder (member message mh-delete-list)))) 204 (deleted-flag (unless dest-folder (member message mh-delete-list))))
203 (message "Message %d%s is in sequences: %s" 205 (message "Message %d%s is in sequences: %s"
204 message 206 message
@@ -209,6 +211,9 @@ redone to get the new thread tree. This makes incremental threading easier.")
209 (mh-list-to-string (mh-seq-containing-msg message t)) 211 (mh-list-to-string (mh-seq-containing-msg message t))
210 " ")))) 212 " "))))
211 213
214;; Avoid compiler warning
215(defvar tool-bar-map)
216
212;;;###mh-autoload 217;;;###mh-autoload
213(defun mh-narrow-to-seq (sequence) 218(defun mh-narrow-to-seq (sequence)
214 "Restrict display of this folder to just messages in SEQUENCE. 219 "Restrict display of this folder to just messages in SEQUENCE.
@@ -224,6 +229,7 @@ Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command."
224 (setq mh-thread-scan-line-map (make-hash-table :test #'eql)) 229 (setq mh-thread-scan-line-map (make-hash-table :test #'eql))
225 (mh-copy-seq-to-eob sequence) 230 (mh-copy-seq-to-eob sequence)
226 (narrow-to-region eob (point-max)) 231 (narrow-to-region eob (point-max))
232 (setq mh-narrowed-to-seq sequence)
227 (mh-notate-user-sequences) 233 (mh-notate-user-sequences)
228 (mh-notate-deleted-and-refiled) 234 (mh-notate-deleted-and-refiled)
229 (mh-notate-cur) 235 (mh-notate-cur)
@@ -233,44 +239,42 @@ Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command."
233 (setq mh-mode-line-annotation (symbol-name sequence)) 239 (setq mh-mode-line-annotation (symbol-name sequence))
234 (mh-make-folder-mode-line) 240 (mh-make-folder-mode-line)
235 (mh-recenter nil) 241 (mh-recenter nil)
236 (if (and (boundp 'tool-bar-mode) tool-bar-mode) 242 (when (and (boundp 'tool-bar-mode) tool-bar-mode)
237 (set (make-local-variable 'tool-bar-map) 243 (set (make-local-variable 'tool-bar-map)
238 mh-folder-seq-tool-bar-map)) 244 mh-folder-seq-tool-bar-map)
239 (setq mh-narrowed-to-seq sequence) 245 (when (buffer-live-p (get-buffer mh-show-buffer))
246 (save-excursion
247 (set-buffer (get-buffer mh-show-buffer))
248 (set (make-local-variable 'tool-bar-map)
249 mh-show-seq-tool-bar-map))))
240 (push 'widen mh-view-ops))) 250 (push 'widen mh-view-ops)))
241 (t 251 (t
242 (error "No messages in sequence `%s'" (symbol-name sequence)))))) 252 (error "No messages in sequence `%s'" (symbol-name sequence))))))
243 253
244;;;###mh-autoload 254;;;###mh-autoload
245(defun mh-put-msg-in-seq (msg-or-seq sequence) 255(defun mh-put-msg-in-seq (msg-or-seq sequence)
246 "Add MSG-OR-SEQ (default: displayed message) to SEQUENCE. 256 "Add MSG-OR-SEQ to SEQUENCE.
247If optional prefix argument provided, then prompt for the message sequence. 257Default is the displayed message.
248If variable `transient-mark-mode' is non-nil and the mark is active, then 258If optional prefix argument is provided, then prompt for the message sequence.
249the selected region is added to the sequence." 259If variable `transient-mark-mode' is non-nil and the mark is active, then the
250 (interactive (list (cond 260selected region is added to the sequence.
251 ((mh-mark-active-p t) 261In a program, MSG-OR-SEQ can be a message number, a list of message numbers, a
252 (cons (region-beginning) (region-end))) 262region in a cons cell, or a sequence."
253 (current-prefix-arg 263 (interactive (list (mh-interactive-msg-or-seq "Add messages from")
254 (mh-read-seq-default "Add messages from" t))
255 (t
256 (cons (line-beginning-position) (line-end-position))))
257 (mh-read-seq-default "Add to" nil))) 264 (mh-read-seq-default "Add to" nil)))
258 (let ((internal-seq-flag (mh-internal-seq sequence)) 265 (when (and (interactive-p) mh-tick-seq (eq sequence mh-tick-seq))
259 msg-list) 266 (error "Use `mh-toggle-tick' to add messages to %s" mh-tick-seq))
260 (cond ((and (consp msg-or-seq) 267 (let* ((internal-seq-flag (mh-internal-seq sequence))
261 (numberp (car msg-or-seq)) (numberp (cdr msg-or-seq))) 268 (note-seq (if internal-seq-flag nil mh-note-seq))
262 (mh-iterate-on-messages-in-region m (car msg-or-seq) (cdr msg-or-seq) 269 (msg-list ()))
263 (push m msg-list) 270 (mh-iterate-on-msg-or-seq m msg-or-seq
264 (unless internal-seq-flag 271 (push m msg-list)
265 (mh-notate nil mh-note-seq (1+ mh-cmd-note)))) 272 (mh-notate nil note-seq (1+ mh-cmd-note)))
266 (mh-add-msgs-to-seq msg-list sequence internal-seq-flag t)) 273 (mh-add-msgs-to-seq msg-list sequence nil t)
267 ((or (numberp msg-or-seq) (listp msg-or-seq))
268 (when (numberp msg-or-seq)
269 (setq msg-or-seq (list msg-or-seq)))
270 (mh-add-msgs-to-seq msg-or-seq sequence internal-seq-flag))
271 (t (mh-add-msgs-to-seq (mh-seq-to-msgs msg-or-seq) sequence)))
272 (if (not internal-seq-flag) 274 (if (not internal-seq-flag)
273 (setq mh-last-seq-used sequence)))) 275 (setq mh-last-seq-used sequence))
276 (when (and (eq sequence mh-unseen-seq) (mh-speed-flists-active-p))
277 (mh-speed-flists t mh-current-folder))))
274 278
275(defun mh-valid-view-change-operation-p (op) 279(defun mh-valid-view-change-operation-p (op)
276 "Check if the view change operation can be performed. 280 "Check if the view change operation can be performed.
@@ -300,13 +304,18 @@ OP is one of 'widen and 'unthread."
300 (mh-make-folder-mode-line)) 304 (mh-make-folder-mode-line))
301 (if msg 305 (if msg
302 (mh-goto-msg msg t t)) 306 (mh-goto-msg msg t t))
307 (setq mh-narrowed-to-seq nil)
308 (setq mh-tick-seq-changed-when-narrowed-flag nil)
303 (mh-notate-deleted-and-refiled) 309 (mh-notate-deleted-and-refiled)
304 (mh-notate-user-sequences) 310 (mh-notate-user-sequences)
305 (mh-notate-cur) 311 (mh-notate-cur)
306 (mh-recenter nil))) 312 (mh-recenter nil)))
307 (if (and (boundp 'tool-bar-mode) tool-bar-mode) 313 (when (and (boundp 'tool-bar-mode) tool-bar-mode)
308 (set (make-local-variable 'tool-bar-map) mh-folder-tool-bar-map)) 314 (set (make-local-variable 'tool-bar-map) mh-folder-tool-bar-map)
309 (setq mh-narrowed-to-seq nil)) 315 (when (buffer-live-p (get-buffer mh-show-buffer))
316 (save-excursion
317 (set-buffer (get-buffer mh-show-buffer))
318 (set (make-local-variable 'tool-bar-map) mh-show-tool-bar-map)))))
310 319
311;; FIXME? We may want to clear all notations and add one for current-message 320;; FIXME? We may want to clear all notations and add one for current-message
312;; and process user sequences. 321;; and process user sequences.
@@ -408,8 +417,9 @@ In addition to notating the current message with `mh-note-cur' the function
408uses `overlay-arrow-position' to put a marker in the fringe." 417uses `overlay-arrow-position' to put a marker in the fringe."
409 (let ((cur (car (mh-seq-to-msgs 'cur)))) 418 (let ((cur (car (mh-seq-to-msgs 'cur))))
410 (when (and cur (mh-goto-msg cur t t)) 419 (when (and cur (mh-goto-msg cur t t))
411 (mh-notate nil mh-note-cur mh-cmd-note)
412 (beginning-of-line) 420 (beginning-of-line)
421 (when (looking-at mh-scan-good-msg-regexp)
422 (mh-notate nil mh-note-cur mh-cmd-note))
413 (setq mh-arrow-marker (set-marker mh-arrow-marker (point))) 423 (setq mh-arrow-marker (set-marker mh-arrow-marker (point)))
414 (setq overlay-arrow-position mh-arrow-marker)))) 424 (setq overlay-arrow-position mh-arrow-marker))))
415 425
@@ -431,6 +441,8 @@ uses `overlay-arrow-position' to put a marker in the fringe."
431; ;; LOCATION in the current buffer. 441; ;; LOCATION in the current buffer.
432; (mh-map-to-seq-msgs 'mh-copy-line-to-point seq location)) 442; (mh-map-to-seq-msgs 'mh-copy-line-to-point seq location))
433 443
444(defvar mh-thread-last-ancestor)
445
434(defun mh-copy-seq-to-eob (seq) 446(defun mh-copy-seq-to-eob (seq)
435 "Copy SEQ to the end of the buffer." 447 "Copy SEQ to the end of the buffer."
436 ;; It is quite involved to write something which will work at any place in 448 ;; It is quite involved to write something which will work at any place in
@@ -455,12 +467,8 @@ uses `overlay-arrow-position' to put a marker in the fringe."
455 (forward-line)) 467 (forward-line))
456 ;; Remove scan lines and read results from pre-computed tree 468 ;; Remove scan lines and read results from pre-computed tree
457 (delete-region (point-min) (point-max)) 469 (delete-region (point-min) (point-max))
458 (let ((thread-tree (mh-thread-generate mh-current-folder ())) 470 (mh-thread-print-scan-lines
459 (mh-thread-body-width 471 (mh-thread-generate mh-current-folder ())))
460 (- (window-width) mh-cmd-note
461 (1- mh-scan-field-subject-start-offset)))
462 (mh-thread-last-ancestor nil))
463 (mh-thread-generate-scan-lines thread-tree -2)))
464 (mh-index-data 472 (mh-index-data
465 (mh-index-insert-folder-headers))))))) 473 (mh-index-insert-folder-headers)))))))
466 474
@@ -491,12 +499,83 @@ If VAR is nil then the loop is executed without any binding."
491 (let ((binding-needed-flag var)) 499 (let ((binding-needed-flag var))
492 `(save-excursion 500 `(save-excursion
493 (goto-char ,begin) 501 (goto-char ,begin)
502 (beginning-of-line)
494 (while (and (<= (point) ,end) (not (eobp))) 503 (while (and (<= (point) ,end) (not (eobp)))
495 (when (looking-at mh-scan-valid-regexp) 504 (when (looking-at mh-scan-valid-regexp)
496 (let ,(if binding-needed-flag `((,var (mh-get-msg-num t))) ()) 505 (let ,(if binding-needed-flag `((,var (mh-get-msg-num t))) ())
497 ,@body)) 506 ,@body))
498 (forward-line 1))))) 507 (forward-line 1)))))
499 508
509(put 'mh-iterate-on-messages-in-region 'lisp-indent-hook 'defun)
510
511;;;###mh-autoload
512(defmacro mh-iterate-on-msg-or-seq (var msg-or-seq &rest body)
513 "Iterate an operation over a region or sequence.
514
515VAR is bound to each message in turn in a loop over MSG-OR-SEQ, which can be a
516message number, a list of message numbers, a sequence, or a region in a cons
517cell. In each iteration, BODY is executed.
518
519The parameter MSG-OR-SEQ is usually created with `mh-interactive-msg-or-seq'
520in order to provide a uniform interface to MH-E functions."
521 (unless (symbolp var)
522 (error "Can not bind the non-symbol %s" var))
523 (let ((binding-needed-flag var)
524 (msgs (make-symbol "msgs"))
525 (seq-hash-table (make-symbol "seq-hash-table")))
526 `(cond ((numberp ,msg-or-seq)
527 (when (mh-goto-msg ,msg-or-seq t t)
528 (let ,(if binding-needed-flag `((,var ,msg-or-seq)) ())
529 ,@body)))
530 ((and (consp ,msg-or-seq)
531 (numberp (car ,msg-or-seq)) (numberp (cdr ,msg-or-seq)))
532 (mh-iterate-on-messages-in-region ,var
533 (car ,msg-or-seq) (cdr ,msg-or-seq)
534 ,@body))
535 (t (let ((,msgs (if (and ,msg-or-seq (symbolp ,msg-or-seq))
536 (mh-seq-to-msgs ,msg-or-seq)
537 ,msg-or-seq))
538 (,seq-hash-table (make-hash-table)))
539 (dolist (msg ,msgs)
540 (setf (gethash msg ,seq-hash-table) t))
541 (mh-iterate-on-messages-in-region v (point-min) (point-max)
542 (when (gethash v ,seq-hash-table)
543 (let ,(if binding-needed-flag `((,var v)) ())
544 ,@body))))))))
545
546(put 'mh-iterate-on-msg-or-seq 'lisp-indent-hook 'defun)
547
548;;;###mh-autoload
549(defun mh-msg-or-seq-to-msg-list (msg-or-seq)
550 "Return a list of messages for MSG-OR-SEQ.
551MSG-OR-SEQ can be a message number, a list of message numbers, a sequence, or
552a region in a cons cell."
553 (let (msg-list)
554 (mh-iterate-on-msg-or-seq msg msg-or-seq
555 (push msg msg-list))
556 (nreverse msg-list)))
557
558;;;###mh-autoload
559(defun mh-interactive-msg-or-seq (sequence-prompt)
560 "Return interactive specification for message, sequence, or region.
561By convention, the name of this argument is msg-or-seq.
562
563If variable `transient-mark-mode' is non-nil and the mark is active, then this
564function returns a cons-cell of the region.
565If optional prefix argument provided, then prompt for message sequence with
566SEQUENCE-PROMPT and return sequence.
567Otherwise, the message number at point is returned.
568
569This function is usually used with `mh-iterate-on-msg-or-seq' in order to
570provide a uniform interface to MH-E functions."
571 (cond
572 ((mh-mark-active-p t)
573 (cons (region-beginning) (region-end)))
574 (current-prefix-arg
575 (mh-read-seq-default sequence-prompt t))
576 (t
577 (mh-get-msg-num t))))
578
500;;;###mh-autoload 579;;;###mh-autoload
501(defun mh-region-to-msg-list (begin end) 580(defun mh-region-to-msg-list (begin end)
502 "Return a list of messages within the region between BEGIN and END." 581 "Return a list of messages within the region between BEGIN and END."
@@ -1005,17 +1084,12 @@ All messages after START-POINT are added to the thread tree."
1005 (buffer-read-only nil) 1084 (buffer-read-only nil)
1006 (old-buffer-modified-flag (buffer-modified-p))) 1085 (old-buffer-modified-flag (buffer-modified-p)))
1007 (delete-region (point-min) (point-max)) 1086 (delete-region (point-min) (point-max))
1008 (let ((mh-thread-body-width (- (window-width) mh-cmd-note 1087 (mh-thread-print-scan-lines thread-tree)
1009 (1- mh-scan-field-subject-start-offset)))
1010 (mh-thread-last-ancestor nil))
1011 (mh-thread-generate-scan-lines thread-tree -2))
1012 (mh-notate-user-sequences) 1088 (mh-notate-user-sequences)
1013 (mh-notate-deleted-and-refiled) 1089 (mh-notate-deleted-and-refiled)
1014 (mh-notate-cur) 1090 (mh-notate-cur)
1015 (set-buffer-modified-p old-buffer-modified-flag)))) 1091 (set-buffer-modified-p old-buffer-modified-flag))))
1016 1092
1017(defvar mh-thread-last-ancestor)
1018
1019(defun mh-thread-generate-scan-lines (tree level) 1093(defun mh-thread-generate-scan-lines (tree level)
1020 "Generate scan lines. 1094 "Generate scan lines.
1021TREE is the hierarchical tree of messages, SCAN-LINE-MAP maps message indices 1095TREE is the hierarchical tree of messages, SCAN-LINE-MAP maps message indices
@@ -1099,6 +1173,25 @@ Otherwise uses the line at point as the scan line to parse."
1099 (mh-thread-parse-scan-line (format "%s%s" spaces old-line))))) 1173 (mh-thread-parse-scan-line (format "%s%s" spaces old-line)))))
1100 (forward-line 1)))) 1174 (forward-line 1))))
1101 1175
1176(defun mh-thread-print-scan-lines (thread-tree)
1177 "Print scan lines in THREAD-TREE in threaded mode."
1178 (let ((mh-thread-body-width (- (window-width) mh-cmd-note
1179 (1- mh-scan-field-subject-start-offset)))
1180 (mh-thread-last-ancestor nil))
1181 (if (null mh-index-data)
1182 (mh-thread-generate-scan-lines thread-tree -2)
1183 (loop for x in (mh-index-group-by-folder)
1184 do (let* ((old-map mh-thread-scan-line-map)
1185 (mh-thread-scan-line-map (make-hash-table)))
1186 (setq mh-thread-last-ancestor nil)
1187 (loop for msg in (cdr x)
1188 do (let ((v (gethash msg old-map)))
1189 (when v
1190 (setf (gethash msg mh-thread-scan-line-map) v))))
1191 (when (> (hash-table-count mh-thread-scan-line-map) 0)
1192 (insert (if (bobp) "" "\n") (car x) "\n")
1193 (mh-thread-generate-scan-lines thread-tree -2)))))))
1194
1102(defun mh-thread-folder () 1195(defun mh-thread-folder ()
1103 "Generate thread view of folder." 1196 "Generate thread view of folder."
1104 (message "Threading %s..." (buffer-name)) 1197 (message "Threading %s..." (buffer-name))
@@ -1115,10 +1208,7 @@ Otherwise uses the line at point as the scan line to parse."
1115 (let* ((range (mh-coalesce-msg-list msg-list)) 1208 (let* ((range (mh-coalesce-msg-list msg-list))
1116 (thread-tree (mh-thread-generate (buffer-name) range))) 1209 (thread-tree (mh-thread-generate (buffer-name) range)))
1117 (delete-region (point-min) (point-max)) 1210 (delete-region (point-min) (point-max))
1118 (let ((mh-thread-body-width (- (window-width) mh-cmd-note 1211 (mh-thread-print-scan-lines thread-tree)
1119 (1- mh-scan-field-subject-start-offset)))
1120 (mh-thread-last-ancestor nil))
1121 (mh-thread-generate-scan-lines thread-tree -2))
1122 (mh-notate-user-sequences) 1212 (mh-notate-user-sequences)
1123 (mh-notate-deleted-and-refiled) 1213 (mh-notate-deleted-and-refiled)
1124 (mh-notate-cur) 1214 (mh-notate-cur)
@@ -1137,7 +1227,7 @@ Otherwise uses the line at point as the scan line to parse."
1137 (let ((msg-list ())) 1227 (let ((msg-list ()))
1138 (goto-char (point-min)) 1228 (goto-char (point-min))
1139 (while (not (eobp)) 1229 (while (not (eobp))
1140 (let ((index (mh-get-msg-num t))) 1230 (let ((index (mh-get-msg-num nil)))
1141 (when index 1231 (when index
1142 (push index msg-list))) 1232 (push index msg-list)))
1143 (forward-line)) 1233 (forward-line))
@@ -1161,6 +1251,7 @@ Otherwise uses the line at point as the scan line to parse."
1161 (id-index (gethash id mh-thread-id-index-map)) 1251 (id-index (gethash id mh-thread-id-index-map))
1162 (duplicates (gethash id mh-thread-duplicates))) 1252 (duplicates (gethash id mh-thread-duplicates)))
1163 (remhash index mh-thread-index-id-map) 1253 (remhash index mh-thread-index-id-map)
1254 (remhash index mh-thread-scan-line-map)
1164 (cond ((and (eql index id-index) (null duplicates)) 1255 (cond ((and (eql index id-index) (null duplicates))
1165 (remhash id mh-thread-id-index-map)) 1256 (remhash id mh-thread-id-index-map))
1166 ((eql index id-index) 1257 ((eql index id-index)
@@ -1308,6 +1399,85 @@ start of the region and the second is the point at the end."
1308 (mh-refile-a-msg nil folder)) 1399 (mh-refile-a-msg nil folder))
1309 (mh-next-msg))))) 1400 (mh-next-msg)))))
1310 1401
1402
1403
1404;; Tick mark handling
1405
1406;; Functions to highlight and unhighlight ticked messages.
1407(defun mh-tick-add-overlay ()
1408 "Add tick overlay to current line."
1409 (with-mh-folder-updating (t)
1410 (let ((overlay
1411 (or (mh-funcall-if-exists make-overlay (point) (line-end-position))
1412 (mh-funcall-if-exists make-extent (point) (line-end-position)))))
1413 (or (mh-funcall-if-exists overlay-put overlay 'face 'mh-folder-tick-face)
1414 (mh-funcall-if-exists set-extent-face overlay 'mh-folder-tick-face))
1415 (mh-funcall-if-exists set-extent-priority overlay 10)
1416 (add-text-properties (point) (line-end-position) `(mh-tick ,overlay)))))
1417
1418(defun mh-tick-remove-overlay ()
1419 "Remove tick overlay from current line."
1420 (let ((overlay (get-text-property (point) 'mh-tick)))
1421 (when overlay
1422 (with-mh-folder-updating (t)
1423 (or (mh-funcall-if-exists delete-overlay overlay)
1424 (mh-funcall-if-exists delete-extent overlay))
1425 (remove-text-properties (point) (line-end-position) `(mh-tick nil))))))
1426
1427;;;###mh-autoload
1428(defun mh-notate-tick (msg ticked-msgs &optional ignore-narrowing)
1429 "Highlight current line if MSG is in TICKED-MSGS.
1430If optional argument IGNORE-NARROWING is non-nil then highlighting is carried
1431out even if folder is narrowed to `mh-tick-seq'."
1432 (when mh-tick-seq
1433 (let ((narrowed-to-tick (and (not ignore-narrowing)
1434 (eq mh-narrowed-to-seq mh-tick-seq)))
1435 (overlay (get-text-property (point) 'mh-tick))
1436 (in-tick (member msg ticked-msgs)))
1437 (cond (narrowed-to-tick (mh-tick-remove-overlay))
1438 ((and (not overlay) in-tick) (mh-tick-add-overlay))
1439 ((and overlay (not in-tick)) (mh-tick-remove-overlay))))))
1440
1441;; Interactive function to toggle tick.
1442;;;###mh-autoload
1443(defun mh-toggle-tick (begin end)
1444 "Toggle tick mark of all messages in region BEGIN to END."
1445 (interactive (cond ((mh-mark-active-p t)
1446 (list (region-beginning) (region-end)))
1447 (t (list (line-beginning-position) (line-end-position)))))
1448 (unless mh-tick-seq
1449 (error "Enable ticking by customizing `mh-tick-seq'"))
1450 (let* ((tick-seq (mh-find-seq mh-tick-seq))
1451 (tick-seq-msgs (mh-seq-msgs tick-seq)))
1452 (mh-iterate-on-messages-in-region msg begin end
1453 (cond ((member msg tick-seq-msgs)
1454 (mh-undefine-sequence mh-tick-seq (list msg))
1455 (setcdr tick-seq (delq msg (cdr tick-seq)))
1456 (when (null (cdr tick-seq)) (setq mh-last-seq-used nil))
1457 (mh-tick-remove-overlay))
1458 (t
1459 (mh-add-msgs-to-seq (list msg) mh-tick-seq nil t)
1460 (setq mh-last-seq-used mh-tick-seq)
1461 (mh-tick-add-overlay))))
1462 (when (and (eq mh-tick-seq mh-narrowed-to-seq)
1463 (not mh-tick-seq-changed-when-narrowed-flag))
1464 (setq mh-tick-seq-changed-when-narrowed-flag t)
1465 (let ((ticked-msgs (mh-seq-msgs (mh-find-seq mh-tick-seq))))
1466 (mh-iterate-on-messages-in-region msg (point-min) (point-max)
1467 (mh-notate-tick msg ticked-msgs t))))))
1468
1469;;;###mh-autoload
1470(defun mh-narrow-to-tick ()
1471 "Restrict display of this folder to just messages in `mh-tick-seq'.
1472Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command."
1473 (interactive)
1474 (cond ((not mh-tick-seq)
1475 (error "Enable ticking by customizing `mh-tick-seq'"))
1476 ((null (mh-seq-msgs (mh-find-seq mh-tick-seq)))
1477 (message "No messages in tick sequence"))
1478 (t (mh-narrow-to-seq mh-tick-seq))))
1479
1480
1311(provide 'mh-seq) 1481(provide 'mh-seq)
1312 1482
1313;;; Local Variables: 1483;;; Local Variables:
diff --git a/lisp/mh-e/mh-speed.el b/lisp/mh-e/mh-speed.el
index ca60b2f7840..ebde825195f 100644
--- a/lisp/mh-e/mh-speed.el
+++ b/lisp/mh-e/mh-speed.el
@@ -1,6 +1,6 @@
1;;; mh-speed.el --- Speedbar interface for MH-E. 1;;; mh-speed.el --- Speedbar interface for MH-E.
2 2
3;; Copyright (C) 2002 Free Software Foundation, Inc. 3;; Copyright (C) 2002, 2003 Free Software Foundation, Inc.
4 4
5;; Author: Satyaki Das <satyaki@theforce.stanford.edu> 5;; Author: Satyaki Das <satyaki@theforce.stanford.edu>
6;; Maintainer: Bill Wohler <wohler@newt.com> 6;; Maintainer: Bill Wohler <wohler@newt.com>
@@ -31,8 +31,6 @@
31 31
32;;; Change Log: 32;;; Change Log:
33 33
34;; $Id: mh-speed.el,v 1.37 2003/01/31 03:18:18 satyaki Exp $
35
36;;; Code: 34;;; Code:
37 35
38;; Requires 36;; Requires
@@ -70,7 +68,8 @@ BUFFER is the MH-E buffer for which the speedbar buffer is to be created."
70 'mh-speedbar-folder-face 0) 68 'mh-speedbar-folder-face 0)
71 (forward-line -1) 69 (forward-line -1)
72 (setf (gethash nil mh-speed-folder-map) 70 (setf (gethash nil mh-speed-folder-map)
73 (set-marker (make-marker) (1+ (line-beginning-position)))) 71 (set-marker (or (gethash nil mh-speed-folder-map) (make-marker))
72 (1+ (line-beginning-position))))
74 (add-text-properties 73 (add-text-properties
75 (line-beginning-position) (1+ (line-beginning-position)) 74 (line-beginning-position) (1+ (line-beginning-position))
76 `(mh-folder nil mh-expanded nil mh-children-p t mh-level 0)) 75 `(mh-folder nil mh-expanded nil mh-children-p t mh-level 0))
@@ -278,7 +277,9 @@ Do the right thing for the different kinds of buffers that MH-E uses."
278 (save-excursion 277 (save-excursion
279 (forward-line -1) 278 (forward-line -1)
280 (setf (gethash folder-name mh-speed-folder-map) 279 (setf (gethash folder-name mh-speed-folder-map)
281 (set-marker (make-marker) (1+ (line-beginning-position)))) 280 (set-marker (or (gethash folder-name mh-speed-folder-map)
281 (make-marker))
282 (1+ (line-beginning-position))))
282 (add-text-properties 283 (add-text-properties
283 (line-beginning-position) (1+ (line-beginning-position)) 284 (line-beginning-position) (1+ (line-beginning-position))
284 `(mh-folder ,folder-name 285 `(mh-folder ,folder-name
@@ -309,8 +310,10 @@ The otional ARGS are ignored and there for compatibilty with speedbar."
309 (setq start-region (point)) 310 (setq start-region (point))
310 (while (and (get-text-property (point) 'mh-level) 311 (while (and (get-text-property (point) 'mh-level)
311 (> (get-text-property (point) 'mh-level) level)) 312 (> (get-text-property (point) 'mh-level) level))
312 (remhash (get-text-property (point) 'mh-folder) 313 (let ((folder (get-text-property (point) 'mh-folder)))
313 mh-speed-folder-map) 314 (when (gethash folder mh-speed-folder-map)
315 (set-marker (gethash folder mh-speed-folder-map) nil)
316 (remhash folder mh-speed-folder-map)))
314 (forward-line)) 317 (forward-line))
315 (delete-region start-region (point)) 318 (delete-region start-region (point))
316 (forward-line -1) 319 (forward-line -1)
@@ -344,24 +347,29 @@ Optional ARGS are ignored."
344 (delete-other-windows))))) 347 (delete-other-windows)))))
345 348
346(defvar mh-speed-current-folder nil) 349(defvar mh-speed-current-folder nil)
350(defvar mh-speed-flists-folder nil)
347 351
348;;;###mh-autoload 352;;;###mh-autoload
349(defun mh-speed-flists (force) 353(defun mh-speed-flists (force &optional folder)
350 "Execute flists -recurse and update message counts. 354 "Execute flists -recurse and update message counts.
351If FORCE is non-nil the timer is reset." 355If FORCE is non-nil the timer is reset. If FOLDER is non-nil then flists is run
356only for that one folder."
352 (interactive (list t)) 357 (interactive (list t))
353 (when force 358 (when force
354 (when (timerp mh-speed-flists-timer) 359 (when mh-speed-flists-timer
355 (cancel-timer mh-speed-flists-timer)) 360 (cancel-timer mh-speed-flists-timer)
356 (setq mh-speed-flists-timer nil) 361 (setq mh-speed-flists-timer nil))
357 (when (and (processp mh-speed-flists-process) 362 (when (and (processp mh-speed-flists-process)
358 (not (eq (process-status mh-speed-flists-process) 'exit))) 363 (not (eq (process-status mh-speed-flists-process) 'exit)))
364 (set-process-filter mh-speed-flists-process t)
359 (kill-process mh-speed-flists-process) 365 (kill-process mh-speed-flists-process)
366 (setq mh-speed-partial-line "")
360 (setq mh-speed-flists-process nil))) 367 (setq mh-speed-flists-process nil)))
368 (setq mh-speed-flists-folder folder)
361 (unless mh-speed-flists-timer 369 (unless mh-speed-flists-timer
362 (setq mh-speed-flists-timer 370 (setq mh-speed-flists-timer
363 (run-at-time 371 (run-at-time
364 nil mh-speed-flists-interval 372 nil (and mh-speed-run-flists-flag mh-speed-flists-interval)
365 (lambda () 373 (lambda ()
366 (unless (and (processp mh-speed-flists-process) 374 (unless (and (processp mh-speed-flists-process)
367 (not (eq (process-status mh-speed-flists-process) 375 (not (eq (process-status mh-speed-flists-process)
@@ -376,8 +384,11 @@ If FORCE is non-nil the timer is reset."
376 (setq mh-speed-flists-process 384 (setq mh-speed-flists-process
377 (start-process "*flists*" nil 385 (start-process "*flists*" nil
378 (expand-file-name "flists" mh-progs) 386 (expand-file-name "flists" mh-progs)
379 "-recurse" 387 (or mh-speed-flists-folder "-recurse")
388 (if mh-speed-flists-folder "-noall" "-all")
380 "-sequence" (symbol-name mh-unseen-seq))) 389 "-sequence" (symbol-name mh-unseen-seq)))
390 ;; Run flists on all folders the next time around...
391 (setq mh-speed-flists-folder nil)
381 (set-process-filter mh-speed-flists-process 392 (set-process-filter mh-speed-flists-process
382 'mh-speed-parse-flists-output))))))) 393 'mh-speed-parse-flists-output)))))))
383 394
@@ -397,7 +408,10 @@ next."
397 mh-speed-partial-line "") 408 mh-speed-partial-line "")
398 (multiple-value-setq (folder unseen total) 409 (multiple-value-setq (folder unseen total)
399 (mh-parse-flist-output-line line mh-speed-current-folder)) 410 (mh-parse-flist-output-line line mh-speed-current-folder))
400 (when (and folder unseen total) 411 (when (and folder unseen total
412 (let ((old-pair (gethash folder mh-speed-flists-cache)))
413 (or (not (equal (car old-pair) unseen))
414 (not (equal (cdr old-pair) total)))))
401 (setf (gethash folder mh-speed-flists-cache) (cons unseen total)) 415 (setf (gethash folder mh-speed-flists-cache) (cons unseen total))
402 (save-excursion 416 (save-excursion
403 (when (buffer-live-p (get-buffer speedbar-buffer)) 417 (when (buffer-live-p (get-buffer speedbar-buffer))
@@ -514,7 +528,8 @@ The function invalidates the latest ancestor that is present."
514 (insert-char char 1 t) 528 (insert-char char 1 t)
515 (put-text-property (point) (1- (point)) 'invisible nil) 529 (put-text-property (point) (1- (point)) 'invisible nil)
516 ;; make sure we fix the image on the text here. 530 ;; make sure we fix the image on the text here.
517 (speedbar-insert-image-button-maybe (- (point) 2) 3))))) 531 (mh-funcall-if-exists
532 speedbar-insert-image-button-maybe (- (point) 2) 3)))))
518 533
519(provide 'mh-speed) 534(provide 'mh-speed)
520 535
diff --git a/lisp/mh-e/mh-utils.el b/lisp/mh-e/mh-utils.el
index 9b148264003..3e83988a49b 100644
--- a/lisp/mh-e/mh-utils.el
+++ b/lisp/mh-e/mh-utils.el
@@ -1,6 +1,7 @@
1;;; mh-utils.el --- MH-E code needed for both sending and reading 1;;; mh-utils.el --- MH-E code needed for both sending and reading
2 2
3;; Copyright (C) 1993, 1995, 1997, 2000, 2001, 2002 Free Software Foundation, Inc. 3;; Copyright (C) 1993, 95, 1997,
4;; 2000, 01, 02, 2003 Free Software Foundation, Inc.
4 5
5;; Author: Bill Wohler <wohler@newt.com> 6;; Author: Bill Wohler <wohler@newt.com>
6;; Maintainer: Bill Wohler <wohler@newt.com> 7;; Maintainer: Bill Wohler <wohler@newt.com>
@@ -30,8 +31,6 @@
30 31
31;;; Change Log: 32;;; Change Log:
32 33
33;; $Id: mh-utils.el,v 1.2 2003/02/03 20:55:30 wohler Exp $
34
35;;; Code: 34;;; Code:
36 35
37;; Is this XEmacs-land? Located here since needed by mh-customize.el. 36;; Is this XEmacs-land? Located here since needed by mh-customize.el.
@@ -57,7 +56,7 @@
57 56
58;;; Autoloads 57;;; Autoloads
59(autoload 'gnus-article-highlight-citation "gnus-cite") 58(autoload 'gnus-article-highlight-citation "gnus-cite")
60(autoload 'mail-header-end "sendmail") 59(require 'sendmail)
61(autoload 'Info-goto-node "info") 60(autoload 'Info-goto-node "info")
62(unless (fboundp 'make-hash-table) 61(unless (fboundp 'make-hash-table)
63 (autoload 'make-hash-table "cl")) 62 (autoload 'make-hash-table "cl"))
@@ -100,7 +99,30 @@ of `search' in the CL package."
100 when (equal (aref string index) char) return index 99 when (equal (aref string index) char) return index
101 finally return nil)) 100 finally return nil))
102 101
103;;; Macro to generate correct code for different emacs variants 102;;; Macros to generate correct code for different emacs variants
103
104(defmacro mh-do-in-gnu-emacs (&rest body)
105 "Execute BODY if in GNU Emacs."
106 (unless mh-xemacs-flag `(progn ,@body)))
107(put 'mh-do-in-gnu-emacs 'lisp-indent-hook 'defun)
108
109(defmacro mh-do-in-xemacs (&rest body)
110 "Execute BODY if in GNU Emacs."
111 (when mh-xemacs-flag `(progn ,@body)))
112(put 'mh-do-in-xemacs 'lisp-indent-hook 'defun)
113
114(defmacro mh-funcall-if-exists (function &rest args)
115 "Call FUNCTION with ARGS as parameters if it exists."
116 (if (fboundp function)
117 `(funcall ',function ,@args)))
118
119(defmacro mh-make-local-hook (hook)
120 "Make HOOK local if needed.
121XEmacs and versions of GNU Emacs before 21.1 require `make-local-hook' to be
122called."
123 (when (and (fboundp 'make-local-hook)
124 (not (get 'make-local-hook 'byte-obsolete-info)))
125 `(make-local-hook ,hook)))
104 126
105(defmacro mh-mark-active-p (check-transient-mark-mode-flag) 127(defmacro mh-mark-active-p (check-transient-mark-mode-flag)
106 "A macro that expands into appropriate code in XEmacs and nil in GNU Emacs. 128 "A macro that expands into appropriate code in XEmacs and nil in GNU Emacs.
@@ -287,19 +309,6 @@ passed through `regexp-quote' before being used by functions like
287 (".*" mm-inline-text mm-readable-p)) 309 (".*" mm-inline-text mm-readable-p))
288 "Alist of media types/tests saying whether types can be displayed inline.") 310 "Alist of media types/tests saying whether types can be displayed inline.")
289 311
290;; Needed by mh-comp.el and mh-mime.el
291(defvar mh-mhn-compose-insert-flag nil
292 "Non-nil means MIME insertion was done.
293Triggers an automatic call to `mh-edit-mhn' in `mh-send-letter'.
294This variable is buffer-local.")
295(make-variable-buffer-local 'mh-mhn-compose-insert-flag)
296
297(defvar mh-mml-compose-insert-flag nil
298 "Non-nil means that a MIME insertion was done.
299This buffer-local variable is used to remember if a MIME insertion was done.
300Triggers an automatic call to `mh-mml-to-mime' in `mh-send-letter'.")
301(make-variable-buffer-local 'mh-mml-compose-insert-flag)
302
303;; Copy of `goto-address-mail-regexp' 312;; Copy of `goto-address-mail-regexp'
304(defvar mh-address-mail-regexp 313(defvar mh-address-mail-regexp
305 "[-a-zA-Z0-9._]+@[-a-zA-z0-9_]+\\.+[a-zA-Z0-9]+" 314 "[-a-zA-Z0-9._]+@[-a-zA-z0-9_]+\\.+[a-zA-Z0-9]+"
@@ -318,9 +327,17 @@ address. If no e-mail address found, return nil."
318 (goto-char (match-beginning 0)))) 327 (goto-char (match-beginning 0))))
319 (match-string-no-properties 0))) 328 (match-string-no-properties 0)))
320 329
330(defun mh-mail-header-end ()
331 "Substitute for `mail-header-end' that doesn't widen the buffer.
332In MH-E we frequently need to find the end of headers in nested messages, where
333the buffer has been narrowed. This function works in this situation."
334 (save-excursion
335 (rfc822-goto-eoh)
336 (point)))
337
321(defun mh-in-header-p () 338(defun mh-in-header-p ()
322 "Return non-nil if the point is in the header of a draft message." 339 "Return non-nil if the point is in the header of a draft message."
323 (< (point) (mail-header-end))) 340 (< (point) (mh-mail-header-end)))
324 341
325(defun mh-header-field-beginning () 342(defun mh-header-field-beginning ()
326 "Move to the beginning of the current header field. 343 "Move to the beginning of the current header field.
@@ -342,7 +359,7 @@ Handles RFC 822 continuation lines."
342Argument LIMIT limits search." 359Argument LIMIT limits search."
343 (if (= (point) limit) 360 (if (= (point) limit)
344 nil 361 nil
345 (let* ((mail-header-end (save-match-data (mail-header-end))) 362 (let* ((mail-header-end (save-match-data (mh-mail-header-end)))
346 (lesser-limit (if (< mail-header-end limit) mail-header-end limit))) 363 (lesser-limit (if (< mail-header-end limit) mail-header-end limit)))
347 (when (mh-in-header-p) 364 (when (mh-in-header-p)
348 (set-match-data (list 1 lesser-limit)) 365 (set-match-data (list 1 lesser-limit))
@@ -354,7 +371,7 @@ Argument LIMIT limits search."
354Argument LIMIT limits search." 371Argument LIMIT limits search."
355 (if (= (point) limit) 372 (if (= (point) limit)
356 nil 373 nil
357 (let* ((mail-header-end (mail-header-end)) 374 (let* ((mail-header-end (mh-mail-header-end))
358 (lesser-limit (if (< mail-header-end limit) mail-header-end limit)) 375 (lesser-limit (if (< mail-header-end limit) mail-header-end limit))
359 (case-fold-search t)) 376 (case-fold-search t))
360 (when (and (< (point) mail-header-end) ;Only within header 377 (when (and (< (point) mail-header-end) ;Only within header
@@ -424,7 +441,7 @@ Used when `mh-highlight-citation-p' is set to gnus, leaving the body to be
424dealt with by gnus highlighting. The region between BEG and END is 441dealt with by gnus highlighting. The region between BEG and END is
425given over to be fontified and LOUDLY controls if a user sees a 442given over to be fontified and LOUDLY controls if a user sees a
426message about the fontification operation." 443message about the fontification operation."
427 (let ((header-end (mail-header-end))) 444 (let ((header-end (mh-mail-header-end)))
428 (cond 445 (cond
429 ((and (< beg header-end)(< end header-end)) 446 ((and (< beg header-end)(< end header-end))
430 (font-lock-default-fontify-region beg end loudly)) 447 (font-lock-default-fontify-region beg end loudly))
@@ -501,6 +518,10 @@ message about the fontification operation."
501(defconst mh-log-buffer "*MH-E Log*") ;output of MH commands and so on 518(defconst mh-log-buffer "*MH-E Log*") ;output of MH commands and so on
502(defconst mh-recipients-buffer "*MH-E Recipients*") ;killed when draft sent 519(defconst mh-recipients-buffer "*MH-E Recipients*") ;killed when draft sent
503(defconst mh-sequences-buffer "*MH-E Sequences*") ;sequences list 520(defconst mh-sequences-buffer "*MH-E Sequences*") ;sequences list
521(defconst mh-mail-delivery-buffer "*MH-E Mail Delivery*") ;mail delivery log
522
523;; Number of lines to keep in mh-log-buffer.
524(defvar mh-log-buffer-lines 100)
504 525
505;; Window configuration before MH-E command. 526;; Window configuration before MH-E command.
506(defvar mh-previous-window-config nil) 527(defvar mh-previous-window-config nil)
@@ -535,14 +556,23 @@ message about the fontification operation."
535 556
536(defun mh-logo-display () 557(defun mh-logo-display ()
537 "Modify mode line to display MH-E logo." 558 "Modify mode line to display MH-E logo."
538 (when (fboundp 'find-image) 559 (mh-do-in-gnu-emacs
539 (add-text-properties 560 (add-text-properties
540 0 2 561 0 2
541 `(display ,(or mh-logo-cache 562 `(display ,(or mh-logo-cache
542 (setq mh-logo-cache 563 (setq mh-logo-cache
543 (find-image '((:type xpm :ascent center 564 (mh-funcall-if-exists
544 :file "mh-logo.xpm")))))) 565 find-image '((:type xpm :ascent center
545 (car mode-line-buffer-identification)))) 566 :file "mh-logo.xpm"))))))
567 (car mode-line-buffer-identification)))
568 (mh-do-in-xemacs
569 (setq modeline-buffer-identification
570 (list
571 (if mh-modeline-glyph
572 (cons modeline-buffer-id-left-extent mh-modeline-glyph)
573 (cons modeline-buffer-id-left-extent "XEmacs%N:"))
574 (cons modeline-buffer-id-right-extent " %17b")))))
575
546 576
547;;; This holds a documentation string used by describe-mode. 577;;; This holds a documentation string used by describe-mode.
548(defun mh-showing-mode (&optional arg) 578(defun mh-showing-mode (&optional arg)
@@ -585,7 +615,7 @@ flag is unchanged, otherwise it is cleared."
585 ,@(if (not save-modification-flag) 615 ,@(if (not save-modification-flag)
586 '((mh-set-folder-modified-p nil))))) 616 '((mh-set-folder-modified-p nil)))))
587 617
588(put 'with-mh-folder-updating 'lisp-indent-hook 1) 618(put 'with-mh-folder-updating 'lisp-indent-hook 'defun)
589 619
590(defmacro mh-in-show-buffer (show-buffer &rest body) 620(defmacro mh-in-show-buffer (show-buffer &rest body)
591 "Format is (mh-in-show-buffer (SHOW-BUFFER) &body BODY). 621 "Format is (mh-in-show-buffer (SHOW-BUFFER) &body BODY).
@@ -600,7 +630,7 @@ Stronger than `save-excursion', weaker than `save-window-excursion'."
600 ,@body) 630 ,@body)
601 (select-window mh-in-show-buffer-saved-window)))) 631 (select-window mh-in-show-buffer-saved-window))))
602 632
603(put 'mh-in-show-buffer 'lisp-indent-hook 1) 633(put 'mh-in-show-buffer 'lisp-indent-hook 'defun)
604 634
605(defmacro mh-make-seq (name msgs) 635(defmacro mh-make-seq (name msgs)
606 "Create sequence NAME with the given MSGS." 636 "Create sequence NAME with the given MSGS."
@@ -726,11 +756,11 @@ still visible.\n")
726 folder-buffer) 756 folder-buffer)
727 (delete-other-windows)) 757 (delete-other-windows))
728 (mh-goto-cur-msg t) 758 (mh-goto-cur-msg t)
729 (and (fboundp 'deactivate-mark) (deactivate-mark)) 759 (mh-funcall-if-exists deactivate-mark)
730 (unwind-protect 760 (unwind-protect
731 (prog1 (call-interactively (function ,original-function)) 761 (prog1 (call-interactively (function ,original-function))
732 (setq normal-exit t)) 762 (setq normal-exit t))
733 (and (fboundp 'deactivate-mark) (deactivate-mark)) 763 (mh-funcall-if-exists deactivate-mark)
734 (cond ((not normal-exit) 764 (cond ((not normal-exit)
735 (set-window-configuration config)) 765 (set-window-configuration config))
736 ,(if dont-return 766 ,(if dont-return
@@ -819,11 +849,17 @@ still visible.\n")
819(mh-defun-show-buffer mh-show-thread-previous-sibling 849(mh-defun-show-buffer mh-show-thread-previous-sibling
820 mh-thread-previous-sibling) 850 mh-thread-previous-sibling)
821(mh-defun-show-buffer mh-show-index-visit-folder mh-index-visit-folder t) 851(mh-defun-show-buffer mh-show-index-visit-folder mh-index-visit-folder t)
852(mh-defun-show-buffer mh-show-toggle-tick mh-toggle-tick)
853(mh-defun-show-buffer mh-show-narrow-to-tick mh-narrow-to-tick)
854(mh-defun-show-buffer mh-show-junk-blacklist mh-junk-blacklist)
855(mh-defun-show-buffer mh-show-junk-whitelist mh-junk-whitelist)
856(mh-defun-show-buffer mh-show-index-new-messages mh-index-new-messages)
822 857
823;;; Populate mh-show-mode-map 858;;; Populate mh-show-mode-map
824(gnus-define-keys mh-show-mode-map 859(gnus-define-keys mh-show-mode-map
825 " " mh-show-page-msg 860 " " mh-show-page-msg
826 "!" mh-show-refile-or-write-again 861 "!" mh-show-refile-or-write-again
862 "'" mh-show-toggle-tick
827 "," mh-show-header-display 863 "," mh-show-header-display
828 "." mh-show-show 864 "." mh-show-show
829 ">" mh-show-write-message-to-file 865 ">" mh-show-write-message-to-file
@@ -867,6 +903,7 @@ still visible.\n")
867 "i" mh-index-search 903 "i" mh-index-search
868 "k" mh-show-kill-folder 904 "k" mh-show-kill-folder
869 "l" mh-show-list-folders 905 "l" mh-show-list-folders
906 "n" mh-index-new-messages
870 "o" mh-show-visit-folder 907 "o" mh-show-visit-folder
871 "r" mh-show-rescan-folder 908 "r" mh-show-rescan-folder
872 "s" mh-show-search-folder 909 "s" mh-show-search-folder
@@ -884,6 +921,13 @@ still visible.\n")
884 "s" mh-show-msg-is-in-seq 921 "s" mh-show-msg-is-in-seq
885 "w" mh-show-widen) 922 "w" mh-show-widen)
886 923
924(define-key mh-show-mode-map "I" mh-inc-spool-map)
925
926(gnus-define-keys (mh-show-junk-map "J" mh-show-mode-map)
927 "?" mh-prefix-help
928 "b" mh-show-junk-blacklist
929 "w" mh-show-junk-whitelist)
930
887(gnus-define-keys (mh-show-thread-map "T" mh-show-mode-map) 931(gnus-define-keys (mh-show-thread-map "T" mh-show-mode-map)
888 "?" mh-prefix-help 932 "?" mh-prefix-help
889 "u" mh-show-thread-ancestor 933 "u" mh-show-thread-ancestor
@@ -894,6 +938,7 @@ still visible.\n")
894 "o" mh-show-thread-refile) 938 "o" mh-show-thread-refile)
895 939
896(gnus-define-keys (mh-show-limit-map "/" mh-show-mode-map) 940(gnus-define-keys (mh-show-limit-map "/" mh-show-mode-map)
941 "'" mh-show-narrow-to-tick
897 "?" mh-prefix-help 942 "?" mh-prefix-help
898 "s" mh-show-narrow-to-subject 943 "s" mh-show-narrow-to-subject
899 "w" mh-show-widen) 944 "w" mh-show-widen)
@@ -932,7 +977,12 @@ still visible.\n")
932 ["Widen from Sequence" mh-show-widen t] 977 ["Widen from Sequence" mh-show-widen t]
933 "--" 978 "--"
934 ["Narrow to Subject Sequence" mh-show-narrow-to-subject t] 979 ["Narrow to Subject Sequence" mh-show-narrow-to-subject t]
980 ["Narrow to Tick Sequence" mh-show-narrow-to-tick
981 (save-excursion
982 (set-buffer mh-show-folder-buffer)
983 (and mh-tick-seq (mh-seq-msgs (mh-find-seq mh-tick-seq))))]
935 ["Delete Rest of Same Subject" mh-show-delete-subject t] 984 ["Delete Rest of Same Subject" mh-show-delete-subject t]
985 ["Toggle Tick Mark" mh-show-toggle-tick t]
936 "--" 986 "--"
937 ["Push State Out to MH" mh-show-update-sequences t])) 987 ["Push State Out to MH" mh-show-update-sequences t]))
938 988
@@ -979,6 +1029,7 @@ still visible.\n")
979 "--" 1029 "--"
980 ["List Folders" mh-show-list-folders t] 1030 ["List Folders" mh-show-list-folders t]
981 ["Visit a Folder..." mh-show-visit-folder t] 1031 ["Visit a Folder..." mh-show-visit-folder t]
1032 ["View New Messages" mh-show-index-new-messages t]
982 ["Search a Folder..." mh-show-search-folder t] 1033 ["Search a Folder..." mh-show-search-folder t]
983 ["Indexed Search..." mh-index-search t] 1034 ["Indexed Search..." mh-index-search t]
984 "--" 1035 "--"
@@ -988,6 +1039,9 @@ still visible.\n")
988;;; Ensure new buffers won't get this mode if default-major-mode is nil. 1039;;; Ensure new buffers won't get this mode if default-major-mode is nil.
989(put 'mh-show-mode 'mode-class 'special) 1040(put 'mh-show-mode 'mode-class 'special)
990 1041
1042;; Avoid compiler warning
1043(defvar tool-bar-map)
1044
991(define-derived-mode mh-show-mode text-mode "MH-Show" 1045(define-derived-mode mh-show-mode text-mode "MH-Show"
992 "Major mode for showing messages in MH-E.\\<mh-show-mode-map> 1046 "Major mode for showing messages in MH-E.\\<mh-show-mode-map>
993The value of `mh-show-mode-hook' is a list of functions to 1047The value of `mh-show-mode-hook' is a list of functions to
@@ -1015,7 +1069,9 @@ be called, with no arguments, upon entry to this mode."
1015 (turn-on-font-lock)) 1069 (turn-on-font-lock))
1016 (if (and (boundp 'tool-bar-mode) tool-bar-mode) 1070 (if (and (boundp 'tool-bar-mode) tool-bar-mode)
1017 (set (make-local-variable 'tool-bar-map) mh-show-tool-bar-map)) 1071 (set (make-local-variable 'tool-bar-map) mh-show-tool-bar-map))
1072 (mh-funcall-if-exists mh-toolbar-init :show)
1018 (when mh-decode-mime-flag 1073 (when mh-decode-mime-flag
1074 (mh-make-local-hook 'kill-buffer-hook)
1019 (add-hook 'kill-buffer-hook 'mh-mime-cleanup nil t)) 1075 (add-hook 'kill-buffer-hook 'mh-mime-cleanup nil t))
1020 (easy-menu-add mh-show-sequence-menu) 1076 (easy-menu-add mh-show-sequence-menu)
1021 (easy-menu-add mh-show-message-menu) 1077 (easy-menu-add mh-show-message-menu)
@@ -1034,27 +1090,226 @@ be called, with no arguments, upon entry to this mode."
1034 (if (fboundp 'goto-address) 1090 (if (fboundp 'goto-address)
1035 (goto-address)))) 1091 (goto-address))))
1036 1092
1093
1094
1095;; X-Face and Face display
1037(defvar mh-show-xface-function 1096(defvar mh-show-xface-function
1038 (cond ((and mh-xemacs-flag (locate-library "x-face")) 1097 (cond ((and mh-xemacs-flag (locate-library "x-face") (not (featurep 'xface)))
1039 (load "x-face" t t) 1098 (load "x-face" t t)
1040 (if (fboundp 'x-face-xmas-wl-display-x-face) 1099 #'mh-face-display-function)
1041 #'x-face-xmas-wl-display-x-face 1100 ((>= emacs-major-version 21)
1042 #'ignore)) 1101 #'mh-face-display-function)
1043 ((and (not mh-xemacs-flag) (>= emacs-major-version 21))
1044 (load "x-face-e21" t t)
1045 (if (fboundp 'x-face-decode-message-header)
1046 #'x-face-decode-message-header
1047 #'ignore))
1048 (t #'ignore)) 1102 (t #'ignore))
1049 "Determine at run time what function should be called to display X-Face.") 1103 "Determine at run time what function should be called to display X-Face.")
1050 1104
1105(defvar mh-uncompface-executable
1106 (and (fboundp 'executable-find) (executable-find "uncompface")))
1107
1108(defun mh-face-to-png (data)
1109 "Convert base64 encoded DATA to png image."
1110 (with-temp-buffer
1111 (insert data)
1112 (ignore-errors (base64-decode-region (point-min) (point-max)))
1113 (buffer-string)))
1114
1115(defun mh-uncompface (data)
1116 "Run DATA through `uncompface' to generate bitmap."
1117 (with-temp-buffer
1118 (insert data)
1119 (when (and mh-uncompface-executable
1120 (equal (call-process-region (point-min) (point-max)
1121 mh-uncompface-executable t '(t nil))
1122 0))
1123 (mh-icontopbm)
1124 (buffer-string))))
1125
1126(defun mh-icontopbm ()
1127 "Elisp substitute for `icontopbm'."
1128 (goto-char (point-min))
1129 (let ((end (point-max)))
1130 (while (re-search-forward "0x\\(..\\)\\(..\\)," nil t)
1131 (save-excursion
1132 (goto-char (point-max))
1133 (insert (string-to-number (match-string 1) 16))
1134 (insert (string-to-number (match-string 2) 16))))
1135 (delete-region (point-min) end)
1136 (goto-char (point-min))
1137 (insert "P4\n48 48\n")))
1138
1139(mh-do-in-xemacs (defvar default-enable-multibyte-characters))
1140
1141(defun mh-face-display-function ()
1142 "Display a Face or X-Face header field.
1143Display Face if both are present."
1144 (save-restriction
1145 (goto-char (point-min))
1146 (re-search-forward "\n\n" (point-max) t)
1147 (narrow-to-region (point-min) (point))
1148 (let* ((case-fold-search t)
1149 (default-enable-multibyte-characters nil)
1150 (face (message-fetch-field "face" t))
1151 (x-face (message-fetch-field "x-face" t))
1152 (url (message-fetch-field "x-image-url" t))
1153 raw type)
1154 (cond (face (setq raw (mh-face-to-png face)
1155 type 'png))
1156 (x-face (setq raw (mh-uncompface x-face)
1157 type 'pbm))
1158 (url (setq type 'url)))
1159 (when type
1160 (goto-char (point-min))
1161 (when (re-search-forward "^from:" (point-max) t)
1162 ;; GNU Emacs
1163 (mh-do-in-gnu-emacs
1164 (if (eq type 'url)
1165 (mh-x-image-url-display url)
1166 (mh-funcall-if-exists
1167 insert-image (create-image
1168 raw type t
1169 :foreground (face-foreground 'mh-show-xface-face)
1170 :background (face-background 'mh-show-xface-face))
1171 " ")))
1172 ;; XEmacs
1173 (mh-do-in-xemacs
1174 (cond
1175 ((eq type 'url)
1176 (mh-x-image-url-display url))
1177 ((eq type 'png)
1178 (when (featurep 'png)
1179 (set-extent-begin-glyph
1180 (make-extent (point) (point))
1181 (make-glyph (vector 'png ':data (mh-face-to-png face))))))
1182 ;; Try internal xface support if available...
1183 ((and (eq type 'pbm) (featurep 'xface))
1184 (set-glyph-face
1185 (set-extent-begin-glyph
1186 (make-extent (point) (point))
1187 (make-glyph (vector 'xface ':data (concat "X-Face: " x-face))))
1188 'mh-show-xface-face))
1189 ;; Otherwise try external support with x-face...
1190 ((and (eq type 'pbm)
1191 (fboundp 'x-face-xmas-wl-display-x-face)
1192 (fboundp 'executable-find) (executable-find "uncompface"))
1193 (mh-funcall-if-exists x-face-xmas-wl-display-x-face)))
1194 (when raw (insert " "))))))))
1195
1196
1051(defun mh-show-xface () 1197(defun mh-show-xface ()
1052 "Display X-Face." 1198 "Display X-Face."
1053 (when (and mh-show-use-xface-flag 1199 (when (and window-system mh-show-use-xface-flag
1054 (or mh-decode-mime-flag mhl-formfile 1200 (or mh-decode-mime-flag mhl-formfile
1055 mh-clean-message-header-flag)) 1201 mh-clean-message-header-flag))
1056 (funcall mh-show-xface-function))) 1202 (funcall mh-show-xface-function)))
1057 1203
1204
1205
1206;; X-Image-URL display
1207
1208(defvar mh-x-image-cache-directory nil
1209 "Directory where X-Image-URL images are cached.")
1210
1211(defvar mh-convert-executable (executable-find "convert"))
1212(defvar mh-wget-executable (executable-find "wget"))
1213(defvar mh-x-image-temp-file nil)
1214(defvar mh-x-image-url nil)
1215(defvar mh-x-image-marker nil)
1216(defvar mh-x-image-url-cache-file nil)
1217
1218(defun mh-x-image-url-cache-canonicalize (url)
1219 "Canonicalize URL.
1220Replace the ?/ character with a ?! character."
1221 (with-temp-buffer
1222 (insert url)
1223 (goto-char (point-min))
1224 (while (search-forward "/" nil t) (replace-match "!"))
1225 (format "%s/%s.png" mh-x-image-cache-directory (buffer-string))))
1226
1227(defun mh-x-image-url-fetch-image (url cache-file marker sentinel)
1228 "Fetch and display the image specified by URL.
1229After the image is fetched, it is stored in CACHE-FILE. It will be displayed
1230in a buffer and position specified by MARKER. The actual display is carried
1231out by the SENTINEL function."
1232 (if (and mh-wget-executable
1233 mh-fetch-x-image-url
1234 (or (eq mh-fetch-x-image-url t)
1235 (y-or-n-p (format "Fetch %s? " url))))
1236 (let ((buffer (get-buffer-create (generate-new-buffer-name " *mh-url*")))
1237 (filename (make-temp-name "/tmp/mhe-wget")))
1238 (save-excursion
1239 (set-buffer buffer)
1240 (set (make-local-variable 'mh-x-image-url-cache-file) cache-file)
1241 (set (make-local-variable 'mh-x-image-marker) marker)
1242 (set (make-local-variable 'mh-x-image-temp-file) filename))
1243 (set-process-sentinel
1244 (start-process "*wget*" buffer mh-wget-executable "-O" filename url)
1245 sentinel))
1246 ;; Make sure we don't ask about this image again
1247 (when (and mh-wget-executable (eq mh-fetch-x-image-url 'ask))
1248 (make-symbolic-link mh-x-image-cache-directory cache-file t))))
1249
1250(defun mh-x-image-display (image marker)
1251 "Display IMAGE at MARKER."
1252 (save-excursion
1253 (set-buffer (marker-buffer marker))
1254 (let ((buffer-read-only nil)
1255 (default-enable-multibyte-characters nil)
1256 (buffer-modified-flag (buffer-modified-p)))
1257 (unwind-protect
1258 (when (and (file-readable-p image) (not (file-symlink-p image)))
1259 (goto-char marker)
1260 (mh-do-in-gnu-emacs
1261 (mh-funcall-if-exists insert-image (create-image image 'png)))
1262 (mh-do-in-xemacs
1263 (when (featurep 'png)
1264 (set-extent-begin-glyph
1265 (make-extent (point) (point))
1266 (make-glyph
1267 (vector 'png ':data (with-temp-buffer
1268 (insert-file-contents-literally image)
1269 (buffer-string))))))))
1270 (set-buffer-modified-p buffer-modified-flag)))))
1271
1272(defun mh-x-image-scale-and-display (process change)
1273 "When the wget PROCESS terminates scale and display image.
1274The argument CHANGE is ignored."
1275 (when (eq (process-status process) 'exit)
1276 (let (marker temp-file cache-filename wget-buffer)
1277 (save-excursion
1278 (set-buffer (setq wget-buffer (process-buffer process)))
1279 (setq marker mh-x-image-marker
1280 cache-filename mh-x-image-url-cache-file
1281 temp-file mh-x-image-temp-file))
1282 (when mh-convert-executable
1283 (call-process mh-convert-executable nil nil nil "-resize" "96x48"
1284 temp-file cache-filename))
1285 (if (file-exists-p cache-filename)
1286 (mh-x-image-display cache-filename marker)
1287 (make-symbolic-link mh-x-image-cache-directory cache-filename t))
1288 (ignore-errors
1289 (set-marker marker nil)
1290 (delete-process process)
1291 (kill-buffer wget-buffer)
1292 (delete-file temp-file)))))
1293
1294(defun mh-x-image-url-display (url)
1295 "Display image from location URL.
1296If the URL isn't present in the cache then it is fetched with wget."
1297 (let ((cache-filename (mh-x-image-url-cache-canonicalize url))
1298 (marker (set-marker (make-marker) (point))))
1299 (cond ((file-exists-p cache-filename)
1300 (mh-x-image-display cache-filename marker))
1301 ((not mh-fetch-x-image-url)
1302 (set-marker marker nil))
1303 ((and (not (file-exists-p mh-x-image-cache-directory))
1304 (call-process "mkdir" nil nil nil mh-x-image-cache-directory)
1305 nil))
1306 ((and (file-exists-p mh-x-image-cache-directory)
1307 (file-directory-p mh-x-image-cache-directory))
1308 (mh-x-image-url-fetch-image url cache-filename marker
1309 'mh-x-image-scale-and-display)))))
1310
1311
1312
1058(defun mh-maybe-show (&optional msg) 1313(defun mh-maybe-show (&optional msg)
1059 "Display message at cursor, but only if in show mode. 1314 "Display message at cursor, but only if in show mode.
1060If optional arg MSG is non-nil, display that message instead." 1315If optional arg MSG is non-nil, display that message instead."
@@ -1110,6 +1365,7 @@ arguments, after the message has been displayed."
1110 (if (not (memq msg mh-seen-list)) 1365 (if (not (memq msg mh-seen-list))
1111 (setq mh-seen-list (cons msg mh-seen-list))) 1366 (setq mh-seen-list (cons msg mh-seen-list)))
1112 (when mh-update-sequences-after-mh-show-flag 1367 (when mh-update-sequences-after-mh-show-flag
1368 (if mh-index-data (mh-index-update-unseen msg))
1113 (mh-update-sequences)) 1369 (mh-update-sequences))
1114 (run-hooks 'mh-show-hook)) 1370 (run-hooks 'mh-show-hook))
1115 1371
@@ -1147,32 +1403,12 @@ The message is displayed in raw form."
1147 (delete-other-windows) 1403 (delete-other-windows)
1148 (switch-to-buffer edit-buffer))) 1404 (switch-to-buffer edit-buffer)))
1149 1405
1150(defun mh-decode-content-transfer-encoded-message ()
1151 "Run mimencode on message body, if needed."
1152 (let ((case-fold-search t)
1153 (header-end (mail-header-end)))
1154 (goto-char (point-min))
1155 (when (re-search-forward "^content-transfer-encoding: " header-end t)
1156 (let ((enc (buffer-substring-no-properties (point) (line-end-position)))
1157 cmdline)
1158 (setq cmdline
1159 (cond ((string-match "base64" enc) (list "-u" "-b" "-p"))
1160 ((string-match "quoted-printable" enc) (list "-u" "-q"))
1161 (t nil)))
1162 (when cmdline
1163 (beginning-of-line)
1164 (insert "Removed-")
1165 (setq header-end (mail-header-end))
1166 (goto-char (1+ header-end))
1167 (apply #'call-process-region (1+ header-end) (point-max) "mimencode"
1168 t t nil cmdline))))))
1169
1170(defun mh-show-unquote-From () 1406(defun mh-show-unquote-From ()
1171 "Decode >From at beginning of lines for `mh-show-mode'." 1407 "Decode >From at beginning of lines for `mh-show-mode'."
1172 (save-excursion 1408 (save-excursion
1173 (let ((modified (buffer-modified-p)) 1409 (let ((modified (buffer-modified-p))
1174 (case-fold-search nil)) 1410 (case-fold-search nil))
1175 (goto-char (mail-header-end)) 1411 (goto-char (mh-mail-header-end))
1176 (while (re-search-forward "^>From" nil t) 1412 (while (re-search-forward "^>From" nil t)
1177 (replace-match "From")) 1413 (replace-match "From"))
1178 (set-buffer-modified-p modified)))) 1414 (set-buffer-modified-p modified))))
@@ -1226,8 +1462,6 @@ Sets the current buffer to the show buffer."
1226 (list "-form" formfile)) 1462 (list "-form" formfile))
1227 msg-filename) 1463 msg-filename)
1228 (insert-file-contents-literally msg-filename)) 1464 (insert-file-contents-literally msg-filename))
1229 (if mh-decode-content-transfer-encoded-message-flag
1230 (mh-decode-content-transfer-encoded-message))
1231 ;; Cleanup old mime handles 1465 ;; Cleanup old mime handles
1232 (mh-mime-cleanup) 1466 (mh-mime-cleanup)
1233 ;; Use mm to display buffer 1467 ;; Use mm to display buffer
@@ -1235,6 +1469,7 @@ Sets the current buffer to the show buffer."
1235 (mh-add-missing-mime-version-header) 1469 (mh-add-missing-mime-version-header)
1236 (setf (mh-buffer-data) (mh-make-buffer-data)) 1470 (setf (mh-buffer-data) (mh-make-buffer-data))
1237 (mh-mime-display)) 1471 (mh-mime-display))
1472 (mh-show-mode)
1238 ;; Header cleanup 1473 ;; Header cleanup
1239 (goto-char (point-min)) 1474 (goto-char (point-min))
1240 (cond (clean-message-header 1475 (cond (clean-message-header
@@ -1244,6 +1479,7 @@ Sets the current buffer to the show buffer."
1244 (goto-char (point-min))) 1479 (goto-char (point-min)))
1245 (t 1480 (t
1246 (mh-start-of-uncleaned-message))) 1481 (mh-start-of-uncleaned-message)))
1482 (mh-decode-message-header)
1247 ;; the parts of visiting we want to do (no locking) 1483 ;; the parts of visiting we want to do (no locking)
1248 (or (eq buffer-undo-list t) ;don't save undo info for prev msgs 1484 (or (eq buffer-undo-list t) ;don't save undo info for prev msgs
1249 (setq buffer-undo-list nil)) 1485 (setq buffer-undo-list nil))
@@ -1253,7 +1489,6 @@ Sets the current buffer to the show buffer."
1253 (setq buffer-backed-up nil) 1489 (setq buffer-backed-up nil)
1254 (auto-save-mode 1) 1490 (auto-save-mode 1)
1255 (set-mark nil) 1491 (set-mark nil)
1256 (mh-show-mode)
1257 (unwind-protect 1492 (unwind-protect
1258 (when (and mh-decode-mime-flag (not formfile)) 1493 (when (and mh-decode-mime-flag (not formfile))
1259 (setq buffer-read-only nil) 1494 (setq buffer-read-only nil)
@@ -1276,6 +1511,7 @@ INVISIBLE-HEADERS contains a regular expression specifying lines to delete
1276from the header. VISIBLE-HEADERS contains a regular expression specifying the 1511from the header. VISIBLE-HEADERS contains a regular expression specifying the
1277lines to display. INVISIBLE-HEADERS is ignored if VISIBLE-HEADERS is non-nil." 1512lines to display. INVISIBLE-HEADERS is ignored if VISIBLE-HEADERS is non-nil."
1278 (let ((case-fold-search t) 1513 (let ((case-fold-search t)
1514 (buffer-read-only nil)
1279 (after-change-functions nil)) ;Work around emacs-20 font-lock bug 1515 (after-change-functions nil)) ;Work around emacs-20 font-lock bug
1280 ;causing an endless loop. 1516 ;causing an endless loop.
1281 (save-restriction 1517 (save-restriction
@@ -1306,15 +1542,17 @@ lines to display. INVISIBLE-HEADERS is ignored if VISIBLE-HEADERS is non-nil."
1306 1542
1307(defun mh-notate (msg notation offset) 1543(defun mh-notate (msg notation offset)
1308 "Mark MSG with the character NOTATION at position OFFSET. 1544 "Mark MSG with the character NOTATION at position OFFSET.
1309Null MSG means the message at cursor." 1545Null MSG means the message at cursor.
1546If NOTATION is nil then no change in the buffer occurs."
1310 (save-excursion 1547 (save-excursion
1311 (if (or (null msg) 1548 (if (or (null msg)
1312 (mh-goto-msg msg t t)) 1549 (mh-goto-msg msg t t))
1313 (with-mh-folder-updating (t) 1550 (with-mh-folder-updating (t)
1314 (beginning-of-line) 1551 (beginning-of-line)
1315 (forward-char offset) 1552 (forward-char offset)
1316 (delete-char 1) 1553 (let ((notation (or notation (char-after))))
1317 (insert notation))))) 1554 (delete-char 1)
1555 (insert notation))))))
1318 1556
1319(defun mh-find-msg-get-num (step) 1557(defun mh-find-msg-get-num (step)
1320 "Return the message number of the message nearest the cursor. 1558 "Return the message number of the message nearest the cursor.
@@ -1405,6 +1643,9 @@ arguments, after these variable have been set."
1405 (setq mh-user-path 1643 (setq mh-user-path
1406 (file-name-as-directory 1644 (file-name-as-directory
1407 (expand-file-name mh-user-path (expand-file-name "~")))) 1645 (expand-file-name mh-user-path (expand-file-name "~"))))
1646 (unless mh-x-image-cache-directory
1647 (setq mh-x-image-cache-directory
1648 (expand-file-name ".mhe-x-image-cache" mh-user-path)))
1408 (setq mh-draft-folder (mh-get-profile-field "Draft-Folder:")) 1649 (setq mh-draft-folder (mh-get-profile-field "Draft-Folder:"))
1409 (if mh-draft-folder 1650 (if mh-draft-folder
1410 (progn 1651 (progn
@@ -1542,7 +1783,7 @@ The message number width portion of the format is discovered using
1542 (set-buffer tmp-buffer) 1783 (set-buffer tmp-buffer)
1543 (erase-buffer) 1784 (erase-buffer)
1544 (apply 'call-process 1785 (apply 'call-process
1545 (expand-file-name "scan" mh-progs) nil '(t nil) nil 1786 (expand-file-name mh-scan-prog mh-progs) nil '(t nil) nil
1546 (list folder "last" "-format" "%(msg)")) 1787 (list folder "last" "-format" "%(msg)"))
1547 (goto-char (point-min)) 1788 (goto-char (point-min))
1548 (if (re-search-forward mh-scan-msg-number-regexp nil 0 1) 1789 (if (re-search-forward mh-scan-msg-number-regexp nil 0 1)
@@ -1582,6 +1823,7 @@ not updated."
1582 sorted-msgs)) 1823 sorted-msgs))
1583 1824
1584(defvar mh-sub-folders-cache (make-hash-table :test #'equal)) 1825(defvar mh-sub-folders-cache (make-hash-table :test #'equal))
1826(defvar mh-current-folder-name nil)
1585 1827
1586(defun mh-normalize-folder-name (folder &optional empty-string-okay 1828(defun mh-normalize-folder-name (folder &optional empty-string-okay
1587 dont-remove-trailing-slash) 1829 dont-remove-trailing-slash)
@@ -1602,8 +1844,18 @@ if present is retained (if present), otherwise it is removed."
1602 (setq folder (replace-match "/" nil t folder))) 1844 (setq folder (replace-match "/" nil t folder)))
1603 (let* ((length (length folder)) 1845 (let* ((length (length folder))
1604 (trailing-slash-present (and (> length 0) 1846 (trailing-slash-present (and (> length 0)
1605 (equal (aref folder (1- length)) ?/)))) 1847 (equal (aref folder (1- length)) ?/)))
1606 (let ((components (split-string folder "/")) 1848 (leading-slash-present (and (> length 0)
1849 (equal (aref folder 0) ?/))))
1850 (when (and (> length 0) (equal (aref folder 0) ?@)
1851 (stringp mh-current-folder-name))
1852 (setq folder (format "%s/%s/" mh-current-folder-name
1853 (substring folder 1))))
1854 ;; XXX: Purge empty strings from the list that split-string returns. In
1855 ;; XEmacs, (split-string "+foo/" "/") returns ("+foo" "") while in GNU
1856 ;; Emacs it returns ("+foo"). In the code it is assumed that the
1857 ;; components list has no empty strings.
1858 (let ((components (delete "" (split-string folder "/")))
1607 (result ())) 1859 (result ()))
1608 ;; Remove .. and . from the pathname. 1860 ;; Remove .. and . from the pathname.
1609 (dolist (component components) 1861 (dolist (component components)
@@ -1618,7 +1870,9 @@ if present is retained (if present), otherwise it is removed."
1618 ;; Remove trailing '/' if needed. 1870 ;; Remove trailing '/' if needed.
1619 (unless (and trailing-slash-present dont-remove-trailing-slash) 1871 (unless (and trailing-slash-present dont-remove-trailing-slash)
1620 (when (not (equal folder "")) 1872 (when (not (equal folder ""))
1621 (setq folder (substring folder 0 (1- (length folder)))))))) 1873 (setq folder (substring folder 0 (1- (length folder))))))
1874 (when leading-slash-present
1875 (setq folder (concat "/" folder)))))
1622 (cond ((and empty-string-okay (equal folder ""))) 1876 (cond ((and empty-string-okay (equal folder "")))
1623 ((equal folder "") (setq folder "+")) 1877 ((equal folder "") (setq folder "+"))
1624 ((not (equal (aref folder 0) ?+)) (setq folder (concat "+" folder))))) 1878 ((not (equal (aref folder 0) ?+)) (setq folder (concat "+" folder)))))
@@ -1713,9 +1967,23 @@ tell us about the option +foo/bar!"
1713 1967
1714(defvar mh-folder-hist nil) 1968(defvar mh-folder-hist nil)
1715(defvar mh-speed-folder-map) 1969(defvar mh-speed-folder-map)
1970(defvar mh-speed-flists-cache)
1971
1972(defvar mh-allow-root-folder-flag nil
1973 "Non-nil means \"+\" is an acceptable folder name.
1974This variable is used to communicate with `mh-folder-completion-function'. That
1975function can have exactly three arguments so we bind this variable to t or nil.
1976
1977This variable should never be set.")
1978
1716(defvar mh-folder-completion-map (copy-keymap minibuffer-local-completion-map)) 1979(defvar mh-folder-completion-map (copy-keymap minibuffer-local-completion-map))
1717(define-key mh-folder-completion-map " " 'minibuffer-complete) 1980(define-key mh-folder-completion-map " " 'minibuffer-complete)
1718 1981
1982(defun mh-speed-flists-active-p ()
1983 "Check if speedbar is running with message counts enabled."
1984 (and (featurep 'mh-speed)
1985 (> (hash-table-count mh-speed-flists-cache) 0)))
1986
1719(defun mh-folder-completion-function (name predicate flag) 1987(defun mh-folder-completion-function (name predicate flag)
1720 "Programmable completion for folder names. 1988 "Programmable completion for folder names.
1721NAME is the partial folder name that has been input. PREDICATE if non-nil is a 1989NAME is the partial folder name that has been input. PREDICATE if non-nil is a
@@ -1747,14 +2015,19 @@ whether the completion is over."
1747 (all-completions 2015 (all-completions
1748 remainder (mh-sub-folders last-complete t) predicate)) 2016 remainder (mh-sub-folders last-complete t) predicate))
1749 ((eq flag 'lambda) 2017 ((eq flag 'lambda)
1750 (file-exists-p 2018 (let ((path (concat mh-user-path
1751 (concat mh-user-path 2019 (substring (mh-normalize-folder-name name) 1))))
1752 (substring (mh-normalize-folder-name name) 1))))))) 2020 (cond (mh-allow-root-folder-flag (file-exists-p path))
1753 2021 ((equal path mh-user-path) nil)
1754(defun mh-folder-completing-read (prompt default) 2022 (t (file-exists-p path))))))))
1755 "Read folder name with PROMPT and default result DEFAULT." 2023
2024(defun mh-folder-completing-read (prompt default allow-root-folder-flag)
2025 "Read folder name with PROMPT and default result DEFAULT.
2026If ALLOW-ROOT-FOLDER-FLAG is non-nil then \"+\" is allowed to be a folder name
2027corresponding to `mh-user-path'."
1756 (mh-normalize-folder-name 2028 (mh-normalize-folder-name
1757 (let ((minibuffer-local-completion-map mh-folder-completion-map)) 2029 (let ((minibuffer-local-completion-map mh-folder-completion-map)
2030 (mh-allow-root-folder-flag allow-root-folder-flag))
1758 (completing-read prompt 'mh-folder-completion-function nil nil nil 2031 (completing-read prompt 'mh-folder-completion-function nil nil nil
1759 'mh-folder-hist default)) 2032 'mh-folder-hist default))
1760 t)) 2033 t))
@@ -1775,8 +2048,10 @@ when used in searching."
1775 ((equal "" default) "? ") 2048 ((equal "" default) "? ")
1776 (t (format " [%s]? " default)))) 2049 (t (format " [%s]? " default))))
1777 (prompt (format "%s folder%s" prompt default-string)) 2050 (prompt (format "%s folder%s" prompt default-string))
2051 (mh-current-folder-name mh-current-folder)
1778 read-name folder-name) 2052 read-name folder-name)
1779 (while (and (setq read-name (mh-folder-completing-read prompt default)) 2053 (while (and (setq read-name (mh-folder-completing-read
2054 prompt default allow-root-folder-flag))
1780 (equal read-name "") 2055 (equal read-name "")
1781 (equal default ""))) 2056 (equal default "")))
1782 (cond ((or (equal read-name "") 2057 (cond ((or (equal read-name "")
@@ -1790,6 +2065,14 @@ when used in searching."
1790 (cond ((and (> (length folder-name) 0) 2065 (cond ((and (> (length folder-name) 0)
1791 (eq (aref folder-name (1- (length folder-name))) ?/)) 2066 (eq (aref folder-name (1- (length folder-name))) ?/))
1792 (setq folder-name (substring folder-name 0 -1)))) 2067 (setq folder-name (substring folder-name 0 -1))))
2068 (let* ((last-slash (mh-search-from-end ?/ folder-name))
2069 (parent (and last-slash (substring folder-name 0 last-slash)))
2070 (child (if last-slash
2071 (substring folder-name (1+ last-slash))
2072 (substring folder-name 1))))
2073 (unless (member child
2074 (mapcar #'car (gethash parent mh-sub-folders-cache)))
2075 (mh-remove-from-sub-folders-cache folder-name)))
1793 (let ((new-file-flag 2076 (let ((new-file-flag
1794 (not (file-exists-p (mh-expand-file-name folder-name))))) 2077 (not (file-exists-p (mh-expand-file-name folder-name)))))
1795 (cond ((and new-file-flag 2078 (cond ((and new-file-flag
@@ -1809,6 +2092,24 @@ when used in searching."
1809 (mh-expand-file-name folder-name))))) 2092 (mh-expand-file-name folder-name)))))
1810 folder-name)) 2093 folder-name))
1811 2094
2095(defun mh-truncate-log-buffer ()
2096 "If `mh-log-buffer' is too big then truncate it.
2097If the number of lines in `mh-log-buffer' exceeds `mh-log-buffer-lines' then
2098keep only the last `mh-log-buffer-lines'. As a side effect the point is set to
2099the end of the log buffer.
2100
2101The function returns the size of the final size of the log buffer."
2102 (with-current-buffer (get-buffer-create mh-log-buffer)
2103 (goto-char (point-max))
2104 (save-excursion
2105 (when (equal (forward-line (- mh-log-buffer-lines)) 0)
2106 (delete-region (point-min) (point))))
2107 (unless (or (bobp)
2108 (save-excursion
2109 (and (equal (forward-line -1) 0) (equal (char-after) ? ))))
2110 (insert "\n \n"))
2111 (buffer-size)))
2112
1812;;; Issue commands to MH. 2113;;; Issue commands to MH.
1813 2114
1814(defun mh-exec-cmd (command &rest args) 2115(defun mh-exec-cmd (command &rest args)
@@ -1818,14 +2119,14 @@ Any output is assumed to be an error and is shown to the user.
1818The output is not read or parsed by MH-E." 2119The output is not read or parsed by MH-E."
1819 (save-excursion 2120 (save-excursion
1820 (set-buffer (get-buffer-create mh-log-buffer)) 2121 (set-buffer (get-buffer-create mh-log-buffer))
1821 (erase-buffer) 2122 (let ((initial-size (mh-truncate-log-buffer)))
1822 (apply 'call-process 2123 (apply 'call-process
1823 (expand-file-name command mh-progs) nil t nil 2124 (expand-file-name command mh-progs) nil t nil
1824 (mh-list-to-string args)) 2125 (mh-list-to-string args))
1825 (if (> (buffer-size) 0) 2126 (if (> (buffer-size) initial-size)
1826 (save-window-excursion 2127 (save-window-excursion
1827 (switch-to-buffer-other-window mh-log-buffer) 2128 (switch-to-buffer-other-window mh-log-buffer)
1828 (sit-for 5))))) 2129 (sit-for 5))))))
1829 2130
1830(defun mh-exec-cmd-error (env command &rest args) 2131(defun mh-exec-cmd-error (env command &rest args)
1831 "In environment ENV, execute mh-command COMMAND with ARGS. 2132 "In environment ENV, execute mh-command COMMAND with ARGS.
@@ -1834,19 +2135,15 @@ Signals an error if process does not complete successfully."
1834 (save-excursion 2135 (save-excursion
1835 (set-buffer (get-buffer-create mh-temp-buffer)) 2136 (set-buffer (get-buffer-create mh-temp-buffer))
1836 (erase-buffer) 2137 (erase-buffer)
1837 (let ((status 2138 (let ((process-environment process-environment))
1838 (if env 2139 ;; XXX: We should purge the list that split-string returns of empty
1839 ;; the shell hacks necessary here shows just how broken Unix is 2140 ;; strings. This can happen in XEmacs if leading or trailing spaces
1840 (apply 'call-process "/bin/sh" nil t nil "-c" 2141 ;; are present.
1841 (format "%s %s ${1+\"$@\"}" 2142 (dolist (elem (if (stringp env) (split-string env " ") ()))
1842 env 2143 (push elem process-environment))
1843 (expand-file-name command mh-progs)) 2144 (mh-handle-process-error
1844 command 2145 command (apply #'call-process (expand-file-name command mh-progs)
1845 (mh-list-to-string args)) 2146 nil t nil (mh-list-to-string args))))))
1846 (apply 'call-process
1847 (expand-file-name command mh-progs) nil t nil
1848 (mh-list-to-string args)))))
1849 (mh-handle-process-error command status))))
1850 2147
1851(defun mh-exec-cmd-daemon (command filter &rest args) 2148(defun mh-exec-cmd-daemon (command filter &rest args)
1852 "Execute MH command COMMAND in the background. 2149 "Execute MH command COMMAND in the background.
@@ -1858,7 +2155,7 @@ details of FILTER.
1858ARGS are passed to COMMAND as command line arguments." 2155ARGS are passed to COMMAND as command line arguments."
1859 (save-excursion 2156 (save-excursion
1860 (set-buffer (get-buffer-create mh-log-buffer)) 2157 (set-buffer (get-buffer-create mh-log-buffer))
1861 (erase-buffer)) 2158 (mh-truncate-log-buffer))
1862 (let* ((process-connection-type nil) 2159 (let* ((process-connection-type nil)
1863 (process (apply 'start-process 2160 (process (apply 'start-process
1864 command nil 2161 command nil
@@ -1866,6 +2163,22 @@ ARGS are passed to COMMAND as command line arguments."
1866 (mh-list-to-string args)))) 2163 (mh-list-to-string args))))
1867 (set-process-filter process (or filter 'mh-process-daemon)))) 2164 (set-process-filter process (or filter 'mh-process-daemon))))
1868 2165
2166(defun mh-exec-cmd-env-daemon (env command filter &rest args)
2167 "In ennvironment ENV, execute mh-command COMMAND in the background.
2168
2169ENV is nil or a string of space-separated \"var=value\" elements.
2170Signals an error if process does not complete successfully.
2171
2172If FILTER is non-nil then it is used to process the output otherwise the
2173default filter `mh-process-daemon' is used. See `set-process-filter' for more
2174details of FILTER.
2175
2176ARGS are passed to COMMAND as command line arguments."
2177 (let ((process-environment process-environment))
2178 (dolist (elem (if (stringp env) (split-string env " ") ()))
2179 (push elem process-environment))
2180 (apply #'mh-exec-cmd-daemon command filter args)))
2181
1869(defun mh-process-daemon (process output) 2182(defun mh-process-daemon (process output)
1870 "PROCESS daemon that puts OUTPUT into a temporary buffer. 2183 "PROCESS daemon that puts OUTPUT into a temporary buffer.
1871Any output from the process is displayed in an asynchronous pop-up window." 2184Any output from the process is displayed in an asynchronous pop-up window."
@@ -1933,30 +2246,20 @@ Put the output into buffer after point. Set mark after inserted text."
1933 (apply 'mh-exec-cmd-output (expand-file-name command mh-lib-progs) nil args)) 2246 (apply 'mh-exec-cmd-output (expand-file-name command mh-lib-progs) nil args))
1934 2247
1935(defun mh-handle-process-error (command status) 2248(defun mh-handle-process-error (command status)
1936 "Raise error if COMMAND returned non-zero STATUS, otherwise return STATUS. 2249 "Raise error if COMMAND returned non-zero STATUS, otherwise return STATUS."
1937STATUS is return value from `call-process'. 2250 (if (equal status 0)
1938Program output is in current buffer. 2251 status
1939If output is too long to include in error message, display the buffer." 2252 (goto-char (point-min))
1940 (cond ((eq status 0) ;success 2253 (insert (if (integerp status)
1941 status) 2254 (format "%s: exit code %d\n" command status)
1942 ((stringp status) ;kill string 2255 (format "%s: %s\n" command status)))
1943 (error "%s: %s" command status)) 2256 (save-excursion
1944 (t ;exit code 2257 (let ((error-message (buffer-substring (point-min) (point-max))))
1945 (cond 2258 (set-buffer (get-buffer-create mh-log-buffer))
1946 ((= (buffer-size) 0) ;program produced no error message 2259 (mh-truncate-log-buffer)
1947 (error "%s: exit code %d" command status)) 2260 (insert error-message)))
1948 (t 2261 (error "%s failed, check %s buffer for error message"
1949 ;; will error message fit on one line? 2262 command mh-log-buffer)))
1950 (goto-line 2)
1951 (if (and (< (buffer-size) (frame-width))
1952 (eobp))
1953 (error "%s"
1954 (buffer-substring 1 (progn (goto-char 1)
1955 (end-of-line)
1956 (point))))
1957 (display-buffer (current-buffer))
1958 (error "%s failed with status %d. See error message in other window"
1959 command status)))))))
1960 2263
1961(defun mh-list-to-string (l) 2264(defun mh-list-to-string (l)
1962 "Flatten the list L and make every element of the new list into a string." 2265 "Flatten the list L and make every element of the new list into a string."
diff --git a/lisp/mh-e/mh-xemacs-compat.el b/lisp/mh-e/mh-xemacs-compat.el
index 692d792a1bc..e16a9fe012c 100644
--- a/lisp/mh-e/mh-xemacs-compat.el
+++ b/lisp/mh-e/mh-xemacs-compat.el
@@ -1,6 +1,6 @@
1;;; mh-xemacs-compat.el --- GNU Emacs Functions needed by XEmacs 1;;; mh-xemacs-compat.el --- GNU Emacs Functions needed by XEmacs
2 2
3;; Copyright (C) 2001, 2002 Free Software Foundation, Inc. 3;; Copyright (C) 2001, 02, 2003 Free Software Foundation, Inc.
4 4
5;; Author: FSF 5;; Author: FSF
6;; Maintainer: Bill Wohler <wohler@newt.com> 6;; Maintainer: Bill Wohler <wohler@newt.com>
@@ -28,13 +28,13 @@
28 28
29;;; Change Log: 29;;; Change Log:
30 30
31;; $Id: mh-xemacs-compat.el,v 1.13 2002/11/30 01:21:42 wohler Exp $
32
33;;; Code: 31;;; Code:
34 32
35;;; Some requires: 33;;; Some requires:
36(require 'rfc822) 34(require 'rfc822)
37 35
36(eval-when-compile (require 'mh-utils))
37
38;;; Simple compatibility: 38;;; Simple compatibility:
39 39
40(unless (fboundp 'match-string-no-properties) 40(unless (fboundp 'match-string-no-properties)
@@ -52,6 +52,42 @@
52(unless (fboundp 'cancel-timer) 52(unless (fboundp 'cancel-timer)
53 (defalias 'cancel-timer 'delete-itimer)) 53 (defalias 'cancel-timer 'delete-itimer))
54 54
55;; Set up the modeline glyph
56(defconst mh-modeline-logo
57 "/* XPM */
58static char * file[] = {
59\"18 13 2 1\",
60\"# c #666699\",
61\". c None s None\",
62\"........##........\",
63\".......####.......\",
64\"......######......\",
65\"......######......\",
66\"....#########.....\",
67\"..##############..\",
68\".##...######....#.\",
69\"##...#.#.####...#.\",
70\"....#..#.##.#...#.\",
71\"...#..##.#.#.#....\",
72\"...#..#..#..#.#...\",
73\"...#..#.##..#.##..\",
74\"...#..#.#..#....#.\"};"
75 "The image for the modeline logo.")
76
77(mh-do-in-xemacs
78 (defvar mh-modeline-glyph
79 (progn
80 (let* ((data mh-modeline-logo)
81 (glyph (make-glyph
82 (cond ((and (featurep 'xpm)
83 (device-on-window-system-p)
84 has-modeline-p)
85 `[xpm :data ,data])
86 (t [string :data "MH-E"])))))
87 (set-glyph-face glyph 'modeline-buffer-id)
88 glyph))
89 "Cute little logo to put in the modeline of MH-E buffers."))
90
55(provide 'mh-xemacs-compat) 91(provide 'mh-xemacs-compat)
56 92
57;;; Local Variables: 93;;; Local Variables:
diff --git a/lisp/mh-e/mh-xemacs-icons.el b/lisp/mh-e/mh-xemacs-icons.el
new file mode 100644
index 00000000000..bb3651d572d
--- /dev/null
+++ b/lisp/mh-e/mh-xemacs-icons.el
@@ -0,0 +1,1306 @@
1;;; mh-xemacs-icons.el --- icons for the MH-E toolbars under XEmacs
2;;
3;; Copyright (C) 2003 Free Software Foundation, Inc.
4
5;; Author: Various (See below)
6;; Maintainer: Bill Wohler <wohler@newt.com>
7;; Keywords: mail toolbar
8;; See: mh-e.el
9
10;; This file is part of GNU Emacs.
11
12;; GNU Emacs is free software; you can redistribute it and/or modify
13;; it under the terms of the GNU General Public License as published by
14;; the Free Software Foundation; either version 2, or (at your option)
15;; any later version.
16
17;; GNU Emacs is distributed in the hope that it will be useful,
18;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20;; GNU General Public License for more details.
21
22;; You should have received a copy of the GNU General Public License
23;; along with GNU Emacs; see the file COPYING. If not, write to the
24;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
25;; Boston, MA 02111-1307, USA.
26
27;;; Commentary:
28
29;; This file contains the toolbar icons that MH-E uses under XEmacs. Some
30;; icons were created for MH-E and others were copied from other Emacs modes.
31;; The XPM files are copied into defconst's and the background colour is
32;; changed.
33
34;; The alist `mh-xemacs-icon-map' contains a map of the icon file names under
35;; GNU Emacs to the constant name under XEmacs. To add new icons for XEmacs
36;; this variable should be updated as well.
37
38;;; Change Log:
39
40;;; Code:
41
42;; Avoid compiler warning
43(eval-and-compile
44 (require 'mh-utils)
45 (defvar mh-xemacs-toolbar-folder-toolbar nil)
46 (defvar mh-xemacs-toolbar-letter-toolbar nil))
47
48
49
50;; Define the toolbar icons.
51
52;; Derived From lisp/toolbar/mail.xpm
53(defconst mh-xemacs-toolbar-inc-folder-icon
54 (mh-funcall-if-exists toolbar-make-button-list
55 "/* XPM */
56static char *magick[] = {
57/* columns rows colors chars-per-pixel */
58\"24 24 5 1\",
59\" c Gray0\",
60\". c #673e666663d4\",
61\"X c #a852a7bea3d2\",
62\"o c #eb46ea1de471\",
63\"O c Gray75 s backgroundToolBarColor\",
64/* pixels */
65\"OOOOOOOOOOOOOOOOOOOOOOOO\",
66\"OOOOOOOOOOOOOOOOOOOOOOOO\",
67\"OOOOOOOOOOOOOOOOOOOOOOOO\",
68\"OOOOOOOOOOOOOOOOOOOOOOOO\",
69\"OOOOOOOOOOOOOOOOOOOOOOOO\",
70\"OOOOOOOOOOOOOO OOOOOO\",
71\"OOOOOOOOO .ooX OOOOO\",
72\"OOOO .XooooooX OOOOO\",
73\"OOO .Xoooooooooo.XX OOOO\",
74\"OOO o..ooooooooX.Xo OOOO\",
75\"OOO XoX..oooooo.Xoo OOOO\",
76\"OOOO oooXX.Xoo...ooX OOO\",
77\"OOOO oooooXX..XoX.Xo OOO\",
78\"OOOO Xoooo.ooooooo.X OOO\",
79\"OOOOO oooXXoooooooo.X OO\",
80\"OOOOO ooo.oooooooooX OO\",
81\"OOOOO XoXXooooooX OOOO\",
82\"OOOOOO o.ooooX OOOOOOO\",
83\"OOOOOO .XoX OOOOOOOOOO\",
84\"OOOOOO .. OOOOOOOOOOOOO\",
85\"OOOOOOO OOOOOOOOOOOOOOO\",
86\"OOOOOOOOOOOOOOOOOOOOOOOO\",
87\"OOOOOOOOOOOOOOOOOOOOOOOO\",
88\"OOOOOOOOOOOOOOOOOOOOOOOO\"};")
89 "*MH inc folder icon.")
90
91;; Derived from lisp/toolbar/attach.pbm
92(defconst mh-xemacs-toolbar-mime-save-parts-icon
93 (mh-funcall-if-exists toolbar-make-button-list
94 "/* XPM */
95static char * file[] = {
96\"24 24 2 1\",
97\". c Gray75 s backgroundToolBarColor\",
98\" c black\",
99/* pixels */
100\"........................\",
101\"........................\",
102\"........................\",
103\"........... ...........\",
104\".......... .. ..........\",
105\"......... .... .........\",
106\"......... .... .........\",
107\"......... .... .........\",
108\"......... . .. .........\",
109\"......... . .. .........\",
110\"......... . .. . .......\",
111\"......... . .. . .......\",
112\"......... . .. . .......\",
113\"......... . .. . .......\",
114\"......... . .. . .......\",
115\"......... . .. . .......\",
116\"......... . .. . .......\",
117\"......... .. .. .......\",
118\".......... .... ........\",
119\"........... .. .........\",
120\"............ ..........\",
121\"........................\",
122\"........................\",
123\"........................\"};")
124 "*MH save MIME parts icon.")
125
126;; Derived from lisp/toolbar/right_arrow.xpm
127(defconst mh-xemacs-toolbar-next-undeleted-msg-icon
128 (mh-funcall-if-exists toolbar-make-button-list
129 "/* XPM */
130static char * right_arrow_xpm[] = {
131\"24 24 9 1\",
132\" c Gray75 s backgroundToolBarColor\",
133\". c #020202\",
134\"+ c #1A1A1A\",
135\"@ c #779D6D\",
136\"# c #88AE80\",
137\"$ c #97B78B\",
138\"% c #9EBA92\",
139\"& c #E9EFE8\",
140\"* c #3C5936\",
141\" \",
142\" \",
143\" \",
144\" \",
145\" \",
146\" .. \",
147\" .&.. \",
148\" .&&&.. \",
149\" .&&&&&.. \",
150\" .&&&&&&&.. \",
151\" .&&&&&&&&&+. \",
152\" +&&&&&&&&&&%.. \",
153\" .%#######@@*.. \",
154\" .%#####@@*.. \",
155\" .%###@@*.. \",
156\" .$#@@*.. \",
157\" .#@*.. \",
158\" .*.. \",
159\" .. \",
160\" \",
161\" \",
162\" \",
163\" \",
164\" \"};")
165 "*MH previous message icon.")
166
167;; Derived from mh-e/page-down.xpm
168(defconst mh-xemacs-toolbar-page-msg-icon
169 (mh-funcall-if-exists toolbar-make-button-list
170 "/* XPM */
171static char * mail_page_xpm[] = {
172/* columns rows colors chars-per-pixel */
173\"24 24 5 1\",
174\" c Gray75 s backgroundToolBarColor\",
175\". c black\",
176\"X c #ea03ea03d271\",
177\"o c #a5d8a5d89550\",
178\"O c #d305d305bc3c\",
179/* pixels */
180\" \",
181\" \",
182\" .................. \",
183\" .XXXXXXXXXXXXXXXX. \",
184\" .XXXXXXXXXXXXXXXX. \",
185\" .XoooooooooooooXX. \",
186\" .XXXXXXXXXXXXXXXX. \",
187\" .XXXXXXXXXXXXXXXX. \",
188\" .Xoooooooooo..oXX. \",
189\" .XXXXXXXXXXX..XXX. \",
190\" .XXXXXXXXXXX..XXX. \",
191\" .XooooooXXXX..XXX. \",
192\" .XXXXXXXXXXX..XXX. \",
193\" .XXXXXXXXX.O..O.X. \",
194\" .Xoooooooo.....XX. \",
195\" .XXXXXXXXXX....XX. \",
196\" .XXXXXXXXXXX..XXX. \",
197\" .XXXXXXXXXXXooXXX. \",
198\" .XXXXXXXXXXXXXXXX. \",
199\" .XXXXXXXXXXXXXXXX. \",
200\" .................. \",
201\" \",
202\" \",
203\" \"};")
204 "MH page message icon.")
205
206;; Derived from lisp/toolbar/left_arrow.xpm
207(defconst mh-xemacs-toolbar-previous-undeleted-msg-icon
208 (mh-funcall-if-exists toolbar-make-button-list
209 "/* XPM */
210static char * left_arrow_xpm[] = {
211\"24 24 9 1\",
212\" c Gray75 s backgroundToolBarColor\",
213\". c #020202\",
214\"+ c #121A12\",
215\"@ c #78A16E\",
216\"# c #86AD7D\",
217\"$ c #B2C6AE\",
218\"% c #263222\",
219\"& c #E7EDE6\",
220\"* c #497241\",
221\" \",
222\" \",
223\" \",
224\" \",
225\" \",
226\" .. \",
227\" ..$. \",
228\" ..&&$. \",
229\" ..&&&&$. \",
230\" ..&&&&&&$. \",
231\" .+&&&&&&&&$. \",
232\" ..$&&&&&&&&&$% \",
233\" ..**@@@#####@. \",
234\" ..**@#@###@. \",
235\" ..**@#@#@. \",
236\" ..**@@@. \",
237\" ..*@*. \",
238\" ..*. \",
239\" .. \",
240\" \",
241\" \",
242\" \",
243\" \",
244\" \"};")
245 "MH next message icon.")
246
247;; Derived from lisp/toolbar/close.xpm
248(defconst mh-xemacs-toolbar-delete-msg-icon
249 (mh-funcall-if-exists toolbar-make-button-list
250 "/* XPM */
251static char *magick[] = {
252/* columns rows colors chars-per-pixel */
253\"24 24 2 1\",
254\" c Gray0\",
255\". c Gray75 s backgroundToolBarColor\",
256/* pixels */
257\"........................\",
258\"........................\",
259\"........................\",
260\"........................\",
261\"........................\",
262\"........................\",
263\"....... .... ..........\",
264\"....... .. .........\",
265\"........ . ..........\",
266\"........ ...........\",
267\"......... ............\",
268\"......... ...........\",
269\"........ ..........\",
270\"........ . .........\",
271\"....... ... ........\",
272\"....... ..... .........\",
273\"........................\",
274\"........................\",
275\"........................\",
276\"........................\",
277\"........................\",
278\"........................\",
279\"........................\",
280\"........................\"};")
281 "MH delete message icon.")
282
283;; Derived from mh-e/refile.xpm
284(defconst mh-xemacs-toolbar-refile-msg-icon
285 (mh-funcall-if-exists toolbar-make-button-list
286"/* XPM */
287static char * refile_xpm[] = {
288/* columns rows colors chars-per-pixel */
289\"24 24 7 1\",
290\" c Gray75 s backgroundToolBarColor\",
291\". c black\",
292\"X c #a5d8a5d89550\",
293\"o c #d305d305bc3c\",
294\"O c #ea03ea03d271\",
295\"+ c #828282827474\",
296\"@ c #61b761b7600a\",
297/* pixels */
298\" . \",
299\" ..X. \",
300\" ..XoO.... \",
301\" ..XooooO.+. \",
302\" ..XooooooOX.. .. \",
303\" .@@ooooooOOO@. ... \",
304\" .O@oooooOOOOO..@@. \",
305\" .OO@oooOOOOOO..@@. \",
306\" ...OO@XooOOOOO...@@. \",
307\" ..+.O@XooOOOO..@@@@@. \",
308\" .++..XooOOOO..@@@@@@. \",
309\" .++.@oooOO...@@@@@@@. \",
310\" ..+.XooOOO..@@@@@@@. \",
311\" .++.OOOO.@@@@@@@@. \",
312\" .+.oOO..@@@@@@@. \",
313\" .++.OO.@@@@@@@. \",
314\" .++.O.@@@@@.. \",
315\" ..+.O.@@@@@. \",
316\" .++..@@@@. \",
317\" ..++.@@@. \",
318\" .+.@@. \",
319\" ...@. \",
320\" ... \",
321\" . \"};")
322 "MH refile message icon.")
323
324;; Derived from lisp/toolbar/undo.xpm
325(defconst mh-xemacs-toolbar-undo-icon
326 (mh-funcall-if-exists toolbar-make-button-list
327 "/* XPM */
328static char *magick[] = {
329/* columns rows colors chars-per-pixel */
330\"24 24 5 1\",
331\" c Gray0\",
332\". c #ae6e66e76a0a\",
333\"X c #c6c67d7d8181\",
334\"o c #e4e4e4e4dcdc\",
335\"O c Gray75 s backgroundToolBarColor\",
336/* pixels */
337\"OOOOOOOOOOOOOOOOOOOOOOOO\",
338\"OOOOOOOOOOOOOOOOOOOOOOOO\",
339\"OOOOOOOOOOOOOOOOOOOOOOOO\",
340\"OOOOOOOOOOOOOOOOOOOOOOOO\",
341\"OOOOOOOOOOOOOOOOOOOOOOOO\",
342\"OOOOOOOOOOOOOOOOOOOOOOOO\",
343\"OOOOOOOOO OOOOOOOOOOOOOO\",
344\"OOOOOOOO OOOOOOOOOOOOOO\",
345\"OOOOOOO oX OOOOOOOOOOO\",
346\"OOOOOO ooooX. OOOOOOOOO\",
347\"OOOOOOO oo .. OOOOOOOO\",
348\"OOOOOOOO OOO . OOOOOOOO\",
349\"OOOOOOOOO OOOO . OOOOOOO\",
350\"OOOOOOOOOOOOOOO OOOOOOO\",
351\"OOOOOOOOOOOOOOO OOOOOOO\",
352\"OOOOOOOOOOOOOOO OOOOOOOO\",
353\"OOOOOOOOOOOOOO OOOOOOOOO\",
354\"OOOOOOOOOOOOOOOOOOOOOOOO\",
355\"OOOOOOOOOOOOOOOOOOOOOOOO\",
356\"OOOOOOOOOOOOOOOOOOOOOOOO\",
357\"OOOOOOOOOOOOOOOOOOOOOOOO\",
358\"OOOOOOOOOOOOOOOOOOOOOOOO\",
359\"OOOOOOOOOOOOOOOOOOOOOOOO\",
360\"OOOOOOOOOOOOOOOOOOOOOOOO\"};")
361 "MH undo icon.")
362
363;; Derived from mh-e/execute.xpm
364(defconst mh-xemacs-toolbar-execute-commands-icon
365 (mh-funcall-if-exists toolbar-make-button-list
366 "/* XPM */
367static char * mail_exec_xpm[] = {
368/* columns rows colors chars-per-pixel */
369\"24 24 6 1\",
370\" c Gray75 s backgroundToolBarColor\",
371\". c black\",
372\"X c #a5d8a5d89550\",
373\"o c #d305d305bc3c\",
374\"O c #ea03ea03d271\",
375\"+ c white\",
376/* pixels */
377\" \",
378\" \",
379\" \",
380\" .. \",
381\" XX .. \",
382\" oo XX .. \",
383\" OO oo XX .. \",
384\" OO oo XX .. \",
385\" OO oo XX .. \",
386\" OO oo XX .. \",
387\" OO oo XX .. \",
388\" OO oo XX .. \",
389\" OO oo XX .. \",
390\" OO oo XX \",
391\" OO oo \",
392\" OO + .. \",
393\" XX .. \",
394\" oo XX \",
395\" OO oo \",
396\" OO \",
397\" \",
398\" \",
399\" \",
400\" \"};")
401 "MH execute commands icon.")
402
403;; Derived from mh-e/highlight.xpm
404(defconst mh-xemacs-toolbar-toggle-tick-icon
405 (mh-funcall-if-exists toolbar-make-button-list
406 "/* XPM */
407static char * highlight_xpm[] = {
408/* columns rows colors chars-per-pixel */
409\"24 24 4 1\",
410\" c Gray75 s backgroundToolBarColor\",
411\". c black\",
412\"X c #828282827474\",
413\"o c #dd00df007e00\",
414/* pixels */
415\" ..... \",
416\" ..XXX.. \",
417\" .XXXXX. \",
418\" .XXXXX.. \",
419\" .XXXXX. \",
420\" .XXXXX. \",
421\" .XXXXX. \",
422\" .ooXX. \",
423\" ..ooo. \",
424\" oooo .... \",
425\"oo.ooo....oo ... \",
426\"o.o.ooo.oo.o.ooo.o \",
427\".ooo.oo.oo.o.ooooo \",
428\".ooo.oo.oo.o.ooooo \",
429\".ooo.oo...oo.ooooo \",
430\".....oo.oo.o.ooooo \",
431\".ooo.oo.oo.o.ooooo \",
432\".ooo.oo.oo.o.ooo.o \",
433\". oo.o....ooo...o \",
434\" oo oooo \",
435\" \",
436\" \",
437\" \",
438\" \"};")
439 "MH toggle tick icon.")
440
441;; Derived from mh-e/show.xpm
442(defconst mh-xemacs-toolbar-toggle-showing-icon
443 (mh-funcall-if-exists toolbar-make-button-list
444 "/* XPM */
445static char * mail_show_xpm[] = {
446/* columns rows colors chars-per-pixel */
447\"24 24 4 1\",
448\" c Gray75 s backgroundToolBarColor\",
449\". c black\",
450\"X c #ea03ea03d271\",
451\"o c #a5d8a5d89550\",
452/* pixels */
453\" \",
454\" \",
455\" .................. \",
456\" .XXXXXXXXXXXXXXXX. \",
457\" .XXXXXXXXXXXXXXXX. \",
458\" .XoooooooooooooXX. \",
459\" .XXXXXXXXXXXXXXXX. \",
460\" .XXXXXXXXXXXXXXXX. \",
461\" .XoooooooooooooXX. \",
462\" .XXXXXXXXXXXXXXXX. \",
463\" .XXXXXXXXXXXXXXXX. \",
464\" .XooooooXXXXXXXXX. \",
465\" .XXXXXXXXXXXXXXXX. \",
466\" .XXXXXXXXXXXXXXXX. \",
467\" .XoooooooooXXXXXX. \",
468\" .XXXXXXXXXXXXXXXX. \",
469\" .XXXXXXXXXXXXXXXX. \",
470\" .XXXXXXXXXXXXXXXX. \",
471\" .XXXXXXXXXXXXXXXX. \",
472\" .XXXXXXXXXXXXXXXX. \",
473\" .................. \",
474\" \",
475\" \",
476\" \"};")
477 "MH toggle showing icon.")
478
479;; Derived from mh-e/reply-all.xpm
480(defconst mh-xemacs-toolbar-reply-all-icon
481 (mh-funcall-if-exists toolbar-make-button-list
482 "/* XPM */
483static char * reply_all_xpm[] = {
484/* columns rows colors chars-per-pixel */
485\"24 24 9 1\",
486\" c Gray75 s backgroundToolBarColor\",
487\". c black\",
488\"X c #673e666663d4\",
489\"o c #eb46ea1de471\",
490\"O c #a852a7bea3d2\",
491\"+ c #ae51c17b9b26\",
492\"@ c #8d4d97577838\",
493\"# c #7c7c8b8b6e6e\",
494\"$ c #5e0868be52d3\",
495/* pixels */
496\" \",
497\" \",
498\" .... \",
499\" .....XooO. \",
500\" .....XOooooooO. \",
501\" .XOooooooooooXOO. \",
502\" .oXXooooooooOXOo. \",
503\" .OoOXXooooooXOoo. \",
504\" .oooOOXOooXXXooO. \",
505\" ........XXOoOXOo. \",
506\" ..++++@.ooooooXO. \",
507\" ..+@@@.oooooooXO. \",
508\" ..+@@@#.oooooooO.. \",
509\" ..++@@@#$.ooooO... \",
510\" .++++@@#.$ .. \",
511\" .+@@@#.o .. .O .O \",
512\" .+@#$. .O. .O .O \",
513\" .#$. .O .o .O .O \",
514\" .$. . .O .O .O \",
515\" . ....O .O .O \",
516\" .O .O .O .O \",
517\" .O .O .O .O \",
518\" .O .O .O .O \",
519\" \"};")
520 "Reply to \"All\" icon.")
521
522;; Derived from mh-e/reply-from.xpm
523(defconst mh-xemacs-toolbar-reply-from-icon
524 (mh-funcall-if-exists toolbar-make-button-list
525 "/* XPM */
526static char * reply_from_xpm[] = {
527/* columns rows colors chars-per-pixel */
528\"24 24 9 1\",
529\" c Gray75 s backgroundToolBarColor\",
530\". c black\",
531\"X c #673e666663d4\",
532\"o c #eb46ea1de471\",
533\"O c #a852a7bea3d2\",
534\"+ c #ae51c17b9b26\",
535\"@ c #8d4d97577838\",
536\"# c #7c7c8b8b6e6e\",
537\"$ c #5e0868be52d3\",
538/* pixels */
539\" \",
540\" \",
541\" .... \",
542\" .....XooO. \",
543\" .....XOooooooO. \",
544\" .XOooooooooooXOO. \",
545\" .oXXooooooooOXOo. \",
546\" .OoOXXooooooXOoo. \",
547\" .oooOOXOooXXXooO. \",
548\" ........XXOoOXOo. \",
549\" ..++++@.ooooooXO. \",
550\" ..+@@@.oooooooXO. \",
551\" ..+@@@#.oooooooO.. \",
552\" ..++@@@#$.ooooO... \",
553\" #.$.oO... \",
554\" ...O . .... \",
555\" ...O \",
556\" .O \",
557\" ...O ..O .... .O O. \",
558\" ...O ..O .OO. ..... \",
559\" .O .O . . . . . \",
560\" .O .O .OO. . . . \",
561\" .O .O .... . O . \",
562\" \"};")
563 "Reply to \"From\" icon..")
564
565;; Derived from mh-e/reply-to.xpm
566(defconst mh-xemacs-toolbar-reply-to-icon
567 (mh-funcall-if-exists toolbar-make-button-list
568 "/* XPM */
569static char * reply_to_xpm[] = {
570/* columns rows colors chars-per-pixel */
571\"24 24 9 1\",
572\" c Gray75 s backgroundToolBarColor\",
573\". c black\",
574\"X c #673e666663d4\",
575\"o c #eb46ea1de471\",
576\"O c #a852a7bea3d2\",
577\"+ c #ae51c17b9b26\",
578\"@ c #8d4d97577838\",
579\"# c #7c7c8b8b6e6e\",
580\"$ c #5e0868be52d3\",
581/* pixels */
582\" \",
583\" \",
584\" .... \",
585\" .....XooO. \",
586\" .....XOooooooO. \",
587\" .XOooooooooooXOO. \",
588\" .oXXooooooooOXOo. \",
589\" .OoOXXooooooXOoo. \",
590\" .oooOOXOooXXXooO. \",
591\" ........XXOoOXOo. \",
592\" ..++++@.ooooooXO. \",
593\" ..+@@@.oooooooXO. \",
594\" ..+@@@#.oooooooO.. \",
595\" ..++@@@#$.ooooO... \",
596\" .++++@@#.$ \",
597\" .+@@@#.o ...... \",
598\" .+@#$. OO.OOO \",
599\" .#$. .O \",
600\" .$. .O .... \",
601\" . .O .OO. \",
602\" .O . . \",
603\" .O .OO. \",
604\" .O .... \",
605\" \"};")
606 "Reply to \"To\" icon..")
607
608;; Derived from mh-e/mail/reply2.xpm
609(defconst mh-xemacs-toolbar-reply-icon
610 (mh-funcall-if-exists toolbar-make-button-list
611 "/* XPM */
612static char * mail_reply_xpm[] = {
613/* columns rows colors chars-per-pixel */
614\"24 24 9 1\",
615\" c Gray75 s backgroundToolBarColor\",
616\". c black\",
617\"X c #673e666663d4\",
618\"o c #eb46ea1de471\",
619\"O c #a852a7bea3d2\",
620\"+ c #ae51c17b9b26\",
621\"@ c #8d4d97577838\",
622\"# c #7c7c8b8b6e6e\",
623\"$ c #5e0868be52d3\",
624/* pixels */
625\" \",
626\" \",
627\" \",
628\" \",
629\" \",
630\" .... \",
631\" .....XooO. \",
632\" .....XOooooooO. \",
633\" .XOooooooooooXOO. \",
634\" .oXXooooooooOXOo. \",
635\" .OoOXXooooooXOoo. \",
636\" .oooOOXOooXXXooO. \",
637\" ........XXOoOXOo. \",
638\" ..++++@.ooooooXO. \",
639\" ..+@@@.oooooooXO. \",
640\" ..+@@@#.oooooooO.. \",
641\" ..++@@@#$.ooooO... \",
642\" .++++@@#.$.oO... \",
643\" .+@@@#.o.... \",
644\" .+@#$... \",
645\" .#$. \",
646\" .$. \",
647\" . \",
648\" \"};")
649 "Reply to current message icon.")
650
651;; Derived from mh-e/alias.xpm
652(defconst mh-xemacs-toolbar-alias-grab-from-field-icon
653 (mh-funcall-if-exists toolbar-make-button-list
654 "/* XPM */
655static char * alias_xpm[] = {
656/* columns rows colors chars-per-pixel */
657\"24 24 4 1\",
658\" c Gray75 s backgroundToolBarColor\",
659\". c #61b761b7600a\",
660\"X c #a5d8a5d89550\",
661\"o c black\",
662/* pixels */
663\" \",
664\" \",
665\" \",
666\" ...... \",
667\" ...XXXX..XX \",
668\" o..ooooooo... \",
669\" ooo oooo..X \",
670\" o.X ooo... \",
671\" o.X ooo.XX \",
672\" o.X oo.. \",
673\" o.X oo. \",
674\" o... oo.. \",
675\" o.X o.. \",
676\" o.XX oX. \",
677\" o.... oo. \",
678\" o..XX oooo \",
679\" o...XXX XXoooo \",
680\" ooo........ooooo \",
681\" oooooXXooooo.oo \",
682\" ooo o..oo\",
683\" o...\",
684\" ooo\",
685\" oo\",
686\" \"};")
687 "MH alias grab from field icon.")
688
689;; Derived from toolbar/mail_send.xpm
690(defconst mh-xemacs-toolbar-send-icon
691 (mh-funcall-if-exists toolbar-make-button-list
692 "/* XPM */
693static char *magick[] = {
694/* columns rows colors chars-per-pixel */
695\"24 24 9 1\",
696\" c Gray0\",
697\". c #757560602020\",
698\"X c #6711662663d9\",
699\"o c #8e8e7d7d4545\",
700\"O c #adad8e8e3030\",
701\"+ c #d8d8bebe6a6a\",
702\"@ c #a8fba84da483\",
703\"# c #eb79ea70e4f4\",
704\"$ c Gray75 s backgroundToolBarColor\",
705/* pixels */
706\"$$$$$$$$$$$$$$$$$$$$$$$$\",
707\"$$$$$$$$$$$$$$$$$$$$$$$$\",
708\"$$$$$$$$$$$$$ $$$$$$$\",
709\"$$$$$$$$ X##@ $$$$$$\",
710\"$$$ X@######@ $$$$$$\",
711\"$$ X@##########X@@ $$$$$\",
712\"$$ #XX########@X@# $$$$$\",
713\"$$ @#@XX######X@## $$$$$\",
714\"$$$ ###@@X@##XXX##@ $ $$\",
715\"$$$ #####@@XX@#@X@# + $\",
716\"$$$ @####X#######X@ +o $\",
717\"$$$$ ###@@######## +o $$\",
718\"$$$$ ###X######## +o $$$\",
719\"$$$$ @#@@######@ +o $$$$\",
720\"$$$$$ #X####@ +o $$$$$\",
721\"$$$$$ X@#@ $ +o $$$$$$\",
722\"$$$$$ XX $$$ +o $$$$$$$\",
723\"$$$$$$ $$$$ +o $$$$$$$$\",
724\"$$$$$$$$$$$O. $$$$$$$$$\",
725\"$$$$$$$$$$$ $$$$$$$$$$$\",
726\"$$$$$$$$$$$$$$$$$$$$$$$$\",
727\"$$$$$$$$$$$$$$$$$$$$$$$$\",
728\"$$$$$$$$$$$$$$$$$$$$$$$$\",
729\"$$$$$$$$$$$$$$$$$$$$$$$$\"};")
730 "MH send icon.")
731
732;; Derived from mh-e/rescan.xpm
733(defconst mh-xemacs-toolbar-rescan-folder-icon
734 (mh-funcall-if-exists toolbar-make-button-list
735 "/* XPM */
736static char * mail_rescan_xpm[] = {
737/* columns rows colors chars-per-pixel */
738\"24 24 6 1\",
739\" c Gray75 s backgroundToolBarColor\",
740\". c black\",
741\"X c #a5d8a5d89550\",
742\"o c #d305d305bc3c\",
743\"O c #ea03ea03d271\",
744\"+ c #828282827474\",
745/* pixels */
746\" \",
747\" \",
748\" .............. \",
749\" .XXXXXXXXXXXX.. \",
750\" .XXXXXXXXXXXX.X. \",
751\" .XXXXXXXXXXXX.oo. \",
752\" ..............ooo. \",
753\" .OOOOOOOOOOOO.ooo. \",
754\" .O++++++++++O.ooo. \",
755\" .O+XXXXXXXX+O.ooo. \",
756\" .O+XXXXXXXX+O.ooo. \",
757\" .O+XXXXXXXX+O.ooo. \",
758\" .O+XXXXXXXX+O.ooo. \",
759\" .O++++++++++O.ooo. \",
760\" .OOOOOOOOOOOO.ooo. \",
761\" .O++++++++++O.ooo. \",
762\" .O+XXXXXXXX+O.ooo. \",
763\" .O+XXXXXXXX+O.ooX. \",
764\" .O+XXXXXXXX+O.oo.. \",
765\" .O++++++++++O.o.. \",
766\" ..OOOOOOOOOOOO... \",
767\" ................ \",
768\" \",
769\" \"};")
770 "MH rescan folder icon.")
771
772;; Derived from mh-e/repack.xpm
773(defconst mh-xemacs-toolbar-pack-folder-icon
774 (mh-funcall-if-exists toolbar-make-button-list
775 "/* XPM */
776static char * mail_repack_xpm[] = {
777/* columns rows colors chars-per-pixel */
778\"24 24 6 1\",
779\" c Gray75 s backgroundToolBarColor\",
780\". c black\",
781\"X c #a5d8a5d89550\",
782\"o c #d305d305bc3c\",
783\"O c #ea03ea03d271\",
784\"+ c #828282827474\",
785/* pixels */
786\" \",
787\" \",
788\" .............. \",
789\" .XXXXXXXXXXXX.. \",
790\" .XXXXXXXXXXXX.X. \",
791\" .XXXXXXXXXXXX.oo. \",
792\" ..............ooo. \",
793\" .OOOOOOOOOOOO.oo. \",
794\" .O++++++++++O.oo. \",
795\" .O+XXXXXXXX+O.o. \",
796\" .+XXXXXXXX+.o.. \",
797\" .+XX...XXX+.... \",
798\" ....o.......oo. \",
799\" ....o.....Oooo. \",
800\" .OOO...OOOO.oooo. \",
801\" .++++++++++.oooo. \",
802\" .+XXXXXXXX+.oooo. \",
803\" .O+XXXXXXXX+O.ooX. \",
804\" .O+XXXXXXXX+O.oo.. \",
805\" .O++++++++++O.o.. \",
806\" ..OOOOOOOOOOOO... \",
807\" ................ \",
808\" \",
809\" \"};")
810 "MH repack folder icon.")
811
812;; Derived from lisp/toolbar/search.xpm
813(defconst mh-xemacs-toolbar-search-icon
814 (mh-funcall-if-exists toolbar-make-button-list
815 "/* XPM */
816static char *magick[] = {
817/* columns rows colors chars-per-pixel */
818\"24 24 8 1\",
819\" c #011801180102\",
820\". c #464646463e3e\",
821\"X c #5c5c5c5c57a0\",
822\"o c #878787877979\",
823\"O c #a910a91097af\",
824\"+ c #ce5ace5ab851\",
825\"@ c #e79de79dd134\",
826\"# c Gray75 s backgroundToolBarColor\",
827/* pixels */
828\"########################\",
829\"########################\",
830\"############# ##########\",
831\"########### O #########\",
832\"######### O@@.#########\",
833\"####### O@@@@@ ########\",
834\"##### O+@@@@@@O #######\",
835\"#### XX@++@@@@@@.#######\",
836\"#### @.O+@@@@@@@@ ######\",
837\"#### @@.++@@@@@@@O #####\",
838\"#### @@.o+O. .+@@ #####\",
839\"#### @XO+O.O++o.+@@ ####\",
840\"#### O+@.O@@+Oo.@@+ ###\",
841\"#### X@@@ +#+OOO @@@@ ##\",
842\"#### O@@@ +@OOOo @@@o ##\",
843\"##### @@@.oOOOoX.@@ ###\",
844\"##### O@@O.oOOX @ #####\",
845\"######X@@@O. .X ######\",
846\"###### @@@@@@@+ #####\",
847\"####### @@@@@O ## ####\",
848\"####### O@@+. #### ###\",
849\"######## @O ####### ###\",
850\"######### #############\",
851\"########################\"};")
852 "MH search icon.")
853
854;; Derived from lisp/toolbar/fld_open.xpm
855(defconst mh-xemacs-toolbar-visit-folder-icon
856 (mh-funcall-if-exists toolbar-make-button-list
857 "/* XPM */
858static char *magick[] = {
859/* columns rows colors chars-per-pixel */
860\"24 24 4 1\",
861\" c Gray0\",
862\". c #909090909090\",
863\"X c #fefefefefefe\",
864\"o c Gray75 s backgroundToolBarColor\",
865/* pixels */
866\"oooooooooooooooooooooooo\",
867\"oooooooooooooooooooooooo\",
868\"oooooooooooooooooooooooo\",
869\"oooooooooooooooooooooooo\",
870\"oooooooooooooooooooooooo\",
871\"oooooooooooooo oooooooo\",
872\"ooooooooooo .. ooooooo\",
873\"oooo oo ....XXo ooo\",
874\"ooo .. ....XXXX .. ooo\",
875\"ooo .....XXXXX .... ooo\",
876\"oooo ..XXXXX ...... ooo\",
877\"oooo ..XXX ........ ooo\",
878\"ooooo .XX .......... ooo\",
879\"ooooo ..X .......... ooo\",
880\"oooooo .X .......... ooo\",
881\"oooooo .. ........ oooo\",
882\"ooooooo . ...... oooooo\",
883\"ooooooo . ..... oooooooo\",
884\"oooooooo ... ooooooooo\",
885\"oooooooo . ooooooooooo\",
886\"ooooooooo ooooooooooooo\",
887\"oooooooooooooooooooooooo\",
888\"oooooooooooooooooooooooo\",
889\"oooooooooooooooooooooooo\"};")
890 "MH visit folder icon.")
891
892;; Derived from lisp/toolbar/help.xpm
893(defconst mh-xemacs-toolbar-help-icon
894 (mh-funcall-if-exists toolbar-make-button-list
895 "/* XPM */
896static char *magick[] = {
897/* columns rows colors chars-per-pixel */
898\"24 24 6 1\",
899\" c Gray0\",
900\". c #65658b8b5e5e\",
901\"X c #934ab2448dfb\",
902\"o c #b35dc8c8afaf\",
903\"O c #e0b2e944df83\",
904\"+ c Gray75 s backgroundToolBarColor\",
905/* pixels */
906\"++++++++++++++++++++++++\",
907\"++++++++++++++++++++++++\",
908\"++++++++++++++++++++++++\",
909\"++++++++++++++++++++++++\",
910\"+++++++++ ++++++++++\",
911\"++++++++ oOOOO +++++++++\",
912\"+++++++ OOOOOOO ++++++++\",
913\"++++++ oOo oOo +++++++\",
914\"+++++++ O +++ OO +++++++\",
915\"+++++++O ++++ Oo +++++++\",
916\"++++++++++++ OO. +++++++\",
917\"+++++++++++ OOX ++++++++\",
918\"++++++++++ OOX +++++++++\",
919\"+++++++++ XOX ++++++++++\",
920\"+++++++++ OX +++++++++++\",
921\"+++++++++ +++++++++++\",
922\"++++++++++++++++++++++++\",
923\"++++++++++ ++++++++++++\",
924\"+++++++++ Oo +++++++++++\",
925\"+++++++++ oX +++++++++++\",
926\"++++++++++ ++++++++++++\",
927\"++++++++++++++++++++++++\",
928\"++++++++++++++++++++++++\",
929\"++++++++++++++++++++++++\"};")
930 "MH help icon.")
931
932;; Derived from lisp/toolbar/mail_send.xpm
933(defconst mh-xemacs-toolbar-send-letter-icon
934 (mh-funcall-if-exists toolbar-make-button-list
935 "/* XPM */
936static char *magick[] = {
937/* columns rows colors chars-per-pixel */
938\"24 24 9 1\",
939\" c Gray0\",
940\". c #675e6580613e\",
941\"X c #8c8c7c7c6969\",
942\"o c #9b458d377822\",
943\"O c #a941a6459f3e\",
944\"+ c #c8c8b2b29898\",
945\"@ c #dadac2c2a5a5\",
946\"# c #eb4dea2fe4ad\",
947\"$ c Gray75 s backgroundToolBarColor\",
948/* pixels */
949\"$$$$$$$$$$$$$$$$$$$$$$$$\",
950\"$$$$$$$$$$$$$$$$$$$$$$$$\",
951\"$$$$$$$$$$$$$ $$$$$$$\",
952\"$$$$$$$$ .@#+ $$$$$$\",
953\"$$$ .+#####@O $$$$$$\",
954\"$$ .+##########.+O $$$$$\",
955\"$$ @..########O.+# $$$$$\",
956\"$$ O@O..@#####.+## $$$$$\",
957\"$$$ ###+O.O##...##O $$$$\",
958\"$$$ @####@+..O#O.+# $$$$\",
959\"$$$ O####.#######.O $$$$\",
960\"$$$$ ###+O########.O $$$\",
961\"$$$$ ###.########@O $$$\",
962\"$$$$ +#+O#####@O $$$$$\",
963\"$$$$$ #.###@O $$$$$$\",
964\"$$$$$ .O@O $$ .. $$$$$\",
965\"$$$$$ .. $$$$ .oo. $$$$\",
966\"$$$$$$ $$$$$ oo $$$\",
967\"$$$$$$$$$$$$$$$ Oo $$$$$\",
968\"$$$$$$$$$$$$$$ oOOX $$$$\",
969\"$$$$$$$$$$$$$$ ++++ $$$$\",
970\"$$$$$$$$$$$$$ O@@@@O $$$\",
971\"$$$$$$$$$$$$$ $$$\",
972\"$$$$$$$$$$$$$$$$$$$$$$$$\"};")
973 "MH send letter icon.")
974
975;; This is the same icon as `mh-xemacs-toolbar-mime-save-parts-icon',
976;; so there is no point in duplicating it.
977(defconst mh-xemacs-toolbar-compose-insertion-icon
978 mh-xemacs-toolbar-mime-save-parts-icon
979 "MH compose insertion icon.")
980
981;; Derived from lisp/toolbar/spell.xpm
982(defconst mh-xemacs-toolbar-ispell-message-icon
983 (mh-funcall-if-exists toolbar-make-button-list
984 "/* XPM */
985static char *magick[] = {
986/* columns rows colors chars-per-pixel */
987\"24 24 5 1\",
988\" c Gray0\",
989\". c #41415b5b3939\",
990\"X c #4c2f6b4e42d1\",
991\"o c #5fe086865454\",
992\"O c Gray75 s backgroundToolBarColor\",
993/* pixels */
994\"OOOOOOOOOOOOOOOOOOOOOOOO\",
995\"OOOOOOOOOOOOOOOOOOOOOOOO\",
996\"OOOOOOOOOOOOOOOOOOOOOOOO\",
997\"OOOOOOOOOOOOOOOOOOOOOOOO\",
998\"OOOO OO OOO OOOOOOOO\",
999\"OOO OO O OO O OO OOOOOOO\",
1000\"OOO O OO OOOOOOOOOO\",
1001\"OOO OO O OO O OO OOOOOOO\",
1002\"OOO OO O OOO OOOO OO\",
1003\"OOOOOOOOOOOOOOOOOOO OOO\",
1004\"OOOOOOOOOOO OOOOO OOOO\",
1005\"OOOOOOOOOOO X OOO . OOOO\",
1006\"OOOOOOOOOOOO X O X OOOOO\",
1007\"OOOOOOOOOOOO Xo o. OOOOO\",
1008\"OOOOOOOOOOOOO XoX OOOOOO\",
1009\"OOOOOOOOOOOOO Xo. OOOOOO\",
1010\"OOOOOOOOOOOOOO X OOOOOOO\",
1011\"OOOOOOOOOOOOOO X OOOOOOO\",
1012\"OOOOOOOOOOOOOOO OOOOOOOO\",
1013\"OOOOOOOOOOOOOOOOOOOOOOOO\",
1014\"OOOOOOOOOOOOOOOOOOOOOOOO\",
1015\"OOOOOOOOOOOOOOOOOOOOOOOO\",
1016\"OOOOOOOOOOOOOOOOOOOOOOOO\",
1017\"OOOOOOOOOOOOOOOOOOOOOOOO\"};")
1018 "MH Ispell message icon.")
1019
1020;; Derived from lisp/toolbar/save.xpm
1021(defconst mh-xemacs-toolbar-save-buffer-icon
1022 (mh-funcall-if-exists toolbar-make-button-list
1023 "/* XPM */
1024static char *magick[] = {
1025/* columns rows colors chars-per-pixel */
1026\"24 24 5 1\",
1027\" c #01be01be01be\",
1028\". c #62dd62dd62dd\",
1029\"X c Gray62\",
1030\"o c #e625e625e625\",
1031\"O c Gray75 s backgroundToolBarColor\",
1032/* pixels */
1033\"OOOOOOOOOOOOOOOOOOOOOOOO\",
1034\"OOOOOOOOOOOOOOOOOOOOOOOO\",
1035\"OOOOOOOOOOOOOOOOOOOOOOOO\",
1036\"OOOOOOOOOOOOOOOOOOOOOOOO\",
1037\"OOOOOOOOOOOOO OOOOOOOOO\",
1038\"OOOOOOOOOOO X. OOOOOOOO\",
1039\"OOOOOOOOO oXoX OOOOOOOO\",
1040\"OOOOOOO oXoooXX OOOOOOO\",
1041\"OOOOO oXoooooo. OOOOOOO\",
1042\"OOO XoooooooooX OOOOOO\",
1043\"OO XooooooooooooX OOOOOO\",
1044\"OO .XoooooooooooX. OOOOO\",
1045\"OOO XooooooooooXXX OOOOO\",
1046\"OOO .XoooooooXX..X. OOOO\",
1047\"OOOO XoooooXX...X.X OOOO\",
1048\"OOOO .XooXX.Xoo.X.X. OOO\",
1049\"OOOOO XXX.oooooX.X. OOO\",
1050\"OOOOO .XXoo.ooooXX OOO\",
1051\"OOOOOO XX.o XooX. OOOOO\",
1052\"OOOOOO .XXooXoX OOOOOOO\",
1053\"OOOOOOO .X.oX OOOOOOOOO\",
1054\"OOOOOOOO OOOOOOOOOOO\",
1055\"OOOOOOOOOOOOOOOOOOOOOOOO\",
1056\"OOOOOOOOOOOOOOOOOOOOOOOO\"};")
1057 "MH save buffer icon.")
1058
1059;; Derived from lisp/toolbar/cut.xpm
1060(defconst mh-xemacs-toolbar-kill-region-icon
1061 (mh-funcall-if-exists toolbar-make-button-list
1062 "/* XPM */
1063static char *magick[] = {
1064/* columns rows colors chars-per-pixel */
1065\"24 24 2 1\",
1066\" c Gray0\",
1067\". c Gray75 s backgroundToolBarColor\",
1068/* pixels */
1069\"........................\",
1070\"........................\",
1071\"........................\",
1072\"........................\",
1073\"........................\",
1074\".................. .....\",
1075\"................ ......\",
1076\"............... .......\",
1077\".............. ........\",
1078\"............. .........\",
1079\".... .... ..... ..\",
1080\"... ... .. ... ....\",
1081\"... ... ......\",
1082\".... ... .........\",
1083\".......... ............\",
1084\"......... ............\",
1085\"........ .. ............\",
1086\"....... ... ............\",
1087\"....... .. .............\",
1088\"....... ..............\",
1089\"........................\",
1090\"........................\",
1091\"........................\",
1092\"........................\"};")
1093 "MH kill region icon.")
1094
1095;; Derived from lisp/toolbar/copy.xpm
1096(defconst mh-xemacs-toolbar-kill-ring-save-icon
1097 (mh-funcall-if-exists toolbar-make-button-list
1098 "/* XPM */
1099static char *magick[] = {
1100/* columns rows colors chars-per-pixel */
1101\"24 24 7 1\",
1102\" c Gray0\",
1103\". c #424242423a3a\",
1104\"X c #68e968e96363\",
1105\"o c #a8b1a8b1992b\",
1106\"O c #d3d3d3d3bdbd\",
1107\"+ c #e419e419cd6b\",
1108\"@ c Gray75 s backgroundToolBarColor\",
1109/* pixels */
1110\"@@@@@@@@@@@@@@@@@@@@@@@@\",
1111\"@@@@@@@@@@@@@@@@@@@@@@@@\",
1112\"@@@@@@@@@@@@@@@@@@@@@@@@\",
1113\"@@@@@@@@@@@@@@@@@@@@@@@@\",
1114\"@@@@@@@@@@@@@@@@@@@@@@@@\",
1115\"@@@@@@@@ @@@@@@@@@@@@@@\",
1116\"@@@@@@ Oo @@@@@@@@@@@@@\",
1117\"@@@@ .ooOO @@@@ @@@@@@@\",
1118\"@@@@ +XoOOo @ Oo @@@@@@\",
1119\"@@@@ +.oO++ .ooOO @@@@@@\",
1120\"@@@@ XoO+++ +XoOOo @@@@@\",
1121\"@@@@ oOO+++ +.oO++ @@@@@\",
1122\"@@@@ oO++++ XoOO++o @@@@\",
1123\"@@@@@ +++++ oOO++++o @@@\",
1124\"@@@@@ o++++ oO++++++ @@@\",
1125\"@@@@@@ ++o +++++++o @@\",
1126\"@@@@@@ o @@ o++++o @@@\",
1127\"@@@@@@@ @@@@@ ++o @@@@@\",
1128\"@@@@@@@@@@ @@ o @@@@@@@\",
1129\"@@@@@@@ @@ @@@@@@@@@\",
1130\"@@@@@@@ @@@@@@@@@@@@\",
1131\"@@@@@@@@@@ @@@@@@@@@@@@@\",
1132\"@@@@@@@@@@@@@@@@@@@@@@@@\",
1133\"@@@@@@@@@@@@@@@@@@@@@@@@\"};")
1134 "MH kill ring save icon.")
1135
1136;; Derived from lisp/toolbar/paste.xpm
1137(defconst mh-xemacs-toolbar-yank-icon
1138 (mh-funcall-if-exists toolbar-make-button-list
1139 "/* XPM */
1140static char *magick[] = {
1141/* columns rows colors chars-per-pixel */
1142\"24 24 5 1\",
1143\" c Gray0\",
1144\". c #62ee62ee62ee\",
1145\"X c Gray68\",
1146\"o c Gray82\",
1147\"O c Gray75 s backgroundToolBarColor\",
1148/* pixels */
1149\"OOOOOOOOOOOOOOOOOOOOOOOO\",
1150\"OOOOOOOOOOOOOOOOOOOOOOOO\",
1151\"OOOOOOOOOOOOOOOOOOOOOOOO\",
1152\"OOOOOOOOO OOOOOOOOOOOO\",
1153\"OOOOOOO ooo OOOOOO OOOO\",
1154\"OOOOO ooooo OOO OOO\",
1155\"OOO oo. .Xoo OO OOO\",
1156\"OO ooo.oX..oo OOOOO OOOO\",
1157\"OO ooo.X..oooo OOOOOOOOO\",
1158\"OOO oo..Xooooo O OOOOOO\",
1159\"OOO oooooooooo oX OOOOO\",
1160\"OOOO ooooooo XXoo OOOOO\",
1161\"OOOO ooooooo o.XooX OOOO\",
1162\"OOOOO oooooo o.Xooo OOOO\",
1163\"OOOOO oooooo .XooooX OOO\",
1164\"OOOOOO ooooX XooooooX OO\",
1165\"OOOOOO XXOXX Xooooooo OO\",
1166\"OOOOOOO XXXX oooooooX O\",
1167\"OOOOOOO XX O XooooX OO\",
1168\"OOOOOOOO OOOO ooX OOOO\",
1169\"OOOOOOOOOOOOOO X OOOOOO\",
1170\"OOOOOOOOOOOOOOO OOOOOOOO\",
1171\"OOOOOOOOOOOOOOOOOOOOOOOO\",
1172\"OOOOOOOOOOOOOOOOOOOOOOOO\"};")
1173 "MH yank icon.")
1174
1175;; This is the same icon as `mh-xemacs-toolbar-delete-msg-icon'
1176;; so there is no point in duplicating it here.
1177(defconst mh-xemacs-toolbar-fully-kill-draft-icon
1178 mh-xemacs-toolbar-delete-msg-icon
1179 "MH fully kill draft icon.")
1180
1181;; Derived from lisp/toolbar/preferences.xpm
1182(defconst mh-xemacs-toolbar-preferences-icon
1183 (mh-funcall-if-exists toolbar-make-button-list
1184 "/* XPM */
1185static char * preferences_xpm[] = {
1186\"24 24 8 1\",
1187\" c Gray75 s backgroundToolBarColor\",
1188\". c #000000\",
1189\"+ c #E1E0E0\",
1190\"@ c #D7C99B\",
1191\"# c #9A6C4E\",
1192\"$ c #A4A199\",
1193\"% c #858579\",
1194\"& c #AD8E30\",
1195\" \",
1196\" \",
1197\" \",
1198\" .. \",
1199\" ..++. . \",
1200\" ..++++. .@. \",
1201\" ...+++++++. .@#. \",
1202\" ..++++++++++. .@#. \",
1203\" .++++++#++++++.@#. \",
1204\" .+++++#++++++.@#. \",
1205\" .++#+#+++++.@#. \",
1206\" .++#$#++++.@#.+. \",
1207\" .++##+++.@#.++@. \",
1208\" .++++++.@#.+++@%. \",
1209\" .++++&+..@$$$$%. \",
1210\" .++++..$$$$$$@. \",
1211\" .+$%%$+++++.. \",
1212\" .+++++++++. \",
1213\" .++++++.. \",
1214\" .++++@. \",
1215\" .++.. \",
1216\" .. \",
1217\" \",
1218\" \"};")
1219 "MH preferences icon.")
1220
1221;; This is the same icon as `mh-xemacs-toolbar-help-icon' so there is
1222;; no point in duplicating it here.
1223(defconst mh-xemacs-toolbar-letter-help-icon
1224 mh-xemacs-toolbar-help-icon
1225 "MH letter help icon.")
1226
1227;; Derived from mh-e/widen.xpm
1228(defconst mh-xemacs-toolbar-widen-icon
1229 (mh-funcall-if-exists toolbar-make-button-list
1230 "/* XPM */
1231static char * widen_xpm[] = {
1232/* columns rows colors chars-per-pixel */
1233\"24 24 3 1\",
1234\" c Gray75 s backgroundToolBarColor\",
1235\". c #8d4d97577838\",
1236\"X c black\",
1237/* pixels */
1238\" \",
1239\" \",
1240\" \",
1241\" . . \",
1242\" . . \",
1243\" . . \",
1244\" . . \",
1245\" . . \",
1246\" . XX XX . \",
1247\" . XX XX . \",
1248\" . XX XX . \",
1249\" .XXXXXXXX XXXXXXXX. \",
1250\" .XXXXXXXX XXXXXXXX. \",
1251\" . XX XX . \",
1252\" . XX XX . \",
1253\" . XX XX . \",
1254\" . . \",
1255\" . . \",
1256\" . . \",
1257\" . . \",
1258\" . . \",
1259\" \",
1260\" \",
1261\" \"};")
1262 "MH widen icon.")
1263
1264(defvar mh-xemacs-icon-map
1265 '((mail . mh-xemacs-toolbar-inc-folder-icon)
1266 (attach . mh-xemacs-toolbar-mime-save-parts-icon)
1267 (right_arrow . mh-xemacs-toolbar-next-undeleted-msg-icon)
1268 (page-down . mh-xemacs-toolbar-page-msg-icon)
1269 (left_arrow . mh-xemacs-toolbar-previous-undeleted-msg-icon)
1270 (close . mh-xemacs-toolbar-delete-msg-icon)
1271 (refile . mh-xemacs-toolbar-refile-msg-icon)
1272 (undo . mh-xemacs-toolbar-undo-icon)
1273 (execute . mh-xemacs-toolbar-execute-commands-icon)
1274 (highlight . mh-xemacs-toolbar-toggle-tick-icon)
1275 (show . mh-xemacs-toolbar-toggle-showing-icon)
1276 (reply-from . mh-xemacs-toolbar-reply-from-icon)
1277 (reply-to . mh-xemacs-toolbar-reply-to-icon)
1278 (reply-all . mh-xemacs-toolbar-reply-all-icon)
1279 (mail/reply2 . mh-xemacs-toolbar-reply-icon)
1280 (alias . mh-xemacs-toolbar-alias-grab-from-field-icon)
1281 (mail_compose . mh-xemacs-toolbar-send-icon)
1282 (rescan . mh-xemacs-toolbar-rescan-folder-icon)
1283 (repack . mh-xemacs-toolbar-pack-folder-icon)
1284 (search . mh-xemacs-toolbar-search-icon)
1285 (fld_open . mh-xemacs-toolbar-visit-folder-icon)
1286 (mail_send . mh-xemacs-toolbar-send-letter-icon)
1287 (spell . mh-xemacs-toolbar-ispell-message-icon)
1288 (save . mh-xemacs-toolbar-save-buffer-icon)
1289 (cut . mh-xemacs-toolbar-kill-region-icon)
1290 (copy . mh-xemacs-toolbar-kill-ring-save-icon)
1291 (paste . mh-xemacs-toolbar-yank-icon)
1292 (preferences . mh-xemacs-toolbar-preferences-icon)
1293 (help . mh-xemacs-toolbar-help-icon)
1294 (widen . mh-xemacs-toolbar-widen-icon))
1295 "Map GNU Emacs icon file names to XEmacs image constants.")
1296
1297
1298
1299(provide 'mh-xemacs-icons)
1300
1301;;; Local Variables:
1302;;; indent-tabs-mode: nil
1303;;; sentence-end-double-space: nil
1304;;; End:
1305
1306;;; mh-xemacs-icons.el ends here
diff --git a/lisp/toolbar/highlight.pbm b/lisp/toolbar/highlight.pbm
new file mode 100644
index 00000000000..48b499325b1
--- /dev/null
+++ b/lisp/toolbar/highlight.pbm
@@ -0,0 +1,3 @@
1P4
224 24
3/G#Q((?(??(?(?( \ No newline at end of file
diff --git a/lisp/toolbar/highlight.xpm b/lisp/toolbar/highlight.xpm
new file mode 100644
index 00000000000..1844128f02f
--- /dev/null
+++ b/lisp/toolbar/highlight.xpm
@@ -0,0 +1,33 @@
1/* XPM */
2static char * highlight_xpm[] = {
3/* columns rows colors chars-per-pixel */
4"24 24 4 1",
5" c None",
6". c black",
7"X c #828282827474",
8"o c #dd00df007e00",
9/* pixels */
10" ..... ",
11" ..XXX.. ",
12" .XXXXX. ",
13" .XXXXX.. ",
14" .XXXXX. ",
15" .XXXXX. ",
16" .XXXXX. ",
17" .ooXX. ",
18" ..ooo. ",
19" oooo .... ",
20"oo.ooo....oo ... ",
21"o.o.ooo.oo.o.ooo.o ",
22".ooo.oo.oo.o.ooooo ",
23".ooo.oo.oo.o.ooooo ",
24".ooo.oo...oo.ooooo ",
25".....oo.oo.o.ooooo ",
26".ooo.oo.oo.o.ooooo ",
27".ooo.oo.oo.o.ooo.o ",
28". oo.o....ooo...o ",
29" oo oooo ",
30" ",
31" ",
32" ",
33" "};