Ladies and Gentlement, FFmpeg is back!
[sxemacs] / lisp / subr.el
1 ;;; subr.el --- basic lisp subroutines for SXEmacs
2
3 ;; Copyright (C) 1985, 86, 92, 94, 95, 99, 2000, 2001, 2002, 2003
4 ;;   Free Software Foundation, Inc.
5 ;; Copyright (C) 1995 Tinker Systems and INS Engineering Corp.
6 ;; Copyright (C) 1995 Sun Microsystems.
7 ;; Copyright (C) 2000, 2001, 2002, 2003 Ben Wing.
8
9 ;; Maintainer: SXEmacs Development Team
10 ;; Keywords: extensions, dumped, internal
11
12 ;; This file is part of SXEmacs.
13
14 ;; SXEmacs is free software: you can redistribute it and/or modify
15 ;; it under the terms of the GNU General Public License as published by
16 ;; the Free Software Foundation, either version 3 of the License, or
17 ;; (at your option) any later version.
18
19 ;; SXEmacs is distributed in the hope that it will be useful,
20 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
21 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 ;; GNU General Public License for more details.
23
24 ;; You should have received a copy of the GNU General Public License
25 ;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
26
27 ;;; Synched up with: FSF 19.34.  Some things synched up with later versions.
28
29 ;;; Commentary:
30
31 ;; This file is dumped with SXEmacs.
32
33 ;; There's not a whole lot in common now with the FSF version,
34 ;; be wary when applying differences.  I've left in a number of lines
35 ;; of commentary just to give diff(1) something to synch itself with to
36 ;; provide useful context diffs. -sb
37
38 ;; BEGIN SYNCHED WITH FSF 21.2
39
40 ;;; Code:
41 (defvar custom-declare-variable-list nil
42   "Record `defcustom' calls made before `custom.el' is loaded to handle them.
43 Each element of this list holds the arguments to one call to `defcustom'.")
44
45 ;; Use this, rather than defcustom, in subr.el and other files loaded
46 ;; before custom.el.  See dumped-lisp.el.
47 (defun custom-declare-variable-early (&rest arguments)
48   (setq custom-declare-variable-list
49         (cons arguments custom-declare-variable-list)))
50
51 \f
52 (defun macro-declaration-function (macro decl)
53   "Process a declaration found in a macro definition.
54 This is set as the value of the variable `macro-declaration-function'.
55 MACRO is the name of the macro being defined.
56 DECL is a list `(declare ...)' containing the declarations.
57 The return value of this function is not used."
58   (dolist (d (cdr decl))
59     (cond ((and (consp d) (eq (car d) 'indent))
60            (put macro 'lisp-indent-function (cadr d)))
61           ((and (consp d) (eq (car d) 'debug))
62            (put macro 'edebug-form-spec (cadr d)))
63           (t
64            (message "Unknown declaration %s" d)))))
65
66 (setq macro-declaration-function 'macro-declaration-function)
67
68 \f
69 ;;;; Lisp language features.
70
71 (defmacro lambda (&rest cdr)
72   "Return a lambda expression.
73 A call of the form (lambda ARGS DOCSTRING INTERACTIVE BODY) is
74 self-quoting; the result of evaluating the lambda expression is the
75 expression itself.  The lambda expression may then be treated as a
76 function, i.e., stored as the function value of a symbol, passed to
77 funcall or mapcar, etc.
78
79 ARGS should take the same form as an argument list for a `defun'.
80 Optional DOCSTRING is a documentation string.
81 If present, it should describe how to call the function.  Docstrings are
82 rarely useful unless the lambda will be named, eg, using `fset'.
83 Optional INTERACTIVE should be a call to the function `interactive'.
84 BODY should be a list of lisp expressions.
85
86 The byte-compiler treats lambda expressions specially.  If the lambda
87 expression is syntactically a function to be called, it will be compiled
88 unless protected by `quote'.  Conversely, quoting a lambda expression with
89 `function' hints to the byte-compiler that it should compile the expression.
90 \(The byte-compiler may or may not actually compile it; for example it will
91 never compile lambdas nested in a data structure: `'(#'(lambda (x) x))').
92
93 The byte-compiler will warn about common problems such as the form
94 `(fset 'f '(lambda (x) x))' (the lambda cannot be byte-compiled; probably
95 the programmer intended `#'', although leaving the lambda unquoted will
96 normally suffice), but in general is it the programmer's responsibility to
97 quote lambda expressions appropriately."
98   `(function (lambda ,@cdr)))
99
100 ;; FSF 21.2 has various basic macros here.  We don't because they're either
101 ;; in cl*.el (which we dump and hence is always available) or built-in.
102
103 ;; More powerful versions in cl.el.
104 ;(defmacro push (newelt listname)
105 ;(defmacro pop (listname)
106
107 ;; Built-in.
108 ;(defmacro when (cond &rest body)
109 ;(defmacro unless (cond &rest body)
110
111 ;; More powerful versions in cl-macs.el.
112 ;(defmacro dolist (spec &rest body)
113 ;(defmacro dotimes (spec &rest body)
114
115 ;; In cl.el.  Ours are defun, but cl arranges for them to be inlined anyway.
116 ;(defsubst caar (x)
117 ;(defsubst cadr (x)
118 ;(defsubst cdar (x)
119 ;(defsubst cddr (x)
120
121 ;; Built-in.  Our `last' is more powerful in that it handles circularity.
122 ;(defun last (x &optional n)
123 ;(defun butlast (x &optional n)
124 ;(defun nbutlast (x &optional n)
125
126 ;; In cl-seq.el.
127 ;(defun remove (elt seq)
128 ;(defun remq (elt list)
129
130 (defmacro defun-when-void (&rest args)
131   "Define a function, just like `defun', unless it's already defined.
132 Used for compatibility among different emacs variants."
133   `(if (fboundp ',(car args))
134        nil
135      (defun ,@args)))
136
137 (defmacro define-function-when-void (&rest args)
138   "Define a function, just like `define-function', unless it's already defined.
139 Used for compatibility among different emacs variants."
140   `(if (fboundp ,(car args))
141        nil
142      (define-function ,@args)))
143
144 \f
145 (defun assoc-default (key alist &optional test default)
146   "Find object KEY in a pseudo-alist ALIST.
147 ALIST is a list of conses or objects.  Each element (or the element's car,
148 if it is a cons) is compared with KEY by evaluating (TEST (car elt) KEY).
149 If that is non-nil, the element matches;
150 then `assoc-default' returns the element's cdr, if it is a cons,
151 or DEFAULT if the element is not a cons.
152
153 If no element matches, the value is nil.
154 If TEST is omitted or nil, `equal' is used."
155   (let (found (tail alist) value)
156     (while (and tail (not found))
157       (let ((elt (car tail)))
158         (when (funcall (or test 'equal) (if (consp elt) (car elt) elt) key)
159           (setq found t value (if (consp elt) (cdr elt) default))))
160       (setq tail (cdr tail)))
161     value))
162
163 (defun assoc-ignore-case (key alist)
164   "Like `assoc', but ignores differences in case and text representation.
165 KEY must be a string.  Upper-case and lower-case letters are treated as equal."
166   (let (element)
167     (while (and alist (not element))
168       (if (string= (downcase key) (downcase (car (car alist))))
169           (setq element (car alist)))
170       (setq alist (cdr alist)))
171     element))
172
173 (defun assoc-ignore-representation (key alist)
174   "Like `assoc', but ignores differences in text representation.
175 KEY must be a string."
176   (let (element)
177     (while (and alist (not element))
178       (if (string= key (car (car alist)))
179           (setq element (car alist)))
180       (setq alist (cdr alist)))
181     element))
182
183 (defun member-ignore-case (elt list)
184   "Like `member', but ignores differences in case and text representation.
185 ELT must be a string.  Upper-case and lower-case letters are treated as equal."
186   (while (and list (not (string= (downcase elt) (downcase (car list)))))
187     (setq list (cdr list)))
188   list)
189
190 \f
191 ;;;; Keymap support.
192 ;; XEmacs: removed to keymap.el
193
194 ;;;; The global keymap tree.
195
196 ;;; global-map, esc-map, and ctl-x-map have their values set up in
197 ;;; keymap.c; we just give them docstrings here.
198
199 ;;;; Event manipulation functions.
200
201 ;; XEmacs: This stuff is done in C Code.
202
203 ;;;; Obsolescent names for functions generally appear elsewhere, in
204 ;;;; obsolete.el or in the files they are related do.  Many very old
205 ;;;; obsolete stuff has been removed entirely (e.g. anything with `dot' in
206 ;;;; place of `point').
207
208 ; alternate names (not obsolete)
209 (if (not (fboundp 'mod)) (define-function 'mod '%))
210 (define-function 'move-marker 'set-marker)
211 (define-function 'beep 'ding)           ; preserve lingual purity
212 (define-function 'indent-to-column 'indent-to)
213 (define-function 'backward-delete-char 'delete-backward-char)
214 (define-function 'search-forward-regexp (symbol-function 're-search-forward))
215 (define-function 'search-backward-regexp (symbol-function 're-search-backward))
216 (define-function 'remove-directory 'delete-directory)
217 (define-function 'set-match-data 'store-match-data)
218 (define-function 'send-string-to-terminal 'external-debugging-output)
219
220 ;; XEmacs:
221 (defun local-variable-if-set-p (sym buffer)
222   "Return t if SYM would be local to BUFFER after it is set.
223 A nil value for BUFFER is *not* the same as (current-buffer), but
224 can be used to determine whether `make-variable-buffer-local' has been
225 called on SYM."
226   (local-variable-p sym buffer t))
227
228 \f
229 ;;;; Hook manipulation functions.
230
231 ;; (defconst run-hooks 'run-hooks ...)
232
233 (defun make-local-hook (hook)
234   "Make the hook HOOK local to the current buffer.
235 The return value is HOOK.
236
237 You never need to call this function now that `add-hook' does it for you
238 if its LOCAL argument is non-nil.
239
240 When a hook is local, its local and global values
241 work in concert: running the hook actually runs all the hook
242 functions listed in *either* the local value *or* the global value
243 of the hook variable.
244
245 This function works by making `t' a member of the buffer-local value,
246 which acts as a flag to run the hook functions in the default value as
247 well.  This works for all normal hooks, but does not work for most
248 non-normal hooks yet.  We will be changing the callers of non-normal
249 hooks so that they can handle localness; this has to be done one by
250 one.
251
252 This function does nothing if HOOK is already local in the current
253 buffer.
254
255 Do not use `make-local-variable' to make a hook variable buffer-local."
256   (if (local-variable-p hook (current-buffer)) ; XEmacs
257       nil
258     (or (boundp hook) (set hook nil))
259     (make-local-variable hook)
260     (set hook (list t)))
261   hook)
262
263 (defun add-hook (hook function &optional append local)
264   "Add to the value of HOOK the function FUNCTION.
265 FUNCTION is not added if already present.
266 FUNCTION is added (if necessary) at the beginning of the hook list
267 unless the optional argument APPEND is non-nil, in which case
268 FUNCTION is added at the end.
269
270 The optional fourth argument, LOCAL, if non-nil, says to modify
271 the hook's buffer-local value rather than its default value.
272 This makes the hook buffer-local if needed.
273 To make a hook variable buffer-local, always use
274 `make-local-hook', not `make-local-variable'.
275
276 HOOK should be a symbol, and FUNCTION may be any valid function.  If
277 HOOK is void, it is first set to nil.  If HOOK's value is a single
278 function, it is changed to a list of functions.
279
280 You can remove this hook yourself using `remove-hook'.
281
282 See also `add-one-shot-hook'."
283   (or (boundp hook) (set hook nil))
284   (or (default-boundp hook) (set-default hook nil))
285   (if local (unless (local-variable-if-set-p hook (current-buffer)) ; XEmacs
286               (make-local-hook hook))
287     ;; Detect the case where make-local-variable was used on a hook
288     ;; and do what we used to do.
289     (unless (and (consp (symbol-value hook)) (memq t (symbol-value hook)))
290       (setq local t)))
291   (let ((hook-value (if local (symbol-value hook) (default-value hook))))
292     ;; If the hook value is a single function, turn it into a list.
293     (when (or (not (listp hook-value)) (eq (car hook-value) 'lambda))
294       (setq hook-value (list hook-value)))
295     ;; Do the actual addition if necessary
296     (unless (member function hook-value)
297       (setq hook-value
298             (if append
299                 (append hook-value (list function))
300               (cons function hook-value))))
301     ;; Set the actual variable
302     (if local (set hook hook-value) (set-default hook hook-value))))
303
304 (defun remove-hook (hook function &optional local)
305   "Remove from the value of HOOK the function FUNCTION.
306 HOOK should be a symbol, and FUNCTION may be any valid function.  If
307 FUNCTION isn't the value of HOOK, or, if FUNCTION doesn't appear in the
308 list of hooks to run in HOOK, then nothing is done.  See `add-hook'.
309
310 The optional third argument, LOCAL, if non-nil, says to modify
311 the hook's buffer-local value rather than its default value.
312 This makes the hook buffer-local if needed.
313 To make a hook variable buffer-local, always use
314 `make-local-hook', not `make-local-variable'."
315   (or (boundp hook) (set hook nil))
316   (or (default-boundp hook) (set-default hook nil))
317   (if local (unless (local-variable-if-set-p hook (current-buffer)) ; XEmacs
318               (make-local-hook hook))
319     ;; Detect the case where make-local-variable was used on a hook
320     ;; and do what we used to do.
321     (unless (and (consp (symbol-value hook)) (memq t (symbol-value hook)))
322       (setq local t)))
323   (let ((hook-value (if local (symbol-value hook) (default-value hook))))
324     ;; Remove the function, for both the list and the non-list cases.
325     ;; XEmacs: add hook-test, for handling one-shot hooks.
326     (flet ((hook-test
327              (fn hel)
328              (or (equal fn hel)
329                  (and (symbolp hel)
330                       (equal fn
331                              (get hel 'one-shot-hook-fun))))))
332       (if (or (not (listp hook-value)) (eq (car hook-value) 'lambda))
333           (if (equal hook-value function) (setq hook-value nil))
334         (setq hook-value (delete* function (copy-sequence hook-value)
335                                   :test 'hook-test)))
336       ;; If the function is on the global hook, we need to shadow it locally
337       ;;(when (and local (member* function (default-value hook)
338       ;;                          :test 'hook-test)
339       ;;               (not (member* (cons 'not function) hook-value
340       ;;                             :test 'hook-test)))
341       ;;  (push (cons 'not function) hook-value))
342       ;; Set the actual variable
343       (if local (set hook hook-value) (set-default hook hook-value)))))
344
345 ;; XEmacs addition
346 ;; #### we need a coherent scheme for indicating compatibility info,
347 ;; so that it can be programmatically retrieved.
348 (defun add-local-hook (hook function &optional append)
349   "Add to the local value of HOOK the function FUNCTION.
350 You don't need this any more.  It's equivalent to specifying the LOCAL
351 argument to `add-hook'."
352   (add-hook hook function append t))
353
354 ;; XEmacs addition
355 (defun remove-local-hook (hook function)
356   "Remove from the local value of HOOK the function FUNCTION.
357 You don't need this any more.  It's equivalent to specifying the LOCAL
358 argument to `remove-hook'."
359   (remove-hook hook function t))
360
361 (defun add-one-shot-hook (hook function &optional append local)
362   "Add to the value of HOOK the one-shot function FUNCTION.
363 FUNCTION will automatically be removed from the hook the first time
364 after it runs (whether to completion or to an error).
365 FUNCTION is not added if already present.
366 FUNCTION is added (if necessary) at the beginning of the hook list
367 unless the optional argument APPEND is non-nil, in which case
368 FUNCTION is added at the end.
369
370 HOOK should be a symbol, and FUNCTION may be any valid function.  If
371 HOOK is void, it is first set to nil.  If HOOK's value is a single
372 function, it is changed to a list of functions.
373
374 You can remove this hook yourself using `remove-hook'.
375
376 See also `add-hook'."
377   (let ((sym (gensym)))
378     (fset sym `(lambda (&rest args)
379                  (unwind-protect
380                      (apply ',function args)
381                    (remove-hook ',hook ',sym ',local))))
382     (put sym 'one-shot-hook-fun function)
383     (add-hook hook sym append local)))
384
385 (defun add-local-one-shot-hook (hook function &optional append)
386   "Add to the local value of HOOK the one-shot function FUNCTION.
387 You don't need this any more.  It's equivalent to specifying the LOCAL
388 argument to `add-one-shot-hook'."
389   (add-one-shot-hook hook function append t))
390
391
392 (defun add-hook-list (function  hook-list &optional append &optional local)
393   "FUNCTION is not added if already present.
394 FUNCTION is added (if necessary) at the beginning of the hook list
395 unless the optional argument APPEND is non-nil, in which case
396 FUNCTION is added at the end.
397
398 The optional fourth argument, LOCAL, if non-nil, says to modify
399 the hook's buffer-local value rather than its default value.
400 This makes the hook buffer-local if needed.
401 To make a hook variable buffer-local, always use
402 `make-local-hook', not `make-local-variable'.
403
404 HOOK-LIST should be a list of symbols, and FUNCTION may be any valid
405 function.  If HOOK is void, it is first set to nil.  If HOOK's value
406 is a single function, it is changed to a list of functions.
407
408 You can remove this hook yourself using `remove-hook-list'.
409
410 See also `add-hook`, `remove-hook` and `add-one-shot-hook'."
411   (mapc (lambda (hook)
412           (add-hook hook function append local))
413         hook-list))
414
415 (defun remove-hook-list (function  hook-list &optional local)
416   "Remove from the value of all members of HOOK-LIST the function FUNCTION.
417 HOOK-LIST should be a list of symbols, and FUNCTION may be any valid
418 function.  If FUNCTION isn't the value of the member of HOOK-LIST, or,
419 if FUNCTION doesn't appear in the list of hooks to run in HOOK, then
420 nothing is done.  See `add-hook-list` and `add-hook'.
421
422 The optional third argument, LOCAL, if non-nil, says to modify
423 the hook's buffer-local value rather than its default value.
424 This makes the hook buffer-local if needed.
425 To make a hook variable buffer-local, always use
426 `make-local-hook', not `make-local-variable'."
427   (mapc (lambda (hook)
428           (remove-hook hook function local))
429         hook-list))
430
431
432 (defun add-to-list (list-var element &optional append)
433   "Add to the value of LIST-VAR the element ELEMENT if it isn't there yet.
434 The test for presence of ELEMENT is done with `equal'.
435 If ELEMENT is added, it is added at the beginning of the list,
436 unless the optional argument APPEND is non-nil, in which case
437 ELEMENT is added at the end.
438
439 If you want to use `add-to-list' on a variable that is not defined
440 until a certain package is loaded, you should put the call to `add-to-list'
441 into a hook function that will be run only after loading the package.
442 `eval-after-load' provides one way to do this.  In some cases
443 other hooks, such as major mode hooks, can do the job."
444   (if (member element (symbol-value list-var))
445       (symbol-value list-var)
446     (set list-var
447          (if append
448              (append (symbol-value list-var) (list element))
449            (cons element (symbol-value list-var))))))
450
451 ;; END SYNCHED WITH FSF 21.2
452
453 ;; XEmacs additions
454
455 (defun add-to-list* (list-var element &optional append)
456     "Add to the value of LIST-VAR the element ELEMENT if it isn't there yet.
457 The test for presence of ELEMENT is done with `equal'.
458 If ELEMENT is added, it is added at the beginning of the list,
459 unless the optional argument APPEND is non-nil, in which case
460 ELEMENT is added at the end.
461
462 If LIST-VAR is not defined as a variable yet, it will set it to a list
463 of just the element.
464
465 If you want to use `add-to-list*' on a variable that is not defined
466 until a certain package is loaded, you should put the call to `add-to-list*'
467 into a hook function that will be run only after loading the package.
468 `eval-after-load' provides one way to do this.  In some cases
469 other hooks, such as major mode hooks, can do the job."
470     (if (boundp list-var)
471         (add-to-list list-var element append)
472       (set list-var (list element))))
473
474 ;; called by Fkill_buffer()
475 (defvar kill-buffer-hook nil
476   "Function or functions to be called when a buffer is killed.
477 The value of this variable may be buffer-local.
478 The buffer about to be killed is current when this hook is run.")
479
480 ;; in C in FSFmacs
481 (defvar kill-emacs-hook nil
482   "Function or functions to be called when `kill-emacs' is called,
483 just before emacs is actually killed.")
484
485 ;; not obsolete.
486 ;; #### These are a bad idea, because the CL RPLACA and RPLACD
487 ;; return the cons cell, not the new CAR/CDR.         -hniksic
488 ;; The proper definition would be:
489 ;; (defun rplaca (conscell newcar)
490 ;;   (setcar conscell newcar)
491 ;;   conscell)
492 ;; ...and analogously for RPLACD.
493 (define-function 'rplaca 'setcar)
494 (define-function 'rplacd 'setcdr)
495
496 (defun copy-symbol (symbol &optional copy-properties)
497   "Return a new uninterned symbol with the same name as SYMBOL.
498 If COPY-PROPERTIES is non-nil, the new symbol will have a copy of
499 SYMBOL's value, function, and property lists."
500   (let ((new (make-symbol (symbol-name symbol))))
501     (when copy-properties
502       ;; This will not copy SYMBOL's chain of forwarding objects, but
503       ;; I think that's OK.  Callers should not expect such magic to
504       ;; keep working in the copy in the first place.
505       (and (boundp symbol)
506            (set new (symbol-value symbol)))
507       (and (fboundp symbol)
508            (fset new (symbol-function symbol)))
509       (setplist new (copy-list (symbol-plist symbol))))
510     new))
511
512 (defun set-symbol-value-in-buffer (sym val buffer)
513   "Set the value of SYM to VAL in BUFFER.  Useful with buffer-local variables.
514 If SYM has a buffer-local value in BUFFER, or will have one if set, this
515 function allows you to set the local value.
516
517 NOTE: At some point, this will be moved into C and will be very fast."
518   (with-current-buffer buffer
519     (set sym val)))
520
521 \f
522 ;; BEGIN SYNCHED WITH FSF 21.2
523
524 ;; #### #### #### AAaargh!  Must be in C, because it is used insanely
525 ;; early in the bootstrap process.
526 ;(defun split-path (path)
527 ;  "Explode a search path into a list of strings.
528 ;The path components are separated with the characters specified
529 ;with `path-separator'."
530 ;  (while (or (not stringp path-separator)
531 ;            (/= (length path-separator) 1))
532 ;    (setq path-separator (signal 'error (list "\
533 ;`path-separator' should be set to a single-character string"
534 ;                                             path-separator))))
535 ;  (split-string-by-char path (aref separator 0)))
536
537 (defmacro with-current-buffer (buffer &rest body)
538   "Temporarily make BUFFER the current buffer and execute the forms in BODY.
539 The value returned is the value of the last form in BODY.
540 See also `with-temp-buffer'."
541   `(save-current-buffer
542     (set-buffer ,buffer)
543     ,@body))
544
545 (defmacro with-temp-file (filename &rest forms)
546   "Create a new buffer, evaluate FORMS there, and write the buffer to FILENAME.
547 The value of the last form in FORMS is returned, like `progn'.
548 See also `with-temp-buffer'."
549   (let ((temp-file (make-symbol "temp-file"))
550         (temp-buffer (make-symbol "temp-buffer")))
551     `(let ((,temp-file ,filename)
552            (,temp-buffer
553             (get-buffer-create (generate-new-buffer-name " *temp file*"))))
554        (unwind-protect
555            (prog1
556                (with-current-buffer ,temp-buffer
557                  ,@forms)
558              (with-current-buffer ,temp-buffer
559                (widen)
560                (write-region (point-min) (point-max) ,temp-file nil 0)))
561          (and (buffer-name ,temp-buffer)
562               (kill-buffer ,temp-buffer))))))
563
564 ;; FSF compatibility
565 (defmacro with-temp-message (message &rest body)
566   "Display MESSAGE temporarily while BODY is evaluated.
567 The original message is restored to the echo area after BODY has finished.
568 The value returned is the value of the last form in BODY.
569 If MESSAGE is nil, the echo area and message log buffer are unchanged.
570 Use a MESSAGE of \"\" to temporarily clear the echo area.
571
572 Note that this function exists for FSF compatibility purposes.  A better way
573 under XEmacs is to give the message a particular label (see `display-message');
574 then, the old message is automatically restored when you clear your message
575 with `clear-message'."
576 ;; FSF additional doc string from 21.2:
577 ;; MESSAGE is written to the message log buffer if `message-log-max' is non-nil.
578   (let ((current-message (make-symbol "current-message"))
579         (temp-message (make-symbol "with-temp-message")))
580     `(let ((,temp-message ,message)
581            (,current-message))
582        (unwind-protect
583            (progn
584              (when ,temp-message
585                (setq ,current-message (current-message))
586                (message "%s" ,temp-message))
587              ,@body)
588          (and ,temp-message ,current-message
589               (message "%s" ,current-message))))))
590
591 (defmacro with-temp-buffer (&rest forms)
592   "Create a temporary buffer, and evaluate FORMS there like `progn'.
593 See also `with-temp-file' and `with-output-to-string'."
594   (let ((temp-buffer (make-symbol "temp-buffer")))
595     `(let ((,temp-buffer
596             (get-buffer-create (generate-new-buffer-name " *temp*"))))
597        (unwind-protect
598            (with-current-buffer ,temp-buffer
599              ,@forms)
600          (and (buffer-name ,temp-buffer)
601               (kill-buffer ,temp-buffer))))))
602
603 (defmacro with-output-to-string (&rest body)
604   "Execute BODY, return the text it sent to `standard-output', as a string."
605   `(let ((standard-output
606           (get-buffer-create (generate-new-buffer-name " *string-output*"))))
607      (let ((standard-output standard-output))
608        ,@body)
609      (with-current-buffer standard-output
610        (prog1
611            (buffer-string)
612          (kill-buffer nil)))))
613
614 (defmacro with-local-quit (&rest body)
615   "Execute BODY with `inhibit-quit' temporarily bound to nil."
616   `(condition-case nil
617        (let ((inhibit-quit nil))
618          ,@body)
619      (quit (setq quit-flag t))))
620
621 ;; FSF 21.3.
622
623 ; (defmacro combine-after-change-calls (&rest body)
624 ;   "Execute BODY, but don't call the after-change functions till the end.
625 ; If BODY makes changes in the buffer, they are recorded
626 ; and the functions on `after-change-functions' are called several times
627 ; when BODY is finished.
628 ; The return value is the value of the last form in BODY.
629
630 ; If `before-change-functions' is non-nil, then calls to the after-change
631 ; functions can't be deferred, so in that case this macro has no effect.
632
633 ; Do not alter `after-change-functions' or `before-change-functions'
634 ; in BODY."
635 ;   (declare (indent 0) (debug t))
636 ;   `(unwind-protect
637 ;        (let ((combine-after-change-calls t))
638 ;        . ,body)
639 ;      (combine-after-change-execute)))
640
641
642 (defvar delay-mode-hooks nil
643   "If non-nil, `run-mode-hooks' should delay running the hooks.")
644 (defvar delayed-mode-hooks nil
645   "List of delayed mode hooks waiting to be run.")
646 (make-variable-buffer-local 'delayed-mode-hooks)
647 (put 'delay-mode-hooks 'permanent-local t)
648
649 (defun run-mode-hooks (&rest hooks)
650   "Run mode hooks `delayed-mode-hooks' and HOOKS, or delay HOOKS.
651 Execution is delayed if `delay-mode-hooks' is non-nil.
652 Major mode functions should use this."
653   (if delay-mode-hooks
654       ;; Delaying case.
655       (dolist (hook hooks)
656         (push hook delayed-mode-hooks))
657     ;; Normal case, just run the hook as before plus any delayed hooks.
658     (setq hooks (nconc (nreverse delayed-mode-hooks) hooks))
659     (setq delayed-mode-hooks nil)
660     (apply 'run-hooks hooks)))
661
662 (defmacro delay-mode-hooks (&rest body)
663   "Execute BODY, but delay any `run-mode-hooks'.
664 Only affects hooks run in the current buffer."
665   `(progn
666      (make-local-variable 'delay-mode-hooks)
667      (let ((delay-mode-hooks t))
668        ,@body)))
669
670 (defmacro with-syntax-table (table &rest body)
671   "Evaluate BODY with syntax table of current buffer set to a copy of TABLE.
672 The syntax table of the current buffer is saved, BODY is evaluated, and the
673 saved table is restored, even in case of an abnormal exit.
674 Value is what BODY returns."
675   (let ((old-table (make-symbol "table"))
676         (old-buffer (make-symbol "buffer")))
677     `(let ((,old-table (syntax-table))
678            (,old-buffer (current-buffer)))
679        (unwind-protect
680            (progn
681              (set-syntax-table (copy-syntax-table ,table))
682              ,@body)
683          (save-current-buffer
684            (set-buffer ,old-buffer)
685            (set-syntax-table ,old-table))))))
686
687 (put 'with-syntax-table 'lisp-indent-function 1)
688 (put 'with-syntax-table 'edebug-form-spec '(form body))
689
690
691 ;; Moved from mule-coding.el.
692 (defmacro with-string-as-buffer-contents (str &rest body)
693   "With the contents of the current buffer being STR, run BODY.
694 Returns the new contents of the buffer, as modified by BODY.
695 The original current buffer is restored afterwards."
696   `(with-temp-buffer
697      (insert ,str)
698      ,@body
699      (buffer-string)))
700
701 \f
702 (defmacro save-match-data (&rest body)
703   "Execute BODY forms, restoring the global value of the match data."
704   (let ((original (make-symbol "match-data")))
705     (list 'let (list (list original '(match-data)))
706           (list 'unwind-protect
707                 (cons 'progn body)
708                 (list 'store-match-data original)))))
709
710
711 (defun match-string (num &optional string)
712   "Return string of text matched by last search.
713 NUM specifies which parenthesized expression in the last regexp.
714  Value is nil if NUMth pair didn't match, or there were less than NUM pairs.
715 Zero means the entire text matched by the whole regexp or whole string.
716 STRING should be given if the last search was by `string-match' on STRING."
717   (if (match-beginning num)
718       (if string
719           (substring string (match-beginning num) (match-end num))
720         (buffer-substring (match-beginning num) (match-end num)))))
721
722 (defun match-string-no-properties (num &optional string)
723   "Return string of text matched by last search, without text properties.
724 NUM specifies which parenthesized expression in the last regexp.
725  Value is nil if NUMth pair didn't match, or there were less than NUM pairs.
726 Zero means the entire text matched by the whole regexp or whole string.
727 STRING should be given if the last search was by `string-match' on STRING."
728   (if (match-beginning num)
729       (if string
730           (let ((result
731                  (substring string (match-beginning num) (match-end num))))
732             (set-text-properties 0 (length result) nil result)
733             result)
734         (buffer-substring-no-properties (match-beginning num)
735                                         (match-end num)))))
736
737 (defconst split-string-default-separators "[ \f\t\n\r\v]+"
738   "The default value of separators for `split-string'.
739
740 A regexp matching strings of whitespace.  May be locale-dependent
741 \(as yet unimplemented).  Should not match non-breaking spaces.
742
743 Warning: binding this to a different value and using it as default is
744 likely to have undesired semantics.")
745
746 ;; specification for `split-string' agreed with rms 2003-04-23
747 ;; xemacs design <87vfx5vor0.fsf@tleepslib.sk.tsukuba.ac.jp>
748
749 ;; The specification says that if both SEPARATORS and OMIT-NULLS are
750 ;; defaulted, OMIT-NULLS should be treated as t.  Simplifying the logical
751 ;; expression leads to the equivalent implementation that if SEPARATORS
752 ;; is defaulted, OMIT-NULLS is treated as t.
753
754 (defun split-string (string &optional separators omit-nulls)
755   "Splits STRING into substrings bounded by matches for SEPARATORS.
756
757 The beginning and end of STRING, and each match for SEPARATORS, are
758 splitting points.  The substrings matching SEPARATORS are removed, and
759 the substrings between the splitting points are collected as a list,
760 which is returned.
761
762 If SEPARATORS is non-`nil', it should be a regular expression matching text
763 which separates, but is not part of, the substrings.  If `nil' it defaults to
764 `split-string-default-separators', normally \"[ \\f\\t\\n\\r\\v]+\", and
765 OMIT-NULLS is forced to `t'.
766
767 If OMIT-NULLS is `t', zero-length substrings are omitted from the list \(so
768 that for the default value of SEPARATORS leading and trailing whitespace
769 are effectively trimmed).  If `nil', all zero-length substrings are retained,
770 which correctly parses CSV format, for example.
771
772 Note that the effect of `(split-string STRING)' is the same as
773 `(split-string STRING split-string-default-separators t)').  In the rare
774 case that you wish to retain zero-length substrings when splitting on
775 whitespace, use `(split-string STRING split-string-default-separators nil)'.
776
777 Modifies the match data when successful; use `save-match-data' if necessary."
778