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