aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorKaroly Lorentey2006-01-06 16:13:05 +0000
committerKaroly Lorentey2006-01-06 16:13:05 +0000
commita8bf7299ee74781dd485c33c5eac20aee0f0ebef (patch)
treed2bc1c0d3d7a64a19945b5bb5d175cae37088bca /lisp
parente079ecf45241cc5d2904db7ede9592f9861bb9aa (diff)
parent600bc46cd52fbdedf592158c6b03ccfca88dbade (diff)
downloademacs-a8bf7299ee74781dd485c33c5eac20aee0f0ebef.tar.gz
emacs-a8bf7299ee74781dd485c33c5eac20aee0f0ebef.zip
Merged from miles@gnu.org--gnu-2005 (patch 683-684)
Patches applied: * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-683 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-684 Update from CVS git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-493
Diffstat (limited to 'lisp')
-rw-r--r--lisp/ChangeLog218
-rw-r--r--lisp/Makefile.in8
-rw-r--r--lisp/cus-edit.el200
-rw-r--r--lisp/cus-face.el9
-rw-r--r--lisp/cus-theme.el353
-rw-r--r--lisp/custom.el640
-rw-r--r--lisp/emacs-lisp/bytecomp.el12
-rw-r--r--lisp/font-lock.el6
-rw-r--r--lisp/info.el17
-rw-r--r--lisp/language/ind-util.el2
-rw-r--r--lisp/language/mlm-util.el6
-rw-r--r--lisp/mh-e/ChangeLog115
-rw-r--r--lisp/mh-e/mh-alias.el11
-rw-r--r--lisp/mh-e/mh-comp.el95
-rw-r--r--lisp/mh-e/mh-customize.el93
-rw-r--r--lisp/mh-e/mh-e.el49
-rw-r--r--lisp/mh-e/mh-funcs.el30
-rw-r--r--lisp/mh-e/mh-identity.el4
-rw-r--r--lisp/mh-e/mh-index.el104
-rw-r--r--lisp/mh-e/mh-init.el49
-rw-r--r--lisp/mh-e/mh-junk.el83
-rw-r--r--lisp/mh-e/mh-mime.el60
-rw-r--r--lisp/mh-e/mh-pick.el105
-rw-r--r--lisp/mh-e/mh-seq.el48
-rw-r--r--lisp/mh-e/mh-utils.el20
-rw-r--r--lisp/mouse.el93
-rw-r--r--lisp/progmodes/flymake.el586
-rw-r--r--lisp/simple.el34
-rw-r--r--lisp/startup.el8
-rw-r--r--lisp/term/mac-win.el9
-rw-r--r--lisp/textmodes/flyspell.el10
-rw-r--r--lisp/textmodes/org.el545
-rw-r--r--lisp/url/ChangeLog22
-rw-r--r--lisp/url/url-cookie.el13
-rw-r--r--lisp/url/url-history.el82
-rw-r--r--lisp/wid-edit.el89
36 files changed, 2181 insertions, 1647 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 1050d3deb84..061ace7ec79 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,221 @@
12006-01-05 Bill Wohler <wohler@newt.com>
2
3 * Makefile.in (compile-always): Add mh-autoloads dependency.
4 (bootstrap): Remove mh-autoloads dependency, as compile dependency
5 provides it.
6 (updates): Remove mh-autoloads dependency, since it probably has
7 already run recently (via recompile).
8
92006-01-05 Stefan Monnier <monnier@iro.umontreal.ca>
10
11 * textmodes/flyspell.el (flyspell-accept-buffer-local-defs): Add an
12 argument `force' to disable the flyspell-last-buffer optimization.
13 (flyspell-mode-on): Use it.
14
15 * progmodes/flymake.el (flymake-get-cleanup-function): Default to
16 flymake-simple-cleanup.
17 (flymake-allowed-file-name-masks): Use this new default.
18 All the functions are now called in the right buffer rather than
19 passing the buffer as argument.
20 (flymake-process-sentinel): Switch to buffer before calling cleanup.
21 (flymake-parse-err-lines): Remove redundant buffer arg.
22 (flymake-get-program-dir): Comment out unused function.
23 (flymake-start-syntax-check, flymake-start-syntax-check-process):
24 Remove redundant buffer argument.
25 (flymake-get-real-file-name, flymake-simple-java-cleanup)
26 (flymake-simple-cleanup, flymake-master-cleanup): Remove buffer arg.
27
282006-01-05 Richard M. Stallman <rms@gnu.org>
29
30 * info.el (Info-find-node): Don't record previous node if have none.
31 (info): Go to directory only if history is empty.
32
33 * simple.el (mark): Doc fix.
34
352006-01-05 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
36
37 * term/mac-win.el (mac-ae-parameter): Don't coerce data if it is
38 already of desired type.
39 (mac-ae-list): Coerce parameter to "list" type.
40 (mac-dispatch-apple-event): Replace cadr part of event with a
41 dummy position so that event-start returns it.
42
432006-01-05 Carsten Dominik <dominik@science.uva.nl>
44
45 * textmodes/org.el: (org-end-of-subtree): New function.
46 (org-cycle, org-subtree-end-visible-p, org-scan-tags):
47 Use `org-end-of-subtree'.
48 (org-agenda, org-agenda-convert-date): Protect calls to
49 `fit-window-to-buffer'.
50 (org-tags-view): Force matching of sublevels when doing a
51 todo-only search. Define the correct redo command, including the
52 arguments.
53 (org-agenda-redo): Display message.
54 (org-check-for-org-mode): New function.
55 (org-agenda-type): New variable.
56 (org-timeline, org-agenda-list, org-todo-list, org-tags-view):
57 Set `org-agenda-type'.
58 (org-agenda-check-type): New function.
59 (org-agenda-goto-today, org-agenda-later, org-agenda-earlier)
60 (org-agenda-week-view, org-agenda-day-view)
61 (org-agenda-next-date-line, org-agenda-previous-date-line)
62 (org-agenda-log-mode, org-agenda-toggle-diary)
63 (org-agenda-toggle-time-grid, org-agenda-date-later)
64 (org-agenda-date-prompt, org-agenda-diary-entry)
65 (org-agenda-execute-calendar-command, org-agenda-goto-calendar)
66 (org-agenda-convert-date, org-agenda-menu):
67 Use `org-agenda-check-type'.
68 (org-make-overlay, org-delete-overlay)
69 (org-detatch-overlay, org-move-overlay, org-overlay-put):
70 New compatibility functions.
71 (org-calendar-select-mouse): New command.
72
732006-01-04 Chong Yidong <cyd@stupidchicken.com>
74
75 * cus-edit.el (Custom-reset-current, Custom-reset-saved)
76 (Custom-reset-standard): Fix y-or-n-p messages.
77 (custom-link): New face for links.
78 (custom-buffer-create-internal, custom-manual): Use it.
79 (custom-face-save): Push to theme-face before setting face spec.
80
81 * wid-edit.el (widget-default-mouse-face-get): New function.
82 (widget-specify-button): Handle mouse-face like button-face.
83
84 * custom.el (load-theme): Clear old theme settings if reloading.
85
862006-01-03 Luc Teirlinck <teirllm@auburn.edu>
87
88 * cus-edit.el (custom-buffer-create-internal): Move whole buffer
89 "Erase Customization" button back to same position it occupies in
90 the individual State menus.
91
922006-01-04 Kim F. Storm <storm@cua.dk>
93
94 * wid-edit.el (key-sequence): Rework widget to read key binding
95 using `kbd' syntax. Use C-q to insert literal key, event, or code.
96 (widget-key-sequence-default-value): Default value for empty sequence.
97 (widget-key-sequence-map): New map for reading key binding. Bind C-q.
98 (widget-key-sequence-read-event): New command for C-q.
99 (widget-key-sequence-validate, widget-key-sequence-value-to-internal)
100 (widget-key-sequence-value-to-external): New functions.
101
1022006-01-03 Stefan Monnier <monnier@iro.umontreal.ca>
103
104 * progmodes/flymake.el (flymake-create-temp-with-folder-structure):
105 Use expand-file-name.
106 (flymake-delete-temp-directory): Use expand-file-name,
107 file-name-directory, and directory-file-name.
108 (flymake-strrchr): Delete.
109 (flymake-start-syntax-check): Don't pass the redundant buffer argument
110 to the init-f function.
111 (flymake-save-buffer-in-file, flymake-init-create-temp-buffer-copy)
112 (flymake-init-find-buildfile-dir)
113 (flymake-init-create-temp-source-and-master-buffer-copy)
114 (flymake-simple-make-init-impl, flymake-simple-make-init)
115 (flymake-master-make-init, flymake-master-make-header-init)
116 (flymake-simple-make-java-init, flymake-simple-ant-java-init)
117 (flymake-perl-init, flymake-simple-tex-init, flymake-master-tex-init)
118 (flymake-xml-init): Remove corresponding redundant buffer argument.
119 (flymake-allowed-file-name-masks): Remove last elems that are equal to
120 the default anyway. Clean up regexps.
121
122 * progmodes/flymake.el (flymake-temp-source-file-name)
123 (flymake-master-file-name, flymake-temp-master-file-name)
124 (flymake-base-dir): New buffer-local vars.
125 (flymake-buffer-data, flymake-get-buffer-value)
126 (flymake-set-buffer-value): Replace those hash-tables by the new
127 buffer-local vars. Update callers.
128
129 * progmodes/flymake.el (flymake-check-start-time)
130 (flymake-check-was-interrupted, flymake-err-info, flymake-is-running)
131 (flymake-last-change-time, flymake-new-err-info, flymake-timer):
132 Move definition, so we can remove redundant earlier declaration.
133 (flymake-replace-regexp-in-string, flymake-split-string)
134 (flymake-get-temp-dir): Use defalias.
135 (flymake-popup-menu): Remove `pos' argument. Use posn-at-point.
136 (flymake-xemacs-window-edges): Remove unused function.
137 (flymake-get-point-pixel-pos): Move.
138 (flymake-pid-to-names, flymake-reg-names)
139 (flymake-get-source-buffer-name, flymake-unreg-names): Remove.
140 Replace by a simple list flymake-processes and by process-buffer.
141 Update callers. Other than simplify the code, it uses buffers rather
142 than buffer-names so it doesn't get confused by uniquify.
143 (flymake-buffer-data): The global value should just be nil.
144
145 * emacs-lisp/bytecomp.el (byte-compile-file-form-defalias):
146 Optimize the body of a defalias like any other code.
147
148 * font-lock.el (font-lock-fontify-buffer, font-lock-fontify-region):
149 Make sure we've setup font-lock's vars. It may influence which
150 function we then call.
151 (font-lock-default-fontify-buffer): Don't bother calling set-defaults
152 here since it's too late anyway.
153
1542006-01-03 Romain Francoise <romain@orebokech.com>
155
156 * startup.el (fancy-splash-tail, normal-splash-screen):
157 Update copyright year.
158
1592006-01-02 J.D. Smith <jdsmith@as.arizona.edu>
160
161 * mouse.el (mouse-drag-track): Rename, from
162 `mouse-drag-region-1'. Includes optional argument required to
163 enable post-drag event processing (e.g. delete region keys).
164 Can be used without this argument to track a mouse region and operate
165 on it as soon as the drag completes.
166 (mouse-drag-region): Use `mouse-drag-track'.
167
1682006-01-02 Chong Yidong <cyd@stupidchicken.com>
169
170 * cus-edit.el (custom-guess-name-alist, custom-guess-doc-alist):
171 Move to `custom-buffer' group.
172
173 * cus-theme.el: Rewrite the Custom New Theme Mode interface.
174 (custom-new-theme-mode-map, custom-theme-insert-variable-marker)
175 (custom-theme-insert-face-marker, custom-theme-variable-menu)
176 (custom-theme-face-menu): New variables.
177 (custom-theme-add-variable, custom-theme-variable-action)
178 (custom-variable-reset-theme, custom-theme-delete-variable)
179 (custom-face-reset-theme, custom-theme-face-action)
180 (custom-theme-delete-face, custom-theme-merge-theme)
181 (custom-theme-add-face, custom-theme-visit-theme): New functions.
182
1832006-01-01 Chong Yidong <cyd@stupidchicken.com>
184
185 * custom.el: Move Custom Themes commentary to start of theme code.
186 (custom-known-themes): Rename `standard' theme to `changed'.
187 (custom-push-theme): Caller no longer specifies what theme to use
188 when doing `reset'---the setting is simply removed from the theme.
189 Delete MODE from `theme-value' and `theme-settings' properties.
190 (custom-declare-theme): Ignore &rest args since we don't use them.
191
192 (custom-loaded-themes): Delete variable.
193 (custom-theme-load-themes, custom-theme-loaded-p)
194 (custom-theme-value): Delete functions.
195
196 (custom-declare-theme): Signal error on invalid theme names.
197 (provide-theme): custom-loaded-themes was deleted.
198 (load-theme): Load the file unconditionally.
199 (enable-theme): Call `load-theme' if theme is undefined.
200 (custom-enabled-themes): Only update value for successful loads.
201 (disable-theme): Complete from enabled themes when interactive.
202 (custom-variable-theme-value): Calculate theme value directly.
203
204 (custom-theme-reset-variables, custom-reset-variables): Mark as
205 XEmacs compatibility functions. We don't actually use these.
206
207 * cus-edit.el (custom-variable-state-set):
208 Use custom-variable-theme-value instead of custom-theme-value.
209 (custom-face-state-set): Rename `standard' theme to `changed'.
210 (custom-save-variables, custom-save-faces): Delete unneeded
211 references to custom-reset-variables.
212 (custom-save-resets): Delete function.
213 (custom-save-variables, custom-save-faces): MODE argument deleted.
214 (custom-save-variables, custom-save-faces): Ignore theme values.
215
216 * cus-face.el (custom-theme-reset-faces): Mark as XEmacs
217 compatibility function.
218
12006-01-01 Richard M. Stallman <rms@gnu.org> 2192006-01-01 Richard M. Stallman <rms@gnu.org>
2 220
3 * cus-edit.el (Custom-set, Custom-save): Ask for confirmation. 221 * cus-edit.el (Custom-set, Custom-save): Ask for confirmation.
diff --git a/lisp/Makefile.in b/lisp/Makefile.in
index 9a4497679ef..1cc34fcb663 100644
--- a/lisp/Makefile.in
+++ b/lisp/Makefile.in
@@ -1,5 +1,5 @@
1# Maintenance productions for the Lisp directory 1# Maintenance productions for the Lisp directory
2# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. 2# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
3 3
4# This file is part of GNU Emacs. 4# This file is part of GNU Emacs.
5 5
@@ -117,7 +117,7 @@ update-subdirs: doit
117 $(srcdir)/update-subdirs $$file; \ 117 $(srcdir)/update-subdirs $$file; \
118 done; 118 done;
119 119
120updates: update-subdirs autoloads mh-autoloads finder-data custom-deps 120updates: update-subdirs autoloads finder-data custom-deps
121 121
122# This is useful after "cvs up". 122# This is useful after "cvs up".
123cvs-update: recompile autoloads finder-data custom-deps 123cvs-update: recompile autoloads finder-data custom-deps
@@ -169,7 +169,7 @@ compile: $(lisp)/subdirs.el mh-autoloads doit
169# unconditionally. Some files don't actually get compiled because they 169# unconditionally. Some files don't actually get compiled because they
170# set the local variable no-byte-compile. 170# set the local variable no-byte-compile.
171 171
172compile-always: $(lisp)/subdirs.el doit 172compile-always: $(lisp)/subdirs.el mh-autoloads doit
173 # `|| true' prevents old Bash versions from getting confused 173 # `|| true' prevents old Bash versions from getting confused
174 # by an error. 174 # by an error.
175 find $(lisp) -name "*.elc" -print | xargs chmod +w >/dev/null 2>&1 || true; \ 175 find $(lisp) -name "*.elc" -print | xargs chmod +w >/dev/null 2>&1 || true; \
@@ -283,7 +283,7 @@ bootstrap-clean:
283 283
284# Generate/update files for the bootstrap process. 284# Generate/update files for the bootstrap process.
285 285
286bootstrap: update-subdirs autoloads mh-autoloads compile 286bootstrap: update-subdirs autoloads compile
287 287
288# Generate/update files after the bootstrap process. 288# Generate/update files after the bootstrap process.
289# custom-deps needs `preloaded-file-list'. 289# custom-deps needs `preloaded-file-list'.
diff --git a/lisp/cus-edit.el b/lisp/cus-edit.el
index 4c92034eaad..5a4b499d792 100644
--- a/lisp/cus-edit.el
+++ b/lisp/cus-edit.el
@@ -619,7 +619,7 @@ used.
619This is used for guessing the type of variables not declared with 619This is used for guessing the type of variables not declared with
620customize." 620customize."
621 :type '(repeat (group (regexp :tag "Match") (sexp :tag "Type"))) 621 :type '(repeat (group (regexp :tag "Match") (sexp :tag "Type")))
622 :group 'customize) 622 :group 'custom-buffer)
623 623
624(defcustom custom-guess-doc-alist 624(defcustom custom-guess-doc-alist
625 '(("\\`\\*?Non-nil " boolean)) 625 '(("\\`\\*?Non-nil " boolean))
@@ -633,7 +633,7 @@ matches the name of the symbol will be used.
633This is used for guessing the type of variables not declared with 633This is used for guessing the type of variables not declared with
634customize." 634customize."
635 :type '(repeat (group (regexp :tag "Match") (sexp :tag "Type"))) 635 :type '(repeat (group (regexp :tag "Match") (sexp :tag "Type")))
636 :group 'customize) 636 :group 'custom-buffer)
637 637
638(defun custom-guess-type (symbol) 638(defun custom-guess-type (symbol)
639 "Guess a widget suitable for editing the value of SYMBOL. 639 "Guess a widget suitable for editing the value of SYMBOL.
@@ -768,8 +768,8 @@ groups after non-groups, if nil do not order groups at all."
768 (message "Aborted"))) 768 (message "Aborted")))
769 769
770(defvar custom-reset-menu 770(defvar custom-reset-menu
771 '(("Current" . Custom-reset-current) 771 '(("Reset to current settings" . Custom-reset-current)
772 ("Saved" . Custom-reset-saved) 772 ("Reset to saved settings" . Custom-reset-saved)
773 ("Erase Customization (use standard values)" . Custom-reset-standard)) 773 ("Erase Customization (use standard values)" . Custom-reset-standard))
774 "Alist of actions for the `Reset' button. 774 "Alist of actions for the `Reset' button.
775The key is a string containing the name of the action, the value is a 775The key is a string containing the name of the action, the value is a
@@ -779,7 +779,7 @@ when the action is chosen.")
779(defun custom-reset (event) 779(defun custom-reset (event)
780 "Select item from reset menu." 780 "Select item from reset menu."
781 (let* ((completion-ignore-case t) 781 (let* ((completion-ignore-case t)
782 (answer (widget-choose "Reset to" 782 (answer (widget-choose "Reset settings"
783 custom-reset-menu 783 custom-reset-menu
784 event))) 784 event)))
785 (if answer 785 (if answer
@@ -788,7 +788,7 @@ when the action is chosen.")
788(defun Custom-reset-current (&rest ignore) 788(defun Custom-reset-current (&rest ignore)
789 "Reset all modified group members to their current value." 789 "Reset all modified group members to their current value."
790 (interactive) 790 (interactive)
791 (if (y-or-n-p "Update buffer text to show all current settings? ") 791 (if (y-or-n-p "Reset buffer to show current settings? ")
792 (let ((children custom-options)) 792 (let ((children custom-options))
793 (mapc (lambda (widget) 793 (mapc (lambda (widget)
794 (if (memq (widget-get widget :custom-state) 794 (if (memq (widget-get widget :custom-state)
@@ -800,7 +800,7 @@ when the action is chosen.")
800(defun Custom-reset-saved (&rest ignore) 800(defun Custom-reset-saved (&rest ignore)
801 "Reset all modified or set group members to their saved value." 801 "Reset all modified or set group members to their saved value."
802 (interactive) 802 (interactive)
803 (if (y-or-n-p "Update buffer text to show all saved settings? ") 803 (if (y-or-n-p "Reset all settings to saved values? ")
804 (let ((children custom-options)) 804 (let ((children custom-options))
805 (mapc (lambda (widget) 805 (mapc (lambda (widget)
806 (if (memq (widget-get widget :custom-state) 806 (if (memq (widget-get widget :custom-state)
@@ -819,7 +819,7 @@ making them as if they had never been customized at all."
819 (if (or (and (= 1 (length children)) 819 (if (or (and (= 1 (length children))
820 (memq (widget-type (car children)) 820 (memq (widget-type (car children))
821 '(custom-variable custom-face))) 821 '(custom-variable custom-face)))
822 (yes-or-no-p "Really erase all customizations in this buffer? ")) 822 (yes-or-no-p "Erase all customizations in this buffer? "))
823 (mapc (lambda (widget) 823 (mapc (lambda (widget)
824 (and (if (widget-get widget :custom-standard-value) 824 (and (if (widget-get widget :custom-standard-value)
825 (widget-apply widget :custom-standard-value) 825 (widget-apply widget :custom-standard-value)
@@ -1456,12 +1456,16 @@ See "
1456 "Square brackets indicate"))) 1456 "Square brackets indicate")))
1457 (widget-create 'info-link 1457 (widget-create 'info-link
1458 :tag "Custom file" 1458 :tag "Custom file"
1459 :button-face 'custom-link
1460 :mouse-face 'highlight
1459 "(emacs)Saving Customizations") 1461 "(emacs)Saving Customizations")
1460 (widget-insert 1462 (widget-insert
1461 " for information on how to save in a different file.\n 1463 " for information on how to save in a different file.\n
1462See ") 1464See ")
1463 (widget-create 'info-link 1465 (widget-create 'info-link
1464 :tag "Help" 1466 :tag "Help"
1467 :button-face 'custom-link
1468 :mouse-face 'highlight
1465 :help-echo "Read the online help." 1469 :help-echo "Read the online help."
1466 "(emacs)Easy Customization") 1470 "(emacs)Easy Customization")
1467 (widget-insert " for more information.\n\n") 1471 (widget-insert " for more information.\n\n")
@@ -1473,6 +1477,15 @@ See ")
1473Make your editing in this buffer take effect for this session." 1477Make your editing in this buffer take effect for this session."
1474 :action (lambda (widget &optional event) 1478 :action (lambda (widget &optional event)
1475 (Custom-set))) 1479 (Custom-set)))
1480 (if (not custom-buffer-verbose-help)
1481 (progn
1482 (widget-insert " ")
1483 (widget-create 'info-link
1484 :tag "Help"
1485 :button-face 'custom-link
1486 :mouse-face 'highlight
1487 :help-echo "Read the online help."
1488 "(emacs)Easy Customization")))
1476 (when (or custom-file user-init-file) 1489 (when (or custom-file user-init-file)
1477 (widget-insert " ") 1490 (widget-insert " ")
1478 (widget-create 'push-button 1491 (widget-create 'push-button
@@ -1486,18 +1499,11 @@ This updates your Emacs initialization file or creates a new one."
1486 (progn 1499 (progn
1487 (widget-insert " ") 1500 (widget-insert " ")
1488 (widget-create 'push-button 1501 (widget-create 'push-button
1489 :tag "Reset" 1502 :tag "Reset buffer"
1490 :help-echo "Show a menu with reset operations." 1503 :help-echo "Show a menu with reset operations."
1491 :mouse-down-action (lambda (&rest junk) t) 1504 :mouse-down-action (lambda (&rest junk) t)
1492 :action (lambda (widget &optional event) 1505 :action (lambda (widget &optional event)
1493 (custom-reset event)))) 1506 (custom-reset event))))
1494 (widget-insert " ")
1495 (when (or custom-file user-init-file)
1496 (widget-create 'push-button
1497 :tag "Erase Customization"
1498 :help-echo "\
1499Un-customize all settings in this buffer--save them with standard values."
1500 :action 'Custom-reset-standard)))
1501 (widget-insert "\n ") 1507 (widget-insert "\n ")
1502 (widget-create 'push-button 1508 (widget-create 'push-button
1503 :tag "Reset to Current" 1509 :tag "Reset to Current"
@@ -1510,13 +1516,13 @@ Reset all edited text in this buffer to reflect current values."
1510 :help-echo "\ 1516 :help-echo "\
1511Reset all settings in this buffer to their saved values." 1517Reset all settings in this buffer to their saved values."
1512 :action 'Custom-reset-saved) 1518 :action 'Custom-reset-saved)
1513 (if (not custom-buffer-verbose-help) 1519 (widget-insert " ")
1514 (progn 1520 (when (or custom-file user-init-file)
1515 (widget-insert " ") 1521 (widget-create 'push-button
1516 (widget-create 'info-link 1522 :tag "Erase Customization"
1517 :tag "Help" 1523 :help-echo "\
1518 :help-echo "Read the online help." 1524Un-customize all settings in this buffer and save them with standard values."
1519 "(emacs)Easy Customization"))) 1525 :action 'Custom-reset-standard)))
1520 (widget-insert " ") 1526 (widget-insert " ")
1521 (widget-create 'push-button 1527 (widget-create 'push-button
1522 :tag "Finish" 1528 :tag "Finish"
@@ -1701,6 +1707,8 @@ item in another window.\n\n"))
1701(define-widget 'custom-manual 'info-link 1707(define-widget 'custom-manual 'info-link
1702 "Link to the manual entry for this customization option." 1708 "Link to the manual entry for this customization option."
1703 :help-echo "Read the manual entry for this option." 1709 :help-echo "Read the manual entry for this option."
1710 :button-face 'custom-link
1711 :mouse-face 'highlight
1704 :tag "Manual") 1712 :tag "Manual")
1705 1713
1706;;; The `custom-magic' Widget. 1714;;; The `custom-magic' Widget.
@@ -2045,6 +2053,17 @@ and `face'."
2045;; backward-compatibility alias 2053;; backward-compatibility alias
2046(put 'custom-state-face 'face-alias 'custom-state) 2054(put 'custom-state-face 'face-alias 'custom-state)
2047 2055
2056(defface custom-link
2057 '((((min-colors 88)
2058 (class color) (background light)) :foreground "blue1" :underline t)
2059 (((class color) (background light)) :foreground "blue" :underline t)
2060 (((min-colors 88)
2061 (class color) (background dark)) :foreground "cyan1" :underline t)
2062 (((class color) (background dark)) :foreground "cyan" :underline t)
2063 (t :underline t))
2064 "Face for Info links in customization buffers."
2065 :group 'info)
2066
2048(define-widget 'custom 'default 2067(define-widget 'custom 'default
2049 "Customize a user option." 2068 "Customize a user option."
2050 :format "%v" 2069 :format "%v"
@@ -2207,6 +2226,8 @@ If INITIAL-STRING is non-nil, use that rather than \"Parent groups:\"."
2207 (insert " ") 2226 (insert " ")
2208 (push (widget-create-child-and-convert 2227 (push (widget-create-child-and-convert
2209 widget 'custom-group-link 2228 widget 'custom-group-link
2229 :button-face 'custom-link
2230 :mouse-face 'highlight
2210 :tag (custom-unlispify-tag-name symbol) 2231 :tag (custom-unlispify-tag-name symbol)
2211 symbol) 2232 symbol)
2212 buttons) 2233 buttons)
@@ -2578,15 +2599,13 @@ Otherwise, look up symbol in `custom-guess-type-alist'."
2578 (if (condition-case nil 2599 (if (condition-case nil
2579 (and (equal comment temp) 2600 (and (equal comment temp)
2580 (equal value 2601 (equal value
2581 (eval (car 2602 (eval
2582 (custom-theme-value 2603 (car (custom-variable-theme-value
2583 (caar tmp) tmp))))) 2604 symbol)))))
2584 (error nil)) 2605 (error nil))
2585 (cond 2606 (cond
2586 ((eq 'user (caar (get symbol 'theme-value))) 2607 ((eq (caar tmp) 'user) 'saved)
2587 'saved) 2608 ((eq (caar tmp) 'changed) 'changed)
2588 ((eq 'standard (caar (get symbol 'theme-value)))
2589 'changed)
2590 (t 'themed)) 2609 (t 'themed))
2591 'changed)) 2610 'changed))
2592 ((setq tmp (get symbol 'standard-value)) 2611 ((setq tmp (get symbol 'standard-value))
@@ -2603,39 +2622,40 @@ Otherwise, look up symbol in `custom-guess-type-alist'."
2603 (get (widget-value widget) 'standard-value)) 2622 (get (widget-value widget) 'standard-value))
2604 2623
2605(defvar custom-variable-menu 2624(defvar custom-variable-menu
2606 `(("Set for Current Session" custom-variable-set 2625 `(("Set for current session" custom-variable-set
2607 (lambda (widget) 2626 (lambda (widget)
2608 (eq (widget-get widget :custom-state) 'modified))) 2627 (eq (widget-get widget :custom-state) 'modified)))
2609 ,@(when (or custom-file user-init-file) 2628 ,@(when (or custom-file user-init-file)
2610 '(("Save for Future Sessions" custom-variable-save 2629 '(("Save for future sessions" custom-variable-save
2611 (lambda (widget) 2630 (lambda (widget)
2612 (memq (widget-get widget :custom-state) '(modified set changed rogue)))))) 2631 (memq (widget-get widget :custom-state)
2613 ("Reset to Current" custom-redraw 2632 '(modified set changed rogue))))))
2633 ("---" ignore ignore)
2634 ("Reset to current value" custom-redraw
2614 (lambda (widget) 2635 (lambda (widget)
2615 (and (default-boundp (widget-value widget)) 2636 (and (default-boundp (widget-value widget))
2616 (memq (widget-get widget :custom-state) '(modified changed))))) 2637 (memq (widget-get widget :custom-state) '(modified changed)))))
2617 ("Reset to Saved" custom-variable-reset-saved 2638 ("Reset to saved value" custom-variable-reset-saved
2618 (lambda (widget) 2639 (lambda (widget)
2619 (and (or (get (widget-value widget) 'saved-value) 2640 (and (or (get (widget-value widget) 'saved-value)
2620 (get (widget-value widget) 'saved-variable-comment)) 2641 (get (widget-value widget) 'saved-variable-comment))
2621 (memq (widget-get widget :custom-state) 2642 (memq (widget-get widget :custom-state)
2622 '(modified set changed rogue))))) 2643 '(modified set changed rogue)))))
2644 ("Reset to backup value" custom-variable-reset-backup
2645 (lambda (widget)
2646 (get (widget-value widget) 'backup-value)))
2623 ,@(when (or custom-file user-init-file) 2647 ,@(when (or custom-file user-init-file)
2624 '(("Erase Customization" custom-variable-reset-standard 2648 '(("Erase customization" custom-variable-reset-standard
2625 (lambda (widget) 2649 (lambda (widget)
2626 (and (get (widget-value widget) 'standard-value) 2650 (and (get (widget-value widget) 'standard-value)
2627 (memq (widget-get widget :custom-state) 2651 (memq (widget-get widget :custom-state)
2628 '(modified set changed saved rogue))))))) 2652 '(modified set changed saved rogue)))))))
2629 ("Use Backup Value" custom-variable-reset-backup
2630 (lambda (widget)
2631 (get (widget-value widget) 'backup-value)))
2632 ("---" ignore ignore) 2653 ("---" ignore ignore)
2633 ("Add Comment" custom-comment-show custom-comment-invisible-p) 2654 ("Add comment" custom-comment-show custom-comment-invisible-p)
2634 ("---" ignore ignore) 2655 ("Show value widget" custom-variable-edit
2635 ("Don't show as Lisp expression" custom-variable-edit
2636 (lambda (widget) 2656 (lambda (widget)
2637 (eq (widget-get widget :custom-form) 'lisp))) 2657 (eq (widget-get widget :custom-form) 'lisp)))
2638 ("Show initial Lisp expression" custom-variable-edit-lisp 2658 ("Show Lisp expression" custom-variable-edit-lisp
2639 (lambda (widget) 2659 (lambda (widget)
2640 (eq (widget-get widget :custom-form) 'edit)))) 2660 (eq (widget-get widget :custom-form) 'edit))))
2641 "Alist of actions for the `custom-variable' widget. 2661 "Alist of actions for the `custom-variable' widget.
@@ -2772,7 +2792,7 @@ becomes the backup value, so you can get it again."
2772 (cond ((or value comment) 2792 (cond ((or value comment)
2773 (put symbol 'variable-comment comment) 2793 (put symbol 'variable-comment comment)
2774 (custom-variable-backup-value widget) 2794 (custom-variable-backup-value widget)
2775 (custom-push-theme 'theme-value symbol 'user 'set value) 2795 (custom-push-theme 'theme-value symbol 'user 'set (car-safe value))
2776 (condition-case nil 2796 (condition-case nil
2777 (funcall set symbol (eval (car value))) 2797 (funcall set symbol (eval (car value)))
2778 (error nil))) 2798 (error nil)))
@@ -2790,15 +2810,14 @@ This operation eliminates any saved setting for the variable,
2790restoring it to the state of a variable that has never been customized. 2810restoring it to the state of a variable that has never been customized.
2791The value that was current before this operation 2811The value that was current before this operation
2792becomes the backup value, so you can get it again." 2812becomes the backup value, so you can get it again."
2793 (let* ((symbol (widget-value widget)) 2813 (let* ((symbol (widget-value widget)))
2794 (set (or (get symbol 'custom-set) 'set-default)))
2795 (if (get symbol 'standard-value) 2814 (if (get symbol 'standard-value)
2796 (custom-variable-backup-value widget) 2815 (custom-variable-backup-value widget)
2797 (error "No standard setting known for %S" symbol)) 2816 (error "No standard setting known for %S" symbol))
2798 (put symbol 'variable-comment nil) 2817 (put symbol 'variable-comment nil)
2799 (put symbol 'customized-value nil) 2818 (put symbol 'customized-value nil)
2800 (put symbol 'customized-variable-comment nil) 2819 (put symbol 'customized-variable-comment nil)
2801 (custom-push-theme 'theme-value symbol 'user 'reset nil) 2820 (custom-push-theme 'theme-value symbol 'user 'reset)
2802 (custom-theme-recalc-variable symbol) 2821 (custom-theme-recalc-variable symbol)
2803 (when (or (get symbol 'saved-value) (get symbol 'saved-variable-comment)) 2822 (when (or (get symbol 'saved-value) (get symbol 'saved-variable-comment))
2804 (put symbol 'saved-value nil) 2823 (put symbol 'saved-value nil)
@@ -3276,27 +3295,27 @@ SPEC must be a full face spec."
3276 (message "Creating face editor...done")))))) 3295 (message "Creating face editor...done"))))))
3277 3296
3278(defvar custom-face-menu 3297(defvar custom-face-menu
3279 `(("Set for Current Session" custom-face-set) 3298 `(("Set for current session" custom-face-set)
3280 ,@(when (or custom-file user-init-file) 3299 ,@(when (or custom-file user-init-file)
3281 '(("Save for Future Sessions" custom-face-save-command))) 3300 '(("Save for future sessions" custom-face-save-command)))
3282 ("Reset to Saved" custom-face-reset-saved 3301 ("---" ignore ignore)
3302 ("Reset to saved face" custom-face-reset-saved
3283 (lambda (widget) 3303 (lambda (widget)
3284 (or (get (widget-value widget) 'saved-face) 3304 (or (get (widget-value widget) 'saved-face)
3285 (get (widget-value widget) 'saved-face-comment)))) 3305 (get (widget-value widget) 'saved-face-comment))))
3286 ,@(when (or custom-file user-init-file) 3306 ,@(when (or custom-file user-init-file)
3287 '(("Erase Customization" custom-face-reset-standard 3307 '(("Erase customization" custom-face-reset-standard
3288 (lambda (widget) 3308 (lambda (widget)
3289 (get (widget-value widget) 'face-defface-spec))))) 3309 (get (widget-value widget) 'face-defface-spec)))))
3290 ("---" ignore ignore) 3310 ("---" ignore ignore)
3291 ("Add Comment" custom-comment-show custom-comment-invisible-p) 3311 ("Add comment" custom-comment-show custom-comment-invisible-p)
3292 ("---" ignore ignore) 3312 ("Show all attributes" custom-face-edit-all
3293 ("Show all display specs" custom-face-edit-all
3294 (lambda (widget) 3313 (lambda (widget)
3295 (not (eq (widget-get widget :custom-form) 'all)))) 3314 (not (eq (widget-get widget :custom-form) 'all))))
3296 ("Just current attributes" custom-face-edit-selected 3315 ("Show current attributes" custom-face-edit-selected
3297 (lambda (widget) 3316 (lambda (widget)
3298 (not (eq (widget-get widget :custom-form) 'selected)))) 3317 (not (eq (widget-get widget :custom-form) 'selected))))
3299 ("Show as Lisp expression" custom-face-edit-lisp 3318 ("Show Lisp expression" custom-face-edit-lisp
3300 (lambda (widget) 3319 (lambda (widget)
3301 (not (eq (widget-get widget :custom-form) 'lisp))))) 3320 (not (eq (widget-get widget :custom-form) 'lisp)))))
3302 "Alist of actions for the `custom-face' widget. 3321 "Alist of actions for the `custom-face' widget.
@@ -3345,7 +3364,7 @@ widget. If FILTER is nil, ACTION is always valid.")
3345 (cond 3364 (cond
3346 ((eq 'user (caar (get symbol 'theme-face))) 3365 ((eq 'user (caar (get symbol 'theme-face)))
3347 'saved) 3366 'saved)
3348 ((eq 'standard (caar (get symbol 'theme-face))) 3367 ((eq 'changed (caar (get symbol 'theme-face)))
3349 'changed) 3368 'changed)
3350 (t 'themed)) 3369 (t 'themed))
3351 'changed)) 3370 'changed))
@@ -3416,6 +3435,7 @@ Optional EVENT is the location for the menu."
3416 (setq comment nil) 3435 (setq comment nil)
3417 ;; Make the comment invisible by hand if it's empty 3436 ;; Make the comment invisible by hand if it's empty
3418 (custom-comment-hide comment-widget)) 3437 (custom-comment-hide comment-widget))
3438 (custom-push-theme 'theme-face symbol 'user 'set value)
3419 (if (face-spec-choose value) 3439 (if (face-spec-choose value)
3420 (face-spec-set symbol value) 3440 (face-spec-set symbol value)
3421 ;; face-set-spec ignores empty attribute lists, so just give it 3441 ;; face-set-spec ignores empty attribute lists, so just give it
@@ -3423,7 +3443,6 @@ Optional EVENT is the location for the menu."
3423 (face-spec-set symbol '((t :foreground unspecified)))) 3443 (face-spec-set symbol '((t :foreground unspecified))))
3424 (unless (eq (widget-get widget :custom-state) 'standard) 3444 (unless (eq (widget-get widget :custom-state) 'standard)
3425 (put symbol 'saved-face value)) 3445 (put symbol 'saved-face value))
3426 (custom-push-theme 'theme-face symbol 'user 'set value)
3427 (put symbol 'customized-face nil) 3446 (put symbol 'customized-face nil)
3428 (put symbol 'face-comment comment) 3447 (put symbol 'face-comment comment)
3429 (put symbol 'customized-face-comment nil) 3448 (put symbol 'customized-face-comment nil)
@@ -3467,7 +3486,7 @@ restoring it to the state of a face that has never been customized."
3467 (error "No standard setting for this face")) 3486 (error "No standard setting for this face"))
3468 (put symbol 'customized-face nil) 3487 (put symbol 'customized-face nil)
3469 (put symbol 'customized-face-comment nil) 3488 (put symbol 'customized-face-comment nil)
3470 (custom-push-theme 'theme-face symbol 'user 'reset nil) 3489 (custom-push-theme 'theme-face symbol 'user 'reset)
3471 (custom-theme-recalc-face symbol) 3490 (custom-theme-recalc-face symbol)
3472 (when (or (get symbol 'saved-face) (get symbol 'saved-face-comment)) 3491 (when (or (get symbol 'saved-face) (get symbol 'saved-face-comment))
3473 (put symbol 'saved-face nil) 3492 (put symbol 'saved-face nil)
@@ -3757,6 +3776,8 @@ If GROUPS-ONLY non-nil, return only those members that are groups."
3757 (if (eq custom-buffer-style 'links) 3776 (if (eq custom-buffer-style 'links)
3758 (push (widget-create-child-and-convert 3777 (push (widget-create-child-and-convert
3759 widget 'custom-group-link 3778 widget 'custom-group-link
3779 :button-face 'custom-link
3780 :mouse-face 'highlight
3760 :tag "Go to Group" 3781 :tag "Go to Group"
3761 symbol) 3782 symbol)
3762 buttons) 3783 buttons)
@@ -3872,21 +3893,22 @@ Creating group members... %2d%%"
3872 (insert "/\n"))))) 3893 (insert "/\n")))))
3873 3894
3874(defvar custom-group-menu 3895(defvar custom-group-menu
3875 `(("Set for Current Session" custom-group-set 3896 `(("Set for current session" custom-group-set
3876 (lambda (widget) 3897 (lambda (widget)
3877 (eq (widget-get widget :custom-state) 'modified))) 3898 (eq (widget-get widget :custom-state) 'modified)))
3878 ,@(when (or custom-file user-init-file) 3899 ,@(when (or custom-file user-init-file)
3879 '(("Save for Future Sessions" custom-group-save 3900 '(("Save for future sessions" custom-group-save
3880 (lambda (widget) 3901 (lambda (widget)
3881 (memq (widget-get widget :custom-state) '(modified set)))))) 3902 (memq (widget-get widget :custom-state) '(modified set))))))
3882 ("Reset to Current" custom-group-reset-current 3903 ("---" ignore ignore)
3904 ("Reset to current settings" custom-group-reset-current
3883 (lambda (widget) 3905 (lambda (widget)
3884 (memq (widget-get widget :custom-state) '(modified)))) 3906 (memq (widget-get widget :custom-state) '(modified))))
3885 ("Reset to Saved" custom-group-reset-saved 3907 ("Reset to saved settings" custom-group-reset-saved
3886 (lambda (widget) 3908 (lambda (widget)
3887 (memq (widget-get widget :custom-state) '(modified set)))) 3909 (memq (widget-get widget :custom-state) '(modified set))))
3888 ,@(when (or custom-file user-init-file) 3910 ,@(when (or custom-file user-init-file)
3889 '(("Reset to standard setting" custom-group-reset-standard 3911 '(("Reset to standard settings" custom-group-reset-standard
3890 (lambda (widget) 3912 (lambda (widget)
3891 (memq (widget-get widget :custom-state) '(modified set saved))))))) 3913 (memq (widget-get widget :custom-state) '(modified set saved)))))))
3892 "Alist of actions for the `custom-group' widget. 3914 "Alist of actions for the `custom-group' widget.
@@ -4123,16 +4145,15 @@ This function does not save the buffer."
4123(defun custom-save-variables () 4145(defun custom-save-variables ()
4124 "Save all customized variables in `custom-file'." 4146 "Save all customized variables in `custom-file'."
4125 (save-excursion 4147 (save-excursion
4126 (custom-save-delete 'custom-reset-variables)
4127 (custom-save-delete 'custom-set-variables) 4148 (custom-save-delete 'custom-set-variables)
4128 (custom-save-resets 'theme-value 'custom-reset-variables nil)
4129 (let ((standard-output (current-buffer)) 4149 (let ((standard-output (current-buffer))
4130 (saved-list (make-list 1 0)) 4150 (saved-list (make-list 1 0))
4131 sort-fold-case) 4151 sort-fold-case)
4132 ;; First create a sorted list of saved variables. 4152 ;; First create a sorted list of saved variables.
4133 (mapatoms 4153 (mapatoms
4134 (lambda (symbol) 4154 (lambda (symbol)
4135 (if (get symbol 'saved-value) 4155 (if (and (get symbol 'saved-value)
4156 (eq 'user (car (car-safe (get symbol 'theme-value)))))
4136 (nconc saved-list (list symbol))))) 4157 (nconc saved-list (list symbol)))))
4137 (setq saved-list (sort (cdr saved-list) 'string<)) 4158 (setq saved-list (sort (cdr saved-list) 'string<))
4138 (unless (bolp) 4159 (unless (bolp)
@@ -4156,9 +4177,7 @@ This function does not save the buffer."
4156 (when (and (symbolp request) (not (featurep request))) 4177 (when (and (symbolp request) (not (featurep request)))
4157 (message "Unknown requested feature: %s" request) 4178 (message "Unknown requested feature: %s" request)
4158 (setq requests (delq request requests)))) 4179 (setq requests (delq request requests))))
4159 (when (or (and spec 4180 (when (or (and spec (eq (car spec) 'user))
4160 (eq (nth 0 spec) 'user)
4161 (eq (nth 1 spec) 'set))
4162 comment 4181 comment
4163 (and (null spec) (get symbol 'saved-value))) 4182 (and (null spec) (get symbol 'saved-value)))
4164 (unless (bolp) 4183 (unless (bolp)
@@ -4183,46 +4202,19 @@ This function does not save the buffer."
4183 (unless (looking-at "\n") 4202 (unless (looking-at "\n")
4184 (princ "\n"))))) 4203 (princ "\n")))))
4185 4204
4186(defun custom-save-resets (property setter special)
4187 (let (started-writing ignored-special)
4188 ;; (custom-save-delete setter) Done by caller
4189 (let ((standard-output (current-buffer))
4190 (mapper `(lambda (object)
4191 (let ((spec (car-safe (get object (quote ,property)))))
4192 (when (and (not (memq object ignored-special))
4193 (eq (nth 0 spec) 'user)
4194 (eq (nth 1 spec) 'reset))
4195 ;; Do not write reset statements unless necessary.
4196 (unless started-writing
4197 (setq started-writing t)
4198 (unless (bolp)
4199 (princ "\n"))
4200 (princ "(")
4201 (princ (quote ,setter))
4202 (princ "\n '(")
4203 (prin1 object)
4204 (princ " ")
4205 (prin1 (nth 3 spec))
4206 (princ ")")))))))
4207 (mapc mapper special)
4208 (setq ignored-special special)
4209 (mapatoms mapper)
4210 (when started-writing
4211 (princ ")\n")))))
4212
4213(defun custom-save-faces () 4205(defun custom-save-faces ()
4214 "Save all customized faces in `custom-file'." 4206 "Save all customized faces in `custom-file'."
4215 (save-excursion 4207 (save-excursion
4216 (custom-save-delete 'custom-reset-faces) 4208 (custom-save-delete 'custom-reset-faces)
4217 (custom-save-delete 'custom-set-faces) 4209 (custom-save-delete 'custom-set-faces)
4218 (custom-save-resets 'theme-face 'custom-reset-faces '(default))
4219 (let ((standard-output (current-buffer)) 4210 (let ((standard-output (current-buffer))
4220 (saved-list (make-list 1 0)) 4211 (saved-list (make-list 1 0))
4221 sort-fold-case) 4212 sort-fold-case)
4222 ;; First create a sorted list of saved faces. 4213 ;; First create a sorted list of saved faces.
4223 (mapatoms 4214 (mapatoms
4224 (lambda (symbol) 4215 (lambda (symbol)
4225 (if (get symbol 'saved-face) 4216 (if (and (get symbol 'saved-face)
4217 (eq 'user (car (car-safe (get symbol 'theme-face)))))
4226 (nconc saved-list (list symbol))))) 4218 (nconc saved-list (list symbol)))))
4227 (setq saved-list (sort (cdr saved-list) 'string<)) 4219 (setq saved-list (sort (cdr saved-list) 'string<))
4228 ;; The default face must be first, since it affects the others. 4220 ;; The default face must be first, since it affects the others.
@@ -4242,9 +4234,7 @@ This function does not save the buffer."
4242 (and (not (custom-facep symbol)) 4234 (and (not (custom-facep symbol))
4243 (not (get symbol 'force-face)))))) 4235 (not (get symbol 'force-face))))))
4244 (comment (get symbol 'saved-face-comment))) 4236 (comment (get symbol 'saved-face-comment)))
4245 (when (or (and spec 4237 (when (or (and spec (eq (nth 0 spec) 'user))
4246 (eq (nth 0 spec) 'user)
4247 (eq (nth 1 spec) 'set))
4248 comment 4238 comment
4249 (and (null spec) (get symbol 'saved-face))) 4239 (and (null spec) (get symbol 'saved-face)))
4250 ;; Don't print default face here. 4240 ;; Don't print default face here.
@@ -4377,9 +4367,9 @@ The format is suitable for use with `easy-menu-define'."
4377 ,(customize-menu-create 'customize) 4367 ,(customize-menu-create 'customize)
4378 ["Set" Custom-set t] 4368 ["Set" Custom-set t]
4379 ["Save" Custom-save t] 4369 ["Save" Custom-save t]
4380 ["Reset to Current" Custom-reset-current t] 4370 ["Reset to current settings" Custom-reset-current t]
4381 ["Reset to Saved" Custom-reset-saved t] 4371 ["Reset to saved settings" Custom-reset-saved t]
4382 ["Reset to Standard Values" Custom-reset-standard t] 4372 ["Erase customizations" Custom-reset-standard t]
4383 ["Info" (info "(emacs)Easy Customization") t])) 4373 ["Info" (info "(emacs)Easy Customization") t]))
4384 4374
4385(defun Custom-goto-parent () 4375(defun Custom-goto-parent ()
diff --git a/lisp/cus-face.el b/lisp/cus-face.el
index 3e4e32ecc97..c5547657a17 100644
--- a/lisp/cus-face.el
+++ b/lisp/cus-face.el
@@ -353,17 +353,20 @@ FACE's list property `theme-face' \(using `custom-push-theme')."
353 (custom-push-theme 'theme-face face theme 'set spec)) 353 (custom-push-theme 'theme-face face theme 'set spec))
354 (setq args (cdr (cdr args)))))))) 354 (setq args (cdr (cdr args))))))))
355 355
356;; XEmacs compability function. In XEmacs, when you reset a Custom
357;; Theme, you have to specify the theme to reset it to. We just apply
358;; the next theme.
356;;;###autoload 359;;;###autoload
357(defun custom-theme-reset-faces (theme &rest args) 360(defun custom-theme-reset-faces (theme &rest args)
358 "Reset the specs in THEME of some faces to their specs in other themes. 361 "Reset the specs in THEME of some faces to their specs in other themes.
359Each of the arguments ARGS has this form: 362Each of the arguments ARGS has this form:
360 363
361 (FACE FROM-THEME) 364 (FACE IGNORED)
362 365
363This means reset FACE to its value in FROM-THEME." 366This means reset FACE. The argument IGNORED is ignored."
364 (custom-check-theme theme) 367 (custom-check-theme theme)
365 (dolist (arg args) 368 (dolist (arg args)
366 (custom-push-theme 'theme-face (car arg) theme 'reset (cadr arg)))) 369 (custom-push-theme 'theme-face (car arg) theme 'reset)))
367 370
368;;;###autoload 371;;;###autoload
369(defun custom-reset-faces (&rest args) 372(defun custom-reset-faces (&rest args)
diff --git a/lisp/cus-theme.el b/lisp/cus-theme.el
index d7102fc11f7..0a421da925c 100644
--- a/lisp/cus-theme.el
+++ b/lisp/cus-theme.el
@@ -58,18 +58,18 @@ use by `customize-create-theme'."
58 (set (make-local-variable 'widget-link-suffix) ""))) 58 (set (make-local-variable 'widget-link-suffix) "")))
59(put 'custom-new-theme-mode 'mode-class 'special) 59(put 'custom-new-theme-mode 'mode-class 'special)
60 60
61(defvar custom-theme-name) 61(defvar custom-theme-name nil)
62(defvar custom-theme-variables) 62(defvar custom-theme-variables nil)
63(defvar custom-theme-faces) 63(defvar custom-theme-faces nil)
64(defvar custom-theme-description) 64(defvar custom-theme-description)
65(defvar custom-theme-insert-variable-marker)
66(defvar custom-theme-insert-face-marker)
65 67
66;;;###autoload 68;;;###autoload
67(defun customize-create-theme () 69(defun customize-create-theme ()
68 "Create a custom theme." 70 "Create a custom theme."
69 (interactive) 71 (interactive)
70 (if (get-buffer "*New Custom Theme*") 72 (switch-to-buffer (generate-new-buffer "*New Custom Theme*"))
71 (kill-buffer "*New Custom Theme*"))
72 (switch-to-buffer "*New Custom Theme*")
73 (let ((inhibit-read-only t)) 73 (let ((inhibit-read-only t))
74 (erase-buffer)) 74 (erase-buffer))
75 (custom-new-theme-mode) 75 (custom-new-theme-mode)
@@ -77,17 +77,39 @@ use by `customize-create-theme'."
77 (make-local-variable 'custom-theme-variables) 77 (make-local-variable 'custom-theme-variables)
78 (make-local-variable 'custom-theme-faces) 78 (make-local-variable 'custom-theme-faces)
79 (make-local-variable 'custom-theme-description) 79 (make-local-variable 'custom-theme-description)
80 (make-local-variable 'custom-theme-insert-variable-marker)
81 (make-local-variable 'custom-theme-insert-face-marker)
80 (widget-insert "This buffer helps you write a custom theme elisp file. 82 (widget-insert "This buffer helps you write a custom theme elisp file.
81This will help you share your customizations with other people. 83This will help you share your customizations with other people.
82 84
83Just insert the names of all variables and faces you want the theme 85Insert the names of all variables and faces you want the theme to include.
84to include. Then clicking mouse-2 or pressing RET on the [Done] button 86Invoke \"Save Theme\" to save the theme. The theme file will be saved to
85will write a theme file that sets all these variables and faces to their 87the directory " custom-theme-directory "\n\n")
86current global values. It will write that file into the directory given 88 (widget-create 'push-button
87by the variable `custom-theme-directory', usually \"~/.emacs.d/\". 89 :tag "Visit Theme"
90 :help-echo "Insert the settings of a pre-defined theme."
91 :action (lambda (widget &optional event)
92 (call-interactively 'custom-theme-visit-theme)))
93 (widget-insert " ")
94 (widget-create 'push-button
95 :tag "Merge Theme"
96 :help-echo "Merge in the settings of a pre-defined theme."
97 :action (lambda (widget &optional event)
98 (call-interactively 'custom-theme-merge-theme)))
99 (widget-insert " ")
100 (widget-create 'push-button
101 :notify (lambda (&rest ignore)
102 (when (y-or-n-p "Discard current changes?")
103 (kill-buffer (current-buffer))
104 (customize-create-theme)))
105 "Reset Buffer")
106 (widget-insert " ")
107 (widget-create 'push-button
108 :notify (function custom-theme-write)
109 "Save Theme")
110 (widget-insert "\n")
88 111
89To undo all your edits to the buffer, use the [Reset] button.\n\n") 112 (widget-insert "\n\nTheme name: ")
90 (widget-insert "Theme name: ")
91 (setq custom-theme-name 113 (setq custom-theme-name
92 (widget-create 'editable-field 114 (widget-create 'editable-field
93 :size 10 115 :size 10
@@ -96,76 +118,254 @@ To undo all your edits to the buffer, use the [Reset] button.\n\n")
96 (setq custom-theme-description 118 (setq custom-theme-description
97 (widget-create 'text 119 (widget-create 'text
98 :value (format-time-string "Created %Y-%m-%d."))) 120 :value (format-time-string "Created %Y-%m-%d.")))
99 (widget-insert "\nVariables:\n\n")
100 (setq custom-theme-variables
101 (widget-create 'editable-list
102 :entry-format "%i %d %v"
103 'variable))
104 (widget-insert "\nFaces:\n\n")
105 (setq custom-theme-faces
106 (widget-create 'editable-list
107 :entry-format "%i %d %v"
108 'face))
109 (widget-insert "\n") 121 (widget-insert "\n")
110 (widget-create 'push-button 122 (widget-create 'push-button
111 :notify (function custom-theme-write) 123 :tag "Insert Variable"
112 "Done") 124 :help-echo "Add another variable to this theme."
113 (widget-insert " ") 125 :action (lambda (widget &optional event)
126 (call-interactively 'custom-theme-add-variable)))
127 (widget-insert "\n")
128 (setq custom-theme-insert-variable-marker (point-marker))
129 (widget-insert "\n")
114 (widget-create 'push-button 130 (widget-create 'push-button
115 :notify (lambda (&rest ignore) 131 :tag "Insert Face"
116 (customize-create-theme)) 132 :help-echo "Add another face to this theme."
117 "Reset") 133 :action (lambda (widget &optional event)
118 (widget-insert " ") 134 (call-interactively 'custom-theme-add-face)))
135 (widget-insert "\n")
136 (setq custom-theme-insert-face-marker (point-marker))
137 (widget-insert "\n")
119 (widget-create 'push-button 138 (widget-create 'push-button
120 :notify (lambda (&rest ignore) 139 :notify (lambda (&rest ignore)
121 (bury-buffer)) 140 (when (y-or-n-p "Discard current changes?")
122 "Bury Buffer") 141 (kill-buffer (current-buffer))
142 (customize-create-theme)))
143 "Reset Buffer")
144 (widget-insert " ")
145 (widget-create 'push-button
146 :notify (function custom-theme-write)
147 "Save Theme")
123 (widget-insert "\n") 148 (widget-insert "\n")
149 (widget-setup)
150 (goto-char (point-min))
151 (message ""))
152
153;;; Theme variables
154
155(defun custom-theme-add-variable (symbol)
156 (interactive "vVariable name: ")
157 (save-excursion
158 (goto-char custom-theme-insert-variable-marker)
159 (if (assq symbol custom-theme-variables)
160 (message "%s is already in the theme" (symbol-name symbol))
161 (widget-insert "\n")
162 (let ((widget (widget-create 'custom-variable
163 :tag (custom-unlispify-tag-name symbol)
164 :custom-level 0
165 :action 'custom-theme-variable-action
166 :custom-state 'unknown
167 :value symbol)))
168 (push (cons symbol widget) custom-theme-variables)
169 (custom-magic-reset widget))
170 (widget-setup))))
171
172(defvar custom-theme-variable-menu
173 `(("Reset to Current" custom-redraw
174 (lambda (widget)
175 (and (boundp (widget-value widget))
176 (memq (widget-get widget :custom-state)
177 '(themed modified changed)))))
178 ("Reset to Theme Value" custom-variable-reset-theme
179 (lambda (widget)
180 (let ((theme (intern (widget-value custom-theme-name)))
181 (symbol (widget-value widget))
182 found)
183 (and (custom-theme-p theme)
184 (dolist (setting (get theme 'theme-settings) found)
185 (if (and (eq (cadr setting) symbol)
186 (eq (car setting) 'theme-value))
187 (setq found t)))))))
188 ("---" ignore ignore)
189 ("Delete" custom-theme-delete-variable nil))
190 "Alist of actions for the `custom-variable' widget in Custom Theme Mode.
191See the documentation for `custom-variable'.")
192
193(defun custom-theme-variable-action (widget &optional event)
194 "Show the Custom Theme Mode menu for a `custom-variable' widget.
195Optional EVENT is the location for the menu."
196 (let ((custom-variable-menu custom-theme-variable-menu))
197 (custom-variable-action widget event)))
198
199(defun custom-variable-reset-theme (widget)
200 "Reset WIDGET to its value for the currently edited theme."
201 (let ((theme (intern (widget-value custom-theme-name)))
202 (symbol (widget-value widget))
203 found)
204 (dolist (setting (get theme 'theme-settings))
205 (if (and (eq (cadr setting) symbol)
206 (eq (car setting) 'theme-value))
207 (setq found setting)))
208 (widget-value-set (car (widget-get widget :children))
209 (nth 3 found)))
210 (widget-put widget :custom-state 'themed)
211 (custom-redraw-magic widget)
212 (widget-setup))
213
214(defun custom-theme-delete-variable (widget)
215 (setq custom-theme-variables
216 (assq-delete-all (widget-value widget) custom-theme-variables))
217 (widget-delete widget))
218
219;;; Theme faces
220
221(defun custom-theme-add-face (symbol)
222 (interactive (list (read-face-name "Face name" nil nil)))
223 (save-excursion
224 (goto-char custom-theme-insert-face-marker)
225 (if (assq symbol custom-theme-faces)
226 (message "%s is already in the theme" (symbol-name symbol))
227 (widget-insert "\n")
228 (let ((widget (widget-create 'custom-face
229 :tag (custom-unlispify-tag-name symbol)
230 :custom-level 0
231 :action 'custom-theme-face-action
232 :custom-state 'unknown
233 :value symbol)))
234 (push (cons symbol widget) custom-theme-faces)
235 (custom-magic-reset widget)
236 (widget-setup)))))
237
238(defvar custom-theme-face-menu
239 `(("Reset to Theme Value" custom-face-reset-theme
240 (lambda (widget)
241 (let ((theme (intern (widget-value custom-theme-name)))
242 (symbol (widget-value widget))
243 found)
244 (and (custom-theme-p theme)
245 (dolist (setting (get theme 'theme-settings) found)
246 (if (and (eq (cadr setting) symbol)
247 (eq (car setting) 'theme-face))
248 (setq found t)))))))
249 ("---" ignore ignore)
250 ("Delete" custom-theme-delete-face nil))
251 "Alist of actions for the `custom-variable' widget in Custom Theme Mode.
252See the documentation for `custom-variable'.")
253
254(defun custom-theme-face-action (widget &optional event)
255 "Show the Custom Theme Mode menu for a `custom-face' widget.
256Optional EVENT is the location for the menu."
257 (let ((custom-face-menu custom-theme-face-menu))
258 (custom-face-action widget event)))
259
260(defun custom-face-reset-theme (widget)
261 "Reset WIDGET to its value for the currently edited theme."
262 (let ((theme (intern (widget-value custom-theme-name)))
263 (symbol (widget-value widget))
264 found)
265 (dolist (setting (get theme 'theme-settings))
266 (if (and (eq (cadr setting) symbol)
267 (eq (car setting) 'theme-face))
268 (setq found setting)))
269 (widget-value-set (car (widget-get widget :children))
270 (nth 3 found)))
271 (widget-put widget :custom-state 'themed)
272 (custom-redraw-magic widget)
124 (widget-setup)) 273 (widget-setup))
125 274
275(defun custom-theme-delete-face (widget)
276 (setq custom-theme-faces
277 (assq-delete-all (widget-value widget) custom-theme-faces))
278 (widget-delete widget))
279
280;;; Reading and writing
281
282(defun custom-theme-visit-theme ()
283 (interactive)
284 (when (or (null custom-theme-variables)
285 (if (y-or-n-p "Discard current changes?")
286 (progn (customize-create-theme) t)))
287 (let ((theme (call-interactively 'custom-theme-merge-theme)))
288 (unless (eq theme 'user)
289 (widget-value-set custom-theme-name (symbol-name theme)))
290 (widget-value-set custom-theme-description
291 (or (get theme 'theme-documentation)
292 (format-time-string "Created %Y-%m-%d.")))
293 (widget-setup))))
294
295(defun custom-theme-merge-theme (theme)
296 (interactive "SCustom theme name: ")
297 (unless (eq theme 'user)
298 (load-theme theme))
299 (let ((settings (get theme 'theme-settings)))
300 (dolist (setting settings)
301 (if (eq (car setting) 'theme-value)
302 (custom-theme-add-variable (cadr setting))
303 (custom-theme-add-face (cadr setting)))))
304 (disable-theme theme)
305 theme)
306
126(defun custom-theme-write (&rest ignore) 307(defun custom-theme-write (&rest ignore)
127 (let ((name (widget-value custom-theme-name)) 308 (let* ((name (widget-value custom-theme-name))
128 (doc (widget-value custom-theme-description)) 309 (filename (expand-file-name (concat name "-theme.el")
129 (variables (widget-value custom-theme-variables)) 310 custom-theme-directory))
130 (faces (widget-value custom-theme-faces))) 311 (doc (widget-value custom-theme-description))
131 (switch-to-buffer (concat name "-theme.el")) 312 (vars custom-theme-variables)
132 (emacs-lisp-mode) 313 (faces custom-theme-faces))
133 (unless (file-exists-p custom-theme-directory) 314 (cond ((or (string-equal name "")
134 (make-directory (file-name-as-directory custom-theme-directory) t)) 315 (string-equal name "user")
135 (setq default-directory custom-theme-directory) 316 (string-equal name "changed"))
136 (setq buffer-file-name (expand-file-name (concat name "-theme.el"))) 317 (error "Custom themes cannot be named `%s'" name))
137 (let ((inhibit-read-only t)) 318 ((string-match " " name)
138 (erase-buffer)) 319 (error "Custom theme names should not contain spaces"))
139 (insert "(deftheme " name) 320 ((if (file-exists-p filename)
140 (when doc 321 (not (y-or-n-p
141 (newline) 322 (format "File %s exists. Overwrite? " filename))))
142 (insert " \"" doc "\"")) 323 (error "Aborted")))
143 (insert ")\n") 324 (with-temp-buffer
144 (custom-theme-write-variables name variables) 325 (emacs-lisp-mode)
145 (custom-theme-write-faces name faces) 326 (unless (file-exists-p custom-theme-directory)
146 (insert "\n(provide-theme '" name ")\n") 327 (make-directory (file-name-as-directory custom-theme-directory) t))
147 (save-buffer))) 328 (setq buffer-file-name filename)
329 (erase-buffer)
330 (insert "(deftheme " name)
331 (if doc (insert "\n \"" doc "\""))
332 (insert ")\n")
333 (custom-theme-write-variables name vars)
334 (custom-theme-write-faces name faces)
335 (insert "\n(provide-theme '" name ")\n")
336 (save-buffer))
337 (dolist (var vars)
338 (widget-put (cdr var) :custom-state 'saved)
339 (custom-redraw-magic (cdr var)))
340 (dolist (face faces)
341 (widget-put (cdr face) :custom-state 'saved)
342 (custom-redraw-magic (cdr face)))))
148 343
149(defun custom-theme-write-variables (theme vars) 344(defun custom-theme-write-variables (theme vars)
150 "Write a `custom-theme-set-variables' command for THEME. 345 "Write a `custom-theme-set-variables' command for THEME.
151It includes all variables in list VARS." 346It includes all variables in list VARS."
152 ;; Most code is stolen from `custom-save-variables'.
153 (when vars 347 (when vars
154 (let ((standard-output (current-buffer))) 348 (let ((standard-output (current-buffer)))
155 (princ "\n(custom-theme-set-variables\n") 349 (princ "\n(custom-theme-set-variables\n")
156 (princ " '") 350 (princ " '")
157 (princ theme) 351 (princ theme)
158 (princ "\n") 352 (princ "\n")
159 (mapc (lambda (symbol) 353 (mapc (lambda (spec)
160 (when (boundp symbol) 354 (let* ((symbol (car spec))
161 (unless (bolp) 355 (child (car-safe (widget-get (cdr spec) :children)))
162 (princ "\n")) 356 (value (if child
163 (princ " '(") 357 (widget-value child)
164 (prin1 symbol) 358 ;; For hidden widgets, use the standard value
165 (princ " ") 359 (get symbol 'standard-value))))
166 (prin1 (custom-quote (symbol-value symbol))) 360 (when (boundp symbol)
167 (princ ")"))) 361 (unless (bolp)
168 vars) 362 (princ "\n"))
363 (princ " '(")
364 (prin1 symbol)
365 (princ " ")
366 (prin1 (custom-quote value))
367 (princ ")"))))
368 vars)
169 (if (bolp) 369 (if (bolp)
170 (princ " ")) 370 (princ " "))
171 (princ ")") 371 (princ ")")
@@ -181,18 +381,19 @@ It includes all faces in list FACES."
181 (princ " '") 381 (princ " '")
182 (princ theme) 382 (princ theme)
183 (princ "\n") 383 (princ "\n")
184 (mapc (lambda (symbol) 384 (mapc (lambda (spec)
185 (when (facep symbol) 385 (let* ((symbol (car spec))
186 (unless (bolp) 386 (child (car-safe (widget-get (cdr spec) :children)))
187 (princ "\n")) 387 (value (if child (widget-value child))))
188 (princ " '(") 388 (when (and (facep symbol) child)
189 (prin1 symbol) 389 (unless (bolp)
190 (princ " ") 390 (princ "\n"))
191 (prin1 (list (append '(t) 391 (princ " '(")
192 (custom-face-attributes-get 392 (prin1 symbol)
193 'font-lock-comment-face nil)))) 393 (princ " ")
194 (princ ")"))) 394 (prin1 value)
195 faces) 395 (princ ")"))))
396 faces)
196 (if (bolp) 397 (if (bolp)
197 (princ " ")) 398 (princ " "))
198 (princ ")") 399 (princ ")")
diff --git a/lisp/custom.el b/lisp/custom.el
index 18d79a6af23..6267febe0d5 100644
--- a/lisp/custom.el
+++ b/lisp/custom.el
@@ -599,9 +599,160 @@ This recursively follows aliases."
599 ((equal load "cus-edit")) 599 ((equal load "cus-edit"))
600 (t (condition-case nil (load load) (error nil)))))))) 600 (t (condition-case nil (load load) (error nil))))))))
601 601
602(defvar custom-known-themes '(user standard) 602(defvar custom-local-buffer nil
603 "Non-nil, in a Customization buffer, means customize a specific buffer.
604If this variable is non-nil, it should be a buffer,
605and it means customize the local bindings of that buffer.
606This variable is a permanent local, and it normally has a local binding
607in every Customization buffer.")
608(put 'custom-local-buffer 'permanent-local t)
609
610(defun custom-set-default (variable value)
611 "Default :set function for a customizable variable.
612Normally, this sets the default value of VARIABLE to VALUE,
613but if `custom-local-buffer' is non-nil,
614this sets the local binding in that buffer instead."
615 (if custom-local-buffer
616 (with-current-buffer custom-local-buffer
617 (set variable value))
618 (set-default variable value)))
619
620(defun custom-set-minor-mode (variable value)
621 ":set function for minor mode variables.
622Normally, this sets the default value of VARIABLE to nil if VALUE
623is nil and to t otherwise,
624but if `custom-local-buffer' is non-nil,
625this sets the local binding in that buffer instead."
626 (if custom-local-buffer
627 (with-current-buffer custom-local-buffer
628 (funcall variable (if value 1 0)))
629 (funcall variable (if value 1 0))))
630
631(defun custom-quote (sexp)
632 "Quote SEXP iff it is not self quoting."
633 (if (or (memq sexp '(t nil))
634 (keywordp sexp)
635 (and (listp sexp)
636 (memq (car sexp) '(lambda)))
637 (stringp sexp)
638 (numberp sexp)
639 (vectorp sexp)
640;;; (and (fboundp 'characterp)
641;;; (characterp sexp))
642 )
643 sexp
644 (list 'quote sexp)))
645
646(defun customize-mark-to-save (symbol)
647 "Mark SYMBOL for later saving.
648
649If the default value of SYMBOL is different from the standard value,
650set the `saved-value' property to a list whose car evaluates to the
651default value. Otherwise, set it to nil.
652
653To actually save the value, call `custom-save-all'.
654
655Return non-nil iff the `saved-value' property actually changed."
656 (let* ((get (or (get symbol 'custom-get) 'default-value))
657 (value (funcall get symbol))
658 (saved (get symbol 'saved-value))
659 (standard (get symbol 'standard-value))
660 (comment (get symbol 'customized-variable-comment)))
661 ;; Save default value iff different from standard value.
662 (if (or (null standard)
663 (not (equal value (condition-case nil
664 (eval (car standard))
665 (error nil)))))
666 (put symbol 'saved-value (list (custom-quote value)))
667 (put symbol 'saved-value nil))
668 ;; Clear customized information (set, but not saved).
669 (put symbol 'customized-value nil)
670 ;; Save any comment that might have been set.
671 (when comment
672 (put symbol 'saved-variable-comment comment))
673 (not (equal saved (get symbol 'saved-value)))))
674
675(defun customize-mark-as-set (symbol)
676 "Mark current value of SYMBOL as being set from customize.
677
678If the default value of SYMBOL is different from the saved value if any,
679or else if it is different from the standard value, set the
680`customized-value' property to a list whose car evaluates to the
681default value. Otherwise, set it to nil.
682
683Return non-nil iff the `customized-value' property actually changed."
684 (let* ((get (or (get symbol 'custom-get) 'default-value))
685 (value (funcall get symbol))
686 (customized (get symbol 'customized-value))
687 (old (or (get symbol 'saved-value) (get symbol 'standard-value))))
688 ;; Mark default value as set iff different from old value.
689 (if (or (null old)
690 (not (equal value (condition-case nil
691 (eval (car old))
692 (error nil)))))
693 (put symbol 'customized-value (list (custom-quote value)))
694 (put symbol 'customized-value nil))
695 ;; Changed?
696 (not (equal customized (get symbol 'customized-value)))))
697
698(defun custom-reevaluate-setting (symbol)
699 "Reset the value of SYMBOL by re-evaluating its saved or standard value.
700Use the :set function to do so. This is useful for customizable options
701that are defined before their standard value can really be computed.
702E.g. dumped variables whose default depends on run-time information."
703 (funcall (or (get symbol 'custom-set) 'set-default)
704 symbol
705 (eval (car (or (get symbol 'saved-value) (get symbol 'standard-value))))))
706
707
708;;; Custom Themes
709
710;; Custom themes are collections of settings that can be enabled or
711;; disabled as a unit.
712
713;; Each Custom theme is defined by a symbol, called the theme name.
714;; The `theme-settings' property of the theme name records the
715;; variable and face settings of the theme. This property is a list
716;; of elements, each of the form
717;;
718;; (PROP SYMBOL THEME VALUE)
719;;
720;; - PROP is either `theme-value' or `theme-face'
721;; - SYMBOL is the face or variable name
722;; - THEME is the theme name (redundant, but simplifies the code)
723;; - VALUE is an expression that gives the theme's setting for SYMBOL.
724;;
725;; The theme name also has a `theme-feature' property, whose value is
726;; specified when the theme is defined (see `custom-declare-theme').
727;; Usually, this is just a symbol named THEME-theme. This lets
728;; external libraries call (require 'foo-theme).
729
730;; In addition, each symbol (either a variable or a face) affected by
731;; an *enabled* theme has a `theme-value' or `theme-face' property,
732;; which is a list of elements each of the form
733;;
734;; (THEME VALUE)
735;;
736;; which have the same meanings as in `theme-settings'.
737;;
738;; The `theme-value' and `theme-face' lists are ordered by decreasing
739;; theme precedence. Thus, the first element is always the one that
740;; is in effect.
741
742;; Each theme is stored in a theme file, with filename THEME-theme.el.
743;; Loading a theme basically involves calling (load "THEME-theme")
744;; This is done by the function `load-theme'. Loading a theme
745;; automatically enables it.
746;;
747;; When a theme is enabled, the `theme-value' and `theme-face'
748;; properties for the affected symbols are set. When a theme is
749;; disabled, its settings are removed from the `theme-value' and
750;; `theme-face' properties, but the theme's own `theme-settings'
751;; property remains unchanged.
752
753(defvar custom-known-themes '(user changed)
603 "Themes that have been defined with `deftheme'. 754 "Themes that have been defined with `deftheme'.
604The default value is the list (user standard). The theme `standard' 755The default value is the list (user changed). The theme `changed'
605contains the settings before custom themes are applied. The 756contains the settings before custom themes are applied. The
606theme `user' contains all the settings the user customized and saved. 757theme `user' contains all the settings the user customized and saved.
607Additional themes declared with the `deftheme' macro will be added to 758Additional themes declared with the `deftheme' macro will be added to
@@ -616,44 +767,22 @@ the front of this list.")
616 (unless (custom-theme-p theme) 767 (unless (custom-theme-p theme)
617 (error "Unknown theme `%s'" theme))) 768 (error "Unknown theme `%s'" theme)))
618 769
619;;; Initializing. 770(defun custom-push-theme (prop symbol theme mode &optional value)
620 771 "Record VALUE for face or variable SYMBOL in custom theme THEME.
621(defun custom-push-theme (prop symbol theme mode value) 772PROP is `theme-face' for a face, `theme-value' for a variable.
622 "Record a value for face or variable SYMBOL in custom theme THEME.
623PROP is`theme-face' for a face, `theme-value' for a variable.
624The value is specified by (THEME MODE VALUE), which is interpreted
625by `custom-theme-value'.
626 773
627MODE can be either the symbol `set' or the symbol `reset'. If it is the 774MODE 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 775symbol `set', then VALUE is the value to use. If it is the symbol
629`reset', then VALUE is either another theme, which means to use the 776`reset', then SYMBOL will be removed from THEME (VALUE is ignored).
630value defined by that theme; or nil, which means to remove SYMBOL from
631THEME entirely.
632
633In the following example, the variable `goto-address-url-face' has been
634set by three different themes. Its `theme-value' property is:
635
636 \((subtle-hacker reset gnome2)
637 \(jonadab set underline)
638 \(gnome2 set info-xref)
639
640The theme value defined by `subtle-hacker' is in effect, because
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'.
646
647The user has not customized the variable; had he done that, the
648list would contain an entry for the `user' theme, too.
649 777
650See `custom-known-themes' for a list of known themes." 778See `custom-known-themes' for a list of known themes."
651 (unless (memq prop '(theme-value theme-face)) 779 (unless (memq prop '(theme-value theme-face))
652 (error "Unknown theme property")) 780 (error "Unknown theme property"))
653 (let* ((old (get symbol prop)) 781 (let* ((old (get symbol prop))
654 (setting (assq theme old)) 782 (setting (assq theme old)) ; '(theme value)
655 (theme-settings (get theme 'theme-settings))) 783 (theme-settings ; '(prop symbol theme value)
656 (if (and (eq mode 'reset) (null value)) 784 (get theme 'theme-settings)))
785 (if (eq mode 'reset)
657 ;; Remove a setting. 786 ;; Remove a setting.
658 (when setting 787 (when setting
659 (let (res) 788 (let (res)
@@ -671,13 +800,12 @@ See `custom-known-themes' for a list of known themes."
671 (eq (cadr theme-setting) symbol)) 800 (eq (cadr theme-setting) symbol))
672 (setq res theme-setting))) 801 (setq res theme-setting)))
673 (put theme 'theme-settings 802 (put theme 'theme-settings
674 (cons (list prop symbol theme mode value) 803 (cons (list prop symbol theme value)
675 (delq res theme-settings))) 804 (delq res theme-settings)))
676 (setcar (cdr setting) mode) 805 (setcar (cdr setting) value))
677 (setcar (cddr setting) value))
678 ;; Add a new setting. 806 ;; Add a new setting.
679 ;; If the user changed the value outside of Customize, we 807 ;; If the user changed the value outside of Customize, we
680 ;; first save the current value to a fake theme, `standard'. 808 ;; first save the current value to a fake theme, `changed'.
681 ;; This ensures that the user-set value comes back if the 809 ;; This ensures that the user-set value comes back if the
682 ;; theme is later disabled. 810 ;; theme is later disabled.
683 (if (null old) 811 (if (null old)
@@ -686,23 +814,16 @@ See `custom-known-themes' for a list of known themes."
686 (or (null (get symbol 'standard-value)) 814 (or (null (get symbol 'standard-value))
687 (not (equal (eval (car (get symbol 'standard-value))) 815 (not (equal (eval (car (get symbol 'standard-value)))
688 (symbol-value symbol))))) 816 (symbol-value symbol)))))
689 (setq old (list (list 'standard 'set (symbol-value symbol)))) 817 (setq old (list (list 'changed (symbol-value symbol))))
690 (if (facep symbol) 818 (if (facep symbol)
691 (setq old (list (list 'standard 'set (list 819 (setq old (list (list 'changed (list
692 (append '(t) (custom-face-attributes-get symbol nil))))))))) 820 (append '(t) (custom-face-attributes-get symbol nil)))))))))
693 (put symbol prop (cons (list theme mode value) old)) 821 (put symbol prop (cons (list theme value) old))
694 (put theme 'theme-settings 822 (put theme 'theme-settings
695 (cons (list prop symbol theme mode value) 823 (cons (list prop symbol theme value)
696 theme-settings)))))) 824 theme-settings))))))
697
698(defvar custom-local-buffer nil
699 "Non-nil, in a Customization buffer, means customize a specific buffer.
700If this variable is non-nil, it should be a buffer,
701and it means customize the local bindings of that buffer.
702This variable is a permanent local, and it normally has a local binding
703in every Customization buffer.")
704(put 'custom-local-buffer 'permanent-local t)
705 825
826
706(defun custom-set-variables (&rest args) 827(defun custom-set-variables (&rest args)
707 "Install user customizations of variable values specified in ARGS. 828 "Install user customizations of variable values specified in ARGS.
708These settings are registered as theme `user'. 829These settings are registered as theme `user'.
@@ -719,15 +840,6 @@ handle SYMBOL properly.
719COMMENT is a comment string about SYMBOL." 840COMMENT is a comment string about SYMBOL."
720 (apply 'custom-theme-set-variables 'user args)) 841 (apply 'custom-theme-set-variables 'user args))
721 842
722(defun custom-reevaluate-setting (symbol)
723 "Reset the value of SYMBOL by re-evaluating its saved or standard value.
724Use the :set function to do so. This is useful for customizable options
725that are defined before their standard value can really be computed.
726E.g. dumped variables whose default depends on run-time information."
727 (funcall (or (get symbol 'custom-set) 'set-default)
728 symbol
729 (eval (car (or (get symbol 'saved-value) (get symbol 'standard-value))))))
730
731(defun custom-theme-set-variables (theme &rest args) 843(defun custom-theme-set-variables (theme &rest args)
732 "Initialize variables for theme THEME according to settings in ARGS. 844 "Initialize variables for theme THEME according to settings in ARGS.
733Each of the arguments in ARGS should be a list of this form: 845Each of the arguments in ARGS should be a list of this form:
@@ -742,16 +854,6 @@ REQUEST is a list of features we must require in order to
742handle SYMBOL properly. 854handle SYMBOL properly.
743COMMENT is a comment string about SYMBOL. 855COMMENT is a comment string about SYMBOL.
744 856
745Several properties of THEME and SYMBOL are used in the process:
746
747If THEME's property `theme-immediate' is non-nil, this is equivalent of
748providing the NOW argument to all symbols in the argument list:
749evaluate each EXP and set the corresponding SYMBOL. However,
750there's a difference in the handling of SYMBOL's property
751`force-value': if NOW is non-nil, SYMBOL's property `force-value' is set to
752the symbol `rogue', else if THEME's property `theme-immediate' is non-nil,
753SYMBOL's property `force-value' is set to the symbol `immediate'.
754
755EXP itself is saved unevaluated as SYMBOL property `saved-value' and 857EXP itself is saved unevaluated as SYMBOL property `saved-value' and
756in SYMBOL's list property `theme-value' \(using `custom-push-theme')." 858in SYMBOL's list property `theme-value' \(using `custom-push-theme')."
757 (custom-check-theme theme) 859 (custom-check-theme theme)
@@ -814,133 +916,34 @@ in SYMBOL's list property `theme-value' \(using `custom-push-theme')."
814 (custom-push-theme 'theme-value symbol theme 'set value)) 916 (custom-push-theme 'theme-value symbol theme 'set value))
815 (setq args (cdr (cdr args))))))) 917 (setq args (cdr (cdr args)))))))
816 918
817(defun custom-set-default (variable value)
818 "Default :set function for a customizable variable.
819Normally, this sets the default value of VARIABLE to VALUE,
820but if `custom-local-buffer' is non-nil,
821this sets the local binding in that buffer instead."
822 (if custom-local-buffer
823 (with-current-buffer custom-local-buffer
824 (set variable value))
825 (set-default variable value)))
826
827(defun custom-set-minor-mode (variable value)
828 ":set function for minor mode variables.
829Normally, this sets the default value of VARIABLE to nil if VALUE
830is nil and to t otherwise,
831but if `custom-local-buffer' is non-nil,
832this sets the local binding in that buffer instead."
833 (if custom-local-buffer
834 (with-current-buffer custom-local-buffer
835 (funcall variable (if value 1 0)))
836 (funcall variable (if value 1 0))))
837
838(defun custom-quote (sexp)
839 "Quote SEXP iff it is not self quoting."
840 (if (or (memq sexp '(t nil))
841 (keywordp sexp)
842 (and (listp sexp)
843 (memq (car sexp) '(lambda)))
844 (stringp sexp)
845 (numberp sexp)
846 (vectorp sexp)
847;;; (and (fboundp 'characterp)
848;;; (characterp sexp))
849 )
850 sexp
851 (list 'quote sexp)))
852
853(defun customize-mark-to-save (symbol)
854 "Mark SYMBOL for later saving.
855
856If the default value of SYMBOL is different from the standard value,
857set the `saved-value' property to a list whose car evaluates to the
858default value. Otherwise, set it to nil.
859
860To actually save the value, call `custom-save-all'.
861
862Return non-nil iff the `saved-value' property actually changed."
863 (let* ((get (or (get symbol 'custom-get) 'default-value))
864 (value (funcall get symbol))
865 (saved (get symbol 'saved-value))
866 (standard (get symbol 'standard-value))
867 (comment (get symbol 'customized-variable-comment)))
868 ;; Save default value iff different from standard value.
869 (if (or (null standard)
870 (not (equal value (condition-case nil
871 (eval (car standard))
872 (error nil)))))
873 (put symbol 'saved-value (list (custom-quote value)))
874 (put symbol 'saved-value nil))
875 ;; Clear customized information (set, but not saved).
876 (put symbol 'customized-value nil)
877 ;; Save any comment that might have been set.
878 (when comment
879 (put symbol 'saved-variable-comment comment))
880 (not (equal saved (get symbol 'saved-value)))))
881
882(defun customize-mark-as-set (symbol)
883 "Mark current value of SYMBOL as being set from customize.
884
885If the default value of SYMBOL is different from the saved value if any,
886or else if it is different from the standard value, set the
887`customized-value' property to a list whose car evaluates to the
888default value. Otherwise, set it to nil.
889
890Return non-nil iff the `customized-value' property actually changed."
891 (let* ((get (or (get symbol 'custom-get) 'default-value))
892 (value (funcall get symbol))
893 (customized (get symbol 'customized-value))
894 (old (or (get symbol 'saved-value) (get symbol 'standard-value))))
895 ;; Mark default value as set iff different from old value.
896 (if (or (null old)
897 (not (equal value (condition-case nil
898 (eval (car old))
899 (error nil)))))
900 (put symbol 'customized-value (list (custom-quote value)))
901 (put symbol 'customized-value nil))
902 ;; Changed?
903 (not (equal customized (get symbol 'customized-value)))))
904 919
905;;; Defining themes. 920;;; Defining themes.
906 921
907;; deftheme is used at the beginning of the file that records a theme. 922;; A theme file should be named `THEME-theme.el' (where THEME is the theme
923;; name), and found in either `custom-theme-directory' or the load path.
924;; It has the following format:
925;;
926;; (deftheme THEME
927;; DOCSTRING)
928;;
929;; (custom-theme-set-variables
930;; 'THEME
931;; [THEME-VARIABLES])
932;;
933;; (custom-theme-set-faces
934;; 'THEME
935;; [THEME-FACES])
936;;
937;; (provide-theme 'THEME)
908 938
909(defmacro deftheme (theme &optional doc &rest args)
910 "Declare custom theme THEME.
911The optional argument DOC is a doc string describing the theme.
912The remaining arguments should have the form
913 939
914 [KEYWORD VALUE]... 940;; The IGNORED arguments to deftheme come from the XEmacs theme code, where
941;; they were used to supply keyword-value pairs like `:immediate',
942;; `:variable-reset-string', etc. We don't use any of these, so ignore them.
915 943
916The following KEYWORD's are defined: 944(defmacro deftheme (theme &optional doc &rest ignored)
917 945 "Declare THEME to be a Custom theme.
918:short-description 946The optional argument DOC is a doc string describing the theme.
919 VALUE is a short (one line) description of the theme. If not
920 given, DOC is used.
921:immediate
922 If VALUE is non-nil, variables specified in this theme are set
923 immediately when loading the theme.
924:variable-set-string
925 VALUE is a string used to indicate that a variable takes its
926 setting from this theme. It is passed to FORMAT with the name
927 of the theme as an additional argument. If not given, a
928 generic description is used.
929:variable-reset-string
930 VALUE is a string used in the case a variable has been forced
931 to its value in this theme. It is passed to FORMAT with the
932 name of the theme as an additional argument. If not given, a
933 generic description is used.
934:face-set-string
935 VALUE is a string used to indicate that a face takes its
936 setting from this theme. It is passed to FORMAT with the name
937 of the theme as an additional argument. If not given, a
938 generic description is used.
939:face-reset-string
940 VALUE is a string used in the case a face has been forced to
941 its value in this theme. It is passed to FORMAT with the name
942 of the theme as an additional argument. If not given, a
943 generic description is used.
944 947
945Any theme `foo' should be defined in a file called `foo-theme.el'; 948Any theme `foo' should be defined in a file called `foo-theme.el';
946see `custom-make-theme-feature' for more information." 949see `custom-make-theme-feature' for more information."
@@ -948,42 +951,17 @@ see `custom-make-theme-feature' for more information."
948 ;; It is better not to use backquote in this file, 951 ;; It is better not to use backquote in this file,
949 ;; because that makes a bootstrapping problem 952 ;; because that makes a bootstrapping problem
950 ;; if you need to recompile all the Lisp files using interpreted code. 953 ;; if you need to recompile all the Lisp files using interpreted code.
951 (nconc (list 'custom-declare-theme 954 (list 'custom-declare-theme (list 'quote theme) (list 'quote feature) doc)))
952 (list 'quote theme)
953 (list 'quote feature)
954 doc)
955 args)))
956 955
957(defun custom-declare-theme (theme feature &optional doc &rest args) 956(defun custom-declare-theme (theme feature &optional doc &rest ignored)
958 "Like `deftheme', but THEME is evaluated as a normal argument. 957 "Like `deftheme', but THEME is evaluated as a normal argument.
959FEATURE is the feature this theme provides. This symbol is created 958FEATURE is the feature this theme provides. Normally, this is a symbol
960from THEME by `custom-make-theme-feature'." 959created from THEME by `custom-make-theme-feature'."
960 (if (memq theme '(user changed))
961 (error "Custom theme cannot be named %S" theme))
961 (add-to-list 'custom-known-themes theme) 962 (add-to-list 'custom-known-themes theme)
962 (put theme 'theme-feature feature) 963 (put theme 'theme-feature feature)
963 (when doc 964 (when doc (put theme 'theme-documentation doc)))
964 (put theme 'theme-documentation doc))
965 (while args
966 (let ((arg (car args)))
967 (setq args (cdr args))
968 (unless (symbolp arg)
969 (error "Junk in args %S" args))
970 (let ((keyword arg)
971 (value (car args)))
972 (unless args
973 (error "Keyword %s is missing an argument" keyword))
974 (setq args (cdr args))
975 (cond ((eq keyword :short-description)
976 (put theme 'theme-short-description value))
977 ((eq keyword :immediate)
978 (put theme 'theme-immediate value))
979 ((eq keyword :variable-set-string)
980 (put theme 'theme-variable-set-string value))
981 ((eq keyword :variable-reset-string)
982 (put theme 'theme-variable-reset-string value))
983 ((eq keyword :face-set-string)
984 (put theme 'theme-face-set-string value))
985 ((eq keyword :face-reset-string)
986 (put theme 'theme-face-reset-string value)))))))
987 965
988(defun custom-make-theme-feature (theme) 966(defun custom-make-theme-feature (theme)
989 "Given a symbol THEME, create a new symbol by appending \"-theme\". 967 "Given a symbol THEME, create a new symbol by appending \"-theme\".
@@ -998,38 +976,6 @@ Every theme X has a property `provide-theme' whose value is \"X-theme\".
998 976
999;;; Loading themes. 977;;; Loading themes.
1000 978
1001;; The variable and face settings of a theme are recorded in
1002;; the `theme-settings' property of the theme name.
1003;; This property's value is a list of elements, each of the form
1004;; (PROP SYMBOL THEME MODE VALUE), where PROP is `theme-value' or `theme-face'
1005;; and SYMBOL is the face or variable name.
1006;; THEME is the theme name itself; that's redundant, but simplifies things.
1007;; MODE is `set' or `reset'.
1008;; If MODE is `set', then VALUE is an expression that specifies the
1009;; theme's setting for SYMBOL.
1010;; If MODE is `reset', then VALUE is another theme,
1011;; and it means to use the value from that theme.
1012
1013;; Each variable has a `theme-value' property that describes all the
1014;; settings of enabled themes that apply to it.
1015;; Each face name has a `theme-face' property that describes all the
1016;; settings of enabled themes that apply to it.
1017;; The property value is a list of settings, each with the form
1018;; (THEME MODE VALUE). THEME, MODE and VALUE are as above.
1019;; Each of these lists is ordered by decreasing theme precedence.
1020;; Thus, the first element is always the one that is in effect.
1021
1022;; Disabling a theme removes its settings from the `theme-value' and
1023;; `theme-face' properties, but the theme's own `theme-settings'
1024;; property remains unchanged.
1025
1026;; Loading a theme implicitly enables it. Enabling a theme adds its
1027;; settings to the symbols' `theme-value' and `theme-face' properties,
1028;; or moves them to the front of those lists if they're already present.
1029
1030(defvar custom-loaded-themes nil
1031 "Custom themes that have been loaded.")
1032
1033(defcustom custom-theme-directory 979(defcustom custom-theme-directory
1034 (if (eq system-type 'ms-dos) 980 (if (eq system-type 'ms-dos)
1035 ;; MS-DOS cannot have initial dot. 981 ;; MS-DOS cannot have initial dot.
@@ -1043,76 +989,39 @@ into this directory."
1043 :group 'customize 989 :group 'customize
1044 :version "22.1") 990 :version "22.1")
1045 991
1046(defun custom-theme-loaded-p (theme)
1047 "Return non-nil if THEME has been loaded."
1048 (memq theme custom-loaded-themes))
1049
1050(defun provide-theme (theme) 992(defun provide-theme (theme)
1051 "Indicate that this file provides THEME, and mark it as enabled. 993 "Indicate that this file provides THEME.
1052Add THEME to `custom-loaded-themes' and `custom-enabled-themes', 994This calls `provide' to provide the feature name stored in THEME's
1053and `provide' the feature name stored in THEME's property `theme-feature'. 995property `theme-feature' (which is usually a symbol created by
1054 996`custom-make-theme-feature')."
1055Usually the `theme-feature' property contains a symbol created 997 (if (memq theme '(user changed))
1056by `custom-make-theme-feature'." 998 (error "Custom theme cannot be named %S" theme))
1057 (if (eq theme 'user)
1058 (error "Custom theme cannot be named `user'"))
1059 (custom-check-theme theme) 999 (custom-check-theme theme)
1060 (provide (get theme 'theme-feature)) 1000 (provide (get theme 'theme-feature))
1061 (push theme custom-loaded-themes) 1001 ;; Loading a theme also enables it.
1062 ;; Loading a theme also installs its settings,
1063 ;; so mark it as "enabled".
1064 (push theme custom-enabled-themes) 1002 (push theme custom-enabled-themes)
1065 ;; `user' must always be the highest-precedence enabled theme. 1003 ;; `user' must always be the highest-precedence enabled theme.
1066 ;; Make that remain true. (This has the effect of making user settings 1004 ;; Make that remain true. (This has the effect of making user settings
1067 ;; override the ones just loaded, too.) 1005 ;; override the ones just loaded, too.)
1068 (enable-theme 'user)) 1006 (let ((custom-enabling-themes t))
1007 (enable-theme 'user)))
1069 1008
1070(defun load-theme (theme) 1009(defun load-theme (theme)
1071 "Try to load a theme's settings from its file. 1010 "Load a theme's settings from its file.
1072This also enables the theme; use `disable-theme' to disable it." 1011This also enables the theme; use `disable-theme' to disable it."
1073
1074 ;; THEME's feature is stored in THEME's `theme-feature' property.
1075 ;; Usually the `theme-feature' property contains a symbol created
1076 ;; by `custom-make-theme-feature'.
1077
1078 ;; Note we do no check for validity of the theme here. 1012 ;; Note we do no check for validity of the theme here.
1079 ;; This allows to pull in themes by a file-name convention 1013 ;; This allows to pull in themes by a file-name convention
1080 (interactive "SCustom theme name: ") 1014 (interactive "SCustom theme name: ")
1015 ;; If reloading, clear out the old theme settings.
1016 (when (custom-theme-p theme)
1017 (disable-theme theme)
1018 (put theme 'theme-settings nil)
1019 (put theme 'theme-feature nil)
1020 (put theme 'theme-documentation nil))
1081 (let ((load-path (if (file-directory-p custom-theme-directory) 1021 (let ((load-path (if (file-directory-p custom-theme-directory)
1082 (cons custom-theme-directory load-path) 1022 (cons custom-theme-directory load-path)
1083 load-path))) 1023 load-path)))
1084 (require (or (get theme 'theme-feature) 1024 (load (symbol-name (custom-make-theme-feature theme)))))
1085 (custom-make-theme-feature theme)))))
1086
1087;;; How to load and enable various themes as part of `user'.
1088
1089(defun custom-theme-load-themes (by-theme &rest body)
1090 "Load the themes specified by BODY.
1091Record them as required by theme BY-THEME.
1092
1093BODY is a sequence of either
1094
1095THEME
1096 Load THEME and enable it.
1097\(reset THEME)
1098 Undo all the settings made by THEME
1099\(hidden THEME)
1100 Load THEME but do not enable it.
1101
1102All the themes loaded for BY-THEME are recorded in BY-THEME's property
1103`theme-loads-themes'."
1104 (custom-check-theme by-theme)
1105 (let ((themes-loaded (get by-theme 'theme-loads-themes)))
1106 (dolist (theme body)
1107 (cond ((and (consp theme) (eq (car theme) 'reset))
1108 (disable-theme (cadr theme)))
1109 ((and (consp theme) (eq (car theme) 'hidden))
1110 (load-theme (cadr theme))
1111 (disable-theme (cadr theme)))
1112 (t
1113 (load-theme theme)))
1114 (push theme themes-loaded))
1115 (put by-theme 'theme-loads-themes themes-loaded)))
1116 1025
1117;;; Enabling and disabling loaded themes. 1026;;; Enabling and disabling loaded themes.
1118 1027
@@ -1123,25 +1032,26 @@ All the themes loaded for BY-THEME are recorded in BY-THEME's property
1123The newly enabled theme gets the highest precedence (after `user'). 1032The newly enabled theme gets the highest precedence (after `user').
1124If it is already enabled, just give it highest precedence (after `user'). 1033If it is already enabled, just give it highest precedence (after `user').
1125 1034
1126This signals an error if THEME does not specify any theme 1035If THEME does not specify any theme settings, this tries to load
1127settings. Theme settings are set using `load-theme'." 1036the theme from its theme file, by calling `load-theme'."
1128 (interactive "SEnable Custom theme: ") 1037 (interactive "SEnable Custom theme: ")
1129 (unless (or (eq theme 'user) (memq theme custom-loaded-themes)) 1038 (if (not (custom-theme-p theme))
1130 (error "Theme %s not defined" (symbol-name theme))) 1039 (load-theme theme)
1131 (let ((settings (get theme 'theme-settings))) 1040 ;; This could use a bit of optimization -- cyd
1132 (dolist (s settings) 1041 (let ((settings (get theme 'theme-settings)))
1133 (let* ((prop (car s)) 1042 (dolist (s settings)
1134 (symbol (cadr s)) 1043 (let* ((prop (car s))
1135 (spec-list (get symbol prop))) 1044 (symbol (cadr s))
1136 (put symbol prop (cons (cddr s) (assq-delete-all theme spec-list))) 1045 (spec-list (get symbol prop)))
1137 (if (eq prop 'theme-value) 1046 (put symbol prop (cons (cddr s) (assq-delete-all theme spec-list)))
1138 (custom-theme-recalc-variable symbol) 1047 (if (eq prop 'theme-value)
1139 (custom-theme-recalc-face symbol))))) 1048 (custom-theme-recalc-variable symbol)
1140 (unless (eq theme 'user) 1049 (custom-theme-recalc-face symbol)))))
1141 (setq custom-enabled-themes 1050 (unless (eq theme 'user)
1142 (cons theme (delq theme custom-enabled-themes))) 1051 (setq custom-enabled-themes
1143 (unless custom-enabling-themes 1052 (cons theme (delq theme custom-enabled-themes)))
1144 (enable-theme 'user)))) 1053 (unless custom-enabling-themes
1054 (enable-theme 'user)))))
1145 1055
1146(defcustom custom-enabled-themes nil 1056(defcustom custom-enabled-themes nil
1147 "List of enabled Custom Themes, highest precedence first. 1057 "List of enabled Custom Themes, highest precedence first.
@@ -1155,28 +1065,36 @@ and always takes precedence over other Custom Themes."
1155 ;; defined in a theme (e.g. `user'). Enabling the theme sets 1065 ;; defined in a theme (e.g. `user'). Enabling the theme sets
1156 ;; custom-enabled-themes, which enables the theme... 1066 ;; custom-enabled-themes, which enables the theme...
1157 (unless custom-enabling-themes 1067 (unless custom-enabling-themes
1158 (let ((custom-enabling-themes t)) 1068 (let ((custom-enabling-themes t) failures)
1159 (setq themes (delq 'user (delete-dups themes))) 1069 (setq themes (delq 'user (delete-dups themes)))
1160 (if (boundp symbol) 1070 (if (boundp symbol)
1161 (dolist (theme (symbol-value symbol)) 1071 (dolist (theme (symbol-value symbol))
1162 (if (not (memq theme themes)) 1072 (if (not (memq theme themes))
1163 (disable-theme theme)))) 1073 (disable-theme theme))))
1164 (dolist (theme (reverse themes)) 1074 (dolist (theme (reverse themes))
1165 (if (or (custom-theme-loaded-p theme) (eq theme 'user)) 1075 (condition-case nil
1166 (enable-theme theme) 1076 (enable-theme theme)
1167 (load-theme theme))) 1077 (error (progn (push theme failures)
1078 (setq themes (delq theme themes))))))
1168 (enable-theme 'user) 1079 (enable-theme 'user)
1169 (custom-set-default symbol themes))))) 1080 (custom-set-default symbol themes)
1081 (if failures
1082 (message "Failed to enable themes: %s"
1083 (mapconcat 'symbol-name failures " ")))))))
1170 1084
1171(defun custom-theme-enabled-p (theme) 1085(defsubst custom-theme-enabled-p (theme)
1172 "Return non-nil if THEME is enabled." 1086 "Return non-nil if THEME is enabled."
1173 (memq theme custom-enabled-themes)) 1087 (memq theme custom-enabled-themes))
1174 1088
1175(defun disable-theme (theme) 1089(defun disable-theme (theme)
1176 "Disable all variable and face settings defined by THEME. 1090 "Disable all variable and face settings defined by THEME.
1177See `custom-enabled-themes' for a list of enabled themes." 1091See `custom-enabled-themes' for a list of enabled themes."
1178 (interactive "SDisable Custom theme: ") 1092 (interactive (list (intern
1179 (when (memq theme custom-enabled-themes) 1093 (completing-read
1094 "Disable Custom theme: "
1095 (mapcar 'symbol-name custom-enabled-themes)
1096 nil t))))
1097 (when (custom-theme-enabled-p theme)
1180 (let ((settings (get theme 'theme-settings))) 1098 (let ((settings (get theme 'theme-settings)))
1181 (dolist (s settings) 1099 (dolist (s settings)
1182 (let* ((prop (car s)) 1100 (let* ((prop (car s))
@@ -1189,28 +1107,6 @@ See `custom-enabled-themes' for a list of enabled themes."
1189 (setq custom-enabled-themes 1107 (setq custom-enabled-themes
1190 (delq theme custom-enabled-themes)))) 1108 (delq theme custom-enabled-themes))))
1191 1109
1192(defun custom-theme-value (theme setting-list)
1193 "Determine the value specified for THEME according to SETTING-LIST.
1194Returns a list whose car is the specified value, if we
1195find one; nil otherwise.
1196
1197SETTING-LIST is an alist with themes as its key.
1198Each element has the form:
1199
1200 \(THEME MODE VALUE)
1201
1202MODE is either the symbol `set' or the symbol `reset'. See
1203`custom-push-theme' for more information on the format of
1204SETTING-LIST."
1205 ;; Note we do _NOT_ signal an error if the theme is unknown
1206 ;; it might have gone away without the user knowing.
1207 (let ((elt (cdr (assoc theme setting-list))))
1208 (if elt
1209 (if (eq (car elt) 'set)
1210 (cdr elt)
1211 ;; `reset' means refer to another theme's value in the same alist.
1212 (custom-theme-value (cadr elt) setting-list)))))
1213
1214(defun custom-variable-theme-value (variable) 1110(defun custom-variable-theme-value (variable)
1215 "Return (list VALUE) indicating the custom theme value of VARIABLE. 1111 "Return (list VALUE) indicating the custom theme value of VARIABLE.
1216That is to say, it specifies what the value should be according to 1112That is to say, it specifies what the value should be according to
@@ -1219,47 +1115,53 @@ currently enabled custom themes.
1219This function returns nil if no custom theme specifies a value for VARIABLE." 1115This function returns nil if no custom theme specifies a value for VARIABLE."
1220 (let* ((theme-value (get variable 'theme-value))) 1116 (let* ((theme-value (get variable 'theme-value)))
1221 (if theme-value 1117 (if theme-value
1222 (custom-theme-value (car (car theme-value)) theme-value)))) 1118 (cdr (car theme-value)))))
1223 1119
1224(defun custom-theme-recalc-variable (variable) 1120(defun custom-theme-recalc-variable (variable)
1225 "Set VARIABLE according to currently enabled custom themes." 1121 "Set VARIABLE according to currently enabled custom themes."
1226 (let ((valspec (custom-variable-theme-value variable))) 1122 (let ((valspec (custom-variable-theme-value variable)))
1227 (when valspec 1123 (if valspec
1228 (put variable 'saved-value valspec)) 1124 (put variable 'saved-value valspec)
1229 (unless valspec
1230 (setq valspec (get variable 'standard-value))) 1125 (setq valspec (get variable 'standard-value)))
1231 (when valspec 1126 (if (and valspec
1232 (if (or (get 'force-value variable) (default-boundp variable)) 1127 (or (get variable 'force-value)
1233 (funcall (or (get variable 'custom-set) 'set-default) variable 1128 (default-boundp variable)))
1234 (eval (car valspec))))))) 1129 (funcall (or (get variable 'custom-set) 'set-default) variable
1130 (eval (car valspec))))))
1235 1131
1236(defun custom-theme-recalc-face (face) 1132(defun custom-theme-recalc-face (face)
1237 "Set FACE according to currently enabled custom themes." 1133 "Set FACE according to currently enabled custom themes."
1238 (if (facep face) 1134 (if (facep face)
1239 (let ((theme-faces (reverse (get face 'theme-face)))) 1135 (let ((theme-faces (reverse (get face 'theme-face))))
1240 (dolist (spec theme-faces) 1136 (dolist (spec theme-faces)
1241 (face-spec-set face (car (cddr spec))))))) 1137 (face-spec-set face (cadr spec))))))
1242 1138
1139;;; XEmacs compability functions
1140
1141;; In XEmacs, when you reset a Custom Theme, you have to specify the
1142;; theme to reset it to. We just apply the next available theme, so
1143;; just ignore the IGNORED arguments.
1144
1243(defun custom-theme-reset-variables (theme &rest args) 1145(defun custom-theme-reset-variables (theme &rest args)
1244 "Reset the specs in THEME of some variables to their values in other themes. 1146 "Reset some variable settings in THEME to their values in other themes.
1245Each of the arguments ARGS has this form: 1147Each of the arguments ARGS has this form:
1246 1148
1247 (VARIABLE FROM-THEME) 1149 (VARIABLE IGNORED)
1248 1150
1249This means reset VARIABLE to its value in FROM-THEME." 1151This means reset VARIABLE. (The argument IGNORED is ignored)."
1250 (custom-check-theme theme) 1152 (custom-check-theme theme)
1251 (dolist (arg args) 1153 (dolist (arg args)
1252 (custom-push-theme 'theme-value (car arg) theme 'reset (cadr arg)))) 1154 (custom-push-theme 'theme-value (car arg) theme 'reset)))
1253 1155
1254(defun custom-reset-variables (&rest args) 1156(defun custom-reset-variables (&rest args)
1255 "Reset the specs of some variables to their values in certain themes. 1157 "Reset the specs of some variables to their values in other themes.
1256This creates settings in the `user' theme. 1158This creates settings in the `user' theme.
1257 1159
1258Each of the arguments ARGS has this form: 1160Each of the arguments ARGS has this form:
1259 1161
1260 (VARIABLE FROM-THEME) 1162 (VARIABLE IGNORED)
1261 1163
1262This means reset VARIABLE to its value in FROM-THEME." 1164This means reset VARIABLE. (The argument IGNORED is ignored)."
1263 (apply 'custom-theme-reset-variables 'user args)) 1165 (apply 'custom-theme-reset-variables 'user args))
1264 1166
1265;;; The End. 1167;;; The End.
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index 47bcbbcae6c..6219482b12e 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -1,7 +1,7 @@
1;;; bytecomp.el --- compilation of Lisp code into byte code 1;;; bytecomp.el --- compilation of Lisp code into byte code
2 2
3;; Copyright (C) 1985, 1986, 1987, 1992, 1994, 1998, 2000, 2001, 2002, 3;; Copyright (C) 1985, 1986, 1987, 1992, 1994, 1998, 2000, 2001, 2002,
4;; 2003, 2004, 2005 Free Software Foundation, Inc. 4;; 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
5 5
6;; Author: Jamie Zawinski <jwz@lucid.com> 6;; Author: Jamie Zawinski <jwz@lucid.com>
7;; Hallvard Furuseth <hbf@ulrik.uio.no> 7;; Hallvard Furuseth <hbf@ulrik.uio.no>
@@ -3785,7 +3785,15 @@ that suppresses all warnings during execution of BODY."
3785 (push (cons (nth 1 (nth 1 form)) 3785 (push (cons (nth 1 (nth 1 form))
3786 (if constant (nth 1 (nth 2 form)) t)) 3786 (if constant (nth 1 (nth 2 form)) t))
3787 byte-compile-function-environment))) 3787 byte-compile-function-environment)))
3788 (byte-compile-normal-call form)) 3788 ;; We used to jus do: (byte-compile-normal-call form)
3789 ;; But it turns out that this fails to optimize the code.
3790 ;; So instead we now do the same as what other byte-hunk-handlers do,
3791 ;; which is to call back byte-compile-file-form and then return nil.
3792 ;; Except that we can't just call byte-compile-file-form since it would
3793 ;; call us right back.
3794 (byte-compile-keep-pending form)
3795 ;; Return nil so the form is not output twice.
3796 nil)
3789 3797
3790;; Turn off warnings about prior calls to the function being defalias'd. 3798;; Turn off warnings about prior calls to the function being defalias'd.
3791;; This could be smarter and compare those calls with 3799;; This could be smarter and compare those calls with
diff --git a/lisp/font-lock.el b/lisp/font-lock.el
index 7819a0e81cc..4e592da0e9c 100644
--- a/lisp/font-lock.el
+++ b/lisp/font-lock.el
@@ -1,7 +1,7 @@
1;;; font-lock.el --- Electric font lock mode 1;;; font-lock.el --- Electric font lock mode
2 2
3;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 3;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
4;; 2000, 2001, 2002, 2003, 2004 2005 Free Software Foundation, Inc. 4;; 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
5 5
6;; Author: jwz, then rms, then sm 6;; Author: jwz, then rms, then sm
7;; Maintainer: FSF 7;; Maintainer: FSF
@@ -980,6 +980,7 @@ The value of this variable is used when Font Lock mode is turned on."
980(defun font-lock-fontify-buffer () 980(defun font-lock-fontify-buffer ()
981 "Fontify the current buffer the way the function `font-lock-mode' would." 981 "Fontify the current buffer the way the function `font-lock-mode' would."
982 (interactive) 982 (interactive)
983 (font-lock-set-defaults)
983 (let ((font-lock-verbose (or font-lock-verbose (interactive-p)))) 984 (let ((font-lock-verbose (or font-lock-verbose (interactive-p))))
984 (funcall font-lock-fontify-buffer-function))) 985 (funcall font-lock-fontify-buffer-function)))
985 986
@@ -987,6 +988,7 @@ The value of this variable is used when Font Lock mode is turned on."
987 (funcall font-lock-unfontify-buffer-function)) 988 (funcall font-lock-unfontify-buffer-function))
988 989
989(defun font-lock-fontify-region (beg end &optional loudly) 990(defun font-lock-fontify-region (beg end &optional loudly)
991 (font-lock-set-defaults)
990 (funcall font-lock-fontify-region-function beg end loudly)) 992 (funcall font-lock-fontify-region-function beg end loudly))
991 993
992(defun font-lock-unfontify-region (beg end) 994(defun font-lock-unfontify-region (beg end)
@@ -1000,8 +1002,6 @@ The value of this variable is used when Font Lock mode is turned on."
1000 (with-temp-message 1002 (with-temp-message
1001 (when verbose 1003 (when verbose
1002 (format "Fontifying %s..." (buffer-name))) 1004 (format "Fontifying %s..." (buffer-name)))
1003 ;; Make sure we have the right `font-lock-keywords' etc.
1004 (font-lock-set-defaults)
1005 ;; Make sure we fontify etc. in the whole buffer. 1005 ;; Make sure we fontify etc. in the whole buffer.
1006 (save-restriction 1006 (save-restriction
1007 (widen) 1007 (widen)
diff --git a/lisp/info.el b/lisp/info.el
index e3ca18e0ede..386f549d3e2 100644
--- a/lisp/info.el
+++ b/lisp/info.el
@@ -568,8 +568,10 @@ in all the directories in that path."
568 (if (and (stringp file-or-node) (string-match "(.*)" file-or-node)) 568 (if (and (stringp file-or-node) (string-match "(.*)" file-or-node))
569 file-or-node 569 file-or-node
570 (concat "(" file-or-node ")"))) 570 (concat "(" file-or-node ")")))
571 (if (zerop (buffer-size)) 571 (if (and (zerop (buffer-size))
572 (Info-directory)))) 572 (null Info-history))
573 ;; If we just created the Info buffer, go to the directory.
574 (Info-directory))))
573 575
574;;;###autoload 576;;;###autoload
575(defun info-emacs-manual () 577(defun info-emacs-manual ()
@@ -688,11 +690,12 @@ it says do not attempt further (recursive) error recovery."
688 (setq filename (Info-find-file filename)) 690 (setq filename (Info-find-file filename))
689 ;; Go into Info buffer. 691 ;; Go into Info buffer.
690 (or (eq major-mode 'Info-mode) (pop-to-buffer "*info*")) 692 (or (eq major-mode 'Info-mode) (pop-to-buffer "*info*"))
691 ;; Record the node we are leaving. 693 ;; Record the node we are leaving, if we were in one.
692 (if (not no-going-back) 694 (and (not no-going-back)
693 (setq Info-history 695 Info-current-file
694 (cons (list Info-current-file Info-current-node (point)) 696 (setq Info-history
695 Info-history))) 697 (cons (list Info-current-file Info-current-node (point))
698 Info-history)))
696 (Info-find-node-2 filename nodename no-going-back)) 699 (Info-find-node-2 filename nodename no-going-back))
697 700
698;;;###autoload 701;;;###autoload
diff --git a/lisp/language/ind-util.el b/lisp/language/ind-util.el
index da4926ff4c4..141bef2f0ba 100644
--- a/lisp/language/ind-util.el
+++ b/lisp/language/ind-util.el
@@ -821,7 +821,7 @@ Returns new end position."
821 821
822;;;###autoload 822;;;###autoload
823(defun indian-compose-region (from to) 823(defun indian-compose-region (from to)
824 "Compose the region according to `composition-function-table'. " 824 "Compose the region according to `composition-function-table'."
825 (interactive "r") 825 (interactive "r")
826 (save-excursion 826 (save-excursion
827 (save-restriction 827 (save-restriction
diff --git a/lisp/language/mlm-util.el b/lisp/language/mlm-util.el
index 04dfde491d1..e575cfc61f4 100644
--- a/lisp/language/mlm-util.el
+++ b/lisp/language/mlm-util.el
@@ -103,7 +103,7 @@
103;;;###autoload 103;;;###autoload
104(defun malayalam-composition-function (from to pattern &optional string) 104(defun malayalam-composition-function (from to pattern &optional string)
105 "Compose Malayalam characters in REGION, or STRING if specified. 105 "Compose Malayalam characters in REGION, or STRING if specified.
106Assume that the REGION or STRING must fully match the composable 106Assume that the REGION or STRING must fully match the composable
107PATTERN regexp." 107PATTERN regexp."
108 (if string (malayalam-compose-syllable-string string) 108 (if string (malayalam-compose-syllable-string string)
109 (malayalam-compose-syllable-region from to)) 109 (malayalam-compose-syllable-region from to))
@@ -239,7 +239,7 @@ PATTERN regexp."
239 ("$,1@H@m@E(B" . "$,47Y(B") 239 ("$,1@H@m@E(B" . "$,47Y(B")
240 ("$,1@H@m@Q(B" . "$,47b(B") 240 ("$,1@H@m@Q(B" . "$,47b(B")
241 ("$,1@H@a(B" . "$,47k(B") 241 ("$,1@H@a(B" . "$,47k(B")
242 ("$,1@H@m@H@a(B" . "$,47l(B") 242 ("$,1@H@m@H@a(B" . "$,47l(B")
243 243
244 ("$,1@J(B" . "$,46=(B") 244 ("$,1@J(B" . "$,46=(B")
245 ("$,1@J@m@J(B" . "$,478(B") ;; duplicate 245 ("$,1@J@m@J(B" . "$,478(B") ;; duplicate
@@ -401,7 +401,7 @@ PATTERN regexp."
401 (apply 401 (apply
402 'nconc 402 'nconc
403 (mapcar 403 (mapcar
404 (function 404 (function
405 (lambda (x) (list '(5 . 3) x))) ;; default ref. point. 405 (lambda (x) (list '(5 . 3) x))) ;; default ref. point.
406 glyph-str)))) 406 glyph-str))))
407 (compose-region from to glyph-str))))) 407 (compose-region from to glyph-str)))))
diff --git a/lisp/mh-e/ChangeLog b/lisp/mh-e/ChangeLog
index 4f3d56f98c9..1f17d15500e 100644
--- a/lisp/mh-e/ChangeLog
+++ b/lisp/mh-e/ChangeLog
@@ -1,3 +1,118 @@
12006-01-03 Mark D. Baushke <mdb@gnu.org>
2
3 * mh-e.el (mh-delete-a-msg): Fix whitespace nit.
4 * mh-index.el (mh-mairix-execute-search): Fix symbol quote.
5
62006-01-03 Bill Wohler <wohler@newt.com>
7
8 * mh-alias.el (mh-alias-add-alias): Grand message and error string
9 unification. Use single sentence if possible by using semicolon.
10 Don't end message with punctuation. Don't need format with
11 message. Quote messages as in docstrings: use `' around symbols,
12 \" for option choices. Don't use quotes around %s.
13
14 * mh-comp.el (mh-complete-word): Ditto.
15
16 * mh-customize.el (mh-adaptive-cmd-note-flag-check)
17 (mh-scan-format-file-check): Ditto.
18
19 * mh-e.el (mh-refile-or-write-again, mh-previous-unread-msg)
20 (mh-delete-a-msg, mh-refile-a-msg, mh-next-unread-msg)
21 (mh-msg-num-width-to-column): Ditto.
22
23 * mh-identity.el (mh-identity-field-handler): Ditto.
24
25 * mh-index.el (mh-mairix-execute-search)
26 (mh-swish-execute-search, mh-swish++-execute-search)
27 (mh-namazu-execute-search): Ditto.
28
29 * mh-init.el (mh-variant-set): Ditto.
30
31 * mh-mime.el (mh-mh-to-mime-undo, mh-mml-forward-message)
32 (mh-secure-message, mh-mime-display): Ditto.
33
34 * mh-pick.el (mh-search-folder, mh-pick-construct-regexp): Ditto.
35
36 * mh-seq.el (mh-narrow-to-seq, mh-put-msg-in-seq, mh-read-seq)
37 (mh-read-range, mh-thread-container-subject): Ditto.
38
39 * mh-utils.el (mh-x-image-scale-and-display)
40 (mh-prompt-for-folder, mh-handle-process-error)
41 (mh-list-to-string-1): Ditto.
42
43 * mh-comp.el (mh-reply): Use standard default notation in
44 prompts (closes SF #1275933).
45
46 * mh-mime.el (mh-mime-save-parts): Ditto.
47
48 * mh-seq.el (mh-read-seq, mh-read-range): Ditto.
49
50 * mh-customize.el (mh-folder-msg-number): Snow is actually
51 off-white on low color displays which turns to white when bold.
52 This is unreadable on white backgrounds. Use snow with min-colors
53 requirement. Use cyan on low-color displays.
54
55 * mh-init.el (mh-defface-compat): On low-color displays, delete
56 the high-color display rather than simply strip the min-colors
57 requirement since the existing algorithm shadowed the desired
58 display on low-color displays.
59
60 * mh-alias.el (mh-alias-add-alias): Remove leading * from
61 docstring.
62
632006-01-02 Bill Wohler <wohler@newt.com>
64
65 * mh-alias.el (mh-alias-grab-from-field): Remove leading * from
66 docstring. Does this mean something in a defun?
67
68 * mh-customize.el (bw-new-face-to-old, bw-old-face-to-new):
69 Checkdoc fix.
70
71 * mh-e.el (mh-inc-folder): Rename maildrop-name argument to file
72 so it reads better in docstring and manual. Sync docstring with
73 manual.
74
75 * mh-init.el (mh-defface-compat): Remove trailing space (checkdoc).
76
77 * mh-alias.el (mh-alias-apropos): Sync docstring with manual.
78
79 * mh-comp.el (mh-redistribute, mh-to-field, mh-to-fcc)
80 (mh-insert-auto-fields, mh-send-letter, mh-yank-cur-msg)
81 (mh-fully-kill-draft, mh-open-line, mh-letter-complete)
82 (mh-letter-complete-or-space, mh-letter-confirm-address)
83 (mh-letter-next-header-field-or-indent)
84 (mh-letter-previous-header-field): Ditto.
85
86 * mh-customize.el (mh-alias-completion-ignore-case-flag)
87 (mh-default-folder-for-message-function, mh-mml-method-default)
88 (mh-signature-file-name, mh-yank-behavior, mh-show-hook)
89 (mh-show-mode-hook) Ditto.
90
91 * mh-e.el (mh-refile-or-write-again, mh-toggle-showing): Ditto.
92
93 * mh-funcs.el (mh-pipe-msg, mh-sort-folder, mh-undo-folder)
94 (mh-store-msg, mh-store-buffer): Ditto
95
96 * mh-index.el (mh-index-search, mh-index-do-search)
97 (mh-index-next-folder, mh-index-sequenced-messages): Ditto.
98
99 * mh-junk.el (mh-spamassassin-blacklist): Ditto.
100
101 * mh-mime.el (mh-mh-compose-external-compressed-tar)
102 (mh-mh-compose-external-type, mh-mh-to-mime, mh-mh-to-mime-undo)
103 (mh-mml-secure-message-sign, mh-mml-secure-message-encrypt)
104 (mh-mml-secure-message-signencrypt): Ditto
105
106 * mh-pick.el (mh-search-folder): Ditto.
107
108 * mh-seq.el (mh-widen): Ditto.
109
110 * mh-utils.el (mh-show, mh-modify): Ditto.
111
1122006-01-02 Mark D. Baushke <mdb@gnu.org>
113
114 * mh-mime.el (mh-mml-unsecure-message): Remove unused argument.
115
12006-01-01 Bill Wohler <wohler@newt.com> 1162006-01-01 Bill Wohler <wohler@newt.com>
2 117
3 * mh-customize.el: Sync docstrings with manual for faces and sort 118 * mh-customize.el: Sync docstrings with manual for faces and sort
diff --git a/lisp/mh-e/mh-alias.el b/lisp/mh-e/mh-alias.el
index 397cd9ea782..a1bafb3ec51 100644
--- a/lisp/mh-e/mh-alias.el
+++ b/lisp/mh-e/mh-alias.el
@@ -1,7 +1,7 @@
1;;; mh-alias.el --- MH-E mail alias completion and expansion 1;;; mh-alias.el --- MH-E mail alias completion and expansion
2;; 2;;
3;; Copyright (C) 1994, 1995, 1996, 1997, 3;; Copyright (C) 1994, 1995, 1996, 1997,
4;; 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. 4;; 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
5 5
6;; Author: Peter S. Galbraith <psg@debian.org> 6;; Author: Peter S. Galbraith <psg@debian.org>
7;; Maintainer: Bill Wohler <wohler@newt.com> 7;; Maintainer: Bill Wohler <wohler@newt.com>
@@ -548,7 +548,8 @@ folder name hint when filing messages."
548 548
549;;;###mh-autoload 549;;;###mh-autoload
550(defun mh-alias-add-alias (alias address) 550(defun mh-alias-add-alias (alias address)
551 "*Add ALIAS for ADDRESS in personal alias file. 551 "Add ALIAS for ADDRESS in personal alias file.
552
552This function prompts you for an alias and address. If the alias 553This function prompts you for an alias and address. If the alias
553exists already, you will have the choice of inserting the new 554exists already, you will have the choice of inserting the new
554alias before or after the old alias. In the former case, this 555alias before or after the old alias. In the former case, this
@@ -570,7 +571,7 @@ filing messages."
570 (cond 571 (cond
571 ((and (equal alias address-alias) 572 ((and (equal alias address-alias)
572 (equal address alias-address)) 573 (equal address alias-address))
573 (message "Already defined as: %s" alias-address)) 574 (message "Already defined as %s" alias-address))
574 (address-alias 575 (address-alias
575 (if (y-or-n-p (format "Address has alias %s; set new one? " 576 (if (y-or-n-p (format "Address has alias %s; set new one? "
576 address-alias)) 577 address-alias))
@@ -580,7 +581,7 @@ filing messages."
580 581
581;;;###mh-autoload 582;;;###mh-autoload
582(defun mh-alias-grab-from-field () 583(defun mh-alias-grab-from-field ()
583 "*Add alias for the sender of the current message." 584 "Add alias for the sender of the current message."
584 (interactive) 585 (interactive)
585 (mh-alias-reload-maybe) 586 (mh-alias-reload-maybe)
586 (save-excursion 587 (save-excursion
@@ -609,7 +610,7 @@ filing messages."
609 610
610;;;###mh-autoload 611;;;###mh-autoload
611(defun mh-alias-apropos (regexp) 612(defun mh-alias-apropos (regexp)
612 "Show all aliases or addresses that match REGEXP." 613 "Show all aliases or addresses that match a regular expression REGEXP."
613 (interactive "sAlias regexp: ") 614 (interactive "sAlias regexp: ")
614 (if mh-alias-local-users 615 (if mh-alias-local-users
615 (mh-alias-reload-maybe)) 616 (mh-alias-reload-maybe))
diff --git a/lisp/mh-e/mh-comp.el b/lisp/mh-e/mh-comp.el
index 113572153af..9a4c8733959 100644
--- a/lisp/mh-e/mh-comp.el
+++ b/lisp/mh-e/mh-comp.el
@@ -1,7 +1,7 @@
1;;; mh-comp.el --- MH-E functions for composing messages 1;;; mh-comp.el --- MH-E functions for composing messages
2 2
3;; Copyright (C) 1993, 1995, 1997, 3;; Copyright (C) 1993, 1995, 1997,
4;; 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. 4;; 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
5 5
6;; Author: Bill Wohler <wohler@newt.com> 6;; Author: Bill Wohler <wohler@newt.com>
7;; Maintainer: Bill Wohler <wohler@newt.com> 7;; Maintainer: Bill Wohler <wohler@newt.com>
@@ -462,7 +462,7 @@ the message had come from the original sender. When you run this
462command, you are prompted for the TO and CC recipients. The 462command, you are prompted for the TO and CC recipients. The
463default MESSAGE is the current message. 463default MESSAGE is the current message.
464 464
465Also investigate the \\[mh-edit-again] command for another way to 465Also investigate the command \\[mh-edit-again] for another way to
466redistribute messages. 466redistribute messages.
467 467
468See also `mh-redist-full-contents-flag'." 468See also `mh-redist-full-contents-flag'."
@@ -582,7 +582,7 @@ See also `mh-reply-show-message-flag',
582 (let ((minibuffer-help-form 582 (let ((minibuffer-help-form
583 "from => Sender only\nto => Sender and primary recipients\ncc or all => Sender and all recipients")) 583 "from => Sender only\nto => Sender and primary recipients\ncc or all => Sender and all recipients"))
584 (or mh-reply-default-reply-to 584 (or mh-reply-default-reply-to
585 (completing-read "Reply to whom: [from] " 585 (completing-read "Reply to whom (default from): "
586 '(("from") ("to") ("cc") ("all")) 586 '(("from") ("to") ("cc") ("all"))
587 nil 587 nil
588 t))) 588 t)))
@@ -1114,10 +1114,12 @@ lines."
1114;;;###mh-autoload 1114;;;###mh-autoload
1115(defun mh-to-field () 1115(defun mh-to-field ()
1116 "Move to specified header field. 1116 "Move to specified header field.
1117The field is indicated by the previous keystroke (the last keystroke 1117
1118of the command) according to the list in the variable 1118The field is indicated by the previous keystroke (the last
1119`mh-to-field-choices'. Create the field if it does not exist. Set the 1119keystroke of the command) according to the list in the variable
1120mark to point before moving." 1120`mh-to-field-choices'.
1121Create the field if it does not exist.
1122Set the mark to point before moving."
1121 (interactive) 1123 (interactive)
1122 (expand-abbrev) 1124 (expand-abbrev)
1123 (let ((target (cdr (or (assoc (char-to-string (logior last-input-char ?`)) 1125 (let ((target (cdr (or (assoc (char-to-string (logior last-input-char ?`))
@@ -1146,8 +1148,9 @@ mark to point before moving."
1146;;;###mh-autoload 1148;;;###mh-autoload
1147(defun mh-to-fcc (&optional folder) 1149(defun mh-to-fcc (&optional folder)
1148 "Move to \"Fcc:\" header field. 1150 "Move to \"Fcc:\" header field.
1149This command will prompt you for the FOLDER name in which to file a 1151
1150copy of the draft." 1152This command will prompt you for the FOLDER name in which to file
1153a copy of the draft."
1151 (interactive) 1154 (interactive)
1152 (or folder 1155 (or folder
1153 (setq folder (mh-prompt-for-folder 1156 (setq folder (mh-prompt-for-folder
@@ -1333,10 +1336,9 @@ The versions of MH-E, Emacs, and MH are shown."
1333(defun mh-insert-auto-fields (&optional non-interactive) 1336(defun mh-insert-auto-fields (&optional non-interactive)
1334 "Insert custom fields if recipient is found in `mh-auto-fields-list'. 1337 "Insert custom fields if recipient is found in `mh-auto-fields-list'.
1335 1338
1336Sets buffer-local `mh-insert-auto-fields-done-local' when done 1339Sets buffer-local `mh-insert-auto-fields-done-local' if header
1337and inserted something. If NON-INTERACTIVE is non-nil, do not be 1340fields were added. If NON-INTERACTIVE is non-nil, perform actions
1338verbose and only attempt matches if 1341quietly and only if `mh-insert-auto-fields-done-local' is nil.
1339`mh-insert-auto-fields-done-local' is nil.
1340 1342
1341An `identity' entry is skipped if one was already entered 1343An `identity' entry is skipped if one was already entered
1342manually. 1344manually.
@@ -1476,9 +1478,9 @@ command. You can give a prefix argument ARG to monitor the first stage
1476of the delivery\; this output can be found in a buffer called \"*MH-E 1478of the delivery\; this output can be found in a buffer called \"*MH-E
1477Mail Delivery*\". 1479Mail Delivery*\".
1478 1480
1479The hook `mh-before-send-letter-hook' is run at the beginning of the 1481The hook `mh-before-send-letter-hook' is run at the beginning of
1480this command. For example, if you want to check your spelling in your 1482this command. For example, if you want to check your spelling in
1481message before sending, add the `ispell-message' function. 1483your message before sending, add the function `ispell-message'.
1482 1484
1483In case the MH \"send\" program is installed under a different name, 1485In case the MH \"send\" program is installed under a different name,
1484use `mh-send-prog' to tell MH-E the name." 1486use `mh-send-prog' to tell MH-E the name."
@@ -1607,12 +1609,13 @@ text from the message to which you're replying, and inserting
1607`mh-ins-buf-prefix' (`> ') before each line. 1609`mh-ins-buf-prefix' (`> ') before each line.
1608 1610
1609The attribution consists of the sender's name and email address 1611The attribution consists of the sender's name and email address
1610followed by the content of the `mh-extract-from-attribution-verb' 1612followed by the content of the option
1611option. 1613`mh-extract-from-attribution-verb'.
1612 1614
1613You can also turn on the `mh-delete-yanked-msg-window-flag' 1615You can also turn on the option
1614option to delete the window containing the original message after 1616`mh-delete-yanked-msg-window-flag' to delete the window
1615yanking it to make more room on your screen for your reply. 1617containing the original message after yanking it to make more
1618room on your screen for your reply.
1616 1619
1617You can control how the message to which you are replying is 1620You can control how the message to which you are replying is
1618yanked into your reply using `mh-yank-behavior'. 1621yanked into your reply using `mh-yank-behavior'.
@@ -1741,9 +1744,10 @@ Otherwise, simply insert MH-INS-STRING before each line."
1741;;;###mh-autoload 1744;;;###mh-autoload
1742(defun mh-fully-kill-draft () 1745(defun mh-fully-kill-draft ()
1743 "Quit editing and delete draft message. 1746 "Quit editing and delete draft message.
1747
1744If for some reason you are not happy with the draft, you can use 1748If for some reason you are not happy with the draft, you can use
1745the this command to kill the draft buffer and delete the draft 1749this command to kill the draft buffer and delete the draft
1746message. Use the \\[kill-buffer] command if you don't want to 1750message. Use the command \\[kill-buffer] if you don't want to
1747delete the draft message." 1751delete the draft message."
1748 (interactive) 1752 (interactive)
1749 (if (y-or-n-p "Kill draft message? ") 1753 (if (y-or-n-p "Kill draft message? ")
@@ -1771,9 +1775,9 @@ delete the draft message."
1771 1775
1772;;;###mh-autoload 1776;;;###mh-autoload
1773(defun mh-open-line () 1777(defun mh-open-line ()
1774 "Insert a newline and leave point after it. 1778 "Insert a newline and leave point before it.
1775 1779
1776This command is similar to the \\[open-line] command in that it 1780This command is similar to the command \\[open-line] in that it
1777inserts a newline after point. It differs in that it also inserts 1781inserts a newline after point. It differs in that it also inserts
1778the right number of quoting characters and spaces so that the 1782the right number of quoting characters and spaces so that the
1779next line begins in the same column as it was. This is useful 1783next line begins in the same column as it was. This is useful
@@ -1814,7 +1818,7 @@ Any match found replaces the text from BEGIN to END."
1814 ((null completion) 1818 ((null completion)
1815 (ignore-errors 1819 (ignore-errors
1816 (kill-buffer completions-buffer)) 1820 (kill-buffer completions-buffer))
1817 (message "No completion for `%s'" word)) 1821 (message "No completion for %s" word))
1818 ((stringp completion) 1822 ((stringp completion)
1819 (if (equal word completion) 1823 (if (equal word completion)
1820 (with-output-to-temp-buffer completions-buffer 1824 (with-output-to-temp-buffer completions-buffer
@@ -1865,12 +1869,13 @@ Any match found replaces the text from BEGIN to END."
1865 1869
1866(defun mh-letter-complete (arg) 1870(defun mh-letter-complete (arg)
1867 "Perform completion on header field or word preceding point. 1871 "Perform completion on header field or word preceding point.
1872
1868If the field contains addresses (for example, \"To:\" or \"Cc:\") 1873If the field contains addresses (for example, \"To:\" or \"Cc:\")
1869or folders (for example, \"Fcc:\") then this command will 1874or folders (for example, \"Fcc:\") then this command will provide
1870provide alias completion. In the body of the message, this 1875alias completion. In the body of the message, this command runs
1871command runs `mh-letter-complete-function' instead, which is set 1876`mh-letter-complete-function' instead, which is set to
1872to \"'ispell-complete-word\" by default. This command takes a 1877`ispell-complete-word' by default. This command takes a prefix
1873prefix argument ARG that is passed to the 1878argument ARG that is passed to the
1874`mh-letter-complete-function'." 1879`mh-letter-complete-function'."
1875 (interactive "P") 1880 (interactive "P")
1876 (let ((func nil)) 1881 (let ((func nil))
@@ -1883,11 +1888,11 @@ prefix argument ARG that is passed to the
1883 1888
1884(defun mh-letter-complete-or-space (arg) 1889(defun mh-letter-complete-or-space (arg)
1885 "Perform completion or insert space. 1890 "Perform completion or insert space.
1886Turn on the `mh-compose-space-does-completion-flag' option to use
1887this command to perform completion in the header. Otherwise, a
1888space is inserted.
1889 1891
1890ARG is the number of spaces inserted." 1892Turn on the option `mh-compose-space-does-completion-flag' to use
1893this command to perform completion in the header. Otherwise, a
1894space is inserted; use a prefix argument ARG to specify more than
1895one space."
1891 (interactive "p") 1896 (interactive "p")
1892 (let ((func nil) 1897 (let ((func nil)
1893 (end-of-prev (save-excursion 1898 (end-of-prev (save-excursion
@@ -1904,9 +1909,10 @@ ARG is the number of spaces inserted."
1904 1909
1905(defun mh-letter-confirm-address () 1910(defun mh-letter-confirm-address ()
1906 "Flash alias expansion. 1911 "Flash alias expansion.
1907Addresses are separated by a comma\; and when you press the 1912
1908comma, this command flashes the alias expansion in the minibuffer 1913Addresses are separated by a comma\; when you press the comma,
1909if `mh-alias-flash-on-comma' is turned on." 1914this command flashes the alias expansion in the minibuffer if
1915`mh-alias-flash-on-comma' is turned on."
1910 (interactive) 1916 (interactive)
1911 (cond ((not (mh-in-header-p)) (self-insert-command 1)) 1917 (cond ((not (mh-in-header-p)) (self-insert-command 1))
1912 ((eq (cdr (assoc (mh-letter-header-field-at-point) 1918 ((eq (cdr (assoc (mh-letter-header-field-at-point)
@@ -1929,9 +1935,11 @@ downcasing the field name."
1929 1935
1930;;;###mh-autoload 1936;;;###mh-autoload
1931(defun mh-letter-next-header-field-or-indent (arg) 1937(defun mh-letter-next-header-field-or-indent (arg)
1932 "Move to next field or indent depending on point. 1938 "Cycle to next field.
1939
1933Within the header of the message, this command moves between 1940Within the header of the message, this command moves between
1934fields, but skips those fields listed in 1941fields that are highlighted with the face
1942`mh-letter-header-field', skipping those fields listed in
1935`mh-compose-skipped-header-fields'. After the last field, this 1943`mh-compose-skipped-header-fields'. After the last field, this
1936command then moves point to the message body before cycling back 1944command then moves point to the message body before cycling back
1937to the first field. If point is already past the first line of 1945to the first field. If point is already past the first line of
@@ -1969,10 +1977,11 @@ body."
1969;;;###mh-autoload 1977;;;###mh-autoload
1970(defun mh-letter-previous-header-field () 1978(defun mh-letter-previous-header-field ()
1971 "Cycle to the previous header field. 1979 "Cycle to the previous header field.
1980
1972This command moves backwards between the fields and cycles to the 1981This command moves backwards between the fields and cycles to the
1973body of the message after the first field. Unlike the 1982body of the message after the first field. Unlike the command
1974\\[mh-letter-next-header-field-or-indent] command, it will always 1983\\[mh-letter-next-header-field-or-indent], it will always take
1975take point to the last field from anywhere in the body." 1984point to the last field from anywhere in the body."
1976 (interactive) 1985 (interactive)
1977 (let ((header-end (mh-mail-header-end))) 1986 (let ((header-end (mh-mail-header-end)))
1978 (if (>= (point) header-end) 1987 (if (>= (point) header-end)
diff --git a/lisp/mh-e/mh-customize.el b/lisp/mh-e/mh-customize.el
index edd6ee41b01..01b03db63f9 100644
--- a/lisp/mh-e/mh-customize.el
+++ b/lisp/mh-e/mh-customize.el
@@ -1,6 +1,6 @@
1;;; mh-customize.el --- MH-E customization 1;;; mh-customize.el --- MH-E customization
2 2
3;; Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. 3;; Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
4 4
5;; Author: Bill Wohler <wohler@newt.com> 5;; Author: Bill Wohler <wohler@newt.com>
6;; Maintainer: Bill Wohler <wohler@newt.com> 6;; Maintainer: Bill Wohler <wohler@newt.com>
@@ -260,7 +260,7 @@ accordingly."
260 "*Non-nil means don't consider case significant in MH alias completion. 260 "*Non-nil means don't consider case significant in MH alias completion.
261 261
262As MH ignores case in the aliases, so too does MH-E. However, you 262As MH ignores case in the aliases, so too does MH-E. However, you
263may turn this option off to make case significant which can be 263may turn off this option to make case significant which can be
264used to segregate completion of your aliases. You might use 264used to segregate completion of your aliases. You might use
265lowercase for mailing lists and uppercase for people." 265lowercase for mailing lists and uppercase for people."
266 :type 'boolean 266 :type 'boolean
@@ -435,7 +435,7 @@ an alternate view. For example, \"'(\"-nolimit\" \"-textfield\"
435;;; Folder Selection (:group 'mh-folder-selection) 435;;; Folder Selection (:group 'mh-folder-selection)
436 436
437(defcustom mh-default-folder-for-message-function nil 437(defcustom mh-default-folder-for-message-function nil
438 "Function to select a default folder for refiling or \"Fcc\". 438 "Function to select a default folder for refiling or \"Fcc:\".
439 439
440The current buffer is set to the message being refiled with point 440The current buffer is set to the message being refiled with point
441at the start of the message. This function should return the 441at the start of the message. This function should return the
@@ -898,10 +898,11 @@ vanilla \"PGP\" and \"S/MIME\".
898The `pgg' customization group may have some settings which may 898The `pgg' customization group may have some settings which may
899interest you (see Info node `(pgg)'). 899interest you (see Info node `(pgg)').
900 900
901In particular, I set the option `pgg-encrypt-for-me' to t so that all 901In particular, I turn on the option `pgg-encrypt-for-me' so that
902messages I encrypt are encrypted with my public key as well. If you 902all messages I encrypt are encrypted with my public key as well.
903keep a copy of all of your outgoing mail with a \"Fcc:\" header field, 903If you keep a copy of all of your outgoing mail with a \"Fcc:\"
904this setting is vital so that you can read the mail you write!" 904header field, this setting is vital so that you can read the mail
905you write!"
905 :type '(choice (const :tag "PGP (MIME)" "pgpmime") 906 :type '(choice (const :tag "PGP (MIME)" "pgpmime")
906 (const :tag "PGP" "pgp") 907 (const :tag "PGP" "pgp")
907 (const :tag "S/MIME" "smime") 908 (const :tag "S/MIME" "smime")
@@ -925,8 +926,8 @@ said separator). The function `mh-signature-separator-p', which
925reports t if the buffer contains a separator, may be useful as well. 926reports t if the buffer contains a separator, may be useful as well.
926 927
927The signature is inserted into your message with the command 928The signature is inserted into your message with the command
928\\<mh-letter-mode-map>\\[mh-insert-signature] or with the 929\\<mh-letter-mode-map>\\[mh-insert-signature] or with the option
929`mh-identity-list' option." 930`mh-identity-list'."
930 :type 'file 931 :type 'file
931 :group 'mh-letter) 932 :group 'mh-letter)
932 933
@@ -971,33 +972,33 @@ this option doesn't exist."
971(defcustom mh-yank-behavior 'attribution 972(defcustom mh-yank-behavior 'attribution
972 "*Controls which part of a message is yanked by \\<mh-letter-mode-map>\\[mh-yank-cur-msg]. 973 "*Controls which part of a message is yanked by \\<mh-letter-mode-map>\\[mh-yank-cur-msg].
973 974
974To include the entire message, including the entire header, use \"Body 975To include the entire message, including the entire header, use
975and Header\". Use \"Body\" to yank just the body without the header. 976\"Body and Header\". Use \"Body\" to yank just the body without
976To yank only the portion of the message following the point, set this 977the header. To yank only the portion of the message following the
977option to \"Below Point\". 978point, set this option to \"Below Point\".
978 979
979Choose \"Invoke supercite\" to pass the entire message and header 980Choose \"Invoke supercite\" to pass the entire message and header
980through supercite. 981through supercite.
981 982
982If the \"Body With Attribution\" setting is used, then the message 983If the \"Body With Attribution\" setting is used, then the
983minus the header is yanked and a simple attribution line is added at 984message minus the header is yanked and a simple attribution line
984the top using the value of the `mh-extract-from-attribution-verb' 985is added at the top using the value of the option
985option. This is the default. 986`mh-extract-from-attribution-verb'. This is the default.
986 987
987If the \"Invoke supercite\" or \"Body With Attribution\" settings are 988If the \"Invoke supercite\" or \"Body With Attribution\" settings
988used, the \"-noformat\" argument is passed to the \"repl\" program to 989are used, the \"-noformat\" argument is passed to the \"repl\"
989override a \"-filter\" or \"-format\" argument. These settings also 990program to override a \"-filter\" or \"-format\" argument. These
990have \"Automatically\" variants that perform the action automatically 991settings also have \"Automatically\" variants that perform the
991when you reply so that you don't need to use \\[mh-yank-cur-msg] at 992action automatically when you reply so that you don't need to use
992all. Note that this automatic action is only performed if the show 993\\[mh-yank-cur-msg] at all. Note that this automatic action is
993buffer matches the message being replied to. People who use the 994only performed if the show buffer matches the message being
994automatic variants tend to turn on the 995replied to. People who use the automatic variants tend to turn on
995`mh-delete-yanked-msg-window-flag' option as well so that the show 996the option `mh-delete-yanked-msg-window-flag' as well so that the
996window is never displayed. 997show window is never displayed.
997 998
998If the show buffer has a region, the `mh-yank-behavior' option is 999If the show buffer has a region, the option `mh-yank-behavior' is
999ignored unless its value is one of Attribution variants in which case 1000ignored unless its value is one of Attribution variants in which
1000the attribution is added to the yanked region. 1001case the attribution is added to the yanked region.
1001 1002
1002If this option is set to one of the supercite flavors, the hook 1003If this option is set to one of the supercite flavors, the hook
1003`mail-citation-hook' is ignored and `mh-ins-buf-prefix' is not 1004`mail-citation-hook' is ignored and `mh-ins-buf-prefix' is not
@@ -1040,7 +1041,7 @@ Throw an error if user tries to turn on
1040Otherwise, set SYMBOL to VALUE." 1041Otherwise, set SYMBOL to VALUE."
1041 (if (and value 1042 (if (and value
1042 (not (eq mh-scan-format-file t))) 1043 (not (eq mh-scan-format-file t)))
1043 (error "%s %s" "Can't turn on unless mh-scan-format-file" 1044 (error "%s %s" "Can't turn on unless `mh-scan-format-file'"
1044 "is set to \"Use MH-E scan Format\"") 1045 "is set to \"Use MH-E scan Format\"")
1045 (set-default symbol value))) 1046 (set-default symbol value)))
1046 1047
@@ -1051,7 +1052,7 @@ anything but t when `mh-adaptive-cmd-note-flag' is on. Otherwise,
1051set SYMBOL to VALUE." 1052set SYMBOL to VALUE."
1052 (if (and (not (eq value t)) 1053 (if (and (not (eq value t))
1053 (eq mh-adaptive-cmd-note-flag t)) 1054 (eq mh-adaptive-cmd-note-flag t))
1054 (error "%s %s" "You must turn off mh-adaptive-cmd-note-flag" 1055 (error "%s %s" "You must turn off `mh-adaptive-cmd-note-flag'"
1055 "unless you use \"Use MH-E scan Format\"") 1056 "unless you use \"Use MH-E scan Format\"")
1056 (set-default symbol value))) 1057 (set-default symbol value)))
1057 1058
@@ -2460,7 +2461,7 @@ See also `mh-before-quit-hook'."
2460 2461
2461It is the last thing called after messages are displayed. It's 2462It is the last thing called after messages are displayed. It's
2462used to affect the behavior of MH-E in general or when 2463used to affect the behavior of MH-E in general or when
2463`mh-show-mode-hook' is too early." 2464`mh-show-mode-hook' is too early. See `mh-show-mode-hook'."
2464 :type 'hook 2465 :type 'hook
2465 :group 'mh-hooks 2466 :group 'mh-hooks
2466 :group 'mh-show) 2467 :group 'mh-show)
@@ -2470,7 +2471,7 @@ used to affect the behavior of MH-E in general or when
2470 2471
2471This hook is called early on in the process of the message 2472This hook is called early on in the process of the message
2472display. It is usually used to perform some action on the 2473display. It is usually used to perform some action on the
2473message's content." 2474message's content. See `mh-show-hook'."
2474 :type 'hook 2475 :type 'hook
2475 :group 'mh-hooks 2476 :group 'mh-hooks
2476 :group 'mh-show) 2477 :group 'mh-show)
@@ -2535,10 +2536,14 @@ sequence."
2535 :group 'mh-folder) 2536 :group 'mh-folder)
2536 2537
2537(defface mh-folder-msg-number 2538(defface mh-folder-msg-number
2538 '((((class color) (background light)) 2539 (mh-defface-compat
2539 (:foreground "snow4")) 2540 '((((class color) (min-colors 88) (background light))
2540 (((class color) (background dark)) 2541 (:foreground "snow4"))
2541 (:foreground "snow3"))) 2542 (((class color) (min-colors 88) (background dark))
2543 (:foreground "snow3"))
2544 (((class color))
2545 (:foreground "cyan"))))
2546
2542 "Message number face." 2547 "Message number face."
2543 :group 'mh-faces 2548 :group 'mh-faces
2544 :group 'mh-folder) 2549 :group 'mh-folder)
@@ -2802,7 +2807,7 @@ The background and foreground are used in the image."
2802 (setq bw-face-generation 'new)))) 2807 (setq bw-face-generation 'new))))
2803 2808
2804(defun bw-new-face-to-old () 2809(defun bw-new-face-to-old ()
2805 "Sets old faces." 2810 "Set old faces."
2806 (face-spec-set 'mh-folder-body 2811 (face-spec-set 'mh-folder-body
2807 (mh-defface-compat 2812 (mh-defface-compat
2808 '((((class color) (min-colors 88) (background light)) 2813 '((((class color) (min-colors 88) (background light))
@@ -2858,7 +2863,7 @@ The background and foreground are used in the image."
2858 (:bold t))))) 2863 (:bold t)))))
2859 2864
2860(defun bw-old-face-to-new () 2865(defun bw-old-face-to-new ()
2861 "Sets new faces." 2866 "Set new faces."
2862 (face-spec-set 'mh-folder-body 2867 (face-spec-set 'mh-folder-body
2863 '((((class color)) 2868 '((((class color))
2864 (:inherit mh-folder-msg-number)) 2869 (:inherit mh-folder-msg-number))
@@ -2875,7 +2880,9 @@ The background and foreground are used in the image."
2875 '((((class color) (background light)) 2880 '((((class color) (background light))
2876 (:foreground "snow4")) 2881 (:foreground "snow4"))
2877 (((class color) (background dark)) 2882 (((class color) (background dark))
2878 (:foreground "snow3"))))) 2883 (:foreground "snow3"))
2884 (((class color))
2885 (:foreground "cyan")))))
2879 2886
2880 2887
2881;; Local Variables: 2888;; Local Variables:
diff --git a/lisp/mh-e/mh-e.el b/lisp/mh-e/mh-e.el
index 1deb465c1fe..8d0760f331f 100644
--- a/lisp/mh-e/mh-e.el
+++ b/lisp/mh-e/mh-e.el
@@ -2,7 +2,7 @@
2 2
3;; Copyright (C) 1985, 1986, 1987, 1988, 3;; Copyright (C) 1985, 1986, 1987, 1988,
4;; 1990, 1992, 1993, 1994, 1995, 1997, 1999, 4;; 1990, 1992, 1993, 1994, 1995, 1997, 1999,
5;; 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. 5;; 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
6 6
7;; Author: Bill Wohler <wohler@newt.com> 7;; Author: Bill Wohler <wohler@newt.com>
8;; Maintainer: Bill Wohler <wohler@newt.com> 8;; Maintainer: Bill Wohler <wohler@newt.com>
@@ -711,21 +711,18 @@ Use the command \\[mh-show] to show the message normally again."
711 (mh-recenter 0)) 711 (mh-recenter 0))
712 (setq mh-showing-with-headers t))) 712 (setq mh-showing-with-headers t)))
713 713
714(defun mh-inc-folder (&optional maildrop-name folder) 714(defun mh-inc-folder (&optional file folder)
715 "Incorporate new mail into a folder. 715 "Incorporate new mail into a folder.
716 716
717You can incorporate mail from any file into the current folder by 717You can incorporate mail from any file into the current folder by
718specifying a prefix argument; you'll be prompted for the name of 718specifying a prefix argument; you'll be prompted for the name of
719the file to use as well as the destination folder 719the FILE to use as well as the destination FOLDER
720 720
721The hook `mh-inc-folder-hook' is run after incorporating new 721The hook `mh-inc-folder-hook' is run after incorporating new
722mail. Do not call this function from outside MH-E; use 722mail.
723\\[mh-rmail] instead.
724 723
725In a program optional argument MAILDROP-NAME specifies an 724Do not call this function from outside MH-E; use \\[mh-rmail]
726alternate maildrop from the default. The optional argument FOLDER 725instead."
727specifies where to incorporate mail instead of the default named
728by `mh-inbox'."
729 (interactive (list (if current-prefix-arg 726 (interactive (list (if current-prefix-arg
730 (expand-file-name 727 (expand-file-name
731 (read-file-name "inc mail from file: " 728 (read-file-name "inc mail from file: "
@@ -745,7 +742,7 @@ by `mh-inbox'."
745 ((not (eq (current-buffer) (get-buffer folder))) 742 ((not (eq (current-buffer) (get-buffer folder)))
746 (switch-to-buffer folder) 743 (switch-to-buffer folder)
747 (setq mh-previous-window-config config)))) 744 (setq mh-previous-window-config config))))
748 (mh-get-new-mail maildrop-name) 745 (mh-get-new-mail file)
749 (when (and threading-needed-flag 746 (when (and threading-needed-flag
750 (save-excursion 747 (save-excursion
751 (goto-char (point-min)) 748 (goto-char (point-min))
@@ -892,8 +889,10 @@ DONT-UPDATE-LAST-DESTINATION-FLAG is non-nil."
892(defun mh-refile-or-write-again (range &optional interactive-flag) 889(defun mh-refile-or-write-again (range &optional interactive-flag)
893 "Repeat last output command. 890 "Repeat last output command.
894 891
895If you are refiling several messages into the same folder, you can use 892If you are refiling several messages into the same folder, you
896this command to repeat the last refile or write. You can use a range. 893can use this command to repeat the last
894refile (\\[mh-refile-msg]) or write (\\[mh-write-msg-to-file]).
895You can use a range.
897 896
898Check the documentation of `mh-interactive-range' to see how RANGE is 897Check the documentation of `mh-interactive-range' to see how RANGE is
899read in interactive use. 898read in interactive use.
@@ -905,8 +904,7 @@ called interactively."
905 (error "No previous refile or write")) 904 (error "No previous refile or write"))
906 (cond ((eq (car mh-last-destination) 'refile) 905 (cond ((eq (car mh-last-destination) 'refile)
907 (mh-refile-msg range (cdr mh-last-destination)) 906 (mh-refile-msg range (cdr mh-last-destination))
908 (message "%s" (format "Destination folder: %s" 907 (message "Destination folder: %s" (cdr mh-last-destination)))
909 (cdr mh-last-destination))))
910 (t 908 (t
911 (mh-iterate-on-range msg range 909 (mh-iterate-on-range msg range
912 (apply 'mh-write-msg-to-file msg (cdr mh-last-destination))) 910 (apply 'mh-write-msg-to-file msg (cdr mh-last-destination)))
@@ -1006,7 +1004,7 @@ This command can be given a prefix argument COUNT to specify how
1006many unread messages to skip." 1004many unread messages to skip."
1007 (interactive "p") 1005 (interactive "p")
1008 (unless (> count 0) 1006 (unless (> count 0)
1009 (error "The function mh-previous-unread-msg expects positive argument")) 1007 (error "The function `mh-previous-unread-msg' expects positive argument"))
1010 (setq count (1- count)) 1008 (setq count (1- count))
1011 (let ((unread-sequence (cdr (assoc mh-unseen-seq mh-seq-list))) 1009 (let ((unread-sequence (cdr (assoc mh-unseen-seq mh-seq-list)))
1012 (cur-msg (mh-get-msg-num nil))) 1010 (cur-msg (mh-get-msg-num nil)))
@@ -1255,7 +1253,14 @@ the command \\[mh-refile-or-write-again]."
1255 (append-to-file (point) (point-max) output-file)))) 1253 (append-to-file (point) (point-max) output-file))))
1256 1254
1257(defun mh-toggle-showing () 1255(defun mh-toggle-showing ()
1258 "Toggle the scanning mode/showing mode of displaying messages." 1256 "Toggle between MH-Folder and MH-Folder Show modes.
1257
1258This command switches between MH-Folder mode and MH-Folder Show
1259mode. MH-Folder mode turns off the associated show buffer so that
1260you can perform operations on the messages quickly without
1261reading them. This is an excellent way to prune out your junk
1262mail or to refile a group of messages to another folder for later
1263examination."
1259 (interactive) 1264 (interactive)
1260 (if mh-showing-mode 1265 (if mh-showing-mode
1261 (mh-set-scan-mode) 1266 (mh-set-scan-mode)
@@ -1521,7 +1526,7 @@ once when he kept statistics on his mail usage."
1521 (beginning-of-line) 1526 (beginning-of-line)
1522 (setq message (mh-get-msg-num t))) 1527 (setq message (mh-get-msg-num t)))
1523 (if (looking-at mh-scan-refiled-msg-regexp) 1528 (if (looking-at mh-scan-refiled-msg-regexp)
1524 (error "Message %d is refiled. Undo refile before deleting" message)) 1529 (error "Message %d is refiled; undo refile before deleting" message))
1525 (if (looking-at mh-scan-deleted-msg-regexp) 1530 (if (looking-at mh-scan-deleted-msg-regexp)
1526 nil 1531 nil
1527 (mh-set-folder-modified-p t) 1532 (mh-set-folder-modified-p t)
@@ -1541,10 +1546,10 @@ be refiled."
1541 (beginning-of-line) 1546 (beginning-of-line)
1542 (setq message (mh-get-msg-num t))) 1547 (setq message (mh-get-msg-num t)))
1543 (cond ((looking-at mh-scan-deleted-msg-regexp) 1548 (cond ((looking-at mh-scan-deleted-msg-regexp)
1544 (error "Message %d is deleted. Undo delete before moving" message)) 1549 (error "Message %d is deleted; undo delete before moving" message))
1545 ((looking-at mh-scan-refiled-msg-regexp) 1550 ((looking-at mh-scan-refiled-msg-regexp)
1546 (if (y-or-n-p 1551 (if (y-or-n-p
1547 (format "Message %d already refiled. Copy to %s as well? " 1552 (format "Message %d already refiled; copy to %s as well? "
1548 message folder)) 1553 message folder))
1549 (mh-exec-cmd "refile" (mh-get-msg-num t) "-link" 1554 (mh-exec-cmd "refile" (mh-get-msg-num t) "-link"
1550 "-src" mh-current-folder 1555 "-src" mh-current-folder
@@ -1575,7 +1580,7 @@ This command can be given a prefix argument COUNT to specify how
1575many unread messages to skip." 1580many unread messages to skip."
1576 (interactive "p") 1581 (interactive "p")
1577 (unless (> count 0) 1582 (unless (> count 0)
1578 (error "The function mh-next-unread-msg expects positive argument")) 1583 (error "The function `mh-next-unread-msg' expects positive argument"))
1579 (setq count (1- count)) 1584 (setq count (1- count))
1580 (let ((unread-sequence (reverse (cdr (assoc mh-unseen-seq mh-seq-list)))) 1585 (let ((unread-sequence (reverse (cdr (assoc mh-unseen-seq mh-seq-list))))
1581 (cur-msg (mh-get-msg-num nil))) 1586 (cur-msg (mh-get-msg-num nil)))
@@ -1983,8 +1988,8 @@ columns contain the message number, and the column for notations
1983comes after that." 1988comes after that."
1984 (if (eq mh-scan-format-file t) 1989 (if (eq mh-scan-format-file t)
1985 (max (1+ width) 2) 1990 (max (1+ width) 2)
1986 (error "%s %s" "Can't call mh-msg-num-width-to-column" 1991 (error "%s %s" "Can't call `mh-msg-num-width-to-column' when"
1987 "when mh-scan-format-file is not t"))) 1992 "`mh-scan-format-file' is not set to \"Use MH-E scan Format\"")))
1988 1993
1989(defun mh-set-cmd-note (column) 1994(defun mh-set-cmd-note (column)
1990 "Set `mh-cmd-note' to COLUMN. 1995 "Set `mh-cmd-note' to COLUMN.
diff --git a/lisp/mh-e/mh-funcs.el b/lisp/mh-e/mh-funcs.el
index 800ff96b510..4fb64b4cd17 100644
--- a/lisp/mh-e/mh-funcs.el
+++ b/lisp/mh-e/mh-funcs.el
@@ -1,7 +1,7 @@
1;;; mh-funcs.el --- MH-E functions not everyone will use right away 1;;; mh-funcs.el --- MH-E functions not everyone will use right away
2 2
3;; Copyright (C) 1993, 1995, 3;; Copyright (C) 1993, 1995,
4;; 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. 4;; 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
5 5
6;; Author: Bill Wohler <wohler@newt.com> 6;; Author: Bill Wohler <wohler@newt.com>
7;; Maintainer: Bill Wohler <wohler@newt.com> 7;; Maintainer: Bill Wohler <wohler@newt.com>
@@ -214,9 +214,9 @@ Display RANGE after packing, or the entire folder if RANGE is nil."
214 "Pipe message through shell command COMMAND. 214 "Pipe message through shell command COMMAND.
215 215
216You are prompted for the Unix command through which you wish to 216You are prompted for the Unix command through which you wish to
217run your message. If you give an argument INCLUDE-HEADER to this 217run your message. If you give a prefix argument INCLUDE-HEADER to
218command, the message header is included in the text passed to the 218this command, the message header is included in the text passed
219command." 219to the command."
220 (interactive 220 (interactive
221 (list (read-string "Shell command on message: ") current-prefix-arg)) 221 (list (read-string "Shell command on message: ") current-prefix-arg))
222 (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)))
@@ -266,12 +266,11 @@ command."
266 266
267;;;###mh-autoload 267;;;###mh-autoload
268(defun mh-sort-folder (&optional extra-args) 268(defun mh-sort-folder (&optional extra-args)
269 "Sort the messages in the current folder by date. 269 "Sort folder.
270 270
271Calls the MH program sortm to do the work. 271By default, messages are sorted by date. The option
272 272`mh-sortm-args' holds extra arguments to pass on to the command
273The arguments in the list `mh-sortm-args' are passed to sortm if 273\"sortm\" when a prefix argument EXTRA-ARGS is used."
274the optional argument EXTRA-ARGS is given."
275 (interactive "P") 274 (interactive "P")
276 (mh-process-or-undo-commands mh-current-folder) 275 (mh-process-or-undo-commands mh-current-folder)
277 (setq mh-next-direction 'forward) 276 (setq mh-next-direction 'forward)
@@ -288,7 +287,7 @@ the optional argument EXTRA-ARGS is given."
288 287
289;;;###mh-autoload 288;;;###mh-autoload
290(defun mh-undo-folder () 289(defun mh-undo-folder ()
291 "Undo all pending deletes and refiles in current folder." 290 "Undo all refiles and deletes in the current folder."
292 (interactive) 291 (interactive)
293 (cond ((or mh-do-not-confirm-flag 292 (cond ((or mh-do-not-confirm-flag
294 (yes-or-no-p "Undo all commands in folder? ")) 293 (yes-or-no-p "Undo all commands in folder? "))
@@ -310,7 +309,9 @@ however, you have a chance to specify a different extraction
310directory. The next time you use this command, the default 309directory. The next time you use this command, the default
311directory is the last directory you used. If you would like to 310directory is the last directory you used. If you would like to
312change the initial default directory, customize the option 311change the initial default directory, customize the option
313`mh-store-default-directory'." 312`mh-store-default-directory', change the value from \"Current\"
313to \"Directory\", and then enter the name of the directory for
314storing the content of these messages."
314 (interactive (list (let ((udir (or mh-store-default-directory 315 (interactive (list (let ((udir (or mh-store-default-directory
315 default-directory))) 316 default-directory)))
316 (read-file-name "Store message in directory: " 317 (read-file-name "Store message in directory: "
@@ -324,12 +325,9 @@ change the initial default directory, customize the option
324 325
325;;;###mh-autoload 326;;;###mh-autoload
326(defun mh-store-buffer (directory) 327(defun mh-store-buffer (directory)
327 "Store the file(s) contained in the current buffer into DIRECTORY. 328 "Unpack buffer created with \"uudecode\" or \"shar\".
328
329The buffer can contain a shar file or uuencoded file.
330 329
331Default directory is the last directory used, or initially the 330See `mh-store-msg' for a description of DIRECTORY."
332value of `mh-store-default-directory' or the current directory."
333 (interactive (list (let ((udir (or mh-store-default-directory 331 (interactive (list (let ((udir (or mh-store-default-directory
334 default-directory))) 332 default-directory)))
335 (read-file-name "Store buffer in directory: " 333 (read-file-name "Store buffer in directory: "
diff --git a/lisp/mh-e/mh-identity.el b/lisp/mh-e/mh-identity.el
index 52bb8f903fe..1af2563eeda 100644
--- a/lisp/mh-e/mh-identity.el
+++ b/lisp/mh-e/mh-identity.el
@@ -1,6 +1,6 @@
1;;; mh-identity.el --- Multiple identify support for MH-E. 1;;; mh-identity.el --- Multiple identify support for MH-E.
2 2
3;; Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. 3;; Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
4 4
5;; Author: Peter S. Galbraith <psg@debian.org> 5;; Author: Peter S. Galbraith <psg@debian.org>
6;; Maintainer: Bill Wohler <wohler@newt.com> 6;; Maintainer: Bill Wohler <wohler@newt.com>
@@ -127,7 +127,7 @@ character \":\", then it must have a special handler defined in
127valid header field." 127valid header field."
128 (or (cdr (mh-assoc-ignore-case field mh-identity-handlers)) 128 (or (cdr (mh-assoc-ignore-case field mh-identity-handlers))
129 (and (eq (aref field 0) ?:) 129 (and (eq (aref field 0) ?:)
130 (error "Field %s - unknown mh-identity-handler" field)) 130 (error "Field %s not found in `mh-identity-handlers'" field))
131 (cdr (assoc ":default" mh-identity-handlers)) 131 (cdr (assoc ":default" mh-identity-handlers))
132 'mh-identity-handler-default)) 132 'mh-identity-handler-default))
133 133
diff --git a/lisp/mh-e/mh-index.el b/lisp/mh-e/mh-index.el
index c8ec7fb399b..c1a30ac68b2 100644
--- a/lisp/mh-e/mh-index.el
+++ b/lisp/mh-e/mh-index.el
@@ -1,6 +1,6 @@
1;;; mh-index -- MH-E interface to indexing programs 1;;; mh-index -- MH-E interface to indexing programs
2 2
3;; Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. 3;; Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
4 4
5;; Author: Satyaki Das <satyaki@theforce.stanford.edu> 5;; Author: Satyaki Das <satyaki@theforce.stanford.edu>
6;; Maintainer: Bill Wohler <wohler@newt.com> 6;; Maintainer: Bill Wohler <wohler@newt.com>
@@ -359,46 +359,52 @@ construct the base name."
359 &optional window-config) 359 &optional window-config)
360 "Perform an indexed search in an MH mail folder. 360 "Perform an indexed search in an MH mail folder.
361 361
362Use a prefix argument to repeat the search. 362Use a prefix argument to repeat the last search.
363 363
364Unlike regular searches, the prompt for the folder to search can be 364Unlike regular searches, the prompt for the folder to search can
365\"all\" to search all folders; in addition, the search works recursively 365be \"all\" to search all folders; in addition, the search works
366on the listed folder. The search criteria are entered in an MH-Pick 366recursively on the listed folder. The search criteria are entered
367buffer as described in `mh-search-folder'. 367in an MH-Pick buffer as described in `mh-search-folder'.\\<mh-pick-mode-map>
368 368
369To perform the search, type \\<mh-pick-mode-map>\\[mh-do-search]. 369To perform the search, type \\[mh-do-search]. Another difference
370Another difference from the regular searches is that because the 370from the regular searches is that because the search operates on
371search operates on more than one folder, the messages that are found 371more than one folder, the messages that are found are put in a
372are put in a temporary sub-folder of \"+mhe-index\" and are displayed in 372temporary sub-folder of \"+mhe-index\" and are displayed in an
373an MH-Folder buffer. This buffer is special because it displays 373MH-Folder buffer. This buffer is special because it displays
374messages from multiple folders; each set of messages from a given 374messages from multiple folders; each set of messages from a given
375folder has a heading with the folder name. 375folder has a heading with the folder name.\\<mh-folder-mode-map>
376 376
377In addition, the \\<mh-folder-mode-map>\\[mh-index-visit-folder] 377The appearance of the heading can be modified by customizing the
378command can be used to visit the folder of the message at point. 378face `mh-index-folder'. You can jump back and forth between the
379Initially, only the messages that matched the search criteria are 379headings using the commands \\[mh-index-next-folder] and
380displayed in the folder. While the temporary buffer has its own set of 380\\[mh-index-previous-folder].
381message numbers, the actual messages numbers are shown in the visited 381
382folder. Thus, the \\[mh-index-visit-folder] command is useful to find 382In addition, the command \\[mh-index-visit-folder] can be used to
383the actual message number of an interesting message, or to view 383visit the folder of the message at point. Initially, only the
384surrounding messages with the \\[mh-rescan-folder] command. 384messages that matched the search criteria are displayed in the
385 385folder. While the temporary buffer has its own set of message
386Because this folder is temporary, you'll probably get in the habit of 386numbers, the actual messages numbers are shown in the visited
387killing it when you're done with \\[mh-kill-folder]. 387folder. Thus, the command \\[mh-index-visit-folder] is useful to
388 388find the actual message number of an interesting message, or to
389If you have run the \\[mh-search-folder] command, but change your mind 389view surrounding messages with the command \\[mh-rescan-folder].
390while entering the search criteria and actually want to run an indexed 390
391search, then you can use the 391Because this folder is temporary, you'll probably get in the
392\\<mh-pick-mode-map>\\[mh-index-do-search] command in the MH-Pick 392habit of killing it when you're done with
393buffer. 393\\[mh-kill-folder].
394 394
395The \\<mh-folder-mode-map>\\[mh-index-search] command runs the command 395If you have run the command \\[mh-search-folder], but change your
396defined by the `mh-index-program' option. The default value is 396mind while entering the search criteria and actually want to run
397\"Auto-detect\" which means that MH-E will automatically choose one of 397an indexed search, then you can use the command
398\\<mh-pick-mode-map>\\[mh-index-do-search] in the MH-Pick
399buffer.\\<mh-folder-mode-map>
400
401The command \\[mh-index-search] runs the command defined by the
402option `mh-index-program'. The default value is \"Auto-detect\"
403which means that MH-E will automatically choose one of
398\"swish++\", \"swish-e\", \"mairix\", \"namazu\", \"pick\" and 404\"swish++\", \"swish-e\", \"mairix\", \"namazu\", \"pick\" and
399\"grep\" in that order. If, for example, you have both \"swish++\" and 405\"grep\" in that order. If, for example, you have both
400\"mairix\" installed and you want to use \"mairix\", then you can set 406\"swish++\" and \"mairix\" installed and you want to use
401this option to \"mairix\". 407\"mairix\", then you can set this option to \"mairix\".
402 408
403 *NOTE* 409 *NOTE*
404 410
@@ -621,7 +627,7 @@ PROC is used to convert the value to actual data."
621 627
622;;;###mh-autoload 628;;;###mh-autoload
623(defun mh-index-do-search () 629(defun mh-index-do-search ()
624 "Construct appropriate regexp and call `mh-index-search'." 630 "Find messages that match the qualifications in the current pattern buffer."
625 (interactive) 631 (interactive)
626 (unless (mh-index-choose) (error "No indexing program found")) 632 (unless (mh-index-choose) (error "No indexing program found"))
627 (let* ((regexp-list (mh-pick-parse-search-buffer)) 633 (let* ((regexp-list (mh-pick-parse-search-buffer))
@@ -736,8 +742,7 @@ parsed."
736;;;###mh-autoload 742;;;###mh-autoload
737(defun mh-index-next-folder (&optional backward-flag) 743(defun mh-index-next-folder (&optional backward-flag)
738 "Jump to the next folder marker. 744 "Jump to the next folder marker.
739The function is only applicable to folders displaying index search 745
740results.
741With non-nil optional argument BACKWARD-FLAG, jump to the previous 746With non-nil optional argument BACKWARD-FLAG, jump to the previous
742group of results." 747group of results."
743 (interactive "P") 748 (interactive "P")
@@ -1163,7 +1168,7 @@ SEARCH-REGEXP-LIST is used to search."
1163 (set-buffer (get-buffer-create mh-index-temp-buffer)) 1168 (set-buffer (get-buffer-create mh-index-temp-buffer))
1164 (erase-buffer) 1169 (erase-buffer)
1165 (unless mh-mairix-binary 1170 (unless mh-mairix-binary
1166 (error "Set mh-mairix-binary appropriately")) 1171 (error "Set `mh-mairix-binary' appropriately"))
1167 (apply #'call-process mh-mairix-binary nil '(t nil) nil 1172 (apply #'call-process mh-mairix-binary nil '(t nil) nil
1168 "-r" "-f" (format "%s%s/config" mh-user-path mh-mairix-directory) 1173 "-r" "-f" (format "%s%s/config" mh-user-path mh-mairix-directory)
1169 search-regexp-list) 1174 search-regexp-list)
@@ -1305,11 +1310,12 @@ recursively. All parameters ARGS are ignored."
1305 1310
1306;;;###mh-autoload 1311;;;###mh-autoload
1307(defun mh-index-sequenced-messages (folders sequence) 1312(defun mh-index-sequenced-messages (folders sequence)
1308 "Display messages from FOLDERS in SEQUENCE. 1313 "Display messages in any sequence.
1309All messages in the sequence you provide from the folders in 1314
1310`mh-new-messages-folders' are listed. With a prefix argument, 1315All messages from the FOLDERS in `mh-new-messages-folders' in the
1311enter a space-separated list of folders, or nothing to search all 1316SEQUENCE you provide are listed. With a prefix argument, enter a
1312folders." 1317space-separated list of folders at the prompt, or nothing to
1318search all folders."
1313 (interactive 1319 (interactive
1314 (list (if current-prefix-arg 1320 (list (if current-prefix-arg
1315 (split-string (read-string "Search folder(s) (default all): ")) 1321 (split-string (read-string "Search folder(s) (default all): "))
@@ -1440,7 +1446,7 @@ is used to search."
1440 (set-buffer (get-buffer-create mh-index-temp-buffer)) 1446 (set-buffer (get-buffer-create mh-index-temp-buffer))
1441 (erase-buffer) 1447 (erase-buffer)
1442 (unless mh-swish-binary 1448 (unless mh-swish-binary
1443 (error "Set mh-swish-binary appropriately")) 1449 (error "Set `mh-swish-binary' appropriately"))
1444 (call-process mh-swish-binary nil '(t nil) nil 1450 (call-process mh-swish-binary nil '(t nil) nil
1445 "-w" search-regexp 1451 "-w" search-regexp
1446 "-f" (format "%s%s/index" mh-user-path mh-swish-directory)) 1452 "-f" (format "%s%s/index" mh-user-path mh-swish-directory))
@@ -1529,7 +1535,7 @@ used to search."
1529 (set-buffer (get-buffer-create mh-index-temp-buffer)) 1535 (set-buffer (get-buffer-create mh-index-temp-buffer))
1530 (erase-buffer) 1536 (erase-buffer)
1531 (unless mh-swish++-binary 1537 (unless mh-swish++-binary
1532 (error "Set mh-swish++-binary appropriately")) 1538 (error "Set `mh-swish++-binary' appropriately"))
1533 (call-process mh-swish++-binary nil '(t nil) nil 1539 (call-process mh-swish++-binary nil '(t nil) nil
1534 "-m" "10000" 1540 "-m" "10000"
1535 (format "-i%s%s/swish++.index" 1541 (format "-i%s%s/swish++.index"
@@ -1608,7 +1614,7 @@ is used to search."
1608 (unless (file-exists-p namazu-index-directory) 1614 (unless (file-exists-p namazu-index-directory)
1609 (error "Namazu directory %s not present" namazu-index-directory)) 1615 (error "Namazu directory %s not present" namazu-index-directory))
1610 (unless (executable-find mh-namazu-binary) 1616 (unless (executable-find mh-namazu-binary)
1611 (error "Set mh-namazu-binary appropriately")) 1617 (error "Set `mh-namazu-binary' appropriately"))
1612 (set-buffer (get-buffer-create mh-index-temp-buffer)) 1618 (set-buffer (get-buffer-create mh-index-temp-buffer))
1613 (erase-buffer) 1619 (erase-buffer)
1614 (call-process mh-namazu-binary nil '(t nil) nil 1620 (call-process mh-namazu-binary nil '(t nil) nil
diff --git a/lisp/mh-e/mh-init.el b/lisp/mh-e/mh-init.el
index 2818674afae..2297fef6a80 100644
--- a/lisp/mh-e/mh-init.el
+++ b/lisp/mh-e/mh-init.el
@@ -127,13 +127,13 @@ finally GNU mailutils."
127 ((mh-variant-set-variant 'mu-mh) 127 ((mh-variant-set-variant 'mu-mh)
128 (message "%s installed as MH variant" mh-variant-in-use)) 128 (message "%s installed as MH variant" mh-variant-in-use))
129 (t 129 (t
130 (message "No MH variant found on the system!")))) 130 (message "No MH variant found on the system"))))
131 ((member variant valid-list) 131 ((member variant valid-list)
132 (when (not (mh-variant-set-variant variant)) 132 (when (not (mh-variant-set-variant variant))
133 (message "Warning: %s variant not found. Autodetecting..." variant) 133 (message "Warning: %s variant not found. Autodetecting..." variant)
134 (mh-variant-set 'autodetect))) 134 (mh-variant-set 'autodetect)))
135 (t 135 (t
136 (message "Unknown variant. Use %s" 136 (message "Unknown variant; use %s"
137 (mapconcat '(lambda (x) (format "%s" (car x))) 137 (mapconcat '(lambda (x) (format "%s" (car x)))
138 mh-variants " or ")))))) 138 mh-variants " or "))))))
139 139
@@ -334,25 +334,30 @@ there. Otherwise, the images directory is added to the
334 334
335(defun mh-defface-compat (spec) 335(defun mh-defface-compat (spec)
336 "Convert SPEC for defface if necessary to run on older platforms. 336 "Convert SPEC for defface if necessary to run on older platforms.
337Modifies SPEC in place and returns it. See `defface' for the spec definition. 337Modifies SPEC in place and returns it. See `defface' for the spec definition.
338 338
339When `mh-min-colors-defined-flag' is nil, this function finds a 339When `mh-min-colors-defined-flag' is nil, this function finds
340display with a single \"class\" requirement with a \"color\" 340display entries with \"min-colors\" requirements and either
341item, renames the requirement to \"tty\" and moves it to the 341removes the \"min-colors\" requirement or strips the display
342beginning of the list. It then strips any \"min-colors\" 342entirely if the display does not support the number of specified
343requirements." 343colors."
344 (when (not mh-min-colors-defined-flag) 344 (if mh-min-colors-defined-flag
345 ;; Insert ((class tty)) display with ((class color)) attributes. 345 spec
346 (let ((attributes (cdr (assoc '((class color)) spec)))) 346 (let ((cells (display-color-cells))
347 (cons (cons '((class tty)) attributes) spec)) 347 new-spec)
348 ;; Delete ((class color)) display. 348 ;; Remove entries with min-colors, or delete them if we have fewer colors
349 (delq (assoc '((class color)) spec) spec) 349 ;; than they specify.
350 ;; Strip min-colors. 350 (loop for entry in (reverse spec) do
351 (loop for entry in spec do 351 (let ((requirement (if (eq (car entry) t)
352 (when (not (eq (car entry) t)) 352 nil
353 (if (assoc 'min-colors (car entry)) 353 (assoc 'min-colors (car entry)))))
354 (delq (assoc 'min-colors (car entry)) (car entry)))))) 354 (if requirement
355 spec) 355 (when (>= cells (nth 1 requirement))
356 (setq new-spec (cons (cons (delq requirement (car entry))
357 (cdr entry))
358 new-spec)))
359 (setq new-spec (cons entry new-spec)))))
360 new-spec)))
356 361
357(provide 'mh-init) 362(provide 'mh-init)
358 363
diff --git a/lisp/mh-e/mh-junk.el b/lisp/mh-e/mh-junk.el
index 5d2bf87581e..71d3fbf7b8b 100644
--- a/lisp/mh-e/mh-junk.el
+++ b/lisp/mh-e/mh-junk.el
@@ -1,6 +1,6 @@
1;;; mh-junk.el --- Interface to anti-spam measures 1;;; mh-junk.el --- Interface to anti-spam measures
2 2
3;; Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. 3;; Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
4 4
5;; Author: Satyaki Das <satyaki@theforce.stanford.edu>, 5;; Author: Satyaki Das <satyaki@theforce.stanford.edu>,
6;; Bill Wohler <wohler@newt.com> 6;; Bill Wohler <wohler@newt.com>
@@ -108,10 +108,12 @@ RANGE is read in interactive use."
108(defun mh-spamassassin-blacklist (msg) 108(defun mh-spamassassin-blacklist (msg)
109 "Blacklist MSG with SpamAssassin. 109 "Blacklist MSG with SpamAssassin.
110 110
111SpamAssassin is one of the more popular spam filtering programs. Get 111SpamAssassin is one of the more popular spam filtering programs.
112it from your local distribution or from http://spamassassin.org/. 112Get it from your local distribution or from
113http://spamassassin.org/.
113 114
114To use SpamAssassin, add the following recipes to \".procmailrc\": 115To use SpamAssassin, add the following recipes to
116\".procmailrc\":
115 117
116 MAILDIR=$HOME/`mhparam Path` 118 MAILDIR=$HOME/`mhparam Path`
117 119
@@ -130,56 +132,59 @@ To use SpamAssassin, add the following recipes to \".procmailrc\":
130 132
131If you don't use \"spamc\", use \"spamassassin -P -a\". 133If you don't use \"spamc\", use \"spamassassin -P -a\".
132 134
133Note that one of the recipes above throws away messages with a score 135Note that one of the recipes above throws away messages with a
134greater than or equal to 10. Here's how you can determine a value that 136score greater than or equal to 10. Here's how you can determine a
135works best for you. 137value that works best for you.
136 138
137First, run \"spamassassin -t\" on every mail message in your archive and 139First, run \"spamassassin -t\" on every mail message in your
138use Gnumeric to verify that the average plus the standard deviation of 140archive and use Gnumeric to verify that the average plus the
139good mail is under 5, the SpamAssassin default for \"spam\". 141standard deviation of good mail is under 5, the SpamAssassin
142default for \"spam\".
140 143
141Using Gnumeric, sort the messages by score and view the messages with 144Using Gnumeric, sort the messages by score and view the messages
142the highest score. Determine the score which encompasses all of your 145with the highest score. Determine the score which encompasses all
143interesting messages and add a couple of points to be conservative. 146of your interesting messages and add a couple of points to be
144Add that many dots to the \"X-Spam-Level:\" header field above to send 147conservative. Add that many dots to the \"X-Spam-Level:\" header
145messages with that score down the drain. 148field above to send messages with that score down the drain.
146 149
147In the example above, messages with a score of 5-9 are set aside in 150In the example above, messages with a score of 5-9 are set aside
148the \"+spam\" folder for later review. The major weakness of rules-based 151in the \"+spam\" folder for later review. The major weakness of
149filters is a plethora of false positives so it is worthwhile to check. 152rules-based filters is a plethora of false positives so it is
153worthwhile to check.
150 154
151If SpamAssassin classifies a message incorrectly, or is unsure, you 155If SpamAssassin classifies a message incorrectly, or is unsure,
152can use the MH-E commands \\[mh-junk-blacklist] and 156you can use the MH-E commands \\[mh-junk-blacklist] and
153\\[mh-junk-whitelist]. 157\\[mh-junk-whitelist].
154 158
155The \\[mh-junk-blacklist] command adds a \"blacklist_from\" entry to 159The command \\[mh-junk-blacklist] adds a \"blacklist_from\" entry
156\"~/spamassassin/user_prefs\", deletes the message, and sends the 160to \"~/spamassassin/user_prefs\", deletes the message, and sends
157message to the Razor, so that others might not see this spam. If the 161the message to the Razor, so that others might not see this spam.
158\"sa-learn\" command is available, the message is also recategorized as 162If the \"sa-learn\" command is available, the message is also
159spam. 163recategorized as spam.
160 164
161The \\[mh-junk-whitelist] command adds a \"whitelist_from\" rule to the 165The command \\[mh-junk-whitelist] adds a \"whitelist_from\" rule
162\"~/.spamassassin/user_prefs\" file. If the \"sa-learn\" command is 166to the \"~/.spamassassin/user_prefs\" file. If the \"sa-learn\"
163available, the message is also recategorized as ham. 167command is available, the message is also recategorized as ham.
164 168
165Over time, you'll observe that the same host or domain occurs 169Over time, you'll observe that the same host or domain occurs
166repeatedly in the \"blacklist_from\" entries, so you might think that 170repeatedly in the \"blacklist_from\" entries, so you might think
167you could avoid future spam by blacklisting all mail from a particular 171that you could avoid future spam by blacklisting all mail from a
168domain. The utility function `mh-spamassassin-identify-spammers' helps 172particular domain. The utility function
169you do precisely that. This function displays a frequency count of the 173`mh-spamassassin-identify-spammers' helps you do precisely that.
170hosts and domains in the \"blacklist_from\" entries from the last blank 174This function displays a frequency count of the hosts and domains
171line in \"~/.spamassassin/user_prefs\" to the end of the file. This 175in the \"blacklist_from\" entries from the last blank line in
176\"~/.spamassassin/user_prefs\" to the end of the file. This
172information can be used so that you can replace multiple 177information can be used so that you can replace multiple
173\"blacklist_from\" entries with a single wildcard entry such as: 178\"blacklist_from\" entries with a single wildcard entry such as:
174 179
175 blacklist_from *@*amazingoffersdirect2u.com 180 blacklist_from *@*amazingoffersdirect2u.com
176 181
177In versions of SpamAssassin (2.50 and on) that support a Bayesian 182In versions of SpamAssassin (2.50 and on) that support a Bayesian
178classifier, \\[mh-junk-blacklist] uses the \"sa-learn\" program to 183classifier, \\[mh-junk-blacklist] uses the program \"sa-learn\"
179recategorize the message as spam. Neither MH-E, nor SpamAssassin, 184to recategorize the message as spam. Neither MH-E, nor
180rebuilds the database after adding words, so you will need to run 185SpamAssassin, rebuilds the database after adding words, so you
181\"sa-learn --rebuild\" periodically. This can be done by adding the 186will need to run \"sa-learn --rebuild\" periodically. This can be
182following to your crontab: 187done by adding the following to your crontab:
183 188
184 0 * * * * sa-learn --rebuild > /dev/null 2>&1" 189 0 * * * * sa-learn --rebuild > /dev/null 2>&1"
185 (unless mh-spamassassin-executable 190 (unless mh-spamassassin-executable
diff --git a/lisp/mh-e/mh-mime.el b/lisp/mh-e/mh-mime.el
index c028890f6a1..f7377d80b2d 100644
--- a/lisp/mh-e/mh-mime.el
+++ b/lisp/mh-e/mh-mime.el
@@ -1,7 +1,7 @@
1;;; mh-mime.el --- MH-E support for composing MIME messages 1;;; mh-mime.el --- MH-E support for composing MIME messages
2 2
3;; Copyright (C) 1993, 1995, 3;; Copyright (C) 1993, 1995,
4;; 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. 4;; 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
5 5
6;; Author: Bill Wohler <wohler@newt.com> 6;; Author: Bill Wohler <wohler@newt.com>
7;; Maintainer: Bill Wohler <wohler@newt.com> 7;; Maintainer: Bill Wohler <wohler@newt.com>
@@ -318,9 +318,10 @@ set of ATTRIBUTES and an optional COMMENT can also be included."
318;;;###mh-autoload 318;;;###mh-autoload
319(defun mh-mh-compose-anon-ftp (host filename type description) 319(defun mh-mh-compose-anon-ftp (host filename type description)
320 "Add tag to include anonymous ftp reference to a file. 320 "Add tag to include anonymous ftp reference to a file.
321You can even have your message initiate an \"ftp\" transfer when 321
322the recipient reads the message. You are prompted for the remote 322You can have your message initiate an \"ftp\" transfer when the
323HOST and FILENAME, the media TYPE, and the content DESCRIPTION. 323recipient reads the message. You are prompted for the remote HOST
324and FILENAME, the media TYPE, and the content DESCRIPTION.
324 325
325See also \\[mh-mh-to-mime]." 326See also \\[mh-mh-to-mime]."
326 (interactive (list 327 (interactive (list
@@ -334,8 +335,9 @@ See also \\[mh-mh-to-mime]."
334;;;###mh-autoload 335;;;###mh-autoload
335(defun mh-mh-compose-external-compressed-tar (host filename description) 336(defun mh-mh-compose-external-compressed-tar (host filename description)
336 "Add tag to include anonymous ftp reference to a compressed tar file. 337 "Add tag to include anonymous ftp reference to a compressed tar file.
338
337In addition to retrieving the file via anonymous \"ftp\" as per 339In addition to retrieving the file via anonymous \"ftp\" as per
338the \\[mh-mh-compose-anon-ftp] command, the file will also be 340the command \\[mh-mh-compose-anon-ftp], the file will also be
339uncompressed and untarred. You are prompted for the remote HOST 341uncompressed and untarred. You are prompted for the remote HOST
340and FILENAME and the content DESCRIPTION. 342and FILENAME and the content DESCRIPTION.
341 343
@@ -356,6 +358,7 @@ See also \\[mh-mh-to-mime]."
356 attributes parameters 358 attributes parameters
357 comment) 359 comment)
358 "Add tag to refer to a remote file. 360 "Add tag to refer to a remote file.
361
359This command is a general utility for referencing external files. 362This command is a general utility for referencing external files.
360In fact, all of the other commands that insert directives to 363In fact, all of the other commands that insert directives to
361access external files call this command. You are prompted for the 364access external files call this command. You are prompted for the
@@ -435,14 +438,14 @@ Typically, you send a message with attachments just like any other
435message. However, you may take a sneak preview of the MIME encoding if 438message. However, you may take a sneak preview of the MIME encoding if
436you wish by running this command. 439you wish by running this command.
437 440
438If you wish to pass additional arguments to \"mhbuild\" (\"mhn\") to 441If you wish to pass additional arguments to \"mhbuild\" (\"mhn\")
439affect how it builds your message, use the `mh-mh-to-mime-args' 442to affect how it builds your message, use the option
440option. For example, you can build a consistency check into the 443`mh-mh-to-mime-args'. For example, you can build a consistency
441message by setting `mh-mh-to-mime-args' to \"-check\". The recipient 444check into the message by setting `mh-mh-to-mime-args' to
442of your message can then run \"mhbuild -check\" on the 445\"-check\". The recipient of your message can then run \"mhbuild
443message--\"mhbuild\" (\"mhn\") will complain if the message has been 446-check\" on the message--\"mhbuild\" (\"mhn\") will complain if
444corrupted on the way. This command only consults this option when 447the message has been corrupted on the way. This command only
445given a prefix argument EXTRA-ARGS. 448consults this option when given a prefix argument EXTRA-ARGS.
446 449
447The hook `mh-mh-to-mime-hook' is called after the message has been 450The hook `mh-mh-to-mime-hook' is called after the message has been
448formatted. 451formatted.
@@ -484,8 +487,10 @@ This function will quote all such characters."
484;;;###mh-autoload 487;;;###mh-autoload
485(defun mh-mh-to-mime-undo (noconfirm) 488(defun mh-mh-to-mime-undo (noconfirm)
486 "Undo effects of \\[mh-mh-to-mime]. 489 "Undo effects of \\[mh-mh-to-mime].
487Optional non-nil argument NOCONFIRM means don't ask for 490
488confirmation." 491It does this by reverting to a backup file. You are prompted to
492confirm this action, but you can avoid the confirmation by adding
493a prefix argument NOCONFIRM."
489 (interactive "*P") 494 (interactive "*P")
490 (if (null buffer-file-name) 495 (if (null buffer-file-name)
491 (error "Buffer does not seem to be associated with any file")) 496 (error "Buffer does not seem to be associated with any file"))
@@ -500,7 +505,7 @@ confirmation."
500 ".orig"))))) 505 ".orig")))))
501 (setq backup-strings (cdr backup-strings))) 506 (setq backup-strings (cdr backup-strings)))
502 (or backup-strings 507 (or backup-strings
503 (error "Backup file for %s no longer exists!" buffer-file-name)) 508 (error "Backup file for %s no longer exists" buffer-file-name))
504 (or noconfirm 509 (or noconfirm
505 (yes-or-no-p (format "Revert buffer from file %s? " 510 (yes-or-no-p (format "Revert buffer from file %s? "
506 backup-file)) 511 backup-file))
@@ -580,7 +585,7 @@ MESSAGE number."
580 mh-user-path (substring folder 1) msg) 585 mh-user-path (substring folder 1) msg)
581 "message/rfc822" 586 "message/rfc822"
582 description))) 587 description)))
583 (t (error "The message number, %s is not a integer!" msg))))) 588 (t (error "The message number, %s, is not a integer" msg)))))
584 589
585(defvar mh-mml-cryptographic-method-history ()) 590(defvar mh-mml-cryptographic-method-history ())
586 591
@@ -628,9 +633,9 @@ IDENTITY is optionally the default-user-id to use."
628 (let ((valid-methods (list "pgpmime" "pgp" "smime")) 633 (let ((valid-methods (list "pgpmime" "pgp" "smime"))
629 (valid-modes (list "sign" "encrypt" "signencrypt" "none"))) 634 (valid-modes (list "sign" "encrypt" "signencrypt" "none")))
630 (if (not (member method valid-methods)) 635 (if (not (member method valid-methods))
631 (error "Method \"%s\" is invalid" method)) 636 (error "Method %s is invalid" method))
632 (if (not (member mode valid-modes)) 637 (if (not (member mode valid-modes))
633 (error "Mode \"%s\" is invalid" mode)) 638 (error "Mode %s is invalid" mode))
634 (mml-unsecure-message) 639 (mml-unsecure-message)
635 (if (not (string= mode "none")) 640 (if (not (string= mode "none"))
636 (save-excursion 641 (save-excursion
@@ -642,10 +647,9 @@ IDENTITY is optionally the default-user-id to use."
642 (mml-insert-tag 'secure 'method method 'mode mode))))))) 647 (mml-insert-tag 'secure 'method method 'mode mode)))))))
643 648
644;;;###mh-autoload 649;;;###mh-autoload
645(defun mh-mml-unsecure-message (&optional ignore) 650(defun mh-mml-unsecure-message ()
646 "Remove any secure message tags. 651 "Remove any secure message tags."
647The argument IGNORE is not used." 652 (interactive)
648 (interactive "P")
649 (if (not mh-pgp-support-flag) 653 (if (not mh-pgp-support-flag)
650 (error "Your version of Gnus does not support PGP/GPG") 654 (error "Your version of Gnus does not support PGP/GPG")
651 (mml-unsecure-message))) 655 (mml-unsecure-message)))
@@ -655,7 +659,7 @@ The argument IGNORE is not used."
655 "Add tag to sign the message. 659 "Add tag to sign the message.
656 660
657A proper multipart message is created for you when you send the 661A proper multipart message is created for you when you send the
658message. Use the \\[mh-mml-unsecure-message] command to remove 662message. Use the command \\[mh-mml-unsecure-message] to remove
659this tag. Use a prefix argument METHOD to be prompted for one of 663this tag. Use a prefix argument METHOD to be prompted for one of
660the possible security methods (see `mh-mml-method-default')." 664the possible security methods (see `mh-mml-method-default')."
661 (interactive (list (mh-mml-query-cryptographic-method))) 665 (interactive (list (mh-mml-query-cryptographic-method)))
@@ -666,7 +670,7 @@ the possible security methods (see `mh-mml-method-default')."
666 "Add tag to encrypt the message. 670 "Add tag to encrypt the message.
667 671
668A proper multipart message is created for you when you send the 672A proper multipart message is created for you when you send the
669message. Use the \\[mh-mml-unsecure-message] command to remove 673message. Use the command \\[mh-mml-unsecure-message] to remove
670this tag. Use a prefix argument METHOD to be prompted for one of 674this tag. Use a prefix argument METHOD to be prompted for one of
671the possible security methods (see `mh-mml-method-default')." 675the possible security methods (see `mh-mml-method-default')."
672 (interactive (list (mh-mml-query-cryptographic-method))) 676 (interactive (list (mh-mml-query-cryptographic-method)))
@@ -677,7 +681,7 @@ the possible security methods (see `mh-mml-method-default')."
677 "Add tag to encrypt and sign the message. 681 "Add tag to encrypt and sign the message.
678 682
679A proper multipart message is created for you when you send the 683A proper multipart message is created for you when you send the
680message. Use the \\[mh-mml-unsecure-message] command to remove 684message. Use the command \\[mh-mml-unsecure-message] to remove
681this tag. Use a prefix argument METHOD to be prompted for one of 685this tag. Use a prefix argument METHOD to be prompted for one of
682the possible security methods (see `mh-mml-method-default')." 686the possible security methods (see `mh-mml-method-default')."
683 (interactive (list (mh-mml-query-cryptographic-method))) 687 (interactive (list (mh-mml-query-cryptographic-method)))
@@ -853,7 +857,7 @@ do the work."
853 (equal t mh-mime-save-parts-default-directory)) 857 (equal t mh-mime-save-parts-default-directory))
854 mh-mime-save-parts-directory) 858 mh-mime-save-parts-directory)
855 (read-file-name (format 859 (read-file-name (format
856 "Store in directory: [%s] " 860 "Store in directory (default %s): "
857 mh-mime-save-parts-directory) 861 mh-mime-save-parts-directory)
858 "" mh-mime-save-parts-directory t "")) 862 "" mh-mime-save-parts-directory t ""))
859 ((stringp mh-mime-save-parts-default-directory) 863 ((stringp mh-mime-save-parts-default-directory)
@@ -963,7 +967,7 @@ parsed and then displayed."
963 (mh-mime-display-part handles)) 967 (mh-mime-display-part handles))
964 (t (mh-signature-highlight)))) 968 (t (mh-signature-highlight))))
965 (error 969 (error
966 (message "Please report this error. The error message is:\n %s" 970 (message "Please report this error:\n %s"
967 (error-message-string err)) 971 (error-message-string err))
968 (delete-region (point-min) (point-max)) 972 (delete-region (point-min) (point-max))
969 (insert raw-message-data)))))) 973 (insert raw-message-data))))))
diff --git a/lisp/mh-e/mh-pick.el b/lisp/mh-e/mh-pick.el
index 03314ffa6c6..e87e3d11f8d 100644
--- a/lisp/mh-e/mh-pick.el
+++ b/lisp/mh-e/mh-pick.el
@@ -1,7 +1,7 @@
1;;; mh-pick.el --- make a search pattern and search for a message in MH-E 1;;; mh-pick.el --- make a search pattern and search for a message in MH-E
2 2
3;; Copyright (C) 1993, 1995, 3;; Copyright (C) 1993, 1995,
4;; 2001, 2003, 2004, 2005 Free Software Foundation, Inc. 4;; 2001, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
5 5
6;; Author: Bill Wohler <wohler@newt.com> 6;; Author: Bill Wohler <wohler@newt.com>
7;; Maintainer: Bill Wohler <wohler@newt.com> 7;; Maintainer: Bill Wohler <wohler@newt.com>
@@ -54,13 +54,14 @@
54(defun mh-search-folder (folder window-config) 54(defun mh-search-folder (folder window-config)
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
58particular person or about a particular subject. In fact, you can also 58from a particular person or about a particular subject. In fact,
59search for messages containing selected strings in any arbitrary 59you can also search for messages containing selected strings in
60header field or any string found within the messages. 60any arbitrary header field or any string found within the
61messages.
61 62
62You are first prompted for the name of the folder to search and then 63You are first prompted for the name of the folder to search and
63placed in the following buffer in MH-Pick mode: 64then placed in the following buffer in MH-Pick mode:
64 65
65 From: 66 From:
66 To: 67 To:
@@ -69,26 +70,27 @@ placed in the following buffer in MH-Pick mode:
69 Subject: 70 Subject:
70 -------- 71 --------
71 72
72Edit this template by entering your search criteria in an appropriate 73Edit this template by entering your search criteria in an
73header field that is already there, or create a new field yourself. If 74appropriate header field that is already there, or create a new
74the string you're looking for could be anywhere in a message, then 75field yourself. If the string you're looking for could be
75place the string underneath the row of dashes. The 76anywhere in a message, then place the string underneath the row
76\\[mh-search-folder] command uses the MH command \"pick\" to do the 77of dashes. The command \\[mh-search-folder] uses the MH command
77real work. 78\"pick\" to do the real work.
78 79
79There are no semantics associated with the search criteria--they are 80There are no semantics associated with the search criteria--they
80simply treated as strings. Case is ignored when all lowercase is used, 81are simply treated as strings. Case is ignored when all lowercase
81and regular expressions (a la \"ed\") are available. It is all right 82is used, and regular expressions (a la \"ed\") are available. It
82to specify several search criteria. What happens then is that a 83is all right to specify several search criteria. What happens
83logical _and_ of the various fields is performed. If you prefer a 84then is that a logical _and_ of the various fields is performed.
84logical _or_ operation, run \\[mh-search-folder] multiple times. 85If you prefer a logical _or_ operation, run \\[mh-search-folder]
85 86multiple times.
86As an example, let's say that we want to find messages from Ginnean 87
87about horseback riding in the Kosciusko National Park (Australia) 88As an example, let's say that we want to find messages from
88during January, 1994. Normally we would start with a broad search and 89Ginnean about horseback riding in the Kosciusko National
89narrow it down if necessary to produce a manageable amount of data, 90Park (Australia) during January, 1994. Normally we would start
90but we'll cut to the chase and create a fairly restrictive set of 91with a broad search and narrow it down if necessary to produce a
91criteria as follows: 92manageable amount of data, but we'll cut to the chase and create
93a fairly restrictive set of criteria as follows:
92 94
93 From: ginnean 95 From: ginnean
94 To: 96 To:
@@ -98,31 +100,32 @@ criteria as follows:
98 -------- 100 --------
99 101
100As with MH-Letter mode, MH-Pick provides commands like 102As with MH-Letter mode, MH-Pick provides commands like
101\\<mh-pick-mode-map>\\[mh-to-field] to help you fill in the blanks. 103\\<mh-pick-mode-map>\\[mh-to-field] to help you fill in the
104blanks.
102 105
103To perform the search, type \\[mh-do-search]. The selected messages 106To perform the search, type \\[mh-do-search]. The selected
104are placed in the \"search\" sequence, which you can use later in 107messages are placed in the \"search\" sequence, which you can use
105forwarding, printing, or narrowing your field of view. Subsequent 108later in forwarding, printing, or narrowing your field of view.
106searches are appended to the \"search\" sequence. If, however, you 109Subsequent searches are appended to the \"search\" sequence. If,
107wish to start with a clean slate, first delete the \"search\" 110however, you wish to start with a clean slate, first delete the
108sequence. 111\"search\" sequence.
109 112
110If you're searching in a folder that is already displayed in an 113If you're searching in a folder that is already displayed in an
111MH-Folder buffer, only those messages contained in the buffer are used 114MH-Folder buffer, only those messages contained in the buffer are
112for the search. Therefore, if you want to search in all messages, 115used for the search. Therefore, if you want to search in all
113first kill the folder's buffer with 116messages, first kill the folder's buffer with
114\\<mh-folder-mode-map>\\[kill-buffer] or scan the entire folder with 117\\<mh-folder-mode-map>\\[kill-buffer] or scan the entire folder
115\\[mh-rescan-folder]. 118with \\[mh-rescan-folder].
116 119
117If you find that you do the same thing over and over when editing the 120If you find that you do the same thing over and over when editing
118search template, you may wish to bind some shortcuts to keys. This can 121the search template, you may wish to bind some shortcuts to keys.
119be done with the variable `mh-pick-mode-hook', which is called when 122This can be done with the variable `mh-pick-mode-hook', which is
120\\[mh-search-folder] is run on a new pattern. 123called when \\[mh-search-folder] is run on a new pattern.
121 124
122If you have run the \\[mh-index-search] command, but change your mind 125If you have run the \\[mh-index-search] command, but change your
123while entering the search criteria and actually want to run a regular 126mind while entering the search criteria and actually want to run
124search, then you can use the \\<mh-pick-mode-map>\\[mh-pick-do-search] 127a regular search, then you can use the command
125command. 128\\<mh-pick-mode-map>\\[mh-pick-do-search] in the MH-Pick buffer.
126 129
127In a program, argument WINDOW-CONFIG is the current window 130In a program, argument WINDOW-CONFIG is the current window
128configuration and is used when the search folder is dismissed." 131configuration and is used when the search folder is dismissed."
@@ -140,7 +143,7 @@ configuration and is used when the search folder is dismissed."
140 'mh-previous-window-config window-config) 143 'mh-previous-window-config window-config)
141 (message "%s" (substitute-command-keys 144 (message "%s" (substitute-command-keys
142 (concat "Type \\[mh-do-search] to search messages, " 145 (concat "Type \\[mh-do-search] to search messages, "
143 "\\[mh-help] for help."))))) 146 "\\[mh-help] for help")))))
144 147
145(defun mh-make-pick-template () 148(defun mh-make-pick-template ()
146 "Initialize the current buffer with a template for a pick pattern." 149 "Initialize the current buffer with a template for a pick pattern."
@@ -332,7 +335,7 @@ COMPONENT is the component to search."
332 ((eq (car expr) 'not) 335 ((eq (car expr) 'not)
333 `("-lbrace" "-not" ,@(mh-pick-construct-regexp (cadr expr) component) 336 `("-lbrace" "-not" ,@(mh-pick-construct-regexp (cadr expr) component)
334 "-rbrace")) 337 "-rbrace"))
335 (t (error "Unknown operator '%s' seen" (car expr))))) 338 (t (error "Unknown operator %s seen" (car expr)))))
336 339
337;; All implementations of pick have special options -cc, -date, -from and 340;; All implementations of pick have special options -cc, -date, -from and
338;; -subject that allow to search for corresponding components. Any other 341;; -subject that allow to search for corresponding components. Any other
diff --git a/lisp/mh-e/mh-seq.el b/lisp/mh-e/mh-seq.el
index 6fb70e61de8..53bae76cc07 100644
--- a/lisp/mh-e/mh-seq.el
+++ b/lisp/mh-e/mh-seq.el
@@ -1,7 +1,7 @@
1;;; mh-seq.el --- MH-E sequences support 1;;; mh-seq.el --- MH-E sequences support
2 2
3;; Copyright (C) 1993, 1995, 3;; Copyright (C) 1993, 1995,
4;; 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. 4;; 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
5 5
6;; Author: Bill Wohler <wohler@newt.com> 6;; Author: Bill Wohler <wohler@newt.com>
7;; Maintainer: Bill Wohler <wohler@newt.com> 7;; Maintainer: Bill Wohler <wohler@newt.com>
@@ -177,6 +177,7 @@ you want to delete the messages, use \"\\[universal-argument]
177;;;###mh-autoload 177;;;###mh-autoload
178(defun mh-list-sequences () 178(defun mh-list-sequences ()
179 "List all sequences in folder. 179 "List all sequences in folder.
180
180The list appears in a buffer named \"*MH-E Sequences*\"." 181The list appears in a buffer named \"*MH-E Sequences*\"."
181 (interactive) 182 (interactive)
182 (let ((folder mh-current-folder) 183 (let ((folder mh-current-folder)
@@ -219,6 +220,7 @@ The list appears in a buffer named \"*MH-E Sequences*\"."
219;;;###mh-autoload 220;;;###mh-autoload
220(defun mh-msg-is-in-seq (message) 221(defun mh-msg-is-in-seq (message)
221 "Display the sequences in which the current message appears. 222 "Display the sequences in which the current message appears.
223
222Use a prefix argument to display the sequences in which another 224Use a prefix argument to display the sequences in which another
223MESSAGE appears." 225MESSAGE appears."
224 (interactive "P") 226 (interactive "P")
@@ -282,7 +284,7 @@ When you want to widen the view to all your messages again, use
282 mh-show-seq-tool-bar-map)))) 284 mh-show-seq-tool-bar-map))))
283 (push 'widen mh-view-ops))) 285 (push 'widen mh-view-ops)))
284 (t 286 (t
285 (error "No messages in sequence \"%s\"" (symbol-name sequence)))))) 287 (error "No messages in sequence %s" (symbol-name sequence))))))
286 288
287;;;###mh-autoload 289;;;###mh-autoload
288(defun mh-put-msg-in-seq (range sequence) 290(defun mh-put-msg-in-seq (range sequence)
@@ -302,7 +304,7 @@ use."
302 (interactive (list (mh-interactive-range "Add messages from") 304 (interactive (list (mh-interactive-range "Add messages from")
303 (mh-read-seq-default "Add to" nil))) 305 (mh-read-seq-default "Add to" nil)))
304 (unless (mh-valid-seq-p sequence) 306 (unless (mh-valid-seq-p sequence)
305 (error "Can't put message in invalid sequence \"%s\"" sequence)) 307 (error "Can't put message in invalid sequence %s" sequence))
306 (let* ((internal-seq-flag (mh-internal-seq sequence)) 308 (let* ((internal-seq-flag (mh-internal-seq sequence))
307 (original-msgs (mh-seq-msgs (mh-find-seq sequence))) 309 (original-msgs (mh-seq-msgs (mh-find-seq sequence)))
308 (folders (list mh-current-folder)) 310 (folders (list mh-current-folder))
@@ -329,8 +331,10 @@ OP is one of 'widen and 'unthread."
329;;;###mh-autoload 331;;;###mh-autoload
330(defun mh-widen (&optional all-flag) 332(defun mh-widen (&optional all-flag)
331 "Remove last restriction. 333 "Remove last restriction.
332If optional prefix argument ALL-FLAG is non-nil, remove all 334
333limits." 335Each limit or sequence restriction can be undone in turn with
336this command. Give this command a prefix argument ALL-FLAG to
337remove all limits and sequence restrictions."
334 (interactive "P") 338 (interactive "P")
335 (let ((msg (mh-get-msg-num nil))) 339 (let ((msg (mh-get-msg-num nil)))
336 (when mh-folder-view-stack 340 (when mh-folder-view-stack
@@ -416,9 +420,9 @@ Prompt with PROMPT, raise an error if the sequence is empty and
416the NOT-EMPTY flag is non-nil, and supply an optional DEFAULT 420the NOT-EMPTY flag is non-nil, and supply an optional DEFAULT
417sequence. A reply of '%' defaults to the first sequence 421sequence. A reply of '%' defaults to the first sequence
418containing the current message." 422containing the current message."
419 (let* ((input (completing-read (format "%s %s %s" prompt "sequence:" 423 (let* ((input (completing-read (format "%s sequence%s: " prompt
420 (if default 424 (if default
421 (format "[%s] " default) 425 (format " (default %s)" default)
422 "")) 426 ""))
423 (mh-seq-names mh-seq-list) 427 (mh-seq-names mh-seq-list)
424 nil nil nil 'mh-sequence-history)) 428 nil nil nil 'mh-sequence-history))
@@ -428,7 +432,7 @@ containing the current message."
428 (t (intern input)))) 432 (t (intern input))))
429 (msgs (mh-seq-to-msgs seq))) 433 (msgs (mh-seq-to-msgs seq)))
430 (if (and (null msgs) not-empty) 434 (if (and (null msgs) not-empty)
431 (error "No messages in sequence \"%s\"" seq)) 435 (error "No messages in sequence %s" seq))
432 seq)) 436 seq))
433 437
434 438
@@ -509,20 +513,22 @@ should be replaced with:
509 (car (mh-seq-containing-msg (mh-get-msg-num nil) t))) 513 (car (mh-seq-containing-msg (mh-get-msg-num nil) t)))
510 prompt (format "%s range" prompt)) 514 prompt (format "%s range" prompt))
511 (let* ((folder (or folder mh-current-folder)) 515 (let* ((folder (or folder mh-current-folder))
512 (default (cond ((or (eq default t) (stringp default)) default)
513 ((symbolp default) (symbol-name default))))
514 (guess (eq default t)) 516 (guess (eq default t))
515 (counts (and guess (mh-folder-size folder))) 517 (counts (and guess (mh-folder-size folder)))
516 (unseen (and counts (> (cadr counts) 0))) 518 (unseen (and counts (> (cadr counts) 0)))
517 (large (and counts mh-large-folder (> (car counts) mh-large-folder))) 519 (large (and counts mh-large-folder (> (car counts) mh-large-folder)))
518 (str (cond ((and guess large 520 (default (cond ((and guess large) (format "last:%s" mh-large-folder))
519 (setq default (format "last:%s" mh-large-folder) 521 ((and guess (not large)) "all")
520 prompt (format "%s (folder has %s messages)" 522 ((stringp default) default)
521 prompt (car counts))) 523 ((symbolp default) (symbol-name default))))
522 nil)) 524 (prompt (cond ((and guess large default)
523 ((and guess (not large) (setq default "all") nil)) 525 (format "%s (folder has %s messages, default %s)"
524 ((eq default nil) "") 526 prompt (car counts) default))
525 (t (format "[%s] " default)))) 527 ((and guess large)
528 (format "%s (folder has %s messages)"
529 prompt (car counts)))
530 (default
531 (format "%s (default %s)" prompt default))))
526 (minibuffer-local-completion-map mh-range-completion-map) 532 (minibuffer-local-completion-map mh-range-completion-map)
527 (seq-list (if (eq folder mh-current-folder) 533 (seq-list (if (eq folder mh-current-folder)
528 mh-seq-list 534 mh-seq-list
@@ -532,7 +538,7 @@ should be replaced with:
532 (mh-seq-names seq-list))) 538 (mh-seq-names seq-list)))
533 (input (cond ((and (not ask-flag) unseen) (symbol-name mh-unseen-seq)) 539 (input (cond ((and (not ask-flag) unseen) (symbol-name mh-unseen-seq))
534 ((and (not ask-flag) (not large)) "all") 540 ((and (not ask-flag) (not large)) "all")
535 (t (completing-read (format "%s: %s" prompt str) 541 (t (completing-read (format "%s: " prompt)
536 'mh-range-completion-function nil nil 542 'mh-range-completion-function nil nil
537 nil 'mh-range-history default)))) 543 nil 'mh-range-history default))))
538 msg-list) 544 msg-list)
@@ -543,7 +549,7 @@ should be replaced with:
543 ((assoc (intern input) seq-list) 549 ((assoc (intern input) seq-list)
544 (cdr (assoc (intern input) seq-list))) 550 (cdr (assoc (intern input) seq-list)))
545 ((setq msg-list (mh-translate-range folder input)) msg-list) 551 ((setq msg-list (mh-translate-range folder input)) msg-list)
546 (t (error "No messages in range \"%s\"" input))))) 552 (t (error "No messages in range %s" input)))))
547 553
548;;;###mh-autoload 554;;;###mh-autoload
549(defun mh-translate-range (folder expr) 555(defun mh-translate-range (folder expr)
@@ -1170,7 +1176,7 @@ children."
1170 (mh-message-id (mh-container-message kid))) 1176 (mh-message-id (mh-container-message kid)))
1171 (let ((kid-message (mh-container-message kid))) 1177 (let ((kid-message (mh-container-message kid)))
1172 (return (mh-message-subject kid-message))))) 1178 (return (mh-message-subject kid-message)))))
1173 (error "This can't happen!"))))) 1179 (error "This can't happen")))))
1174 1180
1175(defun mh-thread-rewind-pruning () 1181(defun mh-thread-rewind-pruning ()
1176 "Restore the thread tree to its state before pruning." 1182 "Restore the thread tree to its state before pruning."
diff --git a/lisp/mh-e/mh-utils.el b/lisp/mh-e/mh-utils.el
index e008c93916e..f3205a932a2 100644
--- a/lisp/mh-e/mh-utils.el
+++ b/lisp/mh-e/mh-utils.el
@@ -1,7 +1,7 @@
1;;; mh-utils.el --- MH-E code needed for both sending and reading 1;;; mh-utils.el --- MH-E code needed for both sending and reading
2 2
3;; Copyright (C) 1993, 1995, 1997, 3;; Copyright (C) 1993, 1995, 1997,
4;; 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. 4;; 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
5 5
6;; Author: Bill Wohler <wohler@newt.com> 6;; Author: Bill Wohler <wohler@newt.com>
7;; Maintainer: Bill Wohler <wohler@newt.com> 7;; Maintainer: Bill Wohler <wohler@newt.com>
@@ -1582,7 +1582,7 @@ The argument CHANGE is ignored."
1582 (cond 1582 (cond
1583 ;; Check if we have `convert' 1583 ;; Check if we have `convert'
1584 ((eq mh-x-image-scaling-function 'ignore) 1584 ((eq mh-x-image-scaling-function 'ignore)
1585 (message "The `convert' program is needed to display X-Image-URL") 1585 (message "The \"convert\" program is needed to display X-Image-URL")
1586 (mh-x-image-set-download-state cache-filename 'try-again)) 1586 (mh-x-image-set-download-state cache-filename 'try-again))
1587 ;; Scale fetched image 1587 ;; Scale fetched image
1588 ((and (funcall mh-x-image-scaling-function temp-file cache-filename) 1588 ((and (funcall mh-x-image-scaling-function temp-file cache-filename)
@@ -1647,6 +1647,14 @@ scrolls to the beginning of the message. MH-E normally hides a lot of
1647the superfluous header fields that mailers add to a message, but if 1647the superfluous header fields that mailers add to a message, but if
1648you wish to see all of them, use the command \\[mh-header-display]. 1648you wish to see all of them, use the command \\[mh-header-display].
1649 1649
1650Two hooks can be used to control how messages are displayed. The
1651first hook, `mh-show-mode-hook', is called early on in the
1652process of the message display. It is usually used to perform
1653some action on the message's content. The second hook,
1654`mh-show-hook', is the last thing called after messages are
1655displayed. It's used to affect the behavior of MH-E in general or
1656when `mh-show-mode-hook' is too early.
1657
1650From a program, optional argument MESSAGE can be used to display an 1658From a program, optional argument MESSAGE can be used to display an
1651alternative message. The optional argument REDISPLAY-FLAG forces the 1659alternative message. The optional argument REDISPLAY-FLAG forces the
1652redisplay of the message even if the show buffer was already 1660redisplay of the message even if the show buffer was already
@@ -1728,7 +1736,7 @@ this with this command. It displays the raw message in an
1728editable buffer. When you are done editing, save and kill the 1736editable buffer. When you are done editing, save and kill the
1729buffer as you would any other. 1737buffer as you would any other.
1730 1738
1731From a program, edit MESSAGE instead if it is non-nil." 1739From a program, edit MESSAGE; nil means edit current message."
1732 (interactive) 1740 (interactive)
1733 (let* ((message (or message (mh-get-msg-num t))) 1741 (let* ((message (or message (mh-get-msg-num t)))
1734 (msg-filename (mh-msg-filename message)) 1742 (msg-filename (mh-msg-filename message))
@@ -2471,7 +2479,7 @@ used in searching."
2471 (new-file-flag 2479 (new-file-flag
2472 (error "Folder %s does not exist" folder-name)) 2480 (error "Folder %s does not exist" folder-name))
2473 ((not (file-directory-p (mh-expand-file-name folder-name))) 2481 ((not (file-directory-p (mh-expand-file-name folder-name)))
2474 (error "\"%s\" is not a directory" 2482 (error "%s is not a directory"
2475 (mh-expand-file-name folder-name))))) 2483 (mh-expand-file-name folder-name)))))
2476 folder-name)) 2484 folder-name))
2477 2485
@@ -2655,7 +2663,7 @@ Set mark after inserted text."
2655 (set-buffer (get-buffer-create mh-log-buffer)) 2663 (set-buffer (get-buffer-create mh-log-buffer))
2656 (mh-truncate-log-buffer) 2664 (mh-truncate-log-buffer)
2657 (insert error-message))) 2665 (insert error-message)))
2658 (error "%s failed, check %s buffer for error message" 2666 (error "%s failed, check buffer %s for error message"
2659 command mh-log-buffer))) 2667 command mh-log-buffer)))
2660 2668
2661(defun mh-list-to-string (l) 2669(defun mh-list-to-string (l)
@@ -2676,7 +2684,7 @@ Set mark after inserted text."
2676 ((listp (car l)) 2684 ((listp (car l))
2677 (setq new-list (nconc (mh-list-to-string-1 (car l)) 2685 (setq new-list (nconc (mh-list-to-string-1 (car l))
2678 new-list))) 2686 new-list)))
2679 (t (error "Bad element in mh-list-to-string: %s" (car l)))) 2687 (t (error "Bad element in `mh-list-to-string': %s" (car l))))
2680 (setq l (cdr l))) 2688 (setq l (cdr l)))
2681 new-list)) 2689 new-list))
2682 2690
diff --git a/lisp/mouse.el b/lisp/mouse.el
index ef655ba836f..e772858b3c7 100644
--- a/lisp/mouse.el
+++ b/lisp/mouse.el
@@ -765,7 +765,7 @@ If the click is in the echo area, display the `*Messages*' buffer."
765 (display-buffer (current-buffer))) 765 (display-buffer (current-buffer)))
766 ;; Give temporary modes such as isearch a chance to turn off. 766 ;; Give temporary modes such as isearch a chance to turn off.
767 (run-hooks 'mouse-leave-buffer-hook) 767 (run-hooks 'mouse-leave-buffer-hook)
768 (mouse-drag-region-1 start-event)))) 768 (mouse-drag-track start-event t))))
769 769
770 770
771(defun mouse-on-link-p (pos) 771(defun mouse-on-link-p (pos)
@@ -865,7 +865,12 @@ at the same position."
865 (let ((range (mouse-start-end start end mode))) 865 (let ((range (mouse-start-end start end mode)))
866 (move-overlay ol (car range) (nth 1 range)))) 866 (move-overlay ol (car range) (nth 1 range))))
867 867
868(defun mouse-drag-region-1 (start-event) 868(defun mouse-drag-track (start-event &optional
869 do-mouse-drag-region-post-process)
870 "Track mouse drags by highlighting area between point and cursor.
871The region will be defined with mark and point, and the overlay
872will be deleted after return. DO-MOUSE-DRAG-REGION-POST-PROCESS
873should only be used by mouse-drag-region."
869 (mouse-minibuffer-check start-event) 874 (mouse-minibuffer-check start-event)
870 (setq mouse-selection-click-count-buffer (current-buffer)) 875 (setq mouse-selection-click-count-buffer (current-buffer))
871 (let* ((original-window (selected-window)) 876 (let* ((original-window (selected-window))
@@ -949,12 +954,15 @@ at the same position."
949 (integer-or-marker-p end-point)) 954 (integer-or-marker-p end-point))
950 (mouse-move-drag-overlay mouse-drag-overlay start-point end-point click-count)) 955 (mouse-move-drag-overlay mouse-drag-overlay start-point end-point click-count))
951 956
957 ;; Handle the terminating event
952 (if (consp event) 958 (if (consp event)
953 (let* ((fun (key-binding (vector (car event)))) 959 (let* ((fun (key-binding (vector (car event))))
954 (do-multi-click (and (> (event-click-count event) 0) 960 (do-multi-click (and (> (event-click-count event) 0)
955 (functionp fun) 961 (functionp fun)
956 (not (memq fun '(mouse-set-point mouse-set-region)))))) 962 (not (memq fun
957 ;; Run the binding of the terminating up-event, if possible. 963 '(mouse-set-point
964 mouse-set-region))))))
965 ;; Run the binding of the terminating up-event, if possible.
958 (if (and (not (= (overlay-start mouse-drag-overlay) 966 (if (and (not (= (overlay-start mouse-drag-overlay)
959 (overlay-end mouse-drag-overlay))) 967 (overlay-end mouse-drag-overlay)))
960 (not do-multi-click)) 968 (not do-multi-click))
@@ -965,31 +973,34 @@ at the same position."
965 ;; The end that comes from where we ended the drag. 973 ;; The end that comes from where we ended the drag.
966 ;; Point goes here. 974 ;; Point goes here.
967 (region-termination 975 (region-termination
968 (if (and stop-point (< stop-point start-point)) 976 (if (and stop-point (< stop-point start-point))
969 (overlay-start mouse-drag-overlay) 977 (overlay-start mouse-drag-overlay)
970 (overlay-end mouse-drag-overlay))) 978 (overlay-end mouse-drag-overlay)))
971 ;; The end that comes from where we started the drag. 979 ;; The end that comes from where we started the drag.
972 ;; Mark goes there. 980 ;; Mark goes there.
973 (region-commencement 981 (region-commencement
974 (- (+ (overlay-end mouse-drag-overlay) 982 (- (+ (overlay-end mouse-drag-overlay)
975 (overlay-start mouse-drag-overlay)) 983 (overlay-start mouse-drag-overlay))
976 region-termination)) 984 region-termination))
977 last-command this-command) 985 last-command this-command)
978 (push-mark region-commencement t t) 986 (push-mark region-commencement t t)
979 (goto-char region-termination) 987 (goto-char region-termination)
980 ;; Don't let copy-region-as-kill set deactivate-mark. 988 (if (not do-mouse-drag-region-post-process)
981 (when mouse-drag-copy-region 989 ;; Skip all post-event handling, return immediately.
982 (let (deactivate-mark) 990 (delete-overlay mouse-drag-overlay)
983 (copy-region-as-kill (point) (mark t)))) 991 ;; Don't let copy-region-as-kill set deactivate-mark.
984 (let ((buffer (current-buffer))) 992 (when mouse-drag-copy-region
985 (mouse-show-mark) 993 (let (deactivate-mark)
986 ;; mouse-show-mark can call read-event, 994 (copy-region-as-kill (point) (mark t))))
987 ;; and that means the Emacs server could switch buffers 995 (let ((buffer (current-buffer)))
988 ;; under us. If that happened, 996 (mouse-show-mark)
989 ;; avoid trying to use the region. 997 ;; mouse-show-mark can call read-event,
990 (and (mark t) mark-active 998 ;; and that means the Emacs server could switch buffers
991 (eq buffer (current-buffer)) 999 ;; under us. If that happened,
992 (mouse-set-region-1)))) 1000 ;; avoid trying to use the region.
1001 (and (mark t) mark-active
1002 (eq buffer (current-buffer))
1003 (mouse-set-region-1)))))
993 ;; Run the binding of the terminating up-event. 1004 ;; Run the binding of the terminating up-event.
994 ;; If a multiple click is not bound to mouse-set-point, 1005 ;; If a multiple click is not bound to mouse-set-point,
995 ;; cancel the effects of mouse-move-drag-overlay to 1006 ;; cancel the effects of mouse-move-drag-overlay to
@@ -997,18 +1008,18 @@ at the same position."
997 (if do-multi-click (goto-char start-point)) 1008 (if do-multi-click (goto-char start-point))
998 (delete-overlay mouse-drag-overlay) 1009 (delete-overlay mouse-drag-overlay)
999 (when (and (functionp fun) 1010 (when (and (functionp fun)
1000 (= start-hscroll (window-hscroll start-window)) 1011 (= start-hscroll (window-hscroll start-window))
1001 ;; Don't run the up-event handler if the 1012 ;; Don't run the up-event handler if the
1002 ;; window start changed in a redisplay after 1013 ;; window start changed in a redisplay after
1003 ;; the mouse-set-point for the down-mouse 1014 ;; the mouse-set-point for the down-mouse
1004 ;; event at the beginning of this function. 1015 ;; event at the beginning of this function.
1005 ;; When the window start has changed, the 1016 ;; When the window start has changed, the
1006 ;; up-mouse event will contain a different 1017 ;; up-mouse event will contain a different
1007 ;; position due to the new window contents, 1018 ;; position due to the new window contents,
1008 ;; and point is set again. 1019 ;; and point is set again.
1009 (or end-point 1020 (or end-point
1010 (= (window-start start-window) 1021 (= (window-start start-window)
1011 start-window-start))) 1022 start-window-start)))
1012 (when (and on-link 1023 (when (and on-link
1013 (or (not end-point) (= end-point start-point)) 1024 (or (not end-point) (= end-point start-point))
1014 (consp event) 1025 (consp event)
diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el
index 6f5d0855e19..4b14d321a46 100644
--- a/lisp/progmodes/flymake.el
+++ b/lisp/progmodes/flymake.el
@@ -1,6 +1,6 @@
1;;; flymake.el -- a universal on-the-fly syntax checker 1;;; flymake.el -- a universal on-the-fly syntax checker
2 2
3;; Copyright (C) 2003, 2004, 2005 Free Software Foundation 3;; Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation
4 4
5;; Author: Pavel Kobiakov <pk_at_work@yahoo.com> 5;; Author: Pavel Kobiakov <pk_at_work@yahoo.com>
6;; Maintainer: Pavel Kobiakov <pk_at_work@yahoo.com> 6;; Maintainer: Pavel Kobiakov <pk_at_work@yahoo.com>
@@ -32,16 +32,33 @@
32 32
33;;; Code: 33;;; Code:
34 34
35;;;; [[ Silence the byte-compiler 35(defvar flymake-is-running nil
36 "If t, flymake syntax check process is running for the current buffer.")
37(make-variable-buffer-local 'flymake-is-running)
36 38
37(defvar flymake-check-start-time) 39(defvar flymake-timer nil
38(defvar flymake-check-was-interrupted) 40 "Timer for starting syntax check.")
39(defvar flymake-err-info) 41(make-variable-buffer-local 'flymake-timer)
40(defvar flymake-is-running)
41(defvar flymake-last-change-time)
42(defvar flymake-new-err-info)
43 42
44;;;; ]] 43(defvar flymake-last-change-time nil
44 "Time of last buffer change.")
45(make-variable-buffer-local 'flymake-last-change-time)
46
47(defvar flymake-check-start-time nil
48 "Time at which syntax check was started.")
49(make-variable-buffer-local 'flymake-check-start-time)
50
51(defvar flymake-check-was-interrupted nil
52 "Non-nil if syntax check was killed by `flymake-compile'.")
53(make-variable-buffer-local 'flymake-check-was-interrupted)
54
55(defvar flymake-err-info nil
56 "Sorted list of line numbers and lists of err info in the form (file, err-text).")
57(make-variable-buffer-local 'flymake-err-info)
58
59(defvar flymake-new-err-info nil
60 "Same as `flymake-err-info', effective when a syntax check is in progress.")
61(make-variable-buffer-local 'flymake-new-err-info)
45 62
46;;;; [[ Xemacs overlay compatibility 63;;;; [[ Xemacs overlay compatibility
47(if (featurep 'xemacs) (progn 64(if (featurep 'xemacs) (progn
@@ -69,25 +86,30 @@
69 (multiple-value-bind (s0 s1 s2) (current-time) 86 (multiple-value-bind (s0 s1 s2) (current-time)
70 (+ (* (float (ash 1 16)) s0) (float s1) (* 0.0000001 s2))))))) 87 (+ (* (float (ash 1 16)) s0) (float s1) (* 0.0000001 s2)))))))
71 88
72(defsubst flymake-replace-regexp-in-string (regexp rep str) 89(defalias 'flymake-replace-regexp-in-string
73 (if (fboundp 'replace-in-string) 90 (if (eval-when-compile (fboundp 'replace-regexp-in-string))
74 (replace-in-string str regexp rep) 91 'replace-regexp-in-string
75 (replace-regexp-in-string regexp rep str))) 92 (lambda (regexp rep str)
76 93 (replace-in-string str regexp rep))))
77(defun flymake-split-string (str pattern) 94
78 "Split STR into a list of substrings bounded by PATTERN. 95(defalias 'flymake-split-string
96 (if (condition-case nil (equal (split-string " bc " " " t) '("bc"))
97 (error nil))
98 (lambda (str pattern) (split-string str pattern t))
99 (lambda (str pattern)
100 "Split STR into a list of substrings bounded by PATTERN.
79Zero-length substrings at the beginning and end of the list are omitted." 101Zero-length substrings at the beginning and end of the list are omitted."
80 (let* ((splitted (split-string str pattern))) 102 (let ((split (split-string str pattern)))
81 (if (and (> (length splitted) 0) (= 0 (length (elt splitted 0)))) 103 (if (and (> (length split) 0) (= 0 (length (elt split 0))))
82 (setq splitted (cdr splitted))) 104 (setq split (cdr split)))
83 (if (and (> (length splitted) 0) (= 0 (length (elt splitted (1- (length splitted)))))) 105 (if (and (> (length split) 0) (= 0 (length (elt split (1- (length split))))))
84 (setq splitted (reverse (cdr (reverse splitted))))) 106 (setq split (nreverse (cdr (nreverse split)))))
85 splitted)) 107 split))))
86 108
87(defsubst flymake-get-temp-dir () 109(defalias 'flymake-get-temp-dir
88 (if (fboundp 'temp-directory) 110 (if (fboundp 'temp-directory)
89 (temp-directory) 111 'temp-directory
90 temporary-file-directory)) 112 (lambda () temporary-file-directory)))
91 113
92(defalias 'flymake-line-beginning-position 114(defalias 'flymake-line-beginning-position
93 (if (fboundp 'line-beginning-position) 115 (if (fboundp 'line-beginning-position)
@@ -99,20 +121,26 @@ Zero-length substrings at the beginning and end of the list are omitted."
99 'line-end-position 121 'line-end-position
100 (lambda (&optional arg) (save-excursion (end-of-line arg) (point))))) 122 (lambda (&optional arg) (save-excursion (end-of-line arg) (point)))))
101 123
102(defun flymake-popup-menu (pos menu-data) 124
103 "Pop up the flymake menu at position POS, using the data MENU-DATA. 125(defun flymake-popup-menu (menu-data)
126 "Pop up the flymake menu at point, using the data MENU-DATA.
104POS is a list of the form ((X Y) WINDOW), where X and Y are 127POS is a list of the form ((X Y) WINDOW), where X and Y are
105pixels positions from the top left corner of WINDOW's frame. 128pixels positions from the top left corner of WINDOW's frame.
106MENU-DATA is a list of error and warning messages returned by 129MENU-DATA is a list of error and warning messages returned by
107`flymake-make-err-menu-data'." 130`flymake-make-err-menu-data'."
108 (if (featurep 'xemacs) 131 (if (featurep 'xemacs)
109 (let* ((x-pos (nth 0 (nth 0 pos))) 132 (let* ((pos (flymake-get-point-pixel-pos))
110 (y-pos (nth 1 (nth 0 pos))) 133 (x-pos (nth 0 pos))
134 (y-pos (nth 1 pos))
111 (fake-event-props '(button 1 x 1 y 1))) 135 (fake-event-props '(button 1 x 1 y 1)))
112 (setq fake-event-props (plist-put fake-event-props 'x x-pos)) 136 (setq fake-event-props (plist-put fake-event-props 'x x-pos))
113 (setq fake-event-props (plist-put fake-event-props 'y y-pos)) 137 (setq fake-event-props (plist-put fake-event-props 'y y-pos))
114 (popup-menu (flymake-make-xemacs-menu menu-data) (make-event 'button-press fake-event-props))) 138 (popup-menu (flymake-make-xemacs-menu menu-data)
115 (x-popup-menu pos (flymake-make-emacs-menu menu-data)))) 139 (make-event 'button-press fake-event-props)))
140 (x-popup-menu (if (eval-when-compile (fboundp 'posn-at-point))
141 (posn-at-point)
142 (list (flymake-get-point-pixel-pos) (selected-window)))
143 (flymake-make-emacs-menu menu-data))))
116 144
117(defun flymake-make-emacs-menu (menu-data) 145(defun flymake-make-emacs-menu (menu-data)
118 "Return a menu specifier using MENU-DATA. 146 "Return a menu specifier using MENU-DATA.
@@ -121,10 +149,9 @@ MENU-DATA is a list of error and warning messages returned by
121See `x-popup-menu' for the menu specifier format." 149See `x-popup-menu' for the menu specifier format."
122 (let* ((menu-title (nth 0 menu-data)) 150 (let* ((menu-title (nth 0 menu-data))
123 (menu-items (nth 1 menu-data)) 151 (menu-items (nth 1 menu-data))
124 (menu-commands nil)) 152 (menu-commands (mapcar (lambda (foo)
125 (setq menu-commands (mapcar (lambda (foo) 153 (cons (nth 0 foo) (nth 1 foo)))
126 (cons (nth 0 foo) (nth 1 foo))) 154 menu-items)))
127 menu-items))
128 (list menu-title (cons "" menu-commands)))) 155 (list menu-title (cons "" menu-commands))))
129 156
130(if (featurep 'xemacs) (progn 157(if (featurep 'xemacs) (progn
@@ -141,21 +168,10 @@ See `x-popup-menu' for the menu specifier format."
141 menu-items)) 168 menu-items))
142 (cons menu-title menu-commands))) 169 (cons menu-title menu-commands)))
143 170
144(defun flymake-xemacs-window-edges (&optional window)
145 (let ((edges (window-pixel-edges window))
146 tmp)
147 (setq tmp edges)
148 (setcar tmp (/ (car tmp) (face-width 'default)))
149 (setq tmp (cdr tmp))
150 (setcar tmp (/ (car tmp) (face-height 'default)))
151 (setq tmp (cdr tmp))
152 (setcar tmp (/ (car tmp) (face-width 'default)))
153 (setq tmp (cdr tmp))
154 (setcar tmp (/ (car tmp) (face-height 'default)))
155 edges))
156
157)) ;; xemacs 171)) ;; xemacs
158 172
173(unless (eval-when-compile (fboundp 'posn-at-point))
174
159(defun flymake-current-row () 175(defun flymake-current-row ()
160 "Return current row number in current frame." 176 "Return current row number in current frame."
161 (if (fboundp 'window-edges) 177 (if (fboundp 'window-edges)
@@ -167,6 +183,24 @@ See `x-popup-menu' for the menu specifier format."
167 (selected-frame) 183 (selected-frame)
168 (selected-window))) 184 (selected-window)))
169 185
186(defun flymake-get-point-pixel-pos ()
187 "Return point position in pixels: (x, y)."
188 (let ((mouse-pos (mouse-position))
189 (pixel-pos nil)
190 (ret nil))
191 (if (car (cdr mouse-pos))
192 (progn
193 (set-mouse-position (flymake-selected-frame) (current-column) (flymake-current-row))
194 (setq pixel-pos (mouse-pixel-position))
195 (set-mouse-position (car mouse-pos) (car (cdr mouse-pos)) (cdr (cdr mouse-pos)))
196 (setq ret (list (car (cdr pixel-pos)) (cdr (cdr pixel-pos)))))
197 (progn
198 (setq ret '(0 0))))
199 (flymake-log 3 "mouse pos is %s" ret)
200 ret))
201
202) ;; End of (unless (fboundp 'posn-at-point)
203
170;;;; ]] 204;;;; ]]
171 205
172(defcustom flymake-log-level -1 206(defcustom flymake-log-level -1
@@ -187,7 +221,7 @@ are the string substitutions (see `format')."
187 ;;(with-temp-buffer 221 ;;(with-temp-buffer
188 ;; (insert msg) 222 ;; (insert msg)
189 ;; (insert "\n") 223 ;; (insert "\n")
190 ;; (flymake-save-buffer-in-file (current-buffer) "d:/flymake.log" t) ; make log file name customizable 224 ;; (flymake-save-buffer-in-file "d:/flymake.log" t) ; make log file name customizable
191 ;;) 225 ;;)
192 ))) 226 )))
193 227
@@ -203,59 +237,34 @@ are the string substitutions (see `format')."
203 (setcar (nthcdr pos tmp) val) 237 (setcar (nthcdr pos tmp) val)
204 tmp)) 238 tmp))
205 239
206(defvar flymake-pid-to-names (flymake-makehash) 240(defvar flymake-processes nil
207 "Hash table mapping PIDs to source buffer names and output files.") 241 "List of currently active flymake processes.")
208
209(defun flymake-reg-names (pid source-buffer-name)
210 "Associate PID with SOURCE-BUFFER-NAME in `flymake-pid-to-names'."
211 (unless (stringp source-buffer-name)
212 (error "Invalid buffer name"))
213 (puthash pid (list source-buffer-name) flymake-pid-to-names))
214
215(defun flymake-get-source-buffer-name (pid)
216 "Return buffer name associated with PID in `flymake-pid-to-names'."
217 (nth 0 (gethash pid flymake-pid-to-names)))
218
219(defun flymake-unreg-names (pid)
220 "Remove the entry associated with PID from `flymake-pid-to-names'."
221 (remhash pid flymake-pid-to-names))
222
223(defvar flymake-buffer-data (flymake-makehash)
224 "Data specific to syntax check tool, in name-value pairs.")
225
226(make-variable-buffer-local 'flymake-buffer-data)
227
228(defun flymake-get-buffer-value (buffer name)
229 (gethash name (with-current-buffer buffer flymake-buffer-data)))
230
231(defun flymake-set-buffer-value (buffer name value)
232 (puthash name value (with-current-buffer buffer flymake-buffer-data)))
233 242
234(defvar flymake-output-residual nil) 243(defvar flymake-output-residual nil)
235 244
236(make-variable-buffer-local 'flymake-output-residual) 245(make-variable-buffer-local 'flymake-output-residual)
237 246
238(defcustom flymake-allowed-file-name-masks 247(defcustom flymake-allowed-file-name-masks
239 '((".+\\.c$" flymake-simple-make-init flymake-simple-cleanup flymake-get-real-file-name) 248 '(("\\.c\\'" flymake-simple-make-init)
240 (".+\\.cpp$" flymake-simple-make-init flymake-simple-cleanup flymake-get-real-file-name) 249 ("\\.cpp\\'" flymake-simple-make-init)
241 (".+\\.xml$" flymake-xml-init flymake-simple-cleanup flymake-get-real-file-name) 250 ("\\.xml\\'" flymake-xml-init)
242 (".+\\.html?$" flymake-xml-init flymake-simple-cleanup flymake-get-real-file-name) 251 ("\\.html?\\'" flymake-xml-init)
243 (".+\\.cs$" flymake-simple-make-init flymake-simple-cleanup flymake-get-real-file-name) 252 ("\\.cs\\'" flymake-simple-make-init)
244 (".+\\.pl$" flymake-perl-init flymake-simple-cleanup flymake-get-real-file-name) 253 ("\\.pl\\'" flymake-perl-init)
245 (".+\\.h$" flymake-master-make-header-init flymake-master-cleanup flymake-get-real-file-name) 254 ("\\.h\\'" flymake-master-make-header-init flymake-master-cleanup)
246 (".+\\.java$" flymake-simple-make-java-init flymake-simple-java-cleanup flymake-get-real-file-name) 255 ("\\.java\\'" flymake-simple-make-java-init flymake-simple-java-cleanup)
247 (".+[0-9]+\\.tex$" flymake-master-tex-init flymake-master-cleanup flymake-get-real-file-name) 256 ("[0-9]+\\.tex\\'" flymake-master-tex-init flymake-master-cleanup)
248 (".+\\.tex$" flymake-simple-tex-init flymake-simple-cleanup flymake-get-real-file-name) 257 ("\\.tex\\'" flymake-simple-tex-init)
249 (".+\\.idl$" flymake-simple-make-init flymake-simple-cleanup flymake-get-real-file-name) 258 ("\\.idl\\'" flymake-simple-make-init)
250 ;; (".+\\.cpp$" 1) 259 ;; ("\\.cpp\\'" 1)
251 ;; (".+\\.java$" 3) 260 ;; ("\\.java\\'" 3)
252 ;; (".+\\.h$" 2 (".+\\.cpp$" ".+\\.c$") 261 ;; ("\\.h\\'" 2 ("\\.cpp\\'" "\\.c\\'")
253 ;; ("[ \t]*#[ \t]*include[ \t]*\"\\([\w0-9/\\_\.]*[/\\]*\\)\\(%s\\)\"" 1 2)) 262 ;; ("[ \t]*#[ \t]*include[ \t]*\"\\([\w0-9/\\_\.]*[/\\]*\\)\\(%s\\)\"" 1 2))
254 ;; (".+\\.idl$" 1) 263 ;; ("\\.idl\\'" 1)
255 ;; (".+\\.odl$" 1) 264 ;; ("\\.odl\\'" 1)
256 ;; (".+[0-9]+\\.tex$" 2 (".+\\.tex$") 265 ;; ("[0-9]+\\.tex\\'" 2 ("\\.tex\\'")
257 ;; ("[ \t]*\\input[ \t]*{\\(.*\\)\\(%s\\)}" 1 2 )) 266 ;; ("[ \t]*\\input[ \t]*{\\(.*\\)\\(%s\\)}" 1 2 ))
258 ;; (".+\\.tex$" 1) 267 ;; ("\\.tex\\'" 1)
259 ) 268 )
260 "*Files syntax checking is allowed for." 269 "*Files syntax checking is allowed for."
261 :group 'flymake 270 :group 'flymake
@@ -288,10 +297,12 @@ Return nil if we cannot, non-nil if we can."
288 297
289(defun flymake-get-cleanup-function (file-name) 298(defun flymake-get-cleanup-function (file-name)
290 "Return cleanup function to be used for the file." 299 "Return cleanup function to be used for the file."
291 (nth 1 (flymake-get-file-name-mode-and-masks file-name))) 300 (or (nth 1 (flymake-get-file-name-mode-and-masks file-name))
301 'flymake-simple-cleanup))
292 302
293(defun flymake-get-real-file-name-function (file-name) 303(defun flymake-get-real-file-name-function (file-name)
294 (or (nth 2 (flymake-get-file-name-mode-and-masks file-name)) 'flymake-get-real-file-name)) 304 (or (nth 2 (flymake-get-file-name-mode-and-masks file-name))
305 'flymake-get-real-file-name))
295 306
296(defcustom flymake-buildfile-dirs '("." ".." "../.." "../../.." "../../../.." "../../../../.." "../../../../../.." "../../../../../../.." "../../../../../../../.." "../../../../../../../../.." "../../../../../../../../../.." "../../../../../../../../../../..") 307(defcustom flymake-buildfile-dirs '("." ".." "../.." "../../.." "../../../.." "../../../../.." "../../../../../.." "../../../../../../.." "../../../../../../../.." "../../../../../../../../.." "../../../../../../../../../.." "../../../../../../../../../../..")
297 "Dirs to look for buildfile." 308 "Dirs to look for buildfile."
@@ -491,7 +502,7 @@ instead of reading master file from disk."
491 (file-name-nondirectory patched-source-file-name)))) 502 (file-name-nondirectory patched-source-file-name))))
492 (forward-line 1))) 503 (forward-line 1)))
493 (when found 504 (when found
494 (flymake-save-buffer-in-file (current-buffer) patched-master-file-name))) 505 (flymake-save-buffer-in-file patched-master-file-name)))
495 ;;+(flymake-log 3 "killing buffer %s" (buffer-name master-file-temp-buffer)) 506 ;;+(flymake-log 3 "killing buffer %s" (buffer-name master-file-temp-buffer))
496 (kill-buffer master-file-temp-buffer))) 507 (kill-buffer master-file-temp-buffer)))
497 ;;+(flymake-log 3 "check-patch master file %s: %s" master-file-name found) 508 ;;+(flymake-log 3 "check-patch master file %s: %s" master-file-name found)
@@ -581,15 +592,12 @@ Find master file, patch and save it."
581 (file-name-nondirectory source-file-name)) 592 (file-name-nondirectory source-file-name))
582 nil)))) 593 nil))))
583 594
584(defun flymake-save-buffer-in-file (buffer file-name) 595(defun flymake-save-buffer-in-file (file-name)
585 (or buffer 596 (save-restriction
586 (error "Invalid buffer")) 597 (widen)
587 (with-current-buffer buffer 598 (make-directory (file-name-directory file-name) 1)
588 (save-restriction 599 (write-region (point-min) (point-max) file-name nil 566))
589 (widen) 600 (flymake-log 3 "saved buffer %s in file %s" (buffer-name) file-name))
590 (make-directory (file-name-directory file-name) 1)
591 (write-region (point-min) (point-max) file-name nil 566)))
592 (flymake-log 3 "saved buffer %s in file %s" (buffer-name buffer) file-name))
593 601
594(defun flymake-save-string-to-file (file-name data) 602(defun flymake-save-string-to-file (file-name data)
595 "Save string DATA to file FILE-NAME." 603 "Save string DATA to file FILE-NAME."
@@ -604,44 +612,46 @@ Find master file, patch and save it."
604(defun flymake-process-filter (process output) 612(defun flymake-process-filter (process output)
605 "Parse OUTPUT and highlight error lines. 613 "Parse OUTPUT and highlight error lines.
606It's flymake process filter." 614It's flymake process filter."
607 (let* ((pid (process-id process)) 615 (let ((source-buffer (process-buffer process)))
608 (source-buffer (get-buffer (flymake-get-source-buffer-name pid))))
609 616
610 (flymake-log 3 "received %d byte(s) of output from process %d" (length output) pid) 617 (flymake-log 3 "received %d byte(s) of output from process %d"
618 (length output) (process-id process))
611 (when source-buffer 619 (when source-buffer
612 (with-current-buffer source-buffer 620 (with-current-buffer source-buffer
613 (flymake-parse-output-and-residual output))))) 621 (flymake-parse-output-and-residual output)))))
614 622
615(defun flymake-process-sentinel (process event) 623(defun flymake-process-sentinel (process event)
616 "Sentinel for syntax check buffers." 624 "Sentinel for syntax check buffers."
617 (if (memq (process-status process) '(signal exit)) 625 (when (memq (process-status process) '(signal exit))
618 (let*((exit-status (process-exit-status process)) 626 (let* ((exit-status (process-exit-status process))
619 (command (process-command process)) 627 (command (process-command process))
620 (pid (process-id process)) 628 (source-buffer (process-buffer process))
621 (source-buffer (get-buffer (flymake-get-source-buffer-name pid))) 629 (cleanup-f (flymake-get-cleanup-function (buffer-file-name source-buffer))))
622 (cleanup-f (flymake-get-cleanup-function (buffer-file-name source-buffer)))) 630
623 631 (flymake-log 2 "process %d exited with code %d"
624 (flymake-log 2 "process %d exited with code %d" pid exit-status) 632 (process-id process) exit-status)
625 (condition-case err 633 (condition-case err
626 (progn 634 (progn
627 (flymake-log 3 "cleaning up using %s" cleanup-f) 635 (flymake-log 3 "cleaning up using %s" cleanup-f)
628 (funcall cleanup-f source-buffer) 636 (when (buffer-live-p source-buffer)
629 637 (with-current-buffer source-buffer
630 (flymake-unreg-names pid) 638 (funcall cleanup-f)))
631 (delete-process process) 639
632 640 (delete-process process)
633 (when source-buffer 641 (setq flymake-processes (delq process flymake-processes))
634 (with-current-buffer source-buffer 642
635 643 (when (buffer-live-p source-buffer)
636 (flymake-parse-residual) 644 (with-current-buffer source-buffer
637 (flymake-post-syntax-check exit-status command) 645
638 (setq flymake-is-running nil)))) 646 (flymake-parse-residual)
639 (error 647 (flymake-post-syntax-check exit-status command)
640 (let ((err-str (format "Error in process sentinel for buffer %s: %s" 648 (setq flymake-is-running nil))))
641 source-buffer (error-message-string err)))) 649 (error
642 (flymake-log 0 err-str) 650 (let ((err-str (format "Error in process sentinel for buffer %s: %s"
643 (with-current-buffer source-buffer 651 source-buffer (error-message-string err))))
644 (setq flymake-is-running nil)))))))) 652 (flymake-log 0 err-str)
653 (with-current-buffer source-buffer
654 (setq flymake-is-running nil))))))))
645 655
646(defun flymake-post-syntax-check (exit-status command) 656(defun flymake-post-syntax-check (exit-status command)
647 (setq flymake-err-info flymake-new-err-info) 657 (setq flymake-err-info flymake-new-err-info)
@@ -689,11 +699,6 @@ It's flymake process filter."
689 (list flymake-output-residual))) 699 (list flymake-output-residual)))
690 (setq flymake-output-residual nil))) 700 (setq flymake-output-residual nil)))
691 701
692(defvar flymake-err-info nil
693 "Sorted list of line numbers and lists of err info in the form (file, err-text).")
694
695(make-variable-buffer-local 'flymake-err-info)
696
697(defun flymake-er-make-er (line-no line-err-info-list) 702(defun flymake-er-make-er (line-no line-err-info-list)
698 (list line-no line-err-info-list)) 703 (list line-no line-err-info-list))
699 704
@@ -703,11 +708,6 @@ It's flymake process filter."
703(defun flymake-er-get-line-err-info-list (err-info) 708(defun flymake-er-get-line-err-info-list (err-info)
704 (nth 1 err-info)) 709 (nth 1 err-info))
705 710
706(defvar flymake-new-err-info nil
707 "Same as `flymake-err-info', effective when a syntax check is in progress.")
708
709(make-variable-buffer-local 'flymake-new-err-info)
710
711;; getters/setters for line-err-info: (file, line, type, text). 711;; getters/setters for line-err-info: (file, line, type, text).
712(defun flymake-ler-make-ler (file line type text &optional full-file) 712(defun flymake-ler-make-ler (file line type text &optional full-file)
713 (list file line type text full-file)) 713 (list file line type text full-file))
@@ -897,7 +897,8 @@ Perhaps use text from LINE-ERR-INFO-LIST to enhance highlighting."
897 (while (< idx count) 897 (while (< idx count)
898 (setq line-err-info (flymake-parse-line (nth idx lines))) 898 (setq line-err-info (flymake-parse-line (nth idx lines)))
899 (when line-err-info 899 (when line-err-info
900 (setq real-file-name (funcall get-real-file-name-f (current-buffer) (flymake-ler-get-file line-err-info))) 900 (setq real-file-name (funcall get-real-file-name-f
901 (flymake-ler-get-file line-err-info)))
901 (setq line-err-info (flymake-ler-set-full-file line-err-info real-file-name)) 902 (setq line-err-info (flymake-ler-set-full-file line-err-info real-file-name))
902 903
903 (if (flymake-same-files real-file-name source-file-name) 904 (if (flymake-same-files real-file-name source-file-name)
@@ -1131,12 +1132,12 @@ For the format of LINE-ERR-INFO, see `flymake-ler-make-ler'."
1131;; "Remove any formatting made by flymake." 1132;; "Remove any formatting made by flymake."
1132;; ) 1133;; )
1133 1134
1134(defun flymake-get-program-dir (buffer) 1135;; (defun flymake-get-program-dir (buffer)
1135 "Get dir to start program in." 1136;; "Get dir to start program in."
1136 (unless (bufferp buffer) 1137;; (unless (bufferp buffer)
1137 (error "Invalid buffer")) 1138;; (error "Invalid buffer"))
1138 (with-current-buffer buffer 1139;; (with-current-buffer buffer
1139 default-directory)) 1140;; default-directory))
1140 1141
1141(defun flymake-safe-delete-file (file-name) 1142(defun flymake-safe-delete-file (file-name)
1142 (when (and file-name (file-exists-p file-name)) 1143 (when (and file-name (file-exists-p file-name))
@@ -1168,19 +1169,18 @@ For the format of LINE-ERR-INFO, see `flymake-ler-make-ler'."
1168 (flymake-clear-project-include-dirs-cache) 1169 (flymake-clear-project-include-dirs-cache)
1169 1170
1170 (setq flymake-check-was-interrupted nil) 1171 (setq flymake-check-was-interrupted nil)
1171 (setq flymake-buffer-data (flymake-makehash 'equal))
1172 1172
1173 (let* ((source-file-name buffer-file-name) 1173 (let* ((source-file-name buffer-file-name)
1174 (init-f (flymake-get-init-function source-file-name)) 1174 (init-f (flymake-get-init-function source-file-name))
1175 (cleanup-f (flymake-get-cleanup-function source-file-name)) 1175 (cleanup-f (flymake-get-cleanup-function source-file-name))
1176 (cmd-and-args (funcall init-f (current-buffer))) 1176 (cmd-and-args (funcall init-f))
1177 (cmd (nth 0 cmd-and-args)) 1177 (cmd (nth 0 cmd-and-args))
1178 (args (nth 1 cmd-and-args)) 1178 (args (nth 1 cmd-and-args))
1179 (dir (nth 2 cmd-and-args))) 1179 (dir (nth 2 cmd-and-args)))
1180 (if (not cmd-and-args) 1180 (if (not cmd-and-args)
1181 (progn 1181 (progn
1182 (flymake-log 0 "init function %s for %s failed, cleaning up" init-f source-file-name) 1182 (flymake-log 0 "init function %s for %s failed, cleaning up" init-f source-file-name)
1183 (funcall cleanup-f (current-buffer))) 1183 (funcall cleanup-f))
1184 (progn 1184 (progn
1185 (setq flymake-last-change-time nil) 1185 (setq flymake-last-change-time nil)
1186 (flymake-start-syntax-check-process cmd args dir))))))) 1186 (flymake-start-syntax-check-process cmd args dir)))))))
@@ -1193,11 +1193,10 @@ For the format of LINE-ERR-INFO, see `flymake-ler-make-ler'."
1193 (when dir 1193 (when dir
1194 (let ((default-directory dir)) 1194 (let ((default-directory dir))
1195 (flymake-log 3 "starting process on dir %s" default-directory))) 1195 (flymake-log 3 "starting process on dir %s" default-directory)))
1196 (setq process (get-process (apply 'start-process "flymake-proc" nil cmd args))) 1196 (setq process (apply 'start-process "flymake-proc" (current-buffer) cmd args))
1197 (set-process-sentinel process 'flymake-process-sentinel) 1197 (set-process-sentinel process 'flymake-process-sentinel)
1198 (set-process-filter process 'flymake-process-filter) 1198 (set-process-filter process 'flymake-process-filter)
1199 1199 (push process flymake-processes)
1200 (flymake-reg-names (process-id process) (buffer-name))
1201 1200
1202 (setq flymake-is-running t) 1201 (setq flymake-is-running t)
1203 (setq flymake-last-change-time nil) 1202 (setq flymake-last-change-time nil)
@@ -1205,7 +1204,8 @@ For the format of LINE-ERR-INFO, see `flymake-ler-make-ler'."
1205 1204
1206 (flymake-report-status nil "*") 1205 (flymake-report-status nil "*")
1207 (flymake-log 2 "started process %d, command=%s, dir=%s" 1206 (flymake-log 2 "started process %d, command=%s, dir=%s"
1208 (process-id process) (process-command process) default-directory) 1207 (process-id process) (process-command process)
1208 default-directory)
1209 process) 1209 process)
1210 (error 1210 (error
1211 (let* ((err-str (format "Failed to launch syntax check process '%s' with args %s: %s" 1211 (let* ((err-str (format "Failed to launch syntax check process '%s' with args %s: %s"
@@ -1213,23 +1213,23 @@ For the format of LINE-ERR-INFO, see `flymake-ler-make-ler'."
1213 (source-file-name buffer-file-name) 1213 (source-file-name buffer-file-name)
1214 (cleanup-f (flymake-get-cleanup-function source-file-name))) 1214 (cleanup-f (flymake-get-cleanup-function source-file-name)))
1215 (flymake-log 0 err-str) 1215 (flymake-log 0 err-str)
1216 (funcall cleanup-f (current-buffer)) 1216 (funcall cleanup-f)
1217 (flymake-report-fatal-status "PROCERR" err-str)))))) 1217 (flymake-report-fatal-status "PROCERR" err-str))))))
1218 1218
1219(defun flymake-kill-process (pid &optional rest) 1219(defun flymake-kill-process (proc)
1220 "Kill process PID." 1220 "Kill process PROC."
1221 (signal-process pid 9) 1221 (kill-process proc)
1222 (let* ((buffer-name (flymake-get-source-buffer-name pid))) 1222 (let* ((buf (process-buffer proc)))
1223 (when (and buffer-name (get-buffer buffer-name)) 1223 (when (buffer-live-p buf)
1224 (with-current-buffer (get-buffer buffer-name) 1224 (with-current-buffer buf
1225 (setq flymake-check-was-interrupted t)))) 1225 (setq flymake-check-was-interrupted t))))
1226 (flymake-log 1 "killed process %d" pid)) 1226 (flymake-log 1 "killed process %d" (process-id proc)))
1227 1227
1228(defun flymake-stop-all-syntax-checks () 1228(defun flymake-stop-all-syntax-checks ()
1229 "Kill all syntax check processes." 1229 "Kill all syntax check processes."
1230 (interactive) 1230 (interactive)
1231 (let ((pids (copy-hash-table flymake-pid-to-names))) 1231 (while flymake-processes
1232 (maphash 'flymake-kill-process pids))) 1232 (flymake-kill-process (pop flymake-processes))))
1233 1233
1234(defun flymake-compilation-is-running () 1234(defun flymake-compilation-is-running ()
1235 (and (boundp 'compilation-in-progress) 1235 (and (boundp 'compilation-in-progress)
@@ -1241,31 +1241,6 @@ For the format of LINE-ERR-INFO, see `flymake-ler-make-ler'."
1241 (flymake-stop-all-syntax-checks) 1241 (flymake-stop-all-syntax-checks)
1242 (call-interactively 'compile)) 1242 (call-interactively 'compile))
1243 1243
1244(defvar flymake-is-running nil
1245 "If t, flymake syntax check process is running for the current buffer.")
1246
1247(make-variable-buffer-local 'flymake-is-running)
1248
1249(defvar flymake-timer nil
1250 "Timer for starting syntax check.")
1251
1252(make-variable-buffer-local 'flymake-timer)
1253
1254(defvar flymake-last-change-time nil
1255 "Time of last buffer change.")
1256
1257(make-variable-buffer-local 'flymake-last-change-time)
1258
1259(defvar flymake-check-start-time nil
1260 "Time at which syntax check was started.")
1261
1262(make-variable-buffer-local 'flymake-check-start-time)
1263
1264(defvar flymake-check-was-interrupted nil
1265 "Non-nil if syntax check was killed by `flymake-compile'.")
1266
1267(make-variable-buffer-local 'flymake-check-was-interrupted)
1268
1269(defcustom flymake-no-changes-timeout 0.5 1244(defcustom flymake-no-changes-timeout 0.5
1270 "Time to wait after last change before starting compilation." 1245 "Time to wait after last change before starting compilation."
1271 :group 'flymake 1246 :group 'flymake
@@ -1294,33 +1269,16 @@ For the format of LINE-ERR-INFO, see `flymake-ler-make-ler'."
1294 "Return number of lines in buffer BUFFER." 1269 "Return number of lines in buffer BUFFER."
1295 (count-lines (point-min) (point-max))) 1270 (count-lines (point-min) (point-max)))
1296 1271
1297(defun flymake-get-point-pixel-pos ()
1298 "Return point position in pixels: (x, y)."
1299 (let ((mouse-pos (mouse-position))
1300 (pixel-pos nil)
1301 (ret nil))
1302 (if (car (cdr mouse-pos))
1303 (progn
1304 (set-mouse-position (flymake-selected-frame) (current-column) (flymake-current-row))
1305 (setq pixel-pos (mouse-pixel-position))
1306 (set-mouse-position (car mouse-pos) (car (cdr mouse-pos)) (cdr (cdr mouse-pos)))
1307 (setq ret (list (car (cdr pixel-pos)) (cdr (cdr pixel-pos)))))
1308 (progn
1309 (setq ret '(0 0))))
1310 (flymake-log 3 "mouse pos is %s" ret)
1311 ret))
1312
1313(defun flymake-display-err-menu-for-current-line () 1272(defun flymake-display-err-menu-for-current-line ()
1314 "Display a menu with errors/warnings for current line if it has errors and/or warnings." 1273 "Display a menu with errors/warnings for current line if it has errors and/or warnings."
1315 (interactive) 1274 (interactive)
1316 (let* ((line-no (flymake-current-line-no)) 1275 (let* ((line-no (flymake-current-line-no))
1317 (line-err-info-list (nth 0 (flymake-find-err-info flymake-err-info line-no))) 1276 (line-err-info-list (nth 0 (flymake-find-err-info flymake-err-info line-no)))
1318 (menu-data (flymake-make-err-menu-data line-no line-err-info-list)) 1277 (menu-data (flymake-make-err-menu-data line-no line-err-info-list))
1319 (choice nil) 1278 (choice nil))
1320 (menu-pos (list (flymake-get-point-pixel-pos) (selected-window))))
1321 (if menu-data 1279 (if menu-data
1322 (progn 1280 (progn
1323 (setq choice (flymake-popup-menu menu-pos menu-data)) 1281 (setq choice (flymake-popup-menu menu-data))
1324 (flymake-log 3 "choice=%s" choice) 1282 (flymake-log 3 "choice=%s" choice)
1325 (when choice 1283 (when choice
1326 (eval choice))) 1284 (eval choice)))
@@ -1579,20 +1537,14 @@ With arg, turn Flymake mode on if and only if arg is positive."
1579 (error "Invalid file-name")) 1537 (error "Invalid file-name"))
1580 1538
1581 (let* ((dir (file-name-directory file-name)) 1539 (let* ((dir (file-name-directory file-name))
1540 ;; Not sure what this slash-pos is all about, but I guess it's just
1541 ;; trying to remove the leading / of absolute file names.
1582 (slash-pos (string-match "/" dir)) 1542 (slash-pos (string-match "/" dir))
1583 (temp-dir (concat (file-name-as-directory (flymake-get-temp-dir)) (substring dir (1+ slash-pos))))) 1543 (temp-dir (expand-file-name (substring dir (1+ slash-pos))
1544 (flymake-get-temp-dir))))
1584 1545
1585 (file-truename (concat (file-name-as-directory temp-dir) 1546 (file-truename (expand-file-name (file-name-nondirectory file-name)
1586 (file-name-nondirectory file-name))))) 1547 temp-dir))))
1587
1588(defun flymake-strrchr (str ch)
1589 (let* ((count (length str))
1590 (pos nil))
1591 (while (and (not pos) (> count 0))
1592 (if (= ch (elt str (1- count)))
1593 (setq pos (1- count)))
1594 (setq count (1- count)))
1595 pos))
1596 1548
1597(defun flymake-delete-temp-directory (dir-name) 1549(defun flymake-delete-temp-directory (dir-name)
1598 "Attempt to delete temp dir created by `flymake-create-temp-with-folder-structure', do not fail on error." 1550 "Attempt to delete temp dir created by `flymake-create-temp-with-folder-structure', do not fail on error."
@@ -1601,45 +1553,55 @@ With arg, turn Flymake mode on if and only if arg is positive."
1601 (slash-pos nil)) 1553 (slash-pos nil))
1602 1554
1603 (while (> (length suffix) 0) 1555 (while (> (length suffix) 0)
1556 (setq suffix (directory-file-name suffix))
1604 ;;+(flymake-log 0 "suffix=%s" suffix) 1557 ;;+(flymake-log 0 "suffix=%s" suffix)
1605 (flymake-safe-delete-directory (file-truename (concat (file-name-as-directory temp-dir) suffix))) 1558 (flymake-safe-delete-directory
1606 (setq slash-pos (flymake-strrchr suffix (string-to-char "/"))) 1559 (file-truename (expand-file-name suffix temp-dir)))
1607 (if slash-pos 1560 (setq suffix (file-name-directory suffix)))))
1608 (setq suffix (substring suffix 0 slash-pos)) 1561
1609 (setq suffix ""))))) 1562(defvar flymake-temp-source-file-name nil)
1563(make-variable-buffer-local 'flymake-temp-source-file-name)
1564
1565(defvar flymake-master-file-name nil)
1566(make-variable-buffer-local 'flymake-master-file-name)
1567
1568(defvar flymake-temp-master-file-name nil)
1569(make-variable-buffer-local 'flymake-temp-master-file-name)
1610 1570
1611(defun flymake-init-create-temp-buffer-copy (buffer create-temp-f) 1571(defvar flymake-base-dir nil)
1572(make-variable-buffer-local 'flymake-base-dir)
1573
1574(defun flymake-init-create-temp-buffer-copy (create-temp-f)
1612 "Make a temporary copy of the current buffer, save its name in buffer data and return the name." 1575 "Make a temporary copy of the current buffer, save its name in buffer data and return the name."
1613 (let* ((source-file-name (buffer-file-name buffer)) 1576 (let* ((source-file-name buffer-file-name)
1614 (temp-source-file-name (funcall create-temp-f source-file-name "flymake"))) 1577 (temp-source-file-name (funcall create-temp-f source-file-name "flymake")))
1615 1578
1616 (flymake-save-buffer-in-file buffer temp-source-file-name) 1579 (flymake-save-buffer-in-file temp-source-file-name)
1617 (flymake-set-buffer-value buffer "temp-source-file-name" temp-source-file-name) 1580 (setq flymake-temp-source-file-name temp-source-file-name)
1618 temp-source-file-name)) 1581 temp-source-file-name))
1619 1582
1620(defun flymake-simple-cleanup (buffer) 1583(defun flymake-simple-cleanup ()
1621 "Do cleanup after `flymake-init-create-temp-buffer-copy'. 1584 "Do cleanup after `flymake-init-create-temp-buffer-copy'.
1622Delete temp file." 1585Delete temp file."
1623 (let* ((temp-source-file-name (flymake-get-buffer-value buffer "temp-source-file-name"))) 1586 (flymake-safe-delete-file flymake-temp-source-file-name)
1624 (flymake-safe-delete-file temp-source-file-name) 1587 (setq flymake-last-change-time nil))
1625 (with-current-buffer buffer
1626 (setq flymake-last-change-time nil))))
1627 1588
1628(defun flymake-get-real-file-name (buffer file-name-from-err-msg) 1589(defun flymake-get-real-file-name (file-name-from-err-msg)
1629 "Translate file name from error message to \"real\" file name. 1590 "Translate file name from error message to \"real\" file name.
1630Return full-name. Names are real, not patched." 1591Return full-name. Names are real, not patched."
1631 (let* ((real-name nil) 1592 (let* ((real-name nil)
1632 (source-file-name (buffer-file-name buffer)) 1593 (source-file-name buffer-file-name)
1633 (master-file-name (flymake-get-buffer-value buffer "master-file-name")) 1594 (master-file-name flymake-master-file-name)
1634 (temp-source-file-name (flymake-get-buffer-value buffer "temp-source-file-name")) 1595 (temp-source-file-name flymake-temp-source-file-name)
1635 (temp-master-file-name (flymake-get-buffer-value buffer "temp-master-file-name")) 1596 (temp-master-file-name flymake-temp-master-file-name)
1636 (base-dirs (list (flymake-get-buffer-value buffer "base-dir") 1597 (base-dirs
1637 (file-name-directory source-file-name) 1598 (list flymake-base-dir
1638 (if master-file-name (file-name-directory master-file-name) nil))) 1599 (file-name-directory source-file-name)
1639 (files (list (list source-file-name source-file-name) 1600 (if master-file-name (file-name-directory master-file-name))))
1640 (list temp-source-file-name source-file-name) 1601 (files (list (list source-file-name source-file-name)
1641 (list master-file-name master-file-name) 1602 (list temp-source-file-name source-file-name)
1642 (list temp-master-file-name master-file-name)))) 1603 (list master-file-name master-file-name)
1604 (list temp-master-file-name master-file-name))))
1643 1605
1644 (when (equal 0 (length file-name-from-err-msg)) 1606 (when (equal 0 (length file-name-from-err-msg))
1645 (setq file-name-from-err-msg source-file-name)) 1607 (setq file-name-from-err-msg source-file-name))
@@ -1687,27 +1649,23 @@ Return full-name. Names are real, not patched."
1687 (setq base-dirs-count (1- base-dirs-count)))))) 1649 (setq base-dirs-count (1- base-dirs-count))))))
1688 real-name)) 1650 real-name))
1689 1651
1690(defun flymake-init-find-buildfile-dir (buffer source-file-name buildfile-name) 1652(defun flymake-init-find-buildfile-dir (source-file-name buildfile-name)
1691 "Find buildfile, store its dir in buffer data and return its dir, if found." 1653 "Find buildfile, store its dir in buffer data and return its dir, if found."
1692 (let* ((buildfile-dir (flymake-find-buildfile buildfile-name 1654 (let* ((buildfile-dir
1693 (file-name-directory source-file-name) 1655 (flymake-find-buildfile buildfile-name
1694 flymake-buildfile-dirs))) 1656 (file-name-directory source-file-name)
1695 (if (not buildfile-dir) 1657 flymake-buildfile-dirs)))
1696 (progn 1658 (if buildfile-dir
1697 (flymake-log 1 "no buildfile (%s) for %s" buildfile-name source-file-name) 1659 (setq flymake-base-dir buildfile-dir)
1698 (with-current-buffer buffer 1660 (flymake-log 1 "no buildfile (%s) for %s" buildfile-name source-file-name)
1699 (flymake-report-fatal-status "NOMK" (format "No buildfile (%s) found for %s" buildfile-name source-file-name))) 1661 (flymake-report-fatal-status
1700 ) 1662 "NOMK" (format "No buildfile (%s) found for %s"
1701 (progn 1663 buildfile-name source-file-name)))))
1702 (flymake-set-buffer-value buffer "base-dir" buildfile-dir)))
1703 buildfile-dir))
1704 1664
1705(defun flymake-init-create-temp-source-and-master-buffer-copy (buffer get-incl-dirs-f create-temp-f master-file-masks include-regexp-list) 1665(defun flymake-init-create-temp-source-and-master-buffer-copy (get-incl-dirs-f create-temp-f master-file-masks include-regexp-list)
1706 "Find master file (or buffer), create it's copy along with a copy of the source file." 1666 "Find master file (or buffer), create it's copy along with a copy of the source file."
1707 (let* ((source-file-name (buffer-file-name buffer)) 1667 (let* ((source-file-name buffer-file-name)
1708 (temp-source-file-name (flymake-init-create-temp-buffer-copy buffer create-temp-f)) 1668 (temp-source-file-name (flymake-init-create-temp-buffer-copy create-temp-f))
1709 (master-file-name nil)
1710 (temp-master-file-name nil)
1711 (master-and-temp-master (flymake-create-master-file 1669 (master-and-temp-master (flymake-create-master-file
1712 source-file-name temp-source-file-name 1670 source-file-name temp-source-file-name
1713 get-incl-dirs-f create-temp-f 1671 get-incl-dirs-f create-temp-f
@@ -1716,21 +1674,14 @@ Return full-name. Names are real, not patched."
1716 (if (not master-and-temp-master) 1674 (if (not master-and-temp-master)
1717 (progn 1675 (progn
1718 (flymake-log 1 "cannot find master file for %s" source-file-name) 1676 (flymake-log 1 "cannot find master file for %s" source-file-name)
1719 (when (bufferp buffer) 1677 (flymake-report-status "!" "") ; NOMASTER
1720 (with-current-buffer buffer 1678 nil)
1721 (flymake-report-status "!" ""))) ; NOMASTER 1679 (setq flymake-master-file-name (nth 0 master-and-temp-master))
1722 ) 1680 (setq flymake-temp-master-file-name (nth 1 master-and-temp-master)))))
1723 (progn
1724 (setq master-file-name (nth 0 master-and-temp-master))
1725 (setq temp-master-file-name (nth 1 master-and-temp-master))
1726 (flymake-set-buffer-value buffer "master-file-name" master-file-name)
1727 (flymake-set-buffer-value buffer "temp-master-file-name" temp-master-file-name)
1728 ))
1729 temp-master-file-name))
1730 1681
1731(defun flymake-master-cleanup (buffer) 1682(defun flymake-master-cleanup ()
1732 (flymake-simple-cleanup buffer) 1683 (flymake-simple-cleanup)
1733 (flymake-safe-delete-file (flymake-get-buffer-value buffer "temp-master-file-name"))) 1684 (flymake-safe-delete-file flymake-temp-master-file-name))
1734 1685
1735;;;; make-specific init-cleanup routines 1686;;;; make-specific init-cleanup routines
1736(defun flymake-get-syntax-check-program-args (source-file-name base-dir use-relative-base-dir use-relative-source get-cmd-line-f) 1687(defun flymake-get-syntax-check-program-args (source-file-name base-dir use-relative-base-dir use-relative-source get-cmd-line-f)
@@ -1762,30 +1713,30 @@ Return full-name. Names are real, not patched."
1762 (concat "-DCHK_SOURCES=" source) 1713 (concat "-DCHK_SOURCES=" source)
1763 "check-syntax"))) 1714 "check-syntax")))
1764 1715
1765(defun flymake-simple-make-init-impl (buffer create-temp-f use-relative-base-dir use-relative-source build-file-name get-cmdline-f) 1716(defun flymake-simple-make-init-impl (create-temp-f use-relative-base-dir use-relative-source build-file-name get-cmdline-f)
1766 "Create syntax check command line for a directly checked source file. 1717 "Create syntax check command line for a directly checked source file.
1767Use CREATE-TEMP-F for creating temp copy." 1718Use CREATE-TEMP-F for creating temp copy."
1768 (let* ((args nil) 1719 (let* ((args nil)
1769 (source-file-name (buffer-file-name buffer)) 1720 (source-file-name buffer-file-name)
1770 (buildfile-dir (flymake-init-find-buildfile-dir buffer source-file-name build-file-name))) 1721 (buildfile-dir (flymake-init-find-buildfile-dir source-file-name build-file-name)))
1771 (if buildfile-dir 1722 (if buildfile-dir
1772 (let* ((temp-source-file-name (flymake-init-create-temp-buffer-copy buffer create-temp-f))) 1723 (let* ((temp-source-file-name (flymake-init-create-temp-buffer-copy create-temp-f)))
1773 (setq args (flymake-get-syntax-check-program-args temp-source-file-name buildfile-dir 1724 (setq args (flymake-get-syntax-check-program-args temp-source-file-name buildfile-dir
1774 use-relative-base-dir use-relative-source 1725 use-relative-base-dir use-relative-source
1775 get-cmdline-f)))) 1726 get-cmdline-f))))
1776 args)) 1727 args))
1777 1728
1778(defun flymake-simple-make-init (buffer) 1729(defun flymake-simple-make-init ()
1779 (flymake-simple-make-init-impl buffer 'flymake-create-temp-inplace t t "Makefile" 'flymake-get-make-cmdline)) 1730 (flymake-simple-make-init-impl 'flymake-create-temp-inplace t t "Makefile" 'flymake-get-make-cmdline))
1780 1731
1781(defun flymake-master-make-init (buffer get-incl-dirs-f master-file-masks include-regexp-list) 1732(defun flymake-master-make-init (get-incl-dirs-f master-file-masks include-regexp-list)
1782 "Create make command line for a source file checked via master file compilation." 1733 "Create make command line for a source file checked via master file compilation."
1783 (let* ((make-args nil) 1734 (let* ((make-args nil)
1784 (temp-master-file-name (flymake-init-create-temp-source-and-master-buffer-copy 1735 (temp-master-file-name (flymake-init-create-temp-source-and-master-buffer-copy
1785 buffer get-incl-dirs-f 'flymake-create-temp-inplace 1736 get-incl-dirs-f 'flymake-create-temp-inplace
1786 master-file-masks include-regexp-list))) 1737 master-file-masks include-regexp-list)))
1787 (when temp-master-file-name 1738 (when temp-master-file-name
1788 (let* ((buildfile-dir (flymake-init-find-buildfile-dir buffer temp-master-file-name "Makefile"))) 1739 (let* ((buildfile-dir (flymake-init-find-buildfile-dir temp-master-file-name "Makefile")))
1789 (if buildfile-dir 1740 (if buildfile-dir
1790 (setq make-args (flymake-get-syntax-check-program-args 1741 (setq make-args (flymake-get-syntax-check-program-args
1791 temp-master-file-name buildfile-dir nil nil 'flymake-get-make-cmdline))))) 1742 temp-master-file-name buildfile-dir nil nil 'flymake-get-make-cmdline)))))
@@ -1795,30 +1746,29 @@ Use CREATE-TEMP-F for creating temp copy."
1795 (flymake-find-buildfile "Makefile" source-dir flymake-buildfile-dirs)) 1746 (flymake-find-buildfile "Makefile" source-dir flymake-buildfile-dirs))
1796 1747
1797;;;; .h/make specific 1748;;;; .h/make specific
1798(defun flymake-master-make-header-init (buffer) 1749(defun flymake-master-make-header-init ()
1799 (flymake-master-make-init buffer 1750 (flymake-master-make-init 'flymake-get-include-dirs
1800 'flymake-get-include-dirs 1751 '("\\.cpp\\'" "\\.c\\'")
1801 '(".+\\.cpp$" ".+\\.c$")
1802 '("[ \t]*#[ \t]*include[ \t]*\"\\([\w0-9/\\_\.]*[/\\]*\\)\\(%s\\)\"" 1 2))) 1752 '("[ \t]*#[ \t]*include[ \t]*\"\\([\w0-9/\\_\.]*[/\\]*\\)\\(%s\\)\"" 1 2)))
1803 1753
1804;;;; .java/make specific 1754;;;; .java/make specific
1805(defun flymake-simple-make-java-init (buffer) 1755(defun flymake-simple-make-java-init ()
1806 (flymake-simple-make-init-impl buffer 'flymake-create-temp-with-folder-structure nil nil "Makefile" 'flymake-get-make-cmdline)) 1756 (flymake-simple-make-init-impl 'flymake-create-temp-with-folder-structure nil nil "Makefile" 'flymake-get-make-cmdline))
1807 1757
1808(defun flymake-simple-ant-java-init (buffer) 1758(defun flymake-simple-ant-java-init ()
1809 (flymake-simple-make-init-impl buffer 'flymake-create-temp-with-folder-structure nil nil "build.xml" 'flymake-get-ant-cmdline)) 1759 (flymake-simple-make-init-impl 'flymake-create-temp-with-folder-structure nil nil "build.xml" 'flymake-get-ant-cmdline))
1810 1760
1811(defun flymake-simple-java-cleanup (buffer) 1761(defun flymake-simple-java-cleanup ()
1812 "Cleanup after `flymake-simple-make-java-init' -- delete temp file and dirs." 1762 "Cleanup after `flymake-simple-make-java-init' -- delete temp file and dirs."
1813 (let* ((temp-source-file-name (flymake-get-buffer-value buffer "temp-source-file-name"))) 1763 (flymake-safe-delete-file flymake-temp-source-file-name)
1814 (flymake-safe-delete-file temp-source-file-name) 1764 (when flymake-temp-source-file-name
1815 (when temp-source-file-name 1765 (flymake-delete-temp-directory
1816 (flymake-delete-temp-directory (file-name-directory temp-source-file-name))))) 1766 (file-name-directory flymake-temp-source-file-name))))
1817 1767
1818;;;; perl-specific init-cleanup routines 1768;;;; perl-specific init-cleanup routines
1819(defun flymake-perl-init (buffer) 1769(defun flymake-perl-init ()
1820 (let* ((temp-file (flymake-init-create-temp-buffer-copy 1770 (let* ((temp-file (flymake-init-create-temp-buffer-copy
1821 buffer 'flymake-create-temp-inplace)) 1771 'flymake-create-temp-inplace))
1822 (local-file (concat (flymake-build-relative-filename 1772 (local-file (concat (flymake-build-relative-filename
1823 (file-name-directory buffer-file-name) 1773 (file-name-directory buffer-file-name)
1824 (file-name-directory temp-file)) 1774 (file-name-directory temp-file))
@@ -1830,13 +1780,13 @@ Use CREATE-TEMP-F for creating temp copy."
1830 ;;(list "latex" (list "-c-style-errors" file-name)) 1780 ;;(list "latex" (list "-c-style-errors" file-name))
1831 (list "texify" (list "--pdf" "--tex-option=-c-style-errors" file-name))) 1781 (list "texify" (list "--pdf" "--tex-option=-c-style-errors" file-name)))
1832 1782
1833(defun flymake-simple-tex-init (buffer) 1783(defun flymake-simple-tex-init ()
1834 (flymake-get-tex-args (flymake-init-create-temp-buffer-copy buffer 'flymake-create-temp-inplace))) 1784 (flymake-get-tex-args (flymake-init-create-temp-buffer-copy 'flymake-create-temp-inplace)))
1835 1785
1836(defun flymake-master-tex-init (buffer) 1786(defun flymake-master-tex-init ()
1837 (let* ((temp-master-file-name (flymake-init-create-temp-source-and-master-buffer-copy 1787 (let* ((temp-master-file-name (flymake-init-create-temp-source-and-master-buffer-copy
1838 buffer 'flymake-get-include-dirs-dot 'flymake-create-temp-inplace 1788 'flymake-get-include-dirs-dot 'flymake-create-temp-inplace
1839 '(".+\\.tex$") 1789 '("\\.tex\\'")
1840 '("[ \t]*\\input[ \t]*{\\(.*\\)\\(%s\\)}" 1 2)))) 1790 '("[ \t]*\\input[ \t]*{\\(.*\\)\\(%s\\)}" 1 2))))
1841 (when temp-master-file-name 1791 (when temp-master-file-name
1842 (flymake-get-tex-args temp-master-file-name)))) 1792 (flymake-get-tex-args temp-master-file-name))))
@@ -1845,8 +1795,8 @@ Use CREATE-TEMP-F for creating temp copy."
1845 '(".")) 1795 '("."))
1846 1796
1847;;;; xml-specific init-cleanup routines 1797;;;; xml-specific init-cleanup routines
1848(defun flymake-xml-init (buffer) 1798(defun flymake-xml-init ()
1849 (list "xml" (list "val" (flymake-init-create-temp-buffer-copy buffer 'flymake-create-temp-inplace)))) 1799 (list "xml" (list "val" (flymake-init-create-temp-buffer-copy 'flymake-create-temp-inplace))))
1850 1800
1851(provide 'flymake) 1801(provide 'flymake)
1852 1802
diff --git a/lisp/simple.el b/lisp/simple.el
index 77345333137..01a1cc74a5a 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -3061,10 +3061,12 @@ it is possible that the region may have changed")
3061 "Hook run when the mark becomes inactive.") 3061 "Hook run when the mark becomes inactive.")
3062 3062
3063(defun mark (&optional force) 3063(defun mark (&optional force)
3064 "Return this buffer's mark value as integer; error if mark inactive. 3064 "Return this buffer's mark value as integer, or nil if never set.
3065If optional argument FORCE is non-nil, access the mark value 3065
3066even if the mark is not currently active, and return nil 3066In Transient Mark mode, this function signals an error if
3067if there is no mark at all. 3067the mark is not active. However, if `mark-even-if-inactive' is non-nil,
3068or the argument FORCE is non-nil, it disregards whether the mark
3069is active, and returns an integer or nil in the usual way.
3068 3070
3069If you are using this in an editing command, you are most likely making 3071If you are using this in an editing command, you are most likely making
3070a mistake; see the documentation of `set-mark'." 3072a mistake; see the documentation of `set-mark'."
@@ -3679,15 +3681,13 @@ and `current-column' to be able to ignore invisible text."
3679 (goto-char (previous-char-property-change (point) line-beg)))))))) 3681 (goto-char (previous-char-property-change (point) line-beg))))))))
3680 3682
3681(defun move-end-of-line (arg) 3683(defun move-end-of-line (arg)
3682 "Move point to end of current line. 3684 "Move point to end of current line as displayed.
3685\(If there's an image in the line, this disregards newlines
3686which are part of the text that the image rests on.)
3687
3683With argument ARG not nil or 1, move forward ARG - 1 lines first. 3688With argument ARG not nil or 1, move forward ARG - 1 lines first.
3684If point reaches the beginning or end of buffer, it stops there. 3689If point reaches the beginning or end of buffer, it stops there.
3685To ignore intangibility, bind `inhibit-point-motion-hooks' to t. 3690To ignore intangibility, bind `inhibit-point-motion-hooks' to t."
3686
3687This command does not move point across a field boundary unless doing so
3688would move beyond there to a different line; if ARG is nil or 1, and
3689point starts at a field boundary, point does not move. To ignore field
3690boundaries bind `inhibit-field-text-motion' to t."
3691 (interactive "p") 3691 (interactive "p")
3692 (or arg (setq arg 1)) 3692 (or arg (setq arg 1))
3693 (let (done) 3693 (let (done)
@@ -3715,15 +3715,13 @@ boundaries bind `inhibit-field-text-motion' to t."
3715 (setq done t))))))) 3715 (setq done t)))))))
3716 3716
3717(defun move-beginning-of-line (arg) 3717(defun move-beginning-of-line (arg)
3718 "Move point to beginning of current display line. 3718 "Move point to beginning of current line as displayed.
3719\(If there's an image in the line, this disregards newlines
3720which are part of the text that the image rests on.)
3721
3719With argument ARG not nil or 1, move forward ARG - 1 lines first. 3722With argument ARG not nil or 1, move forward ARG - 1 lines first.
3720If point reaches the beginning or end of buffer, it stops there. 3723If point reaches the beginning or end of buffer, it stops there.
3721To ignore intangibility, bind `inhibit-point-motion-hooks' to t. 3724To ignore intangibility, bind `inhibit-point-motion-hooks' to t."
3722
3723This command does not move point across a field boundary unless doing so
3724would move beyond there to a different line; if ARG is nil or 1, and
3725point starts at a field boundary, point does not move. To ignore field
3726boundaries bind `inhibit-field-text-motion' to t."
3727 (interactive "p") 3725 (interactive "p")
3728 (or arg (setq arg 1)) 3726 (or arg (setq arg 1))
3729 (if (/= arg 1) 3727 (if (/= arg 1)
diff --git a/lisp/startup.el b/lisp/startup.el
index 21e9fce07c1..2db01f1eecb 100644
--- a/lisp/startup.el
+++ b/lisp/startup.el
@@ -1,7 +1,7 @@
1;;; startup.el --- process Emacs shell arguments 1;;; startup.el --- process Emacs shell arguments
2 2
3;; Copyright (C) 1985, 1986, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 3;; Copyright (C) 1985, 1986, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
4;; 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. 4;; 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
5 5
6;; Maintainer: FSF 6;; Maintainer: FSF
7;; Keywords: internal 7;; Keywords: internal
@@ -1250,7 +1250,7 @@ where FACE is a valid face specification, as it can be used with
1250 (emacs-version) 1250 (emacs-version)
1251 "\n" 1251 "\n"
1252 :face '(variable-pitch :height 0.5) 1252 :face '(variable-pitch :height 0.5)
1253 "Copyright (C) 2005 Free Software Foundation, Inc.") 1253 "Copyright (C) 2006 Free Software Foundation, Inc.")
1254 (and auto-save-list-file-prefix 1254 (and auto-save-list-file-prefix
1255 ;; Don't signal an error if the 1255 ;; Don't signal an error if the
1256 ;; directory for auto-save-list files 1256 ;; directory for auto-save-list files
@@ -1439,7 +1439,7 @@ More Manuals / Ordering Manuals How to order printed manuals from the FSF
1439") 1439")
1440 (insert "\n\n" (emacs-version) 1440 (insert "\n\n" (emacs-version)
1441 " 1441 "
1442Copyright (C) 2005 Free Software Foundation, Inc.")) 1442Copyright (C) 2006 Free Software Foundation, Inc."))
1443 1443
1444 ;; No mouse menus, so give help using kbd commands. 1444 ;; No mouse menus, so give help using kbd commands.
1445 1445
@@ -1487,7 +1487,7 @@ If you have no Meta key, you may instead type ESC followed by the character.)")
1487 1487
1488 (insert "\n\n" (emacs-version) 1488 (insert "\n\n" (emacs-version)
1489 " 1489 "
1490Copyright (C) 2005 Free Software Foundation, Inc.") 1490Copyright (C) 2006 Free Software Foundation, Inc.")
1491 1491
1492 (if (and (eq (key-binding "\C-h\C-c") 'describe-copying) 1492 (if (and (eq (key-binding "\C-h\C-c") 'describe-copying)
1493 (eq (key-binding "\C-h\C-d") 'describe-distribution) 1493 (eq (key-binding "\C-h\C-d") 'describe-distribution)
diff --git a/lisp/term/mac-win.el b/lisp/term/mac-win.el
index 6feaa347c8b..dea988868eb 100644
--- a/lisp/term/mac-win.el
+++ b/lisp/term/mac-win.el
@@ -1381,7 +1381,7 @@ in `selection-converter-alist', which see."
1381(put 'core-event 'mac-apple-event-class "aevt") ; kCoreEventClass 1381(put 'core-event 'mac-apple-event-class "aevt") ; kCoreEventClass
1382(put 'internet-event 'mac-apple-event-class "GURL") ; kAEInternetEventClass 1382(put 'internet-event 'mac-apple-event-class "GURL") ; kAEInternetEventClass
1383 1383
1384;;; Event IDs 1384;;; Event IDs
1385;; kCoreEventClass 1385;; kCoreEventClass
1386(put 'open-application 'mac-apple-event-id "oapp") ; kAEOpenApplication 1386(put 'open-application 'mac-apple-event-id "oapp") ; kAEOpenApplication
1387(put 'reopen-application 'mac-apple-event-id "rapp") ; kAEReopenApplication 1387(put 'reopen-application 'mac-apple-event-id "rapp") ; kAEReopenApplication
@@ -1409,14 +1409,14 @@ in `selection-converter-alist', which see."
1409 (error "Not an Apple event: %S" ae) 1409 (error "Not an Apple event: %S" ae)
1410 (let ((type-data (cdr (assoc keyword (cdr ae)))) 1410 (let ((type-data (cdr (assoc keyword (cdr ae))))
1411 data) 1411 data)
1412 (when (and type type-data) 1412 (when (and type type-data (not (equal type (car type-data))))
1413 (setq data (mac-coerce-ae-data (car type-data) (cdr type-data) type)) 1413 (setq data (mac-coerce-ae-data (car type-data) (cdr type-data) type))
1414 (setq type-data (if data (cons type data) nil))) 1414 (setq type-data (if data (cons type data) nil)))
1415 type-data))) 1415 type-data)))
1416 1416
1417(defun mac-ae-list (ae &optional keyword type) 1417(defun mac-ae-list (ae &optional keyword type)
1418 (or keyword (setq keyword "----")) ;; Direct object. 1418 (or keyword (setq keyword "----")) ;; Direct object.
1419 (let ((desc (mac-ae-parameter ae keyword))) 1419 (let ((desc (mac-ae-parameter ae keyword "list")))
1420 (cond ((null desc) 1420 (cond ((null desc)
1421 nil) 1421 nil)
1422 ((not (equal (car desc) "list")) 1422 ((not (equal (car desc) "list"))
@@ -1588,6 +1588,9 @@ Currently the `mailto' scheme is supported."
1588 (setq service-message 1588 (setq service-message
1589 (intern (decode-coding-string service-message 'utf-8))) 1589 (intern (decode-coding-string service-message 'utf-8)))
1590 (setq binding (lookup-key binding (vector service-message)))) 1590 (setq binding (lookup-key binding (vector service-message))))
1591 ;; Replace (cadr event) with a dummy position so that event-start
1592 ;; returns it.
1593 (setcar (cdr event) (list (selected-window) (point) '(0 . 0) 0))
1591 (call-interactively binding))) 1594 (call-interactively binding)))
1592 1595
1593(global-set-key [mac-apple-event] 'mac-dispatch-apple-event) 1596(global-set-key [mac-apple-event] 'mac-dispatch-apple-event)
diff --git a/lisp/textmodes/flyspell.el b/lisp/textmodes/flyspell.el
index 33582af28b9..39d4b1f7b69 100644
--- a/lisp/textmodes/flyspell.el
+++ b/lisp/textmodes/flyspell.el
@@ -1,7 +1,7 @@
1;;; flyspell.el --- on-the-fly spell checker 1;;; flyspell.el --- on-the-fly spell checker
2 2
3;; Copyright (C) 1998, 2000, 2002, 2003, 2004, 3;; Copyright (C) 1998, 2000, 2002, 2003, 2004,
4;; 2005 Free Software Foundation, Inc. 4;; 2005, 2006 Free Software Foundation, Inc.
5 5
6;; Author: Manuel Serrano <Manuel.Serrano@sophia.inria.fr> 6;; Author: Manuel Serrano <Manuel.Serrano@sophia.inria.fr>
7;; Maintainer: FSF 7;; Maintainer: FSF
@@ -504,11 +504,11 @@ in your .emacs file.
504(defvar flyspell-last-buffer nil 504(defvar flyspell-last-buffer nil
505 "The buffer in which the last flyspell operation took place.") 505 "The buffer in which the last flyspell operation took place.")
506 506
507(defun flyspell-accept-buffer-local-defs () 507(defun flyspell-accept-buffer-local-defs (&optional force)
508 ;; When flyspell-word is used inside a loop (e.g. when processing 508 ;; When flyspell-word is used inside a loop (e.g. when processing
509 ;; flyspell-changes), the calls to `ispell-accept-buffer-local-defs' end 509 ;; flyspell-changes), the calls to `ispell-accept-buffer-local-defs' end
510 ;; up dwarfing everything else, so only do it when the buffer has changed. 510 ;; up dwarfing everything else, so only do it when the buffer has changed.
511 (unless (eq flyspell-last-buffer (current-buffer)) 511 (when (or force (not (eq flyspell-last-buffer (current-buffer))))
512 (setq flyspell-last-buffer (current-buffer)) 512 (setq flyspell-last-buffer (current-buffer))
513 ;; Strange problem: If buffer in current window has font-lock turned on, 513 ;; Strange problem: If buffer in current window has font-lock turned on,
514 ;; but SET-BUFFER was called to point to an invisible buffer, this ispell 514 ;; but SET-BUFFER was called to point to an invisible buffer, this ispell
@@ -539,7 +539,9 @@ in your .emacs file.
539 ;; we have to force ispell to accept the local definition or 539 ;; we have to force ispell to accept the local definition or
540 ;; otherwise it could be too late, the local dictionary may 540 ;; otherwise it could be too late, the local dictionary may
541 ;; be forgotten! 541 ;; be forgotten!
542 (flyspell-accept-buffer-local-defs) 542 ;; Pass the `force' argument for the case where flyspell was active already
543 ;; but the buffer's local-defs have been edited.
544 (flyspell-accept-buffer-local-defs 'force)
543 ;; we put the `flyspell-delayed' property on some commands 545 ;; we put the `flyspell-delayed' property on some commands
544 (flyspell-delay-commands) 546 (flyspell-delay-commands)
545 ;; we put the `flyspell-deplacement' property on some commands 547 ;; we put the `flyspell-deplacement' property on some commands
diff --git a/lisp/textmodes/org.el b/lisp/textmodes/org.el
index 3cdc40b9f32..dfb169769d3 100644
--- a/lisp/textmodes/org.el
+++ b/lisp/textmodes/org.el
@@ -1,11 +1,11 @@
1;;; org.el --- Outline-based notes management and organize 1;;; org.el --- Outline-based notes management and organize
2;; Carstens outline-mode for keeping track of everything. 2;; Carstens outline-mode for keeping track of everything.
3;; Copyright (c) 2004, 2005 Free Software Foundation 3;; Copyright (c) 2004, 2005, 2006 Free Software Foundation
4;; 4;;
5;; Author: Carsten Dominik <dominik at science dot uva dot nl> 5;; Author: Carsten Dominik <dominik at science dot uva dot nl>
6;; Keywords: outlines, hypermedia, calendar, wp 6;; Keywords: outlines, hypermedia, calendar, wp
7;; Homepage: http://www.astro.uva.nl/~dominik/Tools/org/ 7;; Homepage: http://www.astro.uva.nl/~dominik/Tools/org/
8;; Version: 4.01 8;; Version: 4.02
9;; 9;;
10;; This file is part of GNU Emacs. 10;; This file is part of GNU Emacs.
11;; 11;;
@@ -79,8 +79,12 @@
79;; excellent reference card made by Philip Rooke. This card can be found 79;; excellent reference card made by Philip Rooke. This card can be found
80;; in the etc/ directory of Emacs 22. 80;; in the etc/ directory of Emacs 22.
81;; 81;;
82;; Changes: 82;; Changes since version 4.00:
83;; ------- 83;; ---------------------------
84;; Version 4.02
85;; - Minor bug fixes and improvements around tag searches.
86;; - XEmacs compatibility fixes.
87;;
84;; Version 4.01 88;; Version 4.01
85;; - Tags can also be set remotely from agenda buffer. 89;; - Tags can also be set remotely from agenda buffer.
86;; - Boolean logic for tag searches. 90;; - Boolean logic for tag searches.
@@ -88,178 +92,6 @@
88;; `org-agenda-custom-commands'. 92;; `org-agenda-custom-commands'.
89;; - Minor bug fixes. 93;; - Minor bug fixes.
90;; 94;;
91;; Version 4.00
92;; - Headlines can contain TAGS, and Org-mode can produced a list
93;; of matching headlines based on a TAG search expression.
94;; - `org-agenda' has now become a dispatcher that will produce the agenda
95;; and other views on org-mode data with an additional keypress.
96;;
97;; Version 3.24
98;; - Switching and item to DONE records a time stamp when the variable
99;; `org-log-done' is turned on. Default is off.
100;;
101;; Version 3.23
102;; - M-RET makes new items as well as new headings.
103;; - Various small bug fixes
104;;
105;; Version 3.22
106;; - CamelCase words link to other locations in the same file.
107;; - File links accept search options, to link to specific locations.
108;; - Plain list items can be folded with `org-cycle'. See new option
109;; `org-cycle-include-plain-lists'.
110;; - Sparse trees for specific TODO keywords through numeric prefix
111;; argument to `C-c C-v'.
112;; - Global TODO list, also for specific keywords.
113;; - Matches in sparse trees are highlighted (highlights disappear with
114;; next buffer change due to editing).
115;;
116;; Version 3.21
117;; - Improved CSS support for the HTML export. Thanks to Christian Egli.
118;; - Editing support for hand-formatted lists
119;; - M-S-cursor keys handle plain list items
120;; - C-c C-c renumbers ordered plain lists
121;;
122;; Version 3.20
123;; - There is finally an option to make TAB jump over horizontal lines
124;; in tables instead of creating a new line before that line.
125;; The option is `org-table-tab-jumps-over-hlines', default nil.
126;; - New command for sorting tables, on `C-c ^'.
127;; - Changes to the HTML exporter
128;; - hand-formatted lists are exported correctly, similar to
129;; markdown lists. Nested lists are possible. See the docstring
130;; of the variable `org-export-plain-list-max-depth'.
131;; - cleaned up to produce valid HTML 4.0 (transitional).
132;; - support for cascading style sheets.
133;; - New command to cycle through all agenda files, on C-,
134;; - C-c [ can now also be used to change the sequence of agenda files.
135;;
136;; Version 3.19
137;; - Bug fixes
138;;
139;; Version 3.18
140;; - Export of calendar information in the standard iCalendar format.
141;; - Some bug fixes.
142;;
143;; Version 3.17
144;; - HTML export specifies character set depending on coding-system.
145;;
146;; Version 3.16
147;; - In tables, directly after the field motion commands like TAB and RET,
148;; typing a character will blank the field. Can be turned off with
149;; variable `org-table-auto-blank-field'.
150;; - Inactive timestamps with `C-c !'. These do not trigger the agenda
151;; and are not linked to the calendar.
152;; - Additional key bindings to allow Org-mode to function on a tty emacs.
153;; - `C-c C-h' prefix key replaced by `C-c C-x', and `C-c C-x C-h' replaced
154;; by `C-c C-x b' (b=Browser). This was necessary to recover the
155;; standard meaning of C-h after a prefix key (show prefix bindings).
156;;
157;; Version 3.15
158;; - QUOTE keyword at the beginning of an entry causes fixed-width export
159;; of unmodified entry text. `C-c :' toggles this keyword.
160;; - New face `org-special-keyword' which is used for COMMENT, QUOTE,
161;; DEADLINE and SCHEDULED, and priority cookies. Default is only a weak
162;; color, to reduce the amount of aggressive color in the buffer.
163;;
164;; Version 3.14
165;; - Formulas for individual fields in table.
166;; - Automatic recalculation in calculating tables.
167;; - Named fields and columns in tables.
168;; - Fixed bug with calling `org-archive' several times in a row.
169;;
170;; Version 3.13
171;; - Efficiency improvements: Fewer table re-alignments needed.
172;; - New special lines in tables, for defining names for individual cells.
173;;
174;; Version 3.12
175;; - Tables can store formulas (one per column) and compute fields.
176;; Not quite like a full spreadsheet, but very powerful.
177;; - table.el keybinding is now `C-c ~'.
178;; - Numeric argument to org-cycle does `show-subtree' above on level ARG.
179;; - Small changes to keys in agenda buffer. Affected keys:
180;; [w] weekly view; [d] daily view; [D] toggle diary inclusion.
181;; - Bug fixes.
182;;
183;; Version 3.11
184;; - Links inserted with C-c C-l are now by default enclosed in angle
185;; brackets. See the new variable `org-link-format'.
186;; - ">" terminates a link, this is a way to have several links in a line.
187;; Both "<" and ">" are no longer allowed as characters in a link.
188;; - Archiving of finished tasks.
189;; - C-<up>/<down> bindings removed, to allow access to paragraph commands.
190;; - Compatibility with CUA-mode (see variable `org-CUA-compatible').
191;; - Compatibility problems with viper-mode fixed.
192;; - Improved html export of tables.
193;; - Various clean-up changes.
194;;
195;; Version 3.10
196;; - Using `define-derived-mode' to derive `org-mode' from `outline-mode'.
197;;
198;; Version 3.09
199;; - Time-of-day specifications in agenda are extracted and placed
200;; into the prefix. Timed entries can be placed into a time grid for
201;; day.
202;;
203;; Version 3.08
204;; - "|" no longer allowed as part of a link, to allow links in tables.
205;; - The prefix of items in the agenda buffer can be configured.
206;; - Cleanup.
207;;
208;; Version 3.07
209;; - Some folding inconsistencies removed.
210;; - BBDB links to company-only entries.
211;; - Bug fixes and global cleanup.
212;;
213;; Version 3.06
214;; - M-S-RET inserts a new TODO heading.
215;; - New startup option `content'.
216;; - Better visual response when TODO items in agenda change status.
217;; - Window positioning after visibility state changes optimized and made
218;; configurable. See `org-cycle-hook' and `org-occur-hook'.
219;;
220;; Version 3.05
221;; - Agenda entries from the diary are linked to the diary file, so
222;; adding and editing diary entries can be done directly from the agenda.
223;; - Many calendar/diary commands available directly from agenda.
224;; - Field copying in tables with S-RET does increment.
225;; - C-c C-x C-v extracts the visible part of the buffer for printing.
226;; - Moving subtrees up and down preserves the whitespace at the tree end.
227;;
228;; Version 3.04
229;; - Table editor optimized to need fewer realignments, and to keep
230;; table shape when typing in fields.
231;; - A new minor mode, orgtbl-mode, introduces the Org-mode table editor
232;; into arbitrary major modes.
233;; - Fixed bug with realignment in XEmacs.
234;; - Startup options can be set with special #+STARTUP line.
235;; - Heading following a match in org-occur can be suppressed.
236;;
237;; Version 3.03
238;; - Copyright transfer to the FSF.
239;; - Effect of C-u and C-u C-u in org-timeline swapped.
240;; - Timeline now always contains today, and `.' jumps to it.
241;; - Table editor:
242;; - cut and paste of rectangular regions in tables
243;; - command to convert org-mode table to table.el table and back
244;; - command to treat several cells like a paragraph and fill it
245;; - command to convert a buffer region to a table
246;; - import/export tables as tab-separated files (exchange with Excel)
247;; - Agenda:
248;; - Sorting mechanism for agenda items rewritten from scratch.
249;; - Sorting fully configurable.
250;; - Entries specifying a time are sorted together.
251;; - Completion also covers option keywords after `#-'.
252;; - Bug fixes.
253;;
254;; Version 3.01
255;; - New reference card, thanks to Philip Rooke for creating it.
256;; - Single file agenda renamed to "Timeline". It no longer shows
257;; warnings about upcoming deadlines/overdue scheduled items.
258;; That functionality is now limited to the (multifile) agenda.
259;; - When reading a date, the calendar can be manipulated with keys.
260;; - Link support for RMAIL and Wanderlust (from planner.el, untested).
261;; - Minor bug fixes and documentation improvements.
262
263;;; Code: 95;;; Code:
264 96
265(eval-when-compile (require 'cl) (require 'calendar)) 97(eval-when-compile (require 'cl) (require 'calendar))
@@ -601,21 +433,31 @@ Entries are added to this list with \\[org-agenda-file-to-front] and removed wit
601 :group 'org-agenda 433 :group 'org-agenda
602 :type '(repeat file)) 434 :type '(repeat file))
603 435
604(defcustom org-agenda-custom-commands 436(defcustom org-agenda-custom-commands '(("w" todo "WAITING"))
605 '(("w" todo "WAITING")
606 ("u" tags "+WORK+URGENT-BOSS"))
607 "Custom commands for the agenda. 437 "Custom commands for the agenda.
608These commands will be offered on the splash screen displayed by the 438These commands will be offered on the splash screen displayed by the
609agenda dispatcher \\[org-agenda]. Each entry is a list of 3 items: 439agenda dispatcher \\[org-agenda]. Each entry is a list of 3 items:
610 440
611key The key (as a string) to be associated with the command. 441key The key (a single char as a string) to be associated with the command.
612type The command type, either `todo' for a todo list with a specific 442type The command type, any of the following symbols:
613 todo keyword, or `tags' for a tags search. 443 todo Entries with a specific TODO keyword, in all agenda files.
614match What to search for. Either a TODO keyword, or a tags match query." 444 tags Tags match in all agenda files.
445 todo-tree Sparse tree of specific TODO keyword in *current* file.
446 tags-tree Sparse tree with all tags matches in *current* file.
447 occur-tree Occur sparse tree for current file.
448match What to search for:
449 - a single keyword for TODO keyword searches
450 - a tags match expression for tags searches
451 - a regular expression for occur searches"
615 :group 'org-agenda 452 :group 'org-agenda
616 :type '(repeat 453 :type '(repeat
617 (list (string :tag "Key") 454 (list (string :tag "Key")
618 (choice :tag "Type" (const tags) (const todo)) 455 (choice :tag "Type"
456 (const :tag "Tags search in all agenda files" tags)
457 (const :tag "TODO keyword search in all agenda files" todo)
458 (const :tag "Tags sparse tree in current buffer" tags-tree)
459 (const :tag "TODO keyword tree in current buffer" todo-tree)
460 (const :tag "Occur tree in current buffer" occur-tree))
619 (string :tag "Match")))) 461 (string :tag "Match"))))
620 462
621(defcustom org-select-timeline-window t 463(defcustom org-select-timeline-window t
@@ -1036,7 +878,11 @@ the sublevels of a headline matching a tag search often also match
1036the same search. Listing all of them can create very long lists. 878the same search. Listing all of them can create very long lists.
1037Setting this variable to nil causes subtrees to be skipped. 879Setting this variable to nil causes subtrees to be skipped.
1038This option is off by default, because inheritance in on. If you turn 880This option is off by default, because inheritance in on. If you turn
1039inheritance off, you very likely want to turn this option on." 881inheritance off, you very likely want to turn this option on.
882
883As a special case, if the tag search is restricted to TODO items, the
884value of this variable is ignored and sublevels are always checked, to
885make sure all corresponding TODO items find their way into the list."
1040 :group 'org-tags 886 :group 'org-tags
1041 :type 'boolean) 887 :type 'boolean)
1042 888
@@ -2137,6 +1983,12 @@ The following commands are available:
2137 (make-local-hook 'before-change-functions) ;; needed for XEmacs 1983 (make-local-hook 'before-change-functions) ;; needed for XEmacs
2138 (add-hook 'before-change-functions 'org-before-change-function nil 1984 (add-hook 'before-change-functions 'org-before-change-function nil
2139 'local) 1985 'local)
1986 ;; FIXME: The following does not work because isearch-mode-end-hook
1987 ;; is called *before* the visibility overlays as removed.
1988 ;; There should be another hook then for me to be used.
1989;; (make-local-hook 'isearch-mode-end-hook) ;; needed for XEmacs
1990;; (add-hook 'isearch-mode-end-hook 'org-show-hierarchy-above nil
1991;; 'local)
2140 ;; Paragraphs and auto-filling 1992 ;; Paragraphs and auto-filling
2141 (org-set-autofill-regexps) 1993 (org-set-autofill-regexps)
2142 ;; Settings for Calc embedded mode 1994 ;; Settings for Calc embedded mode
@@ -2173,6 +2025,13 @@ The following commands are available:
2173(defsubst org-current-line (&optional pos) 2025(defsubst org-current-line (&optional pos)
2174 (+ (if (bolp) 1 0) (count-lines (point-min) (or pos (point))))) 2026 (+ (if (bolp) 1 0) (count-lines (point-min) (or pos (point)))))
2175 2027
2028
2029;; FIXME: Do we need to copy?
2030(defun org-string-props (string &rest properties)
2031 "Add PROPERTIES to string."
2032 (add-text-properties 0 (length string) properties string)
2033 string)
2034
2176;;; Font-Lock stuff 2035;;; Font-Lock stuff
2177 2036
2178(defvar org-mouse-map (make-sparse-keymap)) 2037(defvar org-mouse-map (make-sparse-keymap))
@@ -2452,7 +2311,7 @@ The following commands are available:
2452 (get-char-property (1- (point)) 'invisible)) 2311 (get-char-property (1- (point)) 'invisible))
2453 (beginning-of-line 2)) (setq eol (point))) 2312 (beginning-of-line 2)) (setq eol (point)))
2454 (outline-end-of-heading) (setq eoh (point)) 2313 (outline-end-of-heading) (setq eoh (point))
2455 (outline-end-of-subtree) (setq eos (point)) 2314 (org-end-of-subtree t) (setq eos (point))
2456 (outline-next-heading)) 2315 (outline-next-heading))
2457 ;; Find out what to do next and set `this-command' 2316 ;; Find out what to do next and set `this-command'
2458 (cond 2317 (cond
@@ -2513,7 +2372,7 @@ This function is the default value of the hook `org-cycle-hook'."
2513(defun org-subtree-end-visible-p () 2372(defun org-subtree-end-visible-p ()
2514 "Is the end of the current subtree visible?" 2373 "Is the end of the current subtree visible?"
2515 (pos-visible-in-window-p 2374 (pos-visible-in-window-p
2516 (save-excursion (outline-end-of-subtree) (point)))) 2375 (save-excursion (org-end-of-subtree t) (point))))
2517 2376
2518(defun org-first-headline-recenter (&optional N) 2377(defun org-first-headline-recenter (&optional N)
2519 "Move cursor to the first headline and recenter the headline. 2378 "Move cursor to the first headline and recenter the headline.
@@ -3626,25 +3485,43 @@ that the match should indeed be shown."
3626 3485
3627(defun org-show-hierarchy-above () 3486(defun org-show-hierarchy-above ()
3628 "Make sure point and the headings hierarchy above is visible." 3487 "Make sure point and the headings hierarchy above is visible."
3629 (if (org-on-heading-p t) 3488 (catch 'exit
3630 (org-flag-heading nil) ; only show the heading 3489 (if (org-on-heading-p t)
3631 (and (org-invisible-p) (org-show-hidden-entry))) ; show entire entry 3490 (org-flag-heading nil) ; only show the heading
3632 (save-excursion 3491 (and (org-invisible-p) (org-show-hidden-entry))) ; show entire entry
3633 (and org-show-following-heading 3492 (save-excursion
3634 (outline-next-heading) 3493 (and org-show-following-heading
3635 (org-flag-heading nil))) ; show the next heading 3494 (outline-next-heading)
3636 (when org-show-hierarchy-above 3495 (org-flag-heading nil))) ; show the next heading
3637 (save-excursion ; show all higher headings 3496 (when org-show-hierarchy-above
3638 (while (condition-case nil 3497 (save-excursion ; show all higher headings
3639 (progn (org-up-heading-all 1) t) 3498 (while (and (condition-case nil
3640 (error nil)) 3499 (progn (org-up-heading-all 1) t)
3641 (org-flag-heading nil))))) 3500 (error nil))
3501 (not (bobp)))
3502 (org-flag-heading nil))))))
3503
3504;; Overlay compatibility functions
3505(defun org-make-overlay (beg end &optional buffer)
3506 (if org-xemacs-p (make-extent beg end buffer) (make-overlay beg end buffer)))
3507(defun org-delete-overlay (ovl)
3508 (if org-xemacs-p (delete-extent ovl) (delete-overlay ovl)))
3509(defun org-detatch-overlay (ovl)
3510 (if org-xemacs-p (detach-extent ovl) (delete-overlay ovl)))
3511(defun org-move-overlay (ovl beg end &optional buffer)
3512 (if org-xemacs-p
3513 (set-extent-endpoints ovl beg end buffer)
3514 (move-overlay ovl beg end buffer)))
3515(defun org-overlay-put (ovl prop value)
3516 (if org-xemacs-p
3517 (set-extent-property ovl prop value)
3518 (overlay-put ovl prop value)))
3642 3519
3643(defvar org-occur-highlights nil) 3520(defvar org-occur-highlights nil)
3644(defun org-highlight-new-match (beg end) 3521(defun org-highlight-new-match (beg end)
3645 "Highlight from BEG to END and mark the highlight is an occur headline." 3522 "Highlight from BEG to END and mark the highlight is an occur headline."
3646 (let ((ov (make-overlay beg end))) 3523 (let ((ov (org-make-overlay beg end)))
3647 (overlay-put ov 'face 'secondary-selection) 3524 (org-overlay-put ov 'face 'secondary-selection)
3648 (push ov org-occur-highlights))) 3525 (push ov org-occur-highlights)))
3649 3526
3650(defun org-remove-occur-highlights (&optional beg end noremove) 3527(defun org-remove-occur-highlights (&optional beg end noremove)
@@ -3652,7 +3529,7 @@ that the match should indeed be shown."
3652BEG and END are ignored. If NOREMOVE is nil, remove this function 3529BEG and END are ignored. If NOREMOVE is nil, remove this function
3653from the before-change-functions in the current buffer." 3530from the before-change-functions in the current buffer."
3654 (interactive) 3531 (interactive)
3655 (mapc 'delete-overlay org-occur-highlights) 3532 (mapc 'org-delete-overlay org-occur-highlights)
3656 (setq org-occur-highlights nil) 3533 (setq org-occur-highlights nil)
3657 (unless noremove 3534 (unless noremove
3658 (remove-hook 'before-change-functions 3535 (remove-hook 'before-change-functions
@@ -3786,6 +3663,10 @@ So these are more for recording a certain time/date."
3786 (setq fmt (concat "[" (substring fmt 1 -1) "]")) 3663 (setq fmt (concat "[" (substring fmt 1 -1) "]"))
3787 (insert (format-time-string fmt time)))) 3664 (insert (format-time-string fmt time))))
3788 3665
3666(defvar org-date-ovl (org-make-overlay 1 1))
3667(org-overlay-put org-date-ovl 'face 'org-warning)
3668(org-detatch-overlay org-date-ovl)
3669
3789;;; FIXME: Make the function take "Fri" as "next friday" 3670;;; FIXME: Make the function take "Fri" as "next friday"
3790;;; because these are mostly being used to record the current time. 3671;;; because these are mostly being used to record the current time.
3791(defun org-read-date (&optional with-time to-time) 3672(defun org-read-date (&optional with-time to-time)
@@ -3847,12 +3728,15 @@ used to insert the time stamp into the buffer to include the time."
3847 (calendar-forward-day (- (time-to-days default-time) 3728 (calendar-forward-day (- (time-to-days default-time)
3848 (calendar-absolute-from-gregorian 3729 (calendar-absolute-from-gregorian
3849 (calendar-current-date)))) 3730 (calendar-current-date))))
3731 (org-eval-in-calendar nil)
3850 (let* ((old-map (current-local-map)) 3732 (let* ((old-map (current-local-map))
3851 (map (copy-keymap calendar-mode-map)) 3733 (map (copy-keymap calendar-mode-map))
3852 (minibuffer-local-map (copy-keymap minibuffer-local-map))) 3734 (minibuffer-local-map (copy-keymap minibuffer-local-map)))
3853 (define-key map (kbd "RET") 'org-calendar-select) 3735 (define-key map (kbd "RET") 'org-calendar-select)
3854 (define-key map (if org-xemacs-p [button1] [mouse-1]) 3736 (define-key map (if org-xemacs-p [button1] [mouse-1])
3855 'org-calendar-select) 3737 'org-calendar-select-mouse)
3738 (define-key map (if org-xemacs-p [button2] [mouse-2])
3739 'org-calendar-select-mouse)
3856 (define-key minibuffer-local-map [(meta shift left)] 3740 (define-key minibuffer-local-map [(meta shift left)]
3857 (lambda () (interactive) 3741 (lambda () (interactive)
3858 (org-eval-in-calendar '(calendar-backward-month 1)))) 3742 (org-eval-in-calendar '(calendar-backward-month 1))))
@@ -3885,6 +3769,7 @@ used to insert the time stamp into the buffer to include the time."
3885 (use-local-map old-map))))) 3769 (use-local-map old-map)))))
3886 ;; Naked prompt only 3770 ;; Naked prompt only
3887 (setq ans (read-string prompt "" nil timestr))) 3771 (setq ans (read-string prompt "" nil timestr)))
3772 (org-detatch-overlay org-date-ovl)
3888 3773
3889 (if (string-match 3774 (if (string-match
3890 "^ *\\(\\([0-9]+\\)-\\)?\\([0-1]?[0-9]\\)-\\([0-3]?[0-9]\\)\\([^-0-9]\\|$\\)" ans) 3775 "^ *\\(\\([0-9]+\\)-\\)?\\([0-1]?[0-9]\\)-\\([0-3]?[0-9]\\)\\([^-0-9]\\|$\\)" ans)
@@ -3924,7 +3809,7 @@ Also, store the cursor date in variable ans2."
3924 (let* ((date (calendar-cursor-to-date)) 3809 (let* ((date (calendar-cursor-to-date))
3925 (time (encode-time 0 0 0 (nth 1 date) (nth 0 date) (nth 2 date)))) 3810 (time (encode-time 0 0 0 (nth 1 date) (nth 0 date) (nth 2 date))))
3926 (setq ans2 (format-time-string "%Y-%m-%d" time)))) 3811 (setq ans2 (format-time-string "%Y-%m-%d" time))))
3927 (and org-xemacs-p (sit-for .2)) 3812 (org-move-overlay org-date-ovl (1- (point)) (1+ (point)) (current-buffer))
3928 (select-window sw))) 3813 (select-window sw)))
3929 3814
3930(defun org-calendar-select () 3815(defun org-calendar-select ()
@@ -3937,6 +3822,17 @@ This is used by `org-read-date' in a temporary keymap for the calendar buffer."
3937 (setq ans1 (format-time-string "%Y-%m-%d" time))) 3822 (setq ans1 (format-time-string "%Y-%m-%d" time)))
3938 (if (active-minibuffer-window) (exit-minibuffer)))) 3823 (if (active-minibuffer-window) (exit-minibuffer))))
3939 3824
3825(defun org-calendar-select-mouse (ev)
3826 "Return to `org-read-date' with the date currently selected.
3827This is used by `org-read-date' in a temporary keymap for the calendar buffer."
3828 (interactive "e")
3829 (mouse-set-point ev)
3830 (when (calendar-cursor-to-date)
3831 (let* ((date (calendar-cursor-to-date))
3832 (time (encode-time 0 0 0 (nth 1 date) (nth 0 date) (nth 2 date))))
3833 (setq ans1 (format-time-string "%Y-%m-%d" time)))
3834 (if (active-minibuffer-window) (exit-minibuffer))))
3835
3940(defun org-check-deadlines (ndays) 3836(defun org-check-deadlines (ndays)
3941 "Check if there are any deadlines due or past due. 3837 "Check if there are any deadlines due or past due.
3942A deadline is considered due if it happens within `org-deadline-warning-days' 3838A deadline is considered due if it happens within `org-deadline-warning-days'
@@ -4220,7 +4116,7 @@ If there is already a time stamp at the cursor position, update it."
4220(defvar org-agenda-buffer-name "*Org Agenda*") 4116(defvar org-agenda-buffer-name "*Org Agenda*")
4221(defvar org-agenda-redo-command nil) 4117(defvar org-agenda-redo-command nil)
4222(defvar org-agenda-mode-hook nil) 4118(defvar org-agenda-mode-hook nil)
4223 4119(defvar org-agenda-type nil)
4224(defvar org-agenda-force-single-file nil) 4120(defvar org-agenda-force-single-file nil)
4225 4121
4226;;;###autoload 4122;;;###autoload
@@ -4338,40 +4234,42 @@ The following commands are available:
4338 ["Cycle TODO" org-agenda-todo t] 4234 ["Cycle TODO" org-agenda-todo t]
4339 ["Set Tags" org-agenda-set-tags t] 4235 ["Set Tags" org-agenda-set-tags t]
4340 ("Reschedule" 4236 ("Reschedule"
4341 ["Reschedule +1 day" org-agenda-date-later t] 4237 ["Reschedule +1 day" org-agenda-date-later (org-agenda-check-type nil 'agenda 'timeline)]
4342 ["Reschedule -1 day" org-agenda-date-earlier t] 4238 ["Reschedule -1 day" org-agenda-date-earlier (org-agenda-check-type nil 'agenda 'timeline)]
4343 "--" 4239 "--"
4344 ["Reschedule to ..." org-agenda-date-prompt t]) 4240 ["Reschedule to ..." org-agenda-date-prompt (org-agenda-check-type nil 'agenda 'timeline)])
4345 ("Priority" 4241 ("Priority"
4346 ["Set Priority" org-agenda-priority t] 4242 ["Set Priority" org-agenda-priority t]
4347 ["Increase Priority" org-agenda-priority-up t] 4243 ["Increase Priority" org-agenda-priority-up t]
4348 ["Decrease Priority" org-agenda-priority-down t] 4244 ["Decrease Priority" org-agenda-priority-down t]
4349 ["Show Priority" org-agenda-show-priority t]) 4245 ["Show Priority" org-agenda-show-priority t])
4350 "--" 4246 "--"
4247 ;; ["New agenda command" org-agenda t]
4351 ["Rebuild buffer" org-agenda-redo t] 4248 ["Rebuild buffer" org-agenda-redo t]
4352 ["Goto Today" org-agenda-goto-today t]
4353 ["Next Dates" org-agenda-later (local-variable-p 'starting-day (current-buffer))]
4354 ["Previous Dates" org-agenda-earlier (local-variable-p 'starting-day (current-buffer))]
4355 "--" 4249 "--"
4356 ["Day View" org-agenda-day-view :active (local-variable-p 'starting-day (current-buffer)) 4250 ["Goto Today" org-agenda-goto-today (org-agenda-check-type nil 'agenda 'timeline)]
4251 ["Next Dates" org-agenda-later (org-agenda-check-type nil 'agenda)]
4252 ["Previous Dates" org-agenda-earlier (org-agenda-check-type nil 'agenda)]
4253 "--"
4254 ["Day View" org-agenda-day-view :active (org-agenda-check-type nil 'agenda)
4357 :style radio :selected (equal org-agenda-ndays 1)] 4255 :style radio :selected (equal org-agenda-ndays 1)]
4358 ["Week View" org-agenda-week-view :active (local-variable-p 'starting-day (current-buffer)) 4256 ["Week View" org-agenda-week-view :active (org-agenda-check-type nil 'agenda)
4359 :style radio :selected (equal org-agenda-ndays 7)] 4257 :style radio :selected (equal org-agenda-ndays 7)]
4360 "--" 4258 "--"
4361 ["Show Logbook entries" org-agenda-log-mode 4259 ["Show Logbook entries" org-agenda-log-mode
4362 :style toggle :selected org-agenda-show-log :active t] 4260 :style toggle :selected org-agenda-show-log :active (org-agenda-check-type nil 'agenda 'timeline)]
4363 ["Include Diary" org-agenda-toggle-diary 4261 ["Include Diary" org-agenda-toggle-diary
4364 :style toggle :selected org-agenda-include-diary :active t] 4262 :style toggle :selected org-agenda-include-diary :active (org-agenda-check-type nil 'agenda)]
4365 ["Use Time Grid" org-agenda-toggle-time-grid 4263 ["Use Time Grid" org-agenda-toggle-time-grid
4366 :style toggle :selected org-agenda-use-time-grid :active t] 4264 :style toggle :selected org-agenda-use-time-grid :active (org-agenda-check-type nil 'agenda)]
4367 "--" 4265 "--"
4368 ["New Diary Entry" org-agenda-diary-entry t] 4266 ["New Diary Entry" org-agenda-diary-entry (org-agenda-check-type nil 'agenda 'timeline)]
4369 ("Calendar Commands" 4267 ("Calendar Commands"
4370 ["Goto Calendar" org-agenda-goto-calendar t] 4268 ["Goto Calendar" org-agenda-goto-calendar (org-agenda-check-type nil 'agenda 'timeline)]
4371 ["Phases of the Moon" org-agenda-phases-of-moon t] 4269 ["Phases of the Moon" org-agenda-phases-of-moon (org-agenda-check-type nil 'agenda 'timeline)]
4372 ["Sunrise/Sunset" org-agenda-sunrise-sunset t] 4270 ["Sunrise/Sunset" org-agenda-sunrise-sunset (org-agenda-check-type nil 'agenda 'timeline)]
4373 ["Holidays" org-agenda-holidays t] 4271 ["Holidays" org-agenda-holidays (org-agenda-check-type nil 'agenda 'timeline)]
4374 ["Convert" org-agenda-convert-date t]) 4272 ["Convert" org-agenda-convert-date (org-agenda-check-type nil 'agenda 'timeline)])
4375 ["Create iCalendar file" org-export-icalendar-combine-agenda-files t] 4273 ["Create iCalendar file" org-export-icalendar-combine-agenda-files t]
4376 "--" 4274 "--"
4377 ["Quit" org-agenda-quit t] 4275 ["Quit" org-agenda-quit t]
@@ -4386,19 +4284,19 @@ on to the selected command. The default selections are:
4386 4284
4387a Call `org-agenda' to display the agenda for the current day or week. 4285a Call `org-agenda' to display the agenda for the current day or week.
4388t Call `org-todo-list' to display the global todo list. 4286t Call `org-todo-list' to display the global todo list.
4389T Call `org-todo-list' to display the global todo list, put 4287T Call `org-todo-list' to display the global todo list, select only
4390 select only entries with a specific TODO keyword. 4288 entries with a specific TODO keyword (the user get a prompt).
4391m Call `org-tags-view' to display headlines with tags matching 4289m Call `org-tags-view' to display headlines with tags matching
4392 a condition. The tags condition is a list of positive and negative 4290 a condition (the user is prompted for the condition).
4393 selections, like `+WORK+URGENT-WITHBOSS'.
4394M like `m', but select only TODO entries, no ordinary headlines. 4291M like `m', but select only TODO entries, no ordinary headlines.
4395 4292
4396More commands can be added by configuring the variable 4293More commands can be added by configuring the variable
4397`org-agenda-custom-commands'. 4294`org-agenda-custom-commands'. In particular, specific tags and TODO keyword
4295searches can be pre-defined in this way.
4398 4296
4399If the current buffer is in Org-mode and visiting a file, you can also 4297If the current buffer is in Org-mode and visiting a file, you can also
4400first press `1' to indicate that the agenda should be temporarily 4298first press `1' to indicate that the agenda should be temporarily (until the
4401restricted to the current file." 4299next use of \\[org-agenda]) restricted to the current file."
4402 (interactive "P") 4300 (interactive "P")
4403 (catch 'exit 4301 (catch 'exit
4404 (let ((restrict-ok (and (buffer-file-name) (eq major-mode 'org-mode))) 4302 (let ((restrict-ok (and (buffer-file-name) (eq major-mode 'org-mode)))
@@ -4418,14 +4316,20 @@ m Match a TAGS query M Like m, but only TODO entries.
4418C Configure your own agenda commands") 4316C Configure your own agenda commands")
4419 (while (setq entry (pop custom)) 4317 (while (setq entry (pop custom))
4420 (setq key (car entry) type (nth 1 entry) string (nth 2 entry)) 4318 (setq key (car entry) type (nth 1 entry) string (nth 2 entry))
4421 (insert (format "\n%-4s%-12s: %s" 4319 (insert (format "\n%-4s%-14s: %s"
4422 key 4320 key
4423 (if (eq type 'tags) "Tags query" "TODO keyword") 4321 (cond
4424 string))) 4322 ((eq type 'tags) "Tags query")
4323 ((eq type 'todo) "TODO keyword")
4324 ((eq type 'tags-tree) "Tags tree")
4325 ((eq type 'todo-tree) "TODO kwd tree")
4326 ((eq type 'occur-tree) "Occur tree")
4327 (t "???"))
4328 (org-string-props string 'face 'org-link))))
4425 (goto-char (point-min)) 4329 (goto-char (point-min))
4426 (fit-window-to-buffer) 4330 (if (fboundp 'fit-window-to-buffer) (fit-window-to-buffer))
4427 (message "Press key for agenda command%s" 4331 (message "Press key for agenda command%s"
4428 (if restrict-ok ", or [1] to restrict to current file" "")) 4332 (if restrict-ok ", or [1] to restrict to current file" ""))
4429 (setq c (read-char-exclusive)) 4333 (setq c (read-char-exclusive))
4430 (message "") 4334 (message "")
4431 (when (equal c ?1) 4335 (when (equal c ?1)
@@ -4437,6 +4341,7 @@ C Configure your own agenda commands")
4437 (setq c (read-char-exclusive)) 4341 (setq c (read-char-exclusive))
4438 (message ""))) 4342 (message "")))
4439 (require 'calendar) ; FIXME: can we avoid this for some commands? 4343 (require 'calendar) ; FIXME: can we avoid this for some commands?
4344 ;; For example the todo list should not need it (but does...)
4440 (cond 4345 (cond
4441 ((equal c ?C) (customize-variable 'org-agenda-custom-commands)) 4346 ((equal c ?C) (customize-variable 'org-agenda-custom-commands))
4442 ((equal c ?a) (call-interactively 'org-agenda-list)) 4347 ((equal c ?a) (call-interactively 'org-agenda-list))
@@ -4455,9 +4360,25 @@ C Configure your own agenda commands")
4455 (org-tags-view current-prefix-arg string)) 4360 (org-tags-view current-prefix-arg string))
4456 ((eq type 'todo) 4361 ((eq type 'todo)
4457 (org-todo-list string)) 4362 (org-todo-list string))
4363 ((eq type 'tags-tree)
4364 (org-check-for-org-mode)
4365 (org-tags-sparse-tree current-prefix-arg string))
4366 ((eq type 'todo-tree)
4367 (org-check-for-org-mode)
4368 (org-occur (concat "^" outline-regexp "[ \t]*"
4369 (regexp-quote string) "\\>")))
4370 ((eq type 'occur-tree)
4371 (org-check-for-org-mode)
4372 (org-occur string))
4458 (t (error "Invalid custom agenda command type %s" type)))) 4373 (t (error "Invalid custom agenda command type %s" type))))
4459 (t (error "Invalid key")))))) 4374 (t (error "Invalid key"))))))
4460 4375
4376(defun org-check-for-org-mode ()
4377 "Make sure current buffer is in org-mode. Error if not."
4378 (or (eq major-mode 'org-mode)
4379 (error "Cannot execute org-mode agenda command on buffer in %s."
4380 major-mode)))
4381
4461(defun org-fit-agenda-window () 4382(defun org-fit-agenda-window ()
4462 "Fit the window to the buffer size." 4383 "Fit the window to the buffer size."
4463 (and org-fit-agenda-window 4384 (and org-fit-agenda-window
@@ -4565,6 +4486,7 @@ dates."
4565 (setq buffer-read-only nil) 4486 (setq buffer-read-only nil)
4566 (erase-buffer) 4487 (erase-buffer)
4567 (org-agenda-mode) (setq buffer-read-only nil) 4488 (org-agenda-mode) (setq buffer-read-only nil)
4489 (set (make-local-variable 'org-agenda-type) 'timeline)
4568 (if doclosed (push :closed args)) 4490 (if doclosed (push :closed args))
4569 (push :timestamp args) 4491 (push :timestamp args)
4570 (if dotodo (push :todo args)) 4492 (if dotodo (push :todo args))
@@ -4653,6 +4575,7 @@ NDAYS defaults to `org-agenda-ndays'."
4653 (setq buffer-read-only nil) 4575 (setq buffer-read-only nil)
4654 (erase-buffer) 4576 (erase-buffer)
4655 (org-agenda-mode) (setq buffer-read-only nil) 4577 (org-agenda-mode) (setq buffer-read-only nil)
4578 (set (make-local-variable 'org-agenda-type) 'agenda)
4656 (set (make-local-variable 'starting-day) (car day-numbers)) 4579 (set (make-local-variable 'starting-day) (car day-numbers))
4657 (set (make-local-variable 'include-all-loc) include-all) 4580 (set (make-local-variable 'include-all-loc) include-all)
4658 (when (and (or include-all org-agenda-include-all-todo) 4581 (when (and (or include-all org-agenda-include-all-todo)
@@ -4762,6 +4685,7 @@ for a keyword. A numeric prefix directly selects the Nth keyword in
4762 (setq buffer-read-only nil) 4685 (setq buffer-read-only nil)
4763 (erase-buffer) 4686 (erase-buffer)
4764 (org-agenda-mode) (setq buffer-read-only nil) 4687 (org-agenda-mode) (setq buffer-read-only nil)
4688 (set (make-local-variable 'org-agenda-type) 'todo)
4765 (set (make-local-variable 'last-arg) arg) 4689 (set (make-local-variable 'last-arg) arg)
4766 (set (make-local-variable 'org-todo-keywords) kwds) 4690 (set (make-local-variable 'org-todo-keywords) kwds)
4767 (set (make-local-variable 'org-agenda-redo-command) 4691 (set (make-local-variable 'org-agenda-redo-command)
@@ -4798,7 +4722,8 @@ for a keyword. A numeric prefix directly selects the Nth keyword in
4798(defun org-check-agenda-file (file) 4722(defun org-check-agenda-file (file)
4799 "Make sure FILE exists. If not, ask user what to do." 4723 "Make sure FILE exists. If not, ask user what to do."
4800 ;; FIXME: this does not correctly change the menus 4724 ;; FIXME: this does not correctly change the menus
4801 ;; Could probably be fixed by explicitly going to the buffer. 4725 ;; Could probably be fixed by explicitly going to the buffer where
4726 ;; the call originated.
4802 (when (not (file-exists-p file)) 4727 (when (not (file-exists-p file))
4803 (message "non-existent file %s. [R]emove from agenda-files or [A]bort?" 4728 (message "non-existent file %s. [R]emove from agenda-files or [A]bort?"
4804 file) 4729 file)
@@ -4809,6 +4734,15 @@ for a keyword. A numeric prefix directly selects the Nth keyword in
4809 (throw 'nextfile t)) 4734 (throw 'nextfile t))
4810 (t (error "Abort")))))) 4735 (t (error "Abort"))))))
4811 4736
4737(defun org-agenda-check-type (error &rest types)
4738 "Check if agenda buffer is of allowed type.
4739If ERROR is non-nil, throw an error, otherwise just return nil."
4740 (if (memq org-agenda-type types)
4741 t
4742 (if error
4743 (error "Now allowed in %s-type agenda buffers" org-agenda-type)
4744 nil)))
4745
4812(defun org-agenda-quit () 4746(defun org-agenda-quit ()
4813 "Exit agenda by removing the window or the buffer." 4747 "Exit agenda by removing the window or the buffer."
4814 (interactive) 4748 (interactive)
@@ -4830,11 +4764,14 @@ Org-mode buffers visited directly by the user will not be touched."
4830 "Rebuild Agenda. 4764 "Rebuild Agenda.
4831When this is the global TODO list, a prefix argument will be interpreted." 4765When this is the global TODO list, a prefix argument will be interpreted."
4832 (interactive) 4766 (interactive)
4833 (eval org-agenda-redo-command)) 4767 (message "Rebuilding agenda buffer...")
4768 (eval org-agenda-redo-command)
4769 (message "Rebuilding agenda buffer...done"))
4834 4770
4835(defun org-agenda-goto-today () 4771(defun org-agenda-goto-today ()
4836 "Go to today." 4772 "Go to today."
4837 (interactive) 4773 (interactive)
4774 (org-agenda-check-type t 'timeline 'agenda)
4838 (if (boundp 'starting-day) 4775 (if (boundp 'starting-day)
4839 (let ((cmd (car org-agenda-redo-command)) 4776 (let ((cmd (car org-agenda-redo-command))
4840 (iall (nth 1 org-agenda-redo-command)) 4777 (iall (nth 1 org-agenda-redo-command))
@@ -4848,8 +4785,7 @@ When this is the global TODO list, a prefix argument will be interpreted."
4848 "Go forward in time by `org-agenda-ndays' days. 4785 "Go forward in time by `org-agenda-ndays' days.
4849With prefix ARG, go forward that many times `org-agenda-ndays'." 4786With prefix ARG, go forward that many times `org-agenda-ndays'."
4850 (interactive "p") 4787 (interactive "p")
4851 (unless (boundp 'starting-day) 4788 (org-agenda-check-type t 'agenda)
4852 (error "Not allowed"))
4853 (org-agenda-list (if (boundp 'include-all-loc) include-all-loc nil) 4789 (org-agenda-list (if (boundp 'include-all-loc) include-all-loc nil)
4854 (+ starting-day (* arg org-agenda-ndays)) nil t)) 4790 (+ starting-day (* arg org-agenda-ndays)) nil t))
4855 4791
@@ -4857,16 +4793,14 @@ With prefix ARG, go forward that many times `org-agenda-ndays'."
4857 "Go back in time by `org-agenda-ndays' days. 4793 "Go back in time by `org-agenda-ndays' days.
4858With prefix ARG, go back that many times `org-agenda-ndays'." 4794With prefix ARG, go back that many times `org-agenda-ndays'."
4859 (interactive "p") 4795 (interactive "p")
4860 (unless (boundp 'starting-day) 4796 (org-agenda-check-type t 'agenda)
4861 (error "Not allowed"))
4862 (org-agenda-list (if (boundp 'include-all-loc) include-all-loc nil) 4797 (org-agenda-list (if (boundp 'include-all-loc) include-all-loc nil)
4863 (- starting-day (* arg org-agenda-ndays)) nil t)) 4798 (- starting-day (* arg org-agenda-ndays)) nil t))
4864 4799
4865(defun org-agenda-week-view () 4800(defun org-agenda-week-view ()
4866 "Switch to weekly view for agenda." 4801 "Switch to weekly view for agenda."
4867 (interactive) 4802 (interactive)
4868 (unless (boundp 'starting-day) 4803 (org-agenda-check-type t 'agenda)
4869 (error "Not allowed"))
4870 (setq org-agenda-ndays 7) 4804 (setq org-agenda-ndays 7)
4871 (org-agenda-list include-all-loc 4805 (org-agenda-list include-all-loc
4872 (or (get-text-property (point) 'day) 4806 (or (get-text-property (point) 'day)
@@ -4878,8 +4812,7 @@ With prefix ARG, go back that many times `org-agenda-ndays'."
4878(defun org-agenda-day-view () 4812(defun org-agenda-day-view ()
4879 "Switch to weekly view for agenda." 4813 "Switch to weekly view for agenda."
4880 (interactive) 4814 (interactive)
4881 (unless (boundp 'starting-day) 4815 (org-agenda-check-type t 'agenda)
4882 (error "Not allowed"))
4883 (setq org-agenda-ndays 1) 4816 (setq org-agenda-ndays 1)
4884 (org-agenda-list include-all-loc 4817 (org-agenda-list include-all-loc
4885 (or (get-text-property (point) 'day) 4818 (or (get-text-property (point) 'day)
@@ -4891,6 +4824,7 @@ With prefix ARG, go back that many times `org-agenda-ndays'."
4891(defun org-agenda-next-date-line (&optional arg) 4824(defun org-agenda-next-date-line (&optional arg)
4892 "Jump to the next line indicating a date in agenda buffer." 4825 "Jump to the next line indicating a date in agenda buffer."
4893 (interactive "p") 4826 (interactive "p")
4827 (org-agenda-check-type t 'agenda 'timeline)
4894 (beginning-of-line 1) 4828 (beginning-of-line 1)
4895 (if (looking-at "^\\S-") (forward-char 1)) 4829 (if (looking-at "^\\S-") (forward-char 1))
4896 (if (not (re-search-forward "^\\S-" nil t arg)) 4830 (if (not (re-search-forward "^\\S-" nil t arg))
@@ -4902,14 +4836,14 @@ With prefix ARG, go back that many times `org-agenda-ndays'."
4902(defun org-agenda-previous-date-line (&optional arg) 4836(defun org-agenda-previous-date-line (&optional arg)
4903 "Jump to the next line indicating a date in agenda buffer." 4837 "Jump to the next line indicating a date in agenda buffer."
4904 (interactive "p") 4838 (interactive "p")
4839 (org-agenda-check-type t 'agenda 'timeline)
4905 (beginning-of-line 1) 4840 (beginning-of-line 1)
4906 (if (not (re-search-backward "^\\S-" nil t arg)) 4841 (if (not (re-search-backward "^\\S-" nil t arg))
4907 (error "No previous date before this line in this buffer"))) 4842 (error "No previous date before this line in this buffer")))
4908 4843
4909;; Initialize the highlight 4844;; Initialize the highlight
4910(defvar org-hl (funcall (if org-xemacs-p 'make-extent 'make-overlay) 1 1)) 4845(defvar org-hl (org-make-overlay 1 1))
4911(funcall (if org-xemacs-p 'set-extent-property 'overlay-put) org-hl 4846(org-overlay-put org-hl 'face 'highlight)
4912 'face 'highlight)
4913 4847
4914(defun org-highlight (begin end &optional buffer) 4848(defun org-highlight (begin end &optional buffer)
4915 "Highlight a region with overlay." 4849 "Highlight a region with overlay."
@@ -4932,6 +4866,7 @@ With prefix ARG, go back that many times `org-agenda-ndays'."
4932(defun org-agenda-log-mode () 4866(defun org-agenda-log-mode ()
4933 "Toggle follow mode in an agenda buffer." 4867 "Toggle follow mode in an agenda buffer."
4934 (interactive) 4868 (interactive)
4869 (org-agenda-check-type t 'agenda 'timeline)
4935 (setq org-agenda-show-log (not org-agenda-show-log)) 4870 (setq org-agenda-show-log (not org-agenda-show-log))
4936 (org-agenda-set-mode-name) 4871 (org-agenda-set-mode-name)
4937 (org-agenda-redo) 4872 (org-agenda-redo)
@@ -4941,6 +4876,7 @@ With prefix ARG, go back that many times `org-agenda-ndays'."
4941(defun org-agenda-toggle-diary () 4876(defun org-agenda-toggle-diary ()
4942 "Toggle follow mode in an agenda buffer." 4877 "Toggle follow mode in an agenda buffer."
4943 (interactive) 4878 (interactive)
4879 (org-agenda-check-type t 'agenda)
4944 (setq org-agenda-include-diary (not org-agenda-include-diary)) 4880 (setq org-agenda-include-diary (not org-agenda-include-diary))
4945 (org-agenda-redo) 4881 (org-agenda-redo)
4946 (org-agenda-set-mode-name) 4882 (org-agenda-set-mode-name)
@@ -4950,6 +4886,7 @@ With prefix ARG, go back that many times `org-agenda-ndays'."
4950(defun org-agenda-toggle-time-grid () 4886(defun org-agenda-toggle-time-grid ()
4951 "Toggle follow mode in an agenda buffer." 4887 "Toggle follow mode in an agenda buffer."
4952 (interactive) 4888 (interactive)
4889 (org-agenda-check-type t 'agenda)
4953 (setq org-agenda-use-time-grid (not org-agenda-use-time-grid)) 4890 (setq org-agenda-use-time-grid (not org-agenda-use-time-grid))
4954 (org-agenda-redo) 4891 (org-agenda-redo)
4955 (org-agenda-set-mode-name) 4892 (org-agenda-set-mode-name)
@@ -5365,16 +5302,16 @@ the documentation of `org-diary'."
5365 (goto-char (point-min)) 5302 (goto-char (point-min))
5366 (while (re-search-forward regexp nil t) 5303 (while (re-search-forward regexp nil t)
5367 (goto-char (match-beginning 1)) 5304 (goto-char (match-beginning 1))
5368 (setq marker (org-agenda-new-marker (point-at-bol)) 5305 (setq marker (org-agenda-new-marker (1+ (match-beginning 0)))
5369 category (org-get-category) 5306 category (org-get-category)
5370 txt (org-format-agenda-item "" (match-string 1) category) 5307 txt (org-format-agenda-item "" (match-string 1) category)
5371 priority 5308 priority
5372 (+ (org-get-priority txt) 5309 (+ (org-get-priority txt)
5373 (if org-todo-kwd-priority-p 5310 (if org-todo-kwd-priority-p
5374 (- org-todo-kwd-max-priority -2 5311 (- org-todo-kwd-max-priority -2
5375 (length 5312 (length
5376 (member (match-string 2) org-todo-keywords))) 5313 (member (match-string 2) org-todo-keywords)))
5377 1))) 5314 1)))
5378 (add-text-properties 5315 (add-text-properties
5379 0 (length txt) (append (list 'org-marker marker 'org-hd-marker marker 5316 0 (length txt) (append (list 'org-marker marker 'org-hd-marker marker
5380 'priority priority 'category category) 5317 'priority priority 'category category)
@@ -6089,9 +6026,9 @@ the same tree node, and the headline of the tree node in the Org-mode file."
6089 "Set tags for the current headline." 6026 "Set tags for the current headline."
6090 (interactive) 6027 (interactive)
6091 (org-agenda-check-no-diary) 6028 (org-agenda-check-no-diary)
6092 (let* ((marker (or (get-text-property (point) 'org-marker) 6029 (org-agenda-show) ;;; FIXME This is a stupid hack and should not be needed
6093 (org-agenda-error))) 6030 (let* ((hdmarker (or (get-text-property (point) 'org-hd-marker)
6094 (hdmarker (get-text-property (point) 'org-hd-marker)) 6031 (org-agenda-error)))
6095 (buffer (marker-buffer hdmarker)) 6032 (buffer (marker-buffer hdmarker))
6096 (pos (marker-position hdmarker)) 6033 (pos (marker-position hdmarker))
6097 (buffer-read-only nil) 6034 (buffer-read-only nil)
@@ -6112,6 +6049,7 @@ the same tree node, and the headline of the tree node in the Org-mode file."
6112(defun org-agenda-date-later (arg &optional what) 6049(defun org-agenda-date-later (arg &optional what)
6113 "Change the date of this item to one day later." 6050 "Change the date of this item to one day later."
6114 (interactive "p") 6051 (interactive "p")
6052 (org-agenda-check-type t 'agenda 'timeline)
6115 (org-agenda-check-no-diary) 6053 (org-agenda-check-no-diary)
6116 (let* ((marker (or (get-text-property (point) 'org-marker) 6054 (let* ((marker (or (get-text-property (point) 'org-marker)
6117 (org-agenda-error))) 6055 (org-agenda-error)))
@@ -6135,6 +6073,7 @@ the same tree node, and the headline of the tree node in the Org-mode file."
6135The prefix ARG is passed to the `org-time-stamp' command and can therefore 6073The prefix ARG is passed to the `org-time-stamp' command and can therefore
6136be used to request time specification in the time stamp." 6074be used to request time specification in the time stamp."
6137 (interactive "P") 6075 (interactive "P")
6076 (org-agenda-check-type t 'agenda 'timeline)
6138 (org-agenda-check-no-diary) 6077 (org-agenda-check-no-diary)
6139 (let* ((marker (or (get-text-property (point) 'org-marker) 6078 (let* ((marker (or (get-text-property (point) 'org-marker)
6140 (org-agenda-error))) 6079 (org-agenda-error)))
@@ -6151,9 +6090,10 @@ be used to request time specification in the time stamp."
6151(defun org-get-heading () 6090(defun org-get-heading ()
6152 "Return the heading of the current entry, without the stars." 6091 "Return the heading of the current entry, without the stars."
6153 (save-excursion 6092 (save-excursion
6154 (and (bolp) (end-of-line 1)) 6093 (and (memq (char-before) '(?\n ?\r)) (skip-chars-forward "^\n\r"))
6094;;FIXME???????? (and (bolp) (end-of-line 1))
6155 (if (and (re-search-backward "[\r\n]\\*" nil t) 6095 (if (and (re-search-backward "[\r\n]\\*" nil t)
6156 (looking-at "[\r\n]\\*+[ \t]+\\(.*\\)")) 6096 (looking-at "[\r\n]\\*+[ \t]+\\([^\r\n]*\\)"))
6157 (match-string 1) 6097 (match-string 1)
6158 ""))) 6098 "")))
6159 6099
@@ -6161,6 +6101,7 @@ be used to request time specification in the time stamp."
6161 "Make a diary entry, like the `i' command from the calendar. 6101 "Make a diary entry, like the `i' command from the calendar.
6162All the standard commands work: block, weekly etc" 6102All the standard commands work: block, weekly etc"
6163 (interactive) 6103 (interactive)
6104 (org-agenda-check-type t 'agenda 'timeline)
6164 (require 'diary-lib) 6105 (require 'diary-lib)
6165 (let* ((char (progn 6106 (let* ((char (progn
6166 (message "Diary entry: [d]ay [w]eekly [m]onthly [y]early [a]nniversary [b]lock [c]yclic") 6107 (message "Diary entry: [d]ay [w]eekly [m]onthly [y]early [a]nniversary [b]lock [c]yclic")
@@ -6201,6 +6142,7 @@ All the standard commands work: block, weekly etc"
6201(defun org-agenda-execute-calendar-command (cmd) 6142(defun org-agenda-execute-calendar-command (cmd)
6202 "Execute a calendar command from the agenda, with the date associated to 6143 "Execute a calendar command from the agenda, with the date associated to
6203the cursor position." 6144the cursor position."
6145 (org-agenda-check-type t 'agenda 'timeline)
6204 (require 'diary-lib) 6146 (require 'diary-lib)
6205 (unless (get-text-property (point) 'day) 6147 (unless (get-text-property (point) 'day)
6206 (error "Don't know which date to use for calendar command")) 6148 (error "Don't know which date to use for calendar command"))
@@ -6245,6 +6187,7 @@ argument, latitude and longitude will be prompted for."
6245(defun org-agenda-goto-calendar () 6187(defun org-agenda-goto-calendar ()
6246 "Open the Emacs calendar with the date at the cursor." 6188 "Open the Emacs calendar with the date at the cursor."
6247 (interactive) 6189 (interactive)
6190 (org-agenda-check-type t 'agenda 'timeline)
6248 (let* ((day (or (get-text-property (point) 'day) 6191 (let* ((day (or (get-text-property (point) 'day)
6249 (error "Don't know which date to open in calendar"))) 6192 (error "Don't know which date to open in calendar")))
6250 (date (calendar-gregorian-from-absolute day)) 6193 (date (calendar-gregorian-from-absolute day))
@@ -6263,6 +6206,7 @@ This is a command that has to be installed in `calendar-mode-map'."
6263 6206
6264(defun org-agenda-convert-date () 6207(defun org-agenda-convert-date ()
6265 (interactive) 6208 (interactive)
6209 (org-agenda-check-type t 'agenda 'timeline)
6266 (let ((day (get-text-property (point) 'day)) 6210 (let ((day (get-text-property (point) 'day))
6267 date s) 6211 date s)
6268 (unless day 6212 (unless day
@@ -6285,7 +6229,8 @@ This is a command that has to be installed in `calendar-mode-map'."
6285 "Chinese: " (calendar-chinese-date-string date) "\n")) 6229 "Chinese: " (calendar-chinese-date-string date) "\n"))
6286 (with-output-to-temp-buffer "*Dates*" 6230 (with-output-to-temp-buffer "*Dates*"
6287 (princ s)) 6231 (princ s))
6288 (fit-window-to-buffer (get-buffer-window "*Dates*")))) 6232 (if (fboundp 'fit-window-to-buffer)
6233 (fit-window-to-buffer (get-buffer-window "*Dates*")))))
6289 6234
6290;;; Tags 6235;;; Tags
6291 6236
@@ -6308,6 +6253,7 @@ d are included in the output."
6308 'help-echo 6253 'help-echo
6309 (format "mouse-2 or RET jump to org file %s" 6254 (format "mouse-2 or RET jump to org file %s"
6310 (abbreviate-file-name (buffer-file-name))))) 6255 (abbreviate-file-name (buffer-file-name)))))
6256 lspos
6311 tags tags-list tags-alist (llast 0) rtn level category i txt 6257 tags tags-list tags-alist (llast 0) rtn level category i txt
6312 todo marker) 6258 todo marker)
6313 6259
@@ -6317,7 +6263,7 @@ d are included in the output."
6317 (while (re-search-forward re nil t) 6263 (while (re-search-forward re nil t)
6318 (setq todo (if (match-end 1) (match-string 2)) 6264 (setq todo (if (match-end 1) (match-string 2))
6319 tags (if (match-end 4) (match-string 4))) 6265 tags (if (match-end 4) (match-string 4)))
6320 (goto-char (1+ (match-beginning 0))) 6266 (goto-char (setq lspos (1+ (match-beginning 0))))
6321 (setq level (outline-level) 6267 (setq level (outline-level)
6322 category (org-get-category)) 6268 category (org-get-category))
6323 (setq i llast llast level) 6269 (setq i llast llast level)
@@ -6349,6 +6295,7 @@ d are included in the output."
6349 (make-string (1- level) ?.) "") 6295 (make-string (1- level) ?.) "")
6350 (org-get-heading)) 6296 (org-get-heading))
6351 category)) 6297 category))
6298 (goto-char lspos)
6352 (setq marker (org-agenda-new-marker)) 6299 (setq marker (org-agenda-new-marker))
6353 (add-text-properties 6300 (add-text-properties
6354 0 (length txt) 6301 0 (length txt)
@@ -6358,7 +6305,8 @@ d are included in the output."
6358 txt) 6305 txt)
6359 (push txt rtn)) 6306 (push txt rtn))
6360 ;; if we are to skip sublevels, jump to end of subtree 6307 ;; if we are to skip sublevels, jump to end of subtree
6361 (or org-tags-match-list-sublevels (outline-end-of-subtree))))) 6308 (point)
6309 (or org-tags-match-list-sublevels (org-end-of-subtree)))))
6362 (nreverse rtn))) 6310 (nreverse rtn)))
6363 6311
6364(defun org-tags-sparse-tree (&optional arg match) 6312(defun org-tags-sparse-tree (&optional arg match)
@@ -6399,9 +6347,6 @@ MATCH can contain positive and negative selection of tags, like
6399 ;; Return the string and lisp forms of the matcher 6347 ;; Return the string and lisp forms of the matcher
6400 (cons match0 matcher))) 6348 (cons match0 matcher)))
6401 6349
6402;;(org-make-tags-matcher "&hello&-you")
6403
6404
6405;;;###autoload 6350;;;###autoload
6406(defun org-tags-view (&optional todo-only match keep-modes) 6351(defun org-tags-view (&optional todo-only match keep-modes)
6407 "Show all headlines for all `org-agenda-files' matching a TAGS criterions. 6352 "Show all headlines for all `org-agenda-files' matching a TAGS criterions.
@@ -6410,6 +6355,8 @@ The prefix arg TODO-ONLY limits the search to TODO entries."
6410 (org-agenda-maybe-reset-markers 'force) 6355 (org-agenda-maybe-reset-markers 'force)
6411 (org-compile-prefix-format org-agenda-prefix-format) 6356 (org-compile-prefix-format org-agenda-prefix-format)
6412 (let* ((org-agenda-keep-modes keep-modes) 6357 (let* ((org-agenda-keep-modes keep-modes)
6358 (org-tags-match-list-sublevels
6359 (if todo-only t org-tags-match-list-sublevels))
6413 (win (selected-window)) 6360 (win (selected-window))
6414 (completion-ignore-case t) 6361 (completion-ignore-case t)
6415 rtn rtnall files file pos matcher 6362 rtn rtnall files file pos matcher
@@ -6424,8 +6371,10 @@ The prefix arg TODO-ONLY limits the search to TODO entries."
6424 (setq buffer-read-only nil) 6371 (setq buffer-read-only nil)
6425 (erase-buffer) 6372 (erase-buffer)
6426 (org-agenda-mode) (setq buffer-read-only nil) 6373 (org-agenda-mode) (setq buffer-read-only nil)
6374 (set (make-local-variable 'org-agenda-type) 'tags)
6427 (set (make-local-variable 'org-agenda-redo-command) 6375 (set (make-local-variable 'org-agenda-redo-command)
6428 '(call-interactively 'org-tags-view)) 6376 (list 'org-tags-view (list 'quote todo-only)
6377 (list 'if 'current-prefix-arg nil match) t))
6429 (setq files (org-agenda-files) 6378 (setq files (org-agenda-files)
6430 rtnall nil) 6379 rtnall nil)
6431 (while (setq file (pop files)) 6380 (while (setq file (pop files))
@@ -6459,6 +6408,9 @@ The prefix arg TODO-ONLY limits the search to TODO entries."
6459 (setq pos (point)) 6408 (setq pos (point))
6460 (insert match "\n") 6409 (insert match "\n")
6461 (add-text-properties pos (1- (point)) (list 'face 'org-warning)) 6410 (add-text-properties pos (1- (point)) (list 'face 'org-warning))
6411 (setq pos (point))
6412 (insert "Press `C-u r' to search again with new search string\n")
6413 (add-text-properties pos (1- (point)) (list 'face 'org-link))
6462 (when rtnall 6414 (when rtnall
6463 (insert (mapconcat 'identity rtnall "\n"))) 6415 (insert (mapconcat 'identity rtnall "\n")))
6464 (goto-char (point-min)) 6416 (goto-char (point-min))
@@ -6475,7 +6427,7 @@ With prefix ARG, realign all tags in headings in the current buffer."
6475 (re (concat "^" outline-regexp)) 6427 (re (concat "^" outline-regexp))
6476 (col (current-column)) 6428 (col (current-column))
6477 (current (org-get-tags)) 6429 (current (org-get-tags))
6478 tags hd) 6430 tags hd empty)
6479 (if arg 6431 (if arg
6480 (save-excursion 6432 (save-excursion
6481 (goto-char (point-min)) 6433 (goto-char (point-min))
@@ -6493,15 +6445,18 @@ With prefix ARG, realign all tags in headings in the current buffer."
6493 nil nil current 'org-tags-history))) 6445 nil nil current 'org-tags-history)))
6494 (while (string-match "[-+&]+" tags) 6446 (while (string-match "[-+&]+" tags)
6495 (setq tags (replace-match ":" t t tags))) 6447 (setq tags (replace-match ":" t t tags)))
6496 (unless (string-match ":$" tags) (setq tags (concat tags ":"))) 6448 (unless (setq empty (string-match "\\`[\t ]*\\'" tags))
6497 (unless (string-match "^:" tags) (setq tags (concat ":" tags)))) 6449 (unless (string-match ":$" tags) (setq tags (concat tags ":")))
6450 (unless (string-match "^:" tags) (setq tags (concat ":" tags)))))
6498 (if (equal current "") 6451 (if (equal current "")
6499 (end-of-line 1) 6452 (progn
6453 (end-of-line 1)
6454 (or empty (insert " ")))
6500 (beginning-of-line 1) 6455 (beginning-of-line 1)
6501 (looking-at (concat "\\(.*\\)\\(" (regexp-quote current) "\\)[ \t]*")) 6456 (looking-at (concat "\\(.*\\)\\(" (regexp-quote current) "\\)[ \t]*"))
6502 (setq hd (match-string 1)) 6457 (setq hd (match-string 1))
6503 (delete-region (match-beginning 0) (match-end 0)) 6458 (delete-region (match-beginning 0) (match-end 0))
6504 (insert (org-trim hd) " ")) 6459 (insert (org-trim hd) (if empty "" " ")))
6505 (unless (equal tags "") 6460 (unless (equal tags "")
6506 (move-to-column (max (current-column) 6461 (move-to-column (max (current-column)
6507 (if (> org-tags-column 0) 6462 (if (> org-tags-column 0)
@@ -6553,7 +6508,7 @@ With prefix ARG, realign all tags in headings in the current buffer."
6553 (goto-char (point-min)) 6508 (goto-char (point-min))
6554 (while (re-search-forward "[ \t]:\\([A-Za-z_:]+\\):[ \t\r\n]" nil t) 6509 (while (re-search-forward "[ \t]:\\([A-Za-z_:]+\\):[ \t\r\n]" nil t)
6555 (mapc (lambda (x) (add-to-list 'tags x)) 6510 (mapc (lambda (x) (add-to-list 'tags x))
6556 (org-split-string (match-string-no-properties 1) ":")))) 6511 (org-split-string (match-string 1) ":"))))
6557 (mapcar 'list tags))) 6512 (mapcar 'list tags)))
6558 6513
6559;;; Link Stuff 6514;;; Link Stuff
@@ -11542,13 +11497,17 @@ See the individual commands for more information."
11542 (org-table-paste-rectangle) 11497 (org-table-paste-rectangle)
11543 (org-paste-subtree arg))) 11498 (org-paste-subtree arg)))
11544 11499
11545;; FIXME: document tags
11546(defun org-ctrl-c-ctrl-c (&optional arg) 11500(defun org-ctrl-c-ctrl-c (&optional arg)
11547 "Call realign table, or recognize a table.el table, or update keywords. 11501 "Call realign table, or recognize a table.el table, or update keywords.
11548When the cursor is inside a table created by the table.el package, 11502When the cursor is inside a table created by the table.el package,
11549activate that table. Otherwise, if the cursor is at a normal table 11503activate that table. Otherwise, if the cursor is at a normal table
11550created with org.el, re-align that table. This command works even if 11504created with org.el, re-align that table. This command works even if
11551the automatic table editor has been turned off. 11505the automatic table editor has been turned off.
11506
11507If the cursor is in a headline, prompt for tags and insert them into
11508the current line, aligned to `org-tags-column'. When in a headline and
11509called with prefix arg, realign all tags in the current buffer.
11510
11552If the cursor is in one of the special #+KEYWORD lines, this triggers 11511If the cursor is in one of the special #+KEYWORD lines, this triggers
11553scanning the buffer for these lines and updating the information. 11512scanning the buffer for these lines and updating the information.
11554If the cursor is on a #+TBLFM line, re-apply the formulae to the table." 11513If the cursor is on a #+TBLFM line, re-apply the formulae to the table."
@@ -11946,12 +11905,18 @@ that can be added."
11946 t) 11905 t)
11947 "\\'")))) 11906 "\\'"))))
11948 11907
11949;; Functions needed for compatibility with old outline.el 11908;; Functions needed for compatibility with old outline.el.
11909
11910;; Programming for the old outline.el (that uses selective display
11911;; instead of `invisible' text properties) is a nightmare, mostly
11912;; because regular expressions can no longer be anchored at
11913;; beginning/end of line. Therefore a number of function need special
11914;; treatment when the old outline.el is being used.
11950 11915
11951;; The following functions capture almost the entire compatibility code 11916;; The following functions capture almost the entire compatibility code
11952;; between the different versions of outline-mode. The only other place 11917;; between the different versions of outline-mode. The only other
11953;; where this is important are the font-lock-keywords. Search for 11918;; places where this is important are the font-lock-keywords, and in
11954;; `org-noutline-p' to find it. 11919;; `org-export-copy-visible'. Search for `org-noutline-p' to find them.
11955 11920
11956;; C-a should go to the beginning of a *visible* line, also in the 11921;; C-a should go to the beginning of a *visible* line, also in the
11957;; new outline.el. I guess this should be patched into Emacs? 11922;; new outline.el. I guess this should be patched into Emacs?
@@ -11968,8 +11933,11 @@ to a visible line beginning. This makes the function of C-a more intuitive."
11968 (backward-char 1) 11933 (backward-char 1)
11969 (beginning-of-line 1)) 11934 (beginning-of-line 1))
11970 (forward-char 1)))) 11935 (forward-char 1))))
11936
11971(when org-noutline-p 11937(when org-noutline-p
11972 (define-key org-mode-map "\C-a" 'org-beginning-of-line)) 11938 (define-key org-mode-map "\C-a" 'org-beginning-of-line))
11939;; FIXME: should I use substitute-key-definition to reach other bindings
11940;; of beginning-of-line?
11973 11941
11974(defun org-invisible-p () 11942(defun org-invisible-p ()
11975 "Check if point is at a character currently not visible." 11943 "Check if point is at a character currently not visible."
@@ -11987,7 +11955,8 @@ to a visible line beginning. This makes the function of C-a more intuitive."
11987Only visible heading lines are considered, unless INVISIBLE-OK is non-nil." 11955Only visible heading lines are considered, unless INVISIBLE-OK is non-nil."
11988 (if org-noutline-p 11956 (if org-noutline-p
11989 (outline-back-to-heading invisible-ok) 11957 (outline-back-to-heading invisible-ok)
11990 (if (looking-at outline-regexp) 11958 (if (and (memq (char-before) '(?\n ?\r))
11959 (looking-at outline-regexp))
11991 t 11960 t
11992 (if (re-search-backward (concat (if invisible-ok "\\([\r\n]\\|^\\)" "^") 11961 (if (re-search-backward (concat (if invisible-ok "\\([\r\n]\\|^\\)" "^")
11993 outline-regexp) 11962 outline-regexp)
@@ -12068,6 +12037,27 @@ When ENTRY is non-nil, show the entire entry."
12068 flag 12037 flag
12069 (if flag ?\r ?\n)))))) 12038 (if flag ?\r ?\n))))))
12070 12039
12040(defun org-end-of-subtree (&optional invisible-OK)
12041 ;; This is an exact copy of the original function, but it uses
12042 ;; `org-back-to-heading', to make it work also in invisible
12043 ;; trees. And is uses an invisible-OK argument.
12044 ;; Under Emacs this is not needed, but the old outline.el needs this fix.
12045 (org-back-to-heading invisible-OK)
12046 (let ((opoint (point))
12047 (first t)
12048 (level (funcall outline-level)))
12049 (while (and (not (eobp))
12050 (or first (> (funcall outline-level) level)))
12051 (setq first nil)
12052 (outline-next-heading))
12053 (if (memq (preceding-char) '(?\n ?\^M))
12054 (progn
12055 ;; Go to end of line before heading
12056 (forward-char -1)
12057 (if (memq (preceding-char) '(?\n ?\^M))
12058 ;; leave blank line before heading
12059 (forward-char -1))))))
12060
12071(defun org-show-subtree () 12061(defun org-show-subtree ()
12072 "Show everything after this heading at deeper levels." 12062 "Show everything after this heading at deeper levels."
12073 (outline-flag-region 12063 (outline-flag-region
@@ -12125,3 +12115,4 @@ Show the heading too, if it is currently invisible."
12125 12115
12126;; arch-tag: e77da1a7-acc7-4336-b19e-efa25af3f9fd 12116;; arch-tag: e77da1a7-acc7-4336-b19e-efa25af3f9fd
12127;;; org.el ends here 12117;;; org.el ends here
12118
diff --git a/lisp/url/ChangeLog b/lisp/url/ChangeLog
index cc2d1eace59..d30534ec6be 100644
--- a/lisp/url/ChangeLog
+++ b/lisp/url/ChangeLog
@@ -1,3 +1,25 @@
12006-01-05 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 * url-history.el (url-history-hash-table): Initialize in declaration.
4 (url-history-parse-history): Don't reset the history.
5 (url-history-save-history): Create parent dir if necessary.
6 (url-history-save-history): Don't write the initialization of
7 url-history-hash-table into the history file.
8 (url-have-visited-url): Simplify since url-history-hash-table is non-nil.
9 (url-completion-function): Simplify.
10
11 * url-cookie.el (url-cookie-parse-file): Don't complain of missing file.
12 (url-cookie-parse-file, url-cookie-write-file, url-cookie-retrieve)
13 (url-cookie-generate-header-lines, url-cookie-handle-set-cookie)
14 (url-cookie-setup-save-timer): Remove autoload cookies.
15 They're only called from files that require url-cookie anyway.
16
17 * url-history.el (url-history-setup-save-timer)
18 (url-history-parse-history, url-history-save-history):
19 Remove autoload cookies. They're only called from url.el which requires
20 url-history anyway.
21 (url-history-parse-history): Don't complain if the file is missing.
22
12006-01-02 Stefan Monnier <monnier@iro.umontreal.ca> 232006-01-02 Stefan Monnier <monnier@iro.umontreal.ca>
2 24
3 * url-handlers.el (url-retrieve-synchronously): Don't autoload. 25 * url-handlers.el (url-retrieve-synchronously): Don't autoload.
diff --git a/lisp/url/url-cookie.el b/lisp/url/url-cookie.el
index 3772846607a..53ba75f4cbb 100644
--- a/lisp/url/url-cookie.el
+++ b/lisp/url/url-cookie.el
@@ -1,7 +1,7 @@
1;;; url-cookie.el --- Netscape Cookie support 1;;; url-cookie.el --- Netscape Cookie support
2 2
3;; Copyright (C) 1996, 1997, 1998, 1999, 2004, 3;; Copyright (C) 1996, 1997, 1998, 1999, 2004,
4;; 2005 Free Software Foundation, Inc. 4;; 2005, 2006 Free Software Foundation, Inc.
5 5
6;; Keywords: comm, data, processes, hypermedia 6;; Keywords: comm, data, processes, hypermedia
7 7
@@ -109,12 +109,14 @@ telling Microsoft that."
109(defvar url-cookies-changed-since-last-save nil 109(defvar url-cookies-changed-since-last-save nil
110 "Whether the cookies list has changed since the last save operation.") 110 "Whether the cookies list has changed since the last save operation.")
111 111
112;;;###autoload
113(defun url-cookie-parse-file (&optional fname) 112(defun url-cookie-parse-file (&optional fname)
114 (setq fname (or fname url-cookie-file)) 113 (setq fname (or fname url-cookie-file))
115 (condition-case () 114 (condition-case ()
116 (load fname nil t) 115 (load fname nil t)
117 (error (message "Could not load cookie file %s" fname)))) 116 (error
117 ;; It's completely normal for the cookies file not to exist yet.
118 ;; (message "Could not load cookie file %s" fname)
119 )))
118 120
119(defun url-cookie-clean-up (&optional secure) 121(defun url-cookie-clean-up (&optional secure)
120 (let* ( 122 (let* (
@@ -145,7 +147,6 @@ telling Microsoft that."
145 (setq new (cons cur new)))) 147 (setq new (cons cur new))))
146 (set var new))) 148 (set var new)))
147 149
148;;;###autoload
149(defun url-cookie-write-file (&optional fname) 150(defun url-cookie-write-file (&optional fname)
150 (setq fname (or fname url-cookie-file)) 151 (setq fname (or fname url-cookie-file))
151 (unless (file-directory-p (file-name-directory fname)) 152 (unless (file-directory-p (file-name-directory fname))
@@ -250,7 +251,6 @@ telling Microsoft that."
250 (* 1 (string-to-number (aref exp-time 0)))))) 251 (* 1 (string-to-number (aref exp-time 0))))))
251 (> (- cur-norm exp-norm) 1)))))) 252 (> (- cur-norm exp-norm) 1))))))
252 253
253;;;###autoload
254(defun url-cookie-retrieve (host localpart &optional secure) 254(defun url-cookie-retrieve (host localpart &optional secure)
255 "Retrieve all the netscape-style cookies for a specified HOST and LOCALPART." 255 "Retrieve all the netscape-style cookies for a specified HOST and LOCALPART."
256 (let ((storage (if secure 256 (let ((storage (if secure
@@ -278,7 +278,6 @@ telling Microsoft that."
278 (setq retval (cons cur retval)))))) 278 (setq retval (cons cur retval))))))
279 retval)) 279 retval))
280 280
281;;;###autoload
282(defun url-cookie-generate-header-lines (host localpart secure) 281(defun url-cookie-generate-header-lines (host localpart secure)
283 (let* ((cookies (url-cookie-retrieve host localpart secure)) 282 (let* ((cookies (url-cookie-retrieve host localpart secure))
284 (retval nil) 283 (retval nil)
@@ -344,7 +343,6 @@ telling Microsoft that."
344 (t 343 (t
345 nil)))) 344 nil))))
346 345
347;;;###autoload
348(defun url-cookie-handle-set-cookie (str) 346(defun url-cookie-handle-set-cookie (str)
349 (setq url-cookies-changed-since-last-save t) 347 (setq url-cookies-changed-since-last-save t)
350 (let* ((args (url-parse-args str t)) 348 (let* ((args (url-parse-args str t))
@@ -457,7 +455,6 @@ to run the `url-cookie-setup-save-timer' function manually."
457 :type 'integer 455 :type 'integer
458 :group 'url) 456 :group 'url)
459 457
460;;;###autoload
461(defun url-cookie-setup-save-timer () 458(defun url-cookie-setup-save-timer ()
462 "Reset the cookie saver timer." 459 "Reset the cookie saver timer."
463 (interactive) 460 (interactive)
diff --git a/lisp/url/url-history.el b/lisp/url/url-history.el
index 3bb7145b451..0cdfe329bc2 100644
--- a/lisp/url/url-history.el
+++ b/lisp/url/url-history.el
@@ -1,7 +1,7 @@
1;;; url-history.el --- Global history tracking for URL package 1;;; url-history.el --- Global history tracking for URL package
2 2
3;; Copyright (C) 1996, 1997, 1998, 1999, 2004, 3;; Copyright (C) 1996, 1997, 1998, 1999, 2004,
4;; 2005 Free Software Foundation, Inc. 4;; 2005, 2006 Free Software Foundation, Inc.
5 5
6;; Keywords: comm, data, processes, hypermedia 6;; Keywords: comm, data, processes, hypermedia
7 7
@@ -75,12 +75,11 @@ to run the `url-history-setup-save-timer' function manually."
75(defvar url-history-changed-since-last-save nil 75(defvar url-history-changed-since-last-save nil
76 "Whether the history list has changed since the last save operation.") 76 "Whether the history list has changed since the last save operation.")
77 77
78(defvar url-history-hash-table nil 78(defvar url-history-hash-table (make-hash-table :size 31 :test 'equal)
79 "Hash table for global history completion.") 79 "Hash table for global history completion.")
80 80
81;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 81;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
82 82
83;;;###autoload
84(defun url-history-setup-save-timer () 83(defun url-history-setup-save-timer ()
85 "Reset the history list timer." 84 "Reset the history list timer."
86 (interactive) 85 (interactive)
@@ -92,28 +91,27 @@ to run the `url-history-setup-save-timer' function manually."
92 url-history-save-interval 91 url-history-save-interval
93 'url-history-save-history)))) 92 'url-history-save-history))))
94 93
95;;;###autoload
96(defun url-history-parse-history (&optional fname) 94(defun url-history-parse-history (&optional fname)
97 "Parse a history file stored in FNAME." 95 "Parse a history file stored in FNAME."
98 ;; Parse out the mosaic global history file for completions, etc. 96 ;; Parse out the mosaic global history file for completions, etc.
99 (or fname (setq fname (expand-file-name url-history-file))) 97 (or fname (setq fname (expand-file-name url-history-file)))
100 (cond 98 (cond
101 ((not (file-exists-p fname)) 99 ((not (file-exists-p fname))
102 (message "%s does not exist." fname)) 100 ;; It's completely normal for this file not to exist, so don't complain.
101 ;; (message "%s does not exist." fname)
102 )
103 ((not (file-readable-p fname)) 103 ((not (file-readable-p fname))
104 (message "%s is unreadable." fname)) 104 (message "%s is unreadable." fname))
105 (t 105 (t
106 (condition-case nil 106 (condition-case nil
107 (load fname nil t) 107 (load fname nil t)
108 (error (message "Could not load %s" fname))))) 108 (error (message "Could not load %s" fname))))))
109 (if (not url-history-hash-table)
110 (setq url-history-hash-table (make-hash-table :size 31 :test 'equal))))
111 109
112(defun url-history-update-url (url time) 110(defun url-history-update-url (url time)
113 (setq url-history-changed-since-last-save t) 111 (setq url-history-changed-since-last-save t)
114 (puthash (if (vectorp url) (url-recreate-url url) url) time url-history-hash-table)) 112 (puthash (if (vectorp url) (url-recreate-url url) url) time
113 url-history-hash-table))
115 114
116;;;###autoload
117(defun url-history-save-history (&optional fname) 115(defun url-history-save-history (&optional fname)
118 "Write the global history file into `url-history-file'. 116 "Write the global history file into `url-history-file'.
119The type of data written is determined by what is in the file to begin 117The type of data written is determined by what is in the file to begin
@@ -121,6 +119,8 @@ with. If the type of storage cannot be determined, then prompt the
121user for what type to save as." 119user for what type to save as."
122 (interactive) 120 (interactive)
123 (or fname (setq fname (expand-file-name url-history-file))) 121 (or fname (setq fname (expand-file-name url-history-file)))
122 (unless (file-directory-p (file-name-directory fname))
123 (ignore-errors (make-directory (file-name-directory fname))))
124 (cond 124 (cond
125 ((not url-history-changed-since-last-save) nil) 125 ((not url-history-changed-since-last-save) nil)
126 ((not (file-writable-p fname)) 126 ((not (file-writable-p fname))
@@ -129,26 +129,27 @@ user for what type to save as."
129 (let ((make-backup-files nil) 129 (let ((make-backup-files nil)
130 (version-control nil) 130 (version-control nil)
131 (require-final-newline t)) 131 (require-final-newline t))
132 (save-excursion 132 (with-current-buffer (get-buffer-create " *url-tmp*")
133 (set-buffer (get-buffer-create " *url-tmp*"))
134 (erase-buffer) 133 (erase-buffer)
135 (let ((count 0)) 134 (let ((count 0))
136 (maphash (function 135 (maphash (lambda (key value)
137 (lambda (key value) 136 (while (string-match "[\r\n]+" key)
138 (while (string-match "[\r\n]+" key) 137 (setq key (concat (substring key 0 (match-beginning 0))
139 (setq key (concat (substring key 0 (match-beginning 0)) 138 (substring key (match-end 0) nil))))
140 (substring key (match-end 0) nil)))) 139 (setq count (1+ count))
141 (setq count (1+ count)) 140 (insert "(puthash \"" key "\""
142 (insert "(puthash \"" key "\"" 141 (if (not (stringp value)) " '" "")
143 (if (not (stringp value)) " '" "") 142 (prin1-to-string value)
144 (prin1-to-string value) 143 " url-history-hash-table)\n"))
145 " url-history-hash-table)\n"))) 144 url-history-hash-table)
146 url-history-hash-table) 145 ;; We used to add this in the file, but it just makes the code
147 (goto-char (point-min)) 146 ;; more complex with no benefit. Worse: it makes it harder to
148 (insert (format 147 ;; preserve preexisting history when loading the history file.
149 "(setq url-history-hash-table (make-hash-table :size %d :test 'equal))\n" 148 ;; (goto-char (point-min))
150 (/ count 4))) 149 ;; (insert (format
151 (goto-char (point-max)) 150 ;; "(setq url-history-hash-table (make-hash-table :size %d :test 'equal))\n"
151 ;; (/ count 4)))
152 ;; (goto-char (point-max))
152 (insert "\n") 153 (insert "\n")
153 (write-file fname)) 154 (write-file fname))
154 (kill-buffer (current-buffer)))))) 155 (kill-buffer (current-buffer))))))
@@ -156,33 +157,30 @@ user for what type to save as."
156 157
157(defun url-have-visited-url (url) 158(defun url-have-visited-url (url)
158 (url-do-setup) 159 (url-do-setup)
159 (and url-history-hash-table 160 (gethash url url-history-hash-table nil))
160 (gethash url url-history-hash-table nil)))
161 161
162(defun url-completion-function (string predicate function) 162(defun url-completion-function (string predicate function)
163 ;; Completion function to complete urls from the history.
164 ;; This is obsolete since we can now pass the hash-table directly as a
165 ;; completion table.
163 (url-do-setup) 166 (url-do-setup)
164 (cond 167 (cond
165 ((eq function nil) 168 ((eq function nil)
166 (let ((list nil)) 169 (let ((list nil))
167 (maphash (function (lambda (key val) 170 (maphash (lambda (key val) (push key list))
168 (setq list (cons (cons key val) 171 url-history-hash-table)
169 list)))) 172 ;; Not sure why we bother reversing the list. --Stef
170 url-history-hash-table)
171 (try-completion string (nreverse list) predicate))) 173 (try-completion string (nreverse list) predicate)))
172 ((eq function t) 174 ((eq function t)
173 (let ((stub (concat "^" (regexp-quote string))) 175 (let ((stub (concat "\\`" (regexp-quote string)))
174 (retval nil)) 176 (retval nil))
175 (maphash 177 (maphash
176 (function 178 (lambda (url time)
177 (lambda (url time) 179 (if (string-match stub url) (push url retval)))
178 (if (string-match stub url)
179 (setq retval (cons url retval)))))
180 url-history-hash-table) 180 url-history-hash-table)
181 retval)) 181 retval))
182 ((eq function 'lambda) 182 ((eq function 'lambda)
183 (and url-history-hash-table 183 (and (gethash string url-history-hash-table) t))
184 (gethash string url-history-hash-table)
185 t))
186 (t 184 (t
187 (error "url-completion-function very confused")))) 185 (error "url-completion-function very confused"))))
188 186
diff --git a/lisp/wid-edit.el b/lisp/wid-edit.el
index 1f0b8e746c7..0735c467439 100644
--- a/lisp/wid-edit.el
+++ b/lisp/wid-edit.el
@@ -403,7 +403,8 @@ new value.")
403 ;; We want to avoid the face with image buttons. 403 ;; We want to avoid the face with image buttons.
404 (unless (widget-get widget :suppress-face) 404 (unless (widget-get widget :suppress-face)
405 (overlay-put overlay 'face (widget-apply widget :button-face-get)) 405 (overlay-put overlay 'face (widget-apply widget :button-face-get))
406 (overlay-put overlay 'mouse-face widget-mouse-face)) 406 (overlay-put overlay 'mouse-face
407 (widget-apply widget :mouse-face-get)))
407 (overlay-put overlay 'pointer 'hand) 408 (overlay-put overlay 'pointer 'hand)
408 (overlay-put overlay 'follow-link follow-link) 409 (overlay-put overlay 'follow-link follow-link)
409 (overlay-put overlay 'help-echo help-echo))) 410 (overlay-put overlay 'help-echo help-echo)))
@@ -1391,6 +1392,7 @@ The value of the :type attribute should be an unconverted widget type."
1391 :offset 0 1392 :offset 0
1392 :format-handler 'widget-default-format-handler 1393 :format-handler 'widget-default-format-handler
1393 :button-face-get 'widget-default-button-face-get 1394 :button-face-get 'widget-default-button-face-get
1395 :mouse-face-get 'widget-default-mouse-face-get
1394 :sample-face-get 'widget-default-sample-face-get 1396 :sample-face-get 'widget-default-sample-face-get
1395 :delete 'widget-default-delete 1397 :delete 'widget-default-delete
1396 :copy 'identity 1398 :copy 'identity
@@ -1535,6 +1537,14 @@ If that does not exists, call the value of `widget-complete-field'."
1535 (widget-apply parent :button-face-get) 1537 (widget-apply parent :button-face-get)
1536 widget-button-face)))) 1538 widget-button-face))))
1537 1539
1540(defun widget-default-mouse-face-get (widget)
1541 ;; Use :mouse-face or widget-mouse-face
1542 (or (widget-get widget :mouse-face)
1543 (let ((parent (widget-get widget :parent)))
1544 (if parent
1545 (widget-apply parent :mouse-face-get)
1546 widget-mouse-face))))
1547
1538(defun widget-default-sample-face-get (widget) 1548(defun widget-default-sample-face-get (widget)
1539 ;; Use :sample-face. 1549 ;; Use :sample-face.
1540 (widget-get widget :sample-face)) 1550 (widget-get widget :sample-face))
@@ -3161,28 +3171,83 @@ It reads a directory name from an editable text field."
3161 (widget-apply widget :notify widget event) 3171 (widget-apply widget :notify widget event)
3162 (widget-setup))) 3172 (widget-setup)))
3163 3173
3174;;; I'm not sure about what this is good for? KFS.
3164(defvar widget-key-sequence-prompt-value-history nil 3175(defvar widget-key-sequence-prompt-value-history nil
3165 "History of input to `widget-key-sequence-prompt-value'.") 3176 "History of input to `widget-key-sequence-prompt-value'.")
3166 3177
3167;; This mostly works, but I am pretty sure it needs more change 3178(defvar widget-key-sequence-default-value [ignore]
3168;; to be 100% correct. I don't know what the change should be -- rms. 3179 "Default value for an empty key sequence.")
3180
3181(defvar widget-key-sequence-map
3182 (let ((map (make-sparse-keymap)))
3183 (set-keymap-parent map widget-field-keymap)
3184 (define-key map [(control ?q)] 'widget-key-sequence-read-event)
3185 map))
3169 3186
3170(define-widget 'key-sequence 'restricted-sexp 3187(define-widget 'key-sequence 'restricted-sexp
3171 "A Lisp function." 3188 "A key sequence."
3172 :prompt-value 'widget-field-prompt-value 3189 :prompt-value 'widget-field-prompt-value
3173 :prompt-internal 'widget-symbol-prompt-internal 3190 :prompt-internal 'widget-symbol-prompt-internal
3174 :prompt-match 'fboundp 3191; :prompt-match 'fboundp ;; What was this good for? KFS
3175 :prompt-history 'widget-key-sequence-prompt-value-history 3192 :prompt-history 'widget-key-sequence-prompt-value-history
3176 :action 'widget-field-action 3193 :action 'widget-field-action
3177 :match-alternatives '(stringp vectorp) 3194 :match-alternatives '(stringp vectorp)
3178 :validate (lambda (widget) 3195 :format "%{%t%}: %v"
3179 (unless (or (stringp (widget-value widget)) 3196 :validate 'widget-key-sequence-validate
3180 (vectorp (widget-value widget))) 3197 :value-to-internal 'widget-key-sequence-value-to-internal
3181 (widget-put widget :error (format "Invalid key sequence: %S" 3198 :value-to-external 'widget-key-sequence-value-to-external
3182 (widget-value widget))) 3199 :value widget-key-sequence-default-value
3183 widget)) 3200 :keymap widget-key-sequence-map
3184 :value 'ignore 3201 :help-echo "C-q: insert KEY, EVENT, or CODE; RET: enter value"
3185 :tag "Key sequence") 3202 :tag "Key sequence")
3203
3204(defun widget-key-sequence-read-event (ev)
3205 (interactive (list
3206 (let ((inhibit-quit t) quit-flag)
3207 (read-event "Insert KEY, EVENT, or CODE: "))))
3208 (let ((ev2 (and (memq 'down (event-modifiers ev))
3209 (read-event)))
3210 (tr (and (keymapp function-key-map)
3211 (lookup-key function-key-map (vector ev)))))
3212 (when (and (integerp ev)
3213 (or (and (<= ?0 ev) (< ev (+ ?0 (min 10 read-quoted-char-radix))))
3214 (and (<= ?a (downcase ev))
3215 (< (downcase ev) (+ ?a -10 (min 36 read-quoted-char-radix))))))
3216 (setq unread-command-events (cons ev unread-command-events)
3217 ev (read-quoted-char (format "Enter code (radix %d)" read-quoted-char-radix))
3218 tr nil)
3219 (if (and (integerp ev) (not (char-valid-p ev)))
3220 (insert (char-to-string ev)))) ;; throw invalid char error
3221 (setq ev (key-description (list ev)))
3222 (when (arrayp tr)
3223 (setq tr (key-description (list (aref tr 0))))
3224 (if (y-or-n-p (format "Key %s is translated to %s -- use %s? " ev tr tr))
3225 (setq ev tr ev2 nil)))
3226 (insert (if (= (char-before) ?\s) "" " ") ev " ")
3227 (if ev2
3228 (insert (key-description (list ev2)) " "))))
3229
3230(defun widget-key-sequence-validate (widget)
3231 (unless (or (stringp (widget-value widget))
3232 (vectorp (widget-value widget)))
3233 (widget-put widget :error (format "Invalid key sequence: %S"
3234 (widget-value widget)))
3235 widget))
3236
3237(defun widget-key-sequence-value-to-internal (widget value)
3238 (if (widget-apply widget :match value)
3239 (if (equal value widget-key-sequence-default-value)
3240 ""
3241 (key-description value))
3242 value))
3243
3244(defun widget-key-sequence-value-to-external (widget value)
3245 (if (stringp value)
3246 (if (string-match "\\`[[:space:]]*\\'" value)
3247 widget-key-sequence-default-value
3248 (read-kbd-macro value))
3249 value))
3250
3186 3251
3187(define-widget 'sexp 'editable-field 3252(define-widget 'sexp 'editable-field
3188 "An arbitrary Lisp expression." 3253 "An arbitrary Lisp expression."