aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaroly Lorentey2004-08-19 15:05:01 +0000
committerKaroly Lorentey2004-08-19 15:05:01 +0000
commitbda56b550fc7fffcec4d94e2cafc3793d0cec624 (patch)
tree6fff2c4bd2b46711c2527c403b95a621b7e9bf5e
parentccc84c2458c0a2e4e2ca62fa4c43527902f7e101 (diff)
parenteacd5edcd3f50db44271fae73dce8949ceb47ca8 (diff)
downloademacs-bda56b550fc7fffcec4d94e2cafc3793d0cec624.tar.gz
emacs-bda56b550fc7fffcec4d94e2cafc3793d0cec624.zip
Merged in changes from CVS trunk.
Patches applied: * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-489 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-490 Update from CVS: man/fixit.texi (Spelling): Fix typo. * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-491 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-492 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-493 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-494 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-495 Update from CVS: Add missing lisp/mh-e files * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-496 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-497 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-498 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-499 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-500 Update from CVS git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-234
-rw-r--r--etc/ChangeLog14
-rw-r--r--etc/MH-E-NEWS368
-rw-r--r--etc/NEWS15
-rw-r--r--etc/TUTORIAL.es28
-rw-r--r--leim/quail/georgian.el2
-rw-r--r--lisp/ChangeLog194
-rw-r--r--lisp/battery.el2
-rw-r--r--lisp/cus-start.el3
-rw-r--r--lisp/emacs-lisp/bytecomp.el2
-rw-r--r--lisp/emacs-lisp/copyright.el44
-rw-r--r--lisp/emacs-lisp/lisp-mode.el4
-rw-r--r--lisp/emacs-lisp/re-builder.el30
-rw-r--r--lisp/imenu.el9
-rw-r--r--lisp/isearch.el234
-rw-r--r--lisp/mh-e/ChangeLog2008
-rw-r--r--lisp/mh-e/mh-acros.el143
-rw-r--r--lisp/mh-e/mh-alias.el207
-rw-r--r--lisp/mh-e/mh-comp.el450
-rw-r--r--lisp/mh-e/mh-customize.el2662
-rw-r--r--lisp/mh-e/mh-e.el524
-rw-r--r--lisp/mh-e/mh-funcs.el97
-rw-r--r--lisp/mh-e/mh-gnus.el36
-rw-r--r--lisp/mh-e/mh-identity.el296
-rw-r--r--lisp/mh-e/mh-inc.el8
-rw-r--r--lisp/mh-e/mh-index.el225
-rw-r--r--lisp/mh-e/mh-init.el308
-rw-r--r--lisp/mh-e/mh-junk.el454
-rw-r--r--lisp/mh-e/mh-loaddefs.el513
-rw-r--r--lisp/mh-e/mh-mime.el288
-rw-r--r--lisp/mh-e/mh-pick.el39
-rw-r--r--lisp/mh-e/mh-print.el279
-rw-r--r--lisp/mh-e/mh-seq.el212
-rw-r--r--lisp/mh-e/mh-speed.el33
-rw-r--r--lisp/mh-e/mh-utils.el743
-rw-r--r--lisp/progmodes/cc-align.el35
-rw-r--r--lisp/progmodes/cc-cmds.el9
-rw-r--r--lisp/progmodes/cc-defs.el215
-rw-r--r--lisp/progmodes/cc-engine.el290
-rw-r--r--lisp/progmodes/cc-fonts.el114
-rw-r--r--lisp/progmodes/cc-langs.el6
-rw-r--r--lisp/progmodes/cc-styles.el2
-rw-r--r--lisp/progmodes/cc-vars.el146
-rw-r--r--lisp/progmodes/compile.el4
-rw-r--r--lisp/progmodes/sh-script.el7
-rw-r--r--lisp/progmodes/which-func.el2
-rw-r--r--lisp/ps-mule.el2
-rw-r--r--lisp/speedbar.el85
-rw-r--r--lisp/term.el9
-rw-r--r--lisp/term/x-win.el3
-rw-r--r--lispref/ChangeLog6
-rw-r--r--lispref/processes.texi27
-rw-r--r--man/ChangeLog37
-rw-r--r--man/Makefile.in4
-rw-r--r--man/cc-mode.texi129
-rw-r--r--man/custom.texi43
-rw-r--r--man/emacs.texi4
-rw-r--r--man/fixit.texi2
-rw-r--r--man/help.texi2
-rw-r--r--man/killing.texi7
-rw-r--r--man/kmacro.texi10
-rw-r--r--man/mark.texi16
-rw-r--r--man/regs.texi6
-rw-r--r--msdos/ChangeLog6
-rw-r--r--msdos/sedleim.inp1
-rw-r--r--src/ChangeLog41
-rw-r--r--src/buffer.c2
-rw-r--r--src/fileio.c5
-rw-r--r--src/intervals.c4
-rw-r--r--src/minibuf.c5
-rw-r--r--src/process.c69
-rw-r--r--src/sysdep.c23
-rw-r--r--src/xfaces.c5
72 files changed, 8145 insertions, 3712 deletions
diff --git a/etc/ChangeLog b/etc/ChangeLog
index c26a8a7d786..3c6ac1e165b 100644
--- a/etc/ChangeLog
+++ b/etc/ChangeLog
@@ -1,3 +1,17 @@
12004-08-15 Bill Wohler <wohler@newt.com>
2
3 * NEWS, MH-E-NEWS: Upgraded to MH-E version 7.4.80.
4
52004-08-14 Romain Francoise <romain@orebokech.com>
6
7 * NEWS: Mention the thumbs.el package.
8
92004-08-14 Eric Hanchrow <offby1@blarg.net>
10
11 * TUTORIAL.es: Replace actual whitespace with the magic string
12 that causes help-with-tutorial to automatically insert the correct
13 amount.
14
12004-08-10 Steven Tamm <steventamm@mac.com> 152004-08-10 Steven Tamm <steventamm@mac.com>
2 16
3 * PROBLEMS: Remove description of Mac OS version upgrade 17 * PROBLEMS: Remove description of Mac OS version upgrade
diff --git a/etc/MH-E-NEWS b/etc/MH-E-NEWS
index 5bea16d91ba..264acf8ead1 100644
--- a/etc/MH-E-NEWS
+++ b/etc/MH-E-NEWS
@@ -6,6 +6,372 @@ Copying and distribution of this file, with or without modification,
6are permitted in any medium without royalty provided the copyright 6are permitted in any medium without royalty provided the copyright
7notice and this notice are preserved. 7notice and this notice are preserved.
8 8
9* Changes in MH-E 7.4.80
10
11Version 7.4.80 now supports GNU mailutils, S/MIME, picons,
12which-func-mode, has an improved interface for hiding header fields,
13improves upon the MH variant detection, and contains many bug fixes.
14Those of you familiar with the GNU version numbering schemes will
15recognize this as an alpha release. This does not reflect on the
16quality of this release which is as high as it has always been.
17Although we are not ready to release 8.0, we want you to have access
18to the work that has been hiding in CVS. At the same time we want to
19make it clear that there are incompatible changes with previous
20versions.
21
22We are planning to release the long-awaited manual update synchronized
23with version 8.0. We are using documentation from the manual in the
24docstrings which is hoped to make "C-h f (describe-function)" really
25useful and create a seamless experience when switching back and forth
26between the manual and the docstrings. This has been done in about
27half of the variables and functions in this version.
28
29The writing of the manual has revealed a few inconsistencies in the
30software whose fixes have resulted in incompatible changes, and there
31may well be more. So, unlike version 7 which was chock full of new
32features, version 8's strengths will include complete documentation
33and higher quality.
34
35** New Features in MH-E 7.4.80
36
37*** GNU mailutils Support
38
39MH-E now supports GNU mailutils 0.4 and higher versions.
40
41*** S/MIME Support
42
43MH-E now supports S/MIME using Gnus 5.10.6 or higher.
44
45*** Picon Support
46
47In addition to the other methods of displaying an icon for the sender
48of a message, MH-E can now display images from a picon directory. The
49directory search path is found in the `mh-picon-directory-list'
50variable. More documentation is found in the "facedb" sections in the
51xfaces man page. [NOTE: need to make mh-picon-directory-list an option
52and add xfaces facedb documentation to it.]
53
54*** X-Image-URL Updates
55
56Now support the use of `curl' and `fetch' as alternatives to `wget' to
57obtain the image. The display of images are controlled with the
58`mh-show-use-xface-flag' option while the `mh-fetch-x-image-url'
59option controls how the images are fetched.
60
61WARNING: There are security concerns with this feature. Please read
62the documentation for these options carefully before changing the
63default.
64
65*** Updates to mh-identity-list
66
67Note that the field names found in `mh-identity-list' that refer to
68the fields in `mh-identity-handlers' have changed in an incompatible
69way from 7.4.4. In general, the symbolic names now have a ":" prefix
70to avoid collisions with header fields. Before starting Emacs, edit
71your .emacs and insert ":" before "signature" if you have defined it.
72
73You can change your attribution in replies with the new "Attribution
74Verb" field, and you can set your default GPG user ID with the "GPG
75key ID" field.
76
77Signatures can now be read from the `mh-signature-file-name' variable,
78or come from a function, in addition to a named file. If you write
79your own function, variables that you can use include
80`mh-signature-separator-regexp', `mh-signature-separator',
81and `mh-signature-separator-p'.
82
83The handling of these fields has been moved into a new
84`mh-identity-handlers' option, an alist of fields (strings) and
85handlers (functions). Strings are lowercase. Use ":signature" for
86Signature and ":pgg-default-user-id" for GPG Key ID. The function
87associated with the string "default" is used if no other functions are
88appropriate. For this reason, don't name a header field "Default".
89
90If you point your signature at a vCard file with a vcf suffix, then it
91will be incorporated as a vCard body part (closes SF #802723).
92
93*** Catchup Command
94
95There is a new "F c (mh-catchup)" command that marks all unread
96messages in the current folder as read.
97
98*** Change Content-Type Renderer on the Fly in MH-Show Buffer
99
100This has been implemented by adding the key binding "K e
101(mh-display-with-external-viewer)". For inline text/html parts,
102buttons aren't displayed by default. In that case use "K t
103(mh-toggle-mime-buttons)" to display the button before viewing it with
104an external browser (closes SF #839318).
105
106*** Use which-func-mode to Display Folder in Index Mode
107
108Turning on `which-func-mode' displays the folder name of the message
109under the cursor in index folders (closes SF #855520).
110
111*** Render Signature and vCard in Italics
112
113This has been implemented. Use `mh-show-signature-face' to customize
114the face used (closes SF #802722).
115
116*** New Print Map
117
118There is now a keymap for the printing functions whose prefix is "P".
119The command "l (mh-print-msg)" has been replaced with "P l". Other new
120functions in this keymap include:
121
122 P A mh-ps-print-toggle-mime
123 P C mh-ps-print-toggle-color
124 P F mh-ps-print-toggle-faces
125 P M mh-ps-print-toggle-mime
126 P f mh-ps-print-msg-file
127 P l mh-print-msg
128 P p mh-ps-print-msg
129 P s mh-ps-print-msg-show
130
131*** Draft Buffer Keymap Changes
132
133The keymap in the draft buffer has been modified slightly. The old
134anonymous ftp and tar composition commands have been reinstated and
135letter signing and encrypting keymaps have been added.
136
137The type of signing or encryption has been generalized so the method
138is now an option rather than a part of the function's name. The option
139is `mh-mml-method-default' and choices include PGP (MIME), PGP,
140S/MIME, or none.
141
142Key 7.4.4 7.4.80
143
144C-c RET C-e mh-mml-secure-message-encrypt-pgpmime
145 mh-mml-secure-message-encrypt
146C-c RET C-s mh-mml-secure-message-sign-pgpmime
147 -
148C-c RET C-g - mh-mhn-compose-anon-ftp
149C-c RET C-n - mh-mml-unsecure-message
150C-c RET C-s - mh-mml-secure-message-sign
151C-c RET C-t - mh-mhn-compose-external-compressed-tar
152C-c RET C-s mh-mml-secure-message-sign-pgpmime
153 mh-mml-secure-message-sign
154C-c RET C-x - mh-mhn-compose-external-type
155C-c RET e mh-mml-secure-message-encrypt-pgpmime
156 Prefix Command
157C-c RET e e - mh-mml-secure-message-encrypt
158C-c RET e s - mh-mml-secure-message-signencrypt
159C-c RET g - mh-mhn-compose-anon-ftp
160C-c RET n - mh-mml-unsecure-message
161C-c RET s mh-mml-secure-message-sign-pgpmime
162 Prefix Command
163C-c RET s e - mh-mml-secure-message-signencrypt
164C-c RET s s - mh-mml-secure-message-sign
165C-c RET t - mh-mhn-compose-external-compressed-tar
166C-c RET x - mh-mhn-compose-external-type
167
168*** Speedbar: Highlight Folders With Unseen
169
170The speedbar now renders the folders with unseen messages in boldface
171which makes them easier to identify (closes SF #623369).
172
173*** Quick Key Help
174
175The "? (mh-help)" function now displays the help in its own buffer
176called *MH-E Help* (closes SF #493740 and SF #656631).
177
178*** New Startup File mh-e-autoloads.el
179
180If you are installing MH-E yourself, then you can replace any
181autoloads you may have with "(require 'mh-e-autoloads.el)". See the
182README for details.
183
184*** Glimpse Support Removed
185
186Since glimpse isn't free, we cannot mention it. Glimpse has been
187removed from the option `mh-indexer-choices' (closes SF #831276).
188
189*** mh-msg-is-in-seq Update
190
191Can now specify an alternate message number to "S s
192(mh-msg-is-in-seq)" with a prefix argument.
193
194** New Variables in MH-E 7.4.80
195
196Variables that have been added to MH-E that have not been discussed
197elsewhere are listed here.
198
199*** mail-citation-hook
200
201Hook for modifying a citation just inserted in the mail buffer.
202
203*** mh-alias-reloaded-hook
204
205Invoked by `mh-alias-reload' after reloading aliases.
206
207*** mh-auto-fields-prompt-flag
208
209Non-nil means to prompt before sending if fields in
210`mh-auto-fields-list' are inserted.
211
212*** mh-default-folder-for-message-function
213
214Function to select a default folder for refiling or `Fcc'.
215
216*** mh-forward-hook
217
218Invoked on the forwarded letter by "f (mh-forward)".
219
220*** mh-invisible-header-fields-default
221
222List of hidden header fields. The header fields listed in this option
223are hidden, although you can check off any field that you would like
224to see. Header fields that you would like to hide that aren't listed
225can be added to the `mh-invisible-header-fields' option (closes SF
226#752045).
227
228The option `mh-visible-header-fields' has been deleted.
229
230*** mh-junk-background
231
232If on, spam programs are run in background. This used to be the
233default behavior but this could overwhelm a system if many messages
234were black- or whitelisted at once. The spam programs are now run in
235the foreground, but this option can be used to put them back in the
236background.
237
238*** mh-signature-separator-flag
239
240Non-nil means a signature separator should be inserted. It is not
241recommended that you change this option since various mail user
242agents, including MH-E, use the separator to present the signature
243differently, and to suppress the signature when replying or yanking a
244letter into a draft.
245
246*** mh-variant
247
248Specifies the variant used by MH-E. The default setting of this option
249is `Auto-detect' which means that MH-E will automatically choose the
250first of nmh, MH, or GNU mailutils that it finds in the directories
251listed in `mh-path', `mh-sys-path', and `exec-path'. If, for example,
252you have both nmh and mailutils installed and `mh-variant-in-use' was
253initialized to nmh but you want to use mailutils, then you can set
254this option to `mailutils'.
255
256When this variable is changed, MH-E resets `mh-progs', `mh-lib',
257`mh-lib-progs', `mh-flists-present-flag', and `mh-variant-in-use'
258accordingly.
259
260If you've set these variables in your .emacs, it is strongly suggested
261that you comment them out. The MH detection code has been completely
262rewritten and it is very likely that you no longer to set them and
263their setting may confuse other MH-E settings.
264
265** Variables Deleted in MH-E
266
267Variables that have been removed from MH-E that have not been
268discussed elsewhere are listed here.
269
270*** mh-alias-system-aliases
271
272System definitions should not be a user option.
273
274*** mh-junk-mail-folder
275
276Since this variable can accept values other than folder names, it was
277renamed to `mh-junk-disposition' to more accurately reflect the content.
278
279** Bug Fixes in MH-E 7.4.80
280
281Many bugs were fixed in this version that aren't listed below.
282
283*** mh-extract-rejected-mail Can't Do MIME (and Other Formats)
284
285Now handles qmail and exim bounces (addresses SF #404965).
286
287*** mh-rmail Hangs in XEmacs
288
289We've determined that MH-E is incompatible with some versions of
290XEmacs (21.5.9-21.5.16). More recent versions work fine. If you think
291our list is too broad, please let us know which version of XEmacs you
292are using (closes SF #644321).
293
294*** Inconsistent Prompts
295
296Prompt formats are now consistent throughout the application (closes
297SF #730470).
298
299*** Empty Shell Comments Confuse mh-mhn-directive-present-p
300
301If you had a string that matched the regexp "^# $" in your draft, it
302would cause an error. This has been fixed (closes SF #762458).
303
304*** Quote Hashes When mhbuild Directives Used
305
306A related bug, if you had empty shell comments but inserted your own
307directives, you'd get another error from mhbuild. This has been fixed
308by quoting the hash ("^# $") like this "##" before submitting to
309mhbuild (closes SF #762464).
310
311*** Inconsistent Usage in Scan Formatting Variables
312
313The variables:
314
315 mh-note-cur
316 mh-note-deleted
317 mh-note-dist
318 mh-note-forw
319 mh-note-refiled
320 mh-note-repl
321 mh-note-seq
322
323used to contain strings. Although only the first character was read,
324the entire string would be inserted which may have caused problems.
325These variables have been converted to character constants so that
326only a single character can be inserted into the scan line (closes SF
327#770772).
328
329*** Bad Handling of Aliases That Conflict With Local User Names
330
331If a user name existed both locally and in the aliases file, the local
332user would be flashed, but the alias would be used when sending. This
333has been fixed so that the user name that is flashed is the same as
334the name that is sent (closes SF #772595).
335
336*** Args out of range
337
338In rare and non-reproducible circumstances, compilation sometimes
339threw an "Args out of range" error. Nonetheless, this has been fixed
340(closes SF #806577).
341
342*** mh-forward hard-codes '-mime' Switch on nmh
343
344Added new option `mh-compose-forward-as-mime-flag' that controls whether
345messages are forwarded as MIME attachments (closes SF #827203).
346
347*** Not Re-prompted to Sign After Pass Phrase Typo
348
349If there were errors when sending a signed message (like getting the
350pass phrase wrong), the MML markup remained in the draft buffer. The
351draft buffer is now restored if there is an error (closes SF #839303).
352
353*** Font-lock Gets Confused in MH-Letter Buffer
354
355If a user manually moved the cursor to the end of the header field
356separator line (by mouse click or keyboard navigation) and hit Enter
357to start typing their message, any line in the body with a colon would
358be fontified with a gray background. This has been fixed (closes SF
359#855479).
360
361*** mh-refile-msg Fails to Suggest Folder for Empty Message
362
363If you received a message with an empty body from someone who is
364listed in your aliases file, "o (mh-refile-msg)" failed to suggest the
365correct folder. This has been fixed (closes SF #917096).
366
367*** Error Visiting Folder With no Unseen Messages
368
369If you visited a folder without unseen messages and the option "flist:
370-noshowzero" is present in your ~/.mh_profile, you'd get an error. This
371has been fixed (closes SF #933954).
372
373
374
9* Changes in MH-E 7.4.4 375* Changes in MH-E 7.4.4
10 376
11Version 7.4.4 addresses programmatic issues from the FSF and prepares 377Version 7.4.4 addresses programmatic issues from the FSF and prepares
@@ -18,7 +384,7 @@ code moved here from desktop.el.
18 384
19* Changes in MH-E 7.4.3 385* Changes in MH-E 7.4.3
20 386
21Version 7.4.3 fixes the problem where mh-identity-list was not getting 387Version 7.4.3 fixes the problem where `mh-identity-list' was not getting
22set from .emacs. 388set from .emacs.
23 389
24* Changes in MH-E 7.4.2 390* Changes in MH-E 7.4.2
diff --git a/etc/NEWS b/etc/NEWS
index 2d8b10e81ec..e966270f4bb 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -658,7 +658,7 @@ You can now put the init files .emacs and .emacs_SHELL under
658 658
659** MH-E changes. 659** MH-E changes.
660 660
661Upgraded to MH-E version 7.4.4. There have been major changes since 661Upgraded to MH-E version 7.4.80. There have been major changes since
662version 5.0.2; see MH-E-NEWS for details. 662version 5.0.2; see MH-E-NEWS for details.
663 663
664+++ 664+++
@@ -1966,9 +1966,12 @@ source files. See the Flymake's Info manual for more details.
1966of hierarchical data as an outline. For example, the tree-widget is 1966of hierarchical data as an outline. For example, the tree-widget is
1967well suited to display a hierarchy of directories and files. 1967well suited to display a hierarchy of directories and files.
1968 1968
1969** The wdired.el package allows you to use normal editing commands on dired 1969** The wdired.el package allows you to use normal editing commands on Dired
1970buffers to change filenames, permissions, etc... 1970buffers to change filenames, permissions, etc...
1971 1971
1972** The thumbs.el package allows you to preview image files as thumbnails
1973and can be invoked from a Dired buffer.
1974
1972** The new python.el package is used to edit Python and Jython programs. 1975** The new python.el package is used to edit Python and Jython programs.
1973 1976
1974** The URL package (which had been part of W3) is now part of Emacs. 1977** The URL package (which had been part of W3) is now part of Emacs.
@@ -3268,7 +3271,13 @@ and modify elements on this property list.
3268The new low-level functions process-plist and set-process-plist are 3271The new low-level functions process-plist and set-process-plist are
3269used to access and replace the entire property list of a process. 3272used to access and replace the entire property list of a process.
3270 3273
3271??? 3274*** Function accept-process-output now has an optional fourth arg
3275`just-this-one'. If non-nil, only output from the specified process
3276is handled, suspending output from other processes. If value is an
3277integer, also inhibit running timers. This feature is generally not
3278recommended, but may be necessary for specific applications, such as
3279speech synthesis.
3280
3272*** Adaptive read buffering of subprocess output. 3281*** Adaptive read buffering of subprocess output.
3273 3282
3274On some systems, when emacs reads the output from a subprocess, the 3283On some systems, when emacs reads the output from a subprocess, the
diff --git a/etc/TUTORIAL.es b/etc/TUTORIAL.es
index 9cd6100e84f..e4850649c7d 100644
--- a/etc/TUTORIAL.es
+++ b/etc/TUTORIAL.es
@@ -18,32 +18,8 @@ ocasión, usaremos las siguientes abreviaturas.
18Nota importante: para terminar la sesión de Emacs teclee C-x C-c (dos 18Nota importante: para terminar la sesión de Emacs teclee C-x C-c (dos
19caracteres). Los caracteres ">>" en el margen izquierdo indican 19caracteres). Los caracteres ">>" en el margen izquierdo indican
20instrucciones para que usted trate de usar un comando. Por ejemplo: 20instrucciones para que usted trate de usar un comando. Por ejemplo:
21 21<<Blank lines inserted around following line by help-with-tutorial>>
22 22[Mitad de página en blanco para propósitos didácticos. El texto continúa abajo]
23
24
25
26
27
28
29
30
31
32
33[Mitad de página en blanco para propósitos didácticos. El texto
34 continúa abajo]
35
36
37
38
39
40
41
42
43
44
45
46
47>> Ahora teclee C-v (ver la próxima pantalla) para desplazarse a la 23>> Ahora teclee C-v (ver la próxima pantalla) para desplazarse a la
48 siguiente pantalla (hágalo manteniendo la tecla control 24 siguiente pantalla (hágalo manteniendo la tecla control
49 oprimida mientras teclea v). Desde ahora debería hacer esto 25 oprimida mientras teclea v). Desde ahora debería hacer esto
diff --git a/leim/quail/georgian.el b/leim/quail/georgian.el
index d823b2c4cd9..9a08ff5ef42 100644
--- a/leim/quail/georgian.el
+++ b/leim/quail/georgian.el
@@ -34,7 +34,7 @@
34(quail-define-package 34(quail-define-package
35 "georgian" "Georgian" "გ" t 35 "georgian" "Georgian" "გ" t
36 "A common Georgian transliteration (using Unicode)" 36 "A common Georgian transliteration (using Unicode)"
37 nil t nil nil nil nil nil nil nil nil t) 37 nil t nil nil t nil nil nil nil nil t)
38 38
39(quail-define-rules 39(quail-define-rules
40 ("a" ?áƒ) 40 ("a" ?áƒ)
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 8321253666a..58ab47fe3f7 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,197 @@
12004-08-17 Luc Teirlinck <teirllm@auburn.edu>
2
3 * emacs-lisp/copyright.el (copyright-update-year): Delete code
4 that replaces 20xy with xy.
5
62004-08-17 John Paul Wallington <jpw@gnu.org>
7
8 * emacs-lisp/re-builder.el (reb-mode-map): Define within defvar.
9 (reb-force-update): Doc fix.
10
112004-08-16 Richard M. Stallman <rms@gnu.org>
12
13 * progmodes/which-func.el (which-func-update-1): Doc fix.
14
15 * progmodes/sh-script.el (sh-set-shell): Use sh-mode-abbrev-table.
16 (sh-mode-abbrev-table): New variable.
17
18 * progmodes/compile.el (compilation-mode): Doc fix.
19
20 * emacs-lisp/lisp-mode.el (eval-last-sexp):
21 Don't cons a new symbol each time.
22 (eval-last-sexp-fake-value): New variable.
23
24 * emacs-lisp/copyright.el (copyright-years-regexp): New variable.
25 (copyright-update-year): Detect continuation of list of years.
26
27 * term.el (term-default-fg-color, term-default-bg-color)
28 (ansi-term-color-vector): Use `unspecified', not nil, as default.
29
30 * imenu.el: Several doc fixes: don't say variables are buffer-local.
31
322004-08-16 Davis Herring <herring@lanl.gov>
33
34 * isearch.el (isearch-string, isearch-message-string, isearch-point)
35 (isearch-success, isearch-forward-flag, isearch-other-end)
36 (isearch-word, isearch-invalid-regexp, isearch-wrapped)
37 (isearch-barrier, isearch-within-brackets)
38 (isearch-case-fold-search): Fix broken `nth'-like calls to `aref'.
39
402004-08-16 Kenichi Handa <handa@m17n.org>
41
42 * ps-mule.el (ps-mule-font-info-database): Fix docstring.
43
442004-08-15 Kenichi Handa <handa@m17n.org>
45
46 * term/x-win.el (x-selection-value): If utf8 was successful but
47 ctext was not, use utf8 string.
48
492004-08-14 Davis Herring <herring@lanl.gov>
50
51 * isearch.el: Remove accidental changes of March 4. Fix backing
52 up when a regexp isearch is made more general. Use symbolic
53 accessor functions for isearch stack frames to make usage clearer.
54 (search-whitespace-regexp): Made groups in documentation shy (as
55 is the group in the default value).
56 (isearch-fallback): New function, addresses problems with regexps
57 liberalized by `\|', adds support for liberalization by `\}' (the
58 general repetition construct), and incorporates behavior for
59 `*'/`?'.
60 (isearch-}-char): New command, calls `isearch-fallback' with
61 arguments appropriate to a typed `}'.
62 (isearch-*-char, isearch-|-char): Now just call `isearch-fallback'
63 appropriately.
64 (isearch-mode-map): Bind `}' to `isearch-}-char'.
65 (isearch-string, isearch-message,string, isearch-point)
66 (isearch-success, isearch-forward-flag, isearch-other-end)
67 (isearch-word, isearch-invalid-regexp, isearch-wrapped)
68 (isearch-barrier, isearch-within-brackets, isearch-case-fold-search):
69 New inline functions to read fields of a stack frame.
70
712004-08-14 Kurt Hornik <Kurt.Hornik@wu-wien.ac.at> (tiny change)
72
73 * battery.el (battery-linux-proc-acpi): Look into battery
74 directories matching the literal string "CMB", too (required for
75 Linux kernel version 2.6.7).
76
772004-08-14 John Paul Wallington <jpw@gnu.org>
78
79 * cus-start.el (read-file-name-completion-ignore-case): Add.
80 (blink-cursor-alist): Change version to "21.4".
81
82 * emacs-lisp/bytecomp.el (forward-word): Allow 0 args.
83
842004-08-11 Daniel Pfeiffer <occitan@esperanto.org>
85
86 * speedbar.el (speedbar-scan-subdirs): New option.
87 (speedbar-file-lists): Don't ignore file-name case on Unix and use
88 dolist.
89 (speedbar-insert-files-at-point): Take an extra argument and use
90 it to optionally find out if a subdir is empty. Also unreadable
91 files don't get expand buttons.
92 (speedbar-directory): New image (unused pixmap already existed).
93 (speedbar-expand-image-button-alist): Use it.
94
952004-08-11 Martin Stjernholm <bug-cc-mode@gnu.org>
96
97 CC Mode update to 5.30.9:
98
99 * progmodes/cc-defs.el, progmodes/cc-vars.el (c-emacs-features):
100 Moved from cc-vars to cc-defs for dependency reasons. Fixed the
101 POSIX char class test to check that it works in
102 `skip-chars-(forward|backward)' too.
103
104 * progmodes/cc-align.el (c-lineup-arglist): Fixed bug when the
105 first argument starts with a special brace list.
106
107 * progmodes/cc-engine.el (c-forward-type): Fixed promotion bug
108 when `c-opt-type-concat-key' is used (i.e. in Pike).
109
110 * progmodes/cc-engine.el (c-looking-at-special-brace-list): Fixed
111 bug when the inner char pair doesn't have paren syntax, i.e. "(<
112 >)".
113
114 * progmodes/cc-align.el (c-lineup-multi-inher): Made it syntactic
115 whitespace safe.
116
117 * progmodes/cc-engine.el (c-guess-basic-syntax): Fixed anchor
118 position for `arglist-intro', `arglist-cont-nonempty' and
119 `arglist-close' when there are two arglist open parens on the same
120 line and there's nothing in front of the first.
121
122 * progmodes/cc-fonts.el (c-basic-matchers-before): Fixed font
123 locking of qualified names in Java, which previously could fontify
124 common indexing expressions in many cases. The standard Java
125 naming conventions are used to tell them apart.
126
127 * progmodes/cc-align.el (c-lineup-whitesmith-in-block): Fixed
128 inconsistency wrt opening parens on the first line inside a paren
129 block.
130
131 * progmodes/cc-defs.el (c-langs-are-parametric): Must be known at
132 compile time for the sake of `c-major-mode-is'.
133
134 (c-mode-is-new-awk-p): Made it a macro to delay expansion of
135 `c-major-mode-is' in the event that this is used inside a
136 `c-lang-defconst'.
137
138 * progmodes/cc-defs.el (c-major-mode-is): Fixed expansion inside
139 `c-lang-defconst' so that it works better with fallback languages.
140
141 * progmodes/cc-defs.el (c-add-language): Fixed a typo that caused
142 it to fail to record the base mode.
143
144 * progmodes/cc-engine.el (c-syntactic-re-search-forward): Fixed
145 bug so that it doesn't go past the closing paren when PAREN-LEVEL
146 is used. Reordered the syntax checks to get more efficient
147 skipping in some situations.
148
149 * progmodes/cc-cmds.el (c-electric-brace): Don't trip up on a line
150 continuation which might precede the newly inserted '{'.
151
152 * progmodes/cc-engine.el (c-syntactic-re-search-forward): Fixed
153 cases where it could loop indefinitely.
154
155 * progmodes/cc-fonts.el (c-font-lock-declarators): Handle array
156 size specs correctly. Only fontify identifiers in front of '('
157 with as functions - don't accept any paren char. Tightened up
158 initializer skipping to stop before function and class blocks.
159
160 * progmodes/cc-engine.el (c-beginning-of-decl-1): Fixed bug where
161 the point could be left directly after an open paren when finding
162 the beginning of the first decl in the block.
163
164 * progmodes/cc-engine.el (c-parse-state): Don't use the syntax
165 table when filtering out legitimate open parens to be recorded.
166 This could cause cache inconsistencies when e.g.
167 `c++-template-syntax-table' was temporarily in use.
168
169 * progmodes/cc-engine.el (c-on-identifier,
170 c-simple-skip-symbol-backward): Small fix for handling "-"
171 correctly in `skip-chars-backward'. Affected the operator lfun
172 syntax in Pike.
173
174 * progmodes/cc-engine.el (c-invalidate-sws-region-after): Fixed
175 bug that could cause an error from `after-change-functions' when
176 the changed region is at bob.
177
1782004-08-11 Alan Mackenzie <bug-cc-mode@gnu.org>
179
180 CC Mode update to 5.30.9:
181
182 * progmodes/cc-cmds.el, progmodes/cc-vars.el: Amend doc(-strings)
183 to say that <TAB> doesn't insert WS into a CPP line.
184 (c-indent-command, c-tab-always-indent): Amend doc strings.
185
186 * progmodes/cc-styles.el, progmodes/cc-engine.el: Add in two
187 checks for user errors, thus eliminating cryptic and unhelpful
188 Emacs error messages. (1) Check the arg to `c-set-style' is a
189 string. (2) Check that settings to `c-offsets-alist' are not
190 spuriously quoted.
191
192 * progmodes/cc-cmds.el: (c-electric-brace): don't delete a comment
193 which precedes the newly inserted `{'.
194
12004-08-10 Michael Albinus <michael.albinus@gmx.de> 1952004-08-10 Michael Albinus <michael.albinus@gmx.de>
2 196
3 Sync with Tramp 2.0.44. 197 Sync with Tramp 2.0.44.
diff --git a/lisp/battery.el b/lisp/battery.el
index 73d78067571..3b44ff891f9 100644
--- a/lisp/battery.el
+++ b/lisp/battery.el
@@ -290,7 +290,7 @@ The following %-sequences are provided:
290 nil t) 290 nil t)
291 (setq low (+ (or low 0) 291 (setq low (+ (or low 0)
292 (string-to-int (match-string 1)))))))) 292 (string-to-int (match-string 1))))))))
293 (directory-files "/proc/acpi/battery/" t "BAT"))) 293 (directory-files "/proc/acpi/battery/" t "\\(BAT\\|CMB\\)")))
294 (and capacity rate 294 (and capacity rate
295 (setq minutes (if (zerop rate) 0 295 (setq minutes (if (zerop rate) 0
296 (floor (* (/ (float (if (string= charging-state 296 (floor (* (/ (float (if (string= charging-state
diff --git a/lisp/cus-start.el b/lisp/cus-start.el
index 5e237cd0db7..c9ce8f8474c 100644
--- a/lisp/cus-start.el
+++ b/lisp/cus-start.el
@@ -121,6 +121,7 @@
121 (const :tag "always" t))) 121 (const :tag "always" t)))
122 ;; fileio.c 122 ;; fileio.c
123 (insert-default-directory minibuffer boolean) 123 (insert-default-directory minibuffer boolean)
124 (read-file-name-completion-ignore-case minibuffer boolean "21.4")
124 ;; fns.c 125 ;; fns.c
125 (use-dialog-box menu boolean "21.1") 126 (use-dialog-box menu boolean "21.1")
126 (use-file-dialog menu boolean "21.4") 127 (use-file-dialog menu boolean "21.4")
@@ -264,7 +265,7 @@
264 :format "%v") 265 :format "%v")
265 (other :tag "Unlimited" t))) 266 (other :tag "Unlimited" t)))
266 (unibyte-display-via-language-environment mule boolean) 267 (unibyte-display-via-language-environment mule boolean)
267 (blink-cursor-alist cursor alist "21.5") 268 (blink-cursor-alist cursor alist "21.4")
268 ;; xfaces.c 269 ;; xfaces.c
269 (scalable-fonts-allowed display boolean) 270 (scalable-fonts-allowed display boolean)
270 ;; xfns.c 271 ;; xfns.c
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index a4ae751cab7..0a12f6fae9f 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -2900,7 +2900,7 @@ If FORM is a lambda or a macro, byte-compile it as a function."
2900(byte-defop-compiler char-after 0-1) 2900(byte-defop-compiler char-after 0-1)
2901(byte-defop-compiler set-buffer 1) 2901(byte-defop-compiler set-buffer 1)
2902;;(byte-defop-compiler set-mark 1) ;; obsolete 2902;;(byte-defop-compiler set-mark 1) ;; obsolete
2903(byte-defop-compiler19 forward-word 1) 2903(byte-defop-compiler19 forward-word 0-1)
2904(byte-defop-compiler19 char-syntax 1) 2904(byte-defop-compiler19 char-syntax 1)
2905(byte-defop-compiler19 nreverse 1) 2905(byte-defop-compiler19 nreverse 1)
2906(byte-defop-compiler19 car-safe 1) 2906(byte-defop-compiler19 car-safe 1)
diff --git a/lisp/emacs-lisp/copyright.el b/lisp/emacs-lisp/copyright.el
index 6a95c60f859..3d160f54606 100644
--- a/lisp/emacs-lisp/copyright.el
+++ b/lisp/emacs-lisp/copyright.el
@@ -54,6 +54,13 @@ The second \\( \\) construct must match the years."
54 :group 'copyright 54 :group 'copyright
55 :type 'regexp) 55 :type 'regexp)
56 56
57(defcustom copyright-years-regexp
58 "\\(\\s *\\)\\([1-9]\\([-0-9, ';/*%#\n\t]\\|\\s<\\|\\s>\\)*[0-9]+\\)"
59 "*Match additional copyright notice years.
60The second \\( \\) construct must match the years."
61 :group 'copyright
62 :type 'regexp)
63
57 64
58(defcustom copyright-query 'function 65(defcustom copyright-query 'function
59 "*If non-nil, ask user before changing copyright. 66 "*If non-nil, ask user before changing copyright.
@@ -77,6 +84,23 @@ When this is `function', only ask when called non-interactively."
77 84
78(defun copyright-update-year (replace noquery) 85(defun copyright-update-year (replace noquery)
79 (when (re-search-forward copyright-regexp (+ (point) copyright-limit) t) 86 (when (re-search-forward copyright-regexp (+ (point) copyright-limit) t)
87 ;; If the years are continued onto multiple lined
88 ;; that are marked as comments, skip to the end of the years anyway.
89 (while (save-excursion
90 (and (eq (following-char) ?,)
91 (progn (forward-char 1) t)
92 (progn (skip-chars-forward " \t") (eolp))
93 comment-start-skip
94 (save-match-data
95 (forward-line 1)
96 (and (looking-at comment-start-skip)
97 (goto-char (match-end 0))))
98 (save-match-data
99 (looking-at copyright-years-regexp))))
100 (forward-line 1)
101 (re-search-forward comment-start-skip)
102 (re-search-forward copyright-years-regexp))
103
80 ;; Note that `current-time-string' isn't locale-sensitive. 104 ;; Note that `current-time-string' isn't locale-sensitive.
81 (setq copyright-current-year (substring (current-time-string) -4)) 105 (setq copyright-current-year (substring (current-time-string) -4))
82 (unless (string= (buffer-substring (- (match-end 2) 2) (match-end 2)) 106 (unless (string= (buffer-substring (- (match-end 2) 2) (match-end 2))
@@ -100,26 +124,6 @@ When this is `function', only ask when called non-interactively."
100 (eq (char-after (+ (point) size -2)) ?-))) 124 (eq (char-after (+ (point) size -2)) ?-)))
101 ;; This is a range so just replace the end part. 125 ;; This is a range so just replace the end part.
102 (delete-char size) 126 (delete-char size)
103 ;; Detect if this is using the following shorthand:
104 ;; (C) 1993, 94, 95, 1998, 2000, 01, 02, 2003
105 (if (and
106 ;; Check that the last year was 4-chars and same century.
107 (eq size -4)
108 (equal (buffer-substring (- (point) 4) (- (point) 2))
109 (substring copyright-current-year 0 2))
110 ;; Check that there are 2-char years as well.
111 (save-excursion
112 (re-search-backward "[^0-9][0-9][0-9][^0-9]"
113 (line-beginning-position) t))
114 ;; Make sure we don't remove the first century marker.
115 (save-excursion
116 (forward-char size)
117 (re-search-backward
118 (concat (buffer-substring (point) (+ (point) 2))
119 "[0-9][0-9]")
120 (line-beginning-position) t)))
121 ;; Remove the century marker of the last entry.
122 (delete-region (- (point) 4) (- (point) 2)))
123 ;; Insert a comma with the preferred number of spaces. 127 ;; Insert a comma with the preferred number of spaces.
124 (insert 128 (insert
125 (save-excursion 129 (save-excursion
diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el
index d471ad79538..df05555ae7b 100644
--- a/lisp/emacs-lisp/lisp-mode.el
+++ b/lisp/emacs-lisp/lisp-mode.el
@@ -555,13 +555,15 @@ With argument, print output into current buffer."
555 )))) 555 ))))
556 556
557 557
558(defvar eval-last-sexp-fake-value (make-symbol "t"))
559
558(defun eval-last-sexp (eval-last-sexp-arg-internal) 560(defun eval-last-sexp (eval-last-sexp-arg-internal)
559 "Evaluate sexp before point; print value in minibuffer. 561 "Evaluate sexp before point; print value in minibuffer.
560Interactively, with prefix argument, print output into current buffer." 562Interactively, with prefix argument, print output into current buffer."
561 (interactive "P") 563 (interactive "P")
562 (if (null eval-expression-debug-on-error) 564 (if (null eval-expression-debug-on-error)
563 (eval-last-sexp-1 eval-last-sexp-arg-internal) 565 (eval-last-sexp-1 eval-last-sexp-arg-internal)
564 (let ((old-value (make-symbol "t")) new-value value) 566 (let ((old-value eval-last-sexp-fake-value) new-value value)
565 (let ((debug-on-error old-value)) 567 (let ((debug-on-error old-value))
566 (setq value (eval-last-sexp-1 eval-last-sexp-arg-internal)) 568 (setq value (eval-last-sexp-1 eval-last-sexp-arg-internal))
567 (setq new-value debug-on-error)) 569 (setq new-value debug-on-error))
diff --git a/lisp/emacs-lisp/re-builder.el b/lisp/emacs-lisp/re-builder.el
index 6eb1ffa2e54..77a12167c30 100644
--- a/lisp/emacs-lisp/re-builder.el
+++ b/lisp/emacs-lisp/re-builder.el
@@ -45,7 +45,7 @@
45;; call `reb-force-update' ("\C-c\C-u") which should reveal the error. 45;; call `reb-force-update' ("\C-c\C-u") which should reveal the error.
46 46
47;; The target buffer can be changed with `reb-change-target-buffer' 47;; The target buffer can be changed with `reb-change-target-buffer'
48;; ("\C-c\C-b"). Changing the target buffer automatically removes 48;; ("\C-c\C-b"). Changing the target buffer automatically removes
49;; the overlays from the old buffer and displays the new one in the 49;; the overlays from the old buffer and displays the new one in the
50;; target window. 50;; target window.
51 51
@@ -229,22 +229,20 @@ Except for Lisp syntax this is the same as `reb-regexp'.")
229 "Buffer to use for the RE Builder.") 229 "Buffer to use for the RE Builder.")
230 230
231;; Define the local "\C-c" keymap 231;; Define the local "\C-c" keymap
232(defvar reb-mode-map nil 232(defvar reb-mode-map
233 (let ((map (make-sparse-keymap)))
234 (define-key map "\C-c\C-c" 'reb-toggle-case)
235 (define-key map "\C-c\C-q" 'reb-quit)
236 (define-key map "\C-c\C-w" 'reb-copy)
237 (define-key map "\C-c\C-s" 'reb-next-match)
238 (define-key map "\C-c\C-r" 'reb-prev-match)
239 (define-key map "\C-c\C-i" 'reb-change-syntax)
240 (define-key map "\C-c\C-e" 'reb-enter-subexp-mode)
241 (define-key map "\C-c\C-b" 'reb-change-target-buffer)
242 (define-key map "\C-c\C-u" 'reb-force-update)
243 map)
233 "Keymap used by the RE Builder.") 244 "Keymap used by the RE Builder.")
234 245
235(if (not reb-mode-map)
236 (progn
237 (setq reb-mode-map (make-sparse-keymap))
238 (define-key reb-mode-map "\C-c\C-c" 'reb-toggle-case)
239 (define-key reb-mode-map "\C-c\C-q" 'reb-quit)
240 (define-key reb-mode-map "\C-c\C-w" 'reb-copy)
241 (define-key reb-mode-map "\C-c\C-s" 'reb-next-match)
242 (define-key reb-mode-map "\C-c\C-r" 'reb-prev-match)
243 (define-key reb-mode-map "\C-c\C-i" 'reb-change-syntax)
244 (define-key reb-mode-map "\C-c\C-e" 'reb-enter-subexp-mode)
245 (define-key reb-mode-map "\C-c\C-b" 'reb-change-target-buffer)
246 (define-key reb-mode-map "\C-c\C-u" 'reb-force-update)))
247
248(defun reb-mode () 246(defun reb-mode ()
249 "Major mode for interactively building Regular Expressions. 247 "Major mode for interactively building Regular Expressions.
250\\{reb-mode-map}" 248\\{reb-mode-map}"
@@ -367,7 +365,7 @@ Except for Lisp syntax this is the same as `reb-regexp'.")
367 (reb-update-modestring)))) 365 (reb-update-modestring))))
368 366
369(defun reb-force-update () 367(defun reb-force-update ()
370 "Forces an update in the RE Builder target window without a match limit." 368 "Force an update in the RE Builder target window without a match limit."
371 (interactive) 369 (interactive)
372 370
373 (let ((reb-auto-match-limit nil)) 371 (let ((reb-auto-match-limit nil))
diff --git a/lisp/imenu.el b/lisp/imenu.el
index 238adfe9505..1c82fcacf34 100644
--- a/lisp/imenu.el
+++ b/lisp/imenu.el
@@ -211,8 +211,6 @@ menu. See the info section on Regexps for more information.
211INDEX points to the substring in REGEXP that contains the name (of the 211INDEX points to the substring in REGEXP that contains the name (of the
212function, variable or type) that is to appear in the menu. 212function, variable or type) that is to appear in the menu.
213 213
214The variable is buffer-local.
215
216The variable `imenu-case-fold-search' determines whether or not the 214The variable `imenu-case-fold-search' determines whether or not the
217regexp matches are case sensitive, and `imenu-syntax-alist' can be 215regexp matches are case sensitive, and `imenu-syntax-alist' can be
218used to alter the syntax table for the search. 216used to alter the syntax table for the search.
@@ -240,9 +238,7 @@ A nested sub-alist element looks like (INDEX-NAME SUB-ALIST).
240The function `imenu--subalist-p' tests an element and returns t 238The function `imenu--subalist-p' tests an element and returns t
241if it is a sub-alist. 239if it is a sub-alist.
242 240
243This function is called within a `save-excursion'. 241This function is called within a `save-excursion'.")
244
245The variable is buffer-local.")
246;;;###autoload 242;;;###autoload
247(make-variable-buffer-local 'imenu-create-index-function) 243(make-variable-buffer-local 'imenu-create-index-function)
248 244
@@ -977,8 +973,7 @@ A trivial interface to `imenu-add-to-menubar' suitable for use in a hook."
977(defvar imenu-buffer-menubar nil) 973(defvar imenu-buffer-menubar nil)
978 974
979(defvar imenu-menubar-modified-tick 0 975(defvar imenu-menubar-modified-tick 0
980 "The value of (buffer-modified-tick) as of last call to `imenu-update-menubar'. 976 "The value of (buffer-modified-tick) as of last call to `imenu-update-menubar'.")
981This value becomes local in every buffer when it is set.")
982(make-variable-buffer-local 'imenu-menubar-modified-tick) 977(make-variable-buffer-local 'imenu-menubar-modified-tick)
983 978
984(defun imenu-update-menubar () 979(defun imenu-update-menubar ()
diff --git a/lisp/isearch.el b/lisp/isearch.el
index a5261d2530c..2c20d45bbd8 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -153,9 +153,9 @@ string, and RET terminates editing and does a nonincremental search."
153(defcustom search-whitespace-regexp "\\(?:\\s-+\\)" 153(defcustom search-whitespace-regexp "\\(?:\\s-+\\)"
154 "*If non-nil, regular expression to match a sequence of whitespace chars. 154 "*If non-nil, regular expression to match a sequence of whitespace chars.
155This applies to regular expression incremental search. 155This applies to regular expression incremental search.
156You might want to use something like \"[ \\t\\r\\n]+\" instead. 156You might want to use something like \"\\\\(?:[ \\t\\r\\n]+\\\\)\" instead.
157In the Customization buffer, that is `[' followed by a space, 157In the Customization buffer, that is `\\(?:[' followed by a space,
158a tab, a carriage return (control-M), a newline, and `]+'." 158a tab, a carriage return (control-M), a newline, and `]+\\)'."
159 :type 'regexp 159 :type 'regexp
160 :group 'isearch) 160 :group 'isearch)
161 161
@@ -298,11 +298,11 @@ Default value, nil, means edit the string instead."
298 (define-key map "\M-\C-y" 'isearch-yank-char) 298 (define-key map "\M-\C-y" 'isearch-yank-char)
299 (define-key map "\C-y" 'isearch-yank-line) 299 (define-key map "\C-y" 'isearch-yank-line)
300 300
301 ;; Define keys for regexp chars * ? |. 301 ;; Define keys for regexp chars * ? } |.
302 ;; Nothing special for + because it matches at least once. 302 ;; Nothing special for + because it matches at least once.
303 (define-key map "*" 'isearch-*-char) 303 (define-key map "*" 'isearch-*-char)
304 (define-key map "?" 'isearch-*-char) 304 (define-key map "?" 'isearch-*-char)
305 (define-key map "{" 'isearch-{-char) 305 (define-key map "}" 'isearch-}-char)
306 (define-key map "|" 'isearch-|-char) 306 (define-key map "|" 'isearch-|-char)
307 307
308 ;; Turned off because I find I expect to get the global definition--rms. 308 ;; Turned off because I find I expect to get the global definition--rms.
@@ -372,9 +372,9 @@ Default value, nil, means edit the string instead."
372 372
373(defvar isearch-cmds nil 373(defvar isearch-cmds nil
374 "Stack of search status sets. 374 "Stack of search status sets.
375Each set is a list of the form: 375Each set is a vector of the form:
376 (STRING MESSAGE POINT SUCCESS FORWARD OTHER-END WORD 376 [STRING MESSAGE POINT SUCCESS FORWARD OTHER-END WORD
377 INVALID-REGEXP WRAPPED BARRIER WITHIN-BRACKETS CASE-FOLD-SEARCH)") 377 INVALID-REGEXP WRAPPED BARRIER WITHIN-BRACKETS CASE-FOLD-SEARCH]")
378 378
379(defvar isearch-string "") ; The current search string. 379(defvar isearch-string "") ; The current search string.
380(defvar isearch-message "") ; text-char-description version of isearch-string 380(defvar isearch-message "") ; text-char-description version of isearch-string
@@ -774,6 +774,74 @@ REGEXP says which ring to use."
774;; (handle-switch-frame (car (cdr last-command-char)))) 774;; (handle-switch-frame (car (cdr last-command-char))))
775 775
776 776
777;; The search status structure and stack.
778
779(defsubst isearch-string (frame)
780 "Return the search string in FRAME."
781 (aref frame 0))
782(defsubst isearch-message-string (frame)
783 "Return the search string to display to the user in FRAME."
784 (aref frame 1))
785(defsubst isearch-point (frame)
786 "Return the point in FRAME."
787 (aref frame 2))
788(defsubst isearch-success (frame)
789 "Return the success flag in FRAME."
790 (aref frame 3))
791(defsubst isearch-forward-flag (frame)
792 "Return the searching-forward flag in FRAME."
793 (aref frame 4))
794(defsubst isearch-other-end (frame)
795 "Return the other end of the match in FRAME."
796 (aref frame 5))
797(defsubst isearch-word (frame)
798 "Return the search-by-word flag in FRAME."
799 (aref frame 6))
800(defsubst isearch-invalid-regexp (frame)
801 "Return the regexp error message in FRAME, or nil if its regexp is valid."
802 (aref frame 7))
803(defsubst isearch-wrapped (frame)
804 "Return the search-wrapped flag in FRAME."
805 (aref frame 8))
806(defsubst isearch-barrier (frame)
807 "Return the barrier value in FRAME."
808 (aref frame 9))
809(defsubst isearch-within-brackets (frame)
810 "Return the in-character-class flag in FRAME."
811 (aref frame 10))
812(defsubst isearch-case-fold-search (frame)
813 "Return the case-folding flag in FRAME."
814 (aref frame 11))
815
816(defun isearch-top-state ()
817 (let ((cmd (car isearch-cmds)))
818 (setq isearch-string (isearch-string cmd)
819 isearch-message (isearch-message-string cmd)
820 isearch-success (isearch-success cmd)
821 isearch-forward (isearch-forward-flag cmd)
822 isearch-other-end (isearch-other-end cmd)
823 isearch-word (isearch-word cmd)
824 isearch-invalid-regexp (isearch-invalid-regexp cmd)
825 isearch-wrapped (isearch-wrapped cmd)
826 isearch-barrier (isearch-barrier cmd)
827 isearch-within-brackets (isearch-within-brackets cmd)
828 isearch-case-fold-search (isearch-case-fold-search cmd))
829 (goto-char (isearch-point cmd))))
830
831(defun isearch-pop-state ()
832 (setq isearch-cmds (cdr isearch-cmds))
833 (isearch-top-state))
834
835(defun isearch-push-state ()
836 (setq isearch-cmds
837 (cons (vector isearch-string isearch-message (point)
838 isearch-success isearch-forward isearch-other-end
839 isearch-word
840 isearch-invalid-regexp isearch-wrapped isearch-barrier
841 isearch-within-brackets isearch-case-fold-search)
842 isearch-cmds)))
843
844
777;; Commands active while inside of the isearch minor mode. 845;; Commands active while inside of the isearch minor mode.
778 846
779(defun isearch-exit () 847(defun isearch-exit ()
@@ -1249,53 +1317,93 @@ might return the position of the end of the line."
1249 (isearch-update)) 1317 (isearch-update))
1250 1318
1251 1319
1252(defun isearch-{-char () 1320;; *, ?, }, and | chars can make a regexp more liberal.
1253 "Handle \{ specially in regexps."
1254 (interactive)
1255 (isearch-*-char t))
1256
1257;; *, ?, and | chars can make a regexp more liberal.
1258;; They can make a regexp match sooner or make it succeed instead of failing. 1321;; They can make a regexp match sooner or make it succeed instead of failing.
1259;; So go back to place last successful search started 1322;; So go back to place last successful search started
1260;; or to the last ^S/^R (barrier), whichever is nearer. 1323;; or to the last ^S/^R (barrier), whichever is nearer.
1261;; + needs no special handling because the string must match at least once. 1324;; + needs no special handling because the string must match at least once.
1262 1325
1263(defun isearch-*-char (&optional want-backslash) 1326(defun isearch-backslash (str)
1264 "Handle * and ? specially in regexps. 1327 "Return t if STR ends in an odd number of backslashes."
1265When WANT-BACKSLASH is non-nil, do special handling for \{." 1328 (= (mod (- (length str) (string-match "\\\\*\\'" str)) 2) 1))
1266 (interactive) 1329
1267 (if isearch-regexp 1330(defun isearch-fallback (want-backslash &optional allow-invalid to-barrier)
1268 (let ((idx (length isearch-string))) 1331 "Return point to previous successful match to allow regexp liberalization.
1269 (while (and (> idx 0) 1332\\<isearch-mode-map>
1270 (eq (aref isearch-string (1- idx)) ?\\)) 1333Respects \\[isearch-repeat-forward] and \\[isearch-repeat-backward] by
1271 (setq idx (1- idx))) 1334stopping at `isearch-barrier' as needed.
1272 ;; * and ? are special when not preceded by \. 1335
1273 ;; { is special when it is preceded by \. 1336Do nothing if a backslash is escaping the liberalizing character. If
1274 (when (= (mod (- (length isearch-string) idx) 2) 1337WANT-BACKSLASH is non-nil, invert this behavior (for \\} and \\|).
1275 (if want-backslash 1 0)) 1338
1276 (setq isearch-adjusted t) 1339Do nothing if regexp has recently been invalid unless optional ALLOW-INVALID
1277 ;; Get the isearch-other-end from before the last search. 1340non-nil.
1278 ;; We want to start from there, 1341
1279 ;; so that we don't retreat farther than that. 1342If optional TO-BARRIER non-nil, ignore previous matches and go exactly to the
1280 ;; (car isearch-cmds) is after last search; 1343barrier."
1281 ;; (car (cdr isearch-cmds)) is from before it. 1344 ;; (eq (not a) (not b)) makes all non-nil values equivalent
1282 (let ((cs (nth 5 (car (cdr isearch-cmds))))) 1345 (when (and isearch-regexp (eq (not (isearch-backslash isearch-string))
1283 (setq cs (or cs isearch-barrier)) 1346 (not want-backslash))
1284 (goto-char 1347 ;; We have to check 2 stack frames because the last might be
1285 (if isearch-forward 1348 ;; invalid just because of a backslash.
1286 (max cs isearch-barrier) 1349 (or (not isearch-invalid-regexp)
1287 (min cs isearch-barrier))))))) 1350 (not (isearch-invalid-regexp (cadr isearch-cmds)))
1351 allow-invalid))
1352 (if to-barrier
1353 (progn (goto-char isearch-barrier)
1354 (setq isearch-adjusted t))
1355 (let* ((stack isearch-cmds)
1356 (previous (cdr stack)) ; lookbelow in the stack
1357 (frame (car stack)))
1358 ;; Walk down the stack looking for a valid regexp (as of course only
1359 ;; they can be the previous successful match); this conveniently
1360 ;; removes all bracket-sets and groups that might be in the way, as
1361 ;; well as partial \{\} constructs that the code below leaves behind.
1362 ;; Also skip over postfix operators -- though horrid,
1363 ;; 'ab?\{5,6\}+\{1,2\}*' is perfectly legal.
1364 (while (and previous
1365 (or (isearch-invalid-regexp frame)
1366 (let* ((string (isearch-string frame))
1367 (lchar (aref string (1- (length string)))))
1368 ;; The operators aren't always operators; check
1369 ;; backslashes. This doesn't handle the case of
1370 ;; operators at the beginning of the regexp not
1371 ;; being special, but then we should fall back to
1372 ;; the barrier anyway because it's all optional.
1373 (if (isearch-backslash
1374 (isearch-string (car previous)))
1375 (eq lchar ?\})
1376 (memq lchar '(?* ?? ?+))))))
1377 (setq stack previous previous (cdr previous) frame (car stack)))
1378 (when stack
1379 ;; `stack' now refers the most recent valid regexp that is not at
1380 ;; all optional in its last term. Now dig one level deeper and find
1381 ;; what matched before that.
1382 (let ((last-other-end (or (isearch-other-end (car previous))
1383 isearch-barrier)))
1384 (goto-char (if isearch-forward
1385 (max last-other-end isearch-barrier)
1386 (min last-other-end isearch-barrier)))
1387 (setq isearch-adjusted t))))))
1288 (isearch-process-search-char last-command-char)) 1388 (isearch-process-search-char last-command-char))
1289 1389
1390;; * and ? are special when not preceded by \.
1391(defun isearch-*-char ()
1392 "Maybe back up to handle * and ? specially in regexps."
1393 (interactive)
1394 (isearch-fallback nil))
1395
1396;; } is special when it is preceded by \.
1397(defun isearch-}-char ()
1398 "Handle \\} specially in regexps."
1399 (interactive)
1400 (isearch-fallback t t))
1290 1401
1402;; | is special when it is preceded by \.
1291(defun isearch-|-char () 1403(defun isearch-|-char ()
1292 "If in regexp search, jump to the barrier." 1404 "If in regexp search, jump to the barrier unless in a group."
1293 (interactive) 1405 (interactive)
1294 (if isearch-regexp 1406 (isearch-fallback t nil t))
1295 (progn
1296 (setq isearch-adjusted t)
1297 (goto-char isearch-barrier)))
1298 (isearch-process-search-char last-command-char))
1299 1407
1300(defun isearch-unread-key-sequence (keylist) 1408(defun isearch-unread-key-sequence (keylist)
1301 "Unread the given key-sequence KEYLIST. 1409 "Unread the given key-sequence KEYLIST.
@@ -1775,38 +1883,6 @@ If there is no completion possible, say so and continue searching."
1775 (insert isearch-string)))) 1883 (insert isearch-string))))
1776 1884
1777 1885
1778;; The search status stack (and isearch window-local variables, not used).
1779;; Need a structure for this.
1780
1781(defun isearch-top-state ()
1782 (let ((cmd (car isearch-cmds)))
1783 (setq isearch-string (car cmd)
1784 isearch-message (car (cdr cmd))
1785 isearch-success (nth 3 cmd)
1786 isearch-forward (nth 4 cmd)
1787 isearch-other-end (nth 5 cmd)
1788 isearch-word (nth 6 cmd)
1789 isearch-invalid-regexp (nth 7 cmd)
1790 isearch-wrapped (nth 8 cmd)
1791 isearch-barrier (nth 9 cmd)
1792 isearch-within-brackets (nth 10 cmd)
1793 isearch-case-fold-search (nth 11 cmd))
1794 (goto-char (car (cdr (cdr cmd))))))
1795
1796(defun isearch-pop-state ()
1797 (setq isearch-cmds (cdr isearch-cmds))
1798 (isearch-top-state))
1799
1800(defun isearch-push-state ()
1801 (setq isearch-cmds
1802 (cons (list isearch-string isearch-message (point)
1803 isearch-success isearch-forward isearch-other-end
1804 isearch-word
1805 isearch-invalid-regexp isearch-wrapped isearch-barrier
1806 isearch-within-brackets isearch-case-fold-search)
1807 isearch-cmds)))
1808
1809
1810;; Message string 1886;; Message string
1811 1887
1812(defun isearch-message (&optional c-q-hack ellipsis) 1888(defun isearch-message (&optional c-q-hack ellipsis)
@@ -1936,9 +2012,9 @@ Can be changed via `isearch-search-fun-function' for special needs."
1936 (if isearch-success 2012 (if isearch-success
1937 nil 2013 nil
1938 ;; Ding if failed this time after succeeding last time. 2014 ;; Ding if failed this time after succeeding last time.
1939 (and (nth 3 (car isearch-cmds)) 2015 (and (isearch-success (car isearch-cmds))
1940 (ding)) 2016 (ding))
1941 (goto-char (nth 2 (car isearch-cmds))))) 2017 (goto-char (isearch-point (car isearch-cmds)))))
1942 2018
1943 2019
1944;; Called when opening an overlay, and we are still in isearch. 2020;; Called when opening an overlay, and we are still in isearch.
diff --git a/lisp/mh-e/ChangeLog b/lisp/mh-e/ChangeLog
index 3d19028b099..645e9a1bd6d 100644
--- a/lisp/mh-e/ChangeLog
+++ b/lisp/mh-e/ChangeLog
@@ -1,3 +1,239 @@
12004-08-15 Bill Wohler <wohler@newt.com>
2
3 * Released MH-E version 7.4.80.
4
5 * MH-E-NEWS, README: Updated for release 7.4.80.
6
7 * mh-e.el (Version, mh-version): Updated for release 7.4.80.
8
92004-08-15 Bill Wohler <wohler@newt.com>
10
11 * mh-funcs.el, mh-gnus.el, mh-inc.el, mh-init.el, mh-junk.el,
12 mh-pick.el, mh-print.el, mh-xemacs.el: Added 2004 to Copyright.
13
14 * mh-acros.el, mh-alias.el: Checkdoc fixes.
15
162004-08-12 Satyaki Das <satyaki@theforce.stanford.edu>
17
18 * mh-acros.el (cl): Load cl in this file. That is all right, since
19 this file is only used at compile time, and so cl doesn't get
20 loaded at run time. This avoids problems with stale *.elc files
21 present in the Emacs source tree during compilation.
22 (mh-defstruct): Modify it to make it more CL like and in the
23 process simplify it a bit. This makes the argument list of the
24 constructor compatible with the previous version, thereby avoiding
25 a compilation error when an old version of mh-seq.elc is present.
26
27 * mh-seq.el (mh-thread-id-container, mh-thread-get-message)
28 (mh-thread-get-message-container): Revert back to the CL style
29 of using keyword arguments, since the mh-defstruct now produces
30 code compatible to such usage.
31
322004-08-11 Satyaki Das <satyaki@theforce.stanford.edu>
33
34 * mh-acros.el (mh-defstruct, mh-require-cl): Checkdoc fixes.
35
36 * mh-utils.el (message-tokenize-header, message-fetch-field): Add
37 autoloads.
38 (mh-folder-completing-read): Make the folder completion look
39 better with CVS Emacs.
40
41 * mh-init.el (mh-variant-set): Remove dead code.
42
432004-08-11 Bill Wohler <wohler@newt.com>
44
45 * *.el: Use the following at the top of each file which seems to
46 do a good job of suppressing compilation warnings in 21.3 and CVS
47 Emacs (21.4). This replaces (require 'cl) or (require
48 'utils) (mh-require-cl) calls:
49
50 (eval-when-compile (require 'mh-acros))
51 (mh-require-cl)
52
532004-08-10 Bill Wohler <wohler@newt.com>
54
55 * release-utils (DESCRIPTION): Added one.
56 (FILES, SEE ALSO, VERSION): Deleted empty and incorrect sections.
57
58 * mh-e.el (mh-colors-available-p): Call x-display-color-cells with
59 mh-funcall-if-exists since it no longer seems to be defined in
60 GNU Emacs 21.4.
61
622004-08-10 Satyaki Das <satyaki@theforce.stanford.edu>
63
64 * mh-speed.el (mh-process-kill-without-query, mh-speed-flists):
65 Avoid a compiler warning in versions of Emacs where
66 process-kill-without-query is a deprecated function.
67
68 * mh-seq.el (mh-thread-message, mh-thread-container): Use
69 mh-defstruct instead of defstruct.
70 (mh-thread-id-container, mh-thread-get-message-container)
71 (mh-thread-get-message): Use the slightly different structure
72 constructor function.
73
74 * mh-acros.el (mh-defstruct): New macro which is a partial
75 replacement of the defstruct in CL.
76 (no-byte-compile): Don't compile the file since it isn't loaded at
77 run time, so efficiency isn't an issue.
78
79 * mh-utils.el (mh-buffer-data): Use mh-defstruct instead of
80 defstruct.
81
822004-08-09 Satyaki Das <satyaki@theforce.stanford.edu>
83
84 * mh-funcs.el, mh-junk.el, mh-print.el: Use mh-require-cl to avoid
85 compilation warnings in Emacs-21.3.
86
87 * mh-acros.el (mh-require-cl): Add autoloads of CL functions used.
88
892004-08-09 Bill Wohler <wohler@newt.com>
90
91 * mh-customize.el (mh-show-use-xface-flag): Mention that `fetch' and
92 `curl' are supported as well.
93
942004-08-08 Bill Wohler <wohler@newt.com>
95
96 * mh-xemacs.el (mh-xemacs-has-toolbar-flag): Checkdoc fixes.
97
98 * mh-mime.el (mh-display-with-external-viewer): Checkdoc fixes.
99
100 * mh-identity.el: (mh-identity-attribution-verb-end): Stripped
101 trailing space; checkdoc fixes.
102
103 * mh-e.el (mh-restore-desktop-buffer): Checkdoc fixes.
104
105 * mh-customize.el: (mh-inc-spool-list,
106 mh-compose-forward-as-mime-flag, defcustom): Stripped trailing
107 space; checkdoc fixes.
108
109 * mh-comp.el (mh-reply): Stripped trailing space.
110
111 * mh-unit.el (mh-unit-files): Added mh-acros.el and mh-gnus.el.
112 (mh-unit): Don't lm-verify pre-21.4. Save buffers before killing
113 since we might have done some editing.
114
115 * import-emacs: Deleted. Functionality subsumed by release-utils.
116
117 * release-utils: New script. Performs import-emacs functionality
118 and displays new and deleted options.
119
120 * Makefile (import-emacs): Call release-utils instead of
121 import-emacs.
122
123 * mh-funcs.el (mh-undo-folder): Removed deprecated `ignore'
124 argument.
125
126 * mh-e.el (mh-scan-date-regexp): Deleted as Peter claims it is
127 obsolete.
128 (mh-folder-font-lock-keywords): Removed reference to deleted
129 variable `mh-scan-date-regexp'.
130
131 * mh-customize.el (mh-auto-fields-prompt-flag): Made reference to
132 `mh-auto-fileds-lists'.
133 (mh-forward-hook): Fixed docstring typo.
134
1352004-08-07 Bill Wohler <wohler@newt.com>
136
137 * mh-acros.el: New file. Currently holds macros needed by
138 mh-customize.el but is planned to hold all macros to avoid
139 dependency problems when compiling.
140
141 * mh-utils.el (mh-xemacs-flag): Defined in mh-customize.el now.
142 (mh-require-cl, mh-do-in-gnu-emacs, mh-do-in-xemacs)
143 (mh-funcall-if-exists, mh-make-local-hook, mh-mark-active-p):
144 Moved to new file mh-acros.el.
145
146 * mh-customize.el: Require mh-acros and cl only when compiling and
147 mh-loaddefs at runtime instead of mh-utils.
148 (mh-xemacs-flag): Define it here instead of mh-utils.el.
149
150 * Makefile (MH-E-SRC): Added mh-acros.el.
151
152 * mh-gnus.el (default-enable-multibyte-characters): Don't define
153 any more. It doesn't seem to be needed.
154
155 * mh-customize.el (mh-junk-background): New variable. If on, spam
156 programs are run in background. Running in foreground can be slow.
157 Defaults to nil to spare machines with little memory.
158
159 * mh-junk.el (mh-spamassassin-blacklist, mh-bogofilter-blacklist)
160 (mh-bogofilter-whitelist, mh-spamprobe-blacklist)
161 (mh-spamprobe-whitelist): Use new option mh-junk-background.
162
1632004-07-25 Satyaki Das <satyaki@theforce.stanford.edu>
164
165 * mh-utils.el (mh-folder-completing-read): In recent CVS Emacs,
166 the first letter of the possible choices in the completion buffer
167 is highlighted. The change is needed for this feature to work
168 during folder name completion. This is not entirely sufficient,
169 since the leading "+" in folder names is still mishandled. A patch
170 is required in Emacs itself to address that.
171
1722004-07-22 Mark D. Baushke <mdb@gnu.org>
173
174 * mh-e.el (recursive-load-depth-limit): Move
175 recursive-load-depth-limit code to ...
176 * mh-utils.el (recursive-load-depth-limit): ... here to avoid
177 problems compiling mh-utils.el and mh-alias.el with gnus-5.10.6
178 under emacs-21.1. Use eval-and-compile instead of eval-when.
179
1802004-07-20 Bill Wohler <wohler@newt.com>
181
182 * mh-customize.el (mh-invisible-header-fields-internal): Added
183 header fields emitted by T-Mobile picture phones (X-Mms-*, and
184 commented out X-Operator field saying it's like X-Mailer).
185
1862004-07-12 Bill Wohler <wohler@newt.com>
187
188 * mh-gnus.el: Set local variables indent-tabs-mode and
189 sentence-end-double-space to nil.
190
191 * mh-customize.el: Checkpoint from option docstring updates and
192 manual synchronization from last summer. For the options listed
193 below, docstring was usually completely rewritten. Use "on"
194 instead of "t" in docstring to match what is seen in customization
195 buffer. Use headline capitalization. Standardize on "Auto-detect"
196 text when option has that capibility.
197 (mh): Since we work on more than one type of Emacs, use Emacs
198 instead of GNU Emacs. Prefer GNU mailutils over GNU Mailutils.
199 (mh-variant): s/Autodetect at startup/Auto-detect/.
200 (mh-alias-insertion-location): s/Sorted
201 alphabetically/Alphabetical/. s/At the top of file/Top/. s/At the
202 bottom of file/Bottom/.
203 (mh-alias-local-users-prefix): s/Use login instead of real
204 name/Use Login/.
205 (mh-identity-list): Sorted values by fields, attribution,
206 signature, GPG key.
207 (mh-auto-fields-list): Missing quote.
208 (mh-compose-insertion): s/Use Gnus/Gnus/. s/Use mhn/mhn/.
209 (mh-compose-space-does-completion-flag): s/SPACE/<SPC>/.
210 (mh-extract-from-attribution-verb): Since we have French, added
211 German too ;-).
212 (mh-letter-complete-function): Mention default in docstring.
213 (mh-invisible-header-fields-internal): Added X-ELNK-Trace from
214 Earthlink.
215 (mh-alias-flash-on-comma, mh-alias-insert-file)
216 (mh-alias-passwd-gecos-comma-separator-flag)
217 (mh-recenter-summary-flag, mh-default-folder-for-message-function)
218 (mh-default-folder-must-exist-flag, mh-index-program)
219 (mh-index-ticked-messages-folders, mh-ins-buf-prefix)
220 (mh-delete-yanked-msg-window-flag, mh-identity-default): See
221 summary above.
222
223 * mh-init.el (mh-variant-set, mh-sys-path, mh-variant-mu-mh-info):
224 Prefer GNU mailutils over GNU Mailutils MH.
225
226 * mh-comp.el (sc-cite-original, mh-smail, mh-smail-batch)
227 (mh-edit-again, mh-extract-rejected-mail, mh-forward)
228 (mh-smail-other-window, mh-reply, mh-send, mh-send-other-window):
229 Use `mh-send' instead of \\[mh-send]] since links in the docstring
230 are more useful than a key sequence in these cases. Use "See also"
231 instead of "See also documentation for".
232
233 * Merged in 7.4.4 changes, described below.
234
235 * mh-e.el (Version, mh-version): Set to 7.4.4+cvs.
236
12004-07-10 Bill Wohler <wohler@newt.com> 2372004-07-10 Bill Wohler <wohler@newt.com>
2 238
3 * Released MH-E version 7.4.4. 239 * Released MH-E version 7.4.4.
@@ -66,7 +302,7 @@
66 require that the cl package not be required at runtime. However, 302 require that the cl package not be required at runtime. However,
67 the cl package in versions of Emacs prior to 21.4 left cl routines 303 the cl package in versions of Emacs prior to 21.4 left cl routines
68 in their macro expansions. Use mh-require-cl to provide the cl 304 in their macro expansions. Use mh-require-cl to provide the cl
69 routines in the best way possible. 305 routines in the best way possible (closes SF #930012).
70 (require 'mouse): To shush compiler. 306 (require 'mouse): To shush compiler.
71 307
72 * Use new function mh-require-cl throughout. 308 * Use new function mh-require-cl throughout.
@@ -87,6 +323,128 @@
87 4. Run xbmtopbm < file.xbm > file.pbm. 323 4. Run xbmtopbm < file.xbm > file.pbm.
88 Thanks to jan.h.d@swipnet.se for the help. 324 Thanks to jan.h.d@swipnet.se for the help.
89 325
3262004-07-07 Stephen Gildea
327
328 * mh-customize.el (mh-invisible-header-fields-internal):
329 Add X-Greylist, X-Source*, and X-WebTV-Signature.
330 Replace specific X-Spam-* headers with general pattern.
331
3322004-06-15 Bill Wohler <wohler@newt.com>
333
334 * README: Vladimir Ivanovic reports that mh-rmail works with
335 XEmacs 21.5.17, so updated requirements text accordingly (closes
336 SF #644321).
337
3382004-05-12 Satyaki Das <satyaki@theforce.stanford.edu>
339
340 * mh-utils.el (mh-mail-header-end): Replace call to
341 rfc822-goto-eoh with something that allows From_ lines in the mail
342 header.
343
3442004-04-14 Bill Wohler <wohler@newt.com>
345
346 * mh-utils.el (mh-show-mouse): s/EVENT/event/. Thanks to John Paul
347 Wallington <jpw@gnu.org> for pointing this out.
348
3492004-04-12 Satyaki Das <satyaki@theforce.stanford.edu>
350
351 * mh-e.el (mh-folder-size-flist): Add -showzero option so that the
352 parsing code doesn't get confused by the presence of -noshowzero
353 in the user's .mh_profile (closes SF #933954).
354
3552004-04-07 Satyaki Das <satyaki@theforce.stanford.edu>
356
357 * mh-mime.el (mh-insert-mime-button)
358 (mh-insert-mime-security-button): Add evaporate property to
359 overlays used in MIME part buttons. This avoids problems with
360 CVS Emacs.
361
3622004-03-16 Satyaki Das <satyaki@theforce.stanford.edu>
363
364 * mh-e.el (mh-folder-from-address): Go to the end of buffer if the
365 re-search-forward fails (closes SF #917096).
366
3672004-02-02 Satyaki Das <satyaki@theforce.stanford.edu>
368
369 * mh-customize.el (mh-compose-forward-as-mime-flag): New user
370 customizable variable that controls whether messages are forwarded
371 as MIME attachments (closes SF #827203).
372
373 * mh-comp.el (mh-forward): Call forw with -mime option only if
374 mh-compose-forward-as-mime-flag is non-nil.
375
3762003-12-26 Jeffrey C Honig <jch@honig.net>
377
378 * mh-junk.el (mh-junk-blacklist, mh-junk-whitelist)
379 (mh-spamassassin-blacklist, mh-spamassassin-blacklist)
380 (mh-spamassassin-blacklist, mh-spamassassin-whitelist)
381 (mh-spamassassin-whitelist, mh-bogofilter-blacklist)
382 (mh-spamprobe-blacklist): Add progress messages. Change "Couldn't"
383 to "Unable" in error messages. Run bogofilter and spamprobe in
384 the foreground to prevent a large number of processes from
385 swamping the system.
386
3872003-12-25 Satyaki Das <satyaki@theforce.stanford.edu>
388
389 * mh-e.el (mh-prompt-for-refile-folder): Marking the whole folder
390 and then refiling all messages throws an error, since this
391 function expects point to be on a valid scan line. The change
392 relaxes this requirement, thereby avoiding the above problem.
393
3942003-12-14 Satyaki Das <satyaki@theforce.stanford.edu>
395
396 * mh-comp.el (mh-ascii-buffer-p): New function that checks if a
397 buffer is entirely composed of ASCII.
398 (mh-send-letter): Encode the draft if it contains non-ASCII
399 characters.
400
4012003-12-12 Satyaki Das <satyaki@theforce.stanford.edu>
402
403 * mh-customize.el (mh-invisible-headers): Keep only unique fields
404 in list of header fields to hide. This avoids problems in XEmacs.
405
4062003-12-10 Satyaki Das <satyaki@theforce.stanford.edu>
407
408 * mh-seq.el (mh-thread-print-scan-lines): The imenu index was not
409 getting created for threaded index buffers. The change fixes this.
410
411 * mh-index.el (mh-index-insert-folder-headers): Always create the
412 imenu index.
413 (mh-index-create-imenu-index): Set which-func-mode to t. If
414 which-function-mode is turned on after the folder buffer has been
415 prepared, display of the folder info was being inhibited. The
416 change fixes that.
417
4182003-12-09 Satyaki Das <satyakid@stanford.edu>
419
420 * mh-comp.el (mh-letter-mode): Setup mh-mail-header-separator
421 based on draft contents.
422 (mh-letter-mode, mh-letter-mail-header-end-marker)
423 (mh-letter-header-end): Remove use of the variable
424 mh-letter-mail-header-end-marker. Instead use
425 mh-mail-header-separator. This avoids problems in font locking
426 draft buffers (closes SF #855479).
427
4282003-12-09 Satyaki Das <satyakid@stanford.edu>
429
430 * mh-index.el (mh-index-insert-folder-headers): Modified so that
431 imenu--index-alist is updated.
432 (mh-index-create-imenu-index): New function that generates an
433 index usable by imenu. This adds which-func-mode support to index
434 folders (closes SF #855520).
435
436 * mh-e.el (which-func, which-func-modes): Tell which-func that
437 mh-folder-mode supports it.
438 (mh-folder-mode): Add support for imenu.
439
4402003-11-22 Peter S Galbraith <psg@debian.org>
441
442 * Makefile: renamed mh-startup.el to mh-e-autoloads.el
443
444 * README: renamed mh-startup.el to mh-e-autoloads.el
445
446 * .cvsignore: Added mh-e-autoloads.el
447
902003-11-18 Bill Wohler <wohler@newt.com> 4482003-11-18 Bill Wohler <wohler@newt.com>
91 449
92 * Released MH-E version 7.4.3. 450 * Released MH-E version 7.4.3.
@@ -95,6 +453,8 @@
95 453
96 * mh-e.el (Version, mh-version): Updated for release 7.4.3. 454 * mh-e.el (Version, mh-version): Updated for release 7.4.3.
97 455
456 * This patch release contains the following two patches:
457
98 * mh-identity.el (mh-identity-make-menu): Removed condition on 458 * mh-identity.el (mh-identity-make-menu): Removed condition on
99 mh-auto-fields-list. Use it to enable or disable menu item 459 mh-auto-fields-list. Use it to enable or disable menu item
100 instead. 460 instead.
@@ -103,6 +463,810 @@
103 defcustom before mh-auto-fields-list so that defvar wouldn't 463 defcustom before mh-auto-fields-list so that defvar wouldn't
104 clobber user's customization settings. 464 clobber user's customization settings.
105 465
4662003-11-17 Jeffrey C Honig <jch@honig.net>
467
468 * mh-print.el (mh-print-msg): Do not print a message on deprecated
469 usage, the bindings have been removed.
470
471 * mh-e.el (mh-folder-mode-map): Remove "l" binding for
472 mh-print-msg.
473
474 * mh-utils.el (mh-show-mode-map): Remove "l" binding for
475 mh-print-msg.
476
4772003-11-16 Satyaki Das <satyakid@stanford.edu>
478
479 * mh-comp.el (mh-beginning-of-word): Use the function
480 mh-mail-abbrev-make-syntax-table instead of the function
481 mail-abbrev-make-syntax-table.
482
483 * mh-gnus.el (mh-mail-abbrev-make-syntax-table): Add a wrapper
484 function that calls mail-abbrev-make-syntax-table if available.
485 This is needed so that MH-E built with CVS Emacs will work with
486 released versions of Emacs21 and vice versa.
487
4882003-11-14 Peter S Galbraith <psg@debian.org>
489
490 * mh-customize.el (mh-invisible-header-fields-internal): Add
491 "X-NAI-Spam-" and "X-Spam-Report:".
492
4932003-11-14 Mark D. Baushke <mdb@gnu.org>
494
495 * mh-customize.el (mh-invisible-header-fields-internal):
496 Add X-AntiAbuse and X-MailScanner.
497 (Patch from Stephen Gildea.)
498
4992003-11-13 Peter S Galbraith <psg@debian.org>
500
501 * mh-identity.el (mh-identity-handler-attribution-verb): New
502 function. A new Identity handler for the attribution verb (e.g.
503 "wrote:") to allow for different identities to use different
504 languages.
505 (mh-identity-insert-attribution-verb): New function. Insert the
506 attribution verb, placing special markers so it can be deleted and
507 replaced later.
508 (mh-identity-attribution-verb-start): New variable. Holds the
509 marker for the start of the attribution verb.
510 (mh-identity-attribution-verb-end): New variable. Holds the
511 marker for the end of the attribution verb.
512
513 * mh-customize.el (mh-identity-handlers): Add new
514 ":attribution-verb" tag for the attribution-verb handler.
515 (mh-identity-list): Idem.
516
517 * mh-comp.el (mh-yank-cur-msg): Insert attribution verb using
518 mh-identity-insert-attribution-verb.
519 (mh-extract-from-attribution): Extract only the name from the From
520 line, without appending `mh-extract-from-attribution-verb' since
521 markers need to be inserted around that now.
522
5232003-11-12 Bill Wohler <wohler@newt.com>
524
525 * mh-e.el (mh-rmail, mh-nmail): Well, actually, we run in both GNU
526 Emacs and XEmacs, so removed the "GNU" in the docstrings unless
527 one is strictly talking about GNU Emacs.
528
529 * mh-comp.el (mh-smail, mh-smail-batch, mh-smail-other-window):
530 Ditto.
531
5322003-11-11 Bill Wohler <wohler@newt.com>
533
534 * mh-customize.el (mh-customize): Minor docstring change.
535 (mh, mh-e): The short description for MH-E is: The GNU Emacs
536 Interface to the MH Mail System. Therefore, updated docstrings
537 accordingly.
538
539 * mh-comp.el (mh-smail, mh-smail-batch, mh-smail-other-window):
540 Ditto.
541
542 * mh-e.el (mh-rmail, mh-nmail): Ditto.
543
5442003-11-10 Satyaki Das <satyakid@stanford.edu>
545
546 * mh-mime.el (mh-mml-to-mime): In case errors happen in
547 mml-to-mime, restore contents of the draft buffer (closes SF
548 #839303).
549
5502003-11-07 Bill Wohler <wohler@newt.com>
551
552 * mh-customize.el (mh-letter-mode-hook): Moved to mh-sending-mail
553 group (where it is now documented in the manual).
554 (mh-pick-mode-hook): Moved to mh-index group (where it is now
555 documented in the manual).
556
557 * mh-loaddefs.el: Deleted per our discussion on mh-e-devel. No
558 more conflicts! No more check-ins! Anyone pulling CVS MH-E is
559 expected to compile. This file shall be added to the tarball so
560 that users of the distribution are not.
561
5622003-11-07 Mark D. Baushke <mdb@gnu.org>
563
564 * mh-loaddefs.el: Regenerated.
565
566 * mh-customize.el (mh-forward-hook): Define new hook.
567 * mh-comp.el (mh-forward): Use it.
568
5692003-11-07 Satyaki Das <satyakid@stanford.edu>
570
571 * mh-loaddefs.el: Regenerated.
572
573 * mh-utils.el (mh-show-toggle-mime-buttons)
574 (mh-show-display-with-external-viewer): New interactive functions
575 callable from the show buffer.
576 (mh-show-mime-map): Add bindings for "K t" and "K e".
577 (mh-show-msg): Propagate change to
578 mh-display-buttons-for-inline-parts-flag to the show buffer.
579
580 * mh-mime.el (mh-display-with-external-viewer): New interactive
581 function to display MIME parts with external viewer (closes SF
582 #839318).
583
584 * mh-e.el (mh-folder-mode): Make the variable
585 mh-display-buttons-for-inline-parts-flag buffer-local so that
586 display of MIME buttons can be toggled.
587 (mh-toggle-mime-buttons): New interactive function to toggle
588 display of MIME buttons.
589 (mh-mime-map): Modified to add bindings for "K t" and "K e".
590
5912003-11-04 Steve Youngs <sryoungs@bigpond.net.au>
592
593 * Makefile (XEMACS_LOADDEFS_FILE): New. Used to generate mh-loaddefs.el
594 in XEmacs.
595 (XEMACS_LOADDEFS_COOKIE): Ditto.
596 (XEMACS_LOADDEFS_PKG_NAME): Ditto.
597 (xemacs): Add target to build mh-loaddefs.el in XEmacs
598 (clean-xemacs): Remove `mh-loaddefs.el*'
599 (loaddefs-xemacs): New rule to build mh-loaddefs.el in XEmacs.
600
6012003-11-02 Peter S Galbraith <psg@debian.org>
602
603 * mh-init.el (mh-variant-set-variant): Reset `mh-x-mailer-string'
604 when we select an MH variant.
605
6062003-11-02 Jeffrey C Honig <jch@honig.net>
607
608 * mh-loaddefs.el: Regenerated.
609
610 * mh-funcs.el (mh-print-msg): Move to mh-print.el.
611
612 * mh-e.el (mh-folder-mode-map): Add mh-print-msg ("l") back, it
613 will print a message that this usage is deprecated.
614
615 * mh-print.el (require, mh-ps-print-msg, mh-ps-print-msg-file):
616 Require mh-funcs for mh-note-printed. PS print functions were not
617 setting the printed notation. Move mh-print-msg here for
618 consistency. Print message if mh-print-msg invoked via deprecated
619 key binding.
620
6212003-11-01 Peter S Galbraith <psg@debian.org>
622
623 * Makefile: Add target to make `mh-startup.el', a file containg
624 usual entry commands into MH-E to be used for users installing
625 MH-E separately from Emacs.
626
627 * README: Document the above for users.
628
6292003-10-29 Jeffrey C Honig <jch@honig.net>
630
631 * mh-utils.el (mh-show-ps-print-map): Add "?" and "l" to
632 mh-show-ps-print-map.
633
634 * mh-e.el (mh-ps-print-map, mh-help-messages): Add "?" and "l" to
635 mh-ps-print-map. Add "l" to help message.
636
6372003-10-27 Bill Wohler <wohler@newt.com>
638
639 * Makefile (MH-E-SRC): Moved mh-xemacs.el to new variable
640 MH-E-XEMACS-SRC.
641 (MH-E-XEMACS-SRC): New variable to hold XEmacs source files.
642 (MH-E-XEMACS-OBJ): New variable to hold XEmacs object files.
643 (clean): Moved XEmacs-specific code to clean-xemacs.
644 (xemacs): Added clean-xemacs prerequisite. Moved down to
645 XEmacs section of file.
646 (clean-xemacs): New target to remove XEmacs-specific files.
647 (compile-xemacs): Added $(MH-E-XEMACS-SRC) prerequisite.
648 (dist): Added $(MH-E-XEMACS-SRC) to tarball.
649
6502003-10-27 Satyaki Das <satyakid@stanford.edu>
651
652 * mh-loaddefs.el: Regenerated.
653
654 * mh-index.el (mh-indexer-choices): Remove option for the non-free
655 glimpse indexer (closes SF #831276).
656 (mh-glimpse-binary, mh-glimpse-directory)
657 (mh-glimpse-execute-search, mh-glimpse-next-result): Functions
658 and variables to implement glimpse support are removed.
659
660 * mh-customize.el (mh-index-program): Remove option for glimpse.
661
6622003-10-24 Satyaki Das <satyakid@stanford.edu>
663
664 * mh-customize.el: Remove top-level test for toolbar enabled
665 XEmacs since it is not needed.
666 (mh-tool-bar-define): Add test for XEmacs toolbar in the functions
667 mh-toolbar-init, mh-tool-bar-letter-buttons-set and
668 mh-tool-bar-folder-buttons-set. This enables proper compilation
669 irrespective of whether the XEmacs was built with toolbar support
670 or not.
671
672 * mh-comp.el (mh-letter-mode): Remove conditional since it is not
673 needed.
674
675 * mh-e.el (mh-folder-mode): Same as above.
676
677 * mh-utils.el (mh-show-mode): Same as above.
678
679 * mh-xemacs.el (mh-xemacs-icon-map): Remove condition on toolbar
680 presence since we want the build to work if XEmacs without
681 toolbars is used during compilation.
682
6832003-10-23 Bill Wohler <wohler@newt.com>
684
685 * mh-customize.el: The Great Reorganization. Sorted groups
686 alphabetically. Aligned variables in customization groups with
687 manual sections. Group docstrings changed to match manual chapter
688 titles.
689
6902003-10-22 Satyaki Das <satyakid@stanford.edu>
691
692 * mh-speed.el (timer): Avoid compiler warning in XEmacs.
693
6942003-10-22 Steve Youngs <sryoungs@bigpond.net.au>
695
696 * Makefile (XEMACS_OPTIONS): Add '-no-autoloads' to give a cleaner
697 build environment.
698 (AUTO_PRELOADS): Removed, in favour of 'AUTOLOAD_PACKAGE_NAME' and
699 'AUTOLOAD_FILE'.
700 (AUTOLOAD_PACKAGE_NAME): New.
701 (AUTOLOAD_FILE): New.
702 (all): Don't set $EMACS_HOME if building with XEmacs.
703 (xemacs): Use 'compile-xemacs' instead of 'compile'.
704 (auto-autoloads.elc): Use new $AUTOLOAD_* vars and allow for
705 '-no-autoloads'.
706 (custom-load.elc): Allow for '-no-autoloads'.
707 (compile-xemacs): New. It allows for the '-no-autoloads' option
708 and byte-compiles all the source files with a single instance of
709 XEmacs.
710
711 * mh-e.el (mh-folder-mode): Only load the toolbar in XEmacs if
712 toolbar support is available.
713
714 * mh-comp.el (mh-letter-mode): Only load the toolbar in XEmacs if
715 toolbar support is available.
716
717 * mh-customize.el: Require 'mh-xemacs' at toplevel when
718 'mh-xemacs-flag' is non-nil.
719 Wrap all the toolbar code in a test that is true if using
720 GNU/Emacs or a toolbar-enabled XEmacs.
721
722 * mh-print.el (mh-ps-spool-a-msg): Comment out
723 `clean-message-header-flag' because it isn't used anywhere.
724
725 * mh-utils.el (mh-show-mode): Only load the toolbar in XEmacs if
726 toolbar support is available.
727
728 * mh-xemacs.el: Autoload `regexp-opt', `customize-group',
729 `view-mode', `with-electric-help', `pp', `sort-numeric-fields',
730 `reverse-region', and `goto-address' at compile time.
731 (mh-xemacs-has-toolbar-flag): New. This is non-nil when XEmacs
732 has toolbar support.
733 (mh-xemacs-toolbar-*-icon): Use it.
734
7352003-10-21 Mark D. Baushke <mdb@gnu.org>
736
737 * mh-identity.el (mh-identity-field-handler): Fields that begin
738 with ":" must have an mh-identity-handler defined or the user
739 gets an error.
740
7412003-10-17 Peter S Galbraith <psg@debian.org>
742
743 * mh-customize.el (mh-identity-list): This change affects users!
744 The keyword "signature" becomes ":signature". The recently added
745 keyword "pgg-default-user-id" becomes ":pgg-default-user-id".
746 (mh-auto-fields-list): The keyword "Identity" becomes ":identity".
747 (mh-identity-handlers): Idem for signature and pgg-default-user-id.
748
749 * mh-comp.el (mh-insert-auto-fields): Idem for Identity.
750
7512003-10-17 Peter S Galbraith <psg@debian.org>
752
753 * mh-xemacs.el: Add eval-and-compile call to (load "toolbar" t t) to
754 make sure `toolbar-make-button-list' is defined. We can't use
755 require because Emacs doesn't have this library.
756
7572003-10-16 Bill Wohler <wohler@newt.com>
758
759 * mh-customize.el (mh-signature-file-name)
760 (mh-letter-insert-signature-hook): Merge docstring with manual.
761
762 * mh-comp.el (mh-file-is-vcard-p): Checkdoc fix.
763 (mh-insert-signature): Merge docstring with manual.
764
765 * mh-customize.el (mh-junk): Changed manual link in defgroup from
766 Customizing mh-e to Junk.
767 (mh-junk-function-alist): Moved SpamAssassin to first in list on
768 the hunch that it is the most popular and should be chosen if
769 other anti-spam programs exist.
770 (mh-junk-mail-folder): Since the variable can accept values other
771 than folder names, renamed to mh-junk-disposition to more
772 accurately reflect the content. Merge docstring with manual.
773 (mh-junk-program): Moved SpamAssassin to the top of the menu for
774 the same reason presented in mh-junk-function-alist. Also, fixed
775 case of spam programs to match official usage. Merge docstring
776 with manual.
777
778 * mh-junk.el (mh-junk-blacklist):
779 s/mh-junk-mail-folder/mh-junk-disposition/. Merge docstring with
780 manual.
781 (mh-junk-whitelist): Merge docstring with manual.
782 (mh-bogofilter-blacklist): No longer suggest using automatic
783 classification so use -s instead of -Ns.
784 (mh-bogofilter-whitelist): No longer suggest using automatic
785 classification so use -n instead of -Sn.
786 (mh-spamassassin-blacklist, mh-spamassassin-whitelist): Merge
787 docstring with manual. Moved spamassassin functions to top of file
788 so functions appear in same order that they are presented in menu.
789
7902003-10-09 Peter S Galbraith <psg@debian.org>
791
792 * mh-customize.el (mail-citation-hook): Moved from mh-comp.el and
793 made into a defcustom.
794
7952003-10-09 Satyaki Das <satyakid@stanford.edu>
796
797 * mh-loaddefs.el: Regenerated.
798
799 * mh-comp.el (mh-get-header-field): Add autoload cookie.
800
801 * mh-utils.el (mh-show-ps-print-toggle-mime)
802 (mh-show-ps-print-toggle-color, mh-show-ps-print-toggle-faces)
803 (mh-show-ps-print-msg-file, mh-show-ps-print-msg)
804 (mh-show-ps-print-msg-show): New interactive functions callable
805 from the show buffer.
806 (mh-show-ps-print-map): New key map for printing.
807
808 * mh-e.el (mh-folder-mode-map): Remove key binding for
809 mh-print-msg.
810 (mh-ps-print-map): Add new key map for printing.
811
812 * Makefile (MH-E-SRC): Add mh-print.el.
813
8142003-10-07 Satyaki Das <satyakid@stanford.edu>
815
816 * mh-utils.el (mh-x-image-url-fetch-image): In XEmacs,
817 make-temp-file is not present. So to avoid security problems, use
818 a temporary file in the user's home directory. This avoids issues
819 in creating files in a world-writable directory.
820
821 * mh-mime.el (mh-signature-highlight): In Emacs, arrange for the
822 overlay to be freed when it is no longer needed. Also, implement
823 signature highlighting in XEmacs.
824
8252003-10-05 Satyaki Das <satyakid@stanford.edu>
826
827 * mh-mime.el (mh-mime-display, mh-mm-inline-message): Respect the
828 value of `mm-verify-option' and `mm-decrypt-option'.
829 (mh-mime-display-security): Rearrange code a bit to avoid too many
830 new lines being inserted when message verification/decryption is
831 carried out while the message is being read. Also use the
832 point-m{in|ax}-marker functions to make the function easier to read.
833 (mh-mime-security-press-button): Extend the function so that the
834 user can verify/decrypt messages while reading them.
835
836 * mh-gnus.el (mm-possibly-verify-or-decrypt): Added to avoid
837 compiler warning with old Gnus.
838
839 * mh-utils.el (mh-x-image-url-sane-p): New function which checks
840 if the URL in X-Image-URL is something we can handle.
841 (mh-x-image-url-display): Don't display image if the URL looks
842 malformed.
843
8442003-10-04 Mark D Baushke <mdb@gnu.org>
845
846 * mh-comp.el (mh-letter-menu): Simplify menu heading.
847
8482003-10-03 Mark D Baushke <mdb@gnu.org>
849
850 * mh-mime.el (mh-mml-query-cryptographic-method): Avoid
851 revisionist history and still provide a good default.
852
853 * mh-comp.el (mh-letter-menu): Remove the Disable Security
854 parenthetical comment.
855
856 * mh-loaddefs.el: Regenerated.
857
858 * mh-customize.el (mh-mml-method-default): What method should be
859 used in secure directives.
860
861 * mh-mime.el (mh-secure-message): New function used to generate
862 the mml security tags.
863 (mh-mml-unsecure-message): New wrapper function around
864 mml-unsecure-messages.
865 (mh-mml-secure-message-sign-pgpmime): Remove function.
866 (mh-mml-secure-message-encrypt-pgpmime): Ditto.
867 (mh-mml-cryptographic-method-history): New variable.
868 (mh-mml-query-cryptographic-method): New function.
869 (mh-mml-secure-message-encrypt): Ditto.
870 (mh-mml-secure-message-signencrypt): Ditto.
871 (mh-mml-secure-message-sign): Ditto.
872
873 * mh-comp.el (mh-letter-menu, mh-letter-mode-help-messages,
874 (mh-letter-mode-map): Update to use new functions.
875
8762003-09-26 Satyaki Das <satyakid@stanford.edu>
877
878 * mh-seq.el (mh-interactive-range): The function has been
879 extended so that it now takes a default result to return if no
880 interactive prefix arg is given and no region is active.
881
882 * mh-e.el (mh-add-sequence-notation): If transient-mark-mode is
883 on, then the active region is deactivated based on whether a user
884 sequence or a internal sequence is being notated. The change
885 removes this inconsistency.
886 (mh-catchup, mh-folder-map): A new interactive function to mark
887 messages as read has been added and bound to "F c" in the folder
888 mode.
889
890 * mh-utils.el (mh-show-catchup, mh-show-folder-map): New
891 interactive function callable from show mode buffers has been
892 bound to "F c".
893
8942003-09-24 Bill Wohler <wohler@newt.com>
895
896 * mh-customize.el (mh-clean-message-header-flag)
897 (mh-invisible-header-fields-default, mh-invisible-header-fields):
898 Merge docstring with manual.
899
9002003-09-24 Mark D. Baushke <mdb@gnu.org>
901
902 * mh-junk.el (mh-junk-blacklist): Junked messages should be put
903 into the mh-seen-list to avoid propagating the unseen sequence
904 into the spam folder.
905
906 * mh-loaddefs.el: Regenerated.
907
908 * mh-mime.el (mh-mml-secure-message-sign-pgpmime): Add an optional
909 dontsign argument to remove an existing secure message directive.
910 Update the docstring -- this fuction does not allow for
911 encrypt/sign, just sign directives.
912
913 * mh-mime.el (mh-mml-secure-message-sign-pgpmime): Use
914 mml-insert-tag directly to provide a sender if
915 mh-identity-pgg-default-user-id is set.
916 (mh-mml-secure-message-encrypt-pgpmime): Use mml-insert-tag
917 directly to provide a sender if this message is to be both signed
918 and encrypted and mh-identity-pgg-default-user-id is set.
919
9202003-09-23 Bill Wohler <wohler@newt.com>
921
922 * mh-alias.el (Commentary): Removed as it is now in the manual.
923 (mh-alias-system-aliases): Moved here from mh-customize.el. By
924 definition, "system" definitions are not user-visible, and user
925 filenames are in the the Aliasfile: profile component, so this
926 variable really shouldn't be a defcustom
927 (mh-alias-tstamp, mh-alias-filenames, mh-alias-reload)
928 (mh-alias-add-alias, mh-alias-grab-from-field)
929 (mh-alias-add-address-under-point, mh-alias-apropos): Merge
930 docstring with manual.
931 (mh-alias-reload-maybe): Minor comment update.
932 (mh-alias-insert-file): Merge docstring with manual. Removed
933 "[press TAB]" from prompt since users should know about completion
934 and space can be used as well.
935 (mh-alias-for-from-p): No longer returns a surprising result (t if
936 there was **not** an alias for the From field) if the From header
937 field is missing. This function now returns what you would expect
938 a function of this name to return. Renamed from
939 mh-alias-from-has-no-alias-p since negatives in the function name
940 make logic harder to follow.
941 (mh-alias-add-alias-to-file): Merge docstring with manual.
942 Improved verbiage of prompt. Aliases are now inserted "[b]efore"
943 or "[a]fter" the existing alias instead of "[i]nsert" or
944 "[a]ppend." Note how the new usage flows better.
945
946 * mh-customize.el (mh-alias): Changed manual link in defgroup from
947 Customizing mh-e to Aliases.
948 (mh-alias-grab-from-field button): mh-alias-from-has-no-alias-p
949 renamed to mh-alias-for-from-p and no longer returns surprising
950 value if there isn't a From field. Therefore, enable button if
951 there is a From header field and mh-alias-for-from-p returns nil.
952 (mh-letter-complete-function)
953 (mh-alias-completion-ignore-case-flag, mh-alias-flash-on-comma)
954 (mh-alias-insert-file, mh-alias-insertion-location)
955 (mh-alias-local-users, mh-alias-local-users-prefix)
956 (mh-alias-passwd-gecos-comma-separator-flag): Merge docstring with
957 manual.
958 (mh-alias-system-aliases): Moved to mh-alias.el.
959
960 * mh-comp.el (mh-letter-complete-function-alist): Removed comment
961 about making this customizable since I didn't think it seemed
962 appropriate in the manual.
963 (mh-letter-complete): Merge docstring with manual.
964
9652003-09-23 Satyaki Das <satyakid@stanford.edu>
966
967 * mh-speed.el (mh-speed-flists): When exiting emacs, don't ask if
968 the flists process should be killed.
969
970 * mh-e.el (mh-folder-message-menu): Enable undo menu entry only
971 if something can be undone.
972
973 * mh-customize.el (undo): Enable undo button only if something
974 can be undone.
975
9762003-09-22 Peter S Galbraith <psg@debian.org>
977
978 * mh-customize.el (mh-identity-handlers): New defcustom. Alist of
979 Handler functions for mh-identity (downcased) fields.
980 (mh-identity-list): Add support for pgg-default-user-id.
981
982 * mh-identity.el (mh-insert-identity): Modified to use
983 `mh-identity-handlers', adding hacking flexibility for those who
984 might need it.
985 (mh-identity-field-handler): New function. Return the handler for
986 a FIELD or nil if none set. The field name is downcased.
987 (mh-identity-handler-gpg-identity): New function; handler for pgg
988 pgp identities. It sets a buffer-local value for
989 `mh-pgg-default-user-id' which must be handled by mh-send-letter.
990 (mh-identity-pgg-default-user-id): New buffer-local variable to
991 hold the requested key ID.
992 (mh-identity-handler-signature): New function; handler t insert
993 and remove signature files.
994 (mh-identity-handler-default): New function; the default handler
995 to insert or remove generic field.
996 (mh-identity-handler-top): Insert a field at the top of the
997 header.
998 (mh-identity-handler-bottom): Insert a field at the bottom of the
999 header.
1000 (mh-header-field-delete): Make more robust wrt the field having a
1001 trailing colon or not.
1002 (mh-identity-make-menu): Add a "Customize Identities" menu entry.
1003
1004 * mh-loaddefs.el: Regenerated.
1005
10062003-09-21 Peter S Galbraith <psg@debian.org>
1007
1008 * mh-init.el (mh-variant-set): Bug fix for mh-variant long names
1009 with version numbers.
1010
1011 * mh-e.el (mh-scan-format): patch from Sergey Poznyakoff.
1012 GNU mailutils now supports the %(decode) format
1013
10142003-09-20 Satyaki Das <satyakid@stanford.edu>
1015
1016 * mh-gnus.el (mh-mm-text-html-renderer): New function to query
1017 which HTML renderer is being used by Gnus.
1018
1019 * mh-mime.el (mh-signature-highlight): Renderers used to display
1020 HTML parts garble the signature separator in various ways. The
1021 function has been modified to take that into account.
1022 (mh-mime-display-single, mh-mm-display-part): Pass the new
1023 optional argument to `mh-signature-highlight'.
1024
10252003-09-19 Mark D. Baushke <mdb@gnu.org>
1026
1027 * mh-mime.el (mh-have-file-command, mh-file-mime-type): Made an
1028 mh-autoload as they are used in mh-comp.el.
1029
1030 * mh-loaddefs.el: Regenerated.
1031
10322003-09-18 Peter S Galbraith <psg@debian.org>
1033
1034 * mh-comp.el (mh-insert-fields): Make sure field has a colon.
1035
10362003-09-18 Satyaki Das <satyakid@stanford.edu>
1037
1038 * mh-seq.el (mh-toggle-tick): Don't hardcode the name of the tick
1039 sequencence in the function. This would have caused improper
1040 highlighting of the tick sequence if the user had changed its
1041 name.
1042
10432003-09-15 Satyaki Das <satyakid@stanford.edu>
1044
1045 * mh-e.el (mh-folder-message-menu): Fix a little bug which shows
1046 up as a problem during compilation (closes SF #806577).
1047
10482003-09-15 Mark D. Baushke <mdb@gnu.org>
1049
1050 * mh-customize.el (mh-invisible-header-fields-internal): Added
1051 a new field for GNU mailutils per Sergey Poznyakoff.
1052
10532003-09-09 Satyaki Das <satyakid@stanford.edu>
1054
1055 * mh-utils.el (vcard): Unconditionally load vcard.el, if
1056 available, so that vcards are always inlined.
1057
10582003-09-09 Peter S Galbraith <psg@debian.org>
1059
1060 * mh-mime.el (mh-file-mime-type-substitutions): Add entry to
1061 convert text/plain .vcf files to text/x-vcard.
1062 (mh-mime-content-types): Add text/x-vcard.
1063
10642003-09-09 Bill Wohler <wohler@newt.com>
1065
1066 * mh-comp.el (mh-rejected-letter-start): Added strings for qmail
1067 and exim (addresses SF #404965).
1068
10692003-09-09 Satyaki Das <satyakid@stanford.edu>
1070
1071 * mh-gnus.el (mm-inline-text-vcard): Make vcard display work with
1072 Gnus-5.9. The extra file vcard.el is still needed.
1073
1074 * mh-mime.el (mh-signature-highlight): New function that
1075 highlights message signatures.
1076 (mh-mm-display-part, mh-mime-display-single): Highlight signatures
1077 using `mh-signature-highlight' (closes SF #802722). More work is
1078 needed for XEmacs.
1079 (mh-mime-display): Highlight signature in non-MIME email too.
1080
1081 * mh-customize.el (mh-show-signature-face): New face used to
1082 display message signature.
1083
10842003-09-08 Peter S Galbraith <psg@debian.org>
1085
1086 * mh-e.el (mh-version): Do something sensible when
1087 mh-variant-in-use is undefined.
1088 * mh-junk.el (mh-spamassassin-blacklist)
1089 (mh-spamassassin-whitelist): Change options to be compatoble with
1090 old version of spamassassin (V2.20).
1091
10922003-09-07 Mark D. Baushke <mdb@gnu.org>
1093
1094 * mh-mime.el (mh-access-types): Per RFC 2049, the "afs"
1095 access-type for message/external-body has been removed.
1096 Update the comments to reference the current MIME RFCs
1097 2045, 2046 and 2049 rather than the obsolete RFC 1521.
1098
10992003-09-05 Peter S Galbraith <psg@debian.org>
1100
1101 * mh-e.el (mh-version): Bumped version number to 7.4.2+cvs.
1102
11032003-09-04 Satyaki Das <satyakid@stanford.edu>
1104
1105 * mh-utils.el (mh-picon-directory-list, mh-picon-directory): The
1106 mh-picon-directory-list variable supersedes mh-picon-directory.
1107 (mh-picon-existing-directory-list): New variable that contains
1108 the list of picon directories that actually exist.
1109 (mh-picon-set-directory-list): New function to update
1110 mh-picon-existing-directory-list from mh-picon-directory-list.
1111 (mh-picon-get-image): The function has been modified to search a
1112 list of possible picon source directories. The regexp to extract
1113 the username from the email address has been made smarter so that
1114 it can recognize email addresses of the form user+random@foo.net
1115 and extract "user" from there.
1116 (mh-picon-file-contents): The file type recognition code has been
1117 moved from mh-picon-get-image into this function.
1118 (mh-picon-generate-path): The function has been generalized so
1119 that searching multiple paths is now feasible.
1120
1121 * mh-pick.el, mh-e.el: Checkdoc fixes.
1122
11232003-09-02 Satyaki Das <satyakid@stanford.edu>
1124
1125 * mh-identity.el (eval-when): It seems that the mh-comp-loaded
1126 code isn't required any more.
1127
11282003-08-30 Satyaki Das <satyakid@stanford.edu>
1129
1130 * mh-init.el (mh-variant-set): Replace `error' with `message' so
1131 that Emacs CVS will compile without errors if no MH variant is
1132 present.
1133
11342003-08-29 Satyaki Das <satyakid@stanford.edu>
1135
1136 * mh-init.el (mh-variant-set): Add interactive spec to the
1137 function.
1138
1139 * mh-mime.el (mh-mhn-compose-external-type): Optional arguments
1140 are prompted for only if prefix arg is given.
1141
11422003-08-29 Mark D. Baushke <mdb@gnu.org>
1143
1144 * mh-mime.el (mh-mhn-compose-external-type): Modified to be
1145 interactive and prompts for many of the fields. Made an
1146 mh-autoload.
1147 (mh-access-types): New table derived from RFC2017, RFC1521 and
1148 RFC1738, used in a completing-read in
1149 mh-mhn-compose-external-type.
1150
1151 * mh-loaddefs.el: Regenerated.
1152
11532003-08-26 Satyaki Das <satyakid@stanford.edu>
1154
1155 * mh-utils.el (mh-picon-image-types, mh-picon-get-image): Avoid
1156 compiler warnings.
1157 (mh-sub-folders-actual): Parsing of the output from folders has
1158 been modified, so that it also works for MH (closes SF #792300).
1159
1160 * mh-junk.el (mh-spamassassin-whitelist): Avoid calling
1161 ietf-drums-parse-address if it isn't present.
1162 (mh-spamassassin-identify-spammers): Avoid use of puthash so that
1163 Emacs20 doesn't complain.
1164
1165 * mh-e.el (mh-colors-available-p): Wrap call to
1166 display-color-cells in a mh-funcall-if-exists to avoid compiler
1167 warning in Emacs20.
1168
11692003-08-25 Satyaki Das <satyakid@stanford.edu>
1170
1171 * mh-e.el (mh-colors-available-flag, mh-folder-mode): New
1172 variable to track if colors are available and it is set
1173 appropriately in mh-folder-mode.
1174 (mh-colors-available-p, mh-colors-in-use-p): Two functions to
1175 check whether colors are available and if they are actually being
1176 used.
1177 (mh-add-sequence-notation): Just changing a scan line doesn't
1178 make font-lock refontify the line in Emacs20. So explicitly
1179 refontify the scan line in such a situation.
1180 (mh-internal-seq): If colors aren't being used then treat the
1181 tick sequence like a normal user sequence.
1182
1183 * mh-seq.el (mh-put-msg-in-seq): Do font-lock highlighting after
1184 the messages have been added to the sequence.
1185 (mh-toggle-tick): Modified so that highlighting of the ticked
1186 messages will be properly done. If font-lock isn't being used or
1187 if colors aren't supported by the Emacs where MH-E is running,
1188 then the `%' character is used to annotate ticked messages.
1189
1190 * mh-utils.el (mh-picon-image-types): Since Emacs20 doesn't have
1191 image-type-available-p, wrap calls to that function in
1192 ignore-errors.
1193 (mh-add-msgs-to-seq): Do the font-lock highlighting after the
1194 messages have been added.
1195
11962003-08-24 Bill Wohler <wohler@newt.com>
1197
1198 * Makefile (MH-E-SRC): Replaced mh-xemacs-compat.el and
1199 mh-xemacs-icons.el with mh-xemacs.el.
1200
1201 * mh-e.el: Don't require mh-xemacs-compat which no longer exists.
1202 The XEmacs stuff gets required by mh-customize.el which is
1203 required by mh-utils.el which is required by mh-e.el. This all
1204 happens before mh-xemacs-compat was required, so all should be
1205 well.
1206
1207 * mh-unit.el (mh-unit-files): Replaced mh-xemacs-compat.el and
1208 mh-xemacs-icons.el with mh-xemacs.el.
1209
1210 * mh-xemacs.el: New file from concatenation of mh-xemacs-compat.el
1211 and mh-xemacs-icons.el which were removed since their names
1212 exceeded DOS 8+3 limits.
1213
1214 * mh-customize.el (mh-compose-skipped-header-fields): Use
1215 uppercase for field names.
1216
12172003-08-21 Bill Wohler <wohler@newt.com>
1218
1219 * mh-customize.el (mh-sequences): Introduced new customization
1220 group for sequences.
1221 (mh-refile-preserves-sequences-flag, mh-tick-seq)
1222 (mh-update-sequences-after-mh-show-flag): Moved option from
1223 mh-folder to mh-sequences group. Synced docstring with manual.
1224 (mh-index-ticked-messages-folders): Since mh-tick-seq is
1225 customizable, use it instead of tick in the docstring.
1226
1227 * mh-index.el (mh-index-ticked-messages): Since mh-tick-seq is
1228 customizable, use it instead of tick in the docstring.
1229
1230 * mh-seq.el (mh-msg-is-in-seq): Can now specify an alternate
1231 message number with a prefix argument.
1232 (mh-narrow-to-tick): Since mh-tick-seq is customizable, use it
1233 instead of tick in the docstring. Also, use mh-tick-seq instead of
1234 tick in warning message.
1235
12362003-08-20 Peter S Galbraith <psg@debian.org>
1237
1238 * mh-customize.el: setq mh-variant to 'none when byte-compiling,
1239 since we don't care what MH variant (if any) is on the system at
1240 that point.
1241
1242 * mh-init.el (mh-variant-set): Don't probe for MH variant when
1243 mh-variant is set to'none (during byte-compilation).
1244
12452003-08-19 Peter S Galbraith <psg@debian.org>
1246
1247 * mh-pick.el (mh-pick-single-dash): New defconst. Search
1248 components that are supported by single-dash option in
1249 pick.
1250 (mh-pick-regexp-builder): Use `mh-pick-single-dash' and adapt
1251 patch from Sergey Poznyakoff.
1252
1253 * mh-comp.el (mh-reply): mu-mh supports `repl -group', thanks to
1254 Sergey Poznyakof.
1255
1256 * mh-init.el: checkdoc fixes.
1257
12582003-08-19 Bill Wohler <wohler@newt.com>
1259
1260 * mh-seq.el: (mh-edit-pick-expr): Renamed from mh-read-pick-regexp
1261 since the new name is more indicative of what the function does.
1262 Prompt now says "Pick expression" instead of "Pick regexp".
1263 (mh-narrow-to-subject): Rewrote function to behave like other
1264 similar functions.
1265 (mh-narrow-to-header-field, mh-narrow-to-range)
1266 (mh-narrow-to-tick): s/regexp/pick-expr/.
1267 (mh-widen, mh-narrow-to-from, mh-narrow-to-cc, mh-narrow-to-to):
1268 Synced docstrings with manual
1269
1062003-08-19 Bill Wohler <wohler@newt.com> 12702003-08-19 Bill Wohler <wohler@newt.com>
107 1271
108 * Released MH-E version 7.4.2. 1272 * Released MH-E version 7.4.2.
@@ -131,6 +1295,848 @@
131 (patches from 1.307 and 1.309 and branched for 7.4.2, closes SF 1295 (patches from 1.307 and 1.309 and branched for 7.4.2, closes SF
132 #791021). 1296 #791021).
133 1297
12982003-08-18 Bill Wohler <wohler@newt.com>
1299
1300 * mh-index.el (mh-index-sequenced-messages)
1301 (mh-index-new-messages, mh-index-ticked-messages): Updated
1302 docstrings from manual (closes SF #718833).
1303
1304 * mh-customize.el (mh-variant): Checkdoc fix.
1305 (mh-index-new-messages-folders): Don't mention defvar in
1306 docstring, use `+inbox' instead.
1307 (mh-index-ticked-messages-folders): Don't mention defvar in
1308 docstring, use `tick' instead.
1309
1310 * mh-comp.el (mh-repl-group-formfile): Checkdoc fix.
1311
13122003-08-18 Peter S Galbraith <psg@debian.org>
1313
1314 * mh-init.el (mh-variant-set, mh-sys-path, mh-variant-info): Add
1315 support for GNU mailutils.
1316 (mh-variant-mu-mh-info): New function to detect mu-mh and return
1317 info about it for `mh-variants'.
1318
1319 * mh-e.el (mh-regenerate-headers): mu-mh has different error
1320 message for a invalid mesage list.
1321
13222003-08-18 Peter S Galbraith <psg@debian.org>
1323
1324 * mh-customize.el (mh-e): New defgroup. Sort of an alias for the
1325 'mh group that a user might be more likely to find.
1326
13272003-08-18 Bill Wohler <wohler@newt.com>
1328
1329 * mh-comp.el (mh-insert-auto-fields-done-local): Docstring tweak.
1330 (mh-compose-and-send-mail): Do not call mh-insert-auto-fields.
1331 This should be done only once in mh-send-letter.
1332
13332003-08-18 Peter S Galbraith <psg@debian.org>
1334
1335 * mh-comp.el (mh-letter-mode): Call `mh-find-path unconditionally,
1336 like elsewehere in MH-E.
1337
1338 * mh-utils.el (mh-find-path): Run setup code only if
1339 `mh-find-path-run' is nil such that this is only done once.
1340 Also remove the `setq' for `read-mail-command' and `mail-user-agent'.
1341
13422003-08-18 Peter S Galbraith <psg@debian.org>
1343
1344 * mh-e.el: require 'mh-utils first
1345
1346 * mh-customize.el (mh-variant): defcustom moved here.
1347
1348 * mh-init.el (mh-variants): Made an mh-autoload.
1349
13502003-08-18 Peter S Galbraith <psg@debian.org>
1351
1352 * Makefile (MH-E-SRC): Added mh-init.el to MH-E-SRC.
1353
1354 * mh-utils.el (mh-find-progs): Deleted. Make obsolete by mh-init.el.
1355 (mh-find-path): Call `mh-variants' instead of now obsolete
1356 `mh-find-progs'.
1357 (mh-path-search): Deleted. Was only used by `mh-find-progs'.
1358
1359 * mh-e.el: require mh-init.el.
1360 (mh-version): Use simpler `mh-variant-in-use'.
1361 (mh-scan-format): Use (mh-variant-p 'nmh) instead of mh-nmh-flag.
1362
1363 * mh-comp.el (mh-insert-x-mailer): Use simpler `mh-variant-in-use'.
1364
1365 * mh-utils.el (mh-progs, mh-lib, mh-lib-progs)
1366 (mh-flists-present-flag): Moved to mh-init.el.
1367 (mh-nmh-flag): Deleted. Use (mh-variant-p 'nmh) instead.
1368
1369 * mh-comp.el (mh-repl-group-formfile, mh-forward, mh-reply)
1370 (mh-send-letter): Use (mh-variant-p 'nmh) instead of mh-nmh-flag.
1371
1372 * mh-mime.el (mh-edit-mhn, mh-mime-save-parts): Use (mh-variant-p
1373 'nmh) instead of mh-nmh-flag.
1374
13752003-08-16 Bill Wohler <wohler@newt.com>
1376
1377 * mh-customize.el (mh-folder-selection): New group to hold
1378 variables described in Folder Selection section in manual.
1379 (mh-default-folder-list, mh-default-folder-must-exist-flag,
1380 mh-default-folder-prefix): Moved to mh-folder-selection group.
1381 Updated docstrings per manual update.
1382 (mh-default-folder-for-message-function): New defcustom. Was a
1383 defvar in mh-utils.el. Updated docstring per manual update.
1384
1385 * mh-utils.el (mh-default-folder-for-message-function): Moved to
1386 mh-customize.el.
1387
1388 * mh-e.el (mh-folder-from-address, mh-prompt-for-refile-folder):
1389 Updated docstrings per manual update.
1390
1391 * mh-unit.el (mh-unit-files): Added mh-init.el.
1392
13932003-08-16 Peter S Galbraith <psg@debian.org>
1394
1395 * mh-init.el: New file. Code to initialize the MH-E back-end.
1396 Highlights:
1397 (mh-variant): New defcustom. Users may customize `mh-variant' to
1398 switch between available variants.
1399 (mh-variants): Available MH variants are described in this variable.
1400 (mh-variant-in-use, mh-variant-p): Developers may check which
1401 variant is currently in use with the variable `mh-variant-in-use'
1402 or the function `mh-variant-p'.
1403
14042003-08-15 Bill Wohler <wohler@newt.com>
1405
1406 * mh-customize.el (mh-auto-fields-list): The manual uses Fcc
1407 instead of fcc, so I've changed the user-visible text
1408 accordingly. I've left the const alone for backwards
1409 compatibility.
1410
14112003-08-14 Bill Wohler <wohler@newt.com>
1412
1413 * mh-identity.el (mh-insert-identity): Changed signature deletion
1414 test to test for both markers, rather than testing to see if the
1415 start marker is bound. Since the start marker is defined in this
1416 file, it should always be bound. Suggestion by Satyaki.
1417
1418 * mh-comp.el (mh-send-letter): Go to the top of the draft so that
1419 the user can see which header fields have been inserted. I think
1420 this is more important than leaving point alone or going to the
1421 end to see the signature since Mail-Followup-To or Bcc or cc could
1422 have some deleterious effects.
1423
1424 * mh-customize.el (mh-auto-fields-prompt-flag): New variable.
1425 Non-nil means to prompt before sending if fields inserted.
1426
1427 * mh-comp.el (mh-insert-auto-fields): Now return t if fields
1428 inserted; otherwise nil.
1429 (mh-send-letter): Deleted obsolete documentation about adding
1430 X-Mailer and X-Face. Prompt before sending if auto fields added
1431 and mh-auto-fields-prompt-flag is t.
1432
1433 * mh-customize.el (mh-identity-list): Allow signature to come from
1434 mh-signature-file-name. In this case, the "signature" value is set
1435 to nil. This might not be the best implementation. Suggestions
1436 welcome.
1437
1438 * mh-identity.el (mh-insert-identity): Now that the signature can
1439 be a nil value, moved test higher up in cond so that the test for
1440 a nil value would not be executed first prevening signature
1441 handling. Handle nil signature value by calling
1442 mh-insert-signature with no arguments which means to use
1443 mh-signature-file-name.
1444
1445 * mh-comp.el (mh-insert-signature): Changed text of message if no
1446 signature inserted.
1447
1448 * mh-customize.el (mh-identity-list): Changed "Signature" constant
1449 back to "signature" so it *won't* be backwards-incompatible any
1450 more. I discovered one could use the :tag keyword to get headline
1451 captalization in the menu.
1452
1453 * mh-identity.el (mh-insert-identity): Ditto.
1454
1455 * mh-identity.el (mh-identity-make-menu): Always build menu.
1456 Always create Insert Auto Fields menu item. Just don't enable it
1457 if mh-auto-fields-list is nil. Enable radio buttons always. Make
1458 None a radio button choice with the other identities.
1459
1460 * mh-comp.el (mh-letter-menu): Removed cond on fboundp
1461 'easy-menu-define. We don't do this elsewhere.
1462
14632003-08-13 Bill Wohler <wohler@newt.com>
1464
1465 * mh-identity.el (mh-identity-make-menu, mh-insert-identity): Use
1466 headline capitalization in menu items. Even the internal names are
1467 exposed in the customize interface, so they need to be uppercase
1468 too.
1469 (mh-insert-identity): Rather than goto-char to
1470 mh-identity-signature-start before deleting, simply pass it to
1471 delete-region. When setting markers, use point-min-marker and
1472 point-max-marker instead of moving point. Set marker type of
1473 mh-identity-signature-start to t to fix a bug where changing
1474 identity deleted user's text.
1475
1476 * mh-customize.el (mh-identity-list, mh-auto-fields-list):
1477 Reworked docstring. Use headline capitalization. Commented out
1478 implementation details for later deletion or resurrection upon
1479 popular demand. N.B. If your mh-identity-list contains "signature"
1480 then you will need to either edit your .emacs file manually, or
1481 delete your existing "signature" which will become a regular field
1482 with this change and create a new signature. I figured I could get
1483 away with this since 8.0 is a major release, and coinciding with
1484 the manual update will be a MAJOR release. I apologize profusely
1485 that I didn't catch this before it was released.
1486 (mh-identity-default): Use headline capitalization in example.
1487
14882003-08-12 Jeffrey C Honig <jch@honig.net>
1489
1490 * mh-customize.el (mh-alias-reloaded-hook): Define
1491 `mh-alias-reloaded-hook'.
1492
1493 * mh-alias.el (mh-alias-reload): Run `mh-alias-reloaded-hook'
1494 after reloading the aliases.
1495
14962003-08-12 Mark D. Baushke <mdb@gnu.org>
1497
1498 * mh-comp.el (mh-insert-signature): Use functionp to avoid
1499 the possibility of doing a funcall on a void function.
1500
15012003-08-12 Bill Wohler <wohler@newt.com>
1502
1503 * mh-customize.el (mh-identity): Point group manual link to new
1504 Identities section.
1505 (mh-signature-separator-flag): New variable which can be used to
1506 suppress the output of the signature separator.
1507
1508 * mh-comp.el (mh-insert-signature): Use
1509 mh-signature-separator-flag.
1510
1511 * mh-identity.el (mh-insert-identity): If the identity's signature
1512 file didn't exist, an fboundp error was thrown. This was fixed by
1513 removing signature tests that were redundant and out of date with
1514 the tests in mh-insert-signature. Removed second signature
1515 condition as it is now handled in the first signature condition.
1516
15172003-08-12 Peter S Galbraith <psg@debian.org>
1518
1519 * mh-identity.el (mh-insert-identity): Don't insert new lines on
1520 signatures anymore.
1521
1522 * mh-comp.el (mh-insert-signature): Make sure signature file is
1523 readable before trying to insert it.
1524
15252003-08-11 Bill Wohler <wohler@newt.com>
1526
1527 * mh-comp.el (mh-insert-signature): Unconditionally insert a
1528 newline so that signatures are inserted consistently, and so that
1529 there isn't any text after the cursor so that the user can start
1530 typing his message immediately. Use new variable and function
1531 mh-signature-separator and mh-signature-separator-p.
1532
1533 * mh-customize.el (mh-delete-yanked-msg-window-flag): Checkdoc
1534 fix.
1535 (mh-signature-file-name): Updated docstring now that this variable
1536 can be a function. Added cross-references to
1537 mh-signature-separator, mh-signature-separator-regexp, and
1538 mh-signature-separator-p which might be used in such functions.
1539
1540 * mh-identity.el (mh-insert-identity): Don't include signature if
1541 signature separator already present. Useful when running
1542 mh-edit-again.
1543
1544 * mh-mime.el (mh-inline-vcard-p): Use mh-signature-separator-p.
1545
1546 * mh-utils.el (mh-signature-separator-regexp): New variable
1547 containing "^-- $" which should be used when looking for the
1548 signature separator.
1549 (mh-signature-separator): New variable containing "-- \n" which
1550 should be used when inserting the signature separator.
1551 (mh-signature-separator-p): New function that returns non-nil if
1552 mh-signature-separator-regexp is found in the buffer.
1553
15542003-08-09 Satyaki Das <satyakid@stanford.edu>
1555
1556 * mh-utils.el (mh-x-image-scaling-function): Variable that
1557 contains function used to scale images. Possible choices are
1558 mh-x-image-scale-with-convert and mh-x-image-scale-with-pnm.
1559 (mh-convert-executable): Removed.
1560 (mh-x-image-scale-with-pnm, mh-x-image-scale-with-convert): New
1561 functions that scale images using pnm tools or ImageMagick.
1562 (mh-x-image-scale-and-display, mh-x-image-url-display): Use
1563 mh-x-image-scaling-function instead of mh-convert-executable.
1564
15652003-08-08 Peter S Galbraith <psg@debian.org>
1566
1567 * mh-comp.el (mh-insert-signature): Bug fix. Handle case of nil
1568 `mh-signature-file-name' and hooks correctly.
1569
1570 * mh-identity.el (mh-insert-identity): Refactor to use
1571 mh-insert-signature
1572
1573 * mh-comp.el (mh-signature-separator-p): Removed.
1574
1575 * mh-comp.el (mh-insert-signature): Merge MIME awareness from
1576 mh-insert-identity into this command. Allow
1577 `mh-signature-file-name' to be a function to call. See if "-- "
1578 needs to be inserted only after hooks have run.
1579
15802003-08-07 Bill Wohler <wohler@newt.com>
1581
1582 * mh-customize.el (mh-compose-skipped-header-fields): Added
1583 X-Image-URL.
1584 (mh-autoload): Removed cookies. They aren't necessary in
1585 mh-e.el, mh-utils.el, or mh-customize.el.
1586
1587 * mh-e.el (mh-autoload): Removed cookies. They aren't necessary in
1588 mh-e.el, mh-utils.el, or mh-customize.el.
1589
1590 * mh-identity.el (mh-insert-identity): Made regexp for signature
1591 separator more explicit. Hmmm, maybe we should create
1592 mh-signature-separator-regexp...
1593
1594 * mh-index.el (mh-replace-string): Moved to mh-utils.el.
1595
1596 * mh-utils.el (mh-replace-string): Moved here from mh-index.el.
1597 (mh-autoload): Removed cookies. They aren't necessary in mh-e.el,
1598 mh-utils.el, or mh-customize.el.
1599
1600 * mh-comp.el (mh-insert-signature): Added file argument to insert
1601 a file other than mh-signature-file-name. Insert signature
1602 separator, unless file already contains one.
1603
16042003-08-06 Satyaki Das <satyakid@stanford.edu>
1605
1606 * mh-e.el (mh-folder-size, mh-folder-size-folder)
1607 (mh-folder-size-flist): If flist is not present use folder to
1608 find the number of messages in the folder. Also the .mh_sequences
1609 file is read to find the number of unseen messages.
1610
1611 * mh-utils.el (mh-flists-present-flag, mh-find-progs): Introduce
1612 a new variable to test for the presence of the flists program and
1613 set it in mh-find-progs.
1614
16152003-08-06 Peter S Galbraith <psg@debian.org>
1616
1617 * mh-customize.el: Change the order of `mh-identity-list' and
1618 `mh-auto-fields-list' and remove byte-compilation defvar for
1619 `mh-identity-list'. This fixes a customization bug for
1620 `mh-identity-list', where it wasn't set correctly.
1621
1622 * mh-identity.el (mh-identity-make-menu): mh-auto-fields-list may
1623 not be bound yet when initially loaded.
1624
16252003-08-06 Bill Wohler <wohler@newt.com>
1626
1627 * mh-alias.el (mh-alias-add-address-under-point): Removed trailing
1628 period from messages. The conventions say that errors should not
1629 end with a period and that "Foo...done" messages should not end in
1630 a period, but they aren't explicit about messages in general.
1631 Given what the conventions *do* say, and because most of our
1632 messages don't end with a period, let's just say that messages in
1633 general don't end in a period, just like error messages.
1634
1635 * mh-comp.el (mh-extract-rejected-mail, mh-letter-mode-message):
1636 Ditto.
1637
1638 * mh-e.el (mh-refile-a-msg): Ditto.
1639
1640 * mh-funcs.el (mh-undo-folder): Ditto.
1641
1642 * mh-mime.el (mh-mime-save-parts): Ditto.
1643
1644 * mh-seq.el (mh-subject-to-sequence-unthreaded)
1645 (mh-narrow-to-subject, mh-delete-subject): Ditto.
1646
1647 * mh-index.el (mh-index-sequenced-messages)
1648 (mh-index-new-messages, mh-index-ticked-messages): Discovered that
1649 in general we should only use question marks in yes-or-no-p or
1650 y-or-n-p prompts, but not in other prompts that use
1651 completing-read and offer defaults. In these cases, use colons
1652 instead (closes SF #730470).
1653
1654 * mh-mime.el (mh-mime-save-parts): Ditto.
1655
1656 * mh-utils.el (mh-prompt-for-folder): Ditto.
1657
1658 * mh-alias.el (mh-alias-apropos): Multiple messages are usually
1659 shown one at a time rather than appended. Send output to
1660 mh-aliases-buffer instead of *Help*.
1661 (mh-alias-local-users): Checkdoc fix.
1662
1663 * mh-funcs.el (mh-undo-folder): Removed commented-out code since
1664 its deadline had expired.
1665
1666 * mh-utils.el (mh-aliases-buffer): New buffer name, used in
1667 mh-aliases.el.
1668
16692003-08-06 Satyaki Das <satyakid@stanford.edu>
1670
1671 * mh-utils.el (mh-x-image-url-cache-canonicalize): Make this
1672 function work for XEmacs too.
1673 (mh-collect-folder-names): Use folders instead of flists. One
1674 advantage is that folders is available on MH while flists is not.
1675 Another is that if an explicit -sequence argument isn't given and
1676 Unseen-Sequence profile is not present then flists croaks while
1677 folders doesn't.
1678 (mh-collect-folder-names-filter): Don't consider folder names that
1679 start with a `.' character. This is needed since the folders
1680 command doesn't filter them out like flists does.
1681
1682 * mh-index.el (mh-replace-string): Add autoload for it.
1683
16842003-08-05 Satyaki Das <satyakid@stanford.edu>
1685
1686 * mh-mime.el (mh-compose-forward, mh-mhn-compose-forw)
1687 (mh-mml-forward-message): The variable mh-sent-from-msg can be a
1688 list. So check that the value is really a number before using it
1689 like one.
1690
1691 * mh-comp.el (mh-insert-letter): Same as above.
1692
1693 * mh-utils.el (mh-picon-get-image): Make the code that finds the
1694 address of the sender more robust.
1695 (mh-face-display-function): Make it work with XEmacs.
1696 (mh-picon-image-types): A new variable that stores what image
1697 types can be used.
1698
16992003-08-05 Satyaki Das <satyakid@stanford.edu>
1700
1701 * mh-customize.el (mh-tool-bar-define): Make the save button such
1702 that is activated only if the buffer needs to saved.
1703
1704 * mh-utils.el (mh-face-display-function, mh-picon-get-image): Some
1705 domains, for instance cs.cmu.edu, don't have xpm files. So we need
1706 to search for all three files. The change does that.
1707 (mh-picon-file-contents): A utility function to return the
1708 contents of a file as a string.
1709 (mh-picon-get-image): Write it as a loop to make it simpler.
1710 (mh-x-image-set-download-state): Make the link simpler.
1711
17122003-08-04 Satyaki Das <satyakid@stanford.edu>
1713
1714 * mh-utils.el (mh-x-image-url-display): Don't bother to try to
1715 download image if we don't have the necessary tools to display
1716 it.
1717 (mh-face-display-function): Add preliminary support for "domain"
1718 picons.
1719 (mh-picon-get-image, mh-picon-generate-path): Functions to find
1720 best match for domain in the From header field.
1721
1722 * mh-e.el (mh-previous-unread-msg): If some of the messages in the
1723 unseen sequence are not present in the folder buffer then calling
1724 this function gets stuck and can't skip over them. The change
1725 fixes this.
1726 (mh-next-unread-msg): Same as above.
1727
17282003-08-04 Bill Wohler <wohler@newt.com>
1729
1730 * mh-utils.el (mh-show-mode): Added cross reference to
1731 mh-folder-mode in docstring (closes SF #728638). Added
1732 \\{mh-show-mode-map} to show keymap.
1733
1734 * mh-e.el (mh-folder-mode): Added information about ranges to
1735 docstring (closes SF #728638).
1736
1737 * mh-speed.el (mh-speed-refresh): New function that calls
1738 mh-speed-flists and mh-invalidate-map.
1739 (mh-folder-speedbar-key-map): Replaced keybindings for
1740 mh-speed-invalidate-map and mh-speed-flists with a single binding
1741 for mh-speed-refresh.
1742 (mh-folder-speedbar-menu-items): Replaced menu items for Run
1743 Flists and Invalidate Cached Folders with the single menu item
1744 Refresh Speedbar in order to simplify the UI.
1745
1746 * mh-customize.el (mh-fetch-x-image-url): Added DOS as another
1747 reason not to set this to t.
1748
17492003-08-04 Satyaki Das <satyakid@stanford.edu>
1750
1751 * mh-e.el (mh-scan-folder): Handle ranges from user input properly.
1752
17532003-08-03 Satyaki Das <satyakid@stanford.edu>
1754
1755 * mh-utils.el (mh-find-msg-get-num): Removed. If threading isn't
1756 present, the messages are sorted by index. So `mh-goto-msg' was
1757 implemented as a binary search and this function was used in that
1758 implementation. So this isn't needed any more.
1759 (mh-msg-search-pat): Removed. Before the advent of message
1760 threading, this function was used to generate a regexp used to
1761 search for a particular message. It isn't used anymore. The
1762 variable `mh-scan-msg-number-regexp' should be updated and used in
1763 `mh-goto-msg' instead of hardcoding the regexp in the code. Then
1764 we might be able to better support other scan line formats in the
1765 future.
1766
1767 * mh-seq.el (mh-map-to-seq-msgs, mh-notate-seq): Removed. These
1768 functions were used to notate user sequences. But calling
1769 `mh-goto-msg' inside of a loop is inefficient. So the sequence
1770 notation code was rewritten thereby making these functions
1771 redundant.
1772 (mh-copy-line-to-point): Removed. This function was used in the
1773 implementation the now removed function `mh-copy-seq-to-point'.
1774 That function was problematic and was replaced by the less general
1775 `mh-copy-seq-to-eob'. This makes `mh-copy-line-to-point'
1776 redundant.
1777 (mh-region-to-msg-list): Removed since this is a special case of
1778 the more general `mh-range-to-msg-list'.
1779
1780 * mh-loaddefs.el: Regenerated.
1781
17822003-08-03 Jeffrey C Honig <jch@honig.net>
1783
1784 * mh-customize.el (mh-invisible-header-fields-default): Added
1785 several new fields to hide. Sorted the list with sort-lines.
1786
17872003-08-03 Peter S Galbraith <psg@debian.org>
1788
1789 * mh-customize.el (mh-invisible-headers): Variable renamed to
1790 `mh-invisible-header-fields-compiled'.
1791 (mh-invisible-headers): Implement above change.
1792
1793 * mh-utils.el (mh-display-msg): Idem.
1794
1795 * mh-mime.el (mh-mm-inline-message): Idem.
1796
1797 * mh-comp.el (mh-insert-letter): Idem.
1798
17992003-08-03 Bill Wohler <wohler@newt.com>
1800
1801 * mh-speed.el (mh-folder-speedbar-menu-items): Added separator
1802 between standard and MH-E menu items. Use headline capitalization
1803 in menu items.
1804
1805 * mh-utils.el (mh-temp-fetch-buffer): New constant to hold
1806 buffer name for wget output.
1807 (mh-x-image-url-fetch-image): Use mh-temp-fetch-buffer instead
1808 of hard-coded buffer name. Use make-temp-file to avoid race
1809 conditions and subsequent security issues raised in make-temp-name
1810 docstring.
1811
18122003-08-03 Satyaki Das <satyakid@stanford.edu>
1813
1814 * mh-utils.el (mh-wget-executable, mh-wget-choice, mh-wget-option)
1815 (mh-x-image-url-fetch-image): Support the use of `curl' and
1816 `fetch' as alternatives to `wget'.
1817 (mh-wget-choice): Change order of search.
1818 (mh-x-image-url-fetch-image): Rename buffer.
1819
18202003-08-03 Satyaki Das <satyakid@stanford.edu>
1821
1822 * mh-utils.el (mh-x-image-set-download-state)
1823 (mh-x-image-get-download-state): Specially named symbolic links
1824 are used to keep track of whether a X-Image-URL header field needs
1825 to downloaded the next time it is seen. These functions get and
1826 set the symlinks appropriately.
1827 (mh-x-image-url-fetch-image): Simplified since the query has been
1828 moved to `mh-x-image-url-display'. Also if wget isn't present then
1829 try again next time since the user might install wget before
1830 trying once more.
1831 (mh-x-image-scale-and-display): Handle absence of the `convert'
1832 program better. If it isn't present then we will try to display
1833 the image the next time it is encountered. Also use the -geometry
1834 option to convert since the -resize option isn't present in older
1835 versions.
1836 (mh-x-image-url-display): Move all the code that decides whether
1837 an X-Image-URL header field will be fetched in this function. Also
1838 remember the user's decision so that if the image couldn't be
1839 fetched the first time, we will try to fetch it later on without
1840 asking again.
1841
18422003-08-02 Peter S Galbraith <psg@debian.org>
1843
1844 * mh-alias.el (mh-alias-local-users): Exclude all aliases already
1845 in mh-alias-alist from `ali' (closes SF #772595).
1846
18472003-08-01 Satyaki Das <satyakid@stanford.edu>
1848
1849 * mh-utils.el (mh-x-image-display, mh-x-image-url-display): Avoid
1850 a race. The X-Image-URL is displayed asynchronously. Suppose a
1851 message with a image is shown with `mh-show'. If a different
1852 message is displayed before the image can be fetched, then the new
1853 message will have the image displayed. With this change the race
1854 is less likely to happen.
1855
18562003-08-01 Peter S Galbraith <psg@debian.org>
1857
1858 * mh-inc.el (mh-inc-spool-map): Fix what `mh-inc-spool-map-help'
1859 must look like as a fake `mh-help-messages' in order to work
1860 correctly in mh-help.
1861
18622003-07-31 Bill Wohler <wohler@newt.com>
1863
1864 * mh-inc.el (mh-inc-spool-map): Use mh-help instead of
1865 mh-ephem-message in order to display help in its own buffer
1866 instead of minibuffer.
1867
1868 * mh-utils.el (mh-help-buffer): New variable to hold the name of
1869 the MH-E help buffer name.
1870
1871 * mh-funcs.el (mh-help, mh-prefix-help): Use with-electric-help to
1872 display help messages. I observed a friend with a vision
1873 disability and the 5 seconds the help appeared on the screen was
1874 not long enough for him to lock on it. I've therefore changed the
1875 help function to display the help in its own buffer called *MH-E
1876 Help* (closes SF #493740 and SF #656631).
1877
1878 * mh-customize.el (mh-fetch-x-image-url): Changed default from nil
1879 to 'ask. Updated docstring from manual.
1880 (mh-invisible-header-fields-internal): Added X-Image-URL.
1881 (mh-show-use-xface-flag): Updated docstring from manual.
1882 (mh-x-face-file): Ditto.
1883
1884 * mh-mime.el (mh-mhn-compose-external-type): Don't insert the
1885 directory parameter if it's nil. The mhbuild man page indicates
1886 that this parameter is optional, so this should be fine.
1887
1888 * mh-comp.el (mh-letter-mode-map): Added keybindings for
1889 mh-mhn-compose-anon-ftp and
1890 mh-mhn-compose-external-compressed-tar.
1891 (mh-letter-menu): Uncommented menu items for same.
1892
18932003-07-30 Satyaki Das <satyakid@stanford.edu>
1894
1895 * mh-loaddefs.el: Regenerated.
1896
1897 * mh-pick.el (mh-do-pick-search): Removed since the function
1898 `mh-pick-do-search' performs the same action as this function.
1899
1900 * mh-index.el (mh-index-update-unseen): Removed since the
1901 generalized sequence synchronization code that keeps sequences in
1902 index folders in sync with the sequences in the source folders
1903 makes this function redundant.
1904
1905 * mh-e.el (mh-folder-unseen-seq-name, mh-folder-unseen-seq-list):
1906 Removed. These two functions were used in the unseen sequence
1907 highlighting before the sequence highlighting code was
1908 generalized. In any event calls to the function
1909 `mh-folder-unseen-seq-name' can be replaced by the variable
1910 `mh-unseen-seq' and calls to `mh-folder-unseen-seq-list' can be
1911 replaced with (cdr (assoc mh-unseen-seq mh-seq-list)).
1912 (mh-unmark-all-headers): Removed since this function has been
1913 superseded by mh-remove-all-notation.
1914 (mh-map-over-seqs): Removed since we now have the generalized
1915 iteration over message ranges (the `mh-iterate-on-range' macro)
1916 that can be used instead.
1917 (mh-notate-if-in-one-seq): Removed. This function was used for
1918 changing the `%' notation for user sequences. It can't be used for
1919 that purpose any more, since we have a different scheme now.
1920
1921 * mh-unit.el (mh-unit-tests): Removed since it isn't needed any
1922 more.
1923 (mh-unit): Run all function that start with the string
1924 "mh-unit-test-".
1925
19262003-07-30 Bill Wohler <wohler@newt.com>
1927
1928 * mh-customize.el (mh-invisible-header-fields): Checkdoc fix.
1929
1930 * mh-utils.el (mh-x-image-url-cache-canonicalize): Shortened using
1931 example in files.el:make-backup-file-name-1.
1932 (mh-face-display-function): Added X-Image-URL to docstring.
1933
1934 * mh-unit.el (mh-unit-x-image-url-cache-canonicalize): New
1935 function to test mh-x-image-url-cache-canonicalize since it lent
1936 itself well to unit testing. Had to start somewhere!
1937 (mh-unit-equal): New function that throws an error if RESULT
1938 doesn't equal EXPECTED.
1939 (mh-unit): Call mh-unit-x-image-url-cache-canonicalize.
1940
19412003-07-29 Satyaki Das <satyakid@stanford.edu>
1942
1943 * mh-unit.el (mh-unit-update-call-graph): Make the function work
1944 better with dotted lists, that is lists of the form (a b c . d)
1945 where `d' isn't nil. With this we are able to avoid marking some
1946 functions as unused even though they are actually used in alists.
1947
19482003-07-28 Peter S Galbraith <psg@debian.org>
1949
1950 * mh-comp.el (mh-insert-letter): Remove `mh-visible-headers'
1951 operation.
1952
1953 * mh-mime.el (mh-mm-inline-message): Same.
1954
1955 * mh-utils.el (mh-display-msg): Same.
1956 (mh-clean-msg-header): Make a note of above change.
1957
1958 * mh-customize.el (mh-invisible-header-fields-internal): Renamed
1959 from prior `mh-invisible-header-fields-default'.
1960 (mh-invisible-header-fields-default): Renamed from prior
1961 `mh-invisible-header-fields-default-override'.
1962 (mh-invisible-header-fields): Renamed from prior
1963 `mh-invisible-header-fields-user'.
1964 (mh-visible-headers): Removed! We use invisible fields only now.
1965 (mh-visible-header-fields): Removed!
1966
19672003-07-28 Peter S Galbraith <psg@debian.org>
1968
1969 * mh-customize.el (mh-invisible-header-fields-default): Added 3
1970 new fields to hide.
1971
19722003-07-28 Satyaki Das <satyakid@stanford.edu>
1973
1974 * mh-utils.el (mh-show): Add an extra argument to the function so
1975 that interactive use will always force redisplay of the message.
1976
1977 * mh-mime.el (mh-mime-display, mh-mm-inline-message): Bind the
1978 variables `mm-verify-option' and `mm-decrypt-option' so that
1979 verification and decryption of mail can happen without any
1980 additional tinkering.
1981
19822003-07-25 Peter S Galbraith <psg@debian.org>
1983
1984 * mh-customize.el (mh-invisible-header-fields-default): New defvar
1985 holding default fields to hide. This replaces the old
1986 `mh-invisible-header-fields' defcustom.
1987 (mh-invisible-header-fields-user): New defcustom. Users add
1988 fields to suppress that we didn't include in
1989 `mh-invisible-header-fields-default'. This could be named simply
1990 `mh-invisible-header-fields' and it wouldn't really break anything
1991 for users who have customized it to a long list now redundant with
1992 `mh-invisible-header-fields-default'.
1993 (mh-invisible-header-fields-default-override): New defcustom.
1994 Users check off the fields they want displyed from what we
1995 included in `mh-invisible-header-fields-default'.
1996 (mh-invisible-headers): Function adapted to new variables.
1997
19982003-07-25 Satyaki Das <satyakid@stanford.edu>
1999
2000 * mh-e.el (mh-inc-folder): If the user is in a different folder
2001 displaying a message and runs mh-inc-folder, then the folder
2002 changes to +inbox but the show window continues to display the
2003 message in the old folder. The change fixes this.
2004 (mh-visit-folder): Make the handling of the show window similar to
2005 that of mh-inc-folder.
2006
20072003-07-24 Satyaki Das <satyakid@stanford.edu>
2008
2009 * mh-e.el (mh-folder-message-menu, mh-folder-folder-menu): Use the
2010 predicate mh-outstanding-commands-p instead of its exapansion.
2011 Also use the same label in both menus.
2012 (mh-outstanding-commands-p): Generalized so that it will work in
2013 mh-show-mode buffers as well.
2014
2015 * mh-customize.el (mh-tool-bar-define): Enable tool-bar button for
2016 mh-execute-commands only if there are pending deletes or refiles.
2017
20182003-07-19 Satyaki Das <satyakid@stanford.edu>
2019
2020 * mh-utils.el (mh-show-msg): If a unseen message is first marked
2021 for deletion/refiling and then displayed, the bold highlighting
2022 does not go away. This change fixes that.
2023
2024 * mh-seq.el (mh-msg-is-in-seq): Fix a bug in the function. If any
2025 message was marked for refiling, then the function would have you
2026 believe that every message in the folder is being refiled.
2027
20282003-07-17 Bill Wohler <wohler@newt.com>
2029
2030 * mh-e.el: Removed email address for Stephen Gildea's in Change
2031 Log at his request (damn spammers). Removed other email addresses
2032 while I was at it since the SourceForge URL should be sufficient
2033 contact information.
2034
2035 (mh-scan-format-*mh): Fixed typo in comment above these variables.
2036 These variables are used if mh-scan-format-file is t, not nil.
2037 Also mh-scan-format-file is no longer "above" (courtesy Stephen
2038 Gildea).
2039
20402003-07-17 Satyaki Das <satyakid@stanford.edu>
2041
2042 * mh-mime.el (mh-mhn-quote-unescaped-sharp): New function that
2043 quotes `#' characters in the first column that aren't part of a
2044 MHN directive.
2045 (mh-mhn-directive-present-p): Generalized to allow the function
2046 to search for MHN directives in a part of the buffer.
2047 (mh-edit-mhn): Quote unescaped `#' characters in the draft (closes
2048 SF #762464).
2049
20502003-07-16 Satyaki Das <satyakid@stanford.edu>
2051
2052 * mh-alias.el (mh-alias-read-address-map): If
2053 mh-alias-flash-on-comma is nil when mh-alias is loaded, then
2054 setting mh-alias-flash-on-comma to t later on doesn't turn on
2055 address completion display till Emacs is restarted. The change
2056 fixes this.
2057
20582003-07-15 Bill Wohler <wohler@newt.com>
2059
2060 * mh-utils.el (mh-cmd-note): Cleaned up docstring (changed phrase
2061 to sentences). Moved to Scan Line Formats section.
2062 (mh-scan-msg-number-regexp)
2063 (mh-scan-msg-overflow-regexp, mh-scan-msg-format-regexp)
2064 (mh-scan-msg-format-string, mh-scan-msg-search-regexp): Cleaned up
2065 docstrings (changed phrases to sentences).
2066 (mh-note-seq): Cleaned up docstring (changed phrase to sentences).
2067 Also, this variable is now a character and not a string. Moved to
2068 Scan Line Formats section.
2069
2070 * mh-funcs.el (mh-note-copied, mh-note-printed): Cleaned up
2071 docstrings (changed phrases to sentences). Also, these variables
2072 are now characters and not strings.
2073
2074 * mh-e.el (mh-scan-format-mh, mh-scan-format-nmh): Filled. I was
2075 hoping to quote the hint `t' but checkdoc wouldn't let me.
2076 (mh-note-deleted, mh-note-refiled, mh-note-cur): Moved to Scan
2077 Line Formats section.
2078 (mh-scan-good-msg-regexp, mh-scan-deleted-msg-regexp)
2079 (mh-scan-refiled-msg-regexp, mh-scan-valid-regexp)
2080 (mh-scan-cur-msg-number-regexp, mh-scan-date-regexp)
2081 (mh-scan-rcpt-regexp, mh-scan-body-regexp)
2082 (mh-scan-subject-regexp, mh-scan-format-regexp): Cleaned
2083 up docstrings (changed phrases to sentences).
2084 (mh-scan-cur-msg-regexp): Marked this variable as obsolete; it
2085 should be removed for 8.0.
2086
2087 * mh-comp.el (mh-note-repl, mh-note-forw, mh-note-dist): Cleaned
2088 up docstrings (changed phrases to sentences). Also, these
2089 variables are now characters and not strings.
2090
20912003-07-15 Satyaki Das <satyakid@stanford.edu>
2092
2093 * mh-index.el (mh-index-update-single-msg)
2094 (mh-index-create-sequences): Handle the situation where there are
2095 copies of the exact same message correctly.
2096
20972003-07-15 Satyaki Das <satyakid@stanford.edu>
2098
2099 * mh-seq.el (mh-thread-update-scan-line-map): Modified since
2100 notation is already a character.
2101
2102 * mh-utils.el (mh-note-seq): Convert from string to character.
2103 (mh-notate): Modified since characters are used to notate instead
2104 of strings of length one.
2105
2106 * mh-comp.el (mh-note-repl, mh-note-forw, mh-note-dist): Convert
2107 from string to characters.
2108
2109 * mh-e.el (mh-note-deleted, mh-note-refiled, mh-note-cur): Same as
2110 above (closes SF #770772).
2111 (mh-unmark-all-headers): Modified since mh-note-* variables are
2112 now characters.
2113 (mh-remove-sequence-notation): The mh-notate function remembers
2114 the previous notation. Before the change to the mh-note-*
2115 variables, mh-notate would only remember the change if a string
2116 was used to notate the message. Now mh-notate is always called
2117 with a character notation. So the deletion has to take place
2118 explicitly.
2119
21202003-06-28 Bill Wohler <wohler@newt.com>
2121
2122 * mh-mime.el (mh-mhn-directive-present-p): If shell comments are
2123 present that have a space after the # but no content, then this
2124 function would throw an error. This has been fixed (closes SF
2125 #762458).
2126
21272003-06-27 Satyaki Das <satyakid@stanford.edu>
2128
2129 * mh-index.el (mh-index-search): Use the new and improved
2130 mh-index-new-folder.
2131 (mh-index-new-folder): Improved so that redoing the same search
2132 will reuse the old index folder.
2133 (mh-index-folder-search-regexp): New function which that extracts
2134 out the search expression that produced the index folder.
2135
21362003-06-24 Bill Wohler <wohler@newt.com>
2137
2138 * mh-e.el (Version, mh-version): Set to 7.4.1+cvs.
2139
1342003-06-25 Bill Wohler <wohler@newt.com> 21402003-06-25 Bill Wohler <wohler@newt.com>
135 2141
136 * Released MH-E version 7.4.1. 2142 * Released MH-E version 7.4.1.
diff --git a/lisp/mh-e/mh-acros.el b/lisp/mh-e/mh-acros.el
new file mode 100644
index 00000000000..c409cf8d36e
--- /dev/null
+++ b/lisp/mh-e/mh-acros.el
@@ -0,0 +1,143 @@
1;;; mh-acros.el --- Macros used in MH-E
2
3;; Copyright (C) 2004 Free Software Foundation, Inc.
4
5;; Author: Satyaki Das <satyaki@theforce.stanford.edu>
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;; This file contains macros that would normally be in mh-utils.el except that
30;; their presence there would cause a dependency loop with mh-customize.el.
31;; This file must always be included like this:
32;;
33;; (eval-when-compile (require 'mh-acros))
34;;
35;; It is so named with a silent `m' so that it is compiled first. Otherwise,
36;; "make recompile" in Emacs 21.4 fails.
37
38;;; Change Log:
39
40;;; Code:
41
42(require 'cl)
43
44;; The Emacs coding conventions require that the cl package not be required at
45;; runtime. However, the cl package in versions of Emacs prior to 21.4 left cl
46;; routines in their macro expansions. Use mh-require-cl to provide the cl
47;; routines in the best way possible.
48(defmacro mh-require-cl ()
49 "Macro to load `cl' if needed.
50Some versions of `cl' produce code for the expansion of
51\(setf (gethash ...) ...) that uses functions in `cl' at run time. This macro
52recognizes that and loads `cl' where appropriate."
53 (if (eq (car (macroexpand '(setf (gethash foo bar) baz))) 'cl-puthash)
54 `(progn
55 (require 'cl)
56 ;; Autoloads of CL functions go here...
57 (autoload 'cl-puthash "cl")
58 (autoload 'values "cl")
59 (autoload 'copy-tree "cl"))
60 `(eval-when-compile (require 'cl))))
61
62;;; Macros to generate correct code for different emacs variants
63
64(defmacro mh-do-in-gnu-emacs (&rest body)
65 "Execute BODY if in GNU Emacs."
66 (unless (featurep 'xemacs) `(progn ,@body)))
67(put 'mh-do-in-gnu-emacs 'lisp-indent-hook 'defun)
68
69(defmacro mh-do-in-xemacs (&rest body)
70 "Execute BODY if in GNU Emacs."
71 (when (featurep 'xemacs) `(progn ,@body)))
72(put 'mh-do-in-xemacs 'lisp-indent-hook 'defun)
73
74(defmacro mh-funcall-if-exists (function &rest args)
75 "Call FUNCTION with ARGS as parameters if it exists."
76 (if (fboundp function)
77 `(funcall ',function ,@args)))
78
79(defmacro mh-make-local-hook (hook)
80 "Make HOOK local if needed.
81XEmacs and versions of GNU Emacs before 21.1 require `make-local-hook' to be
82called."
83 (when (and (fboundp 'make-local-hook)
84 (not (get 'make-local-hook 'byte-obsolete-info)))
85 `(make-local-hook ,hook)))
86
87(defmacro mh-mark-active-p (check-transient-mark-mode-flag)
88 "A macro that expands into appropriate code in XEmacs and nil in GNU Emacs.
89In GNU Emacs if CHECK-TRANSIENT-MARK-MODE-FLAG is non-nil then check if
90variable `transient-mark-mode' is active."
91 (cond ((featurep 'xemacs) ;XEmacs
92 `(and (boundp 'zmacs-regions) zmacs-regions (region-active-p)))
93 ((not check-transient-mark-mode-flag) ;GNU Emacs
94 `(and (boundp 'mark-active) mark-active))
95 (t ;GNU Emacs
96 `(and (boundp 'transient-mark-mode) transient-mark-mode
97 (boundp 'mark-active) mark-active))))
98
99(defmacro mh-defstruct (name-spec &rest fields)
100 "Replacement for `defstruct' from the `cl' package.
101The `defstruct' in the `cl' library produces compiler warnings, and generates
102code that uses functions present in `cl' at run-time. This is a partial
103replacement, that avoids these issues.
104
105NAME-SPEC declares the name of the structure, while FIELDS describes the
106various structure fields. Lookup `defstruct' for more details."
107 (let* ((struct-name (if (atom name-spec) name-spec (car name-spec)))
108 (conc-name (or (and (consp name-spec)
109 (cadr (assoc :conc-name (cdr name-spec))))
110 (format "%s-" struct-name)))
111 (predicate (intern (format "%s-p" struct-name)))
112 (constructor (or (and (consp name-spec)
113 (cadr (assoc :constructor (cdr name-spec))))
114 (intern (format "make-%s" struct-name))))
115 (field-names (mapcar #'(lambda (x) (if (atom x) x (car x))) fields))
116 (field-init-forms (mapcar #'(lambda (x) (and (consp x) (cadr x)))
117 fields))
118 (struct (gensym "S"))
119 (x (gensym "X"))
120 (y (gensym "Y")))
121 `(progn
122 (defun* ,constructor (&key ,@(mapcar* #'(lambda (x y) (list x y))
123 field-names field-init-forms))
124 (list ,@field-names))
125 (defun ,predicate (arg)
126 (and (consp arg) (eql (length arg) ,(length fields))))
127 ,@(loop for x from 0
128 for y in field-names
129 collect `(defmacro ,(intern (format "%s%s" conc-name y)) (z)
130 (list 'nth ,x z)))
131 (quote ,struct-name))))
132
133
134(provide 'mh-acros)
135
136;;; Local Variables:
137;;; no-byte-compile: t
138;;; indent-tabs-mode: nil
139;;; sentence-end-double-space: nil
140;;; End:
141
142;; arch-tag: b383b49a-494f-4ed0-a30a-cb6d5d2da4ff
143;;; mh-acros.el ends here
diff --git a/lisp/mh-e/mh-alias.el b/lisp/mh-e/mh-alias.el
index bd20b9118b0..1356e2c8b95 100644
--- a/lisp/mh-e/mh-alias.el
+++ b/lisp/mh-e/mh-alias.el
@@ -27,75 +27,12 @@
27 27
28;;; Commentary: 28;;; Commentary:
29 29
30;; [To be deleted when documented in MH-E manual.]
31;;
32;; This module provides mail alias completion when entering addresses.
33;;
34;; Use the TAB key to complete aliases (and optionally local usernames) when
35;; initially composing a message in the To: and Cc: minibuffer prompts. You
36;; may enter multiple addressees separated with a comma (but do *not* add any
37;; space after the comma).
38;;
39;; In the header of a message draft, use "M-TAB (mh-letter-complete)" to
40;; complete aliases. This is useful when you want to add an addressee as an
41;; afterthought when creating a message, or when adding an additional
42;; addressee to a reply.
43;;
44;; By default, completion is case-insensitive. This can be changed by
45;; customizing the variable `mh-alias-completion-ignore-case-flag'. This is
46;; useful, for example, to differentiate between people aliases in lowercase
47;; such as:
48;;
49;; p.galbraith: Peter Galbraith <GalbraithP@dfo-mpo.gc.ca>
50;;
51;; and lists in uppercase such as:
52;;
53;; MH-E: MH-E mailing list <mh-e-devel@lists.sourceforge.net>
54;;
55;; Note that this variable affects minibuffer completion only. If you have an
56;; alias for P.Galbraith and type in p.galbraith at the prompt, it will still
57;; be expanded in the letter buffer because MH is case-insensitive.
58;;
59;; When you press ", (mh-alias-minibuffer-confirm-address)" after an alias in
60;; the minibuffer, the expansion for the previous mail alias appears briefly.
61;; To inhibit this, customize the variable `mh-alias-flash-on-comma'.
62;;
63;; The addresses and aliases entered in the minibuffer are added to the
64;; message draft. To expand the aliases before they are added to the draft,
65;; customize the variable `mh-alias-expand-aliases-flag'.
66;;
67;; Completion is also performed on usernames extracted from the /etc/passwd
68;; file. This can be a handy tool on a machine where you and co-workers
69;; exchange messages, but should probably be disabled on a system with
70;; thousands of users you don't know. This is done by customizing the
71;; variable `mh-alias-local-users'. This variable also takes a string which
72;; is executed to generate the password file. For example, you'd use "ypcat
73;; passwd" for NIS.
74;;
75;; Aliases are loaded the first time you send mail and get the "To:" prompt
76;; and whenever a source of aliases changes. Sources of system aliases are
77;; defined in the customization variable `mh-alias-system-aliases' and
78;; include:
79;;
80;; /etc/nmh/MailAliases
81;; /usr/lib/mh/MailAliases
82;; /etc/passwd
83;;
84;; Sources of personal aliases are read from the files listed in your MH
85;; profile component Aliasfile. Multiple files are separated by white space
86;; and are relative to your mail directory.
87;;
88;; Alias Insertions
89;; ~~~~~~~~~~~~~~~~
90;; There are commands to insert new aliases into your alias file(s) (defined
91;; by the `Aliasfile' component in the .mh_profile file or by the variable
92;; `mh-alias-insert-file'). In particular, there is a tool-bar icon to grab
93;; an alias from the From line of the current message.
94
95;;; Change Log: 30;;; Change Log:
96 31
97;;; Code: 32;;; Code:
98 33
34(eval-when-compile (require 'mh-acros))
35(mh-require-cl)
99(require 'mh-e) 36(require 'mh-e)
100(load "cmr" t t) ; Non-fatal dependency for 37(load "cmr" t t) ; Non-fatal dependency for
101 ; completing-read-multiple. 38 ; completing-read-multiple.
@@ -116,15 +53,23 @@
116(defvar mh-alias-tstamp nil 53(defvar mh-alias-tstamp nil
117 "Time aliases were last loaded.") 54 "Time aliases were last loaded.")
118(defvar mh-alias-read-address-map nil) 55(defvar mh-alias-read-address-map nil)
119(if mh-alias-read-address-map 56(unless mh-alias-read-address-map
120 ()
121 (setq mh-alias-read-address-map 57 (setq mh-alias-read-address-map
122 (copy-keymap minibuffer-local-completion-map)) 58 (copy-keymap minibuffer-local-completion-map))
123 (if mh-alias-flash-on-comma 59 (define-key mh-alias-read-address-map
124 (define-key mh-alias-read-address-map 60 "," 'mh-alias-minibuffer-confirm-address)
125 "," 'mh-alias-minibuffer-confirm-address))
126 (define-key mh-alias-read-address-map " " 'self-insert-command)) 61 (define-key mh-alias-read-address-map " " 'self-insert-command))
127 62
63(defvar mh-alias-system-aliases
64 '("/etc/nmh/MailAliases" "/etc/mh/MailAliases"
65 "/usr/lib/mh/MailAliases" "/usr/share/mailutils/mh/MailAliases"
66 "/etc/passwd")
67 "*A list of system files which are a source of aliases.
68If these files are modified, they are automatically reread. This list need
69include only system aliases and the passwd file, since personal alias files
70listed in your `Aliasfile:' MH profile component are automatically included.
71You can update the alias list manually using \\[mh-alias-reload].")
72
128 73
129;;; Alias Loading 74;;; Alias Loading
130 75
@@ -138,7 +83,7 @@ This is a wrapper around `assoc-string' or `assoc-ignore-case'. Avoid
138 83
139(defun mh-alias-tstamp (arg) 84(defun mh-alias-tstamp (arg)
140 "Check whether alias files have been modified. 85 "Check whether alias files have been modified.
141Return t if any file listed in the MH profile component Aliasfile has been 86Return t if any file listed in the Aliasfile MH profile component has been
142modified since the timestamp. 87modified since the timestamp.
143If ARG is non-nil, set timestamp with the current time." 88If ARG is non-nil, set timestamp with the current time."
144 (if arg 89 (if arg
@@ -157,7 +102,7 @@ If ARG is non-nil, set timestamp with the current time."
157 102
158(defun mh-alias-filenames (arg) 103(defun mh-alias-filenames (arg)
159 "Return list of filenames that contain aliases. 104 "Return list of filenames that contain aliases.
160The filenames come from the MH profile component Aliasfile and are expanded. 105The filenames come from the Aliasfile profile component and are expanded.
161If ARG is non-nil, filenames listed in `mh-alias-system-aliases' are appended." 106If ARG is non-nil, filenames listed in `mh-alias-system-aliases' are appended."
162 (or mh-progs (mh-find-path)) 107 (or mh-progs (mh-find-path))
163 (save-excursion 108 (save-excursion
@@ -201,7 +146,8 @@ non-nil."
201 res)) 146 res))
202 147
203(defun mh-alias-local-users () 148(defun mh-alias-local-users ()
204 "Return an alist of local users from /etc/passwd." 149 "Return an alist of local users from /etc/passwd.
150Exclude all aliases already in `mh-alias-alist' from `ali'"
205 (let (passwd-alist) 151 (let (passwd-alist)
206 (save-excursion 152 (save-excursion
207 (set-buffer (get-buffer-create mh-temp-buffer)) 153 (set-buffer (get-buffer-create mh-temp-buffer))
@@ -222,23 +168,33 @@ non-nil."
222 (gecos-name (match-string 3)) 168 (gecos-name (match-string 3))
223 (realname (mh-alias-gecos-name 169 (realname (mh-alias-gecos-name
224 gecos-name username 170 gecos-name username
225 mh-alias-passwd-gecos-comma-separator-flag))) 171 mh-alias-passwd-gecos-comma-separator-flag))
226 (setq passwd-alist 172 (alias-name (if mh-alias-local-users-prefix
227 (cons 173 (concat mh-alias-local-users-prefix
228 (list (if mh-alias-local-users-prefix 174 (mh-alias-suggest-alias realname t))
229 (concat mh-alias-local-users-prefix 175 username))
230 (mh-alias-suggest-alias realname t)) 176 (alias-translation
231 username) 177 (if (string-equal username realname)
232 (if (string-equal username realname) 178 (concat "<" username ">")
233 (concat "<" username ">") 179 (concat realname " <" username ">"))))
234 (concat realname " <" username ">"))) 180 (when (not (mh-assoc-ignore-case alias-name mh-alias-alist))
235 passwd-alist)))))) 181 (setq passwd-alist (cons (list alias-name alias-translation)
182 passwd-alist)))))))
236 (forward-line 1))) 183 (forward-line 1)))
237 passwd-alist)) 184 passwd-alist))
238 185
239;;;###mh-autoload 186;;;###mh-autoload
240(defun mh-alias-reload () 187(defun mh-alias-reload ()
241 "Load MH aliases into `mh-alias-alist'." 188 "Reload MH aliases.
189
190Since aliases are updated frequently, MH-E will reload aliases automatically
191whenever an alias lookup occurs if an alias source (a file listed in your
192`Aliasfile:' profile component and your password file if variable
193`mh-alias-local-users' is non-nil) has changed. However, you can reload your
194aliases manually by calling this command directly.
195
196The value of `mh-alias-reloaded-hook' is a list of functions to be called,
197with no arguments, after the aliases have been loaded."
242 (interactive) 198 (interactive)
243 (save-excursion 199 (save-excursion
244 (message "Loading MH aliases...") 200 (message "Loading MH aliases...")
@@ -269,13 +225,14 @@ non-nil."
269 (if (not (mh-assoc-ignore-case (car user) mh-alias-alist)) 225 (if (not (mh-assoc-ignore-case (car user) mh-alias-alist))
270 (setq mh-alias-alist (append mh-alias-alist (list user)))) 226 (setq mh-alias-alist (append mh-alias-alist (list user))))
271 (setq local-users (cdr local-users))))) 227 (setq local-users (cdr local-users)))))
228 (run-hooks 'mh-alias-reloaded-hook)
272 (message "Loading MH aliases...done")) 229 (message "Loading MH aliases...done"))
273 230
274;;;###mh-autoload 231;;;###mh-autoload
275(defun mh-alias-reload-maybe () 232(defun mh-alias-reload-maybe ()
276 "Load new MH aliases." 233 "Load new MH aliases."
277 (if (or (eq mh-alias-alist 'not-read) ; Doesn't exist, so create it. 234 (if (or (eq mh-alias-alist 'not-read) ; Doesn't exist?
278 (mh-alias-tstamp nil)) ; Out of date, so recreate it. 235 (mh-alias-tstamp nil)) ; Out of date?
279 (mh-alias-reload))) 236 (mh-alias-reload)))
280 237
281 238
@@ -461,21 +418,21 @@ is converted to lower case."
461 found))) 418 found)))
462 419
463(defun mh-alias-insert-file (&optional alias) 420(defun mh-alias-insert-file (&optional alias)
464 "Return the alias file to write a new entry for ALIAS in. 421 "Return filename which should be used to add ALIAS.
465Use variable `mh-alias-insert-file' if non-nil, else use AliasFile component 422The value of the option `mh-alias-insert-file' is used if non-nil\; otherwise
466value. 423the value of the `Aliasfile:' profile component is used.
467If ALIAS is specified and it already exists, try to return the file that 424If the alias already exists, try to return the name of the file that contains
468contains it." 425it."
469 (cond 426 (cond
470 ((and mh-alias-insert-file (listp mh-alias-insert-file)) 427 ((and mh-alias-insert-file (listp mh-alias-insert-file))
471 (if (not (elt mh-alias-insert-file 1)) ; Only one entry, use it 428 (if (not (elt mh-alias-insert-file 1)) ; Only one entry, use it
472 (car mh-alias-insert-file) 429 (car mh-alias-insert-file)
473 (if (or (not alias) 430 (if (or (not alias)
474 (string-equal alias (mh-alias-ali alias))) ;alias doesn't exist 431 (string-equal alias (mh-alias-ali alias))) ;alias doesn't exist
475 (completing-read "Alias file [press Tab]: " 432 (completing-read "Alias file: "
476 (mapcar 'list mh-alias-insert-file) nil t) 433 (mapcar 'list mh-alias-insert-file) nil t)
477 (or (mh-alias-which-file-has-alias alias mh-alias-insert-file) 434 (or (mh-alias-which-file-has-alias alias mh-alias-insert-file)
478 (completing-read "Alias file [press Tab]: " 435 (completing-read "Alias file: "
479 (mapcar 'list mh-alias-insert-file) nil t))))) 436 (mapcar 'list mh-alias-insert-file) nil t)))))
480 ((and mh-alias-insert-file (stringp mh-alias-insert-file)) 437 ((and mh-alias-insert-file (stringp mh-alias-insert-file))
481 mh-alias-insert-file) 438 mh-alias-insert-file)
@@ -490,16 +447,15 @@ contains it."
490 (cond 447 (cond
491 ((not autolist) 448 ((not autolist)
492 (error "No writable alias file. 449 (error "No writable alias file.
493Set `mh-alias-insert-file' or set AliasFile in your .mh_profile file")) 450Set `mh-alias-insert-file' or the Aliasfile profile component"))
494 ((not (elt autolist 1)) ; Only one entry, use it 451 ((not (elt autolist 1)) ; Only one entry, use it
495 (car autolist)) 452 (car autolist))
496 ((or (not alias) 453 ((or (not alias)
497 (string-equal alias (mh-alias-ali alias))) ;alias doesn't exist 454 (string-equal alias (mh-alias-ali alias))) ;alias doesn't exist
498 (completing-read "Alias file [press Tab]: " 455 (completing-read "Alias file: " (mapcar 'list autolist) nil t))
499 (mapcar 'list autolist) nil t))
500 (t 456 (t
501 (or (mh-alias-which-file-has-alias alias autolist) 457 (or (mh-alias-which-file-has-alias alias autolist)
502 (completing-read "Alias file [press Tab]: " 458 (completing-read "Alias file: "
503 (mapcar 'list autolist) nil t)))))))) 459 (mapcar 'list autolist) nil t))))))))
504 460
505;;;###mh-autoload 461;;;###mh-autoload
@@ -520,10 +476,8 @@ Set `mh-alias-insert-file' or set AliasFile in your .mh_profile file"))
520 (split-string aliases ", +"))))))) 476 (split-string aliases ", +")))))))
521 477
522;;;###mh-autoload 478;;;###mh-autoload
523(defun mh-alias-from-has-no-alias-p () 479(defun mh-alias-for-from-p ()
524 "Return t is From has no current alias set. 480 "Return t if sender's address has a corresponding alias."
525In the exceptional situation where there isn't a From header in the message the
526function returns nil."
527 (mh-alias-reload-maybe) 481 (mh-alias-reload-maybe)
528 (save-excursion 482 (save-excursion
529 (if (not (mh-folder-line-matches-show-buffer-p)) 483 (if (not (mh-folder-line-matches-show-buffer-p))
@@ -532,13 +486,16 @@ function returns nil."
532 (set-buffer mh-show-buffer)) 486 (set-buffer mh-show-buffer))
533 (let ((from-header (mh-extract-from-header-value))) 487 (let ((from-header (mh-extract-from-header-value)))
534 (and from-header 488 (and from-header
535 (not (mh-alias-address-to-alias from-header))))))) 489 (mh-alias-address-to-alias from-header))))))
536 490
537(defun mh-alias-add-alias-to-file (alias address &optional file) 491(defun mh-alias-add-alias-to-file (alias address &optional file)
538 "Add ALIAS for ADDRESS in alias FILE without alias check or prompts. 492 "Add ALIAS for ADDRESS in alias FILE without alias check or prompts.
539Prompt for alias file if not provided and there is more than one candidate. 493Prompt for alias file if not provided and there is more than one candidate.
540If ALIAS matches exactly, prompt to [i]nsert before old value or [a]ppend 494
541after it." 495If the alias exists already, you will have the choice of inserting the new
496alias before or after the old alias. In the former case, this alias will be
497used when sending mail to this alias. In the latter case, the alias serves as
498an additional folder name hint when filing messages."
542 (if (not file) 499 (if (not file)
543 (setq file (mh-alias-insert-file alias))) 500 (setq file (mh-alias-insert-file alias)))
544 (save-excursion 501 (save-excursion
@@ -552,14 +509,15 @@ after it."
552 ((re-search-forward 509 ((re-search-forward
553 (concat "^" (regexp-quote alias-search) " *\\(.*\\)") nil t) 510 (concat "^" (regexp-quote alias-search) " *\\(.*\\)") nil t)
554 (let ((answer (read-string 511 (let ((answer (read-string
555 (format "Exists for %s; [i]nsert, [a]ppend: " 512 (format (concat "Alias %s exists; insert new address "
513 "[b]efore or [a]fter: ")
556 (match-string 1)))) 514 (match-string 1))))
557 (case-fold-search t)) 515 (case-fold-search t))
558 (cond ((string-match "^i" answer)) 516 (cond ((string-match "^b" answer))
559 ((string-match "^a" answer) 517 ((string-match "^a" answer)
560 (forward-line 1)) 518 (forward-line 1))
561 (t 519 (t
562 (error "Quitting"))))) 520 (error "Unrecognized response")))))
563 ;; No, so sort-in at the right place 521 ;; No, so sort-in at the right place
564 ;; search for "^alias", then "^alia", etc. 522 ;; search for "^alias", then "^alia", etc.
565 ((eq mh-alias-insertion-location 'sorted) 523 ((eq mh-alias-insertion-location 'sorted)
@@ -587,8 +545,11 @@ after it."
587;;;###mh-autoload 545;;;###mh-autoload
588(defun mh-alias-add-alias (alias address) 546(defun mh-alias-add-alias (alias address)
589 "*Add ALIAS for ADDRESS in personal alias file. 547 "*Add ALIAS for ADDRESS in personal alias file.
590Prompts for confirmation if the address already has an alias. 548This function prompts you for an alias and address. If the alias exists
591If the alias is already is use, `mh-alias-add-alias-to-file' will prompt." 549already, you will have the choice of inserting the new alias before or after
550the old alias. In the former case, this alias will be used when sending mail
551to this alias. In the latter case, the alias serves as an additional folder
552name hint when filing messages."
592 (interactive "P\nP") 553 (interactive "P\nP")
593 (mh-alias-reload-maybe) 554 (mh-alias-reload-maybe)
594 (setq alias (completing-read "Alias: " mh-alias-alist nil nil alias)) 555 (setq alias (completing-read "Alias: " mh-alias-alist nil nil alias))
@@ -614,9 +575,7 @@ If the alias is already is use, `mh-alias-add-alias-to-file' will prompt."
614 575
615;;;###mh-autoload 576;;;###mh-autoload
616(defun mh-alias-grab-from-field () 577(defun mh-alias-grab-from-field ()
617 "*Add ALIAS for ADDRESS in personal alias file. 578 "*Add alias for the sender of the current message."
618Prompts for confirmation if the alias is already in use or if the address
619already has an alias."
620 (interactive) 579 (interactive)
621 (mh-alias-reload-maybe) 580 (mh-alias-reload-maybe)
622 (save-excursion 581 (save-excursion
@@ -636,24 +595,26 @@ already has an alias."
636 595
637;;;###mh-autoload 596;;;###mh-autoload
638(defun mh-alias-add-address-under-point () 597(defun mh-alias-add-address-under-point ()
639 "Insert an alias for email address under point." 598 "Insert an alias for address under point."
640 (interactive) 599 (interactive)
641 (let ((address (mh-goto-address-find-address-at-point))) 600 (let ((address (mh-goto-address-find-address-at-point)))
642 (if address 601 (if address
643 (mh-alias-add-alias nil address) 602 (mh-alias-add-alias nil address)
644 (message "No email address found under point.")))) 603 (message "No email address found under point"))))
645 604
646;;;###mh-autoload 605;;;###mh-autoload
647(defun mh-alias-apropos (regexp) 606(defun mh-alias-apropos (regexp)
648 "Show all aliases that match REGEXP either in name or content." 607 "Show all aliases or addresses that match REGEXP."
649 (interactive "sAlias regexp: ") 608 (interactive "sAlias regexp: ")
650 (if mh-alias-local-users 609 (if mh-alias-local-users
651 (mh-alias-reload-maybe)) 610 (mh-alias-reload-maybe))
652 (let ((matches "")(group-matches "")(passwd-matches)) 611 (let ((matches "")
612 (group-matches "")
613 (passwd-matches))
653 (save-excursion 614 (save-excursion
654 (message "Reading MH aliases...") 615 (message "Reading MH aliases...")
655 (mh-exec-cmd-quiet t "ali" "-nolist" "-nouser") 616 (mh-exec-cmd-quiet t "ali" "-nolist" "-nouser")
656 (message "Reading MH aliases...done. Parsing...") 617 (message "Parsing MH aliases...")
657 (while (re-search-forward regexp nil t) 618 (while (re-search-forward regexp nil t)
658 (beginning-of-line) 619 (beginning-of-line)
659 (cond 620 (cond
@@ -673,10 +634,9 @@ already has an alias."
673 (concat matches 634 (concat matches
674 (buffer-substring (point)(progn (end-of-line)(point))) 635 (buffer-substring (point)(progn (end-of-line)(point)))
675 "\n"))))) 636 "\n")))))
676 (message "Reading MH aliases...done. Parsing...done.") 637 (message "Parsing MH aliases...done")
677 (when mh-alias-local-users 638 (when mh-alias-local-users
678 (message 639 (message "Making passwd aliases...")
679 "Reading MH aliases...done. Parsing...done. Passwd aliases...")
680 (setq passwd-matches 640 (setq passwd-matches
681 (mapconcat 641 (mapconcat
682 '(lambda (elem) 642 '(lambda (elem)
@@ -684,13 +644,12 @@ already has an alias."
684 (string-match regexp (cadr elem))) 644 (string-match regexp (cadr elem)))
685 (format "%s: %s\n" (car elem) (cadr elem)))) 645 (format "%s: %s\n" (car elem) (cadr elem))))
686 mh-alias-passwd-alist "")) 646 mh-alias-passwd-alist ""))
687 (message 647 (message "Making passwd aliases...done")))
688 "Reading MH aliases...done. Parsing...done. Passwd aliases...done.")))
689 (if (and (string-equal "" matches) 648 (if (and (string-equal "" matches)
690 (string-equal "" group-matches) 649 (string-equal "" group-matches)
691 (string-equal "" passwd-matches)) 650 (string-equal "" passwd-matches))
692 (message "No matches") 651 (message "No matches")
693 (with-output-to-temp-buffer "*Help*" 652 (with-output-to-temp-buffer mh-aliases-buffer
694 (if (not (string-equal "" matches)) 653 (if (not (string-equal "" matches))
695 (princ matches)) 654 (princ matches))
696 (when (not (string-equal group-matches "")) 655 (when (not (string-equal group-matches ""))
diff --git a/lisp/mh-e/mh-comp.el b/lisp/mh-e/mh-comp.el
index 489b6690bc7..cde52c65043 100644
--- a/lisp/mh-e/mh-comp.el
+++ b/lisp/mh-e/mh-comp.el
@@ -33,11 +33,12 @@
33 33
34;;; Code: 34;;; Code:
35 35
36(eval-when-compile (require 'mh-acros))
37(mh-require-cl)
36(require 'mh-e) 38(require 'mh-e)
37(require 'gnus-util) 39(require 'gnus-util)
38(require 'easymenu) 40(require 'easymenu)
39(require 'mh-utils) 41(require 'mh-gnus)
40(mh-require-cl)
41(eval-when (compile load eval) 42(eval-when (compile load eval)
42 (ignore-errors (require 'mailabbrev))) 43 (ignore-errors (require 'mailabbrev)))
43 44
@@ -48,6 +49,7 @@
48(defvar sendmail-coding-system) 49(defvar sendmail-coding-system)
49(defvar mh-identity-list) 50(defvar mh-identity-list)
50(defvar mh-identity-default) 51(defvar mh-identity-default)
52(defvar mh-mml-mode-default)
51(defvar mh-identity-menu) 53(defvar mh-identity-menu)
52 54
53;;; Autoloads 55;;; Autoloads
@@ -58,7 +60,7 @@
58(autoload 'sc-cite-original "sc" 60(autoload 'sc-cite-original "sc"
59 "Workhorse citing function which performs the initial citation. 61 "Workhorse citing function which performs the initial citation.
60This is callable from the various mail and news readers' reply 62This is callable from the various mail and news readers' reply
61function according to the agreed upon standard. See `\\[sc-describe]' 63function according to the agreed upon standard. See `sc-describe'
62for more details. `sc-cite-original' does not do any yanking of the 64for more details. `sc-cite-original' does not do any yanking of the
63original message but it does require a few things: 65original message but it does require a few things:
64 66
@@ -95,14 +97,16 @@ If MH will not allow you to redist a previously redist'd msg, set to nil.")
95This allows transaction log to be visible if -watch, -verbose or -snoop are 97This allows transaction log to be visible if -watch, -verbose or -snoop are
96used.") 98used.")
97 99
98(defvar mh-note-repl "-" 100;;; Scan Line Formats
99 "String whose first character is used to notate replied to messages.") 101
102(defvar mh-note-repl ?-
103 "Messages that have been replied to are marked by this character.")
100 104
101(defvar mh-note-forw "F" 105(defvar mh-note-forw ?F
102 "String whose first character is used to notate forwarded messages.") 106 "Messages that have been forwarded are marked by this character.")
103 107
104(defvar mh-note-dist "R" 108(defvar mh-note-dist ?R
105 "String whose first character is used to notate redistributed messages.") 109 "Messages that have been redistributed are marked by this character.")
106 110
107(defvar mh-yank-hooks nil 111(defvar mh-yank-hooks nil
108 "Obsolete hook for modifying a citation just inserted in the mail buffer. 112 "Obsolete hook for modifying a citation just inserted in the mail buffer.
@@ -113,23 +117,6 @@ text as modified.
113This is a normal hook, misnamed for historical reasons. 117This is a normal hook, misnamed for historical reasons.
114It is semi-obsolete and is only used if `mail-citation-hook' is nil.") 118It is semi-obsolete and is only used if `mail-citation-hook' is nil.")
115 119
116(defvar mail-citation-hook nil
117 "*Hook for modifying a citation just inserted in the mail buffer.
118Each hook function can find the citation between point and mark.
119And each hook function should leave point and mark around the citation
120text as modified.
121
122If this hook is entirely empty (nil), the text of the message is inserted
123with `mh-ins-buf-prefix' prefixed to each line.
124
125See also the variable `mh-yank-from-start-of-msg', which controls how
126much of the message passed to the hook.
127
128This hook was historically provided to set up supercite. You may now leave
129this nil and set up supercite by setting the variable
130`mh-yank-from-start-of-msg' to 'supercite or, for more automatic insertion,
131to 'autosupercite.")
132
133(defvar mh-comp-formfile "components" 120(defvar mh-comp-formfile "components"
134 "Name of file to be used as a skeleton for composing messages. 121 "Name of file to be used as a skeleton for composing messages.
135Default is \"components\". If not an absolute file name, the file 122Default is \"components\". If not an absolute file name, the file
@@ -145,7 +132,8 @@ system MH lib directory.")
145(defvar mh-repl-group-formfile "replgroupcomps" 132(defvar mh-repl-group-formfile "replgroupcomps"
146 "Name of file to be used as a skeleton for replying to messages. 133 "Name of file to be used as a skeleton for replying to messages.
147This file is used to form replies to the sender and all recipients of a 134This file is used to form replies to the sender and all recipients of a
148message. Only used if `mh-nmh-flag' is non-nil. Default is \"replgroupcomps\". 135message. Only used if `(mh-variant-p 'nmh)' is non-nil.
136Default is \"replgroupcomps\".
149If not an absolute file name, the file is searched for first in the user's MH 137If not an absolute file name, the file is searched for first in the user's MH
150directory, then in the system MH lib directory.") 138directory, then in the system MH lib directory.")
151 139
@@ -153,6 +141,8 @@ directory, then in the system MH lib directory.")
153 (format "^%s$" 141 (format "^%s$"
154 (regexp-opt 142 (regexp-opt
155 '("Content-Type: message/rfc822" ;MIME MDN 143 '("Content-Type: message/rfc822" ;MIME MDN
144 "------ This is a copy of the message, including all the headers. ------";from exim
145 "--- Below this line is a copy of the message."; from qmail
156 " ----- Unsent message follows -----" ;from sendmail V5 146 " ----- Unsent message follows -----" ;from sendmail V5
157 " --------Unsent Message below:" ; from sendmail at BU 147 " --------Unsent Message below:" ; from sendmail at BU
158 " ----- Original message follows -----" ;from sendmail V8 148 " ----- Original message follows -----" ;from sendmail V8
@@ -201,16 +191,16 @@ Used by the \\<mh-folder-mode-map>`\\[mh-edit-again]' and `\\[mh-extract-rejecte
201 "Field name for message annotation.") 191 "Field name for message annotation.")
202 192
203(defvar mh-insert-auto-fields-done-local nil 193(defvar mh-insert-auto-fields-done-local nil
204 "Buffer-local variable set when `mh-insert-auto-fields' successfully called.") 194 "Buffer-local variable set when `mh-insert-auto-fields' called successfully.")
205(make-variable-buffer-local 'mh-insert-auto-fields-done-local) 195(make-variable-buffer-local 'mh-insert-auto-fields-done-local)
206 196
207;;;###autoload 197;;;###autoload
208(defun mh-smail () 198(defun mh-smail ()
209 "Compose and send mail with the MH mail system. 199 "Compose and send mail with the MH mail system.
210This function is an entry point to MH-E, the Emacs front end 200This function is an entry point to MH-E, the Emacs interface to the MH mail
211to the MH mail system. 201system.
212 202
213See documentation of `\\[mh-send]' for more details on composing mail." 203See `mh-send' for more details on composing mail."
214 (interactive) 204 (interactive)
215 (mh-find-path) 205 (mh-find-path)
216 (call-interactively 'mh-send)) 206 (call-interactively 'mh-send))
@@ -220,11 +210,11 @@ See documentation of `\\[mh-send]' for more details on composing mail."
220;;;###autoload 210;;;###autoload
221(defun mh-smail-batch (&optional to subject other-headers &rest ignored) 211(defun mh-smail-batch (&optional to subject other-headers &rest ignored)
222 "Set up a mail composition draft with the MH mail system. 212 "Set up a mail composition draft with the MH mail system.
223This function is an entry point to MH-E, the Emacs front end 213This function is an entry point to MH-E, the Emacs interface to the MH mail
224to the MH mail system. This function does not prompt the user 214system. This function does not prompt the user for any header fields, and thus
225for any header fields, and thus is suitable for use by programs 215is suitable for use by programs that want to create a mail buffer. Users
226that want to create a mail buffer. 216should use `mh-smail' to compose mail.
227Users should use `\\[mh-smail]' to compose mail. 217
228Optional arguments for setting certain fields include TO, SUBJECT, and 218Optional arguments for setting certain fields include TO, SUBJECT, and
229OTHER-HEADERS. Additional arguments are IGNORED." 219OTHER-HEADERS. Additional arguments are IGNORED."
230 (mh-find-path) 220 (mh-find-path)
@@ -260,7 +250,8 @@ CONTINUE, SWITCH-FUNCTION, YANK-ACTION and SEND-ACTIONS are ignored."
260 "Clean up a draft or a message MSG previously sent and make it resendable. 250 "Clean up a draft or a message MSG previously sent and make it resendable.
261Default is the current message. 251Default is the current message.
262The variable `mh-new-draft-cleaned-headers' specifies the headers to remove. 252The variable `mh-new-draft-cleaned-headers' specifies the headers to remove.
263See also documentation for `\\[mh-send]' function." 253
254See also `mh-send'."
264 (interactive (list (mh-get-msg-num t))) 255 (interactive (list (mh-get-msg-num t)))
265 (let* ((from-folder mh-current-folder) 256 (let* ((from-folder mh-current-folder)
266 (config (current-window-configuration)) 257 (config (current-window-configuration))
@@ -292,7 +283,8 @@ See also documentation for `\\[mh-send]' function."
292 "Extract message MSG returned by the mail system and make it resendable. 283 "Extract message MSG returned by the mail system and make it resendable.
293Default is the current message. The variable `mh-new-draft-cleaned-headers' 284Default is the current message. The variable `mh-new-draft-cleaned-headers'
294gives the headers to clean out of the original message. 285gives the headers to clean out of the original message.
295See also documentation for `\\[mh-send]' function." 286
287See also `mh-send'."
296 (interactive (list (mh-get-msg-num t))) 288 (interactive (list (mh-get-msg-num t)))
297 (let ((from-folder mh-current-folder) 289 (let ((from-folder mh-current-folder)
298 (config (current-window-configuration)) 290 (config (current-window-configuration))
@@ -303,7 +295,7 @@ See also documentation for `\\[mh-send]' function."
303 (delete-region (point-min) (point)) 295 (delete-region (point-min) (point))
304 (mh-clean-msg-header (point-min) mh-new-draft-cleaned-headers nil)) 296 (mh-clean-msg-header (point-min) mh-new-draft-cleaned-headers nil))
305 (t 297 (t
306 (message "Does not appear to be a rejected letter."))) 298 (message "Does not appear to be a rejected letter")))
307 (mh-insert-header-separator) 299 (mh-insert-header-separator)
308 (goto-char (point-min)) 300 (goto-char (point-min))
309 (save-buffer) 301 (save-buffer)
@@ -323,7 +315,7 @@ Default is the displayed message.
323Check the documentation of `mh-interactive-range' to see how RANGE is read in 315Check the documentation of `mh-interactive-range' to see how RANGE is read in
324interactive use. 316interactive use.
325 317
326See also documentation for `\\[mh-send]' function." 318See also `mh-send'."
327 (interactive (list (mh-interactive-read-address "To: ") 319 (interactive (list (mh-interactive-read-address "To: ")
328 (mh-interactive-read-address "Cc: ") 320 (mh-interactive-read-address "Cc: ")
329 (mh-interactive-range "Forward"))) 321 (mh-interactive-range "Forward")))
@@ -335,7 +327,10 @@ See also documentation for `\\[mh-send]' function."
335 (draft-name (expand-file-name "draft" mh-user-path)) 327 (draft-name (expand-file-name "draft" mh-user-path))
336 (draft (cond ((or (not (file-exists-p draft-name)) 328 (draft (cond ((or (not (file-exists-p draft-name))
337 (y-or-n-p "The file 'draft' exists. Discard it? ")) 329 (y-or-n-p "The file 'draft' exists. Discard it? "))
338 (mh-exec-cmd "forw" "-build" (if mh-nmh-flag "-mime") 330 (mh-exec-cmd "forw" "-build"
331 (if (and (mh-variant-p 'nmh)
332 mh-compose-forward-as-mime-flag)
333 "-mime")
339 mh-current-folder 334 mh-current-folder
340 (mh-coalesce-msg-list msgs)) 335 (mh-coalesce-msg-list msgs))
341 (prog1 336 (prog1
@@ -388,7 +383,8 @@ See also documentation for `\\[mh-send]' function."
388 mh-note-forw "Forwarded:" 383 mh-note-forw "Forwarded:"
389 config) 384 config)
390 (mh-letter-mode-message) 385 (mh-letter-mode-message)
391 (mh-letter-adjust-point))))) 386 (mh-letter-adjust-point)
387 (run-hooks 'mh-forward-hook)))))
392 388
393(defun mh-forwarded-letter-subject (from subject) 389(defun mh-forwarded-letter-subject (from subject)
394 "Return a Subject suitable for a forwarded message. 390 "Return a Subject suitable for a forwarded message.
@@ -406,10 +402,10 @@ Original message has headers FROM and SUBJECT."
406;;;###autoload 402;;;###autoload
407(defun mh-smail-other-window () 403(defun mh-smail-other-window ()
408 "Compose and send mail in other window with the MH mail system. 404 "Compose and send mail in other window with the MH mail system.
409This function is an entry point to MH-E, the Emacs front end 405This function is an entry point to MH-E, the Emacs interface to the MH mail
410to the MH mail system. 406system.
411 407
412See documentation of `\\[mh-send]' for more details on composing mail." 408See `mh-send' for more details on composing mail."
413 (interactive) 409 (interactive)
414 (mh-find-path) 410 (mh-find-path)
415 (call-interactively 'mh-send-other-window)) 411 (call-interactively 'mh-send-other-window))
@@ -496,13 +492,15 @@ to reply to:
496If optional prefix argument INCLUDEP provided, then include the message 492If optional prefix argument INCLUDEP provided, then include the message
497in the reply using filter `mhl.reply' in your MH directory. 493in the reply using filter `mhl.reply' in your MH directory.
498If the file named by `mh-repl-formfile' exists, it is used as a skeleton 494If the file named by `mh-repl-formfile' exists, it is used as a skeleton
499for the reply. See also documentation for `\\[mh-send]' function." 495for the reply.
496
497See also `mh-send'."
500 (interactive (list 498 (interactive (list
501 (mh-get-msg-num t) 499 (mh-get-msg-num t)
502 (let ((minibuffer-help-form 500 (let ((minibuffer-help-form
503 "from => Sender only\nto => Sender and primary recipients\ncc or all => Sender and all recipients")) 501 "from => Sender only\nto => Sender and primary recipients\ncc or all => Sender and all recipients"))
504 (or mh-reply-default-reply-to 502 (or mh-reply-default-reply-to
505 (completing-read "Reply to whom? (from, to, all) [from]: " 503 (completing-read "Reply to whom: [from] "
506 '(("from") ("to") ("cc") ("all")) 504 '(("from") ("to") ("cc") ("all"))
507 nil 505 nil
508 t))) 506 t)))
@@ -511,7 +509,7 @@ for the reply. See also documentation for `\\[mh-send]' function."
511 (show-buffer mh-show-buffer) 509 (show-buffer mh-show-buffer)
512 (config (current-window-configuration)) 510 (config (current-window-configuration))
513 (group-reply (or (equal reply-to "cc") (equal reply-to "all"))) 511 (group-reply (or (equal reply-to "cc") (equal reply-to "all")))
514 (form-file (cond ((and mh-nmh-flag group-reply 512 (form-file (cond ((and (mh-variant-p 'nmh 'mu-mh) group-reply
515 (stringp mh-repl-group-formfile)) 513 (stringp mh-repl-group-formfile))
516 mh-repl-group-formfile) 514 mh-repl-group-formfile)
517 ((stringp mh-repl-formfile) mh-repl-formfile) 515 ((stringp mh-repl-formfile) mh-repl-formfile)
@@ -525,7 +523,7 @@ for the reply. See also documentation for `\\[mh-send]' function."
525 '("-nocc" "all")) 523 '("-nocc" "all"))
526 ((equal reply-to "to") 524 ((equal reply-to "to")
527 '("-cc" "to")) 525 '("-cc" "to"))
528 (group-reply (if mh-nmh-flag 526 (group-reply (if (mh-variant-p 'nmh 'mu-mh)
529 '("-group" "-nocc" "me") 527 '("-group" "-nocc" "me")
530 '("-cc" "all" "-nocc" "me")))) 528 '("-cc" "all" "-nocc" "me"))))
531 (cond ((or (eq mh-yank-from-start-of-msg 'autosupercite) 529 (cond ((or (eq mh-yank-from-start-of-msg 'autosupercite)
@@ -562,7 +560,6 @@ for the reply. See also documentation for `\\[mh-send]' function."
562;;;###mh-autoload 560;;;###mh-autoload
563(defun mh-send (to cc subject) 561(defun mh-send (to cc subject)
564 "Compose and send a letter. 562 "Compose and send a letter.
565
566Do not call this function from outside MH-E; use \\[mh-smail] instead. 563Do not call this function from outside MH-E; use \\[mh-smail] instead.
567 564
568The file named by `mh-comp-formfile' will be used as the form. 565The file named by `mh-comp-formfile' will be used as the form.
@@ -581,7 +578,6 @@ passed three arguments: TO, CC, and SUBJECT."
581;;;###mh-autoload 578;;;###mh-autoload
582(defun mh-send-other-window (to cc subject) 579(defun mh-send-other-window (to cc subject)
583 "Compose and send a letter in another window. 580 "Compose and send a letter in another window.
584
585Do not call this function from outside MH-E; use \\[mh-smail-other-window] 581Do not call this function from outside MH-E; use \\[mh-smail-other-window]
586instead. 582instead.
587 583
@@ -711,6 +707,8 @@ Do not insert any pairs whose value is the empty string."
711 (while name-values 707 (while name-values
712 (let ((field-name (car name-values)) 708 (let ((field-name (car name-values))
713 (value (car (cdr name-values)))) 709 (value (car (cdr name-values))))
710 (if (not (string-match "^.*:$" field-name))
711 (setq field-name (concat field-name ":")))
714 (cond ((equal value "") 712 (cond ((equal value "")
715 nil) 713 nil)
716 ((mh-position-on-field field-name) 714 ((mh-position-on-field field-name)
@@ -730,6 +728,7 @@ The optional second arg is for pre-version 4 compatibility and is IGNORED."
730 ((mh-goto-header-end 0) 728 ((mh-goto-header-end 0)
731 nil))) 729 nil)))
732 730
731;;;###mh-autoload
733(defun mh-get-header-field (field) 732(defun mh-get-header-field (field)
734 "Find and return the body of FIELD in the mail header. 733 "Find and return the body of FIELD in the mail header.
735Returns the empty string if the field is not in the header of the 734Returns the empty string if the field is not in the header of the
@@ -777,35 +776,53 @@ Returns t if found, nil if not."
777 776
778;;; Menu extracted from mh-menubar.el V1.1 (31 July 2001) 777;;; Menu extracted from mh-menubar.el V1.1 (31 July 2001)
779(eval-when-compile (defvar mh-letter-menu nil)) 778(eval-when-compile (defvar mh-letter-menu nil))
780(cond 779(easy-menu-define
781 ((fboundp 'easy-menu-define) 780 mh-letter-menu mh-letter-mode-map "Menu for MH-E letter mode."
782 (easy-menu-define 781 '("Letter"
783 mh-letter-menu mh-letter-mode-map "Menu for MH-E letter mode." 782 ["Send This Draft" mh-send-letter t]
784 '("Letter" 783 ["Split Current Line" mh-open-line t]
785 ["Send This Draft" mh-send-letter t] 784 ["Check Recipient" mh-check-whom t]
786 ["Split Current Line" mh-open-line t] 785 ["Yank Current Message" mh-yank-cur-msg t]
787 ["Check Recipient" mh-check-whom t] 786 ["Insert a Message..." mh-insert-letter t]
788 ["Yank Current Message" mh-yank-cur-msg t] 787 ["Insert Signature" mh-insert-signature t]
789 ["Insert a Message..." mh-insert-letter t] 788 ("Encrypt/Sign Message"
790 ["Insert Signature" mh-insert-signature t] 789 ["Sign Message"
791 ["GPG Sign message" 790 mh-mml-secure-message-sign mh-gnus-pgp-support-flag]
792 mh-mml-secure-message-sign-pgpmime mh-gnus-pgp-support-flag] 791 ["Encrypt Message"
793 ["GPG Encrypt message" 792 mh-mml-secure-message-encrypt mh-gnus-pgp-support-flag]
794 mh-mml-secure-message-encrypt-pgpmime mh-gnus-pgp-support-flag] 793 ["Sign+Encrypt Message"
795 ["Compose Insertion (MIME)..." mh-compose-insertion t] 794 mh-mml-secure-message-signencrypt mh-gnus-pgp-support-flag]
796 ;; ["Compose Compressed tar (MIME)..." 795 ["Disable Security"
797 ;;mh-mhn-compose-external-compressed-tar t] 796 mh-mml-unsecure-message mh-gnus-pgp-support-flag]
798 ;; ["Compose Anon FTP (MIME)..." mh-mhn-compose-anon-ftp t] 797 "--"
799 ["Compose Forward (MIME)..." mh-compose-forward t] 798 "Security Method"
800 ;; The next two will have to be merged. But I also need to make sure the 799 ["PGP (MIME)" (setq mh-mml-method-default "pgpmime")
801 ;; user can't mix directives of both types. 800 :style radio
802 ["Pull in All Compositions (mhn)" 801 :selected (equal mh-mml-method-default "pgpmime")]
803 mh-edit-mhn (mh-mhn-directive-present-p)] 802 ["PGP" (setq mh-mml-method-default "pgp")
804 ["Pull in All Compositions (gnus)" 803 :style radio
805 mh-mml-to-mime (mh-mml-directive-present-p)] 804 :selected (equal mh-mml-method-default "pgp")]
806 ["Revert to Non-MIME Edit (mhn)" 805 ["S/MIME" (setq mh-mml-method-default "smime")
807 mh-revert-mhn-edit (equal mh-compose-insertion 'mhn)] 806 :style radio
808 ["Kill This Draft" mh-fully-kill-draft t])))) 807 :selected (equal mh-mml-method-default "smime")]
808 "--"
809 ["Save Method as Default"
810 (customize-save-variable 'mh-mml-method-default mh-mml-method-default) t]
811 )
812 ["Compose Insertion (MIME)..." mh-compose-insertion t]
813 ["Compose Compressed tar (MIME)..."
814 mh-mhn-compose-external-compressed-tar t]
815 ["Compose Get File (MIME)..." mh-mhn-compose-anon-ftp t]
816 ["Compose Forward (MIME)..." mh-compose-forward t]
817 ;; The next two will have to be merged. But I also need to make sure the
818 ;; user can't mix directives of both types.
819 ["Pull in All Compositions (mhn)"
820 mh-edit-mhn (mh-mhn-directive-present-p)]
821 ["Pull in All Compositions (gnus)"
822 mh-mml-to-mime (mh-mml-directive-present-p)]
823 ["Revert to Non-MIME Edit (mhn)"
824 mh-revert-mhn-edit (equal mh-compose-insertion 'mhn)]
825 ["Kill This Draft" mh-fully-kill-draft t]))
809 826
810;;; Help Messages 827;;; Help Messages
811;;; Group messages logically, more or less. 828;;; Group messages logically, more or less.
@@ -817,12 +834,15 @@ Returns t if found, nil if not."
817 "\t\tInsert:\n" 834 "\t\tInsert:\n"
818 "Check recipients: \\[mh-check-whom]" 835 "Check recipients: \\[mh-check-whom]"
819 "\t\t Current message: \\[mh-yank-cur-msg]\n" 836 "\t\t Current message: \\[mh-yank-cur-msg]\n"
820 "Encrypt message: \\[mh-mml-secure-message-encrypt-pgpmime]" 837 "\t\t Attachment: \\[mh-compose-insertion]\n"
821 "\t\t Attachment: \\[mh-compose-insertion]\n" 838 "\t\t Message to forward: \\[mh-compose-forward]\n"
822 "Sign message: \\[mh-mml-secure-message-sign-pgpmime]" 839 " "
823 "\t\t Message to forward: \\[mh-compose-forward]\n" 840 "Security:"
841 "\t\t Encrypt message: \\[mh-mml-secure-message-encrypt]"
842 "\t\t Sign+Encrypt message: \\[mh-mml-secure-message-signencrypt]"
843 "\t\t Sign message: \\[mh-mml-secure-message-sign]\n"
824 " " 844 " "
825 "\t\t Signature: \\[mh-insert-signature]")) 845 "\t\t Signature: \\[mh-insert-signature]"))
826 "Key binding cheat sheet. 846 "Key binding cheat sheet.
827 847
828This is an associative array which is used to show the most common commands. 848This is an associative array which is used to show the most common commands.
@@ -872,13 +892,19 @@ When a message is composed, the hooks `text-mode-hook' and
872`mh-letter-mode-hook' are run. 892`mh-letter-mode-hook' are run.
873 893
874\\{mh-letter-mode-map}" 894\\{mh-letter-mode-map}"
875 (or mh-user-path (mh-find-path)) 895 (mh-find-path)
876 (make-local-variable 'mh-send-args) 896 (make-local-variable 'mh-send-args)
877 (make-local-variable 'mh-annotate-char) 897 (make-local-variable 'mh-annotate-char)
878 (make-local-variable 'mh-annotate-field) 898 (make-local-variable 'mh-annotate-field)
879 (make-local-variable 'mh-previous-window-config) 899 (make-local-variable 'mh-previous-window-config)
880 (make-local-variable 'mh-sent-from-folder) 900 (make-local-variable 'mh-sent-from-folder)
881 (make-local-variable 'mh-sent-from-msg) 901 (make-local-variable 'mh-sent-from-msg)
902 ;; Set the local value of mh-mail-header-separator according to what is
903 ;; present in the buffer...
904 (set (make-local-variable 'mh-mail-header-separator)
905 (save-excursion
906 (goto-char (mh-mail-header-end))
907 (buffer-substring-no-properties (point) (line-end-position))))
882 (make-local-variable 'mail-header-separator) 908 (make-local-variable 'mail-header-separator)
883 (setq mail-header-separator mh-mail-header-separator) ;override sendmail.el 909 (setq mail-header-separator mh-mail-header-separator) ;override sendmail.el
884 (make-local-variable 'mh-help-messages) 910 (make-local-variable 'mh-help-messages)
@@ -886,12 +912,6 @@ When a message is composed, the hooks `text-mode-hook' and
886 (setq buffer-invisibility-spec '((vanish . t) t)) 912 (setq buffer-invisibility-spec '((vanish . t) t))
887 (set (make-local-variable 'line-move-ignore-invisible) t) 913 (set (make-local-variable 'line-move-ignore-invisible) t)
888 914
889 ;; Set mh-mail-header-end-marker to remember end of message header.
890 (set (make-local-variable 'mh-letter-mail-header-end-marker)
891 (set-marker (make-marker) (save-excursion
892 (goto-char (mh-mail-header-end))
893 (line-beginning-position 2))))
894
895 ;; From sendmail.el for proper paragraph fill 915 ;; From sendmail.el for proper paragraph fill
896 ;; sendmail.el also sets a normal-auto-fill-function (not done here) 916 ;; sendmail.el also sets a normal-auto-fill-function (not done here)
897 (make-local-variable 'paragraph-separate) 917 (make-local-variable 'paragraph-separate)
@@ -965,11 +985,15 @@ When a message is composed, the hooks `text-mode-hook' and
965 t))) 985 t)))
966 986
967(defun mh-letter-header-end () 987(defun mh-letter-header-end ()
968 "Find the end of header from `mh-letter-mail-header-end-marker'." 988 "Find the end of the message header.
989This function is to be used only for font locking. It works by searching for
990`mh-mail-header-separator' in the buffer."
969 (save-excursion 991 (save-excursion
970 (goto-char (marker-position mh-letter-mail-header-end-marker)) 992 (goto-char (point-min))
971 (forward-line -1) 993 (cond ((equal mh-mail-header-separator "") (point-min))
972 (point))) 994 ((search-forward (format "\n%s\n" mh-mail-header-separator) nil t)
995 (line-beginning-position 0))
996 (t (point-min)))))
973 997
974(defun mh-auto-fill-for-letter () 998(defun mh-auto-fill-for-letter ()
975 "Perform auto-fill for message. 999 "Perform auto-fill for message.
@@ -1041,16 +1065,69 @@ Prompt for the field name with a completion list of the current folders."
1041 (substring folder 1) 1065 (substring folder 1)
1042 folder))))) 1066 folder)))))
1043 1067
1068(defun mh-file-is-vcard-p (file)
1069 "Return t if FILE is a .vcf vcard."
1070 (let ((case-fold-search t))
1071 (and (stringp file)
1072 (file-exists-p file)
1073 (or (and (not (mh-have-file-command))
1074 (not (null (string-match "\.vcf$" file))))
1075 (and (mh-have-file-command)
1076 (string-equal "text/x-vcard" (mh-file-mime-type file)))))))
1077
1044;;;###mh-autoload 1078;;;###mh-autoload
1045(defun mh-insert-signature () 1079(defun mh-insert-signature (&optional file)
1046 "Insert the file named by `mh-signature-file-name' at point. 1080 "Insert the signature specified by `mh-signature-file-name' or FILE at point.
1081A signature separator (`-- ') will be added if the signature block does not
1082contain one and `mh-signature-separator-flag' is on.
1047The value of `mh-letter-insert-signature-hook' is a list of functions to be 1083The value of `mh-letter-insert-signature-hook' is a list of functions to be
1048called, with no arguments, before the signature is actually inserted." 1084called, with no arguments, after the signature is inserted.
1049 (interactive) 1085The signature can also be inserted with `mh-identity-list'."
1050 (let ((mh-signature-file-name mh-signature-file-name)) 1086(interactive)
1051 (run-hooks 'mh-letter-insert-signature-hook) 1087 (save-excursion
1052 (if mh-signature-file-name 1088 (insert "\n")
1053 (insert-file-contents mh-signature-file-name))) 1089 (let ((mh-signature-file-name (or file mh-signature-file-name))
1090 (mh-mhn-p (mh-mhn-directive-present-p))
1091 (mh-mml-p (mh-mml-directive-present-p)))
1092 (save-restriction
1093 (narrow-to-region (point) (point))
1094 (cond
1095 ((mh-file-is-vcard-p mh-signature-file-name)
1096 (if (equal mh-compose-insertion 'gnus)
1097 (insert "<#part type=\"text/x-vcard\" filename=\""
1098 mh-signature-file-name
1099 "\" disposition=inline description=VCard>\n<#/part>")
1100 (insert "#text/x-vcard; name=\""
1101 (file-name-nondirectory mh-signature-file-name)
1102 "\" [VCard] " (expand-file-name mh-signature-file-name))))
1103 (t
1104 (cond
1105 (mh-mhn-p
1106 (insert "#\n" "Content-Description: Signature\n"))
1107 (mh-mml-p
1108 (mml-insert-tag 'part 'type "text/plain" 'disposition "inline"
1109 'description "Signature")))
1110 (cond ((null mh-signature-file-name))
1111 ((and (stringp mh-signature-file-name)
1112 (file-readable-p mh-signature-file-name))
1113 (insert-file-contents mh-signature-file-name))
1114 ((functionp mh-signature-file-name)
1115 (funcall mh-signature-file-name)))))
1116 (save-restriction
1117 (widen)
1118 (run-hooks 'mh-letter-insert-signature-hook))
1119 (goto-char (point-min))
1120 (when (and (not (mh-file-is-vcard-p mh-signature-file-name))
1121 mh-signature-separator-flag
1122 (> (point-max) (point-min))
1123 (not (mh-signature-separator-p)))
1124 (cond (mh-mhn-p
1125 (forward-line 2))
1126 (mh-mml-p
1127 (forward-line 1)))
1128 (insert mh-signature-separator))
1129 (if (not (> (point-max) (point-min)))
1130 (message "No signature found")))))
1054 (force-mode-line-update)) 1131 (force-mode-line-update))
1055 1132
1056;;;###mh-autoload 1133;;;###mh-autoload
@@ -1100,33 +1177,18 @@ MH the first time a message is composed.")
1100(defun mh-insert-x-mailer () 1177(defun mh-insert-x-mailer ()
1101 "Append an X-Mailer field to the header. 1178 "Append an X-Mailer field to the header.
1102The versions of MH-E, Emacs, and MH are shown." 1179The versions of MH-E, Emacs, and MH are shown."
1103
1104 ;; Lazily initialize mh-x-mailer-string. 1180 ;; Lazily initialize mh-x-mailer-string.
1105 (when (and mh-insert-x-mailer-flag (null mh-x-mailer-string)) 1181 (when (and mh-insert-x-mailer-flag (null mh-x-mailer-string))
1106 (save-window-excursion 1182 (setq mh-x-mailer-string
1107 ;; User would be confused if version info buffer disappeared magically, 1183 (format "MH-E %s; %s; %sEmacs %s"
1108 ;; so don't delete buffer if it already existed. 1184 mh-version mh-variant-in-use
1109 (let ((info-buffer-exists-p (get-buffer mh-info-buffer))) 1185 (if mh-xemacs-flag "X" "GNU ")
1110 (mh-version) 1186 (cond ((not mh-xemacs-flag) emacs-version)
1111 (set-buffer mh-info-buffer) 1187 ((string-match "[0-9.]*\\( +\([ a-z]+[0-9]+\)\\)?"
1112 (if mh-nmh-flag 1188 emacs-version)
1113 (search-forward-regexp "^nmh-\\(\\S +\\)") 1189 (match-string 0 emacs-version))
1114 (search-forward-regexp "^MH \\(\\S +\\)" nil t)) 1190 (t (format "%s.%s" emacs-major-version
1115 (let ((x-mailer-mh (buffer-substring (match-beginning 1) 1191 emacs-minor-version))))))
1116 (match-end 1))))
1117 (setq mh-x-mailer-string
1118 (format "MH-E %s; %s %s; %sEmacs %s"
1119 mh-version (if mh-nmh-flag "nmh" "MH") x-mailer-mh
1120 (if mh-xemacs-flag "X" "GNU ")
1121 (cond ((not mh-xemacs-flag) emacs-version)
1122 ((string-match "[0-9.]*\\( +\([ a-z]+[0-9]+\)\\)?"
1123 emacs-version)
1124 (match-string 0 emacs-version))
1125 (t (format "%s.%s"
1126 emacs-major-version
1127 emacs-minor-version))))))
1128 (if (not info-buffer-exists-p)
1129 (kill-buffer mh-info-buffer)))))
1130 ;; Insert X-Mailer, but only if it doesn't already exist. 1192 ;; Insert X-Mailer, but only if it doesn't already exist.
1131 (save-excursion 1193 (save-excursion
1132 (when (and mh-insert-x-mailer-flag 1194 (when (and mh-insert-x-mailer-flag
@@ -1155,25 +1217,31 @@ Sets buffer-local `mh-insert-auto-fields-done-local' when done and inserted
1155something. If NON-INTERACTIVE is non-nil, do not be verbose and only 1217something. If NON-INTERACTIVE is non-nil, do not be verbose and only
1156attempt matches if `mh-insert-auto-fields-done-local' is nil. 1218attempt matches if `mh-insert-auto-fields-done-local' is nil.
1157 1219
1158An `identity' entry is skipped if one was already entered manually." 1220An `identity' entry is skipped if one was already entered manually.
1221
1222Return t if fields added; otherwise return nil."
1159 (interactive) 1223 (interactive)
1160 (when (or (not non-interactive) (not mh-insert-auto-fields-done-local)) 1224 (when (or (not non-interactive)
1225 (not mh-insert-auto-fields-done-local))
1161 (save-excursion 1226 (save-excursion
1162 (when (and (or (mh-goto-header-field "To:")(mh-goto-header-field "cc:"))) 1227 (when (and (or (mh-goto-header-field "To:")
1163 (let ((list mh-auto-fields-list)) 1228 (mh-goto-header-field "cc:")))
1229 (let ((list mh-auto-fields-list)
1230 (fields-inserted nil))
1164 (while list 1231 (while list
1165 (let ((regexp (nth 0 (car list))) 1232 (let ((regexp (nth 0 (car list)))
1166 (entries (nth 1 (car list)))) 1233 (entries (nth 1 (car list))))
1167 (when (mh-regexp-in-field-p regexp "To:" "cc:") 1234 (when (mh-regexp-in-field-p regexp "To:" "cc:")
1168 (setq mh-insert-auto-fields-done-local t) 1235 (setq mh-insert-auto-fields-done-local t)
1236 (setq fields-inserted t)
1169 (if (not non-interactive) 1237 (if (not non-interactive)
1170 (message "Matched for regexp %s" regexp)) 1238 (message "Fields for %s added" regexp))
1171 (let ((entry-list entries)) 1239 (let ((entry-list entries))
1172 (while entry-list 1240 (while entry-list
1173 (let ((field (caar entry-list)) 1241 (let ((field (caar entry-list))
1174 (value (cdar entry-list))) 1242 (value (cdar entry-list)))
1175 (cond 1243 (cond
1176 ((equal "identity" field) 1244 ((equal ":identity" field)
1177 (when (and (not mh-identity-local) 1245 (when (and (not mh-identity-local)
1178 (assoc value mh-identity-list)) 1246 (assoc value mh-identity-list))
1179 (mh-insert-identity value))) 1247 (mh-insert-identity value)))
@@ -1181,7 +1249,8 @@ An `identity' entry is skipped if one was already entered manually."
1181 (mh-modify-header-field field value 1249 (mh-modify-header-field field value
1182 (equal field "From"))))) 1250 (equal field "From")))))
1183 (setq entry-list (cdr entry-list)))))) 1251 (setq entry-list (cdr entry-list))))))
1184 (setq list (cdr list)))))))) 1252 (setq list (cdr list)))
1253 fields-inserted)))))
1185 1254
1186(defun mh-modify-header-field (field value &optional overwrite-flag) 1255(defun mh-modify-header-field (field value &optional overwrite-flag)
1187 "To header FIELD add VALUE. 1256 "To header FIELD add VALUE.
@@ -1201,8 +1270,6 @@ If OVERWRITE-FLAG is non-nil then the old value, if present, is discarded."
1201 (mh-goto-header-end 0) 1270 (mh-goto-header-end 0)
1202 (insert field ": " value "\n")))) 1271 (insert field ": " value "\n"))))
1203 1272
1204(defvar mh-letter-mail-header-end-marker nil)
1205
1206(defun mh-compose-and-send-mail (draft send-args 1273(defun mh-compose-and-send-mail (draft send-args
1207 sent-from-folder sent-from-msg 1274 sent-from-folder sent-from-msg
1208 to subject cc 1275 to subject cc
@@ -1221,22 +1288,19 @@ for `mh-annotate-msg'.
1221CONFIG is the window configuration to restore after sending the letter." 1288CONFIG is the window configuration to restore after sending the letter."
1222 (pop-to-buffer draft) 1289 (pop-to-buffer draft)
1223 (mh-letter-mode) 1290 (mh-letter-mode)
1224 (mh-insert-auto-fields t)
1225 1291
1226 ;; mh-identity support 1292 ;; Insert identity.
1227 (if (and (boundp 'mh-identity-default) 1293 (if (and (boundp 'mh-identity-default)
1228 mh-identity-default 1294 mh-identity-default
1229 (not mh-identity-local)) 1295 (not mh-identity-local))
1230 (mh-insert-identity mh-identity-default)) 1296 (mh-insert-identity mh-identity-default))
1231 (when (and (boundp 'mh-identity-list) 1297 (mh-identity-make-menu)
1232 mh-identity-list) 1298 (easy-menu-add mh-identity-menu)
1233 (mh-identity-make-menu)
1234 (easy-menu-add mh-identity-menu))
1235 1299
1236 ;; Extra fields 1300 ;; Insert extra fields.
1237 (mh-insert-x-mailer) 1301 (mh-insert-x-mailer)
1238 (mh-insert-x-face) 1302 (mh-insert-x-face)
1239 ;; Hide skipped fields 1303
1240 (mh-letter-hide-all-skipped-fields) 1304 (mh-letter-hide-all-skipped-fields)
1241 1305
1242 (setq mh-sent-from-folder sent-from-folder) 1306 (setq mh-sent-from-folder sent-from-folder)
@@ -1264,7 +1328,16 @@ CONFIG is the window configuration to restore after sending the letter."
1264This should be the last function called when composing the draft." 1328This should be the last function called when composing the draft."
1265 (message "%s" (substitute-command-keys 1329 (message "%s" (substitute-command-keys
1266 (concat "Type \\[mh-send-letter] to send message, " 1330 (concat "Type \\[mh-send-letter] to send message, "
1267 "\\[mh-help] for help.")))) 1331 "\\[mh-help] for help"))))
1332
1333(defun mh-ascii-buffer-p ()
1334 "Check if current buffer is entirely composed of ASCII.
1335The function doesn't work for XEmacs since `find-charset-region' doesn't exist
1336there."
1337 (loop for charset in (mh-funcall-if-exists
1338 find-charset-region (point-min) (point-max))
1339 unless (eq charset 'ascii) return nil
1340 finally return t))
1268 1341
1269;;;###mh-autoload 1342;;;###mh-autoload
1270(defun mh-send-letter (&optional arg) 1343(defun mh-send-letter (&optional arg)
@@ -1273,15 +1346,17 @@ If optional prefix argument ARG is provided, monitor delivery.
1273The value of `mh-before-send-letter-hook' is a list of functions to be called, 1346The value of `mh-before-send-letter-hook' is a list of functions to be called,
1274with no arguments, before doing anything. 1347with no arguments, before doing anything.
1275Run `\\[mh-edit-mhn]' if mhn directives are present; otherwise 1348Run `\\[mh-edit-mhn]' if mhn directives are present; otherwise
1276run `\\[mh-mml-to-mime]' if mml directives are present. 1349run `\\[mh-mml-to-mime]' if mml directives are present."
1277Insert X-Mailer field if variable `mh-insert-x-mailer-flag' is set.
1278Insert X-Face field if the file specified by `mh-x-face-file' exists."
1279 (interactive "P") 1350 (interactive "P")
1280 (run-hooks 'mh-before-send-letter-hook) 1351 (run-hooks 'mh-before-send-letter-hook)
1281 (mh-insert-auto-fields t) 1352 (if (and (mh-insert-auto-fields t)
1353 mh-auto-fields-prompt-flag
1354 (goto-char (point-min)))
1355 (if (not (y-or-n-p "Auto fields inserted, send? "))
1356 (error "Send aborted")))
1282 (cond ((mh-mhn-directive-present-p) 1357 (cond ((mh-mhn-directive-present-p)
1283 (mh-edit-mhn)) 1358 (mh-edit-mhn))
1284 ((mh-mml-directive-present-p) 1359 ((or (mh-mml-directive-present-p) (not (mh-ascii-buffer-p)))
1285 (mh-mml-to-mime))) 1360 (mh-mml-to-mime)))
1286 (save-buffer) 1361 (save-buffer)
1287 (message "Sending...") 1362 (message "Sending...")
@@ -1302,7 +1377,7 @@ Insert X-Face field if the file specified by `mh-x-face-file' exists."
1302 'iso-latin-1)))) 1377 'iso-latin-1))))
1303 ;; The default BCC encapsulation will make a MIME message unreadable. 1378 ;; The default BCC encapsulation will make a MIME message unreadable.
1304 ;; With nmh use the -mime arg to prevent this. 1379 ;; With nmh use the -mime arg to prevent this.
1305 (if (and mh-nmh-flag 1380 (if (and (mh-variant-p 'nmh)
1306 (mh-goto-header-field "Bcc:") 1381 (mh-goto-header-field "Bcc:")
1307 (mh-goto-header-field "Content-Type:")) 1382 (mh-goto-header-field "Content-Type:"))
1308 (setq mh-send-args (format "-mime %s" mh-send-args))) 1383 (setq mh-send-args (format "-mime %s" mh-send-args)))
@@ -1338,7 +1413,8 @@ Insert X-Face field if the file specified by `mh-x-face-file' exists."
1338;;;###mh-autoload 1413;;;###mh-autoload
1339(defun mh-insert-letter (folder message verbatim) 1414(defun mh-insert-letter (folder message verbatim)
1340 "Insert a message into the current letter. 1415 "Insert a message into the current letter.
1341Removes the header fields according to the variable `mh-invisible-headers'. 1416Removes the header fields according to the variable
1417`mh-invisible-header-fields-compiled'.
1342Prefixes each non-blank line with `mh-ins-buf-prefix', unless 1418Prefixes each non-blank line with `mh-ins-buf-prefix', unless
1343`mh-yank-from-start-of-msg' is set for supercite in which case supercite is 1419`mh-yank-from-start-of-msg' is set for supercite in which case supercite is
1344used to format the message. 1420used to format the message.
@@ -1355,11 +1431,12 @@ and point after it."
1355 (save-restriction 1431 (save-restriction
1356 (narrow-to-region (point) (point)) 1432 (narrow-to-region (point) (point))
1357 (let ((start (point-min))) 1433 (let ((start (point-min)))
1358 (if (equal message "") (setq message (int-to-string mh-sent-from-msg))) 1434 (if (and (equal message "") (numberp mh-sent-from-msg))
1435 (setq message (int-to-string mh-sent-from-msg)))
1359 (insert-file-contents 1436 (insert-file-contents
1360 (expand-file-name message (mh-expand-file-name folder))) 1437 (expand-file-name message (mh-expand-file-name folder)))
1361 (when (not verbatim) 1438 (when (not verbatim)
1362 (mh-clean-msg-header start mh-invisible-headers mh-visible-headers) 1439 (mh-clean-msg-header start mh-invisible-header-fields-compiled nil)
1363 (goto-char (point-max)) ;Needed for sc-cite-original 1440 (goto-char (point-max)) ;Needed for sc-cite-original
1364 (push-mark) ;Needed for sc-cite-original 1441 (push-mark) ;Needed for sc-cite-original
1365 (goto-char (point-min)) ;Needed for sc-cite-original 1442 (goto-char (point-min)) ;Needed for sc-cite-original
@@ -1373,15 +1450,13 @@ and point after it."
1373 (skip-chars-forward " ") 1450 (skip-chars-forward " ")
1374 (cond 1451 (cond
1375 ((looking-at "\"\\([^\"\n]+\\)\" \\(<.+>\\)") 1452 ((looking-at "\"\\([^\"\n]+\\)\" \\(<.+>\\)")
1376 (format "%s %s %s" (match-string 1)(match-string 2) 1453 (format "%s %s " (match-string 1)(match-string 2)))
1377 mh-extract-from-attribution-verb))
1378 ((looking-at "\\([^<\n]+<.+>\\)$") 1454 ((looking-at "\\([^<\n]+<.+>\\)$")
1379 (format "%s %s" (match-string 1) mh-extract-from-attribution-verb)) 1455 (format "%s " (match-string 1)))
1380 ((looking-at "\\([^ ]+@[^ ]+\\) +(\\(.+\\))$") 1456 ((looking-at "\\([^ ]+@[^ ]+\\) +(\\(.+\\))$")
1381 (format "%s <%s> %s" (match-string 2)(match-string 1) 1457 (format "%s <%s> " (match-string 2)(match-string 1)))
1382 mh-extract-from-attribution-verb))
1383 ((looking-at " *\\(.+\\)$") 1458 ((looking-at " *\\(.+\\)$")
1384 (format "%s %s" (match-string 1) mh-extract-from-attribution-verb)))))) 1459 (format "%s " (match-string 1)))))))
1385 1460
1386;;;###mh-autoload 1461;;;###mh-autoload
1387(defun mh-yank-cur-msg () 1462(defun mh-yank-cur-msg ()
@@ -1444,9 +1519,11 @@ yanked message will be deleted."
1444 (push-mark) ;Needed for sc-cite-original 1519 (push-mark) ;Needed for sc-cite-original
1445 (goto-char (point-min)) ;Needed for sc-cite-original 1520 (goto-char (point-min)) ;Needed for sc-cite-original
1446 (mh-insert-prefix-string mh-ins-buf-prefix) 1521 (mh-insert-prefix-string mh-ins-buf-prefix)
1447 (if (or (eq 'attribution mh-yank-from-start-of-msg) 1522 (when (or (eq 'attribution mh-yank-from-start-of-msg)
1448 (eq 'autoattrib mh-yank-from-start-of-msg)) 1523 (eq 'autoattrib mh-yank-from-start-of-msg))
1449 (insert from-attr "\n\n")) 1524 (insert from-attr)
1525 (mh-identity-insert-attribution-verb nil)
1526 (insert "\n\n"))
1450 ;; If the user has selected a region, he has already "edited" the 1527 ;; If the user has selected a region, he has already "edited" the
1451 ;; text, so leave the cursor at the end of the yanked text. In 1528 ;; text, so leave the cursor at the end of the yanked text. In
1452 ;; either case, leave a mark at the opposite end of the included 1529 ;; either case, leave a mark at the opposite end of the included
@@ -1572,7 +1649,7 @@ Any match found replaces the text from BEGIN to END."
1572 (let ((syntax-table (syntax-table))) 1649 (let ((syntax-table (syntax-table)))
1573 (unwind-protect 1650 (unwind-protect
1574 (save-excursion 1651 (save-excursion
1575 (mh-funcall-if-exists mail-abbrev-make-syntax-table) 1652 (mh-mail-abbrev-make-syntax-table)
1576 (set-syntax-table mail-abbrev-syntax-table) 1653 (set-syntax-table mail-abbrev-syntax-table)
1577 (backward-word n) 1654 (backward-word n)
1578 (point)) 1655 (point))
@@ -1593,7 +1670,6 @@ Any match found replaces the text from BEGIN to END."
1593 (mh-folder-completion-function folder nil t)))) 1670 (mh-folder-completion-function folder nil t))))
1594 (mh-complete-word folder choices beg end))) 1671 (mh-complete-word folder choices beg end)))
1595 1672
1596;; XXX: This should probably be customizable
1597(defvar mh-letter-complete-function-alist 1673(defvar mh-letter-complete-function-alist
1598 '((cc . mh-alias-letter-expand-alias) 1674 '((cc . mh-alias-letter-expand-alias)
1599 (bcc . mh-alias-letter-expand-alias) 1675 (bcc . mh-alias-letter-expand-alias)
@@ -1607,10 +1683,10 @@ Any match found replaces the text from BEGIN to END."
1607 1683
1608(defun mh-letter-complete (arg) 1684(defun mh-letter-complete (arg)
1609 "Perform completion on header field or word preceding point. 1685 "Perform completion on header field or word preceding point.
1610Alias completion is done within the mail header on selected fields based on 1686If the field contains addresses (for example, `To:' or `Cc:') or folders (for
1611the matches in `mh-letter-complete-function-alist'. Elsewhere the function 1687example, `Fcc:') then this function will provide alias completion. Elsewhere,
1612designated by `mh-letter-complete-function' is used and given the prefix ARG, 1688this function runs `mh-letter-complete-function' instead and passes the prefix
1613if present." 1689ARG, if present."
1614 (interactive "P") 1690 (interactive "P")
1615 (let ((func nil)) 1691 (let ((func nil))
1616 (cond ((not (mh-in-header-p)) 1692 (cond ((not (mh-in-header-p))
@@ -1832,10 +1908,13 @@ Otherwise return the empty string."
1832;;; Build the letter-mode keymap: 1908;;; Build the letter-mode keymap:
1833;;; If this changes, modify mh-letter-mode-help-messages accordingly, above. 1909;;; If this changes, modify mh-letter-mode-help-messages accordingly, above.
1834(gnus-define-keys mh-letter-mode-map 1910(gnus-define-keys mh-letter-mode-map
1911 " " mh-letter-complete-or-space
1912 "," mh-letter-confirm-address
1835 "\C-c?" mh-help 1913 "\C-c?" mh-help
1914 "\C-c\C-\\" mh-fully-kill-draft ;if no C-q
1915 "\C-c\C-^" mh-insert-signature ;if no C-s
1836 "\C-c\C-c" mh-send-letter 1916 "\C-c\C-c" mh-send-letter
1837 "\C-c\C-d" mh-insert-identity 1917 "\C-c\C-d" mh-insert-identity
1838 "\C-c\M-d" mh-insert-auto-fields
1839 "\C-c\C-e" mh-edit-mhn 1918 "\C-c\C-e" mh-edit-mhn
1840 "\C-c\C-f\C-b" mh-to-field 1919 "\C-c\C-f\C-b" mh-to-field
1841 "\C-c\C-f\C-c" mh-to-field 1920 "\C-c\C-f\C-c" mh-to-field
@@ -1852,31 +1931,38 @@ Otherwise return the empty string."
1852 "\C-c\C-fs" mh-to-field 1931 "\C-c\C-fs" mh-to-field
1853 "\C-c\C-ft" mh-to-field 1932 "\C-c\C-ft" mh-to-field
1854 "\C-c\C-i" mh-insert-letter 1933 "\C-c\C-i" mh-insert-letter
1855 "\C-c\C-m\C-e" mh-mml-secure-message-encrypt-pgpmime 1934 "\C-c\C-m\C-e" mh-mml-secure-message-encrypt
1856 "\C-c\C-m\C-f" mh-compose-forward 1935 "\C-c\C-m\C-f" mh-compose-forward
1936 "\C-c\C-m\C-g" mh-mhn-compose-anon-ftp
1857 "\C-c\C-m\C-i" mh-compose-insertion 1937 "\C-c\C-m\C-i" mh-compose-insertion
1858 "\C-c\C-m\C-m" mh-mml-to-mime 1938 "\C-c\C-m\C-m" mh-mml-to-mime
1859 "\C-c\C-m\C-s" mh-mml-secure-message-sign-pgpmime 1939 "\C-c\C-m\C-n" mh-mml-unsecure-message
1940 "\C-c\C-m\C-s" mh-mml-secure-message-sign
1941 "\C-c\C-m\C-t" mh-mhn-compose-external-compressed-tar
1860 "\C-c\C-m\C-u" mh-revert-mhn-edit 1942 "\C-c\C-m\C-u" mh-revert-mhn-edit
1861 "\C-c\C-me" mh-mml-secure-message-encrypt-pgpmime 1943 "\C-c\C-m\C-x" mh-mhn-compose-external-type
1944 "\C-c\C-mee" mh-mml-secure-message-encrypt
1945 "\C-c\C-mes" mh-mml-secure-message-signencrypt
1862 "\C-c\C-mf" mh-compose-forward 1946 "\C-c\C-mf" mh-compose-forward
1947 "\C-c\C-mg" mh-mhn-compose-anon-ftp
1863 "\C-c\C-mi" mh-compose-insertion 1948 "\C-c\C-mi" mh-compose-insertion
1864 "\C-c\C-mm" mh-mml-to-mime 1949 "\C-c\C-mm" mh-mml-to-mime
1865 "\C-c\C-ms" mh-mml-secure-message-sign-pgpmime 1950 "\C-c\C-mn" mh-mml-unsecure-message
1951 "\C-c\C-mse" mh-mml-secure-message-signencrypt
1952 "\C-c\C-mss" mh-mml-secure-message-sign
1953 "\C-c\C-mt" mh-mhn-compose-external-compressed-tar
1866 "\C-c\C-mu" mh-revert-mhn-edit 1954 "\C-c\C-mu" mh-revert-mhn-edit
1955 "\C-c\C-mx" mh-mhn-compose-external-type
1867 "\C-c\C-o" mh-open-line 1956 "\C-c\C-o" mh-open-line
1868 "\C-c\C-q" mh-fully-kill-draft 1957 "\C-c\C-q" mh-fully-kill-draft
1869 "\C-c\C-\\" mh-fully-kill-draft ;if no C-q
1870 "\C-c\C-s" mh-insert-signature 1958 "\C-c\C-s" mh-insert-signature
1871 "\C-c\C-^" mh-insert-signature ;if no C-s 1959 "\C-c\C-t" mh-letter-toggle-header-field-display
1872 "\C-c\C-w" mh-check-whom 1960 "\C-c\C-w" mh-check-whom
1873 "\C-c\C-y" mh-yank-cur-msg 1961 "\C-c\C-y" mh-yank-cur-msg
1874 "\C-c\C-t" mh-letter-toggle-header-field-display 1962 "\C-c\M-d" mh-insert-auto-fields
1875 " " mh-letter-complete-or-space
1876 "\M-\t" mh-letter-complete 1963 "\M-\t" mh-letter-complete
1877 "\t" mh-letter-next-header-field-or-indent 1964 "\t" mh-letter-next-header-field-or-indent
1878 [backtab] mh-letter-previous-header-field 1965 [backtab] mh-letter-previous-header-field)
1879 "," mh-letter-confirm-address)
1880 1966
1881;; "C-c /" prefix is used in mh-letter-mode by pgp.el and mailcrypt.el. 1967;; "C-c /" prefix is used in mh-letter-mode by pgp.el and mailcrypt.el.
1882 1968
diff --git a/lisp/mh-e/mh-customize.el b/lisp/mh-e/mh-customize.el
index 2ce36c88726..0cf35b3c0d9 100644
--- a/lisp/mh-e/mh-customize.el
+++ b/lisp/mh-e/mh-customize.el
@@ -34,814 +34,585 @@
34;; 34;;
35;; 1. MH-E Customization Groups 35;; 1. MH-E Customization Groups
36;; 36;;
37;; These are the customization group definitions. These are organized in a 37;; These are the customization group definitions. Every group has a
38;; logical order. High-level, windows and toolbar, folder, message, 38;; associated manual node. The ordering is alphabetical, except for the
39;; composing and hooks. 39;; groups mh-faces and mh-hooks which are last .
40;; 40;;
41;; 2. MH-E Customization 41;; 2. MH-E Customization
42;; 42;;
43;; Here are the actual customization variables. There is a sub-section for 43;; These are the actual customization variables. There is a sub-section for
44;; each group in the MH-E Customization Groups section. Within each 44;; each group in the MH-E Customization Groups section, in the same order,
45;; section, variables are sorted alphabetically. The manual section 45;; separated by page breaks. Within each section, variables are sorted
46;; dictates which group a variable should be placed. New variables should 46;; alphabetically.
47;; be placed in the section where they would most likely be defined.
48;; 47;;
49;; All hooks should be placed in the 'mh-hook group; in addition, add the 48;; 3. Hooks
50;; group in which the hook is defined in the manual (or, if it is new, 49;;
51;; where it would be defined). These two actions insures that the hooks 50;; All hooks must be placed in the mh-hook group; in addition, add the
52;; appear last in each group. 51;; group associated with the manual node in which the hook is described.
52;; Since the mh-hook group appears near the end of this file, the hooks
53;; will appear at the end of these other groups.
54;;
55;; 4. Faces
56;;
57;; Create a new face group if necessary; in this case, add the group
58;; associated with the manual node in which the faces are described to the
59;; faces' group definition. Since the face groups appear last, the face
60;; groups will appear at the end of these other groups.
53;; 61;;
54;; 3. Faces
55
56;;; Change Log: 62;;; Change Log:
57 63
58;;; Code: 64;;; Code:
65
59(provide 'mh-customize) 66(provide 'mh-customize)
60(require 'mh-utils) 67
68(eval-when-compile (require 'mh-acros))
69(mh-require-cl)
70(require 'mh-loaddefs)
71
72(autoload 'Info-goto-node "info")
73
74(eval-and-compile
75 (defvar mh-xemacs-flag (featurep 'xemacs)
76 "Non-nil means the current Emacs is XEmacs."))
61 77
62(when mh-xemacs-flag 78(when mh-xemacs-flag
63 (require 'mh-xemacs)) 79 (require 'mh-xemacs))
64 80
65;;;###mh-autoload
66(defun mh-customize (&optional delete-other-windows-flag) 81(defun mh-customize (&optional delete-other-windows-flag)
67 "Customize MH-E variables. 82 "Customize MH-E variables.
68With optional argument DELETE-OTHER-WINDOWS-FLAG, other windows in the frame 83If optional argument DELETE-OTHER-WINDOWS-FLAG is non-nil, other windows in
69are removed." 84the frame are removed."
70 (interactive "P") 85 (interactive "P")
71 (customize-group 'mh) 86 (customize-group 'mh)
72 (when delete-other-windows-flag 87 (when delete-other-windows-flag
73 (delete-other-windows))) 88 (delete-other-windows)))
74 89
90
91
92;;; For compiler warnings...
93(defvar mh-show-buffer)
94(defvar mh-show-folder-buffer)
95
75;;; MH-E Customization Groups 96;;; MH-E Customization Groups
76 97
77(defgroup mh nil 98(defgroup mh nil
78 "GNU Emacs interface to the MH mail system." 99 "Emacs interface to the MH mail system.
100MH is the Rand Mail Handler. Other implementations include nmh and GNU
101mailutils."
79 :link '(custom-manual "(mh-e)Top") 102 :link '(custom-manual "(mh-e)Top")
80 :group 'mail) 103 :group 'mail)
81 104
82(defgroup mh-toolbar nil 105(defgroup mh-e '((mh custom-group)) ; Sort of an alias for 'mh group
83 "Toolbar configuration." 106 "Emacs interface to the MH mail system.
84 :prefix "mh-" 107MH is the Rand Mail Handler. Other implementations include nmh and GNU
108mailutils."
109 :link '(custom-manual "(mh-e)Top"))
110
111(defgroup mh-alias nil
112 "Aliases."
113 :link '(custom-manual "(mh-e)Aliases")
114 :prefix "mh-alias-"
85 :group 'mh) 115 :group 'mh)
86 116
87(defgroup mh-speed nil 117(defgroup mh-folder nil
88 "Speedbar and folder configuration." 118 "Organizing your mail with folders."
89 :prefix "mh-" 119 :prefix "mh-"
90 :link '(custom-manual "(mh-e)Customizing Moving Mail") 120 :link '(custom-manual "(mh-e)Organizing")
91 :group 'mh) 121 :group 'mh)
92 122
93(defgroup mh-folder nil 123(defgroup mh-folder-selection nil
94 "Options for controlling scan listing." 124 "Folder selection."
95 :prefix "mh-" 125 :prefix "mh-"
96 :link '(custom-manual "(mh-e)Customizing Moving Mail") 126 :link '(custom-manual "(mh-e)Folder Selection")
127 :group 'mh)
128
129(defgroup mh-identity nil
130 "Identities."
131 :link '(custom-manual "(mh-e)Identities")
132 :prefix "mh-identity-"
133 :group 'mh)
134
135(defgroup mh-inc nil
136 "Incorporating your mail."
137 :prefix "mh-inc-"
138 :link '(custom-manual "(mh-e)Incorporating Mail")
97 :group 'mh) 139 :group 'mh)
98 140
99(defgroup mh-index nil 141(defgroup mh-index nil
100 "Indexed searching." 142 "Searching."
101 :link '(custom-manual "(mh-e)Customizing mh-e") 143 :link '(custom-manual "(mh-e)Searching")
102 :prefix "mh-" 144 :prefix "mh-index-"
103 :group 'mh) 145 :group 'mh)
104 146
105(defgroup mh-junk nil 147(defgroup mh-junk nil
106 "Spam handling." 148 "Dealing with junk mail."
107 :link '(custom-manual "(mh-e)Customizing mh-e") 149 :link '(custom-manual "(mh-e)Junk")
108 :prefix "mh-junk-" 150 :prefix "mh-junk-"
109 :group 'mh) 151 :group 'mh)
110 152
111(defgroup mh-show nil 153(defgroup mh-letter nil
112 "Message display." 154 "Editing a draft."
113 :prefix "mh-" 155 :prefix "mh-"
114 :link '(custom-manual "(mh-e)Customizing Reading") 156 :link '(custom-manual "(mh-e)Editing Drafts")
115 :group 'mh) 157 :group 'mh)
116 158
117(defgroup mh-faces nil 159(defgroup mh-ranges nil
118 "Faces used in MH-E." 160 "Ranges."
119 :link '(custom-manual "(mh-e)Customizing mh-e")
120 :prefix "mh-" 161 :prefix "mh-"
121 :group 'faces 162 :link '(custom-manual "(mh-e)Ranges")
122 :group 'mh) 163 :group 'mh)
123 164
124(defgroup mh-letter nil 165(defgroup mh-scan-line-formats nil
125 "Composing messages." 166 "Scan line formats."
167 :link '(custom-manual "(mh-e)Scan Line Formats")
126 :prefix "mh-" 168 :prefix "mh-"
127 :link '(custom-manual "(mh-e)Customizing Sending")
128 :group 'mh) 169 :group 'mh)
129 170
130(defgroup mh-alias nil 171(defgroup mh-sending-mail nil
131 "Alias handling." 172 "Sending mail."
132 :link '(custom-manual "(mh-e)Customizing mh-e") 173 :prefix "mh-"
133 :prefix "mh-alias-" 174 :link '(custom-manual "(mh-e)Sending Mail")
134 :group 'mh) 175 :group 'mh)
135 176
136(defgroup mh-identity nil 177(defgroup mh-sequences nil
137 "Multiple personalities." 178 "Sequences."
138 :link '(custom-manual "(mh-e)Customizing mh-e") 179 :prefix "mh-"
180 :link '(custom-manual "(mh-e)Sequences")
181 :group 'mh)
182
183(defgroup mh-show nil
184 "Reading your mail."
139 :prefix "mh-" 185 :prefix "mh-"
186 :link '(custom-manual "(mh-e)Reading Mail")
187 :group 'mh)
188
189(defgroup mh-speed nil
190 "The speedbar."
191 :prefix "mh-speed-"
192 :link '(custom-manual "(mh-e)Speedbar")
193 :group 'mh)
194
195(defgroup mh-toolbar nil
196 "The toolbar"
197 :link '(custom-manual "(mh-e)Toolbar")
198 :prefix "mh-"
199 :group 'mh)
200
201(defgroup mh-faces nil
202 "Faces used in MH-E."
203 :link '(custom-manual "(mh-e)Top")
204 :prefix "mh-"
205 :group 'faces
140 :group 'mh) 206 :group 'mh)
141 207
142(defgroup mh-hooks nil 208(defgroup mh-hooks nil
143 "MH-E hooks." 209 "MH-E hooks."
144 :link '(custom-manual "(mh-e)Customizing mh-e") 210 :link '(custom-manual "(mh-e)Top")
145 :prefix "mh-" 211 :prefix "mh-"
146 :group 'mh) 212 :group 'mh)
147 213
148;;; Faces 214;;; Faces
149 215
150(defgroup mh-speed-faces nil
151 "Faces used in speedbar."
152 :link '(custom-manual "(mh-e)Customizing mh-e")
153 :prefix "mh-"
154 :group 'mh-faces
155 :group 'mh-speed)
156
157(defgroup mh-folder-faces nil 216(defgroup mh-folder-faces nil
158 "Faces used in scan listing." 217 "Faces used in scan listing."
159 :link '(custom-manual "(mh-e)Customizing mh-e") 218 :link '(custom-manual "(mh-e)Organizing")
160 :prefix "mh-" 219 :prefix "mh-"
161 :group 'mh-faces 220 :group 'mh-faces
162 :group 'mh-folder) 221 :group 'mh-show)
163 222
164(defgroup mh-index-faces nil 223(defgroup mh-index-faces nil
165 "Faces used in indexed searches." 224 "Faces used in searching."
166 :link '(custom-manual "(mh-e)Customizing mh-e") 225 :link '(custom-manual "(mh-e)Searching")
167 :prefix "mh-" 226 :prefix "mh-"
168 :group 'mh-faces 227 :group 'mh-faces
169 :group 'mh-index) 228 :group 'mh-index)
170 229
230(defgroup mh-letter-faces nil
231 "Faces used in message drafts."
232 :link '(custom-manual "(mh-e)Sending Mail")
233 :prefix "mh-"
234 :group 'mh-faces
235 :group 'mh-letter)
236
171(defgroup mh-show-faces nil 237(defgroup mh-show-faces nil
172 "Faces used in message display." 238 "Faces used in message display."
173 :link '(custom-manual "(mh-e)Customizing mh-e") 239 :link '(custom-manual "(mh-e)Reading Mail")
174 :prefix "mh-" 240 :prefix "mh-"
175 :group 'mh-faces 241 :group 'mh-faces
176 :group 'mh-show) 242 :group 'mh-show)
177 243
178(defgroup mh-letter-faces nil 244(defgroup mh-speed-faces nil
179 "Faces used when composing messages." 245 "Faces used in speedbar."
180 :link '(custom-manual "(mh-e)Customizing mh-e") 246 :link '(custom-manual "(mh-e)Speedbar")
181 :prefix "mh-" 247 :prefix "mh-"
182 :group 'mh-faces 248 :group 'mh-faces
183 :group 'mh-letter) 249 :group 'mh-speed)
184 250
185 251
186 252
187;;; MH-E Customization (:group mh) 253;;; Emacs interface to the MH mail system (:group mh)
188 254(eval-when (compile)
189;;; Toolbar configuration (:group 'mh-toolbar) 255 (setq mh-variant 'none))
190 256
191(defcustom mh-tool-bar-search-function 'mh-search-folder 257(defcustom mh-variant 'autodetect
192 "*Function called by the tool-bar search button. 258 "*Specifies the variant used by MH-E.
193See `mh-search-folder' and `mh-index-search' for details." 259
194 :type '(choice (const mh-search-folder) 260The default setting of this option is `Auto-detect' which means that MH-E will
195 (const mh-index-search) 261automatically choose the first of nmh, MH, or GNU mailutils that it finds in
196 (function :tag "Other function")) 262the directories listed in `mh-path', `mh-sys-path', and `exec-path'. If, for
197 :group 'mh-toolbar) 263example, you have both nmh and mailutils installed and `mh-variant-in-use' was
198 264initialized to nmh but you want to use mailutils, then you can set this option
199;; Functions called from the tool bar 265to `mailutils'.
200(defun mh-tool-bar-search (&optional arg) 266
201 "Interactively call `mh-tool-bar-search-function'. 267When this variable is changed, MH-E resets `mh-progs', `mh-lib',
202Optional argument ARG is not used." 268`mh-lib-progs', `mh-flists-present-flag', and `mh-variant-in-use'
203 (interactive "P") 269accordingly."
204 (call-interactively mh-tool-bar-search-function)) 270 :type `(radio
205 271 (const :tag "Auto-detect" autodetect)
206(defun mh-tool-bar-customize () 272 ,@(mapcar (lambda (x) `(const ,(car x))) (mh-variants)))
207 "Call `mh-customize' from the toolbar." 273 :set (lambda (symbol value)
208 (interactive) 274 (set-default symbol value) ;Done in mh-variant-set-variant!
209 (mh-customize t)) 275 (mh-variant-set value))
210 276 :group 'mh)
211(defun mh-tool-bar-folder-help ()
212 "Visit \"(mh-e)Top\"."
213 (interactive)
214 (Info-goto-node "(mh-e)Top")
215 (delete-other-windows))
216
217(defun mh-tool-bar-letter-help ()
218 "Visit \"(mh-e)Draft Editing\"."
219 (interactive)
220 (Info-goto-node "(mh-e)Draft Editing")
221 (delete-other-windows))
222
223(defmacro mh-tool-bar-reply-generator (function recipient folder-buffer-flag)
224 "Generate FUNCTION that replies to RECIPIENT.
225If FOLDER-BUFFER-FLAG is nil then the function generated
226When INCLUDE-FLAG is non-nil, include message body being replied to."
227 `(defun ,function (&optional arg)
228 ,(format "Reply to \"%s\".\nWhen ARG is non-nil include message in reply."
229 recipient)
230 (interactive "P")
231 ,(if folder-buffer-flag nil '(set-buffer mh-show-folder-buffer))
232 (mh-reply (mh-get-msg-num nil) ,recipient arg)))
233
234(mh-tool-bar-reply-generator mh-tool-bar-reply-from "from" t)
235(mh-tool-bar-reply-generator mh-show-tool-bar-reply-from "from" nil)
236(mh-tool-bar-reply-generator mh-tool-bar-reply-to "to" t)
237(mh-tool-bar-reply-generator mh-show-tool-bar-reply-to "to" nil)
238(mh-tool-bar-reply-generator mh-tool-bar-reply-all "all" t)
239(mh-tool-bar-reply-generator mh-show-tool-bar-reply-all "all" nil)
240 277
241;; XEmacs has a couple of extra customizations... 278
242(mh-do-in-xemacs
243 (defcustom mh-xemacs-use-toolbar-flag (if (and (featurep 'toolbar)
244 (featurep 'xpm)
245 (device-on-window-system-p))
246 t
247 nil)
248 "*If non-nil, use toolbar.
249 279
250This will default to t if you are in an environment that supports 280;;; Aliases (:group 'mh-alias)
251toolbars and xpm."
252 :type 'boolean
253 :group 'mh-toolbar)
254 281
255 (defcustom mh-xemacs-toolbar-position (if mh-xemacs-use-toolbar-flag 282(defcustom mh-alias-completion-ignore-case-flag t
256 'default 283 "*Non-nil means don't consider case significant in MH alias completion.
257 nil) 284As MH ignores case in the aliases, so too does MH-E. However, you may turn
258 "*Where to put the toolbar. 285this option off to make case significant which can be used to segregate
286completion of your aliases. You might use lowercase for mailing lists and
287uppercase for people."
288 :type 'boolean
289 :group 'mh-alias)
259 290
260Valid non-nil values are \"default\", \"top\", \"bottom\", \"left\", 291(defcustom mh-alias-expand-aliases-flag nil
261\"right\". These match the four edges of the frame, with \"default\" 292 "*Non-nil means to expand aliases entered in the minibuffer.
262meaning \"use the same position as the default-toolbar\". 293In other words, aliases entered in the minibuffer will be expanded to the full
294address in the message draft. By default, this expansion is not performed."
295 :type 'boolean
296 :group 'mh-alias)
263 297
264A nil value means do not use a toolbar. 298(defcustom mh-alias-flash-on-comma t
299 "*Specify whether to flash address or warn on translation.
300This option controls the behavior when a [comma] is pressed while entering
301aliases or addresses. The default setting flashes the address associated with
302an address in the minibuffer briefly, but does not display a warning if the
303alias is not found."
304 :type '(choice (const :tag "Flash but Don't Warn If No Alias" t)
305 (const :tag "Flash and Warn If No Alias" 1)
306 (const :tag "Don't Flash Nor Warn If No Alias" nil))
307 :group 'mh-alias)
265 308
266If this variable is set to anything other than \"default\" and the 309(defcustom mh-alias-insert-file nil
267default-toolbar has a different positional setting from the value of 310 "*Filename used to store a new MH-E alias.
268this variable, then two toolbars will be displayed. The MH-E toolbar 311The default setting of this option is `Use Aliasfile Profile Component'. This
269and the default-toolbar." 312option can also hold the name of a file or a list a file names. If this option
270 :type '(radio (const :tag "Same position as the \"default-toolbar\"" 313is set to a list of file names, or the `Aliasfile:' profile component contains
271 :value default) 314more than one file name, MH-E will prompt for one of them when MH-E adds an
272 (const :tag "Along the top edge of the frame" 315alias."
273 :value top) 316 :type '(choice (const :tag "Use Aliasfile Profile Component" nil)
274 (const :tag "Along the bottom edge of the frame" 317 (file :tag "Alias File")
275 :value bottom) 318 (repeat :tag "List of Alias Files" file))
276 (const :tag "Along the left edge of the frame" 319 :group 'mh-alias)
277 :value left)
278 (const :tag "Along the right edge of the frame"
279 :value right)
280 (const :tag "Don't use a toolbar" nil))
281 :group 'mh-toolbar))
282 320
283(defmacro mh-tool-bar-define (defaults &rest buttons) 321(defcustom mh-alias-insertion-location 'sorted
284 "Define a tool bar for MH-E. 322 "Specifies where new aliases are entered in alias files.
285DEFAULTS is the list of buttons that are present by default. It is a list of 323This option is set to `Alphabetical' by default. If you organize your alias
286lists where the sublists are of the following form: 324file in other ways, then adding aliases to the `Top' or `Bottom' of your alias
325file might be more appropriate."
326 :type '(choice (const :tag "Alphabetical" sorted)
327 (const :tag "Top" top)
328 (const :tag "Bottom" bottom))
329 :group 'mh-alias)
287 330
288 (:KEYWORD FUNC1 FUNC2 FUNC3 ...) 331(defcustom mh-alias-local-users t
332 "*If on, local users are added to alias completion.
289 333
290Here :KEYWORD is one of :folder or :letter. If it is :folder then the default 334Aliases are created from `/etc/passwd' entries with a user ID larger than
291buttons in the folder and show mode buffers are being specified. If it is 335a magical number, typically 200. This can be a handy tool on a machine where
292:letter then the default buttons in the letter mode are listed. FUNC1, FUNC2, 336you and co-workers exchange messages. These aliases have the form
293FUNC3, ... are the names of the functions that the buttons would execute. 337`local.first.last' if a real name is present in the password file.
338Otherwise, the alias will have the form `local.login'.
294 339
295Each element of BUTTONS is a list consisting of four mandatory items and one 340If you're on a system with thousands of users you don't know, and the loading
296optional item as follows: 341of local aliases slows MH-E down noticeably, then turn this option off.
297 342
298 (FUNCTION MODES ICON DOC &optional ENABLE-EXPR) 343This option also takes a string which is executed to generate the password
344file. For example, use \"ypcat passwd\" to obtain the NIS password file."
345 :type '(choice (boolean) (string))
346 :group 'mh-alias)
299 347
300where, 348(defcustom mh-alias-local-users-prefix "local."
349 "*String prepended to the real names of users from the password file.
350This option can also be set to `Use Login'.
301 351
302 FUNCTION is the name of the function that will be executed when the button 352For example, consider the following password file entry:
303 is clicked.
304 353
305 MODES is a list of symbols. List elements must be from `folder', `letter' and 354 psg:x:1000:1000:Peter S Galbraith,,,:/home/psg:/bin/tcsh
306 `sequence'. If `folder' is present then the button is available in the
307 folder and show buffer. If the name of FUNCTION is of the form \"mh-foo\",
308 where foo is some arbitrary string, then we check if the function
309 `mh-show-foo' exists. If it exists then that function is used in the show
310 buffer. Otherwise the original function `mh-foo' is used in the show buffer
311 as well. Presence of `sequence' is handled similar to the above. The only
312 difference is that the button is shown only when the folder is narrowed to a
313 sequence. If `letter' is present in MODES, then the button is available
314 during draft editing and runs FUNCTION when clicked.
315 355
316 ICON is the icon that is drawn in the button. 356The following settings of this option will produce the associated aliases:
317 357
318 DOC is the documentation for the button. It is used in tool-tips and in 358 \"local.\" local.peter.galbraith
319 providing other help to the user. GNU Emacs uses only the first line of the 359 \"\" peter.galbraith
320 string. So the DOC should be formatted such that the first line is useful and 360 Use Login psg
321 complete without the rest of the string.
322 361
323 Optional item ENABLE-EXPR is an arbitrary lisp expression. If it evaluates 362This option has no effect if variable `mh-alias-local-users' is turned off."
324 to nil, then the button is deactivated, otherwise it is active. If is in't 363 :type '(choice (const :tag "Use Login" nil)
325 present then the button is always active." 364 (string))
326 ;; The following variable names have been carefully chosen to make code 365 :group 'mh-alias)
327 ;; generation easier. Modifying the names should be done carefully.
328 (let (folder-buttons folder-docs folder-button-setter sequence-button-setter
329 show-buttons show-button-setter show-seq-button-setter
330 letter-buttons letter-docs letter-button-setter
331 folder-defaults letter-defaults
332 folder-vectors show-vectors letter-vectors)
333 (dolist (x defaults)
334 (cond ((eq (car x) :folder) (setq folder-defaults (cdr x)))
335 ((eq (car x) :letter) (setq letter-defaults (cdr x)))))
336 (dolist (button buttons)
337 (unless (and (listp button)
338 (or (equal (length button) 4) (equal (length button) 5)))
339 (error "Incorrect MH-E tool-bar button specification: %s" button))
340 (let* ((name (nth 0 button))
341 (name-str (symbol-name name))
342 (icon (nth 2 button))
343 (xemacs-icon (mh-do-in-xemacs
344 (cdr (assoc (intern icon) mh-xemacs-icon-map))))
345 (full-doc (nth 3 button))
346 (doc (if (string-match "\\(.*\\)\n" full-doc)
347 (match-string 1 full-doc)
348 full-doc))
349 (enable-expr (or (nth 4 button) t))
350 (modes (nth 1 button))
351 functions show-sym)
352 (when (memq 'letter modes) (setq functions `(:letter ,name)))
353 (when (or (memq 'folder modes) (memq 'sequence modes))
354 (setq functions
355 (append `(,(if (memq 'folder modes) :folder :sequence) ,name)
356 functions))
357 (setq show-sym
358 (if (string-match "^mh-\\(.*\\)$" name-str)
359 (intern (concat "mh-show-" (match-string 1 name-str)))
360 name))
361 (setq functions
362 (append `(,(if (memq 'folder modes) :show :show-seq)
363 ,(if (fboundp show-sym) show-sym name))
364 functions)))
365 (do ((functions functions (cddr functions)))
366 ((null functions))
367 (let* ((type (car functions))
368 (function (cadr functions))
369 (type1 (substring (symbol-name type) 1))
370 (vector-list (cond ((eq type :show) 'show-vectors)
371 ((eq type :show-seq) 'show-vectors)
372 ((eq type :letter) 'letter-vectors)
373 (t 'folder-vectors)))
374 (list (cond ((eq type :letter) 'mh-tool-bar-letter-buttons)
375 (t 'mh-tool-bar-folder-buttons)))
376 (key (intern (concat "mh-" type1 "toolbar-" name-str)))
377 (setter (intern (concat type1 "-button-setter")))
378 (mbuttons (cond ((eq type :letter) 'letter-buttons)
379 ((eq type :show) 'show-buttons)
380 ((eq type :show-seq) 'show-buttons)
381 (t 'folder-buttons)))
382 (docs (cond ((eq mbuttons 'letter-buttons) 'letter-docs)
383 ((eq mbuttons 'folder-buttons) 'folder-docs))))
384 (add-to-list vector-list `[,xemacs-icon ,function t ,full-doc])
385 (add-to-list
386 setter `(when (member ',name ,list)
387 (mh-funcall-if-exists
388 tool-bar-add-item ,icon ',function ',key
389 :help ,doc :enable ',enable-expr)))
390 (add-to-list mbuttons name)
391 (if docs (add-to-list docs doc))))))
392 (setq folder-buttons (nreverse folder-buttons)
393 letter-buttons (nreverse letter-buttons)
394 show-buttons (nreverse show-buttons)
395 letter-docs (nreverse letter-docs)
396 folder-docs (nreverse folder-docs)
397 folder-vectors (nreverse folder-vectors)
398 show-vectors (nreverse show-vectors)
399 letter-vectors (nreverse letter-vectors))
400 (dolist (x folder-defaults)
401 (unless (memq x folder-buttons)
402 (error "Folder defaults contains unknown button '%s'" x)))
403 (dolist (x letter-defaults)
404 (unless (memq x letter-buttons)
405 (error "Letter defaults contains unknown button '%s'" x)))
406 `(eval-when (compile load eval)
407 (defvar mh-folder-tool-bar-map nil)
408 (defvar mh-folder-seq-tool-bar-map nil)
409 (defvar mh-show-tool-bar-map nil)
410 (defvar mh-show-seq-tool-bar-map nil)
411 (defvar mh-letter-tool-bar-map nil)
412 ;; GNU Emacs tool bar specific code
413 (mh-do-in-gnu-emacs
414 ;; Custom setter functions
415 (defun mh-tool-bar-folder-buttons-set (symbol value)
416 "Construct toolbar for `mh-folder-mode' and `mh-show-mode'."
417 (set-default symbol value)
418 (setq mh-folder-tool-bar-map
419 (let ((tool-bar-map (make-sparse-keymap)))
420 ,@(nreverse folder-button-setter)
421 tool-bar-map))
422 (setq mh-show-tool-bar-map
423 (let ((tool-bar-map (make-sparse-keymap)))
424 ,@(nreverse show-button-setter)
425 tool-bar-map))
426 (setq mh-show-seq-tool-bar-map
427 (let ((tool-bar-map (copy-keymap mh-show-tool-bar-map)))
428 ,@(nreverse show-seq-button-setter)
429 tool-bar-map))
430 (setq mh-folder-seq-tool-bar-map
431 (let ((tool-bar-map (copy-keymap mh-folder-tool-bar-map)))
432 ,@(nreverse sequence-button-setter)
433 tool-bar-map)))
434 (defun mh-tool-bar-letter-buttons-set (symbol value)
435 "Construct toolbar for `mh-letter-mode'."
436 (set-default symbol value)
437 (setq mh-letter-tool-bar-map
438 (let ((tool-bar-map (make-sparse-keymap)))
439 ,@(nreverse letter-button-setter)
440 tool-bar-map))))
441 ;; XEmacs specific code
442 (mh-do-in-xemacs
443 (defvar mh-toolbar-folder-vector-map
444 ',(loop for button in folder-buttons
445 for vector in folder-vectors
446 collect (cons button vector)))
447 (defvar mh-toolbar-show-vector-map
448 ',(loop for button in show-buttons
449 for vector in show-vectors
450 collect (cons button vector)))
451 (defvar mh-toolbar-letter-vector-map
452 ',(loop for button in letter-buttons
453 for vector in letter-vectors
454 collect (cons button vector)))
455 (defvar mh-toolbar-folder-buttons nil)
456 (defvar mh-toolbar-show-buttons nil)
457 (defvar mh-toolbar-letter-buttons nil)
458 ;; Custom setter functions
459 (defun mh-tool-bar-letter-buttons-set (symbol value)
460 (set-default symbol value)
461 (setq mh-toolbar-letter-buttons
462 (loop for b in value
463 collect (cdr (assoc b mh-toolbar-letter-vector-map)))))
464 (defun mh-tool-bar-folder-buttons-set (symbol value)
465 (set-default symbol value)
466 (setq mh-toolbar-folder-buttons
467 (loop for b in value
468 collect (cdr (assoc b mh-toolbar-folder-vector-map))))
469 (setq mh-toolbar-show-buttons
470 (loop for b in value
471 collect (cdr (assoc b mh-toolbar-show-vector-map)))))
472 ;; Initialize toolbar
473 (defun mh-toolbar-init (mode)
474 "Install toolbar in MODE."
475 (let ((toolbar (cond ((eq mode :folder) mh-toolbar-folder-buttons)
476 ((eq mode :letter) mh-toolbar-letter-buttons)
477 ((eq mode :show) mh-toolbar-show-buttons)))
478 (height 37)
479 (width 40)
480 (buffer (current-buffer)))
481 (when (and mh-xemacs-toolbar-position mh-xemacs-use-toolbar-flag)
482 (cond
483 ((eq mh-xemacs-toolbar-position 'top)
484 (set-specifier top-toolbar toolbar buffer)
485 (set-specifier top-toolbar-visible-p t)
486 (set-specifier top-toolbar-height height))
487 ((eq mh-xemacs-toolbar-position 'bottom)
488 (set-specifier bottom-toolbar toolbar buffer)
489 (set-specifier bottom-toolbar-visible-p t)
490 (set-specifier bottom-toolbar-height height))
491 ((eq mh-xemacs-toolbar-position 'left)
492 (set-specifier left-toolbar toolbar buffer)
493 (set-specifier left-toolbar-visible-p t)
494 (set-specifier left-toolbar-width width))
495 ((eq mh-xemacs-toolbar-position 'right)
496 (set-specifier right-toolbar toolbar buffer)
497 (set-specifier right-toolbar-visible-p t)
498 (set-specifier right-toolbar-width width))
499 (t (set-specifier default-toolbar toolbar buffer)))))))
500 ;; Declare customizable toolbars
501 (custom-declare-variable
502 'mh-tool-bar-folder-buttons
503 '(list ,@(mapcar (lambda (x) `(quote ,x)) folder-defaults))
504 "Choose buttons to include in MH-E folder/show toolbar."
505 :group 'mh-toolbar :set 'mh-tool-bar-folder-buttons-set
506 :type '(set ,@(loop for x in folder-buttons
507 for y in folder-docs
508 collect `(const :tag ,y ,x))))
509 (custom-declare-variable
510 'mh-tool-bar-letter-buttons
511 '(list ,@(mapcar (lambda (x) `(quote ,x)) letter-defaults))
512 "Choose buttons to include in MH-E letter toolbar."
513 :group 'mh-toolbar :set 'mh-tool-bar-letter-buttons-set
514 :type '(set ,@(loop for x in letter-buttons
515 for y in letter-docs
516 collect `(const :tag ,y ,x)))))))
517 366
518(mh-tool-bar-define 367(defcustom mh-alias-passwd-gecos-comma-separator-flag t
519 ((:folder mh-inc-folder mh-mime-save-parts mh-previous-undeleted-msg 368 "*Non-nil means the gecos field in the password file uses a comma separator.
520 mh-page-msg mh-next-undeleted-msg mh-delete-msg mh-refile-msg 369In the example in `mh-alias-local-users-prefix', commas are used to separate
521 mh-undo mh-execute-commands mh-toggle-tick mh-reply 370different values within the so-called gecos field. This is a fairly common
522 mh-alias-grab-from-field mh-send mh-rescan-folder 371usage. However, in the rare case that the gecos field in your password file is
523 mh-tool-bar-search mh-visit-folder 372not separated by commas and whose contents may contain commas, you can turn
524 mh-tool-bar-customize mh-tool-bar-folder-help mh-widen) 373this option off."
525 (:letter mh-send-letter mh-compose-insertion ispell-message save-buffer 374 :type 'boolean
526 undo kill-region menu-bar-kill-ring-save yank mh-fully-kill-draft 375 :group 'mh-alias)
527 mh-tool-bar-customize mh-tool-bar-letter-help))
528 ;; Folder/Show buffer buttons
529 (mh-inc-folder (folder) "mail"
530 "Incorporate new mail in Inbox
531This button runs `mh-inc-folder' which drags any
532new mail into your Inbox folder.")
533 (mh-mime-save-parts (folder) "attach"
534 "Save MIME parts from this message
535This button runs `mh-mime-save-parts' which saves a message's
536different parts into separate files.")
537 (mh-previous-undeleted-msg (folder) "left_arrow"
538 "Go to the previous undeleted message
539This button runs `mh-previous-undeleted-msg'")
540 (mh-page-msg (folder) "page-down"
541 "Page the current message forwards\nThis button runs `mh-page-msg'")
542 (mh-next-undeleted-msg (folder) "right_arrow"
543 "Go to the next undeleted message\nThe button runs `mh-next-undeleted-msg'")
544 (mh-delete-msg (folder) "close"
545 "Mark this message for deletion\nThis button runs `mh-delete-msg'")
546 (mh-refile-msg (folder) "refile"
547 "Refile this message\nThis button runs `mh-refile-msg'")
548 (mh-undo (folder) "undo" "Undo last operation\nThis button runs `undo'")
549 (mh-execute-commands (folder) "execute"
550 "Perform moves and deletes\nThis button runs `mh-execute-commands'")
551 (mh-toggle-tick (folder) "highlight"
552 "Toggle tick mark\nThis button runs `mh-toggle-tick'")
553 (mh-toggle-showing (folder) "show"
554 "Toggle showing message\nThis button runs `mh-toggle-showing'")
555 (mh-tool-bar-reply-from (folder) "reply-from" "Reply to \"from\"")
556 (mh-tool-bar-reply-to (folder) "reply-to" "Reply to \"to\"")
557 (mh-tool-bar-reply-all (folder) "reply-all" "Reply to \"all\"")
558 (mh-reply (folder) "mail/reply2"
559 "Reply to this message\nThis button runs `mh-reply'")
560 (mh-alias-grab-from-field (folder) "alias"
561 "Grab From alias\nThis button runs `mh-alias-grab-from-field'"
562 (mh-alias-from-has-no-alias-p))
563 (mh-send (folder) "mail_compose"
564 "Compose new message\nThis button runs `mh-send'")
565 (mh-rescan-folder (folder) "rescan"
566 "Rescan this folder\nThis button runs `mh-rescan-folder'")
567 (mh-pack-folder (folder) "repack"
568 "Repack this folder\nThis button runs `mh-pack-folder'")
569 (mh-tool-bar-search (folder) "search"
570 "Search\nThis button runs `mh-tool-bar-search-function'")
571 (mh-visit-folder (folder) "fld_open"
572 "Visit other folder\nThis button runs `mh-visit-folder'")
573 ;; Letter buffer buttons
574 (mh-send-letter (letter) "mail_send" "Send this letter")
575 (mh-compose-insertion (letter) "attach" "Insert attachment")
576 (ispell-message (letter) "spell" "Check spelling")
577 (save-buffer (letter) "save" "Save current buffer to its file")
578 (undo (letter) "undo" "Undo last operation")
579 (kill-region (letter) "cut"
580 "Cut (kill) text in region between mark and current position")
581 (menu-bar-kill-ring-save (letter) "copy"
582 "Copy text in region between mark and current position")
583 (yank (letter) "paste" "Paste (yank) text cut or copied earlier")
584 (mh-fully-kill-draft (letter) "close" "Kill this draft")
585 ;; Common buttons
586 (mh-tool-bar-customize (folder letter) "preferences" "MH-E Preferences")
587 (mh-tool-bar-folder-help (folder) "help"
588 "Help! (general help)\nThis button runs `Info-goto-node'")
589 (mh-tool-bar-letter-help (letter) "help"
590 "Help! (general help)\nThis button runs `Info-goto-node'")
591 ;; Folder narrowed to sequence buttons
592 (mh-widen (sequence) "widen"
593 "Widen from the sequence\nThis button runs `mh-widen'"))
594 376
595 377
596 378
597;;; Speedbar and folder configuration (:group 'mh-speed) 379;;; Organizing Your Mail with Folders (:group 'mh-folder)
598
599(defcustom mh-large-folder 200
600 "The number of messages that indicates a large folder.
601If a folder is deemed to be large, that is the number of messages in it exceed
602this value, then confirmation is needed when it is visited. Even when
603`mh-show-threads-flag' is non-nil, the folder is not automatically threaded, if
604it is large. If set to nil all folders are treated as if they are small."
605 :type '(choice (const :tag "No limit") integer)
606 :group 'mh-speed)
607
608(defcustom mh-speed-flists-interval 60
609 "Time between calls to flists in seconds.
610If 0, flists is not called repeatedly."
611 :type 'integer
612 :group 'mh-speed)
613 380
614(defcustom mh-speed-run-flists-flag t 381(defcustom mh-recenter-summary-flag nil
615 "Non-nil means flists is used. 382 "*Non-nil means to recenter the summary window.
616If non-nil, flists is executed every `mh-speed-flists-interval' seconds to 383If this option is turned on, recenter the summary window when the show window
617update the display of the number of unseen and total messages in each folder. 384is toggled off."
618If resources are limited, this can be set to nil and the speedbar display can
619be updated manually with the \\[mh-speed-flists] command."
620 :type 'boolean 385 :type 'boolean
621 :group 'mh-speed) 386 :group 'mh-folder)
622 387
623 388
624 389
625;;; Options for controlling scan listing (:group 'mh-folder) 390;;; Folder Selection (:group 'mh-folder-selection)
626 391
627(defcustom mh-adaptive-cmd-note-flag t 392(defcustom mh-default-folder-for-message-function nil
628 "*Non-nil means that the message number width is determined dynamically. 393 "Function to select a default folder for refiling or `Fcc'.
629This is done once when a folder is first opened by running scan on the last 394The current buffer is set to the message being refiled with point at the start
630message of the folder. The message number for the last message is extracted 395of the message. This function should return the default folder as a string
631and its width calculated. This width is used when calling `mh-set-cmd-note'. 396with a leading `+' sign. It can also return nil so that the last folder name
632 397is used as the default, or an empty string to suppress the default entirely."
633If you prefer fixed-width message numbers, set this variable to nil and call 398 :type 'function
634`mh-set-cmd-note' with the width specified by the scan format in 399 :group 'mh-folder-selection)
635`mh-scan-format-file'. For example, the default width is 4, so you would use
636\"(mh-set-cmd-note 4)\" if `mh-scan-format-file' were nil."
637 :type 'boolean
638 :group 'mh-folder)
639 400
640(defcustom mh-default-folder-list nil 401(defcustom mh-default-folder-list nil
641 "*Alist of addresses and folders. 402 "*List of addresses and folders.
642When refiling messages, these folders are the default that is provided if the 403The folder name associated with the first address found in this list is used
643sender (or recipient if the Check Recipient checkbox has been selected) has 404as the default for `mh-refile-msg' and similar functions. Each element in this
644the associated address, a regexp. The first entry to match will be used, so 405list contains a `Check Recipient' item. If this item is turned on, then the
645order them according to the wanted priority. You do not need to list your 406address is checked against the recipient instead of the sender. This is useful
646aliases here as that lookup is already performed. 407for mailing lists.
647 408
648See `mh-prompt-for-refile-folder' and `mh-folder-from-address' for more 409See `mh-prompt-for-refile-folder' and `mh-folder-from-address' for more
649information." 410information."
650 :type '(repeat (list (regexp :tag "Address") 411 :type '(repeat (list (regexp :tag "Address")
651 (string :tag "Folder") 412 (string :tag "Folder")
652 (boolean :tag "Check Recipient"))) 413 (boolean :tag "Check Recipient")))
653 :group 'mh-folder) 414 :group 'mh-folder-selection)
654 415
655(defcustom mh-default-folder-must-exist-flag t 416(defcustom mh-default-folder-must-exist-flag t
656 "*Non-nil means guessed folder name must exist to be used. 417 "*Non-nil means guessed folder name must exist to be used.
657If this variable is t, then the guessed name is only used if the folder 418If the derived folder does not exist, and this option is on, then the last
658already exists\; if the folder doesn't exist, then the last folder name used 419folder name used is suggested. This is useful if you get mail from various
659is suggested. This is useful if you get mail from various people for whom you 420people for whom you have an alias, but file them all in the same project
660have an alias, but file them all in the same project folder. 421folder.
422
661See `mh-prompt-for-refile-folder' and `mh-folder-from-address' for more 423See `mh-prompt-for-refile-folder' and `mh-folder-from-address' for more
662information." 424information."
663 :type 'boolean 425 :type 'boolean
664 :group 'mh-folder) 426 :group 'mh-folder-selection)
665 427
666(defcustom mh-default-folder-prefix "" 428(defcustom mh-default-folder-prefix ""
667 "*Prefix used for guessed folder names. 429 "*Prefix used for folder names generated from aliases.
668This can be used to put folders associated with your aliases in a sub-folder 430The prefix is used to prevent clutter in your mail directory.
669so as to not clutter your mail directory. 431
670See `mh-prompt-for-refile-folder' and `mh-folder-from-address' for more 432See `mh-prompt-for-refile-folder' and `mh-folder-from-address' for more
671information." 433information."
672 :type 'string 434 :type 'string
673 :group 'mh-folder) 435 :group 'mh-folder-selection)
674
675(defcustom mh-inc-prog "inc"
676 "*Program to run to incorporate new mail into a folder.
677Normally \"inc\". This file is searched for relative to
678the `mh-progs' directory unless it is an absolute pathname."
679 :type 'string
680 :group 'mh-folder)
681
682(defcustom mh-inc-spool-list nil
683 "*Alist of alternate spool files, corresponding folders and keybindings.
684Here's an example. Suppose you have subscribed to the MH-E devel mailing
685list. You could filter its mail into a separate spool file named
686~/mail/mh-e using Procmail and a .procmailrc entry like:
687
688MAILDIR=$HOME/mail #you'd better make sure it exists
689:0:
690* ^From mh-e-devel-admin@lists.sourceforge.net
691mh-e
692
693If you wanted to incorporate that spool file into an MH folder called
694mh-e by pressing \"I m\" in folder-mode or by `M-x mh-inc-spool-mh-e',
695you would setup `mh-inc-spool-list' with an entry:
696
697 Spool file: ~/mail/mh-e
698 Folder: mh-e
699 Key binding: m
700
701Then, you could also install `xbuffy' and configure an extra mailbox like so:
702
703box ~/mail/mh-e
704 title mh-e
705 origMode
706 polltime 10
707 headertime 0
708 command gnudoit -q '(mh-inc-spool-mh-e)'
709
710Note that the entry above uses the gnuserv package to communicate the
711command `mh-inc-spool-mh-e' to Emacs. It will incorporate the spool file
712when clicking the xbuffy box with the middle mouse button."
713 :type '(repeat (list (file :tag "Spool file")
714 (string :tag "Folder")
715 (character :tag "Key binding")))
716 :set 'mh-inc-spool-list-set
717 :group 'mh-folder)
718 436
719(defcustom mh-interpret-number-as-range-flag t 437
720 "Non-nil means interpret a number as a range.
721If the variable is non-nil, and you use an integer, N, when asked for a
722range to scan, then MH-E uses the range \"last:N\"."
723 :type 'boolean
724 :group 'mh-folder)
725
726(defcustom mh-lpr-command-format "lpr -J '%s'"
727 "*Format for Unix command that prints a message.
728The string should be a Unix command line, with the string '%s' where
729the job's name (folder and message number) should appear. The formatted
730message text is piped to this command when you type \\<mh-folder-mode-map>`\\[mh-print-msg]'."
731 :type 'string
732 :group 'mh-folder)
733 438
734(defcustom mh-mime-save-parts-default-directory t 439;;; Identities (:group 'mh-identity)
735 "Default directory to use for `mh-mime-save-parts'.
736If nil, prompt and set for next time the command is used during same session.
737If t, prompt always"
738 :type '(choice (const :tag "Prompt the first time" nil)
739 (const :tag "Prompt always" t)
740 directory)
741 :group 'mh-folder)
742 440
743(defcustom mh-print-background-flag nil 441(defcustom mh-identity-list nil
744 "*Non-nil means messages should be printed in the background. 442 "*List of identities.
745WARNING: do not delete the messages until printing is finished; 443
746otherwise, your output may be truncated." 444Each element consists of an identity label, and a collection of header fields
747 :type 'boolean 445and a signature to insert if the identity is selected (see
748 :group 'mh-folder) 446`mh-identity-default', `mh-insert-identity' and the `Identity' menu in a
447MH-Letter buffer). The `Value Menu' contains the common header fields `From'
448and `Organization'. Other header fields may be added using the `Other Field'
449menu item. The `Signature' menu item is used to insert a signature with
450`mh-insert-signature'. The `GPG Key ID' menu item is used to specify a
451different key to sign or encrypt messages."
452 :type '(repeat (list :tag ""
453 (string :tag "Label")
454 (repeat :tag "Add at least one item below"
455 (choice
456 (cons :tag "From Field"
457 (const "From")
458 (string :tag "Value"))
459 (cons :tag "Organization Field"
460 (const "Organization")
461 (string :tag "Value"))
462 (cons :tag "Other Field"
463 (string :tag "Field")
464 (string :tag "Value"))
465 (cons :tag "Attribution Verb"
466 (const ":attribution-verb")
467 (string :tag "Value"))
468 (cons :tag "Signature"
469 (const :tag "Signature"
470 ":signature")
471 (choice
472 (const :tag "mh-signature-file-name"
473 nil)
474 (file)
475 (function)))
476 (cons :tag "GPG Key ID"
477 (const :tag "GPG Key ID"
478 ":pgg-default-user-id")
479 (string :tag "Value"))))))
480 :set 'mh-identity-list-set
481 :group 'mh-identity)
749 482
750(defcustom mh-recenter-summary-flag nil 483(defcustom mh-auto-fields-list nil
751 "*Non-nil means to recenter the summary window. 484 "List of recipients for which header lines are automatically inserted.
752Recenter the summary window when the show window is toggled off if non-nil." 485Each element consists of the recipient, which is a regular expression, and a
753 :type 'boolean 486collection of header fields and identities to insert if the message is sent to
754 :group 'mh-folder) 487this recipient. The `Value Menu' contains the common header fields `Fcc' and
488`Mail-Followup-To'. Other header fields may be added using the `Other Field'
489menu item. The `Identity' menu item is used to insert entire identities with
490`mh-insert-identity'."
491 :type `(repeat
492 (list :tag ""
493 (string :tag "Recipient")
494 (repeat :tag "Add at least one item below"
495 (choice
496 (cons :tag "Identity"
497 (const ":identity")
498 ,(append
499 '(radio)
500 (mapcar
501 (function (lambda (arg) `(const ,arg)))
502 (mapcar 'car mh-identity-list))))
503 (cons :tag "Fcc Field"
504 (const "fcc")
505 (string :tag "Value"))
506 (cons :tag "Mail-Followup-To Field"
507 (const "Mail-Followup-To")
508 (string :tag "Value"))
509 (cons :tag "Other Field"
510 (string :tag "Field")
511 (string :tag "Value"))))))
512 :group 'mh-identity)
755 513
756(defcustom mh-recursive-folders-flag nil 514(defcustom mh-auto-fields-prompt-flag t
757 "*Non-nil means that commands which operate on folders do so recursively." 515 "*Non-nil means to prompt before sending if fields inserted.
516See `mh-auto-fields-list'."
758 :type 'boolean 517 :type 'boolean
759 :group 'mh-folder) 518 :group 'mh-identity)
760 519
761;;; If `mh-unpropagated-sequences' becomes a defcustom, add the following tot 520(defcustom mh-identity-default nil
762;;; he docstring: "Additional sequences that should not to be preserved can be 521 "Default identity to use when `mh-letter-mode' is called."
763;;; specified by setting `mh-unpropagated-sequences' appropriately." XXX 522 :type (append
523 '(radio)
524 (cons '(const :tag "None" nil)
525 (mapcar (function (lambda (arg) `(const ,arg)))
526 (mapcar 'car mh-identity-list))))
527 :group 'mh-identity)
764 528
765(defcustom mh-refile-preserves-sequences-flag t 529(defcustom mh-identity-handlers
766 "*Non-nil means that sequences are preserved when messages are refiled. 530 '(("default" . mh-identity-handler-bottom)
767If this variable is non-nil and a message belonging to a sequence other than 531 ("from" . mh-identity-handler-top)
768cur or Previous-Sequence (see mh-profile 5) is refiled then it is put in the 532 (":attribution-verb" . mh-identity-handler-attribution-verb)
769same sequence in the destination folder." 533 (":signature" . mh-identity-handler-signature)
770 :type 'boolean 534 (":pgg-default-user-id" . mh-identity-handler-gpg-identity))
771 :group 'mh-folder) 535 "Handler functions for fields in `mh-identity-list'.
536This is an alist of fields (strings) and handlers (functions). Strings are
537lowercase. Use \":signature\" for Signature and \":pgg-default-user-id\" for
538GPG Key ID. The function associated with the string \"default\" is used if no
539other functions are appropriate. For this reason, don't name a header field
540\"Default\"."
541 :type '(repeat (cons (string :tag "Field") function))
542 :group 'mh-identity)
772 543
773(defcustom mh-scan-format-file t 544
774 "Specifies the format file to pass to the scan program.
775If t, the format string will be taken from the either `mh-scan-format-mh'
776or `mh-scan-format-nmh' depending on whether MH or nmh is in use.
777If nil, the default scan output will be used.
778 545
779If you customize the scan format, you may need to modify a few variables 546;;; Incorporating Your Mail (:group 'mh-inc)
780containing regexps that MH-E uses to identify specific portions of the output.
781Use `M-x apropos RET mh-scan.*regexp' to obtain a list of these variables. You
782may also have to call `mh-set-cmd-note' with the width of your message
783numbers. See also `mh-adaptive-cmd-note-flag'."
784 :type '(choice (const :tag "Use MH-E scan format" t)
785 (const :tag "Use default scan format" nil)
786 (file :tag "Specify a scan format file"))
787 :group 'mh-folder)
788 547
789(defcustom mh-scan-prog "scan" 548(defcustom mh-inc-prog "inc"
790 "*Program to run to generate one-line-per-message listing of a folder. 549 "*Program to run to incorporate new mail into a folder.
791Normally \"scan\" or a file name linked to scan. This file is searched 550Normally \"inc\". This program is relative to the `mh-progs' directory unless
792for relative to the `mh-progs' directory unless it is an absolute pathname." 551it is an absolute pathname."
793 :type 'string 552 :type 'string
794 :group 'mh-folder) 553 :group 'mh-inc)
795(make-variable-buffer-local 'mh-scan-prog)
796
797(defcustom mh-show-threads-flag nil
798 "Non-nil means new folders start in threaded mode.
799Threading large number of messages can be time consuming. So if the flag is
800non-nil then threading will be done only if the number of messages being
801threaded is less than `mh-large-folder'."
802 :type 'boolean
803 :group 'mh-folder)
804
805(defcustom mh-store-default-directory nil
806 "*Last directory used by \\[mh-store-msg]; default for next store.
807A directory name string, or nil to use current directory."
808 :type '(choice (const :tag "Current" nil)
809 directory)
810 :group 'mh-folder)
811 554
812(defcustom mh-tick-seq 'tick 555(defcustom mh-inc-spool-list nil
813 "The name of the MH tick sequence." 556 "*Alist of alternate spool files, corresponding folders and keybindings.
814 :type '(choice (const :tag "Disable ticking" nil) 557This option will be described by example.
815 symbol) 558
816 :group 'mh-folder) 559Suppose you have subscribed to the mh-e-devel mailing list and you use
817 560procmail to filter its mail into `~/mail/mh-e' with the following
818(defcustom mh-update-sequences-after-mh-show-flag t 561`.procmailrc' recipe:
819 "*Non-nil means `mh-update-sequence' is called from `mh-show-mode'. 562
820If set, `mh-update-sequence' is run every time a message is shown, telling 563 MAILDIR=$HOME/mail
821MH or nmh that this is your current message. It's useful, for example, to 564 :0:
822display MIME content using \"M-! mhshow RET\"" 565 * ^From mh-e-devel-admin@lists.sourceforge.net
823 :type 'boolean 566 mh-e
824 :group 'mh-folder) 567
568If you wanted to incorporate that spool file into an MH folder called mh-e
569with the \"I m\" or \\[mh-inc-spool-mh-e] commands, you would use the
570following:
571
572 Spool File: ~/mail/mh-e
573 Folder: mh-e
574 Key Binding: m
575
576Then, you could also install `xbuffy' and configure an extra mailbox using the
577gnuserv package to run the `mh-inc-spool-mh-e' command in Emacs:
578
579 box ~/mail/mh-e
580 title mh-e
581 origMode
582 polltime 10
583 headertime 0
584 command gnudoit -q '(mh-inc-spool-mh-e)'
585
586To incorporate the spool file, click the xbuffy box with the middle mouse
587button."
588 :type '(repeat (list (file :tag "Spool File")
589 (string :tag "Folder")
590 (character :tag "Key Binding")))
591 :set 'mh-inc-spool-list-set
592 :group 'mh-inc)
825 593
826 594
827 595
828;;; Indexed searching (:group 'mh-index) 596;;; Searching (:group 'mh-index)
829 597
830(defcustom mh-index-new-messages-folders t 598(defcustom mh-index-new-messages-folders t
831 "Folders searched for `mh-unseen-seq'. 599 "Folders searched for the `unseen' sequence.
832If t, then `mh-inbox' is searched. If nil, all the top level folders are 600This option can be set to `Inbox' to search the `+inbox' folder or `All' to
833searched. Otherwise the list of folders specified as strings are searched. 601search all of the top level folders. Otherwise, list the folders that should
602be searched with the `Choose Folders' menu item.
603
834See also `mh-recursive-folders-flag'." 604See also `mh-recursive-folders-flag'."
835 :group 'mh-index 605 :group 'mh-index
836 :type '(choice (const :tag "Inbox" t) 606 :type '(choice (const :tag "Inbox" t)
837 (const :tag "All" nil) 607 (const :tag "All" nil)
838 (repeat :tag "Choose folders" (string :tag "Folder")))) 608 (repeat :tag "Choose Folders" (string :tag "Folder"))))
839 609
840(defcustom mh-index-program nil 610(defcustom mh-index-program nil
841 "Indexing program that MH-E shall use. 611 "Indexing program that MH-E shall use.
842The possible choices are swish++, swish-e, mairix, namazu, glimpse, pick and 612The default setting of this option is `Auto-detect' which means that MH-E will
843grep. By default this variable is nil which means that the programs are tried 613automatically choose one of swish++, swish-e, mairix, namazu, pick and grep in
844in order and the first one found is used. 614that order. If, for example, you have both swish++ and mairix installed and
615you want to use mairix, then you can set this option to `mairix'.
845 616
846More information about setting up an indexing program to use with MH-E can be 617More information about setting up an indexing program to use with MH-E can be
847found in the documentation of `mh-index-search'." 618found in the documentation of `mh-index-search'."
@@ -850,33 +621,34 @@ found in the documentation of `mh-index-search'."
850 (const :tag "swish-e" swish) 621 (const :tag "swish-e" swish)
851 (const :tag "mairix" mairix) 622 (const :tag "mairix" mairix)
852 (const :tag "namazu" namazu) 623 (const :tag "namazu" namazu)
853 (const :tag "glimpse" glimpse)
854 (const :tag "pick" pick) 624 (const :tag "pick" pick)
855 (const :tag "grep" grep)) 625 (const :tag "grep" grep))
856 :group 'mh-index) 626 :group 'mh-index)
857 627
858(defcustom mh-index-ticked-messages-folders t 628(defcustom mh-index-ticked-messages-folders t
859 "Folders searched for `mh-tick-seq'. 629 "Folders searched for `mh-tick-seq'.
860If t, then `mh-inbox' is searched. If nil, all the top level folders are 630This option can be set to `Inbox' to search the `+inbox' folder or `All' to
861searched. Otherwise the list of folders specified as strings are searched. 631search all of the top level folders. Otherwise, list the folders that should
632be searched with the `Choose Folders' menu item.
633
862See also `mh-recursive-folders-flag'." 634See also `mh-recursive-folders-flag'."
863 :group 'mh-index 635 :group 'mh-index
864 :type '(choice (const :tag "Inbox" t) 636 :type '(choice (const :tag "Inbox" t)
865 (const :tag "All" nil) 637 (const :tag "All" nil)
866 (repeat :tag "Choose folders" (string :tag "Folder")))) 638 (repeat :tag "Choose Folders" (string :tag "Folder"))))
867 639
868 640
869 641
870;;; Spam Handling (:group 'mh-junk) 642;;; Dealing with Junk Mail (:group 'mh-junk)
871 643
872;; Spam fighting program chosen 644;; Spam fighting program chosen
873(defvar mh-junk-choice nil) 645(defvar mh-junk-choice nil)
874 646
875;; Available spam filter interfaces 647;; Available spam filter interfaces
876(defvar mh-junk-function-alist 648(defvar mh-junk-function-alist
877 '((bogofilter mh-bogofilter-blacklist mh-bogofilter-whitelist) 649 '((spamassassin mh-spamassassin-blacklist mh-spamassassin-whitelist)
878 (spamprobe mh-spamprobe-blacklist mh-spamprobe-whitelist) 650 (bogofilter mh-bogofilter-blacklist mh-bogofilter-whitelist)
879 (spamassassin mh-spamassassin-blacklist mh-spamassassin-whitelist)) 651 (spamprobe mh-spamprobe-blacklist mh-spamprobe-whitelist))
880 "Available choices of spam programs to use. 652 "Available choices of spam programs to use.
881This is an alist. For each element there are functions that blacklist a message 653This is an alist. For each element there are functions that blacklist a message
882as spam and whitelist a message incorrectly classified as spam.") 654as spam and whitelist a message incorrectly classified as spam.")
@@ -894,28 +666,348 @@ bound to the new value of `mh-junk-program'. The function sets the variable
894 finally return (car element))))) 666 finally return (car element)))))
895 667
896;; User customizable variables 668;; User customizable variables
897(defcustom mh-junk-mail-folder nil 669(defcustom mh-junk-disposition nil
898 "Folder to put spam mail in. 670 "Disposition of junk mail."
899If nil then the spam is deleted." 671 :type '(choice (const :tag "Delete Spam" nil)
900 :type '(choice (const :tag "Delete spam" nil) 672 (string :tag "Spam Folder"))
901 (string :tag "Spam folder"))
902 :group 'mh-junk) 673 :group 'mh-junk)
903 674
904(defcustom mh-junk-program nil 675(defcustom mh-junk-program nil
905 "Spam program that MH-E shall use. 676 "Spam program that MH-E should use.
906The possible choices are bogofilter, spamprobe, and spamassassin. By default 677The default setting of this option is `Auto-detect' which means that MH-E will
907this variable is nil which means that the programs are tried in order and the 678automatically choose one of SpamAssassin, Bogofilter, or SpamProbe in that
908first one found is used." 679order. If, for example, you have both SpamAssassin and Bogofilter installed
909 :type '(choice (const :tag "auto-detect" nil) 680and you want to use BogoFilter, then you can set this option to `Bogofilter'."
910 (const :tag "bogofilter" bogofilter) 681 :type '(choice (const :tag "Auto-detect" nil)
911 (const :tag "spamprobe" spamprobe) 682 (const :tag "SpamAssassin" spamassassin)
912 (const :tag "spamassassin" spamassassin)) 683 (const :tag "Bogofilter" bogofilter)
684 (const :tag "SpamProbe" spamprobe))
913 :set 'mh-junk-choose 685 :set 'mh-junk-choose
914 :group 'mh-junk) 686 :group 'mh-junk)
915 687
688(defcustom mh-junk-background nil
689 "If on, spam programs are run in background.
690By default, the programs are run in the foreground, but this can be slow when
691junking large numbers of messages. If you have enough memory or don't junk
692that many messages at the same time, you might try turning on this option."
693 :type '(choice (const :tag "Off" nil)
694 (const :tag "On" 0))
695 :group 'mh-junk)
696
697
698
699;;; Editing a Draft (:group 'mh-letter)
700
701(defcustom mh-mml-method-default (if mh-gnus-pgp-support-flag "pgpmime" "none")
702 "Default method to use in security directives."
703 :type '(choice (const :tag "PGP (MIME)" "pgpmime")
704 (const :tag "PGP" "pgp")
705 (const :tag "S/MIME" "smime")
706 (const :tag "None" "none"))
707 :group 'mh-letter)
708
709(defcustom mh-compose-forward-as-mime-flag t
710 "Non-nil means that messages are forwarded as a MIME part."
711 :type 'boolean
712 :group 'mh-letter)
713
714(defcustom mh-compose-insertion (if (locate-library "mml") 'gnus 'mhn)
715 "Type of MIME message directives in messages.
716
717By default, this option is set to `Gnus' if it is supported. This option can
718also be set manually to `mhn' if mhn directives are preferred."
719 :type '(choice (const :tag "Gnus" gnus)
720 (const :tag "mhn" mhn))
721 :group 'mh-letter)
722
723(defcustom mh-compose-skipped-header-fields
724 '("From" "Organization" "References" "In-Reply-To"
725 "X-Face" "Face" "X-Image-URL" "X-Mailer")
726 "List of header fields to skip over when navigating in draft."
727 :type '(repeat (string :tag "Field"))
728 :group 'mh-letter)
729
730(defcustom mh-compose-space-does-completion-flag nil
731 "*Non-nil means that <SPC> does completion in message header."
732 :type 'boolean
733 :group 'mh-letter)
734
735(defcustom mh-delete-yanked-msg-window-flag nil
736 "*Non-nil means delete any window displaying the message.
737If this option is on, yanking the current message into a draft letter with
738\\<mh-letter-mode-map>\\[mh-yank-cur-msg] deletes any windows displaying the
739message."
740 :type 'boolean
741 :group 'mh-letter)
742
743(defcustom mh-extract-from-attribution-verb "wrote:"
744 "*Verb to use for attribution when a message is yanked by \\<mh-letter-mode-map>\\[mh-yank-cur-msg]."
745 :type '(choice (const "wrote:")
746 (const "a écrit:")
747 (const "schrieb:")
748 (string :tag "Custom String"))
749 :group 'mh-letter)
750
751(defcustom mh-ins-buf-prefix "> "
752 "*String to put before each non-blank line of a yanked or inserted message.
753Used when the message is inserted into an outgoing letter
754by \\<mh-letter-mode-map>\\[mh-insert-letter] or \\[mh-yank-cur-msg]."
755 :type 'string
756 :group 'mh-letter)
757
758(defcustom mh-insert-x-mailer-flag t
759 "*Non-nil means append an X-Mailer field to the header."
760 :type 'boolean
761 :group 'mh-letter)
762
763(defcustom mh-letter-complete-function 'ispell-complete-word
764 "*Function to call when completing outside of address or folder fields.
765By default, this is set to `ispell-complete-word'."
766 :type '(choice function (const nil))
767 :group 'mh-letter)
768
769(defcustom mh-letter-fill-column 72
770 "*Fill column to use in `mh-letter-mode'.
771This is usually less than in other text modes because email messages get
772quoted by some prefix (sometimes many times) when they are replied to,
773and it's best to avoid quoted lines that span more than 80 columns."
774 :type 'integer
775 :group 'mh-letter)
776
777(defcustom mh-reply-show-message-flag t
778 "*Non-nil means the show buffer is displayed using \\<mh-letter-mode-map>\\[mh-reply].
779
780The setting of this variable determines whether the MH `show-buffer' is
781displayed with the current message when using `mh-reply' without a prefix
782argument. Set it to nil if you already include the message automatically
783in your draft using
784 repl: -filter repl.filter
785in your ~/.mh_profile file."
786 :type 'boolean
787 :group 'mh-letter)
788
789(defcustom mh-signature-file-name "~/.signature"
790 "*Source of user's signature.
791
792By default, the text of your signature is taken from the file `~/.signature'.
793You can read from other files by changing this option. This file may contain a
794vCard in which case an attachment is added with the vCard.
795
796This option may also be a symbol, in which case that function is called. You
797may not want a signature separator to be added for you; instead you may want
798to insert one yourself. Variables that you may find useful to do this include
799`mh-signature-separator' (when inserting a signature separator) and
800`mh-signature-separator-regexp' (for finding said separator). The function
801`mh-signature-separator-p', which reports t if the buffer contains a
802separator, may be useful as well.
803
804The signature is inserted into your message with the command
805\\<mh-letter-mode-map>\\[mh-insert-signature] or with the `mh-identity-list'
806option."
807 :type 'file
808 :group 'mh-letter)
809
810(defcustom mh-signature-separator-flag t
811 "*Non-nil means a signature separator should be inserted.
812It is not recommended that you change this option since various mail user
813agents, including MH-E, use the separator to present the signature
814differently, and to suppress the signature when replying or yanking a letter
815into a draft."
816 :type 'boolean
817 :group 'mh-letter)
818
819(defcustom mh-x-face-file "~/.face"
820 "*File containing face header field to insert in outgoing mail.
821
822If the file starts with either of the strings `X-Face:', `Face:' or
823`X-Image-URL:' then the contents are added to the message header verbatim.
824Otherwise it is assumed that the file contains the value of the `X-Face:'
825header field.
826
827The `X-Face:' header field, which is a low-resolution, black and white image,
828can be generated using the `compface' command, which can be obtained from
829ftp://ftp.cs.indiana.edu/pub/faces/compface/compface.tar.Z. The \"Online
830X-Face Convertor\" at http://www.dairiki.org/xface/ is a useful resource for
831quick conversion of images into `X-Face:' header fields.
832
833Use the `make-face' script (http://quimby.gnus.org/circus/face/make-face) to
834convert a JPEG image to the higher resolution, color, `Face:' header field.
835
836The URL of any image can be used for the `X-Image-URL:' field and no
837processing of the image is required.
838
839To prevent the setting of any of these header fields, either set
840`mh-x-face-file' to nil, or simply ensure that the file defined by this option
841doesn't exist."
842 :type 'file
843 :group 'mh-letter)
844
845(defcustom mh-yank-from-start-of-msg 'attribution
846 "*Controls which part of a message is yanked by \\<mh-letter-mode-map>\\[mh-yank-cur-msg].
847If t, include the entire message, with full headers. This is historically
848here for use with supercite, but is now deprecated in favor of the setting
849`supercite' below.
850
851If the symbol `body', then yank the message minus the header.
852
853If the symbol `supercite', include the entire message, with full headers.
854This also causes the invocation of `sc-cite-original' without the setting
855of `mail-citation-hook', now deprecated practice.
856
857If the symbol `autosupercite', do as for `supercite' automatically when
858show buffer matches the message being replied-to. When this option is used,
859the -noformat switch is passed to the repl program to override a -filter or
860-format switch.
861
862If the symbol `attribution', then yank the message minus the header and add
863a simple attribution line at the top.
864
865If the symbol `autoattrib', do as for `attribution' automatically when show
866buffer matches the message being replied-to. You can make sure this is
867always the case by setting `mh-reply-show-message-flag' to t (which is the
868default) and optionally `mh-delete-yanked-msg-window-flag' to t as well such
869that the show window is never displayed. When the `autoattrib' option is
870used, the -noformat switch is passed to the repl program to override a
871-filter or -format switch.
872
873If nil, yank only the portion of the message following the point.
874
875If the show buffer has a region, this variable is ignored unless its value is
876one of `attribution' or `autoattrib' in which case the attribution is added
877to the yanked region."
878 :type '(choice (const :tag "Below point" nil)
879 (const :tag "Without header" body)
880 (const :tag "Invoke supercite" supercite)
881 (const :tag "Invoke supercite, automatically" autosupercite)
882 (const :tag "Without header, with attribution" attribution)
883 (const :tag "Without header, with attribution, automatically"
884 autoattrib)
885 (const :tag "Entire message with headers" t))
886 :group 'mh-letter)
887
916 888
917 889
918;;; Message display (:group 'mh-show) 890;;; Ranges (:group 'mh-ranges)
891
892(defcustom mh-interpret-number-as-range-flag t
893 "Non-nil means interpret a number as a range.
894If the variable is non-nil, and you use an integer, N, when asked for a
895range to scan, then MH-E uses the range \"last:N\"."
896 :type 'boolean
897 :group 'mh-ranges)
898
899
900
901;;; Scan Line Formats (:group 'mh-scan-line-formats)
902
903(defcustom mh-adaptive-cmd-note-flag t
904 "*Non-nil means that the message number width is determined dynamically.
905This is done once when a folder is first opened by running scan on the last
906message of the folder. The message number for the last message is extracted
907and its width calculated. This width is used when calling `mh-set-cmd-note'.
908
909If you prefer fixed-width message numbers, set this variable to nil and call
910`mh-set-cmd-note' with the width specified by the scan format in
911`mh-scan-format-file'. For example, the default width is 4, so you would use
912\"(mh-set-cmd-note 4)\" if `mh-scan-format-file' were nil."
913 :type 'boolean
914 :group 'mh-scan-line-formats)
915
916(defcustom mh-scan-format-file t
917 "Specifies the format file to pass to the scan program.
918If t, the format string will be taken from the either `mh-scan-format-mh'
919or `mh-scan-format-nmh' depending on whether MH or nmh is in use.
920If nil, the default scan output will be used.
921
922If you customize the scan format, you may need to modify a few variables
923containing regexps that MH-E uses to identify specific portions of the output.
924Use `M-x apropos RET mh-scan.*regexp' to obtain a list of these variables. You
925may also have to call `mh-set-cmd-note' with the width of your message
926numbers. See also `mh-adaptive-cmd-note-flag'."
927 :type '(choice (const :tag "Use MH-E scan Format" t)
928 (const :tag "Use Default scan Format" nil)
929 (file :tag "Specify a scan Format File"))
930 :group 'mh-scan-line-formats)
931
932(defcustom mh-scan-prog "scan"
933 "*Program to run to generate one-line-per-message listing of a folder.
934Normally \"scan\" or a file name linked to scan. This file is searched
935for relative to the `mh-progs' directory unless it is an absolute pathname."
936 :type 'string
937 :group 'mh-scan-line-formats)
938(make-variable-buffer-local 'mh-scan-prog)
939
940
941
942;;; Sending Mail (:group 'mh-sending-mail)
943
944(defcustom mh-compose-letter-function nil
945 "Invoked when setting up a letter draft.
946It is passed three arguments: TO recipients, SUBJECT, and CC recipients."
947 :type '(choice (const nil) function)
948 :group 'mh-sending-mail)
949
950(defcustom mh-compose-prompt-flag nil
951 "*Non-nil means prompt for header fields when composing a new draft."
952 :type 'boolean
953 :group 'mh-sending-mail)
954
955(defcustom mh-forward-subject-format "%s: %s"
956 "*Format to generate the Subject: line contents for a forwarded message.
957The two string arguments to the format are the sender of the original
958message and the original subject line."
959 :type 'string
960 :group 'mh-sending-mail)
961
962(defcustom mh-reply-default-reply-to nil
963 "*Sets the person or persons to whom a reply will be sent.
964If nil, prompt for recipient. If non-nil, then \\<mh-folder-mode-map>`\\[mh-reply]' will use this
965value and it should be one of \"from\", \"to\", \"cc\", or \"all\".
966The values \"cc\" and \"all\" do the same thing."
967 :type '(choice (const :tag "Prompt" nil)
968 (const "from") (const "to")
969 (const "cc") (const "all"))
970 :group 'mh-sending-mail)
971
972
973
974;;; Sequences (:group 'mh-sequences)
975
976;;; If `mh-unpropagated-sequences' becomes a defcustom, add the following to
977;;; the docstring: "Additional sequences that should not to be preserved can be
978;;; specified by setting `mh-unpropagated-sequences' appropriately." XXX
979
980(defcustom mh-refile-preserves-sequences-flag t
981 "*Non-nil means that sequences are preserved when messages are refiled.
982If this variable is non-nil and a message belonging to a sequence other than
983cur or Previous-Sequence (see mh-profile 5) is refiled then it is put in the
984same sequence in the destination folder."
985 :type 'boolean
986 :group 'mh-sequences)
987
988(defcustom mh-tick-seq 'tick
989 "The name of the MH sequence for ticked messages.
990You would change this option if you already use the `tick' sequence for your
991own use. You can also disable all of the ticking functions by choosing the
992`Disable Ticking' item but there isn't much advantage to that."
993 :type '(choice (const :tag "Disable Ticking" nil)
994 symbol)
995 :group 'mh-sequences)
996
997(defcustom mh-update-sequences-after-mh-show-flag t
998 "*Non-nil means flush MH sequences to disk after message is shown.
999Three sequences are maintained internally by MH-E and pushed out to MH when a
1000message is shown. They include the sequence specified by your
1001`Unseen-Sequence:' profile entry, `cur', and the sequence listed by
1002the `mh-tick-seq' option which is `tick' by default.
1003If you do not like this behavior, set this option to nil. You can then update
1004the state manually with the \\<mh-folder-mode-map>`\\[mh-execute-commands]', `\\[mh-quit]', or `\\[mh-update-sequences]' commands."
1005 :type 'boolean
1006 :group 'mh-sequences)
1007
1008
1009
1010;;; Reading Your Mail (:group 'mh-show)
919 1011
920(defcustom mh-bury-show-buffer-flag t 1012(defcustom mh-bury-show-buffer-flag t
921 "*Non-nil means that the displayed show buffer for a folder is buried." 1013 "*Non-nil means that the displayed show buffer for a folder is buried."
@@ -923,10 +1015,11 @@ first one found is used."
923 :group 'mh-show) 1015 :group 'mh-show)
924 1016
925(defcustom mh-clean-message-header-flag t 1017(defcustom mh-clean-message-header-flag t
926 "*Non-nil means clean headers of messages that are displayed or inserted. 1018 "*Non-nil means remove extraneous header fields.
927The variable `mh-invisible-headers' if set determines the header fields that 1019The header fields listed in the `mh-invisible-header-fields-default' option
928are displayed. If it isn't set, then the variable `mh-invisible-headers' 1020are hidden, although you can check off any field that you would like to see.
929determines the header fields that are removed." 1021Header fields that you would like to hide that aren't listed can be added to
1022the `mh-invisible-header-fields' option."
930 :type 'boolean 1023 :type 'boolean
931 :group 'mh-show) 1024 :group 'mh-show)
932 1025
@@ -960,19 +1053,28 @@ question."
960 :type 'boolean 1053 :type 'boolean
961 :group 'mh-show) 1054 :group 'mh-show)
962 1055
963(defcustom mh-fetch-x-image-url nil 1056(defcustom mh-fetch-x-image-url 'ask
964 "Control fetching of X-Image-URL header field image. 1057 "*Control fetching of `X-Image-URL:' header field image.
965This setting only has effect if `mh-show-use-xface-flag' is non-nil. 1058If set to \"Always fetch\" (t), the image is always fetched. You probably want
1059to avoid this setting for privacy and DOS (denial of service) reasons. For
1060example, fetching a URL can tip off a spammer that you've read his email.
1061Someone may also flood your network and fill your disk drive by sending a
1062torrent of messages, each specifying a unique URL to a very large file.
1063
1064If set to \"Ask before fetching\" ('ask), you are prompted before the image is
1065fetched. MH-E will remember your reply and will either use the already fetched
1066image the next time the same URL is encountered or silently skip it if you
1067didn't fetch it the first time. This is the default.
1068
1069If set to \"Never fetch\" (nil), images are never fetched and only displayed
1070if they are already present in the cache.
966 1071
967If set to t, the image is fetched. 1072The cache of images is found in the directory `.mhe-x-image-cache' within your
1073MH directory. To see how you can add your own face to the `From:' field, see
1074`mh-x-face-file'.
968 1075
969If set to 'ask, the user is prompted before the image is fetched. MH-E will 1076This setting only has effect if `mh-show-use-xface-flag' is non-nil."
970remember your reply and will either use the already fetched image the next time
971the same URL is encountered or silently skip it if you didn't fetch it the
972first time.
973 1077
974If set to nil, the default, images are not fetched and only displayed if they
975are already present in the cache."
976 :type '(choice (const :tag "Always fetch" t) 1078 :type '(choice (const :tag "Always fetch" t)
977 (const :tag "Ask before fetching" ask) 1079 (const :tag "Ask before fetching" ask)
978 (const :tag "Never fetch" nil)) 1080 (const :tag "Never fetch" nil))
@@ -1002,28 +1104,8 @@ The gnus method uses a different color for each indentation."
1002 (const :tag "Don't fontify" nil)) 1104 (const :tag "Don't fontify" nil))
1003 :group 'mh-show) 1105 :group 'mh-show)
1004 1106
1005(defvar mh-invisible-headers nil
1006 "*Regexp matching lines in a message header that are not to be shown.
1007Customize the variable `mh-invisible-header-fields' to generate this variable;
1008It will in turn automatically use the function `mh-invisible-headers' to
1009generate this variable.
1010If the variable `mh-visible-headers' is non-nil, it is used instead to specify
1011what to keep.")
1012
1013(defun mh-invisible-headers ()
1014 "Make or remake the variable `mh-invisible-headers'.
1015Done using `mh-invisible-header-fields' as input."
1016 (if mh-invisible-header-fields
1017 (setq mh-invisible-headers
1018 (concat
1019 "^"
1020 (let ((max-specpdl-size 1000) ;workaround for insufficient default
1021 (fields mh-invisible-header-fields))
1022 (regexp-opt fields t))))
1023 (setq mh-invisible-headers nil)))
1024
1025;; Keep fields alphabetized. Mention source, if known. 1107;; Keep fields alphabetized. Mention source, if known.
1026(defcustom mh-invisible-header-fields 1108(defvar mh-invisible-header-fields-internal
1027 '("Approved:" 1109 '("Approved:"
1028 "Autoforwarded:" 1110 "Autoforwarded:"
1029 "Bestservhost:" 1111 "Bestservhost:"
@@ -1053,12 +1135,13 @@ Done using `mh-invisible-header-fields' as input."
1053 "Old-Return-Path:" 1135 "Old-Return-Path:"
1054 "Original-Encoded-Information-Types:" ; X400 1136 "Original-Encoded-Information-Types:" ; X400
1055 "Original-Lines:" ; mail to news 1137 "Original-Lines:" ; mail to news
1056 "Original-Newsgroups:" ; mail to news
1057 "Original-NNTP-" ; mail to news 1138 "Original-NNTP-" ; mail to news
1139 "Original-Newsgroups:" ; mail to news
1058 "Original-Path:" ; mail to news 1140 "Original-Path:" ; mail to news
1059 "Original-Received:" ; mail to news 1141 "Original-Received:" ; mail to news
1060 "Original-To:" ; mail to news 1142 "Original-To:" ; mail to news
1061 "Original-X-" ; mail to news 1143 "Original-X-" ; mail to news
1144 "Originator:"
1062 "P1-Content-Type:" ; X400 1145 "P1-Content-Type:" ; X400
1063 "P1-Message-Id:" ; X400 1146 "P1-Message-Id:" ; X400
1064 "P1-Recipient:" ; X400 1147 "P1-Recipient:" ; X400
@@ -1074,13 +1157,17 @@ Done using `mh-invisible-header-fields' as input."
1074 "Return-Path:" ; RFC 822 1157 "Return-Path:" ; RFC 822
1075 "Sensitivity:" ; MS Outlook 1158 "Sensitivity:" ; MS Outlook
1076 "Status:" ; sendmail 1159 "Status:" ; sendmail
1160 "Thread-"
1077 "Ua-Content-Id:" ; X400 1161 "Ua-Content-Id:" ; X400
1078;; "User-Agent:" ; Similar to X-Mailer, so display it. 1162;; "User-Agent:" ; Similar to X-Mailer, so display it.
1079 "Via:" ; MH 1163 "Via:" ; MH
1080 "X-Abuse-Info:" 1164 "X-Abuse-Info:"
1165 "X-Abuse-and-DMCA-"
1081 "X-Accept-Language:" 1166 "X-Accept-Language:"
1082 "X-Accept-Language:" ; Netscape/Mozilla 1167 "X-Accept-Language:" ; Netscape/Mozilla
1083 "X-Ack:" 1168 "X-Ack:"
1169 "X-Administrivia-To:"
1170 "X-AntiAbuse:" ; cPanel
1084 "X-Apparently-From:" ; MS Outlook 1171 "X-Apparently-From:" ; MS Outlook
1085 "X-Apparently-To:" ; Egroups/yahoogroups mailing list manager 1172 "X-Apparently-To:" ; Egroups/yahoogroups mailing list manager
1086 "X-Authentication-Warning:" ; sendmail 1173 "X-Authentication-Warning:" ; sendmail
@@ -1088,13 +1175,18 @@ Done using `mh-invisible-header-fields' as input."
1088 "X-Bogosity:" ; bogofilter 1175 "X-Bogosity:" ; bogofilter
1089 "X-Complaints-To:" 1176 "X-Complaints-To:"
1090 "X-Cron-Env:" 1177 "X-Cron-Env:"
1178 "X-DMCA"
1091 "X-Delivered" 1179 "X-Delivered"
1180 "X-ELNK-Trace:" ; Earthlink mailer
1181 "X-Envelope-Date:" ; GNU mailutils
1182 "X-Envelope-From:"
1092 "X-Envelope-Sender:" 1183 "X-Envelope-Sender:"
1093 "X-Envelope-To:" 1184 "X-Envelope-To:"
1094 "X-Face:" 1185 "X-Face:"
1095 "X-Folder:" ; Spam 1186 "X-Folder:" ; Spam
1096 "X-From-Line" 1187 "X-From-Line"
1097 "X-Gnus-Mail-Source:" ; gnus 1188 "X-Gnus-Mail-Source:" ; gnus
1189 "X-Greylist:" ; milter-greylist-1.2.1
1098 "X-Habeas-SWE-1:" ; Spam 1190 "X-Habeas-SWE-1:" ; Spam
1099 "X-Habeas-SWE-2:" ; Spam 1191 "X-Habeas-SWE-2:" ; Spam
1100 "X-Habeas-SWE-3:" ; Spam 1192 "X-Habeas-SWE-3:" ; Spam
@@ -1104,27 +1196,35 @@ Done using `mh-invisible-header-fields' as input."
1104 "X-Habeas-SWE-7:" ; Spam 1196 "X-Habeas-SWE-7:" ; Spam
1105 "X-Habeas-SWE-8:" ; Spam 1197 "X-Habeas-SWE-8:" ; Spam
1106 "X-Habeas-SWE-9:" ; Spam 1198 "X-Habeas-SWE-9:" ; Spam
1199 "X-Image-URL:" ; URL equivalent of X-Face and Face
1107 "X-Info:" ; NTMail 1200 "X-Info:" ; NTMail
1108 "X-Juno-" ; Juno 1201 "X-Juno-" ; Juno
1109 "X-List-Host:" ; Unknown mailing list managers 1202 "X-List-Host:" ; Unknown mailing list managers
1110 "X-List-Subscribe:" ; Unknown mailing list managers 1203 "X-List-Subscribe:" ; Unknown mailing list managers
1111 "X-List-Unsubscribe:" ; Unknown mailing list managers 1204 "X-List-Unsubscribe:" ; Unknown mailing list managers
1205 "X-Listprocessor-" ; ListProc(tm) by CREN
1112 "X-Listserver:" ; Unknown mailing list managers 1206 "X-Listserver:" ; Unknown mailing list managers
1113 "X-Loop:" ; Unknown mailing list managers 1207 "X-Loop:" ; Unknown mailing list managers
1208 "X-MHE-Checksum" ; Checksum added during index search
1114 "X-MIME-Autoconverted:" ; sendmail 1209 "X-MIME-Autoconverted:" ; sendmail
1115 "X-MIMETrack:" 1210 "X-MIMETrack:"
1116 "X-MS-TNEF-Correlator:" ; MS Outlook 1211 "X-Mms-" ; T-Mobile pictures
1212 "X-MS-" ; MS Outlook
1213 "X-MailScanner" ; ListProc(tm) by CREN
1117 "X-Mailing-List:" ; Unknown mailing list managers 1214 "X-Mailing-List:" ; Unknown mailing list managers
1118 "X-Mailman-Version:" ; Mailman mailing list manager 1215 "X-Mailman-Version:" ; Mailman mailing list manager
1119 "X-Majordomo:" ; Majordomo mailing list manager 1216 "X-Majordomo:" ; Majordomo mailing list manager
1120 "X-Message-Id" 1217 "X-Message-Id"
1121 "X-MHE-Checksum" ; Checksum added during index search 1218 "X-MessageWall-Score:" ; Unknown mailing list manager, AUC TeX
1122 "X-MimeOLE:" ; MS Outlook 1219 "X-MimeOLE:" ; MS Outlook
1123 "X-Mozilla-Status:" ; Netscape/Mozilla 1220 "X-Mozilla-Status:" ; Netscape/Mozilla
1124 "X-Msmail-" ; MS Outlook 1221 "X-Msmail-" ; MS Outlook
1222 "X-NAI-Spam-" ; Network Associates Inc. SpamKiller
1125 "X-News:" ; News 1223 "X-News:" ; News
1126 "X-No-Archive:" 1224 "X-No-Archive:"
1127 "X-Notes-Item:" ; Lotus Notes Domino structured header 1225 "X-Notes-Item:" ; Lotus Notes Domino structured header
1226 "X-OperatingSystem:"
1227 ;;"X-Operator:" ; Similar to X-Mailer, so display it
1128 "X-Orcl-Content-Type:" 1228 "X-Orcl-Content-Type:"
1129 "X-Original-Complaints-To:" 1229 "X-Original-Complaints-To:"
1130 "X-Original-Date:" ; SourceForge mailing list manager 1230 "X-Original-Date:" ; SourceForge mailing list manager
@@ -1132,8 +1232,10 @@ Done using `mh-invisible-header-fields' as input."
1132 "X-Original-Trace:" 1232 "X-Original-Trace:"
1133 "X-OriginalArrivalTime:" ; Hotmail 1233 "X-OriginalArrivalTime:" ; Hotmail
1134 "X-Originating-IP:" ; Hotmail 1234 "X-Originating-IP:" ; Hotmail
1235 "X-Postfilter:"
1135 "X-Priority:" ; MS Outlook 1236 "X-Priority:" ; MS Outlook
1136 "X-Qotd-" ; User added 1237 "X-Qotd-" ; User added
1238 "X-RM"
1137 "X-Received-Date:" 1239 "X-Received-Date:"
1138 "X-Received:" 1240 "X-Received:"
1139 "X-Request-" 1241 "X-Request-"
@@ -1141,38 +1243,108 @@ Done using `mh-invisible-header-fields' as input."
1141 "X-SBNote:" ; Spam 1243 "X-SBNote:" ; Spam
1142 "X-SBPass:" ; Spam 1244 "X-SBPass:" ; Spam
1143 "X-SBRule:" ; Spam 1245 "X-SBRule:" ; Spam
1246 "X-SMTP-"
1144 "X-Scanned-By" 1247 "X-Scanned-By"
1145 "X-Sender:" 1248 "X-Sender:"
1146 "X-Server-Date:" 1249 "X-Server-Date:"
1147 "X-Server-Uuid:" 1250 "X-Server-Uuid:"
1148 "X-Sieve:" ; Sieve filtering 1251 "X-Sieve:" ; Sieve filtering
1149 "X-Spam-Checker-Version:" ; Spamassassin 1252 "X-Source"
1150 "X-Spam-Level:" ; Spamassassin 1253 "X-Spam-" ; Spamassassin
1151 "X-Spam-Score:" ; Spamassassin
1152 "X-Spam-Status:" ; Spamassassin
1153 "X-SpamBouncer:" ; Spam 1254 "X-SpamBouncer:" ; Spam
1255 "X-Status"
1256 "X-Submissions-To:"
1257 "X-Telecom-Digest"
1154 "X-Trace:" 1258 "X-Trace:"
1259 "X-UID"
1155 "X-UIDL:" 1260 "X-UIDL:"
1156 "X-UserInfo1:" 1261 "X-UserInfo1:"
1157 "X-VSMLoop:" ; NTMail 1262 "X-VSMLoop:" ; NTMail
1158 "X-Vms-To:" 1263 "X-Vms-To:"
1264 "X-WebTV-Signature:"
1159 "X-Wss-Id:" ; Worldtalk gateways 1265 "X-Wss-Id:" ; Worldtalk gateways
1266 "X-Yahoo"
1160 "X-eGroups-" ; Egroups/yahoogroups mailing list manager 1267 "X-eGroups-" ; Egroups/yahoogroups mailing list manager
1161 "X-pgp:" 1268 "X-pgp:"
1162 "X-submission-address:" 1269 "X-submission-address:"
1163 "X400-" ; X400 1270 "X400-" ; X400
1164 "Xref:") 1271 "Xref:")
1165"*List of header fields that are not to be shown. 1272 "List of default header fields that are not to be shown.
1166Regexps are not allowed. Unique fields should have a \":\" suffix; otherwise, 1273Do not alter this variable directly. Instead, add entries from here that you
1167the element can be used to render invisible an entire class of fields that 1274would like to be displayed in `mh-invisible-header-fields-default'
1168start with the same prefix. 1275and add entries to hide in `mh-invisible-header-fields'.")
1169This variable is ignored if the variable `mh-visible-headers' is set." 1276
1277(defvar mh-invisible-header-fields-compiled nil
1278 "*Regexp matching lines in a message header that are not to be shown.
1279Do not alter this variable directly. Instead, customize
1280`mh-invisible-header-fields-default' checking for fields normally
1281hidden that you wish to display, and add extra entries to hide in
1282`mh-invisible-header-fields'.")
1283
1284(defun mh-invisible-headers ()
1285 "Make or remake the variable `mh-invisible-header-fields-compiled'.
1286Done using `mh-invisible-header-fields-internal' as input, from which entries
1287from `mh-invisible-header-fields-default' are removed and entries
1288from `mh-invisible-header-fields' are added."
1289 (let ((fields mh-invisible-header-fields-internal))
1290 (when mh-invisible-header-fields-default
1291 ;; Remove entries from `mh-invisible-header-fields-default'
1292 (setq fields
1293 (loop for x in fields
1294 unless (member x mh-invisible-header-fields-default)
1295 collect x)))
1296 (when (and (boundp 'mh-invisible-header-fields)
1297 mh-invisible-header-fields)
1298 (dolist (x mh-invisible-header-fields)
1299 (unless (member x fields) (setq fields (cons x fields)))))
1300 (if fields
1301 (setq mh-invisible-header-fields-compiled
1302 (concat
1303 "^"
1304 ;; workaround for insufficient default
1305 (let ((max-specpdl-size 1000))
1306 (regexp-opt fields t))))
1307 (setq mh-invisible-header-fields-compiled nil))))
1308
1309(defcustom mh-invisible-header-fields-default nil
1310 "*List of hidden header fields.
1311The header fields listed in this option are hidden, although you can check off
1312any field that you would like to see. Header fields that you would like to
1313hide that aren't listed can be added to the `mh-invisible-header-fields'
1314option.
1315
1316See also `mh-clean-message-header-flag'."
1317 :type `(set ,@(mapcar (lambda (x) `(const ,x))
1318 mh-invisible-header-fields-internal))
1319 :set (lambda (symbol value)
1320 (set-default symbol value)
1321 (mh-invisible-headers))
1322 :group 'mh-show)
1323
1324(defcustom mh-invisible-header-fields nil
1325 "*Additional header fields to hide.
1326Header fields that you would like to hide that aren't listed in
1327`mh-invisible-header-fields-default' can be added to this option with a couple
1328of caveats. Regular expressions are not allowed. Unique fields should have a
1329`:' suffix; otherwise, the element can be used to render invisible an entire
1330class of fields that start with the same prefix.
1331
1332See also `mh-clean-message-header-flag'."
1333
1170 :type '(repeat (string :tag "Header field")) 1334 :type '(repeat (string :tag "Header field"))
1171 :set (lambda (symbol value) 1335 :set (lambda (symbol value)
1172 (set-default symbol value) 1336 (set-default symbol value)
1173 (mh-invisible-headers)) 1337 (mh-invisible-headers))
1174 :group 'mh-show) 1338 :group 'mh-show)
1175 1339
1340(defcustom mh-lpr-command-format "lpr -J '%s'"
1341 "*Format for Unix command that prints a message.
1342The string should be a Unix command line, with the string '%s' where
1343the job's name (folder and message number) should appear. The formatted
1344message text is piped to this command when you type \\<mh-folder-mode-map>`\\[mh-print-msg]'."
1345 :type 'string
1346 :group 'mh-show)
1347
1176(defcustom mh-max-inline-image-height nil 1348(defcustom mh-max-inline-image-height nil
1177 "*Maximum inline image height if Content-Disposition is not present. 1349 "*Maximum inline image height if Content-Disposition is not present.
1178If nil, image will be displayed if its height is smaller than the height of 1350If nil, image will be displayed if its height is smaller than the height of
@@ -1187,6 +1359,27 @@ window."
1187 :type '(choice (const nil) integer) 1359 :type '(choice (const nil) integer)
1188 :group 'mh-show) 1360 :group 'mh-show)
1189 1361
1362(defcustom mh-mime-save-parts-default-directory t
1363 "Default directory to use for `mh-mime-save-parts'.
1364If nil, prompt and set for next time the command is used during same session.
1365If t, prompt always"
1366 :type '(choice (const :tag "Prompt the first time" nil)
1367 (const :tag "Prompt always" t)
1368 directory)
1369 :group 'mh-show)
1370
1371(defcustom mh-print-background-flag nil
1372 "*Non-nil means messages should be printed in the background.
1373WARNING: do not delete the messages until printing is finished;
1374otherwise, your output may be truncated."
1375 :type 'boolean
1376 :group 'mh-show)
1377
1378(defcustom mh-recursive-folders-flag nil
1379 "*Non-nil means that commands which operate on folders do so recursively."
1380 :type 'boolean
1381 :group 'mh-show)
1382
1190(defcustom mh-show-maximum-size 0 1383(defcustom mh-show-maximum-size 0
1191 "*Maximum size of message (in bytes) to display automatically. 1384 "*Maximum size of message (in bytes) to display automatically.
1192Provides an opportunity to skip over large messages which may be slow to load. 1385Provides an opportunity to skip over large messages which may be slow to load.
@@ -1194,6 +1387,14 @@ Use a value of 0 to display all messages automatically regardless of size."
1194 :type 'integer 1387 :type 'integer
1195 :group 'mh-show) 1388 :group 'mh-show)
1196 1389
1390(defcustom mh-show-threads-flag nil
1391 "Non-nil means new folders start in threaded mode.
1392Threading large number of messages can be time consuming. So if the flag is
1393non-nil then threading will be done only if the number of messages being
1394threaded is less than `mh-large-folder'."
1395 :type 'boolean
1396 :group 'mh-show)
1397
1197;; Use goto-addr if it was already loaded (which probably sets this 1398;; Use goto-addr if it was already loaded (which probably sets this
1198;; variable to t), or if this variable is otherwise set to t. 1399;; variable to t), or if this variable is otherwise set to t.
1199(defcustom mh-show-use-goto-addr-flag (and (boundp 'goto-address-highlight-p) 1400(defcustom mh-show-use-goto-addr-flag (and (boundp 'goto-address-highlight-p)
@@ -1205,80 +1406,55 @@ The `goto-addr' module is used."
1205 1406
1206(defcustom mh-show-use-xface-flag (>= emacs-major-version 21) 1407(defcustom mh-show-use-xface-flag (>= emacs-major-version 21)
1207 "*Non-nil means display face images in `mh-show-mode'. 1408 "*Non-nil means display face images in `mh-show-mode'.
1208This flag controls the display of three kinds of faces. 1409
1209 1410MH-E can display the content of `Face:', `X-Face:', and `X-Image-URL:' header
1210The first is the traditional X-Face header field. For GNU Emacs 21 1411fields. If any of these fields occur in the header of your message, the
1211and above, the `uncompface' binary is required to be in the execute 1412sender's face will appear in the `From:' header field. If more than one of
1212PATH for the display of X-Face images. It can be obtained from 1413these fields appear, then the first field found in the order `Face:',
1213ftp://ftp.cs.indiana.edu/pub/faces/compface/compface.tar.Z. 1414`X-Face:', and `X-Image-URL:' will be used. Note that versions of GNU Emacs
1214 1415prior to 21.1 don't support the display of inline images, so face images are
1215If the XEmacs you are using has internal support for X-Face images, then MH-E 1416not displayed in these versions.
1216will display X-Face images in XEmacs \"out of the box\". Even if you don't have 1417
1217X-Face support compiled into your XEmacs, you can still see the X-Face images 1418The option `mh-show-use-xface-flag' is used to turn this feature on and off.
1218in MH-E with the aid of an external x-face package and `uncompface'. It is 1419This feature will be turned on by default if your system supports it.
1219available from ftp://ftp.jpl.org/pub/elisp/. Download it, put its files in the 1420
1220`load-path' and MH-E will invoke it automatically. 1421The first header field used, if present, is the Gnus-specific `Face:' field.
1221 1422The `Face:' field appeared in GNU Emacs 21 and XEmacs. For more information,
1222Second, MH-E supports the display of the Gnus-specific Face 1423see http://quimby.gnus.org/circus/face/. Next is the traditional `X-Face:'
1223header field in GNU Emacs >= 21 and XEmacs. No external packages 1424header field. The display of this field requires the `uncompface' program
1224are required. More information about the Face header can be found 1425which can be obtained from
1225at: http://quimby.gnus.org/circus/face/. 1426ftp://ftp.cs.indiana.edu/pub/faces/compface/compface.tar.Z. Recent versions of
1226 1427XEmacs have internal support for `X-Face:' images. If your version of XEmacs
1227Finally, MH-E can also display images from the X-Image-URL header field. The 1428does not, then you'll need both `uncompface' and the x-face package which is
1228display of the images requires the `wget' program, available from 1429available at ftp://ftp.jpl.org/pub/elisp/.
1229http://www.gnu.org/software/wget/wget.html, to fetch the image and the 1430
1230`convert' program from the ImageMagick suite, available from 1431Finally, MH-E will display images referenced by the `X-Image-URL:' header
1432field if neither the `Face:' nor the `X-Face:' fields are present. The display
1433of the images requires `wget' (available from
1434http://www.gnu.org/software/wget/wget.html), `fetch', or `curl' to fetch the
1435image and the `convert' program from the ImageMagick suite, available from
1231http://www.imagemagick.org/. Of the three header fields this is the most 1436http://www.imagemagick.org/. Of the three header fields this is the most
1232efficient in terms of network usage since the image doesn't need to be 1437efficient in terms of network usage since the image doesn't need to be
1233transmitted with every single mail. However its display needs the recipient to 1438transmitted with every single mail.
1234fetch a URL and this can be misused. So it is disabled by default. It can be
1235enabled by customizing `mh-fetch-x-image-url'. Setting that to ask for
1236confirmation before fetching seems like a good choice.
1237 1439
1238Versions of GNU Emacs prior to 21.1 don't support the display of 1440The option `mh-fetch-x-image-url' controls the fetching of the `X-Image-URL:'
1239inline images. So face images are not displayed in these versions." 1441header field image."
1240 :type 'boolean 1442 :type 'boolean
1241 :group 'mh-show) 1443 :group 'mh-show)
1242 1444
1445(defcustom mh-store-default-directory nil
1446 "*Last directory used by \\[mh-store-msg]; default for next store.
1447A directory name string, or nil to use current directory."
1448 :type '(choice (const :tag "Current" nil)
1449 directory)
1450 :group 'mh-show)
1451
1243(defcustom mh-summary-height nil 1452(defcustom mh-summary-height nil
1244 "*Number of lines in MH-Folder window (including the mode line)." 1453 "*Number of lines in MH-Folder window (including the mode line)."
1245 :type '(choice (const :tag "Automatic" nil) 1454 :type '(choice (const :tag "Automatic" nil)
1246 (integer :tag "Fixed sized")) 1455 (integer :tag "Fixed sized"))
1247 :group 'mh-show) 1456 :group 'mh-show)
1248 1457
1249(defvar mh-visible-headers nil
1250 "*Regexp matching lines in a message header that are to be shown.
1251Customize the variable `mh-visible-header-fields' to generate this variable;
1252It will in turn automatically use the function `mh-visible-headers' to
1253generate this variable.
1254Only used if `mh-clean-message-header-flag' is non-nil. Setting it overrides
1255the variable `mh-invisible-headers'.")
1256
1257(defun mh-visible-headers ()
1258 "Make or remake the variable `mh-visible-headers'.
1259Done using `mh-visible-header-fields' as input."
1260 (if mh-visible-header-fields
1261 (setq mh-visible-headers
1262 (concat
1263 "^"
1264 (let ((max-specpdl-size 1000) ;workaround for insufficient default
1265 (fields mh-visible-header-fields))
1266 (regexp-opt fields t))))
1267 (setq mh-visible-headers nil)))
1268
1269(defcustom mh-visible-header-fields nil
1270"*List of header fields that are to be shown.
1271Regexps are not allowed. Unique fields should have a \":\" suffix; otherwise,
1272the element can be used to render visible an entire class of fields that
1273start with the same prefix.
1274Only used if `mh-clean-message-header-flag' is non-nil.
1275Setting it overrides the variable `mh-invisible-headers'."
1276 :type '(repeat (string :tag "Header field"))
1277 :set (lambda (symbol value)
1278 (set-default symbol value)
1279 (mh-visible-headers))
1280 :group 'mh-show)
1281
1282(defcustom mhl-formfile nil 1458(defcustom mhl-formfile nil
1283 "*Name of format file to be used by mhl to show and print messages. 1459 "*Name of format file to be used by mhl to show and print messages.
1284A value of t means use the default format file. 1460A value of t means use the default format file.
@@ -1292,387 +1468,489 @@ the message continues to conform to RFC 822 and MH-E can parse the headers."
1292 1468
1293 1469
1294 1470
1295;;; Composing messages (:group 'mh-letter) 1471;;; The Speedbar (:group 'mh-speed)
1296
1297(defcustom mh-compose-insertion (if (locate-library "mml") 'gnus 'mhn)
1298 "Use either 'gnus or 'mhn to insert MIME message directives in messages."
1299 :type '(choice (const :tag "Use Gnus" gnus)
1300 (const :tag "Use mhn" mhn))
1301 :group 'mh-letter)
1302
1303(defcustom mh-compose-letter-function nil
1304 "Invoked when setting up a letter draft.
1305It is passed three arguments: TO recipients, SUBJECT, and CC recipients."
1306 :type '(choice (const nil) function)
1307 :group 'mh-letter)
1308 1472
1309(defcustom mh-compose-prompt-flag nil 1473(defcustom mh-large-folder 200
1310 "*Non-nil means prompt for header fields when composing a new draft." 1474 "The number of messages that indicates a large folder.
1311 :type 'boolean 1475If a folder is deemed to be large, that is the number of messages in it exceed
1312 :group 'mh-letter) 1476this value, then confirmation is needed when it is visited. Even when
1313 1477`mh-show-threads-flag' is non-nil, the folder is not automatically threaded, if
1314(defcustom mh-compose-skipped-header-fields 1478it is large. If set to nil all folders are treated as if they are small."
1315 '("from" "organization" "references" "in-reply-to" "x-face" "face" 1479 :type '(choice (const :tag "No limit") integer)
1316 "x-mailer") 1480 :group 'mh-speed)
1317 "List of header fields to skip over when navigating in draft."
1318 :type '(repeat (string :tag "Field"))
1319 :group 'mh-letter)
1320
1321(defcustom mh-compose-space-does-completion-flag nil
1322 "*Non-nil means that SPACE does completion in message header."
1323 :type 'boolean
1324 :group 'mh-letter)
1325
1326(defcustom mh-delete-yanked-msg-window-flag nil
1327 "*Non-nil means delete any window displaying the message.
1328Controls window display when a message is yanked by \\<mh-letter-mode-map>\\[mh-yank-cur-msg].
1329If non-nil, yanking the current message into a draft letter deletes any
1330windows displaying the message."
1331 :type 'boolean
1332 :group 'mh-letter)
1333
1334(defcustom mh-extract-from-attribution-verb "wrote:"
1335 "*Verb to use for attribution when a message is yanked by \\<mh-letter-mode-map>\\[mh-yank-cur-msg]."
1336 :type '(choice (const "wrote:")
1337 (const "a écrit :")
1338 (string :tag "Custom string"))
1339 :group 'mh-letter)
1340
1341(defcustom mh-forward-subject-format "%s: %s"
1342 "*Format to generate the Subject: line contents for a forwarded message.
1343The two string arguments to the format are the sender of the original
1344message and the original subject line."
1345 :type 'string
1346 :group 'mh-letter)
1347
1348(defcustom mh-ins-buf-prefix "> "
1349 "*String to put before each non-blank line of a yanked or inserted message.
1350\\<mh-letter-mode-map>Used when the message is inserted into an outgoing letter
1351by \\[mh-insert-letter] or \\[mh-yank-cur-msg]."
1352 :type 'string
1353 :group 'mh-letter)
1354
1355(defcustom mh-insert-x-mailer-flag t
1356 "*Non-nil means append an X-Mailer field to the header."
1357 :type 'boolean
1358 :group 'mh-letter)
1359
1360(defcustom mh-letter-complete-function 'ispell-complete-word
1361 "*Function to call when completing outside of fields specific to aliases."
1362 :type '(choice function (const nil))
1363 :group 'mh-letter)
1364 1481
1365(defcustom mh-letter-fill-column 72 1482(defcustom mh-speed-flists-interval 60
1366 "*Fill column to use in `mh-letter-mode'. 1483 "Time between calls to flists in seconds.
1367This is usually less than in other text modes because email messages get 1484If 0, flists is not called repeatedly."
1368quoted by some prefix (sometimes many times) when they are replied to,
1369and it's best to avoid quoted lines that span more than 80 columns."
1370 :type 'integer 1485 :type 'integer
1371 :group 'mh-letter) 1486 :group 'mh-speed)
1372
1373(defcustom mh-reply-default-reply-to nil
1374 "*Sets the person or persons to whom a reply will be sent.
1375If nil, prompt for recipient. If non-nil, then \\<mh-folder-mode-map>`\\[mh-reply]' will use this
1376value and it should be one of \"from\", \"to\", \"cc\", or \"all\".
1377The values \"cc\" and \"all\" do the same thing."
1378 :type '(choice (const :tag "Prompt" nil)
1379 (const "from") (const "to")
1380 (const "cc") (const "all"))
1381 :group 'mh-letter)
1382
1383(defcustom mh-reply-show-message-flag t
1384 "*Non-nil means the show buffer is displayed using \\<mh-letter-mode-map>\\[mh-reply].
1385 1487
1386The setting of this variable determines whether the MH `show-buffer' is 1488(defcustom mh-speed-run-flists-flag t
1387displayed with the current message when using `mh-reply' without a prefix 1489 "Non-nil means flists is used.
1388argument. Set it to nil if you already include the message automatically 1490If non-nil, flists is executed every `mh-speed-flists-interval' seconds to
1389in your draft using 1491update the display of the number of unseen and total messages in each folder.
1390 repl: -filter repl.filter 1492If resources are limited, this can be set to nil and the speedbar display can
1391in your ~/.mh_profile file." 1493be updated manually with the \\[mh-speed-flists] command."
1392 :type 'boolean 1494 :type 'boolean
1393 :group 'mh-letter) 1495 :group 'mh-speed)
1394
1395(defcustom mh-signature-file-name "~/.signature"
1396 "*Name of file containing the user's signature.
1397Inserted into message by \\<mh-letter-mode-map>\\[mh-insert-signature]."
1398 :type 'file
1399 :group 'mh-letter)
1400
1401(defcustom mh-x-face-file "~/.face"
1402 "*File containing X-Face or Face header field to insert in outgoing mail.
1403
1404If the file starts with either of the strings \"X-Face: \", \"Face: \" or
1405\"X-Image-URL: \" then it is assumed to contain the whole field and is added to
1406the message header verbatim. Otherwise it is assumed that the file contains the
1407value of the X-Face header field.
1408
1409X-Face header fields can be generated using `compface', which can be obtained
1410from ftp://ftp.cs.indiana.edu/pub/faces/compface/compface.tar.Z. The \"Online
1411X-Face Convertor\" at http://www.dairiki.org/xface/ is a useful resource for
1412quick conversion of images into X-Face header fields.
1413
1414There is a `make-face' script that converts a jpeg image to a Face header
1415field at http://quimby.gnus.org/circus/face/make-face.
1416
1417The URL of any image can be used for the X-Image-URL field and no processing
1418of the image is required.
1419 1496
1420If nil, or the file does not exist, nothing is added to the message header." 1497
1421 :type 'file
1422 :group 'mh-letter)
1423 1498
1424(defcustom mh-yank-from-start-of-msg 'attribution 1499;;; The Toolbar (:group 'mh-toolbar)
1425 "*Controls which part of a message is yanked by \\<mh-letter-mode-map>\\[mh-yank-cur-msg].
1426If t, include the entire message, with full headers. This is historically
1427here for use with supercite, but is now deprecated in favor of the setting
1428`supercite' below.
1429 1500
1430If the symbol `body', then yank the message minus the header. 1501(defcustom mh-tool-bar-search-function 'mh-search-folder
1502 "*Function called by the tool-bar search button.
1503See `mh-search-folder' and `mh-index-search' for details."
1504 :type '(choice (const mh-search-folder)
1505 (const mh-index-search)
1506 (function :tag "Other function"))
1507 :group 'mh-toolbar)
1431 1508
1432If the symbol `supercite', include the entire message, with full headers. 1509;; Functions called from the tool bar
1433This also causes the invocation of `sc-cite-original' without the setting 1510(defun mh-tool-bar-search (&optional arg)
1434of `mail-citation-hook', now deprecated practice. 1511 "Interactively call `mh-tool-bar-search-function'.
1512Optional argument ARG is not used."
1513 (interactive "P")
1514 (call-interactively mh-tool-bar-search-function))
1435 1515
1436If the symbol `autosupercite', do as for `supercite' automatically when 1516(defun mh-tool-bar-customize ()
1437show buffer matches the message being replied-to. When this option is used, 1517 "Call `mh-customize' from the toolbar."
1438the -noformat switch is passed to the repl program to override a -filter or 1518 (interactive)
1439-format switch. 1519 (mh-customize t))
1440 1520
1441If the symbol `attribution', then yank the message minus the header and add 1521(defun mh-tool-bar-folder-help ()
1442a simple attribution line at the top. 1522 "Visit \"(mh-e)Top\"."
1523 (interactive)
1524 (Info-goto-node "(mh-e)Top")
1525 (delete-other-windows))
1443 1526
1444If the symbol `autoattrib', do as for `attribution' automatically when show 1527(defun mh-tool-bar-letter-help ()
1445buffer matches the message being replied-to. You can make sure this is 1528 "Visit \"(mh-e)Draft Editing\"."
1446always the case by setting `mh-reply-show-message-flag' to t (which is the 1529 (interactive)
1447default) and optionally `mh-delete-yanked-msg-window-flag' to t as well such 1530 (Info-goto-node "(mh-e)Draft Editing")
1448that the show window is never displayed. When the `autoattrib' option is 1531 (delete-other-windows))
1449used, the -noformat switch is passed to the repl program to override a
1450-filter or -format switch.
1451 1532
1452If nil, yank only the portion of the message following the point. 1533(defmacro mh-tool-bar-reply-generator (function recipient folder-buffer-flag)
1534 "Generate FUNCTION that replies to RECIPIENT.
1535If FOLDER-BUFFER-FLAG is nil then the function generated
1536When INCLUDE-FLAG is non-nil, include message body being replied to."
1537 `(defun ,function (&optional arg)
1538 ,(format "Reply to \"%s\".\nWhen ARG is non-nil include message in reply."
1539 recipient)
1540 (interactive "P")
1541 ,(if folder-buffer-flag nil '(set-buffer mh-show-folder-buffer))
1542 (mh-reply (mh-get-msg-num nil) ,recipient arg)))
1453 1543
1454If the show buffer has a region, this variable is ignored unless its value is 1544(mh-tool-bar-reply-generator mh-tool-bar-reply-from "from" t)
1455one of `attribution' or `autoattrib' in which case the attribution is added 1545(mh-tool-bar-reply-generator mh-show-tool-bar-reply-from "from" nil)
1456to the yanked region." 1546(mh-tool-bar-reply-generator mh-tool-bar-reply-to "to" t)
1457 :type '(choice (const :tag "Below point" nil) 1547(mh-tool-bar-reply-generator mh-show-tool-bar-reply-to "to" nil)
1458 (const :tag "Without header" body) 1548(mh-tool-bar-reply-generator mh-tool-bar-reply-all "all" t)
1459 (const :tag "Invoke supercite" supercite) 1549(mh-tool-bar-reply-generator mh-show-tool-bar-reply-all "all" nil)
1460 (const :tag "Invoke supercite, automatically" autosupercite)
1461 (const :tag "Without header, with attribution" attribution)
1462 (const :tag "Without header, with attribution, automatically"
1463 autoattrib)
1464 (const :tag "Entire message with headers" t))
1465 :group 'mh-letter)
1466 1550
1467 1551;; XEmacs has a couple of extra customizations...
1552(mh-do-in-xemacs
1553 (defcustom mh-xemacs-use-toolbar-flag (if (and (featurep 'toolbar)
1554 (featurep 'xpm)
1555 (device-on-window-system-p))
1556 t
1557 nil)
1558 "*If non-nil, use toolbar.
1468 1559
1469;;; Alias handling (:group 'mh-alias) 1560This will default to t if you are in an environment that supports
1561toolbars and xpm."
1562 :type 'boolean
1563 :group 'mh-toolbar)
1470 1564
1471(defcustom mh-alias-completion-ignore-case-flag t 1565 (defcustom mh-xemacs-toolbar-position (if mh-xemacs-use-toolbar-flag
1472 "*Non-nil means don't consider case significant in MH alias completion. 1566 'default
1473This is the default in plain MH, so it is the default here as well. It 1567 nil)
1474can be useful to set this to t if, for example, you use lowercase 1568 "*Where to put the toolbar.
1475aliases for people and uppercase for mailing lists."
1476 :type 'boolean
1477 :group 'mh-alias)
1478 1569
1479(defcustom mh-alias-expand-aliases-flag nil 1570Valid non-nil values are \"default\", \"top\", \"bottom\", \"left\",
1480 "*Non-nil means to expand aliases entered in the minibuffer. 1571\"right\". These match the four edges of the frame, with \"default\"
1481In other words, aliases entered in the minibuffer will be expanded to the full 1572meaning \"use the same position as the default-toolbar\".
1482address in the message draft. By default, this expansion is not performed."
1483 :type 'boolean
1484 :group 'mh-alias)
1485 1573
1486(defcustom mh-alias-flash-on-comma t 1574A nil value means do not use a toolbar.
1487 "*Specify whether to flash or warn on translation.
1488When a [comma] is pressed while entering aliases or addresses, setting this
1489variable to the following values has the listed effects:
1490t Flash alias translation but don't warn if there is no translation.
14911 Flash alias translation and warn if there is no translation.
1492nil Do not flash alias translation nor warn if there is no translation."
1493 :type '(choice (const :tag "Flash but don't warn if no translation" t)
1494 (const :tag "Flash and warn if no translation" 1)
1495 (const :tag "Don't flash nor warn if no translation" nil))
1496 :group 'mh-alias)
1497 1575
1498(defcustom mh-alias-insert-file nil 1576If this variable is set to anything other than \"default\" and the
1499 "*Filename to use to store new MH-E aliases. 1577default-toolbar has a different positional setting from the value of
1500This variable can also be a list of filenames, in which case MH-E will prompt 1578this variable, then two toolbars will be displayed. The MH-E toolbar
1501for one of them. If nil, the default, then MH-E will use the first file found 1579and the default-toolbar."
1502in the \"AliasFile\" component of the MH profile." 1580 :type '(radio (const :tag "Same position as the \"default-toolbar\""
1503 :type '(choice (const :tag "Use AliasFile MH profile component" nil) 1581 :value default)
1504 (file :tag "Alias file") 1582 (const :tag "Along the top edge of the frame"
1505 (repeat :tag "List of alias files" file)) 1583 :value top)
1506 :group 'mh-alias) 1584 (const :tag "Along the bottom edge of the frame"
1585 :value bottom)
1586 (const :tag "Along the left edge of the frame"
1587 :value left)
1588 (const :tag "Along the right edge of the frame"
1589 :value right)
1590 (const :tag "Don't use a toolbar" nil))
1591 :group 'mh-toolbar))
1507 1592
1508(defcustom mh-alias-insertion-location 'sorted 1593(defmacro mh-tool-bar-define (defaults &rest buttons)
1509 "Specifies where new aliases are entered in alias files. 1594 "Define a tool bar for MH-E.
1510Options are sorted alphabetically, at the top of the file or at the bottom." 1595DEFAULTS is the list of buttons that are present by default. It is a list of
1511 :type '(choice (const :tag "Sorted alphabetically" sorted) 1596lists where the sublists are of the following form:
1512 (const :tag "At the top of file" top)
1513 (const :tag "At the bottom of file" bottom))
1514 :group 'mh-alias)
1515 1597
1516(defcustom mh-alias-local-users t 1598 (:KEYWORD FUNC1 FUNC2 FUNC3 ...)
1517 "*If t, local users are completed in MH-E To: and Cc: prompts.
1518 1599
1519Users with a userid greater than some magic number (usually 200) are available 1600Here :KEYWORD is one of :folder or :letter. If it is :folder then the default
1520for completion. 1601buttons in the folder and show mode buffers are being specified. If it is
1602:letter then the default buttons in the letter mode are listed. FUNC1, FUNC2,
1603FUNC3, ... are the names of the functions that the buttons would execute.
1521 1604
1522If you set this variable to a string, it will be executed to generate a 1605Each element of BUTTONS is a list consisting of four mandatory items and one
1523password file. A value of \"ypcat passwd\" is helpful if NIS is in use." 1606optional item as follows:
1524 :type '(choice (boolean) (string))
1525 :group 'mh-alias)
1526 1607
1527(defcustom mh-alias-local-users-prefix "local." 1608 (FUNCTION MODES ICON DOC &optional ENABLE-EXPR)
1528 "*String prepended to the real names of users from the passwd file.
1529If nil, use the username string unmodified instead of the real name from
1530the gecos field of the passwd file.
1531 1609
1532For example, given the following passwd file line: 1610where,
1533 1611
1534 psg:x:1000:1000:Peter S Galbraith,,,:/home/psg:/bin/tcsh 1612 FUNCTION is the name of the function that will be executed when the button
1613 is clicked.
1535 1614
1536here are the derived aliases for different values of this variable: 1615 MODES is a list of symbols. List elements must be from `folder', `letter' and
1616 `sequence'. If `folder' is present then the button is available in the
1617 folder and show buffer. If the name of FUNCTION is of the form \"mh-foo\",
1618 where foo is some arbitrary string, then we check if the function
1619 `mh-show-foo' exists. If it exists then that function is used in the show
1620 buffer. Otherwise the original function `mh-foo' is used in the show buffer
1621 as well. Presence of `sequence' is handled similar to the above. The only
1622 difference is that the button is shown only when the folder is narrowed to a
1623 sequence. If `letter' is present in MODES, then the button is available
1624 during draft editing and runs FUNCTION when clicked.
1537 1625
1538 \"local.\" -> local.peter.galbraith 1626 ICON is the icon that is drawn in the button.
1539 \"\" -> peter.galbraith
1540 nii -> psg
1541 1627
1542This variable is only meaningful if the variable `mh-alias-local-users' is 1628 DOC is the documentation for the button. It is used in tool-tips and in
1543non-nil." 1629 providing other help to the user. GNU Emacs uses only the first line of the
1544 :type '(choice (const :tag "Use username instead of real name" nil) 1630 string. So the DOC should be formatted such that the first line is useful and
1545 (string)) 1631 complete without the rest of the string.
1546 :group 'mh-alias)
1547 1632
1548(defcustom mh-alias-passwd-gecos-comma-separator-flag t 1633 Optional item ENABLE-EXPR is an arbitrary lisp expression. If it evaluates
1549 "*Non-nil means the gecos field in the passwd file uses comma as a separator. 1634 to nil, then the button is deactivated, otherwise it is active. If is in't
1550Used to construct aliases for users in the passwd file." 1635 present then the button is always active."
1551 :type 'boolean 1636 ;; The following variable names have been carefully chosen to make code
1552 :group 'mh-alias) 1637 ;; generation easier. Modifying the names should be done carefully.
1638 (let (folder-buttons folder-docs folder-button-setter sequence-button-setter
1639 show-buttons show-button-setter show-seq-button-setter
1640 letter-buttons letter-docs letter-button-setter
1641 folder-defaults letter-defaults
1642 folder-vectors show-vectors letter-vectors)
1643 (dolist (x defaults)
1644 (cond ((eq (car x) :folder) (setq folder-defaults (cdr x)))
1645 ((eq (car x) :letter) (setq letter-defaults (cdr x)))))
1646 (dolist (button buttons)
1647 (unless (and (listp button)
1648 (or (equal (length button) 4) (equal (length button) 5)))
1649 (error "Incorrect MH-E tool-bar button specification: %s" button))
1650 (let* ((name (nth 0 button))
1651 (name-str (symbol-name name))
1652 (icon (nth 2 button))
1653 (xemacs-icon (mh-do-in-xemacs
1654 (cdr (assoc (intern icon) mh-xemacs-icon-map))))
1655 (full-doc (nth 3 button))
1656 (doc (if (string-match "\\(.*\\)\n" full-doc)
1657 (match-string 1 full-doc)
1658 full-doc))
1659 (enable-expr (or (nth 4 button) t))
1660 (modes (nth 1 button))
1661 functions show-sym)
1662 (when (memq 'letter modes) (setq functions `(:letter ,name)))
1663 (when (or (memq 'folder modes) (memq 'sequence modes))
1664 (setq functions
1665 (append `(,(if (memq 'folder modes) :folder :sequence) ,name)
1666 functions))
1667 (setq show-sym
1668 (if (string-match "^mh-\\(.*\\)$" name-str)
1669 (intern (concat "mh-show-" (match-string 1 name-str)))
1670 name))
1671 (setq functions
1672 (append `(,(if (memq 'folder modes) :show :show-seq)
1673 ,(if (fboundp show-sym) show-sym name))
1674 functions)))
1675 (do ((functions functions (cddr functions)))
1676 ((null functions))
1677 (let* ((type (car functions))
1678 (function (cadr functions))
1679 (type1 (substring (symbol-name type) 1))
1680 (vector-list (cond ((eq type :show) 'show-vectors)
1681 ((eq type :show-seq) 'show-vectors)
1682 ((eq type :letter) 'letter-vectors)
1683 (t 'folder-vectors)))
1684 (list (cond ((eq type :letter) 'mh-tool-bar-letter-buttons)
1685 (t 'mh-tool-bar-folder-buttons)))
1686 (key (intern (concat "mh-" type1 "toolbar-" name-str)))
1687 (setter (intern (concat type1 "-button-setter")))
1688 (mbuttons (cond ((eq type :letter) 'letter-buttons)
1689 ((eq type :show) 'show-buttons)
1690 ((eq type :show-seq) 'show-buttons)
1691 (t 'folder-buttons)))
1692 (docs (cond ((eq mbuttons 'letter-buttons) 'letter-docs)
1693 ((eq mbuttons 'folder-buttons) 'folder-docs))))
1694 (add-to-list vector-list `[,xemacs-icon ,function t ,full-doc])
1695 (add-to-list
1696 setter `(when (member ',name ,list)
1697 (mh-funcall-if-exists
1698 tool-bar-add-item ,icon ',function ',key
1699 :help ,doc :enable ',enable-expr)))
1700 (add-to-list mbuttons name)
1701 (if docs (add-to-list docs doc))))))
1702 (setq folder-buttons (nreverse folder-buttons)
1703 letter-buttons (nreverse letter-buttons)
1704 show-buttons (nreverse show-buttons)
1705 letter-docs (nreverse letter-docs)
1706 folder-docs (nreverse folder-docs)
1707 folder-vectors (nreverse folder-vectors)
1708 show-vectors (nreverse show-vectors)
1709 letter-vectors (nreverse letter-vectors))
1710 (dolist (x folder-defaults)
1711 (unless (memq x folder-buttons)
1712 (error "Folder defaults contains unknown button '%s'" x)))
1713 (dolist (x letter-defaults)
1714 (unless (memq x letter-buttons)
1715 (error "Letter defaults contains unknown button '%s'" x)))
1716 `(eval-when (compile load eval)
1717 (defvar mh-folder-tool-bar-map nil)
1718 (defvar mh-folder-seq-tool-bar-map nil)
1719 (defvar mh-show-tool-bar-map nil)
1720 (defvar mh-show-seq-tool-bar-map nil)
1721 (defvar mh-letter-tool-bar-map nil)
1722 ;; GNU Emacs tool bar specific code
1723 (mh-do-in-gnu-emacs
1724 ;; Custom setter functions
1725 (defun mh-tool-bar-folder-buttons-set (symbol value)
1726 "Construct toolbar for `mh-folder-mode' and `mh-show-mode'."
1727 (set-default symbol value)
1728 (setq mh-folder-tool-bar-map
1729 (let ((tool-bar-map (make-sparse-keymap)))
1730 ,@(nreverse folder-button-setter)
1731 tool-bar-map))
1732 (setq mh-show-tool-bar-map
1733 (let ((tool-bar-map (make-sparse-keymap)))
1734 ,@(nreverse show-button-setter)
1735 tool-bar-map))
1736 (setq mh-show-seq-tool-bar-map
1737 (let ((tool-bar-map (copy-keymap mh-show-tool-bar-map)))
1738 ,@(nreverse show-seq-button-setter)
1739 tool-bar-map))
1740 (setq mh-folder-seq-tool-bar-map
1741 (let ((tool-bar-map (copy-keymap mh-folder-tool-bar-map)))
1742 ,@(nreverse sequence-button-setter)
1743 tool-bar-map)))
1744 (defun mh-tool-bar-letter-buttons-set (symbol value)
1745 "Construct toolbar for `mh-letter-mode'."
1746 (set-default symbol value)
1747 (setq mh-letter-tool-bar-map
1748 (let ((tool-bar-map (make-sparse-keymap)))
1749 ,@(nreverse letter-button-setter)
1750 tool-bar-map))))
1751 ;; XEmacs specific code
1752 (mh-do-in-xemacs
1753 (defvar mh-toolbar-folder-vector-map
1754 ',(loop for button in folder-buttons
1755 for vector in folder-vectors
1756 collect (cons button vector)))
1757 (defvar mh-toolbar-show-vector-map
1758 ',(loop for button in show-buttons
1759 for vector in show-vectors
1760 collect (cons button vector)))
1761 (defvar mh-toolbar-letter-vector-map
1762 ',(loop for button in letter-buttons
1763 for vector in letter-vectors
1764 collect (cons button vector)))
1765 (defvar mh-toolbar-folder-buttons nil)
1766 (defvar mh-toolbar-show-buttons nil)
1767 (defvar mh-toolbar-letter-buttons nil)
1768 ;; Custom setter functions
1769 (defun mh-tool-bar-letter-buttons-set (symbol value)
1770 (set-default symbol value)
1771 (when mh-xemacs-has-toolbar-flag
1772 (setq mh-toolbar-letter-buttons
1773 (loop for b in value
1774 collect (cdr (assoc b mh-toolbar-letter-vector-map))))))
1775 (defun mh-tool-bar-folder-buttons-set (symbol value)
1776 (set-default symbol value)
1777 (when mh-xemacs-has-toolbar-flag
1778 (setq mh-toolbar-folder-buttons
1779 (loop for b in value
1780 collect (cdr (assoc b mh-toolbar-folder-vector-map))))
1781 (setq mh-toolbar-show-buttons
1782 (loop for b in value
1783 collect (cdr (assoc b mh-toolbar-show-vector-map))))))
1784 ;; Initialize toolbar
1785 (defun mh-toolbar-init (mode)
1786 "Install toolbar in MODE."
1787 (let ((toolbar (cond ((eq mode :folder) mh-toolbar-folder-buttons)
1788 ((eq mode :letter) mh-toolbar-letter-buttons)
1789 ((eq mode :show) mh-toolbar-show-buttons)))
1790 (height 37)
1791 (width 40)
1792 (buffer (current-buffer)))
1793 (when (and mh-xemacs-toolbar-position mh-xemacs-use-toolbar-flag
1794 mh-xemacs-has-toolbar-flag)
1795 (cond
1796 ((eq mh-xemacs-toolbar-position 'top)
1797 (set-specifier top-toolbar toolbar buffer)
1798 (set-specifier top-toolbar-visible-p t)
1799 (set-specifier top-toolbar-height height))
1800 ((eq mh-xemacs-toolbar-position 'bottom)
1801 (set-specifier bottom-toolbar toolbar buffer)
1802 (set-specifier bottom-toolbar-visible-p t)
1803 (set-specifier bottom-toolbar-height height))
1804 ((eq mh-xemacs-toolbar-position 'left)
1805 (set-specifier left-toolbar toolbar buffer)
1806 (set-specifier left-toolbar-visible-p t)
1807 (set-specifier left-toolbar-width width))
1808 ((eq mh-xemacs-toolbar-position 'right)
1809 (set-specifier right-toolbar toolbar buffer)
1810 (set-specifier right-toolbar-visible-p t)
1811 (set-specifier right-toolbar-width width))
1812 (t (set-specifier default-toolbar toolbar buffer)))))))
1813 ;; Declare customizable toolbars
1814 (custom-declare-variable
1815 'mh-tool-bar-folder-buttons
1816 '(list ,@(mapcar (lambda (x) `(quote ,x)) folder-defaults))
1817 "Choose buttons to include in MH-E folder/show toolbar."
1818 :group 'mh-toolbar :set 'mh-tool-bar-folder-buttons-set
1819 :type '(set ,@(loop for x in folder-buttons
1820 for y in folder-docs
1821 collect `(const :tag ,y ,x))))
1822 (custom-declare-variable
1823 'mh-tool-bar-letter-buttons
1824 '(list ,@(mapcar (lambda (x) `(quote ,x)) letter-defaults))
1825 "Choose buttons to include in MH-E letter toolbar."
1826 :group 'mh-toolbar :set 'mh-tool-bar-letter-buttons-set
1827 :type '(set ,@(loop for x in letter-buttons
1828 for y in letter-docs
1829 collect `(const :tag ,y ,x)))))))
1553 1830
1554(defcustom mh-alias-system-aliases 1831(mh-tool-bar-define
1555 '("/etc/nmh/MailAliases" "/usr/lib/mh/MailAliases" "/etc/passwd") 1832 ((:folder mh-inc-folder mh-mime-save-parts mh-previous-undeleted-msg
1556 "*A list of system files from which to cull aliases. 1833 mh-page-msg mh-next-undeleted-msg mh-delete-msg mh-refile-msg
1557If these files are modified, they are automatically reread. This list need 1834 mh-undo mh-execute-commands mh-toggle-tick mh-reply
1558include only system aliases and the passwd file, since personal alias files 1835 mh-alias-grab-from-field mh-send mh-rescan-folder
1559listed in your \"AliasFile\" MH profile component are automatically included. 1836 mh-tool-bar-search mh-visit-folder
1560You can update the alias list manually using \\[mh-alias-reload]." 1837 mh-tool-bar-customize mh-tool-bar-folder-help mh-widen)
1561 :type '(choice (file) (repeat file)) 1838 (:letter mh-send-letter mh-compose-insertion ispell-message save-buffer
1562 :group 'mh-alias) 1839 undo kill-region menu-bar-kill-ring-save yank mh-fully-kill-draft
1840 mh-tool-bar-customize mh-tool-bar-letter-help))
1841 ;; Folder/Show buffer buttons
1842 (mh-inc-folder (folder) "mail"
1843 "Incorporate new mail in Inbox
1844This button runs `mh-inc-folder' which drags any
1845new mail into your Inbox folder.")
1846 (mh-mime-save-parts (folder) "attach"
1847 "Save MIME parts from this message
1848This button runs `mh-mime-save-parts' which saves a message's
1849different parts into separate files.")
1850 (mh-previous-undeleted-msg (folder) "left_arrow"
1851 "Go to the previous undeleted message
1852This button runs `mh-previous-undeleted-msg'")
1853 (mh-page-msg (folder) "page-down"
1854 "Page the current message forwards\nThis button runs `mh-page-msg'")
1855 (mh-next-undeleted-msg (folder) "right_arrow"
1856 "Go to the next undeleted message\nThe button runs `mh-next-undeleted-msg'")
1857 (mh-delete-msg (folder) "close"
1858 "Mark this message for deletion\nThis button runs `mh-delete-msg'")
1859 (mh-refile-msg (folder) "refile"
1860 "Refile this message\nThis button runs `mh-refile-msg'")
1861 (mh-undo (folder) "undo" "Undo last operation\nThis button runs `undo'"
1862 (mh-outstanding-commands-p))
1863 (mh-execute-commands (folder) "execute"
1864 "Perform moves and deletes\nThis button runs `mh-execute-commands'"
1865 (mh-outstanding-commands-p))
1866 (mh-toggle-tick (folder) "highlight"
1867 "Toggle tick mark\nThis button runs `mh-toggle-tick'")
1868 (mh-toggle-showing (folder) "show"
1869 "Toggle showing message\nThis button runs `mh-toggle-showing'")
1870 (mh-tool-bar-reply-from (folder) "reply-from" "Reply to \"from\"")
1871 (mh-tool-bar-reply-to (folder) "reply-to" "Reply to \"to\"")
1872 (mh-tool-bar-reply-all (folder) "reply-all" "Reply to \"all\"")
1873 (mh-reply (folder) "mail/reply2"
1874 "Reply to this message\nThis button runs `mh-reply'")
1875 (mh-alias-grab-from-field (folder) "alias"
1876 "Grab From alias\nThis button runs `mh-alias-grab-from-field'"
1877 (and (mh-extract-from-header-value) (not (mh-alias-for-from-p))))
1878 (mh-send (folder) "mail_compose"
1879 "Compose new message\nThis button runs `mh-send'")
1880 (mh-rescan-folder (folder) "rescan"
1881 "Rescan this folder\nThis button runs `mh-rescan-folder'")
1882 (mh-pack-folder (folder) "repack"
1883 "Repack this folder\nThis button runs `mh-pack-folder'")
1884 (mh-tool-bar-search (folder) "search"
1885 "Search\nThis button runs `mh-tool-bar-search-function'")
1886 (mh-visit-folder (folder) "fld_open"
1887 "Visit other folder\nThis button runs `mh-visit-folder'")
1888 ;; Letter buffer buttons
1889 (mh-send-letter (letter) "mail_send" "Send this letter")
1890 (mh-compose-insertion (letter) "attach" "Insert attachment")
1891 (ispell-message (letter) "spell" "Check spelling")
1892 (save-buffer (letter) "save" "Save current buffer to its file"
1893 (buffer-modified-p))
1894 (undo (letter) "undo" "Undo last operation")
1895 (kill-region (letter) "cut"
1896 "Cut (kill) text in region between mark and current position")
1897 (menu-bar-kill-ring-save (letter) "copy"
1898 "Copy text in region between mark and current position")
1899 (yank (letter) "paste" "Paste (yank) text cut or copied earlier")
1900 (mh-fully-kill-draft (letter) "close" "Kill this draft")
1901 ;; Common buttons
1902 (mh-tool-bar-customize (folder letter) "preferences" "MH-E Preferences")
1903 (mh-tool-bar-folder-help (folder) "help"
1904 "Help! (general help)\nThis button runs `Info-goto-node'")
1905 (mh-tool-bar-letter-help (letter) "help"
1906 "Help! (general help)\nThis button runs `Info-goto-node'")
1907 ;; Folder narrowed to sequence buttons
1908 (mh-widen (sequence) "widen"
1909 "Widen from the sequence\nThis button runs `mh-widen'"))
1563 1910
1564 1911
1565 1912
1566;;; Multiple personalities (:group 'mh-identity) 1913;;; Hooks (:group 'mh-hooks + group where hook described)
1567 1914
1568(defcustom mh-identity-list nil 1915(defcustom mail-citation-hook nil
1569 "*List holding MH-E identity. 1916 "*Hook for modifying a citation just inserted in the mail buffer.
1570Omit the colon and trailing space from the field names. 1917Each hook function can find the citation between point and mark.
1571The keyword name \"none\" is reserved for internal use. 1918And each hook function should leave point and mark around the citation
1572Use the keyname name \"signature\" to specify either a signature file or a 1919text as modified.
1573function to call to insert a signature at point.
1574
1575Providing an empty Value (\"\") will cause the field to be deleted.
1576
1577Example entries using the customize interface:
1578 Keyword name: work
1579 From
1580 Value: John Doe <john@work.com>
1581 Organization
1582 Value: Acme Inc.
1583 Keyword name: home
1584 From
1585 Value: John Doe <johndoe@home.net>
1586 Organization
1587 Value:
1588
1589This would produce the equivalent of:
1590 (setq mh-identity-list
1591 '((\"work\"
1592 ((\"From\" . \"John Doe <john@work.com>\")
1593 (\"Organization\" . \"Acme Inc.\")))
1594 (\"home\"
1595 ((\"From\" . \"John Doe <johndoe@home.net>\")
1596 (\"Organization\" . \"\")))))"
1597 :type '(repeat (list :tag ""
1598 (string :tag "Keyword name")
1599 (repeat :tag "At least one pair from below"
1600 (choice (cons :tag "From field"
1601 (const "From")
1602 (string :tag "Value"))
1603 (cons :tag "Organization field"
1604 (const "Organization")
1605 (string :tag "Value"))
1606 (cons :tag "Signature"
1607 (const "signature")
1608 (choice (file) (function)))
1609 (cons :tag "Other field & value pair"
1610 (string :tag "Field")
1611 (string :tag "Value"))))))
1612 :set 'mh-identity-list-set
1613 :group 'mh-identity)
1614 1920
1615(defcustom mh-auto-fields-list nil 1921If this hook is entirely empty (nil), the text of the message is inserted
1616 "Alist of addresses for which header lines are automatically inserted. 1922with `mh-ins-buf-prefix' prefixed to each line.
1617Each element has the form (REGEXP ((KEYWORD VALUE) (KEYWORD VALUE)).
1618When the REGEXP appears in the To or cc fields of a message, the corresponding
1619KEYWORD header field is insert with its VALUE in the message header.
1620 1923
1621There is one special case for KEYWORD, that of \"identity\", which means to 1924See also the variable `mh-yank-from-start-of-msg', which controls how
1622insert that identity using `mh-insert-identity'. 1925much of the message passed to the hook.
1623 1926
1624The common KEYWORD cases of \"Mail-Followup-To\" and \"fcc\" are also 1927This hook was historically provided to set up supercite. You may now leave
1625prompted for in the customization interface." 1928this nil and set up supercite by setting the variable
1626 :type `(repeat 1929`mh-yank-from-start-of-msg' to 'supercite or, for more automatic insertion,
1627 (list :tag "" 1930to 'autosupercite.
1628 (string :tag "Regular expression to match")
1629 (repeat :tag "At least one pair from below"
1630 (choice
1631 (cons :tag "Identity entry"
1632 (const "identity")
1633 ,(append
1634 '(radio)
1635 (mapcar (function (lambda (arg) `(const ,arg)))
1636 (mapcar 'car mh-identity-list))))
1637 (cons :tag "fcc field"
1638 (const "fcc")
1639 (string :tag "Value"))
1640 (cons :tag "Mail-Followup-To field"
1641 (const "Mail-Followup-To")
1642 (string :tag "Value"))
1643 (cons :tag "Other field and value pair"
1644 (string :tag "Field")
1645 (string :tag "Value"))))))
1646 :group 'mh-identity)
1647 1931
1648(defcustom mh-identity-default nil 1932The hook 'trivial-cite is NOT part of Emacs. It is provided from tc.el,
1649 "Default identity to use when `mh-letter-mode' is called." 1933available here:
1650 ;; Dynamically render :type corresponding to `mh-identity-list' entries, 1934 http://shasta.cs.uiuc.edu/~lrclause/tc.html
1651 ;; e.g.: 1935If you use it, customize `mh-yank-from-start-of-msg' to
1652 ;; :type '(radio (const :tag "none" nil) 1936 \"Entire message with headers\"."
1653 ;; (const "home") 1937 :type 'hook
1654 ;; (const "work")) 1938 :options '(trivial-cite)
1655 :type (append 1939 :group 'mh-hooks
1656 '(radio) 1940 :group 'mh-letter)
1657 (cons '(const :tag "None" nil)
1658 (mapcar (function (lambda (arg) `(const ,arg)))
1659 (mapcar 'car mh-identity-list))))
1660 :group 'mh-identity)
1661
1662
1663
1664;;; Hooks (:group 'mh-hooks + group where hook defined)
1665 1941
1666;;; These are alphabetized. All hooks should be placed in the 'mh-hook group; 1942(defcustom mh-alias-reloaded-hook nil
1667;;; in addition, add the group in which the hook is defined in the manual (or, 1943 "Invoked by `mh-alias-reload' after reloading aliases."
1668;;; if it is new, where it would be defined). 1944 :type 'hook
1945 :group 'mh-hooks
1946 :group 'mh-alias)
1669 1947
1670(defcustom mh-before-quit-hook nil 1948(defcustom mh-before-quit-hook nil
1671 "Invoked by \\<mh-folder-mode-map>`\\[mh-quit]' before quitting MH-E. 1949 "Invoked by \\<mh-folder-mode-map>`\\[mh-quit]' before quitting MH-E.
1672See also `mh-quit-hook'." 1950See also `mh-quit-hook'."
1673 :type 'hook 1951 :type 'hook
1674 :group 'mh-hooks 1952 :group 'mh-hooks
1675 :group 'mh-folder) 1953 :group 'mh-show)
1676 1954
1677(defcustom mh-before-send-letter-hook nil 1955(defcustom mh-before-send-letter-hook nil
1678 "Invoked at the beginning of the \\<mh-letter-mode-map>\\[mh-send-letter] command." 1956 "Invoked at the beginning of the \\<mh-letter-mode-map>\\[mh-send-letter] command."
@@ -1684,7 +1962,7 @@ See also `mh-quit-hook'."
1684 "Invoked after marking each message for deletion." 1962 "Invoked after marking each message for deletion."
1685 :type 'hook 1963 :type 'hook
1686 :group 'mh-hooks 1964 :group 'mh-hooks
1687 :group 'mh-folder) 1965 :group 'mh-show)
1688 1966
1689(defcustom mh-edit-mhn-hook nil 1967(defcustom mh-edit-mhn-hook nil
1690 "Invoked on the formatted letter by \\<mh-letter-mode-map>\\[mh-edit-mhn]." 1968 "Invoked on the formatted letter by \\<mh-letter-mode-map>\\[mh-edit-mhn]."
@@ -1696,13 +1974,13 @@ See also `mh-quit-hook'."
1696 "Invoked by `mh-find-path' after reading the user's MH profile." 1974 "Invoked by `mh-find-path' after reading the user's MH profile."
1697 :type 'hook 1975 :type 'hook
1698 :group 'mh-hooks 1976 :group 'mh-hooks
1699 :group 'mh-folder) 1977 :group 'mh-show)
1700 1978
1701(defcustom mh-folder-mode-hook nil 1979(defcustom mh-folder-mode-hook nil
1702 "Invoked in `mh-folder-mode' on a new folder." 1980 "Invoked in `mh-folder-mode' on a new folder."
1703 :type 'hook 1981 :type 'hook
1704 :group 'mh-hooks 1982 :group 'mh-hooks
1705 :group 'mh-folder) 1983 :group 'mh-show)
1706 1984
1707(defcustom mh-folder-updated-hook nil 1985(defcustom mh-folder-updated-hook nil
1708 "Invoked when the folder actions (such as moves and deletes) are performed. 1986 "Invoked when the folder actions (such as moves and deletes) are performed.
@@ -1712,11 +1990,17 @@ current folder, `mh-current-folder'."
1712 :type 'hook 1990 :type 'hook
1713 :group 'mh-hooks) 1991 :group 'mh-hooks)
1714 1992
1993(defcustom mh-forward-hook nil
1994 "Invoked on the forwarded letter by \\<mh-folder-mode-map>\\[mh-forward]."
1995 :type 'hook
1996 :group 'mh-hooks
1997 :group 'mh-folder)
1998
1715(defcustom mh-inc-folder-hook nil 1999(defcustom mh-inc-folder-hook nil
1716 "Invoked by \\<mh-folder-mode-map>`\\[mh-inc-folder]' after incorporating mail into a folder." 2000 "Invoked by \\<mh-folder-mode-map>`\\[mh-inc-folder]' after incorporating mail into a folder."
1717 :type 'hook 2001 :type 'hook
1718 :group 'mh-hooks 2002 :group 'mh-hooks
1719 :group 'mh-folder) 2003 :group 'mh-inc)
1720 2004
1721(defcustom mh-kill-folder-suppress-prompt-hook '(mh-index-p) 2005(defcustom mh-kill-folder-suppress-prompt-hook '(mh-index-p)
1722 "Invoked at the beginning of the \\<mh-folder-mode-map>`\\[mh-kill-folder]' command. 2006 "Invoked at the beginning of the \\<mh-folder-mode-map>`\\[mh-kill-folder]' command.
@@ -1733,13 +2017,12 @@ t on +inbox and you hit \\<mh-folder-mode-map>`\\[mh-kill-folder]' by accident
1733in the +inbox buffer, you will not be happy." 2017in the +inbox buffer, you will not be happy."
1734 :type 'hook 2018 :type 'hook
1735 :group 'mh-hooks 2019 :group 'mh-hooks
1736 :group 'mh-folder) 2020 :group 'mh-show)
1737 2021
1738(defcustom mh-letter-insert-signature-hook nil 2022(defcustom mh-letter-insert-signature-hook nil
1739 "Invoked at the beginning of the \\<mh-letter-mode-map>\\[mh-insert-signature] command. 2023 "Invoked after signature has been inserted.
1740Can be used to determine which signature file to use based on message content. 2024This hook may access the actual name of the file or the function used to
1741On return, if `mh-signature-file-name' is non-nil that file will be inserted at 2025insert the signature with `mh-signature-file-name'."
1742the current point in the buffer."
1743 :type 'hook 2026 :type 'hook
1744 :group 'mh-hooks 2027 :group 'mh-hooks
1745 :group 'mh-letter) 2028 :group 'mh-letter)
@@ -1748,26 +2031,26 @@ the current point in the buffer."
1748 "Invoked in `mh-letter-mode' on a new letter." 2031 "Invoked in `mh-letter-mode' on a new letter."
1749 :type 'hook 2032 :type 'hook
1750 :group 'mh-hooks 2033 :group 'mh-hooks
1751 :group 'mh-letter) 2034 :group 'mh-sending-mail)
1752 2035
1753(defcustom mh-pick-mode-hook nil 2036(defcustom mh-pick-mode-hook nil
1754 "Invoked upon entry to `mh-pick-mode'." 2037 "Invoked upon entry to `mh-pick-mode'."
1755 :type 'hook 2038 :type 'hook
1756 :group 'mh-hooks 2039 :group 'mh-hooks
1757 :group 'mh-folder) 2040 :group 'mh-index)
1758 2041
1759(defcustom mh-quit-hook nil 2042(defcustom mh-quit-hook nil
1760 "Invoked after \\<mh-folder-mode-map>`\\[mh-quit]' quits MH-E. 2043 "Invoked after \\<mh-folder-mode-map>`\\[mh-quit]' quits MH-E.
1761See also `mh-before-quit-hook'." 2044See also `mh-before-quit-hook'."
1762 :type 'hook 2045 :type 'hook
1763 :group 'mh-hooks 2046 :group 'mh-hooks
1764 :group 'mh-folder) 2047 :group 'mh-show)
1765 2048
1766(defcustom mh-refile-msg-hook nil 2049(defcustom mh-refile-msg-hook nil
1767 "Invoked after marking each message for refiling." 2050 "Invoked after marking each message for refiling."
1768 :type 'hook 2051 :type 'hook
1769 :group 'mh-hooks 2052 :group 'mh-hooks
1770 :group 'mh-folder) 2053 :group 'mh-show)
1771 2054
1772(defcustom mh-show-hook nil 2055(defcustom mh-show-hook nil
1773 "Invoked after \\<mh-folder-mode-map>`\\[mh-show]' shows a message." 2056 "Invoked after \\<mh-folder-mode-map>`\\[mh-show]' shows a message."
@@ -1787,44 +2070,13 @@ The variable `mh-seen-list' can be used to obtain the list of messages which
1787will be removed from the unseen sequence." 2070will be removed from the unseen sequence."
1788 :type 'hook 2071 :type 'hook
1789 :group 'mh-hooks 2072 :group 'mh-hooks
1790 :group 'mh-folder) 2073 :group 'mh-show)
1791 2074
1792 2075
1793 2076
1794;;; Faces 2077;;; Faces (:group 'mh-*-faces + group where faces described)
1795
1796;;; Faces used in speedbar (:group mh-speed-faces)
1797
1798(defface mh-speedbar-folder-face
1799 '((((class color) (background light))
1800 (:foreground "blue4"))
1801 (((class color) (background dark))
1802 (:foreground "light blue")))
1803 "Face used for folders in the speedbar buffer."
1804 :group 'mh-speed-faces)
1805
1806(defface mh-speedbar-selected-folder-face
1807 '((((class color) (background light))
1808 (:foreground "red" :underline t))
1809 (((class color) (background dark))
1810 (:foreground "red" :underline t))
1811 (t (:underline t)))
1812 "Face used for the current folder."
1813 :group 'mh-speed-faces)
1814
1815(defface mh-speedbar-folder-with-unseen-messages-face
1816 '((t (:inherit mh-speedbar-folder-face :bold t)))
1817 "Face used for folders in the speedbar buffer which have unread messages."
1818 :group 'mh-speed-faces)
1819
1820(defface mh-speedbar-selected-folder-with-unseen-messages-face
1821 '((t (:inherit mh-speedbar-selected-folder-face :bold t)))
1822 "Face used for the current folder when it has unread messages."
1823 :group 'mh-speed-faces)
1824
1825
1826 2078
1827;;; Faces used in scan listing (:group mh-folder-faces) 2079;;; Faces Used in Scan Listing (:group 'mh-folder-faces)
1828 2080
1829(defvar mh-folder-body-face 'mh-folder-body-face 2081(defvar mh-folder-body-face 'mh-folder-body-face
1830 "Face for highlighting body text in MH-Folder buffers.") 2082 "Face for highlighting body text in MH-Folder buffers.")
@@ -1962,7 +2214,36 @@ will be removed from the unseen sequence."
1962 2214
1963 2215
1964 2216
1965;;; Faces used in message display (:group mh-show-faces) 2217;;; Faces Used in Searching (:group 'mh-index-faces)
2218
2219(defvar mh-index-folder-face 'mh-index-folder-face
2220 "Face for highlighting folders in MH-Index buffers.")
2221(defface mh-index-folder-face
2222 '((((class color) (background light))
2223 (:foreground "dark green" :bold t))
2224 (((class color) (background dark))
2225 (:foreground "indian red" :bold t))
2226 (t
2227 (:bold t)))
2228 "Face for highlighting folders in MH-Index buffers."
2229 :group 'mh-index-faces)
2230
2231
2232
2233;;; Faces Used in Message Drafts (:group 'mh-letter-faces)
2234
2235(defface mh-letter-header-field-face
2236 '((((class color) (background light))
2237 (:background "gray90"))
2238 (((class color) (background dark))
2239 (:background "gray10"))
2240 (t (:bold t)))
2241 "Face for displaying header fields in draft buffers."
2242 :group 'mh-letter-faces)
2243
2244
2245
2246;;; Faces Used in Message Display (:group 'mh-show-faces)
1966 2247
1967(defvar mh-show-cc-face 'mh-show-cc-face 2248(defvar mh-show-cc-face 'mh-show-cc-face
1968 "Face for highlighting cc header fields.") 2249 "Face for highlighting cc header fields.")
@@ -2002,6 +2283,11 @@ will be removed from the unseen sequence."
2002 "Face used to deemphasize unspecified header fields." 2283 "Face used to deemphasize unspecified header fields."
2003 :group 'mh-show-faces) 2284 :group 'mh-show-faces)
2004 2285
2286(defface mh-show-signature-face
2287 '((t (:italic t)))
2288 "Face for highlighting message signature."
2289 :group 'mh-show-faces)
2290
2005(defvar mh-show-to-face 'mh-show-to-face 2291(defvar mh-show-to-face 'mh-show-to-face
2006 "Face for highlighting the To: header field.") 2292 "Face for highlighting the To: header field.")
2007(if (boundp 'facemenu-unlisted-faces) 2293(if (boundp 'facemenu-unlisted-faces)
@@ -2041,32 +2327,34 @@ The background and foreground is used in the image."
2041 2327
2042 2328
2043 2329
2044;;; Faces used in indexed searches (:group mh-index-faces) 2330;;; Faces Used in Speedbar (:group 'mh-speed-faces)
2045 2331
2046(defvar mh-index-folder-face 'mh-index-folder-face 2332(defface mh-speedbar-folder-face
2047 "Face for highlighting folders in MH-Index buffers.")
2048(defface mh-index-folder-face
2049 '((((class color) (background light)) 2333 '((((class color) (background light))
2050 (:foreground "dark green" :bold t)) 2334 (:foreground "blue4"))
2051 (((class color) (background dark)) 2335 (((class color) (background dark))
2052 (:foreground "indian red" :bold t)) 2336 (:foreground "light blue")))
2053 (t 2337 "Face used for folders in the speedbar buffer."
2054 (:bold t))) 2338 :group 'mh-speed-faces)
2055 "Face for highlighting folders in MH-Index buffers."
2056 :group 'mh-index-faces)
2057
2058
2059
2060;;; Faces used when composing messages.
2061 2339
2062(defface mh-letter-header-field-face 2340(defface mh-speedbar-selected-folder-face
2063 '((((class color) (background light)) 2341 '((((class color) (background light))
2064 (:background "gray90")) 2342 (:foreground "red" :underline t))
2065 (((class color) (background dark)) 2343 (((class color) (background dark))
2066 (:background "gray10")) 2344 (:foreground "red" :underline t))
2067 (t (:bold t))) 2345 (t (:underline t)))
2068 "Face for displaying header fields in draft buffers." 2346 "Face used for the current folder."
2069 :group 'mh-letter-faces) 2347 :group 'mh-speed-faces)
2348
2349(defface mh-speedbar-folder-with-unseen-messages-face
2350 '((t (:inherit mh-speedbar-folder-face :bold t)))
2351 "Face used for folders in the speedbar buffer which have unread messages."
2352 :group 'mh-speed-faces)
2353
2354(defface mh-speedbar-selected-folder-with-unseen-messages-face
2355 '((t (:inherit mh-speedbar-selected-folder-face :bold t)))
2356 "Face used for the current folder when it has unread messages."
2357 :group 'mh-speed-faces)
2070 2358
2071;;; Local Variables: 2359;;; Local Variables:
2072;;; indent-tabs-mode: nil 2360;;; indent-tabs-mode: nil
diff --git a/lisp/mh-e/mh-e.el b/lisp/mh-e/mh-e.el
index e72304c4412..5cb7f90f1e3 100644
--- a/lisp/mh-e/mh-e.el
+++ b/lisp/mh-e/mh-e.el
@@ -5,7 +5,7 @@
5 5
6;; Author: Bill Wohler <wohler@newt.com> 6;; Author: Bill Wohler <wohler@newt.com>
7;; Maintainer: Bill Wohler <wohler@newt.com> 7;; Maintainer: Bill Wohler <wohler@newt.com>
8;; Version: 7.4.4 8;; Version: 7.4.80
9;; Keywords: mail 9;; Keywords: mail
10 10
11;; This file is part of GNU Emacs. 11;; This file is part of GNU Emacs.
@@ -75,24 +75,19 @@
75 75
76;; Original version for Gosling emacs by Brian Reid, Stanford, 1982. 76;; Original version for Gosling emacs by Brian Reid, Stanford, 1982.
77;; Modified by James Larus, BBN, July 1984 and UCB, 1984 & 1985. 77;; Modified by James Larus, BBN, July 1984 and UCB, 1984 & 1985.
78;; Rewritten for GNU Emacs, James Larus 1985. larus@ginger.berkeley.edu 78;; Rewritten for GNU Emacs, James Larus, 1985.
79;; Modified by Stephen Gildea 1988. gildea@lcs.mit.edu 79;; Modified by Stephen Gildea, 1988.
80;; Maintenance picked up by Bill Wohler <wohler@newt.com> and the 80;; Maintenance picked up by Bill Wohler and the
81;; SourceForge Crew <http://mh-e.sourceforge.net/>. 2001. 81;; SourceForge Crew <http://mh-e.sourceforge.net/>, 2001.
82 82
83;;; Code: 83;;; Code:
84 84
85(provide 'mh-e) 85(provide 'mh-e)
86(require 'mh-utils)
87(mh-require-cl)
88
89(defvar recursive-load-depth-limit)
90(eval-when (compile load eval)
91 (if (and (boundp 'recursive-load-depth-limit)
92 (integerp recursive-load-depth-limit)
93 (> 50 recursive-load-depth-limit))
94 (setq recursive-load-depth-limit 50)))
95 86
87(eval-when-compile (require 'mh-acros))
88(mh-require-cl)
89(require 'mh-utils)
90(require 'mh-init)
96(require 'mh-inc) 91(require 'mh-inc)
97(require 'gnus-util) 92(require 'gnus-util)
98(require 'easymenu) 93(require 'easymenu)
@@ -101,35 +96,27 @@
101(defvar font-lock-auto-fontify) 96(defvar font-lock-auto-fontify)
102(defvar font-lock-defaults) 97(defvar font-lock-defaults)
103 98
104(defconst mh-version "7.4.4" "Version number of MH-E.") 99(defconst mh-version "7.4.80" "Version number of MH-E.")
105 100
106;;; Autoloads 101;;; Autoloads
107(autoload 'Info-goto-node "info") 102(autoload 'Info-goto-node "info")
108 103
109
110
111(defvar mh-note-deleted "D"
112 "String whose first character is used to notate deleted messages.")
113
114(defvar mh-note-refiled "^"
115 "String whose first character is used to notate refiled messages.")
116
117(defvar mh-note-cur "+"
118 "String whose first character is used to notate the current message.")
119
120(defvar mh-partial-folder-mode-line-annotation "select" 104(defvar mh-partial-folder-mode-line-annotation "select"
121 "Annotation when displaying part of a folder. 105 "Annotation when displaying part of a folder.
122The string is displayed after the folder's name. nil for no annotation.") 106The string is displayed after the folder's name. nil for no annotation.")
123 107
108
109;;; Scan Line Formats
110
124;;; Parameterize MH-E to work with different scan formats. The defaults work 111;;; Parameterize MH-E to work with different scan formats. The defaults work
125;;; with the standard MH scan listings, in which the first 4 characters on 112;;; with the standard MH scan listings, in which the first 4 characters on
126;;; the line are the message number, followed by two places for notations. 113;;; the line are the message number, followed by two places for notations.
127 114
128;; The following scan formats are passed to the scan program if the 115;; The following scan formats are passed to the scan program if the setting of
129;; setting of `mh-scan-format-file' above is nil. They are identical 116;; `mh-scan-format-file' is t. They are identical except the later one makes
130;; except the later one makes use of the nmh `decode' function to 117;; use of the nmh `decode' function to decode RFC 2047 encodings. If you just
131;; decode RFC 2047 encodings. If you just want to change the width of 118;; want to change the width of the msg number, use the `mh-set-cmd-note'
132;; the msg number, use the `mh-set-cmd-note' function. 119;; function.
133 120
134(defvar mh-scan-format-mh 121(defvar mh-scan-format-mh
135 (concat 122 (concat
@@ -150,11 +137,10 @@ This format is identical to the default except that additional hints for
150fontification have been added to the fifth column (remember that in Emacs, the 137fontification have been added to the fifth column (remember that in Emacs, the
151first column is 0). 138first column is 0).
152 139
153The values of the fifth column, in priority order, are: `-' if the 140The values of the fifth column, in priority order, are: `-' if the message has
154message has been replied to, t if an address on the To: line matches 141been replied to, t if an address on the To: line matches one of the
155one of the mailboxes of the current user, `c' if the Cc: line matches, 142mailboxes of the current user, `c' if the Cc: line matches, `b' if the Bcc:
156`b' if the Bcc: line matches, and `n' if a non-empty Newsgroups: header 143line matches, and `n' if a non-empty Newsgroups: header is present.")
157is present.")
158 144
159(defvar mh-scan-format-nmh 145(defvar mh-scan-format-nmh
160 (concat 146 (concat
@@ -176,78 +162,94 @@ This format is identical to the default except that additional hints for
176fontification have been added to the fifth column (remember that in Emacs, the 162fontification have been added to the fifth column (remember that in Emacs, the
177first column is 0). 163first column is 0).
178 164
179The values of the fifth column, in priority order, are: `-' if the 165The values of the fifth column, in priority order, are: `-' if the message has
180message has been replied to, t if an address on the To: line matches 166been replied to, t if an address on the To: field matches one of the
181one of the mailboxes of the current user, `c' if the Cc: line matches, 167mailboxes of the current user, `c' if the Cc: field matches, `b' if the Bcc:
182`b' if the Bcc: line matches, and `n' if a non-empty Newsgroups: header 168field matches, and `n' if a non-empty Newsgroups: field is present.")
183is present.") 169
170(defvar mh-note-deleted ?D
171 "Deleted messages are marked by this character.
172See also `mh-scan-deleted-msg-regexp'.")
173
174(defvar mh-note-refiled ?^
175 "Refiled messages are marked by this character.
176See also `mh-scan-refiled-msg-regexp'.")
177
178(defvar mh-note-cur ?+
179 "The current message (in MH) is marked by this character.
180See also `mh-scan-cur-msg-number-regexp'.")
184 181
185(defvar mh-scan-good-msg-regexp "^\\( *[0-9]+\\)[^D^0-9]" 182(defvar mh-scan-good-msg-regexp "^\\( *[0-9]+\\)[^D^0-9]"
186 "Regexp specifying the scan lines that are 'good' messages. 183 "This regexp specifies the scan lines that are 'good' messages.
187The default `mh-folder-font-lock-keywords' expects this expression to contain 184Note that the default setting of `mh-folder-font-lock-keywords' expects this
188at least one parenthesized expression which matches the message number.") 185expression to contain at least one parenthesized expression which matches the
186message number as in the default of \"^\\\\( *[0-9]+\\\\)[^D^0-9]\".")
189 187
190(defvar mh-scan-deleted-msg-regexp "^\\( *[0-9]+\\)D" 188(defvar mh-scan-deleted-msg-regexp "^\\( *[0-9]+\\)D"
191 "Regexp matching scan lines of deleted messages. 189 "This regexp matches deleted messages.
192The default `mh-folder-font-lock-keywords' expects this expression to contain 190Note that the default setting of `mh-folder-font-lock-keywords' expects this
193at least one parenthesized expression which matches the message number.") 191expression to contain at least one parenthesized expression which matches the
192message number as in the default of \"^\\\\( *[0-9]+\\\\)D\".
193See also `mh-note-deleted'.")
194 194
195(defvar mh-scan-refiled-msg-regexp "^\\( *[0-9]+\\)\\^" 195(defvar mh-scan-refiled-msg-regexp "^\\( *[0-9]+\\)\\^"
196 "Regexp matching scan lines of refiled messages. 196 "This regexp matches refiled messages.
197The default `mh-folder-font-lock-keywords' expects this expression to contain 197Note that the default setting of `mh-folder-font-lock-keywords' expects this
198at least one parenthesized expression which matches the message number.") 198expression to contain at least one parenthesized expression which matches the
199message number as in the default of \"^\\\\( *[0-9]+\\\\)\\\\^\".
200See also `mh-note-refiled'.")
199 201
200(defvar mh-scan-valid-regexp "^ *[0-9]" 202(defvar mh-scan-valid-regexp "^ *[0-9]"
201 "Regexp matching scan lines for messages (not error messages).") 203 "This regexp matches scan lines for messages (not error messages).")
202 204
203(defvar mh-scan-cur-msg-number-regexp "^\\( *[0-9]+\\+\\).*" 205(defvar mh-scan-cur-msg-number-regexp "^\\( *[0-9]+\\+\\).*"
204 "Regexp matching scan line for the current message. 206 "This regexp matches the current message.
205The default `mh-folder-font-lock-keywords' expects this expression to contain 207Note that the default setting of `mh-folder-font-lock-keywords' expects this
206at least one parenthesized expression which matches the message number. 208expression to contain at least one parenthesized expression which matches the
207Don't disable this regexp as it's needed by non fontifying functions.") 209message number as in the default of \"^\\\\( *[0-9]+\\\\+\\\\).*\". Don't
208 210disable this regexp as it's needed by non-fontifying functions.
209(defvar mh-scan-cur-msg-regexp "^\\( *[0-9]+\\+DISABLED.*\\)" 211See also `mh-note-cur'.")
210 "Regexp matching scan line for the current message.
211The default `mh-folder-font-lock-keywords' expects this expression to contain
212at least one parenthesized expression which matches the whole line.
213To enable this feature, remove the string DISABLED from the regexp.")
214 212
215(defvar mh-scan-date-regexp "\\([0-9][0-9]/[0-9][0-9]\\)" 213(defvar mh-scan-date-regexp "\\([0-9][0-9]/[0-9][0-9]\\)"
216 "Regexp matching a valid date in scan lines. 214 "This regexp matches a valid date.
217The default `mh-folder-font-lock-keywords' expects this expression to contain 215Note that the default setting of `mh-folder-font-lock-keywords' expects this
218only one parenthesized expression which matches the date field 216expression to contain only one parenthesized expression which matches the date
219\(see `mh-scan-format-regexp').") 217field as in the default of \"\\\\([0-9][0-9]/[0-9][0-9]\\\\)\"}.
218See also `mh-scan-format-regexp'.")
220 219
221(defvar mh-scan-rcpt-regexp "\\(To:\\)\\(..............\\)" 220(defvar mh-scan-rcpt-regexp "\\(To:\\)\\(..............\\)"
222 "Regexp specifying the recipient in scan lines for messages we sent. 221 "This regexp specifies the recipient in messages you sent.
223The default `mh-folder-font-lock-keywords' expects this expression to contain 222Note that the default setting of `mh-folder-font-lock-keywords'
224two parenthesized expressions. The first is expected to match the To: 223expects this expression to contain two parenthesized expressions. The
225that the default scan format file generates. The second is expected to match 224first is expected to match the `To:' that the default scan format
226the recipient's name.") 225file generates. The second is expected to match the recipient's name
226as in the default of \"\\\\(To:\\\\)\\\\(..............\\\\)\".")
227 227
228(defvar mh-scan-body-regexp "\\(<<\\([^\n]+\\)?\\)" 228(defvar mh-scan-body-regexp "\\(<<\\([^\n]+\\)?\\)"
229 "Regexp matching the message body beginning displayed in scan lines. 229 "This regexp matches the message body fragment displayed in scan lines.
230The default `mh-folder-font-lock-keywords' expects this expression to contain 230Note that the default setting of `mh-folder-font-lock-keywords' expects this
231at least one parenthesized expression which matches the body text.") 231expression to contain at least one parenthesized expression which matches the
232body text as in the default of \"\\\\(<<\\\\([^\\n]+\\\\)?\\\\)\".")
232 233
233(defvar mh-scan-subject-regexp 234(defvar mh-scan-subject-regexp
234 ;;"^ *[0-9]+........[ ]*...................\\([Rr][Ee]:\\s-*\\)*\\([^<\n]*\\)"
235 "^ *[0-9]+........[ ]*...................\\([Rr][Ee]\\(\\[[0-9]+\\]\\)?:\\s-*\\)*\\([^<\n]*\\)" 235 "^ *[0-9]+........[ ]*...................\\([Rr][Ee]\\(\\[[0-9]+\\]\\)?:\\s-*\\)*\\([^<\n]*\\)"
236 "*Regexp matching the subject string in MH folder mode. 236 "This regexp matches the subject.
237The default `mh-folder-font-lock-keywords' expects this expression to contain 237Note that the default setting of `mh-folder-font-lock-keywords' expects this
238at least tree parenthesized expressions. The first is expected to match the Re: 238expression to contain at least three parenthesized expressions. The first is
239string, if any. The second matches an optional bracketed number after Re, 239expected to match the `Re:' string, if any. The second matches an optional
240such as in Re[2]: and the third is expected to match the subject line itself.") 240bracketed number after `Re:', such as in `Re[2]:' (and is thus a
241sub-expression of the first expression) and the third is expected to match
242the subject line itself as in the default of \"^ *[0-9]+........[ ]*...................\\\\([Rr][Ee]\\\\(\\\\\\=[[0-9]+\\\\]\\\\)?:\\\\s-*\\\\)*\\\\([^<\\n]*\\\\)\".")
241 243
242(defvar mh-scan-format-regexp 244(defvar mh-scan-format-regexp
243 (concat "\\([bct]\\)" mh-scan-date-regexp " *\\(..................\\)") 245 (concat "\\([bct]\\)" mh-scan-date-regexp " *\\(..................\\)")
244 "Regexp matching the output of scan. 246 "This regexp matches the output of scan.
245The default value is based upon the default values of either 247Note that the default setting of `mh-folder-font-lock-keywords' expects this
246`mh-scan-format-mh' or `mh-scan-format-nmh'. 248expression to contain at least three parenthesized expressions. The first
247The default `mh-folder-font-lock-keywords' expects this expression to contain 249should match the fontification hint, the second is found in
248at least three parenthesized expressions. The first should match the 250`mh-scan-date-regexp', and the third should match the user name as in the
249fontification hint, the second is found in `mh-scan-date-regexp', and the 251default of \"(concat \"\\\\([bct]\\\\)\" mh-scan-date-regexp
250third should match the user name.") 252 \"*\\\\(..................\\\\)\")\".")
251 253
252 254
253 255
@@ -279,10 +281,7 @@ third should match the user name.")
279 ;; scan font-lock name 281 ;; scan font-lock name
280 (list mh-scan-format-regexp 282 (list mh-scan-format-regexp
281 '(1 mh-folder-date-face) 283 '(1 mh-folder-date-face)
282 '(3 mh-folder-scan-format-face)) 284 '(3 mh-folder-scan-format-face)))
283 ;; Current message line
284 (list mh-scan-cur-msg-regexp
285 '(1 mh-folder-cur-msg-face prepend t)))
286 "Regexp keywords used to fontify the MH-Folder buffer.") 285 "Regexp keywords used to fontify the MH-Folder buffer.")
287 286
288(defvar mh-scan-cmd-note-width 1 287(defvar mh-scan-cmd-note-width 1
@@ -356,46 +355,6 @@ This column will only ever have spaces in it.")
356 355
357;; Fontifify unseen mesages in bold. 356;; Fontifify unseen mesages in bold.
358 357
359(defvar mh-folder-unseen-seq-name nil
360 "Name of unseen sequence.
361The default for this is provided by the function `mh-folder-unseen-seq-name'
362On nmh systems.")
363
364(defun mh-folder-unseen-seq-name ()
365 "Provide name of unseen sequence from mhparam."
366 (or mh-progs (mh-find-path))
367 (save-excursion
368 (let ((unseen-seq-name "unseen"))
369 (with-temp-buffer
370 (unwind-protect
371 (progn
372 (call-process (expand-file-name "mhparam" mh-progs)
373 nil '(t t) nil "-component" "Unseen-Sequence")
374 (goto-char (point-min))
375 (if (re-search-forward "Unseen-Sequence: \\(.*\\)$" nil t)
376 (setq unseen-seq-name (match-string 1))))))
377 unseen-seq-name)))
378
379(defun mh-folder-unseen-seq-list ()
380 "Return a list of unseen message numbers for current folder."
381 (if (not mh-folder-unseen-seq-name)
382 (setq mh-folder-unseen-seq-name (mh-folder-unseen-seq-name)))
383 (cond
384 ((not mh-folder-unseen-seq-name)
385 nil)
386 (t
387 (let ((folder mh-current-folder))
388 (save-excursion
389 (with-temp-buffer
390 (unwind-protect
391 (progn
392 (call-process (expand-file-name "mark" mh-progs)
393 nil '(t t) nil
394 folder "-seq" mh-folder-unseen-seq-name
395 "-list")
396 (goto-char (point-min))
397 (sort (mh-read-msg-list) '<)))))))))
398
399(defmacro mh-generate-sequence-font-lock (seq prefix face) 358(defmacro mh-generate-sequence-font-lock (seq prefix face)
400 "Generate the appropriate code to fontify messages in SEQ. 359 "Generate the appropriate code to fontify messages in SEQ.
401PREFIX is used to generate unique names for the variables and functions 360PREFIX is used to generate unique names for the variables and functions
@@ -492,6 +451,8 @@ is done highlighting.")
492 ;Rememeber original notation that 451 ;Rememeber original notation that
493 ;is overwritten by `mh-note-seq'. 452 ;is overwritten by `mh-note-seq'.
494 453
454(defvar mh-colors-available-flag nil) ;Are colors available?
455
495;;; Macros and generic functions: 456;;; Macros and generic functions:
496 457
497(defun mh-mapc (function list) 458(defun mh-mapc (function list)
@@ -503,7 +464,7 @@ is done highlighting.")
503(defun mh-scan-format () 464(defun mh-scan-format ()
504 "Return the output format argument for the scan program." 465 "Return the output format argument for the scan program."
505 (if (equal mh-scan-format-file t) 466 (if (equal mh-scan-format-file t)
506 (list "-format" (if mh-nmh-flag 467 (list "-format" (if (mh-variant-p 'nmh 'mu-mh)
507 (list (mh-update-scan-format 468 (list (mh-update-scan-format
508 mh-scan-format-nmh mh-cmd-note)) 469 mh-scan-format-nmh mh-cmd-note))
509 (list (mh-update-scan-format 470 (list (mh-update-scan-format
@@ -519,7 +480,7 @@ is done highlighting.")
519(defun mh-rmail (&optional arg) 480(defun mh-rmail (&optional arg)
520 "Inc(orporate) new mail with MH. 481 "Inc(orporate) new mail with MH.
521Scan an MH folder if ARG is non-nil. This function is an entry point to MH-E, 482Scan an MH folder if ARG is non-nil. This function is an entry point to MH-E,
522the Emacs front end to the MH mail system." 483the Emacs interface to the MH mail system."
523 (interactive "P") 484 (interactive "P")
524 (mh-find-path) 485 (mh-find-path)
525 (if arg 486 (if arg
@@ -532,7 +493,7 @@ the Emacs front end to the MH mail system."
532(defun mh-nmail (&optional arg) 493(defun mh-nmail (&optional arg)
533 "Check for new mail in inbox folder. 494 "Check for new mail in inbox folder.
534Scan an MH folder if ARG is non-nil. This function is an entry point to MH-E, 495Scan an MH folder if ARG is non-nil. This function is an entry point to MH-E,
535the Emacs front end to the MH mail system." 496the Emacs interface to the MH mail system."
536 (interactive "P") 497 (interactive "P")
537 (mh-find-path) ; init mh-inbox 498 (mh-find-path) ; init mh-inbox
538 (if arg 499 (if arg
@@ -616,6 +577,7 @@ Do not call this function from outside MH-E; use \\[mh-rmail] instead."
616 (setq folder mh-inbox)) 577 (setq folder mh-inbox))
617 (let ((threading-needed-flag nil)) 578 (let ((threading-needed-flag nil))
618 (let ((config (current-window-configuration))) 579 (let ((config (current-window-configuration)))
580 (delete-other-windows)
619 (cond ((not (get-buffer folder)) 581 (cond ((not (get-buffer folder))
620 (mh-make-folder folder) 582 (mh-make-folder folder)
621 (setq threading-needed-flag mh-show-threads-flag) 583 (setq threading-needed-flag mh-show-threads-flag)
@@ -659,25 +621,26 @@ last undeleted message then pause for a second after printing message."
659 (if wait-after-complaining-flag (sit-for 1))))) 621 (if wait-after-complaining-flag (sit-for 1)))))
660 622
661(defun mh-folder-from-address () 623(defun mh-folder-from-address ()
662 "Determine folder name from address in From field. 624 "Derive folder name from sender.
663Takes the address in the From: header field, and returns one of: 625
626The name of the folder is derived as follows:
664 627
665 a) The folder name associated with the address in the alist 628 a) The folder name associated with the first address found in the list
666 `mh-default-folder-list'. If the `Check Recipient' boolean 629 `mh-default-folder-list' is used. Each element in this list contains a
667 is set, then the `mh-default-folder-list' addresses are 630 `Check Recipient' item. If this item is turned on, then the address is
668 checked against the recipient instead of the originator 631 checked against the recipient instead of the sender. This is useful for
669 (making possible to use this feature for mailing lists). 632 mailing lists.
670 The first match found in `mh-default-folder-list' is used.
671 633
672 b) The address' corresponding alias from the user's personal 634 b) An alias prefixed by `mh-default-folder-prefix' corresponding to the
673 aliases file prefixed by `mh-default-folder-prefix'. 635 address is used. The prefix is used to prevent clutter in your mail
636 directory.
674 637
675Returns nil if the address was not found in either place or if the variable 638Return nil if a folder name was not derived, or if the variable
676`mh-default-folder-must-exist-flag' is nil and the folder does not exist." 639`mh-default-folder-must-exist-flag' is t and the folder does not exist."
677 ;; Loop for all entries in mh-default-folder-list 640 ;; Loop for all entries in mh-default-folder-list
678 (save-restriction 641 (save-restriction
679 (goto-char (point-min)) 642 (goto-char (point-min))
680 (re-search-forward "\n\n" nil t) 643 (re-search-forward "\n\n" nil 'limit)
681 (narrow-to-region (point-min) (point)) 644 (narrow-to-region (point-min) (point))
682 (let ((to/cc (concat (or (message-fetch-field "to") "") ", " 645 (let ((to/cc (concat (or (message-fetch-field "to") "") ", "
683 (or (message-fetch-field "cc") ""))) 646 (or (message-fetch-field "cc") "")))
@@ -715,25 +678,24 @@ Returns nil if the address was not found in either place or if the variable
715 "Prompt the user for a folder in which the message should be filed. 678 "Prompt the user for a folder in which the message should be filed.
716The folder is returned as a string. 679The folder is returned as a string.
717 680
718If `mh-default-folder-for-message-function' is a function then the message 681The default folder name is generated by the option
719being refiled is yanked into a temporary buffer and the function is called to 682`mh-default-folder-for-message-function' if it is non-nil or
720intelligently guess where the message is to be refiled. 683`mh-folder-from-address'."
721
722Otherwise, a default folder name is generated by `mh-folder-from-address'."
723 (mh-prompt-for-folder 684 (mh-prompt-for-folder
724 "Destination" 685 "Destination"
725 (let ((refile-file (mh-msg-filename (mh-get-msg-num t)))) 686 (let ((refile-file (ignore-errors (mh-msg-filename (mh-get-msg-num t)))))
726 (save-excursion 687 (if (null refile-file) ""
727 (set-buffer (get-buffer-create mh-temp-buffer)) 688 (save-excursion
728 (erase-buffer) 689 (set-buffer (get-buffer-create mh-temp-buffer))
729 (insert-file-contents refile-file) 690 (erase-buffer)
730 (or (and mh-default-folder-for-message-function 691 (insert-file-contents refile-file)
731 (let ((buffer-file-name refile-file)) 692 (or (and mh-default-folder-for-message-function
732 (funcall mh-default-folder-for-message-function))) 693 (let ((buffer-file-name refile-file))
733 (mh-folder-from-address) 694 (funcall mh-default-folder-for-message-function)))
734 (and (eq 'refile (car mh-last-destination-folder)) 695 (mh-folder-from-address)
735 (symbol-name (cdr mh-last-destination-folder))) 696 (and (eq 'refile (car mh-last-destination-folder))
736 ""))) 697 (symbol-name (cdr mh-last-destination-folder)))
698 ""))))
737 t)) 699 t))
738 700
739(defun mh-refile-msg (range folder &optional dont-update-last-destination-flag) 701(defun mh-refile-msg (range folder &optional dont-update-last-destination-flag)
@@ -872,7 +834,9 @@ are skipped."
872 (setq count (1- count))) 834 (setq count (1- count)))
873 (not (car unread-sequence))) 835 (not (car unread-sequence)))
874 (message "No more unread messages")) 836 (message "No more unread messages"))
875 (t (mh-goto-msg (car unread-sequence)))))) 837 (t (loop for msg in unread-sequence
838 when (mh-goto-msg msg t) return nil
839 finally (message "No more unread messages"))))))
876 840
877(defun mh-goto-next-button (backward-flag &optional criterion) 841(defun mh-goto-next-button (backward-flag &optional criterion)
878 "Search for next button satisfying criterion. 842 "Search for next button satisfying criterion.
@@ -1090,7 +1054,7 @@ interactive use."
1090 (if (not (mh-outstanding-commands-p)) 1054 (if (not (mh-outstanding-commands-p))
1091 (mh-set-folder-modified-p nil))) 1055 (mh-set-folder-modified-p nil)))
1092 1056
1093;;;###mh-autoload 1057
1094(defun mh-folder-line-matches-show-buffer-p () 1058(defun mh-folder-line-matches-show-buffer-p ()
1095 "Return t if the message under point in folder-mode is in the show buffer. 1059 "Return t if the message under point in folder-mode is in the show buffer.
1096Return nil in any other circumstance (no message under point, no show buffer, 1060Return nil in any other circumstance (no message under point, no show buffer,
@@ -1123,7 +1087,6 @@ compiled then macro expansion happens at compile time."
1123(defun mh-version () 1087(defun mh-version ()
1124 "Display version information about MH-E and the MH mail handling system." 1088 "Display version information about MH-E and the MH mail handling system."
1125 (interactive) 1089 (interactive)
1126 (mh-find-progs)
1127 (set-buffer (get-buffer-create mh-info-buffer)) 1090 (set-buffer (get-buffer-create mh-info-buffer))
1128 (erase-buffer) 1091 (erase-buffer)
1129 ;; MH-E version. 1092 ;; MH-E version.
@@ -1140,19 +1103,12 @@ compiled then macro expansion happens at compile time."
1140 ;; Emacs version. 1103 ;; Emacs version.
1141 (insert (emacs-version) "\n\n") 1104 (insert (emacs-version) "\n\n")
1142 ;; MH version. 1105 ;; MH version.
1143 (let ((help-start (point))) 1106 (if mh-variant-in-use
1144 (condition-case err-data 1107 (insert mh-variant-in-use "\n"
1145 (mh-exec-cmd-output "inc" nil (if mh-nmh-flag "-version" "-help")) 1108 " mh-progs:\t" mh-progs "\n"
1146 (file-error (insert (mapconcat 'concat (cdr err-data) ": ") "\n"))) 1109 " mh-lib:\t" mh-lib "\n"
1147 (goto-char help-start) 1110 " mh-lib-progs:\t" mh-lib-progs "\n\n")
1148 (if mh-nmh-flag 1111 (insert "No MH variant detected\n"))
1149 (search-forward "inc -- " nil t)
1150 (search-forward "version: " nil t))
1151 (delete-region help-start (point)))
1152 (goto-char (point-max))
1153 (insert " mh-progs:\t" mh-progs "\n"
1154 " mh-lib:\t" mh-lib "\n"
1155 " mh-lib-progs:\t" mh-lib-progs "\n\n")
1156 ;; Linux version. 1112 ;; Linux version.
1157 (condition-case () 1113 (condition-case ()
1158 (call-process "uname" nil t nil "-a") 1114 (call-process "uname" nil t nil "-a")
@@ -1202,7 +1158,7 @@ used to avoid problems in corner cases involving folders whose names end with a
1202(defun mh-folder-size-flist (folder) 1158(defun mh-folder-size-flist (folder)
1203 "Find size of FOLDER using `flist'." 1159 "Find size of FOLDER using `flist'."
1204 (with-temp-buffer 1160 (with-temp-buffer
1205 (call-process (expand-file-name "flist" mh-progs) nil t nil 1161 (call-process (expand-file-name "flist" mh-progs) nil t nil "-showzero"
1206 "-norecurse" folder "-sequence" (symbol-name mh-unseen-seq)) 1162 "-norecurse" folder "-sequence" (symbol-name mh-unseen-seq))
1207 (goto-char (point-min)) 1163 (goto-char (point-min))
1208 (multiple-value-bind (folder unseen total) 1164 (multiple-value-bind (folder unseen total)
@@ -1236,6 +1192,7 @@ regardless of the size of the `mh-large-folder' variable."
1236 (let ((config (current-window-configuration)) 1192 (let ((config (current-window-configuration))
1237 (current-buffer (current-buffer)) 1193 (current-buffer (current-buffer))
1238 (threaded-view-flag mh-show-threads-flag)) 1194 (threaded-view-flag mh-show-threads-flag))
1195 (delete-other-windows)
1239 (save-excursion 1196 (save-excursion
1240 (when (get-buffer folder) 1197 (when (get-buffer folder)
1241 (set-buffer folder) 1198 (set-buffer folder)
@@ -1258,12 +1215,11 @@ regardless of the size of the `mh-large-folder' variable."
1258 (mh-toggle-threads)) 1215 (mh-toggle-threads))
1259 (mh-index-data 1216 (mh-index-data
1260 (mh-index-insert-folder-headers))) 1217 (mh-index-insert-folder-headers)))
1261 (unless mh-showing-mode (delete-other-windows))
1262 (unless (eq current-buffer (current-buffer)) 1218 (unless (eq current-buffer (current-buffer))
1263 (setq mh-previous-window-config config))) 1219 (setq mh-previous-window-config config)))
1264 nil) 1220 nil)
1265 1221
1266;;;###mh-autoload 1222
1267(defun mh-update-sequences () 1223(defun mh-update-sequences ()
1268 "Update MH's Unseen-Sequence and current folder and message. 1224 "Update MH's Unseen-Sequence and current folder and message.
1269Flush MH-E's state out to MH. The message at the cursor becomes current." 1225Flush MH-E's state out to MH. The message at the cursor becomes current."
@@ -1334,7 +1290,7 @@ arguments, after the message has been refiled."
1334 (mh-exec-cmd "refile" (mh-get-msg-num t) "-link" 1290 (mh-exec-cmd "refile" (mh-get-msg-num t) "-link"
1335 "-src" mh-current-folder 1291 "-src" mh-current-folder
1336 (symbol-name folder)) 1292 (symbol-name folder))
1337 (message "Message not copied."))) 1293 (message "Message not copied")))
1338 (t 1294 (t
1339 (mh-set-folder-modified-p t) 1295 (mh-set-folder-modified-p t)
1340 (cond ((null (assoc folder mh-refile-list)) 1296 (cond ((null (assoc folder mh-refile-list))
@@ -1381,7 +1337,9 @@ With optional argument COUNT, COUNT-1 unread messages are skipped."
1381 (setq count (1- count))) 1337 (setq count (1- count)))
1382 (not (car unread-sequence))) 1338 (not (car unread-sequence)))
1383 (message "No more unread messages")) 1339 (message "No more unread messages"))
1384 (t (mh-goto-msg (car unread-sequence)))))) 1340 (t (loop for msg in unread-sequence
1341 when (mh-goto-msg msg t) return nil
1342 finally (message "No more unread messages"))))))
1385 1343
1386(defun mh-set-scan-mode () 1344(defun mh-set-scan-mode ()
1387 "Display the scan listing buffer, but do not show a message." 1345 "Display the scan listing buffer, but do not show a message."
@@ -1472,12 +1430,12 @@ Make it the current folder."
1472 ["Go to First Message" mh-first-msg t] 1430 ["Go to First Message" mh-first-msg t]
1473 ["Go to Last Message" mh-last-msg t] 1431 ["Go to Last Message" mh-last-msg t]
1474 ["Go to Message by Number..." mh-goto-msg t] 1432 ["Go to Message by Number..." mh-goto-msg t]
1475 ["Modify Message" mh-modify] 1433 ["Modify Message" mh-modify t]
1476 ["Delete Message" mh-delete-msg (mh-get-msg-num nil)] 1434 ["Delete Message" mh-delete-msg (mh-get-msg-num nil)]
1477 ["Refile Message" mh-refile-msg (mh-get-msg-num nil)] 1435 ["Refile Message" mh-refile-msg (mh-get-msg-num nil)]
1478 ["Undo Delete/Refile" mh-undo t] 1436 ["Undo Delete/Refile" mh-undo (mh-outstanding-commands-p)]
1479 ["Process Delete/Refile" mh-execute-commands 1437 ["Execute Delete/Refile" mh-execute-commands
1480 (or mh-refile-list mh-delete-list)] 1438 (mh-outstanding-commands-p)]
1481 "--" 1439 "--"
1482 ["Compose a New Message" mh-send t] 1440 ["Compose a New Message" mh-send t]
1483 ["Reply to Message..." mh-reply (mh-get-msg-num nil)] 1441 ["Reply to Message..." mh-reply (mh-get-msg-num nil)]
@@ -1501,7 +1459,7 @@ Make it the current folder."
1501 ["Incorporate New Mail" mh-inc-folder t] 1459 ["Incorporate New Mail" mh-inc-folder t]
1502 ["Toggle Show/Folder" mh-toggle-showing t] 1460 ["Toggle Show/Folder" mh-toggle-showing t]
1503 ["Execute Delete/Refile" mh-execute-commands 1461 ["Execute Delete/Refile" mh-execute-commands
1504 (or mh-refile-list mh-delete-list)] 1462 (mh-outstanding-commands-p)]
1505 ["Rescan Folder" mh-rescan-folder t] 1463 ["Rescan Folder" mh-rescan-folder t]
1506 ["Thread Folder" mh-toggle-threads 1464 ["Thread Folder" mh-toggle-threads
1507 (not (memq 'unthread mh-view-ops))] 1465 (not (memq 'unthread mh-view-ops))]
@@ -1541,6 +1499,12 @@ is used in previous versions and XEmacs."
1541 (defvar tool-bar-map) 1499 (defvar tool-bar-map)
1542 (defvar desktop-save-buffer)) ;Emacs 21.4 1500 (defvar desktop-save-buffer)) ;Emacs 21.4
1543 1501
1502;; Register mh-folder-mode as supporting which-function-mode...
1503(load "which-func" t t)
1504(when (and (boundp 'which-func-modes)
1505 (not (member 'mh-folder-mode which-func-modes)))
1506 (push 'mh-folder-mode which-func-modes))
1507
1544(define-derived-mode mh-folder-mode fundamental-mode "MH-Folder" 1508(define-derived-mode mh-folder-mode fundamental-mode "MH-Folder"
1545 "Major MH-E mode for \"editing\" an MH folder scan listing.\\<mh-folder-mode-map> 1509 "Major MH-E mode for \"editing\" an MH folder scan listing.\\<mh-folder-mode-map>
1546 1510
@@ -1548,16 +1512,49 @@ You can show the message the cursor is pointing to, and step through the
1548messages. Messages can be marked for deletion or refiling into another 1512messages. Messages can be marked for deletion or refiling into another
1549folder; these commands are executed all at once with a separate command. 1513folder; these commands are executed all at once with a separate command.
1550 1514
1551A prefix argument (\\[universal-argument]) to delete, refile, list, or undo
1552applies the action to a message sequence. If `transient-mark-mode',
1553is non-nil, the action is applied to the region.
1554
1555Options that control this mode can be changed with \\[customize-group]; 1515Options that control this mode can be changed with \\[customize-group];
1556specify the \"mh\" group. In particular, please see the `mh-scan-format-file' 1516specify the \"mh\" group. In particular, please see the `mh-scan-format-file'
1557option if you wish to modify scan's format. 1517option if you wish to modify scan's format.
1558 1518
1559When a folder is visited, the hook `mh-folder-mode-hook' is run. 1519When a folder is visited, the hook `mh-folder-mode-hook' is run.
1560 1520
1521Ranges
1522======
1523Many commands that operate on individual messages, such as `mh-forward' or
1524`mh-refile-msg' take a RANGE argument. This argument can be used in several
1525ways.
1526
1527If you provide the prefix argument (\\[universal-argument]) to these commands,
1528then you will be prompted for the message range. This can be any legal MH
1529range which can include messages, sequences, and the abbreviations (described
1530in the mh(1) man page):
1531
1532<num1>-<num2>
1533 Indicates all messages in the range <num1> to <num2>, inclusive. The range
1534 must be nonempty.
1535
1536`<num>:N'
1537`<num>:+N'
1538`<num>:-N'
1539 Up to N messages beginning with (or ending with) message num. Num may be
1540 any of the pre-defined symbols: first, prev, cur, next or last.
1541
1542`first:N'
1543`prev:N'
1544`next:N'
1545`last:N'
1546 The first, previous, next or last messages, if they exist.
1547
1548`all'
1549 All of the messages.
1550
1551For example, a range that shows all of these things is `1 2 3 5-10 last:5
1552unseen'.
1553
1554If the option `transient-mark-mode' is set to t and you set a region in the
1555MH-Folder buffer, then the MH-E command will perform the operation on all
1556messages in that region.
1557
1561\\{mh-folder-mode-map}" 1558\\{mh-folder-mode-map}"
1562 1559
1563 (make-local-variable 'font-lock-defaults) 1560 (make-local-variable 'font-lock-defaults)
@@ -1565,10 +1562,15 @@ When a folder is visited, the hook `mh-folder-mode-hook' is run.
1565 (make-local-variable 'desktop-save-buffer) 1562 (make-local-variable 'desktop-save-buffer)
1566 (setq desktop-save-buffer t) 1563 (setq desktop-save-buffer t)
1567 (mh-make-local-vars 1564 (mh-make-local-vars
1565 'mh-colors-available-flag (mh-colors-available-p)
1566 ; Do we have colors available
1568 'mh-current-folder (buffer-name) ; Name of folder, a string 1567 'mh-current-folder (buffer-name) ; Name of folder, a string
1569 'mh-show-buffer (format "show-%s" (buffer-name)) ; Buffer that displays msgs 1568 'mh-show-buffer (format "show-%s" (buffer-name)) ; Buffer that displays msgs
1570 'mh-folder-filename ; e.g. "/usr/foobar/Mail/inbox/" 1569 'mh-folder-filename ; e.g. "/usr/foobar/Mail/inbox/"
1571 (file-name-as-directory (mh-expand-file-name (buffer-name))) 1570 (file-name-as-directory (mh-expand-file-name (buffer-name)))
1571 'mh-display-buttons-for-inline-parts-flag
1572 mh-display-buttons-for-inline-parts-flag ; Allow for display of buttons to
1573 ; be toggled.
1572 'mh-arrow-marker (make-marker) ; Marker where arrow is displayed 1574 'mh-arrow-marker (make-marker) ; Marker where arrow is displayed
1573 'overlay-arrow-position nil ; Allow for simultaneous display in 1575 'overlay-arrow-position nil ; Allow for simultaneous display in
1574 'overlay-arrow-string ">" ; different MH-E buffers. 1576 'overlay-arrow-string ">" ; different MH-E buffers.
@@ -1597,6 +1599,8 @@ When a folder is visited, the hook `mh-folder-mode-hook' is run.
1597 'mh-sequence-notation-history (make-hash-table) 1599 'mh-sequence-notation-history (make-hash-table)
1598 ; Remember what is overwritten by 1600 ; Remember what is overwritten by
1599 ; mh-note-seq. 1601 ; mh-note-seq.
1602 'imenu-create-index-function 'mh-index-create-imenu-index
1603 ; Setup imenu support
1600 'mh-previous-window-config nil) ; Previous window configuration 1604 'mh-previous-window-config nil) ; Previous window configuration
1601 (mh-remove-xemacs-horizontal-scrollbar) 1605 (mh-remove-xemacs-horizontal-scrollbar)
1602 (setq truncate-lines t) 1606 (setq truncate-lines t)
@@ -1620,6 +1624,26 @@ When a folder is visited, the hook `mh-folder-mode-hook' is run.
1620 font-lock-auto-fontify) 1624 font-lock-auto-fontify)
1621 (turn-on-font-lock))) ; Force font-lock in XEmacs. 1625 (turn-on-font-lock))) ; Force font-lock in XEmacs.
1622 1626
1627(defun mh-toggle-mime-buttons ()
1628 "Toggle display of buttons for inline MIME parts."
1629 (interactive)
1630 (setq mh-display-buttons-for-inline-parts-flag
1631 (not mh-display-buttons-for-inline-parts-flag))
1632 (mh-show nil t))
1633
1634(defun mh-colors-available-p ()
1635 "Check if colors are available in the Emacs being used."
1636 (or mh-xemacs-flag
1637 (let ((color-cells
1638 (or (ignore-errors (mh-funcall-if-exists display-color-cells))
1639 (ignore-errors (mh-funcall-if-exists
1640 x-display-color-cells)))))
1641 (and (numberp color-cells) (>= color-cells 8)))))
1642
1643(defun mh-colors-in-use-p ()
1644 "Check if colors are being used in the folder buffer."
1645 (and mh-colors-available-flag font-lock-mode))
1646
1623(defun mh-make-local-vars (&rest pairs) 1647(defun mh-make-local-vars (&rest pairs)
1624 "Initialize local variables according to the variable-value PAIRS." 1648 "Initialize local variables according to the variable-value PAIRS."
1625 1649
@@ -1631,7 +1655,11 @@ When a folder is visited, the hook `mh-folder-mode-hook' is run.
1631(defun mh-restore-desktop-buffer (desktop-buffer-file-name 1655(defun mh-restore-desktop-buffer (desktop-buffer-file-name
1632 desktop-buffer-name 1656 desktop-buffer-name
1633 desktop-buffer-misc) 1657 desktop-buffer-misc)
1634 "Restore an MH folder buffer specified in a desktop file." 1658 "Restore an MH folder buffer specified in a desktop file.
1659When desktop creates a buffer, DESKTOP-BUFFER-FILE-NAME holds the file name to
1660visit, DESKTOP-BUFFER-NAME holds the desired buffer name, and
1661DESKTOP-BUFFER-MISC holds a list of miscellaneous info used by the
1662`desktop-buffer-handlers' functions."
1635 (mh-find-path) 1663 (mh-find-path)
1636 (mh-visit-folder desktop-buffer-name) 1664 (mh-visit-folder desktop-buffer-name)
1637 (current-buffer)) 1665 (current-buffer))
@@ -1641,6 +1669,8 @@ When a folder is visited, the hook `mh-folder-mode-hook' is run.
1641If the optional argument DONT-EXEC-PENDING is non-nil then pending deletes and 1669If the optional argument DONT-EXEC-PENDING is non-nil then pending deletes and
1642refiles aren't carried out. 1670refiles aren't carried out.
1643Return in the folder's buffer." 1671Return in the folder's buffer."
1672 (when (stringp range)
1673 (setq range (delete "" (split-string range "[ \t\n]"))))
1644 (cond ((null (get-buffer folder)) 1674 (cond ((null (get-buffer folder))
1645 (mh-make-folder folder)) 1675 (mh-make-folder folder))
1646 (t 1676 (t
@@ -1693,7 +1723,9 @@ If UPDATE, append the scan lines, otherwise replace."
1693 (goto-char scan-start) 1723 (goto-char scan-start)
1694 (cond ((looking-at "scan: no messages in") 1724 (cond ((looking-at "scan: no messages in")
1695 (keep-lines mh-scan-valid-regexp)) ; Flush random scan lines 1725 (keep-lines mh-scan-valid-regexp)) ; Flush random scan lines
1696 ((looking-at "scan: bad message list ") 1726 ((looking-at (if (mh-variant-p 'mu-mh)
1727 "scan: message set .* does not exist"
1728 "scan: bad message list "))
1697 (keep-lines mh-scan-valid-regexp)) 1729 (keep-lines mh-scan-valid-regexp))
1698 ((looking-at "scan: ")) ; Keep error messages 1730 ((looking-at "scan: ")) ; Keep error messages
1699 (t 1731 (t
@@ -1869,46 +1901,21 @@ in what is now stored in the buffer-local variable `mh-mode-line-annotation'."
1869 ("")))))) 1901 (""))))))
1870 (mh-logo-display)))) 1902 (mh-logo-display))))
1871 1903
1872;;; XXX: Remove this function, if no one uses it any more...
1873(defun mh-unmark-all-headers (remove-all-flags)
1874 "Remove all '+' flags from the folder listing.
1875With non-nil argument REMOVE-ALL-FLAGS, remove all 'D', '^' and '%' flags too.
1876Optimized for speed (i.e., no regular expressions).
1877
1878This function is deprecated. Use `mh-remove-all-notation' instead."
1879 (save-excursion
1880 (let ((case-fold-search nil)
1881 (last-line (1- (point-max)))
1882 char)
1883 (mh-first-msg)
1884 (while (<= (point) last-line)
1885 (forward-char mh-cmd-note)
1886 (setq char (following-char))
1887 (if (or (and remove-all-flags
1888 (or (= char (aref mh-note-deleted 0))
1889 (= char (aref mh-note-refiled 0))))
1890 (= char (aref mh-note-cur 0)))
1891 (progn
1892 (delete-char 1)
1893 (insert " ")))
1894 (if remove-all-flags
1895 (progn
1896 (forward-char 1)
1897 (if (= (following-char) (aref mh-note-seq 0))
1898 (progn
1899 (delete-char 1)
1900 (insert " ")))))
1901 (forward-line)))))
1902
1903(defun mh-add-sequence-notation (msg internal-seq-flag) 1904(defun mh-add-sequence-notation (msg internal-seq-flag)
1904 "Add sequence notation to the MSG on the current line. 1905 "Add sequence notation to the MSG on the current line.
1905If INTERNAL-SEQ-FLAG is non-nil, then just remove text properties from the 1906If INTERNAL-SEQ-FLAG is non-nil, then refontify the scan line if font-lock is
1906current line, so that font-lock would automatically refontify it." 1907turned on."
1907 (with-mh-folder-updating (t) 1908 (with-mh-folder-updating (t)
1908 (save-excursion 1909 (save-excursion
1909 (beginning-of-line) 1910 (beginning-of-line)
1910 (if internal-seq-flag 1911 (if internal-seq-flag
1911 (mh-notate nil nil mh-cmd-note) 1912 (progn
1913 ;; Change the buffer so that if transient-mark-mode is active
1914 ;; and there is an active region it will get deactivated as in
1915 ;; the case of user sequences.
1916 (mh-notate nil nil mh-cmd-note)
1917 (when font-lock-mode
1918 (font-lock-fontify-region (point) (line-end-position))))
1912 (forward-char (1+ mh-cmd-note)) 1919 (forward-char (1+ mh-cmd-note))
1913 (let ((stack (gethash msg mh-sequence-notation-history))) 1920 (let ((stack (gethash msg mh-sequence-notation-history)))
1914 (setf (gethash msg mh-sequence-notation-history) 1921 (setf (gethash msg mh-sequence-notation-history)
@@ -1930,7 +1937,11 @@ If ALL is non-nil, then all sequence marks on the scan line are removed."
1930 (while (and all (cdr stack)) 1937 (while (and all (cdr stack))
1931 (setq stack (cdr stack))) 1938 (setq stack (cdr stack)))
1932 (when stack 1939 (when stack
1933 (mh-notate nil (car stack) (1+ mh-cmd-note))) 1940 (save-excursion
1941 (beginning-of-line)
1942 (forward-char (1+ mh-cmd-note))
1943 (delete-char 1)
1944 (insert (car stack))))
1934 (setf (gethash msg mh-sequence-notation-history) (cdr stack)))))) 1945 (setf (gethash msg mh-sequence-notation-history) (cdr stack))))))
1935 1946
1936(defun mh-remove-cur-notation () 1947(defun mh-remove-cur-notation ()
@@ -1953,7 +1964,7 @@ If ALL is non-nil, then all sequence marks on the scan line are removed."
1953 (mh-remove-sequence-notation msg nil t)) 1964 (mh-remove-sequence-notation msg nil t))
1954 (clrhash mh-sequence-notation-history))) 1965 (clrhash mh-sequence-notation-history)))
1955 1966
1956;;;###mh-autoload 1967
1957(defun mh-goto-cur-msg (&optional minimal-changes-flag) 1968(defun mh-goto-cur-msg (&optional minimal-changes-flag)
1958 "Position the cursor at the current message. 1969 "Position the cursor at the current message.
1959When optional argument MINIMAL-CHANGES-FLAG is non-nil, the function doesn't 1970When optional argument MINIMAL-CHANGES-FLAG is non-nil, the function doesn't
@@ -2102,7 +2113,10 @@ with no arguments, after the unseen sequence is updated."
2102 2113
2103(defun mh-outstanding-commands-p () 2114(defun mh-outstanding-commands-p ()
2104 "Return non-nil if there are outstanding deletes or refiles." 2115 "Return non-nil if there are outstanding deletes or refiles."
2105 (or mh-delete-list mh-refile-list)) 2116 (save-excursion
2117 (when (eq major-mode 'mh-show-mode)
2118 (set-buffer mh-show-folder-buffer))
2119 (or mh-delete-list mh-refile-list)))
2106 2120
2107(defun mh-coalesce-msg-list (messages) 2121(defun mh-coalesce-msg-list (messages)
2108 "Given a list of MESSAGES, return a list of message number ranges. 2122 "Given a list of MESSAGES, return a list of message number ranges.
@@ -2223,7 +2237,7 @@ numbers, a sequence, a region in a cons cell. If nil all messages are notated."
2223 "Return non-nil if NAME is the name of an internal MH-E sequence." 2237 "Return non-nil if NAME is the name of an internal MH-E sequence."
2224 (or (memq name mh-internal-seqs) 2238 (or (memq name mh-internal-seqs)
2225 (eq name mh-unseen-seq) 2239 (eq name mh-unseen-seq)
2226 (and mh-tick-seq (eq name mh-tick-seq)) 2240 (and (mh-colors-in-use-p) mh-tick-seq (eq name mh-tick-seq))
2227 (eq name mh-previous-seq) 2241 (eq name mh-previous-seq)
2228 (mh-folder-name-p name))) 2242 (mh-folder-name-p name)))
2229 2243
@@ -2264,6 +2278,15 @@ change."
2264 (when (and (eq sequence mh-unseen-seq) (mh-speed-flists-active-p)) 2278 (when (and (eq sequence mh-unseen-seq) (mh-speed-flists-active-p))
2265 (apply #'mh-speed-flists t folders-changed))))) 2279 (apply #'mh-speed-flists t folders-changed)))))
2266 2280
2281(defun mh-catchup (range)
2282 "Delete RANGE from the `mh-unseen-seq' sequence.
2283
2284Check the document of `mh-interactive-range' to see how RANGE is read in
2285interactive use."
2286 (interactive (list (mh-interactive-range "Catchup"
2287 (cons (point-min) (point-max)))))
2288 (mh-delete-msg-from-seq range mh-unseen-seq))
2289
2267(defun mh-delete-a-msg-from-seq (msg sequence internal-flag) 2290(defun mh-delete-a-msg-from-seq (msg sequence internal-flag)
2268 "Delete MSG from SEQUENCE. 2291 "Delete MSG from SEQUENCE.
2269If INTERNAL-FLAG is non-nil, then do not inform MH of the change." 2292If INTERNAL-FLAG is non-nil, then do not inform MH of the change."
@@ -2291,23 +2314,6 @@ Signals an error if SEQ is an illegal name."
2291 "-sequence" (symbol-name seq) 2314 "-sequence" (symbol-name seq)
2292 (mh-coalesce-msg-list msgs))))) 2315 (mh-coalesce-msg-list msgs)))))
2293 2316
2294(defun mh-map-over-seqs (function seq-list)
2295 "Apply FUNCTION to each sequence in SEQ-LIST.
2296The sequence name and the list of messages are passed as arguments."
2297 (while seq-list
2298 (funcall function
2299 (mh-seq-name (car seq-list))
2300 (mh-seq-msgs (car seq-list)))
2301 (setq seq-list (cdr seq-list))))
2302
2303(defun mh-notate-if-in-one-seq (msg character offset seq)
2304 "Notate MSG.
2305The CHARACTER is placed at the given OFFSET from the beginning of the listing.
2306The notation is performed if the MSG is only in SEQ."
2307 (let ((in-seqs (mh-seq-containing-msg msg nil)))
2308 (if (and (eq seq (car in-seqs)) (null (cdr in-seqs)))
2309 (mh-notate msg character offset))))
2310
2311(defun mh-seq-containing-msg (msg &optional include-internal-flag) 2317(defun mh-seq-containing-msg (msg &optional include-internal-flag)
2312 "Return a list of the sequences containing MSG. 2318 "Return a list of the sequences containing MSG.
2313If INCLUDE-INTERNAL-FLAG non-nil, include MH-E internal sequences in list." 2319If INCLUDE-INTERNAL-FLAG non-nil, include MH-E internal sequences in list."
@@ -2362,7 +2368,6 @@ If INCLUDE-INTERNAL-FLAG non-nil, include MH-E internal sequences in list."
2362 "g" mh-goto-msg 2368 "g" mh-goto-msg
2363 "i" mh-inc-folder 2369 "i" mh-inc-folder
2364 "k" mh-delete-subject-or-thread 2370 "k" mh-delete-subject-or-thread
2365 "l" mh-print-msg
2366 "m" mh-alt-send 2371 "m" mh-alt-send
2367 "n" mh-next-undeleted-msg 2372 "n" mh-next-undeleted-msg
2368 "\M-n" mh-next-unread-msg 2373 "\M-n" mh-next-unread-msg
@@ -2382,6 +2387,7 @@ If INCLUDE-INTERNAL-FLAG non-nil, include MH-E internal sequences in list."
2382 "?" mh-prefix-help 2387 "?" mh-prefix-help
2383 "'" mh-index-ticked-messages 2388 "'" mh-index-ticked-messages
2384 "S" mh-sort-folder 2389 "S" mh-sort-folder
2390 "c" mh-catchup
2385 "f" mh-alt-visit-folder 2391 "f" mh-alt-visit-folder
2386 "i" mh-index-search 2392 "i" mh-index-search
2387 "k" mh-kill-folder 2393 "k" mh-kill-folder
@@ -2402,6 +2408,17 @@ If INCLUDE-INTERNAL-FLAG non-nil, include MH-E internal sequences in list."
2402 "b" mh-junk-blacklist 2408 "b" mh-junk-blacklist
2403 "w" mh-junk-whitelist) 2409 "w" mh-junk-whitelist)
2404 2410
2411(gnus-define-keys (mh-ps-print-map "P" mh-folder-mode-map)
2412 "?" mh-prefix-help
2413 "A" mh-ps-print-toggle-mime
2414 "C" mh-ps-print-toggle-color
2415 "F" mh-ps-print-toggle-faces
2416 "M" mh-ps-print-toggle-mime
2417 "f" mh-ps-print-msg-file
2418 "l" mh-print-msg
2419 "p" mh-ps-print-msg
2420 "s" mh-ps-print-msg-show)
2421
2405(gnus-define-keys (mh-sequence-map "S" mh-folder-mode-map) 2422(gnus-define-keys (mh-sequence-map "S" mh-folder-mode-map)
2406 "'" mh-narrow-to-tick 2423 "'" mh-narrow-to-tick
2407 "?" mh-prefix-help 2424 "?" mh-prefix-help
@@ -2446,8 +2463,10 @@ If INCLUDE-INTERNAL-FLAG non-nil, include MH-E internal sequences in list."
2446(gnus-define-keys (mh-mime-map "K" mh-folder-mode-map) 2463(gnus-define-keys (mh-mime-map "K" mh-folder-mode-map)
2447 "?" mh-prefix-help 2464 "?" mh-prefix-help
2448 "a" mh-mime-save-parts 2465 "a" mh-mime-save-parts
2466 "e" mh-display-with-external-viewer
2449 "i" mh-folder-inline-mime-part 2467 "i" mh-folder-inline-mime-part
2450 "o" mh-folder-save-mime-part 2468 "o" mh-folder-save-mime-part
2469 "t" mh-toggle-mime-buttons
2451 "v" mh-folder-toggle-mime-part 2470 "v" mh-folder-toggle-mime-part
2452 "\t" mh-next-button 2471 "\t" mh-next-button
2453 [backtab] mh-prev-button 2472 [backtab] mh-prev-button
@@ -2484,6 +2503,9 @@ If INCLUDE-INTERNAL-FLAG non-nil, include MH-E internal sequences in list."
2484 (?F "[l]ist; [v]isit folder;\n" 2503 (?F "[l]ist; [v]isit folder;\n"
2485 "[n]ew messages; [']ticked messages; [s]earch; [i]ndexed search;\n" 2504 "[n]ew messages; [']ticked messages; [s]earch; [i]ndexed search;\n"
2486 "[p]ack; [S]ort; [r]escan; [k]ill") 2505 "[p]ack; [S]ort; [r]escan; [k]ill")
2506 (?P "PS [p]rint message; [l]non-PS print;\n"
2507 "PS Print [s]how window, message to [f]ile;\n"
2508 "Toggle printing of [M]IME parts, [C]olor, [F]aces")
2487 (?S "[p]ut message in sequence, [n]arrow, [']narrow to ticked, [w]iden,\n" 2509 (?S "[p]ut message in sequence, [n]arrow, [']narrow to ticked, [w]iden,\n"
2488 "[s]equences, [l]ist,\n" 2510 "[s]equences, [l]ist,\n"
2489 "[d]elete message from sequence, [k]ill sequence") 2511 "[d]elete message from sequence, [k]ill sequence")
diff --git a/lisp/mh-e/mh-funcs.el b/lisp/mh-e/mh-funcs.el
index 46201860e2a..ef745f4c06f 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, 02, 2003 Free Software Foundation, Inc. 3;; Copyright (C) 1993, 1995, 2001, 02, 03, 2004 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>
@@ -34,6 +34,8 @@
34 34
35;;; Code: 35;;; Code:
36 36
37(eval-when-compile (require 'mh-acros))
38(mh-require-cl)
37(require 'mh-e) 39(require 'mh-e)
38 40
39;;; Customization 41;;; Customization
@@ -45,11 +47,13 @@ prefix argument. Normally default arguments to sortm are specified in the
45MH profile. 47MH profile.
46For example, '(\"-nolimit\" \"-textfield\" \"subject\") is a useful setting.") 48For example, '(\"-nolimit\" \"-textfield\" \"subject\") is a useful setting.")
47 49
50;;; Scan Line Formats
51
48(defvar mh-note-copied "C" 52(defvar mh-note-copied "C"
49 "String whose first character is used to notate copied messages.") 53 "Copied messages are marked by this character.")
50 54
51(defvar mh-note-printed "P" 55(defvar mh-note-printed "P"
52 "String whose first character is used to notate printed messages.") 56 "Messages that have been printed are marked by this character.")
53 57
54;;; Functions 58;;; Functions
55 59
@@ -233,60 +237,6 @@ Otherwise just send the message's body without the headers."
233 (mh-recenter 0))) 237 (mh-recenter 0)))
234 238
235;;;###mh-autoload 239;;;###mh-autoload
236(defun mh-print-msg (range)
237 "Print RANGE on printer.
238
239Check the documentation of `mh-interactive-range' to see how RANGE is read in
240interactive use.
241
242The variable `mh-lpr-command-format' is used to generate the print command.
243The messages are formatted by mhl. See the variable `mhl-formfile'."
244 (interactive (list (mh-interactive-range "Print")))
245 (message "Printing...")
246 (let (msgs)
247 ;; Gather message numbers and add them to "printed" sequence.
248 (mh-iterate-on-range msg range
249 (mh-add-msgs-to-seq msg 'printed t)
250 (mh-notate nil mh-note-printed mh-cmd-note)
251 (push msg msgs))
252 (setq msgs (nreverse msgs))
253 ;; Print scan listing if we have more than one message.
254 (if (> (length msgs) 1)
255 (let* ((msgs-string
256 (mapconcat 'identity (mh-list-to-string
257 (mh-coalesce-msg-list msgs)) " "))
258 (lpr-command
259 (format mh-lpr-command-format
260 (cond ((listp range)
261 (format "Folder: %s, Messages: %s"
262 mh-current-folder msgs-string))
263 ((symbolp range)
264 (format "Folder: %s, Sequence: %s"
265 mh-current-folder range)))))
266 (scan-command
267 (format "scan %s | %s" msgs-string lpr-command)))
268 (if mh-print-background-flag
269 (mh-exec-cmd-daemon shell-file-name nil "-c" scan-command)
270 (call-process shell-file-name nil nil nil "-c" scan-command))))
271 ;; Print the messages
272 (dolist (msg msgs)
273 (let* ((mhl-command (format "%s %s %s"
274 (expand-file-name "mhl" mh-lib-progs)
275 (if mhl-formfile
276 (format " -form %s" mhl-formfile)
277 "")
278 (mh-msg-filename msg)))
279 (lpr-command
280 (format mh-lpr-command-format
281 (format "%s/%s" mh-current-folder msg)))
282 (print-command
283 (format "%s | %s" mhl-command lpr-command)))
284 (if mh-print-background-flag
285 (mh-exec-cmd-daemon shell-file-name nil "-c" print-command)
286 (call-process shell-file-name nil nil nil "-c" print-command)))))
287 (message "Printing...done"))
288
289;;;###mh-autoload
290(defun mh-sort-folder (&optional extra-args) 240(defun mh-sort-folder (&optional extra-args)
291 "Sort the messages in the current folder by date. 241 "Sort the messages in the current folder by date.
292Calls the MH program sortm to do the work. 242Calls the MH program sortm to do the work.
@@ -307,9 +257,8 @@ argument EXTRA-ARGS is given."
307 (mh-index-data (mh-index-insert-folder-headers))))) 257 (mh-index-data (mh-index-insert-folder-headers)))))
308 258
309;;;###mh-autoload 259;;;###mh-autoload
310(defun mh-undo-folder (&rest ignore) 260(defun mh-undo-folder ()
311 "Undo all pending deletes and refiles in current folder. 261 "Undo all pending deletes and refiles in current folder."
312Argument IGNORE is deprecated."
313 (interactive) 262 (interactive)
314 (cond ((or mh-do-not-confirm-flag 263 (cond ((or mh-do-not-confirm-flag
315 (yes-or-no-p "Undo all commands in folder? ")) 264 (yes-or-no-p "Undo all commands in folder? "))
@@ -320,10 +269,7 @@ Argument IGNORE is deprecated."
320 (with-mh-folder-updating (nil) 269 (with-mh-folder-updating (nil)
321 (mh-remove-all-notation))) 270 (mh-remove-all-notation)))
322 (t 271 (t
323 (message "Commands not undone.") 272 (message "Commands not undone"))))
324 ;; Remove by 2003-06-30 if nothing seems amiss. XXX
325 ;; (sit-for 2)
326 )))
327 273
328;;;###mh-autoload 274;;;###mh-autoload
329(defun mh-store-msg (directory) 275(defun mh-store-msg (directory)
@@ -413,11 +359,15 @@ Default directory is the last directory used, or initially the value of
413 359
414;;;###mh-autoload 360;;;###mh-autoload
415(defun mh-help () 361(defun mh-help ()
416 "Display cheat sheet for the MH-Folder commands in minibuffer." 362 "Display cheat sheet for the MH-E commands."
417 (interactive) 363 (interactive)
418 (mh-ephem-message 364 (with-electric-help
419 (substitute-command-keys 365 (function
420 (mapconcat 'identity (cdr (assoc nil mh-help-messages)) "")))) 366 (lambda ()
367 (insert
368 (substitute-command-keys
369 (mapconcat 'identity (cdr (assoc nil mh-help-messages)) ""))))
370 mh-help-buffer)))
421 371
422;;;###mh-autoload 372;;;###mh-autoload
423(defun mh-prefix-help () 373(defun mh-prefix-help ()
@@ -430,9 +380,14 @@ Default directory is the last directory used, or initially the value of
430 ;; from the recent keys. 380 ;; from the recent keys.
431 (let* ((keys (recent-keys)) 381 (let* ((keys (recent-keys))
432 (prefix-char (elt keys (- (length keys) 2)))) 382 (prefix-char (elt keys (- (length keys) 2))))
433 (mh-ephem-message 383 (with-electric-help
434 (substitute-command-keys 384 (function
435 (mapconcat 'identity (cdr (assoc prefix-char mh-help-messages)) ""))))) 385 (lambda ()
386 (insert
387 (substitute-command-keys
388 (mapconcat 'identity
389 (cdr (assoc prefix-char mh-help-messages)) "")))))
390 mh-help-buffer)))
436 391
437(provide 'mh-funcs) 392(provide 'mh-funcs)
438 393
diff --git a/lisp/mh-e/mh-gnus.el b/lisp/mh-e/mh-gnus.el
index 0a893efa3c9..b850c8fdc43 100644
--- a/lisp/mh-e/mh-gnus.el
+++ b/lisp/mh-e/mh-gnus.el
@@ -1,6 +1,6 @@
1;;; mh-gnus.el --- Make MH-E compatible with installed version of Gnus. 1;;; mh-gnus.el --- Make MH-E compatible with installed version of Gnus.
2 2
3;; Copyright (C) 2003 Free Software Foundation, Inc. 3;; Copyright (C) 2003, 2004 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>
@@ -34,6 +34,7 @@
34(load "mm-uu" t t) ; Non-fatal dependency 34(load "mm-uu" t t) ; Non-fatal dependency
35(load "mailcap" t t) ; Non-fatal dependency 35(load "mailcap" t t) ; Non-fatal dependency
36(load "smiley" t t) ; Non-fatal dependency 36(load "smiley" t t) ; Non-fatal dependency
37(load "mailabbrev" t t)
37 38
38(defmacro mh-defun-compat (function arg-list &rest body) 39(defmacro mh-defun-compat (function arg-list &rest body)
39 "This is a macro to define functions which are not defined. 40 "This is a macro to define functions which are not defined.
@@ -74,12 +75,28 @@ BODY."
74 (put-text-property 0 (length (car handle)) parameter value 75 (put-text-property 0 (length (car handle)) parameter value
75 (car handle)))) 76 (car handle))))
76 77
78;; Copy of function from mm-view.el
79(mh-defun-compat mm-inline-text-vcard (handle)
80 (let (buffer-read-only)
81 (mm-insert-inline
82 handle
83 (concat "\n-- \n"
84 (ignore-errors
85 (if (fboundp 'vcard-pretty-print)
86 (vcard-pretty-print (mm-get-part handle))
87 (vcard-format-string
88 (vcard-parse-string (mm-get-part handle)
89 'vcard-standard-filter))))))))
90
91;; Function from mm-decode.el used in PGP messages. Just define it with older
92;; gnus to avoid compiler warning.
93(mh-defun-compat mm-possibly-verify-or-decrypt (parts ctl)
94 nil)
95
77;; Copy of original macro is in mm-decode.el 96;; Copy of original macro is in mm-decode.el
78(mh-defmacro-compat mm-handle-multipart-ctl-parameter (handle parameter) 97(mh-defmacro-compat mm-handle-multipart-ctl-parameter (handle parameter)
79 `(get-text-property 0 ,parameter (car ,handle))) 98 `(get-text-property 0 ,parameter (car ,handle)))
80 99
81(mh-do-in-xemacs (defvar default-enable-multibyte-characters))
82
83;; Copy of original function in mm-decode.el 100;; Copy of original function in mm-decode.el
84(mh-defun-compat mm-readable-p (handle) 101(mh-defun-compat mm-readable-p (handle)
85 "Say whether the content of HANDLE is readable." 102 "Say whether the content of HANDLE is readable."
@@ -134,10 +151,23 @@ BODY."
134 file))) 151 file)))
135 (mm-save-part-to-file handle file)))) 152 (mm-save-part-to-file handle file))))
136 153
154(defun mh-mm-text-html-renderer ()
155 "Find the renderer gnus is using to display text/html MIME parts."
156 (or (and (boundp 'mm-inline-text-html-renderer) mm-inline-text-html-renderer)
157 (and (boundp 'mm-text-html-renderer) mm-text-html-renderer)))
158
159(defun mh-mail-abbrev-make-syntax-table ()
160 "Call `mail-abbrev-make-syntax-table' if available."
161 (when (fboundp 'mail-abbrev-make-syntax-table)
162 (mail-abbrev-make-syntax-table)))
163
137(provide 'mh-gnus) 164(provide 'mh-gnus)
165
138;;; Local Variables: 166;;; Local Variables:
139;;; no-byte-compile: t 167;;; no-byte-compile: t
140;;; no-update-autoloads: t 168;;; no-update-autoloads: t
169;;; indent-tabs-mode: nil
170;;; sentence-end-double-space: nil
141;;; End: 171;;; End:
142 172
143;; arch-tag: 1e3638af-cad3-4c69-8427-bc8eb6e5e4fa 173;; arch-tag: 1e3638af-cad3-4c69-8427-bc8eb6e5e4fa
diff --git a/lisp/mh-e/mh-identity.el b/lisp/mh-e/mh-identity.el
index f4edc7a2087..2b430a52fe1 100644
--- a/lisp/mh-e/mh-identity.el
+++ b/lisp/mh-e/mh-identity.el
@@ -39,47 +39,50 @@
39 39
40;;; Code: 40;;; Code:
41 41
42 42(eval-when-compile (require 'mh-acros))
43(require 'mh-utils)
44(mh-require-cl) 43(mh-require-cl)
45 44(require 'mh-comp)
46(eval-when (compile load eval)
47 (defvar mh-comp-loaded nil)
48 (unless mh-comp-loaded
49 (setq mh-comp-loaded t)
50 (require 'mh-comp))) ;Since we do this on sending
51 45
52(autoload 'mml-insert-tag "mml") 46(autoload 'mml-insert-tag "mml")
53 47
48(defvar mh-identity-pgg-default-user-id nil
49 "Holds the GPG key ID to be used by pgg.el.
50This is normally set as part of an Identity in `mh-identity-list'.")
51(make-variable-buffer-local 'mh-identity-pgg-default-user-id)
52
54;;;###mh-autoload 53;;;###mh-autoload
55(defun mh-identity-make-menu () 54(defun mh-identity-make-menu ()
56 "Build (or rebuild) the Identity menu (e.g. after the list is modified)." 55 "Build the Identity menu.
57 (when (and mh-identity-list (boundp 'mh-letter-mode-map)) 56This should be called any time `mh-identity-list' or `mh-auto-fields-list'
58 (easy-menu-define mh-identity-menu mh-letter-mode-map 57change."
59 "mh-e identity menu" 58 (easy-menu-define mh-identity-menu mh-letter-mode-map
60 (append 59 "MH-E identity menu"
61 '("Identity") 60 (append
62 ;; Dynamically render :type corresponding to `mh-identity-list' 61 '("Identity")
63 ;; e.g.: 62 ;; Dynamically render :type corresponding to `mh-identity-list'
64 ;; ["home" (mh-insert-identity "home") 63 ;; e.g.:
65 ;; :style radio :active (not (equal mh-identity-local "home")) 64 ;; ["Home" (mh-insert-identity "Home")
66 ;; :selected (equal mh-identity-local "home")] 65 ;; :style radio :active (not (equal mh-identity-local "Home"))
67 '(["Insert Auto Fields" (mh-insert-auto-fields) mh-auto-fields-list] 66 ;; :selected (equal mh-identity-local "Home")]
68 "--") 67 '(["Insert Auto Fields"
69 (mapcar (function 68 (mh-insert-auto-fields) mh-auto-fields-list]
70 (lambda (arg) 69 "--")
71 `[,arg (mh-insert-identity ,arg) :style radio 70
72 :active (not (equal mh-identity-local ,arg)) 71 (mapcar (function
73 :selected (equal mh-identity-local ,arg)])) 72 (lambda (arg)
74 (mapcar 'car mh-identity-list)) 73 `[,arg (mh-insert-identity ,arg) :style radio
75 '("--" 74 :selected (equal mh-identity-local ,arg)]))
76 ["none" (mh-insert-identity "none") mh-identity-local] 75 (mapcar 'car mh-identity-list))
77 ["Set Default for Session" 76 '(["None"
78 (setq mh-identity-default mh-identity-local) t] 77 (mh-insert-identity "None") :style radio
79 ["Save as Default" 78 :selected (not mh-identity-local)]
80 (customize-save-variable 79 "--"
81 'mh-identity-default mh-identity-local) t] 80 ["Set Default for Session"
82 ))))) 81 (setq mh-identity-default mh-identity-local) t]
82 ["Save as Default"
83 (customize-save-variable 'mh-identity-default mh-identity-local) t]
84 ["Customize Identities" (customize-variable 'mh-identity-list) t]
85 ))))
83 86
84;;;###mh-autoload 87;;;###mh-autoload
85(defun mh-identity-list-set (symbol value) 88(defun mh-identity-list-set (symbol value)
@@ -97,21 +100,36 @@ customization). This is called after 'customize is used to alter
97(defun mh-header-field-delete (field value-only) 100(defun mh-header-field-delete (field value-only)
98 "Delete FIELD in the mail header, or only its value if VALUE-ONLY is t. 101 "Delete FIELD in the mail header, or only its value if VALUE-ONLY is t.
99Return t if anything is deleted." 102Return t if anything is deleted."
100 (when (mh-goto-header-field field) 103 (let ((field-colon (if (string-match "^.*:$" field)
101 (if (not value-only) 104 field
102 (beginning-of-line) 105 (concat field ":"))))
103 (forward-char)) 106 (when (mh-goto-header-field field-colon)
104 (delete-region (point) 107 (if (not value-only)
105 (progn (mh-header-field-end) 108 (beginning-of-line)
106 (if (not value-only) (forward-char 1)) 109 (forward-char))
107 (point))) 110 (delete-region (point)
108 t)) 111 (progn (mh-header-field-end)
112 (if (not value-only) (forward-char 1))
113 (point)))
114 t)))
109 115
110(defvar mh-identity-signature-start nil 116(defvar mh-identity-signature-start nil
111 "Marker for the beginning of a signature inserted by `mh-insert-identity'.") 117 "Marker for the beginning of a signature inserted by `mh-insert-identity'.")
112(defvar mh-identity-signature-end nil 118(defvar mh-identity-signature-end nil
113 "Marker for the end of a signature inserted by `mh-insert-identity'.") 119 "Marker for the end of a signature inserted by `mh-insert-identity'.")
114 120
121(defun mh-identity-field-handler (field)
122 "Return the handler for a FIELD or nil if none set.
123The field name is downcased. If the FIELD begins with the character
124`:', then it must have a special handler defined in
125`mh-identity-handlers', else return an error since it is not a legal
126message header."
127 (or (cdr (assoc (downcase field) mh-identity-handlers))
128 (and (eq (aref field 0) ?:)
129 (error (format "Field %s - unknown mh-identity-handler" field)))
130 (cdr (assoc "default" mh-identity-handlers))
131 'mh-identity-handler-default))
132
115;;;###mh-autoload 133;;;###mh-autoload
116(defun mh-insert-identity (identity) 134(defun mh-insert-identity (identity)
117 "Insert proper fields for given IDENTITY. 135 "Insert proper fields for given IDENTITY.
@@ -120,7 +138,7 @@ Edit the `mh-identity-list' variable to define identity."
120 (list (completing-read 138 (list (completing-read
121 "Identity: " 139 "Identity: "
122 (if mh-identity-local 140 (if mh-identity-local
123 (cons '("none") 141 (cons '("None")
124 (mapcar 'list (mapcar 'car mh-identity-list))) 142 (mapcar 'list (mapcar 'car mh-identity-list)))
125 (mapcar 'list (mapcar 'car mh-identity-list))) 143 (mapcar 'list (mapcar 'car mh-identity-list)))
126 nil t))) 144 nil t)))
@@ -129,83 +147,135 @@ Edit the `mh-identity-list' variable to define identity."
129 (when mh-identity-local 147 (when mh-identity-local
130 (let ((pers-list (cadr (assoc mh-identity-local mh-identity-list)))) 148 (let ((pers-list (cadr (assoc mh-identity-local mh-identity-list))))
131 (while pers-list 149 (while pers-list
132 (let ((field (concat (caar pers-list) ":"))) 150 (let* ((field (caar pers-list))
133 (cond 151 (handler (mh-identity-field-handler field)))
134 ((string-equal "signature:" field) 152 (funcall handler field 'remove))
135 (when (and (boundp 'mh-identity-signature-start)
136 (markerp mh-identity-signature-start))
137 (goto-char mh-identity-signature-start)
138 (forward-char -1)
139 (delete-region (point) mh-identity-signature-end)))
140 ((mh-header-field-delete field nil))))
141 (setq pers-list (cdr pers-list))))) 153 (setq pers-list (cdr pers-list)))))
142 ;; Then insert the replacement 154 ;; Then insert the replacement
143 (when (not (equal "none" identity)) 155 (when (not (equal "None" identity))
144 (let ((pers-list (cadr (assoc identity mh-identity-list)))) 156 (let ((pers-list (cadr (assoc identity mh-identity-list))))
145 (while pers-list 157 (while pers-list
146 (let ((field (concat (caar pers-list) ":")) 158 (let* ((field (caar pers-list))
147 (value (cdar pers-list))) 159 (value (cdar pers-list))
148 (cond 160 (handler (mh-identity-field-handler field)))
149 ;; No value, remove field 161 (funcall handler field 'add value))
150 ((or (not value)
151 (string= value ""))
152 (mh-header-field-delete field nil))
153 ;; Existing field, replace
154 ((mh-header-field-delete field t)
155 (insert value))
156 ;; Handle "signature" special case. Insert file or call function.
157 ((and (string-equal "signature:" field)
158 (or (and (stringp value)
159 (file-readable-p value))
160 (fboundp value)))
161 (goto-char (point-max))
162 (if (not (looking-at "^$"))
163 (insert "\n"))
164 (insert "\n")
165 (save-restriction
166 (narrow-to-region (point) (point))
167 (set (make-local-variable 'mh-identity-signature-start)
168 (make-marker))
169 (set-marker mh-identity-signature-start (point))
170 (cond
171 ;; If MIME composition done, insert signature at the end as
172 ;; an inline MIME part.
173 ((mh-mhn-directive-present-p)
174 (insert "#\n" "Content-Description: Signature\n"))
175 ((mh-mml-directive-present-p)
176 (mml-insert-tag 'part 'type "text/plain"
177 'disposition "inline"
178 'description "Signature")))
179 (if (stringp value)
180 (insert-file-contents value)
181 (funcall value))
182 (goto-char (point-min))
183 (when (not (re-search-forward "^--" nil t))
184 (cond ((mh-mhn-directive-present-p)
185 (forward-line 2))
186 ((mh-mml-directive-present-p)
187 (forward-line 1)))
188 (insert "-- \n"))
189 (set (make-local-variable 'mh-identity-signature-end)
190 (make-marker))
191 (set-marker mh-identity-signature-end (point-max))))
192 ;; Handle "From" field differently, adding it at the beginning.
193 ((string-equal "From:" field)
194 (goto-char (point-min))
195 (insert "From: " value "\n"))
196 ;; Skip empty signature (Can't remove what we don't know)
197 ((string-equal "signature:" field))
198 ;; Other field, add at end
199 (t ;Otherwise, add the end.
200 (goto-char (point-min))
201 (mh-goto-header-end 0)
202 (mh-insert-fields field value))))
203 (setq pers-list (cdr pers-list)))))) 162 (setq pers-list (cdr pers-list))))))
204 ;; Remember what is in use in this buffer 163 ;; Remember what is in use in this buffer
205 (if (equal "none" identity) 164 (if (equal "None" identity)
206 (setq mh-identity-local nil) 165 (setq mh-identity-local nil)
207 (setq mh-identity-local identity))) 166 (setq mh-identity-local identity)))
208 167
168;;;###mh-autoload
169(defun mh-identity-handler-gpg-identity (field action &optional value)
170 "For FIELD \"pgg-default-user-id\", process for ACTION 'remove or 'add.
171The buffer-local variable `mh-identity-pgg-default-user-id' is set to VALUE
172when action 'add is selected."
173 (cond
174 ((or (equal action 'remove)
175 (not value)
176 (string= value ""))
177 (setq mh-identity-pgg-default-user-id nil))
178 ((equal action 'add)
179 (setq mh-identity-pgg-default-user-id value))))
180
181;;;###mh-autoload
182(defun mh-identity-handler-signature (field action &optional value)
183 "For FIELD \"signature\", process headers for ACTION 'remove or 'add.
184The VALUE is added."
185 (cond
186 ((equal action 'remove)
187 (when (and (markerp mh-identity-signature-start)
188 (markerp mh-identity-signature-end))
189 (delete-region mh-identity-signature-start
190 mh-identity-signature-end)))
191 (t
192 ;; Insert "signature". Nil value means to use `mh-signature-file-name'.
193 (when (not (mh-signature-separator-p)) ;...unless already present
194 (goto-char (point-max))
195 (save-restriction
196 (narrow-to-region (point) (point))
197 (if (null value)
198 (mh-insert-signature)
199 (mh-insert-signature value))
200 (set (make-local-variable 'mh-identity-signature-start)
201 (point-min-marker))
202 (set-marker-insertion-type mh-identity-signature-start t)
203 (set (make-local-variable 'mh-identity-signature-end)
204 (point-max-marker)))))))
205
206(defvar mh-identity-attribution-verb-start nil
207 "Marker for the beginning of the attribution verb.")
208(defvar mh-identity-attribution-verb-end nil
209 "Marker for the end of the attribution verb.")
210
211;;;###mh-autoload
212(defun mh-identity-handler-attribution-verb (field action &optional value)
213 "For FIELD \"attribution_verb\", process headers for ACTION 'remove or 'add.
214The VALUE is added."
215 (when (and (markerp mh-identity-attribution-verb-start)
216 (markerp mh-identity-attribution-verb-end))
217 (delete-region mh-identity-attribution-verb-start
218 mh-identity-attribution-verb-end)
219 (goto-char mh-identity-attribution-verb-start)
220 (cond
221 ((equal action 'remove) ; Replace with default
222 (mh-identity-insert-attribution-verb nil))
223 (t ; Insert attribution verb.
224 (mh-identity-insert-attribution-verb value)))))
225
226;;;###mh-autoload
227(defun mh-identity-insert-attribution-verb (value)
228 "Insert VALUE as attribution verb, setting up delimiting markers.
229If VALUE is nil, use `mh-extract-from-attribution-verb'."
230 (save-restriction
231 (narrow-to-region (point) (point))
232 (if (null value)
233 (insert mh-extract-from-attribution-verb)
234 (insert value))
235 (set (make-local-variable 'mh-identity-attribution-verb-start)
236 (point-min-marker))
237 (set-marker-insertion-type mh-identity-attribution-verb-start t)
238 (set (make-local-variable 'mh-identity-attribution-verb-end)
239 (point-max-marker))))
240
241(defun mh-identity-handler-default (field action top &optional value)
242 "For FIELD, process mh-identity headers for ACTION 'remove or 'add.
243if TOP is non-nil, add the field and it's VALUE at the top of the header, else
244add it at the bottom of the header."
245 (let ((field-colon (if (string-match "^.*:$" field)
246 field
247 (concat field ":"))))
248 (cond
249 ((equal action 'remove)
250 (mh-header-field-delete field-colon nil))
251 (t
252 (cond
253 ;; No value, remove field
254 ((or (not value)
255 (string= value ""))
256 (mh-header-field-delete field-colon nil))
257 ;; Existing field, replace
258 ((mh-header-field-delete field-colon t)
259 (insert value))
260 ;; Other field, add at end or top
261 (t
262 (goto-char (point-min))
263 (if (not top)
264 (mh-goto-header-end 0))
265 (insert field-colon " " value "\n")))))))
266
267;;;###mh-autoload
268(defun mh-identity-handler-top (field action &optional value)
269 "For FIELD, process mh-identity headers for ACTION 'remove or 'add.
270If the field wasn't present, the VALUE is added at the top of the header."
271 (mh-identity-handler-default field action t value))
272
273;;;###mh-autoload
274(defun mh-identity-handler-bottom (field action &optional value)
275 "For FIELD, process mh-identity headers for ACTION 'remove or 'add.
276If the field wasn't present, the VALUE is added at the bottom of the header."
277 (mh-identity-handler-default field action nil value))
278
209(provide 'mh-identity) 279(provide 'mh-identity)
210 280
211;;; Local Variables: 281;;; Local Variables:
diff --git a/lisp/mh-e/mh-inc.el b/lisp/mh-e/mh-inc.el
index 1c052b140bd..42ca018506f 100644
--- a/lisp/mh-e/mh-inc.el
+++ b/lisp/mh-e/mh-inc.el
@@ -1,6 +1,6 @@
1;;; mh-inc.el --- MH-E `inc' and separate mail spool handling 1;;; mh-inc.el --- MH-E `inc' and separate mail spool handling
2;; 2;;
3;; Copyright (C) 2003 Free Software Foundation, Inc. 3;; Copyright (C) 2003, 2004 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>
@@ -34,7 +34,8 @@
34 34
35;;; Code: 35;;; Code:
36 36
37(eval-when-compile (require 'cl)) 37(eval-when-compile (require 'mh-acros))
38(mh-require-cl)
38 39
39(defvar mh-inc-spool-map (make-sparse-keymap) 40(defvar mh-inc-spool-map (make-sparse-keymap)
40 "Keymap for MH-E's mh-inc-spool commands.") 41 "Keymap for MH-E's mh-inc-spool commands.")
@@ -46,7 +47,8 @@
46 '(lambda () 47 '(lambda ()
47 (interactive) 48 (interactive)
48 (if mh-inc-spool-map-help 49 (if mh-inc-spool-map-help
49 (mh-ephem-message (substring mh-inc-spool-map-help 0 -1)) 50 (let ((mh-help-messages (list (list nil mh-inc-spool-map-help))))
51 (mh-help))
50 (mh-ephem-message 52 (mh-ephem-message
51 "There are no keys defined yet. Customize `mh-inc-spool-list'")))) 53 "There are no keys defined yet. Customize `mh-inc-spool-list'"))))
52 54
diff --git a/lisp/mh-e/mh-index.el b/lisp/mh-e/mh-index.el
index 734ce938616..91eed420e2e 100644
--- a/lisp/mh-e/mh-index.el
+++ b/lisp/mh-e/mh-index.el
@@ -31,7 +31,6 @@
31;;; swish-e 31;;; swish-e
32;;; mairix 32;;; mairix
33;;; namazu 33;;; namazu
34;;; glimpse
35;;; grep 34;;; grep
36;;; 35;;;
37;;; (2) To use this package, you first have to build an index. Please read 36;;; (2) To use this package, you first have to build an index. Please read
@@ -43,7 +42,7 @@
43 42
44;;; Code: 43;;; Code:
45 44
46(require 'mh-utils) 45(eval-when-compile (require 'mh-acros))
47(mh-require-cl) 46(mh-require-cl)
48(require 'mh-e) 47(require 'mh-e)
49(require 'mh-mime) 48(require 'mh-mime)
@@ -66,8 +65,6 @@
66 mh-mairix-regexp-builder) 65 mh-mairix-regexp-builder)
67 (namazu 66 (namazu
68 mh-namazu-binary mh-namazu-execute-search mh-namazu-next-result nil) 67 mh-namazu-binary mh-namazu-execute-search mh-namazu-next-result nil)
69 (glimpse
70 mh-glimpse-binary mh-glimpse-execute-search mh-glimpse-next-result nil)
71 (pick 68 (pick
72 mh-pick-binary mh-pick-execute-search mh-pick-next-result 69 mh-pick-binary mh-pick-execute-search mh-pick-next-result
73 mh-pick-regexp-builder) 70 mh-pick-regexp-builder)
@@ -200,7 +197,8 @@ This function should only be called in the appropriate index folder buffer."
200 (call-process "rm" nil nil nil 197 (call-process "rm" nil nil nil
201 (format "%s%s/%s" mh-user-path 198 (format "%s%s/%s" mh-user-path
202 (substring mh-current-folder 1) msg)) 199 (substring mh-current-folder 1) msg))
203 (remhash omsg (gethash ofolder mh-index-data)))) 200 (when (gethash ofolder mh-index-data)
201 (remhash omsg (gethash ofolder mh-index-data)))))
204 (t 202 (t
205 (setf (gethash msg mh-index-msg-checksum-map) checksum) 203 (setf (gethash msg mh-index-msg-checksum-map) checksum)
206 (when origin-map 204 (when origin-map
@@ -301,7 +299,8 @@ list of messages in that sequence."
301 (pair (gethash checksum mh-index-checksum-origin-map)) 299 (pair (gethash checksum mh-index-checksum-origin-map))
302 (ofolder (car pair)) 300 (ofolder (car pair))
303 (omsg (cdr pair))) 301 (omsg (cdr pair)))
304 (loop for seq in (gethash omsg (gethash ofolder seq-hash)) 302 (loop for seq in (ignore-errors
303 (gethash omsg (gethash ofolder seq-hash)))
305 do (if (assoc seq seq-list) 304 do (if (assoc seq seq-list)
306 (push msg (cdr (assoc seq seq-list))) 305 (push msg (cdr (assoc seq seq-list)))
307 (push (list seq msg) seq-list))))) 306 (push (list seq msg) seq-list)))))
@@ -374,7 +373,6 @@ index for each program:
374 - `mh-swish-execute-search' 373 - `mh-swish-execute-search'
375 - `mh-mairix-execute-search' 374 - `mh-mairix-execute-search'
376 - `mh-namazu-execute-search' 375 - `mh-namazu-execute-search'
377 - `mh-glimpse-execute-search'
378 376
379If none of these programs are present then we use pick. If desired grep can be 377If none of these programs are present then we use pick. If desired grep can be
380used instead. Details about these methods can be found in: 378used instead. Details about these methods can be found in:
@@ -436,7 +434,7 @@ This has the effect of renaming already present X-MHE-Checksum headers."
436 (save-excursion (mh-exec-cmd-quiet nil "rmf" buffer-name)) 434 (save-excursion (mh-exec-cmd-quiet nil "rmf" buffer-name))
437 (mh-exec-cmd-quiet nil "folder" "-create" "-fast" buffer-name) 435 (mh-exec-cmd-quiet nil "folder" "-create" "-fast" buffer-name)
438 (setq index-folder buffer-name)) 436 (setq index-folder buffer-name))
439 (setq index-folder (mh-index-new-folder index-folder))) 437 (setq index-folder (mh-index-new-folder index-folder search-regexp)))
440 438
441 (let ((folder-path (format "%s%s" mh-user-path (substring folder 1))) 439 (let ((folder-path (format "%s%s" mh-user-path (substring folder 1)))
442 (folder-results-map (make-hash-table :test #'equal)) 440 (folder-results-map (make-hash-table :test #'equal))
@@ -587,13 +585,6 @@ PROC is used to convert the value to actual data."
587 mh-previous-window-config) 585 mh-previous-window-config)
588 (error "No search terms")))) 586 (error "No search terms"))))
589 587
590(defun mh-replace-string (old new)
591 "Replace all occurrences of OLD with NEW in the current buffer."
592 (goto-char (point-min))
593 (let ((case-fold-search t))
594 (while (search-forward old nil t)
595 (replace-match new t t))))
596
597;;;###mh-autoload 588;;;###mh-autoload
598(defun mh-index-parse-search-regexp (input-string) 589(defun mh-index-parse-search-regexp (input-string)
599 "Construct parse tree for INPUT-STRING. 590 "Construct parse tree for INPUT-STRING.
@@ -739,28 +730,48 @@ results."
739 "Check if MSG exists in FOLDER." 730 "Check if MSG exists in FOLDER."
740 (file-exists-p (format "%s%s/%s" mh-user-path (substring folder 1) msg))) 731 (file-exists-p (format "%s%s/%s" mh-user-path (substring folder 1) msg)))
741 732
742(defun mh-index-new-folder (name) 733(defun mh-index-new-folder (name search-regexp)
743 "Create and return an MH folder name based on NAME. 734 "Return a folder name based on NAME for search results of SEARCH-REGEXP.
744If the folder NAME already exists then check if NAME<2> exists. If it doesn't 735
745then it is created and returned. Otherwise try NAME<3>. This is repeated till 736If folder NAME already exists and was generated for the same SEARCH-REGEXP
746we find a new folder name." 737then it is reused.
738
739Otherwise if the folder NAME was generated from a different search then check
740if NAME<2> can be used. Otherwise try NAME<3>. This is repeated till we find a
741new folder name.
742
743If the folder returned doesn't exist then it is created."
747 (unless (mh-folder-name-p name) 744 (unless (mh-folder-name-p name)
748 (error "The argument should be a valid MH folder name")) 745 (error "The argument should be a valid MH folder name"))
749 (let ((chosen-name name)) 746 (let ((chosen-name
750 (block unique-name 747 (loop for i from 1
751 (unless (mh-folder-exists-p name) 748 for candidate = (if (equal i 1) name (format "%s<%s>" name i))
752 (return-from unique-name)) 749 when (or (not (mh-folder-exists-p candidate))
753 (loop for index from 2 750 (equal (mh-index-folder-search-regexp candidate)
754 do (let ((new-name (format "%s<%s>" name index))) 751 search-regexp))
755 (unless (mh-folder-exists-p new-name) 752 return candidate)))
756 (setq chosen-name new-name) 753 ;; Do pending refiles/deletes...
757 (return-from unique-name))))) 754 (when (get-buffer chosen-name)
755 (mh-process-or-undo-commands chosen-name))
756 ;; Recreate folder...
757 (save-excursion (mh-exec-cmd-quiet nil "rmf" chosen-name))
758 (mh-exec-cmd-quiet nil "folder" "-create" "-fast" chosen-name) 758 (mh-exec-cmd-quiet nil "folder" "-create" "-fast" chosen-name)
759 (mh-remove-from-sub-folders-cache chosen-name) 759 (mh-remove-from-sub-folders-cache chosen-name)
760 (when (boundp 'mh-speed-folder-map) 760 (when (boundp 'mh-speed-folder-map)
761 (mh-speed-add-folder chosen-name)) 761 (mh-speed-add-folder chosen-name))
762 chosen-name)) 762 chosen-name))
763 763
764(defun mh-index-folder-search-regexp (folder)
765 "If FOLDER was created by a index search, return the search regexp.
766Return nil if FOLDER doesn't exist or the .mhe_index file is garbled."
767 (ignore-errors
768 (with-temp-buffer
769 (insert-file-contents
770 (format "%s%s/%s" mh-user-path (substring folder 1) mh-index-data-file))
771 (goto-char (point-min))
772 (forward-list 3)
773 (cadr (read (current-buffer))))))
774
764;;;###mh-autoload 775;;;###mh-autoload
765(defun mh-index-insert-folder-headers () 776(defun mh-index-insert-folder-headers ()
766 "Annotate the search results with original folder names." 777 "Annotate the search results with original folder names."
@@ -777,8 +788,27 @@ we find a new folder name."
777 (insert (if last-folder "\n" "") current-folder "\n") 788 (insert (if last-folder "\n" "") current-folder "\n")
778 (setq last-folder current-folder)) 789 (setq last-folder current-folder))
779 (forward-line)) 790 (forward-line))
780 (when cur-msg (mh-goto-msg cur-msg t)) 791 (when cur-msg
781 (set-buffer-modified-p old-buffer-modified-flag))) 792 (mh-notate-cur)
793 (mh-goto-msg cur-msg t))
794 (set-buffer-modified-p old-buffer-modified-flag))
795 (mh-index-create-imenu-index))
796
797;;;###mh-autoload
798(defun mh-index-create-imenu-index ()
799 "Create alist of folder names and positions in index folder buffers."
800 (save-excursion
801 (setq which-func-mode t)
802 (let ((alist ()))
803 (goto-char (point-min))
804 (while (re-search-forward "^+" nil t)
805 (save-excursion
806 (beginning-of-line)
807 (push (cons (buffer-substring-no-properties
808 (point) (line-end-position))
809 (set-marker (make-marker) (point)))
810 alist)))
811 (setq imenu--index-alist (nreverse alist)))))
782 812
783;;;###mh-autoload 813;;;###mh-autoload
784(defun mh-index-group-by-folder () 814(defun mh-index-group-by-folder ()
@@ -837,23 +867,6 @@ list of messages originally from that folder."
837 folder (loop for x being the hash-keys of (gethash folder mh-index-data) 867 folder (loop for x being the hash-keys of (gethash folder mh-index-data)
838 when (mh-msg-exists-p x folder) collect x))))) 868 when (mh-msg-exists-p x folder) collect x)))))
839 869
840;;;###mh-autoload
841(defun mh-index-update-unseen (msg)
842 "Remove counterpart of MSG in source folder from `mh-unseen-seq'.
843Also `mh-update-unseen' is called in the original folder, if we have it open."
844 (let* ((checksum (gethash msg mh-index-msg-checksum-map))
845 (folder-msg-pair (gethash checksum mh-index-checksum-origin-map))
846 (orig-folder (car folder-msg-pair))
847 (orig-msg (cdr folder-msg-pair)))
848 (when (mh-index-match-checksum orig-msg orig-folder checksum)
849 (when (get-buffer orig-folder)
850 (save-excursion
851 (set-buffer orig-folder)
852 (unless (member orig-msg mh-seen-list) (push orig-msg mh-seen-list))
853 (mh-update-unseen)))
854 (mh-exec-cmd-daemon "mark" #'ignore orig-folder (format "%s" orig-msg)
855 "-sequence" (symbol-name mh-unseen-seq) "-del"))))
856
857(defun mh-index-match-checksum (msg folder checksum) 870(defun mh-index-match-checksum (msg folder checksum)
858 "Check if MSG in FOLDER has X-MHE-Checksum header value of CHECKSUM." 871 "Check if MSG in FOLDER has X-MHE-Checksum header value of CHECKSUM."
859 (with-temp-buffer 872 (with-temp-buffer
@@ -973,90 +986,6 @@ update the source folder buffer if present."
973 986
974 987
975 988
976;; Glimpse interface
977
978(defvar mh-glimpse-binary (executable-find "glimpse"))
979(defvar mh-glimpse-directory ".glimpse")
980
981;;;###mh-autoload
982(defun mh-glimpse-execute-search (folder-path search-regexp)
983 "Execute glimpse and read the results.
984
985In the examples below, replace /home/user/Mail with the path to your MH
986directory.
987
988First create the directory /home/user/Mail/.glimpse. Then create the file
989/home/user/Mail/.glimpse/.glimpse_exclude with the following contents:
990
991 */.*
992 */#*
993 */,*
994 */*~
995 ^/home/user/Mail/.glimpse
996 ^/home/user/Mail/mhe-index
997
998If there are any directories you would like to ignore, append lines like the
999following to .glimpse_exclude:
1000
1001 ^/home/user/Mail/scripts
1002
1003You do not want to index the folders that hold the results of your searches
1004since they tend to be ephemeral and the original messages are indexed anyway.
1005The configuration file above assumes that the results are found in sub-folders
1006of `mh-index-folder' which is +mhe-index by default.
1007
1008Use the following command line to generate the glimpse index. Run this
1009daily from cron:
1010
1011 glimpseindex -H /home/user/Mail/.glimpse /home/user/Mail
1012
1013FOLDER-PATH is the directory in which SEARCH-REGEXP is used to search."
1014 (set-buffer (get-buffer-create mh-index-temp-buffer))
1015 (erase-buffer)
1016 (call-process mh-glimpse-binary nil '(t nil) nil
1017 ;(format "-%s" fuzz)
1018 "-i" "-y"
1019 "-H" (format "%s%s" mh-user-path mh-glimpse-directory)
1020 "-F" (format "^%s" folder-path)
1021 search-regexp)
1022 (goto-char (point-min)))
1023
1024(defun mh-glimpse-next-result ()
1025 "Read the next result.
1026Parse it and return the message folder, message index and the match. If no
1027other matches left then return nil. If the current record is invalid return
1028'error."
1029 (prog1
1030 (block nil
1031 (when (eobp)
1032 (return nil))
1033 (let ((eol-pos (line-end-position))
1034 (bol-pos (line-beginning-position))
1035 folder-start msg-end)
1036 (goto-char bol-pos)
1037 (unless (search-forward mh-user-path eol-pos t)
1038 (return 'error))
1039 (setq folder-start (point))
1040 (unless (search-forward ": " eol-pos t)
1041 (return 'error))
1042 (let ((match (buffer-substring-no-properties (point) eol-pos)))
1043 (forward-char -2)
1044 (setq msg-end (point))
1045 (unless (search-backward "/" folder-start t)
1046 (return 'error))
1047 (list (format "+%s" (buffer-substring-no-properties
1048 folder-start (point)))
1049 (let ((val (ignore-errors (read-from-string
1050 (buffer-substring-no-properties
1051 (1+ (point)) msg-end)))))
1052 (if (and (consp val) (integerp (car val)))
1053 (car val)
1054 (return 'error)))
1055 match))))
1056 (forward-line)))
1057
1058
1059
1060;; Pick interface 989;; Pick interface
1061 990
1062(defvar mh-index-pick-folder) 991(defvar mh-index-pick-folder)
@@ -1319,16 +1248,12 @@ then the folders are searched recursively. All parameters ARGS are ignored."
1319;;;###mh-autoload 1248;;;###mh-autoload
1320(defun mh-index-sequenced-messages (folders sequence) 1249(defun mh-index-sequenced-messages (folders sequence)
1321 "Display messages from FOLDERS in SEQUENCE. 1250 "Display messages from FOLDERS in SEQUENCE.
1322By default the folders specified by `mh-index-new-messages-folders' are 1251All messages in the sequence you provide from the folders in
1323searched. With a prefix argument, enter a space-separated list of folders, or 1252`mh-index-new-messages-folders' are listed. With a prefix argument, enter a
1324nothing to search all folders. 1253space-separated list of folders, or nothing to search all folders."
1325
1326Argument SEQUENCE defaults to `mh-unseen-seq' and is the sequence that the
1327function searches for in each of the FOLDERS. With a prefix argument, enter a
1328sequence to use."
1329 (interactive 1254 (interactive
1330 (list (if current-prefix-arg 1255 (list (if current-prefix-arg
1331 (split-string (read-string "Search folder(s) [all]? ")) 1256 (split-string (read-string "Search folder(s): [all] "))
1332 mh-index-new-messages-folders) 1257 mh-index-new-messages-folders)
1333 (mh-read-seq-default "Search" nil))) 1258 (mh-read-seq-default "Search" nil)))
1334 (unless sequence (setq sequence mh-unseen-seq)) 1259 (unless sequence (setq sequence mh-unseen-seq))
@@ -1367,26 +1292,26 @@ sequence to use."
1367;;;###mh-autoload 1292;;;###mh-autoload
1368(defun mh-index-new-messages (folders) 1293(defun mh-index-new-messages (folders)
1369 "Display unseen messages. 1294 "Display unseen messages.
1370All messages in the `unseen' sequence from FOLDERS are displayed. 1295If you use a program such as `procmail' to use `rcvstore' to file your
1371By default the folders specified by `mh-index-new-messages-folders' 1296incoming mail automatically, you can display new, unseen, messages using this
1372are searched. With a prefix argument, enter a space-separated list of 1297command. All messages in the `unseen' sequence from the folders in
1373folders, or nothing to search all folders." 1298`mh-index-new-messages-folders' are listed. With a prefix argument, enter a
1299space-separated list of FOLDERS, or nothing to search all folders."
1374 (interactive 1300 (interactive
1375 (list (if current-prefix-arg 1301 (list (if current-prefix-arg
1376 (split-string (read-string "Search folder(s) [all]? ")) 1302 (split-string (read-string "Search folder(s): [all] "))
1377 mh-index-new-messages-folders))) 1303 mh-index-new-messages-folders)))
1378 (mh-index-sequenced-messages folders mh-unseen-seq)) 1304 (mh-index-sequenced-messages folders mh-unseen-seq))
1379 1305
1380;;;###mh-autoload 1306;;;###mh-autoload
1381(defun mh-index-ticked-messages (folders) 1307(defun mh-index-ticked-messages (folders)
1382 "Display ticked messages. 1308 "Display ticked messages.
1383All messages in the `tick' sequence from FOLDERS are displayed. 1309All messages in `mh-tick-seq' from the folders in
1384By default the folders specified by `mh-index-ticked-messages-folders' 1310`mh-index-ticked-messages-folders' are listed. With a prefix argument, enter a
1385are searched. With a prefix argument, enter a space-separated list of 1311space-separated list of FOLDERS, or nothing to search all folders."
1386folders, or nothing to search all folders."
1387 (interactive 1312 (interactive
1388 (list (if current-prefix-arg 1313 (list (if current-prefix-arg
1389 (split-string (read-string "Search folder(s) [all]? ")) 1314 (split-string (read-string "Search folder(s): [all] "))
1390 mh-index-ticked-messages-folders))) 1315 mh-index-ticked-messages-folders)))
1391 (mh-index-sequenced-messages folders mh-tick-seq)) 1316 (mh-index-sequenced-messages folders mh-tick-seq))
1392 1317
diff --git a/lisp/mh-e/mh-init.el b/lisp/mh-e/mh-init.el
new file mode 100644
index 00000000000..ac7305fa217
--- /dev/null
+++ b/lisp/mh-e/mh-init.el
@@ -0,0 +1,308 @@
1;;; mh-init.el --- MH-E initialization.
2
3;; Copyright (C) 2003, 2004 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;; Sets up the MH variant (currently nmh or MH).
30;;
31;; Users may customize `mh-variant' to switch between available variants.
32;; Available MH variants are described in the variable `mh-variants'.
33;; Developers may check which variant is currently in use with the
34;; variable `mh-variant-in-use' or the function `mh-variant-p'.
35
36;;; Change Log:
37
38;;; Code:
39
40(eval-when-compile (require 'mh-acros))
41(mh-require-cl)
42(require 'mh-utils)
43
44;;; Set for local environment:
45;;; mh-progs and mh-lib used to be set in paths.el, which tried to
46;;; figure out at build time which of several possible directories MH
47;;; was installed into. But if you installed MH after building Emacs,
48;;; this would almost certainly be wrong, so now we do it at run time.
49
50(defvar mh-progs nil
51 "Directory containing MH commands, such as inc, repl, and rmm.")
52
53(defvar mh-lib nil
54 "Directory containing the MH library.
55This directory contains, among other things, the components file.")
56
57(defvar mh-lib-progs nil
58 "Directory containing MH helper programs.
59This directory contains, among other things, the mhl program.")
60
61(defvar mh-flists-present-flag nil
62 "Non-nil means that we have `flists'.")
63
64;;;###autoload
65(put 'mh-progs 'risky-local-variable t)
66;;;###autoload
67(put 'mh-lib 'risky-local-variable t)
68;;;###autoload
69(put 'mh-lib-progs 'risky-local-variable t)
70
71(defvar mh-variant-in-use nil
72 "The MH variant currently in use; a string with variant and version number.
73This differs from `mh-variant' when the latter is set to `autodetect'.")
74
75;;;###mh-autoload
76(defun mh-variant-set (variant)
77 "Set the MH variant to VARIANT.
78Sets `mh-progs', `mh-lib', `mh-lib-progs' and `mh-flists-present-flag'.
79If the VARIANT is `autodetect', then first try nmh, then MH and finally
80GNU mailutils."
81 (interactive
82 (list (completing-read
83 "MH Variant: "
84 (mapcar (lambda (x) (list (car x))) (mh-variants))
85 nil t)))
86 (let ((valid-list (mapcar (lambda (x) (car x)) (mh-variants))))
87 (cond
88 ((eq variant 'none))
89 ((eq variant 'autodetect)
90 (cond
91 ((mh-variant-set-variant 'nmh)
92 (message "%s installed as MH variant" mh-variant-in-use))
93 ((mh-variant-set-variant 'MH)
94 (message "%s installed as MH variant" mh-variant-in-use))
95 ((mh-variant-set-variant 'mu-mh)
96 (message "%s installed as MH variant" mh-variant-in-use))
97 (t
98 (message "No MH variant found on the system!"))))
99 ((member variant valid-list)
100 (when (not (mh-variant-set-variant variant))
101 (message "Warning: %s variant not found. Autodetecting..." variant)
102 (mh-variant-set 'autodetect)))
103 (t
104 (message "Unknown variant. Use %s"
105 (mapconcat '(lambda (x) (format "%s" (car x)))
106 mh-variants " or "))))))
107
108(defun mh-variant-set-variant (variant)
109 "Setup the system variables for the MH variant named VARIANT.
110If VARIANT is a string, use that key in the variable `mh-variants'.
111If VARIANT is a symbol, select the first entry that matches that variant."
112 (cond
113 ((stringp variant) ;e.g. "nmh 1.1-RC1"
114 (when (assoc variant mh-variants)
115 (let* ((alist (cdr (assoc variant mh-variants)))
116 (lib-progs (cadr (assoc 'mh-lib-progs alist)))
117 (lib (cadr (assoc 'mh-lib alist)))
118 (progs (cadr (assoc 'mh-progs alist)))
119 (flists (cadr (assoc 'flists alist))))
120 ;;(set-default mh-variant variant)
121 (setq mh-x-mailer-string nil
122 mh-flists-present-flag flists
123 mh-lib-progs lib-progs
124 mh-lib lib
125 mh-progs progs
126 mh-variant-in-use variant))))
127 ((symbolp variant) ;e.g. 'nmh (pick the first match)
128 (loop for variant-list in mh-variants
129 when (eq variant (cadr (assoc 'variant (cdr variant-list))))
130 return (let* ((version (car variant-list))
131 (alist (cdr variant-list))
132 (lib-progs (cadr (assoc 'mh-lib-progs alist)))
133 (lib (cadr (assoc 'mh-lib alist)))
134 (progs (cadr (assoc 'mh-progs alist)))
135 (flists (cadr (assoc 'flists alist))))
136 ;;(set-default mh-variant flavor)
137 (setq mh-x-mailer-string nil
138 mh-flists-present-flag flists
139 mh-lib-progs lib-progs
140 mh-lib lib
141 mh-progs progs
142 mh-variant-in-use version)
143 t)))))
144
145;;;###mh-autoload
146(defun mh-variant-p (&rest variants)
147 "Return t if variant is any of VARIANTS.
148Currently known variants are 'mh and 'nmh."
149 (let ((variant-in-use
150 (cadr (assoc 'variant (assoc mh-variant-in-use mh-variants)))))
151 (not (null (member variant-in-use variants)))))
152
153(defvar mh-sys-path
154 '("/usr/local/nmh/bin" ; nmh default
155 "/usr/local/bin/mh/"
156 "/usr/local/mh/"
157 "/usr/bin/mh/" ; Ultrix 4.2, Linux
158 "/usr/new/mh/" ; Ultrix < 4.2
159 "/usr/contrib/mh/bin/" ; BSDI
160 "/usr/pkg/bin/" ; NetBSD
161 "/usr/local/bin/"
162 "/usr/local/bin/mu-mh/" ; GNU mailutils - default
163 "/usr/bin/mu-mh/") ; GNU mailutils - packaged
164 "List of directories to search for variants of the MH variant.
165The list `exec-path' is searched in addition to this list.
166There's no need for users to modify this list. Instead add extra
167directories to the customizable variable `mh-path'.")
168
169(defcustom mh-path nil
170 "*List of directories to search for variants of the MH variant.
171The directories will be searched for `mhparam' in addition to directories
172listed in `mh-sys-path' and `exec-path'."
173 :group 'mh
174 :type '(repeat (directory)))
175
176(defvar mh-variants nil
177 "List describing known MH variants.
178Created by the function `mh-variants'")
179
180(defun mh-variant-mh-info (dir)
181 "Return info for MH variant in DIR assuming a temporary buffer is setup."
182 ;; MH does not have the -version option.
183 ;; Its version number is included in the output of `-help' as:
184 ;;
185 ;; version: MH 6.8.4 #2[UCI] (burrito) of Fri Jan 15 20:01:39 EST 1999
186 ;; options: [ATHENA] [BIND] [DUMB] [LIBLOCKFILE] [LOCALE] [MAILGROUP] [MHE]
187 ;; [MHRC] [MIME] [MORE='"/usr/bin/sensible-pager"'] [NLINK_HACK]
188 ;; [NORUSERPASS] [OVERHEAD] [POP] [POPSERVICE='"pop-3"'] [RENAME]
189 ;; [RFC1342] [RPATHS] [RPOP] [SENDMTS] [SMTP] [SOCKETS]
190 ;; [SPRINTFTYPE=int] [SVR4] [SYS5] [SYS5DIR] [TERMINFO]
191 ;; [TYPESIG=void] [UNISTD] [UTK] [VSPRINTF]
192 (let ((mhparam (expand-file-name "mhparam" dir)))
193 (when (and (file-exists-p mhparam) (file-executable-p mhparam))
194 (erase-buffer)
195 (call-process mhparam nil '(t nil) nil "-help")
196 (goto-char (point-min))
197 (when (search-forward-regexp "version: MH \\(\\S +\\)" nil t)
198 (let ((version (format "MH %s" (match-string 1))))
199 (erase-buffer)
200 (call-process mhparam nil '(t nil) nil "libdir")
201 (goto-char (point-min))
202 (when (search-forward-regexp "^.*$" nil t)
203 (let ((libdir (match-string 0)))
204 `(,version
205 (variant mh)
206 (mh-lib-progs ,libdir)
207 (mh-lib ,libdir)
208 (mh-progs ,dir)
209 (flists nil)))))))))
210
211(defun mh-variant-mu-mh-info (dir)
212 "Return info for GNU mailutils variant in DIR.
213This assumes that a temporary buffer is setup."
214 ;; 'mhparam -version' output:
215 ;; mhparam (GNU mailutils 0.3.2)
216 (let ((mhparam (expand-file-name "mhparam" dir)))
217 (when (and (file-exists-p mhparam) (file-executable-p mhparam))
218 (erase-buffer)
219 (call-process mhparam nil '(t nil) nil "-version")
220 (goto-char (point-min))
221 (when (search-forward-regexp "mhparam (\\(GNU [Mm]ailutils \\S +\\))"
222 nil t)
223 (let ((version (match-string 1)))
224 (erase-buffer)
225 (call-process mhparam nil '(t nil) nil "libdir" "etcdir")
226 (goto-char (point-min))
227 (when (search-forward-regexp "^libdir:\\s-\\(\\S-+\\)\\s-*$" nil t)
228 (let ((libdir (match-string 1)))
229 (goto-char (point-min))
230 (when (search-forward-regexp
231 "^etcdir:\\s-\\(\\S-+\\)\\s-*$" nil t)
232 (let ((etcdir (match-string 1))
233 (flists (file-exists-p (expand-file-name "flists" dir))))
234 `(,version
235 (variant mu-mh)
236 (mh-lib-progs ,libdir)
237 (mh-lib ,etcdir)
238 (mh-progs ,dir)
239 (flists ,flists)))))))))))
240
241(defun mh-variant-nmh-info (dir)
242 "Return info for nmh variant in DIR assuming a temporary buffer is setup."
243 ;; `mhparam -version' outputs:
244 ;; mhparam -- nmh-1.1-RC1 [compiled on chaak at Fri Jun 20 11:03:28 PDT 2003]
245 (let ((mhparam (expand-file-name "mhparam" dir)))
246 (when (and (file-exists-p mhparam) (file-executable-p mhparam))
247 (erase-buffer)
248 (call-process mhparam nil '(t nil) nil "-version")
249 (goto-char (point-min))
250 (when (search-forward-regexp "mhparam -- nmh-\\(\\S +\\)" nil t)
251 (let ((version (format "nmh %s" (match-string 1))))
252 (erase-buffer)
253 (call-process mhparam nil '(t nil) nil "libdir" "etcdir")
254 (goto-char (point-min))
255 (when (search-forward-regexp "^libdir:\\s-\\(\\S-+\\)\\s-*$" nil t)
256 (let ((libdir (match-string 1)))
257 (goto-char (point-min))
258 (when (search-forward-regexp
259 "^etcdir:\\s-\\(\\S-+\\)\\s-*$" nil t)
260 (let ((etcdir (match-string 1))
261 (flists (file-exists-p (expand-file-name "flists" dir))))
262 `(,version
263 (variant nmh)
264 (mh-lib-progs ,libdir)
265 (mh-lib ,etcdir)
266 (mh-progs ,dir)
267 (flists ,flists)))))))))))
268
269(defun mh-variant-info (dir)
270 "Return MH variant found in DIR, or nil if none present."
271 (save-excursion
272 (let ((tmp-buffer (get-buffer-create mh-temp-buffer)))
273 (set-buffer tmp-buffer)
274 (cond
275 ((mh-variant-mh-info dir))
276 ((mh-variant-nmh-info dir))
277 ((mh-variant-mu-mh-info dir))))))
278
279;;;###mh-autoload
280(defun mh-variants ()
281 "Return a list of installed variants of MH on the system.
282This function looks for MH in `mh-sys-path', `mh-path' and
283`exec-path'. The format of the list of variants that is returned is described
284by the variable `mh-variants'."
285 (if mh-variants
286 mh-variants
287 (let ((list-unique))
288 ;; Make a unique list of directories, keeping the given order.
289 ;; We don't want the same MH variant to be listed multiple times.
290 (loop for dir in (append mh-path mh-sys-path exec-path) do
291 (setq dir (file-chase-links (directory-file-name dir)))
292 (add-to-list 'list-unique dir))
293 (loop for dir in (nreverse list-unique) do
294 (when (and dir (file-directory-p dir) (file-readable-p dir))
295 (let ((variant (mh-variant-info dir)))
296 (if variant
297 (add-to-list 'mh-variants variant)))))
298 mh-variants)))
299
300(provide 'mh-init)
301
302;;; Local Variables:
303;;; indent-tabs-mode: nil
304;;; sentence-end-double-space: nil
305;;; End:
306
307;; arch-tag: e8372aeb-d803-42b1-9c95-3c93ad22f63c
308;;; mh-init.el ends here
diff --git a/lisp/mh-e/mh-junk.el b/lisp/mh-e/mh-junk.el
index 42ec4c444d3..095a8c3c3fd 100644
--- a/lisp/mh-e/mh-junk.el
+++ b/lisp/mh-e/mh-junk.el
@@ -1,6 +1,6 @@
1;;; mh-junk.el --- Interface to anti-spam measures 1;;; mh-junk.el --- Interface to anti-spam measures
2 2
3;; Copyright (C) 2003 Free Software Foundation, Inc. 3;; Copyright (C) 2003, 2004 Free Software Foundation, Inc.
4 4
5;; Author: Satyaki Das <satyaki@theforce.stanford.edu>, 5;; Author: Satyaki Das <satyaki@theforce.stanford.edu>,
6;; Bill Wohler <wohler@newt.com> 6;; Bill Wohler <wohler@newt.com>
@@ -32,6 +32,8 @@
32 32
33;;; Code: 33;;; Code:
34 34
35(eval-when-compile (require 'mh-acros))
36(mh-require-cl)
35(require 'mh-e) 37(require 'mh-e)
36 38
37;; Interactive functions callable from the folder buffer 39;; Interactive functions callable from the folder buffer
@@ -39,36 +41,33 @@
39(defun mh-junk-blacklist (range) 41(defun mh-junk-blacklist (range)
40 "Blacklist RANGE as spam. 42 "Blacklist RANGE as spam.
41 43
42Check the documentation of `mh-interactive-range' to see how RANGE is read in 44This command trains the spam program in use (see the `mh-junk-program' option)
43interactive use. 45with the content of the range (see `mh-interactive-range') and then handles
46the message(s) as specified by the `mh-junk-disposition' option.
44 47
45First the appropriate function is called depending on the value of 48For more information about using your particular spam fighting program, see:
46`mh-junk-choice'. Then if `mh-junk-mail-folder' is a string then the message is
47refiled to that folder. If nil, the message is deleted.
48
49To change the spam program being used, customize `mh-junk-program'. Directly
50setting `mh-junk-choice' is not recommended.
51
52The documentation for the following functions describes what setup is needed
53for the different spam fighting programs:
54 49
50 - `mh-spamassassin-blacklist'
55 - `mh-bogofilter-blacklist' 51 - `mh-bogofilter-blacklist'
56 - `mh-spamprobe-blacklist' 52 - `mh-spamprobe-blacklist'"
57 - `mh-spamassassin-blacklist'"
58 (interactive (list (mh-interactive-range "Blacklist"))) 53 (interactive (list (mh-interactive-range "Blacklist")))
59 (let ((blacklist-func (nth 1 (assoc mh-junk-choice mh-junk-function-alist)))) 54 (let ((blacklist-func (nth 1 (assoc mh-junk-choice mh-junk-function-alist))))
60 (unless blacklist-func 55 (unless blacklist-func
61 (error "Customize `mh-junk-program' appropriately")) 56 (error "Customize `mh-junk-program' appropriately"))
62 (let ((dest (cond ((null mh-junk-mail-folder) nil) 57 (let ((dest (cond ((null mh-junk-disposition) nil)
63 ((equal mh-junk-mail-folder "") "+") 58 ((equal mh-junk-disposition "") "+")
64 ((eq (aref mh-junk-mail-folder 0) ?+) 59 ((eq (aref mh-junk-disposition 0) ?+)
65 mh-junk-mail-folder) 60 mh-junk-disposition)
66 ((eq (aref mh-junk-mail-folder 0) ?@) 61 ((eq (aref mh-junk-disposition 0) ?@)
67 (concat mh-current-folder "/" 62 (concat mh-current-folder "/"
68 (substring mh-junk-mail-folder 1))) 63 (substring mh-junk-disposition 1)))
69 (t (concat "+" mh-junk-mail-folder))))) 64 (t (concat "+" mh-junk-disposition)))))
70 (mh-iterate-on-range msg range 65 (mh-iterate-on-range msg range
66 (message (format "Blacklisting message %d..." msg))
71 (funcall (symbol-function blacklist-func) msg) 67 (funcall (symbol-function blacklist-func) msg)
68 (message (format "Blacklisting message %d...done" msg))
69 (if (not (memq msg mh-seen-list))
70 (setq mh-seen-list (cons msg mh-seen-list)))
72 (if dest 71 (if dest
73 (mh-refile-a-msg nil (intern dest)) 72 (mh-refile-a-msg nil (intern dest))
74 (mh-delete-a-msg nil))) 73 (mh-delete-a-msg nil)))
@@ -76,231 +75,124 @@ for the different spam fighting programs:
76 75
77;;;###mh-autoload 76;;;###mh-autoload
78(defun mh-junk-whitelist (range) 77(defun mh-junk-whitelist (range)
79 "Whitelist RANGE incorrectly classified as spam. 78 "Whitelist RANGE as ham.
80
81Check the documentation of `mh-interactive-range' to see how RANGE is read in
82interactive use.
83 79
84First the appropriate function is called depending on the value of 80This command reclassifies a range of messages (see `mh-interactive-range') as
85`mh-junk-choice'. Then the message is refiled to `mh-inbox'. 81ham if it were incorrectly classified as spam. It then refiles the message
82into the `+inbox' folder.
86 83
87To change the spam program being used, customize `mh-junk-program'. Directly 84The `mh-junk-program' option specifies the spam program in use."
88setting `mh-junk-choice' is not recommended."
89 (interactive (list (mh-interactive-range "Whitelist"))) 85 (interactive (list (mh-interactive-range "Whitelist")))
90 (let ((whitelist-func (nth 2 (assoc mh-junk-choice mh-junk-function-alist)))) 86 (let ((whitelist-func (nth 2 (assoc mh-junk-choice mh-junk-function-alist))))
91 (unless whitelist-func 87 (unless whitelist-func
92 (error "Customize `mh-junk-program' appropriately")) 88 (error "Customize `mh-junk-program' appropriately"))
93 (mh-iterate-on-range msg range 89 (mh-iterate-on-range msg range
90 (message (format "Whitelisting message %d..." msg))
94 (funcall (symbol-function whitelist-func) msg) 91 (funcall (symbol-function whitelist-func) msg)
92 (message (format "Whitelisting message %d...done" msg))
95 (mh-refile-a-msg nil (intern mh-inbox))) 93 (mh-refile-a-msg nil (intern mh-inbox)))
96 (mh-next-msg))) 94 (mh-next-msg)))
97 95
98 96
99 97
100;; Bogofilter Interface 98;; Spamassassin Interface
101
102(defvar mh-bogofilter-executable (executable-find "bogofilter"))
103
104(defun mh-bogofilter-blacklist (msg)
105 "Classify MSG as spam.
106Tell bogofilter that the message is spam.
107 99
108Bogofilter is a Bayesian spam filtering program. Get it from your local 100(defvar mh-spamassassin-executable (executable-find "spamassassin"))
109distribution or from: 101(defvar mh-sa-learn-executable (executable-find "sa-learn"))
110 http://bogofilter.sourceforge.net/
111 102
112You first need to teach bogofilter. This is done by running 103(defun mh-spamassassin-blacklist (msg)
104 "Blacklist MSG with SpamAssassin.
113 105
114 bogofilter -n < good-message 106SpamAssassin is one of the more popular spam filtering programs. Get it from
107your local distribution or from http://spamassassin.org/.
115 108
116on every good message, and 109To use SpamAssassin, add the following recipes to `.procmailrc':
117 110
118 bogofilter -s < spam-message 111 MAILDIR=$HOME/`mhparam Path`
119 112
120on every spam message. Most Bayesian filters need 1000 to 5000 of each to 113 # Fight spam with SpamAssassin.
121start doing a good job. 114 :0fw
115 | spamc
122 116
123To use bogofilter, add the following .procmailrc recipes which you can also 117 # Anything with a spam level of 10 or more is junked immediately.
124find in the bogofilter man page: 118 :0:
119 * ^X-Spam-Level: ..........
120 /dev/null
125 121
126 # Bogofilter 122 :0:
127 :0fw 123 * ^X-Spam-Status: Yes
128 | bogofilter -u -e -p 124 spam/.
129 125
130 :0 126If you don't use `spamc', use `spamassassin -P -a'.
131 * ^X-Bogosity: Yes, tests=bogofilter
132 $SPAM
133 127
134Bogofilter continues to feed the messages it classifies back into its 128Note that one of the recipes above throws away messages with a score greater
135database. Occasionally it misses, and those messages need to be reclassified. 129than or equal to 10. Here's how you can determine a value that works best for
136MH-E can do this for you. Use \\[mh-junk-blacklist] to reclassify messges in 130you.
137your +inbox as spam, and \\[mh-junk-whitelist] to reclassify messages in your
138spambox as good messages."
139 (unless mh-bogofilter-executable
140 (error "Couldn't find the bogofilter executable"))
141 (let ((msg-file (mh-msg-filename msg mh-current-folder)))
142 (call-process mh-bogofilter-executable msg-file 0 nil "-Ns")))
143 131
144(defun mh-bogofilter-whitelist (msg) 132First, run `spamassassin -t' on every mail message in your archive and use
145 "Reinstate incorrectly filtered MSG. 133Gnumeric to verify that the average plus the standard deviation of good mail
146Train bogofilter to think of the message as non-spam." 134is under 5, the SpamAssassin default for \"spam\".
147 (unless mh-bogofilter-executable
148 (error "Couldn't find the bogofilter executable"))
149 (let ((msg-file (mh-msg-filename msg mh-current-folder)))
150 (call-process mh-bogofilter-executable msg-file 0 nil "-Sn")))
151 135
152 136Using Gnumeric, sort the messages by score and view the messages with the
137highest score. Determine the score which encompasses all of your interesting
138messages and add a couple of points to be conservative. Add that many dots to
139the `X-Spam-Level:' header field above to send messages with that score down
140the drain.
153 141
154;; Spamprobe Interface 142In the example above, messages with a score of 5-9 are set aside in the
143`+spam' folder for later review. The major weakness of rules-based filters is
144a plethora of false positives so it is worthwhile to check.
155 145
156(defvar mh-spamprobe-executable (executable-find "spamprobe")) 146If SpamAssassin classifies a message incorrectly, or is unsure, you can use
147the MH-E commands \\[mh-junk-blacklist] and \\[mh-junk-whitelist].
157 148
158(defun mh-spamprobe-blacklist (msg) 149The \\[mh-junk-blacklist] command adds a `blacklist_from' entry to
159 "Classify MSG as spam. 150`~/spamassassin/user_prefs', deletes the message, and sends the message to the
160Tell spamprobe that the message is spam. 151Razor, so that others might not see this spam. If the `sa-learn' command is
161 152available, the message is also recategorized as spam.
162Spamprobe is a Bayesian spam filtering program. More info about the program can
163be found at:
164 http://spamprobe.sourceforge.net
165
166Here is a procmail recipe to stores incoming spam mail into the folder +spam
167and good mail in /home/user/Mail/mdrop/mbox. This recipe is provided as an
168example in the spamprobe man page.
169
170 PATH=/bin:/usr/bin:/usr/local/bin
171 DEFAULT=/home/user/Mail/mdrop/mbox
172 SPAM=/home/user/Mail/spam/.
173
174 # Spamprobe filtering
175 :0
176 SCORE=| spamprobe receive
177 :0 wf
178 | formail -I \"X-SpamProbe: $SCORE\"
179 :0 a:
180 *^X-SpamProbe: SPAM
181 $SPAM
182
183Occasionally some good mail gets misclassified as spam. You can use
184\\[mh-junk-whitelist] to reclassify that as good mail."
185 (unless mh-spamprobe-executable
186 (error "Couldn't find the spamprobe executable"))
187 (let ((msg-file (mh-msg-filename msg mh-current-folder)))
188 (call-process mh-spamprobe-executable msg-file 0 nil "spam")))
189 153
190(defun mh-spamprobe-whitelist (msg) 154The \\[mh-junk-whitelist] command adds a `whitelist_from' rule to the
191 "Reinstate incorrectly filtered MSG. 155`~/.spamassassin/user_prefs' file. If the `sa-learn' command is available, the
192Train spamprobe to think of the message as non-spam." 156message is also recategorized as ham.
193 (unless mh-spamprobe-executable
194 (error "Couldn't find the spamprobe executable"))
195 (let ((msg-file (mh-msg-filename msg mh-current-folder)))
196 (call-process mh-spamprobe-executable msg-file 0 nil "good")))
197 157
198 158Over time, you'll observe that the same host or domain occurs repeatedly in
159the `blacklist_from' entries, so you might think that you could avoid future
160spam by blacklisting all mail from a particular domain. The utility function
161`mh-spamassassin-identify-spammers' helps you do precisely that. This function
162displays a frequency count of the hosts and domains in the `blacklist_from'
163entries from the last blank line in `~/.spamassassin/user_prefs' to the end of
164the file. This information can be used so that you can replace multiple
165`blacklist_from' entries with a single wildcard entry such as:
199 166
200;; Spamassassin Interface 167 blacklist_from *@*amazingoffersdirect2u.com
201 168
202(defvar mh-spamassassin-executable (executable-find "spamassassin")) 169In versions of SpamAssassin (2.50 and on) that support a Bayesian classifier,
203(defvar mh-sa-learn-executable (executable-find "sa-learn")) 170\\[mh-junk-blacklist] uses the `sa-learn' program to recategorize the message
171as spam. Neither MH-E, nor SpamAssassin, rebuilds the database after adding
172words, so you will need to run `sa-learn --rebuild' periodically. This can be
173done by adding the following to your crontab:
204 174
205(defun mh-spamassassin-blacklist (msg) 175 0 * * * * sa-learn --rebuild > /dev/null 2>&1"
206 "Blacklist MSG.
207This is done by sending the message to Razor and by appending the sender to
208~/.spamassassin/user_prefs in a blacklist_from rule. If sa-learn is available,
209the message is also recategorized as spam.
210
211Spamassassin is an excellent spam filter. For more information, see:
212 http://spamassassin.org/.
213
214I ran \"spamassassin -t\" on every mail message in my archive and ran an
215analysis in Gnumeric to find that the standard deviation of good mail
216scored under 5 (coincidentally, the spamassassin default for \"spam\").
217
218Furthermore, I observed that there weren't any messages with a score of 8
219or more that were interesting, so I added a couple of points to be
220conservative and send any message with a score of 10 or more down the
221drain. You might want to use a score of 12 or 13 to be really conservative.
222I have found that this really decreases the amount of junk to review.
223
224Messages with a score of 5-9 are set aside for later review. The major
225weakness of rules-based filters is a plethora of false positives\; I catch one
226or two legitimate messages in here a week, so it is worthwhile to check.
227
228You might choose to do this analysis yourself to pick a good score for
229deleting spam sight unseen, or you might pick a score out of a hat, or you
230might choose to be very conservative and not delete any messages at all.
231
232Based upon this discussion, here is what the associated ~/.procmailrc
233entries look like. These rules appear before my list filters so that spam
234sent to mailing lists gets pruned too.
235
236 #
237 # Spam
238 #
239 :0fw
240 | spamc
241
242 # Anything with a spam level of 10 or more is junked immediately.
243 :0:
244 * ^X-Spam-Level: ..........
245 /dev/null
246
247 :0
248 * ^X-Spam-Status: Yes
249 $SPAM
250
251If you don't use \"spamc\", use \"spamassassin -P -a\".
252
253A handful of spam does find its way into +inbox. In this case, use
254\\[mh-junk-blacklist] to add a \"blacklist_from\" line to
255~/spamassassin/user_prefs, delete the message, and send the message to the
256Razor, so that others might not see this spam.
257
258Over time, you see some patterns in the blacklisted addresses and can
259replace several lines with wildcards. For example, it is clear that High
260Speed Media is the biggest bunch of jerks on the Net. Here are some of the
261entries I have for them, and the list continues to grow.
262
263 blacklist_from *@*-hsm-*.com
264 blacklist_from *@*182*643*.com
265 blacklist_from *@*antarhsm*.com
266 blacklist_from *@*h*speed*
267 blacklist_from *@*hsm*182*.com
268 blacklist_from *@*hsm*643*.com
269 blacklist_from *@*hsmridi2983cslt227.com
270 blacklist_from *@*list*hsm*.com
271 blacklist_from *@h*s*media*
272 blacklist_from *@hsmdrct.com
273 blacklist_from *@hsmridi2983csltsite.com
274
275The function `mh-spamassassin-identify-spammers' is provided that shows the
276frequency counts of the host and domain names in your blacklist_from
277entries. This can be helpful when editing the blacklist_from entries.
278
279In versions of spamassassin (2.50 and on) that support a Bayesian classifier,
280\\[mh-junk-blacklist] uses the sa-learn program to recategorize the message as
281spam. Neither MH-E, nor spamassassin, rebuilds the database after adding
282words, so you will need to run \"sa-learn --rebuild\" periodically. This can
283be done by adding the following to your crontab:
284
285 0 * * * * sa-learn --rebuild > /dev/null 2>&1"
286 (unless mh-spamassassin-executable 176 (unless mh-spamassassin-executable
287 (error "Couldn't find the spamassassin executable")) 177 (error "Unable to find the spamassassin executable"))
288 (let ((current-folder mh-current-folder) 178 (let ((current-folder mh-current-folder)
289 (msg-file (mh-msg-filename msg mh-current-folder)) 179 (msg-file (mh-msg-filename msg mh-current-folder))
290 (sender)) 180 (sender))
291 (save-excursion 181 (save-excursion
292 (message "Giving this message the Razor...") 182 (message (format "Reporting message %d..." msg))
293 (mh-truncate-log-buffer) 183 (mh-truncate-log-buffer)
294 (call-process mh-spamassassin-executable msg-file mh-log-buffer nil 184 (call-process mh-spamassassin-executable msg-file mh-log-buffer nil
295 "--report" "--remove-from-whitelist") 185 ;;"--report" "--remove-from-whitelist"
186 "-r" "-R") ; spamassassin V2.20
296 (when mh-sa-learn-executable 187 (when mh-sa-learn-executable
297 (message "Recategorizing this message as spam...") 188 (message "Recategorizing this message as spam...")
298 (call-process mh-sa-learn-executable msg-file mh-log-buffer nil 189 (call-process mh-sa-learn-executable msg-file mh-log-buffer nil
299 "--single" "--spam" "--local" "--no-rebuild")) 190 "--single" "--spam" "--local" "--no-rebuild"))
300 (message "Blacklisting address...") 191 (message (format "Blacklisting message %d..." msg))
301 (set-buffer (get-buffer-create mh-temp-buffer)) 192 (set-buffer (get-buffer-create mh-temp-buffer))
302 (erase-buffer) 193 (erase-buffer)
303 (call-process (expand-file-name mh-scan-prog mh-progs) nil t nil 194 (call-process (expand-file-name mh-scan-prog mh-progs) mh-junk-background
195 t nil
304 (format "%s" msg) current-folder 196 (format "%s" msg) current-folder
305 "-format" "%<(mymbox{from})%|%(addr{from})%>") 197 "-format" "%<(mymbox{from})%|%(addr{from})%>")
306 (goto-char (point-min)) 198 (goto-char (point-min))
@@ -308,15 +200,19 @@ be done by adding the following to your crontab:
308 (progn 200 (progn
309 (setq sender (match-string 0)) 201 (setq sender (match-string 0))
310 (mh-spamassassin-add-rule "blacklist_from" sender) 202 (mh-spamassassin-add-rule "blacklist_from" sender)
311 (message "Blacklisting address...done")) 203 (message (format "Blacklisting message %d...done" msg)))
312 (message "Blacklisting address...not done (from my address)"))))) 204 (message (format "Blacklisting message %d...not done (from my address)" msg))))))
313 205
314(defun mh-spamassassin-whitelist (msg) 206(defun mh-spamassassin-whitelist (msg)
315 "Whitelist MSG. 207 "Whitelist MSG with SpamAssassin.
316Add a whitelist_from rule to the ~/.spamassassin/user_prefs file. If sa-learn 208
317is available, then the message is recategorized as ham." 209The \\[mh-junk-whitelist] command adds a `whitelist_from' rule to the
210`~/.spamassassin/user_prefs' file. If the `sa-learn' command is available, the
211message is also recategorized as ham.
212
213See `mh-spamassassin-blacklist' for more information."
318 (unless mh-spamassassin-executable 214 (unless mh-spamassassin-executable
319 (error "Couldn't find the spamassassin executable")) 215 (error "Unable to find the spamassassin executable"))
320 (let ((msg-file (mh-msg-filename msg mh-current-folder)) 216 (let ((msg-file (mh-msg-filename msg mh-current-folder))
321 (show-buffer (get-buffer mh-show-buffer)) 217 (show-buffer (get-buffer mh-show-buffer))
322 from) 218 from)
@@ -325,7 +221,8 @@ is available, then the message is recategorized as ham."
325 (erase-buffer) 221 (erase-buffer)
326 (message "Removing spamassassin markup from message...") 222 (message "Removing spamassassin markup from message...")
327 (call-process mh-spamassassin-executable msg-file mh-temp-buffer nil 223 (call-process mh-spamassassin-executable msg-file mh-temp-buffer nil
328 "--remove-markup") 224 ;; "--remove-markup"
225 "-d") ; spamassassin V2.20
329 (if show-buffer 226 (if show-buffer
330 (kill-buffer show-buffer)) 227 (kill-buffer show-buffer))
331 (write-file msg-file) 228 (write-file msg-file)
@@ -333,15 +230,17 @@ is available, then the message is recategorized as ham."
333 (message "Recategorizing this message as ham...") 230 (message "Recategorizing this message as ham...")
334 (call-process mh-sa-learn-executable msg-file mh-temp-buffer nil 231 (call-process mh-sa-learn-executable msg-file mh-temp-buffer nil
335 "--single" "--ham" "--local --no-rebuild")) 232 "--single" "--ham" "--local --no-rebuild"))
336 (message "Whitelisting address...") 233 (message (format "Whitelisting message %d..." msg))
337 (setq from (car (ietf-drums-parse-address (mh-get-header-field "From:")))) 234 (setq from
235 (car (mh-funcall-if-exists
236 ietf-drums-parse-address (mh-get-header-field "From:"))))
338 (kill-buffer nil) 237 (kill-buffer nil)
339 (unless (equal from "") 238 (unless (or (null from) (equal from ""))
340 (mh-spamassassin-add-rule "whitelist_from" from)) 239 (mh-spamassassin-add-rule "whitelist_from" from))
341 (message "Whitelisting address...done")))) 240 (message (format "Whitelisting message %d...done" msg)))))
342 241
343(defun mh-spamassassin-add-rule (rule body) 242(defun mh-spamassassin-add-rule (rule body)
344 "Add a new rule to ~/.spamassassin/user_prefs. 243 "Add a new rule to `~/.spamassassin/user_prefs'.
345The name of the rule is RULE and its body is BODY." 244The name of the rule is RULE and its body is BODY."
346 (save-window-excursion 245 (save-window-excursion
347 (let* ((line (format "%s\t%s\n" rule body)) 246 (let* ((line (format "%s\t%s\n" rule body))
@@ -358,15 +257,15 @@ The name of the rule is RULE and its body is BODY."
358 (kill-buffer nil))))) 257 (kill-buffer nil)))))
359 258
360(defun mh-spamassassin-identify-spammers () 259(defun mh-spamassassin-identify-spammers ()
361 "Identifies spammers who are repeat offenders. 260 "Identify spammers who are repeat offenders.
362 261
363For each blacklist_from entry from the last blank line of 262This function displays a frequency count of the hosts and domains in the
364~/.spamassassin/user_prefs to the end of the file, a list of host and domain 263`blacklist_from' entries from the last blank line in
365names along with their frequency counts is displayed. This information can be 264`~/.spamassassin/user_prefs' to the end of the file. This information can be
366used to replace multiple blacklist_from entries with a single wildcard entry 265used so that you can replace multiple `blacklist_from' entries with a single
367such as: 266wildcard entry such as:
368 267
369 blacklist_from *@*amazingoffersdirect2u.com" 268 blacklist_from *@*amazingoffersdirect2u.com"
370 (interactive) 269 (interactive)
371 (let* ((file (expand-file-name "~/.spamassassin/user_prefs")) 270 (let* ((file (expand-file-name "~/.spamassassin/user_prefs"))
372 (domains (make-hash-table :test 'equal))) 271 (domains (make-hash-table :test 'equal)))
@@ -385,7 +284,7 @@ such as:
385 ;; Add counts for each host and domain part. 284 ;; Add counts for each host and domain part.
386 (while host 285 (while host
387 (setq value (gethash (car host) domains)) 286 (setq value (gethash (car host) domains))
388 (puthash (car host) (1+ (if (not value) 0 value)) domains) 287 (setf (gethash (car host) domains) (1+ (if (not value) 0 value)))
389 (setq host (cdr host)))))) 288 (setq host (cdr host))))))
390 289
391 ;; Output 290 ;; Output
@@ -400,6 +299,121 @@ such as:
400 (reverse-region (point-min) (point-max)) 299 (reverse-region (point-min) (point-max))
401 (goto-char (point-min)))) 300 (goto-char (point-min))))
402 301
302
303
304;; Bogofilter Interface
305
306(defvar mh-bogofilter-executable (executable-find "bogofilter"))
307
308(defun mh-bogofilter-blacklist (msg)
309 "Blacklist MSG with Bogofilter.
310
311Bogofilter is a Bayesian spam filtering program. Get it from your local
312distribution or from http://bogofilter.sourceforge.net/.
313
314Bogofilter is taught by running:
315
316 bogofilter -n < good-message
317
318on every good message, and
319
320 bogofilter -s < spam-message
321
322on every spam message. This is called a full training; three other
323training methods are described in the FAQ that is distributed with bogofilter.
324Note that most Bayesian filters need 1000 to 5000 of each type of message to
325start doing a good job.
326
327To use Bogofilter, add the following recipes to `.procmailrc':
328
329 MAILDIR=$HOME/`mhparam Path`
330
331 # Fight spam with Bogofilter.
332 :0fw
333 | bogofilter -3 -e -p
334
335 :0:
336 * ^X-Bogosity: Yes, tests=bogofilter
337 spam/.
338
339 :0:
340 * ^X-Bogosity: Unsure, tests=bogofilter
341 spam/unsure/.
342
343If Bogofilter classifies a message incorrectly, or is unsure, you can use the
344MH-E commands \\[mh-junk-blacklist] and \\[mh-junk-whitelist] to update
345Bogofilter's training.
346
347The \"Bogofilter FAQ\" suggests that you run the following
348occasionally to shrink the database:
349
350 bogoutil -d wordlist.db | bogoutil -l wordlist.db.new
351 mv wordlist.db wordlist.db.prv
352 mv wordlist.db.new wordlist.db
353
354The \"Bogofilter tuning HOWTO\" describes how you can fine-tune Bogofilter."
355 (unless mh-bogofilter-executable
356 (error "Unable to find the bogofilter executable"))
357 (let ((msg-file (mh-msg-filename msg mh-current-folder)))
358 (call-process mh-bogofilter-executable msg-file mh-junk-background
359 nil "-s")))
360
361(defun mh-bogofilter-whitelist (msg)
362 "Whitelist MSG with Bogofilter.
363
364See `mh-bogofilter-blacklist' for more information."
365 (unless mh-bogofilter-executable
366 (error "Unable to find the bogofilter executable"))
367 (let ((msg-file (mh-msg-filename msg mh-current-folder)))
368 (call-process mh-bogofilter-executable msg-file mh-junk-background
369 nil "-n")))
370
371
372
373;; Spamprobe Interface
374
375(defvar mh-spamprobe-executable (executable-find "spamprobe"))
376
377(defun mh-spamprobe-blacklist (msg)
378 "Blacklist MSG with SpamProbe.
379
380SpamProbe is a Bayesian spam filtering program. Get it from your local
381distribution or from http://spamprobe.sourceforge.net.
382
383To use SpamProbe, add the following recipes to `.procmailrc':
384
385 MAILDIR=$HOME/`mhparam Path`
386
387 # Fight spam with SpamProbe.
388 :0
389 SCORE=| spamprobe receive
390
391 :0 wf
392 | formail -I \"X-SpamProbe: $SCORE\"
393
394 :0:
395 *^X-SpamProbe: SPAM
396 spam/.
397
398If SpamProbe classifies a message incorrectly, you can use the MH-E commands
399\\[mh-junk-blacklist] and \\[mh-junk-whitelist] to update SpamProbe's
400training."
401 (unless mh-spamprobe-executable
402 (error "Unable to find the spamprobe executable"))
403 (let ((msg-file (mh-msg-filename msg mh-current-folder)))
404 (call-process mh-spamprobe-executable msg-file mh-junk-background
405 nil "spam")))
406
407(defun mh-spamprobe-whitelist (msg)
408 "Whitelist MSG with SpamProbe.
409
410See `mh-spamprobe-blacklist' for more information."
411 (unless mh-spamprobe-executable
412 (error "Unable to find the spamprobe executable"))
413 (let ((msg-file (mh-msg-filename msg mh-current-folder)))
414 (call-process mh-spamprobe-executable msg-file mh-junk-background
415 nil "good")))
416
403(provide 'mh-junk) 417(provide 'mh-junk)
404 418
405;;; Local Variables: 419;;; Local Variables:
diff --git a/lisp/mh-e/mh-loaddefs.el b/lisp/mh-e/mh-loaddefs.el
index a5578760845..43119b62be0 100644
--- a/lisp/mh-e/mh-loaddefs.el
+++ b/lisp/mh-e/mh-loaddefs.el
@@ -11,22 +11,24 @@
11;;;;;; mh-beginning-of-word mh-complete-word mh-open-line mh-fully-kill-draft 11;;;;;; mh-beginning-of-word mh-complete-word mh-open-line mh-fully-kill-draft
12;;;;;; mh-yank-cur-msg mh-insert-letter mh-send-letter mh-insert-auto-fields 12;;;;;; mh-yank-cur-msg mh-insert-letter mh-send-letter mh-insert-auto-fields
13;;;;;; mh-check-whom mh-insert-signature mh-to-fcc mh-to-field mh-fill-paragraph-function 13;;;;;; mh-check-whom 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 14;;;;;; mh-get-header-field mh-send-other-window mh-send mh-reply
15;;;;;; mh-extract-rejected-mail mh-edit-again) "mh-comp" "mh-comp.el" 15;;;;;; mh-redistribute mh-forward mh-extract-rejected-mail mh-edit-again)
16;;;;;; (16625 53169)) 16;;;;;; "mh-comp" "mh-comp.el" (16665 55172))
17;;; Generated autoloads from mh-comp.el 17;;; Generated autoloads from mh-comp.el
18 18
19(autoload (quote mh-edit-again) "mh-comp" "\ 19(autoload (quote mh-edit-again) "mh-comp" "\
20Clean up a draft or a message MSG previously sent and make it resendable. 20Clean up a draft or a message MSG previously sent and make it resendable.
21Default is the current message. 21Default is the current message.
22The variable `mh-new-draft-cleaned-headers' specifies the headers to remove. 22The variable `mh-new-draft-cleaned-headers' specifies the headers to remove.
23See also documentation for `\\[mh-send]' function." t nil) 23
24See also `mh-send'." t nil)
24 25
25(autoload (quote mh-extract-rejected-mail) "mh-comp" "\ 26(autoload (quote mh-extract-rejected-mail) "mh-comp" "\
26Extract message MSG returned by the mail system and make it resendable. 27Extract message MSG returned by the mail system and make it resendable.
27Default is the current message. The variable `mh-new-draft-cleaned-headers' 28Default is the current message. The variable `mh-new-draft-cleaned-headers'
28gives the headers to clean out of the original message. 29gives the headers to clean out of the original message.
29See also documentation for `\\[mh-send]' function." t nil) 30
31See also `mh-send'." t nil)
30 32
31(autoload (quote mh-forward) "mh-comp" "\ 33(autoload (quote mh-forward) "mh-comp" "\
32Forward messages to the recipients TO and CC. 34Forward messages to the recipients TO and CC.
@@ -36,7 +38,7 @@ Default is the displayed message.
36Check the documentation of `mh-interactive-range' to see how RANGE is read in 38Check the documentation of `mh-interactive-range' to see how RANGE is read in
37interactive use. 39interactive use.
38 40
39See also documentation for `\\[mh-send]' function." t nil) 41See also `mh-send'." t nil)
40 42
41(autoload (quote mh-redistribute) "mh-comp" "\ 43(autoload (quote mh-redistribute) "mh-comp" "\
42Redistribute displayed message to recipients TO and CC. 44Redistribute displayed message to recipients TO and CC.
@@ -55,11 +57,12 @@ to reply to:
55If optional prefix argument INCLUDEP provided, then include the message 57If optional prefix argument INCLUDEP provided, then include the message
56in the reply using filter `mhl.reply' in your MH directory. 58in the reply using filter `mhl.reply' in your MH directory.
57If the file named by `mh-repl-formfile' exists, it is used as a skeleton 59If the file named by `mh-repl-formfile' exists, it is used as a skeleton
58for the reply. See also documentation for `\\[mh-send]' function." t nil) 60for the reply.
61
62See also `mh-send'." t nil)
59 63
60(autoload (quote mh-send) "mh-comp" "\ 64(autoload (quote mh-send) "mh-comp" "\
61Compose and send a letter. 65Compose and send a letter.
62
63Do not call this function from outside MH-E; use \\[mh-smail] instead. 66Do not call this function from outside MH-E; use \\[mh-smail] instead.
64 67
65The file named by `mh-comp-formfile' will be used as the form. 68The file named by `mh-comp-formfile' will be used as the form.
@@ -70,7 +73,6 @@ passed three arguments: TO, CC, and SUBJECT." t nil)
70 73
71(autoload (quote mh-send-other-window) "mh-comp" "\ 74(autoload (quote mh-send-other-window) "mh-comp" "\
72Compose and send a letter in another window. 75Compose and send a letter in another window.
73
74Do not call this function from outside MH-E; use \\[mh-smail-other-window] 76Do not call this function from outside MH-E; use \\[mh-smail-other-window]
75instead. 77instead.
76 78
@@ -80,6 +82,11 @@ details.
80If `mh-compose-letter-function' is defined, it is called on the draft and 82If `mh-compose-letter-function' is defined, it is called on the draft and
81passed three arguments: TO, CC, and SUBJECT." t nil) 83passed three arguments: TO, CC, and SUBJECT." t nil)
82 84
85(autoload (quote mh-get-header-field) "mh-comp" "\
86Find and return the body of FIELD in the mail header.
87Returns the empty string if the field is not in the header of the
88current buffer." nil nil)
89
83(autoload (quote mh-fill-paragraph-function) "mh-comp" "\ 90(autoload (quote mh-fill-paragraph-function) "mh-comp" "\
84Fill paragraph at or after point. 91Fill paragraph at or after point.
85Prefix ARG means justify as well. This function enables `fill-paragraph' to 92Prefix ARG means justify as well. This function enables `fill-paragraph' to
@@ -96,9 +103,12 @@ Insert an Fcc: FOLDER field in the current message.
96Prompt for the field name with a completion list of the current folders." t nil) 103Prompt for the field name with a completion list of the current folders." t nil)
97 104
98(autoload (quote mh-insert-signature) "mh-comp" "\ 105(autoload (quote mh-insert-signature) "mh-comp" "\
99Insert the file named by `mh-signature-file-name' at point. 106Insert the signature specified by `mh-signature-file-name' or FILE at point.
107A signature separator (`-- ') will be added if the signature block does not
108contain one and `mh-signature-separator-flag' is on.
100The value of `mh-letter-insert-signature-hook' is a list of functions to be 109The value of `mh-letter-insert-signature-hook' is a list of functions to be
101called, with no arguments, before the signature is actually inserted." t nil) 110called, with no arguments, after the signature is inserted.
111The signature can also be inserted with `mh-identity-list'." t nil)
102 112
103(autoload (quote mh-check-whom) "mh-comp" "\ 113(autoload (quote mh-check-whom) "mh-comp" "\
104Verify recipients of the current letter, showing expansion of any aliases." t nil) 114Verify recipients of the current letter, showing expansion of any aliases." t nil)
@@ -109,7 +119,9 @@ Sets buffer-local `mh-insert-auto-fields-done-local' when done and inserted
109something. If NON-INTERACTIVE is non-nil, do not be verbose and only 119something. If NON-INTERACTIVE is non-nil, do not be verbose and only
110attempt matches if `mh-insert-auto-fields-done-local' is nil. 120attempt matches if `mh-insert-auto-fields-done-local' is nil.
111 121
112An `identity' entry is skipped if one was already entered manually." t nil) 122An `identity' entry is skipped if one was already entered manually.
123
124Return t if fields added; otherwise return nil." t nil)
113 125
114(autoload (quote mh-send-letter) "mh-comp" "\ 126(autoload (quote mh-send-letter) "mh-comp" "\
115Send the draft letter in the current buffer. 127Send the draft letter in the current buffer.
@@ -117,13 +129,12 @@ If optional prefix argument ARG is provided, monitor delivery.
117The value of `mh-before-send-letter-hook' is a list of functions to be called, 129The value of `mh-before-send-letter-hook' is a list of functions to be called,
118with no arguments, before doing anything. 130with no arguments, before doing anything.
119Run `\\[mh-edit-mhn]' if mhn directives are present; otherwise 131Run `\\[mh-edit-mhn]' if mhn directives are present; otherwise
120run `\\[mh-mml-to-mime]' if mml directives are present. 132run `\\[mh-mml-to-mime]' if mml directives are present." t nil)
121Insert X-Mailer field if variable `mh-insert-x-mailer-flag' is set.
122Insert X-Face field if the file specified by `mh-x-face-file' exists." t nil)
123 133
124(autoload (quote mh-insert-letter) "mh-comp" "\ 134(autoload (quote mh-insert-letter) "mh-comp" "\
125Insert a message into the current letter. 135Insert a message into the current letter.
126Removes the header fields according to the variable `mh-invisible-headers'. 136Removes the header fields according to the variable
137`mh-invisible-header-fields-compiled'.
127Prefixes each non-blank line with `mh-ins-buf-prefix', unless 138Prefixes each non-blank line with `mh-ins-buf-prefix', unless
128`mh-yank-from-start-of-msg' is set for supercite in which case supercite is 139`mh-yank-from-start-of-msg' is set for supercite in which case supercite is
129used to format the message. 140used to format the message.
@@ -168,42 +179,11 @@ If we are at the first header field go to the start of the message body." t nil)
168 179
169;;;*** 180;;;***
170 181
171;;;### (autoloads (mh-customize) "mh-customize" "mh-customize.el"
172;;;;;; (16625 53481))
173;;; Generated autoloads from mh-customize.el
174
175(autoload (quote mh-customize) "mh-customize" "\
176Customize MH-E variables.
177With optional argument DELETE-OTHER-WINDOWS-FLAG, other windows in the frame
178are removed." t nil)
179
180;;;***
181
182;;;### (autoloads (mh-goto-cur-msg mh-update-sequences mh-folder-line-matches-show-buffer-p)
183;;;;;; "mh-e" "mh-e.el" (16627 22341))
184;;; Generated autoloads from mh-e.el
185
186(autoload (quote mh-folder-line-matches-show-buffer-p) "mh-e" "\
187Return t if the message under point in folder-mode is in the show buffer.
188Return nil in any other circumstance (no message under point, no show buffer,
189the message in the show buffer doesn't match." nil nil)
190
191(autoload (quote mh-update-sequences) "mh-e" "\
192Update MH's Unseen-Sequence and current folder and message.
193Flush MH-E's state out to MH. The message at the cursor becomes current." t nil)
194
195(autoload (quote mh-goto-cur-msg) "mh-e" "\
196Position the cursor at the current message.
197When optional argument MINIMAL-CHANGES-FLAG is non-nil, the function doesn't
198recenter the folder buffer." nil nil)
199
200;;;***
201
202;;;### (autoloads (mh-prefix-help mh-help mh-ephem-message mh-store-buffer 182;;;### (autoloads (mh-prefix-help mh-help mh-ephem-message mh-store-buffer
203;;;;;; mh-store-msg mh-undo-folder mh-sort-folder mh-print-msg mh-page-digest-backwards 183;;;;;; mh-store-msg mh-undo-folder mh-sort-folder mh-page-digest-backwards
204;;;;;; mh-page-digest mh-pipe-msg mh-pack-folder mh-list-folders 184;;;;;; mh-page-digest mh-pipe-msg mh-pack-folder mh-list-folders
205;;;;;; mh-kill-folder mh-copy-msg mh-burst-digest) "mh-funcs" "mh-funcs.el" 185;;;;;; mh-kill-folder mh-copy-msg mh-burst-digest) "mh-funcs" "mh-funcs.el"
206;;;;;; (16625 54011)) 186;;;;;; (16671 49652))
207;;; Generated autoloads from mh-funcs.el 187;;; Generated autoloads from mh-funcs.el
208 188
209(autoload (quote mh-burst-digest) "mh-funcs" "\ 189(autoload (quote mh-burst-digest) "mh-funcs" "\
@@ -245,15 +225,6 @@ Advance displayed message to next digested message." t nil)
245(autoload (quote mh-page-digest-backwards) "mh-funcs" "\ 225(autoload (quote mh-page-digest-backwards) "mh-funcs" "\
246Back up displayed message to previous digested message." t nil) 226Back up displayed message to previous digested message." t nil)
247 227
248(autoload (quote mh-print-msg) "mh-funcs" "\
249Print RANGE on printer.
250
251Check the documentation of `mh-interactive-range' to see how RANGE is read in
252interactive use.
253
254The variable `mh-lpr-command-format' is used to generate the print command.
255The messages are formatted by mhl. See the variable `mhl-formfile'." t nil)
256
257(autoload (quote mh-sort-folder) "mh-funcs" "\ 228(autoload (quote mh-sort-folder) "mh-funcs" "\
258Sort the messages in the current folder by date. 229Sort the messages in the current folder by date.
259Calls the MH program sortm to do the work. 230Calls the MH program sortm to do the work.
@@ -261,8 +232,7 @@ The arguments in the list `mh-sortm-args' are passed to sortm if the optional
261argument EXTRA-ARGS is given." t nil) 232argument EXTRA-ARGS is given." t nil)
262 233
263(autoload (quote mh-undo-folder) "mh-funcs" "\ 234(autoload (quote mh-undo-folder) "mh-funcs" "\
264Undo all pending deletes and refiles in current folder. 235Undo all pending deletes and refiles in current folder." t nil)
265Argument IGNORE is deprecated." t nil)
266 236
267(autoload (quote mh-store-msg) "mh-funcs" "\ 237(autoload (quote mh-store-msg) "mh-funcs" "\
268Store the file(s) contained in the current message into DIRECTORY. 238Store the file(s) contained in the current message into DIRECTORY.
@@ -280,19 +250,24 @@ Default directory is the last directory used, or initially the value of
280Display STRING in the minibuffer momentarily." nil nil) 250Display STRING in the minibuffer momentarily." nil nil)
281 251
282(autoload (quote mh-help) "mh-funcs" "\ 252(autoload (quote mh-help) "mh-funcs" "\
283Display cheat sheet for the MH-Folder commands in minibuffer." t nil) 253Display cheat sheet for the MH-E commands." t nil)
284 254
285(autoload (quote mh-prefix-help) "mh-funcs" "\ 255(autoload (quote mh-prefix-help) "mh-funcs" "\
286Display cheat sheet for the commands of the current prefix in minibuffer." t nil) 256Display cheat sheet for the commands of the current prefix in minibuffer." t nil)
287 257
288;;;*** 258;;;***
289 259
290;;;### (autoloads (mh-insert-identity mh-identity-list-set mh-identity-make-menu) 260;;;### (autoloads (mh-identity-handler-bottom mh-identity-handler-top
291;;;;;; "mh-identity" "mh-identity.el" (16625 54171)) 261;;;;;; mh-identity-insert-attribution-verb mh-identity-handler-attribution-verb
262;;;;;; mh-identity-handler-signature mh-identity-handler-gpg-identity
263;;;;;; mh-insert-identity mh-identity-list-set mh-identity-make-menu)
264;;;;;; "mh-identity" "mh-identity.el" (16665 55172))
292;;; Generated autoloads from mh-identity.el 265;;; Generated autoloads from mh-identity.el
293 266
294(autoload (quote mh-identity-make-menu) "mh-identity" "\ 267(autoload (quote mh-identity-make-menu) "mh-identity" "\
295Build (or rebuild) the Identity menu (e.g. after the list is modified)." nil nil) 268Build the Identity menu.
269This should be called any time `mh-identity-list' or `mh-auto-fields-list'
270change." nil nil)
296 271
297(autoload (quote mh-identity-list-set) "mh-identity" "\ 272(autoload (quote mh-identity-list-set) "mh-identity" "\
298Update the `mh-identity-list' variable, and rebuild the menu. 273Update the `mh-identity-list' variable, and rebuild the menu.
@@ -304,10 +279,35 @@ customization). This is called after 'customize is used to alter
304Insert proper fields for given IDENTITY. 279Insert proper fields for given IDENTITY.
305Edit the `mh-identity-list' variable to define identity." t nil) 280Edit the `mh-identity-list' variable to define identity." t nil)
306 281
282(autoload (quote mh-identity-handler-gpg-identity) "mh-identity" "\
283For FIELD \"pgg-default-user-id\", process for ACTION 'remove or 'add.
284The buffer-local variable `mh-identity-pgg-default-user-id' is set to VALUE
285when action 'add is selected." nil nil)
286
287(autoload (quote mh-identity-handler-signature) "mh-identity" "\
288For FIELD \"signature\", process headers for ACTION 'remove or 'add.
289The VALUE is added." nil nil)
290
291(autoload (quote mh-identity-handler-attribution-verb) "mh-identity" "\
292For FIELD \"attribution_verb\", process headers for ACTION 'remove or 'add.
293The VALUE is added." nil nil)
294
295(autoload (quote mh-identity-insert-attribution-verb) "mh-identity" "\
296Insert VALUE as attribution verb, setting up delimiting markers.
297If VALUE is nil, use `mh-extract-from-attribution-verb'." nil nil)
298
299(autoload (quote mh-identity-handler-top) "mh-identity" "\
300For FIELD, process mh-identity headers for ACTION 'remove or 'add.
301If the field wasn't present, the VALUE is added at the top of the header." nil nil)
302
303(autoload (quote mh-identity-handler-bottom) "mh-identity" "\
304For FIELD, process mh-identity headers for ACTION 'remove or 'add.
305If the field wasn't present, the VALUE is added at the bottom of the header." nil nil)
306
307;;;*** 307;;;***
308 308
309;;;### (autoloads (mh-inc-spool-list-set) "mh-inc" "mh-inc.el" (16625 309;;;### (autoloads (mh-inc-spool-list-set) "mh-inc" "mh-inc.el" (16671
310;;;;;; 54212)) 310;;;;;; 49652))
311;;; Generated autoloads from mh-inc.el 311;;; Generated autoloads from mh-inc.el
312 312
313(autoload (quote mh-inc-spool-list-set) "mh-inc" "\ 313(autoload (quote mh-inc-spool-list-set) "mh-inc" "\
@@ -319,14 +319,14 @@ This is called after 'customize is used to alter `mh-inc-spool-list'." nil nil)
319 319
320;;;### (autoloads (mh-index-choose mh-namazu-execute-search mh-swish++-execute-search 320;;;### (autoloads (mh-index-choose mh-namazu-execute-search mh-swish++-execute-search
321;;;;;; mh-swish-execute-search mh-index-ticked-messages mh-index-new-messages 321;;;;;; mh-swish-execute-search mh-index-ticked-messages mh-index-new-messages
322;;;;;; mh-index-sequenced-messages mh-glimpse-execute-search mh-index-delete-from-sequence 322;;;;;; mh-index-sequenced-messages mh-index-delete-from-sequence
323;;;;;; mh-index-add-to-sequence mh-index-execute-commands mh-index-update-unseen 323;;;;;; mh-index-add-to-sequence mh-index-execute-commands mh-index-visit-folder
324;;;;;; mh-index-visit-folder mh-index-delete-folder-headers mh-index-group-by-folder 324;;;;;; mh-index-delete-folder-headers mh-index-group-by-folder mh-index-create-imenu-index
325;;;;;; mh-index-insert-folder-headers mh-index-previous-folder mh-index-next-folder 325;;;;;; mh-index-insert-folder-headers mh-index-previous-folder mh-index-next-folder
326;;;;;; mh-index-parse-search-regexp mh-index-do-search mh-index-p 326;;;;;; mh-index-parse-search-regexp mh-index-do-search mh-index-p
327;;;;;; mh-index-read-data mh-index-search mh-index-create-sequences 327;;;;;; mh-index-read-data mh-index-search mh-index-create-sequences
328;;;;;; mh-create-sequence-map mh-index-update-maps) "mh-index" "mh-index.el" 328;;;;;; mh-create-sequence-map mh-index-update-maps) "mh-index" "mh-index.el"
329;;;;;; (16625 54348)) 329;;;;;; (16665 55172))
330;;; Generated autoloads from mh-index.el 330;;; Generated autoloads from mh-index.el
331 331
332(autoload (quote mh-index-update-maps) "mh-index" "\ 332(autoload (quote mh-index-update-maps) "mh-index" "\
@@ -367,7 +367,6 @@ index for each program:
367 - `mh-swish-execute-search' 367 - `mh-swish-execute-search'
368 - `mh-mairix-execute-search' 368 - `mh-mairix-execute-search'
369 - `mh-namazu-execute-search' 369 - `mh-namazu-execute-search'
370 - `mh-glimpse-execute-search'
371 370
372If none of these programs are present then we use pick. If desired grep can be 371If none of these programs are present then we use pick. If desired grep can be
373used instead. Details about these methods can be found in: 372used instead. Details about these methods can be found in:
@@ -411,6 +410,9 @@ Jump to the previous folder marker." t nil)
411(autoload (quote mh-index-insert-folder-headers) "mh-index" "\ 410(autoload (quote mh-index-insert-folder-headers) "mh-index" "\
412Annotate the search results with original folder names." nil nil) 411Annotate the search results with original folder names." nil nil)
413 412
413(autoload (quote mh-index-create-imenu-index) "mh-index" "\
414Create alist of folder names and positions in index folder buffers." nil nil)
415
414(autoload (quote mh-index-group-by-folder) "mh-index" "\ 416(autoload (quote mh-index-group-by-folder) "mh-index" "\
415Partition the messages based on source folder. 417Partition the messages based on source folder.
416Returns an alist with the the folder names in the car and the cdr being the 418Returns an alist with the the folder names in the car and the cdr being the
@@ -422,10 +424,6 @@ Delete the folder headers." nil nil)
422(autoload (quote mh-index-visit-folder) "mh-index" "\ 424(autoload (quote mh-index-visit-folder) "mh-index" "\
423Visit original folder from where the message at point was found." t nil) 425Visit original folder from where the message at point was found." t nil)
424 426
425(autoload (quote mh-index-update-unseen) "mh-index" "\
426Remove counterpart of MSG in source folder from `mh-unseen-seq'.
427Also `mh-update-unseen' is called in the original folder, if we have it open." nil nil)
428
429(autoload (quote mh-index-execute-commands) "mh-index" "\ 427(autoload (quote mh-index-execute-commands) "mh-index" "\
430Delete/refile the actual messages. 428Delete/refile the actual messages.
431The copies in the searched folder are then deleted/refiled to get the desired 429The copies in the searched folder are then deleted/refiled to get the desired
@@ -442,62 +440,25 @@ Delete from SEQ the messages in MSGS.
442This function updates the source folder sequences. Also makes an attempt to 440This function updates the source folder sequences. Also makes an attempt to
443update the source folder buffer if present." nil nil) 441update the source folder buffer if present." nil nil)
444 442
445(autoload (quote mh-glimpse-execute-search) "mh-index" "\
446Execute glimpse and read the results.
447
448In the examples below, replace /home/user/Mail with the path to your MH
449directory.
450
451First create the directory /home/user/Mail/.glimpse. Then create the file
452/home/user/Mail/.glimpse/.glimpse_exclude with the following contents:
453
454 */.*
455 */#*
456 */,*
457 */*~
458 ^/home/user/Mail/.glimpse
459 ^/home/user/Mail/mhe-index
460
461If there are any directories you would like to ignore, append lines like the
462following to .glimpse_exclude:
463
464 ^/home/user/Mail/scripts
465
466You do not want to index the folders that hold the results of your searches
467since they tend to be ephemeral and the original messages are indexed anyway.
468The configuration file above assumes that the results are found in sub-folders
469of `mh-index-folder' which is +mhe-index by default.
470
471Use the following command line to generate the glimpse index. Run this
472daily from cron:
473
474 glimpseindex -H /home/user/Mail/.glimpse /home/user/Mail
475
476FOLDER-PATH is the directory in which SEARCH-REGEXP is used to search." nil nil)
477
478(autoload (quote mh-index-sequenced-messages) "mh-index" "\ 443(autoload (quote mh-index-sequenced-messages) "mh-index" "\
479Display messages from FOLDERS in SEQUENCE. 444Display messages from FOLDERS in SEQUENCE.
480By default the folders specified by `mh-index-new-messages-folders' are 445All messages in the sequence you provide from the folders in
481searched. With a prefix argument, enter a space-separated list of folders, or 446`mh-index-new-messages-folders' are listed. With a prefix argument, enter a
482nothing to search all folders. 447space-separated list of folders, or nothing to search all folders." t nil)
483
484Argument SEQUENCE defaults to `mh-unseen-seq' and is the sequence that the
485function searches for in each of the FOLDERS. With a prefix argument, enter a
486sequence to use." t nil)
487 448
488(autoload (quote mh-index-new-messages) "mh-index" "\ 449(autoload (quote mh-index-new-messages) "mh-index" "\
489Display unseen messages. 450Display unseen messages.
490All messages in the `unseen' sequence from FOLDERS are displayed. 451If you use a program such as `procmail' to use `rcvstore' to file your
491By default the folders specified by `mh-index-new-messages-folders' 452incoming mail automatically, you can display new, unseen, messages using this
492are searched. With a prefix argument, enter a space-separated list of 453command. All messages in the `unseen' sequence from the folders in
493folders, or nothing to search all folders." t nil) 454`mh-index-new-messages-folders' are listed. With a prefix argument, enter a
455space-separated list of FOLDERS, or nothing to search all folders." t nil)
494 456
495(autoload (quote mh-index-ticked-messages) "mh-index" "\ 457(autoload (quote mh-index-ticked-messages) "mh-index" "\
496Display ticked messages. 458Display ticked messages.
497All messages in the `tick' sequence from FOLDERS are displayed. 459All messages in `mh-tick-seq' from the folders in
498By default the folders specified by `mh-index-ticked-messages-folders' 460`mh-index-ticked-messages-folders' are listed. With a prefix argument, enter a
499are searched. With a prefix argument, enter a space-separated list of 461space-separated list of FOLDERS, or nothing to search all folders." t nil)
500folders, or nothing to search all folders." t nil)
501 462
502(autoload (quote mh-swish-execute-search) "mh-index" "\ 463(autoload (quote mh-swish-execute-search) "mh-index" "\
503Execute swish-e and read the results. 464Execute swish-e and read the results.
@@ -620,54 +581,69 @@ system." nil nil)
620 581
621;;;*** 582;;;***
622 583
584;;;### (autoloads (mh-variants mh-variant-p mh-variant-set) "mh-init"
585;;;;;; "mh-init.el" (16671 49652))
586;;; Generated autoloads from mh-init.el
587
588(autoload (quote mh-variant-set) "mh-init" "\
589Set the MH variant to VARIANT.
590Sets `mh-progs', `mh-lib', `mh-lib-progs' and `mh-flists-present-flag'.
591If the VARIANT is `autodetect', then first try nmh, then MH and finally
592GNU mailutils." t nil)
593
594(autoload (quote mh-variant-p) "mh-init" "\
595Return t if variant is any of VARIANTS.
596Currently known variants are 'mh and 'nmh." nil nil)
597
598(autoload (quote mh-variants) "mh-init" "\
599Return a list of installed variants of MH on the system.
600This function looks for MH in `mh-sys-path', `mh-path' and
601`exec-path'. The format of the list of variants that is returned is described
602by the variable `mh-variants'." nil nil)
603
604;;;***
605
623;;;### (autoloads (mh-junk-whitelist mh-junk-blacklist) "mh-junk" 606;;;### (autoloads (mh-junk-whitelist mh-junk-blacklist) "mh-junk"
624;;;;;; "mh-junk.el" (16625 54386)) 607;;;;;; "mh-junk.el" (16671 49652))
625;;; Generated autoloads from mh-junk.el 608;;; Generated autoloads from mh-junk.el
626 609
627(autoload (quote mh-junk-blacklist) "mh-junk" "\ 610(autoload (quote mh-junk-blacklist) "mh-junk" "\
628Blacklist RANGE as spam. 611Blacklist RANGE as spam.
629 612
630Check the documentation of `mh-interactive-range' to see how RANGE is read in 613This command trains the spam program in use (see the `mh-junk-program' option)
631interactive use. 614with the content of the range (see `mh-interactive-range') and then handles
632 615the message(s) as specified by the `mh-junk-disposition' option.
633First the appropriate function is called depending on the value of
634`mh-junk-choice'. Then if `mh-junk-mail-folder' is a string then the message is
635refiled to that folder. If nil, the message is deleted.
636
637To change the spam program being used, customize `mh-junk-program'. Directly
638setting `mh-junk-choice' is not recommended.
639 616
640The documentation for the following functions describes what setup is needed 617For more information about using your particular spam fighting program, see:
641for the different spam fighting programs:
642 618
619 - `mh-spamassassin-blacklist'
643 - `mh-bogofilter-blacklist' 620 - `mh-bogofilter-blacklist'
644 - `mh-spamprobe-blacklist' 621 - `mh-spamprobe-blacklist'" t nil)
645 - `mh-spamassassin-blacklist'" t nil)
646 622
647(autoload (quote mh-junk-whitelist) "mh-junk" "\ 623(autoload (quote mh-junk-whitelist) "mh-junk" "\
648Whitelist RANGE incorrectly classified as spam. 624Whitelist RANGE as ham.
649 625
650Check the documentation of `mh-interactive-range' to see how RANGE is read in 626This command reclassifies a range of messages (see `mh-interactive-range') as
651interactive use. 627ham if it were incorrectly classified as spam. It then refiles the message
628into the `+inbox' folder.
652 629
653First the appropriate function is called depending on the value of 630The `mh-junk-program' option specifies the spam program in use." t nil)
654`mh-junk-choice'. Then the message is refiled to `mh-inbox'.
655
656To change the spam program being used, customize `mh-junk-program'. Directly
657setting `mh-junk-choice' is not recommended." t nil)
658 631
659;;;*** 632;;;***
660 633
661;;;### (autoloads (mh-mime-inline-part mh-mime-save-part mh-push-button 634;;;### (autoloads (mh-display-with-external-viewer mh-mime-inline-part
662;;;;;; mh-press-button mh-mime-display mh-decode-message-header 635;;;;;; mh-mime-save-part mh-push-button mh-press-button mh-mime-display
663;;;;;; mh-mime-save-parts mh-display-emphasis mh-display-smileys 636;;;;;; mh-decode-message-header mh-mime-save-parts mh-display-emphasis
664;;;;;; mh-add-missing-mime-version-header mh-destroy-postponed-handles 637;;;;;; mh-display-smileys mh-add-missing-mime-version-header mh-destroy-postponed-handles
665;;;;;; mh-mime-cleanup mh-mml-directive-present-p mh-mml-secure-message-encrypt-pgpmime 638;;;;;; mh-mime-cleanup mh-mml-directive-present-p mh-mml-secure-message-signencrypt
666;;;;;; mh-mml-secure-message-sign-pgpmime mh-mml-attach-file mh-mml-forward-message 639;;;;;; mh-mml-secure-message-encrypt mh-mml-secure-message-sign
667;;;;;; mh-mml-to-mime mh-mhn-directive-present-p mh-revert-mhn-edit 640;;;;;; mh-mml-unsecure-message mh-mml-attach-file mh-mml-query-cryptographic-method
668;;;;;; mh-edit-mhn mh-mhn-compose-forw mh-mhn-compose-external-compressed-tar 641;;;;;; mh-mml-forward-message mh-mml-to-mime mh-mhn-directive-present-p
669;;;;;; mh-mhn-compose-anon-ftp mh-mhn-compose-insertion mh-compose-forward 642;;;;;; mh-revert-mhn-edit mh-edit-mhn mh-mhn-compose-forw mh-mhn-compose-external-type
670;;;;;; mh-compose-insertion) "mh-mime" "mh-mime.el" (16625 54523)) 643;;;;;; mh-mhn-compose-external-compressed-tar mh-mhn-compose-anon-ftp
644;;;;;; mh-mhn-compose-insertion mh-file-mime-type mh-have-file-command
645;;;;;; mh-compose-forward mh-compose-insertion) "mh-mime" "mh-mime.el"
646;;;;;; (16665 55171))
671;;; Generated autoloads from mh-mime.el 647;;; Generated autoloads from mh-mime.el
672 648
673(autoload (quote mh-compose-insertion) "mh-mime" "\ 649(autoload (quote mh-compose-insertion) "mh-mime" "\
@@ -686,6 +662,14 @@ come.
686Optional argument MESSAGE is the message to forward. 662Optional argument MESSAGE is the message to forward.
687If any of the optional arguments are absent, they are prompted for." t nil) 663If any of the optional arguments are absent, they are prompted for." t nil)
688 664
665(autoload (quote mh-have-file-command) "mh-mime" "\
666Return t if 'file' command is on the system.
667'file -i' is used to get MIME type of composition insertion." nil nil)
668
669(autoload (quote mh-file-mime-type) "mh-mime" "\
670Return MIME type of FILENAME from file command.
671Returns nil if file command not on system." nil nil)
672
689(autoload (quote mh-mhn-compose-insertion) "mh-mime" "\ 673(autoload (quote mh-mhn-compose-insertion) "mh-mime" "\
690Add a directive to insert a MIME message part from a file. 674Add a directive to insert a MIME message part from a file.
691This is the typical way to insert non-text parts in a message. 675This is the typical way to insert non-text parts in a message.
@@ -718,6 +702,18 @@ DESCRIPTION, a line of text for the Content-description header.
718 702
719See also \\[mh-edit-mhn]." t nil) 703See also \\[mh-edit-mhn]." t nil)
720 704
705(autoload (quote mh-mhn-compose-external-type) "mh-mime" "\
706Add a directive to include a MIME reference to a remote file.
707The file should be available via anonymous ftp. This directive tells MH to
708include a reference to a message/external-body part.
709
710Arguments are ACCESS-TYPE, HOST and FILENAME, which tell where to find the
711file and TYPE which is the MIME Content-Type. Optional arguments include
712DESCRIPTION, a line of text for the Content-description header, ATTRIBUTES,
713EXTRA-PARAMS, and COMMENT.
714
715See also \\[mh-edit-mhn]." t nil)
716
721(autoload (quote mh-mhn-compose-forw) "mh-mime" "\ 717(autoload (quote mh-mhn-compose-forw) "mh-mime" "\
722Add a forw directive to this message, to forward a message with MIME. 718Add a forw directive to this message, to forward a message with MIME.
723This directive tells MH to include the named messages in this one. 719This directive tells MH to include the named messages in this one.
@@ -758,7 +754,9 @@ Undo the effect of \\[mh-edit-mhn] by reverting to the backup file.
758Optional non-nil argument NOCONFIRM means don't ask for confirmation." t nil) 754Optional non-nil argument NOCONFIRM means don't ask for confirmation." t nil)
759 755
760(autoload (quote mh-mhn-directive-present-p) "mh-mime" "\ 756(autoload (quote mh-mhn-directive-present-p) "mh-mime" "\
761Check if the current buffer has text which might be a MHN directive." nil nil) 757Check if the text between BEGIN and END might be a MHN directive.
758The optional argument BEGIN defaults to the beginning of the buffer, while END
759defaults to the the end of the buffer." nil nil)
762 760
763(autoload (quote mh-mml-to-mime) "mh-mime" "\ 761(autoload (quote mh-mml-to-mime) "mh-mime" "\
764Compose MIME message from mml directives. 762Compose MIME message from mml directives.
@@ -770,6 +768,9 @@ Forward a message as attachment.
770The function will prompt the user for a DESCRIPTION, a FOLDER and MESSAGE 768The function will prompt the user for a DESCRIPTION, a FOLDER and MESSAGE
771number." nil nil) 769number." nil nil)
772 770
771(autoload (quote mh-mml-query-cryptographic-method) "mh-mime" "\
772Read the cryptographic method to use." nil nil)
773
773(autoload (quote mh-mml-attach-file) "mh-mime" "\ 774(autoload (quote mh-mml-attach-file) "mh-mime" "\
774Attach a file to the outgoing MIME message. 775Attach a file to the outgoing MIME message.
775The file is not inserted or encoded until you send the message with 776The file is not inserted or encoded until you send the message with
@@ -781,12 +782,18 @@ This is basically `mml-attach-file' from gnus, modified such that a prefix
781argument yields an `inline' disposition and Content-Type is determined 782argument yields an `inline' disposition and Content-Type is determined
782automatically." nil nil) 783automatically." nil nil)
783 784
784(autoload (quote mh-mml-secure-message-sign-pgpmime) "mh-mime" "\ 785(autoload (quote mh-mml-unsecure-message) "mh-mime" "\
785Add directive to encrypt/sign the entire message." t nil) 786Remove any secure message directives.
787The IGNORE argument is not used." t nil)
786 788
787(autoload (quote mh-mml-secure-message-encrypt-pgpmime) "mh-mime" "\ 789(autoload (quote mh-mml-secure-message-sign) "mh-mime" "\
788Add directive to encrypt and sign the entire message. 790Add security directive to sign the entire message using METHOD." t nil)
789If called with a prefix argument DONTSIGN, only encrypt (do NOT sign)." t nil) 791
792(autoload (quote mh-mml-secure-message-encrypt) "mh-mime" "\
793Add security directive to encrypt the entire message using METHOD." t nil)
794
795(autoload (quote mh-mml-secure-message-signencrypt) "mh-mime" "\
796Add security directive to encrypt and sign the entire message using METHOD." t nil)
790 797
791(autoload (quote mh-mml-directive-present-p) "mh-mime" "\ 798(autoload (quote mh-mml-directive-present-p) "mh-mime" "\
792Check if the current buffer has text which may be an MML directive." nil nil) 799Check if the current buffer has text which may be an MML directive." nil nil)
@@ -840,10 +847,13 @@ Save MIME part at point." t nil)
840(autoload (quote mh-mime-inline-part) "mh-mime" "\ 847(autoload (quote mh-mime-inline-part) "mh-mime" "\
841Toggle display of the raw MIME part." t nil) 848Toggle display of the raw MIME part." t nil)
842 849
850(autoload (quote mh-display-with-external-viewer) "mh-mime" "\
851View MIME PART-INDEX externally." t nil)
852
843;;;*** 853;;;***
844 854
845;;;### (autoloads (mh-do-search mh-pick-do-search mh-do-pick-search 855;;;### (autoloads (mh-do-search mh-pick-do-search mh-search-folder)
846;;;;;; mh-search-folder) "mh-pick" "mh-pick.el" (16625 54571)) 856;;;;;; "mh-pick" "mh-pick.el" (16671 49652))
847;;; Generated autoloads from mh-pick.el 857;;; Generated autoloads from mh-pick.el
848 858
849(autoload (quote mh-search-folder) "mh-pick" "\ 859(autoload (quote mh-search-folder) "mh-pick" "\
@@ -853,13 +863,6 @@ Add the messages found to the sequence named `search'.
853Argument WINDOW-CONFIG is the current window configuration and is used when 863Argument WINDOW-CONFIG is the current window configuration and is used when
854the search folder is dismissed." t nil) 864the search folder is dismissed." t nil)
855 865
856(autoload (quote mh-do-pick-search) "mh-pick" "\
857Find messages that match the qualifications in the current pattern buffer.
858Messages are searched for in the folder named in `mh-searching-folder'.
859Add the messages found to the sequence named `search'.
860
861This is a deprecated function and `mh-pick-do-search' should be used instead." t nil)
862
863(autoload (quote mh-pick-do-search) "mh-pick" "\ 866(autoload (quote mh-pick-do-search) "mh-pick" "\
864Find messages that match the qualifications in the current pattern buffer. 867Find messages that match the qualifications in the current pattern buffer.
865Messages are searched for in the folder named in `mh-searching-folder'. 868Messages are searched for in the folder named in `mh-searching-folder'.
@@ -873,19 +876,62 @@ indexing program specified in `mh-index-program' is used." t nil)
873 876
874;;;*** 877;;;***
875 878
879;;;### (autoloads (mh-print-msg mh-ps-print-toggle-mime mh-ps-print-toggle-color
880;;;;;; mh-ps-print-toggle-faces mh-ps-print-msg-show mh-ps-print-msg-file
881;;;;;; mh-ps-print-msg) "mh-print" "mh-print.el" (16671 49652))
882;;; Generated autoloads from mh-print.el
883
884(autoload (quote mh-ps-print-msg) "mh-print" "\
885Print the messages in RANGE.
886
887Check the documentation of `mh-interactive-range' to see how RANGE is read in
888interactive use." t nil)
889
890(autoload (quote mh-ps-print-msg-file) "mh-print" "\
891Print to FILE the messages in RANGE.
892
893Check the documentation of `mh-interactive-range' to see how RANGE is read in
894interactive use." t nil)
895
896(autoload (quote mh-ps-print-msg-show) "mh-print" "\
897Print current show buffer to FILE." t nil)
898
899(autoload (quote mh-ps-print-toggle-faces) "mh-print" "\
900Toggle whether printing is done with faces or not." t nil)
901
902(autoload (quote mh-ps-print-toggle-color) "mh-print" "\
903Toggle whether color is used in printing messages." t nil)
904
905(autoload (quote mh-ps-print-toggle-mime) "mh-print" "\
906Cycle through available choices on how MIME parts should be printed.
907The available settings are:
908 1. Print only inline MIME parts.
909 2. Print all MIME parts.
910 3. Print no MIME parts." t nil)
911
912(autoload (quote mh-print-msg) "mh-print" "\
913Print RANGE on printer.
914
915Check the documentation of `mh-interactive-range' to see how RANGE is read in
916interactive use.
917
918The variable `mh-lpr-command-format' is used to generate the print command.
919The messages are formatted by mhl. See the variable `mhl-formfile'." t nil)
920
921;;;***
922
876;;;### (autoloads (mh-narrow-to-tick mh-toggle-tick mh-thread-refile 923;;;### (autoloads (mh-narrow-to-tick mh-toggle-tick mh-thread-refile
877;;;;;; mh-thread-delete mh-thread-ancestor mh-thread-previous-sibling 924;;;;;; mh-thread-delete mh-thread-ancestor mh-thread-previous-sibling
878;;;;;; mh-thread-next-sibling mh-thread-forget-message mh-toggle-threads 925;;;;;; mh-thread-next-sibling mh-thread-forget-message mh-toggle-threads
879;;;;;; mh-thread-add-spaces mh-thread-update-scan-line-map mh-thread-inc 926;;;;;; mh-thread-add-spaces mh-thread-update-scan-line-map mh-thread-inc
880;;;;;; mh-delete-subject-or-thread mh-delete-subject mh-narrow-to-range 927;;;;;; mh-delete-subject-or-thread mh-delete-subject mh-narrow-to-range
881;;;;;; mh-narrow-to-to mh-narrow-to-cc mh-narrow-to-from mh-narrow-to-subject 928;;;;;; mh-narrow-to-to mh-narrow-to-cc mh-narrow-to-from mh-narrow-to-subject
882;;;;;; mh-region-to-msg-list mh-interactive-range mh-range-to-msg-list 929;;;;;; mh-interactive-range mh-range-to-msg-list mh-iterate-on-range
883;;;;;; mh-iterate-on-range mh-iterate-on-messages-in-region mh-add-to-sequence 930;;;;;; mh-iterate-on-messages-in-region mh-add-to-sequence mh-notate-cur
884;;;;;; mh-notate-cur mh-notate-seq mh-map-to-seq-msgs mh-rename-seq 931;;;;;; mh-rename-seq mh-translate-range mh-read-range mh-read-seq-default
885;;;;;; mh-translate-range mh-read-range mh-read-seq-default mh-notate-deleted-and-refiled 932;;;;;; mh-notate-deleted-and-refiled mh-widen mh-put-msg-in-seq
886;;;;;; mh-widen mh-put-msg-in-seq mh-narrow-to-seq mh-msg-is-in-seq 933;;;;;; mh-narrow-to-seq mh-msg-is-in-seq mh-list-sequences mh-delete-seq)
887;;;;;; mh-list-sequences mh-delete-seq) "mh-seq" "mh-seq.el" (16625 934;;;;;; "mh-seq" "mh-seq.el" (16668 22297))
888;;;;;; 54690))
889;;; Generated autoloads from mh-seq.el 935;;; Generated autoloads from mh-seq.el
890 936
891(autoload (quote mh-delete-seq) "mh-seq" "\ 937(autoload (quote mh-delete-seq) "mh-seq" "\
@@ -895,8 +941,9 @@ Delete the SEQUENCE." t nil)
895List the sequences defined in the folder being visited." t nil) 941List the sequences defined in the folder being visited." t nil)
896 942
897(autoload (quote mh-msg-is-in-seq) "mh-seq" "\ 943(autoload (quote mh-msg-is-in-seq) "mh-seq" "\
898Display the sequences that contain MESSAGE. 944Display the sequences in which the current message appears.
899Default is the displayed message." t nil) 945Use a prefix argument to display the sequences in which another MESSAGE
946appears." t nil)
900 947
901(autoload (quote mh-narrow-to-seq) "mh-seq" "\ 948(autoload (quote mh-narrow-to-seq) "mh-seq" "\
902Restrict display of this folder to just messages in SEQUENCE. 949Restrict display of this folder to just messages in SEQUENCE.
@@ -909,10 +956,8 @@ Check the documentation of `mh-interactive-range' to see how RANGE is read in
909interactive use." t nil) 956interactive use." t nil)
910 957
911(autoload (quote mh-widen) "mh-seq" "\ 958(autoload (quote mh-widen) "mh-seq" "\
912Remove last restriction from current folder. 959Restore the previous limit.
913If optional prefix argument ALL-FLAG is non-nil, then unwind to the beginning 960If optional prefix argument ALL-FLAG is non-nil, remove all limits." t nil)
914of the view stack thereby showing all messages that the buffer originally
915contained." t nil)
916 961
917(autoload (quote mh-notate-deleted-and-refiled) "mh-seq" "\ 962(autoload (quote mh-notate-deleted-and-refiled) "mh-seq" "\
918Notate messages marked for deletion or refiling. 963Notate messages marked for deletion or refiling.
@@ -965,16 +1010,6 @@ In FOLDER, translate the string EXPR to a list of messages numbers." nil nil)
965(autoload (quote mh-rename-seq) "mh-seq" "\ 1010(autoload (quote mh-rename-seq) "mh-seq" "\
966Rename SEQUENCE to have NEW-NAME." t nil) 1011Rename SEQUENCE to have NEW-NAME." t nil)
967 1012
968(autoload (quote mh-map-to-seq-msgs) "mh-seq" "\
969Invoke the FUNC at each message in the SEQ.
970SEQ can either be a list of messages or a MH sequence. The remaining ARGS are
971passed as arguments to FUNC." nil nil)
972
973(autoload (quote mh-notate-seq) "mh-seq" "\
974Mark the scan listing.
975All messages in SEQ are marked with NOTATION at OFFSET from the beginning of
976the line." nil nil)
977
978(autoload (quote mh-notate-cur) "mh-seq" "\ 1013(autoload (quote mh-notate-cur) "mh-seq" "\
979Mark the MH sequence cur. 1014Mark the MH sequence cur.
980In addition to notating the current message with `mh-note-cur' the function 1015In addition to notating the current message with `mh-note-cur' the function
@@ -1019,37 +1054,44 @@ RANGE-PROMPT. A list of messages in that range is returned.
1019If a MH range is given, say something like last:20, then a list containing 1054If a MH range is given, say something like last:20, then a list containing
1020the messages in that range is returned. 1055the messages in that range is returned.
1021 1056
1057If DEFAULT non-nil then it is returned.
1058
1022Otherwise, the message number at point is returned. 1059Otherwise, the message number at point is returned.
1023 1060
1024This function is usually used with `mh-iterate-on-range' in order to provide 1061This function is usually used with `mh-iterate-on-range' in order to provide
1025a uniform interface to MH-E functions." nil nil) 1062a uniform interface to MH-E functions." nil nil)
1026 1063
1027(autoload (quote mh-region-to-msg-list) "mh-seq" "\
1028Return a list of messages within the region between BEGIN and END." nil nil)
1029
1030(autoload (quote mh-narrow-to-subject) "mh-seq" "\ 1064(autoload (quote mh-narrow-to-subject) "mh-seq" "\
1031Narrow to a sequence containing all following messages with same subject." t nil) 1065Limit to messages with same subject.
1066With a prefix argument, edit PICK-EXPR.
1067
1068Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command." t nil)
1032 1069
1033(autoload (quote mh-narrow-to-from) "mh-seq" "\ 1070(autoload (quote mh-narrow-to-from) "mh-seq" "\
1034Limit to messages with the same From header field as the message at point. 1071Limit to messages with the same `From:' field.
1035With a prefix argument, prompt for the regular expression, REGEXP given to 1072With a prefix argument, edit PICK-EXPR.
1036pick." t nil) 1073
1074Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command." t nil)
1037 1075
1038(autoload (quote mh-narrow-to-cc) "mh-seq" "\ 1076(autoload (quote mh-narrow-to-cc) "mh-seq" "\
1039Limit to messages with the same Cc header field as the message at point. 1077Limit to messages with the same `Cc:' field.
1040With a prefix argument, prompt for the regular expression, REGEXP given to 1078With a prefix argument, edit PICK-EXPR.
1041pick." t nil) 1079
1080Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command." t nil)
1042 1081
1043(autoload (quote mh-narrow-to-to) "mh-seq" "\ 1082(autoload (quote mh-narrow-to-to) "mh-seq" "\
1044Limit to messages with the same To header field as the message at point. 1083Limit to messages with the same `To:' field.
1045With a prefix argument, prompt for the regular expression, REGEXP given to 1084With a prefix argument, edit PICK-EXPR.
1046pick." t nil) 1085
1086Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command." t nil)
1047 1087
1048(autoload (quote mh-narrow-to-range) "mh-seq" "\ 1088(autoload (quote mh-narrow-to-range) "mh-seq" "\
1049Limit to messages in RANGE. 1089Limit to messages in RANGE.
1050 1090
1051Check the documentation of `mh-interactive-range' to see how RANGE is read in 1091Check the documentation of `mh-interactive-range' to see how RANGE is read in
1052interactive use." t nil) 1092interactive use.
1093
1094Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command." t nil)
1053 1095
1054(autoload (quote mh-delete-subject) "mh-seq" "\ 1096(autoload (quote mh-delete-subject) "mh-seq" "\
1055Mark all following messages with same subject to be deleted. 1097Mark all following messages with same subject to be deleted.
@@ -1103,14 +1145,15 @@ Mark current message and all its children for refiling to FOLDER." t nil)
1103Toggle tick mark of all messages in RANGE." t nil) 1145Toggle tick mark of all messages in RANGE." t nil)
1104 1146
1105(autoload (quote mh-narrow-to-tick) "mh-seq" "\ 1147(autoload (quote mh-narrow-to-tick) "mh-seq" "\
1106Restrict display of this folder to just messages in `mh-tick-seq'. 1148Limit to messages in `mh-tick-seq'.
1149
1107Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command." t nil) 1150Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command." t nil)
1108 1151
1109;;;*** 1152;;;***
1110 1153
1111;;;### (autoloads (mh-speed-add-folder mh-speed-invalidate-map mh-speed-flists 1154;;;### (autoloads (mh-speed-add-folder mh-speed-invalidate-map mh-speed-flists
1112;;;;;; mh-speed-view mh-speed-toggle mh-folder-speedbar-buttons) 1155;;;;;; mh-speed-view mh-speed-toggle mh-folder-speedbar-buttons)
1113;;;;;; "mh-speed" "mh-speed.el" (16625 54721)) 1156;;;;;; "mh-speed" "mh-speed.el" (16665 55171))
1114;;; Generated autoloads from mh-speed.el 1157;;; Generated autoloads from mh-speed.el
1115 1158
1116(autoload (quote mh-folder-speedbar-buttons) "mh-speed" "\ 1159(autoload (quote mh-folder-speedbar-buttons) "mh-speed" "\
@@ -1145,31 +1188,24 @@ The function invalidates the latest ancestor that is present." nil nil)
1145 1188
1146;;;*** 1189;;;***
1147 1190
1148;;;### (autoloads (mh-get-msg-num mh-goto-address-find-address-at-point)
1149;;;;;; "mh-utils" "mh-utils.el" (16625 54979))
1150;;; Generated autoloads from mh-utils.el
1151
1152(autoload (quote mh-goto-address-find-address-at-point) "mh-utils" "\
1153Find e-mail address around or before point.
1154Then search backwards to beginning of line for the start of an e-mail
1155address. If no e-mail address found, return nil." nil nil)
1156
1157(autoload (quote mh-get-msg-num) "mh-utils" "\
1158Return the message number of the displayed message.
1159If the argument ERROR-IF-NO-MESSAGE is non-nil, then complain if the cursor is
1160not pointing to a message." nil nil)
1161
1162;;;***
1163
1164;;;### (autoloads (mh-alias-apropos mh-alias-add-address-under-point 1191;;;### (autoloads (mh-alias-apropos mh-alias-add-address-under-point
1165;;;;;; mh-alias-grab-from-field mh-alias-add-alias mh-alias-from-has-no-alias-p 1192;;;;;; mh-alias-grab-from-field mh-alias-add-alias mh-alias-for-from-p
1166;;;;;; mh-alias-address-to-alias mh-alias-letter-expand-alias mh-alias-minibuffer-confirm-address 1193;;;;;; mh-alias-address-to-alias mh-alias-letter-expand-alias mh-alias-minibuffer-confirm-address
1167;;;;;; mh-read-address mh-alias-reload-maybe mh-alias-reload) "mh-alias" 1194;;;;;; mh-read-address mh-alias-reload-maybe mh-alias-reload) "mh-alias"
1168;;;;;; "mh-alias.el" (16625 53006)) 1195;;;;;; "mh-alias.el" (16671 49553))
1169;;; Generated autoloads from mh-alias.el 1196;;; Generated autoloads from mh-alias.el
1170 1197
1171(autoload (quote mh-alias-reload) "mh-alias" "\ 1198(autoload (quote mh-alias-reload) "mh-alias" "\
1172Load MH aliases into `mh-alias-alist'." t nil) 1199Reload MH aliases.
1200
1201Since aliases are updated frequently, MH-E will reload aliases automatically
1202whenever an alias lookup occurs if an alias source (a file listed in your
1203`Aliasfile:' profile component and your password file if variable
1204`mh-alias-local-users' is non-nil) has changed. However, you can reload your
1205aliases manually by calling this command directly.
1206
1207The value of `mh-alias-reloaded-hook' is a list of functions to be called,
1208with no arguments, after the aliases have been loaded." t nil)
1173 1209
1174(autoload (quote mh-alias-reload-maybe) "mh-alias" "\ 1210(autoload (quote mh-alias-reload-maybe) "mh-alias" "\
1175Load new MH aliases." nil nil) 1211Load new MH aliases." nil nil)
@@ -1186,26 +1222,25 @@ Expand mail alias before point." nil nil)
1186(autoload (quote mh-alias-address-to-alias) "mh-alias" "\ 1222(autoload (quote mh-alias-address-to-alias) "mh-alias" "\
1187Return the ADDRESS alias if defined, or nil." nil nil) 1223Return the ADDRESS alias if defined, or nil." nil nil)
1188 1224
1189(autoload (quote mh-alias-from-has-no-alias-p) "mh-alias" "\ 1225(autoload (quote mh-alias-for-from-p) "mh-alias" "\
1190Return t is From has no current alias set. 1226Return t if sender's address has a corresponding alias." nil nil)
1191In the exceptional situation where there isn't a From header in the message the
1192function returns nil." nil nil)
1193 1227
1194(autoload (quote mh-alias-add-alias) "mh-alias" "\ 1228(autoload (quote mh-alias-add-alias) "mh-alias" "\
1195*Add ALIAS for ADDRESS in personal alias file. 1229*Add ALIAS for ADDRESS in personal alias file.
1196Prompts for confirmation if the address already has an alias. 1230This function prompts you for an alias and address. If the alias exists
1197If the alias is already is use, `mh-alias-add-alias-to-file' will prompt." t nil) 1231already, you will have the choice of inserting the new alias before or after
1232the old alias. In the former case, this alias will be used when sending mail
1233to this alias. In the latter case, the alias serves as an additional folder
1234name hint when filing messages." t nil)
1198 1235
1199(autoload (quote mh-alias-grab-from-field) "mh-alias" "\ 1236(autoload (quote mh-alias-grab-from-field) "mh-alias" "\
1200*Add ALIAS for ADDRESS in personal alias file. 1237*Add alias for the sender of the current message." t nil)
1201Prompts for confirmation if the alias is already in use or if the address
1202already has an alias." t nil)
1203 1238
1204(autoload (quote mh-alias-add-address-under-point) "mh-alias" "\ 1239(autoload (quote mh-alias-add-address-under-point) "mh-alias" "\
1205Insert an alias for email address under point." t nil) 1240Insert an alias for address under point." t nil)
1206 1241
1207(autoload (quote mh-alias-apropos) "mh-alias" "\ 1242(autoload (quote mh-alias-apropos) "mh-alias" "\
1208Show all aliases that match REGEXP either in name or content." t nil) 1243Show all aliases or addresses that match REGEXP." t nil)
1209 1244
1210;;;*** 1245;;;***
1211 1246
diff --git a/lisp/mh-e/mh-mime.el b/lisp/mh-e/mh-mime.el
index 91cbcec0c06..6b3c5793be5 100644
--- a/lisp/mh-e/mh-mime.el
+++ b/lisp/mh-e/mh-mime.el
@@ -34,7 +34,7 @@
34 34
35;;; Code: 35;;; Code:
36 36
37(require 'mh-utils) 37(eval-when-compile (require 'mh-acros))
38(mh-require-cl) 38(mh-require-cl)
39(require 'mh-comp) 39(require 'mh-comp)
40(require 'gnus-util) 40(require 'gnus-util)
@@ -46,8 +46,7 @@
46(autoload 'gnus-eval-format "gnus-spec") 46(autoload 'gnus-eval-format "gnus-spec")
47(autoload 'widget-convert-button "wid-edit") 47(autoload 'widget-convert-button "wid-edit")
48(autoload 'message-options-set-recipient "message") 48(autoload 'message-options-set-recipient "message")
49(autoload 'mml-secure-message-sign-pgpmime "mml-sec") 49(autoload 'mml-unsecure-message "mml-sec")
50(autoload 'mml-secure-message-encrypt-pgpmime "mml-sec")
51(autoload 'mml-minibuffer-read-file "mml") 50(autoload 'mml-minibuffer-read-file "mml")
52(autoload 'mml-minibuffer-read-description "mml") 51(autoload 'mml-minibuffer-read-description "mml")
53(autoload 'mml-insert-empty-tag "mml") 52(autoload 'mml-insert-empty-tag "mml")
@@ -82,7 +81,7 @@ If any of the optional arguments are absent, they are prompted for."
82 (read-string "Forw Content-description: ") 81 (read-string "Forw Content-description: ")
83 (mh-prompt-for-folder "Message from" mh-sent-from-folder nil) 82 (mh-prompt-for-folder "Message from" mh-sent-from-folder nil)
84 (read-string (format "Messages%s: " 83 (read-string (format "Messages%s: "
85 (if mh-sent-from-msg 84 (if (numberp mh-sent-from-msg)
86 (format " [%d]" mh-sent-from-msg) 85 (format " [%d]" mh-sent-from-msg)
87 ""))))) 86 "")))))
88 (if (equal mh-compose-insertion 'gnus) 87 (if (equal mh-compose-insertion 'gnus)
@@ -114,6 +113,7 @@ MH profile.")
114;; the variable, so things should work exactly as before. 113;; the variable, so things should work exactly as before.
115(defvar mh-have-file-command) 114(defvar mh-have-file-command)
116 115
116;;;###mh-autoload
117(defun mh-have-file-command () 117(defun mh-have-file-command ()
118 "Return t if 'file' command is on the system. 118 "Return t if 'file' command is on the system.
119'file -i' is used to get MIME type of composition insertion." 119'file -i' is used to get MIME type of composition insertion."
@@ -129,7 +129,8 @@ MH profile.")
129 129
130(defvar mh-file-mime-type-substitutions 130(defvar mh-file-mime-type-substitutions
131 '(("application/msword" "\.xls" "application/ms-excel") 131 '(("application/msword" "\.xls" "application/ms-excel")
132 ("application/msword" "\.ppt" "application/ms-powerpoint")) 132 ("application/msword" "\.ppt" "application/ms-powerpoint")
133 ("text/plain" "\.vcf" "text/x-vcard"))
133 "Substitutions to make for Content-Type returned from file command. 134 "Substitutions to make for Content-Type returned from file command.
134The first element is the Content-Type returned by the file command. 135The first element is the Content-Type returned by the file command.
135The second element is a regexp matching the file name, usually the extension. 136The second element is a regexp matching the file name, usually the extension.
@@ -151,6 +152,7 @@ Substitutions are made from the `mh-file-mime-type-substitutions' variable."
151 (setq subst (cdr subst)))) 152 (setq subst (cdr subst))))
152 answer)) 153 answer))
153 154
155;;;###mh-autoload
154(defun mh-file-mime-type (filename) 156(defun mh-file-mime-type (filename)
155 "Return MIME type of FILENAME from file command. 157 "Return MIME type of FILENAME from file command.
156Returns nil if file command not on system." 158Returns nil if file command not on system."
@@ -192,12 +194,38 @@ Returns nil if file command not on system."
192 ("message/external-body") ("message/partial") ("message/rfc822") 194 ("message/external-body") ("message/partial") ("message/rfc822")
193 195
194 ("text/enriched") ("text/html") ("text/plain") ("text/rfc822-headers") 196 ("text/enriched") ("text/html") ("text/plain") ("text/rfc822-headers")
195 ("text/richtext") ("text/xml") 197 ("text/richtext") ("text/x-vcard") ("text/xml")
196 198
197 ("video/mpeg") ("video/quicktime")) 199 ("video/mpeg") ("video/quicktime"))
198 "Legal MIME content types. 200 "Legal MIME content types.
199See documentation for \\[mh-edit-mhn].") 201See documentation for \\[mh-edit-mhn].")
200 202
203;; RFC 2045 - Multipurpose Internet Mail Extensions (MIME) Part One:
204;; Format of Internet Message Bodies.
205;; RFC 2046 - Multipurpose Internet Mail Extensions (MIME) Part Two:
206;; Media Types.
207;; RFC 2049 - Multipurpose Internet Mail Extensions (MIME) Part Five:
208;; Conformance Criteria and Examples.
209;; RFC 2017 - Definition of the URL MIME External-Body Access-Type
210;; RFC 1738 - Uniform Resource Locators (URL)
211(defvar mh-access-types
212 '(("anon-ftp") ; RFC2046 Anonymous File Transfer Protocol
213 ("file") ; RFC1738 Host-specific file names
214 ("ftp") ; RFC2046 File Transfer Protocol
215 ("gopher") ; RFC1738 The Gopher Protocol
216 ("http") ; RFC1738 Hypertext Transfer Protocol
217 ("local-file") ; RFC2046 Local file access
218 ("mail-server") ; RFC2046 mail-server Electronic mail address
219 ("mailto") ; RFC1738 Electronic mail address
220 ("news") ; RFC1738 Usenet news
221 ("nntp") ; RFC1738 Usenet news using NNTP access
222 ("propspero") ; RFC1738 Prospero Directory Service
223 ("telnet") ; RFC1738 Telnet
224 ("tftp") ; RFC2046 Trivial File Transfer Protocol
225 ("url") ; RFC2017 URL scheme MIME access-type Protocol
226 ("wais")) ; RFC1738 Wide Area Information Servers
227 "Legal MIME access-type values.")
228
201;;;###mh-autoload 229;;;###mh-autoload
202(defun mh-mhn-compose-insertion (filename type description attributes) 230(defun mh-mhn-compose-insertion (filename type description attributes)
203 "Add a directive to insert a MIME message part from a file. 231 "Add a directive to insert a MIME message part from a file.
@@ -286,7 +314,7 @@ See also \\[mh-edit-mhn]."
286 "type=tar; conversions=x-compress" 314 "type=tar; conversions=x-compress"
287 "mode=image")) 315 "mode=image"))
288 316
289 317;;;###mh-autoload
290(defun mh-mhn-compose-external-type (access-type host filename type 318(defun mh-mhn-compose-external-type (access-type host filename type
291 &optional description 319 &optional description
292 attributes extra-params 320 attributes extra-params
@@ -301,6 +329,18 @@ DESCRIPTION, a line of text for the Content-description header, ATTRIBUTES,
301EXTRA-PARAMS, and COMMENT. 329EXTRA-PARAMS, and COMMENT.
302 330
303See also \\[mh-edit-mhn]." 331See also \\[mh-edit-mhn]."
332 (interactive (list
333 (completing-read "Access Type: " mh-access-types)
334 (read-string "Remote host: ")
335 (read-string "Remote url-path: ")
336 (completing-read "Content-Type: "
337 (if (fboundp 'mailcap-mime-types)
338 (mapcar 'list (mailcap-mime-types))
339 mh-mime-content-types))
340 (if current-prefix-arg (read-string "Content-description: "))
341 (if current-prefix-arg (read-string "Attributes: "))
342 (if current-prefix-arg (read-string "Extra Parameters: "))
343 (if current-prefix-arg (read-string "Comment: "))))
304 (beginning-of-line) 344 (beginning-of-line)
305 (insert "#@" type) 345 (insert "#@" type)
306 (and attributes 346 (and attributes
@@ -314,7 +354,9 @@ See also \\[mh-edit-mhn]."
314 (insert "access-type=" access-type "; ") 354 (insert "access-type=" access-type "; ")
315 (insert "site=" host) 355 (insert "site=" host)
316 (insert "; name=" (file-name-nondirectory filename)) 356 (insert "; name=" (file-name-nondirectory filename))
317 (insert "; directory=\"" (file-name-directory filename) "\"") 357 (let ((directory (file-name-directory filename)))
358 (and directory
359 (insert "; directory=\"" directory "\"")))
318 (and extra-params 360 (and extra-params
319 (insert "; " extra-params)) 361 (insert "; " extra-params))
320 (insert "\n")) 362 (insert "\n"))
@@ -332,7 +374,7 @@ See also \\[mh-edit-mhn]."
332 (read-string "Forw Content-description: ") 374 (read-string "Forw Content-description: ")
333 (mh-prompt-for-folder "Message from" mh-sent-from-folder nil) 375 (mh-prompt-for-folder "Message from" mh-sent-from-folder nil)
334 (read-string (format "Messages%s: " 376 (read-string (format "Messages%s: "
335 (if mh-sent-from-msg 377 (if (numberp mh-sent-from-msg)
336 (format " [%d]" mh-sent-from-msg) 378 (format " [%d]" mh-sent-from-msg)
337 ""))))) 379 "")))))
338 (beginning-of-line) 380 (beginning-of-line)
@@ -349,7 +391,7 @@ See also \\[mh-edit-mhn]."
349 (let ((start (point))) 391 (let ((start (point)))
350 (insert " " messages) 392 (insert " " messages)
351 (subst-char-in-region start (point) ?, ? )) 393 (subst-char-in-region start (point) ?, ? ))
352 (if mh-sent-from-msg 394 (if (numberp mh-sent-from-msg)
353 (insert " " (int-to-string mh-sent-from-msg)))) 395 (insert " " (int-to-string mh-sent-from-msg))))
354 (insert "\n")) 396 (insert "\n"))
355 397
@@ -380,10 +422,11 @@ arguments, after performing the conversion.
380 422
381The mhn program is part of MH version 6.8 or later." 423The mhn program is part of MH version 6.8 or later."
382 (interactive "*P") 424 (interactive "*P")
425 (mh-mhn-quote-unescaped-sharp)
383 (save-buffer) 426 (save-buffer)
384 (message "mhn editing...") 427 (message "mhn editing...")
385 (cond 428 (cond
386 (mh-nmh-flag 429 ((mh-variant-p 'nmh)
387 (mh-exec-cmd-error nil 430 (mh-exec-cmd-error nil
388 "mhbuild" (if extra-args mh-mhn-args) buffer-file-name)) 431 "mhbuild" (if extra-args mh-mhn-args) buffer-file-name))
389 (t 432 (t
@@ -393,6 +436,19 @@ The mhn program is part of MH version 6.8 or later."
393 (message "mhn editing...done") 436 (message "mhn editing...done")
394 (run-hooks 'mh-edit-mhn-hook)) 437 (run-hooks 'mh-edit-mhn-hook))
395 438
439(defun mh-mhn-quote-unescaped-sharp ()
440 "Quote `#' characters that haven't been quoted for `mhbuild'.
441If the `#' character is present in the first column, but it isn't part of a
442MHN directive then `mhbuild' gives an error. This function will quote all such
443characters."
444 (save-excursion
445 (goto-char (point-min))
446 (while (re-search-forward "^#" nil t)
447 (beginning-of-line)
448 (unless (mh-mhn-directive-present-p (point) (line-end-position))
449 (insert "#"))
450 (goto-char (line-end-position)))))
451
396;;;###mh-autoload 452;;;###mh-autoload
397(defun mh-revert-mhn-edit (noconfirm) 453(defun mh-revert-mhn-edit (noconfirm)
398 "Undo the effect of \\[mh-edit-mhn] by reverting to the backup file. 454 "Undo the effect of \\[mh-edit-mhn] by reverting to the backup file.
@@ -422,18 +478,24 @@ Optional non-nil argument NOCONFIRM means don't ask for confirmation."
422 (after-find-file nil))) 478 (after-find-file nil)))
423 479
424;;;###mh-autoload 480;;;###mh-autoload
425(defun mh-mhn-directive-present-p () 481(defun mh-mhn-directive-present-p (&optional begin end)
426 "Check if the current buffer has text which might be a MHN directive." 482 "Check if the text between BEGIN and END might be a MHN directive.
483The optional argument BEGIN defaults to the beginning of the buffer, while END
484defaults to the the end of the buffer."
485 (unless begin (setq begin (point-min)))
486 (unless end (setq end (point-max)))
427 (save-excursion 487 (save-excursion
428 (block 'search-for-mhn-directive 488 (block 'search-for-mhn-directive
429 (goto-char (point-min)) 489 (goto-char begin)
430 (while (re-search-forward "^#" nil t) 490 (while (re-search-forward "^#" end t)
431 (let ((s (buffer-substring-no-properties (point) (line-end-position)))) 491 (let ((s (buffer-substring-no-properties (point) (line-end-position))))
432 (cond ((equal s "")) 492 (cond ((equal s ""))
433 ((string-match "^forw[ \t\n]+" s) 493 ((string-match "^forw[ \t\n]+" s)
434 (return-from 'search-for-mhn-directive t)) 494 (return-from 'search-for-mhn-directive t))
435 (t (let ((first-token (car (split-string s "[ \t;@]")))) 495 (t (let ((first-token (car (split-string s "[ \t;@]"))))
436 (when (string-match mh-media-type-regexp first-token) 496 (when (and first-token
497 (string-match mh-media-type-regexp
498 first-token))
437 (return-from 'search-for-mhn-directive t))))))) 499 (return-from 'search-for-mhn-directive t)))))))
438 nil))) 500 nil)))
439 501
@@ -450,14 +512,23 @@ function may be called manually before sending the draft as well."
450 (require 'message) 512 (require 'message)
451 (when mh-gnus-pgp-support-flag ;; This is only needed for PGP 513 (when mh-gnus-pgp-support-flag ;; This is only needed for PGP
452 (message-options-set-recipient)) 514 (message-options-set-recipient))
453 (mml-to-mime)) 515 (let ((saved-text (buffer-string))
516 (buffer (current-buffer))
517 (modified-flag (buffer-modified-p)))
518 (condition-case err (mml-to-mime)
519 (error
520 (with-current-buffer buffer
521 (delete-region (point-min) (point-max))
522 (insert saved-text)
523 (set-buffer-modified-p modified-flag))
524 (error (error-message-string err))))))
454 525
455;;;###mh-autoload 526;;;###mh-autoload
456(defun mh-mml-forward-message (description folder message) 527(defun mh-mml-forward-message (description folder message)
457 "Forward a message as attachment. 528 "Forward a message as attachment.
458The function will prompt the user for a DESCRIPTION, a FOLDER and MESSAGE 529The function will prompt the user for a DESCRIPTION, a FOLDER and MESSAGE
459number." 530number."
460 (let ((msg (if (equal message "") 531 (let ((msg (if (and (equal message "") (numberp mh-sent-from-msg))
461 mh-sent-from-msg 532 mh-sent-from-msg
462 (car (read-from-string message))))) 533 (car (read-from-string message)))))
463 (cond ((integerp msg) 534 (cond ((integerp msg)
@@ -473,6 +544,19 @@ number."
473 description))) 544 description)))
474 (t (error "The message number, %s is not a integer!" msg))))) 545 (t (error "The message number, %s is not a integer!" msg)))))
475 546
547(defvar mh-mml-cryptographic-method-history ())
548
549;;;###mh-autoload
550(defun mh-mml-query-cryptographic-method ()
551 "Read the cryptographic method to use."
552 (if current-prefix-arg
553 (let ((def (or (car mh-mml-cryptographic-method-history)
554 mh-mml-method-default)))
555 (completing-read (format "Method: [%s] " def)
556 '(("pgp") ("pgpmime") ("smime"))
557 nil t nil 'mh-mml-cryptographic-method-history def))
558 mh-mml-method-default))
559
476;;;###mh-autoload 560;;;###mh-autoload
477(defun mh-mml-attach-file (&optional disposition) 561(defun mh-mml-attach-file (&optional disposition)
478 "Attach a file to the outgoing MIME message. 562 "Attach a file to the outgoing MIME message.
@@ -499,22 +583,56 @@ automatically."
499 (mml-insert-empty-tag 'part 'type type 'filename file 583 (mml-insert-empty-tag 'part 'type type 'filename file
500 'disposition dispos 'description description))) 584 'disposition dispos 'description description)))
501 585
502;;;###mh-autoload 586(defun mh-secure-message (method mode &optional identity)
503(defun mh-mml-secure-message-sign-pgpmime () 587 "Add directive to Encrypt/Sign an entire message.
504 "Add directive to encrypt/sign the entire message." 588METHOD should be one of: \"pgpmime\", \"pgp\", \"smime\".
505 (interactive) 589MODE should be one of: \"sign\", \"encrypt\", \"signencrypt\", \"none\".
590IDENTITY is optionally the default-user-id to use."
506 (if (not mh-gnus-pgp-support-flag) 591 (if (not mh-gnus-pgp-support-flag)
507 (error "Sorry. Your version of gnus does not support PGP/GPG") 592 (error "Sorry. Your version of gnus does not support PGP/GPG")
508 (mml-secure-message-sign-pgpmime))) 593 ;; Check the arguments
594 (let ((valid-methods (list "pgpmime" "pgp" "smime"))
595 (valid-modes (list "sign" "encrypt" "signencrypt" "none")))
596 (if (not (member method valid-methods))
597 (error (format "Sorry. METHOD \"%s\" is invalid." method)))
598 (if (not (member mode valid-modes))
599 (error (format "Sorry. MODE \"%s\" is invalid" mode)))
600 (mml-unsecure-message)
601 (if (not (string= mode "none"))
602 (save-excursion
603 (goto-char (point-min))
604 (mh-goto-header-end 1)
605 (if mh-identity-pgg-default-user-id
606 (mml-insert-tag 'secure 'method method 'mode mode
607 'sender mh-identity-pgg-default-user-id)
608 (mml-insert-tag 'secure 'method method 'mode mode)))))))
509 609
510;;;###mh-autoload 610;;;###mh-autoload
511(defun mh-mml-secure-message-encrypt-pgpmime (&optional dontsign) 611(defun mh-mml-unsecure-message (&optional ignore)
512 "Add directive to encrypt and sign the entire message. 612 "Remove any secure message directives.
513If called with a prefix argument DONTSIGN, only encrypt (do NOT sign)." 613The IGNORE argument is not used."
514 (interactive "P") 614 (interactive "P")
515 (if (not mh-gnus-pgp-support-flag) 615 (if (not mh-gnus-pgp-support-flag)
516 (error "Sorry. Your version of gnus does not support PGP/GPG") 616 (error "Sorry. Your version of gnus does not support PGP/GPG")
517 (mml-secure-message-encrypt-pgpmime dontsign))) 617 (mml-unsecure-message)))
618
619;;;###mh-autoload
620(defun mh-mml-secure-message-sign (method)
621 "Add security directive to sign the entire message using METHOD."
622 (interactive (list (mh-mml-query-cryptographic-method)))
623 (mh-secure-message method "sign" mh-identity-pgg-default-user-id))
624
625;;;###mh-autoload
626(defun mh-mml-secure-message-encrypt (method)
627 "Add security directive to encrypt the entire message using METHOD."
628 (interactive (list (mh-mml-query-cryptographic-method)))
629 (mh-secure-message method "encrypt" mh-identity-pgg-default-user-id))
630
631;;;###mh-autoload
632(defun mh-mml-secure-message-signencrypt (method)
633 "Add security directive to encrypt and sign the entire message using METHOD."
634 (interactive (list (mh-mml-query-cryptographic-method)))
635 (mh-secure-message method "signencrypt" mh-identity-pgg-default-user-id))
518 636
519;;;###mh-autoload 637;;;###mh-autoload
520(defun mh-mml-directive-present-p () 638(defun mh-mml-directive-present-p ()
@@ -667,19 +785,19 @@ actual storing."
667 (folder (if (eq major-mode 'mh-show-mode) 785 (folder (if (eq major-mode 'mh-show-mode)
668 mh-show-folder-buffer 786 mh-show-folder-buffer
669 mh-current-folder)) 787 mh-current-folder))
670 (command (if mh-nmh-flag "mhstore" "mhn")) 788 (command (if (mh-variant-p 'nmh) "mhstore" "mhn"))
671 (directory 789 (directory
672 (cond 790 (cond
673 ((and (or arg 791 ((and (or arg
674 (equal nil mh-mime-save-parts-default-directory) 792 (equal nil mh-mime-save-parts-default-directory)
675 (equal t mh-mime-save-parts-default-directory)) 793 (equal t mh-mime-save-parts-default-directory))
676 (not mh-mime-save-parts-directory)) 794 (not mh-mime-save-parts-directory))
677 (read-file-name "Store in what directory? " nil nil t nil)) 795 (read-file-name "Store in directory: " nil nil t nil))
678 ((and (or arg 796 ((and (or arg
679 (equal t mh-mime-save-parts-default-directory)) 797 (equal t mh-mime-save-parts-default-directory))
680 mh-mime-save-parts-directory) 798 mh-mime-save-parts-directory)
681 (read-file-name (format 799 (read-file-name (format
682 "Store in what directory? [%s] " 800 "Store in directory: [%s] "
683 mh-mime-save-parts-directory) 801 mh-mime-save-parts-directory)
684 "" mh-mime-save-parts-directory t "")) 802 "" mh-mime-save-parts-directory t ""))
685 ((stringp mh-mime-save-parts-default-directory) 803 ((stringp mh-mime-save-parts-default-directory)
@@ -689,7 +807,7 @@ actual storing."
689 (if (and (equal directory "") mh-mime-save-parts-directory) 807 (if (and (equal directory "") mh-mime-save-parts-directory)
690 (setq directory mh-mime-save-parts-directory)) 808 (setq directory mh-mime-save-parts-directory))
691 (if (not (file-directory-p directory)) 809 (if (not (file-directory-p directory))
692 (message "No directory specified.") 810 (message "No directory specified")
693 (if (equal nil mh-mime-save-parts-default-directory) 811 (if (equal nil mh-mime-save-parts-default-directory)
694 (setq mh-mime-save-parts-directory directory)) 812 (setq mh-mime-save-parts-directory directory))
695 (save-excursion 813 (save-excursion
@@ -766,17 +884,18 @@ displayed."
766 (mh-mime-handles (mh-buffer-data)))) 884 (mh-mime-handles (mh-buffer-data))))
767 (unless handles (mh-decode-message-body))) 885 (unless handles (mh-decode-message-body)))
768 886
769 (when (and handles 887 (cond ((and handles
770 (or (not (stringp (car handles))) (cdr handles))) 888 (or (not (stringp (car handles))) (cdr handles)))
771 ;; Goto start of message body 889 ;; Goto start of message body
772 (goto-char (point-min)) 890 (goto-char (point-min))
773 (or (search-forward "\n\n" nil t) (goto-char (point-max))) 891 (or (search-forward "\n\n" nil t) (goto-char (point-max)))
774 892
775 ;; Delete the body 893 ;; Delete the body
776 (delete-region (point) (point-max)) 894 (delete-region (point) (point-max))
777 895
778 ;; Display the MIME handles 896 ;; Display the MIME handles
779 (mh-mime-display-part handles))) 897 (mh-mime-display-part handles))
898 (t (mh-signature-highlight))))
780 (error 899 (error
781 (message "Please report this error. The error message is:\n %s" 900 (message "Please report this error. The error message is:\n %s"
782 (error-message-string err)) 901 (error-message-string err))
@@ -874,7 +993,7 @@ This is only useful if a Content-Disposition header is not present."
874 (save-restriction 993 (save-restriction
875 (widen) 994 (widen)
876 (goto-char (point-min)) 995 (goto-char (point-min))
877 (not (re-search-forward "^-- $" nil t))))))) 996 (not (mh-signature-separator-p)))))))
878 997
879(defun mh-mime-display-single (handle) 998(defun mh-mime-display-single (handle)
880 "Display a leaf node, HANDLE in the MIME tree." 999 "Display a leaf node, HANDLE in the MIME tree."
@@ -904,7 +1023,8 @@ This is only useful if a Content-Disposition header is not present."
904 (insert "\n") 1023 (insert "\n")
905 (mh-insert-mime-button handle (mh-mime-part-index handle) nil)) 1024 (mh-insert-mime-button handle (mh-mime-part-index handle) nil))
906 ((and displayp (not mh-display-buttons-for-inline-parts-flag)) 1025 ((and displayp (not mh-display-buttons-for-inline-parts-flag))
907 (or (mm-display-part handle) (mm-display-part handle))) 1026 (or (mm-display-part handle) (mm-display-part handle))
1027 (mh-signature-highlight handle))
908 ((and displayp mh-display-buttons-for-inline-parts-flag) 1028 ((and displayp mh-display-buttons-for-inline-parts-flag)
909 (insert "\n") 1029 (insert "\n")
910 (mh-insert-mime-button handle (mh-mime-part-index handle) nil) 1030 (mh-insert-mime-button handle (mh-mime-part-index handle) nil)
@@ -912,6 +1032,28 @@ This is only useful if a Content-Disposition header is not present."
912 (mh-mm-display-part handle))) 1032 (mh-mm-display-part handle)))
913 (goto-char (point-max))))) 1033 (goto-char (point-max)))))
914 1034
1035(defun mh-signature-highlight (&optional handle)
1036 "Highlight message signature in HANDLE.
1037The optional argument, HANDLE is a MIME handle if the function is being used
1038to highlight the signature in a MIME part."
1039 (let ((regexp
1040 (cond ((not handle) "^-- $")
1041 ((not (and (equal (mm-handle-media-supertype handle) "text")
1042 (equal (mm-handle-media-subtype handle) "html")))
1043 "^-- $")
1044 ((eq (mh-mm-text-html-renderer) 'lynx) "^ --$")
1045 (t "^--$"))))
1046 (save-excursion
1047 (goto-char (point-max))
1048 (when (re-search-backward regexp nil t)
1049 (mh-do-in-gnu-emacs
1050 (let ((ov (make-overlay (point) (point-max))))
1051 (overlay-put ov 'face 'mh-show-signature-face)
1052 (overlay-put ov 'evaporate t)))
1053 (mh-do-in-xemacs
1054 (set-extent-property (make-extent (point) (point-max))
1055 'face 'mh-show-signature-face))))))
1056
915(mh-do-in-xemacs 1057(mh-do-in-xemacs
916 (defvar dots) 1058 (defvar dots)
917 (defvar type)) 1059 (defvar type))
@@ -954,7 +1096,9 @@ like \"K v\" which operate on individual MIME parts."
954 :action 'mh-widget-press-button 1096 :action 'mh-widget-press-button
955 :button-keymap mh-mime-button-map 1097 :button-keymap mh-mime-button-map
956 :help-echo 1098 :help-echo
957 "Mouse-2 click or press RET (in show buffer) to toggle display"))) 1099 "Mouse-2 click or press RET (in show buffer) to toggle display")
1100 (dolist (ov (mh-funcall-if-exists overlays-in begin end))
1101 (mh-funcall-if-exists overlay-put ov 'evaporate t))))
958 1102
959;; There is a bug in Gnus inline image display due to which an extra line 1103;; There is a bug in Gnus inline image display due to which an extra line
960;; gets inserted every time it is viewed. To work around that problem we are 1104;; gets inserted every time it is viewed. To work around that problem we are
@@ -1009,7 +1153,8 @@ like \"K v\" which operate on individual MIME parts."
1009 (when (eq mh-highlight-citation-p 'gnus) 1153 (when (eq mh-highlight-citation-p 'gnus)
1010 (mh-gnus-article-highlight-citation)) 1154 (mh-gnus-article-highlight-citation))
1011 (mh-display-smileys) 1155 (mh-display-smileys)
1012 (mh-display-emphasis)) 1156 (mh-display-emphasis)
1157 (mh-signature-highlight handle))
1013 (setq region (cons (progn (goto-char (point-min)) 1158 (setq region (cons (progn (goto-char (point-min))
1014 (point-marker)) 1159 (point-marker))
1015 (progn (goto-char (point-max)) 1160 (progn (goto-char (point-max))
@@ -1098,6 +1243,31 @@ button."
1098 (goto-char point) 1243 (goto-char point)
1099 (set-buffer-modified-p nil))) 1244 (set-buffer-modified-p nil)))
1100 1245
1246;;;###mh-autoload
1247(defun mh-display-with-external-viewer (part-index)
1248 "View MIME PART-INDEX externally."
1249 (interactive "P")
1250 (when (consp part-index) (setq part-index (car part-index)))
1251 (mh-folder-mime-action
1252 part-index
1253 #'(lambda ()
1254 (let* ((part (get-text-property (point) 'mh-data))
1255 (type (mm-handle-media-type part))
1256 (methods (mapcar (lambda (x) (list (cdr (assoc 'viewer x))))
1257 (mailcap-mime-info type 'all)))
1258 (def (caar methods))
1259 (prompt (format "Viewer: %s" (if def (format "[%s] " def) "")))
1260 (method (completing-read prompt methods nil nil nil nil def))
1261 (folder mh-show-folder-buffer)
1262 (buffer-read-only nil))
1263 (when (string-match "^[^% \t]+$" method)
1264 (setq method (concat method " %s")))
1265 (flet ((mm-handle-set-external-undisplayer (handle function)
1266 (mh-handle-set-external-undisplayer folder handle function)))
1267 (unwind-protect (mm-display-external part method)
1268 (set-buffer-modified-p nil)))))
1269 nil))
1270
1101(defun mh-widget-press-button (widget el) 1271(defun mh-widget-press-button (widget el)
1102 "Callback for widget, WIDGET. 1272 "Callback for widget, WIDGET.
1103Parameter EL is unused." 1273Parameter EL is unused."
@@ -1106,9 +1276,9 @@ Parameter EL is unused."
1106 1276
1107(defun mh-mime-display-security (handle) 1277(defun mh-mime-display-security (handle)
1108 "Display PGP encrypted/signed message, HANDLE." 1278 "Display PGP encrypted/signed message, HANDLE."
1109 (insert "\n")
1110 (save-restriction 1279 (save-restriction
1111 (narrow-to-region (point) (point)) 1280 (narrow-to-region (point) (point))
1281 (insert "\n")
1112 (mh-insert-mime-security-button handle) 1282 (mh-insert-mime-security-button handle)
1113 (mh-mime-display-mixed (cdr handle)) 1283 (mh-mime-display-mixed (cdr handle))
1114 (insert "\n") 1284 (insert "\n")
@@ -1116,9 +1286,7 @@ Parameter EL is unused."
1116 mh-mime-security-button-end-line-format)) 1286 mh-mime-security-button-end-line-format))
1117 (mh-insert-mime-security-button handle)) 1287 (mh-insert-mime-security-button handle))
1118 (mm-set-handle-multipart-parameter 1288 (mm-set-handle-multipart-parameter
1119 handle 'mh-region 1289 handle 'mh-region (cons (point-min-marker) (point-max-marker)))))
1120 (cons (set-marker (make-marker) (point-min))
1121 (set-marker (make-marker) (point-max))))))
1122 1290
1123;;; I rewrote the security part because Gnus doesn't seem to ever minimize 1291;;; I rewrote the security part because Gnus doesn't seem to ever minimize
1124;;; the button. That is once the mime-security button is pressed there seems 1292;;; the button. That is once the mime-security button is pressed there seems
@@ -1149,8 +1317,22 @@ Parameter EL is unused."
1149 1317
1150(defun mh-mime-security-press-button (handle) 1318(defun mh-mime-security-press-button (handle)
1151 "Callback from security button for part HANDLE." 1319 "Callback from security button for part HANDLE."
1152 (when (mm-handle-multipart-ctl-parameter handle 'gnus-info) 1320 (if (mm-handle-multipart-ctl-parameter handle 'gnus-info)
1153 (mh-mime-security-show-details handle))) 1321 (mh-mime-security-show-details handle)
1322 (let ((region (mm-handle-multipart-ctl-parameter handle 'mh-region))
1323 point)
1324 (setq point (point))
1325 (goto-char (car region))
1326 (delete-region (car region) (cdr region))
1327 (with-current-buffer (mm-handle-multipart-ctl-parameter handle 'buffer)
1328 (let* ((mm-verify-option 'known)
1329 (mm-decrypt-option 'known)
1330 (new (mm-possibly-verify-or-decrypt (cdr handle) handle)))
1331 (unless (eq new (cdr handle))
1332 (mm-destroy-parts (cdr handle))
1333 (setcdr handle new))))
1334 (mh-mime-display-security handle)
1335 (goto-char point))))
1154 1336
1155;; These variables should already be initialized in mm-decode.el if we have a 1337;; These variables should already be initialized in mm-decode.el if we have a
1156;; recent enough Gnus. The defvars are here to avoid compiler warnings. 1338;; recent enough Gnus. The defvars are here to avoid compiler warnings.
@@ -1191,6 +1373,8 @@ Parameter EL is unused."
1191 :action 'mh-widget-press-button 1373 :action 'mh-widget-press-button
1192 :button-keymap mh-mime-security-button-map 1374 :button-keymap mh-mime-security-button-map
1193 :help-echo "Mouse-2 click or press RET (in show buffer) to see security details.") 1375 :help-echo "Mouse-2 click or press RET (in show buffer) to see security details.")
1376 (dolist (ov (mh-funcall-if-exists overlays-in begin end))
1377 (mh-funcall-if-exists overlay-put ov 'evaporate t))
1194 (when (equal info "Failed") 1378 (when (equal info "Failed")
1195 (let* ((type (if (equal (car handle) "multipart/signed") 1379 (let* ((type (if (equal (car handle) "multipart/signed")
1196 "verification" "decryption")) 1380 "verification" "decryption"))
@@ -1204,8 +1388,8 @@ The function decodes the message and displays it. It avoids decoding the same
1204message multiple times." 1388message multiple times."
1205 (let ((b (point)) 1389 (let ((b (point))
1206 (clean-message-header mh-clean-message-header-flag) 1390 (clean-message-header mh-clean-message-header-flag)
1207 (invisible-headers mh-invisible-headers) 1391 (invisible-headers mh-invisible-header-fields-compiled)
1208 (visible-headers mh-visible-headers)) 1392 (visible-headers nil))
1209 (save-excursion 1393 (save-excursion
1210 (save-restriction 1394 (save-restriction
1211 (narrow-to-region b b) 1395 (narrow-to-region b b)
diff --git a/lisp/mh-e/mh-pick.el b/lisp/mh-e/mh-pick.el
index a888f02154f..b92a98f26cc 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, 2003 Free Software Foundation, Inc. 3;; Copyright (C) 1993, 1995, 2001, 2003, 2004 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,6 +32,8 @@
32 32
33;;; Code: 33;;; Code:
34 34
35(eval-when-compile (require 'mh-acros))
36(mh-require-cl)
35(require 'mh-e) 37(require 'mh-e)
36(require 'easymenu) 38(require 'easymenu)
37(require 'gnus-util) 39(require 'gnus-util)
@@ -44,6 +46,9 @@
44(defvar mh-searching-folder nil) ;Folder this pick is searching. 46(defvar mh-searching-folder nil) ;Folder this pick is searching.
45(defvar mh-searching-function nil) 47(defvar mh-searching-function nil)
46 48
49(defconst mh-pick-single-dash '(cc date from subject to)
50 "Search components that are supported by single-dash option in pick.")
51
47;;;###mh-autoload 52;;;###mh-autoload
48(defun mh-search-folder (folder window-config) 53(defun mh-search-folder (folder window-config)
49 "Search FOLDER for messages matching a pattern. 54 "Search FOLDER for messages matching a pattern.
@@ -139,16 +144,6 @@ with no arguments, upon entry to this mode.
139 (run-hooks 'mh-pick-mode-hook)) 144 (run-hooks 'mh-pick-mode-hook))
140 145
141;;;###mh-autoload 146;;;###mh-autoload
142(defun mh-do-pick-search ()
143 "Find messages that match the qualifications in the current pattern buffer.
144Messages are searched for in the folder named in `mh-searching-folder'.
145Add the messages found to the sequence named `search'.
146
147This is a deprecated function and `mh-pick-do-search' should be used instead."
148 (interactive)
149 (mh-pick-do-search))
150
151;;;###mh-autoload
152(defun mh-pick-do-search () 147(defun mh-pick-do-search ()
153 "Find messages that match the qualifications in the current pattern buffer. 148 "Find messages that match the qualifications in the current pattern buffer.
154Messages are searched for in the folder named in `mh-searching-folder'. 149Messages are searched for in the folder named in `mh-searching-folder'.
@@ -260,6 +255,13 @@ COMPONENT is the component to search."
260 "-rbrace")) 255 "-rbrace"))
261 (t (error "Unknown operator '%s' seen" (car expr))))) 256 (t (error "Unknown operator '%s' seen" (car expr)))))
262 257
258;; All implementations of pick have special options -cc, -date, -from and
259;; -subject that allow to search for corresponding components. Any other
260;; component is searched using option --COMPNAME, for example: `pick
261;; --x-mailer mh-e'. Mailutils `pick' supports this option using a certain
262;; kludge, but it prefers the following syntax for this purpose:
263;; `--component=COMPNAME --pattern=PATTERN'.
264;; -- Sergey Poznyakoff, Aug 2003
263(defun mh-pick-regexp-builder (pattern-list) 265(defun mh-pick-regexp-builder (pattern-list)
264 "Generate pick search expression from PATTERN-LIST." 266 "Generate pick search expression from PATTERN-LIST."
265 (let ((result ())) 267 (let ((result ()))
@@ -267,9 +269,18 @@ COMPONENT is the component to search."
267 (when (cdr pattern) 269 (when (cdr pattern)
268 (setq result `(,@result "-and" "-lbrace" 270 (setq result `(,@result "-and" "-lbrace"
269 ,@(mh-pick-construct-regexp 271 ,@(mh-pick-construct-regexp
270 (cdr pattern) (if (car pattern) 272 (if (and (mh-variant-p 'mu-mh) (car pattern))
271 (format "-%s" (car pattern)) 273 (format "--pattern=%s" (cdr pattern))
272 "-search")) 274 (cdr pattern))
275 (if (car pattern)
276 (cond
277 ((mh-variant-p 'mu-mh)
278 (format "--component=%s" (car pattern)))
279 ((member (car pattern) mh-pick-single-dash)
280 (format "-%s" (car pattern)))
281 (t
282 (format "--%s" (car pattern))))
283 "-search"))
273 "-rbrace")))) 284 "-rbrace"))))
274 (cdr result))) 285 (cdr result)))
275 286
diff --git a/lisp/mh-e/mh-print.el b/lisp/mh-e/mh-print.el
new file mode 100644
index 00000000000..7539e455919
--- /dev/null
+++ b/lisp/mh-e/mh-print.el
@@ -0,0 +1,279 @@
1;;; mh-print.el --- MH-E printing support
2
3;; Copyright (C) 2003, 2004 Free Software Foundation, Inc.
4
5;; Author: Jeffrey C Honig <jch@honig.net>
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;; Pp Print to lpr | Default inline settings
29;; Pf Print to file | Generate a postscript file
30;; Ps Print show buffer | Fails if no show buffer
31;;
32;; PA Toggle inline/attachments
33;; PC Toggle color
34;; PF Toggle faces
35
36;;; Change Log:
37
38;;; Code:
39
40(eval-when-compile (require 'mh-acros))
41(mh-require-cl)
42(require 'ps-print)
43(require 'mh-utils)
44(require 'mh-funcs)
45(eval-when-compile (require 'mh-seq))
46
47(defvar mh-ps-print-mime nil
48 "Control printing of MIME parts.
49The three possible states are:
50 1. nil to not print inline parts
51 2. t to print inline parts
52 3. non-zero to print inline parts and attachments")
53
54(defvar mh-ps-print-color-option ps-print-color-p
55 "MH-E's version of `\\[ps-print-color-p]'.")
56
57(defvar mh-ps-print-func 'ps-spool-buffer-with-faces
58 "Function to use to spool a buffer.
59Sensible choices are the functions `ps-spool-buffer' and
60`ps-spool-buffer-with-faces'.")
61
62;; XXX - If buffer is already being displayed, use that buffer
63;; XXX - What about showing MIME content?
64;; XXX - Default print buffer is bogus
65(defun mh-ps-spool-buffer (buffer)
66 "Send BUFFER to printer queue."
67 (message (format "mh-ps-spool-buffer %s" buffer))
68 (save-excursion
69 (set-buffer buffer)
70 (let ((ps-print-color-p mh-ps-print-color-option)
71 (ps-left-header
72 (list
73 (concat "("
74 (mh-get-header-field "Subject:") ")")
75 (concat "("
76 (mh-get-header-field "From:") ")")))
77 (ps-right-header
78 (list
79 "/pagenumberstring load"
80 (concat "("
81 (mh-get-header-field "Date:") ")"))))
82 (funcall mh-ps-print-func))))
83
84(defun mh-ps-spool-a-msg (msg buffer)
85 "Print MSG.
86First the message is decoded in BUFFER before the results are sent to the
87printer."
88 (message (format "mh-ps-spool-a-msg msg %s buffer %s"
89 msg buffer))
90 (let ((mh-show-buffer mh-show-buffer)
91 (folder mh-current-folder)
92 ;; The following is commented out because
93 ;; `clean-message-header-flag' isn't used anywhere. I
94 ;; commented rather than deleted in case somebody had some
95 ;; future plans for it. --SY.
96 ;(clean-message-header-flag mh-clean-message-header-flag)
97 )
98 (unwind-protect
99 (progn
100 (setq mh-show-buffer buffer)
101 (save-excursion
102 ;;
103 ;; XXX - Use setting of mh-ps-print-mime
104 ;;
105 (mh-display-msg msg folder)
106 (mh-ps-spool-buffer mh-show-buffer)
107 (kill-buffer mh-show-buffer))))))
108
109;;;###mh-autoload
110(defun mh-ps-print-msg (range)
111 "Print the messages in RANGE.
112
113Check the documentation of `mh-interactive-range' to see how RANGE is read in
114interactive use."
115 (interactive (list (mh-interactive-range "Print")))
116 (message (format "mh-ps-print-msg range %s keys %s"
117 range (this-command-keys)))
118 (mh-iterate-on-range msg range
119 (let ((buffer (get-buffer-create mh-temp-buffer)))
120 (unwind-protect
121 (mh-ps-spool-a-msg msg buffer)
122 (kill-buffer buffer)))
123 (mh-notate nil mh-note-printed mh-cmd-note))
124 (ps-despool nil))
125
126(defun mh-ps-print-preprint (prefix-arg)
127 "Replacement for `ps-print-preprint'.
128The original function does not handle the fact that MH folders are directories
129nicely, when generating the default file name. This function works around
130that. The function is passed the interactive PREFIX-ARG."
131 (let ((buffer-file-name (format "/tmp/%s" (substring (buffer-name) 1))))
132 (ps-print-preprint prefix-arg)))
133
134;;;###mh-autoload
135(defun mh-ps-print-msg-file (file range)
136 "Print to FILE the messages in RANGE.
137
138Check the documentation of `mh-interactive-range' to see how RANGE is read in
139interactive use."
140 (interactive (list
141 (mh-ps-print-preprint 1)
142 (mh-interactive-range "Print")))
143 (mh-iterate-on-range msg range
144 (let ((buffer (get-buffer-create mh-temp-buffer)))
145 (unwind-protect
146 (mh-ps-spool-a-msg msg buffer)
147 (kill-buffer buffer)))
148 (mh-notate nil mh-note-printed mh-cmd-note))
149 (ps-despool file))
150
151;;;###mh-autoload
152(defun mh-ps-print-msg-show (file)
153 "Print current show buffer to FILE."
154 (interactive (list (mh-ps-print-preprint current-prefix-arg)))
155 (message (format "mh-ps-print-msg-show file %s keys %s mh-show-buffer %s"
156 file (this-command-keys) mh-show-buffer))
157 (let ((msg (mh-get-msg-num t))
158 (folder mh-current-folder)
159 (show-buffer mh-show-buffer)
160 (show-window (get-buffer-window mh-show-buffer)))
161 (if (and show-buffer show-window)
162 (mh-in-show-buffer (show-buffer)
163 (if (equal (mh-msg-filename msg folder) buffer-file-name)
164 (progn
165 (mh-ps-spool-buffer show-buffer)
166 (ps-despool file))
167 (message "Current message is not being shown(1).")))
168 (message "Current message is not being shown(2)."))))
169
170;;;###mh-autoload
171(defun mh-ps-print-toggle-faces ()
172 "Toggle whether printing is done with faces or not."
173 (interactive)
174 (if (eq mh-ps-print-func 'ps-spool-buffer-with-faces)
175 (progn
176 (setq mh-ps-print-func 'ps-spool-buffer)
177 (message "Printing without faces"))
178 (setq mh-ps-print-func 'ps-spool-buffer-with-faces)
179 (message "Printing with faces")))
180
181;;;###mh-autoload
182(defun mh-ps-print-toggle-color ()
183 "Toggle whether color is used in printing messages."
184 (interactive)
185 (if (eq mh-ps-print-color-option nil)
186 (progn
187 (setq mh-ps-print-color-option 'black-white)
188 (message "Colors will be printed as black & white."))
189 (if (eq mh-ps-print-color-option 'black-white)
190 (progn
191 (setq mh-ps-print-color-option t)
192 (message "Colors will be printed."))
193 (setq mh-ps-print-color-option nil)
194 (message "Colors will not be printed."))))
195
196;;; XXX: Check option 3. Documentation doesn't sound right.
197;;;###mh-autoload
198(defun mh-ps-print-toggle-mime ()
199 "Cycle through available choices on how MIME parts should be printed.
200The available settings are:
201 1. Print only inline MIME parts.
202 2. Print all MIME parts.
203 3. Print no MIME parts."
204 (interactive)
205 (if (eq mh-ps-print-mime nil)
206 (progn
207 (setq mh-ps-print-mime t)
208 (message "Inline parts will be printed, attachments will not be printed."))
209 (if (eq mh-ps-print-mime t)
210 (progn
211 (setq mh-ps-print-mime 1)
212 (message "Both Inline parts and attachments will be printed."))
213 (setq mh-ps-print-mime nil)
214 (message "Neither inline parts nor attachments will be printed."))))
215
216;;; Old non-PS based printing
217;;;###mh-autoload
218(defun mh-print-msg (range)
219 "Print RANGE on printer.
220
221Check the documentation of `mh-interactive-range' to see how RANGE is read in
222interactive use.
223
224The variable `mh-lpr-command-format' is used to generate the print command.
225The messages are formatted by mhl. See the variable `mhl-formfile'."
226 (interactive (list (mh-interactive-range "Print")))
227 (message "Printing...")
228 (let (msgs)
229 ;; Gather message numbers and add them to "printed" sequence.
230 (mh-iterate-on-range msg range
231 (mh-add-msgs-to-seq msg 'printed t)
232 (mh-notate nil mh-note-printed mh-cmd-note)
233 (push msg msgs))
234 (setq msgs (nreverse msgs))
235 ;; Print scan listing if we have more than one message.
236 (if (> (length msgs) 1)
237 (let* ((msgs-string
238 (mapconcat 'identity (mh-list-to-string
239 (mh-coalesce-msg-list msgs)) " "))
240 (lpr-command
241 (format mh-lpr-command-format
242 (cond ((listp range)
243 (format "Folder: %s, Messages: %s"
244 mh-current-folder msgs-string))
245 ((symbolp range)
246 (format "Folder: %s, Sequence: %s"
247 mh-current-folder range)))))
248 (scan-command
249 (format "scan %s | %s" msgs-string lpr-command)))
250 (if mh-print-background-flag
251 (mh-exec-cmd-daemon shell-file-name nil "-c" scan-command)
252 (call-process shell-file-name nil nil nil "-c" scan-command))))
253 ;; Print the messages
254 (dolist (msg msgs)
255 (let* ((mhl-command (format "%s %s %s"
256 (expand-file-name "mhl" mh-lib-progs)
257 (if mhl-formfile
258 (format " -form %s" mhl-formfile)
259 "")
260 (mh-msg-filename msg)))
261 (lpr-command
262 (format mh-lpr-command-format
263 (format "%s/%s" mh-current-folder msg)))
264 (print-command
265 (format "%s | %s" mhl-command lpr-command)))
266 (if mh-print-background-flag
267 (mh-exec-cmd-daemon shell-file-name nil "-c" print-command)
268 (call-process shell-file-name nil nil nil "-c" print-command)))))
269 (message "Printing...done"))
270
271(provide 'mh-print)
272
273;;; Local Variables:
274;;; indent-tabs-mode: nil
275;;; sentence-end-double-space: nil
276;;; End:
277
278;; arch-tag: 8d84d50b-2a49-4d0d-b51e-ba9c9b6fc679
279;;; mh-print.el ends here
diff --git a/lisp/mh-e/mh-seq.el b/lisp/mh-e/mh-seq.el
index 20950d36c4c..8d2369ed19a 100644
--- a/lisp/mh-e/mh-seq.el
+++ b/lisp/mh-e/mh-seq.el
@@ -70,7 +70,7 @@
70 70
71;;; Code: 71;;; Code:
72 72
73(require 'mh-utils) 73(eval-when-compile (require 'mh-acros))
74(mh-require-cl) 74(mh-require-cl)
75(require 'mh-e) 75(require 'mh-e)
76 76
@@ -78,15 +78,15 @@
78(defvar tool-bar-mode) 78(defvar tool-bar-mode)
79 79
80;;; Data structures (used in message threading)... 80;;; Data structures (used in message threading)...
81(defstruct (mh-thread-message (:conc-name mh-message-) 81(mh-defstruct (mh-thread-message (:conc-name mh-message-)
82 (:constructor mh-thread-make-message)) 82 (:constructor mh-thread-make-message))
83 (id nil) 83 (id nil)
84 (references ()) 84 (references ())
85 (subject "") 85 (subject "")
86 (subject-re-p nil)) 86 (subject-re-p nil))
87 87
88(defstruct (mh-thread-container (:conc-name mh-container-) 88(mh-defstruct (mh-thread-container (:conc-name mh-container-)
89 (:constructor mh-thread-make-container)) 89 (:constructor mh-thread-make-container))
90 message parent children 90 message parent children
91 (real-child-p t)) 91 (real-child-p t))
92 92
@@ -201,12 +201,15 @@ redone to get the new thread tree. This makes incremental threading easier.")
201 201
202;;;###mh-autoload 202;;;###mh-autoload
203(defun mh-msg-is-in-seq (message) 203(defun mh-msg-is-in-seq (message)
204 "Display the sequences that contain MESSAGE. 204 "Display the sequences in which the current message appears.
205Default is the displayed message." 205Use a prefix argument to display the sequences in which another MESSAGE
206 (interactive (list (mh-get-msg-num t))) 206appears."
207 (interactive "P")
208 (if (not message)
209 (setq message (mh-get-msg-num t)))
207 (let* ((dest-folder (loop for seq in mh-refile-list 210 (let* ((dest-folder (loop for seq in mh-refile-list
208 until (member message (cdr seq)) 211 when (member message (cdr seq)) return (car seq)
209 finally return (car seq))) 212 finally return nil))
210 (deleted-flag (unless dest-folder (member message mh-delete-list)))) 213 (deleted-flag (unless dest-folder (member message mh-delete-list))))
211 (message "Message %d%s is in sequences: %s" 214 (message "Message %d%s is in sequences: %s"
212 message 215 message
@@ -269,12 +272,11 @@ interactive use."
269 (let* ((internal-seq-flag (mh-internal-seq sequence)) 272 (let* ((internal-seq-flag (mh-internal-seq sequence))
270 (original-msgs (mh-seq-msgs (mh-find-seq sequence))) 273 (original-msgs (mh-seq-msgs (mh-find-seq sequence)))
271 (folders (list mh-current-folder)) 274 (folders (list mh-current-folder))
272 (msg-list ())) 275 (msg-list (mh-range-to-msg-list range)))
276 (mh-add-msgs-to-seq msg-list sequence nil t)
273 (mh-iterate-on-range m range 277 (mh-iterate-on-range m range
274 (push m msg-list)
275 (unless (memq m original-msgs) 278 (unless (memq m original-msgs)
276 (mh-add-sequence-notation m internal-seq-flag))) 279 (mh-add-sequence-notation m internal-seq-flag)))
277 (mh-add-msgs-to-seq msg-list sequence nil t)
278 (if (not internal-seq-flag) 280 (if (not internal-seq-flag)
279 (setq mh-last-seq-used sequence)) 281 (setq mh-last-seq-used sequence))
280 (when mh-index-data 282 (when mh-index-data
@@ -292,10 +294,8 @@ OP is one of 'widen and 'unthread."
292 294
293;;;###mh-autoload 295;;;###mh-autoload
294(defun mh-widen (&optional all-flag) 296(defun mh-widen (&optional all-flag)
295 "Remove last restriction from current folder. 297 "Restore the previous limit.
296If optional prefix argument ALL-FLAG is non-nil, then unwind to the beginning 298If optional prefix argument ALL-FLAG is non-nil, remove all limits."
297of the view stack thereby showing all messages that the buffer originally
298contained."
299 (interactive "P") 299 (interactive "P")
300 (let ((msg (mh-get-msg-num nil))) 300 (let ((msg (mh-get-msg-num nil)))
301 (when mh-folder-view-stack 301 (when mh-folder-view-stack
@@ -533,28 +533,6 @@ should be replaced with:
533 (rplaca old-seq new-name))) 533 (rplaca old-seq new-name)))
534 534
535;;;###mh-autoload 535;;;###mh-autoload
536(defun mh-map-to-seq-msgs (func seq &rest args)
537 "Invoke the FUNC at each message in the SEQ.
538SEQ can either be a list of messages or a MH sequence. The remaining ARGS are
539passed as arguments to FUNC."
540 (save-excursion
541 (let ((msgs (if (listp seq) seq (mh-seq-to-msgs seq))))
542 (while msgs
543 (if (mh-goto-msg (car msgs) t t)
544 (apply func (car msgs) args))
545 (setq msgs (cdr msgs))))))
546
547;;;###mh-autoload
548(defun mh-notate-seq (seq notation offset)
549 "Mark the scan listing.
550All messages in SEQ are marked with NOTATION at OFFSET from the beginning of
551the line."
552 (let ((msg-list (mh-seq-to-msgs seq)))
553 (mh-iterate-on-messages-in-region msg (point-min) (point-max)
554 (when (member msg msg-list)
555 (mh-notate nil notation offset)))))
556
557;;;###mh-autoload
558(defun mh-notate-cur () 536(defun mh-notate-cur ()
559 "Mark the MH sequence cur. 537 "Mark the MH sequence cur.
560In addition to notating the current message with `mh-note-cur' the function 538In addition to notating the current message with `mh-note-cur' the function
@@ -577,14 +555,6 @@ uses `overlay-arrow-position' to put a marker in the fringe."
577 "-sequence" (symbol-name seq) 555 "-sequence" (symbol-name seq)
578 (mh-coalesce-msg-list msgs))))) 556 (mh-coalesce-msg-list msgs)))))
579 557
580;; This has a tricky bug. mh-map-to-seq-msgs uses mh-goto-msg, which assumes
581;; that the folder buffer is sorted. However in this case that assumption
582;; doesn't hold. So we will do this the dumb way.
583;(defun mh-copy-seq-to-point (seq location)
584; ;; Copy the scan listing of the messages in SEQUENCE to after the point
585; ;; LOCATION in the current buffer.
586; (mh-map-to-seq-msgs 'mh-copy-line-to-point seq location))
587
588(defvar mh-thread-last-ancestor) 558(defvar mh-thread-last-ancestor)
589 559
590(defun mh-copy-seq-to-eob (seq) 560(defun mh-copy-seq-to-eob (seq)
@@ -614,21 +584,6 @@ uses `overlay-arrow-position' to put a marker in the fringe."
614 (mh-index-data 584 (mh-index-data
615 (mh-index-insert-folder-headers))))))) 585 (mh-index-insert-folder-headers)))))))
616 586
617(defun mh-copy-line-to-point (msg location)
618 "Copy current message line to a specific location.
619The argument MSG is not used. The message in the current line is copied to
620LOCATION."
621 ;; msg is not used?
622 ;; Copy the current line to the LOCATION in the current buffer.
623 (beginning-of-line)
624 (save-excursion
625 (let ((beginning-of-line (point))
626 end)
627 (forward-line 1)
628 (setq end (point))
629 (goto-char location)
630 (insert-buffer-substring (current-buffer) beginning-of-line end))))
631
632;;;###mh-autoload 587;;;###mh-autoload
633(defmacro mh-iterate-on-messages-in-region (var begin end &rest body) 588(defmacro mh-iterate-on-messages-in-region (var begin end &rest body)
634 "Iterate over region. 589 "Iterate over region.
@@ -702,7 +657,7 @@ a region in a cons cell."
702 (nreverse msg-list))) 657 (nreverse msg-list)))
703 658
704;;;###mh-autoload 659;;;###mh-autoload
705(defun mh-interactive-range (range-prompt) 660(defun mh-interactive-range (range-prompt &optional default)
706 "Return interactive specification for message, sequence, range or region. 661 "Return interactive specification for message, sequence, range or region.
707By convention, the name of this argument is RANGE. 662By convention, the name of this argument is RANGE.
708 663
@@ -715,24 +670,17 @@ RANGE-PROMPT. A list of messages in that range is returned.
715If a MH range is given, say something like last:20, then a list containing 670If a MH range is given, say something like last:20, then a list containing
716the messages in that range is returned. 671the messages in that range is returned.
717 672
673If DEFAULT non-nil then it is returned.
674
718Otherwise, the message number at point is returned. 675Otherwise, the message number at point is returned.
719 676
720This function is usually used with `mh-iterate-on-range' in order to provide 677This function is usually used with `mh-iterate-on-range' in order to provide
721a uniform interface to MH-E functions." 678a uniform interface to MH-E functions."
722 (cond ((mh-mark-active-p t) (cons (region-beginning) (region-end))) 679 (cond ((mh-mark-active-p t) (cons (region-beginning) (region-end)))
723 (current-prefix-arg (mh-read-range range-prompt nil nil t t)) 680 (current-prefix-arg (mh-read-range range-prompt nil nil t t))
681 (default default)
724 (t (mh-get-msg-num t)))) 682 (t (mh-get-msg-num t))))
725 683
726;;;###mh-autoload
727(defun mh-region-to-msg-list (begin end)
728 "Return a list of messages within the region between BEGIN and END."
729 ;; If end is end of buffer back up one position
730 (setq end (if (equal end (point-max)) (1- end) end))
731 (let ((result))
732 (mh-iterate-on-messages-in-region index begin end
733 (when (numberp index) (push index result)))
734 result))
735
736 684
737 685
738;;; Commands to handle new 'subject sequence. 686;;; Commands to handle new 'subject sequence.
@@ -772,7 +720,7 @@ Return number of messages put in the sequence:
772 (if (or (not (looking-at mh-scan-subject-regexp)) 720 (if (or (not (looking-at mh-scan-subject-regexp))
773 (not (match-string 3)) 721 (not (match-string 3))
774 (string-equal "" (match-string 3))) 722 (string-equal "" (match-string 3)))
775 (progn (message "No subject line.") 723 (progn (message "No subject line")
776 nil) 724 nil)
777 (let ((subject (match-string-no-properties 3)) 725 (let ((subject (match-string-no-properties 3))
778 (list)) 726 (list))
@@ -835,61 +783,57 @@ This function can only be used the folder is threaded."
835 (mh-container-message (gethash (gethash msg mh-thread-index-id-map) 783 (mh-container-message (gethash (gethash msg mh-thread-index-id-map)
836 mh-thread-id-table))))) 784 mh-thread-id-table)))))
837 785
838;;;###mh-autoload 786(defun mh-edit-pick-expr (default)
839(defun mh-narrow-to-subject () 787 "With prefix arg edit a pick expression.
840 "Narrow to a sequence containing all following messages with same subject."
841 (interactive)
842 (let ((num (mh-get-msg-num nil))
843 (count (mh-subject-to-sequence t)))
844 (cond
845 ((not count) ; No subject line, delete msg anyway
846 nil)
847 ((= 0 count) ; No other msgs, delete msg anyway.
848 (message "No other messages with same Subject following this one.")
849 nil)
850 (t ; We have a subject sequence.
851 (message "Found %d messages for subject sequence." count)
852 (mh-narrow-to-seq 'subject)
853 (if (numberp num)
854 (mh-goto-msg num t t))))))
855
856(defun mh-read-pick-regexp (default)
857 "With prefix arg read a pick regexp.
858If no prefix arg is given, then return DEFAULT." 788If no prefix arg is given, then return DEFAULT."
859 (let ((default-string (loop for x in default concat (format " %s" x)))) 789 (let ((default-string (loop for x in default concat (format " %s" x))))
860 (if (or current-prefix-arg (equal default-string "")) 790 (if (or current-prefix-arg (equal default-string ""))
861 (delete "" (split-string (read-string "Pick regexp: " default-string))) 791 (delete "" (split-string (read-string "Pick expression: "
792 default-string)))
862 default))) 793 default)))
863 794
864;;;###mh-autoload 795;;;###mh-autoload
865(defun mh-narrow-to-from (&optional regexp) 796(defun mh-narrow-to-subject (&optional pick-expr)
866 "Limit to messages with the same From header field as the message at point. 797 "Limit to messages with same subject.
867With a prefix argument, prompt for the regular expression, REGEXP given to 798With a prefix argument, edit PICK-EXPR.
868pick." 799
800Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command."
869 (interactive 801 (interactive
870 (list (mh-read-pick-regexp (mh-current-message-header-field 'from)))) 802 (list (mh-edit-pick-expr (mh-current-message-header-field 'subject))))
871 (mh-narrow-to-header-field 'from regexp)) 803 (mh-narrow-to-header-field 'subject pick-expr))
872 804
873;;;###mh-autoload 805;;;###mh-autoload
874(defun mh-narrow-to-cc (&optional regexp) 806(defun mh-narrow-to-from (&optional pick-expr)
875 "Limit to messages with the same Cc header field as the message at point. 807 "Limit to messages with the same `From:' field.
876With a prefix argument, prompt for the regular expression, REGEXP given to 808With a prefix argument, edit PICK-EXPR.
877pick." 809
810Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command."
878 (interactive 811 (interactive
879 (list (mh-read-pick-regexp (mh-current-message-header-field 'cc)))) 812 (list (mh-edit-pick-expr (mh-current-message-header-field 'from))))
880 (mh-narrow-to-header-field 'cc regexp)) 813 (mh-narrow-to-header-field 'from pick-expr))
881 814
882;;;###mh-autoload 815;;;###mh-autoload
883(defun mh-narrow-to-to (&optional regexp) 816(defun mh-narrow-to-cc (&optional pick-expr)
884 "Limit to messages with the same To header field as the message at point. 817 "Limit to messages with the same `Cc:' field.
885With a prefix argument, prompt for the regular expression, REGEXP given to 818With a prefix argument, edit PICK-EXPR.
886pick." 819
820Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command."
887 (interactive 821 (interactive
888 (list (mh-read-pick-regexp (mh-current-message-header-field 'to)))) 822 (list (mh-edit-pick-expr (mh-current-message-header-field 'cc))))
889 (mh-narrow-to-header-field 'to regexp)) 823 (mh-narrow-to-header-field 'cc pick-expr))
890 824
891(defun mh-narrow-to-header-field (header-field regexp) 825;;;###mh-autoload
892 "Limit to messages whose HEADER-FIELD match REGEXP. 826(defun mh-narrow-to-to (&optional pick-expr)
827 "Limit to messages with the same `To:' field.
828With a prefix argument, edit PICK-EXPR.
829
830Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command."
831 (interactive
832 (list (mh-edit-pick-expr (mh-current-message-header-field 'to))))
833 (mh-narrow-to-header-field 'to pick-expr))
834
835(defun mh-narrow-to-header-field (header-field pick-expr)
836 "Limit to messages whose HEADER-FIELD match PICK-EXPR.
893The MH command pick is used to do the match." 837The MH command pick is used to do the match."
894 (let ((folder mh-current-folder) 838 (let ((folder mh-current-folder)
895 (original (mh-coalesce-msg-list 839 (original (mh-coalesce-msg-list
@@ -897,7 +841,7 @@ The MH command pick is used to do the match."
897 (msg-list ())) 841 (msg-list ()))
898 (with-temp-buffer 842 (with-temp-buffer
899 (apply #'mh-exec-cmd-output "pick" nil folder 843 (apply #'mh-exec-cmd-output "pick" nil folder
900 (append original (list "-list") regexp)) 844 (append original (list "-list") pick-expr))
901 (goto-char (point-min)) 845 (goto-char (point-min))
902 (while (not (eobp)) 846 (while (not (eobp))
903 (let ((num (read-from-string 847 (let ((num (read-from-string
@@ -939,7 +883,9 @@ The MH command pick is used to do the match."
939 "Limit to messages in RANGE. 883 "Limit to messages in RANGE.
940 884
941Check the documentation of `mh-interactive-range' to see how RANGE is read in 885Check the documentation of `mh-interactive-range' to see how RANGE is read in
942interactive use." 886interactive use.
887
888Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command."
943 (interactive (list (mh-interactive-range "Narrow to"))) 889 (interactive (list (mh-interactive-range "Narrow to")))
944 (when (assoc 'range mh-seq-list) (mh-delete-seq 'range)) 890 (when (assoc 'range mh-seq-list) (mh-delete-seq 'range))
945 (mh-add-msgs-to-seq (mh-range-to-msg-list range) 'range) 891 (mh-add-msgs-to-seq (mh-range-to-msg-list range) 'range)
@@ -958,7 +904,7 @@ subject sequence."
958 ((not count) ; No subject line, delete msg anyway 904 ((not count) ; No subject line, delete msg anyway
959 (mh-delete-msg (mh-get-msg-num t))) 905 (mh-delete-msg (mh-get-msg-num t)))
960 ((= 0 count) ; No other msgs, delete msg anyway. 906 ((= 0 count) ; No other msgs, delete msg anyway.
961 (message "No other messages with same Subject following this one.") 907 (message "No other messages with same Subject following this one")
962 (mh-delete-msg (mh-get-msg-num t))) 908 (mh-delete-msg (mh-get-msg-num t)))
963 (t ; We have a subject sequence. 909 (t ; We have a subject sequence.
964 (message "Marked %d messages for deletion" count) 910 (message "Marked %d messages for deletion" count)
@@ -1078,13 +1024,12 @@ SUBJECT and REFS fields."
1078 message) 1024 message)
1079 (container 1025 (container
1080 (setf (mh-container-message container) 1026 (setf (mh-container-message container)
1081 (mh-thread-make-message :subject subject 1027 (mh-thread-make-message :id id :references refs
1082 :subject-re-p subject-re-p 1028 :subject subject
1083 :id id :references refs))) 1029 :subject-re-p subject-re-p)))
1084 (t (let ((message (mh-thread-make-message 1030 (t (let ((message (mh-thread-make-message :id id :references refs
1085 :subject subject 1031 :subject-re-p subject-re-p
1086 :subject-re-p subject-re-p 1032 :subject subject)))
1087 :id id :references refs)))
1088 (prog1 message 1033 (prog1 message
1089 (mh-thread-get-message-container message))))))) 1034 (mh-thread-get-message-container message)))))))
1090 1035
@@ -1450,8 +1395,7 @@ MSG is the message being notated with NOTATION at OFFSET."
1450 (cur-scan-line (and mh-thread-scan-line-map 1395 (cur-scan-line (and mh-thread-scan-line-map
1451 (gethash msg mh-thread-scan-line-map))) 1396 (gethash msg mh-thread-scan-line-map)))
1452 (old-scan-lines (loop for map in mh-thread-scan-line-map-stack 1397 (old-scan-lines (loop for map in mh-thread-scan-line-map-stack
1453 collect (and map (gethash msg map)))) 1398 collect (and map (gethash msg map)))))
1454 (notation (if (stringp notation) (aref notation 0) notation)))
1455 (when cur-scan-line 1399 (when cur-scan-line
1456 (setf (aref (car cur-scan-line) offset) notation)) 1400 (setf (aref (car cur-scan-line) offset) notation))
1457 (dolist (line old-scan-lines) 1401 (dolist (line old-scan-lines)
@@ -1486,7 +1430,8 @@ MSG is the message being notated with NOTATION at OFFSET."
1486 (setf (gethash msg mh-thread-scan-line-map) v)))) 1430 (setf (gethash msg mh-thread-scan-line-map) v))))
1487 (when (> (hash-table-count mh-thread-scan-line-map) 0) 1431 (when (> (hash-table-count mh-thread-scan-line-map) 0)
1488 (insert (if (bobp) "" "\n") (car x) "\n") 1432 (insert (if (bobp) "" "\n") (car x) "\n")
1489 (mh-thread-generate-scan-lines thread-tree -2))))))) 1433 (mh-thread-generate-scan-lines thread-tree -2))))
1434 (mh-index-create-imenu-index))))
1490 1435
1491(defun mh-thread-folder () 1436(defun mh-thread-folder ()
1492 "Generate thread view of folder." 1437 "Generate thread view of folder."
@@ -1711,11 +1656,12 @@ start of the region and the second is the point at the end."
1711 (push msg unticked) 1656 (push msg unticked)
1712 (setcdr tick-seq (delq msg (cdr tick-seq))) 1657 (setcdr tick-seq (delq msg (cdr tick-seq)))
1713 (when (null (cdr tick-seq)) (setq mh-last-seq-used nil)) 1658 (when (null (cdr tick-seq)) (setq mh-last-seq-used nil))
1714 (mh-remove-sequence-notation msg t)) 1659 (mh-remove-sequence-notation msg (mh-colors-in-use-p)))
1715 (t 1660 (t
1716 (push msg ticked) 1661 (push msg ticked)
1717 (setq mh-last-seq-used mh-tick-seq) 1662 (setq mh-last-seq-used mh-tick-seq)
1718 (mh-add-sequence-notation msg t)))) 1663 (let ((mh-seq-list (cons `(,mh-tick-seq ,msg) mh-seq-list)))
1664 (mh-add-sequence-notation msg (mh-colors-in-use-p))))))
1719 (mh-add-msgs-to-seq ticked mh-tick-seq nil t) 1665 (mh-add-msgs-to-seq ticked mh-tick-seq nil t)
1720 (mh-undefine-sequence mh-tick-seq unticked) 1666 (mh-undefine-sequence mh-tick-seq unticked)
1721 (when mh-index-data 1667 (when mh-index-data
@@ -1724,16 +1670,16 @@ start of the region and the second is the point at the end."
1724 1670
1725;;;###mh-autoload 1671;;;###mh-autoload
1726(defun mh-narrow-to-tick () 1672(defun mh-narrow-to-tick ()
1727 "Restrict display of this folder to just messages in `mh-tick-seq'. 1673 "Limit to messages in `mh-tick-seq'.
1674
1728Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command." 1675Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command."
1729 (interactive) 1676 (interactive)
1730 (cond ((not mh-tick-seq) 1677 (cond ((not mh-tick-seq)
1731 (error "Enable ticking by customizing `mh-tick-seq'")) 1678 (error "Enable ticking by customizing `mh-tick-seq'"))
1732 ((null (mh-seq-msgs (mh-find-seq mh-tick-seq))) 1679 ((null (mh-seq-msgs (mh-find-seq mh-tick-seq)))
1733 (message "No messages in tick sequence")) 1680 (message "No messages in %s sequence" mh-tick-seq))
1734 (t (mh-narrow-to-seq mh-tick-seq)))) 1681 (t (mh-narrow-to-seq mh-tick-seq))))
1735 1682
1736
1737(provide 'mh-seq) 1683(provide 'mh-seq)
1738 1684
1739;;; Local Variables: 1685;;; Local Variables:
diff --git a/lisp/mh-e/mh-speed.el b/lisp/mh-e/mh-speed.el
index 967984d1104..2617a941de1 100644
--- a/lisp/mh-e/mh-speed.el
+++ b/lisp/mh-e/mh-speed.el
@@ -34,10 +34,11 @@
34;;; Code: 34;;; Code:
35 35
36;; Requires 36;; Requires
37(require 'mh-utils) 37(eval-when-compile (require 'mh-acros))
38(mh-require-cl) 38(mh-require-cl)
39(require 'mh-e) 39(require 'mh-e)
40(require 'speedbar) 40(require 'speedbar)
41(require 'timer)
41 42
42;; Global variables 43;; Global variables
43(defvar mh-speed-refresh-flag nil) 44(defvar mh-speed-refresh-flag nil)
@@ -90,26 +91,25 @@ BUFFER is the MH-E buffer for which the speedbar buffer is to be created."
90 "+" mh-speed-expand-folder 91 "+" mh-speed-expand-folder
91 "-" mh-speed-contract-folder 92 "-" mh-speed-contract-folder
92 "\r" mh-speed-view 93 "\r" mh-speed-view
93 "f" mh-speed-flists 94 "r" mh-speed-refresh)
94 "i" mh-speed-invalidate-map)
95 95
96(defvar mh-show-speedbar-key-map mh-folder-speedbar-key-map) 96(defvar mh-show-speedbar-key-map mh-folder-speedbar-key-map)
97(defvar mh-letter-speedbar-key-map mh-folder-speedbar-key-map) 97(defvar mh-letter-speedbar-key-map mh-folder-speedbar-key-map)
98 98
99;; Menus for speedbar... 99;; Menus for speedbar...
100(defvar mh-folder-speedbar-menu-items 100(defvar mh-folder-speedbar-menu-items
101 '(["Visit Folder" mh-speed-view 101 '("--"
102 ["Visit Folder" mh-speed-view
102 (save-excursion 103 (save-excursion
103 (set-buffer speedbar-buffer) 104 (set-buffer speedbar-buffer)
104 (get-text-property (line-beginning-position) 'mh-folder))] 105 (get-text-property (line-beginning-position) 'mh-folder))]
105 ["Expand nested folders" mh-speed-expand-folder 106 ["Expand Nested Folders" mh-speed-expand-folder
106 (and (get-text-property (line-beginning-position) 'mh-children-p) 107 (and (get-text-property (line-beginning-position) 'mh-children-p)
107 (not (get-text-property (line-beginning-position) 'mh-expanded)))] 108 (not (get-text-property (line-beginning-position) 'mh-expanded)))]
108 ["Contract nested folders" mh-speed-contract-folder 109 ["Contract Nested Folders" mh-speed-contract-folder
109 (and (get-text-property (line-beginning-position) 'mh-children-p) 110 (and (get-text-property (line-beginning-position) 'mh-children-p)
110 (get-text-property (line-beginning-position) 'mh-expanded))] 111 (get-text-property (line-beginning-position) 'mh-expanded))]
111 ["Run Flists" mh-speed-flists t] 112 ["Refresh Speedbar" mh-speed-refresh t])
112 ["Invalidate cached folders" mh-speed-invalidate-map t])
113 "Extra menu items for speedbar.") 113 "Extra menu items for speedbar.")
114 114
115(defvar mh-show-speedbar-menu-items mh-folder-speedbar-menu-items) 115(defvar mh-show-speedbar-menu-items mh-folder-speedbar-menu-items)
@@ -352,6 +352,14 @@ Optional ARGS are ignored."
352(defvar mh-speed-current-folder nil) 352(defvar mh-speed-current-folder nil)
353(defvar mh-speed-flists-folder nil) 353(defvar mh-speed-flists-folder nil)
354 354
355(defmacro mh-process-kill-without-query (process)
356 "PROCESS can be killed without query on Emacs exit.
357Avoid using `process-kill-without-query' if possible since it is now
358obsolete."
359 (if (fboundp 'set-process-query-on-exit-flag)
360 `(set-process-query-on-exit-flag ,process nil)
361 `(process-kill-without-query ,process)))
362
355;;;###mh-autoload 363;;;###mh-autoload
356(defun mh-speed-flists (force &rest folders) 364(defun mh-speed-flists (force &rest folders)
357 "Execute flists -recurse and update message counts. 365 "Execute flists -recurse and update message counts.
@@ -396,6 +404,7 @@ only for that one folder."
396 (or mh-speed-flists-folder '("-recurse")))) 404 (or mh-speed-flists-folder '("-recurse"))))
397 ;; Run flists on all folders the next time around... 405 ;; Run flists on all folders the next time around...
398 (setq mh-speed-flists-folder nil) 406 (setq mh-speed-flists-folder nil)
407 (mh-process-kill-without-query mh-speed-flists-process)
399 (set-process-filter mh-speed-flists-process 408 (set-process-filter mh-speed-flists-process
400 'mh-speed-parse-flists-output))))))) 409 'mh-speed-parse-flists-output)))))))
401 410
@@ -494,6 +503,14 @@ next."
494 (when (equal folder "") 503 (when (equal folder "")
495 (clrhash mh-sub-folders-cache))))) 504 (clrhash mh-sub-folders-cache)))))
496 505
506(defun mh-speed-refresh ()
507 "Refresh the speedbar.
508Use this function to refresh the speedbar if folders have been added or
509deleted or message ranges have been updated outside of MH-E."
510 (interactive)
511 (mh-speed-flists t)
512 (mh-speed-invalidate-map ""))
513
497;;;###mh-autoload 514;;;###mh-autoload
498(defun mh-speed-add-folder (folder) 515(defun mh-speed-add-folder (folder)
499 "Add FOLDER since it is being created. 516 "Add FOLDER since it is being created.
diff --git a/lisp/mh-e/mh-utils.el b/lisp/mh-e/mh-utils.el
index b1966915e86..a57567a7bd3 100644
--- a/lisp/mh-e/mh-utils.el
+++ b/lisp/mh-e/mh-utils.el
@@ -33,20 +33,14 @@
33 33
34;;; Code: 34;;; Code:
35 35
36;; Is this XEmacs-land? Located here since needed by mh-customize.el. 36(defvar recursive-load-depth-limit)
37(defvar mh-xemacs-flag (featurep 'xemacs) 37(eval-and-compile
38 "Non-nil means the current Emacs is XEmacs.") 38 (if (and (boundp 'recursive-load-depth-limit)
39 39 (integerp recursive-load-depth-limit)
40;; The Emacs coding conventions require that the cl package not be required at 40 (> 50 recursive-load-depth-limit))
41;; runtime. However, the cl package in versions of Emacs prior to 21.4 left cl 41 (setq recursive-load-depth-limit 50)))
42;; routines in their macro expansions. Use mh-require-cl to provide the cl
43;; routines in the best way possible.
44(eval-when-compile (require 'cl))
45(defmacro mh-require-cl ()
46 (if (eq (car (macroexpand '(setf (gethash foo bar) baz))) 'cl-puthash)
47 `(require 'cl)
48 `(eval-when-compile (require 'cl))))
49 42
43(eval-when-compile (require 'mh-acros))
50(mh-require-cl) 44(mh-require-cl)
51(require 'gnus-util) 45(require 'gnus-util)
52(require 'font-lock) 46(require 'font-lock)
@@ -58,6 +52,7 @@
58 52
59(load "mm-decode" t t) ; Non-fatal dependency 53(load "mm-decode" t t) ; Non-fatal dependency
60(load "mm-view" t t) ; Non-fatal dependency 54(load "mm-view" t t) ; Non-fatal dependency
55(load "vcard" t t) ; Non-fatal dependency
61(load "hl-line" t t) ; Non-fatal dependency 56(load "hl-line" t t) ; Non-fatal dependency
62(load "executable" t t) ; Non-fatal dependency on 57(load "executable" t t) ; Non-fatal dependency on
63 ; executable-find 58 ; executable-find
@@ -69,43 +64,12 @@
69 64
70;;; Autoloads 65;;; Autoloads
71(autoload 'gnus-article-highlight-citation "gnus-cite") 66(autoload 'gnus-article-highlight-citation "gnus-cite")
67(autoload 'message-fetch-field "message")
68(autoload 'message-tokenize-header "message")
72(require 'sendmail) 69(require 'sendmail)
73(autoload 'Info-goto-node "info")
74(unless (fboundp 'make-hash-table) 70(unless (fboundp 'make-hash-table)
75 (autoload 'make-hash-table "cl")) 71 (autoload 'make-hash-table "cl"))
76 72
77;;; Set for local environment:
78;;; mh-progs and mh-lib used to be set in paths.el, which tried to
79;;; figure out at build time which of several possible directories MH
80;;; was installed into. But if you installed MH after building Emacs,
81;;; this would almost certainly be wrong, so now we do it at run time.
82
83(defvar mh-progs nil
84 "Directory containing MH commands, such as inc, repl, and rmm.")
85
86(defvar mh-lib nil
87 "Directory containing the MH library.
88This directory contains, among other things, the components file.")
89
90(defvar mh-lib-progs nil
91 "Directory containing MH helper programs.
92This directory contains, among other things, the mhl program.")
93
94(defvar mh-nmh-flag nil
95 "Non-nil means nmh is installed on this system instead of MH.")
96
97(defvar mh-flists-present-flag nil
98 "Non-nil means that we have `flists'.")
99
100;;;###autoload
101(put 'mh-progs 'risky-local-variable t)
102;;;###autoload
103(put 'mh-lib 'risky-local-variable t)
104;;;###autoload
105(put 'mh-lib-progs 'risky-local-variable t)
106;;;###autoload
107(put 'mh-nmh-flag 'risky-local-variable t)
108
109;;; CL Replacements 73;;; CL Replacements
110(defun mh-search-from-end (char string) 74(defun mh-search-from-end (char string)
111 "Return the position of last occurrence of CHAR in STRING. 75 "Return the position of last occurrence of CHAR in STRING.
@@ -115,92 +79,52 @@ of `search' in the CL package."
115 when (equal (aref string index) char) return index 79 when (equal (aref string index) char) return index
116 finally return nil)) 80 finally return nil))
117 81
118;;; Macros to generate correct code for different emacs variants
119
120(defmacro mh-do-in-gnu-emacs (&rest body)
121 "Execute BODY if in GNU Emacs."
122 (unless mh-xemacs-flag `(progn ,@body)))
123(put 'mh-do-in-gnu-emacs 'lisp-indent-hook 'defun)
124
125(defmacro mh-do-in-xemacs (&rest body)
126 "Execute BODY if in GNU Emacs."
127 (when mh-xemacs-flag `(progn ,@body)))
128(put 'mh-do-in-xemacs 'lisp-indent-hook 'defun)
129
130(defmacro mh-funcall-if-exists (function &rest args)
131 "Call FUNCTION with ARGS as parameters if it exists."
132 (if (fboundp function)
133 `(funcall ',function ,@args)))
134
135(defmacro mh-make-local-hook (hook)
136 "Make HOOK local if needed.
137XEmacs and versions of GNU Emacs before 21.1 require `make-local-hook' to be
138called."
139 (when (and (fboundp 'make-local-hook)
140 (not (get 'make-local-hook 'byte-obsolete-info)))
141 `(make-local-hook ,hook)))
142
143(defmacro mh-mark-active-p (check-transient-mark-mode-flag)
144 "A macro that expands into appropriate code in XEmacs and nil in GNU Emacs.
145In GNU Emacs if CHECK-TRANSIENT-MARK-MODE-FLAG is non-nil then check if
146variable `transient-mark-mode' is active."
147 (cond (mh-xemacs-flag ;XEmacs
148 `(and (boundp 'zmacs-regions) zmacs-regions (region-active-p)))
149 ((not check-transient-mark-mode-flag) ;GNU Emacs
150 `(and (boundp 'mark-active) mark-active))
151 (t ;GNU Emacs
152 `(and (boundp 'transient-mark-mode) transient-mark-mode
153 (boundp 'mark-active) mark-active))))
154
155;;; Additional header fields that might someday be added: 82;;; Additional header fields that might someday be added:
156;;; "Sender: " "Reply-to: " 83;;; "Sender: " "Reply-to: "
157 84
85
86;;; Scan Line Formats
87
158(defvar mh-scan-msg-number-regexp "^ *\\([0-9]+\\)" 88(defvar mh-scan-msg-number-regexp "^ *\\([0-9]+\\)"
159 "Regexp to find the number of a message in a scan line. 89 "This regexp is used to extract the message number from a scan line.
160The message's number must be surrounded with \\( \\)") 90Note that the message number must be placed in a parenthesized expression as
91in the default of \"^ *\\\\([0-9]+\\\\)\".")
161 92
162(defvar mh-scan-msg-overflow-regexp "^[?0-9][0-9]" 93(defvar mh-scan-msg-overflow-regexp "^[?0-9][0-9]"
163 "Regexp to find a scan line in which the message number overflowed. 94 "This regexp matches scan lines in which the message number overflowed.")
164The message's number is left truncated in this case.")
165 95
166(defvar mh-scan-msg-format-regexp "%\\([0-9]*\\)(msg)" 96(defvar mh-scan-msg-format-regexp "%\\([0-9]*\\)(msg)"
167 "Regexp to find message number width in an scan format. 97 "This regexp is used to find the message number width in a scan format.
168The message number width must be surrounded with \\( \\).") 98Note that the message number must be placed in a parenthesized expression as
99in the default of \"%\\\\([0-9]*\\\\)(msg)\".")
169 100
170(defvar mh-scan-msg-format-string "%d" 101(defvar mh-scan-msg-format-string "%d"
171 "Format string for width of the message number in a scan format. 102 "This is a format string for width of the message number in a scan format.
172Use `0%d' for zero-filled message numbers.") 103Use `0%d' for zero-filled message numbers.")
173 104
174(defvar mh-scan-msg-search-regexp "^[^0-9]*%d[^0-9]" 105(defvar mh-scan-msg-search-regexp "^[^0-9]*%d[^0-9]"
175 "Format string containing a regexp matching the scan listing for a message. 106 "This format string regexp matches the scan line for a particular message.
176The desired message's number will be an argument to format.") 107Use `%d' to represent the location of the message number within the
177 108expression as in the default of \"^[^0-9]*%d[^0-9]\".")
178(defvar mh-default-folder-for-message-function nil 109
179 "Function to select a default folder for refiling or Fcc. 110(defvar mh-cmd-note 4
180If set to a function, that function is called with no arguments by 111 "This is the number of characters to skip over before inserting notation.
181`\\[mh-refile-msg]' and `\\[mh-to-fcc]' to get a default when 112This variable should be set with the function `mh-set-cmd-note'. This variable
182prompting the user for a folder. The function is called from within a 113may be updated dynamically if `mh-adaptive-cmd-note-flag' is non-nil and
183`save-excursion', with point at the start of the message. It should 114`mh-scan-format-file' is t.")
184return the folder to offer as the refile or Fcc folder, as a string 115(make-variable-buffer-local 'mh-cmd-note)
185with a leading `+' sign. It can also return an empty string to use no 116
186default, or nil to calculate the default the usual way. 117(defvar mh-note-seq ?%
187NOTE: This variable is not an ordinary hook; 118 "Messages in a user-defined sequence are marked by this character.
188It may not be a list of functions.") 119Messages in the `search' sequence are marked by this character as well.")
120
121
189 122
190(defvar mh-show-buffer-mode-line-buffer-id " {show-%s} %d" 123(defvar mh-show-buffer-mode-line-buffer-id " {show-%s} %d"
191 "Format string to produce `mode-line-buffer-identification' for show buffers. 124 "Format string to produce `mode-line-buffer-identification' for show buffers.
192First argument is folder name. Second is message number.") 125First argument is folder name. Second is message number.")
193 126
194(defvar mh-cmd-note 4 127
195 "Column to insert notation.
196Use `mh-set-cmd-note' to modify it.
197This value may be dynamically updated if `mh-adaptive-cmd-note-flag' is
198non-nil and `mh-scan-format-file' is t.
199Note that the first column is column number 0.")
200(make-variable-buffer-local 'mh-cmd-note)
201
202(defvar mh-note-seq "%"
203 "String whose first character is used to notate messages in a sequence.")
204 128
205(defvar mh-mail-header-separator "--------" 129(defvar mh-mail-header-separator "--------"
206 "*Line used by MH to separate headers from text in messages being composed. 130 "*Line used by MH to separate headers from text in messages being composed.
@@ -213,11 +137,29 @@ Do not make this a regexp as it may be the argument to `insert' and it is
213passed through `regexp-quote' before being used by functions like 137passed through `regexp-quote' before being used by functions like
214`re-search-forward'.") 138`re-search-forward'.")
215 139
140(defvar mh-signature-separator-regexp "^-- $"
141 "Regexp used to find signature separator.
142See `mh-signature-separator'.")
143
144(defvar mh-signature-separator "-- \n"
145 "Text of a signature separator.
146A signature separator is used to separate the body of a message from the
147signature. This can be used by user agents such as MH-E to render the
148signature differently or to suppress the inclusion of the signature in a
149reply.
150Use `mh-signature-separator-regexp' when searching for a separator.")
151
152(defun mh-signature-separator-p ()
153 "Return non-nil if buffer includes \"^-- $\"."
154 (save-excursion
155 (goto-char (point-min))
156 (re-search-forward mh-signature-separator-regexp nil t)))
157
216;; Variables for MIME display 158;; Variables for MIME display
217 159
218;; Structure to keep track of MIME handles on a per buffer basis. 160;; Structure to keep track of MIME handles on a per buffer basis.
219(defstruct (mh-buffer-data (:conc-name mh-mime-) 161(mh-defstruct (mh-buffer-data (:conc-name mh-mime-)
220 (:constructor mh-make-buffer-data)) 162 (:constructor mh-make-buffer-data))
221 (handles ()) ; List of MIME handles 163 (handles ()) ; List of MIME handles
222 (handles-cache (make-hash-table)) ; Cache to avoid multiple decodes of 164 (handles-cache (make-hash-table)) ; Cache to avoid multiple decodes of
223 ; nested messages 165 ; nested messages
@@ -331,7 +273,7 @@ passed through `regexp-quote' before being used by functions like
331 "A regular expression probably matching an e-mail address.") 273 "A regular expression probably matching an e-mail address.")
332 274
333;; From goto-addr.el, which we don't want to force-load on users. 275;; From goto-addr.el, which we don't want to force-load on users.
334;;;###mh-autoload 276
335(defun mh-goto-address-find-address-at-point () 277(defun mh-goto-address-find-address-at-point ()
336 "Find e-mail address around or before point. 278 "Find e-mail address around or before point.
337Then search backwards to beginning of line for the start of an e-mail 279Then search backwards to beginning of line for the start of an e-mail
@@ -348,7 +290,18 @@ address. If no e-mail address found, return nil."
348In MH-E we frequently need to find the end of headers in nested messages, where 290In MH-E we frequently need to find the end of headers in nested messages, where
349the buffer has been narrowed. This function works in this situation." 291the buffer has been narrowed. This function works in this situation."
350 (save-excursion 292 (save-excursion
351 (rfc822-goto-eoh) 293 ;; XXX: The following replaces a call to rfc822-goto-eoh. Occasionally,
294 ;; mail headers that MH-E has to read contains lines of the form:
295 ;; From xxx@yyy Mon May 10 11:48:07 2004
296 ;; In this situation, rfc822-goto-eoh doesn't go to the end of the
297 ;; header. The replacement allows From_ lines in the mail header.
298 (goto-char (point-min))
299 (loop for p = (re-search-forward
300 "^\\([:\n]\\|[^: \t\n]+[ \t\n]\\)" nil 'move)
301 do (cond ((null p) (return))
302 (t (goto-char (match-beginning 0))
303 (unless (looking-at "From ") (return))
304 (goto-char p))))
352 (point))) 305 (point)))
353 306
354(defun mh-in-header-p () 307(defun mh-in-header-p ()
@@ -528,17 +481,20 @@ message about the fontification operation."
528;; hidden and can be programmatically removed in mh-quit), and the variable 481;; hidden and can be programmatically removed in mh-quit), and the variable
529;; names have the form mh-temp-.*-buffer. 482;; names have the form mh-temp-.*-buffer.
530(defconst mh-temp-buffer " *mh-temp*") ;scratch 483(defconst mh-temp-buffer " *mh-temp*") ;scratch
484(defconst mh-temp-fetch-buffer " *mh-fetch*") ;wget/curl/fetch output
531 485
532;; The names of MH-E buffers that are not ephemeral and can be used by the 486;; The names of MH-E buffers that are not ephemeral and can be used by the
533;; user (and deleted by the user when no longer needed) have a "*MH-E " prefix 487;; user (and deleted by the user when no longer needed) have a "*MH-E " prefix
534;; (so they can be programmatically removed in mh-quit), and the variable 488;; (so they can be programmatically removed in mh-quit), and the variable
535;; names have the form mh-.*-buffer. 489;; names have the form mh-.*-buffer.
490(defconst mh-aliases-buffer "*MH-E Aliases*") ;alias lookups
536(defconst mh-folders-buffer "*MH-E Folders*") ;folder list 491(defconst mh-folders-buffer "*MH-E Folders*") ;folder list
492(defconst mh-help-buffer "*MH-E Help*") ;quick help
537(defconst mh-info-buffer "*MH-E Info*") ;version information buffer 493(defconst mh-info-buffer "*MH-E Info*") ;version information buffer
538(defconst mh-log-buffer "*MH-E Log*") ;output of MH commands and so on 494(defconst mh-log-buffer "*MH-E Log*") ;output of MH commands and so on
495(defconst mh-mail-delivery-buffer "*MH-E Mail Delivery*") ;mail delivery log
539(defconst mh-recipients-buffer "*MH-E Recipients*") ;killed when draft sent 496(defconst mh-recipients-buffer "*MH-E Recipients*") ;killed when draft sent
540(defconst mh-sequences-buffer "*MH-E Sequences*") ;sequences list 497(defconst mh-sequences-buffer "*MH-E Sequences*") ;sequences list
541(defconst mh-mail-delivery-buffer "*MH-E Mail Delivery*") ;mail delivery log
542 498
543;; Number of lines to keep in mh-log-buffer. 499;; Number of lines to keep in mh-log-buffer.
544(defvar mh-log-buffer-lines 100) 500(defvar mh-log-buffer-lines 100)
@@ -593,7 +549,6 @@ message about the fontification operation."
593 (cons modeline-buffer-id-left-extent "XEmacs%N:")) 549 (cons modeline-buffer-id-left-extent "XEmacs%N:"))
594 (cons modeline-buffer-id-right-extent " %17b"))))) 550 (cons modeline-buffer-id-right-extent " %17b")))))
595 551
596
597;;; This holds a documentation string used by describe-mode. 552;;; This holds a documentation string used by describe-mode.
598(defun mh-showing-mode (&optional arg) 553(defun mh-showing-mode (&optional arg)
599 "Change whether messages should be displayed. 554 "Change whether messages should be displayed.
@@ -614,7 +569,6 @@ With arg, display messages iff ARG is positive."
614;; Showing message with headers or normally. 569;; Showing message with headers or normally.
615(defvar mh-showing-with-headers nil) 570(defvar mh-showing-with-headers nil)
616 571
617
618;;; MH-E macros 572;;; MH-E macros
619 573
620(defmacro with-mh-folder-updating (save-modification-flag &rest body) 574(defmacro with-mh-folder-updating (save-modification-flag &rest body)
@@ -742,7 +696,7 @@ of the buffer in the event window is preserved."
742 (unlock-buffer) 696 (unlock-buffer)
743 (setq buffer-file-name nil)) 697 (setq buffer-file-name nil))
744 698
745;;;###mh-autoload 699
746(defun mh-get-msg-num (error-if-no-message) 700(defun mh-get-msg-num (error-if-no-message)
747 "Return the message number of the displayed message. 701 "Return the message number of the displayed message.
748If the argument ERROR-IF-NO-MESSAGE is non-nil, then complain if the cursor is 702If the argument ERROR-IF-NO-MESSAGE is non-nil, then complain if the cursor is
@@ -915,6 +869,16 @@ still visible.\n")
915(mh-defun-show-buffer mh-show-index-ticked-messages mh-index-ticked-messages) 869(mh-defun-show-buffer mh-show-index-ticked-messages mh-index-ticked-messages)
916(mh-defun-show-buffer mh-show-index-sequenced-messages 870(mh-defun-show-buffer mh-show-index-sequenced-messages
917 mh-index-sequenced-messages) 871 mh-index-sequenced-messages)
872(mh-defun-show-buffer mh-show-catchup mh-catchup)
873(mh-defun-show-buffer mh-show-ps-print-toggle-mime mh-ps-print-toggle-mime)
874(mh-defun-show-buffer mh-show-ps-print-toggle-color mh-ps-print-toggle-color)
875(mh-defun-show-buffer mh-show-ps-print-toggle-faces mh-ps-print-toggle-faces)
876(mh-defun-show-buffer mh-show-ps-print-msg-file mh-ps-print-msg-file)
877(mh-defun-show-buffer mh-show-ps-print-msg mh-ps-print-msg)
878(mh-defun-show-buffer mh-show-ps-print-msg-show mh-ps-print-msg-show)
879(mh-defun-show-buffer mh-show-toggle-mime-buttons mh-toggle-mime-buttons)
880(mh-defun-show-buffer mh-show-display-with-external-viewer
881 mh-display-with-external-viewer)
918 882
919;;; Populate mh-show-mode-map 883;;; Populate mh-show-mode-map
920(gnus-define-keys mh-show-mode-map 884(gnus-define-keys mh-show-mode-map
@@ -941,7 +905,6 @@ still visible.\n")
941 "g" mh-show-goto-msg 905 "g" mh-show-goto-msg
942 "i" mh-show-inc-folder 906 "i" mh-show-inc-folder
943 "k" mh-show-delete-subject-or-thread 907 "k" mh-show-delete-subject-or-thread
944 "l" mh-show-print-msg
945 "m" mh-show-send 908 "m" mh-show-send
946 "n" mh-show-next-undeleted-msg 909 "n" mh-show-next-undeleted-msg
947 "\M-n" mh-show-next-unread-msg 910 "\M-n" mh-show-next-unread-msg
@@ -961,6 +924,7 @@ still visible.\n")
961 "?" mh-prefix-help 924 "?" mh-prefix-help
962 "'" mh-index-ticked-messages 925 "'" mh-index-ticked-messages
963 "S" mh-show-sort-folder 926 "S" mh-show-sort-folder
927 "c" mh-show-catchup
964 "f" mh-show-visit-folder 928 "f" mh-show-visit-folder
965 "i" mh-index-search 929 "i" mh-index-search
966 "k" mh-show-kill-folder 930 "k" mh-show-kill-folder
@@ -992,6 +956,17 @@ still visible.\n")
992 "b" mh-show-junk-blacklist 956 "b" mh-show-junk-blacklist
993 "w" mh-show-junk-whitelist) 957 "w" mh-show-junk-whitelist)
994 958
959(gnus-define-keys (mh-show-ps-print-map "P" mh-show-mode-map)
960 "?" mh-prefix-help
961 "A" mh-show-ps-print-toggle-mime
962 "C" mh-show-ps-print-toggle-color
963 "F" mh-show-ps-print-toggle-faces
964 "M" mh-show-ps-print-toggle-mime
965 "f" mh-show-ps-print-msg-file
966 "l" mh-show-print-msg
967 "p" mh-show-ps-print-msg
968 "s" mh-show-ps-print-msg-show)
969
995(gnus-define-keys (mh-show-thread-map "T" mh-show-mode-map) 970(gnus-define-keys (mh-show-thread-map "T" mh-show-mode-map)
996 "?" mh-prefix-help 971 "?" mh-prefix-help
997 "u" mh-show-thread-ancestor 972 "u" mh-show-thread-ancestor
@@ -1026,9 +1001,11 @@ still visible.\n")
1026(gnus-define-keys (mh-show-mime-map "K" mh-show-mode-map) 1001(gnus-define-keys (mh-show-mime-map "K" mh-show-mode-map)
1027 "?" mh-prefix-help 1002 "?" mh-prefix-help
1028 "a" mh-mime-save-parts 1003 "a" mh-mime-save-parts
1004 "e" mh-show-display-with-external-viewer
1029 "v" mh-show-toggle-mime-part 1005 "v" mh-show-toggle-mime-part
1030 "o" mh-show-save-mime-part 1006 "o" mh-show-save-mime-part
1031 "i" mh-show-inline-mime-part 1007 "i" mh-show-inline-mime-part
1008 "t" mh-show-toggle-mime-buttons
1032 "\t" mh-show-next-button 1009 "\t" mh-show-next-button
1033 [backtab] mh-show-prev-button 1010 [backtab] mh-show-prev-button
1034 "\M-\t" mh-show-prev-button) 1011 "\M-\t" mh-show-prev-button)
@@ -1115,7 +1092,10 @@ still visible.\n")
1115(define-derived-mode mh-show-mode text-mode "MH-Show" 1092(define-derived-mode mh-show-mode text-mode "MH-Show"
1116 "Major mode for showing messages in MH-E.\\<mh-show-mode-map> 1093 "Major mode for showing messages in MH-E.\\<mh-show-mode-map>
1117The value of `mh-show-mode-hook' is a list of functions to 1094The value of `mh-show-mode-hook' is a list of functions to
1118be called, with no arguments, upon entry to this mode." 1095be called, with no arguments, upon entry to this mode.
1096See also `mh-folder-mode'.
1097
1098\\{mh-show-mode-map}"
1119 (set (make-local-variable 'mail-header-separator) mh-mail-header-separator) 1099 (set (make-local-variable 'mail-header-separator) mh-mail-header-separator)
1120 (setq paragraph-start (default-value 'paragraph-start)) 1100 (setq paragraph-start (default-value 'paragraph-start))
1121 (mh-show-unquote-From) 1101 (mh-show-unquote-From)
@@ -1210,8 +1190,9 @@ be called, with no arguments, upon entry to this mode."
1210(mh-do-in-xemacs (defvar default-enable-multibyte-characters)) 1190(mh-do-in-xemacs (defvar default-enable-multibyte-characters))
1211 1191
1212(defun mh-face-display-function () 1192(defun mh-face-display-function ()
1213 "Display a Face or X-Face header field. 1193 "Display a Face, X-Face, or X-Image-URL header field.
1214Display Face if both are present." 1194If more than one of these are present, then the first one found in this order
1195is used."
1215 (save-restriction 1196 (save-restriction
1216 (goto-char (point-min)) 1197 (goto-char (point-min))
1217 (re-search-forward "\n\n" (point-max) t) 1198 (re-search-forward "\n\n" (point-max) t)
@@ -1226,7 +1207,8 @@ Display Face if both are present."
1226 type 'png)) 1207 type 'png))
1227 (x-face (setq raw (mh-uncompface x-face) 1208 (x-face (setq raw (mh-uncompface x-face)
1228 type 'pbm)) 1209 type 'pbm))
1229 (url (setq type 'url))) 1210 (url (setq type 'url))
1211 (t (multiple-value-setq (type raw) (mh-picon-get-image))))
1230 (when type 1212 (when type
1231 (goto-char (point-min)) 1213 (goto-char (point-min))
1232 (when (re-search-forward "^from:" (point-max) t) 1214 (when (re-search-forward "^from:" (point-max) t)
@@ -1261,10 +1243,15 @@ Display Face if both are present."
1261 ((and (eq type 'pbm) 1243 ((and (eq type 'pbm)
1262 (fboundp 'x-face-xmas-wl-display-x-face) 1244 (fboundp 'x-face-xmas-wl-display-x-face)
1263 (fboundp 'executable-find) (executable-find "uncompface")) 1245 (fboundp 'executable-find) (executable-find "uncompface"))
1264 (mh-funcall-if-exists x-face-xmas-wl-display-x-face))) 1246 (mh-funcall-if-exists x-face-xmas-wl-display-x-face))
1247 ;; Picon display
1248 ((and raw (member type '(xpm xbm gif)))
1249 (when (featurep type)
1250 (set-extent-begin-glyph
1251 (make-extent (point) (point))
1252 (make-glyph (vector type ':data raw))))))
1265 (when raw (insert " ")))))))) 1253 (when raw (insert " "))))))))
1266 1254
1267
1268(defun mh-show-xface () 1255(defun mh-show-xface ()
1269 "Display X-Face." 1256 "Display X-Face."
1270 (when (and window-system mh-show-use-xface-flag 1257 (when (and window-system mh-show-use-xface-flag
@@ -1274,49 +1261,207 @@ Display Face if both are present."
1274 1261
1275 1262
1276 1263
1264;; Picon display
1265
1266;;; XXX: This should be customizable. As a side-effect of setting this
1267;;; variable, arrange to reset mh-picon-existing-directory-list to 'unset.
1268(defvar mh-picon-directory-list
1269 '("~/.picons" "~/.picons/users" "~/.picons/usenix" "~/.picons/news"
1270 "~/.picons/domains" "~/.picons/misc"
1271 "/usr/share/picons/" "/usr/share/picons/users" "/usr/share/picons/usenix"
1272 "/usr/share/picons/news" "/usr/share/picons/domains"
1273 "/usr/share/picons/misc")
1274 "List of directories where picons reside.
1275The directories are searched for in the order they appear in the list.")
1276
1277(defvar mh-picon-existing-directory-list 'unset
1278 "List of directories to search in.")
1279
1280(defvar mh-picon-cache (make-hash-table :test #'equal))
1281
1282(defvar mh-picon-image-types
1283 (loop for type in '(xpm xbm gif)
1284 when (or (mh-do-in-gnu-emacs
1285 (ignore-errors
1286 (mh-funcall-if-exists image-type-available-p type)))
1287 (mh-do-in-xemacs (featurep type)))
1288 collect type))
1289
1290(defun mh-picon-set-directory-list ()
1291 "Update `mh-picon-existing-directory-list' if needed."
1292 (when (eq mh-picon-existing-directory-list 'unset)
1293 (setq mh-picon-existing-directory-list
1294 (loop for x in mh-picon-directory-list
1295 when (file-directory-p x) collect x))))
1296
1297(defun* mh-picon-get-image ()
1298 "Find the best possible match and return contents."
1299 (mh-picon-set-directory-list)
1300 (save-restriction
1301 (let* ((from-field (ignore-errors (car (message-tokenize-header
1302 (mh-get-header-field "from:")))))
1303 (from (car (ignore-errors
1304 (mh-funcall-if-exists ietf-drums-parse-address
1305 from-field))))
1306 (host (and from
1307 (string-match "\\([^+]*\\)\\(+.*\\)?@\\(.*\\)" from)
1308 (downcase (match-string 3 from))))
1309 (user (and host (downcase (match-string 1 from))))
1310 (canonical-address (format "%s@%s" user host))
1311 (cached-value (gethash canonical-address mh-picon-cache))
1312 (host-list (and host (delete "" (split-string host "\\."))))
1313 (match nil))
1314 (cond (cached-value (return-from mh-picon-get-image cached-value))
1315 ((not host-list) (return-from mh-picon-get-image nil)))
1316 (setq match
1317 (block 'loop
1318 ;; u@h search
1319 (loop for dir in mh-picon-existing-directory-list
1320 do (loop for type in mh-picon-image-types
1321 ;; [path]user@host
1322 for file1 = (format "%s/%s.%s"
1323 dir canonical-address type)
1324 when (file-exists-p file1)
1325 do (return-from 'loop file1)
1326 ;; [path]user
1327 for file2 = (format "%s/%s.%s" dir user type)
1328 when (file-exists-p file2)
1329 do (return-from 'loop file2)
1330 ;; [path]host
1331 for file3 = (format "%s/%s.%s" dir host type)
1332 when (file-exists-p file3)
1333 do (return-from 'loop file3)))
1334 ;; facedb search
1335 ;; Search order for user@foo.net:
1336 ;; [path]net/foo/user
1337 ;; [path]net/foo/user/face
1338 ;; [path]net/user
1339 ;; [path]net/user/face
1340 ;; [path]net/foo/unknown
1341 ;; [path]net/foo/unknown/face
1342 ;; [path]net/unknown
1343 ;; [path]net/unknown/face
1344 (loop for u in (list user "unknown")
1345 do (loop for dir in mh-picon-existing-directory-list
1346 do (loop for x on host-list by #'cdr
1347 for y = (mh-picon-generate-path x u dir)
1348 do (loop for type in mh-picon-image-types
1349 for z1 = (format "%s.%s" y type)
1350 when (file-exists-p z1)
1351 do (return-from 'loop z1)
1352 for z2 = (format "%s/face.%s"
1353 y type)
1354 when (file-exists-p z2)
1355 do (return-from 'loop z2)))))))
1356 (setf (gethash canonical-address mh-picon-cache)
1357 (mh-picon-file-contents match)))))
1358
1359(defun mh-picon-file-contents (file)
1360 "Return details about FILE.
1361A list of consisting of a symbol for the type of the file and the file
1362contents as a string is returned. If FILE is nil, then both elements of the
1363list are nil."
1364 (if (stringp file)
1365 (with-temp-buffer
1366 (let ((type (and (string-match ".*\\.\\(...\\)$" file)
1367 (intern (match-string 1 file)))))
1368 (insert-file-contents-literally file)
1369 (values type (buffer-string))))
1370 (values nil nil)))
1371
1372(defun mh-picon-generate-path (host-list user directory)
1373 "Generate the image file path.
1374HOST-LIST is the parsed host address of the email address, USER the username
1375and DIRECTORY is the directory relative to which the path is generated."
1376 (loop with acc = ""
1377 for elem in host-list
1378 do (setq acc (format "%s/%s" elem acc))
1379 finally return (format "%s/%s%s" directory acc user)))
1380
1381
1382
1277;; X-Image-URL display 1383;; X-Image-URL display
1278 1384
1279(defvar mh-x-image-cache-directory nil 1385(defvar mh-x-image-cache-directory nil
1280 "Directory where X-Image-URL images are cached.") 1386 "Directory where X-Image-URL images are cached.")
1281 1387(defvar mh-x-image-scaling-function
1282(defvar mh-convert-executable (executable-find "convert")) 1388 (cond ((executable-find "convert")
1283(defvar mh-wget-executable (executable-find "wget")) 1389 'mh-x-image-scale-with-convert)
1390 ((and (executable-find "anytopnm") (executable-find "pnmscale")
1391 (executable-find "pnmtopng"))
1392 'mh-x-image-scale-with-pnm)
1393 (t 'ignore))
1394 "Function to use to scale image to proper size.")
1395(defvar mh-wget-executable nil)
1396(defvar mh-wget-choice
1397 (or (and (setq mh-wget-executable (executable-find "wget")) 'wget)
1398 (and (setq mh-wget-executable (executable-find "fetch")) 'fetch)
1399 (and (setq mh-wget-executable (executable-find "curl")) 'curl)))
1400(defvar mh-wget-option
1401 (cdr (assoc mh-wget-choice '((curl . "-o") (fetch . "-o") (wget . "-O")))))
1284(defvar mh-x-image-temp-file nil) 1402(defvar mh-x-image-temp-file nil)
1285(defvar mh-x-image-url nil) 1403(defvar mh-x-image-url nil)
1286(defvar mh-x-image-marker nil) 1404(defvar mh-x-image-marker nil)
1287(defvar mh-x-image-url-cache-file nil) 1405(defvar mh-x-image-url-cache-file nil)
1288 1406
1407;; Functions to scale image to proper size
1408(defun mh-x-image-scale-with-pnm (input output)
1409 "Scale image in INPUT file and write to OUTPUT file using pnm tools."
1410 (let ((res (shell-command-to-string
1411 (format "anytopnm < %s | pnmscale -xysize 96 48 | pnmtopng > %s"
1412 input output))))
1413 (unless (equal res "")
1414 (delete-file output))))
1415
1416(defun mh-x-image-scale-with-convert (input output)
1417 "Scale image in INPUT file and write to OUTPUT file using ImageMagick."
1418 (call-process "convert" nil nil nil "-geometry" "96x48" input output))
1419
1289(defun mh-x-image-url-cache-canonicalize (url) 1420(defun mh-x-image-url-cache-canonicalize (url)
1290 "Canonicalize URL. 1421 "Canonicalize URL.
1291Replace the ?/ character with a ?! character." 1422Replace the ?/ character with a ?! character and append .png."
1292 (with-temp-buffer 1423 (format "%s/%s.png" mh-x-image-cache-directory
1293 (insert url) 1424 (with-temp-buffer
1294 (goto-char (point-min)) 1425 (insert url)
1295 (while (search-forward "/" nil t) (replace-match "!")) 1426 (mh-replace-string "/" "!")
1296 (format "%s/%s.png" mh-x-image-cache-directory (buffer-string)))) 1427 (buffer-string))))
1428
1429(defun mh-x-image-set-download-state (file data)
1430 "Setup a symbolic link from FILE to DATA."
1431 (if data
1432 (make-symbolic-link (symbol-name data) file t)
1433 (delete-file file)))
1434
1435(defun mh-x-image-get-download-state (file)
1436 "Check the state of FILE by following any symbolic links."
1437 (unless (file-exists-p mh-x-image-cache-directory)
1438 (call-process "mkdir" nil nil nil mh-x-image-cache-directory))
1439 (cond ((file-symlink-p file)
1440 (intern (file-name-nondirectory (file-chase-links file))))
1441 ((not (file-exists-p file)) nil)
1442 (t 'ok)))
1297 1443
1298(defun mh-x-image-url-fetch-image (url cache-file marker sentinel) 1444(defun mh-x-image-url-fetch-image (url cache-file marker sentinel)
1299 "Fetch and display the image specified by URL. 1445 "Fetch and display the image specified by URL.
1300After the image is fetched, it is stored in CACHE-FILE. It will be displayed 1446After the image is fetched, it is stored in CACHE-FILE. It will be displayed
1301in a buffer and position specified by MARKER. The actual display is carried 1447in a buffer and position specified by MARKER. The actual display is carried
1302out by the SENTINEL function." 1448out by the SENTINEL function."
1303 (if (and mh-wget-executable 1449 (if mh-wget-executable
1304 mh-fetch-x-image-url 1450 (let ((buffer (get-buffer-create (generate-new-buffer-name
1305 (or (eq mh-fetch-x-image-url t) 1451 mh-temp-fetch-buffer)))
1306 (y-or-n-p (format "Fetch %s? " url)))) 1452 (filename (or (mh-funcall-if-exists make-temp-file "mhe-fetch")
1307 (let ((buffer (get-buffer-create (generate-new-buffer-name " *mh-url*"))) 1453 (expand-file-name (make-temp-name "~/mhe-fetch")))))
1308 (filename (make-temp-name "/tmp/mhe-wget")))
1309 (save-excursion 1454 (save-excursion
1310 (set-buffer buffer) 1455 (set-buffer buffer)
1311 (set (make-local-variable 'mh-x-image-url-cache-file) cache-file) 1456 (set (make-local-variable 'mh-x-image-url-cache-file) cache-file)
1312 (set (make-local-variable 'mh-x-image-marker) marker) 1457 (set (make-local-variable 'mh-x-image-marker) marker)
1313 (set (make-local-variable 'mh-x-image-temp-file) filename)) 1458 (set (make-local-variable 'mh-x-image-temp-file) filename))
1314 (set-process-sentinel 1459 (set-process-sentinel
1315 (start-process "*wget*" buffer mh-wget-executable "-O" filename url) 1460 (start-process "*mh-x-image-url-fetch*" buffer
1461 mh-wget-executable mh-wget-option filename url)
1316 sentinel)) 1462 sentinel))
1317 ;; Make sure we don't ask about this image again 1463 ;; Temporary failure
1318 (when (and mh-wget-executable (eq mh-fetch-x-image-url 'ask)) 1464 (mh-x-image-set-download-state cache-file 'try-again)))
1319 (make-symbolic-link mh-x-image-cache-directory cache-file t))))
1320 1465
1321(defun mh-x-image-display (image marker) 1466(defun mh-x-image-display (image marker)
1322 "Display IMAGE at MARKER." 1467 "Display IMAGE at MARKER."
@@ -1326,7 +1471,8 @@ out by the SENTINEL function."
1326 (default-enable-multibyte-characters nil) 1471 (default-enable-multibyte-characters nil)
1327 (buffer-modified-flag (buffer-modified-p))) 1472 (buffer-modified-flag (buffer-modified-p)))
1328 (unwind-protect 1473 (unwind-protect
1329 (when (and (file-readable-p image) (not (file-symlink-p image))) 1474 (when (and (file-readable-p image) (not (file-symlink-p image))
1475 (eq marker mh-x-image-marker))
1330 (goto-char marker) 1476 (goto-char marker)
1331 (mh-do-in-gnu-emacs 1477 (mh-do-in-gnu-emacs
1332 (mh-funcall-if-exists insert-image (create-image image 'png))) 1478 (mh-funcall-if-exists insert-image (create-image image 'png)))
@@ -1350,32 +1496,56 @@ The argument CHANGE is ignored."
1350 (setq marker mh-x-image-marker 1496 (setq marker mh-x-image-marker
1351 cache-filename mh-x-image-url-cache-file 1497 cache-filename mh-x-image-url-cache-file
1352 temp-file mh-x-image-temp-file)) 1498 temp-file mh-x-image-temp-file))
1353 (when mh-convert-executable 1499 (cond
1354 (call-process mh-convert-executable nil nil nil "-resize" "96x48" 1500 ;; Check if we have `convert'
1355 temp-file cache-filename)) 1501 ((eq mh-x-image-scaling-function 'ignore)
1356 (if (file-exists-p cache-filename) 1502 (message "The `convert' program is needed to display X-Image-URL")
1357 (mh-x-image-display cache-filename marker) 1503 (mh-x-image-set-download-state cache-filename 'try-again))
1358 (make-symbolic-link mh-x-image-cache-directory cache-filename t)) 1504 ;; Scale fetched image
1505 ((and (funcall mh-x-image-scaling-function temp-file cache-filename)
1506 nil))
1507 ;; Attempt to display image if we have it
1508 ((file-exists-p cache-filename)
1509 (mh-x-image-display cache-filename marker))
1510 ;; We didn't find the image. Should we try to display it the next time?
1511 (t (mh-x-image-set-download-state cache-filename 'try-again)))
1359 (ignore-errors 1512 (ignore-errors
1360 (set-marker marker nil) 1513 (set-marker marker nil)
1361 (delete-process process) 1514 (delete-process process)
1362 (kill-buffer wget-buffer) 1515 (kill-buffer wget-buffer)
1363 (delete-file temp-file))))) 1516 (delete-file temp-file)))))
1364 1517
1518(defun mh-x-image-url-sane-p (url)
1519 "Check if URL is something sensible."
1520 (let ((len (length url)))
1521 (cond ((< len 5) nil)
1522 ((not (equal (substring url 0 5) "http:")) nil)
1523 ((> len 100) nil)
1524 (t t))))
1525
1365(defun mh-x-image-url-display (url) 1526(defun mh-x-image-url-display (url)
1366 "Display image from location URL. 1527 "Display image from location URL.
1367If the URL isn't present in the cache then it is fetched with wget." 1528If the URL isn't present in the cache then it is fetched with wget."
1368 (let ((cache-filename (mh-x-image-url-cache-canonicalize url)) 1529 (let* ((cache-filename (mh-x-image-url-cache-canonicalize url))
1369 (marker (set-marker (make-marker) (point)))) 1530 (state (mh-x-image-get-download-state cache-filename))
1370 (cond ((file-exists-p cache-filename) 1531 (marker (set-marker (make-marker) (point))))
1532 (set (make-local-variable 'mh-x-image-marker) marker)
1533 (cond ((not (mh-x-image-url-sane-p url)))
1534 ((eq state 'ok)
1371 (mh-x-image-display cache-filename marker)) 1535 (mh-x-image-display cache-filename marker))
1536 ((or (not mh-wget-executable)
1537 (eq mh-x-image-scaling-function 'ignore)))
1538 ((eq state 'never))
1372 ((not mh-fetch-x-image-url) 1539 ((not mh-fetch-x-image-url)
1373 (set-marker marker nil)) 1540 (set-marker marker nil))
1374 ((and (not (file-exists-p mh-x-image-cache-directory)) 1541 ((eq state 'try-again)
1375 (call-process "mkdir" nil nil nil mh-x-image-cache-directory) 1542 (mh-x-image-set-download-state cache-filename nil)
1376 nil)) 1543 (mh-x-image-url-fetch-image url cache-filename marker
1377 ((and (file-exists-p mh-x-image-cache-directory) 1544 'mh-x-image-scale-and-display))
1378 (file-directory-p mh-x-image-cache-directory)) 1545 ((and (eq mh-fetch-x-image-url 'ask)
1546 (not (y-or-n-p (format "Fetch %s? " url))))
1547 (mh-x-image-set-download-state cache-filename 'never))
1548 ((eq state nil)
1379 (mh-x-image-url-fetch-image url cache-filename marker 1549 (mh-x-image-url-fetch-image url cache-filename marker
1380 'mh-x-image-scale-and-display))))) 1550 'mh-x-image-scale-and-display)))))
1381 1551
@@ -1386,27 +1556,32 @@ If the URL isn't present in the cache then it is fetched with wget."
1386If optional arg MSG is non-nil, display that message instead." 1556If optional arg MSG is non-nil, display that message instead."
1387 (if mh-showing-mode (mh-show msg))) 1557 (if mh-showing-mode (mh-show msg)))
1388 1558
1389(defun mh-show (&optional message) 1559(defun mh-show (&optional message redisplay-flag)
1390 "Show message at cursor. 1560 "Show message at cursor.
1391If optional argument MESSAGE is non-nil, display that message instead. 1561If optional argument MESSAGE is non-nil, display that message instead.
1392Force a two-window display with the folder window on top (size given by the 1562Force a two-window display with the folder window on top (size given by the
1393variable `mh-summary-height') and the show buffer below it. 1563variable `mh-summary-height') and the show buffer below it.
1394If the message is already visible, display the start of the message. 1564If the message is already visible, display the start of the message.
1395 1565
1566If REDISPLAY-FLAG is non-nil, the default when called interactively, the
1567message is redisplayed even if the show buffer was already displaying the
1568correct message.
1569
1396Display of the message is controlled by setting the variables 1570Display of the message is controlled by setting the variables
1397`mh-clean-message-header-flag' and `mhl-formfile'. The default behavior is 1571`mh-clean-message-header-flag' and `mhl-formfile'. The default behavior is
1398to scroll uninteresting headers off the top of the window. 1572to scroll uninteresting headers off the top of the window.
1399Type \"\\[mh-header-display]\" to see the message with all its headers." 1573Type \"\\[mh-header-display]\" to see the message with all its headers."
1400 (interactive) 1574 (interactive (list nil t))
1401 (and mh-showing-with-headers 1575 (when (or redisplay-flag
1402 (or mhl-formfile mh-clean-message-header-flag) 1576 (and mh-showing-with-headers
1403 (mh-invalidate-show-buffer)) 1577 (or mhl-formfile mh-clean-message-header-flag)))
1578 (mh-invalidate-show-buffer))
1404 (mh-show-msg message)) 1579 (mh-show-msg message))
1405 1580
1406(defun mh-show-mouse (EVENT) 1581(defun mh-show-mouse (event)
1407 "Move point to mouse EVENT and show message." 1582 "Move point to mouse EVENT and show message."
1408 (interactive "e") 1583 (interactive "e")
1409 (mouse-set-point EVENT) 1584 (mouse-set-point event)
1410 (mh-show)) 1585 (mh-show))
1411 1586
1412(defun mh-summary-height () 1587(defun mh-summary-height ()
@@ -1428,10 +1603,12 @@ arguments, after the message has been displayed."
1428 (let ((folder mh-current-folder) 1603 (let ((folder mh-current-folder)
1429 (folders (list mh-current-folder)) 1604 (folders (list mh-current-folder))
1430 (clean-message-header mh-clean-message-header-flag) 1605 (clean-message-header mh-clean-message-header-flag)
1431 (show-window (get-buffer-window mh-show-buffer))) 1606 (show-window (get-buffer-window mh-show-buffer))
1607 (display-mime-buttons-flag mh-display-buttons-for-inline-parts-flag))
1432 (if (not (eq (next-window (minibuffer-window)) (selected-window))) 1608 (if (not (eq (next-window (minibuffer-window)) (selected-window)))
1433 (delete-other-windows)) ; force ourself to the top window 1609 (delete-other-windows)) ; force ourself to the top window
1434 (mh-in-show-buffer (mh-show-buffer) 1610 (mh-in-show-buffer (mh-show-buffer)
1611 (setq mh-display-buttons-for-inline-parts-flag display-mime-buttons-flag)
1435 (if (and show-window 1612 (if (and show-window
1436 (equal (mh-msg-filename msg folder) buffer-file-name)) 1613 (equal (mh-msg-filename msg folder) buffer-file-name))
1437 (progn ;just back up to start 1614 (progn ;just back up to start
@@ -1443,6 +1620,9 @@ arguments, after the message has been displayed."
1443 (shrink-window (- (window-height) (or mh-summary-height 1620 (shrink-window (- (window-height) (or mh-summary-height
1444 (mh-summary-height))))) 1621 (mh-summary-height)))))
1445 (mh-recenter nil) 1622 (mh-recenter nil)
1623 ;; The following line is a nop which forces update of the scan line so
1624 ;; that font-lock will update it (if needed)...
1625 (mh-notate nil nil mh-cmd-note)
1446 (if (not (memq msg mh-seen-list)) 1626 (if (not (memq msg mh-seen-list))
1447 (setq mh-seen-list (cons msg mh-seen-list))) 1627 (setq mh-seen-list (cons msg mh-seen-list)))
1448 (when mh-update-sequences-after-mh-show-flag 1628 (when mh-update-sequences-after-mh-show-flag
@@ -1518,8 +1698,8 @@ Sets the current buffer to the show buffer."
1518 ;; Bind variables in folder buffer in case they are local 1698 ;; Bind variables in folder buffer in case they are local
1519 (let ((formfile mhl-formfile) 1699 (let ((formfile mhl-formfile)
1520 (clean-message-header mh-clean-message-header-flag) 1700 (clean-message-header mh-clean-message-header-flag)
1521 (invisible-headers mh-invisible-headers) 1701 (invisible-headers mh-invisible-header-fields-compiled)
1522 (visible-headers mh-visible-headers) 1702 (visible-headers nil)
1523 (msg-filename (mh-msg-filename msg-num folder-name)) 1703 (msg-filename (mh-msg-filename msg-num folder-name))
1524 (show-buffer mh-show-buffer) 1704 (show-buffer mh-show-buffer)
1525 (mm-inline-media-tests mh-mm-inline-media-tests)) 1705 (mm-inline-media-tests mh-mm-inline-media-tests))
@@ -1596,7 +1776,10 @@ Sets the current buffer to the show buffer."
1596Header is cleaned from START to the end of the message header. 1776Header is cleaned from START to the end of the message header.
1597INVISIBLE-HEADERS contains a regular expression specifying lines to delete 1777INVISIBLE-HEADERS contains a regular expression specifying lines to delete
1598from the header. VISIBLE-HEADERS contains a regular expression specifying the 1778from the header. VISIBLE-HEADERS contains a regular expression specifying the
1599lines to display. INVISIBLE-HEADERS is ignored if VISIBLE-HEADERS is non-nil." 1779lines to display. INVISIBLE-HEADERS is ignored if VISIBLE-HEADERS is non-nil.
1780
1781Note that MH-E no longer supports the `mh-visible-headers' variable, so
1782this function could be trimmed of this feature too."
1600 (let ((case-fold-search t) 1783 (let ((case-fold-search t)
1601 (buffer-read-only nil) 1784 (buffer-read-only nil)
1602 (after-change-functions nil)) ;Work around emacs-20 font-lock bug 1785 (after-change-functions nil)) ;Work around emacs-20 font-lock bug
@@ -1639,8 +1822,7 @@ If NOTATION is nil then no change in the buffer occurs."
1639 (with-mh-folder-updating (t) 1822 (with-mh-folder-updating (t)
1640 (beginning-of-line) 1823 (beginning-of-line)
1641 (forward-char offset) 1824 (forward-char offset)
1642 (let* ((change-stack-flag (and (stringp notation) 1825 (let* ((change-stack-flag (and (equal offset (1+ mh-cmd-note))
1643 (equal offset (1+ mh-cmd-note))
1644 (not (eq notation mh-note-seq)))) 1826 (not (eq notation mh-note-seq))))
1645 (msg (and change-stack-flag (or msg (mh-get-msg-num nil)))) 1827 (msg (and change-stack-flag (or msg (mh-get-msg-num nil))))
1646 (stack (and msg (gethash msg mh-sequence-notation-history))) 1828 (stack (and msg (gethash msg mh-sequence-notation-history)))
@@ -1652,7 +1834,7 @@ If NOTATION is nil then no change in the buffer occurs."
1652 ;; at the bottom of the stack. If the sequence is deleted, 1834 ;; at the bottom of the stack. If the sequence is deleted,
1653 ;; the correct notation will be shown. 1835 ;; the correct notation will be shown.
1654 (setf (gethash msg mh-sequence-notation-history) 1836 (setf (gethash msg mh-sequence-notation-history)
1655 (reverse (cons (aref notation 0) (cdr (reverse stack))))) 1837 (reverse (cons notation (cdr (reverse stack)))))
1656 ;; Since we don't have any sequence notations in the way, just 1838 ;; Since we don't have any sequence notations in the way, just
1657 ;; notate the scan line. 1839 ;; notate the scan line.
1658 (delete-char 1) 1840 (delete-char 1)
@@ -1660,25 +1842,6 @@ If NOTATION is nil then no change in the buffer occurs."
1660 (when change-stack-flag 1842 (when change-stack-flag
1661 (mh-thread-update-scan-line-map msg notation offset))))))) 1843 (mh-thread-update-scan-line-map msg notation offset)))))))
1662 1844
1663(defun mh-find-msg-get-num (step)
1664 "Return the message number of the message nearest the cursor.
1665Jumps over non-message lines, such as inc errors.
1666If we have to search, STEP tells whether to search forward or backward."
1667 (or (mh-get-msg-num nil)
1668 (let ((msg-num nil)
1669 (nreverses 0))
1670 (while (and (not msg-num)
1671 (< nreverses 2))
1672 (cond ((eobp)
1673 (setq step -1)
1674 (setq nreverses (1+ nreverses)))
1675 ((bobp)
1676 (setq step 1)
1677 (setq nreverses (1+ nreverses))))
1678 (forward-line step)
1679 (setq msg-num (mh-get-msg-num nil)))
1680 msg-num)))
1681
1682(defun mh-goto-msg (number &optional no-error-if-no-message dont-show) 1845(defun mh-goto-msg (number &optional no-error-if-no-message dont-show)
1683 "Position the cursor at message NUMBER. 1846 "Position the cursor at message NUMBER.
1684Optional non-nil second argument NO-ERROR-IF-NO-MESSAGE means return nil 1847Optional non-nil second argument NO-ERROR-IF-NO-MESSAGE means return nil
@@ -1699,10 +1862,6 @@ Non-nil third argument DONT-SHOW means not to show the message."
1699 (or dont-show (not return-value) (mh-maybe-show number)) 1862 (or dont-show (not return-value) (mh-maybe-show number))
1700 return-value)) 1863 return-value))
1701 1864
1702(defun mh-msg-search-pat (n)
1703 "Return a search pattern for message N in the scan listing."
1704 (format mh-scan-msg-search-regexp n))
1705
1706(defun mh-get-profile-field (field) 1865(defun mh-get-profile-field (field)
1707 "Find and return the value of FIELD in the current buffer. 1866 "Find and return the value of FIELD in the current buffer.
1708Returns nil if the field is not in the buffer." 1867Returns nil if the field is not in the buffer."
@@ -1716,120 +1875,65 @@ Returns nil if the field is not in the buffer."
1716 (end-of-line) 1875 (end-of-line)
1717 (buffer-substring start (point))))))) 1876 (buffer-substring start (point)))))))
1718 1877
1719(defvar mail-user-agent)
1720(defvar read-mail-command)
1721
1722(defvar mh-find-path-run nil 1878(defvar mh-find-path-run nil
1723 "Non-nil if `mh-find-path' has been run already.") 1879 "Non-nil if `mh-find-path' has been run already.")
1724 1880
1725(defun mh-find-path () 1881(defun mh-find-path ()
1726 "Set `mh-progs', `mh-lib', and `mh-lib-progs' variables. 1882 "Set variables from user's MH profile.
1727Set `mh-user-path', `mh-draft-folder', `mh-unseen-seq', `mh-previous-seq', 1883Set `mh-user-path', `mh-draft-folder', `mh-unseen-seq', `mh-previous-seq',
1728`mh-inbox' from user's MH profile. 1884`mh-inbox' from user's MH profile.
1729The value of `mh-find-path-hook' is a list of functions to be called, with no 1885The value of `mh-find-path-hook' is a list of functions to be called, with no
1730arguments, after these variable have been set." 1886arguments, after these variable have been set."
1731 (mh-find-progs) 1887 (mh-variants)
1732 (unless mh-find-path-run 1888 (unless mh-find-path-run
1733 (setq mh-find-path-run t) 1889 (setq mh-find-path-run t)
1734 (setq read-mail-command 'mh-rmail) 1890 (save-excursion
1735 (setq mail-user-agent 'mh-e-user-agent)) 1891 ;; Be sure profile is fully expanded before switching buffers
1736 (save-excursion 1892 (let ((profile (expand-file-name (or (getenv "MH") "~/.mh_profile"))))
1737 ;; Be sure profile is fully expanded before switching buffers 1893 (set-buffer (get-buffer-create mh-temp-buffer))
1738 (let ((profile (expand-file-name (or (getenv "MH") "~/.mh_profile")))) 1894 (setq buffer-offer-save nil) ;for people who set default to t
1739 (set-buffer (get-buffer-create mh-temp-buffer)) 1895 (erase-buffer)
1740 (setq buffer-offer-save nil) ;for people who set default to t 1896 (condition-case err
1741 (erase-buffer) 1897 (insert-file-contents profile)
1742 (condition-case err 1898 (file-error
1743 (insert-file-contents profile) 1899 (mh-install profile err)))
1744 (file-error 1900 (setq mh-user-path (mh-get-profile-field "Path:"))
1745 (mh-install profile err))) 1901 (if (not mh-user-path)
1746 (setq mh-user-path (mh-get-profile-field "Path:")) 1902 (setq mh-user-path "Mail"))
1747 (if (not mh-user-path) 1903 (setq mh-user-path
1748 (setq mh-user-path "Mail")) 1904 (file-name-as-directory
1749 (setq mh-user-path 1905 (expand-file-name mh-user-path (expand-file-name "~"))))
1750 (file-name-as-directory 1906 (unless mh-x-image-cache-directory
1751 (expand-file-name mh-user-path (expand-file-name "~")))) 1907 (setq mh-x-image-cache-directory
1752 (unless mh-x-image-cache-directory 1908 (expand-file-name ".mhe-x-image-cache" mh-user-path)))
1753 (setq mh-x-image-cache-directory 1909 (setq mh-draft-folder (mh-get-profile-field "Draft-Folder:"))
1754 (expand-file-name ".mhe-x-image-cache" mh-user-path))) 1910 (if mh-draft-folder
1755 (setq mh-draft-folder (mh-get-profile-field "Draft-Folder:")) 1911 (progn
1756 (if mh-draft-folder 1912 (if (not (mh-folder-name-p mh-draft-folder))
1757 (progn 1913 (setq mh-draft-folder (format "+%s" mh-draft-folder)))
1758 (if (not (mh-folder-name-p mh-draft-folder)) 1914 (if (not (file-exists-p (mh-expand-file-name mh-draft-folder)))
1759 (setq mh-draft-folder (format "+%s" mh-draft-folder))) 1915 (error
1760 (if (not (file-exists-p (mh-expand-file-name mh-draft-folder))) 1916 "Draft folder \"%s\" not found. Create it and try again"
1761 (error "Draft folder \"%s\" not found. Create it and try again" 1917 (mh-expand-file-name mh-draft-folder)))))
1762 (mh-expand-file-name mh-draft-folder))))) 1918 (setq mh-inbox (mh-get-profile-field "Inbox:"))
1763 (setq mh-inbox (mh-get-profile-field "Inbox:")) 1919 (cond ((not mh-inbox)
1764 (cond ((not mh-inbox) 1920 (setq mh-inbox "+inbox"))
1765 (setq mh-inbox "+inbox")) 1921 ((not (mh-folder-name-p mh-inbox))
1766 ((not (mh-folder-name-p mh-inbox)) 1922 (setq mh-inbox (format "+%s" mh-inbox))))
1767 (setq mh-inbox (format "+%s" mh-inbox)))) 1923 (setq mh-unseen-seq (mh-get-profile-field "Unseen-Sequence:"))
1768 (setq mh-unseen-seq (mh-get-profile-field "Unseen-Sequence:")) 1924 (if mh-unseen-seq
1769 (if mh-unseen-seq 1925 (setq mh-unseen-seq (intern mh-unseen-seq))
1770 (setq mh-unseen-seq (intern mh-unseen-seq)) 1926 (setq mh-unseen-seq 'unseen)) ;old MH default?
1771 (setq mh-unseen-seq 'unseen)) ;old MH default? 1927 (setq mh-previous-seq (mh-get-profile-field "Previous-Sequence:"))
1772 (setq mh-previous-seq (mh-get-profile-field "Previous-Sequence:")) 1928 (if mh-previous-seq
1773 (if mh-previous-seq 1929 (setq mh-previous-seq (intern mh-previous-seq)))
1774 (setq mh-previous-seq (intern mh-previous-seq))) 1930 (run-hooks 'mh-find-path-hook)
1775 (run-hooks 'mh-find-path-hook) 1931 (mh-collect-folder-names)))))
1776 (mh-collect-folder-names))))
1777 1932
1778(defun mh-file-command-p (file) 1933(defun mh-file-command-p (file)
1779 "Return t if file FILE is the name of a executable regular file." 1934 "Return t if file FILE is the name of a executable regular file."
1780 (and (file-regular-p file) (file-executable-p file))) 1935 (and (file-regular-p file) (file-executable-p file)))
1781 1936
1782(defun mh-find-progs ()
1783 "Find the directories for the installed MH/nmh binaries and config files.
1784Set the `mh-progs' and `mh-lib', and `mh-lib-progs' variables to the
1785directory names and set `mh-nmh-flag' if we detect nmh instead of MH."
1786 (unless (and mh-progs mh-lib mh-lib-progs)
1787 (let ((path (or (mh-path-search exec-path "mhparam")
1788 (mh-path-search '("/usr/local/nmh/bin" ; nmh default
1789 "/usr/local/bin/mh/"
1790 "/usr/local/mh/"
1791 "/usr/bin/mh/" ;Ultrix 4.2, Linux
1792 "/usr/new/mh/" ;Ultrix <4.2
1793 "/usr/contrib/mh/bin/" ;BSDI
1794 "/usr/pkg/bin/" ; NetBSD
1795 "/usr/local/bin/"
1796 )
1797 "mhparam"))))
1798 (if (not path)
1799 (error "Unable to find the `mhparam' command"))
1800 (save-excursion
1801 (let ((tmp-buffer (get-buffer-create mh-temp-buffer)))
1802 (set-buffer tmp-buffer)
1803 (unwind-protect
1804 (progn
1805 (call-process (expand-file-name "mhparam" path)
1806 nil '(t nil) nil "libdir" "etcdir")
1807 (goto-char (point-min))
1808 (if (search-forward-regexp "^libdir:\\s-\\(\\S-+\\)\\s-*$"
1809 nil t)
1810 (setq mh-lib-progs (match-string 1)
1811 mh-lib mh-lib-progs
1812 mh-progs path))
1813 (goto-char (point-min))
1814 (if (search-forward-regexp "^etcdir:\\s-\\(\\S-+\\)\\s-*$"
1815 nil t)
1816 (setq mh-lib (match-string 1)
1817 mh-nmh-flag t)))
1818 (kill-buffer tmp-buffer))))
1819 (unless (and mh-progs mh-lib mh-lib-progs)
1820 (error "Unable to determine paths from `mhparam' command"))
1821 (setq mh-flists-present-flag
1822 (file-exists-p (expand-file-name "flists" mh-progs))))))
1823
1824(defun mh-path-search (path file)
1825 "Search PATH, a list of directory names, for FILE.
1826Returns the element of PATH that contains FILE, or nil if not found."
1827 (while (and path
1828 (not (funcall 'mh-file-command-p
1829 (expand-file-name file (car path)))))
1830 (setq path (cdr path)))
1831 (car path))
1832
1833(defvar mh-no-install nil) ;do not run install-mh 1937(defvar mh-no-install nil) ;do not run install-mh
1834 1938
1835(defun mh-install (profile error-val) 1939(defun mh-install (profile error-val)
@@ -1911,18 +2015,18 @@ not updated."
1911 (let ((entry (mh-find-seq seq)) 2015 (let ((entry (mh-find-seq seq))
1912 (internal-seq-flag (mh-internal-seq seq))) 2016 (internal-seq-flag (mh-internal-seq seq)))
1913 (if (and msgs (atom msgs)) (setq msgs (list msgs))) 2017 (if (and msgs (atom msgs)) (setq msgs (list msgs)))
1914 (unless internal-flag
1915 (mh-add-to-sequence seq msgs)
1916 (when (not dont-annotate-flag)
1917 (mh-iterate-on-range msg msgs
1918 (unless (memq msg (cdr entry))
1919 (mh-add-sequence-notation msg internal-seq-flag)))))
1920 (if (null entry) 2018 (if (null entry)
1921 (setq mh-seq-list 2019 (setq mh-seq-list
1922 (cons (mh-make-seq seq (mh-canonicalize-sequence msgs)) 2020 (cons (mh-make-seq seq (mh-canonicalize-sequence msgs))
1923 mh-seq-list)) 2021 mh-seq-list))
1924 (if msgs (setcdr entry (mh-canonicalize-sequence 2022 (if msgs (setcdr entry (mh-canonicalize-sequence
1925 (append msgs (mh-seq-msgs entry)))))))) 2023 (append msgs (mh-seq-msgs entry))))))
2024 (unless internal-flag
2025 (mh-add-to-sequence seq msgs)
2026 (when (not dont-annotate-flag)
2027 (mh-iterate-on-range msg msgs
2028 (unless (memq msg (cdr entry))
2029 (mh-add-sequence-notation msg internal-seq-flag)))))))
1926 2030
1927(defun mh-canonicalize-sequence (msgs) 2031(defun mh-canonicalize-sequence (msgs)
1928 "Sort MSGS in decreasing order and remove duplicates." 2032 "Sort MSGS in decreasing order and remove duplicates."
@@ -2076,12 +2180,15 @@ aren't usually mail folders are hidden."
2076 (goto-char (point-min)) 2180 (goto-char (point-min))
2077 (while (not (and (eolp) (bolp))) 2181 (while (not (and (eolp) (bolp)))
2078 (goto-char (line-end-position)) 2182 (goto-char (line-end-position))
2079 (let ((has-pos (search-backward " has " (line-beginning-position) t))) 2183 (let ((start-pos (line-beginning-position))
2184 (has-pos (search-backward " has " (line-beginning-position) t)))
2080 (when (integerp has-pos) 2185 (when (integerp has-pos)
2081 (while (equal (char-after has-pos) ? ) 2186 (while (equal (char-after has-pos) ? )
2082 (decf has-pos)) 2187 (decf has-pos))
2083 (incf has-pos) 2188 (incf has-pos)
2084 (let* ((name (buffer-substring (line-beginning-position) has-pos)) 2189 (while (equal (char-after start-pos) ? )
2190 (incf start-pos))
2191 (let* ((name (buffer-substring start-pos has-pos))
2085 (first-char (aref name 0)) 2192 (first-char (aref name 0))
2086 (last-char (aref name (1- (length name))))) 2193 (last-char (aref name (1- (length name)))))
2087 (unless (member first-char '(?. ?# ?,)) 2194 (unless (member first-char '(?. ?# ?,))
@@ -2189,7 +2296,9 @@ whether the completion is over."
2189If ALLOW-ROOT-FOLDER-FLAG is non-nil then \"+\" is allowed to be a folder name 2296If ALLOW-ROOT-FOLDER-FLAG is non-nil then \"+\" is allowed to be a folder name
2190corresponding to `mh-user-path'." 2297corresponding to `mh-user-path'."
2191 (mh-normalize-folder-name 2298 (mh-normalize-folder-name
2192 (let ((minibuffer-local-completion-map mh-folder-completion-map) 2299 (let ((minibuffer-completing-file-name t)
2300 (completion-root-regexp "^[+/]")
2301 (minibuffer-local-completion-map mh-folder-completion-map)
2193 (mh-allow-root-folder-flag allow-root-folder-flag)) 2302 (mh-allow-root-folder-flag allow-root-folder-flag))
2194 (completing-read prompt 'mh-folder-completion-function nil nil nil 2303 (completing-read prompt 'mh-folder-completion-function nil nil nil
2195 'mh-folder-hist default)) 2304 'mh-folder-hist default))
@@ -2206,11 +2315,10 @@ non-nil then the function will accept the folder +, which means all folders
2206when used in searching." 2315when used in searching."
2207 (if (null default) 2316 (if (null default)
2208 (setq default "")) 2317 (setq default ""))
2209 (let* ((default-string (cond (default-string (format " [%s]? " 2318 (let* ((default-string (cond (default-string (format "[%s] " default-string))
2210 default-string)) 2319 ((equal "" default) "")
2211 ((equal "" default) "? ") 2320 (t (format "[%s] " default))))
2212 (t (format " [%s]? " default)))) 2321 (prompt (format "%s folder: %s" prompt default-string))
2213 (prompt (format "%s folder%s" prompt default-string))
2214 (mh-current-folder-name mh-current-folder) 2322 (mh-current-folder-name mh-current-folder)
2215 read-name folder-name) 2323 read-name folder-name)
2216 (while (and (setq read-name (mh-folder-completing-read 2324 (while (and (setq read-name (mh-folder-completing-read
@@ -2452,6 +2560,13 @@ Put the output into buffer after point. Set mark after inserted text."
2452 (setq l (cdr l))) 2560 (setq l (cdr l)))
2453 new-list)) 2561 new-list))
2454 2562
2563(defun mh-replace-string (old new)
2564 "Replace all occurrences of OLD with NEW in the current buffer."
2565 (goto-char (point-min))
2566 (let ((case-fold-search t))
2567 (while (search-forward old nil t)
2568 (replace-match new t t))))
2569
2455(defun mh-replace-in-string (regexp newtext string) 2570(defun mh-replace-in-string (regexp newtext string)
2456 "Replace REGEXP with NEWTEXT everywhere in STRING and return result. 2571 "Replace REGEXP with NEWTEXT everywhere in STRING and return result.
2457NEWTEXT is taken literally---no \\DIGIT escapes will be recognized. 2572NEWTEXT is taken literally---no \\DIGIT escapes will be recognized.
diff --git a/lisp/progmodes/cc-align.el b/lisp/progmodes/cc-align.el
index b51a304c531..c5dd091f291 100644
--- a/lisp/progmodes/cc-align.el
+++ b/lisp/progmodes/cc-align.el
@@ -121,7 +121,7 @@ Works with: arglist-cont-nonempty, arglist-close."
121 ;; like "({". 121 ;; like "({".
122 (when c-special-brace-lists 122 (when c-special-brace-lists
123 (let ((special-list (c-looking-at-special-brace-list))) 123 (let ((special-list (c-looking-at-special-brace-list)))
124 (when special-list 124 (when (and special-list (< (car (car special-list)) (point)))
125 (goto-char (+ (car (car special-list)) 2))))) 125 (goto-char (+ (car (car special-list)) 2)))))
126 126
127 (let ((savepos (point)) 127 (let ((savepos (point))
@@ -380,9 +380,7 @@ Works with: inher-cont, member-init-cont."
380 (back-to-indentation) 380 (back-to-indentation)
381 (let* ((eol (c-point 'eol)) 381 (let* ((eol (c-point 'eol))
382 (here (point)) 382 (here (point))
383 (char-after-ip (progn 383 (char-after-ip (char-after)))
384 (skip-chars-forward " \t")
385 (char-after))))
386 (if (cdr langelem) (goto-char (cdr langelem))) 384 (if (cdr langelem) (goto-char (cdr langelem)))
387 385
388 ;; This kludge is necessary to support both inher-cont and 386 ;; This kludge is necessary to support both inher-cont and
@@ -392,13 +390,12 @@ Works with: inher-cont, member-init-cont."
392 (backward-char) 390 (backward-char)
393 (c-backward-syntactic-ws)) 391 (c-backward-syntactic-ws))
394 392
395 (skip-chars-forward "^:" eol) 393 (c-syntactic-re-search-forward ":" eol 'move)
396 (if (eq char-after-ip ?,) 394 (if (looking-at c-syntactic-eol)
397 (skip-chars-forward " \t" eol) 395 (c-forward-syntactic-ws here)
398 (skip-chars-forward " \t:" eol)) 396 (if (eq char-after-ip ?,)
399 (if (or (eolp) 397 (backward-char)
400 (looking-at c-comment-start-regexp)) 398 (skip-chars-forward " \t" eol)))
401 (c-forward-syntactic-ws here))
402 (if (< (point) here) 399 (if (< (point) here)
403 (vector (current-column))) 400 (vector (current-column)))
404 ))) 401 )))
@@ -952,11 +949,17 @@ Works with: defun-close, defun-block-intro, block-close,
952brace-list-close, brace-list-intro, statement-block-intro and all in* 949brace-list-close, brace-list-intro, statement-block-intro and all in*
953symbols, e.g. inclass and inextern-lang." 950symbols, e.g. inclass and inextern-lang."
954 (save-excursion 951 (save-excursion
955 (goto-char (cdr langelem)) 952 (+ (progn
956 (back-to-indentation) 953 (back-to-indentation)
957 (if (eq (char-syntax (char-after)) ?\() 954 (if (eq (char-syntax (char-after)) ?\()
958 0 955 c-basic-offset
959 c-basic-offset))) 956 0))
957 (progn
958 (goto-char (cdr langelem))
959 (back-to-indentation)
960 (if (eq (char-syntax (char-after)) ?\()
961 0
962 c-basic-offset)))))
960 963
961(defun c-lineup-cpp-define (langelem) 964(defun c-lineup-cpp-define (langelem)
962 "Line up macro continuation lines according to the indentation of 965 "Line up macro continuation lines according to the indentation of
diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el
index a61369004e8..806fbade693 100644
--- a/lisp/progmodes/cc-cmds.el
+++ b/lisp/progmodes/cc-cmds.el
@@ -479,7 +479,11 @@ This function does various newline cleanups based on the value of
479 ;; end up before it. 479 ;; end up before it.
480 (setq delete-temp-newline 480 (setq delete-temp-newline
481 (cons (save-excursion 481 (cons (save-excursion
482 (c-backward-syntactic-ws) 482 (end-of-line 0)
483 (if (eq (char-before) ?\\)
484 ;; Ignore a line continuation.
485 (backward-char))
486 (skip-chars-backward " \t")
483 (copy-marker (point) t)) 487 (copy-marker (point) t))
484 (point-marker)))) 488 (point-marker))))
485 (unwind-protect 489 (unwind-protect
@@ -1971,8 +1975,7 @@ If `c-tab-always-indent' is t, always just indent the current line.
1971If nil, indent the current line only if point is at the left margin or 1975If nil, indent the current line only if point is at the left margin or
1972in the line's indentation; otherwise insert some whitespace[*]. If 1976in the line's indentation; otherwise insert some whitespace[*]. If
1973other than nil or t, then some whitespace[*] is inserted only within 1977other than nil or t, then some whitespace[*] is inserted only within
1974literals (comments and strings) and inside preprocessor directives, 1978literals (comments and strings), but the line is always reindented.
1975but the line is always reindented.
1976 1979
1977If `c-syntactic-indentation' is t, indentation is done according to 1980If `c-syntactic-indentation' is t, indentation is done according to
1978the syntactic context. A numeric argument, regardless of its value, 1981the syntactic context. A numeric argument, regardless of its value,
diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el
index ad8b8a92bff..64f3a72f56f 100644
--- a/lisp/progmodes/cc-defs.el
+++ b/lisp/progmodes/cc-defs.el
@@ -48,7 +48,6 @@
48 48
49;; Silence the compiler. 49;; Silence the compiler.
50(cc-bytecomp-defvar c-enable-xemacs-performance-kludge-p) ; In cc-vars.el 50(cc-bytecomp-defvar c-enable-xemacs-performance-kludge-p) ; In cc-vars.el
51(cc-bytecomp-defvar c-emacs-features) ; In cc-vars.el
52(cc-bytecomp-defun buffer-syntactic-context-depth) ; XEmacs 51(cc-bytecomp-defun buffer-syntactic-context-depth) ; XEmacs
53(cc-bytecomp-defun region-active-p) ; XEmacs 52(cc-bytecomp-defun region-active-p) ; XEmacs
54(cc-bytecomp-defvar zmacs-region-stays) ; XEmacs 53(cc-bytecomp-defvar zmacs-region-stays) ; XEmacs
@@ -105,7 +104,7 @@
105 104
106;;; Variables also used at compile time. 105;;; Variables also used at compile time.
107 106
108(defconst c-version "5.30.8" 107(defconst c-version "5.30.9"
109 "CC Mode version number.") 108 "CC Mode version number.")
110 109
111(defconst c-version-sym (intern c-version)) 110(defconst c-version-sym (intern c-version))
@@ -620,20 +619,36 @@ This function does not do any hidden buffer changes."
620 (eq (char-before) ?\\))) 619 (eq (char-before) ?\\)))
621 (backward-char)))) 620 (backward-char))))
622 621
622(eval-and-compile
623 (defvar c-langs-are-parametric nil))
624
623(defmacro c-major-mode-is (mode) 625(defmacro c-major-mode-is (mode)
624 "Return non-nil if the current CC Mode major mode is MODE. 626 "Return non-nil if the current CC Mode major mode is MODE.
625MODE is either a mode symbol or a list of mode symbols. 627MODE is either a mode symbol or a list of mode symbols.
626 628
627This function does not do any hidden buffer changes." 629This function does not do any hidden buffer changes."
628 (if (eq (car-safe mode) 'quote) 630
629 (let ((mode (eval mode))) 631 (if c-langs-are-parametric
630 (if (listp mode) 632 ;; Inside a `c-lang-defconst'.
631 `(memq c-buffer-is-cc-mode ',mode) 633 `(c-lang-major-mode-is ,mode)
632 `(eq c-buffer-is-cc-mode ',mode))) 634
633 `(let ((mode ,mode)) 635 (if (eq (car-safe mode) 'quote)
634 (if (listp mode) 636 (let ((mode (eval mode)))
635 (memq c-buffer-is-cc-mode mode) 637 (if (listp mode)
636 (eq c-buffer-is-cc-mode mode))))) 638 `(memq c-buffer-is-cc-mode ',mode)
639 `(eq c-buffer-is-cc-mode ',mode)))
640
641 `(let ((mode ,mode))
642 (if (listp mode)
643 (memq c-buffer-is-cc-mode mode)
644 (eq c-buffer-is-cc-mode mode))))))
645
646(defmacro c-mode-is-new-awk-p ()
647 ;; Is the current mode the "new" awk mode? It is important for
648 ;; (e.g.) the cc-engine functions do distinguish between the old and
649 ;; new awk-modes.
650 '(and (c-major-mode-is 'awk-mode)
651 (memq 'syntax-properties c-emacs-features)))
637 652
638(defmacro c-parse-sexp-lookup-properties () 653(defmacro c-parse-sexp-lookup-properties ()
639 ;; Return the value of the variable that says whether the 654 ;; Return the value of the variable that says whether the
@@ -968,13 +983,6 @@ the value of the variable with that name.
968This function does not do any hidden buffer changes." 983This function does not do any hidden buffer changes."
969 (symbol-value (c-mode-symbol suffix))) 984 (symbol-value (c-mode-symbol suffix)))
970 985
971(defsubst c-mode-is-new-awk-p ()
972 ;; Is the current mode the "new" awk mode? It is important for
973 ;; (e.g.) the cc-engine functions do distinguish between the old and
974 ;; new awk-modes.
975 (and (c-major-mode-is 'awk-mode)
976 (memq 'syntax-properties c-emacs-features)))
977
978(defsubst c-got-face-at (pos faces) 986(defsubst c-got-face-at (pos faces)
979 "Return non-nil if position POS in the current buffer has any of the 987 "Return non-nil if position POS in the current buffer has any of the
980faces in the list FACES. 988faces in the list FACES.
@@ -1057,11 +1065,155 @@ current language (taken from `c-buffer-is-cc-mode')."
1057(put 'c-make-keywords-re 'lisp-indent-function 1) 1065(put 'c-make-keywords-re 'lisp-indent-function 1)
1058 1066
1059 1067
1068;; Figure out what features this Emacs has
1069
1070(cc-bytecomp-defvar open-paren-in-column-0-is-defun-start)
1071
1072(defconst c-emacs-features
1073 (let (list)
1074
1075 (if (boundp 'infodock-version)
1076 ;; I've no idea what this actually is, but it's legacy. /mast
1077 (setq list (cons 'infodock list)))
1078
1079 ;; XEmacs 19 and beyond use 8-bit modify-syntax-entry flags.
1080 ;; Emacs 19 uses a 1-bit flag. We will have to set up our
1081 ;; syntax tables differently to handle this.
1082 (let ((table (copy-syntax-table))
1083 entry)
1084 (modify-syntax-entry ?a ". 12345678" table)
1085 (cond
1086 ;; XEmacs 19, and beyond Emacs 19.34
1087 ((arrayp table)
1088 (setq entry (aref table ?a))
1089 ;; In Emacs, table entries are cons cells
1090 (if (consp entry) (setq entry (car entry))))
1091 ;; XEmacs 20
1092 ((fboundp 'get-char-table) (setq entry (get-char-table ?a table)))
1093 ;; before and including Emacs 19.34
1094 ((and (fboundp 'char-table-p)
1095 (char-table-p table))
1096 (setq entry (car (char-table-range table [?a]))))
1097 ;; incompatible
1098 (t (error "CC Mode is incompatible with this version of Emacs")))
1099 (setq list (cons (if (= (logand (lsh entry -16) 255) 255)
1100 '8-bit
1101 '1-bit)
1102 list)))
1103
1104 (let ((buf (generate-new-buffer " test"))
1105 parse-sexp-lookup-properties
1106 parse-sexp-ignore-comments
1107 lookup-syntax-properties)
1108 (save-excursion
1109 (set-buffer buf)
1110 (set-syntax-table (make-syntax-table))
1111
1112 ;; For some reason we have to set some of these after the
1113 ;; buffer has been made current. (Specifically,
1114 ;; `parse-sexp-ignore-comments' in Emacs 21.)
1115 (setq parse-sexp-lookup-properties t
1116 parse-sexp-ignore-comments t
1117 lookup-syntax-properties t)
1118
1119 ;; Find out if the `syntax-table' text property works.
1120 (modify-syntax-entry ?< ".")
1121 (modify-syntax-entry ?> ".")
1122 (insert "<()>")
1123 (c-mark-<-as-paren 1)
1124 (c-mark->-as-paren 4)
1125 (goto-char 1)
1126 (c-forward-sexp)
1127 (if (= (point) 5)
1128 (setq list (cons 'syntax-properties list)))
1129
1130 ;; Find out if generic comment delimiters work.
1131 (c-safe
1132 (modify-syntax-entry ?x "!")
1133 (if (string-match "\\s!" "x")
1134 (setq list (cons 'gen-comment-delim list))))
1135
1136 ;; Find out if generic string delimiters work.
1137 (c-safe
1138 (modify-syntax-entry ?x "|")
1139 (if (string-match "\\s|" "x")
1140 (setq list (cons 'gen-string-delim list))))
1141
1142 ;; See if POSIX char classes work.
1143 (when (and (string-match "[[:alpha:]]" "a")
1144 ;; All versions of Emacs 21 so far haven't fixed
1145 ;; char classes in `skip-chars-forward' and
1146 ;; `skip-chars-backward'.
1147 (progn
1148 (delete-region (point-min) (point-max))
1149 (insert "foo123")
1150 (skip-chars-backward "[:alnum:]")
1151 (bobp))
1152 (= (skip-chars-forward "[:alpha:]") 3))
1153 (setq list (cons 'posix-char-classes list)))
1154
1155 ;; See if `open-paren-in-column-0-is-defun-start' exists and
1156 ;; isn't buggy.
1157 (when (boundp 'open-paren-in-column-0-is-defun-start)
1158 (let ((open-paren-in-column-0-is-defun-start nil)
1159 (parse-sexp-ignore-comments t))
1160 (delete-region (point-min) (point-max))
1161 (set-syntax-table (make-syntax-table))
1162 (modify-syntax-entry ?\' "\"")
1163 (cond
1164 ;; XEmacs. Afaik this is currently an Emacs-only
1165 ;; feature, but it's good to be prepared.
1166 ((memq '8-bit list)
1167 (modify-syntax-entry ?/ ". 1456")
1168 (modify-syntax-entry ?* ". 23"))
1169 ;; Emacs
1170 ((memq '1-bit list)
1171 (modify-syntax-entry ?/ ". 124b")
1172 (modify-syntax-entry ?* ". 23")))
1173 (modify-syntax-entry ?\n "> b")
1174 (insert "/* '\n () */")
1175 (backward-sexp)
1176 (if (bobp)
1177 (setq list (cons 'col-0-paren list)))))
1178
1179 (set-buffer-modified-p nil))
1180 (kill-buffer buf))
1181
1182 ;; See if `parse-partial-sexp' returns the eighth element.
1183 (when (c-safe (>= (length (save-excursion (parse-partial-sexp 1 1))) 10))
1184 (setq list (cons 'pps-extended-state list)))
1185
1186 ;;(message "c-emacs-features: %S" list)
1187 list)
1188 "A list of certain features in the (X)Emacs you are using.
1189There are many flavors of Emacs out there, each with different
1190features supporting those needed by CC Mode. The following values
1191might be present:
1192
1193'8-bit 8 bit syntax entry flags (XEmacs style).
1194'1-bit 1 bit syntax entry flags (Emacs style).
1195'syntax-properties It works to override the syntax for specific characters
1196 in the buffer with the 'syntax-table property.
1197'gen-comment-delim Generic comment delimiters work
1198 (i.e. the syntax class `!').
1199'gen-string-delim Generic string delimiters work
1200 (i.e. the syntax class `|').
1201'pps-extended-state `parse-partial-sexp' returns a list with at least 10
1202 elements, i.e. it contains the position of the
1203 start of the last comment or string.
1204'posix-char-classes The regexp engine understands POSIX character classes.
1205'col-0-paren It's possible to turn off the ad-hoc rule that a paren
1206 in column zero is the start of a defun.
1207'infodock This is Infodock (based on XEmacs).
1208
1209'8-bit and '1-bit are mutually exclusive.")
1210
1211
1060;;; Some helper constants. 1212;;; Some helper constants.
1061 1213
1062;; If the regexp engine supports POSIX char classes (e.g. Emacs 21) 1214;; If the regexp engine supports POSIX char classes then we can use
1063;; then we can use them to handle extended charsets correctly. 1215;; them to handle extended charsets correctly.
1064(if (string-match "[[:alpha:]]" "a") ; Can't use c-emacs-features here. 1216(if (memq 'posix-char-classes c-emacs-features)
1065 (progn 1217 (progn
1066 (defconst c-alpha "[:alpha:]") 1218 (defconst c-alpha "[:alpha:]")
1067 (defconst c-alnum "[:alnum:]") 1219 (defconst c-alnum "[:alnum:]")
@@ -1127,8 +1279,8 @@ system."
1127 (error "The mode name symbol `%s' must end with \"-mode\"" mode)) 1279 (error "The mode name symbol `%s' must end with \"-mode\"" mode))
1128 (put mode 'c-mode-prefix (match-string 1 (symbol-name mode))) 1280 (put mode 'c-mode-prefix (match-string 1 (symbol-name mode)))
1129 (unless (get base-mode 'c-mode-prefix) 1281 (unless (get base-mode 'c-mode-prefix)
1130 (error "Unknown base mode `%s'" base-mode) 1282 (error "Unknown base mode `%s'" base-mode))
1131 (put mode 'c-fallback-mode base-mode))) 1283 (put mode 'c-fallback-mode base-mode))
1132 1284
1133(defvar c-lang-constants (make-vector 151 0)) 1285(defvar c-lang-constants (make-vector 151 0))
1134;; This obarray is a cache to keep track of the language constants 1286;; This obarray is a cache to keep track of the language constants
@@ -1144,7 +1296,6 @@ system."
1144;; various other symbols, but those don't have any variable bindings. 1296;; various other symbols, but those don't have any variable bindings.
1145 1297
1146(defvar c-lang-const-expansion nil) 1298(defvar c-lang-const-expansion nil)
1147(defvar c-langs-are-parametric nil)
1148 1299
1149(defsubst c-get-current-file () 1300(defsubst c-get-current-file ()
1150 ;; Return the base name of the current file. 1301 ;; Return the base name of the current file.
@@ -1585,6 +1736,22 @@ This macro does not do any hidden buffer changes."
1585 1736
1586 c-lang-constants))) 1737 c-lang-constants)))
1587 1738
1739(defun c-lang-major-mode-is (mode)
1740 ;; `c-major-mode-is' expands to a call to this function inside
1741 ;; `c-lang-defconst'. Here we also match the mode(s) against any
1742 ;; fallback modes for the one in `c-buffer-is-cc-mode', so that
1743 ;; e.g. (c-major-mode-is 'c++-mode) is true in a derived language
1744 ;; that has c++-mode as base mode.
1745 (unless (listp mode)
1746 (setq mode (list mode)))
1747 (let (match (buf-mode c-buffer-is-cc-mode))
1748 (while (if (memq buf-mode mode)
1749 (progn
1750 (setq match t)
1751 nil)
1752 (setq buf-mode (get buf-mode 'c-fallback-mode))))
1753 match))
1754
1588 1755
1589(cc-provide 'cc-defs) 1756(cc-provide 'cc-defs)
1590 1757
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 2e907589304..ea36064412f 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -1270,7 +1270,7 @@ This function does not do any hidden buffer changes."
1270 1270
1271 (when (and (= beg end) 1271 (when (and (= beg end)
1272 (get-text-property beg 'c-in-sws) 1272 (get-text-property beg 'c-in-sws)
1273 (not (bobp)) 1273 (> beg (point-min))
1274 (get-text-property (1- beg) 'c-in-sws)) 1274 (get-text-property (1- beg) 'c-in-sws))
1275 ;; Ensure that an `c-in-sws' range gets broken. Note that it isn't 1275 ;; Ensure that an `c-in-sws' range gets broken. Note that it isn't
1276 ;; safe to keep a range that was continuous before the change. E.g: 1276 ;; safe to keep a range that was continuous before the change. E.g:
@@ -1906,7 +1906,7 @@ This function does not do any hidden buffer changes."
1906 (if last-pos 1906 (if last-pos
1907 ;; Prepare to loop, but record the open paren only if it's 1907 ;; Prepare to loop, but record the open paren only if it's
1908 ;; outside a macro or within the same macro as point, and 1908 ;; outside a macro or within the same macro as point, and
1909 ;; if it is a "real" open paren and not some character 1909 ;; if it is a legitimate open paren and not some character
1910 ;; that got an open paren syntax-table property. 1910 ;; that got an open paren syntax-table property.
1911 (progn 1911 (progn
1912 (setq pos last-pos) 1912 (setq pos last-pos)
@@ -1914,7 +1914,11 @@ This function does not do any hidden buffer changes."
1914 (save-excursion 1914 (save-excursion
1915 (goto-char last-pos) 1915 (goto-char last-pos)
1916 (not (c-beginning-of-macro)))) 1916 (not (c-beginning-of-macro))))
1917 (= (char-syntax (char-before last-pos)) ?\()) 1917 ;; Check for known types of parens that we want
1918 ;; to record. The syntax table is not to be
1919 ;; trusted here since the caller might be using
1920 ;; e.g. `c++-template-syntax-table'.
1921 (memq (char-before last-pos) '(?{ ?\( ?\[)))
1918 (setq c-state-cache (cons (1- last-pos) c-state-cache)))) 1922 (setq c-state-cache (cons (1- last-pos) c-state-cache))))
1919 1923
1920 (if (setq last-pos (c-up-list-forward pos)) 1924 (if (setq last-pos (c-up-list-forward pos))
@@ -2124,7 +2128,7 @@ This function does not do any hidden buffer changes."
2124 (when (c-major-mode-is 'pike-mode) 2128 (when (c-major-mode-is 'pike-mode)
2125 ;; Handle the `<operator> syntax in Pike. 2129 ;; Handle the `<operator> syntax in Pike.
2126 (let ((pos (point))) 2130 (let ((pos (point)))
2127 (skip-chars-backward "!%&*+\\-/<=>^|~[]()") 2131 (skip-chars-backward "-!%&*+/<=>^|~[]()")
2128 (and (if (< (skip-chars-backward "`") 0) 2132 (and (if (< (skip-chars-backward "`") 0)
2129 t 2133 t
2130 (goto-char pos) 2134 (goto-char pos)
@@ -2144,7 +2148,7 @@ This function does not do any hidden buffer changes."
2144 (and (c-major-mode-is 'pike-mode) 2148 (and (c-major-mode-is 'pike-mode)
2145 ;; Handle the `<operator> syntax in Pike. 2149 ;; Handle the `<operator> syntax in Pike.
2146 (let ((pos (point))) 2150 (let ((pos (point)))
2147 (if (and (< (skip-chars-backward "!%&*+\\-/<=>^|~[]()") 0) 2151 (if (and (< (skip-chars-backward "-!%&*+/<=>^|~[]()") 0)
2148 (< (skip-chars-backward "`") 0) 2152 (< (skip-chars-backward "`") 0)
2149 (looking-at c-symbol-key) 2153 (looking-at c-symbol-key)
2150 (>= (match-end 0) pos)) 2154 (>= (match-end 0) pos))
@@ -2384,8 +2388,11 @@ outside any comment, macro or string literal, or else the content of
2384that region is taken as syntactically significant text. 2388that region is taken as syntactically significant text.
2385 2389
2386If PAREN-LEVEL is non-nil, an additional restriction is added to 2390If PAREN-LEVEL is non-nil, an additional restriction is added to
2387ignore matches in nested paren sexps, and the search will also not go 2391ignore matches in nested paren sexps. The search will also not go
2388outside the current paren sexp. 2392outside the current list sexp, which has the effect that if the point
2393should be moved to BOUND when no match is found \(i.e. NOERROR is
2394neither nil nor t), then it will be at the closing paren if the end of
2395the current list sexp is encountered first.
2389 2396
2390If NOT-INSIDE-TOKEN is non-nil, matches in the middle of tokens are 2397If NOT-INSIDE-TOKEN is non-nil, matches in the middle of tokens are
2391ignored. Things like multicharacter operators and special symbols 2398ignored. Things like multicharacter operators and special symbols
@@ -2401,11 +2408,15 @@ subexpression is never tested before the starting position, so it
2401might be a good idea to include \\=\\= as a match alternative in it. 2408might be a good idea to include \\=\\= as a match alternative in it.
2402 2409
2403Optimization note: Matches might be missed if the \"look behind\" 2410Optimization note: Matches might be missed if the \"look behind\"
2404subexpression should match the end of nonwhite syntactic whitespace, 2411subexpression can match the end of nonwhite syntactic whitespace,
2405i.e. the end of comments or cpp directives. This since the function 2412i.e. the end of comments or cpp directives. This since the function
2406skips over such things before resuming the search. It's also not safe 2413skips over such things before resuming the search. It's on the other
2407to assume that the \"look behind\" subexpression never can match 2414hand not safe to assume that the \"look behind\" subexpression never
2408syntactic whitespace." 2415matches syntactic whitespace.
2416
2417Bug: Unbalanced parens inside cpp directives are currently not handled
2418correctly \(i.e. they don't get ignored as they should) when
2419PAREN-LEVEL is set."
2409 2420
2410 (or bound (setq bound (point-max))) 2421 (or bound (setq bound (point-max)))
2411 (if paren-level (setq paren-level -1)) 2422 (if paren-level (setq paren-level -1))
@@ -2413,53 +2424,55 @@ syntactic whitespace."
2413 ;;(message "c-syntactic-re-search-forward %s %s %S" (point) bound regexp) 2424 ;;(message "c-syntactic-re-search-forward %s %s %S" (point) bound regexp)
2414 2425
2415 (let ((start (point)) 2426 (let ((start (point))
2416 (pos (point)) 2427 tmp
2428 ;; Start position for the last search.
2429 search-pos
2430 ;; The `parse-partial-sexp' state between the start position
2431 ;; and the point.
2432 state
2433 ;; The current position after the last state update. The next
2434 ;; `parse-partial-sexp' continues from here.
2435 (state-pos (point))
2436 ;; The position at which to check the state and the state
2437 ;; there. This is separate from `state-pos' since we might
2438 ;; need to back up before doing the next search round.
2439 check-pos check-state
2440 ;; Last position known to end a token.
2417 (last-token-end-pos (point-min)) 2441 (last-token-end-pos (point-min))
2418 match-pos found state check-pos check-state tmp) 2442 ;; Set when a valid match is found.
2443 found)
2419 2444
2420 (condition-case err 2445 (condition-case err
2421 (while 2446 (while
2422 (and 2447 (and
2423 (re-search-forward regexp bound noerror) 2448 (progn
2449 (setq search-pos (point))
2450 (re-search-forward regexp bound noerror))
2424 2451
2425 (progn 2452 (progn
2426 (setq match-pos (point) 2453 (setq state (parse-partial-sexp
2427 state (parse-partial-sexp 2454 state-pos (match-beginning 0) paren-level nil state)
2428 pos (match-beginning 0) paren-level nil state) 2455 state-pos (point))
2429 pos (point))
2430 (if (setq check-pos (and lookbehind-submatch 2456 (if (setq check-pos (and lookbehind-submatch
2457 (or (not paren-level)
2458 (>= (car state) 0))
2431 (match-end lookbehind-submatch))) 2459 (match-end lookbehind-submatch)))
2432 (setq check-state (parse-partial-sexp 2460 (setq check-state (parse-partial-sexp
2433 pos check-pos paren-level nil state)) 2461 state-pos check-pos paren-level nil state))
2434 (setq check-pos pos 2462 (setq check-pos state-pos
2435 check-state state)) 2463 check-state state))
2436 2464
2437 ;; If we got a look behind subexpression and get an 2465 ;; NOTE: If we got a look behind subexpression and get
2438 ;; insignificant match in something that isn't 2466 ;; an insignificant match in something that isn't
2439 ;; syntactic whitespace (i.e. strings or in nested 2467 ;; syntactic whitespace (i.e. strings or in nested
2440 ;; parentheses), then we can never skip more than a 2468 ;; parentheses), then we can never skip more than a
2441 ;; single character from the match position before 2469 ;; single character from the match start position
2442 ;; continuing the search. That since the look behind 2470 ;; (i.e. `state-pos' here) before continuing the
2443 ;; subexpression might match the end of the 2471 ;; search. That since the look behind subexpression
2444 ;; insignificant region. 2472 ;; might match the end of the insignificant region in
2473 ;; the next search.
2445 2474
2446 (cond 2475 (cond
2447 ((setq tmp (elt check-state 3))
2448 ;; Match inside a string.
2449 (if (or lookbehind-submatch
2450 (not (integerp tmp)))
2451 (goto-char (min (1+ pos) bound))
2452 ;; Skip to the end of the string before continuing.
2453 (let ((ender (make-string 1 tmp)) (continue t))
2454 (while (if (search-forward ender bound noerror)
2455 (progn
2456 (setq state (parse-partial-sexp
2457 pos (point) nil nil state)
2458 pos (point))
2459 (elt state 3))
2460 (setq continue nil)))
2461 continue)))
2462
2463 ((elt check-state 7) 2476 ((elt check-state 7)
2464 ;; Match inside a line comment. Skip to eol. Use 2477 ;; Match inside a line comment. Skip to eol. Use
2465 ;; `re-search-forward' instead of `skip-chars-forward' to get 2478 ;; `re-search-forward' instead of `skip-chars-forward' to get
@@ -2472,6 +2485,7 @@ syntactic whitespace."
2472 2485
2473 ((and (not (elt check-state 5)) 2486 ((and (not (elt check-state 5))
2474 (eq (char-before check-pos) ?/) 2487 (eq (char-before check-pos) ?/)
2488 (not (c-get-char-property (1- check-pos) 'syntax-table))
2475 (memq (char-after check-pos) '(?/ ?*))) 2489 (memq (char-after check-pos) '(?/ ?*)))
2476 ;; Match in the middle of the opener of a block or line 2490 ;; Match in the middle of the opener of a block or line
2477 ;; comment. 2491 ;; comment.
@@ -2479,20 +2493,57 @@ syntactic whitespace."
2479 (re-search-forward "[\n\r]" bound noerror) 2493 (re-search-forward "[\n\r]" bound noerror)
2480 (search-forward "*/" bound noerror))) 2494 (search-forward "*/" bound noerror)))
2481 2495
2482 ((and not-inside-token 2496 ;; The last `parse-partial-sexp' above might have
2483 (or (< check-pos last-token-end-pos) 2497 ;; stopped short of the real check position if the end
2484 (< check-pos 2498 ;; of the current sexp was encountered in paren-level
2485 (save-excursion 2499 ;; mode. The checks above are always false in that
2486 (goto-char check-pos) 2500 ;; case, and since they can do better skipping in
2487 (save-match-data 2501 ;; lookbehind-submatch mode, we do them before
2488 (c-end-of-current-token last-token-end-pos)) 2502 ;; checking the paren level.
2489 (setq last-token-end-pos (point)))))) 2503
2490 ;; Match inside a token. 2504 ((and paren-level
2491 (cond ((<= (point) bound) 2505 (/= (setq tmp (car check-state)) 0))
2492 (goto-char (min (1+ pos) bound)) 2506 ;; Check the paren level first since we're short of the
2493 t) 2507 ;; syntactic checking position if the end of the
2494 (noerror nil) 2508 ;; current sexp was encountered by `parse-partial-sexp'.
2495 (t (signal 'search-failed "end of token")))) 2509 (if (> tmp 0)
2510
2511 ;; Inside a nested paren sexp.
2512 (if lookbehind-submatch
2513 ;; See the NOTE above.
2514 (progn (goto-char state-pos) t)
2515 ;; Skip out of the paren quickly.
2516 (setq state (parse-partial-sexp state-pos bound 0 nil state)
2517 state-pos (point)))
2518
2519 ;; Have exited the current paren sexp.
2520 (if noerror
2521 (progn
2522 ;; The last `parse-partial-sexp' call above
2523 ;; has left us just after the closing paren
2524 ;; in this case, so we can modify the bound
2525 ;; to leave the point at the right position
2526 ;; upon return.
2527 (setq bound (1- (point)))
2528 nil)
2529 (signal 'search-failed (list regexp)))))
2530
2531 ((setq tmp (elt check-state 3))
2532 ;; Match inside a string.
2533 (if (or lookbehind-submatch
2534 (not (integerp tmp)))
2535 ;; See the NOTE above.
2536 (progn (goto-char state-pos) t)
2537 ;; Skip to the end of the string before continuing.
2538 (let ((ender (make-string 1 tmp)) (continue t))
2539 (while (if (search-forward ender bound noerror)
2540 (progn
2541 (setq state (parse-partial-sexp
2542 state-pos (point) nil nil state)
2543 state-pos (point))
2544 (elt state 3))
2545 (setq continue nil)))
2546 continue)))
2496 2547
2497 ((save-excursion 2548 ((save-excursion
2498 (save-match-data 2549 (save-match-data
@@ -2501,48 +2552,52 @@ syntactic whitespace."
2501 (c-end-of-macro) 2552 (c-end-of-macro)
2502 (cond ((<= (point) bound) t) 2553 (cond ((<= (point) bound) t)
2503 (noerror nil) 2554 (noerror nil)
2504 (t (signal 'search-failed "end of macro")))) 2555 (t (signal 'search-failed (list regexp)))))
2505 2556
2506 ((and paren-level 2557 ((and not-inside-token
2507 (/= (setq tmp (car check-state)) 0)) 2558 (or (< check-pos last-token-end-pos)
2508 (if (> tmp 0) 2559 (< check-pos
2509 ;; Match inside a nested paren sexp. 2560 (save-excursion
2510 (if lookbehind-submatch 2561 (goto-char check-pos)
2511 (goto-char (min (1+ pos) bound)) 2562 (save-match-data
2512 ;; Skip out of the paren quickly. 2563 (c-end-of-current-token last-token-end-pos))
2513 (setq state (parse-partial-sexp pos bound 0 nil state) 2564 (setq last-token-end-pos (point))))))
2514 pos (point))) 2565 ;; Inside a token.
2515 ;; Have exited the current paren sexp. The 2566 (if lookbehind-submatch
2516 ;; `parse-partial-sexp' above has left us just after the 2567 ;; See the NOTE above.
2517 ;; closing paren in this case. Just make 2568 (goto-char state-pos)
2518 ;; `re-search-forward' above fail in the appropriate way; 2569 (goto-char (min last-token-end-pos bound))))
2519 ;; we'll adjust the leave off point below if necessary.
2520 (setq bound (point))))
2521 2570
2522 (t 2571 (t
2523 ;; A real match. 2572 ;; A real match.
2524 (setq found t) 2573 (setq found t)
2525 nil))))) 2574 nil)))
2575
2576 ;; Should loop to search again, but take care to avoid
2577 ;; looping on the same spot.
2578 (or (/= search-pos (point))
2579 (if (= (point) bound)
2580 (if noerror
2581 nil
2582 (signal 'search-failed (list regexp)))
2583 (forward-char)
2584 t))))
2526 2585
2527 (error 2586 (error
2528 (goto-char start) 2587 (goto-char start)
2529 (signal (car err) (cdr err)))) 2588 (signal (car err) (cdr err))))
2530 2589
2531 ;;(message "c-syntactic-re-search-forward done %s" (or match-pos (point))) 2590 ;;(message "c-syntactic-re-search-forward done %s" (or (match-end 0) (point)))
2532 2591
2533 (if found 2592 (if found
2534 (progn 2593 (progn
2535 (goto-char match-pos) 2594 (goto-char (match-end 0))
2536 match-pos) 2595 (match-end 0))
2537 2596
2538 ;; Search failed. Set point as appropriate. 2597 ;; Search failed. Set point as appropriate.
2539 (cond ((eq noerror t) 2598 (if (eq noerror t)
2540 (goto-char start)) 2599 (goto-char start)
2541 (paren-level 2600 (goto-char bound))
2542 (if (eq (car (parse-partial-sexp pos bound -1 nil state)) -1)
2543 (backward-char)))
2544 (t
2545 (goto-char bound)))
2546 nil))) 2601 nil)))
2547 2602
2548(defun c-syntactic-skip-backward (skip-chars &optional limit) 2603(defun c-syntactic-skip-backward (skip-chars &optional limit)
@@ -4030,12 +4085,13 @@ This function does not do any hidden buffer changes."
4030(defun c-forward-type () 4085(defun c-forward-type ()
4031 ;; Move forward over a type spec if at the beginning of one, 4086 ;; Move forward over a type spec if at the beginning of one,
4032 ;; stopping at the next following token. Return t if it's a known 4087 ;; stopping at the next following token. Return t if it's a known
4033 ;; type that can't be a name, 'known if it's an otherwise known type 4088 ;; type that can't be a name or other expression, 'known if it's an
4034 ;; (according to `*-font-lock-extra-types'), 'prefix if it's a known 4089 ;; otherwise known type (according to `*-font-lock-extra-types'),
4035 ;; prefix of a type, 'found if it's a type that matches one in 4090 ;; 'prefix if it's a known prefix of a type, 'found if it's a type
4036 ;; `c-found-types', 'maybe if it's an identfier that might be a 4091 ;; that matches one in `c-found-types', 'maybe if it's an identfier
4037 ;; type, or nil if it can't be a type (the point isn't moved then). 4092 ;; that might be a type, or nil if it can't be a type (the point
4038 ;; The point is assumed to be at the beginning of a token. 4093 ;; isn't moved then). The point is assumed to be at the beginning
4094 ;; of a token.
4039 ;; 4095 ;;
4040 ;; Note that this function doesn't skip past the brace definition 4096 ;; Note that this function doesn't skip past the brace definition
4041 ;; that might be considered part of the type, e.g. 4097 ;; that might be considered part of the type, e.g.
@@ -4199,11 +4255,14 @@ This function does not do any hidden buffer changes."
4199 ;; don't let the existence of the operator itself promote two 4255 ;; don't let the existence of the operator itself promote two
4200 ;; uncertain types to a certain one. 4256 ;; uncertain types to a certain one.
4201 (cond ((eq res t)) 4257 (cond ((eq res t))
4202 ((or (eq res 'known) (memq res2 '(t known))) 4258 ((eq res2 t)
4203 (c-add-type id-start id-end) 4259 (c-add-type id-start id-end)
4204 (when c-record-type-identifiers 4260 (when c-record-type-identifiers
4205 (c-record-type-id id-range)) 4261 (c-record-type-id id-range))
4206 (setq res t)) 4262 (setq res t))
4263 ((eq res 'known))
4264 ((eq res2 'known)
4265 (setq res 'known))
4207 ((eq res 'found)) 4266 ((eq res 'found))
4208 ((eq res2 'found) 4267 ((eq res2 'found)
4209 (setq res 'found)) 4268 (setq res 'found))
@@ -4526,7 +4585,8 @@ brace."
4526 4585
4527 ;; `c-beginning-of-statement-1' stops at a block start, but we 4586 ;; `c-beginning-of-statement-1' stops at a block start, but we
4528 ;; want to continue if the block doesn't begin a top level 4587 ;; want to continue if the block doesn't begin a top level
4529 ;; construct, i.e. if it isn't preceded by ';', '}', ':', or bob. 4588 ;; construct, i.e. if it isn't preceded by ';', '}', ':', bob,
4589 ;; or an open paren.
4530 (let ((beg (point)) tentative-move) 4590 (let ((beg (point)) tentative-move)
4531 (while (and 4591 (while (and
4532 ;; Must check with c-opt-method-key in ObjC mode. 4592 ;; Must check with c-opt-method-key in ObjC mode.
@@ -4536,6 +4596,9 @@ brace."
4536 (progn 4596 (progn
4537 (c-backward-syntactic-ws lim) 4597 (c-backward-syntactic-ws lim)
4538 (not (memq (char-before) '(?\; ?} ?: nil)))) 4598 (not (memq (char-before) '(?\; ?} ?: nil))))
4599 (save-excursion
4600 (backward-char)
4601 (not (looking-at "\\s(")))
4539 ;; Check that we don't move from the first thing in a 4602 ;; Check that we don't move from the first thing in a
4540 ;; macro to its header. 4603 ;; macro to its header.
4541 (not (eq (setq tentative-move 4604 (not (eq (setq tentative-move
@@ -4972,33 +5035,44 @@ brace."
4972 (condition-case () 5035 (condition-case ()
4973 (save-excursion 5036 (save-excursion
4974 (let ((beg (point)) 5037 (let ((beg (point))
4975 end type) 5038 inner-beg end type)
4976 (c-forward-syntactic-ws) 5039 (c-forward-syntactic-ws)
4977 (if (eq (char-after) ?\() 5040 (if (eq (char-after) ?\()
4978 (progn 5041 (progn
4979 (forward-char 1) 5042 (forward-char 1)
4980 (c-forward-syntactic-ws) 5043 (c-forward-syntactic-ws)
5044 (setq inner-beg (point))
4981 (setq type (assq (char-after) c-special-brace-lists))) 5045 (setq type (assq (char-after) c-special-brace-lists)))
4982 (if (setq type (assq (char-after) c-special-brace-lists)) 5046 (if (setq type (assq (char-after) c-special-brace-lists))
4983 (progn 5047 (progn
5048 (setq inner-beg (point))
4984 (c-backward-syntactic-ws) 5049 (c-backward-syntactic-ws)
4985 (forward-char -1) 5050 (forward-char -1)
4986 (setq beg (if (eq (char-after) ?\() 5051 (setq beg (if (eq (char-after) ?\()
4987 (point) 5052 (point)
4988 nil))))) 5053 nil)))))
4989 (if (and beg type) 5054 (if (and beg type)
4990 (if (and (c-safe (goto-char beg) 5055 (if (and (c-safe
4991 (c-forward-sexp 1) 5056 (goto-char beg)
4992 (setq end (point)) 5057 (c-forward-sexp 1)
4993 (= (char-before) ?\))) 5058 (setq end (point))
4994 (c-safe (goto-char beg) 5059 (= (char-before) ?\)))
4995 (forward-char 1) 5060 (c-safe
5061 (goto-char inner-beg)
5062 (if (looking-at "\\s(")
5063 ;; Check balancing of the inner paren
5064 ;; below.
5065 (progn
4996 (c-forward-sexp 1) 5066 (c-forward-sexp 1)
4997 ;; Kludges needed to handle inner 5067 t)
4998 ;; chars both with and without 5068 ;; If the inner char isn't a paren then
4999 ;; paren syntax. 5069 ;; we can't check balancing, so just
5000 (or (/= (char-syntax (char-before)) ?\)) 5070 ;; check the char before the outer
5001 (= (char-before) (cdr type))))) 5071 ;; closing paren.
5072 (goto-char end)
5073 (backward-char)
5074 (c-backward-syntactic-ws)
5075 (= (char-before) (cdr type)))))
5002 (if (or (/= (char-syntax (char-before)) ?\)) 5076 (if (or (/= (char-syntax (char-before)) ?\))
5003 (= (progn 5077 (= (progn
5004 (c-forward-syntactic-ws) 5078 (c-forward-syntactic-ws)
@@ -6272,7 +6346,7 @@ This function does not do any hidden buffer changes."
6272 (goto-char containing-sexp) 6346 (goto-char containing-sexp)
6273 (setq placeholder (c-point 'boi)) 6347 (setq placeholder (c-point 'boi))
6274 (if (and (c-safe (backward-up-list 1) t) 6348 (if (and (c-safe (backward-up-list 1) t)
6275 (> (point) placeholder)) 6349 (>= (point) placeholder))
6276 (progn 6350 (progn
6277 (forward-char) 6351 (forward-char)
6278 (skip-chars-forward " \t")) 6352 (skip-chars-forward " \t"))
@@ -6313,7 +6387,7 @@ This function does not do any hidden buffer changes."
6313 (goto-char containing-sexp) 6387 (goto-char containing-sexp)
6314 (setq placeholder (c-point 'boi)) 6388 (setq placeholder (c-point 'boi))
6315 (when (and (c-safe (backward-up-list 1) t) 6389 (when (and (c-safe (backward-up-list 1) t)
6316 (> (point) placeholder)) 6390 (>= (point) placeholder))
6317 (forward-char) 6391 (forward-char)
6318 (skip-chars-forward " \t") 6392 (skip-chars-forward " \t")
6319 (setq placeholder (point))) 6393 (setq placeholder (point)))
@@ -6354,7 +6428,7 @@ This function does not do any hidden buffer changes."
6354 (goto-char containing-sexp) 6428 (goto-char containing-sexp)
6355 (setq placeholder (c-point 'boi)) 6429 (setq placeholder (c-point 'boi))
6356 (if (and (c-safe (backward-up-list 1) t) 6430 (if (and (c-safe (backward-up-list 1) t)
6357 (> (point) placeholder)) 6431 (>= (point) placeholder))
6358 (progn 6432 (progn
6359 (forward-char) 6433 (forward-char)
6360 (skip-chars-forward " \t")) 6434 (skip-chars-forward " \t"))
@@ -6830,6 +6904,10 @@ This function does not do any hidden buffer changes."
6830 ((vectorp offset) offset) 6904 ((vectorp offset) offset)
6831 ((null offset) nil) 6905 ((null offset) nil)
6832 ((listp offset) 6906 ((listp offset)
6907 (if (eq (car offset) 'quote)
6908 (error
6909"Setting in c-offsets-alist element \"(%s . '%s)\" was mistakenly quoted"
6910 symbol (cadr offset)))
6833 (let (done) 6911 (let (done)
6834 (while (and (not done) offset) 6912 (while (and (not done) offset)
6835 (setq done (c-evaluate-offset (car offset) langelem symbol) 6913 (setq done (c-evaluate-offset (car offset) langelem symbol)
diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el
index 27c604b3f33..c5bbfaf86dd 100644
--- a/lisp/progmodes/cc-fonts.el
+++ b/lisp/progmodes/cc-fonts.el
@@ -574,33 +574,65 @@ casts and declarations are fontified. Used on level 2 and higher."
574 ;; Fontify leading identifiers in fully qualified names like 574 ;; Fontify leading identifiers in fully qualified names like
575 ;; "foo::bar" in languages that supports such things. 575 ;; "foo::bar" in languages that supports such things.
576 ,@(when (c-lang-const c-opt-identifier-concat-key) 576 ,@(when (c-lang-const c-opt-identifier-concat-key)
577 `((,(byte-compile 577 (if (c-major-mode-is 'java-mode)
578 ;; Must use a function here since we match longer 578 ;; Java needs special treatment since "." is used both to
579 ;; than we want to move before doing a new search. 579 ;; qualify names and in normal indexing. Here we look for
580 ;; This is not necessary for XEmacs >= 20 since it 580 ;; capital characters at the beginning of an identifier to
581 ;; restarts the search from the end of the first 581 ;; recognize the class. "*" is also recognized to cover
582 ;; highlighted submatch (something that causes 582 ;; wildcard import declarations. All preceding dot separated
583 ;; problems in other places). 583 ;; identifiers are taken as package names and therefore
584 `(lambda (limit) 584 ;; fontified as references.
585 (while (re-search-forward 585 `(,(c-make-font-lock-search-function
586 ,(concat "\\(\\<" ; 1 586 ;; Search for class identifiers preceded by ".". The
587 "\\(" (c-lang-const c-symbol-key) "\\)" ; 2 587 ;; anchored matcher takes it from there.
588 "[ \t\n\r\f\v]*" 588 (concat (c-lang-const c-opt-identifier-concat-key)
589 (c-lang-const c-opt-identifier-concat-key) 589 "[ \t\n\r\f\v]*"
590 "[ \t\n\r\f\v]*" 590 (concat "\\("
591 "\\)" 591 "[" c-upper "][" (c-lang-const c-symbol-chars) "]*"
592 "\\(" 592 "\\|"
593 (c-lang-const c-opt-after-id-concat-key) 593 "\\*"
594 "\\)") 594 "\\)"))
595 limit t) 595 `((let (id-end)
596 (unless (progn 596 (goto-char (1+ (match-beginning 0)))
597 (goto-char (match-beginning 0)) 597 (while (and (eq (char-before) ?.)
598 (c-skip-comments-and-strings limit)) 598 (progn
599 (or (get-text-property (match-beginning 2) 'face) 599 (backward-char)
600 (c-put-font-lock-face (match-beginning 2) 600 (c-backward-syntactic-ws)
601 (match-end 2) 601 (setq id-end (point))
602 c-reference-face-name)) 602 (< (skip-chars-backward
603 (goto-char (match-end 1))))))))) 603 ,(c-lang-const c-symbol-chars)) 0))
604 (not (get-text-property (point) 'face)))
605 (c-put-font-lock-face (point) id-end c-reference-face-name)
606 (c-backward-syntactic-ws)))
607 nil
608 (goto-char (match-end 0)))))
609
610 `((,(byte-compile
611 ;; Must use a function here since we match longer than we
612 ;; want to move before doing a new search. This is not
613 ;; necessary for XEmacs >= 20 since it restarts the search
614 ;; from the end of the first highlighted submatch (something
615 ;; that causes problems in other places).
616 `(lambda (limit)
617 (while (re-search-forward
618 ,(concat "\\(\\<" ; 1
619 "\\(" (c-lang-const c-symbol-key) "\\)" ; 2
620 "[ \t\n\r\f\v]*"
621 (c-lang-const c-opt-identifier-concat-key)
622 "[ \t\n\r\f\v]*"
623 "\\)"
624 "\\("
625 (c-lang-const c-opt-after-id-concat-key)
626 "\\)")
627 limit t)
628 (unless (progn
629 (goto-char (match-beginning 0))
630 (c-skip-comments-and-strings limit))
631 (or (get-text-property (match-beginning 2) 'face)
632 (c-put-font-lock-face (match-beginning 2)
633 (match-end 2)
634 c-reference-face-name))
635 (goto-char (match-end 1))))))))))
604 636
605 ;; Fontify the special declarations in Objective-C. 637 ;; Fontify the special declarations in Objective-C.
606 ,@(when (c-major-mode-is 'objc-mode) 638 ,@(when (c-major-mode-is 'objc-mode)
@@ -787,17 +819,19 @@ casts and declarations are fontified. Used on level 2 and higher."
787 (<= (point) limit) 819 (<= (point) limit)
788 820
789 ;; Search syntactically to the end of the declarator (";", 821 ;; Search syntactically to the end of the declarator (";",
790 ;; ",", ")", ">" (for <> arglists), eob etc) or to the 822 ;; ",", a closen paren, eob etc) or to the beginning of an
791 ;; beginning of an initializer or function prototype ("=" 823 ;; initializer or function prototype ("=" or "\\s\(").
792 ;; or "\\s\("). 824 ;; Note that the open paren will match array specs in
825 ;; square brackets, and we treat them as initializers too.
793 (c-syntactic-re-search-forward 826 (c-syntactic-re-search-forward
794 "[\];,\{\}\[\)>]\\|\\'\\|\\(=\\|\\(\\s\(\\)\\)" limit t t)) 827 "[;,]\\|\\s)\\|\\'\\|\\(=\\|\\s(\\)" limit t t))
795 828
796 (setq next-pos (match-beginning 0) 829 (setq next-pos (match-beginning 0)
797 id-face (if (match-beginning 2) 830 id-face (if (eq (char-after next-pos) ?\()
798 'font-lock-function-name-face 831 'font-lock-function-name-face
799 'font-lock-variable-name-face) 832 'font-lock-variable-name-face)
800 got-init (match-beginning 1)) 833 got-init (and (match-beginning 1)
834 (char-after (match-beginning 1))))
801 835
802 (if types 836 (if types
803 ;; Register and fontify the identifer as a type. 837 ;; Register and fontify the identifer as a type.
@@ -828,9 +862,17 @@ casts and declarations are fontified. Used on level 2 and higher."
828 (goto-char limit))) 862 (goto-char limit)))
829 863
830 (got-init 864 (got-init
831 ;; Skip an initializer expression. 865 ;; Skip an initializer expression. If we're at a '='
832 (if (c-syntactic-re-search-forward "[;,]" limit 'move t) 866 ;; then accept a brace list directly after it to cope
833 (backward-char))) 867 ;; with array initializers. Otherwise stop at braces
868 ;; to avoid going past full function and class blocks.
869 (and (if (and (eq got-init ?=)
870 (= (c-forward-token-2) 0)
871 (looking-at "{"))
872 (c-safe (c-forward-sexp) t)
873 t)
874 (c-syntactic-re-search-forward "[;,{]" limit 'move t)
875 (backward-char)))
834 876
835 (t (c-forward-syntactic-ws limit))) 877 (t (c-forward-syntactic-ws limit)))
836 878
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index 19555b37527..6aeb70ba4e3 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -374,6 +374,12 @@ identifiers, or nil in languages that don't have such things. Does
374not contain a \\| operator at the top level." 374not contain a \\| operator at the top level."
375 t nil 375 t nil
376 c++ "::" 376 c++ "::"
377 ;; Java has "." to concatenate identifiers but it's also used for
378 ;; normal indexing. There's special code in the Java font lock
379 ;; rules to fontify qualified identifiers based on the standard
380 ;; naming conventions. We still define "." here to make
381 ;; `c-forward-name' move over as long names as possible which is
382 ;; necessary to e.g. handle throws clauses correctly.
377 java "\\." 383 java "\\."
378 idl "::" 384 idl "::"
379 pike "\\(::\\|\\.\\)") 385 pike "\\(::\\|\\.\\)")
diff --git a/lisp/progmodes/cc-styles.el b/lisp/progmodes/cc-styles.el
index 13ffd310fce..1a26e54bf06 100644
--- a/lisp/progmodes/cc-styles.el
+++ b/lisp/progmodes/cc-styles.el
@@ -355,6 +355,8 @@ when used elsewhere."
355 (completing-read prompt c-style-alist nil t 355 (completing-read prompt c-style-alist nil t
356 (cons c-indentation-style 0) 356 (cons c-indentation-style 0)
357 'c-set-style-history)))))) 357 'c-set-style-history))))))
358 (or (stringp stylename)
359 (error "Argument to c-set-style was not a string"))
358 (c-initialize-builtin-style) 360 (c-initialize-builtin-style)
359 (let ((vars (c-get-style-variables stylename nil))) 361 (let ((vars (c-get-style-variables stylename nil)))
360 (unless dont-override 362 (unless dont-override
diff --git a/lisp/progmodes/cc-vars.el b/lisp/progmodes/cc-vars.el
index f21531c2f22..2ed23f8ef86 100644
--- a/lisp/progmodes/cc-vars.el
+++ b/lisp/progmodes/cc-vars.el
@@ -271,12 +271,12 @@ nil."
271 271
272(defcustom c-tab-always-indent t 272(defcustom c-tab-always-indent t
273 "*Controls the operation of the TAB key. 273 "*Controls the operation of the TAB key.
274If t, hitting TAB always just indents the current line. If nil, 274If t, hitting TAB always just indents the current line. If nil, hitting
275hitting TAB indents the current line if point is at the left margin or 275TAB indents the current line if point is at the left margin or in the
276in the line's indentation, otherwise it insert a `real' tab character 276line's indentation, otherwise it inserts a `real' tab character \(see
277\(see note\). If the symbol `other', then tab is inserted only within 277note\). If some other value (not nil or t), then tab is inserted only
278literals -- defined as comments and strings -- and inside preprocessor 278within literals \(comments and strings), but the line is always
279directives, but the line is always reindented. 279reindented.
280 280
281Note: The value of `indent-tabs-mode' will determine whether a real 281Note: The value of `indent-tabs-mode' will determine whether a real
282tab character will be inserted, or the equivalent number of spaces. 282tab character will be inserted, or the equivalent number of spaces.
@@ -1546,140 +1546,6 @@ Set from `c-comment-prefix-regexp' at mode initialization.")
1546(make-variable-buffer-local 'c-current-comment-prefix) 1546(make-variable-buffer-local 'c-current-comment-prefix)
1547 1547
1548 1548
1549;; Figure out what features this Emacs has
1550
1551(cc-bytecomp-defvar open-paren-in-column-0-is-defun-start)
1552
1553(defconst c-emacs-features
1554 (let (list)
1555
1556 (if (boundp 'infodock-version)
1557 ;; I've no idea what this actually is, but it's legacy. /mast
1558 (setq list (cons 'infodock list)))
1559
1560 ;; XEmacs 19 and beyond use 8-bit modify-syntax-entry flags.
1561 ;; Emacs 19 uses a 1-bit flag. We will have to set up our
1562 ;; syntax tables differently to handle this.
1563 (let ((table (copy-syntax-table))
1564 entry)
1565 (modify-syntax-entry ?a ". 12345678" table)
1566 (cond
1567 ;; XEmacs 19, and beyond Emacs 19.34
1568 ((arrayp table)
1569 (setq entry (aref table ?a))
1570 ;; In Emacs, table entries are cons cells
1571 (if (consp entry) (setq entry (car entry))))
1572 ;; XEmacs 20
1573 ((fboundp 'get-char-table) (setq entry (get-char-table ?a table)))
1574 ;; before and including Emacs 19.34
1575 ((and (fboundp 'char-table-p)
1576 (char-table-p table))
1577 (setq entry (car (char-table-range table [?a]))))
1578 ;; incompatible
1579 (t (error "CC Mode is incompatible with this version of Emacs")))
1580 (setq list (cons (if (= (logand (lsh entry -16) 255) 255)
1581 '8-bit
1582 '1-bit)
1583 list)))
1584
1585 (let ((buf (generate-new-buffer " test"))
1586 parse-sexp-lookup-properties
1587 parse-sexp-ignore-comments
1588 lookup-syntax-properties)
1589 (save-excursion
1590 (set-buffer buf)
1591 (set-syntax-table (make-syntax-table))
1592
1593 ;; For some reason we have to set some of these after the
1594 ;; buffer has been made current. (Specifically,
1595 ;; `parse-sexp-ignore-comments' in Emacs 21.)
1596 (setq parse-sexp-lookup-properties t
1597 parse-sexp-ignore-comments t
1598 lookup-syntax-properties t)
1599
1600 ;; Find out if the `syntax-table' text property works.
1601 (modify-syntax-entry ?< ".")
1602 (modify-syntax-entry ?> ".")
1603 (insert "<()>")
1604 (c-mark-<-as-paren 1)
1605 (c-mark->-as-paren 4)
1606 (goto-char 1)
1607 (c-forward-sexp)
1608 (if (= (point) 5)
1609 (setq list (cons 'syntax-properties list)))
1610
1611 ;; Find out if generic comment delimiters work.
1612 (c-safe
1613 (modify-syntax-entry ?x "!")
1614 (if (string-match "\\s!" "x")
1615 (setq list (cons 'gen-comment-delim list))))
1616
1617 ;; Find out if generic string delimiters work.
1618 (c-safe
1619 (modify-syntax-entry ?x "|")
1620 (if (string-match "\\s|" "x")
1621 (setq list (cons 'gen-string-delim list))))
1622
1623 ;; See if `open-paren-in-column-0-is-defun-start' exists and
1624 ;; isn't buggy.
1625 (when (boundp 'open-paren-in-column-0-is-defun-start)
1626 (let ((open-paren-in-column-0-is-defun-start nil)
1627 (parse-sexp-ignore-comments t))
1628 (set-syntax-table (make-syntax-table))
1629 (modify-syntax-entry ?\' "\"")
1630 (cond
1631 ;; XEmacs. Afaik this is currently an Emacs-only
1632 ;; feature, but it's good to be prepared.
1633 ((memq '8-bit list)
1634 (modify-syntax-entry ?/ ". 1456")
1635 (modify-syntax-entry ?* ". 23"))
1636 ;; Emacs
1637 ((memq '1-bit list)
1638 (modify-syntax-entry ?/ ". 124b")
1639 (modify-syntax-entry ?* ". 23")))
1640 (modify-syntax-entry ?\n "> b")
1641 (insert "/* '\n () */")
1642 (backward-sexp)
1643 (if (bobp)
1644 (setq list (cons 'col-0-paren list))))
1645 (kill-buffer buf))
1646
1647 (set-buffer-modified-p nil))
1648 (kill-buffer buf))
1649
1650 ;; See if `parse-partial-sexp' returns the eighth element.
1651 (when (c-safe (>= (length (save-excursion (parse-partial-sexp 1 1))) 10))
1652 (setq list (cons 'pps-extended-state list)))
1653
1654 ;; See if POSIX char classes work.
1655 (when (string-match "[[:alpha:]]" "a")
1656 (setq list (cons 'posix-char-classes list)))
1657
1658 list)
1659 "A list of certain features in the (X)Emacs you are using.
1660There are many flavors of Emacs out there, each with different
1661features supporting those needed by CC Mode. The following values
1662might be present:
1663
1664'8-bit 8 bit syntax entry flags (XEmacs style).
1665'1-bit 1 bit syntax entry flags (Emacs style).
1666'syntax-properties It works to override the syntax for specific characters
1667 in the buffer with the 'syntax-table property.
1668'gen-comment-delim Generic comment delimiters work
1669 (i.e. the syntax class `!').
1670'gen-string-delim Generic string delimiters work
1671 (i.e. the syntax class `|').
1672'pps-extended-state `parse-partial-sexp' returns a list with at least 10
1673 elements, i.e. it contains the position of the
1674 start of the last comment or string.
1675'posix-char-classes The regexp engine understands POSIX character classes.
1676'col-0-paren It's possible to turn off the ad-hoc rule that a paren
1677 in column zero is the start of a defun.
1678'infodock This is Infodock (based on XEmacs).
1679
1680'8-bit and '1-bit are mutually exclusive.")
1681
1682
1683(cc-provide 'cc-vars) 1549(cc-provide 'cc-vars)
1684 1550
1685;;; arch-tag: d62e9a55-c9fe-409b-b5b6-050b6aa202c9 1551;;; arch-tag: d62e9a55-c9fe-409b-b5b6-050b6aa202c9
diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el
index 033ce883e5f..32fa246b9f6 100644
--- a/lisp/progmodes/compile.el
+++ b/lisp/progmodes/compile.el
@@ -1101,7 +1101,9 @@ from a different message."
1101move point to the error message line and type \\[compile-goto-error]. 1101move point to the error message line and type \\[compile-goto-error].
1102To kill the compilation, type \\[kill-compilation]. 1102To kill the compilation, type \\[kill-compilation].
1103 1103
1104Runs `compilation-mode-hook' with `run-hooks' (which see)." 1104Runs `compilation-mode-hook' with `run-hooks' (which see).
1105
1106\\{compilation-mode-map}"
1105 (interactive) 1107 (interactive)
1106 (kill-all-local-variables) 1108 (kill-all-local-variables)
1107 (use-local-map compilation-mode-map) 1109 (use-local-map compilation-mode-map)
diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el
index f47ca3a73d4..cef86f8f90e 100644
--- a/lisp/progmodes/sh-script.el
+++ b/lisp/progmodes/sh-script.el
@@ -353,6 +353,11 @@ the car and cdr are the same symbol.")
353(defvar sh-shell (sh-canonicalize-shell (file-name-nondirectory sh-shell-file)) 353(defvar sh-shell (sh-canonicalize-shell (file-name-nondirectory sh-shell-file))
354 "The shell being programmed. This is set by \\[sh-set-shell].") 354 "The shell being programmed. This is set by \\[sh-set-shell].")
355 355
356(defvar sh-mode-abbrev-table nil)
357
358(define-abbrev-table 'sh-mode-abbrev-table ())
359
360
356;; I turned off this feature because it doesn't permit typing commands 361;; I turned off this feature because it doesn't permit typing commands
357;; in the usual way without help. 362;; in the usual way without help.
358;;(defvar sh-abbrevs 363;;(defvar sh-abbrevs
@@ -1483,7 +1488,7 @@ Calls the value of `sh-set-shell-hook' if set."
1483 (setq require-final-newline tem))) 1488 (setq require-final-newline tem)))
1484 (setq 1489 (setq
1485 comment-start-skip "#+[\t ]*" 1490 comment-start-skip "#+[\t ]*"
1486;;; local-abbrev-table (sh-feature sh-abbrevs) 1491 local-abbrev-table sh-mode-abbrev-table
1487 mode-line-process (format "[%s]" sh-shell) 1492 mode-line-process (format "[%s]" sh-shell)
1488 sh-shell-variables nil 1493 sh-shell-variables nil
1489 sh-shell-variables-initialized nil 1494 sh-shell-variables-initialized nil
diff --git a/lisp/progmodes/which-func.el b/lisp/progmodes/which-func.el
index 87df0769314..845c995371d 100644
--- a/lisp/progmodes/which-func.el
+++ b/lisp/progmodes/which-func.el
@@ -186,7 +186,7 @@ It creates the Imenu index for the buffer, if necessary."
186 (which-func-update-1 (selected-window))) 186 (which-func-update-1 (selected-window)))
187 187
188(defun which-func-update-1 (window) 188(defun which-func-update-1 (window)
189 "Update the Which-Function mode display for window WINDOW." 189 "Update the Which Function mode display for window WINDOW."
190 (with-selected-window window 190 (with-selected-window window
191 (when which-func-mode 191 (when which-func-mode
192 (condition-case info 192 (condition-case info
diff --git a/lisp/ps-mule.el b/lisp/ps-mule.el
index 1d13358f53d..4b41c41b69c 100644
--- a/lisp/ps-mule.el
+++ b/lisp/ps-mule.el
@@ -273,7 +273,7 @@ CHARSET is a charset (symbol) for this font family,
273 273
274FONT-TYPE is a font type: normal, bold, italic, or bold-italic. 274FONT-TYPE is a font type: normal, bold, italic, or bold-italic.
275 275
276FONT-SRC is a font source: builtin, ps-bdf, vflib, or nil. 276FONT-SRC is a font source: builtin, bdf, vflib, or nil.
277 277
278 If FONT-SRC is builtin, FONT-NAME is a built-in PostScript font name. 278 If FONT-SRC is builtin, FONT-NAME is a built-in PostScript font name.
279 279
diff --git a/lisp/speedbar.el b/lisp/speedbar.el
index f8e9386585d..0556af489ef 100644
--- a/lisp/speedbar.el
+++ b/lisp/speedbar.el
@@ -689,8 +689,16 @@ file."
689 :type '(repeat (regexp :tag "Extension Regexp")) 689 :type '(repeat (regexp :tag "Extension Regexp"))
690 :set (lambda (sym val) 690 :set (lambda (sym val)
691 (setq speedbar-supported-extension-expressions val 691 (setq speedbar-supported-extension-expressions val
692 speedbar-file-regexp (speedbar-extension-list-to-regex val))) 692 speedbar-file-regexp (speedbar-extension-list-to-regex val))))
693 ) 693
694(defcustom speedbar-scan-subdirs nil
695 "*Non-nil means speedbar will check if subdirs are empty.
696That way you don't have to click on them to find out. But this
697incurs extra I/O, hence it slows down directory display
698proportionally to the number of subdirs."
699 :group 'speedbar
700 :type 'boolean
701 :version 21.4)
694 702
695(defvar speedbar-file-regexp 703(defvar speedbar-file-regexp
696 (speedbar-extension-list-to-regex speedbar-supported-extension-expressions) 704 (speedbar-extension-list-to-regex speedbar-supported-extension-expressions)
@@ -2185,21 +2193,17 @@ the file-system."
2185 ;; find the directory, either in the cache, or build it. 2193 ;; find the directory, either in the cache, or build it.
2186 (or (cdr-safe (assoc directory speedbar-directory-contents-alist)) 2194 (or (cdr-safe (assoc directory speedbar-directory-contents-alist))
2187 (let ((default-directory directory) 2195 (let ((default-directory directory)
2188 (dir (directory-files directory nil)) 2196 (case-fold-search read-file-name-completion-ignore-case)
2189 (dirs nil) 2197 dirs files)
2190 (files nil)) 2198 (dolist (file (directory-files directory nil))
2191 (while dir 2199 (or (string-match speedbar-file-unshown-regexp file)
2192 (if (not 2200 (string-match speedbar-directory-unshown-regexp file)
2193 (or (string-match speedbar-file-unshown-regexp (car dir)) 2201 (if (file-directory-p file)
2194 (string-match speedbar-directory-unshown-regexp (car dir)))) 2202 (setq dirs (cons file dirs))
2195 (if (file-directory-p (car dir)) 2203 (setq files (cons file files)))))
2196 (setq dirs (cons (car dir) dirs)) 2204 (let ((nl `(,(nreverse dirs) ,(nreverse files))))
2197 (setq files (cons (car dir) files))))
2198 (setq dir (cdr dir)))
2199 (let ((nl (cons (nreverse dirs) (list (nreverse files)))))
2200 (aput 'speedbar-directory-contents-alist directory nl) 2205 (aput 'speedbar-directory-contents-alist directory nl)
2201 nl)) 2206 nl))))
2202 ))
2203 2207
2204(defun speedbar-directory-buttons (directory index) 2208(defun speedbar-directory-buttons (directory index)
2205 "Insert a single button group at point for DIRECTORY. 2209 "Insert a single button group at point for DIRECTORY.
@@ -2343,34 +2347,40 @@ position to insert a new item, and that the new item will end with a CR."
2343 2347
2344;;; Build button lists 2348;;; Build button lists
2345;; 2349;;
2346(defun speedbar-insert-files-at-point (files level) 2350(defun speedbar-insert-files-at-point (files level directory)
2347 "Insert list of FILES starting at point, and indenting all files to LEVEL. 2351 "Insert list of FILES starting at point, and indenting all files to LEVEL.
2348Tag expandable items with a +, otherwise a ?. Don't highlight ? as we 2352Tag expandable items with a +, otherwise a ?. Don't highlight ? as we
2349don't know how to manage them. The input parameter FILES is a cons 2353don't know how to manage them. The input parameter FILES is a cons
2350cell of the form ( 'DIRLIST . 'FILELIST )." 2354cell of the form ( 'DIRLIST . 'FILELIST )."
2351 ;; Start inserting all the directories 2355 ;; Start inserting all the directories
2352 (let ((dirs (car files))) 2356 (dolist (dir (car files))
2353 (while dirs 2357 (if (if speedbar-scan-subdirs
2354 (speedbar-make-tag-line 'angle ?+ 'speedbar-dired (car dirs) 2358 (condition-case nil
2355 (car dirs) 'speedbar-dir-follow nil 2359 (let ((l (speedbar-file-lists (concat directory dir))))
2356 'speedbar-directory-face level) 2360 (or (car l) (cadr l)))
2357 (setq dirs (cdr dirs)))) 2361 (file-error))
2358 (let ((lst (car (cdr files))) 2362 (file-readable-p (concat directory dir)))
2359 (case-fold-search t)) 2363 (speedbar-make-tag-line 'angle ?+ 'speedbar-dired dir
2360 (while lst 2364 dir 'speedbar-dir-follow nil
2361 (let* ((known (string-match speedbar-file-regexp (car lst))) 2365 'speedbar-directory-face level)
2366 (speedbar-make-tag-line 'angle ? nil dir
2367 dir 'speedbar-dir-follow nil
2368 'speedbar-directory-face level)))
2369 (let ((case-fold-search read-file-name-completion-ignore-case))
2370 (dolist (file (cadr files))
2371 (let* ((known (and (file-readable-p (concat directory file))
2372 (string-match speedbar-file-regexp file)))
2362 (expchar (if known ?+ ??)) 2373 (expchar (if known ?+ ??))
2363 (fn (if known 'speedbar-tag-file nil))) 2374 (fn (if known 'speedbar-tag-file nil)))
2364 (if (or speedbar-show-unknown-files (/= expchar ??)) 2375 (if (or speedbar-show-unknown-files (/= expchar ??))
2365 (speedbar-make-tag-line 'bracket expchar fn (car lst) 2376 (speedbar-make-tag-line 'bracket expchar fn file
2366 (car lst) 'speedbar-find-file nil 2377 file 'speedbar-find-file nil
2367 'speedbar-file-face level))) 2378 'speedbar-file-face level))))))
2368 (setq lst (cdr lst)))))
2369 2379
2370(defun speedbar-default-directory-list (directory index) 2380(defun speedbar-default-directory-list (directory index)
2371 "Insert files for DIRECTORY with level INDEX at point." 2381 "Insert files for DIRECTORY with level INDEX at point."
2372 (speedbar-insert-files-at-point 2382 (speedbar-insert-files-at-point
2373 (speedbar-file-lists directory) index) 2383 (speedbar-file-lists directory) index directory)
2374 (speedbar-reset-scanners) 2384 (speedbar-reset-scanners)
2375 (if (= index 0) 2385 (if (= index 0)
2376 ;; If the shown files variable has extra directories, then 2386 ;; If the shown files variable has extra directories, then
@@ -2918,7 +2928,7 @@ updated."
2918 (newcf (if newcfd newcfd)) 2928 (newcf (if newcfd newcfd))
2919 (lastb (current-buffer)) 2929 (lastb (current-buffer))
2920 (sucf-recursive (boundp 'sucf-recursive)) 2930 (sucf-recursive (boundp 'sucf-recursive))
2921 (case-fold-search t)) 2931 (case-fold-search read-file-name-completion-ignore-case))
2922 (if (and newcf 2932 (if (and newcf
2923 ;; check here, that way we won't refresh to newcf until 2933 ;; check here, that way we won't refresh to newcf until
2924 ;; its been written, thus saving ourselves some time 2934 ;; its been written, thus saving ourselves some time
@@ -4235,9 +4245,7 @@ IMAGESPEC is the image data, and DOCSTRING is documentation for the image."
4235 (speedbar-convert-emacs21-imagespec-to-xemacs (quote ,imagespec))) 4245 (speedbar-convert-emacs21-imagespec-to-xemacs (quote ,imagespec)))
4236 'buffer) 4246 'buffer)
4237 (error nil)) 4247 (error nil))
4238 ,docstring)) 4248 ,docstring)))))
4239
4240)))
4241 4249
4242(defimage-speedbar speedbar-directory-plus 4250(defimage-speedbar speedbar-directory-plus
4243 ((:type xpm :file "sb-dir-plus.xpm" :ascent center)) 4251 ((:type xpm :file "sb-dir-plus.xpm" :ascent center))
@@ -4247,6 +4255,10 @@ IMAGESPEC is the image data, and DOCSTRING is documentation for the image."
4247 ((:type xpm :file "sb-dir-minus.xpm" :ascent center)) 4255 ((:type xpm :file "sb-dir-minus.xpm" :ascent center))
4248 "Image used for open directories with stuff in them.") 4256 "Image used for open directories with stuff in them.")
4249 4257
4258(defimage-speedbar speedbar-directory
4259 ((:type xpm :file "sb-dir.xpm" :ascent center))
4260 "Image used for empty or unreadable directories.")
4261
4250(defimage-speedbar speedbar-page-plus 4262(defimage-speedbar speedbar-page-plus
4251 ((:type xpm :file "sb-pg-plus.xpm" :ascent center)) 4263 ((:type xpm :file "sb-pg-plus.xpm" :ascent center))
4252 "Image used for closed files with stuff in them.") 4264 "Image used for closed files with stuff in them.")
@@ -4290,6 +4302,7 @@ IMAGESPEC is the image data, and DOCSTRING is documentation for the image."
4290(defvar speedbar-expand-image-button-alist 4302(defvar speedbar-expand-image-button-alist
4291 '(("<+>" . speedbar-directory-plus) 4303 '(("<+>" . speedbar-directory-plus)
4292 ("<->" . speedbar-directory-minus) 4304 ("<->" . speedbar-directory-minus)
4305 ("< >" . speedbar-directory)
4293 ("[+]" . speedbar-page-plus) 4306 ("[+]" . speedbar-page-plus)
4294 ("[-]" . speedbar-page-minus) 4307 ("[-]" . speedbar-page-minus)
4295 ("[?]" . speedbar-page) 4308 ("[?]" . speedbar-page)
diff --git a/lisp/term.el b/lisp/term.el
index f1bd8d9a4f6..9866db7e29c 100644
--- a/lisp/term.el
+++ b/lisp/term.el
@@ -705,18 +705,18 @@ Buffer local variable.")
705 705
706;;; faces -mm 706;;; faces -mm
707 707
708(defcustom term-default-fg-color nil 708(defcustom term-default-fg-color 'unspecified
709 "Default color for foreground in `term'." 709 "Default color for foreground in `term'."
710 :group 'term 710 :group 'term
711 :type 'string) 711 :type 'string)
712 712
713(defcustom term-default-bg-color nil 713(defcustom term-default-bg-color 'unspecified
714 "Default color for background in `term'." 714 "Default color for background in `term'."
715 :group 'term 715 :group 'term
716 :type 'string) 716 :type 'string)
717 717
718(defvar ansi-term-color-vector 718(defvar ansi-term-color-vector
719 [nil "black" "red" "green" "yellow" "blue" 719 [unspecified "black" "red" "green" "yellow" "blue"
720 "magenta" "cyan" "white"]) 720 "magenta" "cyan" "white"])
721 721
722;;; Inspiration came from comint.el -mm 722;;; Inspiration came from comint.el -mm
@@ -3080,8 +3080,7 @@ See `term-prompt-regexp'."
3080 (setq term-current-face 3080 (setq term-current-face
3081 (append '(:underline t) term-current-face)))))) 3081 (append '(:underline t) term-current-face))))))
3082 3082
3083; (message "Debug %S" term-current-face) 3083;;; (message "Debug %S" term-current-face)
3084
3085 (setq term-ansi-face-already-done 0)) 3084 (setq term-ansi-face-already-done 0))
3086 3085
3087 3086
diff --git a/lisp/term/x-win.el b/lisp/term/x-win.el
index 55ad3800e0b..76f0e5ac2ba 100644
--- a/lisp/term/x-win.el
+++ b/lisp/term/x-win.el
@@ -2217,7 +2217,8 @@ order until succeed.")
2217 (if utf8 2217 (if utf8
2218 (setq text (x-select-utf8-or-ctext utf8 ctext)) 2218 (setq text (x-select-utf8-or-ctext utf8 ctext))
2219 ;; Othewise, choose CTEXT. 2219 ;; Othewise, choose CTEXT.
2220 (setq text ctext)))) 2220 (setq text ctext))
2221 (setq text utf8)))
2221 ;; If not yet decided, try STRING. 2222 ;; If not yet decided, try STRING.
2222 (or text 2223 (or text
2223 (setq text (condition-case nil 2224 (setq text (condition-case nil
diff --git a/lispref/ChangeLog b/lispref/ChangeLog
index ed0c2e9d421..4a2314b58dd 100644
--- a/lispref/ChangeLog
+++ b/lispref/ChangeLog
@@ -1,3 +1,9 @@
12004-08-18 Kim F. Storm <storm@cua.dk>
2
3 * processes.texi (Accepting Output): Add `just-this-one' arg to
4 `accept-process-output'.
5 (Output from Processes): New var `process-adaptive-read-buffering'.
6
12004-08-10 Luc Teirlinck <teirllm@auburn.edu> 72004-08-10 Luc Teirlinck <teirllm@auburn.edu>
2 8
3 * keymaps.texi: Various changes in addition to: 9 * keymaps.texi: Various changes in addition to:
diff --git a/lispref/processes.texi b/lispref/processes.texi
index f580a774ae7..ccf8f76d87e 100644
--- a/lispref/processes.texi
+++ b/lispref/processes.texi
@@ -929,6 +929,16 @@ process and only then specify its buffer or filter function; no output
929can arrive before you finish, if the code in between does not call any 929can arrive before you finish, if the code in between does not call any
930primitive that waits. 930primitive that waits.
931 931
932@defvar process-adaptive-read-buffering
933On some systems, when Emacs reads the output from a subprocess, the
934output data is read in very small blocks, potentially resulting in
935very poor performance. This behaviour can be remedied to some extent
936by setting the variable @var{process-adaptive-read-buffering} to a
937non-nil value (the default), as it will automatically delay reading
938from such processes, thus allowing them to produce more output before
939Emacs tries to read it.
940@end defvar
941
932 It is impossible to separate the standard output and standard error 942 It is impossible to separate the standard output and standard error
933streams of the subprocess, because Emacs normally spawns the subprocess 943streams of the subprocess, because Emacs normally spawns the subprocess
934inside a pseudo-TTY, and a pseudo-TTY has only one output channel. If 944inside a pseudo-TTY, and a pseudo-TTY has only one output channel. If
@@ -1240,7 +1250,7 @@ or terminal input. Occasionally it is useful in a Lisp program to
1240explicitly permit output to arrive at a specific point, or even to wait 1250explicitly permit output to arrive at a specific point, or even to wait
1241until output arrives from a process. 1251until output arrives from a process.
1242 1252
1243@defun accept-process-output &optional process seconds millisec 1253@defun accept-process-output &optional process seconds millisec just-this-one
1244This function allows Emacs to read pending output from processes. The 1254This function allows Emacs to read pending output from processes. The
1245output is inserted in the associated buffers or given to their filter 1255output is inserted in the associated buffers or given to their filter
1246functions. If @var{process} is non-@code{nil} then this function does 1256functions. If @var{process} is non-@code{nil} then this function does
@@ -1263,6 +1273,15 @@ Not all operating systems support waiting periods other than multiples
1263of a second; on those that do not, you get an error if you specify 1273of a second; on those that do not, you get an error if you specify
1264nonzero @var{millisec}. 1274nonzero @var{millisec}.
1265 1275
1276@c Emacs 21.4 feature
1277If @var{process} is a process, and the argument @var{just-this-one} is
1278non-nil, only output from that process is handled, suspending output
1279from other processes until some output has been received from that
1280process or the timeout expires. If @var{just-this-one} is an integer,
1281also inhibit running timers. This feature is generally not
1282recommended, but may be necessary for specific applications, such as
1283speech synthesis.
1284
1266The function @code{accept-process-output} returns non-@code{nil} if it 1285The function @code{accept-process-output} returns non-@code{nil} if it
1267did get some output, or @code{nil} if the timeout expired before output 1286did get some output, or @code{nil} if the timeout expired before output
1268arrived. 1287arrived.
@@ -1664,7 +1683,7 @@ meaning ask the system to allocate an unused port to listen on.
1664@end defun 1683@end defun
1665 1684
1666@node Datagrams 1685@node Datagrams
1667@section Datagrams 1686@section Datagrams
1668@cindex datagrams 1687@cindex datagrams
1669 1688
1670 A datagram connection communicates with individual packets rather 1689 A datagram connection communicates with individual packets rather
@@ -1951,7 +1970,7 @@ the port number.
1951 1970
1952@example 1971@example
1953(featurep 'make-network-process '(@var{keyword} @var{value})) 1972(featurep 'make-network-process '(@var{keyword} @var{value}))
1954@end example 1973@end example
1955 1974
1956@noindent 1975@noindent
1957The result of the first form is @code{t} if it works to specify 1976The result of the first form is @code{t} if it works to specify
@@ -1977,7 +1996,7 @@ Non-@code{nil} if the system can select the port for a server.
1977 1996
1978@example 1997@example
1979(featurep 'make-network-process '@var{keyword}) 1998(featurep 'make-network-process '@var{keyword})
1980@end example 1999@end example
1981 2000
1982Here are some of the option @var{keyword}s you can test in 2001Here are some of the option @var{keyword}s you can test in
1983this way. 2002this way.
diff --git a/man/ChangeLog b/man/ChangeLog
index d6e105977fc..3ff412eb881 100644
--- a/man/ChangeLog
+++ b/man/ChangeLog
@@ -1,3 +1,40 @@
12004-08-17 Luc Teirlinck <teirllm@auburn.edu>
2
3 * emacs.texi (Top): Mention "cutting" and "pasting" as synonyms
4 for "killing" and "yanking" in main menu.
5
62004-08-16 Richard M. Stallman <rms@gnu.org>
7
8 * killing.texi (Yanking, Killing): Minor cleanups.
9
10 * mark.texi (Momentary Mark): Minor cleanups.
11
122004-08-15 Kenichi Handa <handa@etl.go.jp>
13
14 * custom.texi (Non-ASCII Rebinding):
15 C-q always inserts the right code to pass to global-set-key.
16
172004-08-14 Eli Zaretskii <eliz@gnu.org>
18
19 * Makefile.in (../info/tramp, tramp.dvi): Depend on trampver.texi.
20
212004-08-13 Luc Teirlinck <teirllm@auburn.edu>
22
23 * regs.texi (RegNumbers): Mention `C-x r i' binding for
24 `insert-register', instead of `C-x r g' binding, for consistency.
25
262004-08-12 Luc Teirlinck <teirllm@auburn.edu>
27
28 * fixit.texi (Spelling): Fix typo.
29
302004-08-11 Luc Teirlinck <teirllm@auburn.edu>
31
32 * help.texi (Help): Fix Texinfo usage.
33
342004-08-11 Martin Stjernholm <bug-cc-mode@gnu.org>
35
36 * cc-mode.texi: Various updates for CC Mode 5.30.9.
37
12004-08-10 Michael Albinus <michael.albinus@gmx.de> 382004-08-10 Michael Albinus <michael.albinus@gmx.de>
2 39
3 Sync with Tramp 2.0.44. 40 Sync with Tramp 2.0.44.
diff --git a/man/Makefile.in b/man/Makefile.in
index 468adf54844..ddf3fd320c8 100644
--- a/man/Makefile.in
+++ b/man/Makefile.in
@@ -279,9 +279,9 @@ speedbar.dvi: speedbar.texi
279emacs-mime.dvi: emacs-mime.texi 279emacs-mime.dvi: emacs-mime.texi
280 $(ENVADD) $(TEXI2DVI) ${srcdir}/emacs-mime.texi 280 $(ENVADD) $(TEXI2DVI) ${srcdir}/emacs-mime.texi
281 281
282../info/tramp: tramp.texi 282../info/tramp: tramp.texi trampver.texi
283 cd $(srcdir); $(MAKEINFO) -D emacs tramp.texi 283 cd $(srcdir); $(MAKEINFO) -D emacs tramp.texi
284tramp.dvi: tramp.texi 284tramp.dvi: tramp.texi trampver.texi
285 $(ENVADD) $(TEXI2DVI) ${srcdir}/tramp.texi 285 $(ENVADD) $(TEXI2DVI) ${srcdir}/tramp.texi
286 286
287../info/ses: ses.texi 287../info/ses: ses.texi
diff --git a/man/cc-mode.texi b/man/cc-mode.texi
index c3b7dd4833f..2c0933a5335 100644
--- a/man/cc-mode.texi
+++ b/man/cc-mode.texi
@@ -1340,9 +1340,9 @@ block comments.
1340@findex setup-paragraph-variables (c-) 1340@findex setup-paragraph-variables (c-)
1341Also note that since @ccmode{} uses the value of 1341Also note that since @ccmode{} uses the value of
1342@code{c-comment-prefix-regexp} to set up several other variables at mode 1342@code{c-comment-prefix-regexp} to set up several other variables at mode
1343initialization, there won't have any effect if you change it inside a 1343initialization, there won't be any effect if you just change it inside a
1344@ccmode{} buffer. You need to call the command 1344@ccmode{} buffer. You need to call the command
1345@code{c-setup-paragraph-variables} to update those other variables with 1345@code{c-setup-paragraph-variables} too, to update those other variables with
1346the new value. That's also the case if you modify this variable in a 1346the new value. That's also the case if you modify this variable in a
1347mode hook, since @ccmode{} sets up all variables before calling them. 1347mode hook, since @ccmode{} sets up all variables before calling them.
1348@end defopt 1348@end defopt
@@ -1415,8 +1415,12 @@ namely when a block comment is broken for the first time. This style
1415variable@footnote{In versions before 5.26, this variable was called 1415variable@footnote{In versions before 5.26, this variable was called
1416@code{c-comment-continuation-stars}. As a compatibility measure, 1416@code{c-comment-continuation-stars}. As a compatibility measure,
1417@ccmode{} still uses the value on that variable if it's set.} is used 1417@ccmode{} still uses the value on that variable if it's set.} is used
1418then as the comment prefix. It defaults to @samp{* }, which makes a 1418then as the comment prefix. It defaults to @samp{*
1419comment 1419}@footnote{Actually, this default setting of
1420@code{c-block-comment-prefix} typically gets overriden by the default
1421style @code{gnu}, which sets it to blank. You can see the line
1422splitting effect described here by setting a different style,
1423e.g. @code{k&r} @xref{Choosing a Style}}, which makes a comment
1420 1424
1421@example 1425@example
1422/* Got O(n^2) here, which is a Bad Thing. */ 1426/* Got O(n^2) here, which is a Bad Thing. */
@@ -2057,13 +2061,13 @@ These variables are also useful when indenting code:
2057@vindex tab-always-indent (c-) 2061@vindex tab-always-indent (c-)
2058@kindex TAB 2062@kindex TAB
2059@cindex literal 2063@cindex literal
2060This variable controls how @kbd{TAB} (@code{c-indent-command}) operates. 2064This variable controls how @kbd{TAB} (@code{c-indent-command})
2061When it is @code{t}, @kbd{TAB} always indents the current line. When it 2065operates. When it is @code{t}, @kbd{TAB} always indents the current
2062is @code{nil}, the line is indented only if point is at the left margin, 2066line. When it is @code{nil}, the line is indented only if point is at
2063or on or before the first non-whitespace character on the line, 2067the left margin, or on or before the first non-whitespace character on
2064otherwise some whitespace is inserted. If this variable is the symbol 2068the line, otherwise some whitespace is inserted. If this variable is
2065@code{other}, then some whitespace is inserted only within strings and 2069some other value (not @code{nil} or @code{t}), then some whitespace is
2066comments (literals), and inside preprocessor directives, but the line is 2070inserted only within strings and comments (literals), but the line is
2067always reindented. 2071always reindented.
2068@end defopt 2072@end defopt
2069 2073
@@ -2878,26 +2882,71 @@ string.
2878@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 2882@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2879@node Adding Styles, File Styles, Choosing a Style, Styles 2883@node Adding Styles, File Styles, Choosing a Style, Styles
2880@comment node-name, next, previous, up 2884@comment node-name, next, previous, up
2881@subsection Adding Styles 2885@subsection Adding and Amending Styles
2882@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 2886@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2883 2887
2884If none of the built-in styles is appropriate, you'll probably want to 2888If none of the built-in styles is appropriate, you'll probably want to
2885add a new @dfn{style definition}. Styles are kept in the 2889create a new @dfn{style definition}, possibly based on an existing
2886@code{c-style-alist} variable, but you should never modify this 2890style. To do this, put the new style's settings into a list with the
2887variable directly. Instead, @ccmode{} provides the function 2891following format - the list can then be passed as an argument to the
2888@code{c-add-style} that you can use to easily add new styles or change 2892function @code{c-add-style}:
2889existing styles: 2893
2894@cindex style definition
2895@defvr {List} style definition
2896([@var{base-style}] [(@var{variable} . @var{value}) @dots{}])
2897
2898Optional @var{base-style}, if present, must be a string which is the
2899name of the @dfn{base style} from which this style inherits. At most
2900one @var{base-style} is allowed in a style definition. If
2901@var{base-style} is not specified, the style inherits from a table of
2902default values@footnote{This table is stored internally in the
2903variable c-fallback-style. It is computed during the initialisation
2904of @ccmode{} from the factory defaults of the style variables and any
2905global values they may have been given since starting Emacs.} instead.
2906All styles eventually inherit from this internal table. Style loops
2907generate errors. The list of pre-existing styles can be seen in
2908@ref{Built-in Styles}.
2909
2910The dotted pairs (@var{variable} . @var{value}) each consist of a
2911variable and the value it is to be set to when the style is later
2912activated.@footnote{In certain circumstances, this value can get
2913overridden by another value.} The variable can be either a @ccmode{}
2914style variable or an arbitrary Emacs variable. In the latter case, it
2915is @emph{not} made buffer local by the @ccmode{} style system.
2916@end defvr
2917
2918Two variables are treated specially in the dotted pair list:
2919
2920@table @code
2921@item c-offsets-alist
2922The value is in turn a dotted list on the form
2923
2924(@var{syntactic-symbol} . @var{offset})
2925
2926as described in @ref{Customizing Indentation}. These are passed to
2927@code{c-set-offset} so there is no need to set every syntactic symbol in
2928your style, only those that are different from the inherited style.
2929
2930@item c-special-indent-hook
2931The value is added to @code{c-special-indent-hook} using
2932@code{add-hook}, so any functions already on it are kept. If the value
2933is a list, each element of the list is added with @code{add-hook}.
2934@end table
2935
2936Styles are kept in the @code{c-style-alist} variable, but you
2937should never modify this variable directly. Instead, @ccmode{}
2938provides the function @code{c-add-style} for this purpose.
2890 2939
2891@defun c-add-style stylename description &optional set-p 2940@defun c-add-style stylename description &optional set-p
2892@findex add-style (c-) 2941@findex add-style (c-)
2893Add or update a style. If @var{stylename} is not already in 2942Add or update a style called @var{stylename}, a string.
2894@code{c-style-alist} then a new style according to @var{description} 2943@var{description} is the new style definition in the form described
2895is added, otherwise the existing style is changed. If the optional 2944above. If @var{stylename} already exists in @code{c-style-alist} then
2896@var{set-p} is non-@code{nil} then the new style is applied to the 2945it is replaced by @var{description}. (Note, this replacement is
2897current buffer as well. 2946total. The old style is @emph{not} merged into the new one.)
2898 2947Otherwise, a new style is added. If the optional @var{set-p} is
2899@comment TBD: The next paragraph is bogus. I really need to better 2948non-@code{nil} then the new style is applied to the current buffer as
2900@comment document adding styles, including setting up inherited styles. 2949well.
2901 2950
2902The sample @file{.emacs} file provides a concrete example of how a new 2951The sample @file{.emacs} file provides a concrete example of how a new
2903style can be added and automatically set. @xref{Sample .emacs File}. 2952style can be added and automatically set. @xref{Sample .emacs File}.
@@ -3416,9 +3465,9 @@ Analogous to @code{inclass} syntactic symbol, but used inside lambda
3416Lines continuing the header of a lambda function, i.e., between the 3465Lines continuing the header of a lambda function, i.e., between the
3417@code{lambda} keyword and the function body. Only used in Pike mode. 3466@code{lambda} keyword and the function body. Only used in Pike mode.
3418@item inexpr-statement 3467@item inexpr-statement
3419A statement block inside an expression. The gcc C extension of this is 3468A statement block inside an expression. The gcc C and C++ extension for
3420recognized. It's also used for the special functions that takes a 3469this is recognized. It's also used for the special functions that take
3421statement block as an argument in Pike. 3470a statement block as an argument in Pike.
3422@item inexpr-class 3471@item inexpr-class
3423A class definition inside an expression. This is used for anonymous 3472A class definition inside an expression. This is used for anonymous
3424classes in Java. It's also used for anonymous array initializers in 3473classes in Java. It's also used for anonymous array initializers in
@@ -4022,7 +4071,8 @@ indented just like a normal class, with the added indentation given to
4022@code{inexpr-class}. 4071@code{inexpr-class}.
4023 4072
4024There are a few occasions where a statement block may be used inside an 4073There are a few occasions where a statement block may be used inside an
4025expression. One is in C code using the gcc extension for this, e.g: 4074expression. One is in C or C++ code using the gcc extension for this,
4075e.g:
4026 4076
4027@example 4077@example
4028 1: int res = (@{ 4078 1: int res = (@{
@@ -5225,7 +5275,7 @@ Controls whether a final newline is ensured when the file is saved. The
5225value is an association list that for each language mode specifies the 5275value is an association list that for each language mode specifies the
5226value to give to @code{require-final-newline} at mode initialization; 5276value to give to @code{require-final-newline} at mode initialization;
5227see that variable for details about the value. If a language isn't 5277see that variable for details about the value. If a language isn't
5228present on the association list, CC Mode won't set 5278present on the association list, CC Mode won't touch
5229@code{require-final-newline} in buffers for that language. 5279@code{require-final-newline} in buffers for that language.
5230 5280
5231The default is to set @code{require-final-newline} to @code{t} in the 5281The default is to set @code{require-final-newline} to @code{t} in the
@@ -5484,6 +5534,25 @@ interpreter tries to call the macro as a function, it shows this
5484(somewhat cryptic) error message.}. If you are using the standalone 5534(somewhat cryptic) error message.}. If you are using the standalone
5485@ccmode{} distribution, try recompiling it according to the instructions 5535@ccmode{} distribution, try recompiling it according to the instructions
5486in the @file{README} file. 5536in the @file{README} file.
5537
5538@item
5539@cindex open paren in column zero
5540@emph{I have an open paren character at column zero inside a comment or
5541multiline string literal, and it causes the fontification and/or
5542indentation to go haywire. What gives?}
5543
5544It's due to the ad-hoc rule in (X)Emacs that such open parens always
5545start defuns (which translates to functions, classes, namespaces or any
5546other top-level block constructs in the @ccmode{} languages).
5547@xref{Left Margin Paren,,, emacs, The Emacs Editor}, for details
5548(@xref{Defuns,,, emacs, The Emacs Editor}, in the Emacs 20 manual).
5549
5550This heuristic is built into the core syntax analysis routines in
5551(X)Emacs, so it's not really a @ccmode{} issue. However, in Emacs 21.4
5552it has become possible to turn it off@footnote{Using the variable
5553@code{open-paren-in-column-0-is-defun-start}.} and @ccmode{} does so
5554there since it got its own system to keep track of blocks.
5555
5487@end itemize 5556@end itemize
5488 5557
5489 5558
diff --git a/man/custom.texi b/man/custom.texi
index ce52431f3c6..aa5b35dc43e 100644
--- a/man/custom.texi
+++ b/man/custom.texi
@@ -1619,14 +1619,13 @@ because the terminal sends the same character in both cases.
1619@cindex rebinding non-@acronym{ASCII} keys 1619@cindex rebinding non-@acronym{ASCII} keys
1620@cindex non-@acronym{ASCII} keys, binding 1620@cindex non-@acronym{ASCII} keys, binding
1621 1621
1622If your keyboard has keys that send non-@acronym{ASCII} characters, such as 1622If your keyboard has keys that send non-@acronym{ASCII}
1623accented letters, rebinding these keys is a bit tricky. There are two 1623characters, such as accented letters, rebinding these keys
1624solutions you can use. One is to specify a keyboard coding system, 1624must be done by using a vector like this@footnote{Note that
1625using @code{set-keyboard-coding-system} (@pxref{Specify Coding}). 1625you should avoid the string syntax for binding
1626Then you can bind these keys in the usual way@footnote{Note that you 1626non-@acronym{ASCII} characters, since they will be
1627should avoid the string syntax for binding 8-bit characters, since 1627interpreted as meta keys. @xref{Strings of Events,,,elisp,
1628they will be interpreted as meta keys. @xref{Strings of 1628The Emacs Lisp Reference Manual}.}:
1629Events,,,elisp, The Emacs Lisp Reference Manual}.}, like this:
1630 1629
1631@example 1630@example
1632(global-set-key [?@var{char}] 'some-function) 1631(global-set-key [?@var{char}] 'some-function)
@@ -1635,27 +1634,15 @@ Events,,,elisp, The Emacs Lisp Reference Manual}.}, like this:
1635@noindent 1634@noindent
1636Type @kbd{C-q} followed by the key you want to bind, to insert @var{char}. 1635Type @kbd{C-q} followed by the key you want to bind, to insert @var{char}.
1637 1636
1638Since this puts a non-@acronym{ASCII} character in the @file{.emacs}, you should 1637Since this puts a non-@acronym{ASCII} character in the @file{.emacs},
1639specify the proper coding system for that file. @xref{Init Syntax}. 1638you should specify the proper coding system for that file. @xref{Init
1640Specify the same coding system for the file that you use for your 1639Syntax}. You should specify the same coding system for the file that
1641keyboard. 1640you use for your keyboard.
1642 1641
1643If you don't specify a keyboard coding system, that approach won't 1642@strong{Warning:} if you change the keyboard encoding, or change
1644work. Instead, you need to find out the actual code that the terminal 1643from unibyte to multibyte mode, such that the code that
1645sends. The easiest way to do this in Emacs is to create an empty 1644@kbd{C-q} inserts becomes different, you'll need to edit the
1646buffer with @kbd{C-x b temp @key{RET}}, make it unibyte with @kbd{M-x 1645Lisp expression accordingly.
1647toggle-enable-multibyte-characters @key{RET}}, then type the key to
1648insert the character into this buffer.
1649
1650Move point before the character, then type @kbd{C-x =}. This
1651displays a message in the minibuffer, showing the character code in
1652three ways, octal, decimal and hexadecimal, all within a set of
1653parentheses. Use the second of the three numbers, the decimal one,
1654inside the vector to bind:
1655
1656@example
1657(global-set-key [@var{decimal-code}] 'some-function)
1658@end example
1659 1646
1660If you bind 8-bit characters like this in your init file, you may find it 1647If you bind 8-bit characters like this in your init file, you may find it
1661convenient to specify that it is unibyte. @xref{Enabling Multibyte}. 1648convenient to specify that it is unibyte. @xref{Enabling Multibyte}.
diff --git a/man/emacs.texi b/man/emacs.texi
index 893f01e3baf..ad9658ab368 100644
--- a/man/emacs.texi
+++ b/man/emacs.texi
@@ -158,8 +158,8 @@ Fundamental Editing Commands
158 158
159Important Text-Changing Commands 159Important Text-Changing Commands
160* Mark:: The mark: how to delimit a ``region'' of text. 160* Mark:: The mark: how to delimit a ``region'' of text.
161* Killing:: Killing text. 161* Killing:: Killing (cutting) text.
162* Yanking:: Recovering killed text. Moving text. 162* Yanking:: Recovering killed text. Moving text. (Pasting.)
163* Accumulating Text:: Other ways of copying text. 163* Accumulating Text:: Other ways of copying text.
164* Rectangles:: Operating on the text inside a rectangle on the screen. 164* Rectangles:: Operating on the text inside a rectangle on the screen.
165* Registers:: Saving a text string or a location in the buffer. 165* Registers:: Saving a text string or a location in the buffer.
diff --git a/man/fixit.texi b/man/fixit.texi
index c7078c30b03..84121842b8c 100644
--- a/man/fixit.texi
+++ b/man/fixit.texi
@@ -339,7 +339,7 @@ a different standard dictionary.
339 Ispell uses a separate dictionary for word completion. The variable 339 Ispell uses a separate dictionary for word completion. The variable
340@code{ispell-complete-word-dict} specifies the file name of this 340@code{ispell-complete-word-dict} specifies the file name of this
341dictionary. The completion dictionary must be different because it 341dictionary. The completion dictionary must be different because it
342cannot use employ root and affix information. For some languages 342cannot use root and affix information. For some languages
343there is a spell checking dictionary but no word completion 343there is a spell checking dictionary but no word completion
344dictionary. 344dictionary.
345 345
diff --git a/man/help.texi b/man/help.texi
index 050e600759b..3f7419981d2 100644
--- a/man/help.texi
+++ b/man/help.texi
@@ -63,7 +63,7 @@ match for @var{topic}, a regular expression. @xref{Apropos}.
63@item C-h i d m emacs @key{RET} i @var{topic} @key{RET} 63@item C-h i d m emacs @key{RET} i @var{topic} @key{RET}
64This looks up @var{topic} in the indices of the Emacs on-line manual. 64This looks up @var{topic} in the indices of the Emacs on-line manual.
65If there are several matches, Emacs displays the first one. You can then 65If there are several matches, Emacs displays the first one. You can then
66press @key{,} to move to other matches, until you find what you are 66press @kbd{,} to move to other matches, until you find what you are
67looking for. 67looking for.
68 68
69@item C-h i d m emacs @key{RET} s @var{topic} @key{RET} 69@item C-h i d m emacs @key{RET} s @var{topic} @key{RET}
diff --git a/man/killing.texi b/man/killing.texi
index 60b5129389d..b5f1ce30772 100644
--- a/man/killing.texi
+++ b/man/killing.texi
@@ -31,8 +31,8 @@ one buffer and yank it in another buffer.
31@cindex killing text 31@cindex killing text
32@cindex cutting text 32@cindex cutting text
33@cindex deletion 33@cindex deletion
34 Most commands which erase text from the buffer save it in the kill 34 Most commands which erase text from the buffer save it in the @dfn{kill
35ring so that you can move or copy it to other parts of the buffer. 35ring} so that you can move or copy it to other parts of the buffer.
36These commands are known as @dfn{kill} commands. The rest of the 36These commands are known as @dfn{kill} commands. The rest of the
37commands that erase text do not save it in the kill ring; they are known 37commands that erase text do not save it in the kill ring; they are known
38as @dfn{delete} commands. (This distinction is made only for erasure of 38as @dfn{delete} commands. (This distinction is made only for erasure of
@@ -274,7 +274,8 @@ single kill ring entry as usual.
274 274
275 @dfn{Yanking} means reinserting text previously killed. This is what 275 @dfn{Yanking} means reinserting text previously killed. This is what
276some systems call ``pasting.'' The usual way to move or copy text is to 276some systems call ``pasting.'' The usual way to move or copy text is to
277kill it and then yank it elsewhere one or more times. 277kill it and then yank it elsewhere one or more times. This is very safe
278because Emacs remembers many recent kills, not just the last one.
278 279
279@table @kbd 280@table @kbd
280@item C-y 281@item C-y
diff --git a/man/kmacro.texi b/man/kmacro.texi
index be2b520fc59..8965c4f2167 100644
--- a/man/kmacro.texi
+++ b/man/kmacro.texi
@@ -165,7 +165,7 @@ to plain @kbd{C-x (} followed by retyping the whole definition so far. As
165a consequence it re-executes the macro as previously defined. 165a consequence it re-executes the macro as previously defined.
166 166
167 You can also add to the end of the definition of the last keyboard 167 You can also add to the end of the definition of the last keyboard
168macro without re-execuing it by typing @kbd{C-u C-u C-x (}. 168macro without re-executing it by typing @kbd{C-u C-u C-x (}.
169 169
170 The variable @code{kmacro-execute-before-append} specifies whether 170 The variable @code{kmacro-execute-before-append} specifies whether
171a single @kbd{C-u} prefix causes the existing macro to be re-executed 171a single @kbd{C-u} prefix causes the existing macro to be re-executed
@@ -218,7 +218,7 @@ of the macro ring. The definition of the new head macro is displayed
218in the echo area. You can continue to rotate the macro ring 218in the echo area. You can continue to rotate the macro ring
219immediately by repeating just @kbd{C-n} and @kbd{C-p} until the 219immediately by repeating just @kbd{C-n} and @kbd{C-p} until the
220desired macro is at the head of the ring. To execute the new macro 220desired macro is at the head of the ring. To execute the new macro
221ring head immediately, just type @kbd{C-k}. 221ring head immediately, just type @kbd{C-k}.
222 222
223@findex kmacro-view-macro-repeat 223@findex kmacro-view-macro-repeat
224@kindex C-x C-k C-v 224@kindex C-x C-k C-v
@@ -361,7 +361,7 @@ register as a counter, incrementing it on each repetition of the macro.
361@findex name-last-kbd-macro 361@findex name-last-kbd-macro
362@kindex C-x C-k n 362@kindex C-x C-k n
363 If you wish to save a keyboard macro for later use, you can give it 363 If you wish to save a keyboard macro for later use, you can give it
364a name using @kbd{C-x C-k n} (@code{name-last-kbd-macro}). 364a name using @kbd{C-x C-k n} (@code{name-last-kbd-macro}).
365This reads a name as an argument using the minibuffer and defines that name 365This reads a name as an argument using the minibuffer and defines that name
366to execute the macro. The macro name is a Lisp symbol, and defining it in 366to execute the macro. The macro name is a Lisp symbol, and defining it in
367this way makes it a valid command name for calling with @kbd{M-x} or for 367this way makes it a valid command name for calling with @kbd{M-x} or for
@@ -377,7 +377,7 @@ key using @kbd{C-x C-k b} (@code{kmacro-bind-to-key}) followed by the
377key sequence you want the keyboard macro to be bound to. You can 377key sequence you want the keyboard macro to be bound to. You can
378bind to any key sequence in the global keymap, but since most key 378bind to any key sequence in the global keymap, but since most key
379sequences already have other bindings, you should select the key 379sequences already have other bindings, you should select the key
380sequence carefylly. If you try to bind to a key sequence with an 380sequence carefully. If you try to bind to a key sequence with an
381existing binding (in any keymap), you will be asked if you really 381existing binding (in any keymap), you will be asked if you really
382want to replace the existing binding of that key. 382want to replace the existing binding of that key.
383 383
@@ -448,7 +448,7 @@ keyboard input that you would use to invoke the macro---@kbd{C-x e} or
448@findex kmacro-step-edit-macro 448@findex kmacro-step-edit-macro
449@kindex C-x C-k SPC 449@kindex C-x C-k SPC
450 You can interactively and stepwise replay and edit the last keyboard 450 You can interactively and stepwise replay and edit the last keyboard
451macro one command at a time by typing @kbd{C-x C-k SPC} 451macro one command at a time by typing @kbd{C-x C-k SPC}
452(@code{kmacro-step-edit-macro}). Unless you quit the macro using 452(@code{kmacro-step-edit-macro}). Unless you quit the macro using
453@kbd{q} or @kbd{C-g}, the edited macro replaces the last macro on the 453@kbd{q} or @kbd{C-g}, the edited macro replaces the last macro on the
454macro ring. 454macro ring.
diff --git a/man/mark.texi b/man/mark.texi
index 414fa470348..b4154f9c3ae 100644
--- a/man/mark.texi
+++ b/man/mark.texi
@@ -247,20 +247,20 @@ command twice.)
247 247
248@item C-u C-x C-x 248@item C-u C-x C-x
249@kindex C-u C-x C-x 249@kindex C-u C-x C-x
250Activate the mark without changing it, enable Transient Mark mode just 250Activate the mark without changing it; enable Transient Mark mode just
251once until the mark is deactivated. (This is the @kbd{C-x C-x} command, 251once, until the mark is deactivated. (This is the @kbd{C-x C-x}
252@code{exchange-point-and-mark}, with a prefix argument.) 252command, @code{exchange-point-and-mark}, with a prefix argument.)
253@end table 253@end table
254 254
255 One of the secondary features of Transient Mark mode is that certain 255 One of the secondary features of Transient Mark mode is that certain
256commands operate on the region when there is an active region. If you 256commands operate only on the region, when there is an active region.
257don't use Transient Mark mode, the region once set never becomes 257If you don't use Transient Mark mode, the region once set never
258inactive, so there is no way these commands to make such a 258becomes inactive, so there is no way for these commands to make such a
259distinction. Enabling Transient Mark mode momentarily gives you a way 259distinction. Enabling Transient Mark mode momentarily gives you a way
260to use these commands on the region. 260to use these commands on the region.
261 261
262 The other way momentarily use of Transient Mark mode is useful 262 Momentary use of Transient Mark mode is also a way to highlight the
263is that it highlights the region for the time being. 263region for the time being.
264 264
265@node Using Region 265@node Using Region
266@section Operating on the Region 266@section Operating on the Region
diff --git a/man/regs.texi b/man/regs.texi
index ab1ef42e2f1..7268dd72446 100644
--- a/man/regs.texi
+++ b/man/regs.texi
@@ -30,8 +30,8 @@ Display a description of what register @var{r} contains.
30* Text: RegText. Saving text in registers. 30* Text: RegText. Saving text in registers.
31* Rectangle: RegRect. Saving rectangles in registers. 31* Rectangle: RegRect. Saving rectangles in registers.
32* Configurations: RegConfig. Saving window configurations in registers. 32* Configurations: RegConfig. Saving window configurations in registers.
33* Files: RegFiles. File names in registers.
34* Numbers: RegNumbers. Numbers in registers. 33* Numbers: RegNumbers. Numbers in registers.
34* Files: RegFiles. File names in registers.
35* Bookmarks:: Bookmarks are like registers, but persistent. 35* Bookmarks:: Bookmarks are like registers, but persistent.
36@end menu 36@end menu
37 37
@@ -185,11 +185,11 @@ Store @var{number} into register @var{r} (@code{number-to-register}).
185@findex increment-register 185@findex increment-register
186Increment the number in register @var{r} by @var{number} 186Increment the number in register @var{r} by @var{number}
187(@code{increment-register}). 187(@code{increment-register}).
188@item C-x r g @var{r} 188@item C-x r i @var{r}
189Insert the number from register @var{r} into the buffer. 189Insert the number from register @var{r} into the buffer.
190@end table 190@end table
191 191
192 @kbd{C-x r g} is the same command used to insert any other sort of 192 @kbd{C-x r i} is the same command used to insert any other sort of
193register contents into the buffer. @kbd{C-x r +} with no numeric 193register contents into the buffer. @kbd{C-x r +} with no numeric
194argument increments the register value by 1; @kbd{C-x r n} with no 194argument increments the register value by 1; @kbd{C-x r n} with no
195numeric argument stores zero in the register. 195numeric argument stores zero in the register.
diff --git a/msdos/ChangeLog b/msdos/ChangeLog
index 6d221726b7e..1722153dc51 100644
--- a/msdos/ChangeLog
+++ b/msdos/ChangeLog
@@ -1,3 +1,9 @@
12004-08-14 Eli Zaretskii <eliz@gnu.org>
2
3 * sedleim.inp: Remove the lines which say "<TAB>@true", to avoid
4 running a Unixy shell and to reincarnate the "Nothing to be done
5 for `all'" message from Make when there's nothing to be done.
6
12004-05-11 Eli Zaretskii <eliz@gnu.org> 72004-05-11 Eli Zaretskii <eliz@gnu.org>
2 8
3 * sedleim.inp (distclean): Remove stamp-subdirs. 9 * sedleim.inp (distclean): Remove stamp-subdirs.
diff --git a/msdos/sedleim.inp b/msdos/sedleim.inp
index f4795e749b8..bb81e7ec113 100644
--- a/msdos/sedleim.inp
+++ b/msdos/sedleim.inp
@@ -30,6 +30,7 @@ INSTALLDIR=.
30 30
31/touch stamp-subdir/s|touch|djecho "stamp-subdir" >| 31/touch stamp-subdir/s|touch|djecho "stamp-subdir" >|
32s|\([ ]\)echo|\1djecho|g 32s|\([ ]\)echo|\1djecho|g
33/^ @true *$/d
33 34
34/RUN-EMACS *=/,/^$/c\ 35/RUN-EMACS *=/,/^$/c\
35export EMACSLOADPATH=${buildlisppath}\ 36export EMACSLOADPATH=${buildlisppath}\
diff --git a/src/ChangeLog b/src/ChangeLog
index 3f9b6d85e51..9d9c4ee498c 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,40 @@
12004-08-18 Kim F. Storm <storm@cua.dk>
2
3 * process.c (Faccept_process_output): Add arg JUST-THIS-ONE;
4 forward to wait_reading_process_input via DO_DISPLAY arg.
5 (wait_reading_process_input): If DO_DISPLAY < 0 for a process
6 object, only process output from that process; also inhibit
7 running timers if DO_DISPLAY==-2.
8
92004-08-17 Kim F. Storm <storm@cua.dk>
10
11 * process.c (process_send_signal): Fix last change--use
12 _POSIX_VDISABLE instead of CVDISABLE when available.
13
142004-08-16 Richard M. Stallman <rms@gnu.org>
15
16 * sysdep.c (child_setup_tty) [SIGNALS_VIA_CHARACTERS]:
17 Set VQUIT and VINTR chars to the standard ones if they are unset.
18 [AIX]: Don't do that here. And don't force VINTR to standard
19 when SIGNALS_VIA_CHARACTERS.
20
21 * process.c (process_send_signal)
22 [SIGNALS_VIA_CHARACTERS, HAVE_TERMIOS]: Clean up.
23 Do nothing if the character is CVDISABLE.
24
25 * xfaces.c (merge_face_ref): Specifying `unspecified' is a no-op.
26
27 * intervals.c (move_if_not_intangible):
28 Force POSITION to be between BEGV and ZV.
29
302004-08-14 John Paul Wallington <jpw@gnu.org>
31
32 * buffer.c (Frestore_buffer_modified_p): Doc fix.
33
34 * fileio.c (Fread_file_name): Doc fix.
35
36 * minibuf.c (syms_of_minibuf) <completion-ignore-case>: Doc fix.
37
12004-08-09 Luc Teirlinck <teirllm@auburn.edu> 382004-08-09 Luc Teirlinck <teirllm@auburn.edu>
2 39
3 * keymap.c (Fmake_keymap, Fmap_keymap, Fwhere_is_internal): Doc fixes. 40 * keymap.c (Fmake_keymap, Fmap_keymap, Fwhere_is_internal): Doc fixes.
@@ -66,6 +103,10 @@
66 103
67 * callint.c (Fcall_interactively): Doc fix. 104 * callint.c (Fcall_interactively): Doc fix.
68 105
1062004-07-30 Richard M. Stallman <rms@gnu.org>
107
108 * abbrev.c (Fexpand_abbrev): Undo previous change.
109
692004-07-30 Kim F. Storm <storm@cua.dk> 1102004-07-30 Kim F. Storm <storm@cua.dk>
70 111
71 * editfns.c (Fformat): Allocate extra (dummy) element in info. 112 * editfns.c (Fformat): Allocate extra (dummy) element in info.
diff --git a/src/buffer.c b/src/buffer.c
index f55ae7983f4..bade501b1a7 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -1077,7 +1077,7 @@ A non-nil FLAG means mark the buffer modified. */)
1077 1077
1078DEFUN ("restore-buffer-modified-p", Frestore_buffer_modified_p, 1078DEFUN ("restore-buffer-modified-p", Frestore_buffer_modified_p,
1079 Srestore_buffer_modified_p, 1, 1, 0, 1079 Srestore_buffer_modified_p, 1, 1, 0,
1080 doc: /* Like `set-buffer-modified-p', with a differences concerning redisplay. 1080 doc: /* Like `set-buffer-modified-p', with a difference concerning redisplay.
1081It is not ensured that mode lines will be updated to show the modified 1081It is not ensured that mode lines will be updated to show the modified
1082state of the current buffer. Use with care. */) 1082state of the current buffer. Use with care. */)
1083 (flag) 1083 (flag)
diff --git a/src/fileio.c b/src/fileio.c
index 180f6f94130..da544f72234 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -6195,7 +6195,10 @@ DIR should be an absolute directory name. It defaults to the value of
6195 6195
6196If this command was invoked with the mouse, use a file dialog box if 6196If this command was invoked with the mouse, use a file dialog box if
6197`use-dialog-box' is non-nil, and the window system or X toolkit in use 6197`use-dialog-box' is non-nil, and the window system or X toolkit in use
6198provides a file dialog box. */) 6198provides a file dialog box.
6199
6200See also `read-file-name-completion-ignore-case'
6201and `read-file-name-function'. */)
6199 (prompt, dir, default_filename, mustmatch, initial, predicate) 6202 (prompt, dir, default_filename, mustmatch, initial, predicate)
6200 Lisp_Object prompt, dir, default_filename, mustmatch, initial, predicate; 6203 Lisp_Object prompt, dir, default_filename, mustmatch, initial, predicate;
6201{ 6204{
diff --git a/src/intervals.c b/src/intervals.c
index 33ef9a34177..a822dafefcf 100644
--- a/src/intervals.c
+++ b/src/intervals.c
@@ -2275,6 +2275,10 @@ move_if_not_intangible (position)
2275 pos = Fnext_char_property_change (pos, Qnil); 2275 pos = Fnext_char_property_change (pos, Qnil);
2276 2276
2277 } 2277 }
2278 else if (position < BEGV)
2279 position = BEGV;
2280 else if (position > ZV)
2281 position = ZV;
2278 2282
2279 /* If the whole stretch between PT and POSITION isn't intangible, 2283 /* If the whole stretch between PT and POSITION isn't intangible,
2280 try moving to POSITION (which means we actually move farther 2284 try moving to POSITION (which means we actually move farther
diff --git a/src/minibuf.c b/src/minibuf.c
index d28a5799afa..3d2c6c3a475 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -2678,7 +2678,10 @@ property of a history variable overrides this default. */);
2678 Vcompletion_auto_help = Qt; 2678 Vcompletion_auto_help = Qt;
2679 2679
2680 DEFVAR_BOOL ("completion-ignore-case", &completion_ignore_case, 2680 DEFVAR_BOOL ("completion-ignore-case", &completion_ignore_case,
2681 doc: /* Non-nil means don't consider case significant in completion. */); 2681 doc: /* Non-nil means don't consider case significant in completion.
2682
2683See also `read-file-name-completion-ignore-case' concerning case significance
2684in completion when reading a file name. */);
2682 completion_ignore_case = 0; 2685 completion_ignore_case = 0;
2683 2686
2684 DEFVAR_BOOL ("enable-recursive-minibuffers", &enable_recursive_minibuffers, 2687 DEFVAR_BOOL ("enable-recursive-minibuffers", &enable_recursive_minibuffers,
diff --git a/src/process.c b/src/process.c
index ff3f79158ca..1cebdf07875 100644
--- a/src/process.c
+++ b/src/process.c
@@ -3718,7 +3718,7 @@ close_process_descs ()
3718} 3718}
3719 3719
3720DEFUN ("accept-process-output", Faccept_process_output, Saccept_process_output, 3720DEFUN ("accept-process-output", Faccept_process_output, Saccept_process_output,
3721 0, 3, 0, 3721 0, 4, 0,
3722 doc: /* Allow any pending output from subprocesses to be read by Emacs. 3722 doc: /* Allow any pending output from subprocesses to be read by Emacs.
3723It is read into the process' buffers or given to their filter functions. 3723It is read into the process' buffers or given to their filter functions.
3724Non-nil arg PROCESS means do not return until some output has been received 3724Non-nil arg PROCESS means do not return until some output has been received
@@ -3726,15 +3726,20 @@ from PROCESS.
3726Non-nil second arg TIMEOUT and third arg TIMEOUT-MSECS are number of 3726Non-nil second arg TIMEOUT and third arg TIMEOUT-MSECS are number of
3727seconds and microseconds to wait; return after that much time whether 3727seconds and microseconds to wait; return after that much time whether
3728or not there is input. 3728or not there is input.
3729If optional fourth arg JUST-THIS-ONE is non-nil, only accept output
3730from PROCESS, suspending reading output from other processes.
3731If JUST-THIS-ONE is an integer, don't run any timers either.
3729Return non-nil iff we received any output before the timeout expired. */) 3732Return non-nil iff we received any output before the timeout expired. */)
3730 (process, timeout, timeout_msecs) 3733 (process, timeout, timeout_msecs, just_this_one)
3731 register Lisp_Object process, timeout, timeout_msecs; 3734 register Lisp_Object process, timeout, timeout_msecs, just_this_one;
3732{ 3735{
3733 int seconds; 3736 int seconds;
3734 int useconds; 3737 int useconds;
3735 3738
3736 if (! NILP (process)) 3739 if (! NILP (process))
3737 CHECK_PROCESS (process); 3740 CHECK_PROCESS (process);
3741 else
3742 just_this_one = Qnil;
3738 3743
3739 if (! NILP (timeout_msecs)) 3744 if (! NILP (timeout_msecs))
3740 { 3745 {
@@ -3776,7 +3781,9 @@ Return non-nil iff we received any output before the timeout expired. */)
3776 XSETFASTINT (process, 0); 3781 XSETFASTINT (process, 0);
3777 3782
3778 return 3783 return
3779 (wait_reading_process_input (seconds, useconds, process, 0) 3784 (wait_reading_process_input (seconds, useconds, process,
3785 NILP (just_this_one) ? 0 :
3786 !INTEGERP (just_this_one) ? -1 : -2)
3780 ? Qt : Qnil); 3787 ? Qt : Qnil);
3781} 3788}
3782 3789
@@ -4009,8 +4016,11 @@ wait_reading_process_input_1 ()
4009 process. The return value is true iff we read some input from 4016 process. The return value is true iff we read some input from
4010 that process. 4017 that process.
4011 4018
4012 DO_DISPLAY != 0 means redisplay should be done to show subprocess 4019 If READ_KBD is a process object, DO_DISPLAY < 0 means handle only
4013 output that arrives. 4020 output from that process (suspending output from other processes)
4021 and DO_DISPLAY == -2 specifically means don't run any timers either.
4022 Otherwise, != 0 means redisplay should be done to show subprocess
4023 output that arrives.
4014 4024
4015 If READ_KBD is a pointer to a struct Lisp_Process, then the 4025 If READ_KBD is a pointer to a struct Lisp_Process, then the
4016 function returns true iff we received input from that process 4026 function returns true iff we received input from that process
@@ -4032,6 +4042,7 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
4032 EMACS_TIME timeout, end_time; 4042 EMACS_TIME timeout, end_time;
4033 int wait_channel = -1; 4043 int wait_channel = -1;
4034 struct Lisp_Process *wait_proc = 0; 4044 struct Lisp_Process *wait_proc = 0;
4045 int just_wait_proc = 0;
4035 int got_some_input = 0; 4046 int got_some_input = 0;
4036 /* Either nil or a cons cell, the car of which is of interest and 4047 /* Either nil or a cons cell, the car of which is of interest and
4037 may be changed outside of this routine. */ 4048 may be changed outside of this routine. */
@@ -4048,6 +4059,11 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
4048 wait_proc = XPROCESS (read_kbd); 4059 wait_proc = XPROCESS (read_kbd);
4049 wait_channel = XINT (wait_proc->infd); 4060 wait_channel = XINT (wait_proc->infd);
4050 XSETFASTINT (read_kbd, 0); 4061 XSETFASTINT (read_kbd, 0);
4062 if (do_display < 0)
4063 {
4064 just_wait_proc = do_display;
4065 do_display = 0;
4066 }
4051 } 4067 }
4052 4068
4053 /* If waiting for non-nil in a cell, record where. */ 4069 /* If waiting for non-nil in a cell, record where. */
@@ -4122,7 +4138,8 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
4122 But not if wait_for_cell; in those cases, 4138 But not if wait_for_cell; in those cases,
4123 the wait is supposed to be short, 4139 the wait is supposed to be short,
4124 and those callers cannot handle running arbitrary Lisp code here. */ 4140 and those callers cannot handle running arbitrary Lisp code here. */
4125 if (NILP (wait_for_cell)) 4141 if (NILP (wait_for_cell)
4142 && just_wait_proc != -2)
4126 { 4143 {
4127 EMACS_TIME timer_delay; 4144 EMACS_TIME timer_delay;
4128 4145
@@ -4258,7 +4275,12 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
4258 4275
4259 /* Wait till there is something to do */ 4276 /* Wait till there is something to do */
4260 4277
4261 if (!NILP (wait_for_cell)) 4278 if (just_wait_proc)
4279 {
4280 FD_SET (XINT (wait_proc->infd), &Available);
4281 check_connect = check_delay = 0;
4282 }
4283 else if (!NILP (wait_for_cell))
4262 { 4284 {
4263 Available = non_process_wait_mask; 4285 Available = non_process_wait_mask;
4264 check_connect = check_delay = 0; 4286 check_connect = check_delay = 0;
@@ -5549,29 +5571,40 @@ process_send_signal (process, signo, current_group, nomsg)
5549 work. If the system has it, use it. */ 5571 work. If the system has it, use it. */
5550#ifdef HAVE_TERMIOS 5572#ifdef HAVE_TERMIOS
5551 struct termios t; 5573 struct termios t;
5574 cc_t *sig_char = NULL;
5575
5576 tcgetattr (XINT (p->infd), &t);
5552 5577
5553 switch (signo) 5578 switch (signo)
5554 { 5579 {
5555 case SIGINT: 5580 case SIGINT:
5556 tcgetattr (XINT (p->infd), &t); 5581 sig_char = &t.c_cc[VINTR];
5557 send_process (proc, &t.c_cc[VINTR], 1, Qnil); 5582 break;
5558 return;
5559 5583
5560 case SIGQUIT: 5584 case SIGQUIT:
5561 tcgetattr (XINT (p->infd), &t); 5585 sig_char = &t.c_cc[VQUIT];
5562 send_process (proc, &t.c_cc[VQUIT], 1, Qnil); 5586 break;
5563 return;
5564 5587
5565 case SIGTSTP: 5588 case SIGTSTP:
5566 tcgetattr (XINT (p->infd), &t);
5567#if defined (VSWTCH) && !defined (PREFER_VSUSP) 5589#if defined (VSWTCH) && !defined (PREFER_VSUSP)
5568 send_process (proc, &t.c_cc[VSWTCH], 1, Qnil); 5590 sig_char = &t.c_cc[VSWTCH];
5569#else 5591#else
5570 send_process (proc, &t.c_cc[VSUSP], 1, Qnil); 5592 sig_char = &t.c_cc[VSUSP];
5571#endif 5593#endif
5572 return; 5594 break;
5573 } 5595 }
5574 5596
5597#ifndef _POSIX_VDISABLE
5598#ifdef CVDISABLE
5599#define _POSIX_VDISABLE CVDISABLE
5600#else
5601#define _POSIX_VDISABLE '\0'
5602#endif
5603#endif
5604
5605 if (sig_char && *sig_char != _POSIX_VDISABLE)
5606 send_process (proc, sig_char, 1, Qnil);
5607 return;
5575#else /* ! HAVE_TERMIOS */ 5608#else /* ! HAVE_TERMIOS */
5576 5609
5577 /* On Berkeley descendants, the following IOCTL's retrieve the 5610 /* On Berkeley descendants, the following IOCTL's retrieve the
diff --git a/src/sysdep.c b/src/sysdep.c
index 018fdc1fd57..26f433c9a1d 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -607,6 +607,15 @@ child_setup_tty (out)
607 s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */ 607 s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
608#endif /* HPUX */ 608#endif /* HPUX */
609 609
610#ifdef SIGNALS_VIA_CHARACTERS
611 /* the QUIT and INTR character are used in process_send_signal
612 so set them here to something useful. */
613 if (s.main.c_cc[VQUIT] == 0377)
614 s.main.c_cc[VQUIT] = '\\'&037; /* Control-\ */
615 if (s.main.c_cc[VINTR] == 0377)
616 s.main.c_cc[VINTR] = 'C'&037; /* Control-C */
617#endif /* not SIGNALS_VIA_CHARACTERS */
618
610#ifdef AIX 619#ifdef AIX
611/* AIX enhanced edit loses NULs, so disable it */ 620/* AIX enhanced edit loses NULs, so disable it */
612#ifndef IBMR2AIX 621#ifndef IBMR2AIX
@@ -617,16 +626,10 @@ child_setup_tty (out)
617 don't ignore break, but don't signal either, so it looks like NUL. */ 626 don't ignore break, but don't signal either, so it looks like NUL. */
618 s.main.c_iflag &= ~IGNBRK; 627 s.main.c_iflag &= ~IGNBRK;
619 s.main.c_iflag &= ~BRKINT; 628 s.main.c_iflag &= ~BRKINT;
620 /* QUIT and INTR work better as signals, so disable character forms */ 629 /* rms: Formerly it set s.main.c_cc[VINTR] to 0377 here
621 s.main.c_cc[VINTR] = 0377; 630 unconditionally. Then a SIGNALS_VIA_CHARACTERS conditional
622#ifdef SIGNALS_VIA_CHARACTERS 631 would force it to 0377. That looks like duplicated code. */
623 /* the QUIT and INTR character are used in process_send_signal 632#ifndef SIGNALS_VIA_CHARACTERS
624 so set them here to something useful. */
625 if (s.main.c_cc[VQUIT] == 0377)
626 s.main.c_cc[VQUIT] = '\\'&037; /* Control-\ */
627 if (s.main.c_cc[VINTR] == 0377)
628 s.main.c_cc[VINTR] = 'C'&037; /* Control-C */
629#else /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
630 /* QUIT and INTR work better as signals, so disable character forms */ 633 /* QUIT and INTR work better as signals, so disable character forms */
631 s.main.c_cc[VQUIT] = 0377; 634 s.main.c_cc[VQUIT] = 0377;
632 s.main.c_cc[VINTR] = 0377; 635 s.main.c_cc[VINTR] = 0377;
diff --git a/src/xfaces.c b/src/xfaces.c
index f664249a290..10b7ef1148c 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -3629,7 +3629,10 @@ merge_face_ref (f, face_ref, to, err_msgs, named_merge_points)
3629 Lisp_Object value = XCAR (XCDR (face_ref)); 3629 Lisp_Object value = XCAR (XCDR (face_ref));
3630 int err = 0; 3630 int err = 0;
3631 3631
3632 if (EQ (keyword, QCfamily)) 3632 /* Specifying `unspecified' is a no-op. */
3633 if (EQ (value, Qunspecified))
3634 ;
3635 else if (EQ (keyword, QCfamily))
3633 { 3636 {
3634 if (STRINGP (value)) 3637 if (STRINGP (value))
3635 to[LFACE_FAMILY_INDEX] = value; 3638 to[LFACE_FAMILY_INDEX] = value;