(scan_sexps_forward): Fix previous change.
[bpt/emacs.git] / lisp / subr.el
CommitLineData
c88ab9ce 1;;; subr.el --- basic lisp subroutines for Emacs
630cc463 2
cd323f89 3;;; Copyright (C) 1985, 1986, 1992, 1994, 1995 Free Software Foundation, Inc.
be9b65ac
DL
4
5;; This file is part of GNU Emacs.
6
7;; GNU Emacs is free software; you can redistribute it and/or modify
8;; it under the terms of the GNU General Public License as published by
492878e4 9;; the Free Software Foundation; either version 2, or (at your option)
be9b65ac
DL
10;; any later version.
11
12;; GNU Emacs is distributed in the hope that it will be useful,
13;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15;; GNU General Public License for more details.
16
17;; You should have received a copy of the GNU General Public License
18;; along with GNU Emacs; see the file COPYING. If not, write to
19;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
20
630cc463 21;;; Code:
be9b65ac 22
9a5336ae
JB
23\f
24;;;; Lisp language features.
25
26(defmacro lambda (&rest cdr)
27 "Return a lambda expression.
28A call of the form (lambda ARGS DOCSTRING INTERACTIVE BODY) is
29self-quoting; the result of evaluating the lambda expression is the
30expression itself. The lambda expression may then be treated as a
bec0d7f9
RS
31function, i.e., stored as the function value of a symbol, passed to
32funcall or mapcar, etc.
33
9a5336ae 34ARGS should take the same form as an argument list for a `defun'.
8fd68088
RS
35DOCSTRING is an optional documentation string.
36 If present, it should describe how to call the function.
37 But documentation strings are usually not useful in nameless functions.
9a5336ae
JB
38INTERACTIVE should be a call to the function `interactive', which see.
39It may also be omitted.
40BODY should be a list of lisp expressions."
41 ;; Note that this definition should not use backquotes; subr.el should not
42 ;; depend on backquote.el.
43 (list 'function (cons 'lambda cdr)))
44
45;;(defmacro defun-inline (name args &rest body)
46;; "Create an \"inline defun\" (actually a macro).
47;;Use just like `defun'."
48;; (nconc (list 'defmacro name '(&rest args))
49;; (if (stringp (car body))
50;; (prog1 (list (car body))
51;; (setq body (or (cdr body) body))))
52;; (list (list 'cons (list 'quote
53;; (cons 'lambda (cons args body)))
54;; 'args))))
55
56\f
9a5336ae 57;;;; Keymap support.
be9b65ac
DL
58
59(defun undefined ()
60 (interactive)
61 (ding))
62
63;Prevent the \{...} documentation construct
64;from mentioning keys that run this command.
65(put 'undefined 'suppress-keymap t)
66
67(defun suppress-keymap (map &optional nodigits)
68 "Make MAP override all normally self-inserting keys to be undefined.
69Normally, as an exception, digits and minus-sign are set to make prefix args,
70but optional second arg NODIGITS non-nil treats them like other chars."
80e7b471 71 (substitute-key-definition 'self-insert-command 'undefined map global-map)
be9b65ac
DL
72 (or nodigits
73 (let (loop)
74 (define-key map "-" 'negative-argument)
75 ;; Make plain numbers do numeric args.
76 (setq loop ?0)
77 (while (<= loop ?9)
78 (define-key map (char-to-string loop) 'digit-argument)
79 (setq loop (1+ loop))))))
80
be9b65ac
DL
81;Moved to keymap.c
82;(defun copy-keymap (keymap)
83; "Return a copy of KEYMAP"
84; (while (not (keymapp keymap))
85; (setq keymap (signal 'wrong-type-argument (list 'keymapp keymap))))
86; (if (vectorp keymap)
87; (copy-sequence keymap)
88; (copy-alist keymap)))
89
f14dbba7
KH
90(defvar key-substitution-in-progress nil
91 "Used internally by substitute-key-definition.")
92
7f2c2edd 93(defun substitute-key-definition (olddef newdef keymap &optional oldmap prefix)
be9b65ac
DL
94 "Replace OLDDEF with NEWDEF for any keys in KEYMAP now defined as OLDDEF.
95In other words, OLDDEF is replaced with NEWDEF where ever it appears.
7f2c2edd
RS
96If optional fourth argument OLDMAP is specified, we redefine
97in KEYMAP as NEWDEF those chars which are defined as OLDDEF in OLDMAP."
98 (or prefix (setq prefix ""))
99 (let* ((scan (or oldmap keymap))
100 (vec1 (vector nil))
f14dbba7
KH
101 (prefix1 (vconcat prefix vec1))
102 (key-substitution-in-progress
103 (cons scan key-substitution-in-progress)))
7f2c2edd
RS
104 ;; Scan OLDMAP, finding each char or event-symbol that
105 ;; has any definition, and act on it with hack-key.
106 (while (consp scan)
107 (if (consp (car scan))
108 (let ((char (car (car scan)))
109 (defn (cdr (car scan))))
110 ;; The inside of this let duplicates exactly
111 ;; the inside of the following let that handles array elements.
112 (aset vec1 0 char)
113 (aset prefix1 (length prefix) char)
44d798af 114 (let (inner-def skipped)
7f2c2edd
RS
115 ;; Skip past menu-prompt.
116 (while (stringp (car-safe defn))
44d798af 117 (setq skipped (cons (car defn) skipped))
7f2c2edd 118 (setq defn (cdr defn)))
e025dddf
RS
119 ;; Skip past cached key-equivalence data for menu items.
120 (and (consp defn) (consp (car defn))
121 (setq defn (cdr defn)))
7f2c2edd 122 (setq inner-def defn)
e025dddf 123 ;; Look past a symbol that names a keymap.
7f2c2edd
RS
124 (while (and (symbolp inner-def)
125 (fboundp inner-def))
126 (setq inner-def (symbol-function inner-def)))
127 (if (eq defn olddef)
44d798af 128 (define-key keymap prefix1 (nconc (nreverse skipped) newdef))
f14dbba7 129 (if (and (keymapp defn)
350b7567
RS
130 ;; Avoid recursively scanning
131 ;; where KEYMAP does not have a submap.
132 (keymapp (lookup-key keymap prefix1))
133 ;; Avoid recursively rescanning keymap being scanned.
f14dbba7
KH
134 (not (memq inner-def
135 key-substitution-in-progress)))
e025dddf
RS
136 ;; If this one isn't being scanned already,
137 ;; scan it now.
7f2c2edd
RS
138 (substitute-key-definition olddef newdef keymap
139 inner-def
140 prefix1)))))
141 (if (arrayp (car scan))
142 (let* ((array (car scan))
143 (len (length array))
144 (i 0))
145 (while (< i len)
146 (let ((char i) (defn (aref array i)))
147 ;; The inside of this let duplicates exactly
148 ;; the inside of the previous let.
149 (aset vec1 0 char)
150 (aset prefix1 (length prefix) char)
44d798af 151 (let (inner-def skipped)
7f2c2edd
RS
152 ;; Skip past menu-prompt.
153 (while (stringp (car-safe defn))
44d798af 154 (setq skipped (cons (car defn) skipped))
7f2c2edd 155 (setq defn (cdr defn)))
e025dddf
RS
156 (and (consp defn) (consp (car defn))
157 (setq defn (cdr defn)))
7f2c2edd
RS
158 (setq inner-def defn)
159 (while (and (symbolp inner-def)
160 (fboundp inner-def))
161 (setq inner-def (symbol-function inner-def)))
162 (if (eq defn olddef)
44d798af
RS
163 (define-key keymap prefix1
164 (nconc (nreverse skipped) newdef))
f14dbba7 165 (if (and (keymapp defn)
350b7567 166 (keymapp (lookup-key keymap prefix1))
f14dbba7
KH
167 (not (memq inner-def
168 key-substitution-in-progress)))
7f2c2edd
RS
169 (substitute-key-definition olddef newdef keymap
170 inner-def
171 prefix1)))))
172 (setq i (1+ i))))))
173 (setq scan (cdr scan)))))
9a5336ae 174
06ae9cf2 175(defun define-key-after (keymap key definition after)
4434d61b
RS
176 "Add binding in KEYMAP for KEY => DEFINITION, right after AFTER's binding.
177This is like `define-key' except that the binding for KEY is placed
178just after the binding for the event AFTER, instead of at the beginning
179of the map.
626f67f3 180The order matters when the keymap is used as a menu.
9ed287b0
RS
181KEY must contain just one event type--that is to say, it must be
182a string or vector of length 1."
4434d61b
RS
183 (or (keymapp keymap)
184 (signal 'wrong-type-argument (list 'keymapp keymap)))
ab375e6c 185 (if (> (length key) 1)
626f67f3 186 (error "multi-event key specified in `define-key-after'"))
113d28a8 187 (let ((tail keymap) done inserted
4434d61b
RS
188 (first (aref key 0)))
189 (while (and (not done) tail)
190 ;; Delete any earlier bindings for the same key.
191 (if (eq (car-safe (car (cdr tail))) first)
192 (setcdr tail (cdr (cdr tail))))
193 ;; When we reach AFTER's binding, insert the new binding after.
194 ;; If we reach an inherited keymap, insert just before that.
113d28a8 195 ;; If we reach the end of this keymap, insert at the end.
4434d61b 196 (if (or (eq (car-safe (car tail)) after)
113d28a8
RS
197 (eq (car (cdr tail)) 'keymap)
198 (null (cdr tail)))
4434d61b 199 (progn
113d28a8
RS
200 ;; Stop the scan only if we find a parent keymap.
201 ;; Keep going past the inserted element
202 ;; so we can delete any duplications that come later.
203 (if (eq (car (cdr tail)) 'keymap)
204 (setq done t))
205 ;; Don't insert more than once.
206 (or inserted
207 (setcdr tail (cons (cons (aref key 0) definition) (cdr tail))))
208 (setq inserted t)))
4434d61b
RS
209 (setq tail (cdr tail)))))
210
9a5336ae
JB
211(defun keyboard-translate (from to)
212 "Translate character FROM to TO at a low level.
213This function creates a `keyboard-translate-table' if necessary
214and then modifies one entry in it."
215 (or (arrayp keyboard-translate-table)
216 (setq keyboard-translate-table ""))
217 (if (or (> from (length keyboard-translate-table))
218 (> to (length keyboard-translate-table)))
219 (progn
220 (let* ((i (length keyboard-translate-table))
f4ebbdbe
RS
221 (table (concat keyboard-translate-table
222 (make-string (- 256 i) 0))))
9a5336ae
JB
223 (while (< i 256)
224 (aset table i i)
225 (setq i (1+ i)))
226 (setq keyboard-translate-table table))))
227 (aset keyboard-translate-table from to))
228
229\f
230;;;; The global keymap tree.
231
232;;; global-map, esc-map, and ctl-x-map have their values set up in
233;;; keymap.c; we just give them docstrings here.
234
235(defvar global-map nil
236 "Default global keymap mapping Emacs keyboard input into commands.
237The value is a keymap which is usually (but not necessarily) Emacs's
238global map.")
239
240(defvar esc-map nil
241 "Default keymap for ESC (meta) commands.
242The normal global definition of the character ESC indirects to this keymap.")
243
244(defvar ctl-x-map nil
245 "Default keymap for C-x commands.
246The normal global definition of the character C-x indirects to this keymap.")
247
248(defvar ctl-x-4-map (make-sparse-keymap)
249 "Keymap for subcommands of C-x 4")
059184dd 250(defalias 'ctl-x-4-prefix ctl-x-4-map)
9a5336ae
JB
251(define-key ctl-x-map "4" 'ctl-x-4-prefix)
252
253(defvar ctl-x-5-map (make-sparse-keymap)
254 "Keymap for frame commands.")
059184dd 255(defalias 'ctl-x-5-prefix ctl-x-5-map)
9a5336ae
JB
256(define-key ctl-x-map "5" 'ctl-x-5-prefix)
257
0f03054a 258\f
9a5336ae
JB
259;;;; Event manipulation functions.
260
da16e648
KH
261;; The call to `read' is to ensure that the value is computed at load time
262;; and not compiled into the .elc file. The value is negative on most
263;; machines, but not on all!
264(defconst listify-key-sequence-1 (logior 128 (read "?\\M-\\^@")))
114137b8 265
cde6d7e3
RS
266(defun listify-key-sequence (key)
267 "Convert a key sequence to a list of events."
268 (if (vectorp key)
269 (append key nil)
270 (mapcar (function (lambda (c)
271 (if (> c 127)
114137b8 272 (logxor c listify-key-sequence-1)
cde6d7e3
RS
273 c)))
274 (append key nil))))
275
53e5a4e8
RS
276(defsubst eventp (obj)
277 "True if the argument is an event object."
278 (or (integerp obj)
279 (and (symbolp obj)
280 (get obj 'event-symbol-elements))
281 (and (consp obj)
282 (symbolp (car obj))
283 (get (car obj) 'event-symbol-elements))))
284
285(defun event-modifiers (event)
286 "Returns a list of symbols representing the modifier keys in event EVENT.
287The elements of the list may include `meta', `control',
32295976
RS
288`shift', `hyper', `super', `alt', `click', `double', `triple', `drag',
289and `down'."
53e5a4e8
RS
290 (let ((type event))
291 (if (listp type)
292 (setq type (car type)))
293 (if (symbolp type)
294 (cdr (get type 'event-symbol-elements))
295 (let ((list nil))
da16e648 296 (or (zerop (logand type ?\M-\^@))
53e5a4e8 297 (setq list (cons 'meta list)))
da16e648 298 (or (and (zerop (logand type ?\C-\^@))
53e5a4e8
RS
299 (>= (logand type 127) 32))
300 (setq list (cons 'control list)))
da16e648 301 (or (and (zerop (logand type ?\S-\^@))
53e5a4e8
RS
302 (= (logand type 255) (downcase (logand type 255))))
303 (setq list (cons 'shift list)))
da16e648 304 (or (zerop (logand type ?\H-\^@))
53e5a4e8 305 (setq list (cons 'hyper list)))
da16e648 306 (or (zerop (logand type ?\s-\^@))
53e5a4e8 307 (setq list (cons 'super list)))
da16e648 308 (or (zerop (logand type ?\A-\^@))
53e5a4e8
RS
309 (setq list (cons 'alt list)))
310 list))))
311
d63de416
RS
312(defun event-basic-type (event)
313 "Returns the basic type of the given event (all modifiers removed).
314The value is an ASCII printing character (not upper case) or a symbol."
2b0f4ba5
JB
315 (if (consp event)
316 (setq event (car event)))
d63de416
RS
317 (if (symbolp event)
318 (car (get event 'event-symbol-elements))
319 (let ((base (logand event (1- (lsh 1 18)))))
320 (downcase (if (< base 32) (logior base 64) base)))))
321
0f03054a
RS
322(defsubst mouse-movement-p (object)
323 "Return non-nil if OBJECT is a mouse movement event."
324 (and (consp object)
325 (eq (car object) 'mouse-movement)))
326
327(defsubst event-start (event)
328 "Return the starting position of EVENT.
329If EVENT is a mouse press or a mouse click, this returns the location
330of the event.
331If EVENT is a drag, this returns the drag's starting position.
332The return value is of the form
e55c21be 333 (WINDOW BUFFER-POSITION (X . Y) TIMESTAMP)
0f03054a
RS
334The `posn-' functions access elements of such lists."
335 (nth 1 event))
336
337(defsubst event-end (event)
338 "Return the ending location of EVENT. EVENT should be a click or drag event.
339If EVENT is a click event, this function is the same as `event-start'.
340The return value is of the form
e55c21be 341 (WINDOW BUFFER-POSITION (X . Y) TIMESTAMP)
0f03054a 342The `posn-' functions access elements of such lists."
69b95560 343 (nth (if (consp (nth 2 event)) 2 1) event))
0f03054a 344
32295976
RS
345(defsubst event-click-count (event)
346 "Return the multi-click count of EVENT, a click or drag event.
347The return value is a positive integer."
348 (if (integerp (nth 2 event)) (nth 2 event) 1))
349
0f03054a
RS
350(defsubst posn-window (position)
351 "Return the window in POSITION.
352POSITION should be a list of the form
e55c21be 353 (WINDOW BUFFER-POSITION (X . Y) TIMESTAMP)
0f03054a
RS
354as returned by the `event-start' and `event-end' functions."
355 (nth 0 position))
356
357(defsubst posn-point (position)
358 "Return the buffer location in POSITION.
359POSITION should be a list of the form
e55c21be 360 (WINDOW BUFFER-POSITION (X . Y) TIMESTAMP)
0f03054a 361as returned by the `event-start' and `event-end' functions."
15db4e0e
JB
362 (if (consp (nth 1 position))
363 (car (nth 1 position))
364 (nth 1 position)))
0f03054a 365
e55c21be
RS
366(defsubst posn-x-y (position)
367 "Return the x and y coordinates in POSITION.
0f03054a 368POSITION should be a list of the form
e55c21be 369 (WINDOW BUFFER-POSITION (X . Y) TIMESTAMP)
0f03054a
RS
370as returned by the `event-start' and `event-end' functions."
371 (nth 2 position))
372
ed627e08 373(defun posn-col-row (position)
dbbcac56 374 "Return the column and row in POSITION, measured in characters.
e55c21be
RS
375POSITION should be a list of the form
376 (WINDOW BUFFER-POSITION (X . Y) TIMESTAMP)
ed627e08
RS
377as returned by the `event-start' and `event-end' functions.
378For a scroll-bar event, the result column is 0, and the row
379corresponds to the vertical position of the click in the scroll bar."
380 (let ((pair (nth 2 position))
381 (window (posn-window position)))
dbbcac56
KH
382 (if (eq (if (consp (nth 1 position))
383 (car (nth 1 position))
384 (nth 1 position))
ed627e08
RS
385 'vertical-scroll-bar)
386 (cons 0 (scroll-bar-scale pair (1- (window-height window))))
dbbcac56
KH
387 (if (eq (if (consp (nth 1 position))
388 (car (nth 1 position))
389 (nth 1 position))
ed627e08
RS
390 'horizontal-scroll-bar)
391 (cons (scroll-bar-scale pair (window-width window)) 0)
9ba60df9
RS
392 (let* ((frame (if (framep window) window (window-frame window)))
393 (x (/ (car pair) (frame-char-width frame)))
394 (y (/ (cdr pair) (frame-char-height frame))))
ed627e08 395 (cons x y))))))
e55c21be 396
0f03054a
RS
397(defsubst posn-timestamp (position)
398 "Return the timestamp of POSITION.
399POSITION should be a list of the form
e55c21be 400 (WINDOW BUFFER-POSITION (X . Y) TIMESTAMP)
f415c00c 401as returned by the `event-start' and `event-end' functions."
0f03054a 402 (nth 3 position))
9a5336ae 403
0f03054a 404\f
9a5336ae
JB
405;;;; Obsolescent names for functions.
406
059184dd
ER
407(defalias 'dot 'point)
408(defalias 'dot-marker 'point-marker)
409(defalias 'dot-min 'point-min)
410(defalias 'dot-max 'point-max)
411(defalias 'window-dot 'window-point)
412(defalias 'set-window-dot 'set-window-point)
413(defalias 'read-input 'read-string)
414(defalias 'send-string 'process-send-string)
415(defalias 'send-region 'process-send-region)
416(defalias 'show-buffer 'set-window-buffer)
417(defalias 'buffer-flush-undo 'buffer-disable-undo)
418(defalias 'eval-current-buffer 'eval-buffer)
419(defalias 'compiled-function-p 'byte-code-function-p)
be9b65ac 420
9a5336ae
JB
421;; Some programs still use this as a function.
422(defun baud-rate ()
bcacc42c
RS
423 "Obsolete function returning the value of the `baud-rate' variable.
424Please convert your programs to use the variable `baud-rate' directly."
9a5336ae
JB
425 baud-rate)
426
427\f
428;;;; Alternate names for functions - these are not being phased out.
429
059184dd
ER
430(defalias 'string= 'string-equal)
431(defalias 'string< 'string-lessp)
432(defalias 'move-marker 'set-marker)
433(defalias 'eql 'eq)
434(defalias 'not 'null)
435(defalias 'rplaca 'setcar)
436(defalias 'rplacd 'setcdr)
eb8c3be9 437(defalias 'beep 'ding) ;preserve lingual purity
059184dd
ER
438(defalias 'indent-to-column 'indent-to)
439(defalias 'backward-delete-char 'delete-backward-char)
440(defalias 'search-forward-regexp (symbol-function 're-search-forward))
441(defalias 'search-backward-regexp (symbol-function 're-search-backward))
442(defalias 'int-to-string 'number-to-string)
1e0a78a1 443(defalias 'set-match-data 'store-match-data)
37f6661a
JB
444
445;;; Should this be an obsolete name? If you decide it should, you get
446;;; to go through all the sources and change them.
059184dd 447(defalias 'string-to-int 'string-to-number)
be9b65ac 448\f
9a5336ae 449;;;; Hook manipulation functions.
be9b65ac 450
ba1cc309
SM
451;; We used to have this variable so that C code knew how to run hooks. That
452;; calling convention is made obsolete now the hook running functions are in C.
be9b65ac
DL
453(defconst run-hooks 'run-hooks
454 "Variable by which C primitives find the function `run-hooks'.
ba1cc309 455Don't change it. Don't use it either; use the hook running C primitives.")
be9b65ac 456
0e4d378b
RS
457(defun make-local-hook (hook)
458 "Make the hook HOOK local to the current buffer.
459When a hook is local, its local and global values
460work in concert: running the hook actually runs all the hook
461functions listed in *either* the local value *or* the global value
462of the hook variable.
463
7dd1926e
RS
464This function works by making `t' a member of the buffer-local value,
465which acts as a flag to run the hook functions in the default value as
466well. This works for all normal hooks, but does not work for most
467non-normal hooks yet. We will be changing the callers of non-normal
468hooks so that they can handle localness; this has to be done one by
469one.
470
471This function does nothing if HOOK is already local in the current
472buffer.
0e4d378b
RS
473
474Do not use `make-local-variable' to make a hook variable buffer-local."
475 (if (local-variable-p hook)
476 nil
477 (or (boundp hook) (set hook nil))
478 (make-local-variable hook)
479 (set hook (list t))))
480
481(defun add-hook (hook function &optional append local)
32295976
RS
482 "Add to the value of HOOK the function FUNCTION.
483FUNCTION is not added if already present.
484FUNCTION is added (if necessary) at the beginning of the hook list
485unless the optional argument APPEND is non-nil, in which case
486FUNCTION is added at the end.
487
0e4d378b
RS
488The optional fourth argument, LOCAL, if non-nil, says to modify
489the hook's buffer-local value rather than its default value.
490This makes no difference if the hook is not buffer-local.
491To make a hook variable buffer-local, always use
492`make-local-hook', not `make-local-variable'.
493
32295976
RS
494HOOK should be a symbol, and FUNCTION may be any valid function. If
495HOOK is void, it is first set to nil. If HOOK's value is a single
aa09b5ca 496function, it is changed to a list of functions."
be9b65ac 497 (or (boundp hook) (set hook nil))
0e4d378b 498 (or (default-boundp hook) (set-default hook nil))
32295976
RS
499 ;; If the hook value is a single function, turn it into a list.
500 (let ((old (symbol-value hook)))
501 (if (or (not (listp old)) (eq (car old) 'lambda))
502 (set hook (list old))))
f4e5bca5
RS
503 (if (or local
504 ;; Detect the case where make-local-variable was used on a hook
505 ;; and do what we used to do.
cd2db344 506 (and (local-variable-if-set-p hook)
f4e5bca5 507 (not (memq t (symbol-value hook)))))
0e4d378b
RS
508 ;; Alter the local value only.
509 (or (if (consp function)
510 (member function (symbol-value hook))
511 (memq function (symbol-value hook)))
512 (set hook
513 (if append
514 (append (symbol-value hook) (list function))
515 (cons function (symbol-value hook)))))
516 ;; Alter the global value (which is also the only value,
517 ;; if the hook doesn't have a local value).
518 (or (if (consp function)
519 (member function (default-value hook))
520 (memq function (default-value hook)))
521 (set-default hook
522 (if append
523 (append (default-value hook) (list function))
524 (cons function (default-value hook)))))))
525
526(defun remove-hook (hook function &optional local)
24980d16
RS
527 "Remove from the value of HOOK the function FUNCTION.
528HOOK should be a symbol, and FUNCTION may be any valid function. If
529FUNCTION isn't the value of HOOK, or, if FUNCTION doesn't appear in the
0e4d378b
RS
530list of hooks to run in HOOK, then nothing is done. See `add-hook'.
531
532The optional third argument, LOCAL, if non-nil, says to modify
533the hook's buffer-local value rather than its default value.
534This makes no difference if the hook is not buffer-local.
535To make a hook variable buffer-local, always use
536`make-local-hook', not `make-local-variable'."
24980d16 537 (if (or (not (boundp hook)) ;unbound symbol, or
0e4d378b 538 (not (default-boundp 'hook))
24980d16
RS
539 (null (symbol-value hook)) ;value is nil, or
540 (null function)) ;function is nil, then
541 nil ;Do nothing.
f4e5bca5
RS
542 (if (or local
543 ;; Detect the case where make-local-variable was used on a hook
544 ;; and do what we used to do.
545 (and (local-variable-p hook)
546 (not (memq t (symbol-value hook)))))
0e4d378b
RS
547 (let ((hook-value (symbol-value hook)))
548 (if (consp hook-value)
549 (if (member function hook-value)
550 (setq hook-value (delete function (copy-sequence hook-value))))
551 (if (equal hook-value function)
552 (setq hook-value nil)))
553 (set hook hook-value))
554 (let ((hook-value (default-value hook)))
555 (if (consp hook-value)
556 (if (member function hook-value)
557 (setq hook-value (delete function (copy-sequence hook-value))))
558 (if (equal hook-value function)
559 (setq hook-value nil)))
560 (set-default hook hook-value)))))
6e3af630
RS
561
562(defun add-to-list (list-var element)
8851c1f0
RS
563 "Add to the value of LIST-VAR the element ELEMENT if it isn't there yet.
564If you want to use `add-to-list' on a variable that is not defined
565until a certain package is loaded, you should put the call to `add-to-list'
566into a hook function that will be run only after loading the package.
567`eval-after-load' provides one way to do this. In some cases
568other hooks, such as major mode hooks, can do the job."
6e3af630
RS
569 (or (member element (symbol-value list-var))
570 (set list-var (cons element (symbol-value list-var)))))
be9b65ac 571\f
9a5336ae
JB
572;;;; Specifying things to do after certain files are loaded.
573
574(defun eval-after-load (file form)
575 "Arrange that, if FILE is ever loaded, FORM will be run at that time.
576This makes or adds to an entry on `after-load-alist'.
90914938 577If FILE is already loaded, evaluate FORM right now.
12c7071c 578It does nothing if FORM is already on the list for FILE.
9a5336ae 579FILE should be the name of a library, with no directory name."
90914938 580 ;; Make sure there is an element for FILE.
9a5336ae
JB
581 (or (assoc file after-load-alist)
582 (setq after-load-alist (cons (list file) after-load-alist)))
90914938 583 ;; Add FORM to the element if it isn't there.
12c7071c
RS
584 (let ((elt (assoc file after-load-alist)))
585 (or (member form (cdr elt))
90914938
RS
586 (progn
587 (nconc elt (list form))
588 ;; If the file has been loaded already, run FORM right away.
589 (and (assoc file load-history)
590 (eval form)))))
9a5336ae
JB
591 form)
592
593(defun eval-next-after-load (file)
594 "Read the following input sexp, and run it whenever FILE is loaded.
595This makes or adds to an entry on `after-load-alist'.
596FILE should be the name of a library, with no directory name."
597 (eval-after-load file (read)))
598
599\f
600;;;; Input and display facilities.
601
602(defun read-quoted-char (&optional prompt)
603 "Like `read-char', except that if the first character read is an octal
604digit, we read up to two more octal digits and return the character
605represented by the octal number consisting of those digits.
606Optional argument PROMPT specifies a string to use to prompt the user."
1219a2a4 607 (let ((message-log-max nil) (count 0) (code 0) char)
9a5336ae
JB
608 (while (< count 3)
609 (let ((inhibit-quit (zerop count))
42e636f0
KH
610 ;; Don't let C-h get the help message--only help function keys.
611 (help-char nil)
612 (help-form
613 "Type the special character you want to use,
614or three octal digits representing its character code."))
9a5336ae
JB
615 (and prompt (message "%s-" prompt))
616 (setq char (read-char))
617 (if inhibit-quit (setq quit-flag nil)))
618 (cond ((null char))
619 ((and (<= ?0 char) (<= char ?7))
620 (setq code (+ (* code 8) (- char ?0))
621 count (1+ count))
622 (and prompt (message (setq prompt
623 (format "%s %c" prompt char)))))
624 ((> count 0)
625 (setq unread-command-events (list char) count 259))
626 (t (setq code char count 259))))
0342b545 627 ;; Turn a meta-character into a character with the 0200 bit set.
1219a2a4 628 (logior (if (/= (logand code ?\M-\^@) 0) 128 0)
0342b545 629 (logand 255 code))))
9a5336ae
JB
630
631(defun force-mode-line-update (&optional all)
632 "Force the mode-line of the current buffer to be redisplayed.
7ec2a18c 633With optional non-nil ALL, force redisplay of all mode-lines."
9a5336ae
JB
634 (if all (save-excursion (set-buffer (other-buffer))))
635 (set-buffer-modified-p (buffer-modified-p)))
636
be9b65ac
DL
637(defun momentary-string-display (string pos &optional exit-char message)
638 "Momentarily display STRING in the buffer at POS.
639Display remains until next character is typed.
640If the char is EXIT-CHAR (optional third arg, default is SPC) it is swallowed;
641otherwise it is then available as input (as a command if nothing else).
642Display MESSAGE (optional fourth arg) in the echo area.
643If MESSAGE is nil, instructions to type EXIT-CHAR are displayed there."
644 (or exit-char (setq exit-char ?\ ))
645 (let ((buffer-read-only nil)
ca2ec1c5
RS
646 ;; Don't modify the undo list at all.
647 (buffer-undo-list t)
be9b65ac
DL
648 (modified (buffer-modified-p))
649 (name buffer-file-name)
650 insert-end)
651 (unwind-protect
652 (progn
653 (save-excursion
654 (goto-char pos)
655 ;; defeat file locking... don't try this at home, kids!
656 (setq buffer-file-name nil)
657 (insert-before-markers string)
3eec84bf
RS
658 (setq insert-end (point))
659 ;; If the message end is off screen, recenter now.
660 (if (> (window-end) insert-end)
661 (recenter (/ (window-height) 2)))
662 ;; If that pushed message start off the screen,
663 ;; scroll to start it at the top of the screen.
664 (move-to-window-line 0)
665 (if (> (point) pos)
666 (progn
667 (goto-char pos)
668 (recenter 0))))
be9b65ac
DL
669 (message (or message "Type %s to continue editing.")
670 (single-key-description exit-char))
3547c855 671 (let ((char (read-event)))
be9b65ac 672 (or (eq char exit-char)
dbc4e1c1 673 (setq unread-command-events (list char)))))
be9b65ac
DL
674 (if insert-end
675 (save-excursion
676 (delete-region pos insert-end)))
677 (setq buffer-file-name name)
678 (set-buffer-modified-p modified))))
679
9a5336ae
JB
680\f
681;;;; Miscellanea.
682
448b61c9
RS
683;; A number of major modes set this locally.
684;; Give it a global value to avoid compiler warnings.
685(defvar font-lock-defaults nil)
686
687;; Avoid compiler warnings about this variable,
688;; which has a special meaning on certain system types.
689(defvar buffer-file-type nil
690 "Non-nil if the visited file is a binary file.
691This variable is meaningful on MS-DOG and Windows NT.
692On those systems, it is automatically local in every buffer.
693On other systems, this variable is normally always nil.")
694
f9269e19
RS
695(defun ignore (&rest ignore)
696 "Do nothing and return nil.
697This function accepts any number of arguments, but ignores them."
c0f1a4f6 698 (interactive)
9a5336ae
JB
699 nil)
700
701(defun error (&rest args)
702 "Signal an error, making error message by passing all args to `format'."
703 (while t
704 (signal 'error (list (apply 'format args)))))
705
cef7ae6e 706(defalias 'user-original-login-name 'user-login-name)
9a5336ae 707
be9b65ac
DL
708(defun start-process-shell-command (name buffer &rest args)
709 "Start a program in a subprocess. Return the process object for it.
710Args are NAME BUFFER COMMAND &rest COMMAND-ARGS.
711NAME is name for process. It is modified if necessary to make it unique.
712BUFFER is the buffer or (buffer-name) to associate with the process.
713 Process output goes at end of that buffer, unless you specify
714 an output stream or filter function to handle the output.
715 BUFFER may be also nil, meaning that this process is not associated
716 with any buffer
717Third arg is command name, the name of a shell command.
718Remaining arguments are the arguments for the command.
4f1d6310 719Wildcards and redirection are handled as usual in the shell."
a247bf21
KH
720 (cond
721 ((eq system-type 'vax-vms)
722 (apply 'start-process name buffer args))
b59f6d7a
RS
723 ;; We used to use `exec' to replace the shell with the command,
724 ;; but that failed to handle (...) and semicolon, etc.
a247bf21
KH
725 (t
726 (start-process name buffer shell-file-name shell-command-switch
b59f6d7a 727 (mapconcat 'identity args " ")))))
be9b65ac 728
9a5336ae
JB
729(defmacro save-match-data (&rest body)
730 "Execute the BODY forms, restoring the global value of the match data."
731 (let ((original (make-symbol "match-data")))
993713ce
SM
732 (list 'let (list (list original '(match-data)))
733 (list 'unwind-protect
734 (cons 'progn body)
735 (list 'store-match-data original)))))
736
cd323f89 737(defun match-string (num &optional string)
993713ce
SM
738 "Return string of text matched by last search.
739NUM specifies which parenthesized expression in the last regexp.
740 Value is nil if NUMth pair didn't match, or there were less than NUM pairs.
741Zero means the entire text matched by the whole regexp or whole string.
742STRING should be given if the last search was by `string-match' on STRING."
cd323f89
SM
743 (if (match-beginning num)
744 (if string
745 (substring string (match-beginning num) (match-end num))
746 (buffer-substring (match-beginning num) (match-end num)))))
58f950b4 747
5f7fc6cf
RS
748(defun buffer-substring-no-properties (beg end)
749 "Return the text from BEG to END, without text properties, as a string."
750 (let ((string (buffer-substring beg end)))
751 (set-text-properties 0 (length string) nil string)
752 string))
753
8af7df60
RS
754(defun shell-quote-argument (argument)
755 "Quote an argument for passing as argument to an inferior shell."
c1c74b43
RS
756 (if (eq system-type 'ms-dos)
757 ;; MS-DOS shells don't have quoting, so don't do any.
758 argument
759 (if (eq system-type 'windows-nt)
760 (concat "\"" argument "\"")
761 ;; Quote everything except POSIX filename characters.
762 ;; This should be safe enough even for really weird shells.
763 (let ((result "") (start 0) end)
764 (while (string-match "[^-0-9a-zA-Z_./]" argument start)
765 (setq end (match-beginning 0)
766 result (concat result (substring argument start end)
767 "\\" (substring argument end (1+ end)))
768 start (1+ end)))
769 (concat result (substring argument start))))))
8af7df60 770
297d863b 771(defun make-syntax-table (&optional oldtable)
984f718a
RS
772 "Return a new syntax table.
773It inherits all letters and control characters from the standard
774syntax table; other characters are copied from the standard syntax table."
297d863b
KH
775 (if oldtable
776 (copy-syntax-table oldtable)
777 (let ((table (copy-syntax-table))
778 i)
779 (setq i 0)
780 (while (<= i 31)
781 (aset table i 13)
782 (setq i (1+ i)))
783 (setq i ?A)
784 (while (<= i ?Z)
785 (aset table i 13)
786 (setq i (1+ i)))
787 (setq i ?a)
788 (while (<= i ?z)
789 (aset table i 13)
790 (setq i (1+ i)))
791 (setq i 128)
792 (while (<= i 255)
793 (aset table i 13)
794 (setq i (1+ i)))
795 table)))
baed0109
RS
796\f
797(defun global-set-key (key command)
798 "Give KEY a global binding as COMMAND.
799COMMAND is a symbol naming an interactively-callable function.
800KEY is a key sequence (a string or vector of characters or event types).
801Non-ASCII characters with codes above 127 (such as ISO Latin-1)
802can be included if you use a vector.
803Note that if KEY has a local binding in the current buffer
804that local binding will continue to shadow any global binding."
805 (interactive "KSet key globally: \nCSet key %s to command: ")
806 (or (vectorp key) (stringp key)
807 (signal 'wrong-type-argument (list 'arrayp key)))
808 (define-key (current-global-map) key command)
809 nil)
810
811(defun local-set-key (key command)
812 "Give KEY a local binding as COMMAND.
813COMMAND is a symbol naming an interactively-callable function.
814KEY is a key sequence (a string or vector of characters or event types).
815Non-ASCII characters with codes above 127 (such as ISO Latin-1)
816can be included if you use a vector.
817The binding goes in the current buffer's local map,
818which in most cases is shared with all other buffers in the same major mode."
819 (interactive "KSet key locally: \nCSet key %s locally to command: ")
820 (let ((map (current-local-map)))
821 (or map
822 (use-local-map (setq map (make-sparse-keymap))))
823 (or (vectorp key) (stringp key)
824 (signal 'wrong-type-argument (list 'arrayp key)))
825 (define-key map key command))
826 nil)
984f718a 827
baed0109
RS
828(defun global-unset-key (key)
829 "Remove global binding of KEY.
830KEY is a string representing a sequence of keystrokes."
831 (interactive "kUnset key globally: ")
832 (global-set-key key nil))
833
db2474b8 834(defun local-unset-key (key)
baed0109
RS
835 "Remove local binding of KEY.
836KEY is a string representing a sequence of keystrokes."
837 (interactive "kUnset key locally: ")
838 (if (current-local-map)
db2474b8 839 (local-set-key key nil))
baed0109
RS
840 nil)
841\f
4809d0dd
KH
842;; We put this here instead of in frame.el so that it's defined even on
843;; systems where frame.el isn't loaded.
844(defun frame-configuration-p (object)
845 "Return non-nil if OBJECT seems to be a frame configuration.
846Any list whose car is `frame-configuration' is assumed to be a frame
847configuration."
848 (and (consp object)
849 (eq (car object) 'frame-configuration)))
850
9a5336ae
JB
851;; now in fns.c
852;(defun nth (n list)
853; "Returns the Nth element of LIST.
854;N counts from zero. If LIST is not that long, nil is returned."
855; (car (nthcdr n list)))
856;
857;(defun copy-alist (alist)
858; "Return a copy of ALIST.
859;This is a new alist which represents the same mapping
860;from objects to objects, but does not share the alist structure with ALIST.
861;The objects mapped (cars and cdrs of elements of the alist)
862;are shared, however."
863; (setq alist (copy-sequence alist))
864; (let ((tail alist))
865; (while tail
866; (if (consp (car tail))
867; (setcar tail (cons (car (car tail)) (cdr (car tail)))))
868; (setq tail (cdr tail))))
869; alist)
630cc463
ER
870
871;;; subr.el ends here
9a5336ae 872