aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaroly Lorentey2005-12-29 04:41:02 +0000
committerKaroly Lorentey2005-12-29 04:41:02 +0000
commite583523a108624f7fd0c28294010b19daae5ab97 (patch)
tree6bbb60c1f603809ca8980a459e0c4ed6d2c02378
parentda8e8fc14f3166ec596e34f43fbfea866d1176df (diff)
parentd52c26e925297a2d1663e2293d46ce95e91c4689 (diff)
downloademacs-e583523a108624f7fd0c28294010b19daae5ab97.tar.gz
emacs-e583523a108624f7fd0c28294010b19daae5ab97.zip
Merged from miles@gnu.org--gnu-2005 (patch 678-680)
Patches applied: * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-678 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-679 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-680 Update from CVS git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-468
-rw-r--r--ChangeLog4
-rw-r--r--configure.in1
-rw-r--r--etc/ChangeLog4
-rw-r--r--etc/TODO12
-rw-r--r--lib-src/ChangeLog4
-rw-r--r--lib-src/Makefile.in2
-rw-r--r--lisp/ChangeLog205
-rw-r--r--lisp/battery.el8
-rw-r--r--lisp/cus-edit.el211
-rw-r--r--lisp/custom.el110
-rw-r--r--lisp/descr-text.el190
-rw-r--r--lisp/emacs-lisp/edebug.el16
-rw-r--r--lisp/emacs-lisp/lisp.el55
-rw-r--r--lisp/font-lock.el27
-rw-r--r--lisp/hi-lock.el103
-rw-r--r--lisp/info.el29
-rw-r--r--lisp/locate.el2
-rw-r--r--lisp/log-view.el5
-rw-r--r--lisp/makefile.w32-in8
-rw-r--r--lisp/menu-bar.el13
-rw-r--r--lisp/mh-e/ChangeLog75
-rw-r--r--lisp/mh-e/mh-acros.el39
-rw-r--r--lisp/mh-e/mh-alias.el87
-rw-r--r--lisp/mh-e/mh-comp.el510
-rw-r--r--lisp/mh-e/mh-customize.el1416
-rw-r--r--lisp/mh-e/mh-e.el907
-rw-r--r--lisp/mh-e/mh-funcs.el104
-rw-r--r--lisp/mh-e/mh-gnus.el12
-rw-r--r--lisp/mh-e/mh-identity.el47
-rw-r--r--lisp/mh-e/mh-inc.el4
-rw-r--r--lisp/mh-e/mh-index.el372
-rw-r--r--lisp/mh-e/mh-init.el41
-rw-r--r--lisp/mh-e/mh-junk.el167
-rw-r--r--lisp/mh-e/mh-mime.el278
-rw-r--r--lisp/mh-e/mh-pick.el152
-rw-r--r--lisp/mh-e/mh-print.el89
-rw-r--r--lisp/mh-e/mh-seq.el317
-rw-r--r--lisp/mh-e/mh-speed.el33
-rw-r--r--lisp/mh-e/mh-utils.el461
-rw-r--r--lisp/mouse.el2
-rw-r--r--lisp/progmodes/cpp.el2
-rw-r--r--lisp/progmodes/delphi.el2
-rw-r--r--lisp/progmodes/gud.el2
-rw-r--r--lisp/savehist.el3
-rw-r--r--lisp/simple.el17
-rw-r--r--lisp/textmodes/flyspell.el18
-rw-r--r--lisp/tool-bar.el2
-rw-r--r--lisp/url/ChangeLog6
-rw-r--r--lisp/url/url-cookie.el5
-rw-r--r--lisp/url/url.el6
-rw-r--r--lisp/vc.el308
-rw-r--r--lisp/w32-fns.el12
-rw-r--r--lisp/wid-edit.el4
-rw-r--r--lispref/ChangeLog14
-rw-r--r--lispref/help.texi3
-rw-r--r--lispref/text.texi32
-rw-r--r--man/ChangeLog28
-rw-r--r--man/buffers.texi17
-rw-r--r--man/custom.texi338
-rw-r--r--man/display.texi16
-rw-r--r--man/widget.texi4
-rw-r--r--nt/ChangeLog5
-rw-r--r--nt/gmake.defs6
-rw-r--r--src/ChangeLog138
-rw-r--r--src/gtkutil.c24
-rw-r--r--src/gtkutil.h2
-rw-r--r--src/image.c16
-rw-r--r--src/insdel.c30
-rw-r--r--src/m/amdx86-64.h27
-rw-r--r--src/mac.c355
-rw-r--r--src/macfns.c69
-rw-r--r--src/macgui.h21
-rw-r--r--src/macmenu.c445
-rw-r--r--src/macterm.c612
-rw-r--r--src/macterm.h7
-rw-r--r--src/minibuf.c22
-rw-r--r--src/xfns.c22
-rw-r--r--src/xmenu.c5
78 files changed, 5113 insertions, 3654 deletions
diff --git a/ChangeLog b/ChangeLog
index 9aea9f5ab2b..84f25e00117 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
12005-12-25 Giorgos Keramidas <keramida@ceid.upatras.gr> (tiny change)
2
3 * configure.in: use amdx86-64 for freebsd on x86_64.
4
12005-11-22 Romain Francoise <romain@orebokech.com> 52005-11-22 Romain Francoise <romain@orebokech.com>
2 6
3 * make-dist: Add etc/images/icons. 7 * make-dist: Add etc/images/icons.
diff --git a/configure.in b/configure.in
index f413c57db55..a838d79a135 100644
--- a/configure.in
+++ b/configure.in
@@ -238,6 +238,7 @@ case "${canonical}" in
238 case "${canonical}" in 238 case "${canonical}" in
239 alpha*-*-freebsd*) machine=alpha ;; 239 alpha*-*-freebsd*) machine=alpha ;;
240 i[3456]86-*-freebsd*) machine=intel386 ;; 240 i[3456]86-*-freebsd*) machine=intel386 ;;
241 amd64-*-freebsd*|x86_64-*-freebsd*) machine=amdx86-64 ;;
241 esac 242 esac
242 ;; 243 ;;
243 244
diff --git a/etc/ChangeLog b/etc/ChangeLog
index 0bcd8fc2e72..7c3283d24ff 100644
--- a/etc/ChangeLog
+++ b/etc/ChangeLog
@@ -1,3 +1,7 @@
12005-12-21 L$,1 q(Brentey K,Aa(Broly <lorentey@elte.hu>
2
3 * TODO: Add note on the multi-tty branch.
4
12005-12-16 L$,1 q(Brentey K,Aa(Broly <lorentey@elte.hu> 52005-12-16 L$,1 q(Brentey K,Aa(Broly <lorentey@elte.hu>
2 6
3 * NEWS: Change `prev-buffer' to `previous-buffer'; add note on 7 * NEWS: Change `prev-buffer' to `previous-buffer'; add note on
diff --git a/etc/TODO b/etc/TODO
index 8b6a3aea3d8..6e517f11e86 100644
--- a/etc/TODO
+++ b/etc/TODO
@@ -240,10 +240,8 @@ to the FSF.
240** Highlight rectangles (`mouse-track-rectangle-p' in XEmacs). Already in CUA, 240** Highlight rectangles (`mouse-track-rectangle-p' in XEmacs). Already in CUA,
241 but it's a valuable feature worth making more general. 241 but it's a valuable feature worth making more general.
242 242
243** Support simultaneous tty and X frames. [For a partial 243** Support simultaneous tty and X frames. [See the multi-tty branch of Emacs
244 implementation, see tla branch 244 at http://lorentey.hu/project/emacs.]
245 lorentey@elte.hu--2004/emacs--multi-tty--0 at
246 http://lorentey.hu/arch/2004]
247 245
248** Provide MIME support for Rmail using the Gnus MIME library. [Maybe 246** Provide MIME support for Rmail using the Gnus MIME library. [Maybe
249 not now feasible, given Gnus maintenance decisions. fx looked at 247 not now feasible, given Gnus maintenance decisions. fx looked at
@@ -419,6 +417,12 @@ when the body only calls primitives.
419** Provide the toolbar on ttys. This could map a bit like tmm-menubar 417** Provide the toolbar on ttys. This could map a bit like tmm-menubar
420 for the menubar and buttons could look a bit like those used by customize. 418 for the menubar and buttons could look a bit like those used by customize.
421 419
420** Improve Help buffers: Change the face of previously visited links (like
421 Info, but also with regard to namespace), add a forward button to make the
422 Help buffer more browser like and gives the value of lisp expressions
423 e.g auto-mode-alist, the right face. [nickrob@snap.net.nz has a patch
424 for this for inclusion after 22.1].
425
422* Internal changes 426* Internal changes
423 427
424** Replace gmalloc.c with the modified Doug Lea code from the current 428** Replace gmalloc.c with the modified Doug Lea code from the current
diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog
index bab6d6cea38..223470d2e3d 100644
--- a/lib-src/ChangeLog
+++ b/lib-src/ChangeLog
@@ -1,3 +1,7 @@
12005-12-22 Richard M. Stallman <rms@gnu.org>
2
3 * Makefile.in (update-game-score.o): Delete spurious final `\'.
4
12005-11-18 Hideki IWAMOTO <h-iwamoto@kit.hi-ho.ne.jp> (tiny change) 52005-11-18 Hideki IWAMOTO <h-iwamoto@kit.hi-ho.ne.jp> (tiny change)
2 6
3 * etags.c (main): Cxref mode writes to stdout: do not close tagf, 7 * etags.c (main): Cxref mode writes to stdout: do not close tagf,
diff --git a/lib-src/Makefile.in b/lib-src/Makefile.in
index 29fc2ec5374..7f071543965 100644
--- a/lib-src/Makefile.in
+++ b/lib-src/Makefile.in
@@ -465,7 +465,7 @@ update-game-score${EXEEXT}: update-game-score.o $(GETOPTDEPS)
465 465
466update-game-score.o: ${srcdir}/update-game-score.c ../src/config.h $(GETOPT_H) 466update-game-score.o: ${srcdir}/update-game-score.c ../src/config.h $(GETOPT_H)
467 $(CC) -c ${CPP_CFLAGS} ${srcdir}/update-game-score.c \ 467 $(CC) -c ${CPP_CFLAGS} ${srcdir}/update-game-score.c \
468 -DHAVE_SHARED_GAME_DIR="\"$(gamedir)\"" \ 468 -DHAVE_SHARED_GAME_DIR="\"$(gamedir)\""
469 469
470/* These are NOT included in INSTALLABLES or UTILITIES. 470/* These are NOT included in INSTALLABLES or UTILITIES.
471 See ../src/Makefile.in. */ 471 See ../src/Makefile.in. */
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index b3b1757b2e4..c1cb1296b21 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,206 @@
12005-12-25 Richard M. Stallman <rms@gnu.org>
2
3 * progmodes/delphi.el (delphi-other-face): Allow nil in type.
4
5 * locate.el (locate-header-face): Allow nil in type.
6
7 * progmodes/cpp.el (cpp-face-none-list): Use cpp-face instead of face.
8
92005-12-25 Romain Francoise <romain@orebokech.com>
10
11 * battery.el (battery-linux-proc-acpi): Also try
12 `/proc/acpi/thermal_zone/THM0/temperature'.
13
142005-12-24 Chong Yidong <cyd@stupidchicken.com>
15
16 * custom.el (custom-push-theme): Fix docstring.
17
18 * cus-edit.el (custom-variable-set, custom-variable-save,
19 custom-variable-save): Custom-quote widget values.
20 (customize-save-variable): Fix custom-push-theme call.
21
222005-12-24 Eli Zaretskii <eliz@gnu.org>
23
24 * w32-fns.el (w32-batch-update-autoloads): New function.
25
26 * makefile.w32-in (autoloads, $(lisp)/mh-e/mh-loaddefs.el): Use
27 w32-batch-update-autoloads, and don't setq generated-autoload-file
28 from the command line.
29
302005-12-23 Chong Yidong <cyd@stupidchicken.com>
31
32 * custom.el (custom-push-theme): Clarify docstring. VALUE nil for
33 reset means to remove setting from theme entirely. Don't keep
34 expanding theme-settings list; delete old entries if necessary.
35
36 * cus-edit.el (custom-buffer-create-internal): Move "Erase
37 customization" button one line up.
38 (custom-themed): New face.
39 (custom-magic-alist): New value, THEMED, for theme settings.
40 (custom-variable-state-set, custom-face-state-set): Check
41 theme-value instead of saved-value.
42 (custom-variable-reset-standard, custom-face-reset-standard):
43 Remove theme setting entirely. Recalculate new values.
44 (custom-variable-set, custom-variable-set)
45 (custom-variable-reset-saved, custom-variable-reset-backup)
46 (custom-face-set, custom-face-reset-saved): Update `user' theme.
47 (custom-variable-save): Fix typos.
48
492005-12-23 Juri Linkov <juri@jurta.org>
50
51 * emacs-lisp/edebug.el (edebug-all-defs, edebug-all-forms):
52 Add autoload cookies.
53 (edebug-outside-d-c-i-n-s-w): New variable.
54 (edebug-display, edebug-outside-excursion): Use it to save the
55 original value of default-cursor-in-non-selected-windows.
56 Set default-cursor-in-non-selected-windows to t while Edebug
57 is active.
58 (edebug-mode, edebug-eval-mode): Doc fix.
59
60 * mouse.el (mouse-choose-completion): Replace `buffer-substring'
61 with `buffer-substring-no-properties' to remove common substring
62 highlighting.
63
64 * info.el (info-other-window, info): Rename function argument
65 `file' to `file-or-node'.
66 (Info-complete-menu-item): Use local variable `complete-nodes' to
67 keep the global value of `Info-complete-nodes' unchanged for
68 subsequent completions.
69 (info-tool-bar-map): Put `Info-index' icon just before `Info-search'.
70
71 * simple.el (get-next-valid-buffer, last-buffer)
72 (next-error-buffer-p, next-error-find-buffer)
73 (minibuffer-history-sexp-flag): Doc fix.
74
75 * savehist.el (savehist-mode-hook): Add `:group'.
76
77 * log-view.el: Call autoload for vc-find-version.
78 (log-view-current-file): Adjust subgroup numbers.
79 (log-view-current-tag): Add `length'.
80
812005-12-23 Richard M. Stallman <rms@gnu.org>
82
83 * vc.el (vc-annotate-car-last-cons): Defn moved up.
84
852005-12-23 Juri Linkov <juri@jurta.org>
86
87 * hi-lock.el (hi-lock-archaic-interface-message-used)
88 (hi-lock-archaic-interface-deduce, hi-lock-mode): Doc fix.
89 (hi-lock-mode): Display "Hi" in the mode line only when
90 hi-lock-interactive-patterns or hi-lock-file-patterns is non-nil.
91 (hi-lock-write-interactive-patterns):
92 Use hi-lock-file-patterns-prefix instead of hard-coded "Hi-lock".
93 (hi-lock-set-pattern, hi-lock-set-file-patterns)
94 (hi-lock-font-lock-hook): Set 3rd arg `how' of
95 font-lock-add-keywords to t.
96
972005-12-23 David Koppelman <koppel@ece.lsu.edu>
98
99 * hi-lock.el (hi-lock-highlight-range): New variable.
100 (hi-lock-mode, hi-lock-unface-buffer): Call font-lock-fontify-buffer
101 only if font-lock-fontified is non-nil. Remove overlays.
102 (hi-lock-set-pattern): Call font-lock-fontify-buffer if
103 font-lock-fontified is non-nil, otherwise use overlays (instead of
104 text properties).
105 (hi-lock-string-serialize-hash, hi-lock-string-serialize-serial):
106 New variables.
107 (hi-lock-string-serialize) New function.
108
1092005-12-23 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
110
111 * menu-bar.el (menu-find-file-existing): New function.
112 (menu-bar-file-menu): Use menu-find-file-existing for Open.
113
114 * tool-bar.el (tool-bar-setup): open changed to menu-find-file-existing.
115
1162005-12-22 Stefan Monnier <monnier@iro.umontreal.ca>
117
118 * vc.el: Remove unnecessary leading * in docstrings.
119 (vc-annotate-mode-map): Move initialization into declaration.
120 (vc-static-header-alist): Nitpick on the regexp.
121 (vc-default-init-version): New fun.
122 (vc-register): Use it.
123 (vc-insert-headers): Use dolist.
124 (vc-annotate-get-backend): Remove unused function.
125 (vc-annotate-add-menu): Remove. Build the menu directly at toplevel.
126 (vc-annotate-mode): Remove corresponding call.
127 (vc-annotate-car-last-cons): Simplify.
128 (vc-annotate-buffers): Remove var.
129 (vc-annotate-backend): Make it buffer-local.
130 (vc-annotate): Move the interaction to the interactive spec.
131 Add a `buf' argument.
132 (vc-annotate-warp-version): Use this new `buf' argument to avoid
133 killing&creating a vc-annotate buffer, which is very disruptive when
134 the buffers are shown in dedicated frames.
135
1362005-12-23 Nick Roberts <nickrob@snap.net.nz>
137
138 * descr-text.el: Add FSF as maintainer.
139 (describe-text-mode, describe-text-mode-map)
140 (describe-text-mode-hook, describe-text-done): Delete. Use normal
141 help-mode.
142 (describe-text-widget, describe-text-sexp)
143 (describe-property-list, describe-text-category)
144 (describe-text-properties, describe-text-properties-1)
145 (describe-char): Use help buttons instead of widgets.
146 (describe-char-unicodedata-file): Make URL link in doc string.
147
1482005-12-22 Richard M. Stallman <rms@gnu.org>
149
150 * cus-edit.el (custom-variable-prompt): Say "variable" in prompt.
151 (custom-buffer-create-internal): Reword the top-of-buffer help intro.
152 Don't include buttons that write a file when there's no file.
153 (custom-variable-menu, custom-face-menu, custom-group-menu):
154 Don't include commands that write a file when there's no file.
155 (customize-browse): Reword the top-of-buffer help intro.
156 (custom-buffer-create-internal): Fix previous change.
157 (customize-changed-options-previous-release): Prev release is 21.1.
158 (customize-changed-options): Doc fix.
159 (customize-changed): New alias.
160 (custom-reset-menu, custom-magic-alist, Custom-mode-menu):
161 Say "standard values".
162 (Custom-reset-standard): Doc fix.
163 (custom-face-reset-standard): Doc fix.
164
1652005-12-22 Stefan Monnier <monnier@iro.umontreal.ca>
166
167 * font-lock.el (font-lock-default-fontify-buffer): Try and set-defaults
168 even if font-lock-mode is non-nil since it may be t without having
169 turned on font-lock-mode-internal.
170 (font-lock-choose-keywords): Minor optimization.
171 (font-lock-add-keywords, font-lock-remove-keywords)
172 (font-lock-set-defaults): Don't call make-local-variable on a variable
173 that we know to already be local.
174
1752005-12-22 Katsumi Yamaoka <yamaoka@jpl.org>
176
177 * emacs-lisp/lisp.el (lisp-complete-symbol): Don't print progress
178 messages if in the minibuffer.
179
1802005-12-21 Stefan Monnier <monnier@iro.umontreal.ca>
181
182 * textmodes/flyspell.el (flyspell-check-word-p): Don't quote - in a RE.
183 (tex-mode-flyspell-verify, flyspell-get-word)
184 (flyspell-external-point-words): Don't use point-min/max uselessly.
185
186 * emacs-lisp/lisp.el (lisp-complete-symbol): Mostly undo the change
187 by Kevin Rodgers. Instead, just hide the completions buffer if we
188 don't need to show it.
189
1902005-12-21 Luc Teirlinck <teirllm@auburn.edu>
191
192 * wid-edit.el (file, directory): Doc fixes for the `define-widget's.
193
1942005-12-21 Stefan Monnier <monnier@iro.umontreal.ca>
195
196 * emacs-lisp/lisp.el (lisp-complete-symbol): Don't call
197 delete-windows-on with an inexistent buffer.
198
1992005-12-22 Nick Roberts <nickrob@snap.net.nz>
200
201 * progmodes/gud.el (gud-tooltip-modes, gud-tooltip-display):
202 Delete defcustom variable :tag names.
203
12005-12-20 Stefan Monnier <monnier@iro.umontreal.ca> 2042005-12-20 Stefan Monnier <monnier@iro.umontreal.ca>
2 205
3 * log-view.el (log-view-file-re, log-view-message-re): Use shy groups. 206 * log-view.el (log-view-file-re, log-view-message-re): Use shy groups.
@@ -5506,7 +5709,7 @@
5506 * progmodes/gud.el (gud-speedbar-menu-items): Use :visible 5709 * progmodes/gud.el (gud-speedbar-menu-items): Use :visible
5507 instead of :active. 5710 instead of :active.
5508 5711
55092005-10-08 Eric Hanchrow <offby1@blarg.net> 57122005-10-08 Eric Hanchrow <offby1@blarg.net> (tiny change)
5510 5713
5511 * textmodes/ispell.el (ispell-check-version): 5714 * textmodes/ispell.el (ispell-check-version):
5512 Ignore hyphen, and all that follows, in aspell's version text. 5715 Ignore hyphen, and all that follows, in aspell's version text.
diff --git a/lisp/battery.el b/lisp/battery.el
index 649cbe4c2c3..710be5a4220 100644
--- a/lisp/battery.el
+++ b/lisp/battery.el
@@ -347,6 +347,14 @@ The following %-sequences are provided:
347 (when (re-search-forward 347 (when (re-search-forward
348 "temperature: +\\([0-9]+\\) C$" nil t) 348 "temperature: +\\([0-9]+\\) C$" nil t)
349 (match-string 1)))) 349 (match-string 1))))
350 (when (file-exists-p
351 "/proc/acpi/thermal_zone/THM0/temperature")
352 (with-temp-buffer
353 (insert-file-contents
354 "/proc/acpi/thermal_zone/THM0/temperature")
355 (when (re-search-forward
356 "temperature: +\\([0-9]+\\) C$" nil t)
357 (match-string 1))))
350 "N/A")) 358 "N/A"))
351 (cons ?r (or (and rate (concat (number-to-string rate) " " 359 (cons ?r (or (and rate (concat (number-to-string rate) " "
352 rate-type)) "N/A")) 360 rate-type)) "N/A"))
diff --git a/lisp/cus-edit.el b/lisp/cus-edit.el
index 43c38e172b5..54d0fa23e52 100644
--- a/lisp/cus-edit.el
+++ b/lisp/cus-edit.el
@@ -506,8 +506,8 @@ Return a list suitable for use in `interactive'."
506 (enable-recursive-minibuffers t) 506 (enable-recursive-minibuffers t)
507 val) 507 val)
508 (setq val (completing-read 508 (setq val (completing-read
509 (if default (format "Customize option (default %s): " default) 509 (if default (format "Customize variable (default %s): " default)
510 "Customize option: ") 510 "Customize variable: ")
511 obarray 'custom-variable-p t nil nil default)) 511 obarray 'custom-variable-p t nil nil default))
512 (list (if (equal val "") 512 (list (if (equal val "")
513 (if (symbolp v) v nil) 513 (if (symbolp v) v nil)
@@ -766,7 +766,7 @@ groups after non-groups, if nil do not order groups at all."
766(defvar custom-reset-menu 766(defvar custom-reset-menu
767 '(("Current" . Custom-reset-current) 767 '(("Current" . Custom-reset-current)
768 ("Saved" . Custom-reset-saved) 768 ("Saved" . Custom-reset-saved)
769 ("Erase Customization (use standard settings)" . Custom-reset-standard)) 769 ("Erase Customization (use standard values)" . Custom-reset-standard))
770 "Alist of actions for the `Reset' button. 770 "Alist of actions for the `Reset' button.
771The key is a string containing the name of the action, the value is a 771The key is a string containing the name of the action, the value is a
772Lisp function taking the widget as an element which will be called 772Lisp function taking the widget as an element which will be called
@@ -803,8 +803,8 @@ when the action is chosen.")
803 803
804(defun Custom-reset-standard (&rest ignore) 804(defun Custom-reset-standard (&rest ignore)
805 "Erase all customization (either current or saved) for the group members. 805 "Erase all customization (either current or saved) for the group members.
806The immediate result is to restore them to their standard settings. 806The immediate result is to restore them to their standard values.
807This operation eliminates any saved settings for the group members, 807This operation eliminates any saved values for the group members,
808making them as if they had never been customized at all." 808making them as if they had never been customized at all."
809 (interactive) 809 (interactive)
810 (let ((children custom-options)) 810 (let ((children custom-options))
@@ -940,7 +940,7 @@ If given a prefix (or a COMMENT argument), also prompt for a comment."
940 current-prefix-arg)) 940 current-prefix-arg))
941 (funcall (or (get variable 'custom-set) 'set-default) variable value) 941 (funcall (or (get variable 'custom-set) 'set-default) variable value)
942 (put variable 'saved-value (list (custom-quote value))) 942 (put variable 'saved-value (list (custom-quote value)))
943 (custom-push-theme 'theme-value variable 'user 'set (list (custom-quote value))) 943 (custom-push-theme 'theme-value variable 'user 'set (custom-quote value))
944 (cond ((string= comment "") 944 (cond ((string= comment "")
945 (put variable 'variable-comment nil) 945 (put variable 'variable-comment nil)
946 (put variable 'saved-variable-comment nil)) 946 (put variable 'saved-variable-comment nil))
@@ -1065,19 +1065,21 @@ Show the buffer in another window, but don't select it."
1065 (unless (eq symbol basevar) 1065 (unless (eq symbol basevar)
1066 (message "`%s' is an alias for `%s'" symbol basevar)))) 1066 (message "`%s' is an alias for `%s'" symbol basevar))))
1067 1067
1068(defvar customize-changed-options-previous-release "20.2" 1068(defvar customize-changed-options-previous-release "21.1"
1069 "Version for `customize-changed-options' to refer back to by default.") 1069 "Version for `customize-changed-options' to refer back to by default.")
1070 1070
1071;;;###autoload 1071;;;###autoload
1072(defalias 'customize-changed 'customize-changed-options)
1073
1074;;;###autoload
1072(defun customize-changed-options (since-version) 1075(defun customize-changed-options (since-version)
1073 "Customize all user option variables changed in Emacs itself. 1076 "Customize all settings whose meanings have changed in Emacs itself.
1074This includes new user option variables and faces, and new 1077This includes new user option variables and faces, and new
1075customization groups, as well as older options and faces whose default 1078customization groups, as well as older options and faces whose meanings
1076values have changed since the previous major Emacs release. 1079or default values have changed since the previous major Emacs release.
1077 1080
1078With argument SINCE-VERSION (a string), customize all user option 1081With argument SINCE-VERSION (a string), customize all settings
1079variables that were added (or their meanings were changed) since that 1082that were added or redefined since that version."
1080version."
1081 1083
1082 (interactive "sCustomize options changed, since version (default all versions): ") 1084 (interactive "sCustomize options changed, since version (default all versions): ")
1083 (if (equal since-version "") 1085 (if (equal since-version "")
@@ -1430,25 +1432,25 @@ Otherwise use brackets."
1430 (if description 1432 (if description
1431 (widget-insert description)) 1433 (widget-insert description))
1432 (widget-insert (format ". 1434 (widget-insert (format ".
1433%s show active fields; type RET or click mouse-1 1435%s buttons; type RET or click mouse-1 to actuate one.
1434on an active field to invoke its action. Editing an option value 1436Editing a setting changes only the text in the buffer.
1435changes only the text in the buffer. Invoke the State button to set or 1437Use the setting's State button to set it or save changes in it.
1436save the option value. Saving an option normally edits your init file. 1438Saving a change normally works by editing your Emacs init file.
1437Invoke " 1439See "
1438 (if custom-raised-buttons 1440 (if custom-raised-buttons
1439 "`Raised' buttons" 1441 "`Raised' text indicates"
1440 "Square brackets"))) 1442 "Square brackets indicate")))
1441 (widget-create 'info-link 1443 (widget-create 'info-link
1442 :tag "Custom file" 1444 :tag "Custom file"
1443 "(emacs)Saving Customizations") 1445 "(emacs)Saving Customizations")
1444 (widget-insert 1446 (widget-insert
1445 " for information on how to save in a different file. 1447 " for information on how to save in a different file.\n
1446Invoke ") 1448See ")
1447 (widget-create 'info-link 1449 (widget-create 'info-link
1448 :tag "Help" 1450 :tag "Help"
1449 :help-echo "Read the online help." 1451 :help-echo "Read the online help."
1450 "(emacs)Easy Customization") 1452 "(emacs)Easy Customization")
1451 (widget-insert " for general information.\n\n") 1453 (widget-insert " for more information.\n\n")
1452 (widget-insert "Operate on everything in this buffer:\n ")) 1454 (widget-insert "Operate on everything in this buffer:\n "))
1453 (widget-insert " ")) 1455 (widget-insert " "))
1454 (widget-create 'push-button 1456 (widget-create 'push-button
@@ -1457,14 +1459,15 @@ Invoke ")
1457Make your editing in this buffer take effect for this session." 1459Make your editing in this buffer take effect for this session."
1458 :action (lambda (widget &optional event) 1460 :action (lambda (widget &optional event)
1459 (Custom-set))) 1461 (Custom-set)))
1460 (widget-insert " ") 1462 (when (or custom-file user-init-file)
1461 (widget-create 'push-button 1463 (widget-insert " ")
1462 :tag "Save for Future Sessions" 1464 (widget-create 'push-button
1463 :help-echo "\ 1465 :tag "Save for Future Sessions"
1466 :help-echo "\
1464Make your editing in this buffer take effect for future Emacs sessions. 1467Make your editing in this buffer take effect for future Emacs sessions.
1465This updates your Emacs initialization file or creates a new one." 1468This updates your Emacs initialization file or creates a new one."
1466 :action (lambda (widget &optional event) 1469 :action (lambda (widget &optional event)
1467 (Custom-save))) 1470 (Custom-save))))
1468 (if custom-reset-button-menu 1471 (if custom-reset-button-menu
1469 (progn 1472 (progn
1470 (widget-insert " ") 1473 (widget-insert " ")
@@ -1474,6 +1477,13 @@ This updates your Emacs initialization file or creates a new one."
1474 :mouse-down-action (lambda (&rest junk) t) 1477 :mouse-down-action (lambda (&rest junk) t)
1475 :action (lambda (widget &optional event) 1478 :action (lambda (widget &optional event)
1476 (custom-reset event)))) 1479 (custom-reset event))))
1480 (widget-insert " ")
1481 (when (or custom-file user-init-file)
1482 (widget-create 'push-button
1483 :tag "Erase Customization"
1484 :help-echo "\
1485Un-customize all settings in this buffer--save them with standard values."
1486 :action 'Custom-reset-standard)))
1477 (widget-insert "\n ") 1487 (widget-insert "\n ")
1478 (widget-create 'push-button 1488 (widget-create 'push-button
1479 :tag "Reset to Current" 1489 :tag "Reset to Current"
@@ -1484,14 +1494,8 @@ Reset all edited text in this buffer to reflect current values."
1484 (widget-create 'push-button 1494 (widget-create 'push-button
1485 :tag "Reset to Saved" 1495 :tag "Reset to Saved"
1486 :help-echo "\ 1496 :help-echo "\
1487Reset all values in this buffer to their saved settings." 1497Reset all settings in this buffer to their saved values."
1488 :action 'Custom-reset-saved) 1498 :action 'Custom-reset-saved)
1489 (widget-insert " ")
1490 (widget-create 'push-button
1491 :tag "Erase Customization"
1492 :help-echo "\
1493Un-customize all values in this buffer. They get their standard settings."
1494 :action 'Custom-reset-standard))
1495 (if (not custom-buffer-verbose-help) 1499 (if (not custom-buffer-verbose-help)
1496 (progn 1500 (progn
1497 (widget-insert " ") 1501 (widget-insert " ")
@@ -1560,10 +1564,15 @@ Un-customize all values in this buffer. They get their standard settings."
1560 (let ((name "*Customize Browser*")) 1564 (let ((name "*Customize Browser*"))
1561 (pop-to-buffer (custom-get-fresh-buffer name))) 1565 (pop-to-buffer (custom-get-fresh-buffer name)))
1562 (custom-mode) 1566 (custom-mode)
1563 (widget-insert "\ 1567 (widget-insert (format "\
1564Square brackets show active fields; type RET or click mouse-1 1568%s buttons; type RET or click mouse-1
1565on an active field to invoke its action. 1569on a button to invoke its action.
1566Invoke [+] below to expand a group, and [-] to collapse an expanded group.\n") 1570Invoke [+] to expand a group, and [-] to collapse an expanded group.\n"
1571 (if custom-raised-buttons
1572 "`Raised' text indicates"
1573 "Square brackets indicate")))
1574
1575
1567 (if custom-browse-only-groups 1576 (if custom-browse-only-groups
1568 (widget-insert "\ 1577 (widget-insert "\
1569Invoke the [Group] button below to edit that item in another window.\n\n") 1578Invoke the [Group] button below to edit that item in another window.\n\n")
@@ -1738,6 +1747,15 @@ item in another window.\n\n"))
1738;; backward-compatibility alias 1747;; backward-compatibility alias
1739(put 'custom-changed-face 'face-alias 'custom-changed) 1748(put 'custom-changed-face 'face-alias 'custom-changed)
1740 1749
1750(defface custom-themed '((((min-colors 88) (class color))
1751 (:foreground "white" :background "blue1"))
1752 (((class color))
1753 (:foreground "white" :background "blue"))
1754 (t
1755 (:slant italic)))
1756 "Face used when the customize item has been set by a theme."
1757 :group 'custom-magic-faces)
1758
1741(defface custom-saved '((t (:underline t))) 1759(defface custom-saved '((t (:underline t)))
1742 "Face used when the customize item has been saved." 1760 "Face used when the customize item has been saved."
1743 :group 'custom-magic-faces) 1761 :group 'custom-magic-faces)
@@ -1766,12 +1784,15 @@ something in this group has been changed outside customize.")
1766 (saved "!" custom-saved "\ 1784 (saved "!" custom-saved "\
1767SAVED and set." "\ 1785SAVED and set." "\
1768something in this group has been set and saved.") 1786something in this group has been set and saved.")
1787 (themed "o" custom-themed "\
1788THEMED." "\
1789visible group members are all at standard values.")
1769 (rogue "@" custom-rogue "\ 1790 (rogue "@" custom-rogue "\
1770NO CUSTOMIZATION DATA; not intended to be customized." "\ 1791NO CUSTOMIZATION DATA; not intended to be customized." "\
1771something in this group is not prepared for customization.") 1792something in this group is not prepared for customization.")
1772 (standard " " nil "\ 1793 (standard " " nil "\
1773STANDARD." "\ 1794STANDARD." "\
1774visible group members are all at standard settings.")) 1795visible group members are all at standard values."))
1775 "Alist of customize option states. 1796 "Alist of customize option states.
1776Each entry is of the form (STATE MAGIC FACE ITEM-DESC [ GROUP-DESC ]), where 1797Each entry is of the form (STATE MAGIC FACE ITEM-DESC [ GROUP-DESC ]), where
1777 1798
@@ -2524,14 +2545,22 @@ Otherwise, look up symbol in `custom-guess-type-alist'."
2524 (error nil)) 2545 (error nil))
2525 'set 2546 'set
2526 'changed)) 2547 'changed))
2527 ((progn (setq tmp (get symbol 'saved-value)) 2548 ((progn (setq tmp (get symbol 'theme-value))
2528 (setq temp (get symbol 'saved-variable-comment)) 2549 (setq temp (get symbol 'saved-variable-comment))
2529 (or tmp temp)) 2550 (or tmp temp))
2530 (if (condition-case nil 2551 (if (condition-case nil
2531 (and (equal value (eval (car tmp))) 2552 (and (equal comment temp)
2532 (equal comment temp)) 2553 (equal value
2554 (eval (car
2555 (custom-theme-value
2556 (caar tmp) tmp)))))
2533 (error nil)) 2557 (error nil))
2534 'saved 2558 (cond
2559 ((eq 'user (caar (get symbol 'theme-value)))
2560 'saved)
2561 ((eq 'standard (caar (get symbol 'theme-value)))
2562 'changed)
2563 (t 'themed))
2535 'changed)) 2564 'changed))
2536 ((setq tmp (get symbol 'standard-value)) 2565 ((setq tmp (get symbol 'standard-value))
2537 (if (condition-case nil 2566 (if (condition-case nil
@@ -2547,12 +2576,13 @@ Otherwise, look up symbol in `custom-guess-type-alist'."
2547 (get (widget-value widget) 'standard-value)) 2576 (get (widget-value widget) 'standard-value))
2548 2577
2549(defvar custom-variable-menu 2578(defvar custom-variable-menu
2550 '(("Set for Current Session" custom-variable-set 2579 `(("Set for Current Session" custom-variable-set
2551 (lambda (widget) 2580 (lambda (widget)
2552 (eq (widget-get widget :custom-state) 'modified))) 2581 (eq (widget-get widget :custom-state) 'modified)))
2553 ("Save for Future Sessions" custom-variable-save 2582 ,@(when (or custom-file user-init-file)
2554 (lambda (widget) 2583 '(("Save for Future Sessions" custom-variable-save
2555 (memq (widget-get widget :custom-state) '(modified set changed rogue)))) 2584 (lambda (widget)
2585 (memq (widget-get widget :custom-state) '(modified set changed rogue))))))
2556 ("Reset to Current" custom-redraw 2586 ("Reset to Current" custom-redraw
2557 (lambda (widget) 2587 (lambda (widget)
2558 (and (default-boundp (widget-value widget)) 2588 (and (default-boundp (widget-value widget))
@@ -2563,11 +2593,12 @@ Otherwise, look up symbol in `custom-guess-type-alist'."
2563 (get (widget-value widget) 'saved-variable-comment)) 2593 (get (widget-value widget) 'saved-variable-comment))
2564 (memq (widget-get widget :custom-state) 2594 (memq (widget-get widget :custom-state)
2565 '(modified set changed rogue))))) 2595 '(modified set changed rogue)))))
2566 ("Erase Customization" custom-variable-reset-standard 2596 ,@(when (or custom-file user-init-file)
2567 (lambda (widget) 2597 '(("Erase Customization" custom-variable-reset-standard
2568 (and (get (widget-value widget) 'standard-value) 2598 (lambda (widget)
2569 (memq (widget-get widget :custom-state) 2599 (and (get (widget-value widget) 'standard-value)
2570 '(modified set changed saved rogue))))) 2600 (memq (widget-get widget :custom-state)
2601 '(modified set changed saved rogue)))))))
2571 ("Use Backup Value" custom-variable-reset-backup 2602 ("Use Backup Value" custom-variable-reset-backup
2572 (lambda (widget) 2603 (lambda (widget)
2573 (get (widget-value widget) 'backup-value))) 2604 (get (widget-value widget) 'backup-value)))
@@ -2638,6 +2669,8 @@ Optional EVENT is the location for the menu."
2638 ;; Make the comment invisible by hand if it's empty 2669 ;; Make the comment invisible by hand if it's empty
2639 (custom-comment-hide comment-widget)) 2670 (custom-comment-hide comment-widget))
2640 (custom-variable-backup-value widget) 2671 (custom-variable-backup-value widget)
2672 (custom-push-theme 'theme-value symbol 'user
2673 'set (custom-quote (widget-value child)))
2641 (funcall set symbol (eval (setq val (widget-value child)))) 2674 (funcall set symbol (eval (setq val (widget-value child))))
2642 (put symbol 'customized-value (list val)) 2675 (put symbol 'customized-value (list val))
2643 (put symbol 'variable-comment comment) 2676 (put symbol 'variable-comment comment)
@@ -2648,6 +2681,8 @@ Optional EVENT is the location for the menu."
2648 ;; Make the comment invisible by hand if it's empty 2681 ;; Make the comment invisible by hand if it's empty
2649 (custom-comment-hide comment-widget)) 2682 (custom-comment-hide comment-widget))
2650 (custom-variable-backup-value widget) 2683 (custom-variable-backup-value widget)
2684 (custom-push-theme 'theme-value symbol 'user
2685 'set (custom-quote (widget-value child)))
2651 (funcall set symbol (setq val (widget-value child))) 2686 (funcall set symbol (setq val (widget-value child)))
2652 (put symbol 'customized-value (list (custom-quote val))) 2687 (put symbol 'customized-value (list (custom-quote val)))
2653 (put symbol 'variable-comment comment) 2688 (put symbol 'variable-comment comment)
@@ -2677,7 +2712,7 @@ Optional EVENT is the location for the menu."
2677 (custom-comment-hide comment-widget)) 2712 (custom-comment-hide comment-widget))
2678 (put symbol 'saved-value (list (widget-value child))) 2713 (put symbol 'saved-value (list (widget-value child)))
2679 (custom-push-theme 'theme-value symbol 'user 2714 (custom-push-theme 'theme-value symbol 'user
2680 'set (list (widget-value child))) 2715 'set (custom-quote (widget-value child)))
2681 (funcall set symbol (eval (widget-value child))) 2716 (funcall set symbol (eval (widget-value child)))
2682 (put symbol 'variable-comment comment) 2717 (put symbol 'variable-comment comment)
2683 (put symbol 'saved-variable-comment comment)) 2718 (put symbol 'saved-variable-comment comment))
@@ -2689,8 +2724,7 @@ Optional EVENT is the location for the menu."
2689 (put symbol 'saved-value 2724 (put symbol 'saved-value
2690 (list (custom-quote (widget-value child)))) 2725 (list (custom-quote (widget-value child))))
2691 (custom-push-theme 'theme-value symbol 'user 2726 (custom-push-theme 'theme-value symbol 'user
2692 'set (list (custom-quote (widget-value 2727 'set (custom-quote (widget-value child)))
2693 child))))
2694 (funcall set symbol (widget-value child)) 2728 (funcall set symbol (widget-value child))
2695 (put symbol 'variable-comment comment) 2729 (put symbol 'variable-comment comment)
2696 (put symbol 'saved-variable-comment comment))) 2730 (put symbol 'saved-variable-comment comment)))
@@ -2711,6 +2745,7 @@ becomes the backup value, so you can get it again."
2711 (cond ((or value comment) 2745 (cond ((or value comment)
2712 (put symbol 'variable-comment comment) 2746 (put symbol 'variable-comment comment)
2713 (custom-variable-backup-value widget) 2747 (custom-variable-backup-value widget)
2748 (custom-push-theme 'theme-value symbol 'user 'set value)
2714 (condition-case nil 2749 (condition-case nil
2715 (funcall set symbol (eval (car value))) 2750 (funcall set symbol (eval (car value)))
2716 (error nil))) 2751 (error nil)))
@@ -2731,20 +2766,15 @@ becomes the backup value, so you can get it again."
2731 (let* ((symbol (widget-value widget)) 2766 (let* ((symbol (widget-value widget))
2732 (set (or (get symbol 'custom-set) 'set-default))) 2767 (set (or (get symbol 'custom-set) 'set-default)))
2733 (if (get symbol 'standard-value) 2768 (if (get symbol 'standard-value)
2734 (progn 2769 (custom-variable-backup-value widget)
2735 (custom-variable-backup-value widget)
2736 (funcall set symbol (eval (car (get symbol 'standard-value)))))
2737 (error "No standard setting known for %S" symbol)) 2770 (error "No standard setting known for %S" symbol))
2738 (put symbol 'variable-comment nil) 2771 (put symbol 'variable-comment nil)
2739 (put symbol 'customized-value nil) 2772 (put symbol 'customized-value nil)
2740 (put symbol 'customized-variable-comment nil) 2773 (put symbol 'customized-variable-comment nil)
2774 (custom-push-theme 'theme-value symbol 'user 'reset nil)
2775 (custom-theme-recalc-variable symbol)
2741 (when (or (get symbol 'saved-value) (get symbol 'saved-variable-comment)) 2776 (when (or (get symbol 'saved-value) (get symbol 'saved-variable-comment))
2742 (put symbol 'saved-value nil) 2777 (put symbol 'saved-value nil)
2743 (custom-push-theme 'theme-value symbol 'user 'reset 'standard)
2744 ;; As a special optimizations we do not (explictly)
2745 ;; save resets to standard when no theme set the value.
2746 (if (null (cdr (get symbol 'theme-value)))
2747 (put symbol 'theme-value nil))
2748 (put symbol 'saved-variable-comment nil) 2778 (put symbol 'saved-variable-comment nil)
2749 (custom-save-all)) 2779 (custom-save-all))
2750 (widget-put widget :custom-state 'unknown) 2780 (widget-put widget :custom-state 'unknown)
@@ -2776,6 +2806,7 @@ to switch between two values."
2776 (if value 2806 (if value
2777 (progn 2807 (progn
2778 (custom-variable-backup-value widget) 2808 (custom-variable-backup-value widget)
2809 (custom-push-theme 'theme-value symbol 'user 'set value)
2779 (condition-case nil 2810 (condition-case nil
2780 (funcall set symbol (car value)) 2811 (funcall set symbol (car value))
2781 (error nil))) 2812 (error nil)))
@@ -3218,15 +3249,17 @@ SPEC must be a full face spec."
3218 (message "Creating face editor...done")))))) 3249 (message "Creating face editor...done"))))))
3219 3250
3220(defvar custom-face-menu 3251(defvar custom-face-menu
3221 '(("Set for Current Session" custom-face-set) 3252 `(("Set for Current Session" custom-face-set)
3222 ("Save for Future Sessions" custom-face-save-command) 3253 ,@(when (or custom-file user-init-file)
3254 '(("Save for Future Sessions" custom-face-save-command)))
3223 ("Reset to Saved" custom-face-reset-saved 3255 ("Reset to Saved" custom-face-reset-saved
3224 (lambda (widget) 3256 (lambda (widget)
3225 (or (get (widget-value widget) 'saved-face) 3257 (or (get (widget-value widget) 'saved-face)
3226 (get (widget-value widget) 'saved-face-comment)))) 3258 (get (widget-value widget) 'saved-face-comment))))
3227 ("Erase Customization" custom-face-reset-standard 3259 ,@(when (or custom-file user-init-file)
3228 (lambda (widget) 3260 '(("Erase Customization" custom-face-reset-standard
3229 (get (widget-value widget) 'face-defface-spec))) 3261 (lambda (widget)
3262 (get (widget-value widget) 'face-defface-spec)))))
3230 ("---" ignore ignore) 3263 ("---" ignore ignore)
3231 ("Add Comment" custom-comment-show custom-comment-invisible-p) 3264 ("Add Comment" custom-comment-show custom-comment-invisible-p)
3232 ("---" ignore ignore) 3265 ("---" ignore ignore)
@@ -3282,7 +3315,12 @@ widget. If FILTER is nil, ACTION is always valid.")
3282 (setq temp (get symbol 'saved-face-comment)) 3315 (setq temp (get symbol 'saved-face-comment))
3283 (or tmp temp)) 3316 (or tmp temp))
3284 (if (equal temp comment) 3317 (if (equal temp comment)
3285 'saved 3318 (cond
3319 ((eq 'user (caar (get symbol 'theme-face)))
3320 'saved)
3321 ((eq 'standard (caar (get symbol 'theme-face)))
3322 'changed)
3323 (t 'themed))
3286 'changed)) 3324 'changed))
3287 ((get symbol 'face-defface-spec) 3325 ((get symbol 'face-defface-spec)
3288 (if (equal comment nil) 3326 (if (equal comment nil)
@@ -3329,6 +3367,7 @@ Optional EVENT is the location for the menu."
3329 ;; face-set-spec ignores empty attribute lists, so just give it 3367 ;; face-set-spec ignores empty attribute lists, so just give it
3330 ;; something harmless instead. 3368 ;; something harmless instead.
3331 (face-spec-set symbol '((t :foreground unspecified)))) 3369 (face-spec-set symbol '((t :foreground unspecified))))
3370 (custom-push-theme 'theme-face symbol 'user 'set value)
3332 (put symbol 'customized-face-comment comment) 3371 (put symbol 'customized-face-comment comment)
3333 (put symbol 'face-comment comment) 3372 (put symbol 'face-comment comment)
3334 (custom-face-state-set widget) 3373 (custom-face-state-set widget)
@@ -3377,6 +3416,7 @@ Optional EVENT is the location for the menu."
3377 (error "No saved value for this face")) 3416 (error "No saved value for this face"))
3378 (put symbol 'customized-face nil) 3417 (put symbol 'customized-face nil)
3379 (put symbol 'customized-face-comment nil) 3418 (put symbol 'customized-face-comment nil)
3419 (custom-push-theme 'theme-face symbol 'user 'set value)
3380 (face-spec-set symbol value) 3420 (face-spec-set symbol value)
3381 (put symbol 'face-comment comment) 3421 (put symbol 'face-comment comment)
3382 (widget-value-set child value) 3422 (widget-value-set child value)
@@ -3389,8 +3429,8 @@ Optional EVENT is the location for the menu."
3389 (get (widget-value widget) 'face-defface-spec)) 3429 (get (widget-value widget) 'face-defface-spec))
3390 3430
3391(defun custom-face-reset-standard (widget) 3431(defun custom-face-reset-standard (widget)
3392 "Restore WIDGET to the face's standard settings. 3432 "Restore WIDGET to the face's standard attribute values.
3393This operation eliminates any saved setting for the face, 3433This operation eliminates any saved attributes for the face,
3394restoring it to the state of a face that has never been customized." 3434restoring it to the state of a face that has never been customized."
3395 (let* ((symbol (widget-value widget)) 3435 (let* ((symbol (widget-value widget))
3396 (child (car (widget-get widget :children))) 3436 (child (car (widget-get widget :children)))
@@ -3400,15 +3440,12 @@ restoring it to the state of a face that has never been customized."
3400 (error "No standard setting for this face")) 3440 (error "No standard setting for this face"))
3401 (put symbol 'customized-face nil) 3441 (put symbol 'customized-face nil)
3402 (put symbol 'customized-face-comment nil) 3442 (put symbol 'customized-face-comment nil)
3443 (custom-push-theme 'theme-face symbol 'user 'reset nil)
3444 (custom-theme-recalc-face symbol)
3403 (when (or (get symbol 'saved-face) (get symbol 'saved-face-comment)) 3445 (when (or (get symbol 'saved-face) (get symbol 'saved-face-comment))
3404 (put symbol 'saved-face nil) 3446 (put symbol 'saved-face nil)
3405 (custom-push-theme 'theme-face symbol 'user 'reset 'standard)
3406 ;; Do not explictly save resets to standards without themes.
3407 (if (null (cdr (get symbol 'theme-face)))
3408 (put symbol 'theme-face nil))
3409 (put symbol 'saved-face-comment nil) 3447 (put symbol 'saved-face-comment nil)
3410 (custom-save-all)) 3448 (custom-save-all))
3411 (face-spec-set symbol value)
3412 (put symbol 'face-comment nil) 3449 (put symbol 'face-comment nil)
3413 (widget-value-set child value) 3450 (widget-value-set child value)
3414 ;; This call manages the comment visibility 3451 ;; This call manages the comment visibility
@@ -3808,21 +3845,23 @@ Creating group members... %2d%%"
3808 (insert "/\n"))))) 3845 (insert "/\n")))))
3809 3846
3810(defvar custom-group-menu 3847(defvar custom-group-menu
3811 '(("Set for Current Session" custom-group-set 3848 `(("Set for Current Session" custom-group-set
3812 (lambda (widget) 3849 (lambda (widget)
3813 (eq (widget-get widget :custom-state) 'modified))) 3850 (eq (widget-get widget :custom-state) 'modified)))
3814 ("Save for Future Sessions" custom-group-save 3851 ,@(when (or custom-file user-init-file)
3815 (lambda (widget) 3852 '(("Save for Future Sessions" custom-group-save
3816 (memq (widget-get widget :custom-state) '(modified set)))) 3853 (lambda (widget)
3854 (memq (widget-get widget :custom-state) '(modified set))))))
3817 ("Reset to Current" custom-group-reset-current 3855 ("Reset to Current" custom-group-reset-current
3818 (lambda (widget) 3856 (lambda (widget)
3819 (memq (widget-get widget :custom-state) '(modified)))) 3857 (memq (widget-get widget :custom-state) '(modified))))
3820 ("Reset to Saved" custom-group-reset-saved 3858 ("Reset to Saved" custom-group-reset-saved
3821 (lambda (widget) 3859 (lambda (widget)
3822 (memq (widget-get widget :custom-state) '(modified set)))) 3860 (memq (widget-get widget :custom-state) '(modified set))))
3823 ("Reset to standard setting" custom-group-reset-standard 3861 ,@(when (or custom-file user-init-file)
3824 (lambda (widget) 3862 '(("Reset to standard setting" custom-group-reset-standard
3825 (memq (widget-get widget :custom-state) '(modified set saved))))) 3863 (lambda (widget)
3864 (memq (widget-get widget :custom-state) '(modified set saved)))))))
3826 "Alist of actions for the `custom-group' widget. 3865 "Alist of actions for the `custom-group' widget.
3827Each entry has the form (NAME ACTION FILTER) where NAME is the name of 3866Each entry has the form (NAME ACTION FILTER) where NAME is the name of
3828the menu entry, ACTION is the function to call on the widget when the 3867the menu entry, ACTION is the function to call on the widget when the
@@ -4326,7 +4365,7 @@ The format is suitable for use with `easy-menu-define'."
4326 ["Save" Custom-save t] 4365 ["Save" Custom-save t]
4327 ["Reset to Current" Custom-reset-current t] 4366 ["Reset to Current" Custom-reset-current t]
4328 ["Reset to Saved" Custom-reset-saved t] 4367 ["Reset to Saved" Custom-reset-saved t]
4329 ["Reset to Standard Settings" Custom-reset-standard t] 4368 ["Reset to Standard Values" Custom-reset-standard t]
4330 ["Info" (info "(emacs)Easy Customization") t])) 4369 ["Info" (info "(emacs)Easy Customization") t]))
4331 4370
4332(defun Custom-goto-parent () 4371(defun Custom-goto-parent ()
diff --git a/lisp/custom.el b/lisp/custom.el
index b2a9ba6443c..df2488bda40 100644
--- a/lisp/custom.el
+++ b/lisp/custom.el
@@ -626,63 +626,75 @@ by `custom-theme-value'.
626 626
627MODE can be either the symbol `set' or the symbol `reset'. If it is the 627MODE can be either the symbol `set' or the symbol `reset'. If it is the
628symbol `set', then VALUE is the value to use. If it is the symbol 628symbol `set', then VALUE is the value to use. If it is the symbol
629`reset', then VALUE is another theme, whose value for this face or 629`reset', then VALUE is either another theme, which means to use the
630variable should be used. 630value defined by that theme; or nil, which means to remove SYMBOL from
631THEME entirely.
631 632
632In the following example for the variable `goto-address-url-face', the 633In the following example, the variable `goto-address-url-face' has been
633theme `subtle-hacker' uses the same value for the variable as the theme 634set by three different themes. Its `theme-value' property is:
634`gnome2':
635 635
636 \((standard set bold) 636 \((subtle-hacker reset gnome2)
637 \(gnome2 set info-xref)
638 \(jonadab set underline) 637 \(jonadab set underline)
639 \(subtle-hacker reset gnome2)) 638 \(gnome2 set info-xref)
640
641
642If a value has been stored for themes A B and C, and a new value
643is to be stored for theme C, then the old value of C is discarded.
644If a new value is to be stored for theme B, however, the old value
645of B is not discarded because B is not the car of the list.
646
647For variables, list property PROP is `theme-value'.
648For faces, list property PROP is `theme-face'.
649This is used in `custom-do-theme-reset', for example.
650 639
651The list looks the same in any case; the examples shows a possible 640The theme value defined by `subtle-hacker' is in effect, because
652value of the `theme-face' property for the face `region': 641that theme currently has the highest precedence. The theme
642`subtle-hacker' says to use the same value for the variable as
643the theme `gnome2'. Therefore, the theme value of the variable
644is `info-xref'. To change the precedence of the themes, use
645`enable-theme'.
653 646
654 \((gnome2 set ((t (:foreground \"cyan\" :background \"dark cyan\")))) 647The user has not customized the variable; had he done that, the
655 \(standard set ((((class color) (background dark)) 648list would contain an entry for the `user' theme, too.
656 \(:background \"blue\"))
657 \(t (:background \"gray\")))))
658 649
659This records values for the `standard' and the `gnome2' themes.
660The user has not customized the face; had he done that,
661the list would contain an entry for the `user' theme, too.
662See `custom-known-themes' for a list of known themes." 650See `custom-known-themes' for a list of known themes."
651 (unless (or (eq prop 'theme-value)
652 (eq prop 'theme-face))
653 (error "Unknown theme property"))
663 (let* ((old (get symbol prop)) 654 (let* ((old (get symbol prop))
664 (setting (assq theme old))) 655 (setting (assq theme old))
665 ;; Alter an existing theme-setting for the symbol, 656 (theme-settings (get theme 'theme-settings)))
666 ;; or add a new one. 657 (if (and (eq mode 'reset) (null value))
667 (if setting 658 ;; Remove a setting.
668 (progn 659 (when setting
669 (setcar (cdr setting) mode) 660 (let (res)
670 (setcar (cddr setting) value)) 661 (dolist (theme-setting theme-settings)
671 ;; If no custom theme has been applied yet, first save the 662 (if (and (eq (car theme-setting) prop)
672 ;; current values to the 'standard theme. 663 (eq (cadr theme-setting) symbol))
673 (if (null old) 664 (setq res theme-setting)))
674 (if (and (eq prop 'theme-value) 665 (put theme 'theme-settings (delq res theme-settings)))
675 (boundp symbol)) 666 (put symbol prop (delq setting old)))
676 (setq old 667 (if setting
677 (list (list 'standard 'set (symbol-value symbol)))) 668 ;; Alter an existing setting.
678 (if (facep symbol) 669 (let (res)
679 (setq old (list (list 'standard 'set (list 670 (dolist (theme-setting theme-settings)
680 (append '(t) (custom-face-attributes-get symbol nil))))))))) 671 (if (and (eq (car theme-setting) prop)
681 (put symbol prop (cons (list theme mode value) old))) 672 (eq (cadr theme-setting) symbol))
682 ;; Record, for each theme, all its settings. 673 (setq res theme-setting)))
683 (put theme 'theme-settings 674 (put theme 'theme-settings
684 (cons (list prop symbol theme mode value) 675 (cons (list prop symbol theme mode value)
685 (get theme 'theme-settings))))) 676 (delq res theme-settings)))
677 (setcar (cdr setting) mode)
678 (setcar (cddr setting) value))
679 ;; Add a new setting.
680 ;; If the user changed the value outside of Customize, we
681 ;; first save the current value to a fake theme, `standard'.
682 ;; This ensures that the user-set value comes back if the
683 ;; theme is later disabled.
684 (if (null old)
685 (if (and (eq prop 'theme-value)
686 (boundp symbol)
687 (or (null (get symbol 'standard-value))
688 (not (equal (eval (car (get symbol 'standard-value)))
689 (symbol-value symbol)))))
690 (setq old (list (list 'standard 'set (symbol-value symbol))))
691 (if (facep symbol)
692 (setq old (list (list 'standard 'set (list
693 (append '(t) (custom-face-attributes-get symbol nil)))))))))
694 (put symbol prop (cons (list theme mode value) old))
695 (put theme 'theme-settings
696 (cons (list prop symbol theme mode value)
697 theme-settings))))))
686 698
687(defvar custom-local-buffer nil 699(defvar custom-local-buffer nil
688 "Non-nil, in a Customization buffer, means customize a specific buffer. 700 "Non-nil, in a Customization buffer, means customize a specific buffer.
diff --git a/lisp/descr-text.el b/lisp/descr-text.el
index a75e227d2b0..76d6ae6be09 100644
--- a/lisp/descr-text.el
+++ b/lisp/descr-text.el
@@ -4,6 +4,7 @@
4;; 2005 Free Software Foundation, Inc. 4;; 2005 Free Software Foundation, Inc.
5 5
6;; Author: Boris Goldowsky <boris@gnu.org> 6;; Author: Boris Goldowsky <boris@gnu.org>
7;; Maintainer: FSF
7;; Keywords: faces, i18n, Unicode, multilingual 8;; Keywords: faces, i18n, Unicode, multilingual
8 9
9;; This file is part of GNU Emacs. 10;; This file is part of GNU Emacs.
@@ -31,50 +32,18 @@
31 32
32(eval-when-compile (require 'button) (require 'quail)) 33(eval-when-compile (require 'button) (require 'quail))
33 34
34(defun describe-text-done ()
35 "Delete the current window or bury the current buffer."
36 (interactive)
37 (if (> (count-windows) 1)
38 (delete-window)
39 (bury-buffer)))
40
41(defvar describe-text-mode-map
42 (let ((map (make-sparse-keymap)))
43 (set-keymap-parent map widget-keymap)
44 map)
45 "Keymap for `describe-text-mode'.")
46
47(defcustom describe-text-mode-hook nil
48 "List of hook functions ran by `describe-text-mode'."
49 :type 'hook
50 :group 'facemenu)
51
52(defun describe-text-mode ()
53 "Major mode for buffers created by `describe-char'.
54
55\\{describe-text-mode-map}
56Entry to this mode calls the value of `describe-text-mode-hook'
57if that value is non-nil."
58 (kill-all-local-variables)
59 (setq major-mode 'describe-text-mode
60 mode-name "Describe-Text")
61 (use-local-map describe-text-mode-map)
62 (widget-setup)
63 (add-hook 'change-major-mode-hook 'font-lock-defontify nil t)
64 (run-mode-hooks 'describe-text-mode-hook))
65
66;;; Describe-Text Utilities. 35;;; Describe-Text Utilities.
67 36
68(defun describe-text-widget (widget) 37(defun describe-text-widget (widget)
69 "Insert text to describe WIDGET in the current buffer." 38 "Insert text to describe WIDGET in the current buffer."
70 (widget-create 'link 39 (insert-text-button
71 :notify `(lambda (&rest ignore) 40 (symbol-name (if (symbolp widget) widget (car widget)))
72 (widget-browse ',widget)) 41 'action `(lambda (&rest ignore)
73 (format "%S" (if (symbolp widget) 42 (widget-browse ',widget)))
74 widget 43 (insert " ")
75 (car widget)))) 44 (insert-text-button "(widget)Top"
76 (widget-insert " ") 45 'action (lambda (&rest ignore) (info "(widget)Top"))
77 (widget-create 'info-link :tag "widget" "(widget)Top")) 46 'help-echo "mouse-2, RET: read this Info node"))
78 47
79(defun describe-text-sexp (sexp) 48(defun describe-text-sexp (sexp)
80 "Insert a short description of SEXP in the current buffer." 49 "Insert a short description of SEXP in the current buffer."
@@ -88,20 +57,19 @@ if that value is non-nil."
88 ((> (length pp) (- (window-width) (current-column))) 57 ((> (length pp) (- (window-width) (current-column)))
89 nil) 58 nil)
90 (t t)) 59 (t t))
91 (widget-insert pp) 60 (insert pp)
92 (widget-create 'push-button 61 (insert-text-button
93 :tag "show" 62 "show" 'action `(lambda (&rest ignore)
94 :action (lambda (widget &optional event) 63 (with-output-to-temp-buffer
95 (with-output-to-temp-buffer 64 "*Pp Eval Output*"
96 "*Pp Eval Output*" 65 (princ ',pp)))
97 (princ (widget-get widget :value)))) 66 'help-echo "mouse-2, RET: pretty print value in another buffer"))))
98 pp))))
99 67
100(defun describe-property-list (properties) 68(defun describe-property-list (properties)
101 "Insert a description of PROPERTIES in the current buffer. 69 "Insert a description of PROPERTIES in the current buffer.
102PROPERTIES should be a list of overlay or text properties. 70PROPERTIES should be a list of overlay or text properties.
103The `category', `face' and `font-lock-face' properties are made 71The `category', `face' and `font-lock-face' properties are made
104into widget buttons that call `describe-text-category' or 72into help buttons that call `describe-text-category' or
105`describe-face' when pushed." 73`describe-face' when pushed."
106 ;; Sort the properties by the size of their value. 74 ;; Sort the properties by the size of their value.
107 (dolist (elt (sort (let (ret) 75 (dolist (elt (sort (let (ret)
@@ -112,23 +80,21 @@ into widget buttons that call `describe-text-category' or
112 (prin1-to-string (nth 0 b) t))))) 80 (prin1-to-string (nth 0 b) t)))))
113 (let ((key (nth 0 elt)) 81 (let ((key (nth 0 elt))
114 (value (nth 1 elt))) 82 (value (nth 1 elt)))
115 (widget-insert (propertize (format " %-20s " key) 83 (insert (propertize (format " %-20s " key)
116 'font-lock-face 'italic)) 84 'face 'italic))
117 (cond ((eq key 'category) 85 (cond ((eq key 'category)
118 (widget-create 'link 86 (insert-text-button (symbol-name value)
119 :notify `(lambda (&rest ignore) 87 'action `(lambda (&rest ignore)
120 (describe-text-category ',value)) 88 (describe-text-category ',value))
121 (format "%S" value))) 89 'help-echo
90 "mouse-2, RET: describe this category"))
122 ((memq key '(face font-lock-face mouse-face)) 91 ((memq key '(face font-lock-face mouse-face))
123 (widget-create 'link 92 (insert (concat "`" (format "%S" value) "'")))
124 :notify `(lambda (&rest ignore)
125 (describe-face ',value))
126 (format "%S" value)))
127 ((widgetp value) 93 ((widgetp value)
128 (describe-text-widget value)) 94 (describe-text-widget value))
129 (t 95 (t
130 (describe-text-sexp value)))) 96 (describe-text-sexp value))))
131 (widget-insert "\n"))) 97 (insert "\n")))
132 98
133;;; Describe-Text Commands. 99;;; Describe-Text Commands.
134 100
@@ -138,9 +104,8 @@ into widget buttons that call `describe-text-category' or
138 (save-excursion 104 (save-excursion
139 (with-output-to-temp-buffer "*Help*" 105 (with-output-to-temp-buffer "*Help*"
140 (set-buffer standard-output) 106 (set-buffer standard-output)
141 (widget-insert "Category " (format "%S" category) ":\n\n") 107 (insert "Category " (format "%S" category) ":\n\n")
142 (describe-property-list (symbol-plist category)) 108 (describe-property-list (symbol-plist category))
143 (describe-text-mode)
144 (goto-char (point-min))))) 109 (goto-char (point-min)))))
145 110
146;;;###autoload 111;;;###autoload
@@ -165,10 +130,9 @@ otherwise."
165 (with-output-to-temp-buffer target-buffer 130 (with-output-to-temp-buffer target-buffer
166 (set-buffer standard-output) 131 (set-buffer standard-output)
167 (setq output-buffer (current-buffer)) 132 (setq output-buffer (current-buffer))
168 (widget-insert "Text content at position " (format "%d" pos) ":\n\n") 133 (insert "Text content at position " (format "%d" pos) ":\n\n")
169 (with-current-buffer buffer 134 (with-current-buffer buffer
170 (describe-text-properties-1 pos output-buffer)) 135 (describe-text-properties-1 pos output-buffer))
171 (describe-text-mode)
172 (goto-char (point-min)))))))) 136 (goto-char (point-min))))))))
173 137
174(defun describe-text-properties-1 (pos output-buffer) 138(defun describe-text-properties-1 (pos output-buffer)
@@ -186,33 +150,33 @@ otherwise."
186 ;; Widgets 150 ;; Widgets
187 (when (widgetp widget) 151 (when (widgetp widget)
188 (newline) 152 (newline)
189 (widget-insert (cond (wid-field "This is an editable text area") 153 (insert (cond (wid-field "This is an editable text area")
190 (wid-button "This is an active area") 154 (wid-button "This is an active area")
191 (wid-doc "This is documentation text"))) 155 (wid-doc "This is documentation text")))
192 (widget-insert " of a ") 156 (insert " of a ")
193 (describe-text-widget widget) 157 (describe-text-widget widget)
194 (widget-insert ".\n\n")) 158 (insert ".\n\n"))
195 ;; Buttons 159 ;; Buttons
196 (when (and button (not (widgetp wid-button))) 160 (when (and button (not (widgetp wid-button)))
197 (newline) 161 (newline)
198 (widget-insert "Here is a " (format "%S" button-type) 162 (insert "Here is a " (format "%S" button-type)
199 " button labeled `" button-label "'.\n\n")) 163 " button labeled `" button-label "'.\n\n"))
200 ;; Overlays 164 ;; Overlays
201 (when overlays 165 (when overlays
202 (newline) 166 (newline)
203 (if (eq (length overlays) 1) 167 (if (eq (length overlays) 1)
204 (widget-insert "There is an overlay here:\n") 168 (insert "There is an overlay here:\n")
205 (widget-insert "There are " (format "%d" (length overlays)) 169 (insert "There are " (format "%d" (length overlays))
206 " overlays here:\n")) 170 " overlays here:\n"))
207 (dolist (overlay overlays) 171 (dolist (overlay overlays)
208 (widget-insert " From " (format "%d" (overlay-start overlay)) 172 (insert " From " (format "%d" (overlay-start overlay))
209 " to " (format "%d" (overlay-end overlay)) "\n") 173 " to " (format "%d" (overlay-end overlay)) "\n")
210 (describe-property-list (overlay-properties overlay))) 174 (describe-property-list (overlay-properties overlay)))
211 (widget-insert "\n")) 175 (insert "\n"))
212 ;; Text properties 176 ;; Text properties
213 (when properties 177 (when properties
214 (newline) 178 (newline)
215 (widget-insert "There are text properties here:\n") 179 (insert "There are text properties here:\n")
216 (describe-property-list properties))))) 180 (describe-property-list properties)))))
217 181
218(defcustom describe-char-unicodedata-file nil 182(defcustom describe-char-unicodedata-file nil
@@ -223,8 +187,8 @@ looked up from it. This facility is mostly of use to people doing
223multilingual development. 187multilingual development.
224 188
225This is a fairly large file, not typically present on GNU systems. At 189This is a fairly large file, not typically present on GNU systems. At
226the time of writing it is at 190the time of writing it is at the URL
227<URL:http://www.unicode.org/Public/UNIDATA/UnicodeData.txt>." 191`http://www.unicode.org/Public/UNIDATA/UnicodeData.txt'."
228 :group 'mule 192 :group 'mule
229 :version "22.1" 193 :version "22.1"
230 :type '(choice (const :tag "None" nil) 194 :type '(choice (const :tag "None" nil)
@@ -488,27 +452,28 @@ as well as widgets, buttons, overlays, and text properties."
488 (format ", U+%04X" unicode) 452 (format ", U+%04X" unicode)
489 ""))) 453 "")))
490 ("charset" 454 ("charset"
491 ,`(widget-create 'link 455 ,`(insert-text-button
492 :notify (lambda (&rest ignore) 456 (symbol-name charset)
493 (describe-character-set ',charset)) 457 'action `(lambda (&rest ignore)
494 ,(symbol-name charset)) 458 (describe-character-set ',charset))
459 'help-echo
460 "mouse-2, RET: describe this character set")
495 ,(format "(%s)" (charset-description charset))) 461 ,(format "(%s)" (charset-description charset)))
496 ("code point" 462 ("code point"
497 ,(let ((split (split-char char))) 463 ,(let ((split (split-char char)))
498 `(widget-create 464 `(insert-text-button ,(if (= (charset-dimension charset) 1)
499 'link 465 (format "%d" (nth 1 split))
500 :notify (lambda (&rest ignore) 466 (format "%d %d" (nth 1 split)
501 (list-charset-chars ',charset) 467 (nth 2 split)))
502 (with-selected-window 468 'action (lambda (&rest ignore)
503 (get-buffer-window "*Character List*" 0) 469 (list-charset-chars ',charset)
504 (goto-char (point-min)) 470 (with-selected-window
471 (get-buffer-window "*Character List*" 0)
472 (goto-char (point-min))
505 (forward-line 2) ;Skip the header. 473 (forward-line 2) ;Skip the header.
506 (let ((case-fold-search nil)) 474 (let ((case-fold-search nil))
507 (search-forward ,(char-to-string char) 475 (search-forward ,(char-to-string char)
508 nil t)))) 476 nil t)))))))
509 ,(if (= (charset-dimension charset) 1)
510 (format "%d" (nth 1 split))
511 (format "%d %d" (nth 1 split) (nth 2 split))))))
512 ("syntax" 477 ("syntax"
513 ,(let ((syntax (syntax-after pos))) 478 ,(let ((syntax (syntax-after pos)))
514 (with-temp-buffer 479 (with-temp-buffer
@@ -537,12 +502,11 @@ as well as widgets, buttons, overlays, and text properties."
537 (mapconcat #'(lambda (x) (concat "\"" x "\"")) 502 (mapconcat #'(lambda (x) (concat "\"" x "\""))
538 key-list " or ") 503 key-list " or ")
539 "with" 504 "with"
540 `(widget-create 505 `(insert-text-button
541 'link 506 (symbol-name current-input-method)
542 :notify (lambda (&rest ignore) 507 'action (lambda (&rest ignore)
543 (describe-input-method 508 (describe-input-method
544 ',current-input-method)) 509 ',current-input-method)))))))
545 ,(format "%s" current-input-method))))))
546 ("buffer code" 510 ("buffer code"
547 ,(encoded-string-description 511 ,(encoded-string-description
548 (string-as-unibyte (char-to-string char)) nil)) 512 (string-as-unibyte (char-to-string char)) nil))
@@ -611,11 +575,8 @@ as well as widgets, buttons, overlays, and text properties."
611 ((and (< char 32) (not (memq char '(9 10)))) 575 ((and (< char 32) (not (memq char '(9 10))))
612 'escape-glyph))))) 576 'escape-glyph)))))
613 (if face (list (list "hardcoded face" 577 (if face (list (list "hardcoded face"
614 `(widget-create 578 '(insert
615 'link 579 (concat "`" (symbol-name face) "'"))))))
616 :notify (lambda (&rest ignore)
617 (describe-face ',face))
618 ,(format "%s" face))))))
619 ,@(let ((unicodedata (and unicode 580 ,@(let ((unicodedata (and unicode
620 (describe-char-unicode-data unicode)))) 581 (describe-char-unicode-data unicode))))
621 (if unicodedata 582 (if unicodedata
@@ -623,17 +584,16 @@ as well as widgets, buttons, overlays, and text properties."
623 (setq max-width (apply #'max (mapcar #'(lambda (x) 584 (setq max-width (apply #'max (mapcar #'(lambda (x)
624 (if (cadr x) (length (car x)) 0)) 585 (if (cadr x) (length (car x)) 0))
625 item-list))) 586 item-list)))
626 (with-output-to-temp-buffer "*Help*" 587 (help-setup-xref nil (interactive-p))
588 (with-output-to-temp-buffer (help-buffer)
627 (with-current-buffer standard-output 589 (with-current-buffer standard-output
628 (let ((help-xref-following t))
629 (help-setup-xref nil nil))
630 (set-buffer-multibyte multibyte-p) 590 (set-buffer-multibyte multibyte-p)
631 (let ((formatter (format "%%%ds:" max-width))) 591 (let ((formatter (format "%%%ds:" max-width)))
632 (dolist (elt item-list) 592 (dolist (elt item-list)
633 (when (cadr elt) 593 (when (cadr elt)
634 (insert (format formatter (car elt))) 594 (insert (format formatter (car elt)))
635 (dolist (clm (cdr elt)) 595 (dolist (clm (cdr elt))
636 (if (eq (car-safe clm) 'widget-create) 596 (if (eq (car-safe clm) 'insert-text-button)
637 (progn (insert " ") (eval clm)) 597 (progn (insert " ") (eval clm))
638 (when (>= (+ (current-column) 598 (when (>= (+ (current-column)
639 (or (string-match "\n" clm) 599 (or (string-match "\n" clm)
@@ -673,17 +633,15 @@ as well as widgets, buttons, overlays, and text properties."
673 "\n") 633 "\n")
674 (when (> (car (aref disp-vector i)) #x7ffff) 634 (when (> (car (aref disp-vector i)) #x7ffff)
675 (let* ((face-id (lsh (car (aref disp-vector i)) -19)) 635 (let* ((face-id (lsh (car (aref disp-vector i)) -19))
676 (face (car (delq nil (mapcar (lambda (face) 636 (face (car (delq nil (mapcar
677 (and (eq (face-id face) 637 (lambda (face)
678 face-id) face)) 638 (and (eq (face-id face)
679 (face-list)))))) 639 face-id) face))
640 (face-list))))))
680 (when face 641 (when face
681 (insert (propertize " " 'display '(space :align-to 5)) 642 (insert (propertize " " 'display '(space :align-to 5))
682 "face: ") 643 "face: ")
683 (widget-create 'link 644 (insert (concat "`" (symbol-name face) "'"))
684 :notify `(lambda (&rest ignore)
685 (describe-face ',face))
686 (format "%S" face))
687 (insert "\n")))))) 645 (insert "\n"))))))
688 (insert "these terminal codes:\n") 646 (insert "these terminal codes:\n")
689 (dotimes (i (length disp-vector)) 647 (dotimes (i (length disp-vector))
@@ -729,9 +687,7 @@ as well as widgets, buttons, overlays, and text properties."
729 "the meaning of the rule.\n")) 687 "the meaning of the rule.\n"))
730 688
731 (if text-props-desc (insert text-props-desc)) 689 (if text-props-desc (insert text-props-desc))
732 (describe-text-mode)
733 (toggle-read-only 1) 690 (toggle-read-only 1)
734 (help-make-xrefs (current-buffer))
735 (print-help-return-message))))) 691 (print-help-return-message)))))
736 692
737(defalias 'describe-char-after 'describe-char) 693(defalias 'describe-char-after 'describe-char)
diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el
index 9290ede2bdf..beb88cfea25 100644
--- a/lisp/emacs-lisp/edebug.el
+++ b/lisp/emacs-lisp/edebug.el
@@ -570,6 +570,7 @@ already is one.)"
570;; Compatibility with old versions. 570;; Compatibility with old versions.
571(defalias 'edebug-all-defuns 'edebug-all-defs) 571(defalias 'edebug-all-defuns 'edebug-all-defs)
572 572
573;;;###autoload
573(defun edebug-all-defs () 574(defun edebug-all-defs ()
574 "Toggle edebugging of all definitions." 575 "Toggle edebugging of all definitions."
575 (interactive) 576 (interactive)
@@ -578,6 +579,7 @@ already is one.)"
578 (if edebug-all-defs "on" "off"))) 579 (if edebug-all-defs "on" "off")))
579 580
580 581
582;;;###autoload
581(defun edebug-all-forms () 583(defun edebug-all-forms ()
582 "Toggle edebugging of all forms." 584 "Toggle edebugging of all forms."
583 (interactive) 585 (interactive)
@@ -2516,6 +2518,7 @@ MSG is printed after `::::} '."
2516(defvar edebug-outside-o-a-p) ; outside overlay-arrow-position 2518(defvar edebug-outside-o-a-p) ; outside overlay-arrow-position
2517(defvar edebug-outside-o-a-s) ; outside overlay-arrow-string 2519(defvar edebug-outside-o-a-s) ; outside overlay-arrow-string
2518(defvar edebug-outside-c-i-e-a) ; outside cursor-in-echo-area 2520(defvar edebug-outside-c-i-e-a) ; outside cursor-in-echo-area
2521(defvar edebug-outside-d-c-i-n-s-w) ; outside default-cursor-in-non-selected-windows
2519 2522
2520(defvar edebug-eval-list nil) ;; List of expressions to evaluate. 2523(defvar edebug-eval-list nil) ;; List of expressions to evaluate.
2521 2524
@@ -2557,11 +2560,13 @@ MSG is printed after `::::} '."
2557 2560
2558 (edebug-outside-o-a-p overlay-arrow-position) 2561 (edebug-outside-o-a-p overlay-arrow-position)
2559 (edebug-outside-o-a-s overlay-arrow-string) 2562 (edebug-outside-o-a-s overlay-arrow-string)
2560 (edebug-outside-c-i-e-a cursor-in-echo-area)) 2563 (edebug-outside-c-i-e-a cursor-in-echo-area)
2564 (edebug-outside-d-c-i-n-s-w default-cursor-in-non-selected-windows))
2561 (unwind-protect 2565 (unwind-protect
2562 (let ((overlay-arrow-position overlay-arrow-position) 2566 (let ((overlay-arrow-position overlay-arrow-position)
2563 (overlay-arrow-string overlay-arrow-string) 2567 (overlay-arrow-string overlay-arrow-string)
2564 (cursor-in-echo-area nil) 2568 (cursor-in-echo-area nil)
2569 (default-cursor-in-non-selected-windows t)
2565 ;; any others?? 2570 ;; any others??
2566 ) 2571 )
2567 (if (not (buffer-name edebug-buffer)) 2572 (if (not (buffer-name edebug-buffer))
@@ -2767,7 +2772,8 @@ MSG is printed after `::::} '."
2767 (setq 2772 (setq
2768 overlay-arrow-position edebug-outside-o-a-p 2773 overlay-arrow-position edebug-outside-o-a-p
2769 overlay-arrow-string edebug-outside-o-a-s 2774 overlay-arrow-string edebug-outside-o-a-s
2770 cursor-in-echo-area edebug-outside-c-i-e-a) 2775 cursor-in-echo-area edebug-outside-c-i-e-a
2776 default-cursor-in-non-selected-windows edebug-outside-d-c-i-n-s-w)
2771 ))) 2777 )))
2772 2778
2773 2779
@@ -3580,6 +3586,7 @@ Return the result of the last expression."
3580 (overlay-arrow-position edebug-outside-o-a-p) 3586 (overlay-arrow-position edebug-outside-o-a-p)
3581 (overlay-arrow-string edebug-outside-o-a-s) 3587 (overlay-arrow-string edebug-outside-o-a-s)
3582 (cursor-in-echo-area edebug-outside-c-i-e-a) 3588 (cursor-in-echo-area edebug-outside-c-i-e-a)
3589 (default-cursor-in-non-selected-windows edebug-outside-d-c-i-n-s-w)
3583 ) 3590 )
3584 (unwind-protect 3591 (unwind-protect
3585 (save-excursion ; of edebug-buffer 3592 (save-excursion ; of edebug-buffer
@@ -3618,6 +3625,7 @@ Return the result of the last expression."
3618 edebug-outside-o-a-p overlay-arrow-position 3625 edebug-outside-o-a-p overlay-arrow-position
3619 edebug-outside-o-a-s overlay-arrow-string 3626 edebug-outside-o-a-s overlay-arrow-string
3620 edebug-outside-c-i-e-a cursor-in-echo-area 3627 edebug-outside-c-i-e-a cursor-in-echo-area
3628 edebug-outside-d-c-i-n-s-w default-cursor-in-non-selected-windows
3621 ) 3629 )
3622 3630
3623 ;; Restore the outside saved values; don't alter 3631 ;; Restore the outside saved values; don't alter
@@ -3897,7 +3905,7 @@ buffer) there are local and global key bindings to several Edebug
3897specific commands. E.g. `edebug-step-mode' is bound to \\[edebug-step-mode] 3905specific commands. E.g. `edebug-step-mode' is bound to \\[edebug-step-mode]
3898in the Edebug buffer and \\<global-map>\\[edebug-step-mode] in any buffer. 3906in the Edebug buffer and \\<global-map>\\[edebug-step-mode] in any buffer.
3899 3907
3900Also see bindings for the eval list buffer, *edebug*. 3908Also see bindings for the eval list buffer *edebug* in `edebug-eval-mode'.
3901 3909
3902The edebug buffer commands: 3910The edebug buffer commands:
3903\\{edebug-mode-map} 3911\\{edebug-mode-map}
@@ -4054,7 +4062,7 @@ buffer and \\<global-map>\\[edebug-step-mode] in any buffer.
4054Eval list buffer commands: 4062Eval list buffer commands:
4055\\{edebug-eval-mode-map} 4063\\{edebug-eval-mode-map}
4056 4064
4057Global commands prefixed by global-edebug-prefix: 4065Global commands prefixed by `global-edebug-prefix':
4058\\{global-edebug-map}") 4066\\{global-edebug-map}")
4059 4067
4060;;; Interface with standard debugger. 4068;;; Interface with standard debugger.
diff --git a/lisp/emacs-lisp/lisp.el b/lisp/emacs-lisp/lisp.el
index 7aeb33a648e..30505c95223 100644
--- a/lisp/emacs-lisp/lisp.el
+++ b/lisp/emacs-lisp/lisp.el
@@ -569,28 +569,37 @@ considered."
569 ((null completion) 569 ((null completion)
570 (message "Can't find completion for \"%s\"" pattern) 570 (message "Can't find completion for \"%s\"" pattern)
571 (ding)) 571 (ding))
572 ((not (string= pattern completion))
573 (delete-region beg end)
574 (insert completion)
575 ;; Don't leave around a completions buffer that's out of date.
576 (let ((win (get-buffer-window "*Completions*" 0)))
577 (if win (with-selected-window win (bury-buffer)))))
572 (t 578 (t
573 (unless (string= completion pattern) 579 (let ((minibuf-is-in-use
574 (delete-region beg end) 580 (eq (minibuffer-window) (selected-window))))
575 (insert completion) 581 (unless minibuf-is-in-use
576 (setq pattern completion)) 582 (message "Making completion list..."))
577 (message "Making completion list...") 583 (let ((list (all-completions pattern obarray predicate)))
578 (let ((list (all-completions pattern obarray predicate))) 584 (setq list (sort list 'string<))
579 (setq list (sort list 'string<)) 585 (or (eq predicate 'fboundp)
580 (or (eq predicate 'fboundp) 586 (let (new)
581 (let (new) 587 (while list
582 (while list 588 (setq new (cons (if (fboundp (intern (car list)))
583 (setq new (cons (if (fboundp (intern (car list))) 589 (list (car list) " <f>")
584 (list (car list) " <f>") 590 (car list))
585 (car list)) 591 new))
586 new)) 592 (setq list (cdr list)))
587 (setq list (cdr list))) 593 (setq list (nreverse new))))
588 (setq list (nreverse new)))) 594 (if (> (length list) 1)
589 (if (> (length list) 1) 595 (with-output-to-temp-buffer "*Completions*"
590 (with-output-to-temp-buffer "*Completions*" 596 (display-completion-list list pattern))
591 (display-completion-list list pattern)) 597 ;; Don't leave around a completions buffer that's
592 (delete-windows-on "*Completions*"))) 598 ;; out of date.
593 (message "Making completion list...%s" "done"))))))) 599 (let ((win (get-buffer-window "*Completions*" 0)))
594 600 (if win (with-selected-window win (bury-buffer))))))
595;;; arch-tag: aa7fa8a4-2e6f-4e9b-9cd9-fef06340e67e 601 (unless minibuf-is-in-use
602 (message "Making completion list...%s" "done")))))))))
603
604;; arch-tag: aa7fa8a4-2e6f-4e9b-9cd9-fef06340e67e
596;;; lisp.el ends here 605;;; lisp.el ends here
diff --git a/lisp/font-lock.el b/lisp/font-lock.el
index 49e576e59db..de366997a93 100644
--- a/lisp/font-lock.el
+++ b/lisp/font-lock.el
@@ -153,8 +153,8 @@
153;; 153;;
154;; (add-hook 'foo-mode-hook 154;; (add-hook 'foo-mode-hook
155;; (lambda () 155;; (lambda ()
156;; (make-local-variable 'font-lock-defaults) 156;; (set (make-local-variable 'font-lock-defaults)
157;; (setq font-lock-defaults '(foo-font-lock-keywords t)))) 157;; '(foo-font-lock-keywords t))))
158 158
159;;; Adding Font Lock support for modes: 159;;; Adding Font Lock support for modes:
160 160
@@ -174,8 +174,8 @@
174;; 174;;
175;; and within `bar-mode' there could be: 175;; and within `bar-mode' there could be:
176;; 176;;
177;; (make-local-variable 'font-lock-defaults) 177;; (set (make-local-variable 'font-lock-defaults)
178;; (setq font-lock-defaults '(bar-font-lock-keywords nil t)) 178;; '(bar-font-lock-keywords nil t))
179 179
180;; What is fontification for? You might say, "It's to make my code look nice." 180;; What is fontification for? You might say, "It's to make my code look nice."
181;; I think it should be for adding information in the form of cues. These cues 181;; I think it should be for adding information in the form of cues. These cues
@@ -723,8 +723,8 @@ see the variables `c-font-lock-extra-types', `c++-font-lock-extra-types',
723 (append keywords old))))) 723 (append keywords old)))))
724 ;; If the keywords were compiled before, compile them again. 724 ;; If the keywords were compiled before, compile them again.
725 (if was-compiled 725 (if was-compiled
726 (set (make-local-variable 'font-lock-keywords) 726 (setq font-lock-keywords
727 (font-lock-compile-keywords font-lock-keywords t))))))) 727 (font-lock-compile-keywords font-lock-keywords t)))))))
728 728
729(defun font-lock-update-removed-keyword-alist (mode keywords how) 729(defun font-lock-update-removed-keyword-alist (mode keywords how)
730 "Update `font-lock-removed-keywords-alist' when adding new KEYWORDS to MODE." 730 "Update `font-lock-removed-keywords-alist' when adding new KEYWORDS to MODE."
@@ -830,8 +830,8 @@ happens, so the major mode can be corrected."
830 830
831 ;; If the keywords were compiled before, compile them again. 831 ;; If the keywords were compiled before, compile them again.
832 (if was-compiled 832 (if was-compiled
833 (set (make-local-variable 'font-lock-keywords) 833 (setq font-lock-keywords
834 (font-lock-compile-keywords font-lock-keywords t))))))) 834 (font-lock-compile-keywords font-lock-keywords t)))))))
835 835
836;;; Font Lock Support mode. 836;;; Font Lock Support mode.
837 837
@@ -1001,8 +1001,7 @@ The value of this variable is used when Font Lock mode is turned on."
1001 (when verbose 1001 (when verbose
1002 (format "Fontifying %s..." (buffer-name))) 1002 (format "Fontifying %s..." (buffer-name)))
1003 ;; Make sure we have the right `font-lock-keywords' etc. 1003 ;; Make sure we have the right `font-lock-keywords' etc.
1004 (unless font-lock-mode 1004 (font-lock-set-defaults)
1005 (font-lock-set-defaults))
1006 ;; Make sure we fontify etc. in the whole buffer. 1005 ;; Make sure we fontify etc. in the whole buffer.
1007 (save-restriction 1006 (save-restriction
1008 (widen) 1007 (widen)
@@ -1574,9 +1573,9 @@ A LEVEL of nil is equal to a LEVEL of 0, a LEVEL of t is equal to
1574 (cond ((not (and (listp keywords) (symbolp (car keywords)))) 1573 (cond ((not (and (listp keywords) (symbolp (car keywords))))
1575 keywords) 1574 keywords)
1576 ((numberp level) 1575 ((numberp level)
1577 (or (nth level keywords) (car (reverse keywords)))) 1576 (or (nth level keywords) (car (last keywords))))
1578 ((eq level t) 1577 ((eq level t)
1579 (car (reverse keywords))) 1578 (car (last keywords)))
1580 (t 1579 (t
1581 (car keywords)))) 1580 (car keywords))))
1582 1581
@@ -1642,8 +1641,8 @@ Sets various variables using `font-lock-defaults' (or, if nil, using
1642 (font-lock-remove-keywords nil removed-keywords)) 1641 (font-lock-remove-keywords nil removed-keywords))
1643 ;; Now compile the keywords. 1642 ;; Now compile the keywords.
1644 (unless (eq (car font-lock-keywords) t) 1643 (unless (eq (car font-lock-keywords) t)
1645 (set (make-local-variable 'font-lock-keywords) 1644 (setq font-lock-keywords
1646 (font-lock-compile-keywords font-lock-keywords t)))))) 1645 (font-lock-compile-keywords font-lock-keywords t))))))
1647 1646
1648;;; Colour etc. support. 1647;;; Colour etc. support.
1649 1648
diff --git a/lisp/hi-lock.el b/lisp/hi-lock.el
index c3e2d814767..956ae3a6798 100644
--- a/lisp/hi-lock.el
+++ b/lisp/hi-lock.el
@@ -97,6 +97,16 @@ of functions `hi-lock-mode' and `hi-lock-find-patterns'."
97 :type 'integer 97 :type 'integer
98 :group 'hi-lock) 98 :group 'hi-lock)
99 99
100(defcustom hi-lock-highlight-range 200000
101 "Size of area highlighted by hi-lock when font-lock not active.
102Font-lock is not active in buffers that do their own highlighting,
103such as the buffer created by `list-colors-display'. In those buffers
104hi-lock patterns will only be applied over a range of
105`hi-lock-highlight-range' characters. If font-lock is active then
106highlighting will be applied throughout the buffer."
107 :type 'integer
108 :group 'hi-lock)
109
100(defcustom hi-lock-exclude-modes 110(defcustom hi-lock-exclude-modes
101 '(rmail-mode mime/viewer-mode gnus-article-mode) 111 '(rmail-mode mime/viewer-mode gnus-article-mode)
102 "List of major modes in which hi-lock will not run. 112 "List of major modes in which hi-lock will not run.
@@ -189,14 +199,14 @@ calls."
189 "Regexp for finding hi-lock patterns at top of file.") 199 "Regexp for finding hi-lock patterns at top of file.")
190 200
191(defvar hi-lock-archaic-interface-message-used nil 201(defvar hi-lock-archaic-interface-message-used nil
192 "True if user alerted that global-hi-lock-mode is now the global switch. 202 "True if user alerted that `global-hi-lock-mode' is now the global switch.
193Earlier versions of hi-lock used hi-lock-mode as the global switch, 203Earlier versions of hi-lock used `hi-lock-mode' as the global switch,
194the message is issued if it appears that hi-lock-mode is used assuming 204the message is issued if it appears that `hi-lock-mode' is used assuming
195that older functionality. This variable avoids multiple reminders.") 205that older functionality. This variable avoids multiple reminders.")
196 206
197(defvar hi-lock-archaic-interface-deduce nil 207(defvar hi-lock-archaic-interface-deduce nil
198 "If non-nil, sometimes assume that hi-lock-mode means global-hi-lock-mode. 208 "If non-nil, sometimes assume that `hi-lock-mode' means `global-hi-lock-mode'.
199Assumption is made if hi-lock-mode used in the *scratch* buffer while 209Assumption is made if `hi-lock-mode' used in the *scratch* buffer while
200a library is being loaded.") 210a library is being loaded.")
201 211
202(make-variable-buffer-local 'hi-lock-interactive-patterns) 212(make-variable-buffer-local 'hi-lock-interactive-patterns)
@@ -247,14 +257,13 @@ a library is being loaded.")
247 257
248;; Visible Functions 258;; Visible Functions
249 259
250
251;;;###autoload 260;;;###autoload
252(define-minor-mode hi-lock-mode 261(define-minor-mode hi-lock-mode
253 "Toggle minor mode for interactively adding font-lock highlighting patterns. 262 "Toggle minor mode for interactively adding font-lock highlighting patterns.
254 263
255If ARG positive turn hi-lock on. Issuing a hi-lock command will also 264If ARG positive, turn hi-lock on. Issuing a hi-lock command will also
256turn hi-lock on; to turn hi-lock on in all buffers use 265turn hi-lock on. To turn hi-lock on in all buffers use
257global-hi-lock-mode or in your .emacs file (global-hi-lock-mode 1). 266`global-hi-lock-mode' or in your .emacs file (global-hi-lock-mode 1).
258When hi-lock is turned on, a \"Regexp Highlighting\" submenu is added 267When hi-lock is turned on, a \"Regexp Highlighting\" submenu is added
259to the \"Edit\" menu. The commands in the submenu, which can be 268to the \"Edit\" menu. The commands in the submenu, which can be
260called interactively, are: 269called interactively, are:
@@ -293,7 +302,9 @@ will be read until
293 Hi-lock: end 302 Hi-lock: end
294is found. A mode is excluded if it's in the list `hi-lock-exclude-modes'." 303is found. A mode is excluded if it's in the list `hi-lock-exclude-modes'."
295 :group 'hi-lock 304 :group 'hi-lock
296 :lighter " H" 305 :lighter (:eval (if (or hi-lock-interactive-patterns
306 hi-lock-file-patterns)
307 " Hi" ""))
297 :global nil 308 :global nil
298 :keymap hi-lock-map 309 :keymap hi-lock-map
299 (when (and (equal (buffer-name) "*scratch*") 310 (when (and (equal (buffer-name) "*scratch*")
@@ -306,7 +317,7 @@ is found. A mode is excluded if it's in the list `hi-lock-exclude-modes'."
306 (warn 317 (warn
307 "Possible archaic use of (hi-lock-mode). 318 "Possible archaic use of (hi-lock-mode).
308Use (global-hi-lock-mode 1) in .emacs to enable hi-lock for all buffers, 319Use (global-hi-lock-mode 1) in .emacs to enable hi-lock for all buffers,
309use (hi-lock-mode 1) for individual buffers. For compatibility with Emacs 320use (hi-lock-mode 1) for individual buffers. For compatibility with Emacs
310versions before 22 use the following in your .emacs file: 321versions before 22 use the following in your .emacs file:
311 322
312 (if (functionp 'global-hi-lock-mode) 323 (if (functionp 'global-hi-lock-mode)
@@ -330,8 +341,8 @@ versions before 22 use the following in your .emacs file:
330 (when hi-lock-file-patterns 341 (when hi-lock-file-patterns
331 (font-lock-remove-keywords nil hi-lock-file-patterns) 342 (font-lock-remove-keywords nil hi-lock-file-patterns)
332 (setq hi-lock-file-patterns nil)) 343 (setq hi-lock-file-patterns nil))
333 (if font-lock-mode 344 (remove-overlays nil nil 'hi-lock-overlay t)
334 (font-lock-fontify-buffer))) 345 (when font-lock-fontified (font-lock-fontify-buffer)))
335 (define-key-after menu-bar-edit-menu [hi-lock] nil) 346 (define-key-after menu-bar-edit-menu [hi-lock] nil)
336 (remove-hook 'font-lock-mode-hook 'hi-lock-font-lock-hook t))) 347 (remove-hook 'font-lock-mode-hook 'hi-lock-font-lock-hook t)))
337 348
@@ -461,7 +472,9 @@ interactive functions. \(See `hi-lock-interactive-patterns'.\)
461 (font-lock-remove-keywords nil (list keyword)) 472 (font-lock-remove-keywords nil (list keyword))
462 (setq hi-lock-interactive-patterns 473 (setq hi-lock-interactive-patterns
463 (delq keyword hi-lock-interactive-patterns)) 474 (delq keyword hi-lock-interactive-patterns))
464 (font-lock-fontify-buffer)))) 475 (remove-overlays
476 nil nil 'hi-lock-overlay-regexp (hi-lock-string-serialize regexp))
477 (when font-lock-fontified (font-lock-fontify-buffer)))))
465 478
466;;;###autoload 479;;;###autoload
467(defun hi-lock-write-interactive-patterns () 480(defun hi-lock-write-interactive-patterns ()
@@ -476,7 +489,9 @@ be found in variable `hi-lock-interactive-patterns'."
476 (let ((beg (point))) 489 (let ((beg (point)))
477 (mapcar 490 (mapcar
478 (lambda (pattern) 491 (lambda (pattern)
479 (insert (format "Hi-lock: (%s)\n" (prin1-to-string pattern)))) 492 (insert (format "%s: (%s)\n"
493 hi-lock-file-patterns-prefix
494 (prin1-to-string pattern))))
480 hi-lock-interactive-patterns) 495 hi-lock-interactive-patterns)
481 (comment-region beg (point))) 496 (comment-region beg (point)))
482 (when (> (point) hi-lock-file-patterns-range) 497 (when (> (point) hi-lock-file-patterns-range)
@@ -526,25 +541,34 @@ not suitable."
526 "Highlight REGEXP with face FACE." 541 "Highlight REGEXP with face FACE."
527 (let ((pattern (list regexp (list 0 (list 'quote face) t)))) 542 (let ((pattern (list regexp (list 0 (list 'quote face) t))))
528 (unless (member pattern hi-lock-interactive-patterns) 543 (unless (member pattern hi-lock-interactive-patterns)
529 (font-lock-add-keywords nil (list pattern)) 544 (font-lock-add-keywords nil (list pattern) t)
530 (push pattern hi-lock-interactive-patterns) 545 (push pattern hi-lock-interactive-patterns)
531 (let ((buffer-undo-list t) 546 (if font-lock-fontified
532 (inhibit-read-only t) 547 (font-lock-fontify-buffer)
533 (mod (buffer-modified-p))) 548 (let* ((serial (hi-lock-string-serialize regexp))
534 (save-excursion 549 (range-min (- (point) (/ hi-lock-highlight-range 2)))
535 (goto-char (point-min)) 550 (range-max (+ (point) (/ hi-lock-highlight-range 2)))
536 (while (re-search-forward regexp (point-max) t) 551 (search-start
537 (put-text-property 552 (max (point-min)
538 (match-beginning 0) (match-end 0) 'face face) 553 (- range-min (max 0 (- range-max (point-max))))))
539 (goto-char (match-end 0)))) 554 (search-end
540 (set-buffer-modified-p mod))))) 555 (min (point-max)
556 (+ range-max (max 0 (- (point-min) range-min))))))
557 (save-excursion
558 (goto-char search-start)
559 (while (re-search-forward regexp search-end t)
560 (let ((overlay (make-overlay (match-beginning 0) (match-end 0))))
561 (overlay-put overlay 'hi-lock-overlay t)
562 (overlay-put overlay 'hi-lock-overlay-regexp serial)
563 (overlay-put overlay 'face face))
564 (goto-char (match-end 0)))))))))
541 565
542(defun hi-lock-set-file-patterns (patterns) 566(defun hi-lock-set-file-patterns (patterns)
543 "Replace file patterns list with PATTERNS and refontify." 567 "Replace file patterns list with PATTERNS and refontify."
544 (when (or hi-lock-file-patterns patterns) 568 (when (or hi-lock-file-patterns patterns)
545 (font-lock-remove-keywords nil hi-lock-file-patterns) 569 (font-lock-remove-keywords nil hi-lock-file-patterns)
546 (setq hi-lock-file-patterns patterns) 570 (setq hi-lock-file-patterns patterns)
547 (font-lock-add-keywords nil hi-lock-file-patterns) 571 (font-lock-add-keywords nil hi-lock-file-patterns t)
548 (font-lock-fontify-buffer))) 572 (font-lock-fontify-buffer)))
549 573
550(defun hi-lock-find-patterns () 574(defun hi-lock-find-patterns ()
@@ -573,10 +597,31 @@ not suitable."
573(defun hi-lock-font-lock-hook () 597(defun hi-lock-font-lock-hook ()
574 "Add hi lock patterns to font-lock's." 598 "Add hi lock patterns to font-lock's."
575 (if font-lock-mode 599 (if font-lock-mode
576 (progn (font-lock-add-keywords nil hi-lock-file-patterns) 600 (progn
577 (font-lock-add-keywords nil hi-lock-interactive-patterns)) 601 (font-lock-add-keywords nil hi-lock-file-patterns t)
602 (font-lock-add-keywords nil hi-lock-interactive-patterns t))
578 (hi-lock-mode -1))) 603 (hi-lock-mode -1)))
579 604
605(defvar hi-lock-string-serialize-hash
606 (make-hash-table :test 'equal)
607 "Hash table used to assign unique numbers to strings.")
608
609(defvar hi-lock-string-serialize-serial 1
610 "Number assigned to last new string in call to `hi-lock-string-serialize'.
611A string is considered new if it had not previously been used in a call to
612`hi-lock-string-serialize'.")
613
614(defun hi-lock-string-serialize (string)
615 "Return unique serial number for STRING."
616 (interactive)
617 (let ((val (gethash string hi-lock-string-serialize-hash)))
618 (if val val
619 (puthash string
620 (setq hi-lock-string-serialize-serial
621 (1+ hi-lock-string-serialize-serial))
622 hi-lock-string-serialize-hash)
623 hi-lock-string-serialize-serial)))
624
580(provide 'hi-lock) 625(provide 'hi-lock)
581 626
582;; arch-tag: d2e8fd07-4cc9-4c6f-a200-1e729bc54066 627;; arch-tag: d2e8fd07-4cc9-4c6f-a200-1e729bc54066
diff --git a/lisp/info.el b/lisp/info.el
index 79a8a5d0a30..e3ca18e0ede 100644
--- a/lisp/info.el
+++ b/lisp/info.el
@@ -521,22 +521,22 @@ Do the right thing if the file has been compressed or zipped."
521 (Info-default-dirs))))))) 521 (Info-default-dirs)))))))
522 522
523;;;###autoload 523;;;###autoload
524(defun info-other-window (&optional file) 524(defun info-other-window (&optional file-or-node)
525 "Like `info' but show the Info buffer in another window." 525 "Like `info' but show the Info buffer in another window."
526 (interactive (if current-prefix-arg 526 (interactive (if current-prefix-arg
527 (list (read-file-name "Info file name: " nil nil t)))) 527 (list (read-file-name "Info file name: " nil nil t))))
528 (let (same-window-buffer-names same-window-regexps) 528 (let (same-window-buffer-names same-window-regexps)
529 (info file))) 529 (info file-or-node)))
530 530
531;;;###autoload (add-hook 'same-window-regexps "\\*info\\*\\(\\|<[0-9]+>\\)") 531;;;###autoload (add-hook 'same-window-regexps "\\*info\\*\\(\\|<[0-9]+>\\)")
532 532
533;;;###autoload (put 'info 'info-file "emacs") 533;;;###autoload (put 'info 'info-file "emacs")
534;;;###autoload 534;;;###autoload
535(defun info (&optional file buffer) 535(defun info (&optional file-or-node buffer)
536 "Enter Info, the documentation browser. 536 "Enter Info, the documentation browser.
537Optional argument FILE specifies the file to examine; 537Optional argument FILE-OR-NODE specifies the file to examine;
538the default is the top-level directory of Info. 538the default is the top-level directory of Info.
539Called from a program, FILE may specify an Info node of the form 539Called from a program, FILE-OR-NODE may specify an Info node of the form
540`(FILENAME)NODENAME'. 540`(FILENAME)NODENAME'.
541Optional argument BUFFER specifies the Info buffer name; 541Optional argument BUFFER specifies the Info buffer name;
542the default buffer name is *info*. If BUFFER exists, 542the default buffer name is *info*. If BUFFER exists,
@@ -559,15 +559,15 @@ in all the directories in that path."
559 (pop-to-buffer (or buffer "*info*")) 559 (pop-to-buffer (or buffer "*info*"))
560 (if (and buffer (not (eq major-mode 'Info-mode))) 560 (if (and buffer (not (eq major-mode 'Info-mode)))
561 (Info-mode)) 561 (Info-mode))
562 (if file 562 (if file-or-node
563 ;; If argument already contains parentheses, don't add another set 563 ;; If argument already contains parentheses, don't add another set
564 ;; since the argument will then be parsed improperly. This also 564 ;; since the argument will then be parsed improperly. This also
565 ;; has the added benefit of allowing node names to be included 565 ;; has the added benefit of allowing node names to be included
566 ;; following the parenthesized filename. 566 ;; following the parenthesized filename.
567 (Info-goto-node 567 (Info-goto-node
568 (if (and (stringp file) (string-match "(.*)" file)) 568 (if (and (stringp file-or-node) (string-match "(.*)" file-or-node))
569 file 569 file-or-node
570 (concat "(" file ")"))) 570 (concat "(" file-or-node ")")))
571 (if (zerop (buffer-size)) 571 (if (zerop (buffer-size))
572 (Info-directory)))) 572 (Info-directory))))
573 573
@@ -2260,7 +2260,8 @@ Because of ambiguities, this should be concatenated with something like
2260 (let ((pattern (concat "\n\\* +\\(" 2260 (let ((pattern (concat "\n\\* +\\("
2261 (regexp-quote string) 2261 (regexp-quote string)
2262 Info-menu-entry-name-re "\\):" Info-node-spec-re)) 2262 Info-menu-entry-name-re "\\):" Info-node-spec-re))
2263 completions) 2263 completions
2264 (complete-nodes Info-complete-nodes))
2264 ;; Check the cache. 2265 ;; Check the cache.
2265 (if (and (equal (nth 0 Info-complete-cache) Info-current-file) 2266 (if (and (equal (nth 0 Info-complete-cache) Info-current-file)
2266 (equal (nth 1 Info-complete-cache) Info-current-node) 2267 (equal (nth 1 Info-complete-cache) Info-current-node)
@@ -2281,9 +2282,9 @@ Because of ambiguities, this should be concatenated with something like
2281 (or (and Info-complete-next-re 2282 (or (and Info-complete-next-re
2282 (setq nextnode (Info-extract-pointer "next" t)) 2283 (setq nextnode (Info-extract-pointer "next" t))
2283 (string-match Info-complete-next-re nextnode)) 2284 (string-match Info-complete-next-re nextnode))
2284 (and Info-complete-nodes 2285 (and complete-nodes
2285 (setq Info-complete-nodes (cdr Info-complete-nodes) 2286 (setq complete-nodes (cdr complete-nodes)
2286 nextnode (car Info-complete-nodes))))) 2287 nextnode (car complete-nodes)))))
2287 (Info-goto-node nextnode)) 2288 (Info-goto-node nextnode))
2288 ;; Go back to the start node (for the next completion). 2289 ;; Go back to the start node (for the next completion).
2289 (unless (equal Info-current-node orignode) 2290 (unless (equal Info-current-node orignode)
@@ -3192,8 +3193,8 @@ if point is in a menu item description, follow that menu item."
3192 (tool-bar-local-item-from-menu 'Info-next "next-node" map Info-mode-map) 3193 (tool-bar-local-item-from-menu 'Info-next "next-node" map Info-mode-map)
3193 (tool-bar-local-item-from-menu 'Info-up "up-node" map Info-mode-map) 3194 (tool-bar-local-item-from-menu 'Info-up "up-node" map Info-mode-map)
3194 (tool-bar-local-item-from-menu 'Info-top-node "home" map Info-mode-map) 3195 (tool-bar-local-item-from-menu 'Info-top-node "home" map Info-mode-map)
3195 (tool-bar-local-item-from-menu 'Info-index "index" map Info-mode-map)
3196 (tool-bar-local-item-from-menu 'Info-goto-node "jump-to" map Info-mode-map) 3196 (tool-bar-local-item-from-menu 'Info-goto-node "jump-to" map Info-mode-map)
3197 (tool-bar-local-item-from-menu 'Info-index "index" map Info-mode-map)
3197 (tool-bar-local-item-from-menu 'Info-search "search" map Info-mode-map) 3198 (tool-bar-local-item-from-menu 'Info-search "search" map Info-mode-map)
3198 map))) 3199 map)))
3199 3200
diff --git a/lisp/locate.el b/lisp/locate.el
index 5934a572d4d..563300f6c03 100644
--- a/lisp/locate.el
+++ b/lisp/locate.el
@@ -149,7 +149,7 @@
149 149
150(defcustom locate-header-face nil 150(defcustom locate-header-face nil
151 "*Face used to highlight the locate header." 151 "*Face used to highlight the locate header."
152 :type 'face 152 :type '(choice face (const nil))
153 :group 'locate) 153 :group 'locate)
154 154
155;;;###autoload 155;;;###autoload
diff --git a/lisp/log-view.el b/lisp/log-view.el
index 9249531129b..ac82c984084 100644
--- a/lisp/log-view.el
+++ b/lisp/log-view.el
@@ -60,6 +60,7 @@
60 60
61(eval-when-compile (require 'cl)) 61(eval-when-compile (require 'cl))
62(require 'pcvs-util) 62(require 'pcvs-util)
63(autoload 'vc-find-version "vc")
63(autoload 'vc-version-diff "vc") 64(autoload 'vc-version-diff "vc")
64 65
65(defvar cvs-minor-wrap-function) 66(defvar cvs-minor-wrap-function)
@@ -168,7 +169,7 @@
168 (forward-line 1) 169 (forward-line 1)
169 (or (re-search-backward log-view-file-re nil t) 170 (or (re-search-backward log-view-file-re nil t)
170 (re-search-forward log-view-file-re)) 171 (re-search-forward log-view-file-re))
171 (let* ((file (or (match-string 2) (match-string 3))) 172 (let* ((file (or (match-string 1) (match-string 2)))
172 (cvsdir (and (re-search-backward log-view-dir-re nil t) 173 (cvsdir (and (re-search-backward log-view-dir-re nil t)
173 (match-string 1))) 174 (match-string 1)))
174 (pcldir (and (boundp 'cvs-pcl-cvs-dirchange-re) 175 (pcldir (and (boundp 'cvs-pcl-cvs-dirchange-re)
@@ -188,7 +189,7 @@
188 (when (re-search-backward log-view-message-re nil t) 189 (when (re-search-backward log-view-message-re nil t)
189 (let (rev) 190 (let (rev)
190 ;; Find the subgroup that matched. 191 ;; Find the subgroup that matched.
191 (dotimes (i (/ (match-data 'integers) 2)) 192 (dotimes (i (/ (length (match-data 'integers)) 2))
192 (setq rev (or rev (match-string (1+ i))))) 193 (setq rev (or rev (match-string (1+ i)))))
193 (unless (re-search-forward log-view-file-re pt t) 194 (unless (re-search-forward log-view-file-re pt t)
194 rev)))))) 195 rev))))))
diff --git a/lisp/makefile.w32-in b/lisp/makefile.w32-in
index 35b9f1cbd28..24acf0009c4 100644
--- a/lisp/makefile.w32-in
+++ b/lisp/makefile.w32-in
@@ -158,8 +158,8 @@ loaddefs.el-CMD:
158autoloads: $(lisp)/loaddefs.el doit 158autoloads: $(lisp)/loaddefs.el doit
159 @echo Directories: . $(WINS) 159 @echo Directories: . $(WINS)
160 $(emacs) -l autoload \ 160 $(emacs) -l autoload \
161 --eval $(ARGQUOTE)(setq find-file-hook nil find-file-suppress-same-file-warnings t generated-autoload-file $(DQUOTE)$(lisp)/loaddefs.el$(DQUOTE))$(ARGQUOTE) \ 161 --eval $(ARGQUOTE)(setq find-file-hook nil find-file-suppress-same-file-warnings t)$(ARGQUOTE) \
162 -f batch-update-autoloads . $(WINS) 162 -f w32-batch-update-autoloads "$(lisp)/loaddefs.el" . $(WINS)
163 163
164$(lisp)/subdirs.el: 164$(lisp)/subdirs.el:
165 $(MAKE) $(MFLAGS) update-subdirs 165 $(MAKE) $(MFLAGS) update-subdirs
@@ -311,10 +311,10 @@ $(lisp)/mh-e/mh-loaddefs.el: $(MH_E_SRC)
311 $(EMACS) $(EMACSOPT) \ 311 $(EMACS) $(EMACSOPT) \
312 -l autoload \ 312 -l autoload \
313 --eval "(setq generate-autoload-cookie \";;;###mh-autoload\")" \ 313 --eval "(setq generate-autoload-cookie \";;;###mh-autoload\")" \
314 --eval "(setq generated-autoload-file \"$(lisp)/mh-e/mh-loaddefs.el\")" \
315 --eval "(setq find-file-suppress-same-file-warnings t)" \ 314 --eval "(setq find-file-suppress-same-file-warnings t)" \
316 --eval "(setq make-backup-files nil)" \ 315 --eval "(setq make-backup-files nil)" \
317 -f batch-update-autoloads $(lisp)/mh-e 316 -f w32-batch-update-autoloads \
317 "$(lisp)/mh-e/mh-loaddefs.el" $(lisp)/mh-e
318 318
319pre-mh-loaddefs.el-SH: 319pre-mh-loaddefs.el-SH:
320 echo ";;; mh-loaddefs.el --- automatically extracted autoloads" > $@ 320 echo ";;; mh-loaddefs.el --- automatically extracted autoloads" > $@
diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el
index afc207bc9f0..e005fc09df6 100644
--- a/lisp/menu-bar.el
+++ b/lisp/menu-bar.el
@@ -178,6 +178,17 @@ A large number or nil slows down menu responsiveness."
178(define-key menu-bar-file-menu [separator-save] 178(define-key menu-bar-file-menu [separator-save]
179 '(menu-item "--")) 179 '(menu-item "--"))
180 180
181(defun menu-find-file-existing ()
182 "Edit the existing file FILENAME."
183 (interactive)
184 (let* ((mustmatch (not (and (fboundp 'x-uses-old-gtk-dialog)
185 (x-uses-old-gtk-dialog))))
186 (filename (car (find-file-read-args "Find file: " mustmatch))))
187 (if mustmatch
188 (find-file-existing filename)
189 (find-file filename))))
190
191
181(define-key menu-bar-file-menu [kill-buffer] 192(define-key menu-bar-file-menu [kill-buffer]
182 '(menu-item "Close" kill-this-buffer 193 '(menu-item "Close" kill-this-buffer
183 :enable (kill-this-buffer-enabled-p) 194 :enable (kill-this-buffer-enabled-p)
@@ -191,7 +202,7 @@ A large number or nil slows down menu responsiveness."
191 :enable (menu-bar-non-minibuffer-window-p) 202 :enable (menu-bar-non-minibuffer-window-p)
192 :help "Read a directory, to operate on its files")) 203 :help "Read a directory, to operate on its files"))
193(define-key menu-bar-file-menu [open-file] 204(define-key menu-bar-file-menu [open-file]
194 '(menu-item "Open File..." find-file-existing 205 '(menu-item "Open File..." menu-find-file-existing
195 :enable (menu-bar-non-minibuffer-window-p) 206 :enable (menu-bar-non-minibuffer-window-p)
196 :help "Read an existing file into an Emacs buffer")) 207 :help "Read an existing file into an Emacs buffer"))
197(define-key menu-bar-file-menu [new-file] 208(define-key menu-bar-file-menu [new-file]
diff --git a/lisp/mh-e/ChangeLog b/lisp/mh-e/ChangeLog
index dce4b1def32..01ebde5bba3 100644
--- a/lisp/mh-e/ChangeLog
+++ b/lisp/mh-e/ChangeLog
@@ -1,3 +1,78 @@
12005-12-23 Bill Wohler <wohler@newt.com>
2
3 * mh-e.el (mh-folders-changed): Fix typo in docstring.
4
5 Follow MH-E Developers Guide conventions. Use `' quotes for Help
6 hyperlinks such as symbols, Info nodes, or URLs. Use \" quotes for
7 everything else. Otherwise, you can accidently get links to
8 nonsense symbols.
9
102005-12-22 Bill Wohler <wohler@newt.com>
11
12 Follow Emacs coding conventions. Use default setting of
13 emacs-lisp-docstring-fill-column which is 65.
14
15 * mh-alias.el (mh-alias-reload): Sync docstrings with manual.
16
17 * mh-comp.el (mh-letter-mode): Use 60 column width.
18 (mh-forward, mh-insert-signature, mh-send-letter): Sync docstrings
19 with manual.
20 (mh-yank-cur-msg): Mention that mh-ins-buf-prefix isn't used if
21 you have added a mail-citation-hook and neither are used if you
22 use one of the supercite flavors of mh-yank-behavior. Sync
23 docstrings with manual.
24
25 * mh-customize.el (mh-kill-folder-suppress-prompt-hooks): Rename
26 from mh-kill-folder-suppress-prompt-hook since it is an abnormal
27 hook. Use "Hook run by `function'..." instead of "Invoked...".
28 Sync docstrings with manual.
29 (mh-ins-buf-prefix, mh-yank-behavior): Mention that
30 mh-ins-buf-prefix isn't used if you have added a
31 mail-citation-hook and neither are used if you use one of the
32 supercite flavors of mh-yank-behavior. Sync docstrings with
33 manual.
34 (mail-citation-hook): Delete. Use one in sendmail.el.
35 (mh-signature-file-name, mh-after-commands-processed-hook)
36 (mh-alias-reloaded-hook, mh-before-commands-processed-hook)
37 (mh-before-quit-hook, mh-before-send-letter-hook)
38 (mh-delete-msg-hook, mh-find-path-hook, mh-folder-mode-hook)
39 (mh-forward-hook, mh-inc-folder-hook, mh-insert-signature-hook)
40 (mh-letter-mode-hook)
41 (mh-mh-to-mime-hook, mh-pick-mode-hook, mh-quit-hook)
42 (mh-refile-msg-hook, mh-show-hook, mh-show-mode-hook)
43 (mh-unseen-updated-hook): Use "Hook run by `function'..." instead
44 of "Invoked...". Sync docstrings with manual.
45
46 * mh-e.el (mh-last-destination, mh-last-destination-folder)
47 (mh-last-destination-write, mh-folder-mode-map, mh-arrow-marker)
48 (mh-delete-list, mh-refile-list, mh-folders-changed)
49 (mh-next-direction, mh-view-ops, mh-folder-view-stack)
50 (mh-index-data, mh-first-msg-num, mh-last-msg-num)
51 (mh-mode-line-annotation, mh-sequence-notation-history)
52 (mh-colors-available-flag): Move comment into docstring.
53 (mh-delete-msg, mh-execute-commands, mh-inc-folder, mh-quit,
54 mh-process-commands): Sync docstrings with manual.
55 (mh-refile-msg): Small doc edit.
56 (mh-delete-a-msg, mh-refile-a-msg): Sync docstrings with manual.
57 Rename msg argument to message.
58
59 * mh-funcs.el (mh-kill-folder): Sync docstrings with manual.
60
61 * mh-e.el (mh-update-unseen): No longer say "The value of
62 `foo-hook' is a list of functions to be called, with no arguments,
63 ...," but rather just "The hook foo-hook is called...".
64
65 * mh-mime.el (mh-mh-to-mime): Ditto
66
67 * mh-pick.el (mh-pick-mode): Ditto.
68
69 * mh-utils.el (mh-showing-mode): Use uppercase for argument in
70 docstring.
71 (mh-seq-list, mh-seen-list, mh-showing-with-headers): Move comment
72 into docstring.
73 (mh-show-mode, mh-show-msg, mh-find-path): Sync docstrings with
74 manual.
75
12005-12-19 Stephen Gildea 762005-12-19 Stephen Gildea
2 77
3 * mh-customize.el (mh-after-commands-processed-hook): New variable. 78 * mh-customize.el (mh-after-commands-processed-hook): New variable.
diff --git a/lisp/mh-e/mh-acros.el b/lisp/mh-e/mh-acros.el
index 5523f1cf46b..fbc8c385863 100644
--- a/lisp/mh-e/mh-acros.el
+++ b/lisp/mh-e/mh-acros.el
@@ -32,7 +32,7 @@
32;; 32;;
33;; (eval-when-compile (require 'mh-acros)) 33;; (eval-when-compile (require 'mh-acros))
34;; 34;;
35;; It is so named with a silent `m' so that it is compiled first. Otherwise, 35;; It is so named with a silent "m" so that it is compiled first. Otherwise,
36;; "make recompile" in Emacs 21.4 fails. 36;; "make recompile" in Emacs 21.4 fails.
37 37
38;;; Change Log: 38;;; Change Log:
@@ -47,10 +47,11 @@
47;; routines in their macro expansions. Use mh-require-cl to provide the cl 47;; routines in their macro expansions. Use mh-require-cl to provide the cl
48;; routines in the best way possible. 48;; routines in the best way possible.
49(defmacro mh-require-cl () 49(defmacro mh-require-cl ()
50 "Macro to load `cl' if needed. 50 "Macro to load \"cl\" if needed.
51Some versions of `cl' produce code for the expansion of 51Some versions of \"cl\" produce code for the expansion of
52\(setf (gethash ...) ...) that uses functions in `cl' at run time. This macro 52\(setf (gethash ...) ...) that uses functions in \"cl\" at run
53recognizes that and loads `cl' where appropriate." 53time. This macro recognizes that and loads \"cl\" where
54appropriate."
54 (if (eq (car (macroexpand '(setf (gethash foo bar) baz))) 'cl-puthash) 55 (if (eq (car (macroexpand '(setf (gethash foo bar) baz))) 'cl-puthash)
55 `(require 'cl) 56 `(require 'cl)
56 `(eval-when-compile (require 'cl)))) 57 `(eval-when-compile (require 'cl))))
@@ -75,16 +76,16 @@ recognizes that and loads `cl' where appropriate."
75 76
76(defmacro mh-make-local-hook (hook) 77(defmacro mh-make-local-hook (hook)
77 "Make HOOK local if needed. 78 "Make HOOK local if needed.
78XEmacs and versions of GNU Emacs before 21.1 require `make-local-hook' to be 79XEmacs and versions of GNU Emacs before 21.1 require
79called." 80`make-local-hook' to be called."
80 (when (and (fboundp 'make-local-hook) 81 (when (and (fboundp 'make-local-hook)
81 (not (get 'make-local-hook 'byte-obsolete-info))) 82 (not (get 'make-local-hook 'byte-obsolete-info)))
82 `(make-local-hook ,hook))) 83 `(make-local-hook ,hook)))
83 84
84(defmacro mh-mark-active-p (check-transient-mark-mode-flag) 85(defmacro mh-mark-active-p (check-transient-mark-mode-flag)
85 "A macro that expands into appropriate code in XEmacs and nil in GNU Emacs. 86 "A macro that expands into appropriate code in XEmacs and nil in GNU Emacs.
86In GNU Emacs if CHECK-TRANSIENT-MARK-MODE-FLAG is non-nil then check if 87In GNU Emacs if CHECK-TRANSIENT-MARK-MODE-FLAG is non-nil then
87variable `transient-mark-mode' is active." 88check if variable `transient-mark-mode' is active."
88 (cond ((featurep 'xemacs) ;XEmacs 89 (cond ((featurep 'xemacs) ;XEmacs
89 `(and (boundp 'zmacs-regions) zmacs-regions (region-active-p))) 90 `(and (boundp 'zmacs-regions) zmacs-regions (region-active-p)))
90 ((not check-transient-mark-mode-flag) ;GNU Emacs 91 ((not check-transient-mark-mode-flag) ;GNU Emacs
@@ -94,13 +95,15 @@ variable `transient-mark-mode' is active."
94 (boundp 'mark-active) mark-active)))) 95 (boundp 'mark-active) mark-active))))
95 96
96(defmacro mh-defstruct (name-spec &rest fields) 97(defmacro mh-defstruct (name-spec &rest fields)
97 "Replacement for `defstruct' from the `cl' package. 98 "Replacement for `defstruct' from the \"cl\" package.
98The `defstruct' in the `cl' library produces compiler warnings, and generates 99The `defstruct' in the \"cl\" library produces compiler warnings,
99code that uses functions present in `cl' at run-time. This is a partial 100and generates code that uses functions present in \"cl\" at
100replacement, that avoids these issues. 101run-time. This is a partial replacement, that avoids these
101 102issues.
102NAME-SPEC declares the name of the structure, while FIELDS describes the 103
103various structure fields. Lookup `defstruct' for more details." 104NAME-SPEC declares the name of the structure, while FIELDS
105describes the various structure fields. Lookup `defstruct' for
106more details."
104 (let* ((struct-name (if (atom name-spec) name-spec (car name-spec))) 107 (let* ((struct-name (if (atom name-spec) name-spec (car name-spec)))
105 (conc-name (or (and (consp name-spec) 108 (conc-name (or (and (consp name-spec)
106 (cadr (assoc :conc-name (cdr name-spec)))) 109 (cadr (assoc :conc-name (cdr name-spec))))
@@ -136,8 +139,8 @@ various structure fields. Lookup `defstruct' for more details."
136 139
137(defmacro mh-assoc-ignore-case (key alist) 140(defmacro mh-assoc-ignore-case (key alist)
138 "Check if KEY is present in ALIST while ignoring case to do the comparison. 141 "Check if KEY is present in ALIST while ignoring case to do the comparison.
139Compatibility macro for Emacs versions that lack `assoc-string', introduced in 142Compatibility macro for Emacs versions that lack `assoc-string',
140Emacs 22." 143introduced in Emacs 22."
141 (if (fboundp 'assoc-string) 144 (if (fboundp 'assoc-string)
142 `(assoc-string ,key ,alist t) 145 `(assoc-string ,key ,alist t)
143 `(assoc-ignore-case ,key ,alist))) 146 `(assoc-ignore-case ,key ,alist)))
diff --git a/lisp/mh-e/mh-alias.el b/lisp/mh-e/mh-alias.el
index f82a0ea24dc..397cd9ea782 100644
--- a/lisp/mh-e/mh-alias.el
+++ b/lisp/mh-e/mh-alias.el
@@ -68,10 +68,11 @@
68 "/usr/lib/mh/MailAliases" "/usr/share/mailutils/mh/MailAliases" 68 "/usr/lib/mh/MailAliases" "/usr/share/mailutils/mh/MailAliases"
69 "/etc/passwd") 69 "/etc/passwd")
70 "*A list of system files which are a source of aliases. 70 "*A list of system files which are a source of aliases.
71If these files are modified, they are automatically reread. This list need 71If these files are modified, they are automatically reread. This list
72include only system aliases and the passwd file, since personal alias files 72need include only system aliases and the passwd file, since personal
73listed in your `Aliasfile:' MH profile component are automatically included. 73alias files listed in your \"Aliasfile:\" MH profile component are
74You can update the alias list manually using \\[mh-alias-reload].") 74automatically included. You can update the alias list manually using
75\\[mh-alias-reload].")
75 76
76 77
77 78
@@ -79,8 +80,8 @@ You can update the alias list manually using \\[mh-alias-reload].")
79 80
80(defun mh-alias-tstamp (arg) 81(defun mh-alias-tstamp (arg)
81 "Check whether alias files have been modified. 82 "Check whether alias files have been modified.
82Return t if any file listed in the Aliasfile MH profile component has been 83Return t if any file listed in the Aliasfile MH profile component has
83modified since the timestamp. 84been modified since the timestamp.
84If ARG is non-nil, set timestamp with the current time." 85If ARG is non-nil, set timestamp with the current time."
85 (if arg 86 (if arg
86 (let ((time (current-time))) 87 (let ((time (current-time)))
@@ -98,8 +99,10 @@ If ARG is non-nil, set timestamp with the current time."
98 99
99(defun mh-alias-filenames (arg) 100(defun mh-alias-filenames (arg)
100 "Return list of filenames that contain aliases. 101 "Return list of filenames that contain aliases.
101The filenames come from the Aliasfile profile component and are expanded. 102The filenames come from the Aliasfile profile component and are
102If ARG is non-nil, filenames listed in `mh-alias-system-aliases' are appended." 103expanded.
104If ARG is non-nil, filenames listed in `mh-alias-system-aliases' are
105appended."
103 (or mh-progs (mh-find-path)) 106 (or mh-progs (mh-find-path))
104 (save-excursion 107 (save-excursion
105 (let* ((filename (mh-profile-component "Aliasfile")) 108 (let* ((filename (mh-profile-component "Aliasfile"))
@@ -120,8 +123,8 @@ If ARG is non-nil, filenames listed in `mh-alias-system-aliases' are appended."
120 123
121(defun mh-alias-gecos-name (gecos-name username comma-separator) 124(defun mh-alias-gecos-name (gecos-name username comma-separator)
122 "Return a usable address string from a GECOS-NAME and USERNAME. 125 "Return a usable address string from a GECOS-NAME and USERNAME.
123Use only part of the GECOS-NAME up to the first comma if COMMA-SEPARATOR is 126Use only part of the GECOS-NAME up to the first comma if
124non-nil." 127COMMA-SEPARATOR is non-nil."
125 (let ((res gecos-name)) 128 (let ((res gecos-name))
126 ;; Keep only string until first comma if COMMA-SEPARATOR is t. 129 ;; Keep only string until first comma if COMMA-SEPARATOR is t.
127 (if (and comma-separator 130 (if (and comma-separator
@@ -143,7 +146,7 @@ non-nil."
143 146
144(defun mh-alias-local-users () 147(defun mh-alias-local-users ()
145 "Return an alist of local users from /etc/passwd. 148 "Return an alist of local users from /etc/passwd.
146Exclude all aliases already in `mh-alias-alist' from `ali'" 149Exclude all aliases already in `mh-alias-alist' from \"ali\""
147 (let (passwd-alist) 150 (let (passwd-alist)
148 (save-excursion 151 (save-excursion
149 (set-buffer (get-buffer-create mh-temp-buffer)) 152 (set-buffer (get-buffer-create mh-temp-buffer))
@@ -183,14 +186,15 @@ Exclude all aliases already in `mh-alias-alist' from `ali'"
183(defun mh-alias-reload () 186(defun mh-alias-reload ()
184 "Reload MH aliases. 187 "Reload MH aliases.
185 188
186Since aliases are updated frequently, MH-E will reload aliases automatically 189Since aliases are updated frequently, MH-E reloads aliases
187whenever an alias lookup occurs if an alias source (a file listed in your 190automatically whenever an alias lookup occurs if an alias source has
188`Aliasfile:' profile component and your password file if variable 191changed. Sources include files listed in your \"Aliasfile:\" profile
189`mh-alias-local-users' is non-nil) has changed. However, you can reload your 192component and your password file if option `mh-alias-local-users' is
190aliases manually by calling this command directly. 193turned on. However, you can reload your aliases manually by calling
194this command directly.
191 195
192The value of `mh-alias-reloaded-hook' is a list of functions to be called, 196This function runs `mh-alias-reloaded-hook' after the aliases have
193with no arguments, after the aliases have been loaded." 197been loaded."
194 (interactive) 198 (interactive)
195 (save-excursion 199 (save-excursion
196 (message "Loading MH aliases...") 200 (message "Loading MH aliases...")
@@ -238,8 +242,8 @@ with no arguments, after the aliases have been loaded."
238(defun mh-alias-ali (alias &optional user) 242(defun mh-alias-ali (alias &optional user)
239 "Return ali expansion for ALIAS. 243 "Return ali expansion for ALIAS.
240ALIAS must be a string for a single alias. 244ALIAS must be a string for a single alias.
241If USER is t, then assume ALIAS is an address and call ali -user. 245If USER is t, then assume ALIAS is an address and call ali -user. ali
242ali returns the string unchanged if not defined. The same is done here." 246returns the string unchanged if not defined. The same is done here."
243 (condition-case err 247 (condition-case err
244 (save-excursion 248 (save-excursion
245 (let ((user-arg (if user "-user" "-nouser"))) 249 (let ((user-arg (if user "-user" "-nouser")))
@@ -322,8 +326,8 @@ Blind aliases or users from /etc/passwd are not expanded."
322 326
323(defun mh-alias-suggest-alias (string &optional no-comma-swap) 327(defun mh-alias-suggest-alias (string &optional no-comma-swap)
324 "Suggest an alias for STRING. 328 "Suggest an alias for STRING.
325Don't reverse the order of strings separated by a comma if NO-COMMA-SWAP is 329Don't reverse the order of strings separated by a comma if
326non-nil." 330NO-COMMA-SWAP is non-nil."
327 (cond 331 (cond
328 ((string-match "^<\\(.*\\)>$" string) 332 ((string-match "^<\\(.*\\)>$" string)
329 ;; <somename@foo.bar> -> recurse, stripping brackets. 333 ;; <somename@foo.bar> -> recurse, stripping brackets.
@@ -378,8 +382,8 @@ non-nil."
378(defun mh-alias-canonicalize-suggestion (string) 382(defun mh-alias-canonicalize-suggestion (string)
379 "Process STRING to replace spaces by periods. 383 "Process STRING to replace spaces by periods.
380First all spaces and commas are replaced by periods. Then every run of 384First all spaces and commas are replaced by periods. Then every run of
381consecutive periods are replaced with a single period. Finally the string 385consecutive periods are replaced with a single period. Finally the
382is converted to lower case." 386string is converted to lower case."
383 (with-temp-buffer 387 (with-temp-buffer
384 (insert string) 388 (insert string)
385 ;; Replace spaces with periods 389 ;; Replace spaces with periods
@@ -417,10 +421,10 @@ is converted to lower case."
417 421
418(defun mh-alias-insert-file (&optional alias) 422(defun mh-alias-insert-file (&optional alias)
419 "Return filename which should be used to add ALIAS. 423 "Return filename which should be used to add ALIAS.
420The value of the option `mh-alias-insert-file' is used if non-nil\; otherwise 424The value of the option `mh-alias-insert-file' is used if non-nil\;
421the value of the `Aliasfile:' profile component is used. 425otherwise the value of the \"Aliasfile:\" profile component is used.
422If the alias already exists, try to return the name of the file that contains 426If the alias already exists, try to return the name of the file that
423it." 427contains it."
424 (cond 428 (cond
425 ((and mh-alias-insert-file (listp mh-alias-insert-file)) 429 ((and mh-alias-insert-file (listp mh-alias-insert-file))
426 (if (not (elt mh-alias-insert-file 1)) ; Only one entry, use it 430 (if (not (elt mh-alias-insert-file 1)) ; Only one entry, use it
@@ -445,7 +449,7 @@ it."
445 (cond 449 (cond
446 ((not autolist) 450 ((not autolist)
447 (error "No writable alias file. 451 (error "No writable alias file.
448Set `mh-alias-insert-file' or the Aliasfile profile component")) 452Set `mh-alias-insert-file' or the \"Aliasfile:\" profile component"))
449 ((not (elt autolist 1)) ; Only one entry, use it 453 ((not (elt autolist 1)) ; Only one entry, use it
450 (car autolist)) 454 (car autolist))
451 ((or (not alias) 455 ((or (not alias)
@@ -488,12 +492,14 @@ Set `mh-alias-insert-file' or the Aliasfile profile component"))
488 492
489(defun mh-alias-add-alias-to-file (alias address &optional file) 493(defun mh-alias-add-alias-to-file (alias address &optional file)
490 "Add ALIAS for ADDRESS in alias FILE without alias check or prompts. 494 "Add ALIAS for ADDRESS in alias FILE without alias check or prompts.
491Prompt for alias file if not provided and there is more than one candidate. 495Prompt for alias file if not provided and there is more than one
492 496candidate.
493If the alias exists already, you will have the choice of inserting the new 497
494alias before or after the old alias. In the former case, this alias will be 498If the alias exists already, you will have the choice of
495used when sending mail to this alias. In the latter case, the alias serves as 499inserting the new alias before or after the old alias. In the
496an additional folder name hint when filing messages." 500former case, this alias will be used when sending mail to this
501alias. In the latter case, the alias serves as an additional
502folder name hint when filing messages."
497 (if (not file) 503 (if (not file)
498 (setq file (mh-alias-insert-file alias))) 504 (setq file (mh-alias-insert-file alias)))
499 (save-excursion 505 (save-excursion
@@ -543,11 +549,12 @@ an additional folder name hint when filing messages."
543;;;###mh-autoload 549;;;###mh-autoload
544(defun mh-alias-add-alias (alias address) 550(defun mh-alias-add-alias (alias address)
545 "*Add ALIAS for ADDRESS in personal alias file. 551 "*Add ALIAS for ADDRESS in personal alias file.
546This function prompts you for an alias and address. If the alias exists 552This function prompts you for an alias and address. If the alias
547already, you will have the choice of inserting the new alias before or after 553exists already, you will have the choice of inserting the new
548the old alias. In the former case, this alias will be used when sending mail 554alias before or after the old alias. In the former case, this
549to this alias. In the latter case, the alias serves as an additional folder 555alias will be used when sending mail to this alias. In the latter
550name hint when filing messages." 556case, the alias serves as an additional folder name hint when
557filing messages."
551 (interactive "P\nP") 558 (interactive "P\nP")
552 (mh-alias-reload-maybe) 559 (mh-alias-reload-maybe)
553 (setq alias (completing-read "Alias: " mh-alias-alist nil nil alias)) 560 (setq alias (completing-read "Alias: " mh-alias-alist nil nil alias))
diff --git a/lisp/mh-e/mh-comp.el b/lisp/mh-e/mh-comp.el
index 47999fbbeff..898f24dccb7 100644
--- a/lisp/mh-e/mh-comp.el
+++ b/lisp/mh-e/mh-comp.el
@@ -92,8 +92,8 @@ Some sites need to change this because of a name conflict.")
92 92
93(defvar mh-redist-background nil 93(defvar mh-redist-background nil
94 "If non-nil redist will be done in background like send. 94 "If non-nil redist will be done in background like send.
95This allows transaction log to be visible if -watch, -verbose or -snoop are 95This allows transaction log to be visible if -watch, -verbose or
96used.") 96-snoop are used.")
97 97
98 98
99 99
@@ -110,32 +110,39 @@ used.")
110 110
111(defvar mh-yank-hooks nil 111(defvar mh-yank-hooks nil
112 "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
113Each hook function can find the citation between point and mark. 114Each hook function can find the citation between point and mark.
114And each hook function should leave point and mark around the citation 115And each hook function should leave point and mark around the
115text as modified. 116citation text as modified.
116 117
117This is a normal hook, misnamed for historical reasons. 118This is a normal hook, misnamed for historical reasons. It is
118It is semi-obsolete and is only used if `mail-citation-hook' is nil.") 119semi-obsolete and is only used if `mail-citation-hook' is nil.")
119 120
120(defvar mh-comp-formfile "components" 121(defvar mh-comp-formfile "components"
121 "Name of file to be used as a skeleton for composing messages. 122 "Name of file to be used as a skeleton for composing messages.
122Default is \"components\". If not an absolute file name, the file 123
123is searched for first in the user's MH directory, then in the 124Default is \"components\".
124system MH lib directory.") 125
126If not an absolute file name, the file is searched for first in the
127user's MH directory, then in the system MH lib directory.")
125 128
126(defvar mh-repl-formfile "replcomps" 129(defvar mh-repl-formfile "replcomps"
127 "Name of file to be used as a skeleton for replying to messages. 130 "Name of file to be used as a skeleton for replying to messages.
128Default is \"replcomps\". If not an absolute file name, the file 131
129is searched for first in the user's MH directory, then in the 132Default is \"replcomps\".
130system MH lib directory.") 133
134If not an absolute file name, the file is searched for first in the
135user's MH directory, then in the system MH lib directory.")
131 136
132(defvar mh-repl-group-formfile "replgroupcomps" 137(defvar mh-repl-group-formfile "replgroupcomps"
133 "Name of file to be used as a skeleton for replying to messages. 138 "Name of file to be used as a skeleton for replying to messages.
134This file is used to form replies to the sender and all recipients of a 139
135message. Only used if `(mh-variant-p 'nmh)' is non-nil.
136Default is \"replgroupcomps\". 140Default is \"replgroupcomps\".
137If not an absolute file name, the file is searched for first in the user's MH 141
138directory, then in the system MH lib directory.") 142This file is used to form replies to the sender and all recipients of
143a message. Only used if `(mh-variant-p 'nmh)' is non-nil.
144If not an absolute file name, the file is searched for first in the
145user's MH directory, then in the system MH lib directory.")
139 146
140(defvar mh-rejected-letter-start 147(defvar mh-rejected-letter-start
141 (format "^%s$" 148 (format "^%s$"
@@ -155,8 +162,8 @@ directory, then in the system MH lib directory.")
155 162
156(defvar mh-new-draft-cleaned-headers 163(defvar mh-new-draft-cleaned-headers
157 "^Date:\\|^Received:\\|^Message-Id:\\|^From:\\|^Sender:\\|^Errors-To:\\|^Delivery-Date:\\|^Return-Path:" 164 "^Date:\\|^Received:\\|^Message-Id:\\|^From:\\|^Sender:\\|^Errors-To:\\|^Delivery-Date:\\|^Return-Path:"
158 "Regexp of header lines to remove before offering a message as a new draft. 165 "Regexp of header lines to remove before offering a message as a new draft\\<mh-folder-mode-map>.
159Used by the \\<mh-folder-mode-map>`\\[mh-edit-again]' and `\\[mh-extract-rejected-mail]' commands.") 166Used by the \\[mh-edit-again] and \\[mh-extract-rejected-mail] commands.")
160 167
161(defvar mh-to-field-choices '(("t" . "To:") ("s" . "Subject:") ("c" . "Cc:") 168(defvar mh-to-field-choices '(("t" . "To:") ("s" . "Subject:") ("c" . "Cc:")
162 ("b" . "Bcc:") ("f" . "Fcc:") ("r" . "From:") 169 ("b" . "Bcc:") ("f" . "Fcc:") ("r" . "From:")
@@ -216,12 +223,12 @@ See `mh-send' for more details on composing mail."
216(defun mh-smail-batch (&optional to subject other-headers &rest ignored) 223(defun mh-smail-batch (&optional to subject other-headers &rest ignored)
217 "Compose a message with the MH mail system. 224 "Compose a message with the MH mail system.
218 225
219This function does not prompt the user for any header fields, and thus 226This function does not prompt the user for any header fields, and
220is suitable for use by programs that want to create a mail buffer. Users 227thus is suitable for use by programs that want to create a mail
221should use \\[mh-smail] to compose mail. 228buffer. Users should use \\[mh-smail] to compose mail.
222 229
223Optional arguments for setting certain fields include TO, SUBJECT, and 230Optional arguments for setting certain fields include TO,
224OTHER-HEADERS. Additional arguments are IGNORED." 231SUBJECT, and OTHER-HEADERS. Additional arguments are IGNORED."
225 (mh-find-path) 232 (mh-find-path)
226 (let ((mh-error-if-no-draft t)) 233 (let ((mh-error-if-no-draft t))
227 (mh-send (or to "") "" (or subject "")))) 234 (mh-send (or to "") "" (or subject ""))))
@@ -237,11 +244,12 @@ This is `mail-user-agent' entry point to MH-E.
237The optional arguments TO and SUBJECT specify recipients and the 244The optional arguments TO and SUBJECT specify recipients and the
238initial Subject field, respectively. 245initial Subject field, respectively.
239 246
240OTHER-HEADERS is an alist specifying additional 247OTHER-HEADERS is an alist specifying additional header fields.
241header fields. Elements look like (HEADER . VALUE) where both 248Elements look like (HEADER . VALUE) where both HEADER and VALUE
242HEADER and VALUE are strings. 249are strings.
243 250
244CONTINUE, SWITCH-FUNCTION, YANK-ACTION and SEND-ACTIONS are ignored." 251CONTINUE, SWITCH-FUNCTION, YANK-ACTION and SEND-ACTIONS are
252ignored."
245 (mh-find-path) 253 (mh-find-path)
246 (let ((mh-error-if-no-draft t)) 254 (let ((mh-error-if-no-draft t))
247 (mh-send to "" subject) 255 (mh-send to "" subject)
@@ -254,20 +262,21 @@ CONTINUE, SWITCH-FUNCTION, YANK-ACTION and SEND-ACTIONS are ignored."
254(defun mh-edit-again (message) 262(defun mh-edit-again (message)
255 "Edit a MESSAGE to send it again. 263 "Edit a MESSAGE to send it again.
256 264
257If you don't complete a draft for one reason or another, and if the draft 265If you don't complete a draft for one reason or another, and if
258buffer is no longer available, you can pick your draft up again with this 266the draft buffer is no longer available, you can pick your draft
259command. If you don't use a draft folder, your last \"draft\" file will be 267up again with this command. If you don't use a draft folder, your
260used. If you use draft folders, you'll need to visit the draft folder with 268last \"draft\" file will be used. If you use draft folders,
261\"\\[mh-visit-folder] drafts <RET>\", use \\[mh-next-undeleted-msg] to move to 269you'll need to visit the draft folder with \"\\[mh-visit-folder]
262the appropriate message, and then use \\[mh-edit-again] to prepare the message 270drafts <RET>\", use \\[mh-next-undeleted-msg] to move to the
263for editing. 271appropriate message, and then use \\[mh-edit-again] to prepare
272the message for editing.
264 273
265This command can also be used to take messages that were sent to you and to 274This command can also be used to take messages that were sent to
266send them to more people. 275you and to send them to more people.
267 276
268Don't use this command to re-edit a message from a Mailer-Daemon who 277Don't use this command to re-edit a message from a Mailer-Daemon
269complained that your mail wasn't posted for some reason or another (see 278who complained that your mail wasn't posted for some reason or
270`mh-extract-rejected-mail'). 279another (see `mh-extract-rejected-mail').
271 280
272The default message is the current message. 281The default message is the current message.
273 282
@@ -303,9 +312,10 @@ See also `mh-send'."
303(defun mh-extract-rejected-mail (message) 312(defun mh-extract-rejected-mail (message)
304 "Edit a MESSAGE that was returned by the mail system. 313 "Edit a MESSAGE that was returned by the mail system.
305 314
306This command prepares the message for editing by removing the Mailer-Daemon 315This command prepares the message for editing by removing the
307envelope and unneeded header fields. Fix whatever addressing problem you had, 316Mailer-Daemon envelope and unneeded header fields. Fix whatever
308and send the message again with \\[mh-send-letter]. 317addressing problem you had, and send the message again with
318\\[mh-send-letter].
309 319
310The default message is the current message. 320The default message is the current message.
311 321
@@ -335,15 +345,19 @@ See also `mh-send'."
335(defun mh-forward (to cc &optional range) 345(defun mh-forward (to cc &optional range)
336 "Forward message. 346 "Forward message.
337 347
338You are prompted for the TO and CC recipients. You are given a draft to edit 348You are prompted for the TO and CC recipients. You are given a
339that looks like it would if you had run the MH command \"forw\". You are given 349draft to edit that looks like it would if you had run the MH
340a chance to add some text. 350command \"forw\". You can then add some text.
351
352You can forward several messages by using a RANGE. All of the
353messages in the range are inserted into your draft. Check the
354documentation of `mh-interactive-range' to see how RANGE is read
355in interactive use.
341 356
342You can forward several messages by using a RANGE. Check the documentation of 357The hook `mh-forward-hook' is called on the draft.
343`mh-interactive-range' to see how RANGE is read in interactive use.
344 358
345See also `mh-compose-forward-as-mime-flag', `mh-forward-subject-format', 359See also `mh-compose-forward-as-mime-flag',
346and `mh-send'." 360`mh-forward-subject-format', and `mh-send'."
347 (interactive (list (mh-interactive-read-address "To: ") 361 (interactive (list (mh-interactive-read-address "To: ")
348 (mh-interactive-read-address "Cc: ") 362 (mh-interactive-read-address "Cc: ")
349 (mh-interactive-range "Forward"))) 363 (mh-interactive-range "Forward")))
@@ -431,14 +445,15 @@ Original message has headers FROM and SUBJECT."
431(defun mh-redistribute (to cc &optional message) 445(defun mh-redistribute (to cc &optional message)
432 "Redistribute a message. 446 "Redistribute a message.
433 447
434This command is similar in function to forwarding mail, but it does not allow 448This command is similar in function to forwarding mail, but it
435you to edit the message, nor does it add your name to the \"From\" header 449does not allow you to edit the message, nor does it add your name
436field. It appears to the recipient as if the message had come from the 450to the \"From\" header field. It appears to the recipient as if
437original sender. When you run this command, you are prompted for the TO and CC 451the message had come from the original sender. When you run this
438recipients. The default MESSAGE is the current message. 452command, you are prompted for the TO and CC recipients. The
453default MESSAGE is the current message.
439 454
440Also investigate the \\[mh-edit-again] command for another way to redistribute 455Also investigate the \\[mh-edit-again] command for another way to
441messages. 456redistribute messages.
442 457
443See also `mh-redist-full-contents-flag'." 458See also `mh-redist-full-contents-flag'."
444 (interactive (list (mh-read-address "Redist-To: ") 459 (interactive (list (mh-read-address "Redist-To: ")
@@ -483,10 +498,11 @@ See also `mh-redist-full-contents-flag'."
483 498
484(defun mh-show-buffer-message-number (&optional buffer) 499(defun mh-show-buffer-message-number (&optional buffer)
485 "Message number of displayed message in corresponding show buffer. 500 "Message number of displayed message in corresponding show buffer.
501
486Return nil if show buffer not displayed. 502Return nil if show buffer not displayed.
487If in `mh-letter-mode', don't display the message number being replied to, 503If in `mh-letter-mode', don't display the message number being replied
488but rather the message number of the show buffer associated with our 504to, but rather the message number of the show buffer associated with
489originating folder buffer. 505our originating folder buffer.
490Optional argument BUFFER can be used to specify the buffer." 506Optional argument BUFFER can be used to specify the buffer."
491 (save-excursion 507 (save-excursion
492 (if buffer 508 (if buffer
@@ -510,14 +526,14 @@ Optional argument BUFFER can be used to specify the buffer."
510(defun mh-reply (message &optional reply-to includep) 526(defun mh-reply (message &optional reply-to includep)
511 "Reply to a MESSAGE. 527 "Reply to a MESSAGE.
512 528
513When you reply to a message, you are first prompted with \"Reply to whom?\" 529When you reply to a message, you are first prompted with \"Reply
514\(unless the optional argument REPLY-TO is provided). You have several choices 530to whom?\" (unless the optional argument REPLY-TO is provided).
515here. 531You have several choices here.
516 532
517 Response Reply Goes To 533 Response Reply Goes To
518 534
519 from The person who sent the message. This is the default, 535 from The person who sent the message. This is the
520 so <RET> is sufficient. 536 default, so <RET> is sufficient.
521 537
522 to Replies to the sender, plus all recipients in the 538 to Replies to the sender, plus all recipients in the
523 \"To:\" header field. 539 \"To:\" header field.
@@ -525,31 +541,32 @@ here.
525 all 541 all
526 cc Forms a reply to the sender, plus all recipients. 542 cc Forms a reply to the sender, plus all recipients.
527 543
528Depending on your answer, \"repl\" is given a different argument to form your 544Depending on your answer, \"repl\" is given a different argument
529reply. Specifically, a choice of \"from\" or none at all runs \"repl -nocc 545to form your reply. Specifically, a choice of \"from\" or none at
530all\", and a choice of \"to\" runs \"repl -cc to\". Finally, either \"cc\" or 546all runs \"repl -nocc all\", and a choice of \"to\" runs \"repl
531\"all\" runs \"repl -cc all -nocc me\". 547-cc to\". Finally, either \"cc\" or \"all\" runs \"repl -cc all
548-nocc me\".
532 549
533Two windows are then created. One window contains the message to which you are 550Two windows are then created. One window contains the message to
534replying in an MH-Show buffer. Your draft, in MH-Letter mode 551which you are replying in an MH-Show buffer. Your draft, in
535\(see `mh-letter-mode'), is in the other window. 552MH-Letter mode (see `mh-letter-mode'), is in the other window.
536 553
537If you supply a prefix argument INCLUDEP, the message you are replying to is 554If you supply a prefix argument INCLUDEP, the message you are
538inserted in your reply after having first been run through \"mhl\" with the 555replying to is inserted in your reply after having first been run
539format file \"mhl.reply\". 556through \"mhl\" with the format file \"mhl.reply\".
540 557
541Alternatively, you can customize the option `mh-yank-behavior' and choose one 558Alternatively, you can customize the option `mh-yank-behavior'
542of its \"Automatically\" variants to do the same thing. If you do so, the 559and choose one of its \"Automatically\" variants to do the same
543prefix argument has no effect. 560thing. If you do so, the prefix argument has no effect.
544 561
545Another way to include the message automatically in your draft is to use 562Another way to include the message automatically in your draft is
546\"repl: -filter repl.filter\" in your MH profile. 563to use \"repl: -filter repl.filter\" in your MH profile.
547 564
548If you wish to customize the header or other parts of the reply draft, please 565If you wish to customize the header or other parts of the reply
549see \"repl\" and \"mh-format\". 566draft, please see \"repl\" and \"mh-format\".
550 567
551See also `mh-reply-show-message-flag', `mh-reply-default-reply-to', and 568See also `mh-reply-show-message-flag',
552`mh-send'." 569`mh-reply-default-reply-to', and `mh-send'."
553 (interactive (list 570 (interactive (list
554 (mh-get-msg-num t) 571 (mh-get-msg-num t)
555 (let ((minibuffer-help-form 572 (let ((minibuffer-help-form
@@ -616,17 +633,19 @@ See also `mh-reply-show-message-flag', `mh-reply-default-reply-to', and
616(defun mh-send (to cc subject) 633(defun mh-send (to cc subject)
617 "Compose a message. 634 "Compose a message.
618 635
619Your letter appears in an Emacs buffer whose mode is MH-Letter (see 636Your letter appears in an Emacs buffer whose mode is
620`mh-letter-mode'). 637MH-Letter (see `mh-letter-mode').
621 638
622The arguments TO, CC, and SUBJECT can be used to prefill the draft fields or 639The arguments TO, CC, and SUBJECT can be used to prefill the
623suppress the prompts if `mh-compose-prompt-flag' is on. They are also passed 640draft fields or suppress the prompts if `mh-compose-prompt-flag'
624to the function set in the option `mh-compose-letter-function'. 641is on. They are also passed to the function set in the option
642`mh-compose-letter-function'.
625 643
626See also `mh-insert-x-mailer-flag' and `mh-letter-mode-hook'. 644See also `mh-insert-x-mailer-flag' and `mh-letter-mode-hook'.
627 645
628Outside of an MH-Folder buffer (`mh-folder-mode'), you must call either 646Outside of an MH-Folder buffer (`mh-folder-mode'), you must call
629\\[mh-smail] or \\[mh-smail-other-window] to compose a new message." 647either \\[mh-smail] or \\[mh-smail-other-window] to compose a new
648message."
630 (interactive (list 649 (interactive (list
631 (mh-interactive-read-address "To: ") 650 (mh-interactive-read-address "To: ")
632 (mh-interactive-read-address "Cc: ") 651 (mh-interactive-read-address "Cc: ")
@@ -639,8 +658,8 @@ Outside of an MH-Folder buffer (`mh-folder-mode'), you must call either
639(defun mh-send-other-window (to cc subject) 658(defun mh-send-other-window (to cc subject)
640 "Compose a message in another window. 659 "Compose a message in another window.
641 660
642See `mh-send' for more information and a description of how the TO, CC, and 661See `mh-send' for more information and a description of how the
643SUBJECT arguments are used." 662TO, CC, and SUBJECT arguments are used."
644 (interactive (list 663 (interactive (list
645 (mh-interactive-read-address "To: ") 664 (mh-interactive-read-address "To: ")
646 (mh-interactive-read-address "Cc: ") 665 (mh-interactive-read-address "Cc: ")
@@ -690,14 +709,16 @@ CONFIG is the window configuration before sending mail."
690 709
691(defun mh-read-draft (use initial-contents delete-contents-file) 710(defun mh-read-draft (use initial-contents delete-contents-file)
692 "Read draft file into a draft buffer and make that buffer the current one. 711 "Read draft file into a draft buffer and make that buffer the current one.
693USE is a message used for prompting about the intended use of the message. 712
713USE is a message used for prompting about the intended use of the
714message.
694INITIAL-CONTENTS is filename that is read into an empty buffer, or nil 715INITIAL-CONTENTS is filename that is read into an empty buffer, or nil
695if buffer should not be modified. Delete the initial-contents file if 716if buffer should not be modified. Delete the initial-contents file if
696DELETE-CONTENTS-FILE flag is set. 717DELETE-CONTENTS-FILE flag is set.
697Returns the draft folder's name. 718Returns the draft folder's name.
698If the draft folder facility is enabled in ~/.mh_profile, a new buffer is 719If the draft folder facility is enabled in ~/.mh_profile, a new buffer
699used each time and saved in the draft folder. The draft file can then be 720is used each time and saved in the draft folder. The draft file can
700reused." 721then be reused."
701 (cond (mh-draft-folder 722 (cond (mh-draft-folder
702 (let ((orig-default-dir default-directory) 723 (let ((orig-default-dir default-directory)
703 (draft-file-name (mh-new-draft-name))) 724 (draft-file-name (mh-new-draft-name)))
@@ -745,7 +766,8 @@ reused."
745 766
746(defun mh-annotate-msg (msg buffer note &rest args) 767(defun mh-annotate-msg (msg buffer note &rest args)
747 "Mark MSG in BUFFER with character NOTE and annotate message with ARGS. 768 "Mark MSG in BUFFER with character NOTE and annotate message with ARGS.
748MSG can be a message number, a list of message numbers, or a sequence." 769MSG can be a message number, a list of message numbers, or a
770sequence."
749 (apply 'mh-exec-cmd "anno" buffer 771 (apply 'mh-exec-cmd "anno" buffer
750 (if (listp msg) (append msg args) (cons msg args))) 772 (if (listp msg) (append msg args) (cons msg args)))
751 (save-excursion 773 (save-excursion
@@ -777,7 +799,8 @@ Do not insert any pairs whose value is the empty string."
777 "Move to the end of the FIELD in the header. 799 "Move to the end of the FIELD in the header.
778Move to end of entire header if FIELD not found. 800Move to end of entire header if FIELD not found.
779Returns non-nil iff FIELD was found. 801Returns non-nil iff FIELD was found.
780The optional second arg is for pre-version 4 compatibility and is IGNORED." 802The optional second arg is for pre-version 4 compatibility and is
803IGNORED."
781 (cond ((mh-goto-header-field field) 804 (cond ((mh-goto-header-field field)
782 (mh-header-field-end) 805 (mh-header-field-end)
783 t) 806 t)
@@ -904,20 +927,21 @@ Returns t if found, nil if not."
904 "\t\t Signature: \\[mh-insert-signature]")) 927 "\t\t Signature: \\[mh-insert-signature]"))
905 "Key binding cheat sheet. 928 "Key binding cheat sheet.
906 929
907This is an associative array which is used to show the most common commands. 930This is an associative array which is used to show the most
908The key is a prefix char. The value is one or more strings which are 931common commands. The key is a prefix char. The value is one or
909concatenated together and displayed in the minibuffer if ? is pressed after 932more strings which are concatenated together and displayed in the
910the prefix character. The special key nil is used to display the 933minibuffer if ? is pressed after the prefix character. The
911non-prefixed commands. 934special key nil is used to display the non-prefixed commands.
912 935
913The substitutions described in `substitute-command-keys' are performed as 936The substitutions described in `substitute-command-keys' are
914well.") 937performed as well.")
915 938
916;;;###mh-autoload 939;;;###mh-autoload
917(defun mh-fill-paragraph-function (arg) 940(defun mh-fill-paragraph-function (arg)
918 "Fill paragraph at or after point. 941 "Fill paragraph at or after point.
919Prefix ARG means justify as well. This function enables `fill-paragraph' to 942Prefix ARG means justify as well. This function enables
920work better in MH-Letter mode (see `mh-letter-mode')." 943`fill-paragraph' to work better in MH-Letter mode (see
944`mh-letter-mode')."
921 (interactive "P") 945 (interactive "P")
922 (let ((fill-paragraph-function) (fill-prefix)) 946 (let ((fill-paragraph-function) (fill-prefix))
923 (if (mh-in-header-p) 947 (if (mh-in-header-p)
@@ -933,18 +957,19 @@ work better in MH-Letter mode (see `mh-letter-mode')."
933 957
934;;;###autoload 958;;;###autoload
935(define-derived-mode mh-letter-mode text-mode "MH-Letter" 959(define-derived-mode mh-letter-mode text-mode "MH-Letter"
936 "Mode for composing letters in MH-E.\\<mh-letter-mode-map> 960 "Mode for composing letters in MH-E\\<mh-letter-mode-map>.
937 961
938When you have finished composing, type \\[mh-send-letter] to send the message 962When you have finished composing, type \\[mh-send-letter] to send
939using the MH mail handling system. 963the message using the MH mail handling system.
940 964
941There are two types of tags used by MH-E when composing MIME messages: MML and 965There are two types of tags used by MH-E when composing MIME
942MH. The option `mh-compose-insertion' controls what type of tags are inserted 966messages: MML and MH. The option `mh-compose-insertion' controls
943by MH-E commands. These tags can be converted to MIME body parts by running 967what type of tags are inserted by MH-E commands. These tags can
944\\[mh-mh-to-mime] for MH-style directives or \\[mh-mml-to-mime] for MML tags. 968be converted to MIME body parts by running \\[mh-mh-to-mime] for
969MH-style directives or \\[mh-mml-to-mime] for MML tags.
945 970
946Options that control this mode can be changed with \\[customize-group]; 971Options that control this mode can be changed with
947specify the \"mh-compose\" group. 972\\[customize-group]; specify the \"mh-compose\" group.
948 973
949When a message is composed, the hooks `text-mode-hook' and 974When a message is composed, the hooks `text-mode-hook' and
950`mh-letter-mode-hook' are run. 975`mh-letter-mode-hook' are run.
@@ -1050,8 +1075,8 @@ When a message is composed, the hooks `text-mode-hook' and
1050 1075
1051(defun mh-letter-header-end () 1076(defun mh-letter-header-end ()
1052 "Find the end of the message header. 1077 "Find the end of the message header.
1053This function is to be used only for font locking. It works by searching for 1078This function is to be used only for font locking. It works by
1054`mh-mail-header-separator' in the buffer." 1079searching for `mh-mail-header-separator' in the buffer."
1055 (save-excursion 1080 (save-excursion
1056 (goto-char (point-min)) 1081 (goto-char (point-min))
1057 (cond ((equal mh-mail-header-separator "") (point-min)) 1082 (cond ((equal mh-mail-header-separator "") (point-min))
@@ -1061,7 +1086,8 @@ This function is to be used only for font locking. It works by searching for
1061 1086
1062(defun mh-auto-fill-for-letter () 1087(defun mh-auto-fill-for-letter ()
1063 "Perform auto-fill for message. 1088 "Perform auto-fill for message.
1064Header is treated specially by inserting a tab before continuation lines." 1089Header is treated specially by inserting a tab before continuation
1090lines."
1065 (if (mh-in-header-p) 1091 (if (mh-in-header-p)
1066 (let ((fill-prefix "\t")) 1092 (let ((fill-prefix "\t"))
1067 (do-auto-fill)) 1093 (do-auto-fill))
@@ -1079,8 +1105,9 @@ Header is treated specially by inserting a tab before continuation lines."
1079(defun mh-to-field () 1105(defun mh-to-field ()
1080 "Move to specified header field. 1106 "Move to specified header field.
1081The field is indicated by the previous keystroke (the last keystroke 1107The field is indicated by the previous keystroke (the last keystroke
1082of the command) according to the list in the variable `mh-to-field-choices'. 1108of the command) according to the list in the variable
1083Create the field if it does not exist. Set the mark to point before moving." 1109`mh-to-field-choices'. Create the field if it does not exist. Set the
1110mark to point before moving."
1084 (interactive) 1111 (interactive)
1085 (expand-abbrev) 1112 (expand-abbrev)
1086 (let ((target (cdr (or (assoc (char-to-string (logior last-input-char ?`)) 1113 (let ((target (cdr (or (assoc (char-to-string (logior last-input-char ?`))
@@ -1109,8 +1136,8 @@ Create the field if it does not exist. Set the mark to point before moving."
1109;;;###mh-autoload 1136;;;###mh-autoload
1110(defun mh-to-fcc (&optional folder) 1137(defun mh-to-fcc (&optional folder)
1111 "Move to \"Fcc:\" header field. 1138 "Move to \"Fcc:\" header field.
1112This command will prompt you for the FOLDER name in which to file a copy of 1139This command will prompt you for the FOLDER name in which to file a
1113the draft." 1140copy of the draft."
1114 (interactive) 1141 (interactive)
1115 (or folder 1142 (or folder
1116 (setq folder (mh-prompt-for-folder 1143 (setq folder (mh-prompt-for-folder
@@ -1143,21 +1170,24 @@ the draft."
1143;;;###mh-autoload 1170;;;###mh-autoload
1144(defun mh-insert-signature (&optional file) 1171(defun mh-insert-signature (&optional file)
1145 "Insert signature in message. 1172 "Insert signature in message.
1173
1146This command inserts your signature at the current cursor location. 1174This command inserts your signature at the current cursor location.
1147 1175
1148By default, the text of your signature is taken from the file 1176By default, the text of your signature is taken from the file
1149\"~/.signature\". You can read from other sources by changing the option 1177\"~/.signature\". You can read from other sources by changing the
1150`mh-signature-file-name' or passing in a signature FILE. 1178option `mh-signature-file-name'.
1179
1180A signature separator (\"-- \") will be added if the signature block
1181does not contain one and `mh-signature-separator-flag' is on.
1151 1182
1152A signature separator (\"-- \") will be added if the signature block does not 1183The hook `mh-insert-signature-hook' is run after the signature is
1153contain one and `mh-signature-separator-flag' is on. 1184inserted. Hook functions may access the actual name of the file or the
1185function used to insert the signature with `mh-signature-file-name'.
1154 1186
1155The value of `mh-insert-signature-hook' is a list of functions to be 1187The signature can also be inserted using Identities (see
1156called, with no arguments, after the signature is inserted. These functions 1188`mh-identity-list').
1157may access the actual name of the file or the function used to insert the
1158signature with `mh-signature-file-name'.
1159 1189
1160The signature can also be inserted using Identities (see `mh-identity-list')" 1190In a program, you can pass in a signature FILE."
1161 (interactive) 1191 (interactive)
1162 (save-excursion 1192 (save-excursion
1163 (insert "\n") 1193 (insert "\n")
@@ -1208,9 +1238,10 @@ The signature can also be inserted using Identities (see `mh-identity-list')"
1208;;;###mh-autoload 1238;;;###mh-autoload
1209(defun mh-check-whom () 1239(defun mh-check-whom ()
1210 "Verify recipients, showing expansion of any aliases. 1240 "Verify recipients, showing expansion of any aliases.
1211This command expands aliases so you can check the actual address(es) in the 1241
1212alias. A new buffer named \"*MH-E Recipients*\" is created with the output of 1242This command expands aliases so you can check the actual address(es)
1213\"whom\"." 1243in the alias. A new buffer named \"*MH-E Recipients*\" is created with
1244the output of \"whom\"."
1214 (interactive) 1245 (interactive)
1215 (let ((file-name buffer-file-name)) 1246 (let ((file-name buffer-file-name))
1216 (save-buffer) 1247 (save-buffer)
@@ -1249,8 +1280,8 @@ If the field already exists, this function does nothing."
1249 1280
1250(defvar mh-x-mailer-string nil 1281(defvar mh-x-mailer-string nil
1251 "*String containing the contents of the X-Mailer header field. 1282 "*String containing the contents of the X-Mailer header field.
1252If nil, this variable is initialized to show the version of MH-E, Emacs, and 1283If nil, this variable is initialized to show the version of MH-E,
1253MH the first time a message is composed.") 1284Emacs, and MH the first time a message is composed.")
1254 1285
1255(defun mh-insert-x-mailer () 1286(defun mh-insert-x-mailer ()
1256 "Append an X-Mailer field to the header. 1287 "Append an X-Mailer field to the header.
@@ -1291,11 +1322,14 @@ The versions of MH-E, Emacs, and MH are shown."
1291;;;###mh-autoload 1322;;;###mh-autoload
1292(defun mh-insert-auto-fields (&optional non-interactive) 1323(defun mh-insert-auto-fields (&optional non-interactive)
1293 "Insert custom fields if recipient is found in `mh-auto-fields-list'. 1324 "Insert custom fields if recipient is found in `mh-auto-fields-list'.
1294Sets buffer-local `mh-insert-auto-fields-done-local' when done and inserted
1295something. If NON-INTERACTIVE is non-nil, do not be verbose and only
1296attempt matches if `mh-insert-auto-fields-done-local' is nil.
1297 1325
1298An `identity' entry is skipped if one was already entered manually. 1326Sets buffer-local `mh-insert-auto-fields-done-local' when done
1327and inserted something. If NON-INTERACTIVE is non-nil, do not be
1328verbose and only attempt matches if
1329`mh-insert-auto-fields-done-local' is nil.
1330
1331An `identity' entry is skipped if one was already entered
1332manually.
1299 1333
1300Return t if fields added; otherwise return nil." 1334Return t if fields added; otherwise return nil."
1301 (interactive) 1335 (interactive)
@@ -1336,7 +1370,8 @@ Return t if fields added; otherwise return nil."
1336 1370
1337(defun mh-modify-header-field (field value &optional overwrite-flag) 1371(defun mh-modify-header-field (field value &optional overwrite-flag)
1338 "To header FIELD add VALUE. 1372 "To header FIELD add VALUE.
1339If OVERWRITE-FLAG is non-nil then the old value, if present, is discarded." 1373If OVERWRITE-FLAG is non-nil then the old value, if present, is
1374discarded."
1340 (cond ((and overwrite-flag 1375 (cond ((and overwrite-flag
1341 (mh-goto-header-field (concat field ":"))) 1376 (mh-goto-header-field (concat field ":")))
1342 (insert " " value) 1377 (insert " " value)
@@ -1359,15 +1394,16 @@ If OVERWRITE-FLAG is non-nil then the old value, if present, is discarded."
1359 config) 1394 config)
1360 "Edit and compose a draft message in buffer DRAFT and send or save it. 1395 "Edit and compose a draft message in buffer DRAFT and send or save it.
1361SEND-ARGS is the argument passed to the send command. 1396SEND-ARGS is the argument passed to the send command.
1362SENT-FROM-FOLDER is buffer containing scan listing of current folder, or 1397SENT-FROM-FOLDER is buffer containing scan listing of current folder,
1363nil if none exists. 1398or nil if none exists.
1364SENT-FROM-MSG is the message number or sequence name or nil. 1399SENT-FROM-MSG is the message number or sequence name or nil.
1365The TO, SUBJECT, and CC fields are passed to the 1400The TO, SUBJECT, and CC fields are passed to the
1366`mh-compose-letter-function'. 1401`mh-compose-letter-function'.
1367If ANNOTATE-CHAR is non-null, it is used to notate the scan listing of the 1402If ANNOTATE-CHAR is non-null, it is used to notate the scan listing of
1368message. In that case, the ANNOTATE-FIELD is used to build a string 1403the message. In that case, the ANNOTATE-FIELD is used to build a
1369for `mh-annotate-msg'. 1404string for `mh-annotate-msg'.
1370CONFIG is the window configuration to restore after sending the letter." 1405CONFIG is the window configuration to restore after sending the
1406letter."
1371 (pop-to-buffer draft) 1407 (pop-to-buffer draft)
1372 (mh-letter-mode) 1408 (mh-letter-mode)
1373 1409
@@ -1414,8 +1450,8 @@ This should be the last function called when composing the draft."
1414 1450
1415(defun mh-ascii-buffer-p () 1451(defun mh-ascii-buffer-p ()
1416 "Check if current buffer is entirely composed of ASCII. 1452 "Check if current buffer is entirely composed of ASCII.
1417The function doesn't work for XEmacs since `find-charset-region' doesn't exist 1453The function doesn't work for XEmacs since `find-charset-region'
1418there." 1454doesn't exist there."
1419 (loop for charset in (mh-funcall-if-exists 1455 (loop for charset in (mh-funcall-if-exists
1420 find-charset-region (point-min) (point-max)) 1456 find-charset-region (point-min) (point-max))
1421 unless (eq charset 'ascii) return nil 1457 unless (eq charset 'ascii) return nil
@@ -1424,16 +1460,18 @@ there."
1424;;;###mh-autoload 1460;;;###mh-autoload
1425(defun mh-send-letter (&optional arg) 1461(defun mh-send-letter (&optional arg)
1426 "Save draft and send message. 1462 "Save draft and send message.
1427When you are all through editing a message, you send it with this command. You
1428can give an argument ARG to monitor the first stage of the delivery\; this
1429output can be found in a buffer called \"*MH-E Mail Delivery*\".
1430 1463
1431The value of `mh-before-send-letter-hook' is a list of functions to be called 1464When you are all through editing a message, you send it with this
1432at the beginning of this command. For example, if you want to check your 1465command. You can give a prefix argument ARG to monitor the first stage
1433spelling in your message before sending, add the `ispell-message' function. 1466of the delivery\; this output can be found in a buffer called \"*MH-E
1467Mail Delivery*\".
1434 1468
1435In case the MH \"send\" program is installed under a different name, use 1469The hook `mh-before-send-letter-hook' is run at the beginning of the
1436`mh-send-prog' to tell MH-E the name." 1470this command. For example, if you want to check your spelling in your
1471message before sending, add the `ispell-message' function.
1472
1473In case the MH \"send\" program is installed under a different name,
1474use `mh-send-prog' to tell MH-E the name."
1437 (interactive "P") 1475 (interactive "P")
1438 (run-hooks 'mh-before-send-letter-hook) 1476 (run-hooks 'mh-before-send-letter-hook)
1439 (if (and (mh-insert-auto-fields t) 1477 (if (and (mh-insert-auto-fields t)
@@ -1500,15 +1538,17 @@ In case the MH \"send\" program is installed under a different name, use
1500;;;###mh-autoload 1538;;;###mh-autoload
1501(defun mh-insert-letter (folder message verbatim) 1539(defun mh-insert-letter (folder message verbatim)
1502 "Insert a message. 1540 "Insert a message.
1503This command prompts you for the FOLDER and MESSAGE number and inserts the 1541
1504message, indented by `mh-ins-buf-prefix' (\"> \") unless `mh-yank-behavior' is 1542This command prompts you for the FOLDER and MESSAGE number and inserts
1505set to one of the supercite flavors in which case supercite is used to format 1543the message, indented by `mh-ins-buf-prefix' (\"> \") unless
1506the message. Certain undesirable header fields (see 1544`mh-yank-behavior' is set to one of the supercite flavors in which
1507`mh-invisible-header-fields-compiled') are removed before insertion. 1545case supercite is used to format the message. Certain undesirable
1508 1546header fields (see `mh-invisible-header-fields-compiled') are removed
1509If given a prefix argument VERBATIM, the header is left intact, the message is 1547before insertion.
1510not indented, and \"> \" is not inserted before each line. This command leaves 1548
1511the mark before the letter and point after it." 1549If given a prefix argument VERBATIM, the header is left intact, the
1550message is not indented, and \"> \" is not inserted before each line.
1551This command leaves the mark before the letter and point after it."
1512 (interactive 1552 (interactive
1513 (list (mh-prompt-for-folder "Message from" mh-sent-from-folder nil) 1553 (list (mh-prompt-for-folder "Message from" mh-sent-from-folder nil)
1514 (read-string (concat "Message number" 1554 (read-string (concat "Message number"
@@ -1550,24 +1590,34 @@ the mark before the letter and point after it."
1550(defun mh-yank-cur-msg () 1590(defun mh-yank-cur-msg ()
1551 "Insert the current message into the draft buffer. 1591 "Insert the current message into the draft buffer.
1552 1592
1553It is often useful to insert a snippet of text from a letter that someone 1593It is often useful to insert a snippet of text from a letter that
1554mailed to provide some context for your reply. This command does this by 1594someone mailed to provide some context for your reply. This
1555adding an attribution, yanking a portion of text from the message to which 1595command does this by adding an attribution, yanking a portion of
1556you're replying, and inserting `mh-ins-buf-prefix' (`> ') before each line. 1596text from the message to which you're replying, and inserting
1597`mh-ins-buf-prefix' (`> ') before each line.
1557 1598
1558The attribution consists of the sender's name and email address 1599The attribution consists of the sender's name and email address
1559followed by the content of the `mh-extract-from-attribution-verb' 1600followed by the content of the `mh-extract-from-attribution-verb'
1560option. 1601option.
1561 1602
1562You can also turn on the `mh-delete-yanked-msg-window-flag' option to delete 1603You can also turn on the `mh-delete-yanked-msg-window-flag'
1563the window containing the original message after yanking it to make more room 1604option to delete the window containing the original message after
1564on your screen for your reply. 1605yanking it to make more room on your screen for your reply.
1565 1606
1566You can control how the message to which you are replying is yanked 1607You can control how the message to which you are replying is
1567into your reply using `mh-yank-behavior'. 1608yanked into your reply using `mh-yank-behavior'.
1568 1609
1569If this isn't enough, you can gain full control over the appearance of the 1610If this isn't enough, you can gain full control over the
1570included text by setting `mail-citation-hook' to a function that modifies it." 1611appearance of the included text by setting `mail-citation-hook'
1612to a function that modifies it. For example, if you set this hook
1613to `trivial-cite' (which is NOT part of Emacs), set
1614`mh-yank-behavior' to \"Body and Header\" (see URL
1615`http://shasta.cs.uiuc.edu/~lrclause/tc.html').
1616
1617Note that if `mail-citation-hook' is set, `mh-ins-buf-prefix' is
1618not inserted. If the option `mh-yank-behavior' is set to one of
1619the supercite flavors, the hook `mail-citation-hook' is ignored
1620and `mh-ins-buf-prefix' is not inserted."
1571 (interactive) 1621 (interactive)
1572 (if (and mh-sent-from-folder 1622 (if (and mh-sent-from-folder
1573 (save-excursion (set-buffer mh-sent-from-folder) mh-show-buffer) 1623 (save-excursion (set-buffer mh-sent-from-folder) mh-show-buffer)
@@ -1660,9 +1710,9 @@ included text by setting `mail-citation-hook' to a function that modifies it."
1660 1710
1661(defun mh-insert-prefix-string (mh-ins-string) 1711(defun mh-insert-prefix-string (mh-ins-string)
1662 "Insert prefix string before each line in buffer. 1712 "Insert prefix string before each line in buffer.
1663The inserted letter is cited using `sc-cite-original' if `mh-yank-behavior' is 1713The inserted letter is cited using `sc-cite-original' if
1664one of 'supercite or 'autosupercite. Otherwise, simply insert MH-INS-STRING 1714`mh-yank-behavior' is one of 'supercite or 'autosupercite.
1665before each line." 1715Otherwise, simply insert MH-INS-STRING before each line."
1666 (goto-char (point-min)) 1716 (goto-char (point-min))
1667 (cond ((or (eq mh-yank-behavior 'supercite) 1717 (cond ((or (eq mh-yank-behavior 'supercite)
1668 (eq mh-yank-behavior 'autosupercite)) 1718 (eq mh-yank-behavior 'autosupercite))
@@ -1681,9 +1731,10 @@ before each line."
1681;;;###mh-autoload 1731;;;###mh-autoload
1682(defun mh-fully-kill-draft () 1732(defun mh-fully-kill-draft ()
1683 "Quit editing and delete draft message. 1733 "Quit editing and delete draft message.
1684If for some reason you are not happy with the draft, you can use the this 1734If for some reason you are not happy with the draft, you can use
1685command to kill the draft buffer and delete the draft message. Use the 1735the this command to kill the draft buffer and delete the draft
1686\\[kill-buffer] command if you don't want to delete the draft message." 1736message. Use the \\[kill-buffer] command if you don't want to
1737delete the draft message."
1687 (interactive) 1738 (interactive)
1688 (if (y-or-n-p "Kill draft message? ") 1739 (if (y-or-n-p "Kill draft message? ")
1689 (let ((config mh-previous-window-config)) 1740 (let ((config mh-previous-window-config))
@@ -1711,10 +1762,12 @@ command to kill the draft buffer and delete the draft message. Use the
1711;;;###mh-autoload 1762;;;###mh-autoload
1712(defun mh-open-line () 1763(defun mh-open-line ()
1713 "Insert a newline and leave point after it. 1764 "Insert a newline and leave point after it.
1714This command is similar to the \\[open-line] command in that it inserts a 1765
1715newline after point. It differs in that it also inserts the right number of 1766This command is similar to the \\[open-line] command in that it
1716quoting characters and spaces so that the next line begins in the same column 1767inserts a newline after point. It differs in that it also inserts
1717as it was. This is useful when breaking up paragraphs in replies." 1768the right number of quoting characters and spaces so that the
1769next line begins in the same column as it was. This is useful
1770when breaking up paragraphs in replies."
1718 (interactive) 1771 (interactive)
1719 (let ((column (current-column)) 1772 (let ((column (current-column))
1720 (prefix (mh-current-fill-prefix))) 1773 (prefix (mh-current-fill-prefix)))
@@ -1731,9 +1784,9 @@ as it was. This is useful when breaking up paragraphs in replies."
1731(defmacro mh-display-completion-list-compat (word choices) 1784(defmacro mh-display-completion-list-compat (word choices)
1732 "Completes WORD from CHOICES using `display-completion-list'. 1785 "Completes WORD from CHOICES using `display-completion-list'.
1733Calls `display-completion-list' correctly in older environments. 1786Calls `display-completion-list' correctly in older environments.
1734Versions of Emacs prior to version 22 lacked a COMMON-SUBSTRING argument 1787Versions of Emacs prior to version 22 lacked a COMMON-SUBSTRING
1735which is used to highlight the next possible character you can enter 1788argument which is used to highlight the next possible character you
1736in the current list of completions." 1789can enter in the current list of completions."
1737 (if (>= emacs-major-version 22) 1790 (if (>= emacs-major-version 22)
1738 `(display-completion-list (all-completions ,word ,choices) ,word) 1791 `(display-completion-list (all-completions ,word ,choices) ,word)
1739 `(display-completion-list (all-completions ,word ,choices)))) 1792 `(display-completion-list (all-completions ,word ,choices))))
@@ -1802,11 +1855,12 @@ Any match found replaces the text from BEGIN to END."
1802 1855
1803(defun mh-letter-complete (arg) 1856(defun mh-letter-complete (arg)
1804 "Perform completion on header field or word preceding point. 1857 "Perform completion on header field or word preceding point.
1805If the field contains addresses (for example, \"To:\" or \"Cc:\") or folders 1858If the field contains addresses (for example, \"To:\" or \"Cc:\")
1806\(for example, \"Fcc:\") then this command will provide alias completion. In 1859or folders (for example, \"Fcc:\") then this command will
1807the body of the message, this command runs `mh-letter-complete-function' 1860provide alias completion. In the body of the message, this
1808instead, which is set to \"'ispell-complete-word\" by default. This command 1861command runs `mh-letter-complete-function' instead, which is set
1809takes a prefix argument ARG that is passed to the 1862to \"'ispell-complete-word\" by default. This command takes a
1863prefix argument ARG that is passed to the
1810`mh-letter-complete-function'." 1864`mh-letter-complete-function'."
1811 (interactive "P") 1865 (interactive "P")
1812 (let ((func nil)) 1866 (let ((func nil))
@@ -1819,8 +1873,9 @@ takes a prefix argument ARG that is passed to the
1819 1873
1820(defun mh-letter-complete-or-space (arg) 1874(defun mh-letter-complete-or-space (arg)
1821 "Perform completion or insert space. 1875 "Perform completion or insert space.
1822Turn on the `mh-compose-space-does-completion-flag' option to use this command 1876Turn on the `mh-compose-space-does-completion-flag' option to use
1823to perform completion in the header. Otherwise, a space is inserted. 1877this command to perform completion in the header. Otherwise, a
1878space is inserted.
1824 1879
1825ARG is the number of spaces inserted." 1880ARG is the number of spaces inserted."
1826 (interactive "p") 1881 (interactive "p")
@@ -1839,9 +1894,9 @@ ARG is the number of spaces inserted."
1839 1894
1840(defun mh-letter-confirm-address () 1895(defun mh-letter-confirm-address ()
1841 "Flash alias expansion. 1896 "Flash alias expansion.
1842Addresses are separated by a comma\; and when you press the comma, this 1897Addresses are separated by a comma\; and when you press the
1843command flashes the alias expansion in the minibuffer if 1898comma, this command flashes the alias expansion in the minibuffer
1844`mh-alias-flash-on-comma' is turned on." 1899if `mh-alias-flash-on-comma' is turned on."
1845 (interactive) 1900 (interactive)
1846 (cond ((not (mh-in-header-p)) (self-insert-command 1)) 1901 (cond ((not (mh-in-header-p)) (self-insert-command 1))
1847 ((eq (cdr (assoc (mh-letter-header-field-at-point) 1902 ((eq (cdr (assoc (mh-letter-header-field-at-point)
@@ -1855,8 +1910,8 @@ command flashes the alias expansion in the minibuffer if
1855 1910
1856(defun mh-letter-header-field-at-point () 1911(defun mh-letter-header-field-at-point ()
1857 "Return the header field name at point. 1912 "Return the header field name at point.
1858A symbol is returned whose name is the string obtained by downcasing the field 1913A symbol is returned whose name is the string obtained by
1859name." 1914downcasing the field name."
1860 (save-excursion 1915 (save-excursion
1861 (end-of-line) 1916 (end-of-line)
1862 (and (re-search-backward mh-letter-header-field-regexp nil t) 1917 (and (re-search-backward mh-letter-header-field-regexp nil t)
@@ -1865,12 +1920,13 @@ name."
1865;;;###mh-autoload 1920;;;###mh-autoload
1866(defun mh-letter-next-header-field-or-indent (arg) 1921(defun mh-letter-next-header-field-or-indent (arg)
1867 "Move to next field or indent depending on point. 1922 "Move to next field or indent depending on point.
1868Within the header of the message, this command moves between fields, but skips 1923Within the header of the message, this command moves between
1869those fields listed in `mh-compose-skipped-header-fields'. After the last 1924fields, but skips those fields listed in
1870field, this command then moves point to the message body before cycling back 1925`mh-compose-skipped-header-fields'. After the last field, this
1871to the first field. If point is already past the first line of the message 1926command then moves point to the message body before cycling back
1872body, then this command indents by calling `indent-relative' with the given 1927to the first field. If point is already past the first line of
1873prefix argument ARG." 1928the message body, then this command indents by calling
1929`indent-relative' with the given prefix argument ARG."
1874 (interactive "P") 1930 (interactive "P")
1875 (let ((header-end (save-excursion 1931 (let ((header-end (save-excursion
1876 (goto-char (mh-mail-header-end)) 1932 (goto-char (mh-mail-header-end))
@@ -1882,7 +1938,8 @@ prefix argument ARG."
1882 1938
1883(defun mh-letter-next-header-field () 1939(defun mh-letter-next-header-field ()
1884 "Cycle to the next header field. 1940 "Cycle to the next header field.
1885If we are at the last header field go to the start of the message body." 1941If we are at the last header field go to the start of the message
1942body."
1886 (let ((header-end (mh-mail-header-end))) 1943 (let ((header-end (mh-mail-header-end)))
1887 (cond ((>= (point) header-end) (goto-char (point-min))) 1944 (cond ((>= (point) header-end) (goto-char (point-min)))
1888 ((< (point) (progn 1945 ((< (point) (progn
@@ -1902,10 +1959,10 @@ If we are at the last header field go to the start of the message body."
1902;;;###mh-autoload 1959;;;###mh-autoload
1903(defun mh-letter-previous-header-field () 1960(defun mh-letter-previous-header-field ()
1904 "Cycle to the previous header field. 1961 "Cycle to the previous header field.
1905This command moves backwards between the fields and cycles to the body of the 1962This command moves backwards between the fields and cycles to the
1906message after the first field. Unlike the 1963body of the message after the first field. Unlike the
1907\\[mh-letter-next-header-field-or-indent] command, it will always take point 1964\\[mh-letter-next-header-field-or-indent] command, it will always
1908to the last field from anywhere in the body." 1965take point to the last field from anywhere in the body."
1909 (interactive) 1966 (interactive)
1910 (let ((header-end (mh-mail-header-end))) 1967 (let ((header-end (mh-mail-header-end)))
1911 (if (>= (point) header-end) 1968 (if (>= (point) header-end)
@@ -1928,8 +1985,8 @@ to the last field from anywhere in the body."
1928 1985
1929(defun mh-letter-skip-leading-whitespace-in-header-field () 1986(defun mh-letter-skip-leading-whitespace-in-header-field ()
1930 "Skip leading whitespace in a header field. 1987 "Skip leading whitespace in a header field.
1931If the header field doesn't have at least one space after the colon then a 1988If the header field doesn't have at least one space after the
1932space character is added." 1989colon then a space character is added."
1933 (let ((need-space t)) 1990 (let ((need-space t))
1934 (while (memq (char-after) '(?\t ?\ )) 1991 (while (memq (char-after) '(?\t ?\ ))
1935 (forward-char) 1992 (forward-char)
@@ -1947,8 +2004,9 @@ space character is added."
1947 2004
1948(defun mh-letter-toggle-header-field-display-button (event) 2005(defun mh-letter-toggle-header-field-display-button (event)
1949 "Toggle header field display at location of EVENT. 2006 "Toggle header field display at location of EVENT.
1950This function does the same thing as `mh-letter-toggle-header-field-display' 2007This function does the same thing as
1951except that it is callable from a mouse button." 2008`mh-letter-toggle-header-field-display' except that it is
2009callable from a mouse button."
1952 (interactive "e") 2010 (interactive "e")
1953 (mh-do-at-event-location event 2011 (mh-do-at-event-location event
1954 (mh-letter-toggle-header-field-display nil))) 2012 (mh-letter-toggle-header-field-display nil)))
@@ -1956,10 +2014,10 @@ except that it is callable from a mouse button."
1956(defun mh-letter-toggle-header-field-display (arg) 2014(defun mh-letter-toggle-header-field-display (arg)
1957 "Toggle display of header field at point. 2015 "Toggle display of header field at point.
1958 2016
1959Use this command to display truncated header fields. This command is a toggle 2017Use this command to display truncated header fields. This command
1960so entering it again will hide the field. This command takes a prefix argument 2018is a toggle so entering it again will hide the field. This
1961ARG: if negative then the field is hidden, if positive then the field is 2019command takes a prefix argument ARG: if negative then the field
1962displayed." 2020is hidden, if positive then the field is displayed."
1963 (interactive (list nil)) 2021 (interactive (list nil))
1964 (when (and (mh-in-header-p) 2022 (when (and (mh-in-header-p)
1965 (progn 2023 (progn
@@ -2019,13 +2077,15 @@ If the current line is too long truncate a part of it as well."
2019 2077
2020(defun mh-interactive-read-address (prompt) 2078(defun mh-interactive-read-address (prompt)
2021 "Read an address. 2079 "Read an address.
2022If `mh-compose-prompt-flag' is non-nil, then read an address with PROMPT. 2080If `mh-compose-prompt-flag' is non-nil, then read an address with
2081PROMPT.
2023Otherwise return the empty string." 2082Otherwise return the empty string."
2024 (if mh-compose-prompt-flag (mh-read-address prompt) "")) 2083 (if mh-compose-prompt-flag (mh-read-address prompt) ""))
2025 2084
2026(defun mh-interactive-read-string (prompt) 2085(defun mh-interactive-read-string (prompt)
2027 "Read a string. 2086 "Read a string.
2028If `mh-compose-prompt-flag' is non-nil, then read a string with PROMPT. 2087If `mh-compose-prompt-flag' is non-nil, then read a string with
2088PROMPT.
2029Otherwise return the empty string." 2089Otherwise return the empty string."
2030 (if mh-compose-prompt-flag (read-string prompt) "")) 2090 (if mh-compose-prompt-flag (read-string prompt) ""))
2031 2091
diff --git a/lisp/mh-e/mh-customize.el b/lisp/mh-e/mh-customize.el
index 0e22e38a742..f5556bda2ba 100644
--- a/lisp/mh-e/mh-customize.el
+++ b/lisp/mh-e/mh-customize.el
@@ -90,8 +90,8 @@
90 90
91(defun mh-customize (&optional delete-other-windows-flag) 91(defun mh-customize (&optional delete-other-windows-flag)
92 "Customize MH-E variables. 92 "Customize MH-E variables.
93If optional argument DELETE-OTHER-WINDOWS-FLAG is non-nil, other windows in 93If optional argument DELETE-OTHER-WINDOWS-FLAG is non-nil, other
94the frame are removed." 94windows in the frame are removed."
95 (interactive "P") 95 (interactive "P")
96 (customize-group 'mh-e) 96 (customize-group 'mh-e)
97 (when delete-other-windows-flag 97 (when delete-other-windows-flag
@@ -103,8 +103,8 @@ the frame are removed."
103 103
104(defgroup mh-e nil 104(defgroup mh-e nil
105 "Emacs interface to the MH mail system. 105 "Emacs interface to the MH mail system.
106MH is the Rand Mail Handler. Other implementations include nmh and GNU 106MH is the Rand Mail Handler. Other implementations include nmh
107mailutils." 107and GNU mailutils."
108 :link '(custom-manual "(mh-e)Top") 108 :link '(custom-manual "(mh-e)Top")
109 :group 'mail) 109 :group 'mail)
110 110
@@ -271,12 +271,14 @@ See `mh-variant'."
271(defcustom mh-variant 'autodetect 271(defcustom mh-variant 'autodetect
272 "*Specifies the variant used by MH-E. 272 "*Specifies the variant used by MH-E.
273 273
274The default setting of this option is `Auto-detect' which means that MH-E will 274The default setting of this option is \"Auto-detect\" which means
275automatically choose the first of nmh, MH, or GNU mailutils that it finds in 275that MH-E will automatically choose the first of nmh, MH, or GNU
276the directories listed in `mh-path' (which you can customize), `mh-sys-path', 276mailutils that it finds in the directories listed in
277and `exec-path'. If, for example, you have both nmh and mailutils installed 277`mh-path' (which you can customize), `mh-sys-path', and
278and `mh-variant-in-use' was initialized to nmh but you want to use mailutils, 278`exec-path'. If, for example, you have both nmh and mailutils
279then you can set this option to `mailutils'. 279installed and `mh-variant-in-use' was initialized to nmh but you
280want to use mailutils, then you can set this option to
281\"mailutils\".
280 282
281When this variable is changed, MH-E resets `mh-progs', `mh-lib', 283When this variable is changed, MH-E resets `mh-progs', `mh-lib',
282`mh-lib-progs', `mh-flists-present-flag', and `mh-variant-in-use' 284`mh-lib-progs', `mh-flists-present-flag', and `mh-variant-in-use'
@@ -295,26 +297,30 @@ accordingly."
295 297
296(defcustom mh-alias-completion-ignore-case-flag t 298(defcustom mh-alias-completion-ignore-case-flag t
297 "*Non-nil means don't consider case significant in MH alias completion. 299 "*Non-nil means don't consider case significant in MH alias completion.
298As MH ignores case in the aliases, so too does MH-E. However, you may turn 300
299this option off to make case significant which can be used to segregate 301As MH ignores case in the aliases, so too does MH-E. However, you
300completion of your aliases. You might use lowercase for mailing lists and 302may turn this option off to make case significant which can be
301uppercase for people." 303used to segregate completion of your aliases. You might use
304lowercase for mailing lists and uppercase for people."
302 :type 'boolean 305 :type 'boolean
303 :group 'mh-alias) 306 :group 'mh-alias)
304 307
305(defcustom mh-alias-expand-aliases-flag nil 308(defcustom mh-alias-expand-aliases-flag nil
306 "*Non-nil means to expand aliases entered in the minibuffer. 309 "*Non-nil means to expand aliases entered in the minibuffer.
307In other words, aliases entered in the minibuffer will be expanded to the full 310
308address in the message draft. By default, this expansion is not performed." 311In other words, aliases entered in the minibuffer will be
312expanded to the full address in the message draft. By default,
313this expansion is not performed."
309 :type 'boolean 314 :type 'boolean
310 :group 'mh-alias) 315 :group 'mh-alias)
311 316
312(defcustom mh-alias-flash-on-comma t 317(defcustom mh-alias-flash-on-comma t
313 "*Specify whether to flash address or warn on translation. 318 "*Specify whether to flash address or warn on translation.
314This option controls the behavior when a [comma] is pressed while entering 319
315aliases or addresses. The default setting flashes the address associated with 320This option controls the behavior when a [comma] is pressed while
316an address in the minibuffer briefly, but does not display a warning if the 321entering aliases or addresses. The default setting flashes the
317alias is not found." 322address associated with an address in the minibuffer briefly, but
323does not display a warning if the alias is not found."
318 :type '(choice (const :tag "Flash but Don't Warn If No Alias" t) 324 :type '(choice (const :tag "Flash but Don't Warn If No Alias" t)
319 (const :tag "Flash and Warn If No Alias" 1) 325 (const :tag "Flash and Warn If No Alias" 1)
320 (const :tag "Don't Flash Nor Warn If No Alias" nil)) 326 (const :tag "Don't Flash Nor Warn If No Alias" nil))
@@ -322,11 +328,12 @@ alias is not found."
322 328
323(defcustom mh-alias-insert-file nil 329(defcustom mh-alias-insert-file nil
324 "*Filename used to store a new MH-E alias. 330 "*Filename used to store a new MH-E alias.
325The default setting of this option is `Use Aliasfile Profile Component'. This 331
326option can also hold the name of a file or a list a file names. If this option 332The default setting of this option is \"Use Aliasfile Profile
327is set to a list of file names, or the `Aliasfile:' profile component contains 333Component\". This option can also hold the name of a file or a
328more than one file name, MH-E will prompt for one of them when MH-E adds an 334list a file names. If this option is set to a list of file names,
329alias." 335or the \"Aliasfile:\" profile component contains more than one file
336name, MH-E will prompt for one of them when MH-E adds an alias."
330 :type '(choice (const :tag "Use Aliasfile Profile Component" nil) 337 :type '(choice (const :tag "Use Aliasfile Profile Component" nil)
331 (file :tag "Alias File") 338 (file :tag "Alias File")
332 (repeat :tag "List of Alias Files" file)) 339 (repeat :tag "List of Alias Files" file))
@@ -334,9 +341,10 @@ alias."
334 341
335(defcustom mh-alias-insertion-location 'sorted 342(defcustom mh-alias-insertion-location 'sorted
336 "Specifies where new aliases are entered in alias files. 343 "Specifies where new aliases are entered in alias files.
337This option is set to `Alphabetical' by default. If you organize your alias 344
338file in other ways, then adding aliases to the `Top' or `Bottom' of your alias 345This option is set to \"Alphabetical\" by default. If you organize
339file might be more appropriate." 346your alias file in other ways, then adding aliases to the \"Top\"
347or \"Bottom\" of your alias file might be more appropriate."
340 :type '(choice (const :tag "Alphabetical" sorted) 348 :type '(choice (const :tag "Alphabetical" sorted)
341 (const :tag "Top" top) 349 (const :tag "Top" top)
342 (const :tag "Bottom" bottom)) 350 (const :tag "Bottom" bottom))
@@ -345,46 +353,52 @@ file might be more appropriate."
345(defcustom mh-alias-local-users t 353(defcustom mh-alias-local-users t
346 "*If on, local users are added to alias completion. 354 "*If on, local users are added to alias completion.
347 355
348Aliases are created from `/etc/passwd' entries with a user ID larger than 356Aliases are created from \"/etc/passwd\" entries with a user ID
349a magical number, typically 200. This can be a handy tool on a machine where 357larger than a magical number, typically 200. This can be a handy
350you and co-workers exchange messages. These aliases have the form 358tool on a machine where you and co-workers exchange messages.
351`local.first.last' if a real name is present in the password file. 359These aliases have the form \"local.first.last\" if a real name is
352Otherwise, the alias will have the form `local.login'. 360present in the password file. Otherwise, the alias will have the
361form \"local.login\".
353 362
354If you're on a system with thousands of users you don't know, and the loading 363If you're on a system with thousands of users you don't know, and
355of local aliases slows MH-E down noticeably, then turn this option off. 364the loading of local aliases slows MH-E down noticeably, then
365turn this option off.
356 366
357This option also takes a string which is executed to generate the password 367This option also takes a string which is executed to generate the
358file. For example, use \"ypcat passwd\" to obtain the NIS password file." 368password file. For example, use \"ypcat passwd\" to obtain the
369NIS password file."
359 :type '(choice (boolean) (string)) 370 :type '(choice (boolean) (string))
360 :group 'mh-alias) 371 :group 'mh-alias)
361 372
362(defcustom mh-alias-local-users-prefix "local." 373(defcustom mh-alias-local-users-prefix "local."
363 "*String prefixed to the real names of users from the password file. 374 "*String prefixed to the real names of users from the password file.
364This option can also be set to `Use Login'. 375This option can also be set to \"Use Login\".
365 376
366For example, consider the following password file entry: 377For example, consider the following password file entry:
367 378
368 psg:x:1000:1000:Peter S Galbraith,,,:/home/psg:/bin/tcsh 379 psg:x:1000:1000:Peter S Galbraith,,,:/home/psg:/bin/tcsh
369 380
370The following settings of this option will produce the associated aliases: 381The following settings of this option will produce the associated
382aliases:
371 383
372 \"local.\" local.peter.galbraith 384 \"local.\" local.peter.galbraith
373 \"\" peter.galbraith 385 \"\" peter.galbraith
374 Use Login psg 386 Use Login psg
375 387
376This option has no effect if variable `mh-alias-local-users' is turned off." 388This option has no effect if variable `mh-alias-local-users' is
389turned off."
377 :type '(choice (const :tag "Use Login" nil) 390 :type '(choice (const :tag "Use Login" nil)
378 (string)) 391 (string))
379 :group 'mh-alias) 392 :group 'mh-alias)
380 393
381(defcustom mh-alias-passwd-gecos-comma-separator-flag t 394(defcustom mh-alias-passwd-gecos-comma-separator-flag t
382 "*Non-nil means the gecos field in the password file uses a comma separator. 395 "*Non-nil means the gecos field in the password file uses a comma separator.
383In the example in `mh-alias-local-users-prefix', commas are used to separate 396
384different values within the so-called gecos field. This is a fairly common 397In the example in `mh-alias-local-users-prefix', commas are used
385usage. However, in the rare case that the gecos field in your password file is 398to separate different values within the so-called gecos field.
386not separated by commas and whose contents may contain commas, you can turn 399This is a fairly common usage. However, in the rare case that the
387this option off." 400gecos field in your password file is not separated by commas and
401whose contents may contain commas, you can turn this option off."
388 :type 'boolean 402 :type 'boolean
389 :group 'mh-alias) 403 :group 'mh-alias)
390 404
@@ -395,9 +409,10 @@ this option off."
395(defcustom mh-new-messages-folders t 409(defcustom mh-new-messages-folders t
396 "Folders searched for the \"unseen\" sequence. 410 "Folders searched for the \"unseen\" sequence.
397 411
398Set this option to \"Inbox\" to search the \"+inbox\" folder or \"All\" to 412Set this option to \"Inbox\" to search the \"+inbox\" folder or
399search all of the top level folders. Otherwise, list the folders that should 413\"All\" to search all of the top level folders. Otherwise, list
400be searched with the \"Choose Folders\" menu item. 414the folders that should be searched with the \"Choose Folders\"
415menu item.
401 416
402See also `mh-recursive-folders-flag'." 417See also `mh-recursive-folders-flag'."
403 :type '(choice (const :tag "Inbox" t) 418 :type '(choice (const :tag "Inbox" t)
@@ -408,9 +423,10 @@ See also `mh-recursive-folders-flag'."
408(defcustom mh-ticked-messages-folders t 423(defcustom mh-ticked-messages-folders t
409 "Folders searched for `mh-tick-seq'. 424 "Folders searched for `mh-tick-seq'.
410 425
411Set this option to \"Inbox\" to search the \"+inbox\" folder or \"All\" to 426Set this option to \"Inbox\" to search the \"+inbox\" folder or
412search all of the top level folders. Otherwise, list the folders that should 427\"All\" to search all of the top level folders. Otherwise, list
413be searched with the \"Choose Folders\" menu item. 428the folders that should be searched with the \"Choose Folders\"
429menu item.
414 430
415See also `mh-recursive-folders-flag'." 431See also `mh-recursive-folders-flag'."
416 :type '(choice (const :tag "Inbox" t) 432 :type '(choice (const :tag "Inbox" t)
@@ -420,17 +436,20 @@ See also `mh-recursive-folders-flag'."
420 436
421(defcustom mh-large-folder 200 437(defcustom mh-large-folder 200
422 "The number of messages that indicates a large folder. 438 "The number of messages that indicates a large folder.
423If a folder is deemed to be large, that is the number of messages in it exceed 439
424this value, then confirmation is needed when it is visited. Even when 440If a folder is deemed to be large, that is the number of messages
425`mh-show-threads-flag' is non-nil, the folder is not automatically threaded, if 441in it exceed this value, then confirmation is needed when it is
426it is large. If set to nil all folders are treated as if they are small." 442visited. Even when `mh-show-threads-flag' is non-nil, the folder
443is not automatically threaded, if it is large. If set to nil all
444folders are treated as if they are small."
427 :type '(choice (const :tag "No Limit") integer) 445 :type '(choice (const :tag "No Limit") integer)
428 :group 'mh-folder) 446 :group 'mh-folder)
429 447
430(defcustom mh-recenter-summary-flag nil 448(defcustom mh-recenter-summary-flag nil
431 "*Non-nil means to recenter the summary window. 449 "*Non-nil means to recenter the summary window.
432If this option is turned on, recenter the summary window when the show window 450
433is toggled off." 451If this option is turned on, recenter the summary window when the
452show window is toggled off."
434 :type 'boolean 453 :type 'boolean
435 :group 'mh-folder) 454 :group 'mh-folder)
436 455
@@ -443,9 +462,10 @@ is toggled off."
443 "*Additional arguments for \"sortm\"\\<mh-folder-mode-map>. 462 "*Additional arguments for \"sortm\"\\<mh-folder-mode-map>.
444 463
445This option is consulted when a prefix argument is used with 464This option is consulted when a prefix argument is used with
446\\[mh-sort-folder]. Normally default arguments to \"sortm\" are specified in 465\\[mh-sort-folder]. Normally default arguments to \"sortm\" are
447the MH profile. This option may be used to provide an alternate view. For 466specified in the MH profile. This option may be used to provide
448example, \"'(\"-nolimit\" \"-textfield\" \"subject\")\" is a useful setting." 467an alternate view. For example, \"'(\"-nolimit\" \"-textfield\"
468\"subject\")\" is a useful setting."
449 :type 'string 469 :type 'string
450 :group 'mh-folder) 470 :group 'mh-folder)
451 471
@@ -454,24 +474,28 @@ example, \"'(\"-nolimit\" \"-textfield\" \"subject\")\" is a useful setting."
454;;; Folder Selection (:group 'mh-folder-selection) 474;;; Folder Selection (:group 'mh-folder-selection)
455 475
456(defcustom mh-default-folder-for-message-function nil 476(defcustom mh-default-folder-for-message-function nil
457 "Function to select a default folder for refiling or `Fcc'. 477 "Function to select a default folder for refiling or \"Fcc\".
458The current buffer is set to the message being refiled with point at the start 478
459of the message. This function should return the default folder as a string 479The current buffer is set to the message being refiled with point
460with a leading `+' sign. It can also return nil so that the last folder name 480at the start of the message. This function should return the
461is used as the default, or an empty string to suppress the default entirely." 481default folder as a string with a leading \"+\" sign. It can also
482return nil so that the last folder name is used as the default,
483or an empty string to suppress the default entirely."
462 :type 'function 484 :type 'function
463 :group 'mh-folder-selection) 485 :group 'mh-folder-selection)
464 486
465(defcustom mh-default-folder-list nil 487(defcustom mh-default-folder-list nil
466 "*List of addresses and folders. 488 "*List of addresses and folders.
467The folder name associated with the first address found in this list is used 489
468as the default for `mh-refile-msg' and similar functions. Each element in this 490The folder name associated with the first address found in this
469list contains a `Check Recipient' item. If this item is turned on, then the 491list is used as the default for `mh-refile-msg' and similar
470address is checked against the recipient instead of the sender. This is useful 492functions. Each element in this list contains a \"Check Recipient\"
471for mailing lists. 493item. If this item is turned on, then the address is checked
472 494against the recipient instead of the sender. This is useful for
473See `mh-prompt-for-refile-folder' and `mh-folder-from-address' for more 495mailing lists.
474information." 496
497See `mh-prompt-for-refile-folder' and `mh-folder-from-address'
498for more information."
475 :type '(repeat (list (regexp :tag "Address") 499 :type '(repeat (list (regexp :tag "Address")
476 (string :tag "Folder") 500 (string :tag "Folder")
477 (boolean :tag "Check Recipient"))) 501 (boolean :tag "Check Recipient")))
@@ -479,13 +503,14 @@ information."
479 503
480(defcustom mh-default-folder-must-exist-flag t 504(defcustom mh-default-folder-must-exist-flag t
481 "*Non-nil means guessed folder name must exist to be used. 505 "*Non-nil means guessed folder name must exist to be used.
482If the derived folder does not exist, and this option is on, then the last
483folder name used is suggested. This is useful if you get mail from various
484people for whom you have an alias, but file them all in the same project
485folder.
486 506
487See `mh-prompt-for-refile-folder' and `mh-folder-from-address' for more 507If the derived folder does not exist, and this option is on, then
488information." 508the last folder name used is suggested. This is useful if you get
509mail from various people for whom you have an alias, but file
510them all in the same project folder.
511
512See `mh-prompt-for-refile-folder' and `mh-folder-from-address'
513for more information."
489 :type 'boolean 514 :type 'boolean
490 :group 'mh-folder-selection) 515 :group 'mh-folder-selection)
491 516
@@ -493,8 +518,8 @@ information."
493 "*Prefix used for folder names generated from aliases. 518 "*Prefix used for folder names generated from aliases.
494The prefix is used to prevent clutter in your mail directory. 519The prefix is used to prevent clutter in your mail directory.
495 520
496See `mh-prompt-for-refile-folder' and `mh-folder-from-address' for more 521See `mh-prompt-for-refile-folder' and `mh-folder-from-address'
497information." 522for more information."
498 :type 'string 523 :type 'string
499 :group 'mh-folder-selection) 524 :group 'mh-folder-selection)
500 525
@@ -505,34 +530,38 @@ information."
505(defcustom mh-identity-list nil 530(defcustom mh-identity-list nil
506 "*List of identities. 531 "*List of identities.
507 532
508To customize this option, click on the `INS' button and enter a label such as 533To customize this option, click on the \"INS\" button and enter a label
509`Home' or `Work'. Then click on the `INS' button with the label `Add at least 534such as \"Home\" or \"Work\". Then click on the \"INS\" button with the
510one item below'. Then choose one of the items in the `Value Menu'. 535label \"Add at least one item below\". Then choose one of the items in
511 536the \"Value Menu\".
512You can specify an alternate `From:' header field using the `From Field' menu 537
513item. You must include a valid email address. A standard format is `First Last 538You can specify an alternate \"From:\" header field using the \"From
514<login@@host.domain>'. If you use an initial with a period, then you must 539Field\" menu item. You must include a valid email address. A standard
515quote your name as in `\"First I. Last\" <login@@host.domain>'. People usually 540format is \"First Last <login@@host.domain>\". If you use an initial
516list the name of the company where they work using the `Organization Field' 541with a period, then you must quote your name as in '\"First I. Last\"
517menu item. Set any arbitrary header field and value in the `Other Field' menu 542<login@@host.domain>'. People usually list the name of the company
518item. Unless the header field is a standard one, precede the name of your 543where they work using the \"Organization Field\" menu item. Set any
519field's label with `X-', as in `X-Fruit-of-the-Day:'. The value of 544arbitrary header field and value in the \"Other Field\" menu item.
520`Attribution Verb' overrides the setting of 545Unless the header field is a standard one, precede the name of your
521`mh-extract-from-attribution-verb'. Set your signature with the `Signature' 546field's label with \"X-\", as in \"X-Fruit-of-the-Day:\". The value of
522menu item. You can specify the contents of `mh-signature-file-name', a file, 547\"Attribution Verb\" overrides the setting of
523or a function. Specify a different key to sign or encrypt messages with the 548`mh-extract-from-attribution-verb'. Set your signature with the
524`GPG Key ID' menu item. 549\"Signature\" menu item. You can specify the contents of
525 550`mh-signature-file-name', a file, or a function. Specify a different
526You can select the identities you have added via the menu called `Identity' in 551key to sign or encrypt messages with the \"GPG Key ID\" menu item.
527the MH-Letter buffer. You can also use \\[mh-insert-identity]. To clear the 552
528fields and signature added by the identity, select the `None' identity. 553You can select the identities you have added via the menu called
529 554\"Identity\" in the MH-Letter buffer. You can also use
530The `Identity' menu contains two other items to save you from having to set 555\\[mh-insert-identity]. To clear the fields and signature added by the
531the identity on every message. The menu item `Set Default for Session' can be 556identity, select the \"None\" identity.
532used to set the default identity to the current identity until you exit Emacs. 557
533The menu item `Save as Default' sets the option `mh-identity-default' to the 558The \"Identity\" menu contains two other items to save you from having
534current identity setting. You can also customize the `mh-identity-default' 559to set the identity on every message. The menu item \"Set Default for
535option in the usual fashion." 560Session\" can be used to set the default identity to the current
561identity until you exit Emacs. The menu item \"Save as Default\" sets
562the option `mh-identity-default' to the current identity setting. You
563can also customize the `mh-identity-default' option in the usual
564fashion."
536 :type '(repeat (list :tag "" 565 :type '(repeat (list :tag ""
537 (string :tag "Label") 566 (string :tag "Label")
538 (repeat :tag "Add at least one item below" 567 (repeat :tag "Add at least one item below"
@@ -567,37 +596,40 @@ option in the usual fashion."
567(defcustom mh-auto-fields-list nil 596(defcustom mh-auto-fields-list nil
568 "List of recipients for which header lines are automatically inserted. 597 "List of recipients for which header lines are automatically inserted.
569 598
570This option can be used to set the identity depending on the recipient. To 599This option can be used to set the identity depending on the
571customize this option, click on the `INS' button and enter a regular 600recipient. To customize this option, click on the \"INS\" button and
572expression for the recipient's address. Click on the `INS' button with the 601enter a regular expression for the recipient's address. Click on the
573`Add at least one item below' label. Then choose one of the items in the 602\"INS\" button with the \"Add at least one item below\" label. Then choose
574`Value Menu'. 603one of the items in the \"Value Menu\".
575 604
576The `Identity' menu item is used to select an identity from those configured 605The \"Identity\" menu item is used to select an identity from those
577in `mh-identity-list'. All of the information for that identity will be added 606configured in `mh-identity-list'. All of the information for that
578if the recipient matches. The `Fcc Field' menu item is used to select a folder 607identity will be added if the recipient matches. The \"Fcc Field\" menu
579that is used in the `Fcc:' header. When you send the message, MH will put a 608item is used to select a folder that is used in the \"Fcc:\" header.
580copy of your message in this folder. The `Mail-Followup-To Field' menu item is 609When you send the message, MH will put a copy of your message in this
581used to insert an `Mail-Followup-To:' header field with the recipients you 610folder. The \"Mail-Followup-To Field\" menu item is used to insert an
582provide. If the recipient's mail user agent supports this header field (as nmh 611\"Mail-Followup-To:\" header field with the recipients you provide. If
583does), then their replies will go to the addresses listed. This is useful if 612the recipient's mail user agent supports this header field (as nmh
584their replies go both to the list and to you and you don't have a mechanism to 613does), then their replies will go to the addresses listed. This is
585suppress duplicates. If you reply to someone not on the list, you must either 614useful if their replies go both to the list and to you and you don't
586remove the `Mail-Followup-To:' field, or ensure the recipient is also listed 615have a mechanism to suppress duplicates. If you reply to someone not
587there so that he receives replies to your reply. Other header fields may be 616on the list, you must either remove the \"Mail-Followup-To:\" field, or
588added using the `Other Field' menu item. 617ensure the recipient is also listed there so that he receives replies
589 618to your reply. Other header fields may be added using the \"Other
590These fields can only be added after the recipient is known. Once the header 619Field\" menu item.
591contains one or more recipients, run the \\[mh-insert-auto-fields] command or 620
592choose the `Identity -> Insert Auto Fields' menu item to insert these fields 621These fields can only be added after the recipient is known. Once the
593manually. However, you can just send the message and the fields will be added 622header contains one or more recipients, run the
594automatically. You are given a chance to see these fields and to confirm them 623\\[mh-insert-auto-fields] command or choose the \"Identity -> Insert
595before the message is actually sent. You can do away with this confirmation by 624Auto Fields\" menu item to insert these fields manually. However, you
596turning off the option `mh-auto-fields-prompt-flag'. 625can just send the message and the fields will be added automatically.
597 626You are given a chance to see these fields and to confirm them before
598You should avoid using the same header field in `mh-auto-fields-list' and 627the message is actually sent. You can do away with this confirmation
599`mh-identity-list' definitions that may apply to the same message as the 628by turning off the option `mh-auto-fields-prompt-flag'.
600result is undefined." 629
630You should avoid using the same header field in `mh-auto-fields-list'
631and `mh-identity-list' definitions that may apply to the same message
632as the result is undefined."
601 :type `(repeat 633 :type `(repeat
602 (list :tag "" 634 (list :tag ""
603 (string :tag "Recipient") 635 (string :tag "Recipient")
@@ -645,25 +677,28 @@ See `mh-identity-list'."
645 (":pgg-default-user-id" . mh-identity-handler-gpg-identity)) 677 (":pgg-default-user-id" . mh-identity-handler-gpg-identity))
646 "Handler functions for fields in `mh-identity-list'. 678 "Handler functions for fields in `mh-identity-list'.
647 679
648This option is used to change the way that fields, signatures, and 680This option is used to change the way that fields, signatures,
649attributions in `mh-identity-list' are added. To customize 681and attributions in `mh-identity-list' are added. To customize
650`mh-identity-handlers', replace the name of an existing handler function 682`mh-identity-handlers', replace the name of an existing handler
651associated with the field you want to change with the name of a function you 683function associated with the field you want to change with the
652have written. You can also click on an `INS' button and insert a field of your 684name of a function you have written. You can also click on an
653choice and the name of the function you have written to handle it. 685\"INS\" button and insert a field of your choice and the name of
654 686the function you have written to handle it.
655The `Field' field can be any field that you've used in your 687
656`mh-identity-list'. The special fields `:attribution-verb', `:signature', or 688The \"Field\" field can be any field that you've used in your
657`:pgg-default-user-id' are used for the `mh-identity-list' choices 689`mh-identity-list'. The special fields \":attribution-verb\",
658`Attribution Verb', `Signature', and `GPG Key ID' respectively. 690\":signature\", or \":pgg-default-user-id\" are used for the
659 691`mh-identity-list' choices \"Attribution Verb\", \"Signature\", and
660The handler associated with the `:default' field is used when no other field 692\"GPG Key ID\" respectively.
661matches. 693
662 694The handler associated with the \":default\" field is used when no
663The handler functions are passed two or three arguments: the FIELD itself (for 695other field matches.
664example, `From'), or one of the special fields (for example, `:signature'), 696
665and the ACTION `'remove' or `'add'. If the action is `'add', an additional 697The handler functions are passed two or three arguments: the
666argument containing the VALUE for the field is given." 698FIELD itself (for example, \"From\"), or one of the special
699fields (for example, \":signature\"), and the ACTION 'remove or
700'add. If the action is 'add, an additional argument
701containing the VALUE for the field is given."
667 :type '(repeat (cons (string :tag "Field") function)) 702 :type '(repeat (cons (string :tag "Field") function))
668 :group 'mh-identity) 703 :group 'mh-identity)
669 704
@@ -674,36 +709,38 @@ argument containing the VALUE for the field is given."
674(defcustom mh-inc-prog "inc" 709(defcustom mh-inc-prog "inc"
675 "*Program to incorporate new mail into a folder. 710 "*Program to incorporate new mail into a folder.
676 711
677This program generates a one-line summary for each of the new messages. Unless 712This program generates a one-line summary for each of the new
678it is an absolute pathname, the file is assumed to be in the `mh-progs' 713messages. Unless it is an absolute pathname, the file is assumed
679directory. You may also link a file to `inc' that uses a different format. 714to be in the `mh-progs' directory. You may also link a file to
680You'll then need to modify several scan line format variables appropriately." 715\"inc\" that uses a different format. You'll then need to modify
716several scan line format variables appropriately."
681 :type 'string 717 :type 'string
682 :group 'mh-inc) 718 :group 'mh-inc)
683 719
684(defcustom mh-inc-spool-list nil 720(defcustom mh-inc-spool-list nil
685 "*Alternate spool files. 721 "*Alternate spool files.
686 722
687You can use the `mh-inc-spool-list' variable to direct MH-E to retrieve mail 723You can use the `mh-inc-spool-list' variable to direct MH-E to
688from arbitrary spool files other than your system mailbox, file it in folders 724retrieve mail from arbitrary spool files other than your system
689other than your `+inbox', and assign key bindings to incorporate this mail. 725mailbox, file it in folders other than your \"+inbox\", and assign
726key bindings to incorporate this mail.
690 727
691Suppose you are subscribed to the `mh-e-devel' mailing list and you use 728Suppose you are subscribed to the \"mh-e-devel\" mailing list and
692`procmail' to filter this mail into `~/mail/mh-e' with the following recipe in 729you use \"procmail\" to filter this mail into \"~/mail/mh-e\" with
693`.procmailrc': 730the following recipe in \".procmailrc\":
694 731
695 MAILDIR=$HOME/mail 732 MAILDIR=$HOME/mail
696 :0: 733 :0:
697 * ^From mh-e-devel-admin@stop.mail-abuse.org 734 * ^From mh-e-devel-admin@stop.mail-abuse.org
698 mh-e 735 mh-e
699 736
700In order to incorporate `~/mail/mh-e' into `+mh-e' with an `I m' 737In order to incorporate \"~/mail/mh-e\" into \"+mh-e\" with an
701\(`mh-inc-spool-mh-e'\) command, customize this option, and click on the `INS' 738\"I m\" (mh-inc-spool-mh-e) command, customize this option, and click
702button. Enter a `Spool File' of `~/mail/mh-e', a `Folder' of `mh-e', and a 739on the \"INS\" button. Enter a \"Spool File\" of \"~/mail/mh-e\", a
703`Key Binding' of `m'. 740\"Folder\" of \"mh-e\", and a \"Key Binding\" of \"m\".
704 741
705You can use `xbuffy' to automate the incorporation of this mail using the 742You can use \"xbuffy\" to automate the incorporation of this mail
706`gnudoit' command in the `gnuserv' package as follows: 743using the \"gnudoit\" command in the \"gnuserv\" package as follows:
707 744
708 box ~/mail/mh-e 745 box ~/mail/mh-e
709 title mh-e 746 title mh-e
@@ -723,13 +760,15 @@ You can use `xbuffy' to automate the incorporation of this mail using the
723 760
724(defcustom mh-index-program nil 761(defcustom mh-index-program nil
725 "Indexing program that MH-E shall use. 762 "Indexing program that MH-E shall use.
726The default setting of this option is `Auto-detect' which means that MH-E will
727automatically choose one of swish++, swish-e, mairix, namazu, pick and grep in
728that order. If, for example, you have both swish++ and mairix installed and
729you want to use mairix, then you can set this option to `mairix'.
730 763
731More information about setting up an indexing program to use with MH-E can be 764The default setting of this option is \"Auto-detect\" which means
732found in the documentation of `mh-index-search'." 765that MH-E will automatically choose one of swish++, swish-e,
766mairix, namazu, pick and grep in that order. If, for example, you
767have both swish++ and mairix installed and you want to use
768mairix, then you can set this option to \"mairix\".
769
770More information about setting up an indexing program to use with
771MH-E can be found in the documentation of `mh-index-search'."
733 :type '(choice (const :tag "Auto-detect" nil) 772 :type '(choice (const :tag "Auto-detect" nil)
734 (const :tag "swish++" swish++) 773 (const :tag "swish++" swish++)
735 (const :tag "swish-e" swish) 774 (const :tag "swish-e" swish)
@@ -752,13 +791,17 @@ found in the documentation of `mh-index-search'."
752 (bogofilter mh-bogofilter-blacklist mh-bogofilter-whitelist) 791 (bogofilter mh-bogofilter-blacklist mh-bogofilter-whitelist)
753 (spamprobe mh-spamprobe-blacklist mh-spamprobe-whitelist)) 792 (spamprobe mh-spamprobe-blacklist mh-spamprobe-whitelist))
754 "Available choices of spam programs to use. 793 "Available choices of spam programs to use.
755This is an alist. For each element there are functions that blacklist a message 794
756as spam and whitelist a message incorrectly classified as spam.") 795This is an alist. For each element there are functions that
796blacklist a message as spam and whitelist a message incorrectly
797classified as spam.")
757 798
758(defun mh-junk-choose (symbol value) 799(defun mh-junk-choose (symbol value)
759 "Choose spam program to use. 800 "Choose spam program to use.
760The function is always called with SYMBOL bound to `mh-junk-program' and VALUE 801
761bound to the new value of `mh-junk-program'. The function sets the variable 802The function is always called with SYMBOL bound to
803`mh-junk-program' and VALUE bound to the new value of
804`mh-junk-program'. The function sets the variable
762`mh-junk-choice' in addition to `mh-junk-program'." 805`mh-junk-choice' in addition to `mh-junk-program'."
763 (set symbol value) 806 (set symbol value)
764 (setq mh-junk-choice 807 (setq mh-junk-choice
@@ -770,9 +813,11 @@ bound to the new value of `mh-junk-program'. The function sets the variable
770;; User customizable variables 813;; User customizable variables
771(defcustom mh-junk-background nil 814(defcustom mh-junk-background nil
772 "If on, spam programs are run in background. 815 "If on, spam programs are run in background.
773By default, the programs are run in the foreground, but this can be slow when 816
774junking large numbers of messages. If you have enough memory or don't junk 817By default, the programs are run in the foreground, but this can
775that many messages at the same time, you might try turning on this option." 818be slow when junking large numbers of messages. If you have
819enough memory or don't junk that many messages at the same time,
820you might try turning on this option."
776 :type '(choice (const :tag "Off" nil) 821 :type '(choice (const :tag "Off" nil)
777 (const :tag "On" 0)) 822 (const :tag "On" 0))
778 :group 'mh-junk) 823 :group 'mh-junk)
@@ -786,11 +831,11 @@ that many messages at the same time, you might try turning on this option."
786(defcustom mh-junk-program nil 831(defcustom mh-junk-program nil
787 "Spam program that MH-E should use. 832 "Spam program that MH-E should use.
788 833
789The default setting of this option is \"Auto-detect\" which means that MH-E 834The default setting of this option is \"Auto-detect\" which means
790will automatically choose one of SpamAssassin, bogofilter, or SpamProbe in 835that MH-E will automatically choose one of SpamAssassin,
791that order. If, for example, you have both SpamAssassin and bogofilter 836bogofilter, or SpamProbe in that order. If, for example, you have
792installed and you want to use bogofilter, then you can set this option to 837both SpamAssassin and bogofilter installed and you want to use
793\"Bogofilter\"." 838bogofilter, then you can set this option to \"Bogofilter\"."
794 :type '(choice (const :tag "Auto-detect" nil) 839 :type '(choice (const :tag "Auto-detect" nil)
795 (const :tag "SpamAssassin" spamassassin) 840 (const :tag "SpamAssassin" spamassassin)
796 (const :tag "Bogofilter" bogofilter) 841 (const :tag "Bogofilter" bogofilter)
@@ -804,11 +849,13 @@ installed and you want to use bogofilter, then you can set this option to
804 849
805(defcustom mh-compose-insertion (if (locate-library "mml") 'mml 'mh) 850(defcustom mh-compose-insertion (if (locate-library "mml") 'mml 'mh)
806 "Type of tags used when composing MIME messages. 851 "Type of tags used when composing MIME messages.
807In addition to MH-style directives, MH-E also supports MML (MIME Meta 852
808Language) tags. (see Info node `(emacs-mime)Composing'). This option can be 853In addition to MH-style directives, MH-E also supports MML (MIME
809used to choose between them. By default, this option is set to \"MML\" if it 854Meta Language) tags. (see Info node `(emacs-mime)Composing').
810is supported since it provides a lot more functionality. This option can also 855This option can be used to choose between them. By default, this
811be set to \"MH\" if MH-style directives are preferred." 856option is set to \"MML\" if it is supported since it provides a
857lot more functionality. This option can also be set to \"MH\" if
858MH-style directives are preferred."
812 :type '(choice (const :tag "MML" mml) 859 :type '(choice (const :tag "MML" mml)
813 (const :tag "MH" mh)) 860 (const :tag "MH" mh))
814 :group 'mh-letter) 861 :group 'mh-letter)
@@ -827,18 +874,20 @@ be set to \"MH\" if MH-style directives are preferred."
827 874
828(defcustom mh-delete-yanked-msg-window-flag nil 875(defcustom mh-delete-yanked-msg-window-flag nil
829 "*Non-nil means delete any window displaying the message. 876 "*Non-nil means delete any window displaying the message.
830This deletes the window containing the original message after yanking it with 877
831\\<mh-letter-mode-map>\\[mh-yank-cur-msg] to make more room on your screen for 878This deletes the window containing the original message after
832your reply." 879yanking it with \\<mh-letter-mode-map>\\[mh-yank-cur-msg] to make
880more room on your screen for your reply."
833 :type 'boolean 881 :type 'boolean
834 :group 'mh-letter) 882 :group 'mh-letter)
835 883
836(defcustom mh-extract-from-attribution-verb "wrote:" 884(defcustom mh-extract-from-attribution-verb "wrote:"
837 "*Verb to use for attribution when a message is yanked by \\<mh-letter-mode-map>\\[mh-yank-cur-msg]. 885 "*Verb to use for attribution when a message is yanked by \\<mh-letter-mode-map>\\[mh-yank-cur-msg].
838The attribution consists of the sender's name and email address followed by 886
839the content of this option. This option can be set to \"wrote:\", \"a 887The attribution consists of the sender's name and email address
840écrit:\", and \"schrieb:\". You can also use the \"Custom String\" menu item 888followed by the content of this option. This option can be set to
841to enter your own verb." 889\"wrote:\", \"a écrit:\", and \"schrieb:\". You can also use the
890\"Custom String\" menu item to enter your own verb."
842 :type '(choice (const "wrote:") 891 :type '(choice (const "wrote:")
843 (const "a écrit:") 892 (const "a écrit:")
844 (const "schrieb:") 893 (const "schrieb:")
@@ -847,40 +896,51 @@ to enter your own verb."
847 896
848(defcustom mh-ins-buf-prefix "> " 897(defcustom mh-ins-buf-prefix "> "
849 "*String to put before each line of a yanked or inserted message. 898 "*String to put before each line of a yanked or inserted message.
850The prefix \"> \" is the default setting of this option. I suggest that you 899
851not modify this option since it is used by many mailers and news readers: 900The prefix \"> \" is the default setting of this option. I
852messages are far easier to read if several included messages have all been 901suggest that you not modify this option since it is used by many
853indented by the same string." 902mailers and news readers: messages are far easier to read if
903several included messages have all been indented by the same
904string.
905
906This prefix is not inserted if you use one of the supercite
907flavors of `mh-yank-behavior' or you have added a
908`mail-citation-hook'."
854 :type 'string 909 :type 'string
855 :group 'mh-letter) 910 :group 'mh-letter)
856 911
857(defcustom mh-letter-complete-function 'ispell-complete-word 912(defcustom mh-letter-complete-function 'ispell-complete-word
858 "*Function to call when completing outside of address or folder fields. 913 "*Function to call when completing outside of address or folder fields.
859In the body of the message, \\<mh-letter-mode-map>\\[mh-letter-complete] runs 914
860this function, which is set to \"ispell-complete-word\" by default." 915In the body of the message,
916\\<mh-letter-mode-map>\\[mh-letter-complete] runs this function,
917which is set to \"ispell-complete-word\" by default."
861 :type '(choice function (const nil)) 918 :type '(choice function (const nil))
862 :group 'mh-letter) 919 :group 'mh-letter)
863 920
864(defcustom mh-letter-fill-column 72 921(defcustom mh-letter-fill-column 72
865 "*Fill column to use in MH Letter mode. 922 "*Fill column to use in MH Letter mode.
866By default, this option is 72 to allow others to quote your message without 923
867line wrapping." 924By default, this option is 72 to allow others to quote your
925message without line wrapping."
868 :type 'integer 926 :type 'integer
869 :group 'mh-letter) 927 :group 'mh-letter)
870 928
871(defcustom mh-mml-method-default (if mh-pgp-support-flag "pgpmime" "none") 929(defcustom mh-mml-method-default (if mh-pgp-support-flag "pgpmime" "none")
872 "Default method to use in security tags. 930 "Default method to use in security tags.
873This option is used to select between a variety of mail security mechanisms.
874The default is \"PGP (MIME)\" if it is supported\; otherwise, the default is
875\"None\". Other mechanisms include vanilla \"PGP\" and \"S/MIME\".
876 931
877The `pgg' customization group may have some settings which may interest you 932This option is used to select between a variety of mail security
878\(see Info node `(pgg)'). 933mechanisms. The default is \"PGP (MIME)\" if it is supported\;
934otherwise, the default is \"None\". Other mechanisms include
935vanilla \"PGP\" and \"S/MIME\".
936
937The `pgg' customization group may have some settings which may
938interest you (see Info node `(pgg)').
879 939
880In particular, I set the option `pgg-encrypt-for-me' to t so that all messages 940In particular, I set the option `pgg-encrypt-for-me' to t so that all
881I encrypt are encrypted with my public key as well. If you keep a copy of all 941messages I encrypt are encrypted with my public key as well. If you
882of your outgoing mail with a \"Fcc:\" header field, this setting is vital so 942keep a copy of all of your outgoing mail with a \"Fcc:\" header field,
883that you can read the mail you write!" 943this setting is vital so that you can read the mail you write!"
884 :type '(choice (const :tag "PGP (MIME)" "pgpmime") 944 :type '(choice (const :tag "PGP (MIME)" "pgpmime")
885 (const :tag "PGP" "pgp") 945 (const :tag "PGP" "pgp")
886 (const :tag "S/MIME" "smime") 946 (const :tag "S/MIME" "smime")
@@ -890,89 +950,97 @@ that you can read the mail you write!"
890(defcustom mh-signature-file-name "~/.signature" 950(defcustom mh-signature-file-name "~/.signature"
891 "*Source of user's signature. 951 "*Source of user's signature.
892 952
893By default, the text of your signature is taken from the file \"~/.signature\". 953By default, the text of your signature is taken from the file
894You can read from other files by changing this option. This file may contain a 954\"~/.signature\". You can read from other sources by changing this
895vCard in which case an attachment is added with the vCard. 955option. This file may contain a vCard in which case an attachment is
956added with the vCard.
896 957
897This option may also be a symbol, in which case that function is called. You 958This option may also be a symbol, in which case that function is
898may not want a signature separator to be added for you; instead you may want 959called. You may not want a signature separator to be added for you;
899to insert one yourself. Options that you may find useful to do this include 960instead you may want to insert one yourself. Options that you may find
900`mh-signature-separator' (when inserting a signature separator) and 961useful to do this include `mh-signature-separator' (when inserting a
901`mh-signature-separator-regexp' (for finding said separator). The function 962signature separator) and `mh-signature-separator-regexp' (for finding
902`mh-signature-separator-p', which reports t if the buffer contains a 963said separator). The function `mh-signature-separator-p', which
903separator, may be useful as well. 964reports t if the buffer contains a separator, may be useful as well.
904 965
905The signature is inserted into your message with the command 966The signature is inserted into your message with the command
906\\<mh-letter-mode-map>\\[mh-insert-signature] or with the `mh-identity-list' 967\\<mh-letter-mode-map>\\[mh-insert-signature] or with the
907option." 968`mh-identity-list' option."
908 :type 'file 969 :type 'file
909 :group 'mh-letter) 970 :group 'mh-letter)
910 971
911(defcustom mh-signature-separator-flag t 972(defcustom mh-signature-separator-flag t
912 "*Non-nil means a signature separator should be inserted. 973 "*Non-nil means a signature separator should be inserted.
913It is not recommended that you change this option since various mail user 974
914agents, including MH-E, use the separator to present the signature 975It is not recommended that you change this option since various
915differently, and to suppress the signature when replying or yanking a letter 976mail user agents, including MH-E, use the separator to present
916into a draft." 977the signature differently, and to suppress the signature when
978replying or yanking a letter into a draft."
917 :type 'boolean 979 :type 'boolean
918 :group 'mh-letter) 980 :group 'mh-letter)
919 981
920(defcustom mh-x-face-file "~/.face" 982(defcustom mh-x-face-file "~/.face"
921 "*File containing face header field to insert in outgoing mail. 983 "*File containing face header field to insert in outgoing mail.
922 984
923If the file starts with either of the strings \"X-Face:\", \"Face:\" or 985If the file starts with either of the strings \"X-Face:\", \"Face:\"
924\"X-Image-URL:\" then the contents are added to the message header verbatim. 986or \"X-Image-URL:\" then the contents are added to the message header
925Otherwise it is assumed that the file contains the value of the \"X-Face:\" 987verbatim. Otherwise it is assumed that the file contains the value of
926header field. 988the \"X-Face:\" header field.
927 989
928The \"X-Face:\" header field, which is a low-resolution, black 990The \"X-Face:\" header field, which is a low-resolution, black and
929and white image, can be generated using the \"compface\" command 991white image, can be generated using the \"compface\" command (see URL
930\(see URL `ftp://ftp.cs.indiana.edu/pub/faces/compface/compface.tar.Z'). 992`ftp://ftp.cs.indiana.edu/pub/faces/compface/compface.tar.Z'). The
931The \"Online X-Face Converter\" is a useful resource for quick 993\"Online X-Face Converter\" is a useful resource for quick conversion
932conversion of images into \"X-Face:\" header fields (see URL 994of images into \"X-Face:\" header fields (see URL
933`http://www.dairiki.org/xface/'). 995`http://www.dairiki.org/xface/').
934 996
935Use the \"make-face\" script to convert a JPEG image to the 997Use the \"make-face\" script to convert a JPEG image to the higher
936higher resolution, color, \"Face:\" header field (see URL 998resolution, color, \"Face:\" header field (see URL
937`http://quimby.gnus.org/circus/face/make-face'). 999`http://quimby.gnus.org/circus/face/make-face').
938 1000
939The URL of any image can be used for the \"X-Image-URL:\" field and no 1001The URL of any image can be used for the \"X-Image-URL:\" field and no
940processing of the image is required. 1002processing of the image is required.
941 1003
942To prevent the setting of any of these header fields, either set 1004To prevent the setting of any of these header fields, either set
943`mh-x-face-file' to nil, or simply ensure that the file defined by this option 1005`mh-x-face-file' to nil, or simply ensure that the file defined by
944doesn't exist." 1006this option doesn't exist."
945 :type 'file 1007 :type 'file
946 :group 'mh-letter) 1008 :group 'mh-letter)
947 1009
948(defcustom mh-yank-behavior 'attribution 1010(defcustom mh-yank-behavior 'attribution
949 "*Controls which part of a message is yanked by \\<mh-letter-mode-map>\\[mh-yank-cur-msg]. 1011 "*Controls which part of a message is yanked by \\<mh-letter-mode-map>\\[mh-yank-cur-msg].
950 1012
951To include the entire message, including the entire header, use \"Body and 1013To include the entire message, including the entire header, use \"Body
952Header\". Use \"Body\" to yank just the body without the header. To yank only 1014and Header\". Use \"Body\" to yank just the body without the header.
953the portion of the message following the point, set this option to \"Below 1015To yank only the portion of the message following the point, set this
954Point\". 1016option to \"Below Point\".
955 1017
956Choose \"Invoke supercite\" to pass the entire message and header through 1018Choose \"Invoke supercite\" to pass the entire message and header
957supercite. 1019through supercite.
958 1020
959If the \"Body With Attribution\" setting is used, then the message minus the 1021If the \"Body With Attribution\" setting is used, then the message
960header is yanked and a simple attribution line is added at the top using the 1022minus the header is yanked and a simple attribution line is added at
961value of the `mh-extract-from-attribution-verb' option. This is the default. 1023the top using the value of the `mh-extract-from-attribution-verb'
962 1024option. This is the default.
963If the \"Invoke supercite\" or \"Body With Attribution\" settings are used, 1025
964the \"-noformat\" argument is passed to the \"repl\" program to override a 1026If the \"Invoke supercite\" or \"Body With Attribution\" settings are
965\"-filter\" or \"-format\" argument. These settings also have 1027used, the \"-noformat\" argument is passed to the \"repl\" program to
966\"Automatically\" variants that perform the action automatically when you 1028override a \"-filter\" or \"-format\" argument. These settings also
967reply so that you don't need to use \\[mh-yank-cur-msg] at all. Note that this 1029have \"Automatically\" variants that perform the action automatically
968automatic action is only performed if the show buffer matches the message 1030when you reply so that you don't need to use \\[mh-yank-cur-msg] at
969being replied to. People who use the automatic variants tend to turn on the 1031all. Note that this automatic action is only performed if the show
970`mh-delete-yanked-msg-window-flag' option as well so that the show window is 1032buffer matches the message being replied to. People who use the
971never displayed. 1033automatic variants tend to turn on the
972 1034`mh-delete-yanked-msg-window-flag' option as well so that the show
973If the show buffer has a region, the `mh-yank-behavior' option is ignored 1035window is never displayed.
974unless its value is one of Attribution variants in which case the attribution 1036
975is added to the yanked region." 1037If the show buffer has a region, the `mh-yank-behavior' option is
1038ignored unless its value is one of Attribution variants in which case
1039the attribution is added to the yanked region.
1040
1041If this option is set to one of the supercite flavors, the hook
1042`mail-citation-hook' is ignored and `mh-ins-buf-prefix' is not
1043inserted."
976 :type '(choice (const :tag "Body and Header" t) 1044 :type '(choice (const :tag "Body and Header" t)
977 (const :tag "Body" body) 1045 (const :tag "Body" body)
978 (const :tag "Below Point" nil) 1046 (const :tag "Below Point" nil)
@@ -989,10 +1057,11 @@ is added to the yanked region."
989 1057
990(defcustom mh-interpret-number-as-range-flag t 1058(defcustom mh-interpret-number-as-range-flag t
991 "*Non-nil means interpret a number as a range. 1059 "*Non-nil means interpret a number as a range.
992Since one of the most frequent ranges used is \"last:N\", MH-E will interpret 1060
993input such as \"200\" as \"last:200\" if this option is on (which is the 1061Since one of the most frequent ranges used is \"last:N\", MH-E
994default). If you need to scan just the message 200, then use the range 1062will interpret input such as \"200\" as \"last:200\" if this
995\"200:200\"." 1063option is on (which is the default). If you need to scan just the
1064message 200, then use the range \"200:200\"."
996 :type 'boolean 1065 :type 'boolean
997 :group 'mh-ranges) 1066 :group 'mh-ranges)
998 1067
@@ -1005,8 +1074,9 @@ default). If you need to scan just the message 200, then use the range
1005 1074
1006(defun mh-adaptive-cmd-note-flag-check (symbol value) 1075(defun mh-adaptive-cmd-note-flag-check (symbol value)
1007 "Check if desired setting is legal. 1076 "Check if desired setting is legal.
1008Throw an error if user tries to turn on `mh-adaptive-cmd-note-flag' when 1077Throw an error if user tries to turn on
1009`mh-scan-format-file' isn't t. Otherwise, set SYMBOL to VALUE." 1078`mh-adaptive-cmd-note-flag' when `mh-scan-format-file' isn't t.
1079Otherwise, set SYMBOL to VALUE."
1010 (if (and value 1080 (if (and value
1011 (not (eq mh-scan-format-file t))) 1081 (not (eq mh-scan-format-file t)))
1012 (error "%s %s" "Can't turn on unless mh-scan-format-file" 1082 (error "%s %s" "Can't turn on unless mh-scan-format-file"
@@ -1015,8 +1085,9 @@ Throw an error if user tries to turn on `mh-adaptive-cmd-note-flag' when
1015 1085
1016(defun mh-scan-format-file-check (symbol value) 1086(defun mh-scan-format-file-check (symbol value)
1017 "Check if desired setting is legal. 1087 "Check if desired setting is legal.
1018Throw an error if user tries to set `mh-scan-format-file' to anything but t 1088Throw an error if user tries to set `mh-scan-format-file' to
1019when `mh-adaptive-cmd-note-flag' is on. Otherwise, set SYMBOL to VALUE." 1089anything but t when `mh-adaptive-cmd-note-flag' is on. Otherwise,
1090set SYMBOL to VALUE."
1020 (if (and (not (eq value t)) 1091 (if (and (not (eq value t))
1021 (eq mh-adaptive-cmd-note-flag t)) 1092 (eq mh-adaptive-cmd-note-flag t))
1022 (error "%s %s" "You must turn off mh-adaptive-cmd-note-flag" 1093 (error "%s %s" "You must turn off mh-adaptive-cmd-note-flag"
@@ -1025,16 +1096,17 @@ when `mh-adaptive-cmd-note-flag' is on. Otherwise, set SYMBOL to VALUE."
1025 1096
1026(defcustom mh-adaptive-cmd-note-flag t 1097(defcustom mh-adaptive-cmd-note-flag t
1027 "*Non-nil means that the message number width is determined dynamically. 1098 "*Non-nil means that the message number width is determined dynamically.
1028If you've created your own format to handle long message numbers, you'll be 1099
1029pleased to know you no longer need it since MH-E adapts its internal format 1100If you've created your own format to handle long message numbers,
1030based upon the largest message number if this option is on (the default). 1101you'll be pleased to know you no longer need it since MH-E adapts its
1031This option may only be turned on when `mh-scan-format-file' is set to \"Use 1102internal format based upon the largest message number if this option
1032MH-E scan Format\". 1103is on (the default). This option may only be turned on when
1033 1104`mh-scan-format-file' is set to \"Use MH-E scan Format\".
1034If you prefer fixed-width message numbers, turn off this option and call 1105
1035`mh-set-cmd-note' with the width specified by your format file 1106If you prefer fixed-width message numbers, turn off this option and
1036\(see `mh-scan-format-file'). For example, the default width is 4, so you would 1107call `mh-set-cmd-note' with the width specified by your format file
1037use \"(mh-set-cmd-note 4)\"." 1108\(see `mh-scan-format-file'). For example, the default width is 4, so
1109you would use \"(mh-set-cmd-note 4)\"."
1038 :type 'boolean 1110 :type 'boolean
1039 :group 'mh-scan-line-formats 1111 :group 'mh-scan-line-formats
1040 :set 'mh-adaptive-cmd-note-flag-check) 1112 :set 'mh-adaptive-cmd-note-flag-check)
@@ -1042,22 +1114,24 @@ use \"(mh-set-cmd-note 4)\"."
1042(defcustom mh-scan-format-file t 1114(defcustom mh-scan-format-file t
1043 "Specifies the format file to pass to the scan program. 1115 "Specifies the format file to pass to the scan program.
1044 1116
1045The default setting for this option is \"Use MH-E scan Format\". This means 1117The default setting for this option is \"Use MH-E scan Format\". This
1046that the format string will be taken from the either `mh-scan-format-mh' or 1118means that the format string will be taken from the either
1047`mh-scan-format-nmh' depending on whether MH or nmh (or GNU mailutils) is in 1119`mh-scan-format-mh' or `mh-scan-format-nmh' depending on whether MH or
1048use. This setting also enables you to turn on the `mh-adaptive-cmd-note-flag' 1120nmh (or GNU mailutils) is in use. This setting also enables you to
1049option. 1121turn on the `mh-adaptive-cmd-note-flag' option.
1050 1122
1051You can also set this option to \"Use Default scan Format\" to get the 1123You can also set this option to \"Use Default scan Format\" to get the
1052same output as you would get if you ran \"scan\" from the shell. If you have a 1124same output as you would get if you ran \"scan\" from the shell. If
1053format file that you want MH-E to use but not MH, you can set this option to 1125you have a format file that you want MH-E to use but not MH, you can
1054\"Specify a scan Format File\" and enter the name of your format file. 1126set this option to \"Specify a scan Format File\" and enter the name
1055 1127of your format file.
1056If you change the format of the scan lines you'll need to tell MH-E how to 1128
1057parse the new format. As you will see, quite a lot of variables are involved 1129If you change the format of the scan lines you'll need to tell MH-E
1058to do that. Use \"\\[apropos] RET mh-scan.*regexp\" to obtain a list of these 1130how to parse the new format. As you will see, quite a lot of variables
1059variables. You will also have to call `mh-set-cmd-note' if your notations are 1131are involved to do that. Use \"\\[apropos] RET mh-scan.*regexp\" to
1060not in column 4 (columns in Emacs start with 0)." 1132obtain a list of these variables. You will also have to call
1133`mh-set-cmd-note' if your notations are not in column 4 (columns in
1134Emacs start with 0)."
1061 :type '(choice (const :tag "Use MH-E scan Format" t) 1135 :type '(choice (const :tag "Use MH-E scan Format" t)
1062 (const :tag "Use Default scan Format" nil) 1136 (const :tag "Use Default scan Format" nil)
1063 (file :tag "Specify a scan Format File")) 1137 (file :tag "Specify a scan Format File"))
@@ -1066,10 +1140,12 @@ not in column 4 (columns in Emacs start with 0)."
1066 1140
1067(defcustom mh-scan-prog "scan" 1141(defcustom mh-scan-prog "scan"
1068 "*Program used to scan messages. 1142 "*Program used to scan messages.
1069The name of the program that generates a listing of one line per message is 1143
1070held in this option. Unless this variable contains an absolute pathname, it is 1144The name of the program that generates a listing of one line per
1071assumed to be in the `mh-progs' directory. You may link another program to 1145message is held in this option. Unless this variable contains an
1072`scan' (see \"mh-profile(5)\") to produce a different type of listing." 1146absolute pathname, it is assumed to be in the `mh-progs'
1147directory. You may link another program to `scan' (see
1148\"mh-profile(5)\") to produce a different type of listing."
1073 :type 'string 1149 :type 'string
1074 :group 'mh-scan-line-formats) 1150 :group 'mh-scan-line-formats)
1075(make-variable-buffer-local 'mh-scan-prog) 1151(make-variable-buffer-local 'mh-scan-prog)
@@ -1081,24 +1157,26 @@ assumed to be in the `mh-progs' directory. You may link another program to
1081(defcustom mh-compose-forward-as-mime-flag t 1157(defcustom mh-compose-forward-as-mime-flag t
1082 "*Non-nil means that messages are forwarded as attachments. 1158 "*Non-nil means that messages are forwarded as attachments.
1083 1159
1084By default, this option is on which means that the forwarded messages are 1160By default, this option is on which means that the forwarded
1085included as attachments. If you would prefer to forward your messages verbatim 1161messages are included as attachments. If you would prefer to
1086\(as text, inline), then turn off this option. Forwarding messages verbatim 1162forward your messages verbatim (as text, inline), then turn off
1087works well for short, textual messages, but your recipient won't be able to 1163this option. Forwarding messages verbatim works well for short,
1088view any non-textual attachments that were in the forwarded message. Be aware 1164textual messages, but your recipient won't be able to view any
1089that if you have \"forw: -mime\" in your MH profile, then forwarded messages 1165non-textual attachments that were in the forwarded message. Be
1090will always be included as attachments regardless of the settings of this 1166aware that if you have \"forw: -mime\" in your MH profile, then
1091option." 1167forwarded messages will always be included as attachments
1168regardless of the settings of this option."
1092 :type 'boolean 1169 :type 'boolean
1093 :group 'mh-sending-mail) 1170 :group 'mh-sending-mail)
1094 1171
1095(defcustom mh-compose-letter-function nil 1172(defcustom mh-compose-letter-function nil
1096 "Invoked when starting a new draft. 1173 "Invoked when starting a new draft.
1097 1174
1098However, it is the last function called before you edit your message. The 1175However, it is the last function called before you edit your
1099consequence of this is that you can write a function to write and send the 1176message. The consequence of this is that you can write a function
1100message for you. This function is passed three arguments: the contents of the 1177to write and send the message for you. This function is passed
1101TO, SUBJECT, and CC header fields." 1178three arguments: the contents of the TO, SUBJECT, and CC header
1179fields."
1102 :type '(choice (const nil) function) 1180 :type '(choice (const nil) function)
1103 :group 'mh-sending-mail) 1181 :group 'mh-sending-mail)
1104 1182
@@ -1110,40 +1188,40 @@ TO, SUBJECT, and CC header fields."
1110(defcustom mh-forward-subject-format "%s: %s" 1188(defcustom mh-forward-subject-format "%s: %s"
1111 "*Format string for forwarded message subject. 1189 "*Format string for forwarded message subject.
1112 1190
1113This option is a string which includes two escapes (\"%s\"). The first \"%s\" 1191This option is a string which includes two escapes (\"%s\"). The
1114is replaced with the sender of the original message, and the second one is 1192first \"%s\" is replaced with the sender of the original message,
1115replaced with the original \"Subject:\"." 1193and the second one is replaced with the original \"Subject:\"."
1116 :type 'string 1194 :type 'string
1117 :group 'mh-sending-mail) 1195 :group 'mh-sending-mail)
1118 1196
1119(defcustom mh-insert-x-mailer-flag t 1197(defcustom mh-insert-x-mailer-flag t
1120 "*Non-nil means append an \"X-Mailer:\" header field to the header. 1198 "*Non-nil means append an \"X-Mailer:\" header field to the header.
1121 1199
1122This header field includes the version of MH-E and Emacs that you are using. 1200This header field includes the version of MH-E and Emacs that you
1123If you don't want to participate in our marketing, you can turn this option 1201are using. If you don't want to participate in our marketing, you
1124off." 1202can turn this option off."
1125 :type 'boolean 1203 :type 'boolean
1126 :group 'mh-sending-mail) 1204 :group 'mh-sending-mail)
1127 1205
1128(defcustom mh-redist-full-contents-flag nil 1206(defcustom mh-redist-full-contents-flag nil
1129 "*Non-nil means the \"dist\" command needs entire letter for redistribution. 1207 "*Non-nil means the \"dist\" command needs entire letter for redistribution.
1130 1208
1131This option must be turned on if \"dist\" requires the whole letter for 1209This option must be turned on if \"dist\" requires the whole
1132redistribution, which is the case if \"send\" is compiled with the BERK option 1210letter for redistribution, which is the case if \"send\" is
1133\(which many people abhor). If you find that MH will not allow you to 1211compiled with the BERK option (which many people abhor). If you
1134redistribute a message that has been redistributed before, turn off this 1212find that MH will not allow you to redistribute a message that
1135option." 1213has been redistributed before, turn off this option."
1136 :type 'boolean 1214 :type 'boolean
1137 :group 'mh-sending-mail) 1215 :group 'mh-sending-mail)
1138 1216
1139(defcustom mh-reply-default-reply-to nil 1217(defcustom mh-reply-default-reply-to nil
1140 "*Sets the person or persons to whom a reply will be sent. 1218 "*Sets the person or persons to whom a reply will be sent.
1141 1219
1142This option is set to \"Prompt\" by default so that you are prompted for the 1220This option is set to \"Prompt\" by default so that you are
1143recipient of a reply. If you find that most of the time that you specify 1221prompted for the recipient of a reply. If you find that most of
1144\"cc\" when you reply to a message, set this option to \"cc\". Other choices 1222the time that you specify \"cc\" when you reply to a message, set
1145include \"from\", \"to\", or \"all\". You can always edit the recipients in 1223this option to \"cc\". Other choices include \"from\", \"to\", or
1146the draft." 1224\"all\". You can always edit the recipients in the draft."
1147 :type '(choice (const :tag "Prompt" nil) 1225 :type '(choice (const :tag "Prompt" nil)
1148 (const "from") 1226 (const "from")
1149 (const "to") 1227 (const "to")
@@ -1154,8 +1232,8 @@ the draft."
1154(defcustom mh-reply-show-message-flag t 1232(defcustom mh-reply-show-message-flag t
1155 "*Non-nil means the MH-Show buffer is displayed when replying. 1233 "*Non-nil means the MH-Show buffer is displayed when replying.
1156 1234
1157If you include the message automatically, you can hide the MH-Show 1235If you include the message automatically, you can hide the
1158buffer by turning off this option. 1236MH-Show buffer by turning off this option.
1159 1237
1160See also `mh-reply'." 1238See also `mh-reply'."
1161 :type 'boolean 1239 :type 'boolean
@@ -1172,32 +1250,34 @@ See also `mh-reply'."
1172(defcustom mh-refile-preserves-sequences-flag t 1250(defcustom mh-refile-preserves-sequences-flag t
1173 "*Non-nil means that sequences are preserved when messages are refiled. 1251 "*Non-nil means that sequences are preserved when messages are refiled.
1174 1252
1175If a message is in any sequence (except \"Previous-Sequence:\" and \"cur\") 1253If a message is in any sequence (except \"Previous-Sequence:\"
1176when it is refiled, then it will still be in those sequences in the 1254and \"cur\") when it is refiled, then it will still be in those
1177destination folder. If this behavior is not desired, then turn off this 1255sequences in the destination folder. If this behavior is not
1178option." 1256desired, then turn off this option."
1179 :type 'boolean 1257 :type 'boolean
1180 :group 'mh-sequences) 1258 :group 'mh-sequences)
1181 1259
1182(defcustom mh-tick-seq 'tick 1260(defcustom mh-tick-seq 'tick
1183 "The name of the MH sequence for ticked messages. 1261 "The name of the MH sequence for ticked messages.
1184 1262
1185You can customize this option if you already use the \"tick\" sequence for 1263You can customize this option if you already use the \"tick\"
1186your own use. You can also disable all of the ticking functions by choosing 1264sequence for your own use. You can also disable all of the
1187the \"Disable Ticking\" item but there isn't much advantage to that." 1265ticking functions by choosing the \"Disable Ticking\" item but
1266there isn't much advantage to that."
1188 :type '(choice (const :tag "Disable Ticking" nil) 1267 :type '(choice (const :tag "Disable Ticking" nil)
1189 symbol) 1268 symbol)
1190 :group 'mh-sequences) 1269 :group 'mh-sequences)
1191 1270
1192(defcustom mh-update-sequences-after-mh-show-flag t 1271(defcustom mh-update-sequences-after-mh-show-flag t
1193 "*Non-nil means flush MH sequences to disk after message is shown. 1272 "*Non-nil means flush MH sequences to disk after message is shown\\<mh-folder-mode-map>.
1194 1273
1195Three sequences are maintained internally by MH-E and pushed out to MH when a 1274Three sequences are maintained internally by MH-E and pushed out
1196message is shown. They include the sequence specified by your 1275to MH when a message is shown. They include the sequence
1197\"Unseen-Sequence:\" profile entry, \"cur\", and the sequence listed by the 1276specified by your \"Unseen-Sequence:\" profile entry, \"cur\",
1198option `mh-tick-seq' which is \"tick\" by default. If you do not like this 1277and the sequence listed by the option `mh-tick-seq' which is
1199behavior, turn off this option. You can then update the state manually with 1278\"tick\" by default. If you do not like this behavior, turn off
1200the `\\[mh-execute-commands]', `\\[mh-quit]', or `\\[mh-update-sequences]' 1279this option. You can then update the state manually with the
1280\\[mh-execute-commands], \\[mh-quit], or \\[mh-update-sequences]
1201commands." 1281commands."
1202 :type 'boolean 1282 :type 'boolean
1203 :group 'mh-sequences) 1283 :group 'mh-sequences)
@@ -1209,10 +1289,10 @@ commands."
1209(defcustom mh-bury-show-buffer-flag t 1289(defcustom mh-bury-show-buffer-flag t
1210 "*Non-nil means show buffer is buried. 1290 "*Non-nil means show buffer is buried.
1211 1291
1212One advantage of not burying the show buffer is that one can delete the show 1292One advantage of not burying the show buffer is that one can
1213buffer more easily in an electric buffer list because of its proximity to its 1293delete the show buffer more easily in an electric buffer list
1214associated MH-Folder buffer. Try running \\[electric-buffer-list] to see what 1294because of its proximity to its associated MH-Folder buffer. Try
1215I mean." 1295running \\[electric-buffer-list] to see what I mean."
1216 :type 'boolean 1296 :type 'boolean
1217 :group 'mh-show) 1297 :group 'mh-show)
1218 1298
@@ -1227,45 +1307,47 @@ See also `mh-invisible-header-fields-default' and
1227(defcustom mh-decode-mime-flag (not (not (locate-library "mm-decode"))) 1307(defcustom mh-decode-mime-flag (not (not (locate-library "mm-decode")))
1228 "*Non-nil means attachments are handled\\<mh-folder-mode-map>. 1308 "*Non-nil means attachments are handled\\<mh-folder-mode-map>.
1229 1309
1230MH-E can handle attachments as well if the Gnus `mm-decode' library is 1310MH-E can handle attachments as well if the Gnus `mm-decode'
1231present. If so, this option will be on. Otherwise, you'll see the MIME body 1311library is present. If so, this option will be on. Otherwise,
1232parts rather than text or attachments. There isn't much point in turning off 1312you'll see the MIME body parts rather than text or attachments.
1233this option; however, you can inspect it if it appears that the body parts are 1313There isn't much point in turning off this option; however, you
1234not being interpreted correctly or toggle it with the command 1314can inspect it if it appears that the body parts are not being
1315interpreted correctly or toggle it with the command
1235\\[mh-toggle-mh-decode-mime-flag] to view the raw message. 1316\\[mh-toggle-mh-decode-mime-flag] to view the raw message.
1236 1317
1237This option also controls the display of quoted-printable messages and other 1318This option also controls the display of quoted-printable
1238graphical widgets. See the options `mh-graphical-smileys-flag' and 1319messages and other graphical widgets. See the options
1239`mh-graphical-emphasis-flag'." 1320`mh-graphical-smileys-flag' and `mh-graphical-emphasis-flag'."
1240 :type 'boolean 1321 :type 'boolean
1241 :group 'mh-show) 1322 :group 'mh-show)
1242 1323
1243(defcustom mh-display-buttons-for-alternatives-flag nil 1324(defcustom mh-display-buttons-for-alternatives-flag nil
1244 "*Non-nil means display buttons for all alternative attachments. 1325 "*Non-nil means display buttons for all alternative attachments.
1245 1326
1246Sometimes, a mail program will produce multiple alternatives of the attachment 1327Sometimes, a mail program will produce multiple alternatives of
1247in increasing degree of faithfulness to the original content. By default, only 1328the attachment in increasing degree of faithfulness to the
1248the preferred alternative is displayed. If this option is on, then the 1329original content. By default, only the preferred alternative is
1249preferred part is shown inline and buttons are shown for each of the other 1330displayed. If this option is on, then the preferred part is shown
1250alternatives." 1331inline and buttons are shown for each of the other alternatives."
1251 :type 'boolean 1332 :type 'boolean
1252 :group 'mh-show) 1333 :group 'mh-show)
1253 1334
1254(defcustom mh-display-buttons-for-inline-parts-flag nil 1335(defcustom mh-display-buttons-for-inline-parts-flag nil
1255 "*Non-nil means display buttons for all inline attachments\\<mh-folder-mode-map>. 1336 "*Non-nil means display buttons for all inline attachments\\<mh-folder-mode-map>.
1256 1337
1257The sender can request that attachments should be viewed inline so that they 1338The sender can request that attachments should be viewed inline so
1258do not really appear like an attachment at all to the reader. Most of the 1339that they do not really appear like an attachment at all to the
1259time, this is desirable, so by default MH-E suppresses the buttons for inline 1340reader. Most of the time, this is desirable, so by default MH-E
1260attachments. On the other hand, you may receive code or HTML which the sender 1341suppresses the buttons for inline attachments. On the other hand, you
1261has added to his message as inline attachments so that you can read them in 1342may receive code or HTML which the sender has added to his message as
1262MH-E. In this case, it is useful to see the buttons so that you know you don't 1343inline attachments so that you can read them in MH-E. In this case, it
1263have to cut and paste the code into a file; you can simply save the 1344is useful to see the buttons so that you know you don't have to cut
1264attachment. 1345and paste the code into a file; you can simply save the attachment.
1265 1346
1266If you want to make the buttons visible for inline attachments, you can use 1347If you want to make the buttons visible for inline attachments, you
1267the command \\[mh-toggle-mime-buttons] to toggle the visibility of these 1348can use the command \\[mh-toggle-mime-buttons] to toggle the
1268buttons. You can turn on these buttons permanently by turning on this option. 1349visibility of these buttons. You can turn on these buttons permanently
1350by turning on this option.
1269 1351
1270MH-E cannot display all attachments inline however. It can display 1352MH-E cannot display all attachments inline however. It can display
1271text (including HTML) and images." 1353text (including HTML) and images."
@@ -1275,42 +1357,44 @@ text (including HTML) and images."
1275(defcustom mh-do-not-confirm-flag nil 1357(defcustom mh-do-not-confirm-flag nil
1276 "*Non-nil means non-reversible commands do not prompt for confirmation. 1358 "*Non-nil means non-reversible commands do not prompt for confirmation.
1277 1359
1278Commands such as `mh-pack-folder' prompt to confirm whether to process 1360Commands such as `mh-pack-folder' prompt to confirm whether to
1279outstanding moves and deletes or not before continuing. Turning on this option 1361process outstanding moves and deletes or not before continuing.
1280means that these actions will be performed--which is usually desired but 1362Turning on this option means that these actions will be
1281cannot be retracted--without question." 1363performed--which is usually desired but cannot be
1364retracted--without question."
1282 :type 'boolean 1365 :type 'boolean
1283 :group 'mh-show) 1366 :group 'mh-show)
1284 1367
1285(defcustom mh-fetch-x-image-url nil 1368(defcustom mh-fetch-x-image-url nil
1286 "*Control fetching of \"X-Image-URL:\" header field image. 1369 "*Control fetching of \"X-Image-URL:\" header field image.
1287 1370
1288Ths option controls the fetching of the \"X-Image-URL:\" header field image 1371Ths option controls the fetching of the \"X-Image-URL:\" header
1289with the following values: 1372field image with the following values:
1290 1373
1291Ask Before Fetching 1374Ask Before Fetching
1292 You are prompted before the image is fetched. MH-E will remember 1375 You are prompted before the image is fetched. MH-E will
1293 your reply and will either use the already fetched image the next 1376 remember your reply and will either use the already fetched
1294 time the same URL is encountered or silently skip it if you didn't 1377 image the next time the same URL is encountered or silently
1295 fetch it the first time. This is a good setting. 1378 skip it if you didn't fetch it the first time. This is a
1379 good setting.
1296 1380
1297Never Fetch 1381Never Fetch
1298 Images are never fetched and only displayed if they are already 1382 Images are never fetched and only displayed if they are
1299 present in the cache. This is the default. 1383 already present in the cache. This is the default.
1300 1384
1301There isn't a value of \"Always Fetch\" for privacy and DOS (denial of 1385There isn't a value of \"Always Fetch\" for privacy and DOS (denial of
1302service) reasons. For example, fetching a URL can tip off a spammer that 1386service) reasons. For example, fetching a URL can tip off a spammer
1303you've read his email (which is why you shouldn't blindly answer yes if you've 1387that you've read his email (which is why you shouldn't blindly answer
1304set this option to \"Ask Before Fetching\"). Someone may also flood your 1388yes if you've set this option to \"Ask Before Fetching\"). Someone may
1305network and fill your disk drive by sending a torrent of messages, each 1389also flood your network and fill your disk drive by sending a torrent
1306specifying a unique URL to a very large file. 1390of messages, each specifying a unique URL to a very large file.
1307 1391
1308The cache of images is found in the directory \".mhe-x-image-cache\" within 1392The cache of images is found in the directory \".mhe-x-image-cache\"
1309your MH directory. You can add your own face to the \"From:\" field too. See 1393within your MH directory. You can add your own face to the \"From:\"
1310Info node `(mh-e)Picture'. 1394field too. See Info node `(mh-e)Picture'.
1311 1395
1312This setting only has effect if the option `mh-show-use-xface-flag' is turned 1396This setting only has effect if the option `mh-show-use-xface-flag' is
1313on." 1397turned on."
1314 1398
1315 :type '(choice (const :tag "Ask Before Fetching" ask) 1399 :type '(choice (const :tag "Ask Before Fetching" ask)
1316 (const :tag "Never Fetch" nil)) 1400 (const :tag "Never Fetch" nil))
@@ -1319,37 +1403,42 @@ on."
1319(defcustom mh-graphical-smileys-flag t 1403(defcustom mh-graphical-smileys-flag t
1320 "*Non-nil means graphical smileys are displayed. 1404 "*Non-nil means graphical smileys are displayed.
1321 1405
1322It is a long standing custom to inject body language using a cornucopia of 1406It is a long standing custom to inject body language using a
1323punctuation, also known as the \"smileys\". MH-E can render these as graphical 1407cornucopia of punctuation, also known as the \"smileys\". MH-E
1324widgets if this option is turned on, which it is by default. Smileys include 1408can render these as graphical widgets if this option is turned
1325patterns such as :-) and ;-). 1409on, which it is by default. Smileys include patterns such as :-)
1410and ;-).
1326 1411
1327This option is disabled if the option `mh-decode-mime-flag' is turned off." 1412This option is disabled if the option `mh-decode-mime-flag' is
1413turned off."
1328 :type 'boolean 1414 :type 'boolean
1329 :group 'mh-show) 1415 :group 'mh-show)
1330 1416
1331(defcustom mh-graphical-emphasis-flag t 1417(defcustom mh-graphical-emphasis-flag t
1332 "*Non-nil means graphical emphasis is displayed. 1418 "*Non-nil means graphical emphasis is displayed.
1333 1419
1334A few typesetting features are indicated in ASCII text with certain 1420A few typesetting features are indicated in ASCII text with
1335characters. If your terminal supports it, MH-E can render these typesetting 1421certain characters. If your terminal supports it, MH-E can render
1336directives naturally if this option is turned on, which it is by default. For 1422these typesetting directives naturally if this option is turned
1337example, _underline_ will be underlined, *bold* will appear in bold, /italics/ 1423on, which it is by default. For example, _underline_ will be
1338will appear in italics, and so on. See the option `gnus-emphasis-alist' for 1424underlined, *bold* will appear in bold, /italics/ will appear in
1339the whole list. 1425italics, and so on. See the option `gnus-emphasis-alist' for the
1426whole list.
1340 1427
1341This option is disabled if the option `mh-decode-mime-flag' is turned off." 1428This option is disabled if the option `mh-decode-mime-flag' is
1429turned off."
1342 :type 'boolean 1430 :type 'boolean
1343 :group 'mh-show) 1431 :group 'mh-show)
1344 1432
1345(defcustom mh-highlight-citation-style 'gnus 1433(defcustom mh-highlight-citation-style 'gnus
1346 "Style for highlighting citations. 1434 "Style for highlighting citations.
1347 1435
1348If the sender of the message has cited other messages in his message, then 1436If the sender of the message has cited other messages in his
1349MH-E will highlight these citations to emphasize the sender's actual response. 1437message, then MH-E will highlight these citations to emphasize
1350This option can be customized to change the highlighting style. The 1438the sender's actual response. This option can be customized to
1351\"Multicolor\" method uses a different color for each indentation while the 1439change the highlighting style. The \"Multicolor\" method uses a
1352\"Monochrome\" method highlights all citations in red. To disable highlighting 1440different color for each indentation while the \"Monochrome\"
1441method highlights all citations in red. To disable highlighting
1353of citations entirely, choose \"None\"." 1442of citations entirely, choose \"None\"."
1354 :type '(choice (const :tag "Multicolor" gnus) 1443 :type '(choice (const :tag "Multicolor" gnus)
1355 (const :tag "Monochrome" font-lock) 1444 (const :tag "Monochrome" font-lock)
@@ -1531,9 +1620,11 @@ of citations entirely, choose \"None\"."
1531 "X400-" ; X400 1620 "X400-" ; X400
1532 "Xref:") 1621 "Xref:")
1533 "List of default header fields that are not to be shown. 1622 "List of default header fields that are not to be shown.
1534Do not alter this variable directly. Instead, add entries from here that you 1623
1535would like to be displayed in `mh-invisible-header-fields-default' 1624Do not alter this variable directly. Instead, add entries from
1536and add entries to hide in `mh-invisible-header-fields'.") 1625here that you would like to be displayed in
1626`mh-invisible-header-fields-default' and add entries to hide in
1627`mh-invisible-header-fields'.")
1537 1628
1538(defvar mh-invisible-header-fields-compiled nil 1629(defvar mh-invisible-header-fields-compiled nil
1539 "*Regexp matching lines in a message header that are not to be shown. 1630 "*Regexp matching lines in a message header that are not to be shown.
@@ -1544,9 +1635,9 @@ hidden that you wish to display, and add extra entries to hide in
1544 1635
1545(defun mh-invisible-headers () 1636(defun mh-invisible-headers ()
1546 "Make or remake the variable `mh-invisible-header-fields-compiled'. 1637 "Make or remake the variable `mh-invisible-header-fields-compiled'.
1547Done using `mh-invisible-header-fields-internal' as input, from which entries 1638Done using `mh-invisible-header-fields-internal' as input, from
1548from `mh-invisible-header-fields-default' are removed and entries 1639which entries from `mh-invisible-header-fields-default' are
1549from `mh-invisible-header-fields' are added." 1640removed and entries from `mh-invisible-header-fields' are added."
1550 (let ((fields mh-invisible-header-fields-internal)) 1641 (let ((fields mh-invisible-header-fields-internal))
1551 (when mh-invisible-header-fields-default 1642 (when mh-invisible-header-fields-default
1552 ;; Remove entries from `mh-invisible-header-fields-default' 1643 ;; Remove entries from `mh-invisible-header-fields-default'
@@ -1570,11 +1661,11 @@ from `mh-invisible-header-fields' are added."
1570(defcustom mh-invisible-header-fields-default nil 1661(defcustom mh-invisible-header-fields-default nil
1571 "*List of hidden header fields. 1662 "*List of hidden header fields.
1572 1663
1573The header fields listed in this option are hidden, although you can check off 1664The header fields listed in this option are hidden, although you
1574any field that you would like to see. 1665can check off any field that you would like to see.
1575 1666
1576Header fields that you would like to hide that aren't listed can be added to 1667Header fields that you would like to hide that aren't listed can
1577the option `mh-invisible-header-fields'. 1668be added to the option `mh-invisible-header-fields'.
1578 1669
1579See also `mh-clean-message-header-flag'." 1670See also `mh-clean-message-header-flag'."
1580 :type `(set ,@(mapcar (lambda (x) `(const ,x)) 1671 :type `(set ,@(mapcar (lambda (x) `(const ,x))
@@ -1588,11 +1679,12 @@ See also `mh-clean-message-header-flag'."
1588 "*Additional header fields to hide. 1679 "*Additional header fields to hide.
1589 1680
1590Header fields that you would like to hide that aren't listed in 1681Header fields that you would like to hide that aren't listed in
1591`mh-invisible-header-fields-default' can be added to this option with a couple 1682`mh-invisible-header-fields-default' can be added to this option
1592of caveats. Regular expressions are not allowed. Unique fields should have a 1683with a couple of caveats. Regular expressions are not allowed.
1593`:' suffix; otherwise, the element can be used to render invisible an entire 1684Unique fields should have a \":\" suffix; otherwise, the element
1594class of fields that start with the same prefix. If you think a header field 1685can be used to render invisible an entire class of fields that
1595should be generally ignored, report a bug (see URL 1686start with the same prefix. If you think a header field should be
1687generally ignored, report a bug (see URL
1596`https://sourceforge.net/tracker/?group_id=13357&atid=113357'). 1688`https://sourceforge.net/tracker/?group_id=13357&atid=113357').
1597 1689
1598See also `mh-clean-message-header-flag'." 1690See also `mh-clean-message-header-flag'."
@@ -1606,12 +1698,13 @@ See also `mh-clean-message-header-flag'."
1606(defcustom mh-lpr-command-format "lpr -J '%s'" 1698(defcustom mh-lpr-command-format "lpr -J '%s'"
1607 "*Command used to print\\<mh-folder-mode-map>. 1699 "*Command used to print\\<mh-folder-mode-map>.
1608 1700
1609This option contains the Unix command line which performs the actual printing 1701This option contains the Unix command line which performs the
1610for the \\[mh-print-msg] command. The string can contain one escape, \"%s\", 1702actual printing for the \\[mh-print-msg] command. The string can
1611which is replaced by the name of the folder and the message number and is 1703contain one escape, \"%s\", which is replaced by the name of the
1612useful for print job names. I use \"mpage -h'%s' -b Letter -H1of -mlrtb -P\" 1704folder and the message number and is useful for print job names.
1613which produces a nice header and adds a bit of margin so the text fits within 1705I use \"mpage -h'%s' -b Letter -H1of -mlrtb -P\" which produces a
1614my printer's margins. 1706nice header and adds a bit of margin so the text fits within my
1707printer's margins.
1615 1708
1616This options is not used by the commands \\[mh-ps-print-msg] or 1709This options is not used by the commands \\[mh-ps-print-msg] or
1617\\[mh-ps-print-msg-file]." 1710\\[mh-ps-print-msg-file]."
@@ -1621,48 +1714,51 @@ This options is not used by the commands \\[mh-ps-print-msg] or
1621(defcustom mh-max-inline-image-height nil 1714(defcustom mh-max-inline-image-height nil
1622 "*Maximum inline image height if \"Content-Disposition:\" is not present. 1715 "*Maximum inline image height if \"Content-Disposition:\" is not present.
1623 1716
1624Some older mail programs do not insert this needed plumbing to tell 1717Some older mail programs do not insert this needed plumbing to
1625MH-E whether to display the attachments inline or not. If this is the 1718tell MH-E whether to display the attachments inline or not. If
1626case, MH-E will display these images inline if they are smaller than 1719this is the case, MH-E will display these images inline if they
1627the window. However, you might want to allow larger images to be 1720are smaller than the window. However, you might want to allow
1628displayed inline. To do this, you can change the options 1721larger images to be displayed inline. To do this, you can change
1629`mh-max-inline-image-width' and `mh-max-inline-image-height' from their 1722the options `mh-max-inline-image-width' and
1630default value of zero to a large number. The size of your screen is a 1723`mh-max-inline-image-height' from their default value of zero to
1631good choice for these numbers." 1724a large number. The size of your screen is a good choice for
1725these numbers."
1632 :type '(choice (const nil) integer) 1726 :type '(choice (const nil) integer)
1633 :group 'mh-show) 1727 :group 'mh-show)
1634 1728
1635(defcustom mh-max-inline-image-width nil 1729(defcustom mh-max-inline-image-width nil
1636 "*Maximum inline image width if \"Content-Disposition:\" is not present. 1730 "*Maximum inline image width if \"Content-Disposition:\" is not present.
1637 1731
1638Some older mail programs do not insert this needed plumbing to tell 1732Some older mail programs do not insert this needed plumbing to
1639MH-E whether to display the attachments inline or not. If this is the 1733tell MH-E whether to display the attachments inline or not. If
1640case, MH-E will display these images inline if they are smaller than 1734this is the case, MH-E will display these images inline if they
1641the window. However, you might want to allow larger images to be 1735are smaller than the window. However, you might want to allow
1642displayed inline. To do this, you can change the options 1736larger images to be displayed inline. To do this, you can change
1643`mh-max-inline-image-width' and `mh-max-inline-image-height' from their 1737the options `mh-max-inline-image-width' and
1644default value of zero to a large number. The size of your screen is a 1738`mh-max-inline-image-height' from their default value of zero to
1645good choice for these numbers." 1739a large number. The size of your screen is a good choice for
1740these numbers."
1646 :type '(choice (const nil) integer) 1741 :type '(choice (const nil) integer)
1647 :group 'mh-show) 1742 :group 'mh-show)
1648 1743
1649(defcustom mh-mhl-format-file nil 1744(defcustom mh-mhl-format-file nil
1650 "*Specifies the format file to pass to the \"mhl\" program. 1745 "*Specifies the format file to pass to the \"mhl\" program.
1651 1746
1652Normally MH-E takes care of displaying messages itself (rather than calling an 1747Normally MH-E takes care of displaying messages itself (rather than
1653MH program to do the work). If you'd rather have \"mhl\" display the 1748calling an MH program to do the work). If you'd rather have \"mhl\"
1654message (within MH-E), change this option from its default value of \"Use 1749display the message (within MH-E), change this option from its default
1655Default mhl Format (Printing Only)\". 1750value of \"Use Default mhl Format (Printing Only)\".
1656 1751
1657You can set this option to \"Use Default mhl Format\" to get the same output 1752You can set this option to \"Use Default mhl Format\" to get the same
1658as you would get if you ran \"mhl\" from the shell. 1753output as you would get if you ran \"mhl\" from the shell.
1659 1754
1660If you have a format file that you want MH-E to use, you can set this option 1755If you have a format file that you want MH-E to use, you can set this
1661to \"Specify an mhl Format File\" and enter the name of your format file. Your 1756option to \"Specify an mhl Format File\" and enter the name of your
1662format file should specify a non-zero value for \"overflowoffset\" to allow 1757format file. Your format file should specify a non-zero value for
1663MH-E to parse the header. Note that \"mhl\" is always used for printing and 1758\"overflowoffset\" to allow MH-E to parse the header. Note that
1664forwarding; in this case, the value of this option is consulted if you have 1759\"mhl\" is always used for printing and forwarding; in this case, the
1665specified a format file." 1760value of this option is consulted if you have specified a format
1761file."
1666 :type '(choice (const :tag "Use Default mhl Format (Printing Only)" nil) 1762 :type '(choice (const :tag "Use Default mhl Format (Printing Only)" nil)
1667 (const :tag "Use Default mhl Format" t) 1763 (const :tag "Use Default mhl Format" t)
1668 (file :tag "Specify an mhl Format File")) 1764 (file :tag "Specify an mhl Format File"))
@@ -1671,12 +1767,13 @@ specified a format file."
1671(defcustom mh-mime-save-parts-default-directory t 1767(defcustom mh-mime-save-parts-default-directory t
1672 "Default directory to use for \\<mh-folder-mode-map>\\[mh-mime-save-parts]. 1768 "Default directory to use for \\<mh-folder-mode-map>\\[mh-mime-save-parts].
1673 1769
1674The default value for this option is \"Prompt Always\" so that you are always 1770The default value for this option is \"Prompt Always\" so that
1675prompted for the directory in which to save the attachments. However, if you 1771you are always prompted for the directory in which to save the
1676usually use the same directory within a session, then you can set this option 1772attachments. However, if you usually use the same directory
1677to \"Prompt the First Time\" to avoid the prompt each time. you can make this 1773within a session, then you can set this option to \"Prompt the
1678directory permanent by choosing \"Directory\" and entering the directory's 1774First Time\" to avoid the prompt each time. you can make this
1679name." 1775directory permanent by choosing \"Directory\" and entering the
1776directory's name."
1680 :type '(choice (const :tag "Prompt the First Time" nil) 1777 :type '(choice (const :tag "Prompt the First Time" nil)
1681 (const :tag "Prompt Always" t) 1778 (const :tag "Prompt Always" t)
1682 directory) 1779 directory)
@@ -1685,11 +1782,12 @@ name."
1685(defcustom mh-print-background-flag nil 1782(defcustom mh-print-background-flag nil
1686 "*Non-nil means messages should be printed in the background\\<mh-folder-mode-map>. 1783 "*Non-nil means messages should be printed in the background\\<mh-folder-mode-map>.
1687 1784
1688Normally messages are printed in the foreground. If this is slow on your 1785Normally messages are printed in the foreground. If this is slow on
1689system, you may elect to turn off this option to print in the background. 1786your system, you may elect to turn off this option to print in the
1787background.
1690 1788
1691WARNING: If you do this, do not delete the message until it is printed or else 1789WARNING: If you do this, do not delete the message until it is printed
1692the output may be truncated. 1790or else the output may be truncated.
1693 1791
1694This option is not used by the commands \\[mh-ps-print-msg] or 1792This option is not used by the commands \\[mh-ps-print-msg] or
1695\\[mh-ps-print-msg-file]." 1793\\[mh-ps-print-msg-file]."
@@ -1699,9 +1797,9 @@ This option is not used by the commands \\[mh-ps-print-msg] or
1699(defcustom mh-show-maximum-size 0 1797(defcustom mh-show-maximum-size 0
1700 "*Maximum size of message (in bytes) to display automatically. 1798 "*Maximum size of message (in bytes) to display automatically.
1701 1799
1702This option provides an opportunity to skip over large messages which may be 1800This option provides an opportunity to skip over large messages
1703slow to load. The default value of 0 means that all message are shown 1801which may be slow to load. The default value of 0 means that all
1704regardless of size." 1802message are shown regardless of size."
1705 :type 'integer 1803 :type 'integer
1706 :group 'mh-show) 1804 :group 'mh-show)
1707 1805
@@ -1709,12 +1807,12 @@ regardless of size."
1709 goto-address-highlight-p) 1807 goto-address-highlight-p)
1710 "*Non-nil means highlight URLs and email addresses\\<goto-address-highlight-keymap>. 1808 "*Non-nil means highlight URLs and email addresses\\<goto-address-highlight-keymap>.
1711 1809
1712To send a message using the highlighted email address or to view the web page 1810To send a message using the highlighted email address or to view
1713for the highlighted URL, use the middle mouse button or 1811the web page for the highlighted URL, use the middle mouse button
1714\\[goto-address-at-point]. 1812or \\[goto-address-at-point].
1715 1813
1716See Info node `(mh-e)Sending Mail' to see how to configure Emacs to send the 1814See Info node `(mh-e)Sending Mail' to see how to configure Emacs
1717message using MH-E. 1815to send the message using MH-E.
1718 1816
1719The default value of this option comes from the value of 1817The default value of this option comes from the value of
1720`goto-address-highlight-p'." 1818`goto-address-highlight-p'."
@@ -1724,33 +1822,36 @@ The default value of this option comes from the value of
1724(defcustom mh-show-use-xface-flag (>= emacs-major-version 21) 1822(defcustom mh-show-use-xface-flag (>= emacs-major-version 21)
1725 "*Non-nil means display face images in MH-show buffers. 1823 "*Non-nil means display face images in MH-show buffers.
1726 1824
1727MH-E can display the content of \"Face:\", \"X-Face:\", and \"X-Image-URL:\" 1825MH-E can display the content of \"Face:\", \"X-Face:\", and
1728header fields. If any of these fields occur in the header of your message, the 1826\"X-Image-URL:\" header fields. If any of these fields occur in the
1729sender's face will appear in the \"From:\" header field. If more than one of 1827header of your message, the sender's face will appear in the \"From:\"
1730these fields appear, then the first field found in the order \"Face:\", 1828header field. If more than one of these fields appear, then the first
1731\"X-Face:\", and \"X-Image-URL:\" will be used. 1829field found in the order \"Face:\", \"X-Face:\", and \"X-Image-URL:\"
1732 1830will be used.
1733The option `mh-show-use-xface-flag' is used to turn this feature on and off. 1831
1734This feature will be turned on by default if your system supports it. 1832The option `mh-show-use-xface-flag' is used to turn this feature on
1735 1833and off. This feature will be turned on by default if your system
1736The first header field used, if present, is the Gnus-specific \"Face:\" field. 1834supports it.
1737The \"Face:\" field appeared in GNU Emacs 21 and XEmacs. For more information, 1835
1738see URL `http://quimby.gnus.org/circus/face/'. Next is the traditional 1836The first header field used, if present, is the Gnus-specific
1837\"Face:\" field. The \"Face:\" field appeared in GNU Emacs 21 and
1838XEmacs. For more information, see URL
1839`http://quimby.gnus.org/circus/face/'. Next is the traditional
1739\"X-Face:\" header field. The display of this field requires the 1840\"X-Face:\" header field. The display of this field requires the
1740\"uncompface\" program (see URL 1841\"uncompface\" program (see URL
1741`ftp://ftp.cs.indiana.edu/pub/faces/compface/compface.tar.z'). Recent versions 1842`ftp://ftp.cs.indiana.edu/pub/faces/compface/compface.tar.z'). Recent
1742of XEmacs have internal support for \"X-Face:\" images. If your version of 1843versions of XEmacs have internal support for \"X-Face:\" images. If
1743XEmacs does not, then you'll need both \"uncompface\" and the x-face 1844your version of XEmacs does not, then you'll need both \"uncompface\"
1744package (see URL `ftp://ftp.jpl.org/pub/elisp/'). 1845and the x-face package (see URL `ftp://ftp.jpl.org/pub/elisp/').
1745 1846
1746Finally, MH-E will display images referenced by the \"X-Image-URL:\" header 1847Finally, MH-E will display images referenced by the \"X-Image-URL:\"
1747field if neither the \"Face:\" nor the \"X-Face:\" fields are present. The 1848header field if neither the \"Face:\" nor the \"X-Face:\" fields are
1748display of the images requires \"wget\" (see URL 1849present. The display of the images requires \"wget\" (see URL
1749`http://www.gnu.org/software/wget/wget.html'), \"fetch\", or \"curl\" to fetch 1850`http://www.gnu.org/software/wget/wget.html'), \"fetch\", or \"curl\"
1750the image and the \"convert\" program from the ImageMagick suite (see URL 1851to fetch the image and the \"convert\" program from the ImageMagick
1751`http://www.imagemagick.org/'). Of the three header fields this is the most 1852suite (see URL `http://www.imagemagick.org/'). Of the three header
1752efficient in terms of network usage since the image doesn't need to be 1853fields this is the most efficient in terms of network usage since the
1753transmitted with every single mail. 1854image doesn't need to be transmitted with every single mail.
1754 1855
1755The option `mh-fetch-x-image-url' controls the fetching of the 1856The option `mh-fetch-x-image-url' controls the fetching of the
1756\"X-Image-URL:\" header field image." 1857\"X-Image-URL:\" header field image."
@@ -1760,9 +1861,10 @@ The option `mh-fetch-x-image-url' controls the fetching of the
1760(defcustom mh-store-default-directory nil 1861(defcustom mh-store-default-directory nil
1761 "*Default directory for \\<mh-folder-mode-map>\\[mh-store-msg]. 1862 "*Default directory for \\<mh-folder-mode-map>\\[mh-store-msg].
1762 1863
1763If you would like to change the initial default directory, customize this 1864If you would like to change the initial default directory,
1764option, change the value from `Current' to `Directory', and then enter the 1865customize this option, change the value from \"Current\" to
1765name of the directory for storing the content of these messages." 1866\"Directory\", and then enter the name of the directory for storing
1867the content of these messages."
1766 :type '(choice (const :tag "Current" nil) 1868 :type '(choice (const :tag "Current" nil)
1767 directory) 1869 directory)
1768 :group 'mh-show) 1870 :group 'mh-show)
@@ -1770,10 +1872,11 @@ name of the directory for storing the content of these messages."
1770(defcustom mh-summary-height nil 1872(defcustom mh-summary-height nil
1771 "*Number of lines in MH-Folder buffer (including the mode line). 1873 "*Number of lines in MH-Folder buffer (including the mode line).
1772 1874
1773The default value of this option is \"Automatic\" which means that the 1875The default value of this option is \"Automatic\" which means
1774MH-Folder buffer will maintain the same proportional size if the frame is 1876that the MH-Folder buffer will maintain the same proportional
1775resized. If you'd prefer a fixed height, then choose the \"Fixed Size\" option 1877size if the frame is resized. If you'd prefer a fixed height,
1776and enter the number of lines you'd like to see." 1878then choose the \"Fixed Size\" option and enter the number of
1879lines you'd like to see."
1777 :type '(choice (const :tag "Automatic" nil) 1880 :type '(choice (const :tag "Automatic" nil)
1778 (integer :tag "Fixed Size")) 1881 (integer :tag "Fixed Size"))
1779 :group 'mh-show) 1882 :group 'mh-show)
@@ -1795,9 +1898,10 @@ Set to 0 to disable automatic update."
1795(defcustom mh-show-threads-flag nil 1898(defcustom mh-show-threads-flag nil
1796 "*Non-nil means new folders start in threaded mode. 1899 "*Non-nil means new folders start in threaded mode.
1797 1900
1798Threading large number of messages can be time consuming so this option is 1901Threading large number of messages can be time consuming so this
1799turned off by default. If you turn this option on, then threading will be done 1902option is turned off by default. If you turn this option on, then
1800only if the number of messages being threaded is less than `mh-large-folder'." 1903threading will be done only if the number of messages being
1904threaded is less than `mh-large-folder'."
1801 :type 'boolean 1905 :type 'boolean
1802 :group 'mh-thread) 1906 :group 'mh-thread)
1803 1907
@@ -1809,8 +1913,8 @@ only if the number of messages being threaded is less than `mh-large-folder'."
1809 "*Function called by the tool bar search button. 1913 "*Function called by the tool bar search button.
1810 1914
1811Available functions include `mh-search-folder', the default, and 1915Available functions include `mh-search-folder', the default, and
1812`mh-index-search'. You can also choose \"Other Function\" from the \"Value 1916`mh-index-search'. You can also choose \"Other Function\" from
1813Menu\" and enter a function of your own choosing." 1917the \"Value Menu\" and enter a function of your own choosing."
1814 :type '(choice (const mh-search-folder) 1918 :type '(choice (const mh-search-folder)
1815 (const mh-index-search) 1919 (const mh-index-search)
1816 (function :tag "Other Function")) 1920 (function :tag "Other Function"))
@@ -1842,7 +1946,7 @@ Optional argument ARG is not used."
1842 1946
1843(defmacro mh-tool-bar-reply-generator (function recipient folder-buffer-flag) 1947(defmacro mh-tool-bar-reply-generator (function recipient folder-buffer-flag)
1844 "Generate FUNCTION that replies to RECIPIENT. 1948 "Generate FUNCTION that replies to RECIPIENT.
1845If FOLDER-BUFFER-FLAG is nil then the function generated 1949If FOLDER-BUFFER-FLAG is nil then the function generated...
1846When INCLUDE-FLAG is non-nil, include message body being replied to." 1950When INCLUDE-FLAG is non-nil, include message body being replied to."
1847 `(defun ,function (&optional arg) 1951 `(defun ,function (&optional arg)
1848 ,(format "Reply to \"%s\".\nWhen ARG is non-nil include message in reply." 1952 ,(format "Reply to \"%s\".\nWhen ARG is non-nil include message in reply."
@@ -1863,9 +1967,10 @@ When INCLUDE-FLAG is non-nil, include message body being replied to."
1863 (defcustom mh-xemacs-use-tool-bar-flag mh-xemacs-has-tool-bar-flag 1967 (defcustom mh-xemacs-use-tool-bar-flag mh-xemacs-has-tool-bar-flag
1864 "*If non-nil, use tool bar. 1968 "*If non-nil, use tool bar.
1865 1969
1866This option controls whether to show the MH-E icons at all. By default, this 1970This option controls whether to show the MH-E icons at all. By
1867option is turned on if the window system supports tool bars. If your system 1971default, this option is turned on if the window system supports
1868doesn't support tool bars, then you won't be able to turn on this option." 1972tool bars. If your system doesn't support tool bars, then you
1973won't be able to turn on this option."
1869 :type 'boolean 1974 :type 'boolean
1870 :group 'mh-tool-bar 1975 :group 'mh-tool-bar
1871 :set (lambda (symbol value) 1976 :set (lambda (symbol value)
@@ -1877,11 +1982,12 @@ doesn't support tool bars, then you won't be able to turn on this option."
1877 (defcustom mh-xemacs-tool-bar-position nil 1982 (defcustom mh-xemacs-tool-bar-position nil
1878 "*Tool bar location. 1983 "*Tool bar location.
1879 1984
1880This option controls the placement of the tool bar along the four edges of the 1985This option controls the placement of the tool bar along the four
1881frame. You can choose from one of \"Same As Default Tool Bar\", \"Top\", 1986edges of the frame. You can choose from one of \"Same As Default
1882\"Bottom\", \"Left\", or \"Right\". If this variable is set to anything other 1987Tool Bar\", \"Top\", \"Bottom\", \"Left\", or \"Right\". If this
1883than \"Same As Default Tool Bar\" and the default tool bar is in a different 1988variable is set to anything other than \"Same As Default Tool
1884location, then two tool bars will be displayed: the MH-E tool bar and the 1989Bar\" and the default tool bar is in a different location, then
1990two tool bars will be displayed: the MH-E tool bar and the
1885default tool bar." 1991default tool bar."
1886 :type '(radio (const :tag "Same As Default Tool Bar" :value nil) 1992 :type '(radio (const :tag "Same As Default Tool Bar" :value nil)
1887 (const :tag "Top" :value top) 1993 (const :tag "Top" :value top)
@@ -1900,47 +2006,49 @@ default tool bar."
1900 2006
1901(defmacro mh-tool-bar-define (defaults &rest buttons) 2007(defmacro mh-tool-bar-define (defaults &rest buttons)
1902 "Define a tool bar for MH-E. 2008 "Define a tool bar for MH-E.
1903DEFAULTS is the list of buttons that are present by default. It is a list of 2009DEFAULTS is the list of buttons that are present by default. It
1904lists where the sublists are of the following form: 2010is a list of lists where the sublists are of the following form:
1905 2011
1906 (:KEYWORD FUNC1 FUNC2 FUNC3 ...) 2012 (:KEYWORD FUNC1 FUNC2 FUNC3 ...)
1907 2013
1908Here :KEYWORD is one of :folder or :letter. If it is :folder then the default 2014Here :KEYWORD is one of :folder or :letter. If it is :folder then
1909buttons in the folder and show mode buffers are being specified. If it is 2015the default buttons in the folder and show mode buffers are being
1910:letter then the default buttons in the letter mode are listed. FUNC1, FUNC2, 2016specified. If it is :letter then the default buttons in the
1911FUNC3, ... are the names of the functions that the buttons would execute. 2017letter mode are listed. FUNC1, FUNC2, FUNC3, ... are the names of
2018the functions that the buttons would execute.
1912 2019
1913Each element of BUTTONS is a list consisting of four mandatory items and one 2020Each element of BUTTONS is a list consisting of four mandatory
1914optional item as follows: 2021items and one optional item as follows:
1915 2022
1916 (FUNCTION MODES ICON DOC &optional ENABLE-EXPR) 2023 (FUNCTION MODES ICON DOC &optional ENABLE-EXPR)
1917 2024
1918where, 2025where,
1919 2026
1920 FUNCTION is the name of the function that will be executed when the button 2027 FUNCTION is the name of the function that will be executed when
1921 is clicked. 2028 the button is clicked.
1922 2029
1923 MODES is a list of symbols. List elements must be from `folder', `letter' and 2030 MODES is a list of symbols. List elements must be from \"folder\",
1924 `sequence'. If `folder' is present then the button is available in the 2031 \"letter\" and \"sequence\". If \"folder\" is present then the button is
1925 folder and show buffer. If the name of FUNCTION is of the form \"mh-foo\", 2032 available in the folder and show buffer. If the name of FUNCTION is
1926 where foo is some arbitrary string, then we check if the function 2033 of the form \"mh-foo\", where foo is some arbitrary string, then we
1927 `mh-show-foo' exists. If it exists then that function is used in the show 2034 check if the function `mh-show-foo' exists. If it exists then that
1928 buffer. Otherwise the original function `mh-foo' is used in the show buffer 2035 function is used in the show buffer. Otherwise the original function
1929 as well. Presence of `sequence' is handled similar to the above. The only 2036 `mh-foo' is used in the show buffer as well. Presence of \"sequence\"
1930 difference is that the button is shown only when the folder is narrowed to a 2037 is handled similar to the above. The only difference is that the
1931 sequence. If `letter' is present in MODES, then the button is available 2038 button is shown only when the folder is narrowed to a sequence. If
1932 during draft editing and runs FUNCTION when clicked. 2039 \"letter\" is present in MODES, then the button is available during
2040 draft editing and runs FUNCTION when clicked.
1933 2041
1934 ICON is the icon that is drawn in the button. 2042 ICON is the icon that is drawn in the button.
1935 2043
1936 DOC is the documentation for the button. It is used in tool-tips and in 2044 DOC is the documentation for the button. It is used in tool-tips and
1937 providing other help to the user. GNU Emacs uses only the first line of the 2045 in providing other help to the user. GNU Emacs uses only the first
1938 string. So the DOC should be formatted such that the first line is useful and 2046 line of the string. So the DOC should be formatted such that the
1939 complete without the rest of the string. 2047 first line is useful and complete without the rest of the string.
1940 2048
1941 Optional item ENABLE-EXPR is an arbitrary lisp expression. If it evaluates 2049 Optional item ENABLE-EXPR is an arbitrary lisp expression. If it
1942 to nil, then the button is deactivated, otherwise it is active. If is in't 2050 evaluates to nil, then the button is deactivated, otherwise it is
1943 present then the button is always active." 2051 active. If it isn't present then the button is always active."
1944 ;; The following variable names have been carefully chosen to make code 2052 ;; The following variable names have been carefully chosen to make code
1945 ;; generation easier. Modifying the names should be done carefully. 2053 ;; generation easier. Modifying the names should be done carefully.
1946 (let (folder-buttons folder-docs folder-button-setter sequence-button-setter 2054 (let (folder-buttons folder-docs folder-button-setter sequence-button-setter
@@ -2227,176 +2335,191 @@ This button runs `mh-previous-undeleted-msg'")
2227 2335
2228;;; Hooks (:group 'mh-hooks + group where hook described) 2336;;; Hooks (:group 'mh-hooks + group where hook described)
2229 2337
2230(defcustom mail-citation-hook nil 2338(defcustom mh-after-commands-processed-hook nil
2231 "*Hook for modifying a citation just inserted in the mail buffer. 2339 "Hook run by \\<mh-folder-mode-map>\\[mh-execute-commands] after performing outstanding requests.
2232You can gain full control over the appearance of the included text by setting 2340
2233this hook to a function that modifies it. This hook is ignored if the option 2341Variables that are useful in this hook include
2234`mh-yank-behavior' is set to one of the supercite flavors. Otherwise, this 2342`mh-folders-changed', which lists which folders were affected by
2235option controls how much of the message is passed to the hook. The function 2343deletes and refiles. This list will always include the current
2236can find the citation between point and mark and it should leave point and 2344folder, which is also available in `mh-current-folder'."
2237mark around the modified citation text for the next hook function. The
2238standard prefix `mh-ins-buf-prefix' is not added if this hook is set.
2239
2240For example, if you use the hook function trivial-cite (which is NOT part of
2241Emacs), set `mh-yank-behavior' to \"Body and Header\" (see URL
2242`http://shasta.cs.uiuc.edu/~lrclause/tc.html')."
2243 :type 'hook 2345 :type 'hook
2244 :options '(trivial-cite)
2245 :group 'mh-hooks 2346 :group 'mh-hooks
2246 :group 'mh-letter) 2347 :group 'mh-folder)
2247 2348
2248(defcustom mh-alias-reloaded-hook nil 2349(defcustom mh-alias-reloaded-hook nil
2249 "Invoked by `mh-alias-reload' after reloading aliases." 2350 "Hook run by `mh-alias-reload' after loading aliases."
2250 :type 'hook 2351 :type 'hook
2251 :group 'mh-hooks 2352 :group 'mh-hooks
2252 :group 'mh-alias) 2353 :group 'mh-alias)
2253 2354
2355(defcustom mh-before-commands-processed-hook nil
2356 "Hook run by \\<mh-folder-mode-map>\\[mh-execute-commands] before performing outstanding requests.
2357
2358Variables that are useful in this hook include `mh-delete-list'
2359and `mh-refile-list' which can be used to see which changes will
2360be made to the current folder, `mh-current-folder'."
2361 :type 'hook
2362 :group 'mh-hooks
2363 :group 'mh-folder)
2364
2254(defcustom mh-before-quit-hook nil 2365(defcustom mh-before-quit-hook nil
2255 "Invoked by \\<mh-folder-mode-map>`\\[mh-quit]' before quitting MH-E. 2366 "Hook run by \\<mh-folder-mode-map>\\[mh-quit] before quitting MH-E.
2367
2368This hook is called before the quit occurs, so you might use it
2369to perform any MH-E operations; you could perform some query and
2370abort the quit or call `mh-execute-commands', for example.
2371
2256See also `mh-quit-hook'." 2372See also `mh-quit-hook'."
2257 :type 'hook 2373 :type 'hook
2258 :group 'mh-hooks 2374 :group 'mh-hooks
2259 :group 'mh-folder) 2375 :group 'mh-folder)
2260 2376
2261(defcustom mh-before-send-letter-hook nil 2377(defcustom mh-before-send-letter-hook nil
2262 "Invoked at the beginning of the \\<mh-letter-mode-map>\\[mh-send-letter] command. 2378 "Hook run at the beginning of the \\<mh-letter-mode-map>\\[mh-send-letter] command.
2263For example, if you want to check your spelling in your message before 2379
2264sending, add the `ispell-message' function." 2380For example, if you want to check your spelling in your message
2381before sending, add the `ispell-message' function."
2265 :type 'hook 2382 :type 'hook
2266 :options '(ispell-message) 2383 :options '(ispell-message)
2267 :group 'mh-hooks 2384 :group 'mh-hooks
2268 :group 'mh-letter) 2385 :group 'mh-letter)
2269 2386
2270(defcustom mh-delete-msg-hook nil 2387(defcustom mh-delete-msg-hook nil
2271 "Invoked after marking each message for deletion. 2388 "Hook run by \\<mh-letter-mode-map>\\[mh-delete-msg] after marking each message for deletion.
2272 2389
2273For example, a past maintainer of MH-E used this once when he kept statistics 2390For example, a past maintainer of MH-E used this once when he
2274on his mail usage." 2391kept statistics on his mail usage."
2275 :type 'hook 2392 :type 'hook
2276 :group 'mh-hooks 2393 :group 'mh-hooks
2277 :group 'mh-show) 2394 :group 'mh-show)
2278 2395
2279(defcustom mh-mh-to-mime-hook nil
2280 "Invoked on the formatted letter by \\<mh-letter-mode-map>\\[mh-mh-to-mime]."
2281 :type 'hook
2282 :group 'mh-hooks
2283 :group 'mh-letter)
2284
2285(defcustom mh-find-path-hook nil 2396(defcustom mh-find-path-hook nil
2286 "Invoked by `mh-find-path' after reading the user's MH profile." 2397 "Hook run by `mh-find-path' after reading the user's MH profile.
2398
2399This hook can be used the change the value of the variables that
2400`mh-find-path' sets if you need to run with different values
2401between MH and MH-E."
2287 :type 'hook 2402 :type 'hook
2288 :group 'mh-hooks 2403 :group 'mh-hooks
2289 :group 'mh-e) 2404 :group 'mh-e)
2290 2405
2291(defcustom mh-folder-mode-hook nil 2406(defcustom mh-folder-mode-hook nil
2292 "Invoked in `mh-folder-mode' on a new folder." 2407 "Hook run by `mh-folder-mode' when visiting a new folder."
2293 :type 'hook 2408 :type 'hook
2294 :group 'mh-hooks 2409 :group 'mh-hooks
2295 :group 'mh-folder) 2410 :group 'mh-folder)
2296 2411
2297(defcustom mh-before-commands-processed-hook nil
2298 "Invoked before the folder actions (such as moves and deletes) are performed.
2299Variables that are useful in this hook include `mh-delete-list' and
2300`mh-refile-list' which can be used to see which changes will be made to
2301current folder, `mh-current-folder'."
2302 :type 'hook
2303 :group 'mh-hooks
2304 :group 'mh-folder)
2305
2306(defcustom mh-after-commands-processed-hook nil
2307 "Invoked after the folder actions (such as moves and deletes) are performed.
2308Variables that are useful in this hook include `mh-folders-changed',
2309which lists which folders were affected by deletes and refiles. This
2310list will always include the current folder, which is also available
2311in `mh-current-folder'."
2312 :type 'hook
2313 :group 'mh-hooks)
2314
2315(defcustom mh-forward-hook nil 2412(defcustom mh-forward-hook nil
2316 "Invoked on the forwarded letter by \\<mh-folder-mode-map>\\[mh-forward]." 2413 "Hook run by `mh-forward' on a forwarded letter."
2317 :type 'hook 2414 :type 'hook
2318 :group 'mh-hooks 2415 :group 'mh-hooks
2319 :group 'mh-sending-mail) 2416 :group 'mh-sending-mail)
2320 2417
2321(defcustom mh-inc-folder-hook nil 2418(defcustom mh-inc-folder-hook nil
2322 "Invoked by \\<mh-folder-mode-map>`\\[mh-inc-folder]' after incorporating mail into a folder." 2419 "Hook run by \\<mh-folder-mode-map>\\[mh-inc-folder] after incorporating mail into a folder."
2323 :type 'hook 2420 :type 'hook
2324 :group 'mh-hooks 2421 :group 'mh-hooks
2325 :group 'mh-inc) 2422 :group 'mh-inc)
2326 2423
2327(defcustom mh-insert-signature-hook nil 2424(defcustom mh-insert-signature-hook nil
2328 "Invoked after signature has been inserted. 2425 "Hook run by \\<mh-letter-mode-map>\\[mh-insert-signature] after signature has been inserted.
2329 2426
2330These functions may access the actual name of the file or the function used to 2427Hook functions may access the actual name of the file or the
2331insert the signature with `mh-signature-file-name'." 2428function used to insert the signature with
2429`mh-signature-file-name'."
2332 :type 'hook 2430 :type 'hook
2333 :group 'mh-hooks 2431 :group 'mh-hooks
2334 :group 'mh-letter) 2432 :group 'mh-letter)
2335 2433
2336(defcustom mh-kill-folder-suppress-prompt-hook '(mh-index-p) 2434(defcustom mh-kill-folder-suppress-prompt-hooks '(mh-index-p)
2337 "Invoked at the beginning of the \\<mh-folder-mode-map>`\\[mh-kill-folder]' command. 2435 "Abnormal hook run at the beginning of \\<mh-folder-mode-map>\\[mh-kill-folder].
2338This hook is a list of functions to be called, with no arguments, which should
2339return a value of non-nil if you should not be asked if you're sure that you
2340want to remove the folder. This is useful for folders that are easily
2341regenerated.
2342 2436
2343The default value of `mh-index-p' suppresses the prompt on folders generated 2437The hook functions are called with no arguments and should return
2344by an index search. 2438a non-nil value to suppress the normal prompt when you remove a
2439folder. This is useful for folders that are easily regenerated.
2345 2440
2346WARNING: Use this hook with care. If there is a bug in your hook which returns 2441The default value of `mh-index-p' suppresses the prompt on
2347t on +inbox and you hit \\<mh-folder-mode-map>`\\[mh-kill-folder]' by accident 2442folders generated by an index search.
2348in the +inbox buffer, you will not be happy." 2443
2444WARNING: Use this hook with care. If there is a bug in your hook
2445which returns t on \"+inbox\" and you hit \\[mh-kill-folder] by
2446accident in the \"+inbox\" folder, you will not be happy."
2349 :type 'hook 2447 :type 'hook
2350 :group 'mh-hooks 2448 :group 'mh-hooks
2351 :group 'mh-folder) 2449 :group 'mh-folder)
2352 2450
2353(defcustom mh-letter-mode-hook nil 2451(defcustom mh-letter-mode-hook nil
2354 "Invoked by `mh-letter-mode' on a new letter." 2452 "Hook run by `mh-letter-mode' on a new letter.
2453
2454This hook allows you to do some processing before editing a
2455letter. For example, you may wish to modify the header after
2456\"repl\" has done its work, or you may have a complicated
2457\"components\" file and need to tell MH-E where the cursor should
2458go."
2355 :type 'hook 2459 :type 'hook
2356 :group 'mh-hooks 2460 :group 'mh-hooks
2357 :group 'mh-sending-mail) 2461 :group 'mh-sending-mail)
2358 2462
2463(defcustom mh-mh-to-mime-hook nil
2464 "Hook run on the formatted letter by \\<mh-letter-mode-map>\\[mh-mh-to-mime]."
2465 :type 'hook
2466 :group 'mh-hooks
2467 :group 'mh-letter)
2468
2359(defcustom mh-pick-mode-hook nil 2469(defcustom mh-pick-mode-hook nil
2360 "Invoked upon entry to `mh-pick-mode'." 2470 "Hook run upon entry to `mh-pick-mode'\\<mh-folder-mode-map>.
2471
2472If you find that you do the same thing over and over when editing
2473the search template, you may wish to bind some shortcuts to keys.
2474This can be done with this hook which is called when
2475\\[mh-search-folder] is run on a new pattern."
2361 :type 'hook 2476 :type 'hook
2362 :group 'mh-hooks 2477 :group 'mh-hooks
2363 :group 'mh-index) 2478 :group 'mh-index)
2364 2479
2365(defcustom mh-quit-hook nil 2480(defcustom mh-quit-hook nil
2366 "Invoked after \\<mh-folder-mode-map>`\\[mh-quit]' quits MH-E. 2481 "Hook run by \\<mh-folder-mode-map>\\[mh-quit] after quitting MH-E.
2482
2483This hook is not run in an MH-E context, so you might use it to
2484modify the window setup.
2485
2367See also `mh-before-quit-hook'." 2486See also `mh-before-quit-hook'."
2368 :type 'hook 2487 :type 'hook
2369 :group 'mh-hooks 2488 :group 'mh-hooks
2370 :group 'mh-folder) 2489 :group 'mh-folder)
2371 2490
2372(defcustom mh-refile-msg-hook nil 2491(defcustom mh-refile-msg-hook nil
2373 "Invoked after marking each message for refiling." 2492 "Hook run by \\<mh-folder-mode-map>\\[mh-refile-msg] after marking each message for refiling."
2374 :type 'hook 2493 :type 'hook
2375 :group 'mh-hooks 2494 :group 'mh-hooks
2376 :group 'mh-folder) 2495 :group 'mh-folder)
2377 2496
2378(defcustom mh-show-hook nil 2497(defcustom mh-show-hook nil
2379 "Invoked after \\<mh-folder-mode-map>\\[mh-show] shows a message. 2498 "Hook run after \\<mh-folder-mode-map>\\[mh-show] shows a message.
2380 2499
2381It is the last thing called after messages are displayed. It's used to affect 2500It is the last thing called after messages are displayed. It's
2382the behavior of MH-E in general or when `mh-show-mode-hook' is too early." 2501used to affect the behavior of MH-E in general or when
2502`mh-show-mode-hook' is too early."
2383 :type 'hook 2503 :type 'hook
2384 :group 'mh-hooks 2504 :group 'mh-hooks
2385 :group 'mh-show) 2505 :group 'mh-show)
2386 2506
2387(defcustom mh-show-mode-hook nil 2507(defcustom mh-show-mode-hook nil
2388 "Invoked upon entry to `mh-show-mode'. 2508 "Hook run upon entry to `mh-show-mode'.
2389 2509
2390This hook is called early on in the process of the message display. It is 2510This hook is called early on in the process of the message
2391usually used to perform some action on the message's content." 2511display. It is usually used to perform some action on the
2512message's content."
2392 :type 'hook 2513 :type 'hook
2393 :group 'mh-hooks 2514 :group 'mh-hooks
2394 :group 'mh-show) 2515 :group 'mh-show)
2395 2516
2396(defcustom mh-unseen-updated-hook nil 2517(defcustom mh-unseen-updated-hook nil
2397 "Invoked after the unseen sequence has been updated. 2518 "Hook run after the unseen sequence has been updated.
2398The variable `mh-seen-list' can be used to obtain the list of messages which 2519
2399will be removed from the unseen sequence." 2520The variable `mh-seen-list' can be used by this hook to obtain
2521the list of messages which were removed from the unseen
2522sequence."
2400 :type 'hook 2523 :type 'hook
2401 :group 'mh-hooks 2524 :group 'mh-hooks
2402 :group 'mh-sequences) 2525 :group 'mh-sequences)
@@ -2675,7 +2798,8 @@ will be removed from the unseen sequence."
2675 2798
2676(defvar mh-show-pgg-unknown-face 'mh-show-pgg-unknown 2799(defvar mh-show-pgg-unknown-face 'mh-show-pgg-unknown
2677 "Face used to highlight a PGG signature whose status is unknown. 2800 "Face used to highlight a PGG signature whose status is unknown.
2678This face is also used for a signature when the signer is untrusted.") 2801This face is also used for a signature when the signer is
2802untrusted.")
2679(defface mh-show-pgg-unknown 2803(defface mh-show-pgg-unknown
2680 '((t 2804 '((t
2681 (:bold t :foreground "DarkGoldenrod2"))) 2805 (:bold t :foreground "DarkGoldenrod2")))
diff --git a/lisp/mh-e/mh-e.el b/lisp/mh-e/mh-e.el
index 0c8c3346ecb..30034008cec 100644
--- a/lisp/mh-e/mh-e.el
+++ b/lisp/mh-e/mh-e.el
@@ -102,7 +102,8 @@
102 102
103(defvar mh-partial-folder-mode-line-annotation "select" 103(defvar mh-partial-folder-mode-line-annotation "select"
104 "Annotation when displaying part of a folder. 104 "Annotation when displaying part of a folder.
105The string is displayed after the folder's name. nil for no annotation.") 105The string is displayed after the folder's name. nil for no
106annotation.")
106 107
107 108
108 109
@@ -133,15 +134,16 @@ The string is displayed after the folder's name. nil for no annotation.")
133 "%<(zero)%17(friendly{from})%> " 134 "%<(zero)%17(friendly{from})%> "
134 "%{subject}%<{body}<<%{body}%>") 135 "%{subject}%<{body}<<%{body}%>")
135 "*Scan format string for MH. 136 "*Scan format string for MH.
136This string is passed to the scan program via the -format argument. 137This string is passed to the scan program via the -format
137This format is identical to the default except that additional hints for 138argument. This format is identical to the default except that
138fontification have been added to the fifth column (remember that in Emacs, the 139additional hints for fontification have been added to the fifth
139first column is 0). 140column (remember that in Emacs, the first column is 0).
140 141
141The values of the fifth column, in priority order, are: `-' if the message has 142The values of the fifth column, in priority order, are: \"-\" if
142been replied to, t if an address on the To: line matches one of the 143the message has been replied to, t if an address on the To: line
143mailboxes of the current user, `c' if the Cc: line matches, `b' if the Bcc: 144matches one of the mailboxes of the current user, \"c\" if the Cc:
144line matches, and `n' if a non-empty Newsgroups: header is present.") 145line matches, \"b\" if the Bcc: line matches, and \"n\" if a
146non-empty Newsgroups: header is present.")
145 147
146(defvar mh-scan-format-nmh 148(defvar mh-scan-format-nmh
147 (concat 149 (concat
@@ -159,14 +161,15 @@ line matches, and `n' if a non-empty Newsgroups: header is present.")
159 "%(decode{subject})%<{body}<<%{body}%>") 161 "%(decode{subject})%<{body}<<%{body}%>")
160 "*Scan format string for nmh. 162 "*Scan format string for nmh.
161This string is passed to the scan program via the -format arg. 163This string is passed to the scan program via the -format arg.
162This format is identical to the default except that additional hints for 164This format is identical to the default except that additional
163fontification have been added to the fifth column (remember that in Emacs, the 165hints for fontification have been added to the fifth
164first column is 0). 166column (remember that in Emacs, the first column is 0).
165 167
166The values of the fifth column, in priority order, are: `-' if the message has 168The values of the fifth column, in priority order, are: \"-\" if
167been replied to, t if an address on the To: field matches one of the 169the message has been replied to, t if an address on the To: field
168mailboxes of the current user, `c' if the Cc: field matches, `b' if the Bcc: 170matches one of the mailboxes of the current user, \"c\" if the Cc:
169field matches, and `n' if a non-empty Newsgroups: field is present.") 171field matches, \"b\" if the Bcc: field matches, and \"n\" if a
172non-empty Newsgroups: field is present.")
170 173
171(defvar mh-note-deleted ?D 174(defvar mh-note-deleted ?D
172 "Messages that have been deleted are marked by this character. 175 "Messages that have been deleted are marked by this character.
@@ -182,101 +185,140 @@ See also `mh-scan-cur-msg-number-regexp'.")
182 185
183(defvar mh-scan-good-msg-regexp "^\\( *[0-9]+\\)[^D^0-9]" 186(defvar mh-scan-good-msg-regexp "^\\( *[0-9]+\\)[^D^0-9]"
184 "This regular expression matches \"good\" messages. 187 "This regular expression matches \"good\" messages.
185It must match from the beginning of the line. Note that the default setting of 188
186`mh-folder-font-lock-keywords' expects this expression to contain at least one 189It must match from the beginning of the line. Note that the
187parenthesized expression which matches the message number as in the default of 190default setting of `mh-folder-font-lock-keywords' expects this
188\"^\\\\( *[0-9]+\\\\)[^D^0-9]\". This expression includes the leading space 191expression to contain at least one parenthesized expression which
189within the parenthesis since it looks better to highlight it as well. This 192matches the message number as in the default of
190regular expression should be correct as it is needed by non-fontification 193
194 \"^\\\\( *[0-9]+\\\\)[^D^0-9]\".
195
196This expression includes the leading space within the parenthesis
197since it looks better to highlight it as well. This regular
198expression should be correct as it is needed by non-fontification
191functions.") 199functions.")
192 200
193(defvar mh-scan-deleted-msg-regexp "^\\( *[0-9]+\\)D" 201(defvar mh-scan-deleted-msg-regexp "^\\( *[0-9]+\\)D"
194 "This regular expression matches deleted messages. 202 "This regular expression matches deleted messages.
195It must match from the beginning of the line. Note that the default setting of 203
196`mh-folder-font-lock-keywords' expects this expression to contain at least one 204It must match from the beginning of the line. Note that the
197parenthesized expression which matches the message number as in the default of 205default setting of `mh-folder-font-lock-keywords' expects this
198\"^\\\\( *[0-9]+\\\\)D\". This expression includes the leading space within 206expression to contain at least one parenthesized expression which
199the parenthesis since it looks better to highlight it as well. This regular 207matches the message number as in the default of
200expression should be correct as it is needed by non-fontification functions. 208
201See also `mh-note-deleted'.") 209 \"^\\\\( *[0-9]+\\\\)D\".
210
211This expression includes the leading space within the parenthesis
212since it looks better to highlight it as well. This regular
213expression should be correct as it is needed by non-fontification
214functions. See also `mh-note-deleted'.")
202 215
203(defvar mh-scan-refiled-msg-regexp "^\\( *[0-9]+\\)\\^" 216(defvar mh-scan-refiled-msg-regexp "^\\( *[0-9]+\\)\\^"
204 "This regular expression matches refiled messages. 217 "This regular expression matches refiled messages.
205It must match from the beginning of the line. Note that the default setting of 218
206`mh-folder-font-lock-keywords' expects this expression to contain at least one 219It must match from the beginning of the line. Note that the
207parenthesized expression which matches the message number as in the default of 220default setting of `mh-folder-font-lock-keywords' expects this
208\"^\\\\( *[0-9]+\\\\)\\\\^\". This expression includes the leading space 221expression to contain at least one parenthesized expression which
209within the parenthesis since it looks better to highlight it as well. This 222matches the message number as in the default of
210regular expression should be correct as it is needed by non-fontification 223
224 \"^\\\\( *[0-9]+\\\\)\\\\^\".
225
226This expression includes the leading space within the parenthesis
227since it looks better to highlight it as well. This regular
228expression should be correct as it is needed by non-fontification
211functions. See also `mh-note-refiled'.") 229functions. See also `mh-note-refiled'.")
212 230
213(defvar mh-scan-valid-regexp "^ *[0-9]" 231(defvar mh-scan-valid-regexp "^ *[0-9]"
214 "This regular expression describes a valid scan line. 232 "This regular expression describes a valid scan line.
215This is used to eliminate error messages that are occasionally produced by 233
216\"inc\".") 234This is used to eliminate error messages that are occasionally
235produced by \"inc\".")
217 236
218(defvar mh-scan-cur-msg-number-regexp "^\\( *[0-9]+\\+\\).*" 237(defvar mh-scan-cur-msg-number-regexp "^\\( *[0-9]+\\+\\).*"
219 "This regular expression matches the current message. 238 "This regular expression matches the current message.
220It must match from the beginning of the line. Note that the default setting of 239
221`mh-folder-font-lock-keywords' expects this expression to contain at least one 240It must match from the beginning of the line. Note that the
222parenthesized expression which matches the message number as in the default of 241default setting of `mh-folder-font-lock-keywords' expects this
223\"^\\\\( *[0-9]+\\\\+\\\\).*\". This expression includes the leading space and 242expression to contain at least one parenthesized expression which
224current message marker \"+\" within the parenthesis since it looks better to 243matches the message number as in the default of
225highlight these items as well. This regular expression should be correct as it 244
226is needed by non-fontification functions. See also `mh-note-cur'.") 245 \"^\\\\( *[0-9]+\\\\+\\\\).*\".
246
247This expression includes the leading space and current message
248marker \"+\" within the parenthesis since it looks better to
249highlight these items as well. This regular expression should be
250correct as it is needed by non-fontification functions. See also
251`mh-note-cur'.")
227 252
228(defvar mh-scan-date-regexp "\\([0-9][0-9]/[0-9][0-9]\\)" 253(defvar mh-scan-date-regexp "\\([0-9][0-9]/[0-9][0-9]\\)"
229 "This regular expression matches a valid date. 254 "This regular expression matches a valid date.
230It must not be anchored to the beginning or the end of the line. Note that the 255
231default setting of `mh-folder-font-lock-keywords' expects this expression to 256It must not be anchored to the beginning or the end of the line.
232contain only one parenthesized expression which matches the date field as in 257Note that the default setting of `mh-folder-font-lock-keywords'
233the default of \"\\\\([0-9][0-9]/[0-9][0-9]\\\\)\"}. If this regular 258expects this expression to contain only one parenthesized
234expression is not correct, the date will not be highlighted. See also 259expression which matches the date field as in the default of
260\"\\\\([0-9][0-9]/[0-9][0-9]\\\\)\"}. If this regular expression
261is not correct, the date will not be highlighted. See also
235`mh-scan-format-regexp'.") 262`mh-scan-format-regexp'.")
236 263
237(defvar mh-scan-rcpt-regexp "\\(To:\\)\\(..............\\)" 264(defvar mh-scan-rcpt-regexp "\\(To:\\)\\(..............\\)"
238 "This regular expression specifies the recipient in messages you sent. 265 "This regular expression specifies the recipient in messages you sent.
266
239Note that the default setting of `mh-folder-font-lock-keywords' 267Note that the default setting of `mh-folder-font-lock-keywords'
240expects this expression to contain two parenthesized expressions. The 268expects this expression to contain two parenthesized expressions.
241first is expected to match the `To:' that the default scan format 269The first is expected to match the \"To:\" that the default scan
242file generates. The second is expected to match the recipient's name 270format file generates. The second is expected to match the
243as in the default of \"\\\\(To:\\\\)\\\\(..............\\\\)\". If this 271recipient's name as in the default of
244regular expression is not correct, the recipient will not be highlighted.") 272\"\\\\(To:\\\\)\\\\(..............\\\\)\". If this regular
273expression is not correct, the recipient will not be
274highlighted.")
245 275
246(defvar mh-scan-body-regexp "\\(<<\\([^\n]+\\)?\\)" 276(defvar mh-scan-body-regexp "\\(<<\\([^\n]+\\)?\\)"
247 "This regular expression matches the message body fragment. 277 "This regular expression matches the message body fragment.
248Note that the default setting of `mh-folder-font-lock-keywords' expects this 278
249expression to contain at least one parenthesized expression which matches the 279Note that the default setting of `mh-folder-font-lock-keywords'
250body text as in the default of \"\\\\(<<\\\\([^\\n]+\\\\)?\\\\)\". If this 280expects this expression to contain at least one parenthesized
251regular expression is not correct, the body fragment will not be highlighted.") 281expression which matches the body text as in the default of
282\"\\\\(<<\\\\([^\\n]+\\\\)?\\\\)\". If this regular expression is
283not correct, the body fragment will not be highlighted.")
252 284
253(defvar mh-scan-subject-regexp 285(defvar mh-scan-subject-regexp
254 "^ *[0-9]+........[ ]*...................\\([Rr][Ee]\\(\\[[0-9]+\\]\\)?:\\s-*\\)*\\([^<\n]*\\)" 286 "^ *[0-9]+........[ ]*...................\\([Rr][Ee]\\(\\[[0-9]+\\]\\)?:\\s-*\\)*\\([^<\n]*\\)"
255 "This regular expression matches the subject. 287 "This regular expression matches the subject.
256It must match from the beginning of the line. Note that the default setting 288
257of `mh-folder-font-lock-keywords' expects this expression to contain at least 289It must match from the beginning of the line. Note that the
258three parenthesized expressions. The first is expected to match the `Re:' 290default setting of `mh-folder-font-lock-keywords' expects this
259string, if any. The second matches an optional bracketed number after `Re:', 291expression to contain at least three parenthesized expressions.
260such as in `Re[2]:' (and is thus a sub-expression of the first expression) and 292The first is expected to match the \"Re:\" string, if any. The
261the third is expected to match the subject line itself as in the default of 293second matches an optional bracketed number after \"Re:\", such as
262\(broken on multiple lines for readability): 294in \"Re[2]:\" (and is thus a sub-expression of the first
295expression) and the third is expected to match the subject line
296itself as in the default of (broken on multiple lines for
297readability):
298
263 ^ *[0-9]+........[ ]*................... 299 ^ *[0-9]+........[ ]*...................
264 \\\\([Rr][Ee]\\\\(\\\\\\=[[0-9]+\\\\]\\\\)?:\\\\s-*\\\\)* 300 \\\\([Rr][Ee]\\\\(\\\\\\=[[0-9]+\\\\]\\\\)?:\\\\s-*\\\\)*
265 \\\\([^<\\n]*\\\\) 301 \\\\([^<\\n]*\\\\)
266This regular expression should be correct as it is needed by non-fontification 302
267functions.") 303This regular expression should be correct as it is needed by
304non-fontification functions.")
268 305
269(defvar mh-scan-format-regexp 306(defvar mh-scan-format-regexp
270 (concat "\\([bct]\\)" mh-scan-date-regexp " *\\(..................\\)") 307 (concat "\\([bct]\\)" mh-scan-date-regexp " *\\(..................\\)")
271 "This regular expression matches the output of scan. 308 "This regular expression matches the output of scan.
272Note that the default setting of `mh-folder-font-lock-keywords' expects this 309
273expression to contain at least three parenthesized expressions. The first 310Note that the default setting of `mh-folder-font-lock-keywords'
274should match the fontification hint (see `mh-scan-format-nmh'), the second is 311expects this expression to contain at least three parenthesized
275found in `mh-scan-date-regexp', and the third should match the user name as in 312expressions. The first should match the fontification hint (see
276the default of \"(concat \"\\\\([bct]\\\\)\" mh-scan-date-regexp 313`mh-scan-format-nmh'), the second is found in
277 \"*\\\\(..................\\\\)\")\". 314`mh-scan-date-regexp', and the third should match the user name
278If this regular expression is not correct, the notation hints and the sender 315as in the default of
279will not be highlighted.") 316
317 \"(concat \"\\\\([bct]\\\\)\" mh-scan-date-regexp
318 \"*\\\\(..................\\\\)\")\".
319
320If this regular expression is not correct, the notation hints and
321the sender will not be highlighted.")
280 322
281 323
282 324
@@ -313,22 +355,27 @@ will not be highlighted.")
313 355
314(defvar mh-scan-cmd-note-width 1 356(defvar mh-scan-cmd-note-width 1
315 "Number of columns consumed by the cmd-note field in `mh-scan-format'. 357 "Number of columns consumed by the cmd-note field in `mh-scan-format'.
316This column will have one of the values: ` ', `D', `^', `+' and where 358
317` ' is the default value, 359This column will have one of the values: \" \", \"D\", \"^\", \"+\" and
318`D' is the `mh-note-deleted' character, 360where \" \" is the default value,
319`^' is the `mh-note-refiled' character, and 361
320`+' is the `mh-note-cur' character.") 362 \"D\" is the `mh-note-deleted' character,
363 \"^\" is the `mh-note-refiled' character, and
364 \"+\" is the `mh-note-cur' character.")
321 365
322(defvar mh-scan-destination-width 1 366(defvar mh-scan-destination-width 1
323 "Number of columns consumed by the destination field in `mh-scan-format'. 367 "Number of columns consumed by the destination field in `mh-scan-format'.
324This column will have one of ' ', '%', '-', 't', 'c', 'b', or `n' in it. 368
325A ' ' blank space is the default character. 369This column will have one of \" \", \"%\", \"-\", \"t\", \"c\", \"b\", or \"n\"
326A '%' indicates that the message in in a named MH sequence. 370in it.
327A '-' indicates that the message has been annotated with a replied field. 371
328A 't' indicates that the message contains mymbox in the To: field. 372 \" \" blank space is the default character.
329A 'c' indicates that the message contains mymbox in the Cc: field. 373 \"%\" indicates that the message in in a named MH sequence.
330A 'b' indicates that the message contains mymbox in the Bcc: field. 374 \"-\" indicates that the message has been annotated with a replied field.
331A 'n' indicates that the message contains a Newsgroups: field.") 375 \"t\" indicates that the message contains mymbox in the To: field.
376 \"c\" indicates that the message contains mymbox in the Cc: field.
377 \"b\" indicates that the message contains mymbox in the Bcc: field.
378 \"n\" indicates that the message contains a Newsgroups: field.")
332 379
333(defvar mh-scan-date-width 5 380(defvar mh-scan-date-width 5
334 "Number of columns consumed by the date field in `mh-scan-format'. 381 "Number of columns consumed by the date field in `mh-scan-format'.
@@ -336,7 +383,8 @@ This column will typically be of the form mm/dd.")
336 383
337(defvar mh-scan-date-flag-width 1 384(defvar mh-scan-date-flag-width 1
338 "Number of columns consumed to flag (in)valid dates in `mh-scan-format'. 385 "Number of columns consumed to flag (in)valid dates in `mh-scan-format'.
339This column will have ` ' for valid and `*' for invalid or missing dates.") 386This column will have \" \" for valid and \"*\" for invalid or
387missing dates.")
340 388
341(defvar mh-scan-from-mbox-width 17 389(defvar mh-scan-from-mbox-width 17
342 "Number of columns consumed with the \"From:\" line in `mh-scan-format'. 390 "Number of columns consumed with the \"From:\" line in `mh-scan-format'.
@@ -388,17 +436,17 @@ This column will only ever have spaces in it.")
388 436
389(defmacro mh-generate-sequence-font-lock (seq prefix face) 437(defmacro mh-generate-sequence-font-lock (seq prefix face)
390 "Generate the appropriate code to fontify messages in SEQ. 438 "Generate the appropriate code to fontify messages in SEQ.
391PREFIX is used to generate unique names for the variables and functions 439PREFIX is used to generate unique names for the variables and
392defined by the macro. So a different prefix should be provided for every 440functions defined by the macro. So a different prefix should be
393invocation. 441provided for every invocation.
394FACE is the font-lock face used to display the matching scan lines." 442FACE is the font-lock face used to display the matching scan lines."
395 (let ((cache (intern (format "mh-folder-%s-seq-cache" prefix))) 443 (let ((cache (intern (format "mh-folder-%s-seq-cache" prefix)))
396 (func (intern (format "mh-folder-font-lock-%s" prefix)))) 444 (func (intern (format "mh-folder-font-lock-%s" prefix))))
397 `(progn 445 `(progn
398 (defvar ,cache nil 446 (defvar ,cache nil
399 "Internal cache variable used for font-lock in MH-E. 447 "Internal cache variable used for font-lock in MH-E.
400Should only be non-nil through font-lock stepping, and nil once font-lock 448Should only be non-nil through font-lock stepping, and nil once
401is done highlighting.") 449font-lock is done highlighting.")
402 (make-variable-buffer-local ',cache) 450 (make-variable-buffer-local ',cache)
403 451
404 (defun ,func (limit) 452 (defun ,func (limit)
@@ -446,45 +494,69 @@ is done highlighting.")
446 494
447;;; Internal variables: 495;;; Internal variables:
448 496
449(defvar mh-last-destination nil) ;Destination of last refile or write 497(defvar mh-last-destination nil
450 ;command. 498 "Destination of last refile or write command.")
451(defvar mh-last-destination-folder nil) ;Destination of last refile command. 499
452(defvar mh-last-destination-write nil) ;Destination of last write command. 500(defvar mh-last-destination-folder nil
501 "Destination of last refile command.")
502
503(defvar mh-last-destination-write nil
504 "Destination of last write command.")
453 505
454(defvar mh-folder-mode-map (make-keymap) 506(defvar mh-folder-mode-map (make-keymap)
455 "Keymap for MH folders.") 507 "Keymap for MH folders.")
456 508
457(defvar mh-arrow-marker nil) ;Marker for arrow display in fringe. 509(defvar mh-arrow-marker nil
510 "Marker for arrow display in fringe.")
511
512(defvar mh-delete-list nil
513 "List of message numbers to delete.
514This variable can be used by
515`mh-before-commands-processed-hook'.")
458 516
459(defvar mh-delete-list nil) ;List of msg numbers to delete. 517(defvar mh-refile-list nil
518 "List of folder names in `mh-seq-list'.
519This variable can be used by
520`mh-before-commands-processed-hook'.")
460 521
461(defvar mh-refile-list nil) ;List of folder names in mh-seq-list. 522(defvar mh-folders-changed nil
523 "Lists which folders were affected by deletes and refiles.
524This list will always include the current folder
525`mh-current-folder'. This variable can be used by
526`mh-after-commands-processed-hook'.")
462 527
463(defvar mh-folders-changed nil) ;For mh-after-commands-processed-hook. 528(defvar mh-next-direction 'forward
529 "Direction to move to next message.")
464 530
465(defvar mh-next-direction 'forward) ;Direction to move to next message. 531(defvar mh-view-ops ()
532 "Stack of operations that change the folder view.
533These operations include narrowing or threading.")
466 534
467(defvar mh-view-ops ()) ;Stack of ops that change the folder 535(defvar mh-folder-view-stack ()
468 ;view (such as narrowing or threading). 536 "Stack of previous folder views.")
469(defvar mh-folder-view-stack ()) ;Stack of previous folder views. 537
538(defvar mh-index-data nil
539 "Info about index search results.")
470 540
471(defvar mh-index-data nil) ;Info about index search results
472(defvar mh-index-previous-search nil) 541(defvar mh-index-previous-search nil)
473(defvar mh-index-msg-checksum-map nil) 542(defvar mh-index-msg-checksum-map nil)
474(defvar mh-index-checksum-origin-map nil) 543(defvar mh-index-checksum-origin-map nil)
475(defvar mh-index-sequence-search-flag nil) 544(defvar mh-index-sequence-search-flag nil)
476 545
477(defvar mh-first-msg-num nil) ;Number of first msg in buffer. 546(defvar mh-first-msg-num nil
547 "Number of first message in buffer.")
478 548
479(defvar mh-last-msg-num nil) ;Number of last msg in buffer. 549(defvar mh-last-msg-num nil
550 "Number of last msg in buffer.")
480 551
481(defvar mh-mode-line-annotation nil) ;Message range displayed in buffer. 552(defvar mh-mode-line-annotation nil
553 "Message range displayed in buffer.")
482 554
483(defvar mh-sequence-notation-history nil) 555(defvar mh-sequence-notation-history nil
484 ;Rememeber original notation that 556 "Remember original notation that is overwritten by `mh-note-seq'.")
485 ;is overwritten by `mh-note-seq'.
486 557
487(defvar mh-colors-available-flag nil) ;Are colors available? 558(defvar mh-colors-available-flag nil
559 "Non-nil means colors are available.")
488 560
489 561
490 562
@@ -513,9 +585,11 @@ is done highlighting.")
513 585
514;;;###autoload 586;;;###autoload
515(defun mh-rmail (&optional arg) 587(defun mh-rmail (&optional arg)
516 "Inc(orporate) new mail with MH. 588 "Incorporate new mail with MH.
517Scan an MH folder if ARG is non-nil. This function is an entry point to MH-E, 589Scan an MH folder if ARG is non-nil.
518the Emacs interface to the MH mail system." 590
591This function is an entry point to MH-E, the Emacs interface to
592the MH mail system."
519 (interactive "P") 593 (interactive "P")
520 (mh-find-path) 594 (mh-find-path)
521 (if arg 595 (if arg
@@ -527,8 +601,10 @@ the Emacs interface to the MH mail system."
527;;;###autoload 601;;;###autoload
528(defun mh-nmail (&optional arg) 602(defun mh-nmail (&optional arg)
529 "Check for new mail in inbox folder. 603 "Check for new mail in inbox folder.
530Scan an MH folder if ARG is non-nil. This function is an entry point to MH-E, 604Scan an MH folder if ARG is non-nil.
531the Emacs interface to the MH mail system." 605
606This function is an entry point to MH-E, the Emacs interface to
607the MH mail system."
532 (interactive "P") 608 (interactive "P")
533 (mh-find-path) ; init mh-inbox 609 (mh-find-path) ; init mh-inbox
534 (if arg 610 (if arg
@@ -542,34 +618,53 @@ the Emacs interface to the MH mail system."
542(defun mh-delete-msg (range) 618(defun mh-delete-msg (range)
543 "Delete RANGE\\<mh-folder-mode-map>. 619 "Delete RANGE\\<mh-folder-mode-map>.
544 620
545To mark a message for deletion, use this command. A \"D\" is placed by the 621To mark a message for deletion, use this command. A \"D\" is
546message in the scan window, and the next undeleted message is displayed. If 622placed by the message in the scan window, and the next undeleted
547the previous command had been \\[mh-previous-undeleted-msg], then the next 623message is displayed. If the previous command had been
548message displayed is the first undeleted message previous to the message just 624\\[mh-previous-undeleted-msg], then the next message displayed is
549deleted. Use \\[mh-next-undeleted-msg] to force subsequent \\[mh-delete-msg] 625the first undeleted message previous to the message just deleted.
550commands to move forward to the next undeleted message after deleting the 626Use \\[mh-next-undeleted-msg] to force subsequent
551message under the cursor. 627\\[mh-delete-msg] commands to move forward to the next undeleted
552 628message after deleting the message under the cursor.
553Check the documentation of `mh-interactive-range' to see how RANGE is read in 629
554interactive use." 630The hook `mh-delete-msg-hook' is called after you mark a message
631for deletion. For example, a past maintainer of MH-E used this
632once when he kept statistics on his mail usage.
633
634Check the documentation of `mh-interactive-range' to see how
635RANGE is read in interactive use."
555 (interactive (list (mh-interactive-range "Delete"))) 636 (interactive (list (mh-interactive-range "Delete")))
556 (mh-delete-msg-no-motion range) 637 (mh-delete-msg-no-motion range)
557 (if (looking-at mh-scan-deleted-msg-regexp) (mh-next-msg))) 638 (if (looking-at mh-scan-deleted-msg-regexp)
639 (mh-next-msg)))
558 640
559(defun mh-delete-msg-no-motion (range) 641(defun mh-delete-msg-no-motion (range)
560 "Delete RANGE, don't move to next message. 642 "Delete RANGE, don't move to next message.
561 643
562This command marks the RANGE for deletion but leaves the cursor at the current 644This command marks the RANGE for deletion but leaves the cursor
563message in case you wish to perform other operations on the message. 645at the current message in case you wish to perform other
646operations on the message.
564 647
565Check the documentation of `mh-interactive-range' to see how RANGE is read in 648Check the documentation of `mh-interactive-range' to see how
566interactive use." 649RANGE is read in interactive use."
567 (interactive (list (mh-interactive-range "Delete"))) 650 (interactive (list (mh-interactive-range "Delete")))
568 (mh-iterate-on-range () range 651 (mh-iterate-on-range () range
569 (mh-delete-a-msg nil))) 652 (mh-delete-a-msg nil)))
570 653
571(defun mh-execute-commands () 654(defun mh-execute-commands ()
572 "Process outstanding delete and refile requests." 655 "Process outstanding delete and refile requests\\<mh-folder-mode-map>.
656
657If you've marked messages to be deleted or refiled and you want
658to go ahead and delete or refile the messages, use this command.
659Many MH-E commands that may affect the numbering of the
660messages (such as \\[mh-rescan-folder] or \\[mh-pack-folder])
661will ask if you want to process refiles or deletes first and then
662either run this command for you or undo the pending refiles and
663deletes, which are lost.
664
665This function runs `mh-before-commands-processed-hook' before the
666commands are processed and `mh-after-commands-processed-hook'
667after the commands are processed."
573 (interactive) 668 (interactive)
574 (if mh-folder-view-stack (mh-widen t)) 669 (if mh-folder-view-stack (mh-widen t))
575 (mh-process-commands mh-current-folder) 670 (mh-process-commands mh-current-folder)
@@ -603,13 +698,20 @@ Use the command \\[mh-show] to show the message normally again."
603 (setq mh-showing-with-headers t))) 698 (setq mh-showing-with-headers t)))
604 699
605(defun mh-inc-folder (&optional maildrop-name folder) 700(defun mh-inc-folder (&optional maildrop-name folder)
606 "Inc(orporate)s new mail into the Inbox folder. 701 "Incorporate new mail into a folder.
607Optional argument MAILDROP-NAME specifies an alternate maildrop from the 702
608default. The optional argument FOLDER specifies where to incorporate mail 703You can incorporate mail from any file into the current folder by
609instead of the default named by `mh-inbox'. 704specifying a prefix argument; you'll be prompted for the name of
610The value of `mh-inc-folder-hook' is a list of functions to be called, with no 705the file to use as well as the destination folder
611arguments, after incorporating new mail. 706
612Do not call this function from outside MH-E; use \\[mh-rmail] instead." 707The hook `mh-inc-folder-hook' is run after incorporating new
708mail. Do not call this function from outside MH-E; use
709\\[mh-rmail] instead.
710
711In a program optional argument MAILDROP-NAME specifies an
712alternate maildrop from the default. The optional argument FOLDER
713specifies where to incorporate mail instead of the default named
714by `mh-inbox'."
613 (interactive (list (if current-prefix-arg 715 (interactive (list (if current-prefix-arg
614 (expand-file-name 716 (expand-file-name
615 (read-file-name "inc mail from file: " 717 (read-file-name "inc mail from file: "
@@ -653,12 +755,12 @@ Do not call this function from outside MH-E; use \\[mh-rmail] instead."
653(defun mh-next-undeleted-msg (&optional count wait-after-complaining-flag) 755(defun mh-next-undeleted-msg (&optional count wait-after-complaining-flag)
654 "Display next message. 756 "Display next message.
655 757
656This command can be given a prefix argument COUNT to specify how many unread 758This command can be given a prefix argument COUNT to specify how
657messages to skip. 759many unread messages to skip.
658 760
659In a program, pause for a second after printing message if we are at the last 761In a program, pause for a second after printing message if we are
660undeleted message and optional argument WAIT-AFTER-COMPLAINING-FLAG is 762at the last undeleted message and optional argument
661non-nil." 763WAIT-AFTER-COMPLAINING-FLAG is non-nil."
662 (interactive "p") 764 (interactive "p")
663 (setq mh-next-direction 'forward) 765 (setq mh-next-direction 'forward)
664 (forward-line 1) 766 (forward-line 1)
@@ -674,18 +776,19 @@ non-nil."
674 776
675The name of the folder is derived as follows: 777The name of the folder is derived as follows:
676 778
677 a) The folder name associated with the first address found in the list 779 a) The folder name associated with the first address found in
678 `mh-default-folder-list' is used. Each element in this list contains a 780 the list `mh-default-folder-list' is used. Each element in
679 `Check Recipient' item. If this item is turned on, then the address is 781 this list contains a \"Check Recipient\" item. If this item is
680 checked against the recipient instead of the sender. This is useful for 782 turned on, then the address is checked against the recipient
681 mailing lists. 783 instead of the sender. This is useful for mailing lists.
682 784
683 b) An alias prefixed by `mh-default-folder-prefix' corresponding to the 785 b) An alias prefixed by `mh-default-folder-prefix'
684 address is used. The prefix is used to prevent clutter in your mail 786 corresponding to the address is used. The prefix is used to
685 directory. 787 prevent clutter in your mail directory.
686 788
687Return nil if a folder name was not derived, or if the variable 789Return nil if a folder name was not derived, or if the variable
688`mh-default-folder-must-exist-flag' is t and the folder does not exist." 790`mh-default-folder-must-exist-flag' is t and the folder does not
791exist."
689 ;; Loop for all entries in mh-default-folder-list 792 ;; Loop for all entries in mh-default-folder-list
690 (save-restriction 793 (save-restriction
691 (goto-char (point-min)) 794 (goto-char (point-min))
@@ -750,18 +853,19 @@ The default folder name is generated by the option
750(defun mh-refile-msg (range folder &optional dont-update-last-destination-flag) 853(defun mh-refile-msg (range folder &optional dont-update-last-destination-flag)
751 "Refile (output) RANGE into FOLDER. 854 "Refile (output) RANGE into FOLDER.
752 855
753You are prompted for the folder name. Note that this command can also be used 856You are prompted for the folder name. Note that this command can also
754to create folders. If you specify a folder that does not exist, you will be 857be used to create folders. If you specify a folder that does not
755prompted to create it. 858exist, you will be prompted to create it.
756 859
757The hook `mh-refile-msg-hook' is called after a message is marked to be 860The hook `mh-refile-msg-hook' is called after a message is marked to
758refiled. 861be refiled.
759 862
760Check the documentation of `mh-interactive-range' to see how RANGE is read in 863Check the documentation of `mh-interactive-range' to see how RANGE is
761interactive use. 864read in interactive use.
762 865
763If DONT-UPDATE-LAST-DESTINATION-FLAG is non-nil, then the variables 866In a program, the variables `mh-last-destination' and
764`mh-last-destination' and `mh-last-destination-folder' are not updated." 867`mh-last-destination-folder' are not updated if
868DONT-UPDATE-LAST-DESTINATION-FLAG is non-nil."
765 (interactive (list (mh-interactive-range "Refile") 869 (interactive (list (mh-interactive-range "Refile")
766 (intern (mh-prompt-for-refile-folder)))) 870 (intern (mh-prompt-for-refile-folder))))
767 (unless dont-update-last-destination-flag 871 (unless dont-update-last-destination-flag
@@ -774,14 +878,14 @@ If DONT-UPDATE-LAST-DESTINATION-FLAG is non-nil, then the variables
774(defun mh-refile-or-write-again (range &optional interactive-flag) 878(defun mh-refile-or-write-again (range &optional interactive-flag)
775 "Repeat last output command. 879 "Repeat last output command.
776 880
777If you are refiling several messages into the same folder, you can use this 881If you are refiling several messages into the same folder, you can use
778command to repeat the last refile or write. You can use a range. 882this command to repeat the last refile or write. You can use a range.
779 883
780Check the documentation of `mh-interactive-range' to see how RANGE is read in 884Check the documentation of `mh-interactive-range' to see how RANGE is
781interactive use. 885read in interactive use.
782 886
783In a program, a non-nil INTERACTIVE-FLAG means that the function was called 887In a program, a non-nil INTERACTIVE-FLAG means that the function was
784interactively." 888called interactively."
785 (interactive (list (mh-interactive-range "Redo") t)) 889 (interactive (list (mh-interactive-range "Redo") t))
786 (if (null mh-last-destination) 890 (if (null mh-last-destination)
787 (error "No previous refile or write")) 891 (error "No previous refile or write"))
@@ -796,13 +900,21 @@ interactively."
796 900
797(defun mh-quit () 901(defun mh-quit ()
798 "Quit the current MH-E folder. 902 "Quit the current MH-E folder.
799Restore the previous window configuration, if one exists. 903
800The value of `mh-before-quit-hook' is a list of functions to be called, with 904When you want to quit using MH-E and go back to editing, you can use
801no arguments, immediately upon entry to this function. 905this command. This buries the buffers of the current MH-E folder and
802The value of `mh-quit-hook' is a list of functions to be called, with no 906restores the buffers that were present when you first ran
803arguments, upon exit of this function. 907\\[mh-rmail]. It also removes any MH-E working buffers whose name
804MH-E working buffers (whose name begins with \" *mh-\" or \"*MH-E \") are 908begins with \" *mh-\" or \"*MH-E \". You can later restore your MH-E
805killed." 909session by selecting the \"+inbox\" buffer or by running \\[mh-rmail]
910again.
911
912The two hooks `mh-before-quit-hook' and `mh-quit-hook' are called by
913this function. The former one is called before the quit occurs, so you
914might use it to perform any MH-E operations; you could perform some
915query and abort the quit or call `mh-execute-commands', for example.
916The latter is not run in an MH-E context, so you might use it to
917modify the window setup."
806 (interactive) 918 (interactive)
807 (run-hooks 'mh-before-quit-hook) 919 (run-hooks 'mh-before-quit-hook)
808 (let ((show-buffer (get-buffer mh-show-buffer))) 920 (let ((show-buffer (get-buffer mh-show-buffer)))
@@ -825,9 +937,9 @@ killed."
825(defun mh-page-msg (&optional lines) 937(defun mh-page-msg (&optional lines)
826 "Display next page in message. 938 "Display next page in message.
827 939
828You can give this command a prefix argument that specifies the number of LINES 940You can give this command a prefix argument that specifies the
829to scroll. This command will also show the next undeleted message if it is 941number of LINES to scroll. This command will also show the next
830used at the bottom of a message." 942undeleted message if it is used at the bottom of a message."
831 (interactive "P") 943 (interactive "P")
832 (if mh-showing-mode 944 (if mh-showing-mode
833 (if mh-page-to-next-msg-flag 945 (if mh-page-to-next-msg-flag
@@ -850,8 +962,8 @@ used at the bottom of a message."
850(defun mh-previous-page (&optional lines) 962(defun mh-previous-page (&optional lines)
851 "Display next page in message. 963 "Display next page in message.
852 964
853You can give this command a prefix argument that specifies the number of LINES 965You can give this command a prefix argument that specifies the
854to scroll." 966number of LINES to scroll."
855 (interactive "P") 967 (interactive "P")
856 (mh-in-show-buffer (mh-show-buffer) 968 (mh-in-show-buffer (mh-show-buffer)
857 (scroll-down lines))) 969 (scroll-down lines)))
@@ -859,12 +971,12 @@ to scroll."
859(defun mh-previous-undeleted-msg (&optional count wait-after-complaining-flag) 971(defun mh-previous-undeleted-msg (&optional count wait-after-complaining-flag)
860 "Display previous message. 972 "Display previous message.
861 973
862This command can be given a prefix argument COUNT to specify how many unread 974This command can be given a prefix argument COUNT to specify how
863messages to skip. 975many unread messages to skip.
864 976
865In a program, pause for a second after printing message if we are at the last 977In a program, pause for a second after printing message if we are
866undeleted message and optional argument WAIT-AFTER-COMPLAINING-FLAG is 978at the last undeleted message and optional argument
867non-nil." 979WAIT-AFTER-COMPLAINING-FLAG is non-nil."
868 (interactive "p") 980 (interactive "p")
869 (setq mh-next-direction 'backward) 981 (setq mh-next-direction 'backward)
870 (beginning-of-line) 982 (beginning-of-line)
@@ -876,8 +988,8 @@ non-nil."
876(defun mh-previous-unread-msg (&optional count) 988(defun mh-previous-unread-msg (&optional count)
877 "Display previous unread message. 989 "Display previous unread message.
878 990
879This command can be given a prefix argument COUNT to specify how many unread 991This command can be given a prefix argument COUNT to specify how
880messages to skip." 992many unread messages to skip."
881 (interactive "p") 993 (interactive "p")
882 (unless (> count 0) 994 (unless (> count 0)
883 (error "The function mh-previous-unread-msg expects positive argument")) 995 (error "The function mh-previous-unread-msg expects positive argument"))
@@ -909,9 +1021,11 @@ messages to skip."
909 1021
910(defun mh-goto-next-button (backward-flag &optional criterion) 1022(defun mh-goto-next-button (backward-flag &optional criterion)
911 "Search for next button satisfying criterion. 1023 "Search for next button satisfying criterion.
912If BACKWARD-FLAG is non-nil search backward in the buffer for a mime button. If 1024
913CRITERION is a function or a symbol which has a function binding then that 1025If BACKWARD-FLAG is non-nil search backward in the buffer for a mime
914function must return non-nil at the button we stop." 1026button.
1027If CRITERION is a function or a symbol which has a function binding
1028then that function must return non-nil at the button we stop."
915 (unless (or (and (symbolp criterion) (fboundp criterion)) 1029 (unless (or (and (symbolp criterion) (fboundp criterion))
916 (functionp criterion)) 1030 (functionp criterion))
917 (setq criterion (lambda (x) t))) 1031 (setq criterion (lambda (x) t)))
@@ -954,11 +1068,11 @@ function must return non-nil at the button we stop."
954(defun mh-next-button (&optional backward-flag) 1068(defun mh-next-button (&optional backward-flag)
955 "Go to the next button. 1069 "Go to the next button.
956 1070
957If the end of the buffer is reached then the search wraps over to the start of 1071If the end of the buffer is reached then the search wraps over to
958the buffer. 1072the start of the buffer.
959 1073
960If an optional prefix argument BACKWARD-FLAG is given, the cursor will move to 1074If an optional prefix argument BACKWARD-FLAG is given, the cursor
961the previous button." 1075will move to the previous button."
962 (interactive (list current-prefix-arg)) 1076 (interactive (list current-prefix-arg))
963 (unless mh-showing-mode 1077 (unless mh-showing-mode
964 (mh-show)) 1078 (mh-show))
@@ -968,17 +1082,18 @@ the previous button."
968(defun mh-prev-button () 1082(defun mh-prev-button ()
969 "Go to the previous button. 1083 "Go to the previous button.
970 1084
971If the beginning of the buffer is reached then the search wraps over to the 1085If the beginning of the buffer is reached then the search wraps
972end of the buffer." 1086over to the end of the buffer."
973 (interactive) 1087 (interactive)
974 (mh-next-button t)) 1088 (mh-next-button t))
975 1089
976(defun mh-folder-mime-action (part-index action include-security-flag) 1090(defun mh-folder-mime-action (part-index action include-security-flag)
977 "Go to PART-INDEX and carry out ACTION. 1091 "Go to PART-INDEX and carry out ACTION.
978If PART-INDEX is nil then go to the next part in the buffer. The search for 1092
979the next buffer wraps around if end of buffer is reached. If argument 1093If PART-INDEX is nil then go to the next part in the buffer. The
980INCLUDE-SECURITY-FLAG is non-nil then include security info buttons when 1094search for the next buffer wraps around if end of buffer is reached.
981searching for a suitable parts." 1095If argument INCLUDE-SECURITY-FLAG is non-nil then include security
1096info buttons when searching for a suitable parts."
982 (unless mh-showing-mode 1097 (unless mh-showing-mode
983 (mh-show)) 1098 (mh-show))
984 (mh-in-show-buffer (mh-show-buffer) 1099 (mh-in-show-buffer (mh-show-buffer)
@@ -1009,15 +1124,17 @@ searching for a suitable parts."
1009(defun mh-folder-toggle-mime-part (part-index) 1124(defun mh-folder-toggle-mime-part (part-index)
1010 "View attachment. 1125 "View attachment.
1011 1126
1012This command displays (or hides) the attachment associated with the button 1127This command displays (or hides) the attachment associated with
1013under the cursor. If the cursor is not located over a button, then the cursor 1128the button under the cursor. If the cursor is not located over a
1014first moves to the next button, wrapping to the beginning of the message if 1129button, then the cursor first moves to the next button, wrapping
1015necessary. This command has the advantage over related commands of working 1130to the beginning of the message if necessary. This command has
1016from the MH-Folder buffer. 1131the advantage over related commands of working from the MH-Folder
1017 1132buffer.
1018You can also provide a numeric prefix argument PART-INDEX to view the 1133
1019attachment labeled with that number. If Emacs does not know how to display the 1134You can also provide a numeric prefix argument PART-INDEX to view
1020attachment, then Emacs offers to save the attachment in a file." 1135the attachment labeled with that number. If Emacs does not know
1136how to display the attachment, then Emacs offers to save the
1137attachment in a file."
1021 (interactive "P") 1138 (interactive "P")
1022 (when (consp part-index) (setq part-index (car part-index))) 1139 (when (consp part-index) (setq part-index (car part-index)))
1023 (mh-folder-mime-action part-index #'mh-press-button t)) 1140 (mh-folder-mime-action part-index #'mh-press-button t))
@@ -1025,14 +1142,15 @@ attachment, then Emacs offers to save the attachment in a file."
1025(defun mh-folder-inline-mime-part (part-index) 1142(defun mh-folder-inline-mime-part (part-index)
1026 "Show attachment verbatim. 1143 "Show attachment verbatim.
1027 1144
1028You can view the raw contents of an attachment with this command. This command 1145You can view the raw contents of an attachment with this command.
1029displays (or hides) the contents of the attachment associated with the button 1146This command displays (or hides) the contents of the attachment
1030under the cursor verbatim. If the cursor is not located over a button, then 1147associated with the button under the cursor verbatim. If the
1031the cursor first moves to the next button, wrapping to the beginning of the 1148cursor is not located over a button, then the cursor first moves
1032message if necessary. 1149to the next button, wrapping to the beginning of the message if
1150necessary.
1033 1151
1034You can also provide a numeric prefix argument PART-INDEX to view the 1152You can also provide a numeric prefix argument PART-INDEX to view
1035attachment labeled with that number." 1153the attachment labeled with that number."
1036 (interactive "P") 1154 (interactive "P")
1037 (when (consp part-index) (setq part-index (car part-index))) 1155 (when (consp part-index) (setq part-index (car part-index)))
1038 (mh-folder-mime-action part-index #'mh-mime-inline-part nil)) 1156 (mh-folder-mime-action part-index #'mh-mime-inline-part nil))
@@ -1040,15 +1158,16 @@ attachment labeled with that number."
1040(defun mh-folder-save-mime-part (part-index) 1158(defun mh-folder-save-mime-part (part-index)
1041 "Save (output) attachment. 1159 "Save (output) attachment.
1042 1160
1043This command saves the attachment associated with the button under the cursor. 1161This command saves the attachment associated with the button under the
1044If the cursor is not located over a button, then the cursor first moves to the 1162cursor. If the cursor is not located over a button, then the cursor
1045next button, wrapping to the beginning of the message if necessary. 1163first moves to the next button, wrapping to the beginning of the
1164message if necessary.
1046 1165
1047You can also provide a numeric prefix argument PART-INDEX to save the 1166You can also provide a numeric prefix argument PART-INDEX to save the
1048attachment labeled with that number. 1167attachment labeled with that number.
1049 1168
1050This command prompts you for a filename and suggests a specific name if it is 1169This command prompts you for a filename and suggests a specific name
1051available." 1170if it is available."
1052 (interactive "P") 1171 (interactive "P")
1053 (when (consp part-index) (setq part-index (car part-index))) 1172 (when (consp part-index) (setq part-index (car part-index)))
1054 (mh-folder-mime-action part-index #'mh-mime-save-part nil)) 1173 (mh-folder-mime-action part-index #'mh-mime-save-part nil))
@@ -1067,16 +1186,17 @@ Also removes all content from the folder buffer."
1067 "Rescan folder\\<mh-folder-mode-map>. 1186 "Rescan folder\\<mh-folder-mode-map>.
1068 1187
1069This command is useful to grab all messages in your \"+inbox\" after 1188This command is useful to grab all messages in your \"+inbox\" after
1070processing your new mail for the first time. If you don't want to rescan the 1189processing your new mail for the first time. If you don't want to
1071entire folder, this command will accept a RANGE. Check the documentation of 1190rescan the entire folder, this command will accept a RANGE. Check the
1072`mh-interactive-range' to see how RANGE is read in interactive use. 1191documentation of `mh-interactive-range' to see how RANGE is read in
1192interactive use.
1073 1193
1074This command will ask if you want to process refiles or deletes first and then 1194This command will ask if you want to process refiles or deletes first
1075either run \\[mh-execute-commands] for you or undo the pending refiles and 1195and then either run \\[mh-execute-commands] for you or undo the
1076deletes, which are lost. 1196pending refiles and deletes, which are lost.
1077 1197
1078In a program, the processing of outstanding commands is not performed if 1198In a program, the processing of outstanding commands is not performed
1079DONT-EXEC-PENDING is non-nil." 1199if DONT-EXEC-PENDING is non-nil."
1080 (interactive (list (if current-prefix-arg 1200 (interactive (list (if current-prefix-arg
1081 (mh-read-range "Rescan" mh-current-folder t nil t 1201 (mh-read-range "Rescan" mh-current-folder t nil t
1082 mh-interpret-number-as-range-flag) 1202 mh-interpret-number-as-range-flag)
@@ -1090,10 +1210,11 @@ DONT-EXEC-PENDING is non-nil."
1090(defun mh-write-msg-to-file (message file no-header) 1210(defun mh-write-msg-to-file (message file no-header)
1091 "Append MESSAGE to end of FILE\\<mh-folder-mode-map>. 1211 "Append MESSAGE to end of FILE\\<mh-folder-mode-map>.
1092 1212
1093You are prompted for the filename. If the file already exists, the message is 1213You are prompted for the filename. If the file already exists,
1094appended to it. You can also write the message to the file without the header 1214the message is appended to it. You can also write the message to
1095by specifying a prefix argument NO-HEADER. Subsequent writes to the same file 1215the file without the header by specifying a prefix argument
1096can be made with the command \\[mh-refile-or-write-again]." 1216NO-HEADER. Subsequent writes to the same file can be made with
1217the command \\[mh-refile-or-write-again]."
1097 (interactive 1218 (interactive
1098 (list (mh-get-msg-num t) 1219 (list (mh-get-msg-num t)
1099 (let ((default-dir (if (eq 'write (car mh-last-destination-write)) 1220 (let ((default-dir (if (eq 'write (car mh-last-destination-write))
@@ -1129,13 +1250,14 @@ can be made with the command \\[mh-refile-or-write-again]."
1129(defun mh-undo (range) 1250(defun mh-undo (range)
1130 "Undo pending deletes or refiles in RANGE. 1251 "Undo pending deletes or refiles in RANGE.
1131 1252
1132If you've deleted a message or refiled it, but changed your mind, you can 1253If you've deleted a message or refiled it, but changed your mind,
1133cancel the action before you've executed it. Use this command to undo a refile 1254you can cancel the action before you've executed it. Use this
1134on or deletion of a single message. You can also undo refiles and deletes for 1255command to undo a refile on or deletion of a single message. You
1135messages that are found in a given RANGE. 1256can also undo refiles and deletes for messages that are found in
1257a given RANGE.
1136 1258
1137Check the documentation of `mh-interactive-range' to see how RANGE is read in 1259Check the documentation of `mh-interactive-range' to see how
1138interactive use." 1260RANGE is read in interactive use."
1139 (interactive (list (mh-interactive-range "Undo"))) 1261 (interactive (list (mh-interactive-range "Undo")))
1140 (cond ((numberp range) 1262 (cond ((numberp range)
1141 (let ((original-position (point))) 1263 (let ((original-position (point)))
@@ -1161,8 +1283,8 @@ interactive use."
1161 1283
1162(defun mh-folder-line-matches-show-buffer-p () 1284(defun mh-folder-line-matches-show-buffer-p ()
1163 "Return t if the message under point in folder-mode is in the show buffer. 1285 "Return t if the message under point in folder-mode is in the show buffer.
1164Return nil in any other circumstance (no message under point, no show buffer, 1286Return nil in any other circumstance (no message under point, no
1165the message in the show buffer doesn't match." 1287show buffer, the message in the show buffer doesn't match."
1166 (and (eq major-mode 'mh-folder-mode) 1288 (and (eq major-mode 'mh-folder-mode)
1167 (mh-get-msg-num nil) 1289 (mh-get-msg-num nil)
1168 mh-show-buffer 1290 mh-show-buffer
@@ -1178,9 +1300,9 @@ the message in the show buffer doesn't match."
1178 1300
1179(defmacro mh-macro-expansion-time-gnus-version () 1301(defmacro mh-macro-expansion-time-gnus-version ()
1180 "Return Gnus version available at macro expansion time. 1302 "Return Gnus version available at macro expansion time.
1181The macro evaluates the Gnus version at macro expansion time. If MH-E was 1303The macro evaluates the Gnus version at macro expansion time. If
1182compiled then macro expansion happens at compile time." 1304MH-E was compiled then macro expansion happens at compile time."
1183 gnus-version) 1305gnus-version)
1184 1306
1185(defun mh-run-time-gnus-version () 1307(defun mh-run-time-gnus-version ()
1186 "Return Gnus version available at run time." 1308 "Return Gnus version available at run time."
@@ -1222,9 +1344,9 @@ compiled then macro expansion happens at compile time."
1222 1344
1223(defun mh-parse-flist-output-line (line &optional current-folder) 1345(defun mh-parse-flist-output-line (line &optional current-folder)
1224 "Parse LINE to generate folder name, unseen messages and total messages. 1346 "Parse LINE to generate folder name, unseen messages and total messages.
1225If CURRENT-FOLDER is non-nil then it contains the current folder name and it is 1347If CURRENT-FOLDER is non-nil then it contains the current folder
1226used to avoid problems in corner cases involving folders whose names end with a 1348name and it is used to avoid problems in corner cases involving
1227'+' character." 1349folders whose names end with a '+' character."
1228 (with-temp-buffer 1350 (with-temp-buffer
1229 (insert line) 1351 (insert line)
1230 (goto-char (point-max)) 1352 (goto-char (point-max))
@@ -1248,7 +1370,7 @@ used to avoid problems in corner cases involving folders whose names end with a
1248 (values (format "+%s" folder) (car unseen) (car total)))))))) 1370 (values (format "+%s" folder) (car unseen) (car total))))))))
1249 1371
1250(defun mh-folder-size-folder (folder) 1372(defun mh-folder-size-folder (folder)
1251 "Find size of FOLDER using `folder'." 1373 "Find size of FOLDER using \"folder\"."
1252 (with-temp-buffer 1374 (with-temp-buffer
1253 (let ((u (length (cdr (assoc mh-unseen-seq 1375 (let ((u (length (cdr (assoc mh-unseen-seq
1254 (mh-read-folder-sequences folder nil)))))) 1376 (mh-read-folder-sequences folder nil))))))
@@ -1260,7 +1382,7 @@ used to avoid problems in corner cases involving folders whose names end with a
1260 (values 0 u folder))))) 1382 (values 0 u folder)))))
1261 1383
1262(defun mh-folder-size-flist (folder) 1384(defun mh-folder-size-flist (folder)
1263 "Find size of FOLDER using `flist'." 1385 "Find size of FOLDER using \"flist\"."
1264 (with-temp-buffer 1386 (with-temp-buffer
1265 (call-process (expand-file-name "flist" mh-progs) nil t nil "-showzero" 1387 (call-process (expand-file-name "flist" mh-progs) nil t nil "-showzero"
1266 "-norecurse" folder "-sequence" (symbol-name mh-unseen-seq)) 1388 "-norecurse" folder "-sequence" (symbol-name mh-unseen-seq))
@@ -1279,27 +1401,31 @@ used to avoid problems in corner cases involving folders whose names end with a
1279(defun mh-visit-folder (folder &optional range index-data) 1401(defun mh-visit-folder (folder &optional range index-data)
1280 "Visit FOLDER. 1402 "Visit FOLDER.
1281 1403
1282When you want to read the messages that you have refiled into folders, use 1404When you want to read the messages that you have refiled into folders,
1283this command to visit the folder. You are prompted for the folder name. 1405use this command to visit the folder. You are prompted for the folder
1406name.
1284 1407
1285The folder buffer will show just unseen messages if there are any; otherwise, 1408The folder buffer will show just unseen messages if there are any;
1286it will show all the messages in the buffer as long there are fewer than 1409otherwise, it will show all the messages in the buffer as long there
1287`mh-large-folder' messages. If there are more, then you are prompted for a 1410are fewer than `mh-large-folder' messages. If there are more, then you
1288range of messages to scan. 1411are prompted for a range of messages to scan.
1289 1412
1290You can provide a prefix argument in order to specify a RANGE of messages to 1413You can provide a prefix argument in order to specify a RANGE of
1291show when you visit the folder. In this case, regions are not used to specify 1414messages to show when you visit the folder. In this case, regions are
1292the range and `mh-large-folder' is ignored. Check the documentation of 1415not used to specify the range and `mh-large-folder' is ignored. Check
1293`mh-interactive-range' to see how RANGE is read in interactive use. 1416the documentation of `mh-interactive-range' to see how RANGE is read
1417in interactive use.
1294 1418
1295Note that this command can also be used to create folders. If you specify a 1419Note that this command can also be used to create folders. If you
1296folder that does not exist, you will be prompted to create it. 1420specify a folder that does not exist, you will be prompted to create
1421it.
1297 1422
1298Do not call this function from outside MH-E; use \\[mh-rmail] instead. 1423Do not call this function from outside MH-E; use \\[mh-rmail] instead.
1299 1424
1300If, in a program, RANGE is nil (the default), then all messages in FOLDER are 1425If, in a program, RANGE is nil (the default), then all messages in
1301displayed. If an index buffer is being created then INDEX-DATA is used to 1426FOLDER are displayed. If an index buffer is being created then
1302initialize the index buffer specific data structures." 1427INDEX-DATA is used to initialize the index buffer specific data
1428structures."
1303 (interactive (let ((folder-name (mh-prompt-for-folder "Visit" mh-inbox t))) 1429 (interactive (let ((folder-name (mh-prompt-for-folder "Visit" mh-inbox t)))
1304 (list folder-name 1430 (list folder-name
1305 (mh-read-range "Scan" folder-name t nil 1431 (mh-read-range "Scan" folder-name t nil
@@ -1338,10 +1464,11 @@ initialize the index buffer specific data structures."
1338 1464
1339(defun mh-update-sequences () 1465(defun mh-update-sequences ()
1340 "Flush MH-E's state out to MH. 1466 "Flush MH-E's state out to MH.
1341This function updates the sequence specified by your \"Unseen-Sequence:\" 1467
1342profile component, \"cur\", and the sequence listed by the `mh-tick-seq' 1468This function updates the sequence specified by your
1343option which is \"tick\" by default. The message at the cursor is used for 1469\"Unseen-Sequence:\" profile component, \"cur\", and the sequence
1344\"cur\"." 1470listed by the `mh-tick-seq' option which is \"tick\" by default.
1471The message at the cursor is used for \"cur\"."
1345 (interactive) 1472 (interactive)
1346 ;; mh-update-sequences is the opposite of mh-read-folder-sequences, 1473 ;; mh-update-sequences is the opposite of mh-read-folder-sequences,
1347 ;; which updates MH-E's state from MH. 1474 ;; which updates MH-E's state from MH.
@@ -1368,44 +1495,43 @@ option which is \"tick\" by default. The message at the cursor is used for
1368 1495
1369;;; Support routines. 1496;;; Support routines.
1370 1497
1371(defun mh-delete-a-msg (msg) 1498(defun mh-delete-a-msg (message)
1372 "Delete the MSG. 1499 "Delete MESSAGE.
1373If MSG is nil then the message at point is deleted. 1500If MESSAGE is nil then the message at point is deleted.
1374 1501The hook `mh-delete-msg-hook' is called after you mark a message
1375The value of `mh-delete-msg-hook' is a list of functions to be called, with no 1502for deletion. For example, a past maintainer of MH-E used this
1376arguments, after the message has been deleted." 1503once when he kept statistics on his mail usage."
1377 (save-excursion 1504 (save-excursion
1378 (if (numberp msg) 1505 (if (numberp message)
1379 (mh-goto-msg msg nil t) 1506 (mh-goto-msg message nil t)
1380 (beginning-of-line) 1507 (beginning-of-line)
1381 (setq msg (mh-get-msg-num t))) 1508 (setq message (mh-get-msg-num t)))
1382 (if (looking-at mh-scan-refiled-msg-regexp) 1509 (if (looking-at mh-scan-refiled-msg-regexp)
1383 (error "Message %d is refiled. Undo refile before deleting" msg)) 1510 (error "Message %d is refiled. Undo refile before deleting" message))
1384 (if (looking-at mh-scan-deleted-msg-regexp) 1511 (if (looking-at mh-scan-deleted-msg-regexp)
1385 nil 1512 nil
1386 (mh-set-folder-modified-p t) 1513 (mh-set-folder-modified-p t)
1387 (setq mh-delete-list (cons msg mh-delete-list)) 1514 (setq mh-delete-list (cons message mh-delete-list))
1388 (mh-notate nil mh-note-deleted mh-cmd-note) 1515 (mh-notate nil mh-note-deleted mh-cmd-note)
1389 (run-hooks 'mh-delete-msg-hook)))) 1516 (run-hooks 'mh-delete-msg-hook))))
1390 1517
1391(defun mh-refile-a-msg (msg folder) 1518(defun mh-refile-a-msg (message folder)
1392 "Refile MSG in FOLDER. 1519 "Refile MESSAGE in FOLDER.
1393If MSG is nil then the message at point is refiled. 1520If MESSAGE is nil then the message at point is refiled.
1394
1395Folder is a symbol, not a string. 1521Folder is a symbol, not a string.
1396The value of `mh-refile-msg-hook' is a list of functions to be called, with no 1522The hook `mh-refile-msg-hook' is called after a message is marked to
1397arguments, after the message has been refiled." 1523be refiled."
1398 (save-excursion 1524 (save-excursion
1399 (if (numberp msg) 1525 (if (numberp message)
1400 (mh-goto-msg msg nil t) 1526 (mh-goto-msg message nil t)
1401 (beginning-of-line) 1527 (beginning-of-line)
1402 (setq msg (mh-get-msg-num t))) 1528 (setq message (mh-get-msg-num t)))
1403 (cond ((looking-at mh-scan-deleted-msg-regexp) 1529 (cond ((looking-at mh-scan-deleted-msg-regexp)
1404 (error "Message %d is deleted. Undo delete before moving" msg)) 1530 (error "Message %d is deleted. Undo delete before moving" message))
1405 ((looking-at mh-scan-refiled-msg-regexp) 1531 ((looking-at mh-scan-refiled-msg-regexp)
1406 (if (y-or-n-p 1532 (if (y-or-n-p
1407 (format "Message %d already refiled. Copy to %s as well? " 1533 (format "Message %d already refiled. Copy to %s as well? "
1408 msg folder)) 1534 message folder))
1409 (mh-exec-cmd "refile" (mh-get-msg-num t) "-link" 1535 (mh-exec-cmd "refile" (mh-get-msg-num t) "-link"
1410 "-src" mh-current-folder 1536 "-src" mh-current-folder
1411 (symbol-name folder)) 1537 (symbol-name folder))
@@ -1413,17 +1539,17 @@ arguments, after the message has been refiled."
1413 (t 1539 (t
1414 (mh-set-folder-modified-p t) 1540 (mh-set-folder-modified-p t)
1415 (cond ((null (assoc folder mh-refile-list)) 1541 (cond ((null (assoc folder mh-refile-list))
1416 (push (list folder msg) mh-refile-list)) 1542 (push (list folder message) mh-refile-list))
1417 ((not (member msg (cdr (assoc folder mh-refile-list)))) 1543 ((not (member message (cdr (assoc folder mh-refile-list))))
1418 (push msg (cdr (assoc folder mh-refile-list))))) 1544 (push message (cdr (assoc folder mh-refile-list)))))
1419 (mh-notate nil mh-note-refiled mh-cmd-note) 1545 (mh-notate nil mh-note-refiled mh-cmd-note)
1420 (run-hooks 'mh-refile-msg-hook))))) 1546 (run-hooks 'mh-refile-msg-hook)))))
1421 1547
1422(defun mh-next-msg (&optional wait-after-complaining-flag) 1548(defun mh-next-msg (&optional wait-after-complaining-flag)
1423 "Move backward or forward to the next undeleted message in the buffer. 1549 "Move backward or forward to the next undeleted message in the buffer.
1424If optional argument WAIT-AFTER-COMPLAINING-FLAG is non-nil and we are at the 1550If optional argument WAIT-AFTER-COMPLAINING-FLAG is non-nil and
1425last message, then wait for a second after telling the user that there aren't 1551we are at the last message, then wait for a second after telling
1426any more unread messages." 1552the user that there aren't any more unread messages."
1427 (if (eq mh-next-direction 'forward) 1553 (if (eq mh-next-direction 'forward)
1428 (mh-next-undeleted-msg 1 wait-after-complaining-flag) 1554 (mh-next-undeleted-msg 1 wait-after-complaining-flag)
1429 (mh-previous-undeleted-msg 1 wait-after-complaining-flag))) 1555 (mh-previous-undeleted-msg 1 wait-after-complaining-flag)))
@@ -1431,8 +1557,8 @@ any more unread messages."
1431(defun mh-next-unread-msg (&optional count) 1557(defun mh-next-unread-msg (&optional count)
1432 "Display next unread message. 1558 "Display next unread message.
1433 1559
1434This command can be given a prefix argument COUNT to specify how many unread 1560This command can be given a prefix argument COUNT to specify how
1435messages to skip." 1561many unread messages to skip."
1436 (interactive "p") 1562 (interactive "p")
1437 (unless (> count 0) 1563 (unless (> count 0)
1438 (error "The function mh-next-unread-msg expects positive argument")) 1564 (error "The function mh-next-unread-msg expects positive argument"))
@@ -1609,9 +1735,9 @@ Make it the current folder."
1609 1735
1610(defmacro mh-write-file-functions-compat () 1736(defmacro mh-write-file-functions-compat ()
1611 "Return `write-file-functions' if it exists. 1737 "Return `write-file-functions' if it exists.
1612Otherwise return `local-write-file-hooks'. This macro exists purely for 1738Otherwise return `local-write-file-hooks'. This macro exists
1613compatibility. The former symbol is used in Emacs 21.4 onward while the latter 1739purely for compatibility. The former symbol is used in Emacs 21.4
1614is used in previous versions and XEmacs." 1740onward while the latter is used in previous versions and XEmacs."
1615 (if (boundp 'write-file-functions) 1741 (if (boundp 'write-file-functions)
1616 ''write-file-functions ;Emacs 21.4 1742 ''write-file-functions ;Emacs 21.4
1617 ''local-write-file-hooks)) ;<Emacs 21.4, XEmacs 1743 ''local-write-file-hooks)) ;<Emacs 21.4, XEmacs
@@ -1635,52 +1761,56 @@ is used in previous versions and XEmacs."
1635(define-derived-mode mh-folder-mode fundamental-mode "MH-Folder" 1761(define-derived-mode mh-folder-mode fundamental-mode "MH-Folder"
1636 "Major MH-E mode for \"editing\" an MH folder scan listing.\\<mh-folder-mode-map> 1762 "Major MH-E mode for \"editing\" an MH folder scan listing.\\<mh-folder-mode-map>
1637 1763
1638You can show the message the cursor is pointing to, and step through the 1764You can show the message the cursor is pointing to, and step through
1639messages. Messages can be marked for deletion or refiling into another 1765the messages. Messages can be marked for deletion or refiling into
1640folder; these commands are executed all at once with a separate command. 1766another folder; these commands are executed all at once with a
1767separate command.
1641 1768
1642Options that control this mode can be changed with \\[customize-group]; 1769Options that control this mode can be changed with
1643specify the \"mh\" group. In particular, please see the `mh-scan-format-file' 1770\\[customize-group]; specify the \"mh\" group. In particular, please
1644option if you wish to modify scan's format. 1771see the `mh-scan-format-file' option if you wish to modify scan's
1772format.
1645 1773
1646When a folder is visited, the hook `mh-folder-mode-hook' is run. 1774When a folder is visited, the hook `mh-folder-mode-hook' is run.
1647 1775
1648Ranges 1776Ranges
1649====== 1777======
1650Many commands that operate on individual messages, such as `mh-forward' or 1778Many commands that operate on individual messages, such as
1651`mh-refile-msg' take a RANGE argument. This argument can be used in several 1779`mh-forward' or `mh-refile-msg' take a RANGE argument. This argument
1652ways. 1780can be used in several ways.
1653 1781
1654If you provide the prefix argument (\\[universal-argument]) to these commands, 1782If you provide the prefix argument (\\[universal-argument]) to
1655then you will be prompted for the message range. This can be any valid MH 1783these commands, then you will be prompted for the message range.
1656range which can include messages, sequences, and the abbreviations (described 1784This can be any valid MH range which can include messages,
1657in the mh(1) man page): 1785sequences, and the abbreviations (described in the mh(1) man
1786page):
1658 1787
1659<num1>-<num2> 1788<num1>-<num2>
1660 Indicates all messages in the range <num1> to <num2>, inclusive. The range 1789 Indicates all messages in the range <num1> to <num2>, inclusive.
1661 must be nonempty. 1790 The range must be nonempty.
1662 1791
1663`<num>:N' 1792<num>:N
1664`<num>:+N' 1793<num>:+N
1665`<num>:-N' 1794<num>:-N
1666 Up to N messages beginning with (or ending with) message num. Num may be 1795 Up to N messages beginning with (or ending with) message num. Num
1667 any of the predefined symbols: first, prev, cur, next or last. 1796 may be any of the predefined symbols: first, prev, cur, next or
1668 1797 last.
1669`first:N' 1798
1670`prev:N' 1799first:N
1671`next:N' 1800prev:N
1672`last:N' 1801next:N
1802last:N
1673 The first, previous, next or last messages, if they exist. 1803 The first, previous, next or last messages, if they exist.
1674 1804
1675`all' 1805all
1676 All of the messages. 1806 All of the messages.
1677 1807
1678For example, a range that shows all of these things is `1 2 3 5-10 last:5 1808For example, a range that shows all of these things is `1 2 3
1679unseen'. 18095-10 last:5 unseen'.
1680 1810
1681If the option `transient-mark-mode' is set to t and you set a region in the 1811If the option `transient-mark-mode' is set to t and you set a
1682MH-Folder buffer, then the MH-E command will perform the operation on all 1812region in the MH-Folder buffer, then the MH-E command will
1683messages in that region. 1813perform the operation on all messages in that region.
1684 1814
1685\\{mh-folder-mode-map}" 1815\\{mh-folder-mode-map}"
1686 (mh-do-in-gnu-emacs 1816 (mh-do-in-gnu-emacs
@@ -1785,10 +1915,10 @@ messages in that region.
1785 desktop-buffer-name 1915 desktop-buffer-name
1786 desktop-buffer-misc) 1916 desktop-buffer-misc)
1787 "Restore an MH folder buffer specified in a desktop file. 1917 "Restore an MH folder buffer specified in a desktop file.
1788When desktop creates a buffer, DESKTOP-BUFFER-FILE-NAME holds the file name to 1918When desktop creates a buffer, DESKTOP-BUFFER-FILE-NAME holds the
1789visit, DESKTOP-BUFFER-NAME holds the desired buffer name, and 1919file name to visit, DESKTOP-BUFFER-NAME holds the desired buffer
1790DESKTOP-BUFFER-MISC holds a list of miscellaneous info used by the 1920name, and DESKTOP-BUFFER-MISC holds a list of miscellaneous info
1791`desktop-buffer-handlers' functions." 1921used by the `desktop-buffer-handlers' functions."
1792 (mh-find-path) 1922 (mh-find-path)
1793 (mh-visit-folder desktop-buffer-name) 1923 (mh-visit-folder desktop-buffer-name)
1794 (current-buffer)) 1924 (current-buffer))
@@ -1801,13 +1931,14 @@ DESKTOP-BUFFER-MISC holds a list of miscellaneous info used by the
1801(defun mh-scan-folder (folder range &optional dont-exec-pending) 1931(defun mh-scan-folder (folder range &optional dont-exec-pending)
1802 "Scan FOLDER over RANGE. 1932 "Scan FOLDER over RANGE.
1803 1933
1804After the scan is performed, switch to the buffer associated with FOLDER. 1934After the scan is performed, switch to the buffer associated with
1935FOLDER.
1805 1936
1806Check the documentation of `mh-interactive-range' to see how RANGE is read in 1937Check the documentation of `mh-interactive-range' to see how RANGE is
1807interactive use. 1938read in interactive use.
1808 1939
1809The processing of outstanding commands is not performed if DONT-EXEC-PENDING 1940The processing of outstanding commands is not performed if
1810is non-nil." 1941DONT-EXEC-PENDING is non-nil."
1811 (when (stringp range) 1942 (when (stringp range)
1812 (setq range (delete "" (split-string range "[ \t\n]")))) 1943 (setq range (delete "" (split-string range "[ \t\n]"))))
1813 (cond ((null (get-buffer folder)) 1944 (cond ((null (get-buffer folder))
@@ -1830,11 +1961,12 @@ is non-nil."
1830 "Return the column for notations given message number WIDTH. 1961 "Return the column for notations given message number WIDTH.
1831Note that columns in Emacs start with 0. 1962Note that columns in Emacs start with 0.
1832 1963
1833If `mh-scan-format-file' is set to \"Use MH-E scan Format\" this means that 1964If `mh-scan-format-file' is set to \"Use MH-E scan Format\" this
1834either `mh-scan-format-mh' or `mh-scan-format-nmh' are in use. This function 1965means that either `mh-scan-format-mh' or `mh-scan-format-nmh' are
1835therefore assumes that the first column is empty (to provide room for the 1966in use. This function therefore assumes that the first column is
1836cursor), the following WIDTH columns contain the message number, and the 1967empty (to provide room for the cursor), the following WIDTH
1837column for notations comes after that." 1968columns contain the message number, and the column for notations
1969comes after that."
1838 (if (eq mh-scan-format-file t) 1970 (if (eq mh-scan-format-file t)
1839 (max (1+ width) 2) 1971 (max (1+ width) 2)
1840 (error "%s %s" "Can't call mh-msg-num-width-to-column" 1972 (error "%s %s" "Can't call mh-msg-num-width-to-column"
@@ -1893,9 +2025,9 @@ If UPDATE, append the scan lines, otherwise replace."
1893After doing an `mh-get-new-mail' operation in this FOLDER, at least 2025After doing an `mh-get-new-mail' operation in this FOLDER, at least
1894one line that looks like a truncated message number was found. 2026one line that looks like a truncated message number was found.
1895 2027
1896Remove the text added by the last `mh-inc' command. It should be the messages 2028Remove the text added by the last `mh-inc' command. It should be the
1897cur-last. Call `mh-set-cmd-note', adjusting the notation column with the width 2029messages cur-last. Call `mh-set-cmd-note', adjusting the notation
1898of the largest message number in FOLDER. 2030column with the width of the largest message number in FOLDER.
1899 2031
1900Reformat the message number width on each line in the buffer and trim 2032Reformat the message number width on each line in the buffer and trim
1901the line length to fit in the window. 2033the line length to fit in the window.
@@ -2016,8 +2148,9 @@ Return in the current buffer."
2016 2148
2017(defun mh-make-folder-mode-line (&optional ignored) 2149(defun mh-make-folder-mode-line (&optional ignored)
2018 "Set the fields of the mode line for a folder buffer. 2150 "Set the fields of the mode line for a folder buffer.
2019The optional argument is now obsolete and IGNORED. It used to be used to pass 2151The optional argument is now obsolete and IGNORED. It used to be
2020in what is now stored in the buffer-local variable `mh-mode-line-annotation'." 2152used to pass in what is now stored in the buffer-local variable
2153`mh-mode-line-annotation'."
2021 (save-excursion 2154 (save-excursion
2022 (save-window-excursion 2155 (save-window-excursion
2023 (mh-first-msg) 2156 (mh-first-msg)
@@ -2057,8 +2190,8 @@ in what is now stored in the buffer-local variable `mh-mode-line-annotation'."
2057 2190
2058(defun mh-add-sequence-notation (msg internal-seq-flag) 2191(defun mh-add-sequence-notation (msg internal-seq-flag)
2059 "Add sequence notation to the MSG on the current line. 2192 "Add sequence notation to the MSG on the current line.
2060If INTERNAL-SEQ-FLAG is non-nil, then refontify the scan line if font-lock is 2193If INTERNAL-SEQ-FLAG is non-nil, then refontify the scan line if
2061turned on." 2194font-lock is turned on."
2062 (with-mh-folder-updating (t) 2195 (with-mh-folder-updating (t)
2063 (save-excursion 2196 (save-excursion
2064 (beginning-of-line) 2197 (beginning-of-line)
@@ -2079,10 +2212,11 @@ turned on."
2079 2212
2080(defun mh-remove-sequence-notation (msg internal-seq-flag &optional all) 2213(defun mh-remove-sequence-notation (msg internal-seq-flag &optional all)
2081 "Remove sequence notation from the MSG on the current line. 2214 "Remove sequence notation from the MSG on the current line.
2082If INTERNAL-SEQ-FLAG is non-nil, then `font-lock' was used to highlight the 2215If INTERNAL-SEQ-FLAG is non-nil, then `font-lock' was used to
2083sequence. In that case, no notation needs to be removed. Otherwise the effect 2216highlight the sequence. In that case, no notation needs to be removed.
2084of inserting `mh-note-seq' needs to be reversed. 2217Otherwise the effect of inserting `mh-note-seq' needs to be reversed.
2085If ALL is non-nil, then all sequence marks on the scan line are removed." 2218If ALL is non-nil, then all sequence marks on the scan line are
2219removed."
2086 (with-mh-folder-updating (t) 2220 (with-mh-folder-updating (t)
2087 ;; This takes care of internal sequences... 2221 ;; This takes care of internal sequences...
2088 (mh-notate nil nil mh-cmd-note) 2222 (mh-notate nil nil mh-cmd-note)
@@ -2122,8 +2256,8 @@ If ALL is non-nil, then all sequence marks on the scan line are removed."
2122 2256
2123(defun mh-goto-cur-msg (&optional minimal-changes-flag) 2257(defun mh-goto-cur-msg (&optional minimal-changes-flag)
2124 "Position the cursor at the current message. 2258 "Position the cursor at the current message.
2125When optional argument MINIMAL-CHANGES-FLAG is non-nil, the function doesn't 2259When optional argument MINIMAL-CHANGES-FLAG is non-nil, the
2126recenter the folder buffer." 2260function doesn't recenter the folder buffer."
2127 (let ((cur-msg (car (mh-seq-to-msgs 'cur)))) 2261 (let ((cur-msg (car (mh-seq-to-msgs 'cur))))
2128 (cond ((and cur-msg 2262 (cond ((and cur-msg
2129 (mh-goto-msg cur-msg t t)) 2263 (mh-goto-msg cur-msg t t))
@@ -2137,7 +2271,8 @@ recenter the folder buffer."
2137 2271
2138(defun mh-process-or-undo-commands (folder) 2272(defun mh-process-or-undo-commands (folder)
2139 "If FOLDER has outstanding commands, then either process or discard them. 2273 "If FOLDER has outstanding commands, then either process or discard them.
2140Called by functions like `mh-sort-folder', so also invalidate show buffer." 2274Called by functions like `mh-sort-folder', so also invalidate
2275show buffer."
2141 (set-buffer folder) 2276 (set-buffer folder)
2142 (if (mh-outstanding-commands-p) 2277 (if (mh-outstanding-commands-p)
2143 (if (or mh-do-not-confirm-flag 2278 (if (or mh-do-not-confirm-flag
@@ -2151,10 +2286,10 @@ Called by functions like `mh-sort-folder', so also invalidate show buffer."
2151 2286
2152(defun mh-process-commands (folder) 2287(defun mh-process-commands (folder)
2153 "Process outstanding commands for FOLDER. 2288 "Process outstanding commands for FOLDER.
2154The value of `mh-before-commands-processed-hook' is a list of functions 2289
2155to be called, with no arguments, before the commands are processed. 2290This function runs `mh-before-commands-processed-hook' before the
2156After all cammands are processed, the functions in 2291commands are processed and `mh-after-commands-processed-hook'
2157`mh-after-commands-processed-hook' are called with no arguments." 2292after the commands are processed."
2158 (message "Processing deletes and refiles for %s..." folder) 2293 (message "Processing deletes and refiles for %s..." folder)
2159 (set-buffer folder) 2294 (set-buffer folder)
2160 (with-mh-folder-updating (nil) 2295 (with-mh-folder-updating (nil)
@@ -2238,7 +2373,7 @@ After all cammands are processed, the functions in
2238 (mh-remove-all-notation) 2373 (mh-remove-all-notation)
2239 (mh-notate-user-sequences) 2374 (mh-notate-user-sequences)
2240 2375
2241 ;; Run the after hook -- now folders-changed is valid, 2376 ;; Run the after hook -- now folders-changed is valid,
2242 ;; but not the lists of specific messages. 2377 ;; but not the lists of specific messages.
2243 (let ((mh-folders-changed folders-changed)) 2378 (let ((mh-folders-changed folders-changed))
2244 (run-hooks 'mh-after-commands-processed-hook))) 2379 (run-hooks 'mh-after-commands-processed-hook)))
@@ -2248,8 +2383,8 @@ After all cammands are processed, the functions in
2248(defun mh-update-unseen () 2383(defun mh-update-unseen ()
2249 "Synchronize the unseen sequence with MH. 2384 "Synchronize the unseen sequence with MH.
2250Return non-nil iff the MH folder was set. 2385Return non-nil iff the MH folder was set.
2251The value of `mh-unseen-updated-hook' is a list of functions to be called, 2386The hook `mh-unseen-updated-hook' is called after the unseen sequence
2252with no arguments, after the unseen sequence is updated." 2387is updated."
2253 (if mh-seen-list 2388 (if mh-seen-list
2254 (let* ((unseen-seq (mh-find-seq mh-unseen-seq)) 2389 (let* ((unseen-seq (mh-find-seq mh-unseen-seq))
2255 (unseen-msgs (mh-seq-msgs unseen-seq))) 2390 (unseen-msgs (mh-seq-msgs unseen-seq)))
@@ -2284,8 +2419,8 @@ with no arguments, after the unseen sequence is updated."
2284(defun mh-coalesce-msg-list (messages) 2419(defun mh-coalesce-msg-list (messages)
2285 "Given a list of MESSAGES, return a list of message number ranges. 2420 "Given a list of MESSAGES, return a list of message number ranges.
2286This is the inverse of `mh-read-msg-list', which expands ranges. 2421This is the inverse of `mh-read-msg-list', which expands ranges.
2287Message lists passed to MH programs should be processed by this function 2422Message lists passed to MH programs should be processed by this
2288to avoid exceeding system command line argument limits." 2423function to avoid exceeding system command line argument limits."
2289 (let ((msgs (sort (copy-sequence messages) 'mh-greaterp)) 2424 (let ((msgs (sort (copy-sequence messages) 'mh-greaterp))
2290 (range-high nil) 2425 (range-high nil)
2291 (prev -1) 2426 (prev -1)
@@ -2383,8 +2518,9 @@ Expands ranges into set of individual numbers."
2383(defun mh-notate-user-sequences (&optional range) 2518(defun mh-notate-user-sequences (&optional range)
2384 "Mark user-defined sequences in RANGE. 2519 "Mark user-defined sequences in RANGE.
2385 2520
2386Check the documentation of `mh-interactive-range' to see how RANGE is read in 2521Check the documentation of `mh-interactive-range' to see how
2387interactive use; if nil all messages are notated." 2522RANGE is read in interactive use; if nil all messages are
2523notated."
2388 (unless range 2524 (unless range
2389 (setq range (cons (point-min) (point-max)))) 2525 (setq range (cons (point-min) (point-max))))
2390 (let ((seqs mh-seq-list) 2526 (let ((seqs mh-seq-list)
@@ -2414,10 +2550,11 @@ interactive use; if nil all messages are notated."
2414(defun mh-delete-msg-from-seq (range sequence &optional internal-flag) 2550(defun mh-delete-msg-from-seq (range sequence &optional internal-flag)
2415 "Delete RANGE from SEQUENCE. 2551 "Delete RANGE from SEQUENCE.
2416 2552
2417Check the documentation of `mh-interactive-range' to see how RANGE is read in 2553Check the documentation of `mh-interactive-range' to see how
2418interactive use. 2554RANGE is read in interactive use.
2419 2555
2420In a program, non-nil INTERNAL-FLAG means do not inform MH of the change." 2556In a program, non-nil INTERNAL-FLAG means do not inform MH of the
2557change."
2421 (interactive (list (mh-interactive-range "Delete") 2558 (interactive (list (mh-interactive-range "Delete")
2422 (mh-read-seq-default "Delete from" t) 2559 (mh-read-seq-default "Delete from" t)
2423 nil)) 2560 nil))
@@ -2445,15 +2582,16 @@ In a program, non-nil INTERNAL-FLAG means do not inform MH of the change."
2445(defun mh-catchup (range) 2582(defun mh-catchup (range)
2446 "Delete RANGE from the \"unseen\" sequence. 2583 "Delete RANGE from the \"unseen\" sequence.
2447 2584
2448Check the documentation of `mh-interactive-range' to see how RANGE is read in 2585Check the documentation of `mh-interactive-range' to see how
2449interactive use." 2586RANGE is read in interactive use."
2450 (interactive (list (mh-interactive-range "Catchup" 2587 (interactive (list (mh-interactive-range "Catchup"
2451 (cons (point-min) (point-max))))) 2588 (cons (point-min) (point-max)))))
2452 (mh-delete-msg-from-seq range mh-unseen-seq)) 2589 (mh-delete-msg-from-seq range mh-unseen-seq))
2453 2590
2454(defun mh-delete-a-msg-from-seq (msg sequence internal-flag) 2591(defun mh-delete-a-msg-from-seq (msg sequence internal-flag)
2455 "Delete MSG from SEQUENCE. 2592 "Delete MSG from SEQUENCE.
2456If INTERNAL-FLAG is non-nil, then do not inform MH of the change." 2593If INTERNAL-FLAG is non-nil, then do not inform MH of the
2594change."
2457 (let ((entry (mh-find-seq sequence))) 2595 (let ((entry (mh-find-seq sequence)))
2458 (when (and entry (memq msg (mh-seq-msgs entry))) 2596 (when (and entry (memq msg (mh-seq-msgs entry)))
2459 (if (not internal-flag) 2597 (if (not internal-flag)
@@ -2480,7 +2618,8 @@ Signals an error if SEQ is an invalid name."
2480 2618
2481(defun mh-seq-containing-msg (msg &optional include-internal-flag) 2619(defun mh-seq-containing-msg (msg &optional include-internal-flag)
2482 "Return a list of the sequences containing MSG. 2620 "Return a list of the sequences containing MSG.
2483If INCLUDE-INTERNAL-FLAG non-nil, include MH-E internal sequences in list." 2621If INCLUDE-INTERNAL-FLAG non-nil, include MH-E internal sequences
2622in list."
2484 (let ((l mh-seq-list) 2623 (let ((l mh-seq-list)
2485 (seqs ())) 2624 (seqs ()))
2486 (while l 2625 (while l
@@ -2504,7 +2643,7 @@ If INCLUDE-INTERNAL-FLAG non-nil, include MH-E internal sequences in list."
2504(defalias 'mh-alt-send 'mh-send) 2643(defalias 'mh-alt-send 'mh-send)
2505(defalias 'mh-alt-visit-folder 'mh-visit-folder) 2644(defalias 'mh-alt-visit-folder 'mh-visit-folder)
2506 2645
2507;; Save the `b' binding for a future `back'. Maybe? 2646;; Save the "b" binding for a future `back'. Maybe?
2508(gnus-define-keys mh-folder-mode-map 2647(gnus-define-keys mh-folder-mode-map
2509 " " mh-page-msg 2648 " " mh-page-msg
2510 "!" mh-refile-or-write-again 2649 "!" mh-refile-or-write-again
@@ -2654,7 +2793,7 @@ If INCLUDE-INTERNAL-FLAG non-nil, include MH-E internal sequences in list."
2654;; 2793;;
2655;; When adding a new prefix, ensure that the help message contains "what" the 2794;; When adding a new prefix, ensure that the help message contains "what" the
2656;; prefix is for. For example, if the word "folder" were not present in the 2795;; prefix is for. For example, if the word "folder" were not present in the
2657;; `F' entry, it would not be clear what these commands operated upon. 2796;; "F" entry, it would not be clear what these commands operated upon.
2658(defvar mh-help-messages 2797(defvar mh-help-messages
2659 '((nil "[i]nc, [.]show, [,]show all, [n]ext, [p]revious,\n" 2798 '((nil "[i]nc, [.]show, [,]show all, [n]ext, [p]revious,\n"
2660 "[d]elete, [o]refile, e[x]ecute,\n" 2799 "[d]elete, [o]refile, e[x]ecute,\n"
diff --git a/lisp/mh-e/mh-funcs.el b/lisp/mh-e/mh-funcs.el
index 813d8a07b6c..800ff96b510 100644
--- a/lisp/mh-e/mh-funcs.el
+++ b/lisp/mh-e/mh-funcs.el
@@ -57,17 +57,19 @@
57(defun mh-burst-digest () 57(defun mh-burst-digest ()
58 "Break up digest into separate messages\\<mh-folder-mode-map>. 58 "Break up digest into separate messages\\<mh-folder-mode-map>.
59 59
60This command uses the MH command \"burst\" to break out each message in the 60This command uses the MH command \"burst\" to break out each
61digest into its own message. Using this command, you can quickly delete 61message in the digest into its own message. Using this command,
62unwanted messages, like this: Once the digest is split up, toggle out of 62you can quickly delete unwanted messages, like this: Once the
63MH-Folder Show mode with \\[mh-toggle-showing] so that the scan lines fill the 63digest is split up, toggle out of MH-Folder Show mode with
64screen and messages aren't displayed. Then use \\[mh-delete-msg] to quickly 64\\[mh-toggle-showing] so that the scan lines fill the screen and
65delete messages that you don't want to read (based on the \"Subject:\" header 65messages aren't displayed. Then use \\[mh-delete-msg] to quickly
66field). You can also burst the digest to reply directly to the people who 66delete messages that you don't want to read (based on the
67posted the messages in the digest. One problem you may encounter is that the 67\"Subject:\" header field). You can also burst the digest to
68\"From:\" header fields are preceded with a \">\" so that your reply can't 68reply directly to the people who posted the messages in the
69create the \"To:\" field correctly. In this case, you must correct the \"To:\" 69digest. One problem you may encounter is that the \"From:\"
70field yourself." 70header fields are preceded with a \">\" so that your reply can't
71create the \"To:\" field correctly. In this case, you must
72correct the \"To:\" field yourself."
71 (interactive) 73 (interactive)
72 (let ((digest (mh-get-msg-num t))) 74 (let ((digest (mh-get-msg-num t)))
73 (mh-process-or-undo-commands mh-current-folder) 75 (mh-process-or-undo-commands mh-current-folder)
@@ -85,15 +87,15 @@ field yourself."
85(defun mh-copy-msg (range folder) 87(defun mh-copy-msg (range folder)
86 "Copy RANGE to FOLDER\\<mh-folder-mode-map>. 88 "Copy RANGE to FOLDER\\<mh-folder-mode-map>.
87 89
88If you wish to copy a message to another folder, you can use this command 90If you wish to copy a message to another folder, you can use this
89\(see the \"-link\" argument to \"refile\"). Like the command 91command (see the \"-link\" argument to \"refile\"). Like the
90\\[mh-refile-msg], this command prompts you for the name of the target folder 92command \\[mh-refile-msg], this command prompts you for the name
91and you can specify a range. Note that unlike the command \\[mh-refile-msg], 93of the target folder and you can specify a range. Note that
92the copy takes place immediately. The original copy remains in the current 94unlike the command \\[mh-refile-msg], the copy takes place
93folder. 95immediately. The original copy remains in the current folder.
94 96
95Check the documentation of `mh-interactive-range' to see how RANGE is read in 97Check the documentation of `mh-interactive-range' to see how
96interactive use." 98RANGE is read in interactive use."
97 (interactive (list (mh-interactive-range "Copy") 99 (interactive (list (mh-interactive-range "Copy")
98 (mh-prompt-for-folder "Copy to" "" t))) 100 (mh-prompt-for-folder "Copy to" "" t)))
99 (let ((msg-list (let ((result ())) 101 (let ((msg-list (let ((result ()))
@@ -106,15 +108,18 @@ interactive use."
106 108
107;;;###mh-autoload 109;;;###mh-autoload
108(defun mh-kill-folder () 110(defun mh-kill-folder ()
109 "Remove the current folder and all included messages. 111 "Remove folder.
110Removes all of the messages (files) within the specified current folder, 112
111and then removes the folder (directory) itself. 113Remove all of the messages (files) within the current folder, and
112The value of `mh-kill-folder-suppress-prompt-hook' is a list of functions to 114then remove the folder (directory) itself.
113be called, with no arguments, which should return a value of non-nil if 115
114verification is not desired." 116Run the abnormal hook `mh-kill-folder-suppress-prompt-hooks'. The
117hook functions are called with no arguments and should return a
118non-nil value to suppress the normal prompt when you remove a
119folder. This is useful for folders that are easily regenerated."
115 (interactive) 120 (interactive)
116 (if (or (run-hook-with-args-until-success 121 (if (or (run-hook-with-args-until-success
117 'mh-kill-folder-suppress-prompt-hook) 122 'mh-kill-folder-suppress-prompt-hooks)
118 (yes-or-no-p (format "Remove folder %s (and all included messages)? " 123 (yes-or-no-p (format "Remove folder %s (and all included messages)? "
119 mh-current-folder))) 124 mh-current-folder)))
120 (let ((folder mh-current-folder) 125 (let ((folder mh-current-folder)
@@ -169,14 +174,15 @@ Display the results only if something went wrong."
169(defun mh-pack-folder (range) 174(defun mh-pack-folder (range)
170 "Pack folder\\<mh-folder-mode-map>. 175 "Pack folder\\<mh-folder-mode-map>.
171 176
172This command packs the folder, removing gaps from the numbering sequence. If 177This command packs the folder, removing gaps from the numbering
173you don't want to rescan the entire folder afterward, this command will accept 178sequence. If you don't want to rescan the entire folder
174a RANGE. Check the documentation of `mh-interactive-range' to see how RANGE is 179afterward, this command will accept a RANGE. Check the
175read in interactive use. 180documentation of `mh-interactive-range' to see how RANGE is read
181in interactive use.
176 182
177This command will ask if you want to process refiles or deletes first and then 183This command will ask if you want to process refiles or deletes
178either run \\[mh-execute-commands] for you or undo the pending refiles and 184first and then either run \\[mh-execute-commands] for you or undo
179deletes, which are lost." 185the pending refiles and deletes, which are lost."
180 (interactive (list (if current-prefix-arg 186 (interactive (list (if current-prefix-arg
181 (mh-read-range "Scan" mh-current-folder t nil t 187 (mh-read-range "Scan" mh-current-folder t nil t
182 mh-interpret-number-as-range-flag) 188 mh-interpret-number-as-range-flag)
@@ -207,9 +213,10 @@ Display RANGE after packing, or the entire folder if RANGE is nil."
207(defun mh-pipe-msg (command include-header) 213(defun mh-pipe-msg (command include-header)
208 "Pipe message through shell command COMMAND. 214 "Pipe message through shell command COMMAND.
209 215
210You are prompted for the Unix command through which you wish to run your 216You are prompted for the Unix command through which you wish to
211message. If you give an argument INCLUDE-HEADER to this command, the message 217run your message. If you give an argument INCLUDE-HEADER to this
212header is included in the text passed to the command." 218command, the message header is included in the text passed to the
219command."
213 (interactive 220 (interactive
214 (list (read-string "Shell command on message: ") current-prefix-arg)) 221 (list (read-string "Shell command on message: ") current-prefix-arg))
215 (let ((msg-file-to-pipe (mh-msg-filename (mh-get-msg-num t))) 222 (let ((msg-file-to-pipe (mh-msg-filename (mh-get-msg-num t)))
@@ -260,9 +267,11 @@ header is included in the text passed to the command."
260;;;###mh-autoload 267;;;###mh-autoload
261(defun mh-sort-folder (&optional extra-args) 268(defun mh-sort-folder (&optional extra-args)
262 "Sort the messages in the current folder by date. 269 "Sort the messages in the current folder by date.
270
263Calls the MH program sortm to do the work. 271Calls the MH program sortm to do the work.
264The arguments in the list `mh-sortm-args' are passed to sortm if the optional 272
265argument EXTRA-ARGS is given." 273The arguments in the list `mh-sortm-args' are passed to sortm if
274the optional argument EXTRA-ARGS is given."
266 (interactive "P") 275 (interactive "P")
267 (mh-process-or-undo-commands mh-current-folder) 276 (mh-process-or-undo-commands mh-current-folder)
268 (setq mh-next-direction 'forward) 277 (setq mh-next-direction 'forward)
@@ -294,12 +303,13 @@ argument EXTRA-ARGS is given."
294 303
295;;;###mh-autoload 304;;;###mh-autoload
296(defun mh-store-msg (directory) 305(defun mh-store-msg (directory)
297 "Unpack message created with `uudecode' or `shar'. 306 "Unpack message created with \"uudecode\" or \"shar\".
298 307
299The default DIRECTORY for extraction is the current directory; however, you 308The default DIRECTORY for extraction is the current directory;
300have a chance to specify a different extraction directory. The next time you 309however, you have a chance to specify a different extraction
301use this command, the default directory is the last directory you used. If you 310directory. The next time you use this command, the default
302would like to change the initial default directory, customize the option 311directory is the last directory you used. If you would like to
312change the initial default directory, customize the option
303`mh-store-default-directory'." 313`mh-store-default-directory'."
304 (interactive (list (let ((udir (or mh-store-default-directory 314 (interactive (list (let ((udir (or mh-store-default-directory
305 default-directory))) 315 default-directory)))
@@ -315,9 +325,11 @@ would like to change the initial default directory, customize the option
315;;;###mh-autoload 325;;;###mh-autoload
316(defun mh-store-buffer (directory) 326(defun mh-store-buffer (directory)
317 "Store the file(s) contained in the current buffer into DIRECTORY. 327 "Store the file(s) contained in the current buffer into DIRECTORY.
328
318The buffer can contain a shar file or uuencoded file. 329The buffer can contain a shar file or uuencoded file.
319Default directory is the last directory used, or initially the value of 330
320`mh-store-default-directory' or the current directory." 331Default directory is the last directory used, or initially the
332value of `mh-store-default-directory' or the current directory."
321 (interactive (list (let ((udir (or mh-store-default-directory 333 (interactive (list (let ((udir (or mh-store-default-directory
322 default-directory))) 334 default-directory)))
323 (read-file-name "Store buffer in directory: " 335 (read-file-name "Store buffer in directory: "
@@ -397,7 +409,7 @@ Default directory is the last directory used, or initially the value of
397(defun mh-prefix-help () 409(defun mh-prefix-help ()
398 "Display cheat sheet for the commands of the current prefix in minibuffer." 410 "Display cheat sheet for the commands of the current prefix in minibuffer."
399 (interactive) 411 (interactive)
400 ;; We got here because the user pressed a `?', but he pressed a prefix key 412 ;; We got here because the user pressed a "?", but he pressed a prefix key
401 ;; before that. Since the the key vector starts at index 0, the index of the 413 ;; before that. Since the the key vector starts at index 0, the index of the
402 ;; last keystroke is length-1 and thus the second to last keystroke is at 414 ;; last keystroke is length-1 and thus the second to last keystroke is at
403 ;; length-2. We use that information to obtain a suitable prefix character 415 ;; length-2. We use that information to obtain a suitable prefix character
diff --git a/lisp/mh-e/mh-gnus.el b/lisp/mh-e/mh-gnus.el
index 71220e2dd3d..a52bc5e463e 100644
--- a/lisp/mh-e/mh-gnus.el
+++ b/lisp/mh-e/mh-gnus.el
@@ -41,9 +41,9 @@
41 41
42(defmacro mh-defun-compat (function arg-list &rest body) 42(defmacro mh-defun-compat (function arg-list &rest body)
43 "This is a macro to define functions which are not defined. 43 "This is a macro to define functions which are not defined.
44It is used for Gnus utility functions which were added recently. If FUNCTION 44It is used for Gnus utility functions which were added recently.
45is not defined then it is defined to have argument list, ARG-LIST and body, 45If FUNCTION is not defined then it is defined to have argument
46BODY." 46list, ARG-LIST and body, BODY."
47 (let ((defined-p (fboundp function))) 47 (let ((defined-p (fboundp function)))
48 (unless defined-p 48 (unless defined-p
49 `(defun ,function ,arg-list ,@body)))) 49 `(defun ,function ,arg-list ,@body))))
@@ -51,9 +51,9 @@ BODY."
51 51
52(defmacro mh-defmacro-compat (function arg-list &rest body) 52(defmacro mh-defmacro-compat (function arg-list &rest body)
53 "This is a macro to define functions which are not defined. 53 "This is a macro to define functions which are not defined.
54It is used for Gnus utility functions which were added recently. If FUNCTION 54It is used for Gnus utility functions which were added recently.
55is not defined then it is defined to have argument list, ARG-LIST and body, 55If FUNCTION is not defined then it is defined to have argument
56BODY." 56list, ARG-LIST and body, BODY."
57 (let ((defined-p (fboundp function))) 57 (let ((defined-p (fboundp function)))
58 (unless defined-p 58 (unless defined-p
59 `(defmacro ,function ,arg-list ,@body)))) 59 `(defmacro ,function ,arg-list ,@body))))
diff --git a/lisp/mh-e/mh-identity.el b/lisp/mh-e/mh-identity.el
index 1e621af7df9..52bb8f903fe 100644
--- a/lisp/mh-e/mh-identity.el
+++ b/lisp/mh-e/mh-identity.el
@@ -47,14 +47,15 @@
47 47
48(defvar mh-identity-pgg-default-user-id nil 48(defvar mh-identity-pgg-default-user-id nil
49 "Holds the GPG key ID to be used by pgg.el. 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'.") 50This is normally set as part of an Identity in
51`mh-identity-list'.")
51(make-variable-buffer-local 'mh-identity-pgg-default-user-id) 52(make-variable-buffer-local 'mh-identity-pgg-default-user-id)
52 53
53;;;###mh-autoload 54;;;###mh-autoload
54(defun mh-identity-make-menu () 55(defun mh-identity-make-menu ()
55 "Build the Identity menu. 56 "Build the Identity menu.
56This should be called any time `mh-identity-list' or `mh-auto-fields-list' 57This should be called any time `mh-identity-list' or
57change." 58`mh-auto-fields-list' change."
58 (easy-menu-define mh-identity-menu mh-letter-mode-map 59 (easy-menu-define mh-identity-menu mh-letter-mode-map
59 "MH-E identity menu" 60 "MH-E identity menu"
60 (append 61 (append
@@ -87,9 +88,9 @@ change."
87;;;###mh-autoload 88;;;###mh-autoload
88(defun mh-identity-list-set (symbol value) 89(defun mh-identity-list-set (symbol value)
89 "Update the `mh-identity-list' variable, and rebuild the menu. 90 "Update the `mh-identity-list' variable, and rebuild the menu.
90Sets the default for SYMBOL (for example, `mh-identity-list') to VALUE (as set 91Sets the default for SYMBOL (for example, `mh-identity-list') to
91in customization). This is called after 'customize is used to alter 92VALUE (as set in customization). This is called after 'customize
92`mh-identity-list'." 93is used to alter `mh-identity-list'."
93 (set-default symbol value) 94 (set-default symbol value)
94 (mh-identity-make-menu)) 95 (mh-identity-make-menu))
95 96
@@ -120,10 +121,10 @@ Return t if anything is deleted."
120 121
121(defun mh-identity-field-handler (field) 122(defun mh-identity-field-handler (field)
122 "Return the handler for header FIELD or nil if none set. 123 "Return the handler for header FIELD or nil if none set.
123The field name is downcased. If the FIELD begins with the character 124The field name is downcased. If the FIELD begins with the
124`:', then it must have a special handler defined in 125character \":\", then it must have a special handler defined in
125`mh-identity-handlers', else return an error since it is not a valid 126`mh-identity-handlers', else return an error since it is not a
126header field." 127valid header field."
127 (or (cdr (mh-assoc-ignore-case field mh-identity-handlers)) 128 (or (cdr (mh-assoc-ignore-case field mh-identity-handlers))
128 (and (eq (aref field 0) ?:) 129 (and (eq (aref field 0) ?:)
129 (error "Field %s - unknown mh-identity-handler" field)) 130 (error "Field %s - unknown mh-identity-handler" field))
@@ -169,8 +170,8 @@ See `mh-identity-list'."
169(defun mh-identity-handler-gpg-identity (field action &optional value) 170(defun mh-identity-handler-gpg-identity (field action &optional value)
170 "Process header FIELD \":pgg-default-user-id\". 171 "Process header FIELD \":pgg-default-user-id\".
171The ACTION is one of 'remove or 'add. If 'add, the VALUE is added. 172The ACTION is one of 'remove or 'add. If 'add, the VALUE is added.
172The buffer-local variable `mh-identity-pgg-default-user-id' is set to VALUE 173The buffer-local variable `mh-identity-pgg-default-user-id' is set to
173when action 'add is selected." 174VALUE when action 'add is selected."
174 (cond 175 (cond
175 ((or (equal action 'remove) 176 ((or (equal action 'remove)
176 (not value) 177 (not value)
@@ -182,7 +183,8 @@ when action 'add is selected."
182;;;###mh-autoload 183;;;###mh-autoload
183(defun mh-identity-handler-signature (field action &optional value) 184(defun mh-identity-handler-signature (field action &optional value)
184 "Process header FIELD \":signature\". 185 "Process header FIELD \":signature\".
185The ACTION is one of 'remove or 'add. If 'add, the VALUE is added." 186The ACTION is one of 'remove or 'add. If 'add, the VALUE is
187added."
186 (cond 188 (cond
187 ((equal action 'remove) 189 ((equal action 'remove)
188 (when (and (markerp mh-identity-signature-start) 190 (when (and (markerp mh-identity-signature-start)
@@ -212,7 +214,8 @@ The ACTION is one of 'remove or 'add. If 'add, the VALUE is added."
212;;;###mh-autoload 214;;;###mh-autoload
213(defun mh-identity-handler-attribution-verb (field action &optional value) 215(defun mh-identity-handler-attribution-verb (field action &optional value)
214 "Process header FIELD \":attribution-verb\". 216 "Process header FIELD \":attribution-verb\".
215The ACTION is one of 'remove or 'add. If 'add, the VALUE is added." 217The ACTION is one of 'remove or 'add. If 'add, the VALUE is
218added."
216 (when (and (markerp mh-identity-attribution-verb-start) 219 (when (and (markerp mh-identity-attribution-verb-start)
217 (markerp mh-identity-attribution-verb-end)) 220 (markerp mh-identity-attribution-verb-end))
218 (delete-region mh-identity-attribution-verb-start 221 (delete-region mh-identity-attribution-verb-start
@@ -241,9 +244,9 @@ If VALUE is nil, use `mh-extract-from-attribution-verb'."
241 244
242(defun mh-identity-handler-default (field action top &optional value) 245(defun mh-identity-handler-default (field action top &optional value)
243 "Process header FIELD. 246 "Process header FIELD.
244The ACTION is one of 'remove or 'add. If TOP is non-nil, add the field and its 247The ACTION is one of 'remove or 'add. If TOP is non-nil, add the
245VALUE at the top of the header, else add it at the bottom of the header. If 248field and its VALUE at the top of the header, else add it at the
246action is 'add, the VALUE is added." 249bottom of the header. If action is 'add, the VALUE is added."
247 (let ((field-colon (if (string-match "^.*:$" field) 250 (let ((field-colon (if (string-match "^.*:$" field)
248 field 251 field
249 (concat field ":")))) 252 (concat field ":"))))
@@ -269,15 +272,17 @@ action is 'add, the VALUE is added."
269;;;###mh-autoload 272;;;###mh-autoload
270(defun mh-identity-handler-top (field action &optional value) 273(defun mh-identity-handler-top (field action &optional value)
271 "Process header FIELD. 274 "Process header FIELD.
272The ACTION is one of 'remove or 'add. If 'add, the VALUE is added. 275The ACTION is one of 'remove or 'add. If 'add, the VALUE is
273If the field wasn't present, it is added to the top of the header." 276added. If the field wasn't present, it is added to the top of the
277header."
274 (mh-identity-handler-default field action t value)) 278 (mh-identity-handler-default field action t value))
275 279
276;;;###mh-autoload 280;;;###mh-autoload
277(defun mh-identity-handler-bottom (field action &optional value) 281(defun mh-identity-handler-bottom (field action &optional value)
278 "Process header FIELD. 282 "Process header FIELD.
279The ACTION is one of 'remove or 'add. If 'add, the VALUE is added. 283The ACTION is one of 'remove or 'add. If 'add, the VALUE is
280If the field wasn't present, it is added to the bottom of the header." 284added. If the field wasn't present, it is added to the bottom of
285the header."
281 (mh-identity-handler-default field action nil value)) 286 (mh-identity-handler-default field action nil value))
282 287
283(provide 'mh-identity) 288(provide 'mh-identity)
diff --git a/lisp/mh-e/mh-inc.el b/lisp/mh-e/mh-inc.el
index d5becd26ce4..51f84f7fb38 100644
--- a/lisp/mh-e/mh-inc.el
+++ b/lisp/mh-e/mh-inc.el
@@ -1,4 +1,4 @@
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, 2004 Free Software Foundation, Inc. 3;; Copyright (C) 2003, 2004 Free Software Foundation, Inc.
4 4
@@ -28,7 +28,7 @@
28 28
29;; Support for inc. In addition to reading from the system mailbox, inc can 29;; Support for inc. In addition to reading from the system mailbox, inc can
30;; also be used to incorporate mail from multiple spool files into separate 30;; also be used to incorporate mail from multiple spool files into separate
31;; folders. See `C-h v mh-inc-spool-list'. 31;; folders. See "C-h v mh-inc-spool-list".
32 32
33;;; Change Log: 33;;; Change Log:
34 34
diff --git a/lisp/mh-e/mh-index.el b/lisp/mh-e/mh-index.el
index e261b47b753..c8ec7fb399b 100644
--- a/lisp/mh-e/mh-index.el
+++ b/lisp/mh-e/mh-index.el
@@ -158,9 +158,10 @@
158 158
159(defun mh-index-execute (cmd &rest args) 159(defun mh-index-execute (cmd &rest args)
160 "Partial imitation of xargs. 160 "Partial imitation of xargs.
161The current buffer contains a list of strings, one on each line. The function 161The current buffer contains a list of strings, one on each line.
162will execute CMD with ARGS and pass the first `mh-index-max-cmdline-args' 162The function will execute CMD with ARGS and pass the first
163strings to it. This is repeated till all the strings have been used." 163`mh-index-max-cmdline-args' strings to it. This is repeated till
164all the strings have been used."
164 (goto-char (point-min)) 165 (goto-char (point-min))
165 (let ((current-buffer (current-buffer))) 166 (let ((current-buffer (current-buffer)))
166 (with-temp-buffer 167 (with-temp-buffer
@@ -183,12 +184,14 @@ strings to it. This is repeated till all the strings have been used."
183 184
184(defun mh-index-update-single-msg (msg checksum origin-map) 185(defun mh-index-update-single-msg (msg checksum origin-map)
185 "Update various maps for one message. 186 "Update various maps for one message.
186MSG is a index folder message, CHECKSUM its MD5 hash and ORIGIN-MAP, if 187MSG is a index folder message, CHECKSUM its MD5 hash and
187non-nil, a hashtable containing which maps each message in the index folder to 188ORIGIN-MAP, if non-nil, a hashtable containing which maps each
188the folder and message that it was copied from. The function updates the hash 189message in the index folder to the folder and message that it was
189tables `mh-index-msg-checksum-map' and `mh-index-checksum-origin-map'. 190copied from. The function updates the hash tables
190 191`mh-index-msg-checksum-map' and `mh-index-checksum-origin-map'.
191This function should only be called in the appropriate index folder buffer." 192
193This function should only be called in the appropriate index
194folder buffer."
192 (cond ((and origin-map (gethash checksum mh-index-checksum-origin-map)) 195 (cond ((and origin-map (gethash checksum mh-index-checksum-origin-map))
193 (let* ((intermediate (gethash msg origin-map)) 196 (let* ((intermediate (gethash msg origin-map))
194 (ofolder (car intermediate)) 197 (ofolder (car intermediate))
@@ -208,10 +211,11 @@ This function should only be called in the appropriate index folder buffer."
208;;;###mh-autoload 211;;;###mh-autoload
209(defun mh-index-update-maps (folder &optional origin-map) 212(defun mh-index-update-maps (folder &optional origin-map)
210 "Annotate all as yet unannotated messages in FOLDER with their MD5 hash. 213 "Annotate all as yet unannotated messages in FOLDER with their MD5 hash.
211As a side effect msg -> checksum map is updated. Optional argument ORIGIN-MAP 214As a side effect msg -> checksum map is updated. Optional
212is a hashtable which maps each message in the index folder to the original 215argument ORIGIN-MAP is a hashtable which maps each message in the
213folder and message from whence it was copied. If present the 216index folder to the original folder and message from whence it
214checksum -> (origin-folder, origin-index) map is updated too." 217was copied. If present the checksum -> (origin-folder,
218origin-index) map is updated too."
215 (clrhash mh-index-msg-checksum-map) 219 (clrhash mh-index-msg-checksum-map)
216 (save-excursion 220 (save-excursion
217 ;; Clear temp buffer 221 ;; Clear temp buffer
@@ -266,8 +270,9 @@ checksum -> (origin-folder, origin-index) map is updated too."
266 270
267(defun mh-unpropagated-sequences () 271(defun mh-unpropagated-sequences ()
268 "Return a list of sequences that aren't propagated to the source folders. 272 "Return a list of sequences that aren't propagated to the source folders.
269It is just the sequences in the variable `mh-unpropagated-sequences' in 273It is just the sequences in the variable
270addition to the Previous-Sequence (see mh-profile 5)." 274`mh-unpropagated-sequences' in addition to the
275Previous-Sequence (see mh-profile 5)."
271 (if mh-previous-seq 276 (if mh-previous-seq
272 (cons mh-previous-seq mh-unpropagated-sequences) 277 (cons mh-previous-seq mh-unpropagated-sequences)
273 mh-unpropagated-sequences)) 278 mh-unpropagated-sequences))
@@ -275,8 +280,8 @@ addition to the Previous-Sequence (see mh-profile 5)."
275;;;###mh-autoload 280;;;###mh-autoload
276(defun mh-create-sequence-map (seq-list) 281(defun mh-create-sequence-map (seq-list)
277 "Return a map from msg number to list of sequences in which it is present. 282 "Return a map from msg number to list of sequences in which it is present.
278SEQ-LIST is an assoc list whose keys are sequence names and whose cdr is the 283SEQ-LIST is an assoc list whose keys are sequence names and whose
279list of messages in that sequence." 284cdr is the list of messages in that sequence."
280 (loop with map = (make-hash-table) 285 (loop with map = (make-hash-table)
281 for seq in seq-list 286 for seq in seq-list
282 when (and (not (memq (car seq) (mh-unpropagated-sequences))) 287 when (and (not (memq (car seq) (mh-unpropagated-sequences)))
@@ -316,10 +321,11 @@ list of messages in that sequence."
316 321
317(defun mh-index-generate-pretty-name (string) 322(defun mh-index-generate-pretty-name (string)
318 "Given STRING generate a name which is suitable for use as a folder name. 323 "Given STRING generate a name which is suitable for use as a folder name.
319White space from the beginning and end are removed. All spaces in the name are 324White space from the beginning and end are removed. All spaces in
320replaced with underscores and all / are replaced with $. If STRING is longer 325the name are replaced with underscores and all / are replaced
321than 20 it is truncated too. STRING could be a list of strings in which case 326with $. If STRING is longer than 20 it is truncated too. STRING
322they are concatenated to construct the base name." 327could be a list of strings in which case they are concatenated to
328construct the base name."
323 (with-temp-buffer 329 (with-temp-buffer
324 (if (stringp string) 330 (if (stringp string)
325 (insert string) 331 (insert string)
@@ -352,60 +358,66 @@ they are concatenated to construct the base name."
352(defun* mh-index-search (redo-search-flag folder search-regexp 358(defun* mh-index-search (redo-search-flag folder search-regexp
353 &optional window-config) 359 &optional window-config)
354 "Perform an indexed search in an MH mail folder. 360 "Perform an indexed search in an MH mail folder.
361
355Use a prefix argument to repeat the search. 362Use a prefix argument to repeat the search.
356 363
357Unlike regular searches, the prompt for the folder to search can be `all' to 364Unlike regular searches, the prompt for the folder to search can be
358search all folders; in addition, the search works recursively on the listed 365\"all\" to search all folders; in addition, the search works recursively
359folder. The search criteria are entered in an MH-Pick buffer as described in 366on the listed folder. The search criteria are entered in an MH-Pick
360`mh-search-folder'. 367buffer as described in `mh-search-folder'.
361 368
362To perform the search, type \\<mh-pick-mode-map>\\[mh-do-search]. Another 369To perform the search, type \\<mh-pick-mode-map>\\[mh-do-search].
363difference from the regular searches is that because the search operates on 370Another difference from the regular searches is that because the
364more than one folder, the messages that are found are put in a temporary 371search operates on more than one folder, the messages that are found
365sub-folder of `+mhe-index' and are displayed in an MH-Folder buffer. This 372are put in a temporary sub-folder of \"+mhe-index\" and are displayed in
366buffer is special because it displays messages from multiple folders; each set 373an MH-Folder buffer. This buffer is special because it displays
367of messages from a given folder has a heading with the folder name. 374messages from multiple folders; each set of messages from a given
368 375folder has a heading with the folder name.
369In addition, the \\<mh-folder-mode-map>\\[mh-index-visit-folder] command can 376
370be used to visit the folder of the message at point. Initially, only the 377In addition, the \\<mh-folder-mode-map>\\[mh-index-visit-folder]
371messages that matched the search criteria are displayed in the folder. While 378command can be used to visit the folder of the message at point.
372the temporary buffer has its own set of message numbers, the actual messages 379Initially, only the messages that matched the search criteria are
373numbers are shown in the visited folder. Thus, the \\[mh-index-visit-folder] 380displayed in the folder. While the temporary buffer has its own set of
374command is useful to find the actual message number of an interesting message, 381message numbers, the actual messages numbers are shown in the visited
375or to view surrounding messages with the \\[mh-rescan-folder] command. 382folder. Thus, the \\[mh-index-visit-folder] command is useful to find
376 383the actual message number of an interesting message, or to view
377Because this folder is temporary, you'll probably get in the habit of killing 384surrounding messages with the \\[mh-rescan-folder] command.
378it when you're done with \\[mh-kill-folder]. 385
379 386Because this folder is temporary, you'll probably get in the habit of
380If you have run the \\[mh-search-folder] command, but change your mind while 387killing it when you're done with \\[mh-kill-folder].
381entering the search criteria and actually want to run an indexed search, then 388
382you can use the \\<mh-pick-mode-map>\\[mh-index-do-search] command in the 389If you have run the \\[mh-search-folder] command, but change your mind
383MH-Pick buffer. 390while entering the search criteria and actually want to run an indexed
384 391search, then you can use the
385The \\<mh-folder-mode-map>\\[mh-index-search] command runs the command defined 392\\<mh-pick-mode-map>\\[mh-index-do-search] command in the MH-Pick
386by the `mh-index-program' option. The default value is \"Auto-detect\" which 393buffer.
387means that MH-E will automatically choose one of \"swish++\", \"swish-e\", 394
388\"mairix\", \"namazu\", \"pick\" and \"grep\" in that order. If, for example, 395The \\<mh-folder-mode-map>\\[mh-index-search] command runs the command
389you have both \"swish++\" and \"mairix\" installed and you want to use 396defined by the `mh-index-program' option. The default value is
390\"mairix\", then you can set this option to \"mairix\". 397\"Auto-detect\" which means that MH-E will automatically choose one of
398\"swish++\", \"swish-e\", \"mairix\", \"namazu\", \"pick\" and
399\"grep\" in that order. If, for example, you have both \"swish++\" and
400\"mairix\" installed and you want to use \"mairix\", then you can set
401this option to \"mairix\".
391 402
392 *NOTE* 403 *NOTE*
393 404
394 The \"pick\" and \"grep\" commands do not perform a recursive search on 405 The \"pick\" and \"grep\" commands do not perform a
395 the given folder. 406 recursive search on the given folder.
396 407
397This command uses an \"X-MHE-Checksum:\" header field to cache the MD5 408This command uses an \"X-MHE-Checksum:\" header field to cache
398checksum of a message. This means that if an incoming message already contains 409the MD5 checksum of a message. This means that if an incoming
399an \"X-MHE-Checksum:\" field, that message might not be found by this command. 410message already contains an \"X-MHE-Checksum:\" field, that
400The following \"procmail\" recipe avoids this problem by renaming the existing 411message might not be found by this command. The following
412\"procmail\" recipe avoids this problem by renaming the existing
401header field: 413header field:
402 414
403 :0 wf 415 :0 wf
404 | formail -R \"X-MHE-Checksum\" \"X-Old-MHE-Checksum\" 416 | formail -R \"X-MHE-Checksum\" \"X-Old-MHE-Checksum\"
405 417
406The documentation for the following commands describe how to set up the 418The documentation for the following commands describe how to set
407various indexing programs to use with MH-E. The \"pick\" and \"grep\" commands 419up the various indexing programs to use with MH-E. The \"pick\"
408do not require additional configuration. 420and \"grep\" commands do not require additional configuration.
409 421
410 - `mh-swish++-execute-search' 422 - `mh-swish++-execute-search'
411 - `mh-swish-execute-search' 423 - `mh-swish-execute-search'
@@ -414,12 +426,14 @@ do not require additional configuration.
414 - `mh-pick-execute-search' 426 - `mh-pick-execute-search'
415 - `mh-grep-execute-search' 427 - `mh-grep-execute-search'
416 428
417In a program, if REDO-SEARCH-FLAG is non-nil and the current folder buffer was 429In a program, if REDO-SEARCH-FLAG is non-nil and the current
418generated by a index search, then the search is repeated. Otherwise, FOLDER is 430folder buffer was generated by a index search, then the search is
419searched with SEARCH-REGEXP and the results are presented in an MH-E folder. 431repeated. Otherwise, FOLDER is searched with SEARCH-REGEXP and
420If FOLDER is \"+\" then mail in all folders are searched. Optional argument 432the results are presented in an MH-E folder. If FOLDER is \"+\"
421WINDOW-CONFIG stores the window configuration that will be restored after the 433then mail in all folders are searched. Optional argument
422user quits the folder containing the index search results." 434WINDOW-CONFIG stores the window configuration that will be
435restored after the user quits the folder containing the index
436search results."
423 (interactive 437 (interactive
424 (list current-prefix-arg 438 (list current-prefix-arg
425 (progn 439 (progn
@@ -540,7 +554,7 @@ user quits the folder containing the index search results."
540 "Write index data to file." 554 "Write index data to file."
541 (ignore-errors 555 (ignore-errors
542 (unless (eq major-mode 'mh-folder-mode) 556 (unless (eq major-mode 'mh-folder-mode)
543 (error "Can't be called from folder in `%s'" major-mode)) 557 (error "Can't be called from folder in \"%s\"" major-mode))
544 (let ((data mh-index-data) 558 (let ((data mh-index-data)
545 (msg-checksum-map mh-index-msg-checksum-map) 559 (msg-checksum-map mh-index-msg-checksum-map)
546 (checksum-origin-map mh-index-checksum-origin-map) 560 (checksum-origin-map mh-index-checksum-origin-map)
@@ -562,7 +576,7 @@ user quits the folder containing the index search results."
562 "Read index data from file." 576 "Read index data from file."
563 (ignore-errors 577 (ignore-errors
564 (unless (eq major-mode 'mh-folder-mode) 578 (unless (eq major-mode 'mh-folder-mode)
565 (error "Can't be called from folder in `%s'" major-mode)) 579 (error "Can't be called from folder in \"%s\"" major-mode))
566 (let ((infile (concat buffer-file-name mh-index-data-file)) 580 (let ((infile (concat buffer-file-name mh-index-data-file))
567 t1 t2 t3 t4 t5) 581 t1 t2 t3 t4 t5)
568 (with-temp-buffer 582 (with-temp-buffer
@@ -585,7 +599,8 @@ user quits the folder containing the index search results."
585 599
586(defun mh-index-write-hashtable (table proc) 600(defun mh-index-write-hashtable (table proc)
587 "Write TABLE to `current-buffer'. 601 "Write TABLE to `current-buffer'.
588PROC is used to serialize the values corresponding to the hash table keys." 602PROC is used to serialize the values corresponding to the hash
603table keys."
589 (pp (loop for x being the hash-keys of table 604 (pp (loop for x being the hash-keys of table
590 collect (cons x (funcall proc (gethash x table)))) 605 collect (cons x (funcall proc (gethash x table))))
591 (current-buffer)) 606 (current-buffer))
@@ -619,8 +634,9 @@ PROC is used to convert the value to actual data."
619;;;###mh-autoload 634;;;###mh-autoload
620(defun mh-index-parse-search-regexp (input-string) 635(defun mh-index-parse-search-regexp (input-string)
621 "Construct parse tree for INPUT-STRING. 636 "Construct parse tree for INPUT-STRING.
622All occurrences of &, |, ! and ~ in INPUT-STRING are replaced by AND, OR and 637All occurrences of &, |, ! and ~ in INPUT-STRING are replaced by
623NOT as appropriate. Then the resulting string is parsed." 638AND, OR and NOT as appropriate. Then the resulting string is
639parsed."
624 (let (input) 640 (let (input)
625 (with-temp-buffer 641 (with-temp-buffer
626 (insert input-string) 642 (insert input-string)
@@ -720,9 +736,10 @@ NOT as appropriate. Then the resulting string is parsed."
720;;;###mh-autoload 736;;;###mh-autoload
721(defun mh-index-next-folder (&optional backward-flag) 737(defun mh-index-next-folder (&optional backward-flag)
722 "Jump to the next folder marker. 738 "Jump to the next folder marker.
723The function is only applicable to folders displaying index search results. 739The function is only applicable to folders displaying index search
724With non-nil optional argument BACKWARD-FLAG, jump to the previous group of 740results.
725results." 741With non-nil optional argument BACKWARD-FLAG, jump to the previous
742group of results."
726 (interactive "P") 743 (interactive "P")
727 (if (null mh-index-data) 744 (if (null mh-index-data)
728 (message "Only applicable in an MH-E index search buffer") 745 (message "Only applicable in an MH-E index search buffer")
@@ -764,12 +781,12 @@ results."
764(defun mh-index-new-folder (name search-regexp) 781(defun mh-index-new-folder (name search-regexp)
765 "Return a folder name based on NAME for search results of SEARCH-REGEXP. 782 "Return a folder name based on NAME for search results of SEARCH-REGEXP.
766 783
767If folder NAME already exists and was generated for the same SEARCH-REGEXP 784If folder NAME already exists and was generated for the same
768then it is reused. 785SEARCH-REGEXP then it is reused.
769 786
770Otherwise if the folder NAME was generated from a different search then check 787Otherwise if the folder NAME was generated from a different
771if NAME<2> can be used. Otherwise try NAME<3>. This is repeated till we find a 788search then check if NAME<2> can be used. Otherwise try NAME<3>.
772new folder name. 789This is repeated till we find a new folder name.
773 790
774If the folder returned doesn't exist then it is created." 791If the folder returned doesn't exist then it is created."
775 (unless (mh-folder-name-p name) 792 (unless (mh-folder-name-p name)
@@ -794,7 +811,8 @@ If the folder returned doesn't exist then it is created."
794 811
795(defun mh-index-folder-search-regexp (folder) 812(defun mh-index-folder-search-regexp (folder)
796 "If FOLDER was created by a index search, return the search regexp. 813 "If FOLDER was created by a index search, return the search regexp.
797Return nil if FOLDER doesn't exist or the .mhe_index file is garbled." 814Return nil if FOLDER doesn't exist or the .mhe_index file is
815garbled."
798 (ignore-errors 816 (ignore-errors
799 (with-temp-buffer 817 (with-temp-buffer
800 (insert-file-contents 818 (insert-file-contents
@@ -844,8 +862,8 @@ Return nil if FOLDER doesn't exist or the .mhe_index file is garbled."
844;;;###mh-autoload 862;;;###mh-autoload
845(defun mh-index-group-by-folder () 863(defun mh-index-group-by-folder ()
846 "Partition the messages based on source folder. 864 "Partition the messages based on source folder.
847Returns an alist with the the folder names in the car and the cdr being the 865Returns an alist with the the folder names in the car and the cdr
848list of messages originally from that folder." 866being the list of messages originally from that folder."
849 (save-excursion 867 (save-excursion
850 (goto-char (point-min)) 868 (goto-char (point-min))
851 (let ((result-table (make-hash-table :test #'equal))) 869 (let ((result-table (make-hash-table :test #'equal)))
@@ -909,9 +927,9 @@ list of messages originally from that folder."
909 927
910(defun mh-index-matching-source-msgs (msgs &optional delete-from-index-data) 928(defun mh-index-matching-source-msgs (msgs &optional delete-from-index-data)
911 "Return a table of original messages and folders for messages in MSGS. 929 "Return a table of original messages and folders for messages in MSGS.
912If optional argument DELETE-FROM-INDEX-DATA is non-nil, then each of the 930If optional argument DELETE-FROM-INDEX-DATA is non-nil, then each
913messages, whose counter-part is found in some source folder, is removed from 931of the messages, whose counter-part is found in some source
914`mh-index-data'." 932folder, is removed from `mh-index-data'."
915 (let ((table (make-hash-table :test #'equal))) 933 (let ((table (make-hash-table :test #'equal)))
916 (dolist (msg msgs) 934 (dolist (msg msgs)
917 (let* ((checksum (gethash msg mh-index-msg-checksum-map)) 935 (let* ((checksum (gethash msg mh-index-msg-checksum-map))
@@ -926,9 +944,10 @@ messages, whose counter-part is found in some source folder, is removed from
926;;;###mh-autoload 944;;;###mh-autoload
927(defun mh-index-execute-commands () 945(defun mh-index-execute-commands ()
928 "Delete/refile the actual messages. 946 "Delete/refile the actual messages.
929The copies in the searched folder are then deleted/refiled to get the desired 947The copies in the searched folder are then deleted/refiled to get
930result. Before deleting the messages we make sure that the message being 948the desired result. Before deleting the messages we make sure
931deleted is identical to the one that the user has marked in the index buffer." 949that the message being deleted is identical to the one that the
950user has marked in the index buffer."
932 (save-excursion 951 (save-excursion
933 (let ((folders ()) 952 (let ((folders ())
934 (mh-speed-flists-inhibit-flag t)) 953 (mh-speed-flists-inhibit-flag t))
@@ -967,8 +986,8 @@ deleted is identical to the one that the user has marked in the index buffer."
967;;;###mh-autoload 986;;;###mh-autoload
968(defun mh-index-add-to-sequence (seq msgs) 987(defun mh-index-add-to-sequence (seq msgs)
969 "Add to SEQ the messages in the list MSGS. 988 "Add to SEQ the messages in the list MSGS.
970This function updates the source folder sequences. Also makes an attempt to 989This function updates the source folder sequences. Also makes an
971update the source folder buffer if we have it open." 990attempt to update the source folder buffer if we have it open."
972 ;; Don't need to do anything for cur 991 ;; Don't need to do anything for cur
973 (save-excursion 992 (save-excursion
974 (when (and (not (memq seq (mh-unpropagated-sequences))) 993 (when (and (not (memq seq (mh-unpropagated-sequences)))
@@ -993,8 +1012,8 @@ update the source folder buffer if we have it open."
993;;;###mh-autoload 1012;;;###mh-autoload
994(defun mh-index-delete-from-sequence (seq msgs) 1013(defun mh-index-delete-from-sequence (seq msgs)
995 "Delete from SEQ the messages in MSGS. 1014 "Delete from SEQ the messages in MSGS.
996This function updates the source folder sequences. Also makes an attempt to 1015This function updates the source folder sequences. Also makes an
997update the source folder buffer if present." 1016attempt to update the source folder buffer if present."
998 (save-excursion 1017 (save-excursion
999 (when (and (not (memq seq (mh-unpropagated-sequences))) 1018 (when (and (not (memq seq (mh-unpropagated-sequences)))
1000 (mh-valid-seq-p seq)) 1019 (mh-valid-seq-p seq))
@@ -1025,12 +1044,12 @@ update the source folder buffer if present."
1025(defun mh-pick-execute-search (folder-path search-regexp) 1044(defun mh-pick-execute-search (folder-path search-regexp)
1026 "Execute pick. 1045 "Execute pick.
1027 1046
1028Unlike the other index search programs \"pick\" only searches messages present 1047Unlike the other index search programs \"pick\" only searches
1029in the folder itself and does not descend into any sub-folders that may be 1048messages present in the folder itself and does not descend into
1030present. 1049any sub-folders that may be present.
1031 1050
1032In a program, FOLDER-PATH is the directory in which SEARCH-REGEXP is used 1051In a program, FOLDER-PATH is the directory in which SEARCH-REGEXP
1033to search." 1052is used to search."
1034 (set-buffer (get-buffer-create mh-index-temp-buffer)) 1053 (set-buffer (get-buffer-create mh-index-temp-buffer))
1035 (erase-buffer) 1054 (erase-buffer)
1036 (setq mh-index-pick-folder 1055 (setq mh-index-pick-folder
@@ -1061,12 +1080,12 @@ to search."
1061(defun mh-grep-execute-search (folder-path search-regexp) 1080(defun mh-grep-execute-search (folder-path search-regexp)
1062 "Execute grep and read the results. 1081 "Execute grep and read the results.
1063 1082
1064Unlike the other index search programs \"grep\" only searches messages present 1083Unlike the other index search programs \"grep\" only searches
1065in the folder itself and does not descend into any sub-folders that may be 1084messages present in the folder itself and does not descend into
1066present. 1085any sub-folders that may be present.
1067 1086
1068In a program, FOLDER-PATH is the directory in which SEARCH-REGEXP is used 1087In a program, FOLDER-PATH is the directory in which SEARCH-REGEXP
1069to search." 1088is used to search."
1070 (set-buffer (get-buffer-create mh-index-temp-buffer)) 1089 (set-buffer (get-buffer-create mh-index-temp-buffer))
1071 (erase-buffer) 1090 (erase-buffer)
1072 (call-process mh-grep-binary nil '(t nil) nil 1091 (call-process mh-grep-binary nil '(t nil) nil
@@ -1075,9 +1094,9 @@ to search."
1075 1094
1076(defun mh-grep-next-result () 1095(defun mh-grep-next-result ()
1077 "Read the next result. 1096 "Read the next result.
1078Parse it and return the message folder, message index and the match. If no 1097Parse it and return the message folder, message index and the
1079other matches left then return nil. If the current record is invalid return 1098match. If no other matches left then return nil. If the current
1080'error." 1099record is invalid return 'error."
1081 (prog1 1100 (prog1
1082 (block nil 1101 (block nil
1083 (when (eobp) 1102 (when (eobp)
@@ -1118,11 +1137,12 @@ other matches left then return nil. If the current record is invalid return
1118(defun mh-mairix-execute-search (folder-path search-regexp-list) 1137(defun mh-mairix-execute-search (folder-path search-regexp-list)
1119 "Execute mairix and read the results. 1138 "Execute mairix and read the results.
1120 1139
1121In the examples below, replace \"/home/user/Mail\" with the path to your MH 1140In the examples below, replace \"/home/user/Mail\" with the path
1122directory. 1141to your MH directory.
1123 1142
1124First create the directory \"/home/user/Mail/.mairix\". Then create the file 1143First create the directory \"/home/user/Mail/.mairix\". Then
1125\"/home/user/Mail/.mairix/config\" with the following contents: 1144create the file \"/home/user/Mail/.mairix/config\" with the
1145following contents:
1126 1146
1127 base=/home/user/Mail 1147 base=/home/user/Mail
1128 1148
@@ -1133,13 +1153,13 @@ First create the directory \"/home/user/Mail/.mairix\". Then create the file
1133 vfolder_format=raw 1153 vfolder_format=raw
1134 database=/home/user/Mail/mairix/database 1154 database=/home/user/Mail/mairix/database
1135 1155
1136Use the following command line to generate the mairix index. Run this daily 1156Use the following command line to generate the mairix index. Run
1137from cron: 1157this daily from cron:
1138 1158
1139 mairix -f /home/user/Mail/.mairix/config 1159 mairix -f /home/user/Mail/.mairix/config
1140 1160
1141In a program, FOLDER-PATH is the directory in which SEARCH-REGEXP-LIST is used 1161In a program, FOLDER-PATH is the directory in which
1142to search." 1162SEARCH-REGEXP-LIST is used to search."
1143 (set-buffer (get-buffer-create mh-index-temp-buffer)) 1163 (set-buffer (get-buffer-create mh-index-temp-buffer))
1144 (erase-buffer) 1164 (erase-buffer)
1145 (unless mh-mairix-binary 1165 (unless mh-mairix-binary
@@ -1258,9 +1278,10 @@ REGEXP-LIST is an alist of fields and values."
1258 1278
1259(defun mh-flists-execute (&rest args) 1279(defun mh-flists-execute (&rest args)
1260 "Execute flists. 1280 "Execute flists.
1261Search for messages belonging to `mh-flists-sequence' in the folders 1281Search for messages belonging to `mh-flists-sequence' in the
1262specified by `mh-flists-search-folders'. If `mh-recursive-folders-flag' is t, 1282folders specified by `mh-flists-search-folders'. If
1263then the folders are searched recursively. All parameters ARGS are ignored." 1283`mh-recursive-folders-flag' is t, then the folders are searched
1284recursively. All parameters ARGS are ignored."
1264 (set-buffer (get-buffer-create mh-index-temp-buffer)) 1285 (set-buffer (get-buffer-create mh-index-temp-buffer))
1265 (erase-buffer) 1286 (erase-buffer)
1266 (unless (executable-find "sh") 1287 (unless (executable-find "sh")
@@ -1286,8 +1307,9 @@ then the folders are searched recursively. All parameters ARGS are ignored."
1286(defun mh-index-sequenced-messages (folders sequence) 1307(defun mh-index-sequenced-messages (folders sequence)
1287 "Display messages from FOLDERS in SEQUENCE. 1308 "Display messages from FOLDERS in SEQUENCE.
1288All messages in the sequence you provide from the folders in 1309All messages in the sequence you provide from the folders in
1289`mh-new-messages-folders' are listed. With a prefix argument, enter a 1310`mh-new-messages-folders' are listed. With a prefix argument,
1290space-separated list of folders, or nothing to search all folders." 1311enter a space-separated list of folders, or nothing to search all
1312folders."
1291 (interactive 1313 (interactive
1292 (list (if current-prefix-arg 1314 (list (if current-prefix-arg
1293 (split-string (read-string "Search folder(s) (default all): ")) 1315 (split-string (read-string "Search folder(s) (default all): "))
@@ -1330,13 +1352,14 @@ space-separated list of folders, or nothing to search all folders."
1330(defun mh-index-new-messages (folders) 1352(defun mh-index-new-messages (folders)
1331 "Display unseen messages. 1353 "Display unseen messages.
1332 1354
1333If you use a program such as `procmail' to use `rcvstore' to file your 1355If you use a program such as \"procmail\" to use \"rcvstore\" to file
1334incoming mail automatically, you can display new, unseen, messages using this 1356your incoming mail automatically, you can display new, unseen,
1335command. All messages in the `unseen' sequence from the folders in 1357messages using this command. All messages in the \"unseen\"
1336`mh-new-messages-folders' are listed. 1358sequence from the folders in `mh-new-messages-folders' are
1359listed.
1337 1360
1338With a prefix argument, enter a space-separated list of FOLDERS, or nothing to 1361With a prefix argument, enter a space-separated list of FOLDERS,
1339search all folders." 1362or nothing to search all folders."
1340 (interactive 1363 (interactive
1341 (list (if current-prefix-arg 1364 (list (if current-prefix-arg
1342 (split-string (read-string "Search folder(s) (default all): ")) 1365 (split-string (read-string "Search folder(s) (default all): "))
@@ -1347,11 +1370,11 @@ search all folders."
1347(defun mh-index-ticked-messages (folders) 1370(defun mh-index-ticked-messages (folders)
1348 "Display ticked messages. 1371 "Display ticked messages.
1349 1372
1350All messages in `mh-tick-seq' from the folders in `mh-ticked-messages-folders' 1373All messages in `mh-tick-seq' from the folders in
1351are listed. 1374`mh-ticked-messages-folders' are listed.
1352 1375
1353With a prefix argument, enter a space-separated list of FOLDERS, or nothing to 1376With a prefix argument, enter a space-separated list of FOLDERS,
1354search all folders." 1377or nothing to search all folders."
1355 (interactive 1378 (interactive
1356 (list (if current-prefix-arg 1379 (list (if current-prefix-arg
1357 (split-string (read-string "Search folder(s) (default all): ")) 1380 (split-string (read-string "Search folder(s) (default all): "))
@@ -1370,11 +1393,12 @@ search all folders."
1370(defun mh-swish-execute-search (folder-path search-regexp) 1393(defun mh-swish-execute-search (folder-path search-regexp)
1371 "Execute swish-e and read the results. 1394 "Execute swish-e and read the results.
1372 1395
1373In the examples below, replace \"/home/user/Mail\" with the path to your 1396In the examples below, replace \"/home/user/Mail\" with the path
1374MH directory. 1397to your MH directory.
1375 1398
1376First create the directory \"/home/user/Mail/.swish\". Then create the file 1399First create the directory \"/home/user/Mail/.swish\". Then
1377\"/home/user/Mail/.swish/config\" with the following contents: 1400create the file \"/home/user/Mail/.swish/config\" with the
1401following contents:
1378 1402
1379 DefaultContents TXT* 1403 DefaultContents TXT*
1380 IndexDir /home/user/Mail 1404 IndexDir /home/user/Mail
@@ -1397,22 +1421,22 @@ First create the directory \"/home/user/Mail/.swish\". Then create the file
1397 FileRules pathname contains /home/user/Mail/.swish 1421 FileRules pathname contains /home/user/Mail/.swish
1398 FileRules pathname contains /home/user/Mail/mhe-index 1422 FileRules pathname contains /home/user/Mail/mhe-index
1399 1423
1400This configuration does not index the folders that hold the results of your 1424This configuration does not index the folders that hold the
1401searches in \"+mhe-index\" since they tend to be ephemeral and the original 1425results of your searches in \"+mhe-index\" since they tend to be
1402messages are indexed anyway. 1426ephemeral and the original messages are indexed anyway.
1403 1427
1404If there are any directories you would like to ignore, append lines like the 1428If there are any directories you would like to ignore, append
1405following to \"config\": 1429lines like the following to \"config\":
1406 1430
1407 FileRules pathname contains /home/user/Mail/scripts 1431 FileRules pathname contains /home/user/Mail/scripts
1408 1432
1409Use the following command line to generate the swish index. Run this daily 1433Use the following command line to generate the swish index. Run
1410from cron: 1434this daily from cron:
1411 1435
1412 swish-e -c /home/user/Mail/.swish/config 1436 swish-e -c /home/user/Mail/.swish/config
1413 1437
1414In a program, FOLDER-PATH is the directory in which SEARCH-REGEXP is used to 1438In a program, FOLDER-PATH is the directory in which SEARCH-REGEXP
1415search." 1439is used to search."
1416 (set-buffer (get-buffer-create mh-index-temp-buffer)) 1440 (set-buffer (get-buffer-create mh-index-temp-buffer))
1417 (erase-buffer) 1441 (erase-buffer)
1418 (unless mh-swish-binary 1442 (unless mh-swish-binary
@@ -1472,11 +1496,12 @@ search."
1472(defun mh-swish++-execute-search (folder-path search-regexp) 1496(defun mh-swish++-execute-search (folder-path search-regexp)
1473 "Execute swish++ and read the results. 1497 "Execute swish++ and read the results.
1474 1498
1475In the examples below, replace \"/home/user/Mail\" with the path to your MH 1499In the examples below, replace \"/home/user/Mail\" with the path to
1476directory. 1500your MH directory.
1477 1501
1478First create the directory \"/home/user/Mail/.swish++\". Then create the file 1502First create the directory \"/home/user/Mail/.swish++\". Then create
1479\"/home/user/Mail/.swish++/swish++.conf\" with the following contents: 1503the file \"/home/user/Mail/.swish++/swish++.conf\" with the following
1504contents:
1480 1505
1481 IncludeMeta Bcc Cc Comments Content-Description From Keywords 1506 IncludeMeta Bcc Cc Comments Content-Description From Keywords
1482 IncludeMeta Newsgroups Resent-To Subject To 1507 IncludeMeta Newsgroups Resent-To Subject To
@@ -1484,23 +1509,23 @@ First create the directory \"/home/user/Mail/.swish++\". Then create the file
1484 IncludeFile Mail * 1509 IncludeFile Mail *
1485 IndexFile /home/user/Mail/.swish++/swish++.index 1510 IndexFile /home/user/Mail/.swish++/swish++.index
1486 1511
1487Use the following command line to generate the swish index. Run this daily 1512Use the following command line to generate the swish index. Run
1488from cron: 1513this daily from cron:
1489 1514
1490 find /home/user/Mail -path /home/user/Mail/mhe-index -prune \\ 1515 find /home/user/Mail -path /home/user/Mail/mhe-index -prune \\
1491 -o -path /home/user/Mail/.swish++ -prune \\ 1516 -o -path /home/user/Mail/.swish++ -prune \\
1492 -o -name \"[0-9]*\" -print \\ 1517 -o -name \"[0-9]*\" -print \\
1493 | index -c /home/user/Mail/.swish++/swish++.conf - 1518 | index -c /home/user/Mail/.swish++/swish++.conf -
1494 1519
1495This command does not index the folders that hold the results of your searches 1520This command does not index the folders that hold the results of your
1496in \"+mhe-index\" since they tend to be ephemeral and the original messages 1521searches in \"+mhe-index\" since they tend to be ephemeral and the
1497are indexed anyway. 1522original messages are indexed anyway.
1498 1523
1499On some systems (Debian GNU/Linux, for example), use \"index++\" instead of 1524On some systems (Debian GNU/Linux, for example), use \"index++\"
1500\"index\". 1525instead of \"index\".
1501 1526
1502In a program, FOLDER-PATH is the directory in which SEARCH-REGEXP is used to 1527In a program, FOLDER-PATH is the directory in which SEARCH-REGEXP is
1503search." 1528used to search."
1504 (set-buffer (get-buffer-create mh-index-temp-buffer)) 1529 (set-buffer (get-buffer-create mh-index-temp-buffer))
1505 (erase-buffer) 1530 (erase-buffer)
1506 (unless mh-swish++-binary 1531 (unless mh-swish++-binary
@@ -1554,29 +1579,30 @@ REGEXP-LIST is an alist of fields and values."
1554(defun mh-namazu-execute-search (folder-path search-regexp) 1579(defun mh-namazu-execute-search (folder-path search-regexp)
1555 "Execute namazu and read the results. 1580 "Execute namazu and read the results.
1556 1581
1557In the examples below, replace \"/home/user/Mail\" with the path to your MH 1582In the examples below, replace \"/home/user/Mail\" with the path to
1558directory. 1583your MH directory.
1559 1584
1560First create the directory \"/home/user/Mail/.namazu\". Then create the file 1585First create the directory \"/home/user/Mail/.namazu\". Then create
1561\"/home/user/Mail/.namazu/mknmzrc\" with the following contents: 1586the file \"/home/user/Mail/.namazu/mknmzrc\" with the following
1587contents:
1562 1588
1563 package conf; # Don't remove this line! 1589 package conf; # Don't remove this line!
1564 $ADDRESS = 'user@localhost'; 1590 $ADDRESS = 'user@localhost';
1565 $ALLOW_FILE = \"[0-9]*\"; 1591 $ALLOW_FILE = \"[0-9]*\";
1566 $EXCLUDE_PATH = \"^/home/user/Mail/(mhe-index|spam)\"; 1592 $EXCLUDE_PATH = \"^/home/user/Mail/(mhe-index|spam)\";
1567 1593
1568This configuration does not index the folders that hold the results of your 1594This configuration does not index the folders that hold the results of
1569searches in \"+mhe-index\" since they tend to be ephemeral and the original 1595your searches in \"+mhe-index\" since they tend to be ephemeral and
1570messages are indexed anyway. 1596the original messages are indexed anyway.
1571 1597
1572Use the following command line to generate the namazu index. Run this daily 1598Use the following command line to generate the namazu index. Run this
1573from cron: 1599daily from cron:
1574 1600
1575 mknmz -f /home/user/Mail/.namazu/mknmzrc -O /home/user/Mail/.namazu \\ 1601 mknmz -f /home/user/Mail/.namazu/mknmzrc -O /home/user/Mail/.namazu \\
1576 /home/user/Mail 1602 /home/user/Mail
1577 1603
1578In a program, FOLDER-PATH is the directory in which SEARCH-REGEXP is used to 1604In a program, FOLDER-PATH is the directory in which SEARCH-REGEXP
1579search." 1605is used to search."
1580 (let ((namazu-index-directory 1606 (let ((namazu-index-directory
1581 (format "%s%s" mh-user-path mh-namazu-directory))) 1607 (format "%s%s" mh-user-path mh-namazu-directory)))
1582 (unless (file-exists-p namazu-index-directory) 1608 (unless (file-exists-p namazu-index-directory)
@@ -1623,10 +1649,10 @@ search."
1623;;;###mh-autoload 1649;;;###mh-autoload
1624(defun mh-index-choose () 1650(defun mh-index-choose ()
1625 "Choose an indexing function. 1651 "Choose an indexing function.
1626The side-effects of this function are that the variables `mh-indexer', 1652The side-effects of this function are that the variables
1627`mh-index-execute-search-function', and `mh-index-next-result-function' are 1653`mh-indexer', `mh-index-execute-search-function', and
1628set according to the first indexer in `mh-indexer-choices' present on the 1654`mh-index-next-result-function' are set according to the first
1629system." 1655indexer in `mh-indexer-choices' present on the system."
1630 (block nil 1656 (block nil
1631 ;; The following favors the user's preference; otherwise, the last 1657 ;; The following favors the user's preference; otherwise, the last
1632 ;; automatically chosen indexer is used for efficiency rather than going 1658 ;; automatically chosen indexer is used for efficiency rather than going
diff --git a/lisp/mh-e/mh-init.el b/lisp/mh-e/mh-init.el
index 1bafe960eff..6b8feda8ccc 100644
--- a/lisp/mh-e/mh-init.el
+++ b/lisp/mh-e/mh-init.el
@@ -64,7 +64,7 @@ This directory contains, among other things, the components file.")
64This directory contains, among other things, the mhl program.") 64This directory contains, among other things, the mhl program.")
65 65
66(defvar mh-flists-present-flag nil 66(defvar mh-flists-present-flag nil
67 "Non-nil means that we have `flists'.") 67 "Non-nil means that we have \"flists\".")
68 68
69;;;###autoload 69;;;###autoload
70(put 'mh-progs 'risky-local-variable t) 70(put 'mh-progs 'risky-local-variable t)
@@ -81,8 +81,8 @@ Created by the function `mh-variants'")
81(defun mh-variants () 81(defun mh-variants ()
82 "Return a list of installed variants of MH on the system. 82 "Return a list of installed variants of MH on the system.
83This function looks for MH in `mh-sys-path', `mh-path' and 83This function looks for MH in `mh-sys-path', `mh-path' and
84`exec-path'. The format of the list of variants that is returned is described 84`exec-path'. The format of the list of variants that is returned
85by the variable `mh-variants'." 85is described by the variable `mh-variants'."
86 (if mh-variants 86 (if mh-variants
87 mh-variants 87 mh-variants
88 (let ((list-unique)) 88 (let ((list-unique))
@@ -100,14 +100,16 @@ by the variable `mh-variants'."
100 100
101(defvar mh-variant-in-use nil 101(defvar mh-variant-in-use nil
102 "The MH variant currently in use; a string with variant and version number. 102 "The MH variant currently in use; a string with variant and version number.
103This differs from `mh-variant' when the latter is set to `autodetect'.") 103This differs from `mh-variant' when the latter is set to
104\"autodetect\".")
104 105
105;;;###mh-autoload 106;;;###mh-autoload
106(defun mh-variant-set (variant) 107(defun mh-variant-set (variant)
107 "Set the MH variant to VARIANT. 108 "Set the MH variant to VARIANT.
108Sets `mh-progs', `mh-lib', `mh-lib-progs' and `mh-flists-present-flag'. 109Sets `mh-progs', `mh-lib', `mh-lib-progs' and
109If the VARIANT is `autodetect', then first try nmh, then MH and finally 110`mh-flists-present-flag'.
110GNU mailutils." 111If the VARIANT is \"autodetect\", then first try nmh, then MH and
112finally GNU mailutils."
111 (interactive 113 (interactive
112 (list (completing-read 114 (list (completing-read
113 "MH Variant: " 115 "MH Variant: "
@@ -138,7 +140,8 @@ GNU mailutils."
138(defun mh-variant-set-variant (variant) 140(defun mh-variant-set-variant (variant)
139 "Setup the system variables for the MH variant named VARIANT. 141 "Setup the system variables for the MH variant named VARIANT.
140If VARIANT is a string, use that key in the variable `mh-variants'. 142If VARIANT is a string, use that key in the variable `mh-variants'.
141If VARIANT is a symbol, select the first entry that matches that variant." 143If VARIANT is a symbol, select the first entry that matches that
144variant."
142 (cond 145 (cond
143 ((stringp variant) ;e.g. "nmh 1.1-RC1" 146 ((stringp variant) ;e.g. "nmh 1.1-RC1"
144 (when (assoc variant mh-variants) 147 (when (assoc variant mh-variants)
@@ -193,13 +196,13 @@ Currently known variants are 'MH, 'nmh, and 'mu-mh."
193 "/usr/bin/mu-mh/") ; GNU mailutils - packaged 196 "/usr/bin/mu-mh/") ; GNU mailutils - packaged
194 "List of directories to search for variants of the MH variant. 197 "List of directories to search for variants of the MH variant.
195The list `exec-path' is searched in addition to this list. 198The list `exec-path' is searched in addition to this list.
196There's no need for users to modify this list. Instead add extra 199There's no need for users to modify this list. Instead add extra
197directories to the customizable variable `mh-path'.") 200directories to the customizable variable `mh-path'.")
198 201
199(defun mh-variant-mh-info (dir) 202(defun mh-variant-mh-info (dir)
200 "Return info for MH variant in DIR assuming a temporary buffer is setup." 203 "Return info for MH variant in DIR assuming a temporary buffer is setup."
201 ;; MH does not have the -version option. 204 ;; MH does not have the -version option.
202 ;; Its version number is included in the output of `-help' as: 205 ;; Its version number is included in the output of "-help" as:
203 ;; 206 ;;
204 ;; version: MH 6.8.4 #2[UCI] (burrito) of Fri Jan 15 20:01:39 EST 1999 207 ;; version: MH 6.8.4 #2[UCI] (burrito) of Fri Jan 15 20:01:39 EST 1999
205 ;; options: [ATHENA] [BIND] [DUMB] [LIBLOCKFILE] [LOCALE] [MAILGROUP] [MHE] 208 ;; options: [ATHENA] [BIND] [DUMB] [LIBLOCKFILE] [LOCALE] [MAILGROUP] [MHE]
@@ -302,10 +305,11 @@ This assumes that a temporary buffer is setup."
302;;;###mh-autoload 305;;;###mh-autoload
303(defun mh-image-load-path () 306(defun mh-image-load-path ()
304 "Ensure that the MH-E images are accessible by `find-image'. 307 "Ensure that the MH-E images are accessible by `find-image'.
305Images for MH-E are found in ../../etc/images relative to the files in 308Images for MH-E are found in ../../etc/images relative to the
306`lisp/mh-e'. If `image-load-path' exists (since Emacs 22), then the images 309files in \"lisp/mh-e\". If `image-load-path' exists (since Emacs
307directory is added to it if isn't already there. Otherwise, the images 31022), then the images directory is added to it if isn't already
308directory is added to the `load-path' if it isn't already there." 311there. Otherwise, the images directory is added to the
312`load-path' if it isn't already there."
309 (unless mh-image-load-path-called-flag 313 (unless mh-image-load-path-called-flag
310 (let (mh-library-name mh-image-load-path) 314 (let (mh-library-name mh-image-load-path)
311 ;; First, find mh-e in the load-path. 315 ;; First, find mh-e in the load-path.
@@ -332,10 +336,11 @@ directory is added to the `load-path' if it isn't already there."
332 "Convert SPEC for defface if necessary to run on older platforms. 336 "Convert SPEC for defface if necessary to run on older platforms.
333See `defface' for the spec definition. 337See `defface' for the spec definition.
334 338
335When `mh-min-colors-defined-flag' is nil, this function finds a display with a 339When `mh-min-colors-defined-flag' is nil, this function finds a
336single \"class\" requirement with a \"color\" item, renames the requirement to 340display with a single \"class\" requirement with a \"color\"
337\"tty\" and moves it to the beginning of the list. It then strips any 341item, renames the requirement to \"tty\" and moves it to the
338\"min-colors\" requirements." 342beginning of the list. It then strips any \"min-colors\"
343requirements."
339 (when (not mh-min-colors-defined-flag) 344 (when (not mh-min-colors-defined-flag)
340 ;; Insert ((class tty)) display with ((class color)) attributes. 345 ;; Insert ((class tty)) display with ((class color)) attributes.
341 (let ((attributes (cdr (assoc '((class color)) spec)))) 346 (let ((attributes (cdr (assoc '((class color)) spec))))
diff --git a/lisp/mh-e/mh-junk.el b/lisp/mh-e/mh-junk.el
index 29caef6cae7..5d2bf87581e 100644
--- a/lisp/mh-e/mh-junk.el
+++ b/lisp/mh-e/mh-junk.el
@@ -41,14 +41,15 @@
41(defun mh-junk-blacklist (range) 41(defun mh-junk-blacklist (range)
42 "Blacklist RANGE as spam. 42 "Blacklist RANGE as spam.
43 43
44This command trains the spam program in use (see the option `mh-junk-program') 44This command trains the spam program in use (see the option
45with the content of RANGE and then handles the message(s) as specified by the 45`mh-junk-program') with the content of RANGE and then handles the
46option `mh-junk-disposition'. 46message(s) as specified by the option `mh-junk-disposition'.
47 47
48Check the documentation of `mh-interactive-range' to see how RANGE is read in 48Check the documentation of `mh-interactive-range' to see how RANGE is
49interactive use. 49read in interactive use.
50 50
51For more information about using your particular spam fighting program, see: 51For more information about using your particular spam fighting
52program, see:
52 53
53 - `mh-spamassassin-blacklist' 54 - `mh-spamassassin-blacklist'
54 - `mh-bogofilter-blacklist' 55 - `mh-bogofilter-blacklist'
@@ -80,12 +81,12 @@ For more information about using your particular spam fighting program, see:
80(defun mh-junk-whitelist (range) 81(defun mh-junk-whitelist (range)
81 "Whitelist RANGE as ham. 82 "Whitelist RANGE as ham.
82 83
83This command reclassifies the RANGE as ham if it were incorrectly classified 84This command reclassifies the RANGE as ham if it were incorrectly
84as spam (see the option `mh-junk-program'). It then refiles the message into 85classified as spam (see the option `mh-junk-program'). It then
85the \"+inbox\" folder. 86refiles the message into the \"+inbox\" folder.
86 87
87Check the documentation of `mh-interactive-range' to see how RANGE is read in 88Check the documentation of `mh-interactive-range' to see how
88interactive use." 89RANGE is read in interactive use."
89 (interactive (list (mh-interactive-range "Whitelist"))) 90 (interactive (list (mh-interactive-range "Whitelist")))
90 (let ((whitelist-func (nth 2 (assoc mh-junk-choice mh-junk-function-alist)))) 91 (let ((whitelist-func (nth 2 (assoc mh-junk-choice mh-junk-function-alist))))
91 (unless whitelist-func 92 (unless whitelist-func
@@ -107,10 +108,10 @@ interactive use."
107(defun mh-spamassassin-blacklist (msg) 108(defun mh-spamassassin-blacklist (msg)
108 "Blacklist MSG with SpamAssassin. 109 "Blacklist MSG with SpamAssassin.
109 110
110SpamAssassin is one of the more popular spam filtering programs. Get it from 111SpamAssassin is one of the more popular spam filtering programs. Get
111your local distribution or from http://spamassassin.org/. 112it from your local distribution or from http://spamassassin.org/.
112 113
113To use SpamAssassin, add the following recipes to `.procmailrc': 114To use SpamAssassin, add the following recipes to \".procmailrc\":
114 115
115 MAILDIR=$HOME/`mhparam Path` 116 MAILDIR=$HOME/`mhparam Path`
116 117
@@ -127,54 +128,58 @@ To use SpamAssassin, add the following recipes to `.procmailrc':
127 * ^X-Spam-Status: Yes 128 * ^X-Spam-Status: Yes
128 spam/. 129 spam/.
129 130
130If you don't use `spamc', use `spamassassin -P -a'. 131If you don't use \"spamc\", use \"spamassassin -P -a\".
131 132
132Note that one of the recipes above throws away messages with a score greater 133Note that one of the recipes above throws away messages with a score
133than or equal to 10. Here's how you can determine a value that works best for 134greater than or equal to 10. Here's how you can determine a value that
134you. 135works best for you.
135 136
136First, run `spamassassin -t' on every mail message in your archive and use 137First, run \"spamassassin -t\" on every mail message in your archive and
137Gnumeric to verify that the average plus the standard deviation of good mail 138use Gnumeric to verify that the average plus the standard deviation of
138is under 5, the SpamAssassin default for \"spam\". 139good mail is under 5, the SpamAssassin default for \"spam\".
139 140
140Using Gnumeric, sort the messages by score and view the messages with the 141Using Gnumeric, sort the messages by score and view the messages with
141highest score. Determine the score which encompasses all of your interesting 142the highest score. Determine the score which encompasses all of your
142messages and add a couple of points to be conservative. Add that many dots to 143interesting messages and add a couple of points to be conservative.
143the `X-Spam-Level:' header field above to send messages with that score down 144Add that many dots to the \"X-Spam-Level:\" header field above to send
144the drain. 145messages with that score down the drain.
145 146
146In the example above, messages with a score of 5-9 are set aside in the 147In the example above, messages with a score of 5-9 are set aside in
147`+spam' folder for later review. The major weakness of rules-based filters is 148the \"+spam\" folder for later review. The major weakness of rules-based
148a plethora of false positives so it is worthwhile to check. 149filters is a plethora of false positives so it is worthwhile to check.
149 150
150If SpamAssassin classifies a message incorrectly, or is unsure, you can use 151If SpamAssassin classifies a message incorrectly, or is unsure, you
151the MH-E commands \\[mh-junk-blacklist] and \\[mh-junk-whitelist]. 152can use the MH-E commands \\[mh-junk-blacklist] and
152 153\\[mh-junk-whitelist].
153The \\[mh-junk-blacklist] command adds a `blacklist_from' entry to 154
154`~/spamassassin/user_prefs', deletes the message, and sends the message to the 155The \\[mh-junk-blacklist] command adds a \"blacklist_from\" entry to
155Razor, so that others might not see this spam. If the `sa-learn' command is 156\"~/spamassassin/user_prefs\", deletes the message, and sends the
156available, the message is also recategorized as spam. 157message to the Razor, so that others might not see this spam. If the
157 158\"sa-learn\" command is available, the message is also recategorized as
158The \\[mh-junk-whitelist] command adds a `whitelist_from' rule to the 159spam.
159`~/.spamassassin/user_prefs' file. If the `sa-learn' command is available, the 160
160message is also recategorized as ham. 161The \\[mh-junk-whitelist] command adds a \"whitelist_from\" rule to the
161 162\"~/.spamassassin/user_prefs\" file. If the \"sa-learn\" command is
162Over time, you'll observe that the same host or domain occurs repeatedly in 163available, the message is also recategorized as ham.
163the `blacklist_from' entries, so you might think that you could avoid future 164
164spam by blacklisting all mail from a particular domain. The utility function 165Over time, you'll observe that the same host or domain occurs
165`mh-spamassassin-identify-spammers' helps you do precisely that. This function 166repeatedly in the \"blacklist_from\" entries, so you might think that
166displays a frequency count of the hosts and domains in the `blacklist_from' 167you could avoid future spam by blacklisting all mail from a particular
167entries from the last blank line in `~/.spamassassin/user_prefs' to the end of 168domain. The utility function `mh-spamassassin-identify-spammers' helps
168the file. This information can be used so that you can replace multiple 169you do precisely that. This function displays a frequency count of the
169`blacklist_from' entries with a single wildcard entry such as: 170hosts and domains in the \"blacklist_from\" entries from the last blank
171line in \"~/.spamassassin/user_prefs\" to the end of the file. This
172information can be used so that you can replace multiple
173\"blacklist_from\" entries with a single wildcard entry such as:
170 174
171 blacklist_from *@*amazingoffersdirect2u.com 175 blacklist_from *@*amazingoffersdirect2u.com
172 176
173In versions of SpamAssassin (2.50 and on) that support a Bayesian classifier, 177In versions of SpamAssassin (2.50 and on) that support a Bayesian
174\\[mh-junk-blacklist] uses the `sa-learn' program to recategorize the message 178classifier, \\[mh-junk-blacklist] uses the \"sa-learn\" program to
175as spam. Neither MH-E, nor SpamAssassin, rebuilds the database after adding 179recategorize the message as spam. Neither MH-E, nor SpamAssassin,
176words, so you will need to run `sa-learn --rebuild' periodically. This can be 180rebuilds the database after adding words, so you will need to run
177done by adding the following to your crontab: 181\"sa-learn --rebuild\" periodically. This can be done by adding the
182following to your crontab:
178 183
179 0 * * * * sa-learn --rebuild > /dev/null 2>&1" 184 0 * * * * sa-learn --rebuild > /dev/null 2>&1"
180 (unless mh-spamassassin-executable 185 (unless mh-spamassassin-executable
@@ -210,9 +215,9 @@ done by adding the following to your crontab:
210(defun mh-spamassassin-whitelist (msg) 215(defun mh-spamassassin-whitelist (msg)
211 "Whitelist MSG with SpamAssassin. 216 "Whitelist MSG with SpamAssassin.
212 217
213The \\[mh-junk-whitelist] command adds a `whitelist_from' rule to the 218The \\[mh-junk-whitelist] command adds a \"whitelist_from\" rule to
214`~/.spamassassin/user_prefs' file. If the `sa-learn' command is available, the 219the \"~/.spamassassin/user_prefs\" file. If the \"sa-learn\" command
215message is also recategorized as ham. 220is available, the message is also recategorized as ham.
216 221
217See `mh-spamassassin-blacklist' for more information." 222See `mh-spamassassin-blacklist' for more information."
218 (unless mh-spamassassin-executable 223 (unless mh-spamassassin-executable
@@ -244,7 +249,7 @@ See `mh-spamassassin-blacklist' for more information."
244 (message "Whitelisting message %d...done" msg)))) 249 (message "Whitelisting message %d...done" msg))))
245 250
246(defun mh-spamassassin-add-rule (rule body) 251(defun mh-spamassassin-add-rule (rule body)
247 "Add a new rule to `~/.spamassassin/user_prefs'. 252 "Add a new rule to \"~/.spamassassin/user_prefs\".
248The name of the rule is RULE and its body is BODY." 253The name of the rule is RULE and its body is BODY."
249 (save-window-excursion 254 (save-window-excursion
250 (let* ((line (format "%s\t%s\n" rule body)) 255 (let* ((line (format "%s\t%s\n" rule body))
@@ -263,11 +268,11 @@ The name of the rule is RULE and its body is BODY."
263(defun mh-spamassassin-identify-spammers () 268(defun mh-spamassassin-identify-spammers ()
264 "Identify spammers who are repeat offenders. 269 "Identify spammers who are repeat offenders.
265 270
266This function displays a frequency count of the hosts and domains in the 271This function displays a frequency count of the hosts and domains
267`blacklist_from' entries from the last blank line in 272in the \"blacklist_from\" entries from the last blank line in
268`~/.spamassassin/user_prefs' to the end of the file. This information can be 273\"~/.spamassassin/user_prefs\" to the end of the file. This
269used so that you can replace multiple `blacklist_from' entries with a single 274information can be used so that you can replace multiple
270wildcard entry such as: 275\"blacklist_from\" entries with a single wildcard entry such as:
271 276
272 blacklist_from *@*amazingoffersdirect2u.com" 277 blacklist_from *@*amazingoffersdirect2u.com"
273 (interactive) 278 (interactive)
@@ -312,8 +317,8 @@ wildcard entry such as:
312(defun mh-bogofilter-blacklist (msg) 317(defun mh-bogofilter-blacklist (msg)
313 "Blacklist MSG with bogofilter. 318 "Blacklist MSG with bogofilter.
314 319
315Bogofilter is a Bayesian spam filtering program. Get it from your local 320Bogofilter is a Bayesian spam filtering program. Get it from your
316distribution or from http://bogofilter.sourceforge.net/. 321local distribution or from http://bogofilter.sourceforge.net/.
317 322
318Bogofilter is taught by running: 323Bogofilter is taught by running:
319 324
@@ -324,11 +329,11 @@ on every good message, and
324 bogofilter -s < spam-message 329 bogofilter -s < spam-message
325 330
326on every spam message. This is called a full training; three other 331on every spam message. This is called a full training; three other
327training methods are described in the FAQ that is distributed with bogofilter. 332training methods are described in the FAQ that is distributed with
328Note that most Bayesian filters need 1000 to 5000 of each type of message to 333bogofilter. Note that most Bayesian filters need 1000 to 5000 of each
329start doing a good job. 334type of message to start doing a good job.
330 335
331To use bogofilter, add the following recipes to `.procmailrc': 336To use bogofilter, add the following recipes to \".procmailrc\":
332 337
333 MAILDIR=$HOME/`mhparam Path` 338 MAILDIR=$HOME/`mhparam Path`
334 339
@@ -344,9 +349,9 @@ To use bogofilter, add the following recipes to `.procmailrc':
344 * ^X-Bogosity: Unsure, tests=bogofilter 349 * ^X-Bogosity: Unsure, tests=bogofilter
345 spam/unsure/. 350 spam/unsure/.
346 351
347If bogofilter classifies a message incorrectly, or is unsure, you can use the 352If bogofilter classifies a message incorrectly, or is unsure, you can
348MH-E commands \\[mh-junk-blacklist] and \\[mh-junk-whitelist] to update 353use the MH-E commands \\[mh-junk-blacklist] and \\[mh-junk-whitelist]
349bogofilter's training. 354to update bogofilter's training.
350 355
351The \"Bogofilter FAQ\" suggests that you run the following 356The \"Bogofilter FAQ\" suggests that you run the following
352occasionally to shrink the database: 357occasionally to shrink the database:
@@ -384,7 +389,7 @@ See `mh-bogofilter-blacklist' for more information."
384SpamProbe is a Bayesian spam filtering program. Get it from your local 389SpamProbe is a Bayesian spam filtering program. Get it from your local
385distribution or from http://spamprobe.sourceforge.net. 390distribution or from http://spamprobe.sourceforge.net.
386 391
387To use SpamProbe, add the following recipes to `.procmailrc': 392To use SpamProbe, add the following recipes to \".procmailrc\":
388 393
389 MAILDIR=$HOME/`mhparam Path` 394 MAILDIR=$HOME/`mhparam Path`
390 395
@@ -399,9 +404,9 @@ To use SpamProbe, add the following recipes to `.procmailrc':
399 *^X-SpamProbe: SPAM 404 *^X-SpamProbe: SPAM
400 spam/. 405 spam/.
401 406
402If SpamProbe classifies a message incorrectly, you can use the MH-E commands 407If SpamProbe classifies a message incorrectly, you can use the
403\\[mh-junk-blacklist] and \\[mh-junk-whitelist] to update SpamProbe's 408MH-E commands \\[mh-junk-blacklist] and \\[mh-junk-whitelist] to
404training." 409update SpamProbe's training."
405 (unless mh-spamprobe-executable 410 (unless mh-spamprobe-executable
406 (error "Unable to find the spamprobe executable")) 411 (error "Unable to find the spamprobe executable"))
407 (let ((msg-file (mh-msg-filename msg mh-current-folder))) 412 (let ((msg-file (mh-msg-filename msg mh-current-folder)))
diff --git a/lisp/mh-e/mh-mime.el b/lisp/mh-e/mh-mime.el
index bb2fc2b8f50..4338a94381b 100644
--- a/lisp/mh-e/mh-mime.el
+++ b/lisp/mh-e/mh-mime.el
@@ -55,12 +55,15 @@
55;;;###mh-autoload 55;;;###mh-autoload
56(defun mh-compose-insertion (&optional inline) 56(defun mh-compose-insertion (&optional inline)
57 "Add tag to include a file such as an image or sound. 57 "Add tag to include a file such as an image or sound.
58You are prompted for the filename containing the object, the media type if it
59cannot be determined automatically, and a content description. If you're using
60MH-style directives, you will also be prompted for additional attributes.
61 58
62The option `mh-compose-insertion' controls what type of tags are inserted. 59You are prompted for the filename containing the object, the
63Optional argument INLINE means make it an inline attachment." 60media type if it cannot be determined automatically, and a
61content description. If you're using MH-style directives, you
62will also be prompted for additional attributes.
63
64The option `mh-compose-insertion' controls what type of tags are
65inserted. Optional argument INLINE means make it an inline
66attachment."
64 (interactive "P") 67 (interactive "P")
65 (if (equal mh-compose-insertion 'mml) 68 (if (equal mh-compose-insertion 'mml)
66 (if inline 69 (if inline
@@ -71,8 +74,10 @@ Optional argument INLINE means make it an inline attachment."
71;;;###mh-autoload 74;;;###mh-autoload
72(defun mh-compose-forward (&optional description folder messages) 75(defun mh-compose-forward (&optional description folder messages)
73 "Add tag to forward a message. 76 "Add tag to forward a message.
74You are prompted for a content DESCRIPTION, the name of the FOLDER in which 77
75the messages to forward are located, and the MESSAGES' numbers. 78You are prompted for a content DESCRIPTION, the name of the
79FOLDER in which the messages to forward are located, and the
80MESSAGES' numbers.
76 81
77The option `mh-compose-insertion' controls what type of tags are inserted." 82The option `mh-compose-insertion' controls what type of tags are inserted."
78 (interactive (let* 83 (interactive (let*
@@ -117,9 +122,9 @@ The option `mh-compose-insertion' controls what type of tags are inserted."
117 122
118(defvar mh-mh-to-mime-args nil 123(defvar mh-mh-to-mime-args nil
119 "Extra arguments for \\[mh-mh-to-mime] to pass to the \"mhbuild\" command. 124 "Extra arguments for \\[mh-mh-to-mime] to pass to the \"mhbuild\" command.
120The arguments are passed to \"mhbuild\" if \\[mh-mh-to-mime] is given a prefix 125The arguments are passed to \"mhbuild\" if \\[mh-mh-to-mime] is
121argument. Normally default arguments to \"mhbuild\" are specified in the MH 126given a prefix argument. Normally default arguments to
122profile.") 127\"mhbuild\" are specified in the MH profile.")
123 128
124(defvar mh-media-type-regexp 129(defvar mh-media-type-regexp
125 (concat (regexp-opt '("text" "image" "audio" "video" "application" 130 (concat (regexp-opt '("text" "image" "audio" "video" "application"
@@ -151,12 +156,14 @@ profile.")
151 ("text/plain" "\.vcf" "text/x-vcard")) 156 ("text/plain" "\.vcf" "text/x-vcard"))
152 "Substitutions to make for Content-Type returned from file command. 157 "Substitutions to make for Content-Type returned from file command.
153The first element is the Content-Type returned by the file command. 158The first element is the Content-Type returned by the file command.
154The second element is a regexp matching the file name, usually the extension. 159The second element is a regexp matching the file name, usually the
160extension.
155The third element is the Content-Type to replace with.") 161The third element is the Content-Type to replace with.")
156 162
157(defun mh-file-mime-type-substitute (content-type filename) 163(defun mh-file-mime-type-substitute (content-type filename)
158 "Return possibly changed CONTENT-TYPE on the FILENAME. 164 "Return possibly changed CONTENT-TYPE on the FILENAME.
159Substitutions are made from the `mh-file-mime-type-substitutions' variable." 165Substitutions are made from the `mh-file-mime-type-substitutions'
166variable."
160 (let ((subst mh-file-mime-type-substitutions) 167 (let ((subst mh-file-mime-type-substitutions)
161 (type) (match) (answer content-type) 168 (type) (match) (answer content-type)
162 (case-fold-search t)) 169 (case-fold-search t))
@@ -225,9 +232,10 @@ See also \\[mh-mh-to-mime].")
225 232
226(defun mh-minibuffer-read-type (filename &optional default) 233(defun mh-minibuffer-read-type (filename &optional default)
227 "Return the content type associated with the given FILENAME. 234 "Return the content type associated with the given FILENAME.
228If the \"file\" command exists and recognizes the given file, then its value 235If the \"file\" command exists and recognizes the given file,
229is returned\; otherwise, the user is prompted for a type (see 236then its value is returned\; otherwise, the user is prompted for
230`mailcap-mime-types' and for Emacs 20, `mh-mime-content-types'). 237a type (see `mailcap-mime-types' and for Emacs 20,
238`mh-mime-content-types').
231Optional argument DEFAULT is returned if a type isn't entered." 239Optional argument DEFAULT is returned if a type isn't entered."
232 (mailcap-parse-mimetypes) 240 (mailcap-parse-mimetypes)
233 (let* ((default (or default 241 (let* ((default (or default
@@ -272,9 +280,10 @@ Optional argument DEFAULT is returned if a type isn't entered."
272;;;###mh-autoload 280;;;###mh-autoload
273(defun mh-mh-attach-file (filename type description attributes) 281(defun mh-mh-attach-file (filename type description attributes)
274 "Add a tag to insert a MIME message part from a file. 282 "Add a tag to insert a MIME message part from a file.
275You are prompted for the FILENAME containing the object, the media TYPE if it 283You are prompted for the FILENAME containing the object, the
276cannot be determined automatically, and a content DESCRIPTION. In addition, 284media TYPE if it cannot be determined automatically, and a
277you are also prompted for additional ATTRIBUTES. 285content DESCRIPTION. In addition, you are also prompted for
286additional ATTRIBUTES.
278 287
279See also \\[mh-mh-to-mime]." 288See also \\[mh-mh-to-mime]."
280 (interactive (let ((filename (mml-minibuffer-read-file "Attach file: "))) 289 (interactive (let ((filename (mml-minibuffer-read-file "Attach file: ")))
@@ -291,9 +300,9 @@ See also \\[mh-mh-to-mime]."
291(defun mh-mh-compose-type (filename type 300(defun mh-mh-compose-type (filename type
292 &optional description attributes comment) 301 &optional description attributes comment)
293 "Insert an MH-style directive to insert a file. 302 "Insert an MH-style directive to insert a file.
294The file specified by FILENAME is encoded as TYPE. An optional DESCRIPTION is 303The file specified by FILENAME is encoded as TYPE. An optional
295used as the Content-Description field, optional set of ATTRIBUTES and an 304DESCRIPTION is used as the Content-Description field, optional
296optional COMMENT can also be included." 305set of ATTRIBUTES and an optional COMMENT can also be included."
297 (beginning-of-line) 306 (beginning-of-line)
298 (insert "#" type) 307 (insert "#" type)
299 (and attributes 308 (and attributes
@@ -309,8 +318,8 @@ optional COMMENT can also be included."
309;;;###mh-autoload 318;;;###mh-autoload
310(defun mh-mh-compose-anon-ftp (host filename type description) 319(defun mh-mh-compose-anon-ftp (host filename type description)
311 "Add tag to include anonymous ftp reference to a file. 320 "Add tag to include anonymous ftp reference to a file.
312You can even have your message initiate an \"ftp\" transfer when the 321You can even have your message initiate an \"ftp\" transfer when
313recipient reads the message. You are prompted for the remote 322the recipient reads the message. You are prompted for the remote
314HOST and FILENAME, the media TYPE, and the content DESCRIPTION. 323HOST and FILENAME, the media TYPE, and the content DESCRIPTION.
315 324
316See also \\[mh-mh-to-mime]." 325See also \\[mh-mh-to-mime]."
@@ -325,10 +334,10 @@ See also \\[mh-mh-to-mime]."
325;;;###mh-autoload 334;;;###mh-autoload
326(defun mh-mh-compose-external-compressed-tar (host filename description) 335(defun mh-mh-compose-external-compressed-tar (host filename description)
327 "Add tag to include anonymous ftp reference to a compressed tar file. 336 "Add tag to include anonymous ftp reference to a compressed tar file.
328In addition to retrieving the file via anonymous \"ftp\" as per the 337In addition to retrieving the file via anonymous \"ftp\" as per
329\\[mh-mh-compose-anon-ftp] command, the file will also be uncompressed and 338the \\[mh-mh-compose-anon-ftp] command, the file will also be
330untarred. You are prompted for the remote HOST and FILENAME and the content 339uncompressed and untarred. You are prompted for the remote HOST
331DESCRIPTION. 340and FILENAME and the content DESCRIPTION.
332 341
333See also \\[mh-mh-to-mime]." 342See also \\[mh-mh-to-mime]."
334 (interactive (list 343 (interactive (list
@@ -347,11 +356,12 @@ See also \\[mh-mh-to-mime]."
347 attributes parameters 356 attributes parameters
348 comment) 357 comment)
349 "Add tag to refer to a remote file. 358 "Add tag to refer to a remote file.
350This command is a general utility for referencing external files. In fact, all 359This command is a general utility for referencing external files.
351of the other commands that insert directives to access external files call 360In fact, all of the other commands that insert directives to
352this command. You are prompted for the ACCESS-TYPE, remote HOST and FILENAME, 361access external files call this command. You are prompted for the
353and content TYPE. If you provide a prefix argument, you are also prompted for 362ACCESS-TYPE, remote HOST and FILENAME, and content TYPE. If you
354a content DESCRIPTION, ATTRIBUTES, PARAMETERS, and a COMMENT. 363provide a prefix argument, you are also prompted for a content
364DESCRIPTION, ATTRIBUTES, PARAMETERS, and a COMMENT.
355 365
356See also \\[mh-mh-to-mime]." 366See also \\[mh-mh-to-mime]."
357 (interactive (list 367 (interactive (list
@@ -386,8 +396,9 @@ See also \\[mh-mh-to-mime]."
386;;;###mh-autoload 396;;;###mh-autoload
387(defun mh-mh-forward-message (&optional description folder messages) 397(defun mh-mh-forward-message (&optional description folder messages)
388 "Add tag to forward a message. 398 "Add tag to forward a message.
389You are prompted for a content DESCRIPTION, the name of the FOLDER in which 399You are prompted for a content DESCRIPTION, the name of the
390the messages to forward are located, and the MESSAGES' numbers. 400FOLDER in which the messages to forward are located, and the
401MESSAGES' numbers.
391 402
392See also \\[mh-mh-to-mime]." 403See also \\[mh-mh-to-mime]."
393 (interactive (list 404 (interactive (list
@@ -419,22 +430,25 @@ See also \\[mh-mh-to-mime]."
419;;;###mh-autoload 430;;;###mh-autoload
420(defun mh-mh-to-mime (&optional extra-args) 431(defun mh-mh-to-mime (&optional extra-args)
421 "Compose MIME message from MH-style directives. 432 "Compose MIME message from MH-style directives.
422Typically, you send a message with attachments just like any other message. 433
423However, you may take a sneak preview of the MIME encoding if you wish by 434Typically, you send a message with attachments just like any other
424running this command. 435message. However, you may take a sneak preview of the MIME encoding if
425 436you wish by running this command.
426If you wish to pass additional arguments to \"mhbuild\" (\"mhn\") to affect 437
427how it builds your message, use the `mh-mh-to-mime-args' option. For example, 438If you wish to pass additional arguments to \"mhbuild\" (\"mhn\") to
428you can build a consistency check into the message by setting 439affect how it builds your message, use the `mh-mh-to-mime-args'
429`mh-mh-to-mime-args' to \"-check\". The recipient of your message can then run 440option. For example, you can build a consistency check into the
430\"mhbuild -check\" on the message--\"mhbuild\" (\"mhn\") will complain if the 441message by setting `mh-mh-to-mime-args' to \"-check\". The recipient
431message has been corrupted on the way. This command only consults this option 442of your message can then run \"mhbuild -check\" on the
432when given a prefix argument EXTRA-ARGS. 443message--\"mhbuild\" (\"mhn\") will complain if the message has been
433 444corrupted on the way. This command only consults this option when
434The value of `mh-mh-to-mime-hook' is a list of functions to be called after 445given a prefix argument EXTRA-ARGS.
435the message has been formatted. 446
436 447The hook `mh-mh-to-mime-hook' is called after the message has been
437The effects of this command can be undone by running \\[mh-mh-to-mime-undo]." 448formatted.
449
450The effects of this command can be undone by running
451\\[mh-mh-to-mime-undo]."
438 (interactive "*P") 452 (interactive "*P")
439 (mh-mh-quote-unescaped-sharp) 453 (mh-mh-quote-unescaped-sharp)
440 (save-buffer) 454 (save-buffer)
@@ -455,10 +469,10 @@ The effects of this command can be undone by running \\[mh-mh-to-mime-undo]."
455 (run-hooks 'mh-mh-to-mime-hook)) 469 (run-hooks 'mh-mh-to-mime-hook))
456 470
457(defun mh-mh-quote-unescaped-sharp () 471(defun mh-mh-quote-unescaped-sharp ()
458 "Quote `#' characters that haven't been quoted for \"mhbuild\". 472 "Quote \"#\" characters that haven't been quoted for \"mhbuild\".
459If the `#' character is present in the first column, but it isn't part of a 473If the \"#\" character is present in the first column, but it isn't
460MH-style directive then \"mhbuild\" gives an error. This function will quote 474part of a MH-style directive then \"mhbuild\" gives an error.
461all such characters." 475This function will quote all such characters."
462 (save-excursion 476 (save-excursion
463 (goto-char (point-min)) 477 (goto-char (point-min))
464 (while (re-search-forward "^#" nil t) 478 (while (re-search-forward "^#" nil t)
@@ -470,7 +484,8 @@ all such characters."
470;;;###mh-autoload 484;;;###mh-autoload
471(defun mh-mh-to-mime-undo (noconfirm) 485(defun mh-mh-to-mime-undo (noconfirm)
472 "Undo effects of \\[mh-mh-to-mime]. 486 "Undo effects of \\[mh-mh-to-mime].
473Optional non-nil argument NOCONFIRM means don't ask for confirmation." 487Optional non-nil argument NOCONFIRM means don't ask for
488confirmation."
474 (interactive "*P") 489 (interactive "*P")
475 (if (null buffer-file-name) 490 (if (null buffer-file-name)
476 (error "Buffer does not seem to be associated with any file")) 491 (error "Buffer does not seem to be associated with any file"))
@@ -498,8 +513,8 @@ Optional non-nil argument NOCONFIRM means don't ask for confirmation."
498;;;###mh-autoload 513;;;###mh-autoload
499(defun mh-mh-directive-present-p (&optional begin end) 514(defun mh-mh-directive-present-p (&optional begin end)
500 "Check if the text between BEGIN and END might be a MH-style directive. 515 "Check if the text between BEGIN and END might be a MH-style directive.
501The optional argument BEGIN defaults to the beginning of the buffer, while END 516The optional argument BEGIN defaults to the beginning of the
502defaults to the the end of the buffer." 517buffer, while END defaults to the the end of the buffer."
503 (unless begin (setq begin (point-min))) 518 (unless begin (setq begin (point-min)))
504 (unless end (setq end (point-max))) 519 (unless end (setq end (point-max)))
505 (save-excursion 520 (save-excursion
@@ -524,9 +539,10 @@ defaults to the the end of the buffer."
524;;;###mh-autoload 539;;;###mh-autoload
525(defun mh-mml-to-mime () 540(defun mh-mml-to-mime ()
526 "Compose MIME message from MML tags. 541 "Compose MIME message from MML tags.
527Typically, you send a message with attachments just like any other message. 542
528However, you may take a sneak preview of the MIME encoding if you wish by 543Typically, you send a message with attachments just like any
529running this command. 544other message. However, you may take a sneak preview of the MIME
545encoding if you wish by running this command.
530 546
531This action can be undone by running \\[undo]." 547This action can be undone by running \\[undo]."
532 (interactive) 548 (interactive)
@@ -547,8 +563,9 @@ This action can be undone by running \\[undo]."
547;;;###mh-autoload 563;;;###mh-autoload
548(defun mh-mml-forward-message (description folder message) 564(defun mh-mml-forward-message (description folder message)
549 "Forward a message as attachment. 565 "Forward a message as attachment.
550The function will prompt the user for a DESCRIPTION, a FOLDER and MESSAGE 566
551number." 567The function will prompt the user for a DESCRIPTION, a FOLDER and
568MESSAGE number."
552 (let ((msg (if (and (equal message "") (numberp mh-sent-from-msg)) 569 (let ((msg (if (and (equal message "") (numberp mh-sent-from-msg))
553 mh-sent-from-msg 570 mh-sent-from-msg
554 (car (read-from-string message))))) 571 (car (read-from-string message)))))
@@ -581,12 +598,13 @@ number."
581;;;###mh-autoload 598;;;###mh-autoload
582(defun mh-mml-attach-file (&optional disposition) 599(defun mh-mml-attach-file (&optional disposition)
583 "Add a tag to insert a MIME message part from a file. 600 "Add a tag to insert a MIME message part from a file.
584You are prompted for the filename containing the object, the media type if it 601
585cannot be determined automatically, a content description and the DISPOSITION 602You are prompted for the filename containing the object, the
586of the attachment. 603media type if it cannot be determined automatically, a content
604description and the DISPOSITION of the attachment.
587 605
588This is basically `mml-attach-file' from Gnus, modified such that a prefix 606This is basically `mml-attach-file' from Gnus, modified such that a prefix
589argument yields an `inline' disposition and Content-Type is determined 607argument yields an \"inline\" disposition and Content-Type is determined
590automatically." 608automatically."
591 (let* ((file (mml-minibuffer-read-file "Attach file: ")) 609 (let* ((file (mml-minibuffer-read-file "Attach file: "))
592 (type (mh-minibuffer-read-type file)) 610 (type (mh-minibuffer-read-type file))
@@ -600,6 +618,7 @@ automatically."
600 618
601(defun mh-secure-message (method mode &optional identity) 619(defun mh-secure-message (method mode &optional identity)
602 "Add tag to encrypt or sign message. 620 "Add tag to encrypt or sign message.
621
603METHOD should be one of: \"pgpmime\", \"pgp\", \"smime\". 622METHOD should be one of: \"pgpmime\", \"pgp\", \"smime\".
604MODE should be one of: \"sign\", \"encrypt\", \"signencrypt\", \"none\". 623MODE should be one of: \"sign\", \"encrypt\", \"signencrypt\", \"none\".
605IDENTITY is optionally the default-user-id to use." 624IDENTITY is optionally the default-user-id to use."
@@ -634,30 +653,33 @@ The argument IGNORE is not used."
634;;;###mh-autoload 653;;;###mh-autoload
635(defun mh-mml-secure-message-sign (method) 654(defun mh-mml-secure-message-sign (method)
636 "Add tag to sign the message. 655 "Add tag to sign the message.
637A proper multipart message is created for you when you send the message. Use 656
638the \\[mh-mml-unsecure-message] command to remove this tag. Use a prefix 657A proper multipart message is created for you when you send the
639argument METHOD to be prompted for one of the possible security methods 658message. Use the \\[mh-mml-unsecure-message] command to remove
640\(see `mh-mml-method-default')." 659this tag. Use a prefix argument METHOD to be prompted for one of
660the possible security methods (see `mh-mml-method-default')."
641 (interactive (list (mh-mml-query-cryptographic-method))) 661 (interactive (list (mh-mml-query-cryptographic-method)))
642 (mh-secure-message method "sign" mh-identity-pgg-default-user-id)) 662 (mh-secure-message method "sign" mh-identity-pgg-default-user-id))
643 663
644;;;###mh-autoload 664;;;###mh-autoload
645(defun mh-mml-secure-message-encrypt (method) 665(defun mh-mml-secure-message-encrypt (method)
646 "Add tag to encrypt the message. 666 "Add tag to encrypt the message.
647A proper multipart message is created for you when you send the message. Use 667
648the \\[mh-mml-unsecure-message] command to remove this tag. Use a prefix 668A proper multipart message is created for you when you send the
649argument METHOD to be prompted for one of the possible security methods 669message. Use the \\[mh-mml-unsecure-message] command to remove
650\(see `mh-mml-method-default')." 670this tag. Use a prefix argument METHOD to be prompted for one of
671the possible security methods (see `mh-mml-method-default')."
651 (interactive (list (mh-mml-query-cryptographic-method))) 672 (interactive (list (mh-mml-query-cryptographic-method)))
652 (mh-secure-message method "encrypt" mh-identity-pgg-default-user-id)) 673 (mh-secure-message method "encrypt" mh-identity-pgg-default-user-id))
653 674
654;;;###mh-autoload 675;;;###mh-autoload
655(defun mh-mml-secure-message-signencrypt (method) 676(defun mh-mml-secure-message-signencrypt (method)
656 "Add tag to encrypt and sign the message. 677 "Add tag to encrypt and sign the message.
657A proper multipart message is created for you when you send the message. Use 678
658the \\[mh-mml-unsecure-message] command to remove this tag. Use a prefix 679A proper multipart message is created for you when you send the
659argument METHOD to be prompted for one of the possible security methods 680message. Use the \\[mh-mml-unsecure-message] command to remove
660\(see `mh-mml-method-default')." 681this tag. Use a prefix argument METHOD to be prompted for one of
682the possible security methods (see `mh-mml-method-default')."
661 (interactive (list (mh-mml-query-cryptographic-method))) 683 (interactive (list (mh-mml-query-cryptographic-method)))
662 (mh-secure-message method "signencrypt" mh-identity-pgg-default-user-id)) 684 (mh-secure-message method "signencrypt" mh-identity-pgg-default-user-id))
663 685
@@ -694,10 +716,11 @@ argument METHOD to be prompted for one of the possible security methods
694 716
695(defun mh-handle-set-external-undisplayer (folder handle function) 717(defun mh-handle-set-external-undisplayer (folder handle function)
696 "Replacement for `mm-handle-set-external-undisplayer'. 718 "Replacement for `mm-handle-set-external-undisplayer'.
697This is only called in recent versions of Gnus. The MIME handles are stored 719
698in data structures corresponding to MH-E folder buffer FOLDER instead of in 720This is only called in recent versions of Gnus. The MIME handles
699Gnus (as in the original). The MIME part, HANDLE is associated with the 721are stored in data structures corresponding to MH-E folder buffer
700undisplayer FUNCTION." 722FOLDER instead of in Gnus (as in the original). The MIME part,
723HANDLE is associated with the undisplayer FUNCTION."
701 (if (mm-keep-viewer-alive-p handle) 724 (if (mm-keep-viewer-alive-p handle)
702 (let ((new-handle (copy-sequence handle))) 725 (let ((new-handle (copy-sequence handle)))
703 (mm-handle-set-undisplayer new-handle function) 726 (mm-handle-set-undisplayer new-handle function)
@@ -715,7 +738,8 @@ undisplayer FUNCTION."
715;;;###mh-autoload 738;;;###mh-autoload
716(defun mh-add-missing-mime-version-header () 739(defun mh-add-missing-mime-version-header ()
717 "Some mail programs don't put a MIME-Version header. 740 "Some mail programs don't put a MIME-Version header.
718I have seen this only in spam, so maybe we shouldn't fix this ;-)" 741I have seen this only in spam, so maybe we shouldn't fix
742this ;-)"
719 (save-excursion 743 (save-excursion
720 (goto-char (point-min)) 744 (goto-char (point-min))
721 (re-search-forward "\n\n" nil t) 745 (re-search-forward "\n\n" nil t)
@@ -728,7 +752,8 @@ I have seen this only in spam, so maybe we shouldn't fix this ;-)"
728 752
729(defun mh-small-show-buffer-p () 753(defun mh-small-show-buffer-p ()
730 "Check if show buffer is small. 754 "Check if show buffer is small.
731This is used to decide if smileys and graphical emphasis will be displayed." 755This is used to decide if smileys and graphical emphasis will be
756displayed."
732 (let ((max nil)) 757 (let ((max nil))
733 (when (and (boundp 'font-lock-maximum-size) font-lock-maximum-size) 758 (when (and (boundp 'font-lock-maximum-size) font-lock-maximum-size)
734 (cond ((numberp font-lock-maximum-size) 759 (cond ((numberp font-lock-maximum-size)
@@ -802,12 +827,13 @@ Set from last use.")
802(defun mh-mime-save-parts (prompt) 827(defun mh-mime-save-parts (prompt)
803 "Save attachments. 828 "Save attachments.
804 829
805You can save all of the attachments at once with this command. The attachments 830You can save all of the attachments at once with this command.
806are saved in the directory specified by the option 831The attachments are saved in the directory specified by the
807`mh-mime-save-parts-default-directory' unless you use a prefix argument PROMPT 832option `mh-mime-save-parts-default-directory' unless you use a
808in which case you are prompted for the directory. These directories may be 833prefix argument PROMPT in which case you are prompted for the
809superseded by MH profile components, since this function calls on 834directory. These directories may be superseded by MH profile
810\"mhstore\" (\"mhn\") to do the work." 835components, since this function calls on \"mhstore\" (\"mhn\") to
836do the work."
811 (interactive "P") 837 (interactive "P")
812 (let ((msg (if (eq major-mode 'mh-show-mode) 838 (let ((msg (if (eq major-mode 'mh-show-mode)
813 (mh-show-buffer-message-number) 839 (mh-show-buffer-message-number)
@@ -899,9 +925,9 @@ If message has been encoded for transfer take that into account."
899;;;###mh-autoload 925;;;###mh-autoload
900(defun mh-mime-display (&optional pre-dissected-handles) 926(defun mh-mime-display (&optional pre-dissected-handles)
901 "Display (and possibly decode) MIME handles. 927 "Display (and possibly decode) MIME handles.
902Optional argument, PRE-DISSECTED-HANDLES is a list of MIME handles. If 928Optional argument, PRE-DISSECTED-HANDLES is a list of MIME
903present they are displayed otherwise the buffer is parsed and then 929handles. If present they are displayed otherwise the buffer is
904displayed." 930parsed and then displayed."
905 (let ((handles ()) 931 (let ((handles ())
906 (folder mh-show-folder-buffer) 932 (folder mh-show-folder-buffer)
907 (raw-message-data (buffer-string))) 933 (raw-message-data (buffer-string)))
@@ -973,8 +999,8 @@ If no part is preferred then all the parts are displayed."
973 999
974(defun mh-mime-maybe-display-alternatives (alternatives) 1000(defun mh-mime-maybe-display-alternatives (alternatives)
975 "Show buttons for ALTERNATIVES. 1001 "Show buttons for ALTERNATIVES.
976If `mh-mime-display-alternatives-flag' is non-nil then display buttons for 1002If `mh-mime-display-alternatives-flag' is non-nil then display
977alternative parts that are usually suppressed." 1003buttons for alternative parts that are usually suppressed."
978 (when (and mh-display-buttons-for-alternatives-flag alternatives) 1004 (when (and mh-display-buttons-for-alternatives-flag alternatives)
979 (insert "\n----------------------------------------------------\n") 1005 (insert "\n----------------------------------------------------\n")
980 (insert "Alternatives:\n") 1006 (insert "Alternatives:\n")
@@ -989,9 +1015,9 @@ alternative parts that are usually suppressed."
989 1015
990(defun mh-mime-part-index (handle) 1016(defun mh-mime-part-index (handle)
991 "Generate the button number for MIME part, HANDLE. 1017 "Generate the button number for MIME part, HANDLE.
992Notice that a hash table is used to display the same number when buttons need 1018Notice that a hash table is used to display the same number when
993to be displayed multiple times (for instance when nested messages are 1019buttons need to be displayed multiple times (for instance when
994opened)." 1020nested messages are opened)."
995 (or (gethash handle (mh-mime-part-index-hash (mh-buffer-data))) 1021 (or (gethash handle (mh-mime-part-index-hash (mh-buffer-data)))
996 (setf (gethash handle (mh-mime-part-index-hash (mh-buffer-data))) 1022 (setf (gethash handle (mh-mime-part-index-hash (mh-buffer-data)))
997 (incf (mh-mime-parts-count (mh-buffer-data)))))) 1023 (incf (mh-mime-parts-count (mh-buffer-data))))))
@@ -1074,8 +1100,8 @@ This is only useful if a Content-Disposition header is not present."
1074 1100
1075(defun mh-signature-highlight (&optional handle) 1101(defun mh-signature-highlight (&optional handle)
1076 "Highlight message signature in HANDLE. 1102 "Highlight message signature in HANDLE.
1077The optional argument, HANDLE is a MIME handle if the function is being used 1103The optional argument, HANDLE is a MIME handle if the function is
1078to highlight the signature in a MIME part." 1104being used to highlight the signature in a MIME part."
1079 (let ((regexp 1105 (let ((regexp
1080 (cond ((not handle) "^-- $") 1106 (cond ((not handle) "^-- $")
1081 ((not (and (equal (mm-handle-media-supertype handle) "text") 1107 ((not (and (equal (mm-handle-media-supertype handle) "text")
@@ -1100,8 +1126,8 @@ to highlight the signature in a MIME part."
1100 1126
1101(defun mh-insert-mime-button (handle index displayed) 1127(defun mh-insert-mime-button (handle index displayed)
1102 "Insert MIME button for HANDLE. 1128 "Insert MIME button for HANDLE.
1103INDEX is the part number that will be DISPLAYED. It is also used by commands 1129INDEX is the part number that will be DISPLAYED. It is also used
1104like \"K v\" which operate on individual MIME parts." 1130by commands like \"K v\" which operate on individual MIME parts."
1105 ;; The button could be displayed by a previous decode. In that case 1131 ;; The button could be displayed by a previous decode. In that case
1106 ;; undisplay it if we need a hidden button. 1132 ;; undisplay it if we need a hidden button.
1107 (when (and (mm-handle-displayed-p handle) (not displayed)) 1133 (when (and (mm-handle-displayed-p handle) (not displayed))
@@ -1213,8 +1239,8 @@ like \"K v\" which operate on individual MIME parts."
1213(defun mh-press-button () 1239(defun mh-press-button ()
1214 "View contents of button. 1240 "View contents of button.
1215 1241
1216This command is a toggle so if you use it again on the same attachment, the 1242This command is a toggle so if you use it again on the same
1217attachment is hidden." 1243attachment, the attachment is hidden."
1218 (interactive) 1244 (interactive)
1219 (let ((mm-inline-media-tests mh-mm-inline-media-tests) 1245 (let ((mm-inline-media-tests mh-mm-inline-media-tests)
1220 (data (get-text-property (point) 'mh-data)) 1246 (data (get-text-property (point) 'mh-data))
@@ -1232,9 +1258,10 @@ attachment is hidden."
1232;;;###mh-autoload 1258;;;###mh-autoload
1233(defun mh-push-button (event) 1259(defun mh-push-button (event)
1234 "Click MIME button for EVENT. 1260 "Click MIME button for EVENT.
1235If the MIME part is visible then it is removed. Otherwise the part is 1261
1236displayed. This function is called when the mouse is used to click the MIME 1262If the MIME part is visible then it is removed. Otherwise the
1237button." 1263part is displayed. This function is called when the mouse is used
1264to click the MIME button."
1238 (interactive "e") 1265 (interactive "e")
1239 (mh-do-at-event-location event 1266 (mh-do-at-event-location event
1240 (let ((folder mh-show-folder-buffer) 1267 (let ((folder mh-show-folder-buffer)
@@ -1288,21 +1315,24 @@ button."
1288(defun mh-display-with-external-viewer (part-index) 1315(defun mh-display-with-external-viewer (part-index)
1289 "View attachment externally. 1316 "View attachment externally.
1290 1317
1291If Emacs does not know how to view an attachment, you could save it into a 1318If Emacs does not know how to view an attachment, you could save
1292file and then run some program to open it. It is easier, however, to launch 1319it into a file and then run some program to open it. It is
1293the program directly from MH-E with this command. While you'll most likely use 1320easier, however, to launch the program directly from MH-E with
1294this to view spreadsheets and documents, it is also useful to use your browser 1321this command. While you'll most likely use this to view
1295to view HTML attachments with higher fidelity than what Emacs can provide. 1322spreadsheets and documents, it is also useful to use your browser
1296 1323to view HTML attachments with higher fidelity than what Emacs can
1297This command displays the attachment associated with the button under the 1324provide.
1298cursor. If the cursor is not located over a button, then the cursor first 1325
1299moves to the next button, wrapping to the beginning of the message if 1326This command displays the attachment associated with the button
1300necessary. You can provide a numeric prefix argument PART-INDEX to view the 1327under the cursor. If the cursor is not located over a button,
1301attachment labeled with that number. 1328then the cursor first moves to the next button, wrapping to the
1302 1329beginning of the message if necessary. You can provide a numeric
1303This command tries to provide a reasonable default for the viewer by calling 1330prefix argument PART-INDEX to view the attachment labeled with
1304the Emacs function `mailcap-mime-info'. This function usually reads the file 1331that number.
1305\"/etc/mailcap\"." 1332
1333This command tries to provide a reasonable default for the viewer
1334by calling the Emacs function `mailcap-mime-info'. This function
1335usually reads the file \"/etc/mailcap\"."
1306 (interactive "P") 1336 (interactive "P")
1307 (when (consp part-index) (setq part-index (car part-index))) 1337 (when (consp part-index) (setq part-index (car part-index)))
1308 (mh-folder-mime-action 1338 (mh-folder-mime-action
@@ -1457,8 +1487,8 @@ Parameter EL is unused."
1457 1487
1458(defun mh-mm-inline-message (handle) 1488(defun mh-mm-inline-message (handle)
1459 "Display message, HANDLE. 1489 "Display message, HANDLE.
1460The function decodes the message and displays it. It avoids decoding the same 1490The function decodes the message and displays it. It avoids
1461message multiple times." 1491decoding the same message multiple times."
1462 (let ((b (point)) 1492 (let ((b (point))
1463 (clean-message-header mh-clean-message-header-flag) 1493 (clean-message-header mh-clean-message-header-flag)
1464 (invisible-headers mh-invisible-header-fields-compiled) 1494 (invisible-headers mh-invisible-header-fields-compiled)
diff --git a/lisp/mh-e/mh-pick.el b/lisp/mh-e/mh-pick.el
index a20172ba6f3..03314ffa6c6 100644
--- a/lisp/mh-e/mh-pick.el
+++ b/lisp/mh-e/mh-pick.el
@@ -55,12 +55,12 @@
55 "Search FOLDER for messages matching a pattern. 55 "Search FOLDER for messages matching a pattern.
56 56
57With this command, you can search a folder for messages to or from a 57With this command, you can search a folder for messages to or from a
58particular person or about a particular subject. In fact, you can also search 58particular person or about a particular subject. In fact, you can also
59for messages containing selected strings in any arbitrary header field or any 59search for messages containing selected strings in any arbitrary
60string found within the messages. 60header field or any string found within the messages.
61 61
62You are first prompted for the name of the folder to search and then placed in 62You are first prompted for the name of the folder to search and then
63the following buffer in MH-Pick mode: 63placed in the following buffer in MH-Pick mode:
64 64
65 From: 65 From:
66 To: 66 To:
@@ -69,24 +69,26 @@ the following buffer in MH-Pick mode:
69 Subject: 69 Subject:
70 -------- 70 --------
71 71
72Edit this template by entering your search criteria in an appropriate header 72Edit this template by entering your search criteria in an appropriate
73field that is already there, or create a new field yourself. If the string 73header field that is already there, or create a new field yourself. If
74you're looking for could be anywhere in a message, then place the string 74the string you're looking for could be anywhere in a message, then
75underneath the row of dashes. The \\[mh-search-folder] command uses the MH 75place the string underneath the row of dashes. The
76command \"pick\" to do the real work. 76\\[mh-search-folder] command uses the MH command \"pick\" to do the
77 77real work.
78There are no semantics associated with the search criteria--they are simply 78
79treated as strings. Case is ignored when all lowercase is used, and regular 79There are no semantics associated with the search criteria--they are
80expressions (a la \"ed\") are available. It is all right to specify several 80simply treated as strings. Case is ignored when all lowercase is used,
81search criteria. What happens then is that a logical _and_ of the various 81and regular expressions (a la \"ed\") are available. It is all right
82fields is performed. If you prefer a logical _or_ operation, run 82to specify several search criteria. What happens then is that a
83\\[mh-search-folder] multiple times. 83logical _and_ of the various fields is performed. If you prefer a
84 84logical _or_ operation, run \\[mh-search-folder] multiple times.
85As an example, let's say that we want to find messages from Ginnean about 85
86horseback riding in the Kosciusko National Park (Australia) during January, 86As an example, let's say that we want to find messages from Ginnean
871994. Normally we would start with a broad search and narrow it down if 87about horseback riding in the Kosciusko National Park (Australia)
88necessary to produce a manageable amount of data, but we'll cut to the chase 88during January, 1994. Normally we would start with a broad search and
89and create a fairly restrictive set of criteria as follows: 89narrow it down if necessary to produce a manageable amount of data,
90but we'll cut to the chase and create a fairly restrictive set of
91criteria as follows:
90 92
91 From: ginnean 93 From: ginnean
92 To: 94 To:
@@ -98,29 +100,32 @@ and create a fairly restrictive set of criteria as follows:
98As with MH-Letter mode, MH-Pick provides commands like 100As with MH-Letter mode, MH-Pick provides commands like
99\\<mh-pick-mode-map>\\[mh-to-field] to help you fill in the blanks. 101\\<mh-pick-mode-map>\\[mh-to-field] to help you fill in the blanks.
100 102
101To perform the search, type \\[mh-do-search]. The selected messages are placed 103To perform the search, type \\[mh-do-search]. The selected messages
102in the \"search\" sequence, which you can use later in forwarding, printing, 104are placed in the \"search\" sequence, which you can use later in
103or narrowing your field of view. Subsequent searches are appended to the 105forwarding, printing, or narrowing your field of view. Subsequent
104\"search\" sequence. If, however, you wish to start with a clean slate, first 106searches are appended to the \"search\" sequence. If, however, you
105delete the \"search\" sequence. 107wish to start with a clean slate, first delete the \"search\"
106 108sequence.
107If you're searching in a folder that is already displayed in an MH-Folder 109
108buffer, only those messages contained in the buffer are used for the search. 110If you're searching in a folder that is already displayed in an
109Therefore, if you want to search in all messages, first kill the folder's 111MH-Folder buffer, only those messages contained in the buffer are used
110buffer with \\<mh-folder-mode-map>\\[kill-buffer] or scan the entire folder 112for the search. Therefore, if you want to search in all messages,
111with \\[mh-rescan-folder]. 113first kill the folder's buffer with
112 114\\<mh-folder-mode-map>\\[kill-buffer] or scan the entire folder with
113If you find that you do the same thing over and over when editing the search 115\\[mh-rescan-folder].
114template, you may wish to bind some shortcuts to keys. This can be done with 116
115the variable `mh-pick-mode-hook', which is called when \\[mh-search-folder] is 117If you find that you do the same thing over and over when editing the
116run on a new pattern. 118search template, you may wish to bind some shortcuts to keys. This can
117 119be done with the variable `mh-pick-mode-hook', which is called when
118If you have run the \\[mh-index-search] command, but change your mind while 120\\[mh-search-folder] is run on a new pattern.
119entering the search criteria and actually want to run a regular search, then 121
120you can use the \\<mh-pick-mode-map>\\[mh-pick-do-search] command. 122If you have run the \\[mh-index-search] command, but change your mind
121 123while entering the search criteria and actually want to run a regular
122In a program, argument WINDOW-CONFIG is the current window configuration and 124search, then you can use the \\<mh-pick-mode-map>\\[mh-pick-do-search]
123is used when the search folder is dismissed." 125command.
126
127In a program, argument WINDOW-CONFIG is the current window
128configuration and is used when the search folder is dismissed."
124 (interactive (list (mh-prompt-for-folder "Search" mh-current-folder nil nil t) 129 (interactive (list (mh-prompt-for-folder "Search" mh-current-folder nil nil t)
125 (current-window-configuration))) 130 (current-window-configuration)))
126 (let ((pick-folder (if (equal folder "+") mh-current-folder folder))) 131 (let ((pick-folder (if (equal folder "+") mh-current-folder folder)))
@@ -182,29 +187,28 @@ is used when the search folder is dismissed."
182 "where <field> is the first letter of the desired field.")) 187 "where <field> is the first letter of the desired field."))
183 "Key binding cheat sheet. 188 "Key binding cheat sheet.
184 189
185This is an associative array which is used to show the most common commands. 190This is an associative array which is used to show the most common
186The key is a prefix char. The value is one or more strings which are 191commands. The key is a prefix char. The value is one or more strings
187concatenated together and displayed in the minibuffer if ? is pressed after 192which are concatenated together and displayed in the minibuffer if ?
188the prefix character. The special key nil is used to display the 193is pressed after the prefix character. The special key nil is used to
189non-prefixed commands. 194display the non-prefixed commands.
190 195
191The substitutions described in `substitute-command-keys' are performed as 196The substitutions described in `substitute-command-keys' are performed
192well.") 197as well.")
193 198
194(put 'mh-pick-mode 'mode-class 'special) 199(put 'mh-pick-mode 'mode-class 'special)
195 200
196(define-derived-mode mh-pick-mode fundamental-mode "MH-Pick" 201(define-derived-mode mh-pick-mode fundamental-mode "MH-Pick"
197 "Mode for creating search templates in MH-E.\\<mh-pick-mode-map> 202 "Mode for creating search templates in MH-E.\\<mh-pick-mode-map>
198 203
199After each field name, enter the pattern to search for. If a field's 204After each field name, enter the pattern to search for. If a field's
200value does not matter for the search, leave it empty. To search the 205value does not matter for the search, leave it empty. To search the
201entire message, supply the pattern in the \"body\" of the template. 206entire message, supply the pattern in the \"body\" of the template.
202Each non-empty field must be matched for a message to be selected. 207Each non-empty field must be matched for a message to be selected. To
203To effect a logical \"or\", use \\[mh-search-folder] multiple times. 208effect a logical \"or\", use \\[mh-search-folder] multiple times. When
204When you have finished, type \\[mh-pick-do-search] to do the search. 209you have finished, type \\[mh-pick-do-search] to do the search.
205 210
206The value of `mh-pick-mode-hook' is a list of functions to be called, 211The hook `mh-pick-mode-hook' is called upon entry to this mode.
207with no arguments, upon entry to this mode.
208 212
209\\{mh-pick-mode-map}" 213\\{mh-pick-mode-map}"
210 214
@@ -217,8 +221,10 @@ with no arguments, upon entry to this mode.
217;;;###mh-autoload 221;;;###mh-autoload
218(defun mh-pick-do-search () 222(defun mh-pick-do-search ()
219 "Find messages that match the qualifications in the current pattern buffer. 223 "Find messages that match the qualifications in the current pattern buffer.
220Messages are searched for in the folder named in `mh-searching-folder'. 224
221Add the messages found to the sequence named `search'." 225Messages are searched for in the folder named in
226`mh-searching-folder'. Add the messages found to the sequence
227named \"search\"."
222 (interactive) 228 (interactive)
223 (let ((pattern-list (mh-pick-parse-search-buffer)) 229 (let ((pattern-list (mh-pick-parse-search-buffer))
224 (folder mh-searching-folder) 230 (folder mh-searching-folder)
@@ -252,9 +258,11 @@ Add the messages found to the sequence named `search'."
252;;;###mh-autoload 258;;;###mh-autoload
253(defun mh-do-search () 259(defun mh-do-search ()
254 "Use the default searching function. 260 "Use the default searching function.
255If \\[mh-search-folder] was used to create the search pattern then pick is used 261
256to search the folder. Otherwise if \\[mh-index-search] was used then the 262If \\[mh-search-folder] was used to create the search pattern
257indexing program specified in `mh-index-program' is used." 263then pick is used to search the folder. Otherwise if
264\\[mh-index-search] was used then the indexing program specified
265in `mh-index-program' is used."
258 (interactive) 266 (interactive)
259 (if (symbolp mh-searching-function) 267 (if (symbolp mh-searching-function)
260 (funcall mh-searching-function) 268 (funcall mh-searching-function)
@@ -262,8 +270,8 @@ indexing program specified in `mh-index-program' is used."
262 270
263(defun mh-seq-from-command (folder seq command) 271(defun mh-seq-from-command (folder seq command)
264 "In FOLDER, make a sequence named SEQ by executing COMMAND. 272 "In FOLDER, make a sequence named SEQ by executing COMMAND.
265COMMAND is a list. The first element is a program name 273COMMAND is a list. The first element is a program name and the
266and the subsequent elements are its arguments, all strings." 274subsequent elements are its arguments, all strings."
267 (let ((msg) 275 (let ((msg)
268 (msgs ()) 276 (msgs ())
269 (case-fold-search t)) 277 (case-fold-search t))
@@ -280,9 +288,9 @@ and the subsequent elements are its arguments, all strings."
280 288
281(defun mh-pick-parse-search-buffer () 289(defun mh-pick-parse-search-buffer ()
282 "Parse the search buffer contents. 290 "Parse the search buffer contents.
283The function returns a alist. The car of each element is either the header name 291The function returns a alist. The car of each element is either
284to search in or nil to search the whole message. The cdr of the element is the 292the header name to search in or nil to search the whole message.
285pattern to search." 293The cdr of the element is the pattern to search."
286 (save-excursion 294 (save-excursion
287 (let ((pattern-list ()) 295 (let ((pattern-list ())
288 (in-body-flag nil) 296 (in-body-flag nil)
@@ -329,9 +337,9 @@ COMPONENT is the component to search."
329;; All implementations of pick have special options -cc, -date, -from and 337;; All implementations of pick have special options -cc, -date, -from and
330;; -subject that allow to search for corresponding components. Any other 338;; -subject that allow to search for corresponding components. Any other
331;; component is searched using option --COMPNAME, for example: `pick 339;; component is searched using option --COMPNAME, for example: `pick
332;; --x-mailer mh-e'. Mailutils `pick' supports this option using a certain 340;; --x-mailer mh-e'. Mailutils "pick" supports this option using a certain
333;; kludge, but it prefers the following syntax for this purpose: 341;; kludge, but it prefers the following syntax for this purpose:
334;; `--component=COMPNAME --pattern=PATTERN'. 342;; "--component=COMPNAME --pattern=PATTERN".
335;; -- Sergey Poznyakoff, Aug 2003 343;; -- Sergey Poznyakoff, Aug 2003
336(defun mh-pick-regexp-builder (pattern-list) 344(defun mh-pick-regexp-builder (pattern-list)
337 "Generate pick search expression from PATTERN-LIST." 345 "Generate pick search expression from PATTERN-LIST."
diff --git a/lisp/mh-e/mh-print.el b/lisp/mh-e/mh-print.el
index acca58c494f..a4d53731c72 100644
--- a/lisp/mh-e/mh-print.el
+++ b/lisp/mh-e/mh-print.el
@@ -47,8 +47,8 @@ Valid values are:
47 black-white - Print colors on black/white printer. 47 black-white - Print colors on black/white printer.
48 See also `ps-black-white-faces'. 48 See also `ps-black-white-faces'.
49 49
50Any other value is treated as t. This variable is initialized from 50Any other value is treated as t. This variable is initialized
51`ps-print-color-p'.") 51from `ps-print-color-p'.")
52 52
53(defvar mh-ps-print-func 'ps-spool-buffer-with-faces 53(defvar mh-ps-print-func 'ps-spool-buffer-with-faces
54 "Function to use to spool a buffer. 54 "Function to use to spool a buffer.
@@ -108,20 +108,22 @@ Pass along the PREFIX-ARG to it."
108(defun mh-ps-print-msg (range) 108(defun mh-ps-print-msg (range)
109 "Print RANGE\\<mh-folder-mode-map>. 109 "Print RANGE\\<mh-folder-mode-map>.
110 110
111Check the documentation of `mh-interactive-range' to see how RANGE is read in 111Check the documentation of `mh-interactive-range' to see how RANGE is
112interactive use. 112read in interactive use.
113 113
114This command will print inline text attachments but will not decrypt messages. 114This command will print inline text attachments but will not decrypt
115However, when a message is displayed in an MH-Show buffer, then that buffer is 115messages. However, when a message is displayed in an MH-Show buffer,
116used verbatim for printing with the caveat that only text attachments, if 116then that buffer is used verbatim for printing with the caveat that
117opened inline, are printed. Therefore, encrypted messages can be printed by 117only text attachments, if opened inline, are printed. Therefore,
118showing and decrypting them first. 118encrypted messages can be printed by showing and decrypting them
119 119first.
120MH-E uses the \"ps-print\" package to do the printing, so you can customize 120
121the printing further by going to the `ps-print' customization group. This 121MH-E uses the \"ps-print\" package to do the printing, so you can
122command does not use the options `mh-lpr-command-format' or 122customize the printing further by going to the `ps-print'
123`mh-print-background-flag'. See also the commands \\[mh-ps-print-toggle-color] 123customization group. This command does not use the options
124and \\[mh-ps-print-toggle-faces]." 124`mh-lpr-command-format' or `mh-print-background-flag'. See also the
125commands \\[mh-ps-print-toggle-color] and
126\\[mh-ps-print-toggle-faces]."
125 (interactive (list (mh-interactive-range "Print"))) 127 (interactive (list (mh-interactive-range "Print")))
126 (mh-ps-print-range range nil)) 128 (mh-ps-print-range range nil))
127 129
@@ -129,20 +131,22 @@ and \\[mh-ps-print-toggle-faces]."
129(defun mh-ps-print-msg-file (range file) 131(defun mh-ps-print-msg-file (range file)
130 "Print RANGE to FILE\\<mh-folder-mode-map>. 132 "Print RANGE to FILE\\<mh-folder-mode-map>.
131 133
132Check the documentation of `mh-interactive-range' to see how RANGE is read in 134Check the documentation of `mh-interactive-range' to see how RANGE is
133interactive use. 135read in interactive use.
134 136
135This command will print inline text attachments but will not decrypt messages. 137This command will print inline text attachments but will not decrypt
136However, when a message is displayed in an MH-Show buffer, then that buffer is 138messages. However, when a message is displayed in an MH-Show buffer,
137used verbatim for printing with the caveat that only text attachments, if 139then that buffer is used verbatim for printing with the caveat that
138opened inline, are printed. Therefore, encrypted messages can be printed by 140only text attachments, if opened inline, are printed. Therefore,
139showing and decrypting them first. 141encrypted messages can be printed by showing and decrypting them
140 142first.
141MH-E uses the \"ps-print\" package to do the printing, so you can customize 143
142the printing further by going to the `ps-print' customization group. This 144MH-E uses the \"ps-print\" package to do the printing, so you can
143command does not use the options `mh-lpr-command-format' or 145customize the printing further by going to the `ps-print'
144`mh-print-background-flag'. See also the commands \\[mh-ps-print-toggle-color] 146customization group. This command does not use the options
145and \\[mh-ps-print-toggle-faces]." 147`mh-lpr-command-format' or `mh-print-background-flag'. See also the
148commands \\[mh-ps-print-toggle-color] and
149\\[mh-ps-print-toggle-faces]."
146 (interactive (list (mh-interactive-range "Print") (mh-ps-print-preprint 1))) 150 (interactive (list (mh-interactive-range "Print") (mh-ps-print-preprint 1)))
147 (mh-ps-print-range range file)) 151 (mh-ps-print-range range file))
148 152
@@ -150,8 +154,8 @@ and \\[mh-ps-print-toggle-faces]."
150(defun mh-ps-print-toggle-faces () 154(defun mh-ps-print-toggle-faces ()
151 "Toggle whether printing is done with faces or not. 155 "Toggle whether printing is done with faces or not.
152 156
153When faces are enabled, the printed message will look very similar to the 157When faces are enabled, the printed message will look very
154message in the MH-Show buffer." 158similar to the message in the MH-Show buffer."
155 (interactive) 159 (interactive)
156 (if (eq mh-ps-print-func 'ps-spool-buffer-with-faces) 160 (if (eq mh-ps-print-func 'ps-spool-buffer-with-faces)
157 (progn 161 (progn
@@ -164,13 +168,13 @@ message in the MH-Show buffer."
164(defun mh-ps-print-toggle-color () 168(defun mh-ps-print-toggle-color ()
165 "Toggle whether color is used in printing messages. 169 "Toggle whether color is used in printing messages.
166 170
167Colors are emulated on black-and-white printers with shades of gray. This 171Colors are emulated on black-and-white printers with shades of
168might produce illegible output, even if your screen colors only use shades of 172gray. This might produce illegible output, even if your screen
169gray. If this is the case, try using this command to toggle between color, no 173colors only use shades of gray. If this is the case, try using
170color, and a black and white representation of the colors and see which works 174this command to toggle between color, no color, and a black and
171best. You change this setting permanently by customizing the option 175white representation of the colors and see which works best. You
176change this setting permanently by customizing the option
172`ps-print-color-p'." 177`ps-print-color-p'."
173
174 (interactive) 178 (interactive)
175 (if (eq mh-ps-print-color-option nil) 179 (if (eq mh-ps-print-color-option nil)
176 (progn 180 (progn
@@ -188,11 +192,12 @@ best. You change this setting permanently by customizing the option
188(defun mh-print-msg (range) 192(defun mh-print-msg (range)
189 "Print RANGE the old fashioned way\\<mh-folder-mode-map>. 193 "Print RANGE the old fashioned way\\<mh-folder-mode-map>.
190 194
191The message is formatted with \"mhl\" (see option `mh-mhl-format-file') and 195The message is formatted with \"mhl\" (see option
192printed with the \"lpr\" command (see option `mh-lpr-command-format'). 196`mh-mhl-format-file') and printed with the \"lpr\" command (see
197option `mh-lpr-command-format').
193 198
194Check the documentation of `mh-interactive-range' to see how RANGE is read in 199Check the documentation of `mh-interactive-range' to see how
195interactive use. 200RANGE is read in interactive use.
196 201
197Consider using \\[mh-ps-print-msg] instead." 202Consider using \\[mh-ps-print-msg] instead."
198 (interactive (list (mh-interactive-range "Print"))) 203 (interactive (list (mh-interactive-range "Print")))
diff --git a/lisp/mh-e/mh-seq.el b/lisp/mh-e/mh-seq.el
index 4942df58f71..6fb70e61de8 100644
--- a/lisp/mh-e/mh-seq.el
+++ b/lisp/mh-e/mh-seq.el
@@ -122,16 +122,18 @@
122 "Map of message index to various parts of the scan line.") 122 "Map of message index to various parts of the scan line.")
123(defvar mh-thread-scan-line-map-stack nil 123(defvar mh-thread-scan-line-map-stack nil
124 "Old map of message index to various parts of the scan line. 124 "Old map of message index to various parts of the scan line.
125This is the original map that is stored when the folder is narrowed.") 125This is the original map that is stored when the folder is
126narrowed.")
126(defvar mh-thread-subject-container-hash nil 127(defvar mh-thread-subject-container-hash nil
127 "Hashtable used to group messages by subject.") 128 "Hashtable used to group messages by subject.")
128(defvar mh-thread-duplicates nil 129(defvar mh-thread-duplicates nil
129 "Hashtable used to associate messages with the same message identifier.") 130 "Hashtable used to associate messages with the same message identifier.")
130(defvar mh-thread-history () 131(defvar mh-thread-history ()
131 "Variable to remember the transformations to the thread tree. 132 "Variable to remember the transformations to the thread tree.
132When new messages are added, these transformations are rewound, then the 133When new messages are added, these transformations are rewound,
133links are added from the newly seen messages. Finally the transformations are 134then the links are added from the newly seen messages. Finally
134redone to get the new thread tree. This makes incremental threading easier.") 135the transformations are redone to get the new thread tree. This
136makes incremental threading easier.")
135(defvar mh-thread-body-width nil 137(defvar mh-thread-body-width nil
136 "Width of scan substring that contains subject and body of message.") 138 "Width of scan substring that contains subject and body of message.")
137 139
@@ -150,9 +152,10 @@ redone to get the new thread tree. This makes incremental threading easier.")
150(defun mh-delete-seq (sequence) 152(defun mh-delete-seq (sequence)
151 "Delete SEQUENCE. 153 "Delete SEQUENCE.
152 154
153You are prompted for the sequence to delete. Note that this deletes only the 155You are prompted for the sequence to delete. Note that this
154sequence, not the messages in the sequence. If you want to delete the 156deletes only the sequence, not the messages in the sequence. If
155messages, use \"\\[universal-argument] \\[mh-delete-msg]\"." 157you want to delete the messages, use \"\\[universal-argument]
158\\[mh-delete-msg]\"."
156 (interactive (list (mh-read-seq-default "Delete" t))) 159 (interactive (list (mh-read-seq-default "Delete" t)))
157 (let ((msg-list (mh-seq-to-msgs sequence)) 160 (let ((msg-list (mh-seq-to-msgs sequence))
158 (internal-flag (mh-internal-seq sequence)) 161 (internal-flag (mh-internal-seq sequence))
@@ -216,8 +219,8 @@ The list appears in a buffer named \"*MH-E Sequences*\"."
216;;;###mh-autoload 219;;;###mh-autoload
217(defun mh-msg-is-in-seq (message) 220(defun mh-msg-is-in-seq (message)
218 "Display the sequences in which the current message appears. 221 "Display the sequences in which the current message appears.
219Use a prefix argument to display the sequences in which another MESSAGE 222Use a prefix argument to display the sequences in which another
220appears." 223MESSAGE appears."
221 (interactive "P") 224 (interactive "P")
222 (if (not message) 225 (if (not message)
223 (setq message (mh-get-msg-num t))) 226 (setq message (mh-get-msg-num t)))
@@ -243,11 +246,13 @@ appears."
243(defun mh-narrow-to-seq (sequence) 246(defun mh-narrow-to-seq (sequence)
244 "Restrict display to messages in SEQUENCE. 247 "Restrict display to messages in SEQUENCE.
245 248
246You are prompted for the name of the sequence. What this command does is show 249You are prompted for the name of the sequence. What this command
247only those messages that are in the selected sequence in the MH-Folder buffer. 250does is show only those messages that are in the selected
248In addition, it limits further MH-E searches to just those messages. 251sequence in the MH-Folder buffer. In addition, it limits further
252MH-E searches to just those messages.
249 253
250When you want to widen the view to all your messages again, use \\[mh-widen]." 254When you want to widen the view to all your messages again, use
255\\[mh-widen]."
251 (interactive (list (mh-read-seq "Narrow to" t))) 256 (interactive (list (mh-read-seq "Narrow to" t)))
252 (with-mh-folder-updating (t) 257 (with-mh-folder-updating (t)
253 (cond ((mh-seq-to-msgs sequence) 258 (cond ((mh-seq-to-msgs sequence)
@@ -277,24 +282,27 @@ When you want to widen the view to all your messages again, use \\[mh-widen]."
277 mh-show-seq-tool-bar-map)))) 282 mh-show-seq-tool-bar-map))))
278 (push 'widen mh-view-ops))) 283 (push 'widen mh-view-ops)))
279 (t 284 (t
280 (error "No messages in sequence `%s'" (symbol-name sequence)))))) 285 (error "No messages in sequence \"%s\"" (symbol-name sequence))))))
281 286
282;;;###mh-autoload 287;;;###mh-autoload
283(defun mh-put-msg-in-seq (range sequence) 288(defun mh-put-msg-in-seq (range sequence)
284 "Add RANGE to SEQUENCE\\<mh-folder-mode-map>. 289 "Add RANGE to SEQUENCE\\<mh-folder-mode-map>.
285 290
286To place a message in a sequence, use this command to do it manually, or use 291To place a message in a sequence, use this command to do it
287the MH command \"pick\" or the MH-E version of \"pick\", \\[mh-search-folder], 292manually, or use the MH command \"pick\" or the MH-E version of
288which create a sequence automatically. 293\"pick\", \\[mh-search-folder], which create a sequence
289 294automatically.
290Give this command a RANGE and you can add all the messages in a sequence to 295
291another sequence (for example, \"\\[universal-argument] \\[mh-put-msg-in-seq] 296Give this command a RANGE and you can add all the messages in a
292SourceSequence RET DestSequence RET\"). Check the documentation of 297sequence to another sequence (for example,
293`mh-interactive-range' to see how RANGE is read in interactive use." 298\"\\[universal-argument] \\[mh-put-msg-in-seq] SourceSequence RET
299DestSequence RET\"). Check the documentation of
300`mh-interactive-range' to see how RANGE is read in interactive
301use."
294 (interactive (list (mh-interactive-range "Add messages from") 302 (interactive (list (mh-interactive-range "Add messages from")
295 (mh-read-seq-default "Add to" nil))) 303 (mh-read-seq-default "Add to" nil)))
296 (unless (mh-valid-seq-p sequence) 304 (unless (mh-valid-seq-p sequence)
297 (error "Can't put message in invalid sequence `%s'" sequence)) 305 (error "Can't put message in invalid sequence \"%s\"" sequence))
298 (let* ((internal-seq-flag (mh-internal-seq sequence)) 306 (let* ((internal-seq-flag (mh-internal-seq sequence))
299 (original-msgs (mh-seq-msgs (mh-find-seq sequence))) 307 (original-msgs (mh-seq-msgs (mh-find-seq sequence)))
300 (folders (list mh-current-folder)) 308 (folders (list mh-current-folder))
@@ -321,7 +329,8 @@ OP is one of 'widen and 'unthread."
321;;;###mh-autoload 329;;;###mh-autoload
322(defun mh-widen (&optional all-flag) 330(defun mh-widen (&optional all-flag)
323 "Remove last restriction. 331 "Remove last restriction.
324If optional prefix argument ALL-FLAG is non-nil, remove all limits." 332If optional prefix argument ALL-FLAG is non-nil, remove all
333limits."
325 (interactive "P") 334 (interactive "P")
326 (let ((msg (mh-get-msg-num nil))) 335 (let ((msg (mh-get-msg-num nil)))
327 (when mh-folder-view-stack 336 (when mh-folder-view-stack
@@ -368,8 +377,8 @@ If optional prefix argument ALL-FLAG is non-nil, remove all limits."
368;;;###mh-autoload 377;;;###mh-autoload
369(defun mh-notate-deleted-and-refiled () 378(defun mh-notate-deleted-and-refiled ()
370 "Notate messages marked for deletion or refiling. 379 "Notate messages marked for deletion or refiling.
371Messages to be deleted are given by `mh-delete-list' while messages to be 380Messages to be deleted are given by `mh-delete-list' while
372refiled are present in `mh-refile-list'." 381messages to be refiled are present in `mh-refile-list'."
373 (let ((refiled-hash (make-hash-table)) 382 (let ((refiled-hash (make-hash-table))
374 (deleted-hash (make-hash-table))) 383 (deleted-hash (make-hash-table)))
375 (dolist (msg mh-delete-list) 384 (dolist (msg mh-delete-list)
@@ -395,17 +404,18 @@ refiled are present in `mh-refile-list'."
395;;;###mh-autoload 404;;;###mh-autoload
396(defun mh-read-seq-default (prompt not-empty) 405(defun mh-read-seq-default (prompt not-empty)
397 "Read and return sequence name with default narrowed or previous sequence. 406 "Read and return sequence name with default narrowed or previous sequence.
398PROMPT is the prompt to use when reading. If NOT-EMPTY is non-nil then a 407PROMPT is the prompt to use when reading. If NOT-EMPTY is non-nil
399non-empty sequence is read." 408then a non-empty sequence is read."
400 (mh-read-seq prompt not-empty 409 (mh-read-seq prompt not-empty
401 (or mh-last-seq-used 410 (or mh-last-seq-used
402 (car (mh-seq-containing-msg (mh-get-msg-num nil) nil))))) 411 (car (mh-seq-containing-msg (mh-get-msg-num nil) nil)))))
403 412
404(defun mh-read-seq (prompt not-empty &optional default) 413(defun mh-read-seq (prompt not-empty &optional default)
405 "Read and return a sequence name. 414 "Read and return a sequence name.
406Prompt with PROMPT, raise an error if the sequence is empty and the NOT-EMPTY 415Prompt with PROMPT, raise an error if the sequence is empty and
407flag is non-nil, and supply an optional DEFAULT sequence. A reply of '%' 416the NOT-EMPTY flag is non-nil, and supply an optional DEFAULT
408defaults to the first sequence containing the current message." 417sequence. A reply of '%' defaults to the first sequence
418containing the current message."
409 (let* ((input (completing-read (format "%s %s %s" prompt "sequence:" 419 (let* ((input (completing-read (format "%s %s %s" prompt "sequence:"
410 (if default 420 (if default
411 (format "[%s] " default) 421 (format "[%s] " default)
@@ -418,7 +428,7 @@ defaults to the first sequence containing the current message."
418 (t (intern input)))) 428 (t (intern input))))
419 (msgs (mh-seq-to-msgs seq))) 429 (msgs (mh-seq-to-msgs seq)))
420 (if (and (null msgs) not-empty) 430 (if (and (null msgs) not-empty)
421 (error "No messages in sequence `%s'" seq)) 431 (error "No messages in sequence \"%s\"" seq))
422 seq)) 432 seq))
423 433
424 434
@@ -459,35 +469,40 @@ completion is over."
459 expand-flag ask-flag number-as-range-flag) 469 expand-flag ask-flag number-as-range-flag)
460 "Read a message range with PROMPT. 470 "Read a message range with PROMPT.
461 471
462If FOLDER is non-nil then a range is read from that folder, otherwise use 472If FOLDER is non-nil then a range is read from that folder, otherwise
463`mh-current-folder'. 473use `mh-current-folder'.
464 474
465If DEFAULT is a string then use that as default range to return. If DEFAULT is 475If DEFAULT is a string then use that as default range to return. If
466nil then ask user with default answer a range based on the sequences that seem 476DEFAULT is nil then ask user with default answer a range based on the
467relevant. Finally if DEFAULT is t, try to avoid prompting the user. Unseen 477sequences that seem relevant. Finally if DEFAULT is t, try to avoid
468messages, if present, are returned. If the folder has fewer than 478prompting the user. Unseen messages, if present, are returned. If the
469`mh-large-folder' messages then \"all\" messages are returned. Finally as a 479folder has fewer than `mh-large-folder' messages then \"all\" messages
470last resort prompt the user. 480are returned. Finally as a last resort prompt the user.
471 481
472If EXPAND-FLAG is non-nil then a list of message numbers corresponding to the 482If EXPAND-FLAG is non-nil then a list of message numbers corresponding
473input is returned. If this list is empty then an error is raised. If 483to the input is returned. If this list is empty then an error is
474EXPAND-FLAG is nil just return the input string. In this case we don't check 484raised. If EXPAND-FLAG is nil just return the input string. In this
475if the range is empty. 485case we don't check if the range is empty.
476 486
477If ASK-FLAG is non-nil, then the user is always queried for a range of 487If ASK-FLAG is non-nil, then the user is always queried for a range of
478messages. If ASK-FLAG is nil, then the function checks if the unseen sequence 488messages. If ASK-FLAG is nil, then the function checks if the unseen
479is non-empty. If that is the case, `mh-unseen-seq', or the list of messages in 489sequence is non-empty. If that is the case, `mh-unseen-seq', or the
480it depending on the value of EXPAND, is returned. Otherwise if the folder has 490list of messages in it depending on the value of EXPAND, is returned.
481fewer than `mh-large-folder' messages then the list of messages corresponding 491Otherwise if the folder has fewer than `mh-large-folder' messages then
482to \"all\" is returned. If neither of the above holds then as a last resort 492the list of messages corresponding to \"all\" is returned. If neither
483the user is queried for a range of messages. 493of the above holds then as a last resort the user is queried for a
494range of messages.
484 495
485If NUMBER-AS-RANGE-FLAG is non-nil, then if a number, N is read as input, it 496If NUMBER-AS-RANGE-FLAG is non-nil, then if a number, N is read as
486is interpreted as the range \"last:N\". 497input, it is interpreted as the range \"last:N\".
498
499This function replaces the existing function `mh-read-msg-range'.
500Calls to:
487 501
488This function replaces the existing function `mh-read-msg-range'. Calls to:
489 (mh-read-msg-range folder flag) 502 (mh-read-msg-range folder flag)
503
490should be replaced with: 504should be replaced with:
505
491 (mh-read-range \"Suitable prompt\" folder t nil flag 506 (mh-read-range \"Suitable prompt\" folder t nil flag
492 mh-interpret-number-as-range-flag)" 507 mh-interpret-number-as-range-flag)"
493 (setq default (or default mh-last-seq-used 508 (setq default (or default mh-last-seq-used
@@ -528,7 +543,7 @@ should be replaced with:
528 ((assoc (intern input) seq-list) 543 ((assoc (intern input) seq-list)
529 (cdr (assoc (intern input) seq-list))) 544 (cdr (assoc (intern input) seq-list)))
530 ((setq msg-list (mh-translate-range folder input)) msg-list) 545 ((setq msg-list (mh-translate-range folder input)) msg-list)
531 (t (error "No messages in range `%s'" input))))) 546 (t (error "No messages in range \"%s\"" input)))))
532 547
533;;;###mh-autoload 548;;;###mh-autoload
534(defun mh-translate-range (folder expr) 549(defun mh-translate-range (folder expr)
@@ -565,8 +580,9 @@ should be replaced with:
565;;;###mh-autoload 580;;;###mh-autoload
566(defun mh-notate-cur () 581(defun mh-notate-cur ()
567 "Mark the MH sequence cur. 582 "Mark the MH sequence cur.
568In addition to notating the current message with `mh-note-cur' the function 583In addition to notating the current message with `mh-note-cur'
569uses `overlay-arrow-position' to put a marker in the fringe." 584the function uses `overlay-arrow-position' to put a marker in the
585fringe."
570 (let ((cur (car (mh-seq-to-msgs 'cur)))) 586 (let ((cur (car (mh-seq-to-msgs 'cur))))
571 (when (and cur (mh-goto-msg cur t t)) 587 (when (and cur (mh-goto-msg cur t t))
572 (beginning-of-line) 588 (beginning-of-line)
@@ -617,8 +633,9 @@ uses `overlay-arrow-position' to put a marker in the fringe."
617;;;###mh-autoload 633;;;###mh-autoload
618(defmacro mh-iterate-on-messages-in-region (var begin end &rest body) 634(defmacro mh-iterate-on-messages-in-region (var begin end &rest body)
619 "Iterate over region. 635 "Iterate over region.
620VAR is bound to the message on the current line as we loop starting from BEGIN 636
621till END. In each step BODY is executed. 637VAR is bound to the message on the current line as we loop
638starting from BEGIN till END. In each step BODY is executed.
622 639
623If VAR is nil then the loop is executed without any binding." 640If VAR is nil then the loop is executed without any binding."
624 (unless (symbolp var) 641 (unless (symbolp var)
@@ -639,13 +656,14 @@ If VAR is nil then the loop is executed without any binding."
639(defmacro mh-iterate-on-range (var range &rest body) 656(defmacro mh-iterate-on-range (var range &rest body)
640 "Iterate an operation over a region or sequence. 657 "Iterate an operation over a region or sequence.
641 658
642VAR is bound to each message in turn in a loop over RANGE, which can be a 659VAR is bound to each message in turn in a loop over RANGE, which
643message number, a list of message numbers, a sequence, a region in a cons 660can be a message number, a list of message numbers, a sequence, a
644cell, or a MH range (something like last:20) in a string. In each iteration, 661region in a cons cell, or a MH range (something like last:20) in
645BODY is executed. 662a string. In each iteration, BODY is executed.
646 663
647The parameter RANGE is usually created with `mh-interactive-range' 664The parameter RANGE is usually created with
648in order to provide a uniform interface to MH-E functions." 665`mh-interactive-range' in order to provide a uniform interface to
666MH-E functions."
649 (unless (symbolp var) 667 (unless (symbolp var)
650 (error "Can not bind the non-symbol %s" var)) 668 (error "Can not bind the non-symbol %s" var))
651 (let ((binding-needed-flag var) 669 (let ((binding-needed-flag var)
@@ -680,8 +698,8 @@ in order to provide a uniform interface to MH-E functions."
680(defun mh-range-to-msg-list (range) 698(defun mh-range-to-msg-list (range)
681 "Return a list of messages for RANGE. 699 "Return a list of messages for RANGE.
682 700
683Check the documentation of `mh-interactive-range' to see how RANGE is read in 701Check the documentation of `mh-interactive-range' to see how
684interactive use." 702RANGE is read in interactive use."
685 (let (msg-list) 703 (let (msg-list)
686 (mh-iterate-on-range msg range 704 (mh-iterate-on-range msg range
687 (push msg msg-list)) 705 (push msg msg-list))
@@ -692,21 +710,21 @@ interactive use."
692 "Return interactive specification for message, sequence, range or region. 710 "Return interactive specification for message, sequence, range or region.
693By convention, the name of this argument is RANGE. 711By convention, the name of this argument is RANGE.
694 712
695If variable `transient-mark-mode' is non-nil and the mark is active, then this 713If variable `transient-mark-mode' is non-nil and the mark is active,
696function returns a cons-cell of the region. 714then this function returns a cons-cell of the region.
697 715
698If optional prefix argument is provided, then prompt for message range with 716If optional prefix argument is provided, then prompt for message range
699RANGE-PROMPT. A list of messages in that range is returned. 717with RANGE-PROMPT. A list of messages in that range is returned.
700 718
701If a MH range is given, say something like last:20, then a list containing 719If a MH range is given, say something like last:20, then a list
702the messages in that range is returned. 720containing the messages in that range is returned.
703 721
704If DEFAULT non-nil then it is returned. 722If DEFAULT non-nil then it is returned.
705 723
706Otherwise, the message number at point is returned. 724Otherwise, the message number at point is returned.
707 725
708This function is usually used with `mh-iterate-on-range' in order to provide 726This function is usually used with `mh-iterate-on-range' in order to
709a uniform interface to MH-E functions." 727provide a uniform interface to MH-E functions."
710 (cond ((mh-mark-active-p t) (cons (region-beginning) (region-end))) 728 (cond ((mh-mark-active-p t) (cons (region-beginning) (region-end)))
711 (current-prefix-arg (mh-read-range range-prompt nil nil t t)) 729 (current-prefix-arg (mh-read-range range-prompt nil nil t t))
712 (default default) 730 (default default)
@@ -720,13 +738,17 @@ a uniform interface to MH-E functions."
720;; 41 for the max size of the subject part. Avoiding this would be desirable. 738;; 41 for the max size of the subject part. Avoiding this would be desirable.
721(defun mh-subject-to-sequence (all) 739(defun mh-subject-to-sequence (all)
722 "Put all following messages with same subject in sequence 'subject. 740 "Put all following messages with same subject in sequence 'subject.
723If arg ALL is t, move to beginning of folder buffer to collect all messages. 741If arg ALL is t, move to beginning of folder buffer to collect all
742messages.
724If arg ALL is nil, collect only messages fron current one on forward. 743If arg ALL is nil, collect only messages fron current one on forward.
725 744
726Return number of messages put in the sequence: 745Return number of messages put in the sequence:
727 746
728 nil -> there was no subject line. 747 nil -> there was no subject line.
729 0 -> there were no later messages with the same subject (sequence not made) 748
749 0 -> there were no later messages with the same
750 subject (sequence not made)
751
730 >1 -> the total number of messages including current one." 752 >1 -> the total number of messages including current one."
731 (if (memq 'unthread mh-view-ops) 753 (if (memq 'unthread mh-view-ops)
732 (mh-subject-to-sequence-threaded all) 754 (mh-subject-to-sequence-threaded all)
@@ -734,14 +756,17 @@ Return number of messages put in the sequence:
734 756
735(defun mh-subject-to-sequence-unthreaded (all) 757(defun mh-subject-to-sequence-unthreaded (all)
736 "Put all following messages with same subject in sequence 'subject. 758 "Put all following messages with same subject in sequence 'subject.
737This function only works with an unthreaded folder. If arg ALL is t, move to 759
738beginning of folder buffer to collect all messages. If arg ALL is nil, collect 760This function only works with an unthreaded folder. If arg ALL is
739only messages fron current one on forward. 761t, move to beginning of folder buffer to collect all messages. If
762arg ALL is nil, collect only messages fron current one on
763forward.
740 764
741Return number of messages put in the sequence: 765Return number of messages put in the sequence:
742 766
743 nil -> there was no subject line. 767 nil -> there was no subject line.
744 0 -> there were no later messages with the same subject (sequence not made) 768 0 -> there were no later messages with the same
769 subject (sequence not made)
745 >1 -> the total number of messages including current one." 770 >1 -> the total number of messages including current one."
746 (if (not (eq major-mode 'mh-folder-mode)) 771 (if (not (eq major-mode 'mh-folder-mode))
747 (error "Not in a folder buffer")) 772 (error "Not in a folder buffer"))
@@ -782,12 +807,14 @@ Return number of messages put in the sequence:
782 807
783(defun mh-subject-to-sequence-threaded (all) 808(defun mh-subject-to-sequence-threaded (all)
784 "Put all messages with the same subject in the 'subject sequence. 809 "Put all messages with the same subject in the 'subject sequence.
785This function works when the folder is threaded. In this situation the subject
786could get truncated and so the normal matching doesn't work.
787 810
788The parameter ALL is non-nil then all the messages in the buffer are 811This function works when the folder is threaded. In this
789considered, otherwise only the messages after the current one are taken into 812situation the subject could get truncated and so the normal
790account." 813matching doesn't work.
814
815The parameter ALL is non-nil then all the messages in the buffer
816are considered, otherwise only the messages after the current one
817are taken into account."
791 (let* ((cur (mh-get-msg-num nil)) 818 (let* ((cur (mh-get-msg-num nil))
792 (subject (mh-thread-find-msg-subject cur)) 819 (subject (mh-thread-find-msg-subject cur))
793 region msgs) 820 region msgs)
@@ -824,9 +851,9 @@ If no prefix arg is given, then return DEFAULT."
824 851
825(defun mh-pick-args-list (s) 852(defun mh-pick-args-list (s)
826 "Form list by grouping elements in string S suitable for pick arguments. 853 "Form list by grouping elements in string S suitable for pick arguments.
827For example, the string \"-subject a b c -from Joe User <user@domain.com>\" 854For example, the string \"-subject a b c -from Joe User
828is converted to (\"-subject\" \"a b c\" \"-from\" 855<user@domain.com>\" is converted to (\"-subject\" \"a b c\"
829\"Joe User <user@domain.com>\"" 856\"-from\" \"Joe User <user@domain.com>\""
830 (let ((full-list (split-string s)) 857 (let ((full-list (split-string s))
831 current-arg collection arg-list) 858 current-arg collection arg-list)
832 (while full-list 859 (while full-list
@@ -857,7 +884,7 @@ Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command."
857 884
858;;;###mh-autoload 885;;;###mh-autoload
859(defun mh-narrow-to-from (&optional pick-expr) 886(defun mh-narrow-to-from (&optional pick-expr)
860 "Limit to messages with the same `From:' field. 887 "Limit to messages with the same \"From:\" field.
861With a prefix argument, edit PICK-EXPR. 888With a prefix argument, edit PICK-EXPR.
862 889
863Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command." 890Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command."
@@ -867,7 +894,7 @@ Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command."
867 894
868;;;###mh-autoload 895;;;###mh-autoload
869(defun mh-narrow-to-cc (&optional pick-expr) 896(defun mh-narrow-to-cc (&optional pick-expr)
870 "Limit to messages with the same `Cc:' field. 897 "Limit to messages with the same \"Cc:\" field.
871With a prefix argument, edit PICK-EXPR. 898With a prefix argument, edit PICK-EXPR.
872 899
873Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command." 900Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command."
@@ -877,7 +904,7 @@ Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command."
877 904
878;;;###mh-autoload 905;;;###mh-autoload
879(defun mh-narrow-to-to (&optional pick-expr) 906(defun mh-narrow-to-to (&optional pick-expr)
880 "Limit to messages with the same `To:' field. 907 "Limit to messages with the same \"To:\" field.
881With a prefix argument, edit PICK-EXPR. 908With a prefix argument, edit PICK-EXPR.
882 909
883Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command." 910Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command."
@@ -935,8 +962,8 @@ The MH command pick is used to do the match."
935(defun mh-narrow-to-range (range) 962(defun mh-narrow-to-range (range)
936 "Limit to RANGE. 963 "Limit to RANGE.
937 964
938Check the documentation of `mh-interactive-range' to see how RANGE is read in 965Check the documentation of `mh-interactive-range' to see how
939interactive use. 966RANGE is read in interactive use.
940 967
941Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command." 968Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command."
942 (interactive (list (mh-interactive-range "Narrow to"))) 969 (interactive (list (mh-interactive-range "Narrow to")))
@@ -949,10 +976,11 @@ Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command."
949(defun mh-delete-subject () 976(defun mh-delete-subject ()
950 "Delete messages with same subject\\<mh-folder-mode-map>. 977 "Delete messages with same subject\\<mh-folder-mode-map>.
951 978
952To delete messages faster, you can use this command to delete all the messages 979To delete messages faster, you can use this command to delete all
953with the same subject as the current message. This command puts these messages 980the messages with the same subject as the current message. This
954in a sequence named \"subject\". You can undo this action by using \\[mh-undo] 981command puts these messages in a sequence named \"subject\". You
955with a prefix argument and then specifying the \"subject\" sequence." 982can undo this action by using \\[mh-undo] with a prefix argument
983and then specifying the \"subject\" sequence."
956 (interactive) 984 (interactive)
957 (let ((count (mh-subject-to-sequence nil))) 985 (let ((count (mh-subject-to-sequence nil)))
958 (cond 986 (cond
@@ -969,13 +997,14 @@ with a prefix argument and then specifying the \"subject\" sequence."
969(defun mh-delete-subject-or-thread () 997(defun mh-delete-subject-or-thread ()
970 "Delete messages with same subject or thread\\<mh-folder-mode-map>. 998 "Delete messages with same subject or thread\\<mh-folder-mode-map>.
971 999
972To delete messages faster, you can use this command to delete all the messages 1000To delete messages faster, you can use this command to delete all
973with the same subject as the current message. This command puts these messages 1001the messages with the same subject as the current message. This
974in a sequence named \"subject\". You can undo this action by using \\[mh-undo] 1002command puts these messages in a sequence named \"subject\". You
975with a prefix argument and then specifying the \"subject\" sequence. 1003can undo this action by using \\[mh-undo] with a prefix argument
1004and then specifying the \"subject\" sequence.
976 1005
977However, if the buffer is displaying a threaded view of the folder then this 1006However, if the buffer is displaying a threaded view of the
978command behaves like \\[mh-thread-delete]." 1007folder then this command behaves like \\[mh-thread-delete]."
979 (interactive) 1008 (interactive)
980 (if (memq 'unthread mh-view-ops) 1009 (if (memq 'unthread mh-view-ops)
981 (mh-thread-delete) 1010 (mh-thread-delete)
@@ -1005,8 +1034,8 @@ TEST is the test to use when creating a new hash table."
1005 1034
1006(defsubst mh-thread-id-container (id) 1035(defsubst mh-thread-id-container (id)
1007 "Given ID, return the corresponding container in `mh-thread-id-table'. 1036 "Given ID, return the corresponding container in `mh-thread-id-table'.
1008If no container exists then a suitable container is created and the id-table 1037If no container exists then a suitable container is created and
1009is updated." 1038the id-table is updated."
1010 (when (not id) 1039 (when (not id)
1011 (error "1")) 1040 (error "1"))
1012 (or (gethash id mh-thread-id-table) 1041 (or (gethash id mh-thread-id-table)
@@ -1027,9 +1056,9 @@ is updated."
1027 1056
1028(defsubst mh-thread-add-link (parent child &optional at-end-p) 1057(defsubst mh-thread-add-link (parent child &optional at-end-p)
1029 "Add links so that PARENT becomes a parent of CHILD. 1058 "Add links so that PARENT becomes a parent of CHILD.
1030Doesn't make any changes if CHILD is already an ancestor of PARENT. If 1059Doesn't make any changes if CHILD is already an ancestor of
1031optional argument AT-END-P is non-nil, the CHILD is added to the end of the 1060PARENT. If optional argument AT-END-P is non-nil, the CHILD is
1032children list of PARENT." 1061added to the end of the children list of PARENT."
1033 (let ((parent-container (cond ((null parent) nil) 1062 (let ((parent-container (cond ((null parent) nil)
1034 ((mh-thread-container-p parent) parent) 1063 ((mh-thread-container-p parent) parent)
1035 (t (mh-thread-id-container parent)))) 1064 (t (mh-thread-id-container parent))))
@@ -1053,8 +1082,8 @@ children list of PARENT."
1053 1082
1054(defun mh-thread-ancestor-p (ancestor successor) 1083(defun mh-thread-ancestor-p (ancestor successor)
1055 "Return t if ANCESTOR is really an ancestor of SUCCESSOR and nil otherwise. 1084 "Return t if ANCESTOR is really an ancestor of SUCCESSOR and nil otherwise.
1056In the limit, the function returns t if ANCESTOR and SUCCESSOR are the same 1085In the limit, the function returns t if ANCESTOR and SUCCESSOR
1057containers." 1086are the same containers."
1058 (block nil 1087 (block nil
1059 (while successor 1088 (while successor
1060 (when (eq ancestor successor) (return t)) 1089 (when (eq ancestor successor) (return t))
@@ -1063,7 +1092,8 @@ containers."
1063 1092
1064(defsubst mh-thread-get-message-container (message) 1093(defsubst mh-thread-get-message-container (message)
1065 "Return container which has MESSAGE in it. 1094 "Return container which has MESSAGE in it.
1066If there is no container present then a new container is allocated." 1095If there is no container present then a new container is
1096allocated."
1067 (let* ((id (mh-message-id message)) 1097 (let* ((id (mh-message-id message))
1068 (container (gethash id mh-thread-id-table))) 1098 (container (gethash id mh-thread-id-table)))
1069 (cond (container (setf (mh-container-message container) message) 1099 (cond (container (setf (mh-container-message container) message)
@@ -1073,8 +1103,8 @@ If there is no container present then a new container is allocated."
1073 1103
1074(defsubst mh-thread-get-message (id subject-re-p subject refs) 1104(defsubst mh-thread-get-message (id subject-re-p subject refs)
1075 "Return appropriate message. 1105 "Return appropriate message.
1076Otherwise update message already present to have the proper ID, SUBJECT-RE-P, 1106Otherwise update message already present to have the proper ID,
1077SUBJECT and REFS fields." 1107SUBJECT-RE-P, SUBJECT and REFS fields."
1078 (let* ((container (gethash id mh-thread-id-table)) 1108 (let* ((container (gethash id mh-thread-id-table))
1079 (message (if container (mh-container-message container) nil))) 1109 (message (if container (mh-container-message container) nil)))
1080 (cond (message 1110 (cond (message
@@ -1103,9 +1133,10 @@ This allows cheap string comparison with EQ."
1103 1133
1104(defsubst mh-thread-prune-subject (subject) 1134(defsubst mh-thread-prune-subject (subject)
1105 "Prune leading Re:'s, Fwd:'s etc. and trailing (fwd)'s from SUBJECT. 1135 "Prune leading Re:'s, Fwd:'s etc. and trailing (fwd)'s from SUBJECT.
1106If the result after pruning is not the empty string then it is canonicalized 1136If the result after pruning is not the empty string then it is
1107so that subjects can be tested for equality with eq. This is done so that all 1137canonicalized so that subjects can be tested for equality with
1108the messages without a subject are not put into a single thread." 1138eq. This is done so that all the messages without a subject are
1139not put into a single thread."
1109 (let ((case-fold-search t) 1140 (let ((case-fold-search t)
1110 (subject-pruned-flag nil)) 1141 (subject-pruned-flag nil))
1111 ;; Prune subject leader 1142 ;; Prune subject leader
@@ -1128,7 +1159,8 @@ the messages without a subject are not put into a single thread."
1128 1159
1129(defun mh-thread-container-subject (container) 1160(defun mh-thread-container-subject (container)
1130 "Return the subject of CONTAINER. 1161 "Return the subject of CONTAINER.
1131If CONTAINER is empty return the subject info of one of its children." 1162If CONTAINER is empty return the subject info of one of its
1163children."
1132 (cond ((and (mh-container-message container) 1164 (cond ((and (mh-container-message container)
1133 (mh-message-id (mh-container-message container))) 1165 (mh-message-id (mh-container-message container)))
1134 (mh-message-subject (mh-container-message container))) 1166 (mh-message-subject (mh-container-message container)))
@@ -1233,8 +1265,8 @@ If CONTAINER is empty return the subject info of one of its children."
1233 1265
1234(defsubst mh-thread-group-by-subject (roots) 1266(defsubst mh-thread-group-by-subject (roots)
1235 "Group the set of message containers, ROOTS based on subject. 1267 "Group the set of message containers, ROOTS based on subject.
1236Bug: Check for and make sure that something without Re: is made the parent in 1268Bug: Check for and make sure that something without Re: is made
1237preference to something that has it." 1269the parent in preference to something that has it."
1238 (clrhash mh-thread-subject-container-hash) 1270 (clrhash mh-thread-subject-container-hash)
1239 (let ((results ())) 1271 (let ((results ()))
1240 (dolist (root roots) 1272 (dolist (root roots)
@@ -1251,9 +1283,9 @@ preference to something that has it."
1251 1283
1252(defun mh-thread-process-in-reply-to (reply-to-header) 1284(defun mh-thread-process-in-reply-to (reply-to-header)
1253 "Extract message id's from REPLY-TO-HEADER. 1285 "Extract message id's from REPLY-TO-HEADER.
1254Ideally this should have some regexp which will try to guess if a string 1286Ideally this should have some regexp which will try to guess if a
1255between < and > is a message id and not an email address. For now it will 1287string between < and > is a message id and not an email address.
1256take the last string inside angles." 1288For now it will take the last string inside angles."
1257 (let ((end (mh-search-from-end ?> reply-to-header))) 1289 (let ((end (mh-search-from-end ?> reply-to-header)))
1258 (when (numberp end) 1290 (when (numberp end)
1259 (let ((begin (mh-search-from-end ?< (substring reply-to-header 0 end)))) 1291 (let ((begin (mh-search-from-end ?< (substring reply-to-header 0 end))))
@@ -1279,9 +1311,9 @@ take the last string inside angles."
1279 1311
1280(defsubst mh-thread-update-id-index-maps (id index) 1312(defsubst mh-thread-update-id-index-maps (id index)
1281 "Message with id, ID is the message in INDEX. 1313 "Message with id, ID is the message in INDEX.
1282The function also checks for duplicate messages (that is multiple messages 1314The function also checks for duplicate messages (that is multiple
1283with the same ID). These messages are put in the `mh-thread-duplicates' hash 1315messages with the same ID). These messages are put in the
1284table." 1316`mh-thread-duplicates' hash table."
1285 (let ((old-index (gethash id mh-thread-id-index-map))) 1317 (let ((old-index (gethash id mh-thread-id-index-map)))
1286 (when old-index (push old-index (gethash id mh-thread-duplicates))) 1318 (when old-index (push old-index (gethash id mh-thread-duplicates)))
1287 (setf (gethash id mh-thread-id-index-map) index) 1319 (setf (gethash id mh-thread-id-index-map) index)
@@ -1383,9 +1415,9 @@ All messages after START-POINT are added to the thread tree."
1383 1415
1384(defun mh-thread-generate-scan-lines (tree level) 1416(defun mh-thread-generate-scan-lines (tree level)
1385 "Generate scan lines. 1417 "Generate scan lines.
1386TREE is the hierarchical tree of messages, SCAN-LINE-MAP maps message indices 1418TREE is the hierarchical tree of messages, SCAN-LINE-MAP maps
1387to the corresponding scan lines and LEVEL used to determine indentation of 1419message indices to the corresponding scan lines and LEVEL used to
1388the message." 1420determine indentation of the message."
1389 (cond ((null tree) nil) 1421 (cond ((null tree) nil)
1390 ((mh-thread-container-p tree) 1422 ((mh-thread-container-p tree)
1391 (let* ((message (mh-container-message tree)) 1423 (let* ((message (mh-container-message tree))
@@ -1436,8 +1468,9 @@ the message."
1436;; the scan which generates the threading info. For now this will have to do. 1468;; the scan which generates the threading info. For now this will have to do.
1437(defun mh-thread-parse-scan-line (&optional string) 1469(defun mh-thread-parse-scan-line (&optional string)
1438 "Parse a scan line. 1470 "Parse a scan line.
1439If optional argument STRING is given then that is assumed to be the scan line. 1471If optional argument STRING is given then that is assumed to be
1440Otherwise uses the line at point as the scan line to parse." 1472the scan line. Otherwise uses the line at point as the scan line
1473to parse."
1441 (let* ((string (or string 1474 (let* ((string (or string
1442 (buffer-substring-no-properties (line-beginning-position) 1475 (buffer-substring-no-properties (line-beginning-position)
1443 (line-end-position)))) 1476 (line-end-position))))
@@ -1583,7 +1616,8 @@ MSG is the message being notated with NOTATION at OFFSET."
1583(defun mh-thread-next-sibling (&optional previous-flag) 1616(defun mh-thread-next-sibling (&optional previous-flag)
1584 "Display next sibling. 1617 "Display next sibling.
1585 1618
1586With non-nil optional argument PREVIOUS-FLAG jump to the previous sibling." 1619With non-nil optional argument PREVIOUS-FLAG jump to the previous
1620sibling."
1587 (interactive) 1621 (interactive)
1588 (cond ((not (memq 'unthread mh-view-ops)) 1622 (cond ((not (memq 'unthread mh-view-ops))
1589 (error "Folder isn't threaded")) 1623 (error "Folder isn't threaded"))
@@ -1632,9 +1666,10 @@ With non-nil optional argument PREVIOUS-FLAG jump to the previous sibling."
1632(defun mh-thread-ancestor (&optional thread-root-flag) 1666(defun mh-thread-ancestor (&optional thread-root-flag)
1633 "Display ancestor of current message. 1667 "Display ancestor of current message.
1634 1668
1635If you do not care for the way a particular thread has turned, you can move up 1669If you do not care for the way a particular thread has turned,
1636the chain of messages with this command. This command can also take a prefix 1670you can move up the chain of messages with this command. This
1637argument THREAD-ROOT-FLAG to jump to the message that started everything." 1671command can also take a prefix argument THREAD-ROOT-FLAG to jump
1672to the message that started everything."
1638 (interactive "P") 1673 (interactive "P")
1639 (beginning-of-line) 1674 (beginning-of-line)
1640 (cond ((not (memq 'unthread mh-view-ops)) 1675 (cond ((not (memq 'unthread mh-view-ops))
@@ -1652,8 +1687,9 @@ argument THREAD-ROOT-FLAG to jump to the message that started everything."
1652 1687
1653(defun mh-thread-find-children () 1688(defun mh-thread-find-children ()
1654 "Return a region containing the current message and its children. 1689 "Return a region containing the current message and its children.
1655The result is returned as a list of two elements. The first is the point at the 1690The result is returned as a list of two elements. The first is
1656start of the region and the second is the point at the end." 1691the point at the start of the region and the second is the point
1692at the end."
1657 (beginning-of-line) 1693 (beginning-of-line)
1658 (if (eobp) 1694 (if (eobp)
1659 nil 1695 nil
@@ -1744,10 +1780,11 @@ interactive use."
1744(defun mh-narrow-to-tick () 1780(defun mh-narrow-to-tick ()
1745 "Limit to ticked messages. 1781 "Limit to ticked messages.
1746 1782
1747What this command does is show only those messages that are in the \"tick\" 1783What this command does is show only those messages that are in
1748sequence (which you can customize via the `mh-tick-seq' option) in the 1784the \"tick\" sequence (which you can customize via the
1749MH-Folder buffer. In addition, it limits further MH-E searches to just those 1785`mh-tick-seq' option) in the MH-Folder buffer. In addition, it
1750messages. When you want to widen the view to all your messages again, use 1786limits further MH-E searches to just those messages. When you
1787want to widen the view to all your messages again, use
1751\\[mh-widen]." 1788\\[mh-widen]."
1752 (interactive) 1789 (interactive)
1753 (cond ((not mh-tick-seq) 1790 (cond ((not mh-tick-seq)
diff --git a/lisp/mh-e/mh-speed.el b/lisp/mh-e/mh-speed.el
index 64aa84fa8d8..5c7f5cda3ba 100644
--- a/lisp/mh-e/mh-speed.el
+++ b/lisp/mh-e/mh-speed.el
@@ -62,7 +62,8 @@
62;;;###mh-autoload 62;;;###mh-autoload
63(defun mh-folder-speedbar-buttons (buffer) 63(defun mh-folder-speedbar-buttons (buffer)
64 "Interface function to create MH-E speedbar buffer. 64 "Interface function to create MH-E speedbar buffer.
65BUFFER is the MH-E buffer for which the speedbar buffer is to be created." 65BUFFER is the MH-E buffer for which the speedbar buffer is to be
66created."
66 (unless (get-text-property (point-min) 'mh-level) 67 (unless (get-text-property (point-min) 'mh-level)
67 (erase-buffer) 68 (erase-buffer)
68 (clrhash mh-speed-folder-map) 69 (clrhash mh-speed-folder-map)
@@ -125,11 +126,13 @@ BUFFER is the MH-E buffer for which the speedbar buffer is to be created."
125 126
126(defun mh-speed-update-current-folder (force) 127(defun mh-speed-update-current-folder (force)
127 "Update speedbar highlighting of the current folder. 128 "Update speedbar highlighting of the current folder.
128The function tries to be smart so that work done is minimized. The currently 129The function tries to be smart so that work done is minimized.
129highlighted folder is cached and no highlighting happens unless it changes. 130The currently highlighted folder is cached and no highlighting
131happens unless it changes.
130Also highlighting is suspended while the speedbar frame is selected. 132Also highlighting is suspended while the speedbar frame is selected.
131Otherwise you get the disconcerting behavior of folders popping open on their 133Otherwise you get the disconcerting behavior of folders popping open
132own when you are trying to navigate around in the speedbar buffer. 134on their own when you are trying to navigate around in the speedbar
135buffer.
133 136
134The update is always carried out if FORCE is non-nil." 137The update is always carried out if FORCE is non-nil."
135 (let* ((lastf (selected-frame)) 138 (let* ((lastf (selected-frame))
@@ -237,7 +240,8 @@ The function will expand out parent folders of FOLDER if needed."
237 240
238(defun mh-speed-extract-folder-name (buffer) 241(defun mh-speed-extract-folder-name (buffer)
239 "Given an MH-E BUFFER find the folder that should be highlighted. 242 "Given an MH-E BUFFER find the folder that should be highlighted.
240Do the right thing for the different kinds of buffers that MH-E uses." 243Do the right thing for the different kinds of buffers that MH-E
244uses."
241 (save-excursion 245 (save-excursion
242 (set-buffer buffer) 246 (set-buffer buffer)
243 (cond ((eq major-mode 'mh-folder-mode) 247 (cond ((eq major-mode 'mh-folder-mode)
@@ -353,8 +357,8 @@ The optional ARGS from speedbar are ignored."
353 357
354(defmacro mh-process-kill-without-query (process) 358(defmacro mh-process-kill-without-query (process)
355 "PROCESS can be killed without query on Emacs exit. 359 "PROCESS can be killed without query on Emacs exit.
356Avoid using `process-kill-without-query' if possible since it is now 360Avoid using `process-kill-without-query' if possible since it is
357obsolete." 361now obsolete."
358 (if (fboundp 'set-process-query-on-exit-flag) 362 (if (fboundp 'set-process-query-on-exit-flag)
359 `(set-process-query-on-exit-flag ,process nil) 363 `(set-process-query-on-exit-flag ,process nil)
360 `(process-kill-without-query ,process))) 364 `(process-kill-without-query ,process)))
@@ -364,8 +368,8 @@ obsolete."
364 "Execute flists -recurse and update message counts. 368 "Execute flists -recurse and update message counts.
365If FORCE is non-nil the timer is reset. 369If FORCE is non-nil the timer is reset.
366 370
367Any number of optional FOLDERS can be specified. If specified, flists is run 371Any number of optional FOLDERS can be specified. If specified,
368only for that one folder." 372flists is run only for that one folder."
369 (interactive (list t)) 373 (interactive (list t))
370 (when force 374 (when force
371 (when mh-speed-flists-timer 375 (when mh-speed-flists-timer
@@ -412,8 +416,8 @@ only for that one folder."
412;; Copied from mh-make-folder-list-filter... 416;; Copied from mh-make-folder-list-filter...
413(defun mh-speed-parse-flists-output (process output) 417(defun mh-speed-parse-flists-output (process output)
414 "Parse the incremental results from flists. 418 "Parse the incremental results from flists.
415PROCESS is the flists process and OUTPUT is the results that must be handled 419PROCESS is the flists process and OUTPUT is the results that must
416next." 420be handled next."
417 (let ((prevailing-match-data (match-data)) 421 (let ((prevailing-match-data (match-data))
418 (position 0) 422 (position 0)
419 line-end line folder unseen total) 423 line-end line folder unseen total)
@@ -506,8 +510,9 @@ next."
506(defun mh-speed-refresh () 510(defun mh-speed-refresh ()
507 "Regenerates the list of folders in the speedbar. 511 "Regenerates the list of folders in the speedbar.
508 512
509Run this command if you've added or deleted a folder, or want to update the 513Run this command if you've added or deleted a folder, or want to
510unseen message count before the next automatic update." 514update the unseen message count before the next automatic
515update."
511 (interactive) 516 (interactive)
512 (mh-speed-flists t) 517 (mh-speed-flists t)
513 (mh-speed-invalidate-map "")) 518 (mh-speed-invalidate-map ""))
diff --git a/lisp/mh-e/mh-utils.el b/lisp/mh-e/mh-utils.el
index e39d141b70b..ca51f59bc3f 100644
--- a/lisp/mh-e/mh-utils.el
+++ b/lisp/mh-e/mh-utils.el
@@ -79,8 +79,8 @@
79 79
80(defun mh-search-from-end (char string) 80(defun mh-search-from-end (char string)
81 "Return the position of last occurrence of CHAR in STRING. 81 "Return the position of last occurrence of CHAR in STRING.
82If CHAR is not present in STRING then return nil. The function is used in lieu 82If CHAR is not present in STRING then return nil. The function is
83of `search' in the CL package." 83used in lieu of `search' in the CL package."
84 (loop for index from (1- (length string)) downto 0 84 (loop for index from (1- (length string)) downto 0
85 when (equal (aref string index) char) return index 85 when (equal (aref string index) char) return index
86 finally return nil)) 86 finally return nil))
@@ -94,59 +94,73 @@ of `search' in the CL package."
94 94
95(defvar mh-scan-msg-number-regexp "^ *\\([0-9]+\\)" 95(defvar mh-scan-msg-number-regexp "^ *\\([0-9]+\\)"
96 "This regular expression extracts the message number. 96 "This regular expression extracts the message number.
97It must match from the beginning of the line. Note that the message number 97
98must be placed in a parenthesized expression as in the default of 98It must match from the beginning of the line. Note that the
99\"^ *\\\\([0-9]+\\\\)\".") 99message number must be placed in a parenthesized expression as in
100the default of \"^ *\\\\([0-9]+\\\\)\".")
100 101
101(defvar mh-scan-msg-overflow-regexp "^[?0-9][0-9]" 102(defvar mh-scan-msg-overflow-regexp "^[?0-9][0-9]"
102 "This regular expression matches overflowed message numbers.") 103 "This regular expression matches overflowed message numbers.")
103 104
104(defvar mh-scan-msg-format-regexp "%\\([0-9]*\\)(msg)" 105(defvar mh-scan-msg-format-regexp "%\\([0-9]*\\)(msg)"
105 "This regular expression finds the message number width in a scan format. 106 "This regular expression finds the message number width in a scan format.
106Note that the message number must be placed in a parenthesized expression as 107
107in the default of \"%\\\\([0-9]*\\\\)(msg)\". This variable is only consulted 108Note that the message number must be placed in a parenthesized
108if `mh-scan-format-file' is set to \"Use MH-E scan Format\".") 109expression as in the default of \"%\\\\([0-9]*\\\\)(msg)\". This
110variable is only consulted if `mh-scan-format-file' is set to
111\"Use MH-E scan Format\".")
109 112
110(defvar mh-scan-msg-format-string "%d" 113(defvar mh-scan-msg-format-string "%d"
111 "This is a format string for width of the message number in a scan format. 114 "This is a format string for width of the message number in a scan format.
112Use `0%d' for zero-filled message numbers. This variable is only consulted if 115
113`mh-scan-format-file' is set to \"Use MH-E scan Format\".") 116Use \"0%d\" for zero-filled message numbers. This variable is only
117consulted if `mh-scan-format-file' is set to \"Use MH-E scan
118Format\".")
114 119
115(defvar mh-scan-msg-search-regexp "^[^0-9]*%d[^0-9]" 120(defvar mh-scan-msg-search-regexp "^[^0-9]*%d[^0-9]"
116 "This regular expression matches a particular message. 121 "This regular expression matches a particular message.
117It is a format string; use `%d' to represent the location of the message 122
118number within the expression as in the default of \"^[^0-9]*%d[^0-9]\".") 123It is a format string; use \"%d\" to represent the location of the
124message number within the expression as in the default of
125\"^[^0-9]*%d[^0-9]\".")
119 126
120(defvar mh-cmd-note 4 127(defvar mh-cmd-note 4
121 "Column for notations. 128 "Column for notations.
122This variable should be set with the function `mh-set-cmd-note'. This variable 129
123may be updated dynamically if `mh-adaptive-cmd-note-flag' is on. 130This variable should be set with the function `mh-set-cmd-note'.
131This variable may be updated dynamically if
132`mh-adaptive-cmd-note-flag' is on.
124 133
125Note that columns in Emacs start with 0.") 134Note that columns in Emacs start with 0.")
126(make-variable-buffer-local 'mh-cmd-note) 135(make-variable-buffer-local 'mh-cmd-note)
127 136
128(defvar mh-note-seq ?% 137(defvar mh-note-seq ?%
129 "Messages in a user-defined sequence are marked by this character. 138 "Messages in a user-defined sequence are marked by this character.
130Messages in the `search' sequence are marked by this character as well.") 139
140Messages in the \"search\" sequence are marked by this character as
141well.")
131 142
132 143
133 144
134(defvar mh-show-buffer-mode-line-buffer-id " {show-%s} %d" 145(defvar mh-show-buffer-mode-line-buffer-id " {show-%s} %d"
135 "Format string to produce `mode-line-buffer-identification' for show buffers. 146 "Format string to produce `mode-line-buffer-identification' for show buffers.
136First argument is folder name. Second is message number.") 147
148First argument is folder name. Second is message number.")
137 149
138 150
139 151
140(defvar mh-mail-header-separator "--------" 152(defvar mh-mail-header-separator "--------"
141 "*Line used by MH to separate headers from text in messages being composed. 153 "*Line used by MH to separate headers from text in messages being composed.
142This variable should not be used directly in programs. Programs should use
143`mail-header-separator' instead. `mail-header-separator' is initialized to
144`mh-mail-header-separator' in `mh-letter-mode'; in other contexts, you may
145have to perform this initialization yourself.
146 154
147Do not make this a regular expression as it may be the argument to `insert' 155This variable should not be used directly in programs. Programs
148and it is passed through `regexp-quote' before being used by functions like 156should use `mail-header-separator' instead.
149`re-search-forward'.") 157`mail-header-separator' is initialized to
158`mh-mail-header-separator' in `mh-letter-mode'; in other
159contexts, you may have to perform this initialization yourself.
160
161Do not make this a regular expression as it may be the argument
162to `insert' and it is passed through `regexp-quote' before being
163used by functions like `re-search-forward'.")
150 164
151(defvar mh-signature-separator-regexp "^-- $" 165(defvar mh-signature-separator-regexp "^-- $"
152 "This regular expression matches the signature separator. 166 "This regular expression matches the signature separator.
@@ -154,11 +168,12 @@ See `mh-signature-separator'.")
154 168
155(defvar mh-signature-separator "-- \n" 169(defvar mh-signature-separator "-- \n"
156 "Text of a signature separator. 170 "Text of a signature separator.
157A signature separator is used to separate the body of a message from the 171
158signature. This can be used by user agents such as MH-E to render the 172A signature separator is used to separate the body of a message
159signature differently or to suppress the inclusion of the signature in a 173from the signature. This can be used by user agents such as MH-E
160reply. 174to render the signature differently or to suppress the inclusion
161Use `mh-signature-separator-regexp' when searching for a separator.") 175of the signature in a reply. Use `mh-signature-separator-regexp'
176when searching for a separator.")
162 177
163(defun mh-signature-separator-p () 178(defun mh-signature-separator-p ()
164 "Return non-nil if buffer includes \"^-- $\"." 179 "Return non-nil if buffer includes \"^-- $\"."
@@ -288,8 +303,9 @@ Use `mh-signature-separator-regexp' when searching for a separator.")
288 303
289(defun mh-goto-address-find-address-at-point () 304(defun mh-goto-address-find-address-at-point ()
290 "Find e-mail address around or before point. 305 "Find e-mail address around or before point.
291Then search backwards to beginning of line for the start of an e-mail 306
292address. If no e-mail address found, return nil." 307Then search backwards to beginning of line for the start of an
308e-mail address. If no e-mail address found, return nil."
293 (re-search-backward "[^-_A-z0-9.@]" (line-beginning-position) 'lim) 309 (re-search-backward "[^-_A-z0-9.@]" (line-beginning-position) 'lim)
294 (if (or (looking-at mh-address-mail-regexp) ; already at start 310 (if (or (looking-at mh-address-mail-regexp) ; already at start
295 (and (re-search-forward mh-address-mail-regexp 311 (and (re-search-forward mh-address-mail-regexp
@@ -299,8 +315,10 @@ address. If no e-mail address found, return nil."
299 315
300(defun mh-mail-header-end () 316(defun mh-mail-header-end ()
301 "Substitute for `mail-header-end' that doesn't widen the buffer. 317 "Substitute for `mail-header-end' that doesn't widen the buffer.
302In MH-E we frequently need to find the end of headers in nested messages, where 318
303the buffer has been narrowed. This function works in this situation." 319In MH-E we frequently need to find the end of headers in nested
320messages, where the buffer has been narrowed. This function works
321in this situation."
304 (save-excursion 322 (save-excursion
305 ;; XXX: The following replaces a call to rfc822-goto-eoh. Occasionally, 323 ;; XXX: The following replaces a call to rfc822-goto-eoh. Occasionally,
306 ;; mail headers that MH-E has to read contains lines of the form: 324 ;; mail headers that MH-E has to read contains lines of the form:
@@ -423,10 +441,11 @@ Argument LIMIT limits search."
423(defun mh-show-font-lock-fontify-region (beg end loudly) 441(defun mh-show-font-lock-fontify-region (beg end loudly)
424 "Limit font-lock in `mh-show-mode' to the header. 442 "Limit font-lock in `mh-show-mode' to the header.
425 443
426Used when the option `mh-highlight-citation-style' is set to \"Gnus\", leaving 444Used when the option `mh-highlight-citation-style' is set to
427the body to be dealt with by Gnus highlighting. The region between BEG and END 445\"Gnus\", leaving the body to be dealt with by Gnus highlighting.
428is given over to be fontified and LOUDLY controls if a user sees a message 446The region between BEG and END is given over to be fontified and
429about the fontification operation." 447LOUDLY controls if a user sees a message about the fontification
448operation."
430 (let ((header-end (mh-mail-header-end))) 449 (let ((header-end (mh-mail-header-end)))
431 (cond 450 (cond
432 ((and (< beg header-end)(< end header-end)) 451 ((and (< beg header-end)(< end header-end))
@@ -469,28 +488,27 @@ about the fontification operation."
469 488
470;;; Internal bookkeeping variables: 489;;; Internal bookkeeping variables:
471 490
472;; Cached value of the `Path:' component in the user's MH profile. 491(defvar mh-user-path nil
473;; User's mail folder directory. 492 "Cached value of the \"Path:\" MH profile component.
474(defvar mh-user-path nil) 493User's mail folder directory.")
475 494
476;; An mh-draft-folder of nil means do not use a draft folder. 495(defvar mh-draft-folder nil
477;; Cached value of the `Draft-Folder:' component in the user's MH profile. 496 "Cached value of the \"Draft-Folder:\" MH profile component.
478;; Name of folder containing draft messages. 497Name of folder containing draft messages.
479(defvar mh-draft-folder nil) 498Nil means do not use a draft folder.")
480 499
481;; Cached value of the `Unseen-Sequence:' component in the user's MH profile. 500(defvar mh-unseen-seq nil
482;; Name of the Unseen sequence. 501 "Cached value of the \"Unseen-Sequence:\" MH profile component.
483(defvar mh-unseen-seq nil) 502Name of the Unseen sequence.")
484 503
485;; Cached value of the `Previous-Sequence:' component in the user's MH 504(defvar mh-previous-seq nil
486;; profile. 505 "Cached value of the \"Previous-Sequence:\" MH profile component.
487;; Name of the Previous sequence. 506Name of the Previous sequence.")
488(defvar mh-previous-seq nil)
489 507
490;; Cached value of the `Inbox:' component in the user's MH profile, 508(defvar mh-inbox nil
491;; or "+inbox" if no such component. 509 "Cached value of the \"Inbox:\" MH profile component.
492;; Name of the Inbox folder. 510Set to \"+inbox\" if no such component.
493(defvar mh-inbox nil) 511Name of the Inbox folder.")
494 512
495;; The names of ephemeral buffers have a " *mh-" prefix (so that they are 513;; The names of ephemeral buffers have a " *mh-" prefix (so that they are
496;; hidden and can be programmatically removed in mh-quit), and the variable 514;; hidden and can be programmatically removed in mh-quit), and the variable
@@ -511,33 +529,33 @@ about the fontification operation."
511(defconst mh-recipients-buffer "*MH-E Recipients*") ;killed when draft sent 529(defconst mh-recipients-buffer "*MH-E Recipients*") ;killed when draft sent
512(defconst mh-sequences-buffer "*MH-E Sequences*") ;sequences list 530(defconst mh-sequences-buffer "*MH-E Sequences*") ;sequences list
513 531
514;; Number of lines to keep in mh-log-buffer. 532(defvar mh-log-buffer-lines 100
515(defvar mh-log-buffer-lines 100) 533 "Number of lines to keep in `mh-log-buffer'.")
516 534
517;; Window configuration before MH-E command. 535(defvar mh-previous-window-config nil
518(defvar mh-previous-window-config nil) 536 "Window configuration before MH-E command.")
519 537
520;;Non-nil means next SPC or whatever goes to next undeleted message. 538(defvar mh-page-to-next-msg-flag nil
521(defvar mh-page-to-next-msg-flag nil) 539 "Non-nil means next SPC or whatever goes to next undeleted message.")
522 540
523 541
524 542
525;;; Internal variables local to a folder. 543;;; Internal variables local to a folder.
526 544
527;; Name of current folder, a string. 545(defvar mh-current-folder nil
528(defvar mh-current-folder nil) 546 "Name of current folder, a string.")
529 547
530;; Buffer that displays message for this folder. 548(defvar mh-show-buffer nil
531(defvar mh-show-buffer nil) 549 "Buffer that displays message for this folder.")
532 550
533;; Full path of directory for this folder. 551(defvar mh-folder-filename nil
534(defvar mh-folder-filename nil) 552 "Full path of directory for this folder.")
535 553
536;;Number of msgs in buffer. 554(defvar mh-msg-count nil
537(defvar mh-msg-count nil) 555 "Number of msgs in buffer.")
538 556
539;; If non-nil, show the message in a separate window. 557(defvar mh-showing-mode nil
540(defvar mh-showing-mode nil) 558 "If non-nil, show the message in a separate window.")
541 559
542(defvar mh-show-mode-map (make-sparse-keymap) 560(defvar mh-show-mode-map (make-sparse-keymap)
543 "Keymap used by the show buffer.") 561 "Keymap used by the show buffer.")
@@ -566,25 +584,25 @@ about the fontification operation."
566 (cons modeline-buffer-id-left-extent "XEmacs%N:")) 584 (cons modeline-buffer-id-left-extent "XEmacs%N:"))
567 (cons modeline-buffer-id-right-extent " %17b"))))) 585 (cons modeline-buffer-id-right-extent " %17b")))))
568 586
569;; This holds a documentation string used by describe-mode.
570(defun mh-showing-mode (&optional arg) 587(defun mh-showing-mode (&optional arg)
571 "Change whether messages should be displayed. 588 "Change whether messages should be displayed.
572With arg, display messages iff ARG is positive." 589
590With ARG, display messages iff ARG is positive."
573 (setq mh-showing-mode 591 (setq mh-showing-mode
574 (if (null arg) 592 (if (null arg)
575 (not mh-showing-mode) 593 (not mh-showing-mode)
576 (> (prefix-numeric-value arg) 0)))) 594 (> (prefix-numeric-value arg) 0))))
577 595
578;; The sequences of this folder. An alist of (seq . msgs). 596(defvar mh-seq-list nil
579(defvar mh-seq-list nil) 597 "Alist of this folder's sequences.
598Elements have the form (SEQUENCE . MESSAGES).")
580 599
581;; List of displayed messages to be removed from the Unseen sequence. 600(defvar mh-seen-list nil
582(defvar mh-seen-list nil) 601 "List of displayed messages to be removed from the \"Unseen\" sequence.")
583 602
584;; If non-nil, show buffer contains message with all headers. 603(defvar mh-showing-with-headers nil
585;; If nil, show buffer contains message processed normally. 604 "If non-nil, MH-Show buffer contains message with all header fields.
586;; Showing message with headers or normally. 605If nil, MH-Show buffer contains message processed normally.")
587(defvar mh-showing-with-headers nil)
588 606
589 607
590 608
@@ -594,8 +612,8 @@ With arg, display messages iff ARG is positive."
594 "Format is (with-mh-folder-updating (SAVE-MODIFICATION-FLAG) &body BODY). 612 "Format is (with-mh-folder-updating (SAVE-MODIFICATION-FLAG) &body BODY).
595Execute BODY, which can modify the folder buffer without having to 613Execute BODY, which can modify the folder buffer without having to
596worry about file locking or the read-only flag, and return its result. 614worry about file locking or the read-only flag, and return its result.
597If SAVE-MODIFICATION-FLAG is non-nil, the buffer's modification 615If SAVE-MODIFICATION-FLAG is non-nil, the buffer's modification flag
598flag is unchanged, otherwise it is cleared." 616is unchanged, otherwise it is cleared."
599 (setq save-modification-flag (car save-modification-flag)) ; CL style 617 (setq save-modification-flag (car save-modification-flag)) ; CL style
600 `(prog1 618 `(prog1
601 (let ((mh-folder-updating-mod-flag (buffer-modified-p)) 619 (let ((mh-folder-updating-mod-flag (buffer-modified-p))
@@ -627,8 +645,9 @@ Stronger than `save-excursion', weaker than `save-window-excursion'."
627 645
628(defmacro mh-do-at-event-location (event &rest body) 646(defmacro mh-do-at-event-location (event &rest body)
629 "Switch to the location of EVENT and execute BODY. 647 "Switch to the location of EVENT and execute BODY.
630After BODY has been executed return to original window. The modification flag 648After BODY has been executed return to original window. The
631of the buffer in the event window is preserved." 649modification flag of the buffer in the event window is
650preserved."
632 (let ((event-window (make-symbol "event-window")) 651 (let ((event-window (make-symbol "event-window"))
633 (event-position (make-symbol "event-position")) 652 (event-position (make-symbol "event-position"))
634 (original-window (make-symbol "original-window")) 653 (original-window (make-symbol "original-window"))
@@ -672,9 +691,12 @@ of the buffer in the event window is preserved."
672 691
673(defun mh-recenter (arg) 692(defun mh-recenter (arg)
674 "Like recenter but with three improvements: 693 "Like recenter but with three improvements:
694
675- At the end of the buffer it tries to show fewer empty lines. 695- At the end of the buffer it tries to show fewer empty lines.
696
676- operates only if the current buffer is in the selected window. 697- operates only if the current buffer is in the selected window.
677 (Commands like `save-some-buffers' can make this false.) 698 (Commands like `save-some-buffers' can make this false.)
699
678- nil ARG means recenter as if prefix argument had been given." 700- nil ARG means recenter as if prefix argument had been given."
679 (cond ((not (eq (get-buffer-window (current-buffer)) (selected-window))) 701 (cond ((not (eq (get-buffer-window (current-buffer)) (selected-window)))
680 nil) 702 nil)
@@ -718,8 +740,8 @@ of the buffer in the event window is preserved."
718 740
719(defun mh-get-msg-num (error-if-no-message) 741(defun mh-get-msg-num (error-if-no-message)
720 "Return the message number of the displayed message. 742 "Return the message number of the displayed message.
721If the argument ERROR-IF-NO-MESSAGE is non-nil, then complain if the cursor is 743If the argument ERROR-IF-NO-MESSAGE is non-nil, then complain if
722not pointing to a message." 744the cursor is not pointing to a message."
723 (save-excursion 745 (save-excursion
724 (beginning-of-line) 746 (beginning-of-line)
725 (cond ((looking-at mh-scan-msg-number-regexp) 747 (cond ((looking-at mh-scan-msg-number-regexp)
@@ -731,7 +753,8 @@ not pointing to a message."
731 753
732(defun mh-folder-name-p (name) 754(defun mh-folder-name-p (name)
733 "Return non-nil if NAME is the name of a folder. 755 "Return non-nil if NAME is the name of a folder.
734A name (a string or symbol) can be a folder name if it begins with \"+\"." 756A name (a string or symbol) can be a folder name if it begins
757with \"+\"."
735 (if (symbolp name) 758 (if (symbolp name)
736 (eq (aref (symbol-name name) 0) ?+) 759 (eq (aref (symbol-name name) 0) ?+)
737 (and (> (length name) 0) 760 (and (> (length name) 0)
@@ -761,10 +784,10 @@ See `expand-file-name' for description of DEFAULT."
761(defmacro mh-defun-show-buffer (function original-function 784(defmacro mh-defun-show-buffer (function original-function
762 &optional dont-return) 785 &optional dont-return)
763 "Define FUNCTION to run ORIGINAL-FUNCTION in folder buffer. 786 "Define FUNCTION to run ORIGINAL-FUNCTION in folder buffer.
764If the buffer we start in is still visible and DONT-RETURN is nil then switch 787If the buffer we start in is still visible and DONT-RETURN is nil
765to it after that." 788then switch to it after that."
766 `(defun ,function () 789 `(defun ,function ()
767 ,(format "Calls %s from the message's folder.\n%s\nSee `%s' for more info.\n" 790 ,(format "Calls %s from the message's folder.\n%s\nSee \"%s\" for more info.\n"
768 original-function 791 original-function
769 (if dont-return "" 792 (if dont-return ""
770 "When function completes, returns to the show buffer if it is 793 "When function completes, returns to the show buffer if it is
@@ -1108,8 +1131,9 @@ still visible.\n")
1108 1131
1109(define-derived-mode mh-show-mode text-mode "MH-Show" 1132(define-derived-mode mh-show-mode text-mode "MH-Show"
1110 "Major mode for showing messages in MH-E.\\<mh-show-mode-map> 1133 "Major mode for showing messages in MH-E.\\<mh-show-mode-map>
1111The value of `mh-show-mode-hook' is a list of functions to 1134
1112be called, with no arguments, upon entry to this mode. 1135The hook `mh-show-mode-hook' is called upon entry to this mode.
1136
1113See also `mh-folder-mode'. 1137See also `mh-folder-mode'.
1114 1138
1115\\{mh-show-mode-map}" 1139\\{mh-show-mode-map}"
@@ -1207,8 +1231,8 @@ See also `mh-folder-mode'.
1207 1231
1208(defun mh-face-display-function () 1232(defun mh-face-display-function ()
1209 "Display a Face, X-Face, or X-Image-URL header field. 1233 "Display a Face, X-Face, or X-Image-URL header field.
1210If more than one of these are present, then the first one found in this order 1234If more than one of these are present, then the first one found
1211is used." 1235in this order is used."
1212 (save-restriction 1236 (save-restriction
1213 (goto-char (point-min)) 1237 (goto-char (point-min))
1214 (re-search-forward "\n\n" (point-max) t) 1238 (re-search-forward "\n\n" (point-max) t)
@@ -1374,9 +1398,9 @@ The directories are searched for in the order they appear in the list.")
1374 1398
1375(defun mh-picon-file-contents (file) 1399(defun mh-picon-file-contents (file)
1376 "Return details about FILE. 1400 "Return details about FILE.
1377A list of consisting of a symbol for the type of the file and the file 1401A list of consisting of a symbol for the type of the file and the
1378contents as a string is returned. If FILE is nil, then both elements of the 1402file contents as a string is returned. If FILE is nil, then both
1379list are nil." 1403elements of the list are nil."
1380 (if (stringp file) 1404 (if (stringp file)
1381 (with-temp-buffer 1405 (with-temp-buffer
1382 (let ((type (and (string-match ".*\\.\\(...\\)$" file) 1406 (let ((type (and (string-match ".*\\.\\(...\\)$" file)
@@ -1387,8 +1411,9 @@ list are nil."
1387 1411
1388(defun mh-picon-generate-path (host-list user directory) 1412(defun mh-picon-generate-path (host-list user directory)
1389 "Generate the image file path. 1413 "Generate the image file path.
1390HOST-LIST is the parsed host address of the email address, USER the username 1414HOST-LIST is the parsed host address of the email address, USER
1391and DIRECTORY is the directory relative to which the path is generated." 1415the username and DIRECTORY is the directory relative to which the
1416path is generated."
1392 (loop with acc = "" 1417 (loop with acc = ""
1393 for elem in host-list 1418 for elem in host-list
1394 do (setq acc (format "%s/%s" elem acc)) 1419 do (setq acc (format "%s/%s" elem acc))
@@ -1459,9 +1484,9 @@ Replace the ?/ character with a ?! character and append .png."
1459 1484
1460(defun mh-x-image-url-fetch-image (url cache-file marker sentinel) 1485(defun mh-x-image-url-fetch-image (url cache-file marker sentinel)
1461 "Fetch and display the image specified by URL. 1486 "Fetch and display the image specified by URL.
1462After the image is fetched, it is stored in CACHE-FILE. It will be displayed 1487After the image is fetched, it is stored in CACHE-FILE. It will
1463in a buffer and position specified by MARKER. The actual display is carried 1488be displayed in a buffer and position specified by MARKER. The
1464out by the SENTINEL function." 1489actual display is carried out by the SENTINEL function."
1465 (if mh-wget-executable 1490 (if mh-wget-executable
1466 (let ((buffer (get-buffer-create (generate-new-buffer-name 1491 (let ((buffer (get-buffer-create (generate-new-buffer-name
1467 mh-temp-fetch-buffer))) 1492 mh-temp-fetch-buffer)))
@@ -1575,18 +1600,18 @@ If optional arg MSG is non-nil, display that message instead."
1575(defun mh-show (&optional message redisplay-flag) 1600(defun mh-show (&optional message redisplay-flag)
1576 "Display message\\<mh-folder-mode-map>. 1601 "Display message\\<mh-folder-mode-map>.
1577 1602
1578If the message under the cursor is already displayed, this command scrolls to 1603If the message under the cursor is already displayed, this command
1579the beginning of the message. MH-E normally hides a lot of the superfluous 1604scrolls to the beginning of the message. MH-E normally hides a lot of
1580header fields that mailers add to a message, but if you wish to see all of 1605the superfluous header fields that mailers add to a message, but if
1581them, use the command \\[mh-header-display]. 1606you wish to see all of them, use the command \\[mh-header-display].
1582 1607
1583From a program, optional argument MESSAGE can be used to display an 1608From a program, optional argument MESSAGE can be used to display an
1584alternative message. The optional argument REDISPLAY-FLAG forces the redisplay 1609alternative message. The optional argument REDISPLAY-FLAG forces the
1585of the message even if the show buffer was already displaying the correct 1610redisplay of the message even if the show buffer was already
1586message. 1611displaying the correct message.
1587 1612
1588See the \"mh-show\" customization group for a litany of options that control 1613See the \"mh-show\" customization group for a litany of options that
1589what displayed messages look like." 1614control what displayed messages look like."
1590 (interactive (list nil t)) 1615 (interactive (list nil t))
1591 (when (or redisplay-flag 1616 (when (or redisplay-flag
1592 (and mh-showing-with-headers 1617 (and mh-showing-with-headers
@@ -1610,8 +1635,9 @@ The current frame height is taken into consideration."
1610 1635
1611(defun mh-show-msg (msg) 1636(defun mh-show-msg (msg)
1612 "Show MSG. 1637 "Show MSG.
1613The value of `mh-show-hook' is a list of functions to be called, with no 1638
1614arguments, after the message has been displayed." 1639The hook `mh-show-hook' is called after the message has been
1640displayed."
1615 (if (not msg) 1641 (if (not msg)
1616 (setq msg (mh-get-msg-num t))) 1642 (setq msg (mh-get-msg-num t)))
1617 (mh-showing-mode t) 1643 (mh-showing-mode t)
@@ -1654,10 +1680,11 @@ arguments, after the message has been displayed."
1654(defun mh-modify (&optional message) 1680(defun mh-modify (&optional message)
1655 "Edit message. 1681 "Edit message.
1656 1682
1657There are times when you need to edit a message. For example, you may need to 1683There are times when you need to edit a message. For example, you
1658fix a broken Content-Type header field. You can do this with this command. It 1684may need to fix a broken Content-Type header field. You can do
1659displays the raw message in an editable buffer. When you are done editing, 1685this with this command. It displays the raw message in an
1660save and kill the buffer as you would any other. 1686editable buffer. When you are done editing, save and kill the
1687buffer as you would any other.
1661 1688
1662From a program, edit MESSAGE instead if it is non-nil." 1689From a program, edit MESSAGE instead if it is non-nil."
1663 (interactive) 1690 (interactive)
@@ -1791,13 +1818,14 @@ Sets the current buffer to the show buffer."
1791 1818
1792(defun mh-clean-msg-header (start invisible-headers visible-headers) 1819(defun mh-clean-msg-header (start invisible-headers visible-headers)
1793 "Flush extraneous lines in message header. 1820 "Flush extraneous lines in message header.
1794Header is cleaned from START to the end of the message header.
1795INVISIBLE-HEADERS contains a regular expression specifying lines to delete
1796from the header. VISIBLE-HEADERS contains a regular expression specifying the
1797lines to display. INVISIBLE-HEADERS is ignored if VISIBLE-HEADERS is non-nil.
1798 1821
1799Note that MH-E no longer supports the `mh-visible-headers' variable, so 1822Header is cleaned from START to the end of the message header.
1800this function could be trimmed of this feature too." 1823INVISIBLE-HEADERS contains a regular expression specifying lines
1824to delete from the header. VISIBLE-HEADERS contains a regular
1825expression specifying the lines to display. INVISIBLE-HEADERS is
1826ignored if VISIBLE-HEADERS is non-nil."
1827 ;; XXX Note that MH-E no longer supports the `mh-visible-headers'
1828 ;; variable, so this function could be trimmed of this feature too."
1801 (let ((case-fold-search t) 1829 (let ((case-fold-search t)
1802 (buffer-read-only nil) 1830 (buffer-read-only nil)
1803 (after-change-functions nil)) ;Work around emacs-20 font-lock bug 1831 (after-change-functions nil)) ;Work around emacs-20 font-lock bug
@@ -1868,10 +1896,11 @@ If NOTATION is nil then no change in the buffer occurs."
1868You can enter the message NUMBER either before or after typing 1896You can enter the message NUMBER either before or after typing
1869\\[mh-goto-msg]. In the latter case, Emacs prompts you. 1897\\[mh-goto-msg]. In the latter case, Emacs prompts you.
1870 1898
1871In a program, optional non-nil second argument NO-ERROR-IF-NO-MESSAGE means 1899In a program, optional non-nil second argument NO-ERROR-IF-NO-MESSAGE
1872return nil instead of signaling an error if message does not exist\; in this 1900means return nil instead of signaling an error if message does not
1873case, the cursor is positioned near where the message would have been. Non-nil 1901exist\; in this case, the cursor is positioned near where the message
1874third argument DONT-SHOW means not to show the message." 1902would have been. Non-nil third argument DONT-SHOW means not to show
1903the message."
1875 (interactive "NGo to message: ") 1904 (interactive "NGo to message: ")
1876 (setq number (prefix-numeric-value number)) 1905 (setq number (prefix-numeric-value number))
1877 (let ((point (point)) 1906 (let ((point (point))
@@ -1904,10 +1933,18 @@ Returns nil if the field is not in the buffer."
1904 1933
1905(defun mh-find-path () 1934(defun mh-find-path ()
1906 "Set variables from user's MH profile. 1935 "Set variables from user's MH profile.
1907Set `mh-user-path', `mh-draft-folder', `mh-unseen-seq', `mh-previous-seq', 1936
1908`mh-inbox' from user's MH profile. 1937This function sets `mh-user-path' from your \"Path:\" MH profile
1909The value of `mh-find-path-hook' is a list of functions to be called, with no 1938component (but defaults to \"Mail\" if one isn't present),
1910arguments, after these variable have been set." 1939`mh-draft-folder' from \"Draft-Folder:\", `mh-unseen-seq' from
1940\"Unseen-Sequence:\", `mh-previous-seq' from
1941\"Previous-Sequence:\", and `mh-inbox' from \"Inbox:\" (defaults
1942to \"+inbox\").
1943
1944The hook `mh-find-path-hook' is run after these variables have
1945been set. This hook can be used the change the value of these
1946variables if you need to run with different values between MH and
1947MH-E."
1911 (mh-variants) 1948 (mh-variants)
1912 (unless mh-find-path-run 1949 (unless mh-find-path-run
1913 (setq mh-find-path-run t) 1950 (setq mh-find-path-run t)
@@ -1962,8 +1999,8 @@ arguments, after these variable have been set."
1962 1999
1963(defun mh-install (profile error-val) 2000(defun mh-install (profile error-val)
1964 "Initialize the MH environment. 2001 "Initialize the MH environment.
1965This is called if we fail to read the PROFILE file. ERROR-VAL is the error 2002This is called if we fail to read the PROFILE file. ERROR-VAL is
1966that made this call necessary." 2003the error that made this call necessary."
1967 (if (or (getenv "MH") 2004 (if (or (getenv "MH")
1968 (file-exists-p profile) 2005 (file-exists-p profile)
1969 mh-no-install) 2006 mh-no-install)
@@ -1999,9 +2036,9 @@ that made this call necessary."
1999(defun mh-update-scan-format (fmt width) 2036(defun mh-update-scan-format (fmt width)
2000 "Return a scan format with the (msg) width in the FMT replaced with WIDTH. 2037 "Return a scan format with the (msg) width in the FMT replaced with WIDTH.
2001 2038
2002The message number width portion of the format is discovered using 2039The message number width portion of the format is discovered
2003`mh-scan-msg-format-regexp'. Its replacement is controlled with 2040using `mh-scan-msg-format-regexp'. Its replacement is controlled
2004`mh-scan-msg-format-string'." 2041with `mh-scan-msg-format-string'."
2005 (or (and 2042 (or (and
2006 (string-match mh-scan-msg-format-regexp fmt) 2043 (string-match mh-scan-msg-format-regexp fmt)
2007 (let ((begin (match-beginning 1)) 2044 (let ((begin (match-beginning 1))
@@ -2030,12 +2067,13 @@ The message number width portion of the format is discovered using
2030 2067
2031(defun mh-add-msgs-to-seq (msgs seq &optional internal-flag dont-annotate-flag) 2068(defun mh-add-msgs-to-seq (msgs seq &optional internal-flag dont-annotate-flag)
2032 "Add MSGS to SEQ. 2069 "Add MSGS to SEQ.
2033Remove duplicates and keep sequence sorted. If optional INTERNAL-FLAG is
2034non-nil, do not mark the message in the scan listing or inform MH of the
2035addition.
2036 2070
2037If DONT-ANNOTATE-FLAG is non-nil then the annotations in the folder buffer are 2071Remove duplicates and keep sequence sorted. If optional
2038not updated." 2072INTERNAL-FLAG is non-nil, do not mark the message in the scan
2073listing or inform MH of the addition.
2074
2075If DONT-ANNOTATE-FLAG is non-nil then the annotations in the
2076folder buffer are not updated."
2039 (let ((entry (mh-find-seq seq)) 2077 (let ((entry (mh-find-seq seq))
2040 (internal-seq-flag (mh-internal-seq seq))) 2078 (internal-seq-flag (mh-internal-seq seq)))
2041 (if (and msgs (atom msgs)) (setq msgs (list msgs))) 2079 (if (and msgs (atom msgs)) (setq msgs (list msgs)))
@@ -2069,7 +2107,7 @@ not updated."
2069 2107
2070;; Initialize mh-sub-folders-cache... 2108;; Initialize mh-sub-folders-cache...
2071(defun mh-collect-folder-names () 2109(defun mh-collect-folder-names ()
2072 "Collect folder names by running `flists'." 2110 "Collect folder names by running \"flists\"."
2073 (unless mh-flists-process 2111 (unless mh-flists-process
2074 (setq mh-flists-process 2112 (setq mh-flists-process
2075 (mh-exec-cmd-daemon "folders" 'mh-collect-folder-names-filter 2113 (mh-exec-cmd-daemon "folders" 'mh-collect-folder-names-filter
@@ -2077,8 +2115,8 @@ not updated."
2077 2115
2078(defun mh-collect-folder-names-filter (process output) 2116(defun mh-collect-folder-names-filter (process output)
2079 "Read folder names. 2117 "Read folder names.
2080PROCESS is the flists process that was run to collect folder names and the 2118PROCESS is the flists process that was run to collect folder
2081function is called when OUTPUT is available." 2119names and the function is called when OUTPUT is available."
2082 (let ((position 0) 2120 (let ((position 0)
2083 (prevailing-match-data (match-data)) 2121 (prevailing-match-data (match-data))
2084 line-end folder) 2122 line-end folder)
@@ -2116,16 +2154,18 @@ function is called when OUTPUT is available."
2116(defun mh-normalize-folder-name (folder &optional empty-string-okay 2154(defun mh-normalize-folder-name (folder &optional empty-string-okay
2117 dont-remove-trailing-slash) 2155 dont-remove-trailing-slash)
2118 "Normalizes FOLDER name. 2156 "Normalizes FOLDER name.
2119Makes sure that two '/' characters never occur next to each other. Also all
2120occurrences of \"..\" and \".\" are suitably processed. So \"+inbox/../news\"
2121will be normalized to \"+news\".
2122 2157
2123If optional argument EMPTY-STRING-OKAY is nil then a '+' is added at the 2158Makes sure that two '/' characters never occur next to each
2124front if FOLDER lacks one. If non-nil and FOLDER is the empty string then 2159other. Also all occurrences of \"..\" and \".\" are suitably
2125nothing is added. 2160processed. So \"+inbox/../news\" will be normalized to \"+news\".
2161
2162If optional argument EMPTY-STRING-OKAY is nil then a '+' is added
2163at the front if FOLDER lacks one. If non-nil and FOLDER is the
2164empty string then nothing is added.
2126 2165
2127If optional argument DONT-REMOVE-TRAILING-SLASH is non-nil then a trailing '/' 2166If optional argument DONT-REMOVE-TRAILING-SLASH is non-nil then a
2128if present is retained (if present), otherwise it is removed." 2167trailing '/' if present is retained (if present), otherwise it is
2168removed."
2129 (when (stringp folder) 2169 (when (stringp folder)
2130 ;; Replace two or more consecutive '/' characters with a single '/' 2170 ;; Replace two or more consecutive '/' characters with a single '/'
2131 (while (string-match "//" folder) 2171 (while (string-match "//" folder)
@@ -2168,11 +2208,12 @@ if present is retained (if present), otherwise it is removed."
2168 2208
2169(defun mh-sub-folders (folder &optional add-trailing-slash-flag) 2209(defun mh-sub-folders (folder &optional add-trailing-slash-flag)
2170 "Find the subfolders of FOLDER. 2210 "Find the subfolders of FOLDER.
2171The function avoids running folders unnecessarily by caching the results of 2211The function avoids running folders unnecessarily by caching the
2172the actual folders call. 2212results of the actual folders call.
2173 2213
2174If optional argument ADD-TRAILING-SLASH-FLAG is non-nil then a slash is added 2214If optional argument ADD-TRAILING-SLASH-FLAG is non-nil then a
2175to each of the sub-folder names that may have nested folders within them." 2215slash is added to each of the sub-folder names that may have
2216nested folders within them."
2176 (let* ((folder (mh-normalize-folder-name folder)) 2217 (let* ((folder (mh-normalize-folder-name folder))
2177 (match (gethash folder mh-sub-folders-cache 'no-result)) 2218 (match (gethash folder mh-sub-folders-cache 'no-result))
2178 (sub-folders (cond ((eq match 'no-result) 2219 (sub-folders (cond ((eq match 'no-result)
@@ -2187,8 +2228,8 @@ to each of the sub-folder names that may have nested folders within them."
2187 2228
2188(defun mh-sub-folders-actual (folder) 2229(defun mh-sub-folders-actual (folder)
2189 "Execute the command folders to return the sub-folders of FOLDER. 2230 "Execute the command folders to return the sub-folders of FOLDER.
2190Filters out the folder names that start with \".\" so that directories that 2231Filters out the folder names that start with \".\" so that
2191aren't usually mail folders are hidden." 2232directories that aren't usually mail folders are hidden."
2192 (let ((arg-list `(,(expand-file-name "folders" mh-progs) 2233 (let ((arg-list `(,(expand-file-name "folders" mh-progs)
2193 nil (t nil) nil "-noheader" "-norecurse" "-nototal" 2234 nil (t nil) nil "-noheader" "-norecurse" "-nototal"
2194 ,@(if (stringp folder) (list folder) ()))) 2235 ,@(if (stringp folder) (list folder) ())))
@@ -2235,13 +2276,15 @@ aren't usually mail folders are hidden."
2235 2276
2236(defun mh-remove-from-sub-folders-cache (folder) 2277(defun mh-remove-from-sub-folders-cache (folder)
2237 "Remove FOLDER and its parent from `mh-sub-folders-cache'. 2278 "Remove FOLDER and its parent from `mh-sub-folders-cache'.
2238FOLDER should be unconditionally removed from the cache. Also the last ancestor 2279FOLDER should be unconditionally removed from the cache. Also the
2239of FOLDER present in the cache must be removed as well. 2280last ancestor of FOLDER present in the cache must be removed as
2240 2281well.
2241To see why this is needed assume we have a folder +foo which has a single 2282
2242sub-folder qux. Now we create the folder +foo/bar/baz. Here we will need to 2283To see why this is needed assume we have a folder +foo which has
2243invalidate the cached sub-folders of +foo, otherwise completion on +foo won't 2284a single sub-folder qux. Now we create the folder +foo/bar/baz.
2244tell us about the option +foo/bar!" 2285Here we will need to invalidate the cached sub-folders of +foo,
2286otherwise completion on +foo won't tell us about the option
2287+foo/bar!"
2245 (remhash folder mh-sub-folders-cache) 2288 (remhash folder mh-sub-folders-cache)
2246 (block ancestor-found 2289 (block ancestor-found
2247 (let ((parent folder) 2290 (let ((parent folder)
@@ -2262,8 +2305,9 @@ tell us about the option +foo/bar!"
2262 2305
2263(defvar mh-allow-root-folder-flag nil 2306(defvar mh-allow-root-folder-flag nil
2264 "Non-nil means \"+\" is an acceptable folder name. 2307 "Non-nil means \"+\" is an acceptable folder name.
2265This variable is used to communicate with `mh-folder-completion-function'. That 2308This variable is used to communicate with
2266function can have exactly three arguments so we bind this variable to t or nil. 2309`mh-folder-completion-function'. That function can have exactly
2310three arguments so we bind this variable to t or nil.
2267 2311
2268This variable should never be set.") 2312This variable should never be set.")
2269 2313
@@ -2280,9 +2324,9 @@ This variable should never be set.")
2280 2324
2281(defun mh-folder-completion-function (name predicate flag) 2325(defun mh-folder-completion-function (name predicate flag)
2282 "Programmable completion for folder names. 2326 "Programmable completion for folder names.
2283NAME is the partial folder name that has been input. PREDICATE if non-nil is a 2327NAME is the partial folder name that has been input. PREDICATE if
2284function that is used to filter the possible choices and FLAG determines 2328non-nil is a function that is used to filter the possible choices
2285whether the completion is over." 2329and FLAG determines whether the completion is over."
2286 (let* ((orig-name name) 2330 (let* ((orig-name name)
2287 (name (mh-normalize-folder-name name nil t)) 2331 (name (mh-normalize-folder-name name nil t))
2288 (last-slash (mh-search-from-end ?/ name)) 2332 (last-slash (mh-search-from-end ?/ name))
@@ -2317,8 +2361,8 @@ whether the completion is over."
2317 2361
2318(defun mh-folder-completing-read (prompt default allow-root-folder-flag) 2362(defun mh-folder-completing-read (prompt default allow-root-folder-flag)
2319 "Read folder name with PROMPT and default result DEFAULT. 2363 "Read folder name with PROMPT and default result DEFAULT.
2320If ALLOW-ROOT-FOLDER-FLAG is non-nil then \"+\" is allowed to be a folder name 2364If ALLOW-ROOT-FOLDER-FLAG is non-nil then \"+\" is allowed to be
2321corresponding to `mh-user-path'." 2365a folder name corresponding to `mh-user-path'."
2322 (mh-normalize-folder-name 2366 (mh-normalize-folder-name
2323 (let ((minibuffer-completing-file-name t) 2367 (let ((minibuffer-completing-file-name t)
2324 (completion-root-regexp "^[+/]") 2368 (completion-root-regexp "^[+/]")
@@ -2331,12 +2375,13 @@ corresponding to `mh-user-path'."
2331(defun mh-prompt-for-folder (prompt default can-create 2375(defun mh-prompt-for-folder (prompt default can-create
2332 &optional default-string allow-root-folder-flag) 2376 &optional default-string allow-root-folder-flag)
2333 "Prompt for a folder name with PROMPT. 2377 "Prompt for a folder name with PROMPT.
2334Returns the folder's name as a string. DEFAULT is used if the folder exists 2378Returns the folder's name as a string. DEFAULT is used if the
2335and the user types return. If the CAN-CREATE flag is t, then a folder is 2379folder exists and the user types return. If the CAN-CREATE flag
2336created if it doesn't already exist. If optional argument DEFAULT-STRING is 2380is t, then a folder is created if it doesn't already exist. If
2337non-nil, use it in the prompt instead of DEFAULT. If ALLOW-ROOT-FOLDER-FLAG is 2381optional argument DEFAULT-STRING is non-nil, use it in the prompt
2338non-nil then the function will accept the folder +, which means all folders 2382instead of DEFAULT. If ALLOW-ROOT-FOLDER-FLAG is non-nil then the
2339when used in searching." 2383function will accept the folder +, which means all folders when
2384used in searching."
2340 (if (null default) 2385 (if (null default)
2341 (setq default "")) 2386 (setq default ""))
2342 (let* ((default-string (cond (default-string (format " (default %s)" default-string)) 2387 (let* ((default-string (cond (default-string (format " (default %s)" default-string))
@@ -2389,9 +2434,10 @@ when used in searching."
2389 2434
2390(defun mh-truncate-log-buffer () 2435(defun mh-truncate-log-buffer ()
2391 "If `mh-log-buffer' is too big then truncate it. 2436 "If `mh-log-buffer' is too big then truncate it.
2392If the number of lines in `mh-log-buffer' exceeds `mh-log-buffer-lines' then 2437If the number of lines in `mh-log-buffer' exceeds
2393keep only the last `mh-log-buffer-lines'. As a side effect the point is set to 2438`mh-log-buffer-lines' then keep only the last
2394the end of the log buffer. 2439`mh-log-buffer-lines'. As a side effect the point is set to the
2440end of the log buffer.
2395 2441
2396The function returns the size of the final size of the log buffer." 2442The function returns the size of the final size of the log buffer."
2397 (with-current-buffer (get-buffer-create mh-log-buffer) 2443 (with-current-buffer (get-buffer-create mh-log-buffer)
@@ -2411,9 +2457,9 @@ The function returns the size of the final size of the log buffer."
2411 2457
2412(defun mh-exec-cmd (command &rest args) 2458(defun mh-exec-cmd (command &rest args)
2413 "Execute mh-command COMMAND with ARGS. 2459 "Execute mh-command COMMAND with ARGS.
2414The side effects are what is desired. 2460The side effects are what is desired. Any output is assumed to be
2415Any output is assumed to be an error and is shown to the user. 2461an error and is shown to the user. The output is not read or
2416The output is not read or parsed by MH-E." 2462parsed by MH-E."
2417 (save-excursion 2463 (save-excursion
2418 (set-buffer (get-buffer-create mh-log-buffer)) 2464 (set-buffer (get-buffer-create mh-log-buffer))
2419 (let* ((initial-size (mh-truncate-log-buffer)) 2465 (let* ((initial-size (mh-truncate-log-buffer))
@@ -2450,9 +2496,9 @@ Signals an error if process does not complete successfully."
2450(defun mh-exec-cmd-daemon (command filter &rest args) 2496(defun mh-exec-cmd-daemon (command filter &rest args)
2451 "Execute MH command COMMAND in the background. 2497 "Execute MH command COMMAND in the background.
2452 2498
2453If FILTER is non-nil then it is used to process the output otherwise the 2499If FILTER is non-nil then it is used to process the output
2454default filter `mh-process-daemon' is used. See `set-process-filter' for more 2500otherwise the default filter `mh-process-daemon' is used. See
2455details of FILTER. 2501`set-process-filter' for more details of FILTER.
2456 2502
2457ARGS are passed to COMMAND as command line arguments." 2503ARGS are passed to COMMAND as command line arguments."
2458 (save-excursion 2504 (save-excursion
@@ -2472,9 +2518,9 @@ ARGS are passed to COMMAND as command line arguments."
2472ENV is nil or a string of space-separated \"var=value\" elements. 2518ENV is nil or a string of space-separated \"var=value\" elements.
2473Signals an error if process does not complete successfully. 2519Signals an error if process does not complete successfully.
2474 2520
2475If FILTER is non-nil then it is used to process the output otherwise the 2521If FILTER is non-nil then it is used to process the output
2476default filter `mh-process-daemon' is used. See `set-process-filter' for more 2522otherwise the default filter `mh-process-daemon' is used. See
2477details of FILTER. 2523`set-process-filter' for more details of FILTER.
2478 2524
2479ARGS are passed to COMMAND as command line arguments." 2525ARGS are passed to COMMAND as command line arguments."
2480 (let ((process-environment process-environment)) 2526 (let ((process-environment process-environment))
@@ -2484,17 +2530,20 @@ ARGS are passed to COMMAND as command line arguments."
2484 2530
2485(defun mh-process-daemon (process output) 2531(defun mh-process-daemon (process output)
2486 "PROCESS daemon that puts OUTPUT into a temporary buffer. 2532 "PROCESS daemon that puts OUTPUT into a temporary buffer.
2487Any output from the process is displayed in an asynchronous pop-up window." 2533Any output from the process is displayed in an asynchronous
2534pop-up window."
2488 (set-buffer (get-buffer-create mh-log-buffer)) 2535 (set-buffer (get-buffer-create mh-log-buffer))
2489 (insert-before-markers output) 2536 (insert-before-markers output)
2490 (display-buffer mh-log-buffer)) 2537 (display-buffer mh-log-buffer))
2491 2538
2492(defun mh-exec-cmd-quiet (raise-error command &rest args) 2539(defun mh-exec-cmd-quiet (raise-error command &rest args)
2493 "Signal RAISE-ERROR if COMMAND with ARGS fails. 2540 "Signal RAISE-ERROR if COMMAND with ARGS fails.
2494Execute MH command COMMAND with ARGS. ARGS is a list of strings. 2541Execute MH command COMMAND with ARGS. ARGS is a list of strings.
2495Return at start of mh-temp buffer, where output can be parsed and used. 2542Return at start of mh-temp buffer, where output can be parsed and
2496Returns value of `call-process', which is 0 for success, unless RAISE-ERROR is 2543used.
2497non-nil, in which case an error is signaled if `call-process' returns non-0." 2544Returns value of `call-process', which is 0 for success, unless
2545RAISE-ERROR is non-nil, in which case an error is signaled if
2546`call-process' returns non-0."
2498 (set-buffer (get-buffer-create mh-temp-buffer)) 2547 (set-buffer (get-buffer-create mh-temp-buffer))
2499 (erase-buffer) 2548 (erase-buffer)
2500 (let ((value 2549 (let ((value
@@ -2514,8 +2563,8 @@ non-nil, in which case an error is signaled if `call-process' returns non-0."
2514 2563
2515(defun mh-exchange-point-and-mark-preserving-active-mark () 2564(defun mh-exchange-point-and-mark-preserving-active-mark ()
2516 "Put the mark where point is now, and point where the mark is now. 2565 "Put the mark where point is now, and point where the mark is now.
2517This command works even when the mark is not active, and preserves whether the 2566This command works even when the mark is not active, and
2518mark is active or not." 2567preserves whether the mark is active or not."
2519 (interactive nil) 2568 (interactive nil)
2520 (let ((is-active (and (boundp 'mark-active) mark-active))) 2569 (let ((is-active (and (boundp 'mark-active) mark-active)))
2521 (let ((omark (mark t))) 2570 (let ((omark (mark t)))
@@ -2529,7 +2578,8 @@ mark is active or not."
2529 2578
2530(defun mh-exec-cmd-output (command display &rest args) 2579(defun mh-exec-cmd-output (command display &rest args)
2531 "Execute MH command COMMAND with DISPLAY flag and ARGS. 2580 "Execute MH command COMMAND with DISPLAY flag and ARGS.
2532Put the output into buffer after point. Set mark after inserted text. 2581Put the output into buffer after point.
2582Set mark after inserted text.
2533Output is expected to be shown to user, not parsed by MH-E." 2583Output is expected to be shown to user, not parsed by MH-E."
2534 (push-mark (point) t) 2584 (push-mark (point) t)
2535 (apply 'call-process 2585 (apply 'call-process
@@ -2545,7 +2595,8 @@ Output is expected to be shown to user, not parsed by MH-E."
2545 2595
2546(defun mh-exec-lib-cmd-output (command &rest args) 2596(defun mh-exec-lib-cmd-output (command &rest args)
2547 "Execute MH library command COMMAND with ARGS. 2597 "Execute MH library command COMMAND with ARGS.
2548Put the output into buffer after point. Set mark after inserted text." 2598Put the output into buffer after point.
2599Set mark after inserted text."
2549 (apply 'mh-exec-cmd-output (expand-file-name command mh-lib-progs) nil args)) 2600 (apply 'mh-exec-cmd-output (expand-file-name command mh-lib-progs) nil args))
2550 2601
2551(defun mh-handle-process-error (command status) 2602(defun mh-handle-process-error (command status)
@@ -2597,11 +2648,13 @@ Put the output into buffer after point. Set mark after inserted text."
2597 "Replace REGEXP with NEWTEXT everywhere in STRING and return result. 2648 "Replace REGEXP with NEWTEXT everywhere in STRING and return result.
2598NEWTEXT is taken literally---no \\DIGIT escapes will be recognized. 2649NEWTEXT is taken literally---no \\DIGIT escapes will be recognized.
2599 2650
2600The function body was copied from `dired-replace-in-string' in dired.el. 2651The function body was copied from `dired-replace-in-string' in
2601Emacs21 has `replace-regexp-in-string' while XEmacs has `replace-in-string'. 2652dired.el.
2602Neither is present in Emacs20. The file gnus-util.el in Gnus 5.10.1 and above 2653Emacs21 has `replace-regexp-in-string' while XEmacs has
2603has `gnus-replace-in-string'. We should use that when we decide to not support 2654`replace-in-string'.
2604older versions of Gnus." 2655Neither is present in Emacs20. The file gnus-util.el in Gnus 5.10.1
2656and above has `gnus-replace-in-string'. We should use that when we
2657decide to not support older versions of Gnus."
2605 (let ((result "") (start 0) mb me) 2658 (let ((result "") (start 0) mb me)
2606 (while (string-match regexp string start) 2659 (while (string-match regexp string start)
2607 (setq mb (match-beginning 0) 2660 (setq mb (match-beginning 0)
diff --git a/lisp/mouse.el b/lisp/mouse.el
index b5881272835..b92413f7383 100644
--- a/lisp/mouse.el
+++ b/lisp/mouse.el
@@ -2230,7 +2230,7 @@ and selects that window."
2230 (setq beg (previous-single-property-change beg 'mouse-face)) 2230 (setq beg (previous-single-property-change beg 'mouse-face))
2231 (setq end (or (next-single-property-change end 'mouse-face) 2231 (setq end (or (next-single-property-change end 'mouse-face)
2232 (point-max))) 2232 (point-max)))
2233 (setq choice (buffer-substring beg end))))) 2233 (setq choice (buffer-substring-no-properties beg end)))))
2234 (let ((owindow (selected-window))) 2234 (let ((owindow (selected-window)))
2235 (select-window (posn-window (event-start event))) 2235 (select-window (posn-window (event-start event)))
2236 (if (and (one-window-p t 'selected-frame) 2236 (if (and (one-window-p t 'selected-frame)
diff --git a/lisp/progmodes/cpp.el b/lisp/progmodes/cpp.el
index 7e0bb8b4f9b..cf119bde719 100644
--- a/lisp/progmodes/cpp.el
+++ b/lisp/progmodes/cpp.el
@@ -189,7 +189,7 @@ or a cons cell (background-color . COLOR)."
189 '(("default" . default) 189 '(("default" . default)
190 ("invisible" . invisible)) 190 ("invisible" . invisible))
191 "Alist of names and faces available even if you don't use a window system." 191 "Alist of names and faces available even if you don't use a window system."
192 :type '(repeat (cons string face)) 192 :type '(repeat (cons string cpp-face))
193 :group 'cpp) 193 :group 'cpp)
194 194
195(defvar cpp-face-all-list 195(defvar cpp-face-all-list
diff --git a/lisp/progmodes/delphi.el b/lisp/progmodes/delphi.el
index 85f7e1339f3..cdc557c7274 100644
--- a/lisp/progmodes/delphi.el
+++ b/lisp/progmodes/delphi.el
@@ -177,7 +177,7 @@ differs from the default."
177 177
178(defcustom delphi-other-face nil 178(defcustom delphi-other-face nil
179 "*Face used to color everything else." 179 "*Face used to color everything else."
180 :type 'face 180 :type '(choice face (const nil))
181 :group 'delphi) 181 :group 'delphi)
182 182
183(defconst delphi-directives 183(defconst delphi-directives
diff --git a/lisp/progmodes/gud.el b/lisp/progmodes/gud.el
index aa0fd0c1378..5b1edbe89be 100644
--- a/lisp/progmodes/gud.el
+++ b/lisp/progmodes/gud.el
@@ -3263,7 +3263,6 @@ Treats actions as defuns."
3263(defcustom gud-tooltip-modes '(gud-mode c-mode c++-mode fortran-mode) 3263(defcustom gud-tooltip-modes '(gud-mode c-mode c++-mode fortran-mode)
3264 "List of modes for which to enable GUD tooltips." 3264 "List of modes for which to enable GUD tooltips."
3265 :type 'sexp 3265 :type 'sexp
3266 :tag "GUD modes"
3267 :group 'gud 3266 :group 'gud
3268 :group 'tooltip) 3267 :group 'tooltip)
3269 3268
@@ -3275,7 +3274,6 @@ Treats actions as defuns."
3275Forms in the list are combined with AND. The default is to display 3274Forms in the list are combined with AND. The default is to display
3276only tooltips in the buffer containing the overlay arrow." 3275only tooltips in the buffer containing the overlay arrow."
3277 :type 'sexp 3276 :type 'sexp
3278 :tag "GUD buffers predicate"
3279 :group 'gud 3277 :group 'gud
3280 :group 'tooltip) 3278 :group 'tooltip)
3281 3279
diff --git a/lisp/savehist.el b/lisp/savehist.el
index 97960199302..ef75369c761 100644
--- a/lisp/savehist.el
+++ b/lisp/savehist.el
@@ -129,7 +129,8 @@ If set to nil, disables timer-based autosaving."
129 129
130(defcustom savehist-mode-hook nil 130(defcustom savehist-mode-hook nil
131 "Hook called when `savehist-mode' is turned on." 131 "Hook called when `savehist-mode' is turned on."
132 :type 'hook) 132 :type 'hook
133 :group 'savehist)
133 134
134(defcustom savehist-save-hook nil 135(defcustom savehist-save-hook nil
135 "Hook called by `savehist-save' before saving the variables. 136 "Hook called by `savehist-save' before saving the variables.
diff --git a/lisp/simple.el b/lisp/simple.el
index 99487430c88..47047d9ef6d 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -52,15 +52,15 @@ wait this many seconds after Emacs becomes idle before doing an update."
52 "Highlight (un)matching of parens and expressions." 52 "Highlight (un)matching of parens and expressions."
53 :group 'matching) 53 :group 'matching)
54 54
55(defun get-next-valid-buffer (list &optional buffer visible-ok frame) "\ 55(defun get-next-valid-buffer (list &optional buffer visible-ok frame)
56Search LIST for a valid buffer to display in FRAME. 56 "Search LIST for a valid buffer to display in FRAME.
57Return nil when all buffers in LIST are undesirable for display, 57Return nil when all buffers in LIST are undesirable for display,
58otherwise return the first suitable buffer in LIST. 58otherwise return the first suitable buffer in LIST.
59 59
60Buffers not visible in windows are preferred to visible buffers, 60Buffers not visible in windows are preferred to visible buffers,
61unless VISIBLE-OK is non-nil. 61unless VISIBLE-OK is non-nil.
62If the optional argument FRAME is nil, it defaults to the selected frame. 62If the optional argument FRAME is nil, it defaults to the selected frame.
63If BUFFER is non-nil, ignore occurances of that buffer in LIST." 63If BUFFER is non-nil, ignore occurrences of that buffer in LIST."
64 ;; This logic is more or less copied from other-buffer. 64 ;; This logic is more or less copied from other-buffer.
65 (setq frame (or frame (selected-frame))) 65 (setq frame (or frame (selected-frame)))
66 (let ((pred (frame-parameter frame 'buffer-predicate)) 66 (let ((pred (frame-parameter frame 'buffer-predicate))
@@ -76,8 +76,8 @@ If BUFFER is non-nil, ignore occurances of that buffer in LIST."
76 (setq list (cdr list)))) 76 (setq list (cdr list))))
77 (car list))) 77 (car list)))
78 78
79(defun last-buffer (&optional buffer visible-ok frame) "\ 79(defun last-buffer (&optional buffer visible-ok frame)
80Return the last non-hidden displayable buffer in the buffer list. 80 "Return the last non-hidden displayable buffer in the buffer list.
81If BUFFER is non-nil, last-buffer will ignore that buffer. 81If BUFFER is non-nil, last-buffer will ignore that buffer.
82Buffers not visible in windows are preferred to visible buffers, 82Buffers not visible in windows are preferred to visible buffers,
83unless optional argument VISIBLE-OK is non-nil. 83unless optional argument VISIBLE-OK is non-nil.
@@ -184,7 +184,7 @@ The function EXTRA-TEST-INCLUSIVE, if non-nil, is called in each buffer
184that normally would not qualify. If it returns t, the buffer 184that normally would not qualify. If it returns t, the buffer
185in question is treated as usable. 185in question is treated as usable.
186 186
187The function EXTRA-TEST-EXCLUSIVE, if non-nil is called in each buffer 187The function EXTRA-TEST-EXCLUSIVE, if non-nil, is called in each buffer
188that would normally be considered usable. If it returns nil, 188that would normally be considered usable. If it returns nil,
189that buffer is rejected." 189that buffer is rejected."
190 (and (buffer-name buffer) ;First make sure it's live. 190 (and (buffer-name buffer) ;First make sure it's live.
@@ -203,6 +203,7 @@ that buffer is rejected."
203 extra-test-inclusive 203 extra-test-inclusive
204 extra-test-exclusive) 204 extra-test-exclusive)
205 "Return a `next-error' capable buffer. 205 "Return a `next-error' capable buffer.
206
206If AVOID-CURRENT is non-nil, treat the current buffer 207If AVOID-CURRENT is non-nil, treat the current buffer
207as an absolute last resort only. 208as an absolute last resort only.
208 209
@@ -210,7 +211,7 @@ The function EXTRA-TEST-INCLUSIVE, if non-nil, is called in each buffer
210that normally would not qualify. If it returns t, the buffer 211that normally would not qualify. If it returns t, the buffer
211in question is treated as usable. 212in question is treated as usable.
212 213
213The function EXTRA-TEST-EXCLUSIVE, if non-nil is called in each buffer 214The function EXTRA-TEST-EXCLUSIVE, if non-nil, is called in each buffer
214that would normally be considered usable. If it returns nil, 215that would normally be considered usable. If it returns nil,
215that buffer is rejected." 216that buffer is rejected."
216 (or 217 (or
@@ -1137,7 +1138,7 @@ except when an alternate history list is specified.")
1137 "Control whether history list elements are expressions or strings. 1138 "Control whether history list elements are expressions or strings.
1138If the value of this variable equals current minibuffer depth, 1139If the value of this variable equals current minibuffer depth,
1139they are expressions; otherwise they are strings. 1140they are expressions; otherwise they are strings.
1140\(That convention is designed to do the right thing fora 1141\(That convention is designed to do the right thing for
1141recursive uses of the minibuffer.)") 1142recursive uses of the minibuffer.)")
1142(setq minibuffer-history-variable 'minibuffer-history) 1143(setq minibuffer-history-variable 'minibuffer-history)
1143(setq minibuffer-history-position nil) 1144(setq minibuffer-history-position nil)
diff --git a/lisp/textmodes/flyspell.el b/lisp/textmodes/flyspell.el
index 4bea438bf2b..cad65b3b59d 100644
--- a/lisp/textmodes/flyspell.el
+++ b/lisp/textmodes/flyspell.el
@@ -324,7 +324,7 @@ property of the major mode name.")
324 "This function is used for `flyspell-generic-check-word-p' in LaTeX mode." 324 "This function is used for `flyspell-generic-check-word-p' in LaTeX mode."
325 (and 325 (and
326 (not (save-excursion 326 (not (save-excursion
327 (re-search-backward "^[ \t]*%%%[ \t]+Local" (point-min) t))) 327 (re-search-backward "^[ \t]*%%%[ \t]+Local" nil t)))
328 (not (save-excursion 328 (not (save-excursion
329 (let ((this (point-marker)) 329 (let ((this (point-marker))
330 (e (progn (end-of-line) (point-marker)))) 330 (e (progn (end-of-line) (point-marker))))
@@ -753,7 +753,7 @@ Mostly we check word delimiters."
753 (backward-char 1) 753 (backward-char 1)
754 (and (looking-at (flyspell-get-not-casechars)) 754 (and (looking-at (flyspell-get-not-casechars))
755 (or flyspell-consider-dash-as-word-delimiter-flag 755 (or flyspell-consider-dash-as-word-delimiter-flag
756 (not (looking-at "\\-")))))) 756 (not (looking-at "-"))))))
757 ;; yes because we have reached or typed a word delimiter. 757 ;; yes because we have reached or typed a word delimiter.
758 t) 758 t)
759 ((symbolp this-command) 759 ((symbolp this-command)
@@ -1225,10 +1225,10 @@ Word syntax described by `flyspell-dictionary-alist' (which see)."
1225 ;; find the word 1225 ;; find the word
1226 (if (not (looking-at flyspell-casechars)) 1226 (if (not (looking-at flyspell-casechars))
1227 (if following 1227 (if following
1228 (re-search-forward flyspell-casechars (point-max) t) 1228 (re-search-forward flyspell-casechars nil t)
1229 (re-search-backward flyspell-casechars (point-min) t))) 1229 (re-search-backward flyspell-casechars nil t)))
1230 ;; move to front of word 1230 ;; move to front of word
1231 (re-search-backward flyspell-not-casechars (point-min) 'start) 1231 (re-search-backward flyspell-not-casechars nil 'start)
1232 (while (and (or (and (not (string= "" ispell-otherchars)) 1232 (while (and (or (and (not (string= "" ispell-otherchars))
1233 (looking-at ispell-otherchars)) 1233 (looking-at ispell-otherchars))
1234 (and extra-otherchars (looking-at extra-otherchars))) 1234 (and extra-otherchars (looking-at extra-otherchars)))
@@ -1240,15 +1240,15 @@ Word syntax described by `flyspell-dictionary-alist' (which see)."
1240 (progn 1240 (progn
1241 (backward-char 1) 1241 (backward-char 1)
1242 (if (looking-at flyspell-casechars) 1242 (if (looking-at flyspell-casechars)
1243 (re-search-backward flyspell-not-casechars (point-min) 'move))) 1243 (re-search-backward flyspell-not-casechars nil 'move)))
1244 (setq did-it-once t 1244 (setq did-it-once t
1245 prevpt (point)) 1245 prevpt (point))
1246 (backward-char 1) 1246 (backward-char 1)
1247 (if (looking-at flyspell-casechars) 1247 (if (looking-at flyspell-casechars)
1248 (re-search-backward flyspell-not-casechars (point-min) 'move) 1248 (re-search-backward flyspell-not-casechars nil 'move)
1249 (backward-char -1)))) 1249 (backward-char -1))))
1250 ;; Now mark the word and save to string. 1250 ;; Now mark the word and save to string.
1251 (if (not (re-search-forward word-regexp (point-max) t)) 1251 (if (not (re-search-forward word-regexp nil t))
1252 nil 1252 nil
1253 (progn 1253 (progn
1254 (setq start (match-beginning 0) 1254 (setq start (match-beginning 0)
@@ -1312,7 +1312,7 @@ The buffer to mark them in is `flyspell-large-region-buffer'."
1312 (with-current-buffer flyspell-external-ispell-buffer 1312 (with-current-buffer flyspell-external-ispell-buffer
1313 (goto-char (point-min)) 1313 (goto-char (point-min))
1314 ;; Loop over incorrect words. 1314 ;; Loop over incorrect words.
1315 (while (re-search-forward "\\([^\n]+\\)\n" (point-max) t) 1315 (while (re-search-forward "\\([^\n]+\\)\n" nil t)
1316 ;; Bind WORD to the next one. 1316 ;; Bind WORD to the next one.
1317 (let ((word (match-string 1)) (wordpos (point))) 1317 (let ((word (match-string 1)) (wordpos (point)))
1318 ;; Here there used to be code to see if WORD is the same 1318 ;; Here there used to be code to see if WORD is the same
diff --git a/lisp/tool-bar.el b/lisp/tool-bar.el
index c4325505ac4..15321a4ffd8 100644
--- a/lisp/tool-bar.el
+++ b/lisp/tool-bar.el
@@ -233,7 +233,7 @@ holds a keymap."
233 ;; might inadvertently click that button. 233 ;; might inadvertently click that button.
234 ;;(tool-bar-add-item-from-menu 'save-buffers-kill-emacs "exit") 234 ;;(tool-bar-add-item-from-menu 'save-buffers-kill-emacs "exit")
235 (tool-bar-add-item-from-menu 'find-file "new") 235 (tool-bar-add-item-from-menu 'find-file "new")
236 (tool-bar-add-item-from-menu 'find-file-existing "open") 236 (tool-bar-add-item-from-menu 'menu-find-file-existing "open")
237 (tool-bar-add-item-from-menu 'dired "diropen") 237 (tool-bar-add-item-from-menu 'dired "diropen")
238 (tool-bar-add-item-from-menu 'kill-this-buffer "close") 238 (tool-bar-add-item-from-menu 'kill-this-buffer "close")
239 (tool-bar-add-item-from-menu 'save-buffer "save" nil 239 (tool-bar-add-item-from-menu 'save-buffer "save" nil
diff --git a/lisp/url/ChangeLog b/lisp/url/ChangeLog
index 81ba66736b0..9abb65d389d 100644
--- a/lisp/url/ChangeLog
+++ b/lisp/url/ChangeLog
@@ -1,3 +1,9 @@
12005-12-21 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 * url-cookie.el (url-cookie-write-file): Create parent dir.
4
5 * url.el (url-configuration-directory): Use ~/.emacs.d if possible.
6
12005-12-07 Klaus Straubinger <KSNetz@Arcor.DE> (tiny change) 72005-12-07 Klaus Straubinger <KSNetz@Arcor.DE> (tiny change)
2 8
3 * url-cookie.el (url-cookie-save-interval): Simplify. 9 * url-cookie.el (url-cookie-save-interval): Simplify.
diff --git a/lisp/url/url-cookie.el b/lisp/url/url-cookie.el
index 480a16c204d..3772846607a 100644
--- a/lisp/url/url-cookie.el
+++ b/lisp/url/url-cookie.el
@@ -148,6 +148,8 @@ telling Microsoft that."
148;;;###autoload 148;;;###autoload
149(defun url-cookie-write-file (&optional fname) 149(defun url-cookie-write-file (&optional fname)
150 (setq fname (or fname url-cookie-file)) 150 (setq fname (or fname url-cookie-file))
151 (unless (file-directory-p (file-name-directory fname))
152 (ignore-errors (make-directory (file-name-directory fname))))
151 (cond 153 (cond
152 ((not url-cookies-changed-since-last-save) nil) 154 ((not url-cookies-changed-since-last-save) nil)
153 ((not (file-writable-p fname)) 155 ((not (file-writable-p fname))
@@ -155,8 +157,7 @@ telling Microsoft that."
155 (t 157 (t
156 (url-cookie-clean-up) 158 (url-cookie-clean-up)
157 (url-cookie-clean-up t) 159 (url-cookie-clean-up t)
158 (save-excursion 160 (with-current-buffer (get-buffer-create " *cookies*")
159 (set-buffer (get-buffer-create " *cookies*"))
160 (erase-buffer) 161 (erase-buffer)
161 (fundamental-mode) 162 (fundamental-mode)
162 (insert ";; Emacs-W3 HTTP cookies file\n" 163 (insert ";; Emacs-W3 HTTP cookies file\n"
diff --git a/lisp/url/url.el b/lisp/url/url.el
index 81d2d39c281..296b2b9f868 100644
--- a/lisp/url/url.el
+++ b/lisp/url/url.el
@@ -48,7 +48,11 @@
48 48
49;; Fixme: customize? convert-standard-filename? 49;; Fixme: customize? convert-standard-filename?
50;;;###autoload 50;;;###autoload
51(defvar url-configuration-directory "~/.url") 51(defvar url-configuration-directory
52 (cond
53 ((file-directory-p "~/.url") "~/.url")
54 ((file-directory-p "~/.emacs.d") "~/.emacs.d/url")
55 (t "~/.url")))
52 56
53(defun url-do-setup () 57(defun url-do-setup ()
54 "Setup the url package. 58 "Setup the url package.
diff --git a/lisp/vc.el b/lisp/vc.el
index d06e49ef1ba..ed6b13ac2ec 100644
--- a/lisp/vc.el
+++ b/lisp/vc.el
@@ -469,12 +469,12 @@
469 :group 'tools) 469 :group 'tools)
470 470
471(defcustom vc-suppress-confirm nil 471(defcustom vc-suppress-confirm nil
472 "*If non-nil, treat user as expert; suppress yes-no prompts on some things." 472 "If non-nil, treat user as expert; suppress yes-no prompts on some things."
473 :type 'boolean 473 :type 'boolean
474 :group 'vc) 474 :group 'vc)
475 475
476(defcustom vc-delete-logbuf-window t 476(defcustom vc-delete-logbuf-window t
477 "*If non-nil, delete the *VC-log* buffer and window after each logical action. 477 "If non-nil, delete the *VC-log* buffer and window after each logical action.
478If nil, bury that buffer instead. 478If nil, bury that buffer instead.
479This is most useful if you have multiple windows on a frame and would like to 479This is most useful if you have multiple windows on a frame and would like to
480preserve the setting." 480preserve the setting."
@@ -482,12 +482,12 @@ preserve the setting."
482 :group 'vc) 482 :group 'vc)
483 483
484(defcustom vc-initial-comment nil 484(defcustom vc-initial-comment nil
485 "*If non-nil, prompt for initial comment when a file is registered." 485 "If non-nil, prompt for initial comment when a file is registered."
486 :type 'boolean 486 :type 'boolean
487 :group 'vc) 487 :group 'vc)
488 488
489(defcustom vc-default-init-version "1.1" 489(defcustom vc-default-init-version "1.1"
490 "*A string used as the default version number when a new file is registered. 490 "A string used as the default version number when a new file is registered.
491This can be overridden by giving a prefix argument to \\[vc-register]. This 491This can be overridden by giving a prefix argument to \\[vc-register]. This
492can also be overridden by a particular VC backend." 492can also be overridden by a particular VC backend."
493 :type 'string 493 :type 'string
@@ -495,12 +495,12 @@ can also be overridden by a particular VC backend."
495 :version "20.3") 495 :version "20.3")
496 496
497(defcustom vc-command-messages nil 497(defcustom vc-command-messages nil
498 "*If non-nil, display run messages from back-end commands." 498 "If non-nil, display run messages from back-end commands."
499 :type 'boolean 499 :type 'boolean
500 :group 'vc) 500 :group 'vc)
501 501
502(defcustom vc-checkin-switches nil 502(defcustom vc-checkin-switches nil
503 "*A string or list of strings specifying extra switches for checkin. 503 "A string or list of strings specifying extra switches for checkin.
504These are passed to the checkin program by \\[vc-checkin]." 504These are passed to the checkin program by \\[vc-checkin]."
505 :type '(choice (const :tag "None" nil) 505 :type '(choice (const :tag "None" nil)
506 (string :tag "Argument String") 506 (string :tag "Argument String")
@@ -510,7 +510,7 @@ These are passed to the checkin program by \\[vc-checkin]."
510 :group 'vc) 510 :group 'vc)
511 511
512(defcustom vc-checkout-switches nil 512(defcustom vc-checkout-switches nil
513 "*A string or list of strings specifying extra switches for checkout. 513 "A string or list of strings specifying extra switches for checkout.
514These are passed to the checkout program by \\[vc-checkout]." 514These are passed to the checkout program by \\[vc-checkout]."
515 :type '(choice (const :tag "None" nil) 515 :type '(choice (const :tag "None" nil)
516 (string :tag "Argument String") 516 (string :tag "Argument String")
@@ -520,7 +520,7 @@ These are passed to the checkout program by \\[vc-checkout]."
520 :group 'vc) 520 :group 'vc)
521 521
522(defcustom vc-register-switches nil 522(defcustom vc-register-switches nil
523 "*A string or list of strings; extra switches for registering a file. 523 "A string or list of strings; extra switches for registering a file.
524These are passed to the checkin program by \\[vc-register]." 524These are passed to the checkin program by \\[vc-register]."
525 :type '(choice (const :tag "None" nil) 525 :type '(choice (const :tag "None" nil)
526 (string :tag "Argument String") 526 (string :tag "Argument String")
@@ -530,30 +530,30 @@ These are passed to the checkin program by \\[vc-register]."
530 :group 'vc) 530 :group 'vc)
531 531
532(defcustom vc-dired-listing-switches "-al" 532(defcustom vc-dired-listing-switches "-al"
533 "*Switches passed to `ls' for vc-dired. MUST contain the `l' option." 533 "Switches passed to `ls' for vc-dired. MUST contain the `l' option."
534 :type 'string 534 :type 'string
535 :group 'vc 535 :group 'vc
536 :version "21.1") 536 :version "21.1")
537 537
538(defcustom vc-dired-recurse t 538(defcustom vc-dired-recurse t
539 "*If non-nil, show directory trees recursively in VC Dired." 539 "If non-nil, show directory trees recursively in VC Dired."
540 :type 'boolean 540 :type 'boolean
541 :group 'vc 541 :group 'vc
542 :version "20.3") 542 :version "20.3")
543 543
544(defcustom vc-dired-terse-display t 544(defcustom vc-dired-terse-display t
545 "*If non-nil, show only locked files in VC Dired." 545 "If non-nil, show only locked files in VC Dired."
546 :type 'boolean 546 :type 'boolean
547 :group 'vc 547 :group 'vc
548 :version "20.3") 548 :version "20.3")
549 549
550(defcustom vc-directory-exclusion-list '("SCCS" "RCS" "CVS" "MCVS" ".svn" "{arch}") 550(defcustom vc-directory-exclusion-list '("SCCS" "RCS" "CVS" "MCVS" ".svn" "{arch}")
551 "*List of directory names to be ignored when walking directory trees." 551 "List of directory names to be ignored when walking directory trees."
552 :type '(repeat string) 552 :type '(repeat string)
553 :group 'vc) 553 :group 'vc)
554 554
555(defcustom vc-diff-switches nil 555(defcustom vc-diff-switches nil
556 "*A string or list of strings specifying switches for diff under VC. 556 "A string or list of strings specifying switches for diff under VC.
557When running diff under a given BACKEND, VC concatenates the values of 557When running diff under a given BACKEND, VC concatenates the values of
558`diff-switches', `vc-diff-switches', and `vc-BACKEND-diff-switches' to 558`diff-switches', `vc-diff-switches', and `vc-BACKEND-diff-switches' to
559get the switches for that command. Thus, `vc-diff-switches' should 559get the switches for that command. Thus, `vc-diff-switches' should
@@ -568,7 +568,7 @@ specific to any particular backend."
568 :version "21.1") 568 :version "21.1")
569 569
570(defcustom vc-allow-async-revert nil 570(defcustom vc-allow-async-revert nil
571 "*Specifies whether the diff during \\[vc-revert-buffer] may be asynchronous. 571 "Specifies whether the diff during \\[vc-revert-buffer] may be asynchronous.
572Enabling this option means that you can confirm a revert operation even 572Enabling this option means that you can confirm a revert operation even
573if the local changes in the file have not been found and displayed yet." 573if the local changes in the file have not been found and displayed yet."
574 :type '(choice (const :tag "No" nil) 574 :type '(choice (const :tag "No" nil)
@@ -578,7 +578,7 @@ if the local changes in the file have not been found and displayed yet."
578 578
579;;;###autoload 579;;;###autoload
580(defcustom vc-checkout-hook nil 580(defcustom vc-checkout-hook nil
581 "*Normal hook (list of functions) run after checking out a file. 581 "Normal hook (list of functions) run after checking out a file.
582See `run-hooks'." 582See `run-hooks'."
583 :type 'hook 583 :type 'hook
584 :group 'vc 584 :group 'vc
@@ -595,7 +595,7 @@ See `run-hooks'."
595 595
596;;;###autoload 596;;;###autoload
597(defcustom vc-checkin-hook nil 597(defcustom vc-checkin-hook nil
598 "*Normal hook (list of functions) run after a checkin is done. 598 "Normal hook (list of functions) run after a checkin is done.
599See also `log-edit-done-hook'." 599See also `log-edit-done-hook'."
600 :type 'hook 600 :type 'hook
601 :options '(log-edit-comment-to-change-log) 601 :options '(log-edit-comment-to-change-log)
@@ -603,13 +603,13 @@ See also `log-edit-done-hook'."
603 603
604;;;###autoload 604;;;###autoload
605(defcustom vc-before-checkin-hook nil 605(defcustom vc-before-checkin-hook nil
606 "*Normal hook (list of functions) run before a file is checked in. 606 "Normal hook (list of functions) run before a file is checked in.
607See `run-hooks'." 607See `run-hooks'."
608 :type 'hook 608 :type 'hook
609 :group 'vc) 609 :group 'vc)
610 610
611(defcustom vc-logentry-check-hook nil 611(defcustom vc-logentry-check-hook nil
612 "*Normal hook run by `vc-backend-logentry-check'. 612 "Normal hook run by `vc-backend-logentry-check'.
613Use this to impose your own rules on the entry in addition to any the 613Use this to impose your own rules on the entry in addition to any the
614version control backend imposes itself." 614version control backend imposes itself."
615 :type 'hook 615 :type 'hook
@@ -634,25 +634,25 @@ version control backend imposes itself."
634 (300. . "#00CCFF") 634 (300. . "#00CCFF")
635 (320. . "#00CC99") 635 (320. . "#00CC99")
636 (340. . "#0099FF")) 636 (340. . "#0099FF"))
637 "*Association list of age versus color, for \\[vc-annotate]. 637 "Association list of age versus color, for \\[vc-annotate].
638Ages are given in units of fractional days. Default is eighteen steps 638Ages are given in units of fractional days. Default is eighteen steps
639using a twenty day increment." 639using a twenty day increment."
640 :type 'alist 640 :type 'alist
641 :group 'vc) 641 :group 'vc)
642 642
643(defcustom vc-annotate-very-old-color "#0046FF" 643(defcustom vc-annotate-very-old-color "#0046FF"
644 "*Color for lines older than the current color range in \\[vc-annotate]]." 644 "Color for lines older than the current color range in \\[vc-annotate]]."
645 :type 'string 645 :type 'string
646 :group 'vc) 646 :group 'vc)
647 647
648(defcustom vc-annotate-background "black" 648(defcustom vc-annotate-background "black"
649 "*Background color for \\[vc-annotate]. 649 "Background color for \\[vc-annotate].
650Default color is used if nil." 650Default color is used if nil."
651 :type 'string 651 :type 'string
652 :group 'vc) 652 :group 'vc)
653 653
654(defcustom vc-annotate-menu-elements '(2 0.5 0.1 0.01) 654(defcustom vc-annotate-menu-elements '(2 0.5 0.1 0.01)
655 "*Menu elements for the mode-specific menu of VC-Annotate mode. 655 "Menu elements for the mode-specific menu of VC-Annotate mode.
656List of factors, used to expand/compress the time scale. See `vc-annotate'." 656List of factors, used to expand/compress the time scale. See `vc-annotate'."
657 :type '(repeat number) 657 :type '(repeat number)
658 :group 'vc) 658 :group 'vc)
@@ -660,24 +660,23 @@ List of factors, used to expand/compress the time scale. See `vc-annotate'."
660(defvar vc-annotate-mode-map 660(defvar vc-annotate-mode-map
661 (let ((m (make-sparse-keymap))) 661 (let ((m (make-sparse-keymap)))
662 (define-key m [menu-bar] (make-sparse-keymap "VC-Annotate")) 662 (define-key m [menu-bar] (make-sparse-keymap "VC-Annotate"))
663 (define-key m "A" 'vc-annotate-revision-previous-to-line)
664 (define-key m "D" 'vc-annotate-show-diff-revision-at-line)
665 (define-key m "J" 'vc-annotate-revision-at-line)
666 (define-key m "L" 'vc-annotate-show-log-revision-at-line)
667 (define-key m "N" 'vc-annotate-next-version)
668 (define-key m "P" 'vc-annotate-prev-version)
669 (define-key m "W" 'vc-annotate-workfile-version)
663 m) 670 m)
664 "Local keymap used for VC-Annotate mode.") 671 "Local keymap used for VC-Annotate mode.")
665 672
666(define-key vc-annotate-mode-map "A" 'vc-annotate-revision-previous-to-line)
667(define-key vc-annotate-mode-map "D" 'vc-annotate-show-diff-revision-at-line)
668(define-key vc-annotate-mode-map "J" 'vc-annotate-revision-at-line)
669(define-key vc-annotate-mode-map "L" 'vc-annotate-show-log-revision-at-line)
670(define-key vc-annotate-mode-map "N" 'vc-annotate-next-version)
671(define-key vc-annotate-mode-map "P" 'vc-annotate-prev-version)
672(define-key vc-annotate-mode-map "W" 'vc-annotate-workfile-version)
673
674(defvar vc-annotate-mode-menu nil 673(defvar vc-annotate-mode-menu nil
675 "Local keymap used for VC-Annotate mode's menu bar menu.") 674 "Local keymap used for VC-Annotate mode's menu bar menu.")
676 675
677;; Header-insertion hair 676;; Header-insertion hair
678 677
679(defcustom vc-static-header-alist 678(defcustom vc-static-header-alist
680 '(("\\.c$" . 679 '(("\\.c\\'" .
681 "\n#ifndef lint\nstatic char vcid[] = \"\%s\";\n#endif /* lint */\n")) 680 "\n#ifndef lint\nstatic char vcid[] = \"\%s\";\n#endif /* lint */\n"))
682 "*Associate static header string templates with file types. 681 "*Associate static header string templates with file types.
683A \%s in the template is replaced with the first string associated with 682A \%s in the template is replaced with the first string associated with
@@ -713,9 +712,7 @@ and that its contents match what the master file says."
713;; Variables the user doesn't need to know about. 712;; Variables the user doesn't need to know about.
714(defvar vc-log-operation nil) 713(defvar vc-log-operation nil)
715(defvar vc-log-after-operation-hook nil) 714(defvar vc-log-after-operation-hook nil)
716(defvar vc-annotate-buffers nil 715
717 "Alist of current \"Annotate\" buffers and their corresponding backends.
718The keys are \(BUFFER . BACKEND\). See also `vc-annotate-get-backend'.")
719;; In a log entry buffer, this is a local variable 716;; In a log entry buffer, this is a local variable
720;; that points to the buffer for which it was made 717;; that points to the buffer for which it was made
721;; (either a file, or a VC dired buffer). 718;; (either a file, or a VC dired buffer).
@@ -1367,6 +1364,8 @@ merge in the changes into your working copy."
1367 1364
1368;; These functions help the vc-next-action entry point 1365;; These functions help the vc-next-action entry point
1369 1366
1367(defun vc-default-init-version (backend) vc-default-init-version)
1368
1370;;;###autoload 1369;;;###autoload
1371(defun vc-register (&optional set-version comment) 1370(defun vc-register (&optional set-version comment)
1372 "Register the current file into a version control system. 1371 "Register the current file into a version control system.
@@ -1398,10 +1397,8 @@ first backend that could register the file is used."
1398 (if set-version 1397 (if set-version
1399 (read-string (format "Initial version level for %s: " 1398 (read-string (format "Initial version level for %s: "
1400 (buffer-name))) 1399 (buffer-name)))
1401 (let ((backend (vc-responsible-backend buffer-file-name))) 1400 (vc-call-backend (vc-responsible-backend buffer-file-name)
1402 (if (vc-find-backend-function backend 'init-version) 1401 'init-version))
1403 (vc-call-backend backend 'init-version)
1404 vc-default-init-version)))
1405 (or comment (not vc-initial-comment)) 1402 (or comment (not vc-initial-comment))
1406 nil 1403 nil
1407 "Enter initial comment." 1404 "Enter initial comment."
@@ -1937,24 +1934,19 @@ the variable `vc-BACKEND-header'."
1937 (widen) 1934 (widen)
1938 (if (or (not (vc-check-headers)) 1935 (if (or (not (vc-check-headers))
1939 (y-or-n-p "Version headers already exist. Insert another set? ")) 1936 (y-or-n-p "Version headers already exist. Insert another set? "))
1940 (progn 1937 (let* ((delims (cdr (assq major-mode vc-comment-alist)))
1941 (let* ((delims (cdr (assq major-mode vc-comment-alist))) 1938 (comment-start-vc (or (car delims) comment-start "#"))
1942 (comment-start-vc (or (car delims) comment-start "#")) 1939 (comment-end-vc (or (car (cdr delims)) comment-end ""))
1943 (comment-end-vc (or (car (cdr delims)) comment-end "")) 1940 (hdsym (vc-make-backend-sym (vc-backend buffer-file-name)
1944 (hdsym (vc-make-backend-sym (vc-backend buffer-file-name) 1941 'header))
1945 'header)) 1942 (hdstrings (and (boundp hdsym) (symbol-value hdsym))))
1946 (hdstrings (and (boundp hdsym) (symbol-value hdsym)))) 1943 (dolist (s hdstrings)
1947 (mapcar (lambda (s) 1944 (insert comment-start-vc "\t" s "\t"
1948 (insert comment-start-vc "\t" s "\t" 1945 comment-end-vc "\n"))
1949 comment-end-vc "\n")) 1946 (if vc-static-header-alist
1950 hdstrings) 1947 (dolist (f vc-static-header-alist)
1951 (if vc-static-header-alist 1948 (if (string-match (car f) buffer-file-name)
1952 (mapcar (lambda (f) 1949 (insert (format (cdr f) (car hdstrings)))))))))))
1953 (if (string-match (car f) buffer-file-name)
1954 (insert (format (cdr f) (car hdstrings)))))
1955 vc-static-header-alist))
1956 )
1957 )))))
1958 1950
1959(defun vc-clear-headers (&optional file) 1951(defun vc-clear-headers (&optional file)
1960 "Clear all version headers in the current buffer (or FILE). 1952 "Clear all version headers in the current buffer (or FILE).
@@ -2897,8 +2889,7 @@ Uses `rcs2log' which only works for RCS and CVS."
2897 (concat odefault f)))) 2889 (concat odefault f))))
2898 files))) 2890 files)))
2899 "done" 2891 "done"
2900 (pop-to-buffer 2892 (pop-to-buffer (get-buffer-create "*vc*"))
2901 (set-buffer (get-buffer-create "*vc*")))
2902 (erase-buffer) 2893 (erase-buffer)
2903 (insert-file-contents tempfile) 2894 (insert-file-contents tempfile)
2904 "failed")) 2895 "failed"))
@@ -2913,9 +2904,9 @@ Uses `rcs2log' which only works for RCS and CVS."
2913;; annotate-mode, which replaces it with the more sensible "span-to 2904;; annotate-mode, which replaces it with the more sensible "span-to
2914;; days", along with autoscaling support. 2905;; days", along with autoscaling support.
2915(defvar vc-annotate-ratio nil "Global variable.") 2906(defvar vc-annotate-ratio nil "Global variable.")
2916(defvar vc-annotate-backend nil "Global variable.")
2917 2907
2918;; internal buffer-local variables 2908;; internal buffer-local variables
2909(defvar vc-annotate-backend nil)
2919(defvar vc-annotate-parent-file nil) 2910(defvar vc-annotate-parent-file nil)
2920(defvar vc-annotate-parent-rev nil) 2911(defvar vc-annotate-parent-rev nil)
2921(defvar vc-annotate-parent-display-mode nil) 2912(defvar vc-annotate-parent-display-mode nil)
@@ -2924,12 +2915,6 @@ Uses `rcs2log' which only works for RCS and CVS."
2924 ;; The fontification is done by vc-annotate-lines instead of font-lock. 2915 ;; The fontification is done by vc-annotate-lines instead of font-lock.
2925 '((vc-annotate-lines))) 2916 '((vc-annotate-lines)))
2926 2917
2927(defun vc-annotate-get-backend (buffer)
2928 "Return the backend matching \"Annotate\" buffer BUFFER.
2929Return nil if no match made. Associations are made based on
2930`vc-annotate-buffers'."
2931 (cdr (assoc buffer vc-annotate-buffers)))
2932
2933(define-derived-mode vc-annotate-mode fundamental-mode "Annotate" 2918(define-derived-mode vc-annotate-mode fundamental-mode "Annotate"
2934 "Major mode for output buffers of the `vc-annotate' command. 2919 "Major mode for output buffers of the `vc-annotate' command.
2935 2920
@@ -2939,8 +2924,7 @@ menu items."
2939 (set (make-local-variable 'truncate-lines) t) 2924 (set (make-local-variable 'truncate-lines) t)
2940 (set (make-local-variable 'font-lock-defaults) 2925 (set (make-local-variable 'font-lock-defaults)
2941 '(vc-annotate-font-lock-keywords t)) 2926 '(vc-annotate-font-lock-keywords t))
2942 (view-mode 1) 2927 (view-mode 1))
2943 (vc-annotate-add-menu))
2944 2928
2945(defun vc-annotate-display-default (&optional ratio) 2929(defun vc-annotate-display-default (&optional ratio)
2946 "Display the output of \\[vc-annotate] using the default color range. 2930 "Display the output of \\[vc-annotate] using the default color range.
@@ -2952,6 +2936,10 @@ if present. The current time is used as the offset."
2952 (if ratio (vc-annotate-time-span vc-annotate-color-map ratio))) 2936 (if ratio (vc-annotate-time-span vc-annotate-color-map ratio)))
2953 (message "Redisplaying annotation...done")) 2937 (message "Redisplaying annotation...done"))
2954 2938
2939(defun vc-annotate-car-last-cons (a-list)
2940 "Return car of last cons in association list A-LIST."
2941 (caar (last a-list)))
2942
2955(defun vc-annotate-display-autoscale (&optional full) 2943(defun vc-annotate-display-autoscale (&optional full)
2956 "Highlight the output of \\[vc-annotate] using an autoscaled color map. 2944 "Highlight the output of \\[vc-annotate] using an autoscaled color map.
2957Autoscaling means that the map is scaled from the current time to the 2945Autoscaling means that the map is scaled from the current time to the
@@ -2987,70 +2975,48 @@ cover the range from the oldest annotation to the newest."
2987 (format "Spanned to %.1f days old" (- current oldest)))))) 2975 (format "Spanned to %.1f days old" (- current oldest))))))
2988 2976
2989;; Menu -- Using easymenu.el 2977;; Menu -- Using easymenu.el
2990(defun vc-annotate-add-menu () 2978(easy-menu-define vc-annotate-mode-menu vc-annotate-mode-map
2991 "Add the menu 'Annotate' to the menu bar in VC-Annotate mode." 2979 "VC Annotate Display Menu"
2992 (let ((menu-elements vc-annotate-menu-elements) 2980 `("VC-Annotate"
2993 (menu-def 2981 ["Default" (unless (null vc-annotate-display-mode)
2994 '("VC-Annotate" 2982 (setq vc-annotate-display-mode nil)
2995 ["Default" (unless (null vc-annotate-display-mode) 2983 (vc-annotate-display-select))
2996 (setq vc-annotate-display-mode nil) 2984 :style toggle :selected (null vc-annotate-display-mode)]
2997 (vc-annotate-display-select)) 2985 ,@(let ((oldest-in-map (vc-annotate-car-last-cons vc-annotate-color-map)))
2998 :style toggle :selected (null vc-annotate-display-mode)])) 2986 (mapcar (lambda (element)
2999 (oldest-in-map (vc-annotate-car-last-cons vc-annotate-color-map))) 2987 (let ((days (* element oldest-in-map)))
3000 (while menu-elements 2988 `([,(format "Span %.1f days" days)
3001 (let* ((element (car menu-elements)) 2989 (unless (and (numberp vc-annotate-display-mode)
3002 (days (* element oldest-in-map))) 2990 (= vc-annotate-display-mode ,days))
3003 (setq menu-elements (cdr menu-elements)) 2991 (vc-annotate-display-select nil ,days))
3004 (setq menu-def 2992 :style toggle :selected
3005 (append menu-def 2993 (and (numberp vc-annotate-display-mode)
3006 `([,(format "Span %.1f days" days) 2994 (= vc-annotate-display-mode ,days)) ])))
3007 (unless (and (numberp vc-annotate-display-mode) 2995 vc-annotate-menu-elements))
3008 (= vc-annotate-display-mode ,days)) 2996 ["Span ..."
3009 (vc-annotate-display-select nil ,days)) 2997 (let ((days
3010 :style toggle :selected 2998 (float (string-to-number
3011 (and (numberp vc-annotate-display-mode) 2999 (read-string "Span how many days? ")))))
3012 (= vc-annotate-display-mode ,days)) ]))))) 3000 (vc-annotate-display-select nil days)) t]
3013 (setq menu-def 3001 "--"
3014 (append menu-def 3002 ["Span to Oldest"
3015 (list 3003 (unless (eq vc-annotate-display-mode 'scale)
3016 ["Span ..." 3004 (vc-annotate-display-select nil 'scale))
3017 (let ((days 3005 :style toggle :selected
3018 (float (string-to-number 3006 (eq vc-annotate-display-mode 'scale)]
3019 (read-string "Span how many days? "))))) 3007 ["Span Oldest->Newest"
3020 (vc-annotate-display-select nil days)) t]) 3008 (unless (eq vc-annotate-display-mode 'fullscale)
3021 (list "--") 3009 (vc-annotate-display-select nil 'fullscale))
3022 (list 3010 :style toggle :selected
3023 ["Span to Oldest" 3011 (eq vc-annotate-display-mode 'fullscale)]
3024 (unless (eq vc-annotate-display-mode 'scale) 3012 "--"
3025 (vc-annotate-display-select nil 'scale)) 3013 ["Annotate previous revision" vc-annotate-prev-version]
3026 :style toggle :selected 3014 ["Annotate next revision" vc-annotate-next-version]
3027 (eq vc-annotate-display-mode 'scale)]) 3015 ["Annotate revision at line" vc-annotate-revision-at-line]
3028 (list 3016 ["Annotate revision previous to line" vc-annotate-revision-previous-to-line]
3029 ["Span Oldest->Newest" 3017 ["Annotate latest revision" vc-annotate-workfile-version]
3030 (unless (eq vc-annotate-display-mode 'fullscale) 3018 ["Show log of revision at line" vc-annotate-show-log-revision-at-line]
3031 (vc-annotate-display-select nil 'fullscale)) 3019 ["Show diff of revision at line" vc-annotate-show-diff-revision-at-line]))
3032 :style toggle :selected
3033 (eq vc-annotate-display-mode 'fullscale)])
3034 (list "--")
3035 (list ["Annotate previous revision"
3036 (call-interactively 'vc-annotate-prev-version)])
3037 (list ["Annotate next revision"
3038 (call-interactively 'vc-annotate-next-version)])
3039 (list ["Annotate revision at line"
3040 (vc-annotate-revision-at-line)])
3041 (list ["Annotate revision previous to line"
3042 (vc-annotate-revision-previous-to-line)])
3043 (list ["Annotate latest revision"
3044 (vc-annotate-workfile-version)])
3045 (list ["Show log of revision at line"
3046 (vc-annotate-show-log-revision-at-line)])
3047 (list ["Show diff of revision at line"
3048 (vc-annotate-show-diff-revision-at-line)])))
3049
3050 ;; Define the menu
3051 (if (or (featurep 'easymenu) (load "easymenu" t))
3052 (easy-menu-define vc-annotate-mode-menu vc-annotate-mode-map
3053 "VC Annotate Display Menu" menu-def))))
3054 3020
3055(defun vc-annotate-display-select (&optional buffer mode) 3021(defun vc-annotate-display-select (&optional buffer mode)
3056 "Highlight the output of \\[vc-annotate]. 3022 "Highlight the output of \\[vc-annotate].
@@ -3083,7 +3049,7 @@ use; you may override this using the second optional arg MODE."
3083;;;; the contents in BUFFER. 3049;;;; the contents in BUFFER.
3084 3050
3085;;;###autoload 3051;;;###autoload
3086(defun vc-annotate (prefix &optional revision display-mode) 3052(defun vc-annotate (file rev &optional display-mode buf)
3087 "Display the edit history of the current file using colors. 3053 "Display the edit history of the current file using colors.
3088 3054
3089This command creates a buffer that shows, for each line of the current 3055This command creates a buffer that shows, for each line of the current
@@ -3108,48 +3074,44 @@ Customization variables:
3108mode-specific menu. `vc-annotate-color-map' and 3074mode-specific menu. `vc-annotate-color-map' and
3109`vc-annotate-very-old-color' defines the mapping of time to 3075`vc-annotate-very-old-color' defines the mapping of time to
3110colors. `vc-annotate-background' specifies the background color." 3076colors. `vc-annotate-background' specifies the background color."
3111 (interactive "P") 3077 (interactive
3078 (save-current-buffer
3079 (vc-ensure-vc-buffer)
3080 (list buffer-file-name
3081 (let ((def (vc-workfile-version buffer-file-name)))
3082 (if (null current-prefix-arg) def
3083 (read-string
3084 (format "Annotate from version (default %s): " def)
3085 nil nil def)))
3086 (if (null current-prefix-arg)
3087 vc-annotate-display-mode
3088 (float (string-to-number
3089 (read-string "Annotate span days (default 20): "
3090 nil nil "20")))))))
3112 (vc-ensure-vc-buffer) 3091 (vc-ensure-vc-buffer)
3113 (let* ((temp-buffer-name nil) 3092 (setq vc-annotate-display-mode display-mode) ;Not sure why. --Stef
3114 (temp-buffer-show-function 'vc-annotate-display-select) 3093 (let* ((temp-buffer-name (format "*Annotate %s (rev %s)*" (buffer-name) rev))
3115 (rev (or revision (vc-workfile-version buffer-file-name))) 3094 (temp-buffer-show-function 'vc-annotate-display-select))
3116 (bfn buffer-file-name)
3117 (vc-annotate-version
3118 (if prefix (read-string
3119 (format "Annotate from version (default %s): " rev)
3120 nil nil rev)
3121 rev)))
3122 (if display-mode
3123 (setq vc-annotate-display-mode display-mode)
3124 (if prefix
3125 (setq vc-annotate-display-mode
3126 (float (string-to-number
3127 (read-string "Annotate span days (default 20): "
3128 nil nil "20"))))))
3129 (setq temp-buffer-name (format "*Annotate %s (rev %s)*"
3130 (buffer-name) vc-annotate-version))
3131 (setq vc-annotate-backend (vc-backend buffer-file-name))
3132 (message "Annotating...") 3095 (message "Annotating...")
3096 ;; If BUF is specified it tells in which buffer we should put the
3097 ;; annotations. This is used when switching annotations to another
3098 ;; revision, so we should update the buffer's name.
3099 (if buf (with-current-buffer buf
3100 (rename-buffer temp-buffer-name t)
3101 ;; In case it had to be uniquified.
3102 (setq temp-buffer-name (buffer-name))))
3133 (if (not (vc-find-backend-function vc-annotate-backend 'annotate-command)) 3103 (if (not (vc-find-backend-function vc-annotate-backend 'annotate-command))
3134 (error "Sorry, annotating is not implemented for %s" 3104 (error "Sorry, annotating is not implemented for %s"
3135 vc-annotate-backend)) 3105 vc-annotate-backend))
3136 (with-output-to-temp-buffer temp-buffer-name 3106 (with-output-to-temp-buffer temp-buffer-name
3137 (vc-call-backend vc-annotate-backend 'annotate-command 3107 (vc-call annotate-command file (get-buffer temp-buffer-name) rev))
3138 buffer-file-name 3108 (with-current-buffer temp-buffer-name
3139 (get-buffer temp-buffer-name) 3109 (set (make-local-variable 'vc-annotate-backend) (vc-backend file))
3140 vc-annotate-version)) 3110 (set (make-local-variable 'vc-annotate-parent-file) file)
3141 (save-excursion 3111 (set (make-local-variable 'vc-annotate-parent-rev) rev)
3142 (set-buffer temp-buffer-name)
3143 (set (make-local-variable 'vc-annotate-parent-file) bfn)
3144 (set (make-local-variable 'vc-annotate-parent-rev) vc-annotate-version)
3145 (set (make-local-variable 'vc-annotate-parent-display-mode) 3112 (set (make-local-variable 'vc-annotate-parent-display-mode)
3146 vc-annotate-display-mode)) 3113 display-mode))
3147 3114
3148 ;; Don't use the temp-buffer-name until the buffer is created
3149 ;; (only after `with-output-to-temp-buffer'.)
3150 (setq vc-annotate-buffers
3151 (append vc-annotate-buffers
3152 (list (cons (get-buffer temp-buffer-name) vc-annotate-backend))))
3153 (message "Annotating... done"))) 3115 (message "Annotating... done")))
3154 3116
3155(defun vc-annotate-prev-version (prefix) 3117(defun vc-annotate-prev-version (prefix)
@@ -3274,21 +3236,13 @@ revision."
3274 ((stringp revspec) (setq newrev revspec)) 3236 ((stringp revspec) (setq newrev revspec))
3275 (t (error "Invalid argument to vc-annotate-warp-version"))) 3237 (t (error "Invalid argument to vc-annotate-warp-version")))
3276 (when newrev 3238 (when newrev
3277 (save-window-excursion 3239 (vc-annotate vc-annotate-parent-file newrev
3278 (find-file vc-annotate-parent-file) 3240 vc-annotate-parent-display-mode
3279 (vc-annotate nil newrev vc-annotate-parent-display-mode)) 3241 (current-buffer))
3280 (kill-buffer (current-buffer)) ;; kill the buffer we started from
3281 (switch-to-buffer (car (car (last vc-annotate-buffers))))
3282 (goto-line (min oldline (progn (goto-char (point-max)) 3242 (goto-line (min oldline (progn (goto-char (point-max))
3283 (previous-line) 3243 (previous-line)
3284 (line-number-at-pos)))))))) 3244 (line-number-at-pos))))))))
3285 3245
3286(defun vc-annotate-car-last-cons (a-list)
3287 "Return car of last cons in association list A-LIST."
3288 (if (not (eq nil (cdr a-list)))
3289 (vc-annotate-car-last-cons (cdr a-list))
3290 (car (car a-list))))
3291
3292(defun vc-annotate-time-span (a-list span &optional quantize) 3246(defun vc-annotate-time-span (a-list span &optional quantize)
3293 "Apply factor SPAN to the time-span of association list A-LIST. 3247 "Apply factor SPAN to the time-span of association list A-LIST.
3294Return the new alist. 3248Return the new alist.
diff --git a/lisp/w32-fns.el b/lisp/w32-fns.el
index e87cf288674..004a4662f5e 100644
--- a/lisp/w32-fns.el
+++ b/lisp/w32-fns.el
@@ -456,6 +456,18 @@ they were unset."
456(setq interprogram-cut-function 'x-select-text) 456(setq interprogram-cut-function 'x-select-text)
457(setq interprogram-paste-function 'x-get-selection-value) 457(setq interprogram-paste-function 'x-get-selection-value)
458 458
459
460;;;; Support for build process
461(defun w32-batch-update-autoloads ()
462 "Like `batch-update-autoloads', but takes the name of the autoloads file
463from the command line.
464
465This is required because some Windows build environments, such as MSYS,
466munge command-line arguments that include file names to a horrible mess
467that Emacs is unable to cope with."
468 (let ((generated-autoload-file
469 (expand-file-name (pop command-line-args-left))))
470 (batch-update-autoloads)))
459 471
460;;; arch-tag: c49b48cc-0f4f-454f-a274-c2dc34815e14 472;;; arch-tag: c49b48cc-0f4f-454f-a274-c2dc34815e14
461;;; w32-fns.el ends here 473;;; w32-fns.el ends here
diff --git a/lisp/wid-edit.el b/lisp/wid-edit.el
index ec3614c4d59..1f0b8e746c7 100644
--- a/lisp/wid-edit.el
+++ b/lisp/wid-edit.el
@@ -2988,7 +2988,7 @@ as the value."
2988 2988
2989(define-widget 'file 'string 2989(define-widget 'file 'string
2990 "A file widget. 2990 "A file widget.
2991It will read a file name from the minibuffer when invoked." 2991It reads a file name from an editable text field."
2992 :complete-function 'widget-file-complete 2992 :complete-function 'widget-file-complete
2993 :prompt-value 'widget-file-prompt-value 2993 :prompt-value 'widget-file-prompt-value
2994 :format "%{%t%}: %v" 2994 :format "%{%t%}: %v"
@@ -3050,7 +3050,7 @@ It will read a file name from the minibuffer when invoked."
3050;; Fixme: use file-name-as-directory. 3050;; Fixme: use file-name-as-directory.
3051(define-widget 'directory 'file 3051(define-widget 'directory 'file
3052 "A directory widget. 3052 "A directory widget.
3053It will read a directory name from the minibuffer when invoked." 3053It reads a directory name from an editable text field."
3054 :tag "Directory") 3054 :tag "Directory")
3055 3055
3056(defvar widget-symbol-prompt-value-history nil 3056(defvar widget-symbol-prompt-value-history nil
diff --git a/lispref/ChangeLog b/lispref/ChangeLog
index 1058beb9f23..0f350aa4480 100644
--- a/lispref/ChangeLog
+++ b/lispref/ChangeLog
@@ -1,3 +1,17 @@
12005-12-23 Richard M. Stallman <rms@gnu.org>
2
3 * text.texi (Undo): Restore some explanation from the version
4 that was deleted.
5
62005-12-23 Eli Zaretskii <eliz@gnu.org>
7
8 * text.texi (Undo): Remove dupliate descriptions of `apply
9 funname' and `apply delta' elements of the undo list.
10
112005-12-20 Richard M. Stallman <rms@gnu.org>
12
13 * help.texi (Help Functions): Update documentation of `apropos'.
14
12005-12-20 Luc Teirlinck <teirllm@auburn.edu> 152005-12-20 Luc Teirlinck <teirllm@auburn.edu>
2 16
3 * customize.texi (Type Keywords): Delete xref to "Text help-echo", 17 * customize.texi (Type Keywords): Delete xref to "Text help-echo",
diff --git a/lispref/help.texi b/lispref/help.texi
index 4821478a3ad..664e8c69c18 100644
--- a/lispref/help.texi
+++ b/lispref/help.texi
@@ -520,7 +520,8 @@ definition as a function, variable, or face, or has properties.
520The function returns a list of elements that look like this: 520The function returns a list of elements that look like this:
521 521
522@example 522@example
523(@var{symbol} @var{score} @var{fn-doc} @var{var-doc} @var{plist-doc} @var{widget-doc} @var{face-doc} @var{group-doc}) 523(@var{symbol} @var{score} @var{fn-doc} @var{var-doc}
524 @var{plist-doc} @var{widget-doc} @var{face-doc} @var{group-doc})
524@end example 525@end example
525 526
526Here, @var{score} is an integer measure of how important the symbol 527Here, @var{score} is an integer measure of how important the symbol
diff --git a/lispref/text.texi b/lispref/text.texi
index ecbce818519..b8d727efca4 100644
--- a/lispref/text.texi
+++ b/lispref/text.texi
@@ -470,6 +470,9 @@ it except to install it on a keymap.
470 470
471In an interactive call, @var{count} is the numeric prefix argument. 471In an interactive call, @var{count} is the numeric prefix argument.
472 472
473Self-insertion translates the input character through
474@code{translation-table-for-input}. @xref{Translation of Characters}.
475
473This command calls @code{auto-fill-function} whenever that is 476This command calls @code{auto-fill-function} whenever that is
474non-@code{nil} and the character inserted is in the table 477non-@code{nil} and the character inserted is in the table
475@code{auto-fill-chars} (@pxref{Auto Filling}). 478@code{auto-fill-chars} (@pxref{Auto Filling}).
@@ -477,10 +480,9 @@ non-@code{nil} and the character inserted is in the table
477@c Cross refs reworded to prevent overfull hbox. --rjc 15mar92 480@c Cross refs reworded to prevent overfull hbox. --rjc 15mar92
478This command performs abbrev expansion if Abbrev mode is enabled and 481This command performs abbrev expansion if Abbrev mode is enabled and
479the inserted character does not have word-constituent 482the inserted character does not have word-constituent
480syntax. (@xref{Abbrevs}, and @ref{Syntax Class Table}.) 483syntax. (@xref{Abbrevs}, and @ref{Syntax Class Table}.) It is also
481 484responsible for calling @code{blink-paren-function} when the inserted
482This is also responsible for calling @code{blink-paren-function} when 485character has close parenthesis syntax (@pxref{Blinking}).
483the inserted character has close parenthesis syntax (@pxref{Blinking}).
484 486
485Do not try substituting your own definition of 487Do not try substituting your own definition of
486@code{self-insert-command} for the standard one. The editor command 488@code{self-insert-command} for the standard one. The editor command
@@ -1241,19 +1243,6 @@ Here's how you might undo the change:
1241(put-text-property @var{beg} @var{end} @var{property} @var{value}) 1243(put-text-property @var{beg} @var{end} @var{property} @var{value})
1242@end example 1244@end example
1243 1245
1244@item (apply @var{funname} . @var{args})
1245This kind of element records a change that can be undone by evaluating
1246(@code{apply} @var{funname} @var{args}).
1247
1248@item (apply @var{delta} @var{beg} @var{end} @var{funname} . @var{args})
1249This kind of element records a change that can be undone by evaluating
1250(@code{apply} @var{funname} @var{args}). The integer values @var{beg}
1251and @var{end} is buffer positions of the range affected by this change
1252and @var{delta} is an integer value which is the number of bytes added
1253or deleted in that range by this change. This kind of element
1254enables undo limited to a region to determine whether the element
1255pertains to that region.
1256
1257@item (@var{marker} . @var{adjustment}) 1246@item (@var{marker} . @var{adjustment})
1258This kind of element records the fact that the marker @var{marker} was 1247This kind of element records the fact that the marker @var{marker} was
1259relocated due to deletion of surrounding text, and that it moved 1248relocated due to deletion of surrounding text, and that it moved
@@ -1270,6 +1259,9 @@ range @var{beg} to @var{end}, which increased the size of the buffer
1270by @var{delta}. It is undone by calling @var{funname} with arguments 1259by @var{delta}. It is undone by calling @var{funname} with arguments
1271@var{args}. 1260@var{args}.
1272 1261
1262This kind of element enables undo limited to a region to determine
1263whether the element pertains to that region.
1264
1273@item nil 1265@item nil
1274This element is a boundary. The elements between two boundaries are 1266This element is a boundary. The elements between two boundaries are
1275called a @dfn{change group}; normally, each change group corresponds to 1267called a @dfn{change group}; normally, each change group corresponds to
@@ -1806,7 +1798,7 @@ a buffer. This is in contrast to the function @code{sort}, which
1806rearranges the order of the elements of a list (@pxref{Rearrangement}). 1798rearranges the order of the elements of a list (@pxref{Rearrangement}).
1807The values returned by these functions are not meaningful. 1799The values returned by these functions are not meaningful.
1808 1800
1809@defun sort-subr reverse nextrecfun endrecfun &optional startkeyfun endkeyfun 1801@defun sort-subr reverse nextrecfun endrecfun &optional startkeyfun endkeyfun predicate
1810This function is the general text-sorting routine that subdivides a 1802This function is the general text-sorting routine that subdivides a
1811buffer into records and then sorts them. Most of the commands in this 1803buffer into records and then sorts them. Most of the commands in this
1812section use this function. 1804section use this function.
@@ -1860,6 +1852,10 @@ is no need for @var{endkeyfun} if @var{startkeyfun} returns a
1860non-@code{nil} value. 1852non-@code{nil} value.
1861@end enumerate 1853@end enumerate
1862 1854
1855The argument @var{predicate} is the function to use to compare keys.
1856If keys are numbers, it defaults to @code{<}; otherwise it defaults to
1857@code{string<}.
1858
1863As an example of @code{sort-subr}, here is the complete function 1859As an example of @code{sort-subr}, here is the complete function
1864definition for @code{sort-lines}: 1860definition for @code{sort-lines}:
1865 1861
diff --git a/man/ChangeLog b/man/ChangeLog
index 2c68beb84a3..a5774d68c87 100644
--- a/man/ChangeLog
+++ b/man/ChangeLog
@@ -1,10 +1,36 @@
12005-12-24 Chong Yidong <cyd@stupidchicken.com>
2
3 * custom.texi (Custom Themes): `load-theme' always loads.
4
52005-12-23 Juri Linkov <juri@jurta.org>
6
7 * display.texi (Highlight Interactively): Use double space to
8 separate sentences. Replace C-p with M-p, and C-n with M-n.
9
102005-12-22 Richard M. Stallman <rms@gnu.org>
11
12 * custom.texi (Easy Customization and subnodes):
13 Replace "active field" with "button".
14 Use "user option" only for variables.
15 Use "setting" for variable-or-face.
16
172005-12-22 Luc Teirlinck <teirllm@auburn.edu>
18
19 * buffers.texi (Select Buffer): Change order in table to make
20 "Similar" refer to the correct item.
21 (Indirect Buffers): Minor rewording.
22
232005-12-21 Luc Teirlinck <teirllm@auburn.edu>
24
25 * widget.texi (atoms): Delete obsolete remark about `file' widget.
26
12005-12-20 Juri Linkov <juri@jurta.org> 272005-12-20 Juri Linkov <juri@jurta.org>
2 28
3 * files.texi (VC Status): Put P and N near p and n. 29 * files.texi (VC Status): Put P and N near p and n.
4 30
52005-12-20 Carsten Dominik <dominik@science.uva.nl> 312005-12-20 Carsten Dominik <dominik@science.uva.nl>
6 32
7 * org.texi: (Tags): Boolean logic documented. 33 * org.texi (Tags): Boolean logic documented.
8 (Agenda Views): Document custom commands. 34 (Agenda Views): Document custom commands.
9 35
102005-12-20 David Kastrup <dak@gnu.org> 362005-12-20 David Kastrup <dak@gnu.org>
diff --git a/man/buffers.texi b/man/buffers.texi
index 4285c22b731..3e4b311bd50 100644
--- a/man/buffers.texi
+++ b/man/buffers.texi
@@ -67,16 +67,16 @@ megabytes.
67@table @kbd 67@table @kbd
68@item C-x b @var{buffer} @key{RET} 68@item C-x b @var{buffer} @key{RET}
69Select or create a buffer named @var{buffer} (@code{switch-to-buffer}). 69Select or create a buffer named @var{buffer} (@code{switch-to-buffer}).
70@item C-x @key{LEFT}
71Select the previous buffer in the list of existing buffers.
72@item C-x @key{RIGHT}
73Select the next buffer in the list of existing buffers.
74@item C-x 4 b @var{buffer} @key{RET} 70@item C-x 4 b @var{buffer} @key{RET}
75Similar, but select @var{buffer} in another window 71Similar, but select @var{buffer} in another window
76(@code{switch-to-buffer-other-window}). 72(@code{switch-to-buffer-other-window}).
77@item C-x 5 b @var{buffer} @key{RET} 73@item C-x 5 b @var{buffer} @key{RET}
78Similar, but select @var{buffer} in a separate frame 74Similar, but select @var{buffer} in a separate frame
79(@code{switch-to-buffer-other-frame}). 75(@code{switch-to-buffer-other-frame}).
76@item C-x @key{LEFT}
77Select the previous buffer in the list of existing buffers.
78@item C-x @key{RIGHT}
79Select the next buffer in the list of existing buffers.
80@item C-u M-g M-g 80@item C-u M-g M-g
81@itemx C-u M-g g 81@itemx C-u M-g g
82Read a number @var{n} and move to line @var{n} in the most recently 82Read a number @var{n} and move to line @var{n} in the most recently
@@ -530,11 +530,10 @@ outline. @xref{Outline Views}.
530@kbd{M-x clone-indirect-buffer}. It creates and selects an indirect 530@kbd{M-x clone-indirect-buffer}. It creates and selects an indirect
531buffer whose base buffer is the current buffer. With a numeric 531buffer whose base buffer is the current buffer. With a numeric
532argument, it prompts for the name of the indirect buffer; otherwise it 532argument, it prompts for the name of the indirect buffer; otherwise it
533defaults to the name of the current buffer, modifying it by adding a 533uses the name of the current buffer, with a @samp{<@var{n}>} suffix
534@samp{<@var{n}>} suffix if required. @kbd{C-x 4 c} 534added. @kbd{C-x 4 c} (@code{clone-indirect-buffer-other-window})
535(@code{clone-indirect-buffer-other-window}) works like @kbd{M-x 535works like @kbd{M-x clone-indirect-buffer}, but it selects the new
536clone-indirect-buffer}, but it selects the new buffer in another 536buffer in another window.
537window.
538 537
539 The more general way to make an indirect buffer is with the command 538 The more general way to make an indirect buffer is with the command
540@kbd{M-x make-indirect-buffer}. It creates an indirect buffer from 539@kbd{M-x make-indirect-buffer}. It creates an indirect buffer from
diff --git a/man/custom.texi b/man/custom.texi
index c1442ca2f3c..c2370b03185 100644
--- a/man/custom.texi
+++ b/man/custom.texi
@@ -34,7 +34,7 @@ replay sequences of keys.
34@menu 34@menu
35* Minor Modes:: Each minor mode is one feature you can turn on 35* Minor Modes:: Each minor mode is one feature you can turn on
36 independently of any others. 36 independently of any others.
37* Easy Customization:: Convenient way to browse and change user options. 37* Easy Customization:: Convenient way to browse and change settings.
38* Variables:: Many Emacs commands examine Emacs variables 38* Variables:: Many Emacs commands examine Emacs variables
39 to decide what to do; by setting variables, 39 to decide what to do; by setting variables,
40 you can control their functioning. 40 you can control their functioning.
@@ -183,31 +183,31 @@ region highlighted. @xref{Mark}.
183@node Easy Customization 183@node Easy Customization
184@section Easy Customization Interface 184@section Easy Customization Interface
185 185
186@cindex user option 186@cindex settings
187 Emacs has many @dfn{user options} which have values that you can set 187 Emacs has many @dfn{settings} which have values that you can specify
188in order to customize various commands. Many user options are 188in order to customize various commands. Many are documented in this
189documented in this manual. Most user options are actually Lisp 189manual. Most settings are @dfn{user options}---that is to say, Lisp
190variables (@pxref{Variables}), so their names appear in the Variable 190variables (@pxref{Variables})---so their names appear in the Variable
191Index (@pxref{Variable Index}). The rest are faces and their 191Index (@pxref{Variable Index}). The other settings are faces and
192attributes (@pxref{Faces}). 192their attributes (@pxref{Faces}).
193 193
194@findex customize 194@findex customize
195@cindex customization buffer 195@cindex customization buffer
196 You can browse interactively through the user options and change 196 You can browse interactively through settings and change them using
197some of them using @kbd{M-x customize}. This command creates a 197@kbd{M-x customize}. This command creates a @dfn{customization
198@dfn{customization buffer}, which offers commands to navigate through 198buffer}, which offers commands to navigate through a logically
199a logically organized structure of the Emacs user options; you can 199organized structure of the Emacs settings; you can also use it to edit
200also use it to edit and set their values, and to save settings 200and set their values, and to save settings permanently in your
201permanently in your @file{~/.emacs} file (@pxref{Init File}). 201@file{~/.emacs} file (@pxref{Init File}).
202 202
203 The appearance of the example buffers in this section is typically 203 The appearance of the example buffers in this section is typically
204different under a window system, since faces are then used to indicate 204different under a window system, since faces are then used to indicate
205the active fields and other features. 205buttons and editable fields.
206 206
207@menu 207@menu
208* Groups: Customization Groups. How options are classified in a structure. 208* Groups: Customization Groups. How settings are classified in a structure.
209* Browsing: Browsing Custom. Browsing and searching for options and faces. 209* Browsing: Browsing Custom. Browsing and searching for settings.
210* Changing a Variable:: How to edit a value and set an option. 210* Changing a Variable:: How to edit an option's value and set the option.
211* Saving Customizations:: Specifying the file for saving customizations. 211* Saving Customizations:: Specifying the file for saving customizations.
212* Face Customization:: How to edit the attributes of a face. 212* Face Customization:: How to edit the attributes of a face.
213* Specific Customization:: Making a customization buffer for specific 213* Specific Customization:: Making a customization buffer for specific
@@ -220,9 +220,9 @@ the active fields and other features.
220@subsection Customization Groups 220@subsection Customization Groups
221@cindex customization groups 221@cindex customization groups
222 222
223 For customization purposes, user options are organized into 223 For customization purposes, settings are organized into @dfn{groups}
224@dfn{groups} to help you find them. Groups are collected into bigger 224to help you find them. Groups are collected into bigger groups, all
225groups, all the way up to a master group called @code{Emacs}. 225the way up to a master group called @code{Emacs}.
226 226
227 @kbd{M-x customize} creates a customization buffer that shows the 227 @kbd{M-x customize} creates a customization buffer that shows the
228top-level @code{Emacs} group and the second-level groups immediately 228top-level @code{Emacs} group and the second-level groups immediately
@@ -255,59 +255,57 @@ documentation string; the @code{Emacs} group also has a @samp{[State]}
255line. 255line.
256 256
257@cindex editable fields (customization buffer) 257@cindex editable fields (customization buffer)
258@cindex active fields (customization buffer) 258@cindex buttons (customization buffer)
259 Most of the text in the customization buffer is read-only, but it 259 Most of the text in the customization buffer is read-only, but it
260typically includes some @dfn{editable fields} that you can edit. There 260typically includes some @dfn{editable fields} that you can edit.
261are also @dfn{active fields}; this means a field that does something 261There are also @dfn{buttons}, which do something when you @dfn{invoke}
262when you @dfn{invoke} it. To invoke an active field, either click on it 262them. To invoke a button, either click on it with @kbd{Mouse-1}, or
263with @kbd{Mouse-1}, or move point to it and type @key{RET}. 263move point to it and type @key{RET}.
264 264
265 For example, the phrase @samp{[Go to Group]} that appears in a 265 For example, the phrase @samp{[Go to Group]} that appears in a
266second-level group is an active field. Invoking the @samp{[Go to 266second-level group is a button. Invoking it creates a new
267Group]} field for a group creates a new customization buffer, which 267customization buffer, which shows that group and its contents. This
268shows that group and its contents. This field is a kind of hypertext 268is a kind of hypertext link to another group.
269link to another group. 269
270 270 The @code{Emacs} group includes a few settings, but mainly it
271 The @code{Emacs} group includes a few user options itself, but 271contains other groups, which contain more groups, which contain the
272mainly it contains other groups, which contain more groups, which 272settings. By browsing the hierarchy of groups, you will eventually
273contain the user options. By browsing the hierarchy of groups, you 273find the feature you are interested in customizing. Then you can use
274will eventually find the feature you are interested in customizing. 274the customization buffer to set that feature's settings. You can also
275Then you can use the customization buffer to set the options 275go straight to a particular group by name, using the command @kbd{M-x
276pertaining to that feature. You can also go straight to a particular 276customize-group}.
277group by name, using the command @kbd{M-x customize-group}.
278 277
279@node Browsing Custom 278@node Browsing Custom
280@subsection Browsing and Searching for Options and Faces 279@subsection Browsing and Searching for Options and Faces
281@findex customize-browse 280@findex customize-browse
282You can use @kbd{M-x customize} to browse the groups and options, but 281
283often @kbd{M-x customize-browse} is a more efficient alternative. 282 @kbd{M-x customize-browse} is another way to browse the available
284That is because it lets you view the structure of customization groups 283settings. This command creates a special customization buffer which
285on a larger scale. This command creates a special kind of 284shows only the names of groups and settings, and puts them in a
286customization buffer which shows only the names of the groups (and 285structure.
287variables and faces), and their structure.
288 286
289 In this buffer, you can show the contents of a group by invoking 287 In this buffer, you can show the contents of a group by invoking
290@samp{[+]}. When the group contents are visible, this button changes to 288@samp{[+]}. When the group contents are visible, this button changes to
291@samp{[-]}; invoking that hides the group contents. 289@samp{[-]}; invoking that hides the group contents.
292 290
293 Each group, variable, or face name in this buffer has an active field 291 Each setting in this buffer has a button which says @samp{[Group]},
294which says @samp{[Group]}, @samp{[Option]} or @samp{[Face]}. Invoking 292@samp{[Option]} or @samp{[Face]}. Invoking this button creates an
295that active field creates an ordinary customization buffer showing just 293ordinary customization buffer showing just that group and its
296that group and its contents, just that variable, or just that face. 294contents, just that user option, or just that face. This is the way
297This is the way to set values in it. 295to change settings that you find with @kbd{M-x customize-browse}.
298 296
299 If you can guess part of the name of the options you are interested 297 If you can guess part of the name of the settings you are interested
300in, then sometimes @kbd{M-x customize-apropos} can be another useful 298in, @kbd{M-x customize-apropos} is another way to search for settings.
301way to search for options. However, unlike @code{customize} and 299However, unlike @code{customize} and @code{customize-browse},
302@code{customize-browse}, @code{customize-apropos} can only find 300@code{customize-apropos} can only find groups and settings that are
303options that are loaded in the current Emacs session. @xref{Specific 301loaded in the current Emacs session. @xref{Specific Customization,,
304Customization,, Customizing Specific Items}. 302Customizing Specific Items}.
305 303
306@node Changing a Variable 304@node Changing a Variable
307@subsection Changing a Variable 305@subsection Changing a Variable
308 306
309 Here is an example of what a variable looks like in the 307 Here is an example of what a variable (a user option) looks like in
310customization buffer: 308the customization buffer:
311 309
312@smallexample 310@smallexample
313Kill Ring Max: [Hide Value] 60 311Kill Ring Max: [Hide Value] 60
@@ -321,34 +319,32 @@ the current value of the variable. If you see @samp{[Show Value]} instead of
321buffer initially hides values that take up several lines. Invoke 319buffer initially hides values that take up several lines. Invoke
322@samp{[Show Value]} to show the value. 320@samp{[Show Value]} to show the value.
323 321
324 The line after the option name indicates the @dfn{customization state} 322 The line after the variable name indicates the @dfn{customization
325of the variable: in the example above, it says you have not changed the 323state} of the variable: in the example above, it says you have not
326option yet. The word @samp{[State]} at the beginning of this line is 324changed the option yet. The @samp{[State]} button at the beginning of
327active; you can get a menu of various operations by invoking it with 325this line gives you a menu of various operations for customizing the
328@kbd{Mouse-1} or @key{RET}. These operations are essential for 326variable.
329customizing the variable.
330 327
331 The line after the @samp{[State]} line displays the beginning of the 328 The line after the @samp{[State]} line displays the beginning of the
332variable's documentation string. If there are more lines of 329variable's documentation string. If there are more lines of
333documentation, this line ends with @samp{[More]}; invoke this to show 330documentation, this line ends with a @samp{[More]} button; invoke that
334the full documentation string. 331to show the full documentation string.
335
336 To enter a new value for @samp{Kill Ring Max}, move point to the value
337and edit it textually. For example, you can type @kbd{M-d}, then insert
338another number.
339 332
340 When you begin to alter the text, you will see the @samp{[State]} line 333 To enter a new value for @samp{Kill Ring Max}, move point to the
341change to say that you have edited the value: 334value and edit it textually. For example, you can type @kbd{M-d},
335then insert another number. As you begin to alter the text, you will
336see the @samp{[State]} line change to say that you have edited the
337value:
342 338
343@smallexample 339@smallexample
344[State]: EDITED, shown value does not take effect until you set or @r{@dots{}} 340[State]: EDITED, shown value does not take effect until you set or @r{@dots{}}
345 save it. 341 save it.
346@end smallexample 342@end smallexample
347 343
348@cindex setting option value 344@cindex settings, how to set
349 Editing the value does not actually set the variable. To do 345 Editing the value does not actually set the variable. To do that,
350that, you must @dfn{set} it. To do this, invoke the word 346you must @dfn{set} the variable. To do this, invoke the
351@samp{[State]} and choose @samp{Set for Current Session}. 347@samp{[State]} button and choose @samp{Set for Current Session}.
352 348
353 The state of the variable changes visibly when you set it: 349 The state of the variable changes visibly when you set it:
354 350
@@ -357,23 +353,24 @@ that, you must @dfn{set} it. To do this, invoke the word
357@end smallexample 353@end smallexample
358 354
359 You don't have to worry about specifying a value that is not valid; 355 You don't have to worry about specifying a value that is not valid;
360setting the variable checks for validity and will not really install an 356the @samp{Set for Current Session} operation checks for validity and
361unacceptable value. 357will not install an unacceptable value.
362 358
363@kindex M-TAB @r{(customization buffer)} 359@kindex M-TAB @r{(customization buffer)}
364@findex widget-complete 360@findex widget-complete
365 While editing a value or field that is a file name, directory name, 361 While editing a field that is a file name, directory name,
366command name, or anything else for which completion is defined, you 362command name, or anything else for which completion is defined, you
367can type @kbd{M-@key{TAB}} (@code{widget-complete}) to do completion. 363can type @kbd{M-@key{TAB}} (@code{widget-complete}) to do completion.
368(@kbd{@key{ESC} @key{TAB}} and @kbd{C-M-i} do the same thing.) 364(@kbd{@key{ESC} @key{TAB}} and @kbd{C-M-i} do the same thing.)
369 365
370 Some variables have a small fixed set of possible legitimate values. 366 Some variables have a small fixed set of possible legitimate values.
371These variables don't let you edit the value textually. Instead, an 367These variables don't let you edit the value textually. Instead, a
372active field @samp{[Value Menu]} appears before the value; invoke this 368@samp{[Value Menu]} button appears before the value; invoke this
373field to edit the value. For a boolean ``on or off'' value, the active 369button to change the value. For a boolean ``on or off'' value, the
374field says @samp{[Toggle]}, and it changes to the other value. 370button says @samp{[Toggle]}, and it changes to the other value.
375@samp{[Value Menu]} and @samp{[Toggle]} edit the buffer; the changes 371@samp{[Value Menu]} and @samp{[Toggle]} simply edit the buffer; the
376take effect when you use the @samp{Set for Current Session} operation. 372changes take real effect when you use the @samp{Set for Current
373Session} operation.
377 374
378 Some variables have values with complex structure. For example, the 375 Some variables have values with complex structure. For example, the
379value of @code{file-coding-system-alist} is an association list. Here 376value of @code{file-coding-system-alist} is an association list. Here
@@ -408,10 +405,10 @@ where PATTERN is a regular expression matching a file name,
408 405
409@noindent 406@noindent
410Each association in the list appears on four lines, with several 407Each association in the list appears on four lines, with several
411editable or ``active'' fields. You can edit the regexps and coding 408editable fields and/or buttons. You can edit the regexps and coding
412systems using ordinary editing commands. You can also invoke 409systems using ordinary editing commands. You can also invoke
413@samp{[Value Menu]} to switch to a kind of value---for instance, to 410@samp{[Value Menu]} to switch to a different kind of value---for
414specify a function instead of a pair of coding systems. 411instance, to specify a function instead of a pair of coding systems.
415 412
416To delete an association from the list, invoke the @samp{[DEL]} button 413To delete an association from the list, invoke the @samp{[DEL]} button
417for that item. To add an association, invoke @samp{[INS]} at the 414for that item. To add an association, invoke @samp{[INS]} at the
@@ -424,19 +421,19 @@ list.
424@kindex S-TAB @r{(customization buffer)} 421@kindex S-TAB @r{(customization buffer)}
425@findex widget-forward 422@findex widget-forward
426@findex widget-backward 423@findex widget-backward
427 Two special commands, @key{TAB} and @kbd{S-@key{TAB}}, are useful for 424 Two special commands, @key{TAB} and @kbd{S-@key{TAB}}, are useful
428moving through the customization buffer. @key{TAB} 425for moving through the customization buffer. @key{TAB}
429(@code{widget-forward}) moves forward to the next active or editable 426(@code{widget-forward}) moves forward to the next button or editable
430field; @kbd{S-@key{TAB}} (@code{widget-backward}) moves backward to the 427field; @kbd{S-@key{TAB}} (@code{widget-backward}) moves backward to
431previous active or editable field. 428the previous button or editable field.
432 429
433 Typing @key{RET} on an editable field also moves forward, just like 430 Typing @key{RET} on an editable field also moves forward, just like
434@key{TAB}. We set it up this way because people often type @key{RET} 431@key{TAB}. We set it up this way because people often type @key{RET}
435when they are finished editing a field. To insert a newline within an 432when they are finished editing a field. To insert a newline within an
436editable field, use @kbd{C-o} or @kbd{C-q C-j}. 433editable field, use @kbd{C-o} or @kbd{C-q C-j}.
437 434
438@cindex saving variable value 435@cindex saving a setting
439@cindex customized variables, saving 436@cindex settings, how to save
440 Setting the variable changes its value in the current Emacs session; 437 Setting the variable changes its value in the current Emacs session;
441@dfn{saving} the value changes it for future sessions as well. To 438@dfn{saving} the value changes it for future sessions as well. To
442save the variable, invoke @samp{[State]} and select the @samp{Save for 439save the variable, invoke @samp{[State]} and select the @samp{Save for
@@ -460,7 +457,7 @@ and updates the text accordingly.
460 457
461@item Erase Customization 458@item Erase Customization
462This sets the variable to its standard value, and updates the text 459This sets the variable to its standard value, and updates the text
463accordingly. This also eliminates any saved value for the option, 460accordingly. This also eliminates any saved value for the variable,
464so that you will get the standard value in future Emacs sessions. 461so that you will get the standard value in future Emacs sessions.
465 462
466@item Use Backup Value 463@item Use Backup Value
@@ -480,8 +477,7 @@ the same variable in a customization buffer, even in another session.
480 The state of a group indicates whether anything in that group has been 477 The state of a group indicates whether anything in that group has been
481edited, set or saved. 478edited, set or saved.
482 479
483 Near the top of the customization buffer there are two lines 480 Near the top of the customization buffer there are two lines of buttons:
484containing several active fields:
485 481
486@smallexample 482@smallexample
487 [Set for Current Session] [Save for Future Sessions] 483 [Set for Current Session] [Save for Future Sessions]
@@ -493,10 +489,10 @@ containing several active fields:
493Invoking @samp{[Finish]} either buries or kills this customization 489Invoking @samp{[Finish]} either buries or kills this customization
494buffer according to the setting of the option 490buffer according to the setting of the option
495@code{custom-buffer-done-kill}; the default is to bury the buffer. 491@code{custom-buffer-done-kill}; the default is to bury the buffer.
496Each of the other fields performs an operation---set, save or 492Each of the other buttons performs an operation---set, save or
497reset---on each of the options in the buffer that could meaningfully 493reset---on each of the settings in the buffer that could meaningfully
498be set, saved or reset. They do not operate on options whose values 494be set, saved or reset. They do not operate on settings whose values
499are hidden, nor on subgroups. 495are hidden, nor on subgroups not visible in the buffer.
500 496
501@node Saving Customizations 497@node Saving Customizations
502@subsection Saving Customizations 498@subsection Saving Customizations
@@ -572,11 +568,12 @@ Attributes: [ ] Font Family: *
572 [ ] Inherit: * 568 [ ] Inherit: *
573@end smallexample 569@end smallexample
574 570
575 Each face attribute has its own line. The @samp{[@var{x}]} field 571 Each face attribute has its own line. The @samp{[@var{x}]} button
576before the attribute name indicates whether the attribute is 572before the attribute name indicates whether the attribute is
577@dfn{enabled}; @samp{X} means that it is. You can enable or disable the 573@dfn{enabled}; @samp{[X]} means that it's enabled, and @samp{[ ]}
578attribute by invoking that field. When the attribute is enabled, you 574means that it's disabled. You can enable or disable the attribute by
579can change the attribute value in the usual ways. 575clicking that button. When the attribute is enabled, you can change
576the attribute value in the usual ways.
580 577
581 For the colors, you can specify a color name (use @kbd{M-x 578 For the colors, you can specify a color name (use @kbd{M-x
582list-colors-display} for a list of them) or a hexadecimal color 579list-colors-display} for a list of them) or a hexadecimal color
@@ -608,9 +605,9 @@ to clear out the attribute.
608@node Specific Customization 605@node Specific Customization
609@subsection Customizing Specific Items 606@subsection Customizing Specific Items
610 607
611 Instead of finding the options you want to change by moving down 608 Instead of finding the setting you want to change by navigating the
612through the structure of groups, you can specify the particular variable, 609structure of groups, here are other ways to specify the settings that
613face, or group that you want to customize. 610you want to customize.
614 611
615@table @kbd 612@table @kbd
616@item M-x customize-variable @key{RET} @var{variable} @key{RET} 613@item M-x customize-variable @key{RET} @var{variable} @key{RET}
@@ -620,17 +617,17 @@ Set up a customization buffer with just one face, @var{face}.
620@item M-x customize-group @key{RET} @var{group} @key{RET} 617@item M-x customize-group @key{RET} @var{group} @key{RET}
621Set up a customization buffer with just one group, @var{group}. 618Set up a customization buffer with just one group, @var{group}.
622@item M-x customize-apropos @key{RET} @var{regexp} @key{RET} 619@item M-x customize-apropos @key{RET} @var{regexp} @key{RET}
623Set up a customization buffer with all the variables, faces and groups 620Set up a customization buffer with all the settings and groups that
624that match @var{regexp}. 621match @var{regexp}.
625@item M-x customize-changed-options @key{RET} @var{version} @key{RET} 622@item M-x customize-changed-options @key{RET} @var{version} @key{RET}
626Set up a customization buffer with all the variables, faces and groups 623Set up a customization buffer with all the settings and groups
627whose meaning has changed since Emacs version @var{version}. 624whose meaning has changed since Emacs version @var{version}.
628@item M-x customize-saved 625@item M-x customize-saved
629Set up a customization buffer containing all variables and faces that you 626Set up a customization buffer containing all settings that you
630have saved with customization buffers. 627have saved with customization buffers.
631@item M-x customize-customized 628@item M-x customize-customized
632Set up a customization buffer containing all variables and faces that you 629Set up a customization buffer containing all settings that you have
633have customized but not saved. 630customized but not saved.
634@end table 631@end table
635 632
636@findex customize-variable 633@findex customize-variable
@@ -639,8 +636,8 @@ buffer, and you know its name, you can use the command @kbd{M-x
639customize-variable} and specify the variable name. This sets up the 636customize-variable} and specify the variable name. This sets up the
640customization buffer with just one variable---the one that you asked 637customization buffer with just one variable---the one that you asked
641for. Editing, setting and saving the value work as described above, 638for. Editing, setting and saving the value work as described above,
642but only for the specified variable. Minibuffer completion is very 639but only for the specified variable. Minibuffer completion is handy
643handy if you only know part of the name. However, it only finds 640if you only know part of the name. However, this command can only see
644options that have been loaded in the current Emacs session. 641options that have been loaded in the current Emacs session.
645 642
646@findex customize-face 643@findex customize-face
@@ -651,57 +648,56 @@ on the character after point.
651@findex customize-group 648@findex customize-group
652 You can also set up the customization buffer with a specific group, 649 You can also set up the customization buffer with a specific group,
653using @kbd{M-x customize-group}. The immediate contents of the chosen 650using @kbd{M-x customize-group}. The immediate contents of the chosen
654group, including user options, faces, and other groups, all appear 651group, including variables, faces, and other groups, all appear
655as well (even if not already loaded). However, the subgroups' own 652as well (even if not already loaded). However, the subgroups' own
656contents are not included. 653contents are not included.
657 654
658@findex customize-apropos 655@findex customize-apropos
659 To control more precisely what to customize, you can use @kbd{M-x 656 To control more precisely what to customize, you can use @kbd{M-x
660customize-apropos}. You specify a regular expression as argument; then 657customize-apropos}. You specify a regular expression as argument;
661all @emph{loaded} options, faces and groups whose names match this 658then all @emph{loaded} settings and groups whose names match this
662regular expression are set up in the customization buffer. If you 659regular expression are set up in the customization buffer. If you
663specify an empty regular expression, this includes @emph{all} groups, 660specify an empty regular expression, this includes @emph{all} loaded
664options and faces (but that takes a long time). 661groups and settings---which takes a long time to set up.
665 662
666@findex customize-changed-options 663@findex customize-changed
667 When you upgrade to a new Emacs version, you might want to customize 664 When you upgrade to a new Emacs version, you might want to customize
668new options and options whose meanings or default values have changed. 665new settings and settings whose meanings or default values have
669To do this, use @kbd{M-x customize-changed-options} and specify a 666changed. To do this, use @kbd{M-x customize-changed} and
670previous Emacs version number using the minibuffer. It creates a 667specify a previous Emacs version number using the minibuffer. It
671customization buffer which shows all the options (and groups) whose 668creates a customization buffer which shows all the settings and groups
672definitions have been changed since the specified version. (Not just 669whose definitions have been changed since the specified version, loading
673those that are already loaded.) 670them if necessary.
674 671
675@findex customize-saved 672@findex customize-saved
676@findex customize-customized 673@findex customize-customized
677 If you change option values and then decide the change was a 674 If you change settings and then decide the change was a mistake, you
678mistake, you can use two special commands to revisit your previous 675can use two special commands to revisit your previous changes. Use
679changes. Use @kbd{M-x customize-saved} to look at the options that 676@kbd{M-x customize-saved} to look at the settings that you have saved.
680you have saved. Use @kbd{M-x customize-customized} to look at the 677Use @kbd{M-x customize-customized} to look at the settings that you
681options that you have set but not saved. 678have set but not saved.
682 679
683@node Custom Themes 680@node Custom Themes
684@subsection Customization Themes 681@subsection Customization Themes
685@cindex custom themes 682@cindex custom themes
686 683
687@dfn{Custom themes} are collections of customized options that can be 684 @dfn{Custom themes} are collections of settings that can be enabled
688enabled or disabled as a unit. You can use Custom themes to switch 685or disabled as a unit. You can use Custom themes to switch quickly
689quickly and easily between various collections of settings, and to 686and easily between various collections of settings, and to transfer
690transfer such collections from one computer to another. 687such collections from one computer to another.
691 688
692@findex customize-create-theme 689@findex customize-create-theme
693To define a Custom theme, use the command 690 To define a Custom theme, use the command @kbd{M-x
694@kbd{M-x customize-create-theme}, which brings up a buffer named 691customize-create-theme}, which brings up a buffer named @samp{*New
695@samp{*New Custom Theme*}. At the top of the buffer is an editable 692Custom Theme*}. At the top of the buffer is an editable field where
696field where you can specify the name of the theme. To add a 693you can specify the name of the theme. To add a customization option
697customization option to the theme, click on the @samp{INS} button to 694to the theme, click on the @samp{INS} button to open up a field where
698open up a field where you can insert the name of the option. The 695you can insert the name of the option. The current value of that
699current value of that option is applied to the theme. After adding as 696option is applied to the theme. After adding as many options as you
700many options as you like, click on @samp{Done} to save the Custom 697like, click on @samp{Done} to save the Custom theme.
701theme.
702 698
703@vindex custom-theme-directory 699@vindex custom-theme-directory
704Saving a Custom theme named @var{foo} writes its definition into the 700 Saving a Custom theme named @var{foo} writes its definition into the
705file @file{@var{foo}-theme.el}, in the directory @file{~/.emacs.d/} 701file @file{@var{foo}-theme.el}, in the directory @file{~/.emacs.d/}
706(you can specify the directory by setting 702(you can specify the directory by setting
707@code{custom-theme-directory}). 703@code{custom-theme-directory}).
@@ -710,13 +706,12 @@ file @file{@var{foo}-theme.el}, in the directory @file{~/.emacs.d/}
710@findex enable-theme 706@findex enable-theme
711@findex disable-theme 707@findex disable-theme
712You can load the themes you've previously defined with the command 708You can load the themes you've previously defined with the command
713@code{load-theme}. It prompts for a theme name in the minibuffer, 709@code{load-theme}. It prompts for a theme name in the minibuffer, and
714then loads that theme if it isn't already loaded. It also 710loads that theme from the theme file. It also @dfn{enables} the
715@dfn{enables} the theme, which means putting its settings into effect. 711theme, which means putting its settings into effect. An enabled theme
716An enabled theme can be @dfn{disabled} with the command 712can be @dfn{disabled} with the command @kbd{M-x disable-theme}; this
717@kbd{M-x disable-theme}; this returns the options specified in the 713returns the options specified in the theme to their original values.
718theme to their original values. To re-enable the theme, use the 714To re-enable the theme, use the command @kbd{M-x enable-theme}.
719command @kbd{M-x enable-theme}.
720 715
721To enable a Custom theme named @var{foo} whenever Emacs is started up, 716To enable a Custom theme named @var{foo} whenever Emacs is started up,
722add the line @code{(load-theme '@var{foo})} to your @file{.emacs} file 717add the line @code{(load-theme '@var{foo})} to your @file{.emacs} file
@@ -747,25 +742,26 @@ variable names consist of words separated by hyphens. A variable can
747have a documentation string which describes what kind of value it should 742have a documentation string which describes what kind of value it should
748have and how the value will be used. 743have and how the value will be used.
749 744
750 Lisp allows any variable to have any kind of value, but most variables 745 Emacs Lisp allows any variable (with a few exceptions) to have any
751that Emacs uses need a value of a certain type. Often the value should 746kind of value, but most variables that Emacs uses need a value of a
752always be a string, or should always be a number. Sometimes we say that a 747certain type. Often the value should always be a string, or should
753certain feature is turned on if a variable is ``non-@code{nil},'' meaning 748always be a number. Sometimes we say that a certain feature is turned
754that if the variable's value is @code{nil}, the feature is off, but the 749on if a variable is ``non-@code{nil},'' meaning that if the variable's
755feature is on for @emph{any} other value. The conventional value to use to 750value is @code{nil}, the feature is off, but the feature is on for
756turn on the feature---since you have to pick one particular value when you 751@emph{any} other value. The conventional value to use to turn on the
757set the variable---is @code{t}. 752feature---since you have to pick one particular value when you set the
753variable---is @code{t}.
758 754
759 Emacs uses many Lisp variables for internal record keeping, but the 755 Emacs uses many Lisp variables for internal record keeping, but the
760most interesting variables for a non-programmer user are those that 756most interesting variables for a non-programmer user are those meant
761are also @dfn{user options}, the variables that are meant for users to 757for users to change---the @dfn{user options}.
762change. Each user option that you can set with the customization 758
763buffer is (if it is not a face) in fact a Lisp variable. Emacs does 759 Each user option that you can set with the customization buffer is
764not (usually) change the values of these variables; instead, you set 760in fact a Lisp variable. Emacs does not (usually) change the values
765the values, and thereby alter and control the behavior of certain 761of these variables; instead, you set the values, and thereby alter and
766Emacs commands. Use of the customization buffer is explained above 762control the behavior of certain Emacs commands. Use of the
767(@pxref{Easy Customization}); here we describe other aspects of Emacs 763customization buffer is explained above (@pxref{Easy Customization});
768variables. 764here we describe other aspects of Emacs variables.
769 765
770@menu 766@menu
771* Examining:: Examining or setting one variable's value. 767* Examining:: Examining or setting one variable's value.
diff --git a/man/display.texi b/man/display.texi
index a0cb73c03bc..2f813c4b7c0 100644
--- a/man/display.texi
+++ b/man/display.texi
@@ -412,25 +412,25 @@ You control Hi Lock mode with these commands:
412@findex highlight-regexp 412@findex highlight-regexp
413Highlight text that matches @var{regexp} using face @var{face} 413Highlight text that matches @var{regexp} using face @var{face}
414(@code{highlight-regexp}). By using this command more than once, you 414(@code{highlight-regexp}). By using this command more than once, you
415can highlight various parts of the text in different ways. The 415can highlight various parts of the text in different ways. The
416highlighting will remain as long as the buffer is loaded. For 416highlighting will remain as long as the buffer is loaded. For
417example, to highlight all occurrences of the word ``whim'' using the 417example, to highlight all occurrences of the word ``whim'' using the
418default face (a yellow background) @kbd{C-x w h whim @key{RET} 418default face (a yellow background) @kbd{C-x w h whim @key{RET}
419@key{RET}}. Any face can be used for highlighting, Hi Lock provides 419@key{RET}}. Any face can be used for highlighting, Hi Lock provides
420several of its own and these are pre-loaded into a history list. While 420several of its own and these are pre-loaded into a history list. While
421being prompted for a face use @kbd{C-p} and @kbd{C-n} to cycle through 421being prompted for a face use @kbd{M-p} and @kbd{M-n} to cycle through
422them. 422them.
423 423
424@item C-x w r @var{regexp} @key{RET} 424@item C-x w r @var{regexp} @key{RET}
425@kindex C-x w r 425@kindex C-x w r
426@findex unhighlight-regexp 426@findex unhighlight-regexp
427Unhighlight @var{regexp} (@code{unhighlight-regexp}). 427Unhighlight @var{regexp} (@code{unhighlight-regexp}).
428When activated from the menu select the expression to unhighlight from 428When activated from the menu select the expression to unhighlight from
429a list. When activated from the keyboard the most recently added 429a list. When activated from the keyboard the most recently added
430expression will be shown. Use @kbd{C-p} to show the next older 430expression will be shown. Use @kbd{M-p} to show the next older
431expression and @kbd{C-n} to select the next newer expression. When 431expression and @kbd{M-n} to select the next newer expression. When
432the expression to unhighlight appears press @kbd{@key{RET}} to unhighlight 432the expression to unhighlight appears press @kbd{@key{RET}} to unhighlight
433it. The expression can also be typed and completion is available. 433it. The expression can also be typed and completion is available.
434 434
435@item C-x w l @var{regexp} @key{RET} @var{face} @key{RET} 435@item C-x w l @var{regexp} @key{RET} @var{face} @key{RET}
436@kindex C-x w l 436@kindex C-x w l
@@ -457,7 +457,7 @@ hi-lock-find-patterns} command.
457@findex hi-lock-find-patterns 457@findex hi-lock-find-patterns
458@vindex hi-lock-exclude-modes 458@vindex hi-lock-exclude-modes
459Re-read regexp/face pairs in the current buffer 459Re-read regexp/face pairs in the current buffer
460(@code{hi-lock-write-interactive-patterns}). Users familiar with Font 460(@code{hi-lock-write-interactive-patterns}). Users familiar with Font
461Lock keywords might interactively enter patterns 461Lock keywords might interactively enter patterns
462(@code{highlight-regexp}), write them into the file 462(@code{highlight-regexp}), write them into the file
463(@code{hi-lock-write-interactive-patterns}), edit them, perhaps 463(@code{hi-lock-write-interactive-patterns}), edit them, perhaps
diff --git a/man/widget.texi b/man/widget.texi
index 5b4a4b12525..91e74dca01c 100644
--- a/man/widget.texi
+++ b/man/widget.texi
@@ -1282,9 +1282,7 @@ Allows you to enter a character in an editable field.
1282@end deffn 1282@end deffn
1283 1283
1284@deffn Widget file 1284@deffn Widget file
1285Allows you to edit a file name in an editable field. If you invoke 1285Allows you to edit a file name in an editable field.
1286the tag button, you can edit the file name in the mini-buffer with
1287completion.
1288 1286
1289Keywords: 1287Keywords:
1290@table @code 1288@table @code
diff --git a/nt/ChangeLog b/nt/ChangeLog
index dc8888b2c87..cc161f830e6 100644
--- a/nt/ChangeLog
+++ b/nt/ChangeLog
@@ -1,3 +1,8 @@
12005-12-24 Eli Zaretskii <eliz@gnu.org>
2
3 * gmake.defs (TEMACS_EXTRA_LINK): Remove redundant -g.
4 (DEBUG_FLAG, DEBUG_LINK): Upgrade to "-gstabs+ -g3".
5
12005-12-09 Eli Zaretskii <eliz@gnu.org> 62005-12-09 Eli Zaretskii <eliz@gnu.org>
2 7
3 * INSTALL: Add explanation of how to debug with GDB starting from 8 * INSTALL: Add explanation of how to debug with GDB starting from
diff --git a/nt/gmake.defs b/nt/gmake.defs
index c3f20fbeabe..9b93aa92074 100644
--- a/nt/gmake.defs
+++ b/nt/gmake.defs
@@ -191,7 +191,7 @@ EMACS_EXTRA_C_FLAGS = -DUSE_CRT_DLL=1
191 191
192# see comments in allocate_heap in w32heap.c before changing any of the 192# see comments in allocate_heap in w32heap.c before changing any of the
193# -stack, -heap, or -image-base settings. 193# -stack, -heap, or -image-base settings.
194TEMACS_EXTRA_LINK = -Wl,-stack,0x00800000 -Wl,-heap,0x00100000 -Wl,-image-base,0x01000000 -g $(SUBSYSTEM_CONSOLE) -Wl,-entry,__start -Wl,-Map,$(BLD)/temacs.map 194TEMACS_EXTRA_LINK = -Wl,-stack,0x00800000 -Wl,-heap,0x00100000 -Wl,-image-base,0x01000000 $(SUBSYSTEM_CONSOLE) -Wl,-entry,__start -Wl,-Map,$(BLD)/temacs.map
195 195
196ifdef NOOPT 196ifdef NOOPT
197OBJDIR = oo 197OBJDIR = oo
@@ -242,8 +242,8 @@ ifdef NODEBUG
242DEBUG_FLAG = 242DEBUG_FLAG =
243DEBUG_LINK = 243DEBUG_LINK =
244else 244else
245DEBUG_FLAG = -g 245DEBUG_FLAG = -gstabs+ -g3
246DEBUG_LINK = -g 246DEBUG_LINK = -gstabs+ -g3
247endif 247endif
248 248
249ifdef NOCYGWIN 249ifdef NOCYGWIN
diff --git a/src/ChangeLog b/src/ChangeLog
index 969f9f6c46d..f14f216f1d3 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,118 @@
12005-12-25 Giorgos Keramidas <keramida@ceid.upatras.gr>
2
3 * m/amdx86-64.h [__FreeBSD__] (START_FILES, LIB_STANDARD):
4 define for FreeBSD on this platform.
5
62005-12-24 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
7
8 * macterm.h (TYPE_FILE_NAME): New define.
9 (posix_pathname_to_fsspec, fsspec_to_posix_pathname): Remove externs.
10
11 * mac.c (posix_pathname_to_fsspec, fsspec_to_posix_pathname): Add
12 prototypes. Make static.
13 (mac_aedesc_to_lisp): Initialize err to noErr.
14 (mac_coerce_file_name_ptr, mac_coerce_file_name_desc)
15 (init_coercion_handler): New functions.
16 (Fmac_coerce_ae_data): Use coercion of Apple event data for
17 translation from/to file names.
18
19 * macterm.c: Don't include sys/param.h.
20 (init_coercion_handler): Add extern.
21 [MAC_OS8] (main): Call init_coercion_handler.
22 (mac_initialize) [MAC_OSX]: Likewise.
23 [TARGET_API_MAC_CARBON] (mac_do_receive_drag): Use coercion of
24 Apple event data for translation from/to file names.
25
26 * macfns.c [TARGET_API_MAC_CARBON] (Fx_file_dialog): Likewise.
27
28 * image.c [MAC_OS] (find_image_fsspec): Likewise.
29
302005-12-23 Martin Rudalics <rudalics@gmx.at> (tiny change)
31
32 * insdel.c (insert, insert_and_inherit, insert_before_markers)
33 (insert_before_markers_and_inherit): Make sure FROM is correct
34 when `after-change-functions' are called.
35
362005-12-23 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
37
38 * xfns.c (Fx_uses_old_gtk_dialog): New function.
39
40 * gtkutil.c (xg_uses_old_file_dialog): New function.
41 (xg_get_file_name): Use xg_uses_old_file_dialog.
42
43 * gtkutil.h: Declare xg_uses_old_file_dialog.
44
452005-12-22 Richard M. Stallman <rms@gnu.org>
46
47 * xmenu.c (xmenu_show): Call inhibit_garbage_collection.
48
492005-12-22 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
50
51 * mac.c (Fmac_coerce_ae_data) [MAC_OSX]: Fix memory leak.
52
53 * macgui.h (XCharStruct): Remove member `valid_p'.
54 (STORE_XCHARSTRUCT): Don't set member `valid_p'.
55 (XCharStructRow): New typedef.
56 (XCHARSTRUCTROW_CHAR_VALID_P, XCHARSTRUCTROW_SET_CHAR_VALID): New
57 macros.
58 (struct MacFontStruct): Add member `bounds'. Remove member
59 `per_char'. All uses for QuichDraw Text fonts are changed to
60 `bounds.per_char'. ATSUI font bounds are represented as an array
61 `bounds.rows' of XCharStructRow's, each of which consists of a
62 bitmap of valid entries and an array of char bounds.
63
64 * macterm.c (mac_per_char_metric): Add prototype.
65 (x_per_char_metric) [USE_CG_TEXT_DRAWING]: Remove prototype.
66 (mac_query_char_extents): New function.
67 (x_per_char_metric): Use it.
68 (XLoadQueryFont): Likewise. Consolidate min/max_bounds calculations.
69 [USE_CG_TEXT_DRAWING] (mac_draw_string_cg): Use
70 mac_per_char_metric instead of x_per_char_metric.
71 (mac_text_extents_16): New function.
72 (mac_compute_glyph_string_overhangs): Use it.
73 (mac_unload_font): Free member `bounds' in struct MacFontStruct.
74
752005-12-21 Stefan Monnier <monnier@iro.umontreal.ca>
76
77 * minibuf.c (Fdisplay_completion_list): Use XCAR/XCDR.
78 (Fminibuffer_completion_help): Remove duplicates before display.
79
802005-12-21 L$,1 q(Brentey K,Aa(Broly <lorentey@elte.hu>
81
82 * print.c (print_preprocess): Don't lose print_depth levels while
83 iterating.
84
852005-12-21 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
86
87 * macmenu.c (Qmac_apple_event): Add extern.
88 (set_frame_menubar, mac_menu_show keymp_panes)
89 (single_keymap_panes, list_of_panes, list_of_item)
90 (single_menu_item): Add argument types to prototypes.
91 (mac_dialog_show) [HAVE_DIALOGS]: Likewise.
92 (struct skp): New struct (from xmenu.c).
93 (single_keymap_panes, single_menu_item, list_of_panes)
94 (list_of_item): Sync with xmenu.c.
95 (Fx_popup_menu, Fx_popup_dialog): Likewise. Don't get window from
96 POSITION if it is mac-apple-event event.
97 (menubar_selection_callback): Don't use menu_command_in_progress.
98 (set_frame_menubar): First parse all submenus, then make
99 widget_value trees from them. Don't allocate any widget_value
100 objects until we are done with the parsing.
101 (parse_single_submenu, digest_single_submenu): New functions.
102 (single_submenu): Function deleted, replaced by those two.
103 (install_menu_quit_handler) [HAVE_CANCELMENUTRACKING]: Don't
104 create or dispose of EventHandlerUPP. Install hander to all submenus.
105 (mac_menu_show) [!HAVE_MULTILINGUAL_MENU]: Use ENCODE_MENU_STRING
106 instead of ENCODE_SYSTEM.
107 (free_frame_menubar, fill_submenu, fill_menu): Don't use NULL for
108 integer values.
109 [HAVE_DIALOGS] (mac_dialog_show): Sync with xdialog_show (in xmenu.c).
110 (add_menu_item) [TARGET_API_MAC_CARBON]: Use CFString functions to
111 format menu item string. Don't use NULL for integer value.
112
113 * macterm.h (struct mac_output): Remove unused member
114 menu_command_in_progress.
115
12005-12-20 Juri Linkov <juri@jurta.org> 1162005-12-20 Juri Linkov <juri@jurta.org>
2 117
3 * xmenu.c (Fx_popup_menu): Set Vmenu_updating_frame to f if 118 * xmenu.c (Fx_popup_menu): Set Vmenu_updating_frame to f if
@@ -25,15 +140,15 @@
25 (x_use_underline_position_properties): Undo 2005-07-13 change. 140 (x_use_underline_position_properties): Undo 2005-07-13 change.
26 (syms_of_macterm) <x-use-underline-position-properties>: Likewise. 141 (syms_of_macterm) <x-use-underline-position-properties>: Likewise.
27 (mac_use_core_graphics, mac_wheel_button_is_mouse_2) 142 (mac_use_core_graphics, mac_wheel_button_is_mouse_2)
28 (mac_pass_command_to_system, mac_pass_control_to_system): New 143 (mac_pass_command_to_system, mac_pass_control_to_system):
29 boolean variables renamed from Lisp_Object ones 144 New boolean variables renamed from Lisp_Object ones
30 Vmac_use_core_graphics, Vmac_wheel_button_is_mouse_2, 145 Vmac_use_core_graphics, Vmac_wheel_button_is_mouse_2,
31 Vmac_pass_command_to_system, and Vmac_pass_control_to_system. All 146 Vmac_pass_command_to_system, and Vmac_pass_control_to_system.
32 uses changed. 147 All uses changed.
33 (syms_of_macterm): DEFVAR_BOOL them. Remove previous DEFVAR_LISPs. 148 (syms_of_macterm): DEFVAR_BOOL them. Remove previous DEFVAR_LISPs.
34 Make them user options. 149 Make them user options.
35 (mac_handle_command_event, mac_store_services_event): Call 150 (mac_handle_command_event, mac_store_services_event):
36 create_apple_event_from_event_ref without 5th argument. 151 Call create_apple_event_from_event_ref without 5th argument.
37 (backtranslate_modified_keycode): Mask off modifier keys that are 152 (backtranslate_modified_keycode): Mask off modifier keys that are
38 mapped to some Emacs modifiers before passing it to KeyTranslate. 153 mapped to some Emacs modifiers before passing it to KeyTranslate.
39 (syms_of_macterm): Make variables `mac-emulate-three-button-mouse', 154 (syms_of_macterm): Make variables `mac-emulate-three-button-mouse',
@@ -41,8 +156,8 @@
41 Fix docstrings of `mac-*-modifier'. 156 Fix docstrings of `mac-*-modifier'.
42 157
43 * mac.c (create_apple_event_from_event_ref): Remove arg `types'. 158 * mac.c (create_apple_event_from_event_ref): Remove arg `types'.
44 (do_applescript): Change argument types to Lisp_Object. All uses 159 (do_applescript): Change argument types to Lisp_Object.
45 changed. 160 All uses changed.
46 161
47 * macterm.h (create_apple_event_from_event_ref): Remove 5th 162 * macterm.h (create_apple_event_from_event_ref): Remove 5th
48 argument from extern. 163 argument from extern.
@@ -85,9 +200,9 @@
85 200
86 * xfns.c (compute_tip_xy): Handle negative dx and dy. 201 * xfns.c (compute_tip_xy): Handle negative dx and dy.
87 202
88 * w32fns.c (compute_tip_xy): Ditto 203 * w32fns.c (compute_tip_xy): Ditto.
89 204
90 * macfns.c (compute_tip_xy): Ditto 205 * macfns.c (compute_tip_xy): Ditto.
91 206
922005-12-14 Chong Yidong <cyd@stupidchicken.com> 2072005-12-14 Chong Yidong <cyd@stupidchicken.com>
93 208
@@ -165,8 +280,7 @@
165 * mac.c (Qundecoded_file_name): New variable. 280 * mac.c (Qundecoded_file_name): New variable.
166 (syms_of_mac): Initialize it. 281 (syms_of_mac): Initialize it.
167 (mac_aelist_to_lisp, mac_aedesc_to_lisp): New functions. 282 (mac_aelist_to_lisp, mac_aedesc_to_lisp): New functions.
168 [TARGET_API_MAC_CARBON] (create_apple_event_from_event_ref): New 283 [TARGET_API_MAC_CARBON] (create_apple_event_from_event_ref): New fun.
169 function.
170 (Fmac_coerce_ae_data): New defun. 284 (Fmac_coerce_ae_data): New defun.
171 (syms_of_mac): Defsubr it. 285 (syms_of_mac): Defsubr it.
172 286
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 54cb43b8398..9da3c5bf457 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -1155,6 +1155,27 @@ create_dialog (wv, select_cb, deactivate_cb)
1155/*********************************************************************** 1155/***********************************************************************
1156 File dialog functions 1156 File dialog functions
1157 ***********************************************************************/ 1157 ***********************************************************************/
1158/* Return non-zero if the old file selection dialog is being used.
1159 Return zero if not. */
1160
1161int
1162xg_uses_old_file_dialog ()
1163{
1164#ifdef HAVE_GTK_FILE_BOTH
1165 extern int x_use_old_gtk_file_dialog;
1166 return x_use_old_gtk_file_dialog;
1167#else /* ! HAVE_GTK_FILE_BOTH */
1168
1169#ifdef HAVE_GTK_FILE_SELECTION_NEW
1170 return 1;
1171#else
1172 return 0;
1173#endif
1174
1175#endif /* ! HAVE_GTK_FILE_BOTH */
1176}
1177
1178
1158/* Function that is called when the file dialog pops down. 1179/* Function that is called when the file dialog pops down.
1159 W is the dialog widget, RESPONSE is the response code. 1180 W is the dialog widget, RESPONSE is the response code.
1160 USER_DATA is what we passed in to g_signal_connect (pointer to int). */ 1181 USER_DATA is what we passed in to g_signal_connect (pointer to int). */
@@ -1343,7 +1364,6 @@ xg_get_file_name (f, prompt, default_filename, mustmatch_p, only_dir_p)
1343 char *fn = 0; 1364 char *fn = 0;
1344 int filesel_done = 0; 1365 int filesel_done = 0;
1345 xg_get_file_func func; 1366 xg_get_file_func func;
1346 extern int x_use_old_gtk_file_dialog;
1347 1367
1348#if defined (HAVE_GTK_AND_PTHREAD) && defined (__SIGRTMIN) 1368#if defined (HAVE_GTK_AND_PTHREAD) && defined (__SIGRTMIN)
1349 /* I really don't know why this is needed, but without this the GLIBC add on 1369 /* I really don't know why this is needed, but without this the GLIBC add on
@@ -1354,7 +1374,7 @@ xg_get_file_name (f, prompt, default_filename, mustmatch_p, only_dir_p)
1354 1374
1355#ifdef HAVE_GTK_FILE_BOTH 1375#ifdef HAVE_GTK_FILE_BOTH
1356 1376
1357 if (x_use_old_gtk_file_dialog) 1377 if (xg_uses_old_file_dialog ())
1358 w = xg_get_file_with_selection (f, prompt, default_filename, 1378 w = xg_get_file_with_selection (f, prompt, default_filename,
1359 mustmatch_p, only_dir_p, &func); 1379 mustmatch_p, only_dir_p, &func);
1360 else 1380 else
diff --git a/src/gtkutil.h b/src/gtkutil.h
index aea4ee9e7cf..6b9fd179ec5 100644
--- a/src/gtkutil.h
+++ b/src/gtkutil.h
@@ -132,6 +132,8 @@ extern int use_old_gtk_file_dialog;
132extern widget_value *malloc_widget_value P_ ((void)); 132extern widget_value *malloc_widget_value P_ ((void));
133extern void free_widget_value P_ ((widget_value *)); 133extern void free_widget_value P_ ((widget_value *));
134 134
135extern int xg_uses_old_file_dialog P_ ((void));
136
135extern char *xg_get_file_name P_ ((FRAME_PTR f, 137extern char *xg_get_file_name P_ ((FRAME_PTR f,
136 char *prompt, 138 char *prompt,
137 char *default_filename, 139 char *default_filename,
diff --git a/src/image.c b/src/image.c
index 8a6d40ae34f..579c04e6f46 100644
--- a/src/image.c
+++ b/src/image.c
@@ -2259,23 +2259,25 @@ find_image_fsspec (specified_file, file, fss)
2259 Lisp_Object specified_file, *file; 2259 Lisp_Object specified_file, *file;
2260 FSSpec *fss; 2260 FSSpec *fss;
2261{ 2261{
2262#if MAC_OSX
2263 FSRef fsr;
2264#endif
2265 OSErr err; 2262 OSErr err;
2263 AEDesc desc;
2266 2264
2267 *file = x_find_image_file (specified_file); 2265 *file = x_find_image_file (specified_file);
2268 if (!STRINGP (*file)) 2266 if (!STRINGP (*file))
2269 return fnfErr; /* file or directory not found; 2267 return fnfErr; /* file or directory not found;
2270 incomplete pathname */ 2268 incomplete pathname */
2271 /* Try to open the image file. */ 2269 /* Try to open the image file. */
2272#if MAC_OSX 2270 err = AECoercePtr (TYPE_FILE_NAME, SDATA (*file),
2273 err = FSPathMakeRef (SDATA (*file), &fsr, NULL); 2271 SBYTES (*file), typeFSS, &desc);
2274 if (err == noErr) 2272 if (err == noErr)
2275 err = FSGetCatalogInfo (&fsr, kFSCatInfoNone, NULL, NULL, fss, NULL); 2273 {
2274#if TARGET_API_MAC_CARBON
2275 err = AEGetDescData (&desc, fss, sizeof (FSSpec));
2276#else 2276#else
2277 err = posix_pathname_to_fsspec (SDATA (*file), fss); 2277 *fss = *(FSSpec *)(*(desc.dataHandle));
2278#endif 2278#endif
2279 AEDisposeDesc (&desc);
2280 }
2279 return err; 2281 return err;
2280} 2282}
2281 2283
diff --git a/src/insdel.c b/src/insdel.c
index fd416037241..a63dce14928 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -749,9 +749,10 @@ insert (string, nbytes)
749{ 749{
750 if (nbytes > 0) 750 if (nbytes > 0)
751 { 751 {
752 int opoint = PT; 752 int len = chars_in_text (string, nbytes), opoint;
753 insert_1 (string, nbytes, 0, 1, 0); 753 insert_1_both (string, len, nbytes, 0, 1, 0);
754 signal_after_change (opoint, 0, PT - opoint); 754 opoint = PT - len;
755 signal_after_change (opoint, 0, len);
755 update_compositions (opoint, PT, CHECK_BORDER); 756 update_compositions (opoint, PT, CHECK_BORDER);
756 } 757 }
757} 758}
@@ -765,9 +766,10 @@ insert_and_inherit (string, nbytes)
765{ 766{
766 if (nbytes > 0) 767 if (nbytes > 0)
767 { 768 {
768 int opoint = PT; 769 int len = chars_in_text (string, nbytes), opoint;
769 insert_1 (string, nbytes, 1, 1, 0); 770 insert_1_both (string, len, nbytes, 1, 1, 0);
770 signal_after_change (opoint, 0, PT - opoint); 771 opoint = PT - len;
772 signal_after_change (opoint, 0, len);
771 update_compositions (opoint, PT, CHECK_BORDER); 773 update_compositions (opoint, PT, CHECK_BORDER);
772 } 774 }
773} 775}
@@ -813,10 +815,10 @@ insert_before_markers (string, nbytes)
813{ 815{
814 if (nbytes > 0) 816 if (nbytes > 0)
815 { 817 {
816 int opoint = PT; 818 int len = chars_in_text (string, nbytes), opoint;
817 819 insert_1_both (string, len, nbytes, 0, 1, 1);
818 insert_1 (string, nbytes, 0, 1, 1); 820 opoint = PT - len;
819 signal_after_change (opoint, 0, PT - opoint); 821 signal_after_change (opoint, 0, len);
820 update_compositions (opoint, PT, CHECK_BORDER); 822 update_compositions (opoint, PT, CHECK_BORDER);
821 } 823 }
822} 824}
@@ -830,10 +832,10 @@ insert_before_markers_and_inherit (string, nbytes)
830{ 832{
831 if (nbytes > 0) 833 if (nbytes > 0)
832 { 834 {
833 int opoint = PT; 835 int len = chars_in_text (string, nbytes), opoint;
834 836 insert_1_both (string, len, nbytes, 1, 1, 1);
835 insert_1 (string, nbytes, 1, 1, 1); 837 opoint = PT - len;
836 signal_after_change (opoint, 0, PT - opoint); 838 signal_after_change (opoint, 0, len);
837 update_compositions (opoint, PT, CHECK_BORDER); 839 update_compositions (opoint, PT, CHECK_BORDER);
838 } 840 }
839} 841}
diff --git a/src/m/amdx86-64.h b/src/m/amdx86-64.h
index 2d7d86ce7c3..14ddd16406e 100644
--- a/src/m/amdx86-64.h
+++ b/src/m/amdx86-64.h
@@ -100,11 +100,38 @@ Boston, MA 02110-1301, USA. */
100/* Define XPNTR to avoid or'ing with DATA_SEG_BITS */ 100/* Define XPNTR to avoid or'ing with DATA_SEG_BITS */
101#undef DATA_SEG_BITS 101#undef DATA_SEG_BITS
102 102
103#ifdef __FreeBSD__
104
105/* The libraries for binaries native to the build host's architecture are
106 installed under /usr/lib in FreeBSD, and the ones that need special paths
107 are 32-bit compatibility libraries (installed under /usr/lib32). To build
108 a native binary of Emacs on FreeBSD/amd64 we can just point to /usr/lib. */
109
110#undef START_FILES
111#define START_FILES pre-crt0.o /usr/lib/crt1.o /usr/lib/crti.o
112
113/* The duplicate -lgcc is intentional in the definition of LIB_STANDARD.
114 The reason is that some functions in libgcc.a call functions from libc.a,
115 and some libc.a functions need functions from libgcc.a. Since most
116 versions of ld are one-pass linkers, we need to mention -lgcc twice,
117 or else we risk getting unresolved externals. */
118#undef LIB_STANDARD
119#define LIB_STANDARD -lgcc -lc -lgcc /usr/lib/crtn.o
120
121#else /* !__FreeBSD__ */
122
103#undef START_FILES 123#undef START_FILES
104#define START_FILES pre-crt0.o /usr/lib64/crt1.o /usr/lib64/crti.o 124#define START_FILES pre-crt0.o /usr/lib64/crt1.o /usr/lib64/crti.o
105 125
126/* The duplicate -lgcc is intentional in the definition of LIB_STANDARD.
127 The reason is that some functions in libgcc.a call functions from libc.a,
128 and some libc.a functions need functions from libgcc.a. Since most
129 versions of ld are one-pass linkers, we need to mention -lgcc twice,
130 or else we risk getting unresolved externals. */
106#undef LIB_STANDARD 131#undef LIB_STANDARD
107#define LIB_STANDARD -lgcc -lc -lgcc /usr/lib64/crtn.o 132#define LIB_STANDARD -lgcc -lc -lgcc /usr/lib64/crtn.o
108 133
134#endif /* __FreeBSD__ */
135
109/* arch-tag: 8a5e001d-e12e-4692-a3a6-0b15ba271c6e 136/* arch-tag: 8a5e001d-e12e-4692-a3a6-0b15ba271c6e
110 (do not change this comment) */ 137 (do not change this comment) */
diff --git a/src/mac.c b/src/mac.c
index d81c6d6a0ae..7c3e495f3a9 100644
--- a/src/mac.c
+++ b/src/mac.c
@@ -79,6 +79,8 @@ static ComponentInstance as_scripting_component;
79/* The single script context used for all script executions. */ 79/* The single script context used for all script executions. */
80static OSAID as_script_context; 80static OSAID as_script_context;
81 81
82static OSErr posix_pathname_to_fsspec P_ ((const char *, FSSpec *));
83static OSErr fsspec_to_posix_pathname P_ ((const FSSpec *, char *, int));
82 84
83/* When converting from Mac to Unix pathnames, /'s in folder names are 85/* When converting from Mac to Unix pathnames, /'s in folder names are
84 converted to :'s. This function, used in copying folder names, 86 converted to :'s. This function, used in copying folder names,
@@ -333,7 +335,7 @@ Lisp_Object
333mac_aedesc_to_lisp (desc) 335mac_aedesc_to_lisp (desc)
334 AEDesc *desc; 336 AEDesc *desc;
335{ 337{
336 OSErr err; 338 OSErr err = noErr;
337 DescType desc_type = desc->descriptorType; 339 DescType desc_type = desc->descriptorType;
338 Lisp_Object result; 340 Lisp_Object result;
339 341
@@ -397,6 +399,277 @@ mac_aedesc_to_lisp (desc)
397 return Fcons (make_unibyte_string ((char *) &desc_type, 4), result); 399 return Fcons (make_unibyte_string ((char *) &desc_type, 4), result);
398} 400}
399 401
402static pascal OSErr
403mac_coerce_file_name_ptr (type_code, data_ptr, data_size,
404 to_type, handler_refcon, result)
405 DescType type_code;
406 const void *data_ptr;
407 Size data_size;
408 DescType to_type;
409 long handler_refcon;
410 AEDesc *result;
411{
412 OSErr err;
413
414 if (type_code == TYPE_FILE_NAME)
415 /* Coercion from undecoded file name. */
416 switch (to_type)
417 {
418 case typeAlias:
419 case typeFSS:
420 case typeFSRef:
421#ifdef MAC_OSX
422 case typeFileURL:
423#endif
424 {
425#ifdef MAC_OSX
426 CFStringRef str;
427 CFURLRef url = NULL;
428 CFDataRef data = NULL;
429
430 str = CFStringCreateWithBytes (NULL, data_ptr, data_size,
431 kCFStringEncodingUTF8, false);
432 if (str)
433 {
434 url = CFURLCreateWithFileSystemPath (NULL, str,
435 kCFURLPOSIXPathStyle, false);
436 CFRelease (str);
437 }
438 if (url)
439 {
440 data = CFURLCreateData (NULL, url, kCFStringEncodingUTF8, true);
441 CFRelease (url);
442 }
443 if (data)
444 {
445 err = AECoercePtr (typeFileURL, CFDataGetBytePtr (data),
446 CFDataGetLength (data), to_type, result);
447 CFRelease (data);
448 }
449 else
450 err = memFullErr;
451#else
452 FSSpec fs;
453 char *buf;
454
455 buf = xmalloc (data_size + 1);
456 if (buf)
457 {
458 memcpy (buf, data_ptr, data_size);
459 buf[data_size] = '\0';
460 err = posix_pathname_to_fsspec (buf, &fs);
461 xfree (buf);
462 }
463 else
464 err = memFullErr;
465 if (err == noErr)
466 err = AECoercePtr (typeFSS, &fs, sizeof (FSSpec),
467 to_type, result);
468#endif
469 }
470 break;
471
472 case TYPE_FILE_NAME:
473 case typeWildCard:
474 err = AECreateDesc (TYPE_FILE_NAME, data_ptr, data_size, result);
475 break;
476
477 default:
478 err = errAECoercionFail;
479 break;
480 }
481 else if (to_type == TYPE_FILE_NAME)
482 /* Coercion to undecoded file name. */
483 switch (type_code)
484 {
485 case typeAlias:
486 case typeFSS:
487 case typeFSRef:
488#ifdef MAC_OSX
489 case typeFileURL:
490#endif
491 {
492 AEDesc desc;
493#ifdef MAC_OSX
494 Size size;
495 char *buf;
496 CFURLRef url = NULL;
497 CFStringRef str = NULL;
498 CFDataRef data = NULL;
499
500 err = AECoercePtr (type_code, data_ptr, data_size,
501 typeFileURL, &desc);
502 if (err == noErr)
503 {
504 size = AEGetDescDataSize (&desc);
505 buf = xmalloc (size);
506 if (buf)
507 {
508 err = AEGetDescData (&desc, buf, size);
509 if (err == noErr)
510 url = CFURLCreateWithBytes (NULL, buf, size,
511 kCFStringEncodingUTF8, NULL);
512 xfree (buf);
513 }
514 AEDisposeDesc (&desc);
515 }
516 if (url)
517 {
518 str = CFURLCopyFileSystemPath (url, kCFURLPOSIXPathStyle);
519 CFRelease (url);
520 }
521 if (str)
522 {
523 data =
524 CFStringCreateExternalRepresentation (NULL, str,
525 kCFStringEncodingUTF8,
526 '\0');
527 CFRelease (str);
528 }
529 if (data)
530 {
531 err = AECreateDesc (TYPE_FILE_NAME, CFDataGetBytePtr (data),
532 CFDataGetLength (data), result);
533 CFRelease (data);
534 }
535 else
536 err = memFullErr;
537#else
538 FSSpec fs;
539 char file_name[MAXPATHLEN];
540
541 err = AECoercePtr (type_code, data_ptr, data_size,
542 typeFSS, &desc);
543 if (err == noErr)
544 {
545#if TARGET_API_MAC_CARBON
546 err = AEGetDescData (&desc, &fs, sizeof (FSSpec));
547#else
548 fs = *(FSSpec *)(*(desc.dataHandle));
549#endif
550 if (err == noErr)
551 err = fsspec_to_posix_pathname (&fs, file_name,
552 sizeof (file_name) - 1);
553 if (err == noErr)
554 err = AECreateDesc (TYPE_FILE_NAME, file_name,
555 strlen (file_name), result);
556 AEDisposeDesc (&desc);
557 }
558#endif
559 }
560 break;
561
562 default:
563 err = errAECoercionFail;
564 break;
565 }
566 else
567 abort ();
568
569 if (err != noErr)
570 return errAECoercionFail;
571 return noErr;
572}
573
574static pascal OSErr
575mac_coerce_file_name_desc (from_desc, to_type, handler_refcon, result)
576 const AEDesc *from_desc;
577 DescType to_type;
578 long handler_refcon;
579 AEDesc *result;
580{
581 OSErr err = noErr;
582 DescType from_type = from_desc->descriptorType;
583
584 if (from_type == TYPE_FILE_NAME)
585 {
586 if (to_type != TYPE_FILE_NAME && to_type != typeWildCard
587 && to_type != typeAlias && to_type != typeFSS
588 && to_type != typeFSRef
589#ifdef MAC_OSX
590 && to_type != typeFileURL
591#endif
592 )
593 return errAECoercionFail;
594 }
595 else if (to_type == TYPE_FILE_NAME)
596 {
597 if (from_type != typeAlias && from_type != typeFSS
598 && from_type != typeFSRef
599#ifdef MAC_OSX
600 && from_type != typeFileURL
601#endif
602 )
603 return errAECoercionFail;
604 }
605 else
606 abort ();
607
608 if (from_type == to_type || to_type == typeWildCard)
609 err = AEDuplicateDesc (from_desc, result);
610 else
611 {
612 char *data_ptr;
613 Size data_size;
614
615#if TARGET_API_MAC_CARBON
616 data_size = AEGetDescDataSize (from_desc);
617#else
618 data_size = GetHandleSize (from_desc->dataHandle);
619#endif
620 data_ptr = xmalloc (data_size);
621 if (data_ptr)
622 {
623#if TARGET_API_MAC_CARBON
624 err = AEGetDescData (from_desc, data_ptr, data_size);
625#else
626 memcpy (data_ptr, *(from_desc->dataHandle), data_size);
627#endif
628 if (err == noErr)
629 err = mac_coerce_file_name_ptr (from_type, data_ptr,
630 data_size, to_type,
631 handler_refcon, result);
632 xfree (data_ptr);
633 }
634 else
635 err = memFullErr;
636 }
637
638 if (err != noErr)
639 return errAECoercionFail;
640 return noErr;
641}
642
643OSErr
644init_coercion_handler ()
645{
646 OSErr err;
647
648 static AECoercePtrUPP coerce_file_name_ptrUPP = NULL;
649 static AECoerceDescUPP coerce_file_name_descUPP = NULL;
650
651 if (coerce_file_name_ptrUPP == NULL)
652 {
653 coerce_file_name_ptrUPP = NewAECoercePtrUPP (mac_coerce_file_name_ptr);
654 coerce_file_name_descUPP = NewAECoerceDescUPP (mac_coerce_file_name_desc);
655 }
656
657 err = AEInstallCoercionHandler (TYPE_FILE_NAME, typeWildCard,
658 (AECoercionHandlerUPP)
659 coerce_file_name_ptrUPP, 0, false, false);
660 if (err == noErr)
661 err = AEInstallCoercionHandler (typeWildCard, TYPE_FILE_NAME,
662 (AECoercionHandlerUPP)
663 coerce_file_name_ptrUPP, 0, false, false);
664 if (err == noErr)
665 err = AEInstallCoercionHandler (TYPE_FILE_NAME, typeWildCard,
666 coerce_file_name_descUPP, 0, true, false);
667 if (err == noErr)
668 err = AEInstallCoercionHandler (typeWildCard, TYPE_FILE_NAME,
669 coerce_file_name_descUPP, 0, true, false);
670 return err;
671}
672
400#if TARGET_API_MAC_CARBON 673#if TARGET_API_MAC_CARBON
401OSErr 674OSErr
402create_apple_event_from_event_ref (event, num_params, names, types, result) 675create_apple_event_from_event_ref (event, num_params, names, types, result)
@@ -2602,7 +2875,7 @@ path_from_vol_dir_name (char *path, int man_path_len, short vol_ref_num,
2602} 2875}
2603 2876
2604 2877
2605OSErr 2878static OSErr
2606posix_pathname_to_fsspec (ufn, fs) 2879posix_pathname_to_fsspec (ufn, fs)
2607 const char *ufn; 2880 const char *ufn;
2608 FSSpec *fs; 2881 FSSpec *fs;
@@ -2618,7 +2891,7 @@ posix_pathname_to_fsspec (ufn, fs)
2618 } 2891 }
2619} 2892}
2620 2893
2621OSErr 2894static OSErr
2622fsspec_to_posix_pathname (fs, ufn, ufnbuflen) 2895fsspec_to_posix_pathname (fs, ufn, ufnbuflen)
2623 const FSSpec *fs; 2896 const FSSpec *fs;
2624 char *ufn; 2897 char *ufn;
@@ -4072,89 +4345,21 @@ Each type should be a string of length 4 or the symbol
4072 4345
4073 CHECK_STRING (src_data); 4346 CHECK_STRING (src_data);
4074 if (EQ (src_type, Qundecoded_file_name)) 4347 if (EQ (src_type, Qundecoded_file_name))
4075 { 4348 src_desc_type = TYPE_FILE_NAME;
4076#ifdef MAC_OSX
4077 src_desc_type = typeFileURL;
4078#else
4079 src_desc_type = typeFSS;
4080#endif
4081 }
4082 else 4349 else
4083 src_desc_type = mac_get_code_from_arg (src_type, 0); 4350 src_desc_type = mac_get_code_from_arg (src_type, 0);
4084 4351
4085 if (EQ (dst_type, Qundecoded_file_name)) 4352 if (EQ (dst_type, Qundecoded_file_name))
4086 { 4353 dst_desc_type = TYPE_FILE_NAME;
4087#ifdef MAC_OSX
4088 dst_desc_type = typeFSRef;
4089#else
4090 dst_desc_type = typeFSS;
4091#endif
4092 }
4093 else 4354 else
4094 dst_desc_type = mac_get_code_from_arg (dst_type, 0); 4355 dst_desc_type = mac_get_code_from_arg (dst_type, 0);
4095 4356
4096 BLOCK_INPUT; 4357 BLOCK_INPUT;
4097 if (EQ (src_type, Qundecoded_file_name)) 4358 err = AECoercePtr (src_desc_type, SDATA (src_data), SBYTES (src_data),
4098 {
4099#ifdef MAC_OSX
4100 CFStringRef str;
4101 CFURLRef url = NULL;
4102 CFDataRef data = NULL;
4103
4104 str = cfstring_create_with_utf8_cstring (SDATA (src_data));
4105 if (str)
4106 {
4107 url = CFURLCreateWithFileSystemPath (NULL, str,
4108 kCFURLPOSIXPathStyle, false);
4109 CFRelease (str);
4110 }
4111 if (url)
4112 {
4113 data = CFURLCreateData (NULL, url, kCFStringEncodingUTF8, true);
4114 CFRelease (url);
4115 }
4116 if (data)
4117 err = AECoercePtr (src_desc_type, CFDataGetBytePtr (data),
4118 CFDataGetLength (data),
4119 dst_desc_type, &dst_desc);
4120 else
4121 err = memFullErr;
4122#else
4123 err = posix_pathname_to_fsspec (SDATA (src_data), &fs);
4124 if (err == noErr)
4125 AECoercePtr (src_desc_type, &fs, sizeof (FSSpec),
4126 dst_desc_type, &dst_desc); 4359 dst_desc_type, &dst_desc);
4127#endif
4128 }
4129 else
4130 err = AECoercePtr (src_desc_type, SDATA (src_data), SBYTES (src_data),
4131 dst_desc_type, &dst_desc);
4132
4133 if (err == noErr) 4360 if (err == noErr)
4134 { 4361 {
4135 if (EQ (dst_type, Qundecoded_file_name)) 4362 result = Fcdr (mac_aedesc_to_lisp (&dst_desc));
4136 {
4137 char file_name[MAXPATHLEN];
4138
4139#ifdef MAC_OSX
4140 err = AEGetDescData (&dst_desc, &fref, sizeof (FSRef));
4141 if (err == noErr)
4142 err = FSRefMakePath (&fref, file_name, sizeof (file_name));
4143#else
4144#if TARGET_API_MAC_CARBON
4145 err = AEGetDescData (&dst_desc, &fs, sizeof (FSSpec));
4146#else
4147 memcpy (&fs, *(dst_desc.dataHandle), sizeof (FSSpec));
4148#endif
4149 if (err == noErr)
4150 err = fsspec_to_posix_pathname (&fs, file_name,
4151 sizeof (file_name) - 1);
4152#endif
4153 if (err == noErr)
4154 result = make_unibyte_string (file_name, strlen (file_name));
4155 }
4156 else
4157 result = Fcdr (mac_aedesc_to_lisp (&dst_desc));
4158 AEDisposeDesc (&dst_desc); 4363 AEDisposeDesc (&dst_desc);
4159 } 4364 }
4160 UNBLOCK_INPUT; 4365 UNBLOCK_INPUT;
diff --git a/src/macfns.c b/src/macfns.c
index 99abc643043..4ede8b7971b 100644
--- a/src/macfns.c
+++ b/src/macfns.c
@@ -4226,21 +4226,13 @@ If ONLY-DIR-P is non-nil, the user can only select directories. */)
4226 /* Set the default location and continue*/ 4226 /* Set the default location and continue*/
4227 if (status == noErr) 4227 if (status == noErr)
4228 { 4228 {
4229 Lisp_Object encoded_dir = ENCODE_FILE (dir);
4229 AEDesc defLocAed; 4230 AEDesc defLocAed;
4230#ifdef MAC_OSX 4231
4231 FSRef defLoc; 4232 status = AECreateDesc (TYPE_FILE_NAME, SDATA (encoded_dir),
4232 status = FSPathMakeRef(SDATA(ENCODE_FILE(dir)), &defLoc, NULL); 4233 SBYTES (encoded_dir), &defLocAed);
4233#else
4234 FSSpec defLoc;
4235 status = posix_pathname_to_fsspec (SDATA (ENCODE_FILE (dir)), &defLoc);
4236#endif
4237 if (status == noErr) 4234 if (status == noErr)
4238 { 4235 {
4239#ifdef MAC_OSX
4240 AECreateDesc(typeFSRef, &defLoc, sizeof(FSRef), &defLocAed);
4241#else
4242 AECreateDesc(typeFSS, &defLoc, sizeof(FSSpec), &defLocAed);
4243#endif
4244 NavCustomControl(dialogRef, kNavCtlSetLocation, (void*) &defLocAed); 4236 NavCustomControl(dialogRef, kNavCtlSetLocation, (void*) &defLocAed);
4245 AEDisposeDesc(&defLocAed); 4237 AEDisposeDesc(&defLocAed);
4246 } 4238 }
@@ -4262,41 +4254,36 @@ If ONLY-DIR-P is non-nil, the user can only select directories. */)
4262 case kNavUserActionSaveAs: 4254 case kNavUserActionSaveAs:
4263 { 4255 {
4264 NavReplyRecord reply; 4256 NavReplyRecord reply;
4265 AEDesc aed; 4257 Size len;
4266#ifdef MAC_OSX
4267 FSRef fsRef;
4268#else
4269 FSSpec fs;
4270#endif
4271 status = NavDialogGetReply(dialogRef, &reply);
4272 4258
4273#ifdef MAC_OSX 4259 status = NavDialogGetReply(dialogRef, &reply);
4274 AECoerceDesc(&reply.selection, typeFSRef, &aed); 4260 if (status != noErr)
4275 AEGetDescData(&aed, (void *) &fsRef, sizeof (FSRef)); 4261 break;
4276 FSRefMakePath(&fsRef, (UInt8 *) filename, sizeof (filename)); 4262 status = AEGetNthPtr (&reply.selection, 1, TYPE_FILE_NAME,
4277#else 4263 NULL, NULL, filename,
4278 AECoerceDesc (&reply.selection, typeFSS, &aed); 4264 sizeof (filename) - 1, &len);
4279 AEGetDescData (&aed, (void *) &fs, sizeof (FSSpec)); 4265 if (status == noErr)
4280 fsspec_to_posix_pathname (&fs, filename, sizeof (filename) - 1);
4281#endif
4282 AEDisposeDesc(&aed);
4283 if (reply.saveFileName)
4284 { 4266 {
4285 /* If it was a saved file, we need to add the file name */ 4267 len = min (len, sizeof (filename) - 1);
4286 int len = strlen(filename); 4268 filename[len] = '\0';
4287 if (len && filename[len-1] != '/') 4269 if (reply.saveFileName)
4288 filename[len++] = '/'; 4270 {
4289 CFStringGetCString(reply.saveFileName, filename+len, 4271 /* If it was a saved file, we need to add the file name */
4290 sizeof (filename) - len, 4272 if (len && len < sizeof (filename) - 1
4273 && filename[len-1] != '/')
4274 filename[len++] = '/';
4275 CFStringGetCString(reply.saveFileName, filename+len,
4276 sizeof (filename) - len,
4291#if MAC_OSX 4277#if MAC_OSX
4292 kCFStringEncodingUTF8 4278 kCFStringEncodingUTF8
4293#else 4279#else
4294 CFStringGetSystemEncoding () 4280 CFStringGetSystemEncoding ()
4295#endif 4281#endif
4296 ); 4282 );
4283 }
4284 file = DECODE_FILE (make_unibyte_string (filename,
4285 strlen (filename)));
4297 } 4286 }
4298 file = DECODE_FILE (make_unibyte_string (filename,
4299 strlen (filename)));
4300 NavDisposeReply(&reply); 4287 NavDisposeReply(&reply);
4301 } 4288 }
4302 break; 4289 break;
diff --git a/src/macgui.h b/src/macgui.h
index 40244dbc7c6..74c64bfb41d 100644
--- a/src/macgui.h
+++ b/src/macgui.h
@@ -109,7 +109,6 @@ typedef struct _XCharStruct
109#if 0 109#if 0
110 unsigned short attributes; /* per char flags (not predefined) */ 110 unsigned short attributes; /* per char flags (not predefined) */
111#endif 111#endif
112 unsigned valid_p : 1;
113} XCharStruct; 112} XCharStruct;
114 113
115#define STORE_XCHARSTRUCT(xcs, w, bds) \ 114#define STORE_XCHARSTRUCT(xcs, w, bds) \
@@ -117,8 +116,19 @@ typedef struct _XCharStruct
117 (xcs).lbearing = (bds).left, \ 116 (xcs).lbearing = (bds).left, \
118 (xcs).rbearing = (bds).right, \ 117 (xcs).rbearing = (bds).right, \
119 (xcs).ascent = -(bds).top, \ 118 (xcs).ascent = -(bds).top, \
120 (xcs).descent = (bds).bottom, \ 119 (xcs).descent = (bds).bottom)
121 (xcs).valid_p = 1) 120
121typedef struct
122{
123 char valid_bits[0x100 / 8];
124 XCharStruct per_char[0x100];
125} XCharStructRow;
126
127#define XCHARSTRUCTROW_CHAR_VALID_P(row, byte2) \
128 ((row)->valid_bits[(byte2) / 8] & (1 << (byte2) % 8))
129
130#define XCHARSTRUCTROW_SET_CHAR_VALID(row, byte2) \
131 ((row)->valid_bits[(byte2) / 8] |= (1 << (byte2) % 8))
122 132
123struct MacFontStruct { 133struct MacFontStruct {
124 char *full_name; 134 char *full_name;
@@ -157,7 +167,10 @@ struct MacFontStruct {
157#endif /* 0 */ 167#endif /* 0 */
158 XCharStruct min_bounds; /* minimum bounds over all existing char */ 168 XCharStruct min_bounds; /* minimum bounds over all existing char */
159 XCharStruct max_bounds; /* maximum bounds over all existing char */ 169 XCharStruct max_bounds; /* maximum bounds over all existing char */
160 XCharStruct *per_char; /* first_char to last_char information */ 170 union {
171 XCharStruct *per_char; /* first_char to last_char information */
172 XCharStructRow **rows; /* first row to last row information */
173 } bounds;
161 int ascent; /* logical extent above baseline for spacing */ 174 int ascent; /* logical extent above baseline for spacing */
162 int descent; /* logical decent below baseline for spacing */ 175 int descent; /* logical decent below baseline for spacing */
163}; 176};
diff --git a/src/macmenu.c b/src/macmenu.c
index 064cec57486..1b132407df7 100644
--- a/src/macmenu.c
+++ b/src/macmenu.c
@@ -1,4 +1,4 @@
1/* Menu support for GNU Emacs on the for Mac OS. 1/* Menu support for GNU Emacs on Mac OS.
2 Copyright (C) 2000, 2001, 2002, 2003, 2004, 2 Copyright (C) 2000, 2001, 2002, 2003, 2004,
3 2005 Free Software Foundation, Inc. 3 2005 Free Software Foundation, Inc.
4 4
@@ -24,6 +24,7 @@ Boston, MA 02110-1301, USA. */
24#include <config.h> 24#include <config.h>
25 25
26#include <stdio.h> 26#include <stdio.h>
27
27#include "lisp.h" 28#include "lisp.h"
28#include "termhooks.h" 29#include "termhooks.h"
29#include "keyboard.h" 30#include "keyboard.h"
@@ -154,7 +155,7 @@ Lisp_Object Vmenu_updating_frame;
154 155
155Lisp_Object Qdebug_on_next_call; 156Lisp_Object Qdebug_on_next_call;
156 157
157extern Lisp_Object Qmenu_bar; 158extern Lisp_Object Qmenu_bar, Qmac_apple_event;
158 159
159extern Lisp_Object QCtoggle, QCradio; 160extern Lisp_Object QCtoggle, QCradio;
160 161
@@ -165,27 +166,28 @@ extern Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
165 166
166extern Lisp_Object Qmenu_bar_update_hook; 167extern Lisp_Object Qmenu_bar_update_hook;
167 168
169void set_frame_menubar P_ ((FRAME_PTR, int, int));
170
168#if TARGET_API_MAC_CARBON 171#if TARGET_API_MAC_CARBON
169#define ENCODE_MENU_STRING(str) ENCODE_UTF_8 (str) 172#define ENCODE_MENU_STRING(str) ENCODE_UTF_8 (str)
170#else 173#else
171#define ENCODE_MENU_STRING(str) ENCODE_SYSTEM (str) 174#define ENCODE_MENU_STRING(str) ENCODE_SYSTEM (str)
172#endif 175#endif
173 176
174void set_frame_menubar ();
175
176static void push_menu_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object, 177static void push_menu_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
177 Lisp_Object, Lisp_Object, Lisp_Object, 178 Lisp_Object, Lisp_Object, Lisp_Object,
178 Lisp_Object, Lisp_Object)); 179 Lisp_Object, Lisp_Object));
179#ifdef HAVE_DIALOGS 180#ifdef HAVE_DIALOGS
180static Lisp_Object mac_dialog_show (); 181static Lisp_Object mac_dialog_show P_ ((FRAME_PTR, int, Lisp_Object,
182 Lisp_Object, char **));
181#endif 183#endif
182static Lisp_Object mac_menu_show (); 184static Lisp_Object mac_menu_show P_ ((struct frame *, int, int, int, int,
183 185 Lisp_Object, char **));
184static void keymap_panes (); 186static void keymap_panes P_ ((Lisp_Object *, int, int));
185static void single_keymap_panes (); 187static void single_keymap_panes P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
186static void single_menu_item (); 188 int, int));
187static void list_of_panes (); 189static void list_of_panes P_ ((Lisp_Object));
188static void list_of_items (); 190static void list_of_items P_ ((Lisp_Object));
189 191
190static void fill_submenu (MenuHandle, widget_value *); 192static void fill_submenu (MenuHandle, widget_value *);
191static void fill_menubar (widget_value *); 193static void fill_menubar (widget_value *);
@@ -280,8 +282,7 @@ init_menu_items ()
280 menu_items_submenu_depth = 0; 282 menu_items_submenu_depth = 0;
281} 283}
282 284
283/* Call at the end of generating the data in menu_items. 285/* Call at the end of generating the data in menu_items. */
284 This fills in the number of items in the last pane. */
285 286
286static void 287static void
287finish_menu_items () 288finish_menu_items ()
@@ -415,11 +416,21 @@ keymap_panes (keymaps, nmaps, notreal)
415 P is the number of panes we have made so far. */ 416 P is the number of panes we have made so far. */
416 for (mapno = 0; mapno < nmaps; mapno++) 417 for (mapno = 0; mapno < nmaps; mapno++)
417 single_keymap_panes (keymaps[mapno], 418 single_keymap_panes (keymaps[mapno],
418 Fkeymap_prompt (keymaps[mapno]), Qnil, notreal, 10); 419 Fkeymap_prompt (keymaps[mapno]), Qnil, notreal, 10);
419 420
420 finish_menu_items (); 421 finish_menu_items ();
421} 422}
422 423
424/* Args passed between single_keymap_panes and single_menu_item. */
425struct skp
426 {
427 Lisp_Object pending_maps;
428 int maxdepth, notreal;
429 };
430
431static void single_menu_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
432 void *));
433
423/* This is a recursive subroutine of keymap_panes. 434/* This is a recursive subroutine of keymap_panes.
424 It handles one keymap, KEYMAP. 435 It handles one keymap, KEYMAP.
425 The other arguments are passed along 436 The other arguments are passed along
@@ -437,89 +448,71 @@ single_keymap_panes (keymap, pane_name, prefix, notreal, maxdepth)
437 int notreal; 448 int notreal;
438 int maxdepth; 449 int maxdepth;
439{ 450{
440 Lisp_Object pending_maps = Qnil; 451 struct skp skp;
441 Lisp_Object tail, item; 452 struct gcpro gcpro1;
442 struct gcpro gcpro1, gcpro2; 453
454 skp.pending_maps = Qnil;
455 skp.maxdepth = maxdepth;
456 skp.notreal = notreal;
443 457
444 if (maxdepth <= 0) 458 if (maxdepth <= 0)
445 return; 459 return;
446 460
447 push_menu_pane (pane_name, prefix); 461 push_menu_pane (pane_name, prefix);
448 462
449 for (tail = keymap; CONSP (tail); tail = XCDR (tail)) 463 GCPRO1 (skp.pending_maps);
450 { 464 map_keymap (keymap, single_menu_item, Qnil, &skp, 1);
451 GCPRO2 (keymap, pending_maps); 465 UNGCPRO;
452 /* Look at each key binding, and if it is a menu item add it
453 to this menu. */
454 item = XCAR (tail);
455 if (CONSP (item))
456 single_menu_item (XCAR (item), XCDR (item),
457 &pending_maps, notreal, maxdepth);
458 else if (VECTORP (item))
459 {
460 /* Loop over the char values represented in the vector. */
461 int len = XVECTOR (item)->size;
462 int c;
463 for (c = 0; c < len; c++)
464 {
465 Lisp_Object character;
466 XSETFASTINT (character, c);
467 single_menu_item (character, XVECTOR (item)->contents[c],
468 &pending_maps, notreal, maxdepth);
469 }
470 }
471 UNGCPRO;
472 }
473 466
474 /* Process now any submenus which want to be panes at this level. */ 467 /* Process now any submenus which want to be panes at this level. */
475 while (!NILP (pending_maps)) 468 while (CONSP (skp.pending_maps))
476 { 469 {
477 Lisp_Object elt, eltcdr, string; 470 Lisp_Object elt, eltcdr, string;
478 elt = Fcar (pending_maps); 471 elt = XCAR (skp.pending_maps);
479 eltcdr = XCDR (elt); 472 eltcdr = XCDR (elt);
480 string = XCAR (eltcdr); 473 string = XCAR (eltcdr);
481 /* We no longer discard the @ from the beginning of the string here. 474 /* We no longer discard the @ from the beginning of the string here.
482 Instead, we do this in mac_menu_show. */ 475 Instead, we do this in mac_menu_show. */
483 single_keymap_panes (Fcar (elt), string, 476 single_keymap_panes (Fcar (elt), string,
484 XCDR (eltcdr), notreal, maxdepth - 1); 477 XCDR (eltcdr), notreal, maxdepth - 1);
485 pending_maps = Fcdr (pending_maps); 478 skp.pending_maps = XCDR (skp.pending_maps);
486 } 479 }
487} 480}
488 481
489/* This is a subroutine of single_keymap_panes that handles one 482/* This is a subroutine of single_keymap_panes that handles one
490 keymap entry. 483 keymap entry.
491 KEY is a key in a keymap and ITEM is its binding. 484 KEY is a key in a keymap and ITEM is its binding.
492 PENDING_MAPS_PTR points to a list of keymaps waiting to be made into 485 SKP->PENDING_MAPS_PTR is a list of keymaps waiting to be made into
493 separate panes. 486 separate panes.
494 If NOTREAL is nonzero, only check for equivalent key bindings, don't 487 If SKP->NOTREAL is nonzero, only check for equivalent key bindings, don't
495 evaluate expressions in menu items and don't make any menu. 488 evaluate expressions in menu items and don't make any menu.
496 If we encounter submenus deeper than MAXDEPTH levels, ignore them. */ 489 If we encounter submenus deeper than SKP->MAXDEPTH levels, ignore them. */
497 490
498static void 491static void
499single_menu_item (key, item, pending_maps_ptr, notreal, maxdepth) 492single_menu_item (key, item, dummy, skp_v)
500 Lisp_Object key, item; 493 Lisp_Object key, item, dummy;
501 Lisp_Object *pending_maps_ptr; 494 void *skp_v;
502 int maxdepth, notreal;
503{ 495{
504 Lisp_Object map, item_string, enabled; 496 Lisp_Object map, item_string, enabled;
505 struct gcpro gcpro1, gcpro2; 497 struct gcpro gcpro1, gcpro2;
506 int res; 498 int res;
499 struct skp *skp = skp_v;
507 500
508 /* Parse the menu item and leave the result in item_properties. */ 501 /* Parse the menu item and leave the result in item_properties. */
509 GCPRO2 (key, item); 502 GCPRO2 (key, item);
510 res = parse_menu_item (item, notreal, 0); 503 res = parse_menu_item (item, skp->notreal, 0);
511 UNGCPRO; 504 UNGCPRO;
512 if (!res) 505 if (!res)
513 return; /* Not a menu item. */ 506 return; /* Not a menu item. */
514 507
515 map = XVECTOR (item_properties)->contents[ITEM_PROPERTY_MAP]; 508 map = XVECTOR (item_properties)->contents[ITEM_PROPERTY_MAP];
516 509
517 if (notreal) 510 if (skp->notreal)
518 { 511 {
519 /* We don't want to make a menu, just traverse the keymaps to 512 /* We don't want to make a menu, just traverse the keymaps to
520 precompute equivalent key bindings. */ 513 precompute equivalent key bindings. */
521 if (!NILP (map)) 514 if (!NILP (map))
522 single_keymap_panes (map, Qnil, key, 1, maxdepth - 1); 515 single_keymap_panes (map, Qnil, key, 1, skp->maxdepth - 1);
523 return; 516 return;
524 } 517 }
525 518
@@ -530,8 +523,8 @@ single_menu_item (key, item, pending_maps_ptr, notreal, maxdepth)
530 { 523 {
531 if (!NILP (enabled)) 524 if (!NILP (enabled))
532 /* An enabled separate pane. Remember this to handle it later. */ 525 /* An enabled separate pane. Remember this to handle it later. */
533 *pending_maps_ptr = Fcons (Fcons (map, Fcons (item_string, key)), 526 skp->pending_maps = Fcons (Fcons (map, Fcons (item_string, key)),
534 *pending_maps_ptr); 527 skp->pending_maps);
535 return; 528 return;
536 } 529 }
537 530
@@ -539,14 +532,14 @@ single_menu_item (key, item, pending_maps_ptr, notreal, maxdepth)
539 XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF], 532 XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF],
540 XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ], 533 XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ],
541 XVECTOR (item_properties)->contents[ITEM_PROPERTY_TYPE], 534 XVECTOR (item_properties)->contents[ITEM_PROPERTY_TYPE],
542 XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED], 535 XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED],
543 XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP]); 536 XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP]);
544 537
545 /* Display a submenu using the toolkit. */ 538 /* Display a submenu using the toolkit. */
546 if (! (NILP (map) || NILP (enabled))) 539 if (! (NILP (map) || NILP (enabled)))
547 { 540 {
548 push_submenu_start (); 541 push_submenu_start ();
549 single_keymap_panes (map, Qnil, key, 0, maxdepth - 1); 542 single_keymap_panes (map, Qnil, key, 0, skp->maxdepth - 1);
550 push_submenu_end (); 543 push_submenu_end ();
551 } 544 }
552} 545}
@@ -563,13 +556,13 @@ list_of_panes (menu)
563 556
564 init_menu_items (); 557 init_menu_items ();
565 558
566 for (tail = menu; !NILP (tail); tail = Fcdr (tail)) 559 for (tail = menu; CONSP (tail); tail = XCDR (tail))
567 { 560 {
568 Lisp_Object elt, pane_name, pane_data; 561 Lisp_Object elt, pane_name, pane_data;
569 elt = Fcar (tail); 562 elt = XCAR (tail);
570 pane_name = Fcar (elt); 563 pane_name = Fcar (elt);
571 CHECK_STRING (pane_name); 564 CHECK_STRING (pane_name);
572 push_menu_pane (pane_name, Qnil); 565 push_menu_pane (ENCODE_MENU_STRING (pane_name), Qnil);
573 pane_data = Fcdr (elt); 566 pane_data = Fcdr (elt);
574 CHECK_CONS (pane_data); 567 CHECK_CONS (pane_data);
575 list_of_items (pane_data); 568 list_of_items (pane_data);
@@ -586,20 +579,22 @@ list_of_items (pane)
586{ 579{
587 Lisp_Object tail, item, item1; 580 Lisp_Object tail, item, item1;
588 581
589 for (tail = pane; !NILP (tail); tail = Fcdr (tail)) 582 for (tail = pane; CONSP (tail); tail = XCDR (tail))
590 { 583 {
591 item = Fcar (tail); 584 item = XCAR (tail);
592 if (STRINGP (item)) 585 if (STRINGP (item))
593 push_menu_item (item, Qnil, Qnil, Qt, Qnil, Qnil, Qnil, Qnil); 586 push_menu_item (ENCODE_MENU_STRING (item), Qnil, Qnil, Qt,
594 else if (NILP (item)) 587 Qnil, Qnil, Qnil, Qnil);
595 push_left_right_boundary (); 588 else if (CONSP (item))
596 else
597 { 589 {
598 CHECK_CONS (item); 590 item1 = XCAR (item);
599 item1 = Fcar (item);
600 CHECK_STRING (item1); 591 CHECK_STRING (item1);
601 push_menu_item (item1, Qt, Fcdr (item), Qt, Qnil, Qnil, Qnil, Qnil); 592 push_menu_item (ENCODE_MENU_STRING (item1), Qt, XCDR (item),
593 Qt, Qnil, Qnil, Qnil, Qnil);
602 } 594 }
595 else
596 push_left_right_boundary ();
597
603 } 598 }
604} 599}
605 600
@@ -659,15 +654,14 @@ no quit occurs and `x-popup-menu' returns nil. */)
659 Lisp_Object keymap, tem; 654 Lisp_Object keymap, tem;
660 int xpos = 0, ypos = 0; 655 int xpos = 0, ypos = 0;
661 Lisp_Object title; 656 Lisp_Object title;
662 char *error_name; 657 char *error_name = NULL;
663 Lisp_Object selection; 658 Lisp_Object selection;
664 FRAME_PTR f = NULL; 659 FRAME_PTR f = NULL;
665 Lisp_Object x, y, window; 660 Lisp_Object x, y, window;
666 int keymaps = 0; 661 int keymaps = 0;
667 int for_click = 0; 662 int for_click = 0;
668 struct gcpro gcpro1;
669 int specpdl_count = SPECPDL_INDEX (); 663 int specpdl_count = SPECPDL_INDEX ();
670 664 struct gcpro gcpro1;
671 665
672#ifdef HAVE_MENUS 666#ifdef HAVE_MENUS
673 if (! NILP (position)) 667 if (! NILP (position))
@@ -677,7 +671,8 @@ no quit occurs and `x-popup-menu' returns nil. */)
677 /* Decode the first argument: find the window and the coordinates. */ 671 /* Decode the first argument: find the window and the coordinates. */
678 if (EQ (position, Qt) 672 if (EQ (position, Qt)
679 || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar) 673 || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar)
680 || EQ (XCAR (position), Qtool_bar)))) 674 || EQ (XCAR (position), Qtool_bar)
675 || EQ (XCAR (position), Qmac_apple_event))))
681 { 676 {
682 /* Use the mouse's current position. */ 677 /* Use the mouse's current position. */
683 FRAME_PTR new_f = SELECTED_FRAME (); 678 FRAME_PTR new_f = SELECTED_FRAME ();
@@ -703,8 +698,8 @@ no quit occurs and `x-popup-menu' returns nil. */)
703 if (CONSP (tem)) 698 if (CONSP (tem))
704 { 699 {
705 window = Fcar (Fcdr (position)); 700 window = Fcar (Fcdr (position));
706 x = Fcar (tem); 701 x = XCAR (tem);
707 y = Fcar (Fcdr (tem)); 702 y = Fcar (XCDR (tem));
708 } 703 }
709 else 704 else
710 { 705 {
@@ -788,11 +783,11 @@ no quit occurs and `x-popup-menu' returns nil. */)
788 783
789 /* The first keymap that has a prompt string 784 /* The first keymap that has a prompt string
790 supplies the menu title. */ 785 supplies the menu title. */
791 for (tem = menu, i = 0; CONSP (tem); tem = Fcdr (tem)) 786 for (tem = menu, i = 0; CONSP (tem); tem = XCDR (tem))
792 { 787 {
793 Lisp_Object prompt; 788 Lisp_Object prompt;
794 789
795 maps[i++] = keymap = get_keymap (Fcar (tem), 1, 0); 790 maps[i++] = keymap = get_keymap (XCAR (tem), 1, 0);
796 791
797 prompt = Fkeymap_prompt (keymap); 792 prompt = Fkeymap_prompt (keymap);
798 if (NILP (title) && !NILP (prompt)) 793 if (NILP (title) && !NILP (prompt))
@@ -879,7 +874,8 @@ for instance using the window manager, then this produces a quit and
879 /* Decode the first argument: find the window or frame to use. */ 874 /* Decode the first argument: find the window or frame to use. */
880 if (EQ (position, Qt) 875 if (EQ (position, Qt)
881 || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar) 876 || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar)
882 || EQ (XCAR (position), Qtool_bar)))) 877 || EQ (XCAR (position), Qtool_bar)
878 || EQ (XCAR (position), Qmac_apple_event))))
883 { 879 {
884#if 0 /* Using the frame the mouse is on may not be right. */ 880#if 0 /* Using the frame the mouse is on may not be right. */
885 /* Use the mouse's current position. */ 881 /* Use the mouse's current position. */
@@ -947,6 +943,7 @@ for instance using the window manager, then this produces a quit and
947 Lisp_Object title; 943 Lisp_Object title;
948 char *error_name; 944 char *error_name;
949 Lisp_Object selection; 945 Lisp_Object selection;
946 int specpdl_count = SPECPDL_INDEX ();
950 947
951 /* Decode the dialog items from what was specified. */ 948 /* Decode the dialog items from what was specified. */
952 title = Fcar (contents); 949 title = Fcar (contents);
@@ -955,11 +952,11 @@ for instance using the window manager, then this produces a quit and
955 list_of_panes (Fcons (contents, Qnil)); 952 list_of_panes (Fcons (contents, Qnil));
956 953
957 /* Display them in a dialog box. */ 954 /* Display them in a dialog box. */
955 record_unwind_protect (cleanup_popup_menu, Qnil);
958 BLOCK_INPUT; 956 BLOCK_INPUT;
959 selection = mac_dialog_show (f, 0, title, header, &error_name); 957 selection = mac_dialog_show (f, 0, title, header, &error_name);
960 UNBLOCK_INPUT; 958 UNBLOCK_INPUT;
961 959 unbind_to (specpdl_count, Qnil);
962 discard_menu_items ();
963 960
964 if (error_name) error (error_name); 961 if (error_name) error (error_name);
965 return selection; 962 return selection;
@@ -971,13 +968,14 @@ for instance using the window manager, then this produces a quit and
971 This is called from keyboard.c when it gets the 968 This is called from keyboard.c when it gets the
972 MENU_BAR_ACTIVATE_EVENT out of the Emacs event queue. 969 MENU_BAR_ACTIVATE_EVENT out of the Emacs event queue.
973 970
974 To activate the menu bar, we signal to the input thread that it can 971 To activate the menu bar, we use the button-press event location
975 return from the WM_INITMENU message, allowing the normal Windows 972 that was saved in saved_menu_event_location.
976 processing of the menus.
977 973
978 But first we recompute the menu bar contents (the whole tree). 974 But first we recompute the menu bar contents (the whole tree).
979 975
980 This way we can safely execute Lisp code. */ 976 The reason for saving the button event until here, instead of
977 passing it to the toolkit right away, is that we can safely
978 execute Lisp code. */
981 979
982void 980void
983x_activate_menubar (f) 981x_activate_menubar (f)
@@ -1074,14 +1072,12 @@ menubar_selection_callback (FRAME_PTR f, int client_data)
1074 buf.arg = entry; 1072 buf.arg = entry;
1075 kbd_buffer_store_event (&buf); 1073 kbd_buffer_store_event (&buf);
1076 1074
1077 f->output_data.mac->menu_command_in_progress = 0;
1078 f->output_data.mac->menubar_active = 0; 1075 f->output_data.mac->menubar_active = 0;
1079 return; 1076 return;
1080 } 1077 }
1081 i += MENU_ITEMS_ITEM_LENGTH; 1078 i += MENU_ITEMS_ITEM_LENGTH;
1082 } 1079 }
1083 } 1080 }
1084 f->output_data.mac->menu_command_in_progress = 0;
1085 f->output_data.mac->menubar_active = 0; 1081 f->output_data.mac->menubar_active = 0;
1086} 1082}
1087 1083
@@ -1127,22 +1123,18 @@ free_menubar_widget_value_tree (wv)
1127 UNBLOCK_INPUT; 1123 UNBLOCK_INPUT;
1128} 1124}
1129 1125
1130/* Return a tree of widget_value structures for a menu bar item 1126/* Set up data in menu_items for a menu bar item
1131 whose event type is ITEM_KEY (with string ITEM_NAME) 1127 whose event type is ITEM_KEY (with string ITEM_NAME)
1132 and whose contents come from the list of keymaps MAPS. */ 1128 and whose contents come from the list of keymaps MAPS. */
1133 1129
1134static widget_value * 1130static int
1135single_submenu (item_key, item_name, maps) 1131parse_single_submenu (item_key, item_name, maps)
1136 Lisp_Object item_key, item_name, maps; 1132 Lisp_Object item_key, item_name, maps;
1137{ 1133{
1138 widget_value *wv, *prev_wv, *save_wv, *first_wv;
1139 int i;
1140 int submenu_depth = 0;
1141 Lisp_Object length; 1134 Lisp_Object length;
1142 int len; 1135 int len;
1143 Lisp_Object *mapvec; 1136 Lisp_Object *mapvec;
1144 widget_value **submenu_stack; 1137 int i;
1145 int previous_items = menu_items_used;
1146 int top_level_items = 0; 1138 int top_level_items = 0;
1147 1139
1148 length = Flength (maps); 1140 length = Flength (maps);
@@ -1156,28 +1148,44 @@ single_submenu (item_key, item_name, maps)
1156 maps = Fcdr (maps); 1148 maps = Fcdr (maps);
1157 } 1149 }
1158 1150
1159 menu_items_n_panes = 0;
1160
1161 /* Loop over the given keymaps, making a pane for each map. 1151 /* Loop over the given keymaps, making a pane for each map.
1162 But don't make a pane that is empty--ignore that map instead. */ 1152 But don't make a pane that is empty--ignore that map instead. */
1163 for (i = 0; i < len; i++) 1153 for (i = 0; i < len; i++)
1164 { 1154 {
1165 if (SYMBOLP (mapvec[i]) 1155 if (!KEYMAPP (mapvec[i]))
1166 || (CONSP (mapvec[i]) && !KEYMAPP (mapvec[i])))
1167 { 1156 {
1168 /* Here we have a command at top level in the menu bar 1157 /* Here we have a command at top level in the menu bar
1169 as opposed to a submenu. */ 1158 as opposed to a submenu. */
1170 top_level_items = 1; 1159 top_level_items = 1;
1171 push_menu_pane (Qnil, Qnil); 1160 push_menu_pane (Qnil, Qnil);
1172 push_menu_item (item_name, Qt, item_key, mapvec[i], 1161 push_menu_item (item_name, Qt, item_key, mapvec[i],
1173 Qnil, Qnil, Qnil, Qnil); 1162 Qnil, Qnil, Qnil, Qnil);
1174 } 1163 }
1175 else 1164 else
1176 single_keymap_panes (mapvec[i], item_name, item_key, 0, 10); 1165 {
1166 Lisp_Object prompt;
1167 prompt = Fkeymap_prompt (mapvec[i]);
1168 single_keymap_panes (mapvec[i],
1169 !NILP (prompt) ? prompt : item_name,
1170 item_key, 0, 10);
1171 }
1177 } 1172 }
1178 1173
1179 /* Create a tree of widget_value objects 1174 return top_level_items;
1180 representing the panes and their items. */ 1175}
1176
1177/* Create a tree of widget_value objects
1178 representing the panes and items
1179 in menu_items starting at index START, up to index END. */
1180
1181static widget_value *
1182digest_single_submenu (start, end, top_level_items)
1183 int start, end, top_level_items;
1184{
1185 widget_value *wv, *prev_wv, *save_wv, *first_wv;
1186 int i;
1187 int submenu_depth = 0;
1188 widget_value **submenu_stack;
1181 1189
1182 submenu_stack 1190 submenu_stack
1183 = (widget_value **) alloca (menu_items_used * sizeof (widget_value *)); 1191 = (widget_value **) alloca (menu_items_used * sizeof (widget_value *));
@@ -1191,12 +1199,12 @@ single_submenu (item_key, item_name, maps)
1191 save_wv = 0; 1199 save_wv = 0;
1192 prev_wv = 0; 1200 prev_wv = 0;
1193 1201
1194 /* Loop over all panes and items made during this call 1202 /* Loop over all panes and items made by the preceding call
1195 and construct a tree of widget_value objects. 1203 to parse_single_submenu and construct a tree of widget_value objects.
1196 Ignore the panes and items made by previous calls to 1204 Ignore the panes and items used by previous calls to
1197 single_submenu, even though those are also in menu_items. */ 1205 digest_single_submenu, even though those are also in menu_items. */
1198 i = previous_items; 1206 i = start;
1199 while (i < menu_items_used) 1207 while (i < end)
1200 { 1208 {
1201 if (EQ (XVECTOR (menu_items)->contents[i], Qnil)) 1209 if (EQ (XVECTOR (menu_items)->contents[i], Qnil))
1202 { 1210 {
@@ -1230,7 +1238,7 @@ single_submenu (item_key, item_name, maps)
1230#ifndef HAVE_MULTILINGUAL_MENU 1238#ifndef HAVE_MULTILINGUAL_MENU
1231 if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name)) 1239 if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name))
1232 { 1240 {
1233 pane_name = ENCODE_SYSTEM (pane_name); 1241 pane_name = ENCODE_MENU_STRING (pane_name);
1234 AREF (menu_items, i + MENU_ITEMS_PANE_NAME) = pane_name; 1242 AREF (menu_items, i + MENU_ITEMS_PANE_NAME) = pane_name;
1235 } 1243 }
1236#endif 1244#endif
@@ -1266,7 +1274,7 @@ single_submenu (item_key, item_name, maps)
1266 { 1274 {
1267 /* Create a new item within current pane. */ 1275 /* Create a new item within current pane. */
1268 Lisp_Object item_name, enable, descrip, def, type, selected; 1276 Lisp_Object item_name, enable, descrip, def, type, selected;
1269 Lisp_Object help; 1277 Lisp_Object help;
1270 1278
1271 item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME); 1279 item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME);
1272 enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE); 1280 enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE);
@@ -1277,13 +1285,13 @@ single_submenu (item_key, item_name, maps)
1277 help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP); 1285 help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP);
1278 1286
1279#ifndef HAVE_MULTILINGUAL_MENU 1287#ifndef HAVE_MULTILINGUAL_MENU
1280 if (STRING_MULTIBYTE (item_name)) 1288 if (STRING_MULTIBYTE (item_name))
1281 { 1289 {
1282 item_name = ENCODE_MENU_STRING (item_name); 1290 item_name = ENCODE_MENU_STRING (item_name);
1283 AREF (menu_items, i + MENU_ITEMS_ITEM_NAME) = item_name; 1291 AREF (menu_items, i + MENU_ITEMS_ITEM_NAME) = item_name;
1284 } 1292 }
1285 1293
1286 if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) 1294 if (STRINGP (descrip) && STRING_MULTIBYTE (descrip))
1287 { 1295 {
1288 descrip = ENCODE_MENU_STRING (descrip); 1296 descrip = ENCODE_MENU_STRING (descrip);
1289 AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip; 1297 AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip;
@@ -1315,7 +1323,7 @@ single_submenu (item_key, item_name, maps)
1315 abort (); 1323 abort ();
1316 1324
1317 wv->selected = !NILP (selected); 1325 wv->selected = !NILP (selected);
1318 if (!STRINGP (help)) 1326 if (! STRINGP (help))
1319 help = Qnil; 1327 help = Qnil;
1320 1328
1321 wv->help = help; 1329 wv->help = help;
@@ -1337,6 +1345,7 @@ single_submenu (item_key, item_name, maps)
1337 1345
1338 return first_wv; 1346 return first_wv;
1339} 1347}
1348
1340/* Walk through the widget_value tree starting at FIRST_WV and update 1349/* Walk through the widget_value tree starting at FIRST_WV and update
1341 the char * pointers from the corresponding lisp values. 1350 the char * pointers from the corresponding lisp values.
1342 We do this after building the whole tree, since GC may happen while the 1351 We do this after building the whole tree, since GC may happen while the
@@ -1418,20 +1427,28 @@ static void
1418install_menu_quit_handler (MenuHandle menu_handle) 1427install_menu_quit_handler (MenuHandle menu_handle)
1419{ 1428{
1420#ifdef HAVE_CANCELMENUTRACKING 1429#ifdef HAVE_CANCELMENUTRACKING
1421 EventHandlerUPP handler = NewEventHandlerUPP(menu_quit_handler);
1422 UInt32 numTypes = 1;
1423 EventTypeSpec typesList[] = { { kEventClassKeyboard, kEventRawKeyDown } }; 1430 EventTypeSpec typesList[] = { { kEventClassKeyboard, kEventRawKeyDown } };
1424 int i = MIN_MENU_ID; 1431 int i = MIN_MENU_ID;
1425 MenuHandle menu = menu_handle ? menu_handle : GetMenuHandle (i); 1432 MenuHandle menu = menu_handle ? menu_handle : GetMenuHandle (i);
1426 1433
1427 while (menu != NULL) 1434 while (menu != NULL)
1428 { 1435 {
1429 InstallMenuEventHandler (menu, handler, GetEventTypeCount (typesList), 1436 InstallMenuEventHandler (menu, menu_quit_handler,
1437 GetEventTypeCount (typesList),
1430 typesList, menu_handle, NULL); 1438 typesList, menu_handle, NULL);
1431 if (menu_handle) break; 1439 if (menu_handle) break;
1432 menu = GetMenuHandle (++i); 1440 menu = GetMenuHandle (++i);
1433 } 1441 }
1434 DisposeEventHandlerUPP (handler); 1442
1443 i = menu_handle ? MIN_POPUP_SUBMENU_ID : MIN_SUBMENU_ID;
1444 menu = GetMenuHandle (i);
1445 while (menu != NULL)
1446 {
1447 InstallMenuEventHandler (menu, menu_quit_handler,
1448 GetEventTypeCount (typesList),
1449 typesList, menu_handle, NULL);
1450 menu = GetMenuHandle (++i);
1451 }
1435#endif /* HAVE_CANCELMENUTRACKING */ 1452#endif /* HAVE_CANCELMENUTRACKING */
1436} 1453}
1437 1454
@@ -1448,7 +1465,9 @@ set_frame_menubar (f, first_time, deep_p)
1448 int menubar_widget = f->output_data.mac->menubar_widget; 1465 int menubar_widget = f->output_data.mac->menubar_widget;
1449 Lisp_Object items; 1466 Lisp_Object items;
1450 widget_value *wv, *first_wv, *prev_wv = 0; 1467 widget_value *wv, *first_wv, *prev_wv = 0;
1451 int i; 1468 int i, last_i = 0;
1469 int *submenu_start, *submenu_end;
1470 int *submenu_top_level_items, *submenu_n_panes;
1452 1471
1453 /* We must not change the menubar when actually in use. */ 1472 /* We must not change the menubar when actually in use. */
1454 if (f->output_data.mac->menubar_active) 1473 if (f->output_data.mac->menubar_active)
@@ -1461,14 +1480,6 @@ set_frame_menubar (f, first_time, deep_p)
1461 else if (pending_menu_activation && !deep_p) 1480 else if (pending_menu_activation && !deep_p)
1462 deep_p = 1; 1481 deep_p = 1;
1463 1482
1464 wv = xmalloc_widget_value ();
1465 wv->name = "menubar";
1466 wv->value = 0;
1467 wv->enabled = 1;
1468 wv->button_type = BUTTON_TYPE_NONE;
1469 wv->help = Qnil;
1470 first_wv = wv;
1471
1472 if (deep_p) 1483 if (deep_p)
1473 { 1484 {
1474 /* Make a widget-value tree representing the entire menu trees. */ 1485 /* Make a widget-value tree representing the entire menu trees. */
@@ -1503,6 +1514,7 @@ set_frame_menubar (f, first_time, deep_p)
1503 1514
1504 /* Run the Lucid hook. */ 1515 /* Run the Lucid hook. */
1505 safe_run_hooks (Qactivate_menubar_hook); 1516 safe_run_hooks (Qactivate_menubar_hook);
1517
1506 /* If it has changed current-menubar from previous value, 1518 /* If it has changed current-menubar from previous value,
1507 really recompute the menubar from the value. */ 1519 really recompute the menubar from the value. */
1508 if (! NILP (Vlucid_menu_bar_dirty_flag)) 1520 if (! NILP (Vlucid_menu_bar_dirty_flag))
@@ -1517,21 +1529,56 @@ set_frame_menubar (f, first_time, deep_p)
1517 bcopy (XVECTOR (f->menu_bar_vector)->contents, previous_items, 1529 bcopy (XVECTOR (f->menu_bar_vector)->contents, previous_items,
1518 previous_menu_items_used * sizeof (Lisp_Object)); 1530 previous_menu_items_used * sizeof (Lisp_Object));
1519 1531
1520 /* Fill in the current menu bar contents. */ 1532 /* Fill in menu_items with the current menu bar contents.
1533 This can evaluate Lisp code. */
1521 menu_items = f->menu_bar_vector; 1534 menu_items = f->menu_bar_vector;
1522 menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0; 1535 menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0;
1536 submenu_start = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
1537 submenu_end = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
1538 submenu_n_panes = (int *) alloca (XVECTOR (items)->size * sizeof (int));
1539 submenu_top_level_items
1540 = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
1523 init_menu_items (); 1541 init_menu_items ();
1524 for (i = 0; i < XVECTOR (items)->size; i += 4) 1542 for (i = 0; i < XVECTOR (items)->size; i += 4)
1525 { 1543 {
1526 Lisp_Object key, string, maps; 1544 Lisp_Object key, string, maps;
1527 1545
1546 last_i = i;
1547
1528 key = XVECTOR (items)->contents[i]; 1548 key = XVECTOR (items)->contents[i];
1529 string = XVECTOR (items)->contents[i + 1]; 1549 string = XVECTOR (items)->contents[i + 1];
1530 maps = XVECTOR (items)->contents[i + 2]; 1550 maps = XVECTOR (items)->contents[i + 2];
1531 if (NILP (string)) 1551 if (NILP (string))
1532 break; 1552 break;
1533 1553
1534 wv = single_submenu (key, string, maps); 1554 submenu_start[i] = menu_items_used;
1555
1556 menu_items_n_panes = 0;
1557 submenu_top_level_items[i]
1558 = parse_single_submenu (key, string, maps);
1559 submenu_n_panes[i] = menu_items_n_panes;
1560
1561 submenu_end[i] = menu_items_used;
1562 }
1563
1564 finish_menu_items ();
1565
1566 /* Convert menu_items into widget_value trees
1567 to display the menu. This cannot evaluate Lisp code. */
1568
1569 wv = xmalloc_widget_value ();
1570 wv->name = "menubar";
1571 wv->value = 0;
1572 wv->enabled = 1;
1573 wv->button_type = BUTTON_TYPE_NONE;
1574 wv->help = Qnil;
1575 first_wv = wv;
1576
1577 for (i = 0; i < last_i; i += 4)
1578 {
1579 menu_items_n_panes = submenu_n_panes[i];
1580 wv = digest_single_submenu (submenu_start[i], submenu_end[i],
1581 submenu_top_level_items[i]);
1535 if (prev_wv) 1582 if (prev_wv)
1536 prev_wv->next = wv; 1583 prev_wv->next = wv;
1537 else 1584 else
@@ -1542,8 +1589,6 @@ set_frame_menubar (f, first_time, deep_p)
1542 prev_wv = wv; 1589 prev_wv = wv;
1543 } 1590 }
1544 1591
1545 finish_menu_items ();
1546
1547 set_buffer_internal_1 (prev); 1592 set_buffer_internal_1 (prev);
1548 unbind_to (specpdl_count, Qnil); 1593 unbind_to (specpdl_count, Qnil);
1549 1594
@@ -1552,22 +1597,18 @@ set_frame_menubar (f, first_time, deep_p)
1552 1597
1553 for (i = 0; i < previous_menu_items_used; i++) 1598 for (i = 0; i < previous_menu_items_used; i++)
1554 if (menu_items_used == i 1599 if (menu_items_used == i
1555 || (NILP (Fequal (previous_items[i], 1600 || (!EQ (previous_items[i], XVECTOR (menu_items)->contents[i])))
1556 XVECTOR (menu_items)->contents[i]))))
1557 break; 1601 break;
1558 if (i == menu_items_used && i == previous_menu_items_used && i != 0) 1602 if (i == menu_items_used && i == previous_menu_items_used && i != 0)
1559 { 1603 {
1560 free_menubar_widget_value_tree (first_wv); 1604 free_menubar_widget_value_tree (first_wv);
1561 menu_items = Qnil; 1605 discard_menu_items ();
1562 1606
1563 return; 1607 return;
1564 } 1608 }
1565 1609
1566 /* Now GC cannot happen during the lifetime of the widget_value, 1610 /* Now GC cannot happen during the lifetime of the widget_value,
1567 so it's safe to store data from a Lisp_String, as long as 1611 so it's safe to store data from a Lisp_String. */
1568 local copies are made when the actual menu is created.
1569 Windows takes care of this for normal string items, but
1570 not for owner-drawn items or additional item-info. */
1571 wv = first_wv->contents; 1612 wv = first_wv->contents;
1572 for (i = 0; i < XVECTOR (items)->size; i += 4) 1613 for (i = 0; i < XVECTOR (items)->size; i += 4)
1573 { 1614 {
@@ -1582,13 +1623,21 @@ set_frame_menubar (f, first_time, deep_p)
1582 1623
1583 f->menu_bar_vector = menu_items; 1624 f->menu_bar_vector = menu_items;
1584 f->menu_bar_items_used = menu_items_used; 1625 f->menu_bar_items_used = menu_items_used;
1585 menu_items = Qnil; 1626 discard_menu_items ();
1586 } 1627 }
1587 else 1628 else
1588 { 1629 {
1589 /* Make a widget-value tree containing 1630 /* Make a widget-value tree containing
1590 just the top level menu bar strings. */ 1631 just the top level menu bar strings. */
1591 1632
1633 wv = xmalloc_widget_value ();
1634 wv->name = "menubar";
1635 wv->value = 0;
1636 wv->enabled = 1;
1637 wv->button_type = BUTTON_TYPE_NONE;
1638 wv->help = Qnil;
1639 first_wv = wv;
1640
1592 items = FRAME_MENU_BAR_ITEMS (f); 1641 items = FRAME_MENU_BAR_ITEMS (f);
1593 for (i = 0; i < XVECTOR (items)->size; i += 4) 1642 for (i = 0; i < XVECTOR (items)->size; i += 4)
1594 { 1643 {
@@ -1676,6 +1725,7 @@ initialize_frame_menubar (f)
1676 set_frame_menubar (f, 1, 1); 1725 set_frame_menubar (f, 1, 1);
1677} 1726}
1678 1727
1728
1679/* Get rid of the menu bar of frame F, and free its storage. 1729/* Get rid of the menu bar of frame F, and free its storage.
1680 This is used when deleting a frame, and when turning off the menu bar. */ 1730 This is used when deleting a frame, and when turning off the menu bar. */
1681 1731
@@ -1683,7 +1733,7 @@ void
1683free_frame_menubar (f) 1733free_frame_menubar (f)
1684 FRAME_PTR f; 1734 FRAME_PTR f;
1685{ 1735{
1686 f->output_data.mac->menubar_widget = NULL; 1736 f->output_data.mac->menubar_widget = 0;
1687} 1737}
1688 1738
1689 1739
@@ -1760,6 +1810,7 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error)
1760 Lisp_Object *subprefix_stack 1810 Lisp_Object *subprefix_stack
1761 = (Lisp_Object *) alloca (menu_items_used * sizeof (Lisp_Object)); 1811 = (Lisp_Object *) alloca (menu_items_used * sizeof (Lisp_Object));
1762 int submenu_depth = 0; 1812 int submenu_depth = 0;
1813
1763 int first_pane; 1814 int first_pane;
1764 int specpdl_count = SPECPDL_INDEX (); 1815 int specpdl_count = SPECPDL_INDEX ();
1765 1816
@@ -1813,12 +1864,14 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error)
1813 /* Create a new pane. */ 1864 /* Create a new pane. */
1814 Lisp_Object pane_name, prefix; 1865 Lisp_Object pane_name, prefix;
1815 char *pane_string; 1866 char *pane_string;
1867
1816 pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME); 1868 pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME);
1817 prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX); 1869 prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
1870
1818#ifndef HAVE_MULTILINGUAL_MENU 1871#ifndef HAVE_MULTILINGUAL_MENU
1819 if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name)) 1872 if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name))
1820 { 1873 {
1821 pane_name = ENCODE_SYSTEM (pane_name); 1874 pane_name = ENCODE_MENU_STRING (pane_name);
1822 AREF (menu_items, i + MENU_ITEMS_PANE_NAME) = pane_name; 1875 AREF (menu_items, i + MENU_ITEMS_PANE_NAME) = pane_name;
1823 } 1876 }
1824#endif 1877#endif
@@ -1861,14 +1914,13 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error)
1861 { 1914 {
1862 /* Create a new item within current pane. */ 1915 /* Create a new item within current pane. */
1863 Lisp_Object item_name, enable, descrip, def, type, selected, help; 1916 Lisp_Object item_name, enable, descrip, def, type, selected, help;
1864
1865 item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME); 1917 item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME);
1866 enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE); 1918 enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE);
1867 descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY); 1919 descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY);
1868 def = AREF (menu_items, i + MENU_ITEMS_ITEM_DEFINITION); 1920 def = AREF (menu_items, i + MENU_ITEMS_ITEM_DEFINITION);
1869 type = AREF (menu_items, i + MENU_ITEMS_ITEM_TYPE); 1921 type = AREF (menu_items, i + MENU_ITEMS_ITEM_TYPE);
1870 selected = AREF (menu_items, i + MENU_ITEMS_ITEM_SELECTED); 1922 selected = AREF (menu_items, i + MENU_ITEMS_ITEM_SELECTED);
1871 help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP); 1923 help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP);
1872 1924
1873#ifndef HAVE_MULTILINGUAL_MENU 1925#ifndef HAVE_MULTILINGUAL_MENU
1874 if (STRINGP (item_name) && STRING_MULTIBYTE (item_name)) 1926 if (STRINGP (item_name) && STRING_MULTIBYTE (item_name))
@@ -1876,8 +1928,9 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error)
1876 item_name = ENCODE_MENU_STRING (item_name); 1928 item_name = ENCODE_MENU_STRING (item_name);
1877 AREF (menu_items, i + MENU_ITEMS_ITEM_NAME) = item_name; 1929 AREF (menu_items, i + MENU_ITEMS_ITEM_NAME) = item_name;
1878 } 1930 }
1931
1879 if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) 1932 if (STRINGP (descrip) && STRING_MULTIBYTE (descrip))
1880 { 1933 {
1881 descrip = ENCODE_MENU_STRING (descrip); 1934 descrip = ENCODE_MENU_STRING (descrip);
1882 AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip; 1935 AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip;
1883 } 1936 }
@@ -1907,7 +1960,8 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error)
1907 abort (); 1960 abort ();
1908 1961
1909 wv->selected = !NILP (selected); 1962 wv->selected = !NILP (selected);
1910 if (!STRINGP (help)) 1963
1964 if (! STRINGP (help))
1911 help = Qnil; 1965 help = Qnil;
1912 1966
1913 wv->help = help; 1967 wv->help = help;
@@ -1934,6 +1988,7 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error)
1934 if (STRING_MULTIBYTE (title)) 1988 if (STRING_MULTIBYTE (title))
1935 title = ENCODE_MENU_STRING (title); 1989 title = ENCODE_MENU_STRING (title);
1936#endif 1990#endif
1991
1937 wv_title->name = (char *) SDATA (title); 1992 wv_title->name = (char *) SDATA (title);
1938 wv_title->enabled = FALSE; 1993 wv_title->enabled = FALSE;
1939 wv_title->title = TRUE; 1994 wv_title->title = TRUE;
@@ -1957,7 +2012,6 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error)
1957 pos.v = y; 2012 pos.v = y;
1958 2013
1959 SetPortWindowPort (FRAME_MAC_WINDOW (f)); 2014 SetPortWindowPort (FRAME_MAC_WINDOW (f));
1960
1961 LocalToGlobal (&pos); 2015 LocalToGlobal (&pos);
1962 2016
1963 /* No selection has been chosen yet. */ 2017 /* No selection has been chosen yet. */
@@ -2167,11 +2221,11 @@ static char * button_names [] = {
2167 "button6", "button7", "button8", "button9", "button10" }; 2221 "button6", "button7", "button8", "button9", "button10" };
2168 2222
2169static Lisp_Object 2223static Lisp_Object
2170mac_dialog_show (f, keymaps, title, header, error) 2224mac_dialog_show (f, keymaps, title, header, error_name)
2171 FRAME_PTR f; 2225 FRAME_PTR f;
2172 int keymaps; 2226 int keymaps;
2173 Lisp_Object title, header; 2227 Lisp_Object title, header;
2174 char **error; 2228 char **error_name;
2175{ 2229{
2176 int i, nb_buttons=0; 2230 int i, nb_buttons=0;
2177 char dialog_name[6]; 2231 char dialog_name[6];
@@ -2184,11 +2238,11 @@ mac_dialog_show (f, keymaps, title, header, error)
2184 /* 1 means we've seen the boundary between left-hand elts and right-hand. */ 2238 /* 1 means we've seen the boundary between left-hand elts and right-hand. */
2185 int boundary_seen = 0; 2239 int boundary_seen = 0;
2186 2240
2187 *error = NULL; 2241 *error_name = NULL;
2188 2242
2189 if (menu_items_n_panes > 1) 2243 if (menu_items_n_panes > 1)
2190 { 2244 {
2191 *error = "Multiple panes in dialog box"; 2245 *error_name = "Multiple panes in dialog box";
2192 return Qnil; 2246 return Qnil;
2193 } 2247 }
2194 2248
@@ -2216,18 +2270,16 @@ mac_dialog_show (f, keymaps, title, header, error)
2216 { 2270 {
2217 2271
2218 /* Create a new item within current pane. */ 2272 /* Create a new item within current pane. */
2219 Lisp_Object item_name, enable, descrip, help; 2273 Lisp_Object item_name, enable, descrip;
2220
2221 item_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_NAME]; 2274 item_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_NAME];
2222 enable = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_ENABLE]; 2275 enable = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_ENABLE];
2223 descrip 2276 descrip
2224 = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_EQUIV_KEY]; 2277 = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_EQUIV_KEY];
2225 help = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_HELP];
2226 2278
2227 if (NILP (item_name)) 2279 if (NILP (item_name))
2228 { 2280 {
2229 free_menubar_widget_value_tree (first_wv); 2281 free_menubar_widget_value_tree (first_wv);
2230 *error = "Submenu in dialog items"; 2282 *error_name = "Submenu in dialog items";
2231 return Qnil; 2283 return Qnil;
2232 } 2284 }
2233 if (EQ (item_name, Qquote)) 2285 if (EQ (item_name, Qquote))
@@ -2241,7 +2293,7 @@ mac_dialog_show (f, keymaps, title, header, error)
2241 if (nb_buttons >= 9) 2293 if (nb_buttons >= 9)
2242 { 2294 {
2243 free_menubar_widget_value_tree (first_wv); 2295 free_menubar_widget_value_tree (first_wv);
2244 *error = "Too many dialog items"; 2296 *error_name = "Too many dialog items";
2245 return Qnil; 2297 return Qnil;
2246 } 2298 }
2247 2299
@@ -2304,8 +2356,8 @@ mac_dialog_show (f, keymaps, title, header, error)
2304 /* Free the widget_value objects we used to specify the contents. */ 2356 /* Free the widget_value objects we used to specify the contents. */
2305 free_menubar_widget_value_tree (first_wv); 2357 free_menubar_widget_value_tree (first_wv);
2306 2358
2307 /* Find the selected item, and its pane, to return the proper 2359 /* Find the selected item, and its pane, to return
2308 value. */ 2360 the proper value. */
2309 if (menu_item_selection != 0) 2361 if (menu_item_selection != 0)
2310 { 2362 {
2311 Lisp_Object prefix; 2363 Lisp_Object prefix;
@@ -2322,6 +2374,12 @@ mac_dialog_show (f, keymaps, title, header, error)
2322 = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX]; 2374 = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX];
2323 i += MENU_ITEMS_PANE_LENGTH; 2375 i += MENU_ITEMS_PANE_LENGTH;
2324 } 2376 }
2377 else if (EQ (XVECTOR (menu_items)->contents[i], Qquote))
2378 {
2379 /* This is the boundary between left-side elts and
2380 right-side elts. */
2381 ++i;
2382 }
2325 else 2383 else
2326 { 2384 {
2327 entry 2385 entry
@@ -2340,6 +2398,9 @@ mac_dialog_show (f, keymaps, title, header, error)
2340 } 2398 }
2341 } 2399 }
2342 } 2400 }
2401 else
2402 /* Make "Cancel" equivalent to C-g. */
2403 Fsignal (Qquit, Qnil);
2343 2404
2344 return Qnil; 2405 return Qnil;
2345} 2406}
@@ -2365,7 +2426,11 @@ static void
2365add_menu_item (MenuHandle menu, widget_value *wv, int submenu, 2426add_menu_item (MenuHandle menu, widget_value *wv, int submenu,
2366 int force_disable) 2427 int force_disable)
2367{ 2428{
2429#if TARGET_API_MAC_CARBON
2430 CFStringRef item_name;
2431#else
2368 Str255 item_name; 2432 Str255 item_name;
2433#endif
2369 int pos; 2434 int pos;
2370 2435
2371 if (name_is_separator (wv->name)) 2436 if (name_is_separator (wv->name))
@@ -2376,42 +2441,49 @@ add_menu_item (MenuHandle menu, widget_value *wv, int submenu,
2376 2441
2377#if TARGET_API_MAC_CARBON 2442#if TARGET_API_MAC_CARBON
2378 pos = CountMenuItems (menu); 2443 pos = CountMenuItems (menu);
2379#else
2380 pos = CountMItems (menu);
2381#endif
2382 2444
2383 strcpy (item_name, ""); 2445 item_name = cfstring_create_with_utf8_cstring (wv->name);
2384 strncat (item_name, wv->name, 255); 2446
2385 if (wv->key != NULL) 2447 if (wv->key != NULL)
2386 { 2448 {
2387 strncat (item_name, " ", 255); 2449 CFStringRef name, key;
2388 strncat (item_name, wv->key, 255); 2450
2451 name = item_name;
2452 key = cfstring_create_with_utf8_cstring (wv->key);
2453 item_name = CFStringCreateWithFormat (NULL, NULL, CFSTR ("%@ %@"),
2454 name, key);
2455 CFRelease (name);
2456 CFRelease (key);
2389 } 2457 }
2390 item_name[255] = 0;
2391#if TARGET_API_MAC_CARBON
2392 {
2393 CFStringRef string = cfstring_create_with_utf8_cstring (item_name);
2394 2458
2395 SetMenuItemTextWithCFString (menu, pos, string); 2459 SetMenuItemTextWithCFString (menu, pos, item_name);
2396 CFRelease (string); 2460 CFRelease (item_name);
2397 } 2461
2398#else 2462 if (wv->enabled && !force_disable)
2463 EnableMenuItem (menu, pos);
2464 else
2465 DisableMenuItem (menu, pos);
2466#else /* ! TARGET_API_MAC_CARBON */
2467 pos = CountMItems (menu);
2468
2469 item_name[sizeof (item_name) - 1] = '\0';
2470 strncpy (item_name, wv->name, sizeof (item_name) - 1);
2471 if (wv->key != NULL)
2472 {
2473 int len = strlen (item_name);
2474
2475 strncpy (item_name + len, " ", sizeof (item_name) - 1 - len);
2476 len = strlen (item_name);
2477 strncpy (item_name + len, wv->key, sizeof (item_name) - 1 - len);
2478 }
2399 c2pstr (item_name); 2479 c2pstr (item_name);
2400 SetMenuItemText (menu, pos, item_name); 2480 SetMenuItemText (menu, pos, item_name);
2401#endif
2402 2481
2403 if (wv->enabled && !force_disable) 2482 if (wv->enabled && !force_disable)
2404#if TARGET_API_MAC_CARBON
2405 EnableMenuItem (menu, pos);
2406#else
2407 EnableItem (menu, pos); 2483 EnableItem (menu, pos);
2408#endif
2409 else 2484 else
2410#if TARGET_API_MAC_CARBON
2411 DisableMenuItem (menu, pos);
2412#else
2413 DisableItem (menu, pos); 2485 DisableItem (menu, pos);
2414#endif 2486#endif /* ! TARGET_API_MAC_CARBON */
2415 2487
2416 /* Draw radio buttons and tickboxes. */ 2488 /* Draw radio buttons and tickboxes. */
2417 { 2489 {
@@ -2425,7 +2497,7 @@ add_menu_item (MenuHandle menu, widget_value *wv, int submenu,
2425 SetMenuItemRefCon (menu, pos, (UInt32) wv->call_data); 2497 SetMenuItemRefCon (menu, pos, (UInt32) wv->call_data);
2426 } 2498 }
2427 2499
2428 if (submenu != NULL) 2500 if (submenu != 0)
2429 SetMenuItemHierarchicalID (menu, pos, submenu); 2501 SetMenuItemHierarchicalID (menu, pos, submenu);
2430} 2502}
2431 2503
@@ -2444,7 +2516,7 @@ fill_submenu (MenuHandle menu, widget_value *wv)
2444 add_menu_item (menu, wv, cur_submenu, 0); 2516 add_menu_item (menu, wv, cur_submenu, 0);
2445 } 2517 }
2446 else 2518 else
2447 add_menu_item (menu, wv, NULL, 0); 2519 add_menu_item (menu, wv, 0, 0);
2448} 2520}
2449 2521
2450 2522
@@ -2463,7 +2535,7 @@ fill_menu (MenuHandle menu, widget_value *wv)
2463 add_menu_item (menu, wv, cur_submenu, 0); 2535 add_menu_item (menu, wv, cur_submenu, 0);
2464 } 2536 }
2465 else 2537 else
2466 add_menu_item (menu, wv, NULL, 0); 2538 add_menu_item (menu, wv, 0, 0);
2467} 2539}
2468 2540
2469/* Construct native Mac OS menubar based on widget_value tree. */ 2541/* Construct native Mac OS menubar based on widget_value tree. */
@@ -2493,7 +2565,6 @@ fill_menubar (widget_value *wv)
2493} 2565}
2494 2566
2495#endif /* HAVE_MENUS */ 2567#endif /* HAVE_MENUS */
2496
2497 2568
2498void 2569void
2499syms_of_macmenu () 2570syms_of_macmenu ()
diff --git a/src/macterm.c b/src/macterm.c
index cbf7078cb25..614525440ec 100644
--- a/src/macterm.c
+++ b/src/macterm.c
@@ -68,7 +68,6 @@ Boston, MA 02110-1301, USA. */
68#include <errno.h> 68#include <errno.h>
69#include <setjmp.h> 69#include <setjmp.h>
70#include <sys/stat.h> 70#include <sys/stat.h>
71#include <sys/param.h>
72 71
73#include "charset.h" 72#include "charset.h"
74#include "coding.h" 73#include "coding.h"
@@ -259,7 +258,7 @@ static void x_scroll_bar_report_motion P_ ((struct frame **, Lisp_Object *,
259 unsigned long *)); 258 unsigned long *));
260 259
261static int is_emacs_window P_ ((WindowPtr)); 260static int is_emacs_window P_ ((WindowPtr));
262 261static XCharStruct *mac_per_char_metric P_ ((XFontStruct *, XChar2b *, int));
263static void XSetFont P_ ((Display *, GC, XFontStruct *)); 262static void XSetFont P_ ((Display *, GC, XFontStruct *));
264 263
265/* Defined in macmenu.h. */ 264/* Defined in macmenu.h. */
@@ -868,9 +867,159 @@ mac_draw_image_string_16 (f, gc, x, y, buf, nchars)
868} 867}
869 868
870 869
870/* Mac replacement for XQueryTextExtents, but takes a character. If
871 STYLE is NULL, measurement is done by QuickDraw Text routines for
872 the font of the current graphics port. If CG_GLYPH is not NULL,
873 *CG_GLYPH is set to the glyph ID or 0 if it cannot be obtained. */
874
875static OSErr
876mac_query_char_extents (style, c,
877 font_ascent_return, font_descent_return,
878 overall_return, cg_glyph)
879#if USE_ATSUI
880 ATSUStyle style;
881#else
882 void *style;
883#endif
884 int c;
885 int *font_ascent_return, *font_descent_return;
886 XCharStruct *overall_return;
871#if USE_CG_TEXT_DRAWING 887#if USE_CG_TEXT_DRAWING
872static XCharStruct *x_per_char_metric P_ ((XFontStruct *, XChar2b *)); 888 CGGlyph *cg_glyph;
889#else
890 void *cg_glyph;
891#endif
892{
893 OSErr err = noErr;
894 int width;
895 Rect char_bounds;
896
897#if USE_ATSUI
898 if (style)
899 {
900 ATSUTextLayout text_layout;
901 UniChar ch = c;
902
903 err = atsu_get_text_layout_with_text_ptr (&ch, 1, style, &text_layout);
904 if (err == noErr)
905 {
906 ATSTrapezoid glyph_bounds;
907
908 err = ATSUGetGlyphBounds (text_layout, 0, 0,
909 kATSUFromTextBeginning, kATSUToTextEnd,
910#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
911 kATSUseFractionalOrigins,
912#else
913 kATSUseDeviceOrigins,
914#endif
915 1, &glyph_bounds, NULL);
916 if (err == noErr)
917 {
918 xassert (glyph_bounds.lowerRight.x - glyph_bounds.lowerLeft.x
919 == glyph_bounds.upperRight.x - glyph_bounds.upperLeft.x);
920
921 width = Fix2Long (glyph_bounds.upperRight.x
922 - glyph_bounds.upperLeft.x);
923 if (font_ascent_return)
924 *font_ascent_return = -Fix2Long (glyph_bounds.upperLeft.y);
925 if (font_descent_return)
926 *font_descent_return = Fix2Long (glyph_bounds.lowerLeft.y);
927 }
928 }
929 if (err == noErr && overall_return)
930 {
931 err = ATSUMeasureTextImage (text_layout,
932 kATSUFromTextBeginning, kATSUToTextEnd,
933 0, 0, &char_bounds);
934 if (err == noErr)
935 STORE_XCHARSTRUCT (*overall_return, width, char_bounds);
936#if USE_CG_TEXT_DRAWING
937 if (err == noErr && cg_glyph)
938 {
939 OSErr err1;
940 ATSUGlyphInfoArray glyph_info_array;
941 ByteCount count = sizeof (ATSUGlyphInfoArray);
942
943 err1 = ATSUMatchFontsToText (text_layout, kATSUFromTextBeginning,
944 kATSUToTextEnd, NULL, NULL, NULL);
945 if (err1 == noErr)
946 err1 = ATSUGetGlyphInfo (text_layout, kATSUFromTextBeginning,
947 kATSUToTextEnd, &count,
948 &glyph_info_array);
949 if (err1 == noErr)
950 {
951 xassert (glyph_info_array.glyphs[0].glyphID);
952 *cg_glyph = glyph_info_array.glyphs[0].glyphID;
953 }
954 else
955 *cg_glyph = 0;
956 }
957#endif
958 }
959 }
960 else
961#endif
962 {
963 if (font_ascent_return || font_descent_return)
964 {
965 FontInfo font_info;
966
967 GetFontInfo (&font_info);
968 if (font_ascent_return)
969 *font_ascent_return = font_info.ascent;
970 if (font_descent_return)
971 *font_descent_return = font_info.descent;
972 }
973 if (overall_return)
974 {
975 char ch = c;
976
977 width = CharWidth (ch);
978 QDTextBounds (1, &ch, &char_bounds);
979 STORE_XCHARSTRUCT (*overall_return, width, char_bounds);
980 }
981 }
982
983 return err;
984}
985
986
987/* Mac replacement for XTextExtents16. Only sets horizontal metrics. */
988
989static int
990mac_text_extents_16 (font_struct, string, nchars, overall_return)
991 XFontStruct *font_struct;
992 XChar2b *string;
993 int nchars;
994 XCharStruct *overall_return;
995{
996 int i;
997 short width = 0, lbearing = 0, rbearing = 0;
998 XCharStruct *pcm;
999
1000 for (i = 0; i < nchars; i++)
1001 {
1002 pcm = mac_per_char_metric (font_struct, string, 0);
1003 if (pcm == NULL)
1004 width += FONT_WIDTH (font_struct);
1005 else
1006 {
1007 lbearing = min (lbearing, width + pcm->lbearing);
1008 rbearing = max (rbearing, width + pcm->rbearing);
1009 width += pcm->width;
1010 }
1011 string++;
1012 }
1013
1014 overall_return->lbearing = lbearing;
1015 overall_return->rbearing = rbearing;
1016 overall_return->width = width;
1017
1018 /* What's the meaning of the return value of XTextExtents16? */
1019}
873 1020
1021
1022#if USE_CG_TEXT_DRAWING
874static int cg_text_anti_aliasing_threshold = 8; 1023static int cg_text_anti_aliasing_threshold = 8;
875 1024
876static void 1025static void
@@ -910,7 +1059,9 @@ mac_draw_string_cg (f, gc, x, y, buf, nchars)
910 advances = xmalloc (sizeof (CGSize) * nchars); 1059 advances = xmalloc (sizeof (CGSize) * nchars);
911 for (i = 0; i < nchars; i++) 1060 for (i = 0; i < nchars; i++)
912 { 1061 {
913 advances[i].width = x_per_char_metric (GC_FONT (gc), buf)->width; 1062 XCharStruct *pcm = mac_per_char_metric (GC_FONT (gc), buf, 0);
1063
1064 advances[i].width = pcm->width;
914 advances[i].height = 0; 1065 advances[i].height = 0;
915 glyphs[i] = GC_FONT (gc)->cg_glyphs[buf->byte2]; 1066 glyphs[i] = GC_FONT (gc)->cg_glyphs[buf->byte2];
916 buf++; 1067 buf++;
@@ -1724,63 +1875,32 @@ x_per_char_metric (font, char2b)
1724#if USE_ATSUI 1875#if USE_ATSUI
1725 if (font->mac_style) 1876 if (font->mac_style)
1726 { 1877 {
1727 if (char2b->byte1 >= font->min_byte1 1878 XCharStructRow **row = font->bounds.rows + char2b->byte1;
1728 && char2b->byte1 <= font->max_byte1 1879
1729 && char2b->byte2 >= font->min_char_or_byte2 1880 if (*row == NULL)
1730 && char2b->byte2 <= font->max_char_or_byte2)
1731 { 1881 {
1732 pcm = (font->per_char 1882 *row = xmalloc (sizeof (XCharStructRow));
1733 + ((font->max_char_or_byte2 - font->min_char_or_byte2 + 1) 1883 if (*row)
1734 * (char2b->byte1 - font->min_byte1)) 1884 bzero (*row, sizeof (XCharStructRow));
1735 + (char2b->byte2 - font->min_char_or_byte2));
1736 } 1885 }
1737 1886 if (*row)
1738 if (pcm && !pcm->valid_p)
1739 { 1887 {
1740 OSErr err; 1888 pcm = (*row)->per_char + char2b->byte2;
1741 ATSUTextLayout text_layout; 1889 if (!XCHARSTRUCTROW_CHAR_VALID_P (*row, char2b->byte2))
1742 UniChar c;
1743 int char_width;
1744 ATSTrapezoid glyph_bounds;
1745 Rect char_bounds;
1746
1747 c = (char2b->byte1 << 8) + char2b->byte2;
1748 BLOCK_INPUT;
1749 err = atsu_get_text_layout_with_text_ptr (&c, 1,
1750 font->mac_style,
1751 &text_layout);
1752 if (err == noErr)
1753 err = ATSUMeasureTextImage (text_layout,
1754 kATSUFromTextBeginning, kATSUToTextEnd,
1755 0, 0, &char_bounds);
1756
1757 if (err == noErr)
1758 err = ATSUGetGlyphBounds (text_layout, 0, 0,
1759 kATSUFromTextBeginning, kATSUToTextEnd,
1760#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
1761 kATSUseFractionalOrigins,
1762#else
1763 kATSUseDeviceOrigins,
1764#endif
1765 1, &glyph_bounds, NULL);
1766 UNBLOCK_INPUT;
1767 if (err != noErr)
1768 pcm = NULL;
1769 else
1770 { 1890 {
1771 xassert (glyph_bounds.lowerRight.x - glyph_bounds.lowerLeft.x 1891 BLOCK_INPUT;
1772 == glyph_bounds.upperRight.x - glyph_bounds.upperLeft.x); 1892 mac_query_char_extents (font->mac_style,
1773 1893 (char2b->byte1 << 8) + char2b->byte2,
1774 char_width = Fix2Long (glyph_bounds.upperRight.x 1894 NULL, NULL, pcm, NULL);
1775 - glyph_bounds.upperLeft.x); 1895 UNBLOCK_INPUT;
1776 STORE_XCHARSTRUCT (*pcm, char_width, char_bounds); 1896 XCHARSTRUCTROW_SET_CHAR_VALID (*row, char2b->byte2);
1777 } 1897 }
1778 } 1898 }
1779 } 1899 }
1780 else 1900 else
1781 { 1901 {
1782#endif 1902#endif
1783 if (font->per_char != NULL) 1903 if (font->bounds.per_char != NULL)
1784 { 1904 {
1785 if (font->min_byte1 == 0 && font->max_byte1 == 0) 1905 if (font->min_byte1 == 0 && font->max_byte1 == 0)
1786 { 1906 {
@@ -1793,7 +1913,8 @@ x_per_char_metric (font, char2b)
1793 if (char2b->byte1 == 0 1913 if (char2b->byte1 == 0
1794 && char2b->byte2 >= font->min_char_or_byte2 1914 && char2b->byte2 >= font->min_char_or_byte2
1795 && char2b->byte2 <= font->max_char_or_byte2) 1915 && char2b->byte2 <= font->max_char_or_byte2)
1796 pcm = font->per_char + char2b->byte2 - font->min_char_or_byte2; 1916 pcm = font->bounds.per_char
1917 + (char2b->byte2 - font->min_char_or_byte2);
1797 } 1918 }
1798 else 1919 else
1799 { 1920 {
@@ -1815,7 +1936,7 @@ x_per_char_metric (font, char2b)
1815 && char2b->byte2 >= font->min_char_or_byte2 1936 && char2b->byte2 >= font->min_char_or_byte2
1816 && char2b->byte2 <= font->max_char_or_byte2) 1937 && char2b->byte2 <= font->max_char_or_byte2)
1817 { 1938 {
1818 pcm = (font->per_char 1939 pcm = (font->bounds.per_char
1819 + ((font->max_char_or_byte2 - font->min_char_or_byte2 + 1) 1940 + ((font->max_char_or_byte2 - font->min_char_or_byte2 + 1)
1820 * (char2b->byte1 - font->min_byte1)) 1941 * (char2b->byte1 - font->min_byte1))
1821 + (char2b->byte2 - font->min_char_or_byte2)); 1942 + (char2b->byte2 - font->min_char_or_byte2));
@@ -2157,67 +2278,32 @@ mac_compute_glyph_string_overhangs (s)
2157{ 2278{
2158 if (s->cmp == NULL 2279 if (s->cmp == NULL
2159 && s->first_glyph->type == CHAR_GLYPH) 2280 && s->first_glyph->type == CHAR_GLYPH)
2160 { 2281 if (!s->two_byte_p
2161 Rect r;
2162 MacFontStruct *font = s->font;
2163
2164#if USE_ATSUI 2282#if USE_ATSUI
2165 if (font->mac_style) 2283 || s->font->mac_style
2166 { 2284#endif
2167 OSErr err; 2285 )
2168 ATSUTextLayout text_layout; 2286 {
2169 UniChar *buf; 2287 XCharStruct cs;
2170 int i;
2171 2288
2172 SetRect (&r, 0, 0, 0, 0); 2289 mac_text_extents_16 (s->font, s->char2b, s->nchars, &cs);
2173 buf = xmalloc (sizeof (UniChar) * s->nchars); 2290 s->right_overhang = cs.rbearing > cs.width ? cs.rbearing - cs.width : 0;
2174 if (buf) 2291 s->left_overhang = cs.lbearing < 0 ? -cs.lbearing : 0;
2175 { 2292 }
2176 for (i = 0; i < s->nchars; i++) 2293 else
2177 buf[i] = (s->char2b[i].byte1 << 8) + s->char2b[i].byte2; 2294 {
2295 Rect r;
2296 MacFontStruct *font = s->font;
2178 2297
2179 err = atsu_get_text_layout_with_text_ptr (buf, s->nchars, 2298 TextFont (font->mac_fontnum);
2180 font->mac_style, 2299 TextSize (font->mac_fontsize);
2181 &text_layout); 2300 TextFace (font->mac_fontface);
2182 if (err == noErr)
2183 err = ATSUMeasureTextImage (text_layout,
2184 kATSUFromTextBeginning,
2185 kATSUToTextEnd,
2186 0, 0, &r);
2187 xfree (buf);
2188 }
2189 }
2190 else
2191 {
2192#endif
2193 TextFont (font->mac_fontnum);
2194 TextSize (font->mac_fontsize);
2195 TextFace (font->mac_fontface);
2196 2301
2197 if (s->two_byte_p)
2198 QDTextBounds (s->nchars * 2, (char *)s->char2b, &r); 2302 QDTextBounds (s->nchars * 2, (char *)s->char2b, &r);
2199 else
2200 {
2201 int i;
2202 char *buf = xmalloc (s->nchars);
2203 2303
2204 if (buf == NULL) 2304 s->right_overhang = r.right > s->width ? r.right - s->width : 0;
2205 SetRect (&r, 0, 0, 0, 0); 2305 s->left_overhang = r.left < 0 ? -r.left : 0;
2206 else 2306 }
2207 {
2208 for (i = 0; i < s->nchars; ++i)
2209 buf[i] = s->char2b[i].byte2;
2210 QDTextBounds (s->nchars, buf, &r);
2211 xfree (buf);
2212 }
2213 }
2214#if USE_ATSUI
2215 }
2216#endif
2217
2218 s->right_overhang = r.right > s->width ? r.right - s->width : 0;
2219 s->left_overhang = r.left < 0 ? -r.left : 0;
2220 }
2221} 2307}
2222 2308
2223 2309
@@ -7375,7 +7461,7 @@ is_fully_specified_xlfd (char *p)
7375static MacFontStruct * 7461static MacFontStruct *
7376XLoadQueryFont (Display *dpy, char *fontname) 7462XLoadQueryFont (Display *dpy, char *fontname)
7377{ 7463{
7378 int i, size, char_width; 7464 int size;
7379 char *name; 7465 char *name;
7380 Str255 family; 7466 Str255 family;
7381 Str31 charset; 7467 Str31 charset;
@@ -7392,6 +7478,7 @@ XLoadQueryFont (Display *dpy, char *fontname)
7392 short scriptcode; 7478 short scriptcode;
7393#endif 7479#endif
7394 MacFontStruct *font; 7480 MacFontStruct *font;
7481 XCharStruct *space_bounds = NULL, *pcm;
7395 7482
7396 if (is_fully_specified_xlfd (fontname)) 7483 if (is_fully_specified_xlfd (fontname))
7397 name = fontname; 7484 name = fontname;
@@ -7488,19 +7575,27 @@ XLoadQueryFont (Display *dpy, char *fontname)
7488 if (font->mac_style) 7575 if (font->mac_style)
7489 { 7576 {
7490 OSErr err; 7577 OSErr err;
7491 ATSUTextLayout text_layout; 7578 UniChar c;
7492 UniChar c = 0x20;
7493 Rect char_bounds, min_bounds, max_bounds;
7494 int min_width, max_width;
7495 ATSTrapezoid glyph_bounds;
7496 7579
7497 font->per_char = xmalloc (sizeof (XCharStruct) * 0x10000); 7580 font->min_byte1 = 0;
7498 if (font->per_char == NULL) 7581 font->max_byte1 = 0xff;
7582 font->min_char_or_byte2 = 0;
7583 font->max_char_or_byte2 = 0xff;
7584
7585 font->bounds.rows = xmalloc (sizeof (XCharStructRow *) * 0x100);
7586 if (font->bounds.rows == NULL)
7499 { 7587 {
7500 mac_unload_font (&one_mac_display_info, font); 7588 mac_unload_font (&one_mac_display_info, font);
7501 return NULL; 7589 return NULL;
7502 } 7590 }
7503 bzero (font->per_char, sizeof (XCharStruct) * 0x10000); 7591 bzero (font->bounds.rows, sizeof (XCharStructRow *) * 0x100);
7592 font->bounds.rows[0] = xmalloc (sizeof (XCharStructRow));
7593 if (font->bounds.rows[0] == NULL)
7594 {
7595 mac_unload_font (&one_mac_display_info, font);
7596 return NULL;
7597 }
7598 bzero (font->bounds.rows[0], sizeof (XCharStructRow));
7504 7599
7505#if USE_CG_TEXT_DRAWING 7600#if USE_CG_TEXT_DRAWING
7506 { 7601 {
@@ -7525,108 +7620,58 @@ XLoadQueryFont (Display *dpy, char *fontname)
7525 if (font->cg_glyphs) 7620 if (font->cg_glyphs)
7526 bzero (font->cg_glyphs, sizeof (CGGlyph) * 0x100); 7621 bzero (font->cg_glyphs, sizeof (CGGlyph) * 0x100);
7527#endif 7622#endif
7528 7623 space_bounds = font->bounds.rows[0]->per_char + 0x20;
7529 err = atsu_get_text_layout_with_text_ptr (&c, 1, 7624 err = mac_query_char_extents (font->mac_style, 0x20,
7530 font->mac_style, 7625 &font->ascent, &font->descent,
7531 &text_layout); 7626 space_bounds,
7627#if USE_CG_TEXT_DRAWING
7628 (font->cg_glyphs ? font->cg_glyphs + 0x20
7629 : NULL)
7630#else
7631 NULL
7632#endif
7633 );
7532 if (err != noErr) 7634 if (err != noErr)
7533 { 7635 {
7534 mac_unload_font (&one_mac_display_info, font); 7636 mac_unload_font (&one_mac_display_info, font);
7535 return NULL; 7637 return NULL;
7536 } 7638 }
7639 XCHARSTRUCTROW_SET_CHAR_VALID (font->bounds.rows[0], 0x20);
7537 7640
7538 for (c = 0x20; c <= 0xff; c++) 7641 pcm = font->bounds.rows[0]->per_char;
7642 for (c = 0x21; c <= 0xff; c++)
7539 { 7643 {
7540 if (c == 0xad) 7644 if (c == 0xad)
7541 /* Soft hyphen is not supported in ATSUI. */ 7645 /* Soft hyphen is not supported in ATSUI. */
7542 continue; 7646 continue;
7543 else if (c == 0x7f) 7647 else if (c == 0x7f)
7544 { 7648 {
7545 STORE_XCHARSTRUCT (font->min_bounds, min_width, min_bounds);
7546 STORE_XCHARSTRUCT (font->max_bounds, max_width, max_bounds);
7547 c = 0x9f; 7649 c = 0x9f;
7548 continue; 7650 continue;
7549 } 7651 }
7550 7652
7551 err = ATSUClearLayoutCache (text_layout, kATSUFromTextBeginning); 7653 mac_query_char_extents (font->mac_style, c, NULL, NULL, pcm + c,
7552 if (err == noErr) 7654#if USE_CG_TEXT_DRAWING
7553 err = ATSUMeasureTextImage (text_layout, 7655 (font->cg_glyphs ? font->cg_glyphs + c
7554 kATSUFromTextBeginning, kATSUToTextEnd, 7656 : NULL)
7555 0, 0, &char_bounds);
7556 if (err == noErr)
7557 err = ATSUGetGlyphBounds (text_layout, 0, 0,
7558 kATSUFromTextBeginning, kATSUToTextEnd,
7559#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
7560 kATSUseFractionalOrigins,
7561#else 7657#else
7562 kATSUseDeviceOrigins, 7658 NULL
7563#endif 7659#endif
7564 1, &glyph_bounds, NULL); 7660 );
7565 if (err == noErr) 7661 XCHARSTRUCTROW_SET_CHAR_VALID (font->bounds.rows[0], c);
7566 {
7567 xassert (glyph_bounds.lowerRight.x - glyph_bounds.lowerLeft.x
7568 == glyph_bounds.upperRight.x - glyph_bounds.upperLeft.x);
7569 7662
7570 char_width = Fix2Long (glyph_bounds.upperRight.x
7571 - glyph_bounds.upperLeft.x);
7572 STORE_XCHARSTRUCT (font->per_char[c],
7573 char_width, char_bounds);
7574 if (c == 0x20)
7575 {
7576 min_width = max_width = char_width;
7577 min_bounds = max_bounds = char_bounds;
7578 font->ascent = -Fix2Long (glyph_bounds.upperLeft.y);
7579 font->descent = Fix2Long (glyph_bounds.lowerLeft.y);
7580 }
7581 else
7582 {
7583 if (char_width > 0)
7584 {
7585 min_width = min (min_width, char_width);
7586 max_width = max (max_width, char_width);
7587 }
7588 if (!EmptyRect (&char_bounds))
7589 {
7590 SetRect (&min_bounds,
7591 max (min_bounds.left, char_bounds.left),
7592 max (min_bounds.top, char_bounds.top),
7593 min (min_bounds.right, char_bounds.right),
7594 min (min_bounds.bottom, char_bounds.bottom));
7595 UnionRect (&max_bounds, &char_bounds, &max_bounds);
7596 }
7597 }
7598 }
7599#if USE_CG_TEXT_DRAWING 7663#if USE_CG_TEXT_DRAWING
7600 if (err == noErr && char_width > 0 && font->cg_font) 7664 if (font->cg_glyphs && font->cg_glyphs[c] == 0)
7601 { 7665 {
7602 ATSUGlyphInfoArray glyph_info_array; 7666 /* Don't use CG text drawing if font substitution occurs in
7603 ByteCount count = sizeof (ATSUGlyphInfoArray); 7667 ASCII or Latin-1 characters. */
7604 7668 CGFontRelease (font->cg_font);
7605 err = ATSUMatchFontsToText (text_layout, kATSUFromTextBeginning, 7669 font->cg_font = NULL;
7606 kATSUToTextEnd, NULL, NULL, NULL); 7670 xfree (font->cg_glyphs);
7607 if (err == noErr) 7671 font->cg_glyphs = NULL;
7608 err = ATSUGetGlyphInfo (text_layout, kATSUFromTextBeginning,
7609 kATSUToTextEnd, &count,
7610 &glyph_info_array);
7611 if (err == noErr)
7612 font->cg_glyphs[c] = glyph_info_array.glyphs[0].glyphID;
7613 else
7614 {
7615 /* Don't use CG text drawing if font substitution
7616 occurs in ASCII or Latin-1 characters. */
7617 CGFontRelease (font->cg_font);
7618 font->cg_font = NULL;
7619 xfree (font->cg_glyphs);
7620 font->cg_glyphs = NULL;
7621 }
7622 } 7672 }
7623#endif 7673#endif
7624 } 7674 }
7625
7626 font->min_byte1 = 0;
7627 font->max_byte1 = 0xff;
7628 font->min_char_or_byte2 = 0;
7629 font->max_char_or_byte2 = 0xff;
7630 } 7675 }
7631 else 7676 else
7632#endif 7677#endif
@@ -7665,6 +7710,8 @@ XLoadQueryFont (Display *dpy, char *fontname)
7665 7710
7666 if (is_two_byte_font) 7711 if (is_two_byte_font)
7667 { 7712 {
7713 int char_width;
7714
7668 font->min_byte1 = 0xa1; 7715 font->min_byte1 = 0xa1;
7669 font->max_byte1 = 0xfe; 7716 font->max_byte1 = 0xfe;
7670 font->min_char_or_byte2 = 0xa1; 7717 font->min_char_or_byte2 = 0xa1;
@@ -7693,21 +7740,8 @@ XLoadQueryFont (Display *dpy, char *fontname)
7693 char_width = StringWidth("\p\xa1\xa1"); 7740 char_width = StringWidth("\p\xa1\xa1");
7694 break; 7741 break;
7695 } 7742 }
7696 }
7697 else
7698 {
7699 font->min_byte1 = font->max_byte1 = 0;
7700 font->min_char_or_byte2 = 0x20;
7701 font->max_char_or_byte2 = 0xff;
7702 7743
7703 /* Do this instead of use the_fontinfo.widMax, which 7744 font->bounds.per_char = NULL;
7704 incorrectly returns 15 for 12-point Monaco! */
7705 char_width = CharWidth ('m');
7706 }
7707
7708 if (is_two_byte_font)
7709 {
7710 font->per_char = NULL;
7711 7745
7712 if (fontface & italic) 7746 if (fontface & italic)
7713 font->max_bounds.rbearing = char_width + 1; 7747 font->max_bounds.rbearing = char_width + 1;
@@ -7722,54 +7756,28 @@ XLoadQueryFont (Display *dpy, char *fontname)
7722 } 7756 }
7723 else 7757 else
7724 { 7758 {
7725 int c, min_width, max_width; 7759 int c;
7726 Rect char_bounds, min_bounds, max_bounds;
7727 char ch;
7728
7729 font->per_char = xmalloc (sizeof (XCharStruct) * (0xff - 0x20 + 1));
7730 bzero (font->per_char, sizeof (XCharStruct) * (0xff - 0x20 + 1));
7731 7760
7732 min_width = max_width = char_width; 7761 font->min_byte1 = font->max_byte1 = 0;
7733 SetRect (&min_bounds, -32767, -32767, 32767, 32767); 7762 font->min_char_or_byte2 = 0x20;
7734 SetRect (&max_bounds, 0, 0, 0, 0); 7763 font->max_char_or_byte2 = 0xff;
7735 for (c = 0x20; c <= 0xff; c++)
7736 {
7737 if (c == 0x7f)
7738 {
7739 STORE_XCHARSTRUCT (font->min_bounds, min_width, min_bounds);
7740 STORE_XCHARSTRUCT (font->max_bounds, max_width, max_bounds);
7741 continue;
7742 }
7743 7764
7744 ch = c; 7765 font->bounds.per_char =
7745 char_width = CharWidth (ch); 7766 xmalloc (sizeof (XCharStruct) * (0xff - 0x20 + 1));
7746 QDTextBounds (1, &ch, &char_bounds); 7767 if (font->bounds.per_char == NULL)
7747 STORE_XCHARSTRUCT (font->per_char[c - 0x20],
7748 char_width, char_bounds);
7749 /* Some Japanese fonts (in SJIS encoding) return 0 as
7750 the character width of 0x7f. */
7751 if (char_width > 0)
7752 {
7753 min_width = min (min_width, char_width);
7754 max_width = max (max_width, char_width);
7755 }
7756 if (!EmptyRect (&char_bounds))
7757 {
7758 SetRect (&min_bounds,
7759 max (min_bounds.left, char_bounds.left),
7760 max (min_bounds.top, char_bounds.top),
7761 min (min_bounds.right, char_bounds.right),
7762 min (min_bounds.bottom, char_bounds.bottom));
7763 UnionRect (&max_bounds, &char_bounds, &max_bounds);
7764 }
7765 }
7766 if (min_width == max_width
7767 && max_bounds.left >= 0 && max_bounds.right <= max_width)
7768 { 7768 {
7769 /* Fixed width and no overhangs. */ 7769 mac_unload_font (&one_mac_display_info, font);
7770 xfree (font->per_char); 7770 return NULL;
7771 font->per_char = NULL;
7772 } 7771 }
7772 bzero (font->bounds.per_char,
7773 sizeof (XCharStruct) * (0xff - 0x20 + 1));
7774
7775 space_bounds = font->bounds.per_char;
7776 mac_query_char_extents (NULL, 0x20, &font->ascent, &font->descent,
7777 space_bounds, NULL);
7778
7779 for (c = 0x21, pcm = space_bounds + 1; c <= 0xff; c++, pcm++)
7780 mac_query_char_extents (NULL, c, NULL, NULL, pcm, NULL);
7773 } 7781 }
7774 7782
7775 /* Restore previous font number, size and face. */ 7783 /* Restore previous font number, size and face. */
@@ -7778,6 +7786,46 @@ XLoadQueryFont (Display *dpy, char *fontname)
7778 TextFace (old_fontface); 7786 TextFace (old_fontface);
7779 } 7787 }
7780 7788
7789 if (space_bounds)
7790 {
7791 int c;
7792
7793 font->min_bounds = font->max_bounds = *space_bounds;
7794 for (c = 0x21, pcm = space_bounds + 1; c <= 0x7f; c++, pcm++)
7795 if (pcm->width > 0)
7796 {
7797 font->min_bounds.lbearing = min (font->min_bounds.lbearing,
7798 pcm->lbearing);
7799 font->min_bounds.rbearing = min (font->min_bounds.rbearing,
7800 pcm->rbearing);
7801 font->min_bounds.width = min (font->min_bounds.width,
7802 pcm->width);
7803 font->min_bounds.ascent = min (font->min_bounds.ascent,
7804 pcm->ascent);
7805
7806 font->max_bounds.lbearing = max (font->max_bounds.lbearing,
7807 pcm->lbearing);
7808 font->max_bounds.rbearing = max (font->max_bounds.rbearing,
7809 pcm->rbearing);
7810 font->max_bounds.width = max (font->max_bounds.width,
7811 pcm->width);
7812 font->max_bounds.ascent = max (font->max_bounds.ascent,
7813 pcm->ascent);
7814 }
7815 if (
7816#if USE_ATSUI
7817 font->mac_style == NULL &&
7818#endif
7819 font->max_bounds.width == font->min_bounds.width
7820 && font->min_bounds.lbearing >= 0
7821 && font->max_bounds.rbearing <= font->max_bounds.width)
7822 {
7823 /* Fixed width and no overhangs. */
7824 xfree (font->bounds.per_char);
7825 font->bounds.per_char = NULL;
7826 }
7827 }
7828
7781#if !defined (MAC_OS8) || USE_ATSUI 7829#if !defined (MAC_OS8) || USE_ATSUI
7782 /* AppKit and WebKit do some adjustment to the heights of Courier, 7830 /* AppKit and WebKit do some adjustment to the heights of Courier,
7783 Helvetica, and Times. This only works on the environments where 7831 Helvetica, and Times. This only works on the environments where
@@ -7797,18 +7845,27 @@ mac_unload_font (dpyinfo, font)
7797 XFontStruct *font; 7845 XFontStruct *font;
7798{ 7846{
7799 xfree (font->full_name); 7847 xfree (font->full_name);
7800 if (font->per_char)
7801 xfree (font->per_char);
7802#if USE_ATSUI 7848#if USE_ATSUI
7803 if (font->mac_style) 7849 if (font->mac_style)
7804 ATSUDisposeStyle (font->mac_style); 7850 {
7851 int i;
7852
7853 for (i = font->min_byte1; i <= font->max_byte1; i++)
7854 if (font->bounds.rows[i])
7855 xfree (font->bounds.rows[i]);
7856 xfree (font->bounds.rows);
7857 ATSUDisposeStyle (font->mac_style);
7858 }
7859 else
7860#endif
7861 if (font->bounds.per_char)
7862 xfree (font->bounds.per_char);
7805#if USE_CG_TEXT_DRAWING 7863#if USE_CG_TEXT_DRAWING
7806 if (font->cg_font) 7864 if (font->cg_font)
7807 CGFontRelease (font->cg_font); 7865 CGFontRelease (font->cg_font);
7808 if (font->cg_glyphs) 7866 if (font->cg_glyphs)
7809 xfree (font->cg_glyphs); 7867 xfree (font->cg_glyphs);
7810#endif 7868#endif
7811#endif
7812 xfree (font); 7869 xfree (font);
7813} 7870}
7814 7871
@@ -8143,6 +8200,7 @@ extern void init_apple_event_handler P_ ((void));
8143extern void mac_find_apple_event_spec P_ ((AEEventClass, AEEventID, 8200extern void mac_find_apple_event_spec P_ ((AEEventClass, AEEventID,
8144 Lisp_Object *, Lisp_Object *, 8201 Lisp_Object *, Lisp_Object *,
8145 Lisp_Object *)); 8202 Lisp_Object *));
8203extern OSErr init_coercion_handler P_ ((void));
8146 8204
8147#if TARGET_API_MAC_CARBON 8205#if TARGET_API_MAC_CARBON
8148/* Drag and Drop */ 8206/* Drag and Drop */
@@ -9149,25 +9207,25 @@ mac_do_receive_drag (WindowPtr window, void *handlerRefCon,
9149 result = GetFlavorFlags (theDrag, theItem, flavorTypeHFS, &theFlags); 9207 result = GetFlavorFlags (theDrag, theItem, flavorTypeHFS, &theFlags);
9150 if (result == noErr) 9208 if (result == noErr)
9151 { 9209 {
9152#ifdef MAC_OSX 9210 OSErr err;
9153 FSRef fref; 9211 AEDesc desc;
9154#endif
9155 char unix_path_name[MAXPATHLEN];
9156 9212
9157 GetFlavorData (theDrag, theItem, flavorTypeHFS, &data, &size, 0L); 9213 err = GetFlavorData (theDrag, theItem, flavorTypeHFS,
9158#ifdef MAC_OSX 9214 &data, &size, 0L);
9159 /* Use Carbon routines, otherwise it converts the file name 9215 if (err == noErr)
9160 to /Macintosh HD/..., which is not correct. */ 9216 err = AECoercePtr (typeFSS, &data.fileSpec, sizeof (FSSpec),
9161 FSpMakeFSRef (&data.fileSpec, &fref); 9217 TYPE_FILE_NAME, &desc);
9162 if (! FSRefMakePath (&fref, unix_path_name, sizeof (unix_path_name))); 9218 if (err == noErr)
9163#else 9219 {
9164 if (fsspec_to_posix_pathname (&data.fileSpec, unix_path_name, 9220 Lisp_Object file;
9165 sizeof (unix_path_name) - 1) == noErr) 9221
9166#endif 9222 /* x-dnd functions expect undecoded filenames. */
9167 /* x-dnd functions expect undecoded filenames. */ 9223 file = make_uninit_string (AEGetDescDataSize (&desc));
9168 file_list = Fcons (make_unibyte_string (unix_path_name, 9224 err = AEGetDescData (&desc, SDATA (file), SBYTES (file));
9169 strlen (unix_path_name)), 9225 if (err == noErr)
9170 file_list); 9226 file_list = Fcons (file, file_list);
9227 AEDisposeDesc (&desc);
9228 }
9171 } 9229 }
9172 } 9230 }
9173 /* If there are items in the list, construct an event and post it to 9231 /* If there are items in the list, construct an event and post it to
@@ -9259,6 +9317,8 @@ main (void)
9259 9317
9260 init_environ (); 9318 init_environ ();
9261 9319
9320 init_coercion_handler ();
9321
9262 initialize_applescript (); 9322 initialize_applescript ();
9263 9323
9264 init_apple_event_handler (); 9324 init_apple_event_handler ();
@@ -10648,6 +10708,8 @@ mac_initialize ()
10648#endif /* USE_CARBON_EVENTS */ 10708#endif /* USE_CARBON_EVENTS */
10649 10709
10650#ifdef MAC_OSX 10710#ifdef MAC_OSX
10711 init_coercion_handler ();
10712
10651 init_apple_event_handler (); 10713 init_apple_event_handler ();
10652 10714
10653 if (!inhibit_window_system) 10715 if (!inhibit_window_system)
diff --git a/src/macterm.h b/src/macterm.h
index 08c2f058cde..2f2ae26b3b3 100644
--- a/src/macterm.h
+++ b/src/macterm.h
@@ -322,9 +322,6 @@ struct mac_output {
322 /* Nonzero means menubar is currently active. */ 322 /* Nonzero means menubar is currently active. */
323 char menubar_active; 323 char menubar_active;
324 324
325 /* Nonzero means a menu command is being processed. */
326 char menu_command_in_progress;
327
328 /* Relief GCs, colors etc. */ 325 /* Relief GCs, colors etc. */
329 struct relief 326 struct relief
330 { 327 {
@@ -569,14 +566,14 @@ extern Lisp_Object mac_make_lispy_event_code P_ ((int));
569#define FONT_TYPE_FOR_UNIBYTE(font, ch) 0 566#define FONT_TYPE_FOR_UNIBYTE(font, ch) 0
570#define FONT_TYPE_FOR_MULTIBYTE(font, ch) 0 567#define FONT_TYPE_FOR_MULTIBYTE(font, ch) 0
571 568
569#define TYPE_FILE_NAME 'fNam'
570
572/* Defined in macselect.c */ 571/* Defined in macselect.c */
573 572
574extern void x_clear_frame_selections P_ ((struct frame *)); 573extern void x_clear_frame_selections P_ ((struct frame *));
575 574
576/* Defined in mac.c. */ 575/* Defined in mac.c. */
577 576
578extern OSErr posix_pathname_to_fsspec P_ ((const char *, FSSpec *));
579extern OSErr fsspec_to_posix_pathname P_ ((const FSSpec *, char *, int));
580extern void mac_clear_font_name_table P_ ((void)); 577extern void mac_clear_font_name_table P_ ((void));
581extern Lisp_Object mac_aedesc_to_lisp P_ ((AEDesc *)); 578extern Lisp_Object mac_aedesc_to_lisp P_ ((AEDesc *));
582#if TARGET_API_MAC_CARBON 579#if TARGET_API_MAC_CARBON
diff --git a/src/minibuf.c b/src/minibuf.c
index 8cc014f84ee..af7fa60aba4 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -2410,7 +2410,7 @@ during running `completion-setup-hook'. */)
2410 else 2410 else
2411 { 2411 {
2412 write_string ("Possible completions are:", -1); 2412 write_string ("Possible completions are:", -1);
2413 for (tail = completions, i = 0; !NILP (tail); tail = Fcdr (tail), i++) 2413 for (tail = completions, i = 0; CONSP (tail); tail = XCDR (tail), i++)
2414 { 2414 {
2415 Lisp_Object tem, string; 2415 Lisp_Object tem, string;
2416 int length; 2416 int length;
@@ -2418,7 +2418,7 @@ during running `completion-setup-hook'. */)
2418 2418
2419 startpos = Qnil; 2419 startpos = Qnil;
2420 2420
2421 elt = Fcar (tail); 2421 elt = XCAR (tail);
2422 if (SYMBOLP (elt)) 2422 if (SYMBOLP (elt))
2423 elt = SYMBOL_NAME (elt); 2423 elt = SYMBOL_NAME (elt);
2424 /* Compute the length of this element. */ 2424 /* Compute the length of this element. */
@@ -2594,9 +2594,21 @@ DEFUN ("minibuffer-completion-help", Fminibuffer_completion_help, Sminibuffer_co
2594 temp_echo_area_glyphs (build_string (" [No completions]")); 2594 temp_echo_area_glyphs (build_string (" [No completions]"));
2595 } 2595 }
2596 else 2596 else
2597 internal_with_output_to_temp_buffer ("*Completions*", 2597 {
2598 display_completion_list_1, 2598 /* Sort and remove duplicates. */
2599 Fsort (completions, Qstring_lessp)); 2599 Lisp_Object tmp = completions = Fsort (completions, Qstring_lessp);
2600 while (CONSP (tmp))
2601 {
2602 if (CONSP (XCDR (tmp))
2603 && !NILP (Fequal (XCAR (tmp), XCAR (XCDR (tmp)))))
2604 XSETCDR (tmp, XCDR (XCDR (tmp)));
2605 else
2606 tmp = XCDR (tmp);
2607 }
2608 internal_with_output_to_temp_buffer ("*Completions*",
2609 display_completion_list_1,
2610 completions);
2611 }
2600 return Qnil; 2612 return Qnil;
2601} 2613}
2602 2614
diff --git a/src/xfns.c b/src/xfns.c
index acd63125e87..2aa237ec549 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -5238,8 +5238,27 @@ Value is t if tooltip was open, nil otherwise. */)
5238 File selection dialog 5238 File selection dialog
5239 ***********************************************************************/ 5239 ***********************************************************************/
5240 5240
5241#ifdef USE_MOTIF 5241DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog,
5242 Sx_uses_old_gtk_dialog,
5243 0, 0, 0,
5244 doc: /* Return t if the old Gtk+ file selection dialog is used. */)
5245 ()
5246{
5247#ifdef USE_GTK
5248 extern int use_dialog_box;
5249 extern int use_file_dialog;
5242 5250
5251 if (use_dialog_box
5252 && use_file_dialog
5253 && have_menus_p ()
5254 && xg_uses_old_file_dialog ())
5255 return Qt;
5256#endif
5257 return Qnil;
5258}
5259
5260
5261#ifdef USE_MOTIF
5243/* Callback for "OK" and "Cancel" on file selection dialog. */ 5262/* Callback for "OK" and "Cancel" on file selection dialog. */
5244 5263
5245static void 5264static void
@@ -5859,6 +5878,7 @@ variable `use-file-dialog'. */);
5859 last_show_tip_args = Qnil; 5878 last_show_tip_args = Qnil;
5860 staticpro (&last_show_tip_args); 5879 staticpro (&last_show_tip_args);
5861 5880
5881 defsubr (&Sx_uses_old_gtk_dialog);
5862#if defined (USE_MOTIF) || defined (USE_GTK) 5882#if defined (USE_MOTIF) || defined (USE_GTK)
5863 defsubr (&Sx_file_dialog); 5883 defsubr (&Sx_file_dialog);
5864#endif 5884#endif
diff --git a/src/xmenu.c b/src/xmenu.c
index 36f95d911f0..70c07702cae 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -3388,6 +3388,11 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
3388 return Qnil; 3388 return Qnil;
3389 } 3389 }
3390 3390
3391 /* Don't GC while we prepare and show the menu,
3392 because we give the oldxmenu library pointers to the
3393 contents of strings. */
3394 inhibit_garbage_collection ();
3395
3391#ifdef HAVE_X_WINDOWS 3396#ifdef HAVE_X_WINDOWS
3392 /* Adjust coordinates to relative to the outer (window manager) window. */ 3397 /* Adjust coordinates to relative to the outer (window manager) window. */
3393 x += FRAME_OUTER_TO_INNER_DIFF_X (f); 3398 x += FRAME_OUTER_TO_INNER_DIFF_X (f);