Undo previous change.
[bpt/emacs.git] / lisp / subr.el
CommitLineData
c88ab9ce 1;;; subr.el --- basic lisp subroutines for Emacs
630cc463 2
64ed733a 3;; Copyright (C) 1985, 86, 92, 94, 95, 1999 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
b578f267
EN
18;; along with GNU Emacs; see the file COPYING. If not, write to the
19;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20;; Boston, MA 02111-1307, USA.
be9b65ac 21
630cc463 22;;; Code:
77a5664f
RS
23(defvar custom-declare-variable-list nil
24 "Record `defcustom' calls made before `custom.el' is loaded to handle them.
25Each element of this list holds the arguments to one call to `defcustom'.")
26
68e3e5f5 27;; Use this, rather than defcustom, in subr.el and other files loaded
77a5664f
RS
28;; before custom.el.
29(defun custom-declare-variable-early (&rest arguments)
30 (setq custom-declare-variable-list
31 (cons arguments custom-declare-variable-list)))
9a5336ae
JB
32\f
33;;;; Lisp language features.
34
35(defmacro lambda (&rest cdr)
36 "Return a lambda expression.
37A call of the form (lambda ARGS DOCSTRING INTERACTIVE BODY) is
38self-quoting; the result of evaluating the lambda expression is the
39expression itself. The lambda expression may then be treated as a
bec0d7f9
RS
40function, i.e., stored as the function value of a symbol, passed to
41funcall or mapcar, etc.
42
9a5336ae 43ARGS should take the same form as an argument list for a `defun'.
8fd68088
RS
44DOCSTRING is an optional documentation string.
45 If present, it should describe how to call the function.
46 But documentation strings are usually not useful in nameless functions.
9a5336ae
JB
47INTERACTIVE should be a call to the function `interactive', which see.
48It may also be omitted.
49BODY should be a list of lisp expressions."
50 ;; Note that this definition should not use backquotes; subr.el should not
51 ;; depend on backquote.el.
52 (list 'function (cons 'lambda cdr)))
53
1be152fc 54(defmacro push (newelt listname)
fa65505b 55 "Add NEWELT to the list stored in the symbol LISTNAME.
1be152fc 56This is equivalent to (setq LISTNAME (cons NEWELT LISTNAME)).
d270117a 57LISTNAME must be a symbol."
22d85d00
DL
58 (list 'setq listname
59 (list 'cons newelt listname)))
d270117a
RS
60
61(defmacro pop (listname)
62 "Return the first element of LISTNAME's value, and remove it from the list.
63LISTNAME must be a symbol whose value is a list.
64If the value is nil, `pop' returns nil but does not actually
65change the list."
66 (list 'prog1 (list 'car listname)
67 (list 'setq listname (list 'cdr listname))))
68
debff3c3
RS
69(defmacro when (cond &rest body)
70 "(when COND BODY...): if COND yields non-nil, do BODY, else return nil."
71 (list 'if cond (cons 'progn body)))
11d431ad
KH
72(put 'when 'lisp-indent-function 1)
73(put 'when 'edebug-form-spec '(&rest form))
9a5336ae 74
debff3c3
RS
75(defmacro unless (cond &rest body)
76 "(unless COND BODY...): if COND yields nil, do BODY, else return nil."
77 (cons 'if (cons cond (cons nil body))))
11d431ad
KH
78(put 'unless 'lisp-indent-function 1)
79(put 'unless 'edebug-form-spec '(&rest form))
d370591d 80
a0b0756a
RS
81(defmacro dolist (spec &rest body)
82 "(dolist (VAR LIST [RESULT]) BODY...): loop over a list.
83Evaluate BODY with VAR bound to each car from LIST, in turn.
84Then evaluate RESULT to get return value, default nil."
85 (let ((temp (gensym "--dolist-temp--")))
86 (list 'block nil
87 (list* 'let (list (list temp (nth 1 spec)) (car spec))
88 (list* 'while temp (list 'setq (car spec) (list 'car temp))
89 (append body (list (list 'setq temp
90 (list 'cdr temp)))))
91 (if (cdr (cdr spec))
92 (cons (list 'setq (car spec) nil) (cdr (cdr spec)))
93 '(nil))))))
94
95(defmacro dotimes (spec &rest body)
96 "(dotimes (VAR COUNT [RESULT]) BODY...): loop a certain number of times.
97Evaluate BODY with VAR bound to successive integers running from 0,
98inclusive, to COUNT, exclusive. Then evaluate RESULT to get
99the return value (nil if RESULT is omitted)."
100 (let ((temp (gensym "--dotimes-temp--")))
101 (list 'block nil
102 (list* 'let (list (list temp (nth 1 spec)) (list (car spec) 0))
103 (list* 'while (list '< (car spec) temp)
104 (append body (list (list 'incf (car spec)))))
105 (or (cdr (cdr spec)) '(nil))))))
106
d370591d
RS
107(defsubst caar (x)
108 "Return the car of the car of X."
109 (car (car x)))
110
111(defsubst cadr (x)
112 "Return the car of the cdr of X."
113 (car (cdr x)))
114
115(defsubst cdar (x)
116 "Return the cdr of the car of X."
117 (cdr (car x)))
118
119(defsubst cddr (x)
120 "Return the cdr of the cdr of X."
121 (cdr (cdr x)))
e8c32c99 122
369fba5f
RS
123(defun last (x &optional n)
124 "Return the last link of the list X. Its car is the last element.
125If X is nil, return nil.
126If N is non-nil, return the Nth-to-last link of X.
127If N is bigger than the length of X, return X."
128 (if n
129 (let ((m 0) (p x))
130 (while (consp p)
131 (setq m (1+ m) p (cdr p)))
132 (if (<= n 0) p
133 (if (< n m) (nthcdr (- m n) x) x)))
134 (while (cdr x)
135 (setq x (cdr x)))
136 x))
526d204e 137
8a288450
RS
138(defun assoc-default (key alist &optional test default)
139 "Find object KEY in a pseudo-alist ALIST.
140ALIST is a list of conses or objects. Each element (or the element's car,
141if it is a cons) is compared with KEY by evaluating (TEST (car elt) KEY).
142If that is non-nil, the element matches;
143then `assoc-default' returns the element's cdr, if it is a cons,
526d204e 144or DEFAULT if the element is not a cons.
8a288450
RS
145
146If no element matches, the value is nil.
147If TEST is omitted or nil, `equal' is used."
148 (let (found (tail alist) value)
149 (while (and tail (not found))
150 (let ((elt (car tail)))
151 (when (funcall (or test 'equal) (if (consp elt) (car elt) elt) key)
152 (setq found t value (if (consp elt) (cdr elt) default))))
153 (setq tail (cdr tail)))
154 value))
98aae5f6
KH
155
156(defun assoc-ignore-case (key alist)
157 "Like `assoc', but ignores differences in case and text representation.
158KEY must be a string. Upper-case and lower-case letters are treated as equal.
159Unibyte strings are converted to multibyte for comparison."
160 (let (element)
161 (while (and alist (not element))
162 (if (eq t (compare-strings key 0 nil (car (car alist)) 0 nil t))
163 (setq element (car alist)))
164 (setq alist (cdr alist)))
165 element))
166
167(defun assoc-ignore-representation (key alist)
168 "Like `assoc', but ignores differences in text representation.
169KEY must be a string.
170Unibyte strings are converted to multibyte for comparison."
171 (let (element)
172 (while (and alist (not element))
173 (if (eq t (compare-strings key 0 nil (car (car alist)) 0 nil))
174 (setq element (car alist)))
175 (setq alist (cdr alist)))
176 element))
9a5336ae 177\f
9a5336ae 178;;;; Keymap support.
be9b65ac
DL
179
180(defun undefined ()
181 (interactive)
182 (ding))
183
184;Prevent the \{...} documentation construct
185;from mentioning keys that run this command.
186(put 'undefined 'suppress-keymap t)
187
188(defun suppress-keymap (map &optional nodigits)
189 "Make MAP override all normally self-inserting keys to be undefined.
190Normally, as an exception, digits and minus-sign are set to make prefix args,
191but optional second arg NODIGITS non-nil treats them like other chars."
80e7b471 192 (substitute-key-definition 'self-insert-command 'undefined map global-map)
be9b65ac
DL
193 (or nodigits
194 (let (loop)
195 (define-key map "-" 'negative-argument)
196 ;; Make plain numbers do numeric args.
197 (setq loop ?0)
198 (while (<= loop ?9)
199 (define-key map (char-to-string loop) 'digit-argument)
200 (setq loop (1+ loop))))))
201
be9b65ac
DL
202;Moved to keymap.c
203;(defun copy-keymap (keymap)
204; "Return a copy of KEYMAP"
205; (while (not (keymapp keymap))
206; (setq keymap (signal 'wrong-type-argument (list 'keymapp keymap))))
207; (if (vectorp keymap)
208; (copy-sequence keymap)
209; (copy-alist keymap)))
210
f14dbba7
KH
211(defvar key-substitution-in-progress nil
212 "Used internally by substitute-key-definition.")
213
7f2c2edd 214(defun substitute-key-definition (olddef newdef keymap &optional oldmap prefix)
be9b65ac
DL
215 "Replace OLDDEF with NEWDEF for any keys in KEYMAP now defined as OLDDEF.
216In other words, OLDDEF is replaced with NEWDEF where ever it appears.
7f2c2edd
RS
217If optional fourth argument OLDMAP is specified, we redefine
218in KEYMAP as NEWDEF those chars which are defined as OLDDEF in OLDMAP."
219 (or prefix (setq prefix ""))
220 (let* ((scan (or oldmap keymap))
221 (vec1 (vector nil))
f14dbba7
KH
222 (prefix1 (vconcat prefix vec1))
223 (key-substitution-in-progress
224 (cons scan key-substitution-in-progress)))
7f2c2edd
RS
225 ;; Scan OLDMAP, finding each char or event-symbol that
226 ;; has any definition, and act on it with hack-key.
227 (while (consp scan)
228 (if (consp (car scan))
229 (let ((char (car (car scan)))
230 (defn (cdr (car scan))))
231 ;; The inside of this let duplicates exactly
232 ;; the inside of the following let that handles array elements.
233 (aset vec1 0 char)
234 (aset prefix1 (length prefix) char)
44d798af 235 (let (inner-def skipped)
7f2c2edd
RS
236 ;; Skip past menu-prompt.
237 (while (stringp (car-safe defn))
44d798af 238 (setq skipped (cons (car defn) skipped))
7f2c2edd 239 (setq defn (cdr defn)))
e025dddf
RS
240 ;; Skip past cached key-equivalence data for menu items.
241 (and (consp defn) (consp (car defn))
242 (setq defn (cdr defn)))
7f2c2edd 243 (setq inner-def defn)
e025dddf 244 ;; Look past a symbol that names a keymap.
7f2c2edd
RS
245 (while (and (symbolp inner-def)
246 (fboundp inner-def))
247 (setq inner-def (symbol-function inner-def)))
328a37ec
RS
248 (if (or (eq defn olddef)
249 ;; Compare with equal if definition is a key sequence.
250 ;; That is useful for operating on function-key-map.
251 (and (or (stringp defn) (vectorp defn))
252 (equal defn olddef)))
44d798af 253 (define-key keymap prefix1 (nconc (nreverse skipped) newdef))
f14dbba7 254 (if (and (keymapp defn)
350b7567
RS
255 ;; Avoid recursively scanning
256 ;; where KEYMAP does not have a submap.
afd9831b
RS
257 (let ((elt (lookup-key keymap prefix1)))
258 (or (null elt)
259 (keymapp elt)))
350b7567 260 ;; Avoid recursively rescanning keymap being scanned.
f14dbba7
KH
261 (not (memq inner-def
262 key-substitution-in-progress)))
e025dddf
RS
263 ;; If this one isn't being scanned already,
264 ;; scan it now.
7f2c2edd
RS
265 (substitute-key-definition olddef newdef keymap
266 inner-def
267 prefix1)))))
916cc49f 268 (if (vectorp (car scan))
7f2c2edd
RS
269 (let* ((array (car scan))
270 (len (length array))
271 (i 0))
272 (while (< i len)
273 (let ((char i) (defn (aref array i)))
274 ;; The inside of this let duplicates exactly
275 ;; the inside of the previous let.
276 (aset vec1 0 char)
277 (aset prefix1 (length prefix) char)
44d798af 278 (let (inner-def skipped)
7f2c2edd
RS
279 ;; Skip past menu-prompt.
280 (while (stringp (car-safe defn))
44d798af 281 (setq skipped (cons (car defn) skipped))
7f2c2edd 282 (setq defn (cdr defn)))
e025dddf
RS
283 (and (consp defn) (consp (car defn))
284 (setq defn (cdr defn)))
7f2c2edd
RS
285 (setq inner-def defn)
286 (while (and (symbolp inner-def)
287 (fboundp inner-def))
288 (setq inner-def (symbol-function inner-def)))
328a37ec
RS
289 (if (or (eq defn olddef)
290 (and (or (stringp defn) (vectorp defn))
291 (equal defn olddef)))
44d798af
RS
292 (define-key keymap prefix1
293 (nconc (nreverse skipped) newdef))
f14dbba7 294 (if (and (keymapp defn)
afd9831b
RS
295 (let ((elt (lookup-key keymap prefix1)))
296 (or (null elt)
297 (keymapp elt)))
f14dbba7
KH
298 (not (memq inner-def
299 key-substitution-in-progress)))
7f2c2edd
RS
300 (substitute-key-definition olddef newdef keymap
301 inner-def
302 prefix1)))))
97fd9abf
RS
303 (setq i (1+ i))))
304 (if (char-table-p (car scan))
305 (map-char-table
306 (function (lambda (char defn)
307 (let ()
308 ;; The inside of this let duplicates exactly
309 ;; the inside of the previous let,
310 ;; except that it uses set-char-table-range
311 ;; instead of define-key.
312 (aset vec1 0 char)
313 (aset prefix1 (length prefix) char)
314 (let (inner-def skipped)
315 ;; Skip past menu-prompt.
316 (while (stringp (car-safe defn))
317 (setq skipped (cons (car defn) skipped))
318 (setq defn (cdr defn)))
319 (and (consp defn) (consp (car defn))
320 (setq defn (cdr defn)))
321 (setq inner-def defn)
322 (while (and (symbolp inner-def)
323 (fboundp inner-def))
324 (setq inner-def (symbol-function inner-def)))
325 (if (or (eq defn olddef)
326 (and (or (stringp defn) (vectorp defn))
327 (equal defn olddef)))
9a5114ac
RS
328 (define-key keymap prefix1
329 (nconc (nreverse skipped) newdef))
97fd9abf
RS
330 (if (and (keymapp defn)
331 (let ((elt (lookup-key keymap prefix1)))
332 (or (null elt)
333 (keymapp elt)))
334 (not (memq inner-def
335 key-substitution-in-progress)))
336 (substitute-key-definition olddef newdef keymap
337 inner-def
338 prefix1)))))))
339 (car scan)))))
7f2c2edd 340 (setq scan (cdr scan)))))
9a5336ae 341
06ae9cf2 342(defun define-key-after (keymap key definition after)
4434d61b
RS
343 "Add binding in KEYMAP for KEY => DEFINITION, right after AFTER's binding.
344This is like `define-key' except that the binding for KEY is placed
345just after the binding for the event AFTER, instead of at the beginning
c34a9d34
RS
346of the map. Note that AFTER must be an event type (like KEY), NOT a command
347\(like DEFINITION).
348
349If AFTER is t, the new binding goes at the end of the keymap.
350
9ed287b0 351KEY must contain just one event type--that is to say, it must be
c34a9d34
RS
352a string or vector of length 1.
353
354The order of bindings in a keymap matters when it is used as a menu."
355
4434d61b
RS
356 (or (keymapp keymap)
357 (signal 'wrong-type-argument (list 'keymapp keymap)))
ab375e6c 358 (if (> (length key) 1)
626f67f3 359 (error "multi-event key specified in `define-key-after'"))
113d28a8 360 (let ((tail keymap) done inserted
4434d61b
RS
361 (first (aref key 0)))
362 (while (and (not done) tail)
363 ;; Delete any earlier bindings for the same key.
364 (if (eq (car-safe (car (cdr tail))) first)
365 (setcdr tail (cdr (cdr tail))))
366 ;; When we reach AFTER's binding, insert the new binding after.
367 ;; If we reach an inherited keymap, insert just before that.
113d28a8 368 ;; If we reach the end of this keymap, insert at the end.
c34a9d34
RS
369 (if (or (and (eq (car-safe (car tail)) after)
370 (not (eq after t)))
113d28a8
RS
371 (eq (car (cdr tail)) 'keymap)
372 (null (cdr tail)))
4434d61b 373 (progn
113d28a8
RS
374 ;; Stop the scan only if we find a parent keymap.
375 ;; Keep going past the inserted element
376 ;; so we can delete any duplications that come later.
377 (if (eq (car (cdr tail)) 'keymap)
378 (setq done t))
379 ;; Don't insert more than once.
380 (or inserted
381 (setcdr tail (cons (cons (aref key 0) definition) (cdr tail))))
382 (setq inserted t)))
4434d61b
RS
383 (setq tail (cdr tail)))))
384
d128fe85
RS
385(defmacro kbd (keys)
386 "Convert KEYS to the internal Emacs key representation.
387KEYS should be a string constant in the format used for
388saving keyboard macros (see `insert-kbd-macro')."
389 (read-kbd-macro keys))
390
8bed5e3d
RS
391(put 'keyboard-translate-table 'char-table-extra-slots 0)
392
9a5336ae
JB
393(defun keyboard-translate (from to)
394 "Translate character FROM to TO at a low level.
395This function creates a `keyboard-translate-table' if necessary
396and then modifies one entry in it."
8bed5e3d
RS
397 (or (char-table-p keyboard-translate-table)
398 (setq keyboard-translate-table
399 (make-char-table 'keyboard-translate-table nil)))
9a5336ae
JB
400 (aset keyboard-translate-table from to))
401
402\f
403;;;; The global keymap tree.
404
405;;; global-map, esc-map, and ctl-x-map have their values set up in
406;;; keymap.c; we just give them docstrings here.
407
408(defvar global-map nil
409 "Default global keymap mapping Emacs keyboard input into commands.
410The value is a keymap which is usually (but not necessarily) Emacs's
411global map.")
412
413(defvar esc-map nil
414 "Default keymap for ESC (meta) commands.
415The normal global definition of the character ESC indirects to this keymap.")
416
417(defvar ctl-x-map nil
418 "Default keymap for C-x commands.
419The normal global definition of the character C-x indirects to this keymap.")
420
421(defvar ctl-x-4-map (make-sparse-keymap)
422 "Keymap for subcommands of C-x 4")
059184dd 423(defalias 'ctl-x-4-prefix ctl-x-4-map)
9a5336ae
JB
424(define-key ctl-x-map "4" 'ctl-x-4-prefix)
425
426(defvar ctl-x-5-map (make-sparse-keymap)
427 "Keymap for frame commands.")
059184dd 428(defalias 'ctl-x-5-prefix ctl-x-5-map)
9a5336ae
JB
429(define-key ctl-x-map "5" 'ctl-x-5-prefix)
430
0f03054a 431\f
9a5336ae
JB
432;;;; Event manipulation functions.
433
da16e648
KH
434;; The call to `read' is to ensure that the value is computed at load time
435;; and not compiled into the .elc file. The value is negative on most
436;; machines, but not on all!
437(defconst listify-key-sequence-1 (logior 128 (read "?\\M-\\^@")))
114137b8 438
cde6d7e3
RS
439(defun listify-key-sequence (key)
440 "Convert a key sequence to a list of events."
441 (if (vectorp key)
442 (append key nil)
443 (mapcar (function (lambda (c)
444 (if (> c 127)
114137b8 445 (logxor c listify-key-sequence-1)
cde6d7e3
RS
446 c)))
447 (append key nil))))
448
53e5a4e8
RS
449(defsubst eventp (obj)
450 "True if the argument is an event object."
451 (or (integerp obj)
452 (and (symbolp obj)
453 (get obj 'event-symbol-elements))
454 (and (consp obj)
455 (symbolp (car obj))
456 (get (car obj) 'event-symbol-elements))))
457
458(defun event-modifiers (event)
459 "Returns a list of symbols representing the modifier keys in event EVENT.
460The elements of the list may include `meta', `control',
32295976
RS
461`shift', `hyper', `super', `alt', `click', `double', `triple', `drag',
462and `down'."
53e5a4e8
RS
463 (let ((type event))
464 (if (listp type)
465 (setq type (car type)))
466 (if (symbolp type)
467 (cdr (get type 'event-symbol-elements))
468 (let ((list nil))
da16e648 469 (or (zerop (logand type ?\M-\^@))
53e5a4e8 470 (setq list (cons 'meta list)))
da16e648 471 (or (and (zerop (logand type ?\C-\^@))
53e5a4e8
RS
472 (>= (logand type 127) 32))
473 (setq list (cons 'control list)))
da16e648 474 (or (and (zerop (logand type ?\S-\^@))
53e5a4e8
RS
475 (= (logand type 255) (downcase (logand type 255))))
476 (setq list (cons 'shift list)))
da16e648 477 (or (zerop (logand type ?\H-\^@))
53e5a4e8 478 (setq list (cons 'hyper list)))
da16e648 479 (or (zerop (logand type ?\s-\^@))
53e5a4e8 480 (setq list (cons 'super list)))
da16e648 481 (or (zerop (logand type ?\A-\^@))
53e5a4e8
RS
482 (setq list (cons 'alt list)))
483 list))))
484
d63de416
RS
485(defun event-basic-type (event)
486 "Returns the basic type of the given event (all modifiers removed).
487The value is an ASCII printing character (not upper case) or a symbol."
2b0f4ba5
JB
488 (if (consp event)
489 (setq event (car event)))
d63de416
RS
490 (if (symbolp event)
491 (car (get event 'event-symbol-elements))
492 (let ((base (logand event (1- (lsh 1 18)))))
493 (downcase (if (< base 32) (logior base 64) base)))))
494
0f03054a
RS
495(defsubst mouse-movement-p (object)
496 "Return non-nil if OBJECT is a mouse movement event."
497 (and (consp object)
498 (eq (car object) 'mouse-movement)))
499
500(defsubst event-start (event)
501 "Return the starting position of EVENT.
502If EVENT is a mouse press or a mouse click, this returns the location
503of the event.
504If EVENT is a drag, this returns the drag's starting position.
505The return value is of the form
e55c21be 506 (WINDOW BUFFER-POSITION (X . Y) TIMESTAMP)
0f03054a
RS
507The `posn-' functions access elements of such lists."
508 (nth 1 event))
509
510(defsubst event-end (event)
511 "Return the ending location of EVENT. EVENT should be a click or drag event.
512If EVENT is a click event, this function is the same as `event-start'.
513The return value is of the form
e55c21be 514 (WINDOW BUFFER-POSITION (X . Y) TIMESTAMP)
0f03054a 515The `posn-' functions access elements of such lists."
69b95560 516 (nth (if (consp (nth 2 event)) 2 1) event))
0f03054a 517
32295976
RS
518(defsubst event-click-count (event)
519 "Return the multi-click count of EVENT, a click or drag event.
520The return value is a positive integer."
521 (if (integerp (nth 2 event)) (nth 2 event) 1))
522
0f03054a
RS
523(defsubst posn-window (position)
524 "Return the window in POSITION.
525POSITION should be a list of the form
e55c21be 526 (WINDOW BUFFER-POSITION (X . Y) TIMESTAMP)
0f03054a
RS
527as returned by the `event-start' and `event-end' functions."
528 (nth 0 position))
529
530(defsubst posn-point (position)
531 "Return the buffer location in POSITION.
532POSITION should be a list of the form
e55c21be 533 (WINDOW BUFFER-POSITION (X . Y) TIMESTAMP)
0f03054a 534as returned by the `event-start' and `event-end' functions."
15db4e0e
JB
535 (if (consp (nth 1 position))
536 (car (nth 1 position))
537 (nth 1 position)))
0f03054a 538
e55c21be
RS
539(defsubst posn-x-y (position)
540 "Return the x and y coordinates in POSITION.
0f03054a 541POSITION should be a list of the form
e55c21be 542 (WINDOW BUFFER-POSITION (X . Y) TIMESTAMP)
0f03054a
RS
543as returned by the `event-start' and `event-end' functions."
544 (nth 2 position))
545
ed627e08 546(defun posn-col-row (position)
dbbcac56 547 "Return the column and row in POSITION, measured in characters.
e55c21be
RS
548POSITION should be a list of the form
549 (WINDOW BUFFER-POSITION (X . Y) TIMESTAMP)
ed627e08
RS
550as returned by the `event-start' and `event-end' functions.
551For a scroll-bar event, the result column is 0, and the row
552corresponds to the vertical position of the click in the scroll bar."
553 (let ((pair (nth 2 position))
554 (window (posn-window position)))
dbbcac56
KH
555 (if (eq (if (consp (nth 1 position))
556 (car (nth 1 position))
557 (nth 1 position))
ed627e08
RS
558 'vertical-scroll-bar)
559 (cons 0 (scroll-bar-scale pair (1- (window-height window))))
dbbcac56
KH
560 (if (eq (if (consp (nth 1 position))
561 (car (nth 1 position))
562 (nth 1 position))
ed627e08
RS
563 'horizontal-scroll-bar)
564 (cons (scroll-bar-scale pair (window-width window)) 0)
9ba60df9
RS
565 (let* ((frame (if (framep window) window (window-frame window)))
566 (x (/ (car pair) (frame-char-width frame)))
567 (y (/ (cdr pair) (frame-char-height frame))))
ed627e08 568 (cons x y))))))
e55c21be 569
0f03054a
RS
570(defsubst posn-timestamp (position)
571 "Return the timestamp of POSITION.
572POSITION should be a list of the form
e55c21be 573 (WINDOW BUFFER-POSITION (X . Y) TIMESTAMP)
f415c00c 574as returned by the `event-start' and `event-end' functions."
0f03054a 575 (nth 3 position))
9a5336ae 576
0f03054a 577\f
9a5336ae
JB
578;;;; Obsolescent names for functions.
579
059184dd
ER
580(defalias 'dot 'point)
581(defalias 'dot-marker 'point-marker)
582(defalias 'dot-min 'point-min)
583(defalias 'dot-max 'point-max)
584(defalias 'window-dot 'window-point)
585(defalias 'set-window-dot 'set-window-point)
586(defalias 'read-input 'read-string)
587(defalias 'send-string 'process-send-string)
588(defalias 'send-region 'process-send-region)
589(defalias 'show-buffer 'set-window-buffer)
590(defalias 'buffer-flush-undo 'buffer-disable-undo)
591(defalias 'eval-current-buffer 'eval-buffer)
592(defalias 'compiled-function-p 'byte-code-function-p)
ae1cc031 593(defalias 'define-function 'defalias)
be9b65ac 594
0cba3a0f
KH
595(defalias 'sref 'aref)
596(make-obsolete 'sref 'aref)
597(make-obsolete 'char-bytes "Now this function always returns 1")
6bb762b3 598
9a5336ae
JB
599;; Some programs still use this as a function.
600(defun baud-rate ()
bcacc42c
RS
601 "Obsolete function returning the value of the `baud-rate' variable.
602Please convert your programs to use the variable `baud-rate' directly."
9a5336ae
JB
603 baud-rate)
604
0a5c0893
MB
605(defalias 'focus-frame 'ignore)
606(defalias 'unfocus-frame 'ignore)
9a5336ae
JB
607\f
608;;;; Alternate names for functions - these are not being phased out.
609
059184dd
ER
610(defalias 'string= 'string-equal)
611(defalias 'string< 'string-lessp)
612(defalias 'move-marker 'set-marker)
059184dd
ER
613(defalias 'not 'null)
614(defalias 'rplaca 'setcar)
615(defalias 'rplacd 'setcdr)
eb8c3be9 616(defalias 'beep 'ding) ;preserve lingual purity
059184dd
ER
617(defalias 'indent-to-column 'indent-to)
618(defalias 'backward-delete-char 'delete-backward-char)
619(defalias 'search-forward-regexp (symbol-function 're-search-forward))
620(defalias 'search-backward-regexp (symbol-function 're-search-backward))
621(defalias 'int-to-string 'number-to-string)
024ae2c6 622(defalias 'store-match-data 'set-match-data)
475fb2fb
KH
623(defalias 'point-at-eol 'line-end-position)
624(defalias 'point-at-bol 'line-beginning-position)
37f6661a
JB
625
626;;; Should this be an obsolete name? If you decide it should, you get
627;;; to go through all the sources and change them.
059184dd 628(defalias 'string-to-int 'string-to-number)
be9b65ac 629\f
9a5336ae 630;;;; Hook manipulation functions.
be9b65ac 631
0e4d378b
RS
632(defun make-local-hook (hook)
633 "Make the hook HOOK local to the current buffer.
71c78f01
RS
634The return value is HOOK.
635
0e4d378b
RS
636When a hook is local, its local and global values
637work in concert: running the hook actually runs all the hook
638functions listed in *either* the local value *or* the global value
639of the hook variable.
640
7dd1926e
RS
641This function works by making `t' a member of the buffer-local value,
642which acts as a flag to run the hook functions in the default value as
643well. This works for all normal hooks, but does not work for most
644non-normal hooks yet. We will be changing the callers of non-normal
645hooks so that they can handle localness; this has to be done one by
646one.
647
648This function does nothing if HOOK is already local in the current
649buffer.
0e4d378b
RS
650
651Do not use `make-local-variable' to make a hook variable buffer-local."
652 (if (local-variable-p hook)
653 nil
654 (or (boundp hook) (set hook nil))
655 (make-local-variable hook)
71c78f01
RS
656 (set hook (list t)))
657 hook)
0e4d378b
RS
658
659(defun add-hook (hook function &optional append local)
32295976
RS
660 "Add to the value of HOOK the function FUNCTION.
661FUNCTION is not added if already present.
662FUNCTION is added (if necessary) at the beginning of the hook list
663unless the optional argument APPEND is non-nil, in which case
664FUNCTION is added at the end.
665
0e4d378b
RS
666The optional fourth argument, LOCAL, if non-nil, says to modify
667the hook's buffer-local value rather than its default value.
668This makes no difference if the hook is not buffer-local.
669To make a hook variable buffer-local, always use
670`make-local-hook', not `make-local-variable'.
671
32295976
RS
672HOOK should be a symbol, and FUNCTION may be any valid function. If
673HOOK is void, it is first set to nil. If HOOK's value is a single
aa09b5ca 674function, it is changed to a list of functions."
be9b65ac 675 (or (boundp hook) (set hook nil))
0e4d378b 676 (or (default-boundp hook) (set-default hook nil))
32295976
RS
677 ;; If the hook value is a single function, turn it into a list.
678 (let ((old (symbol-value hook)))
679 (if (or (not (listp old)) (eq (car old) 'lambda))
680 (set hook (list old))))
f4e5bca5
RS
681 (if (or local
682 ;; Detect the case where make-local-variable was used on a hook
683 ;; and do what we used to do.
cd2db344 684 (and (local-variable-if-set-p hook)
f4e5bca5 685 (not (memq t (symbol-value hook)))))
0e4d378b 686 ;; Alter the local value only.
1fa0de2c 687 (or (if (or (consp function) (byte-code-function-p function))
0e4d378b
RS
688 (member function (symbol-value hook))
689 (memq function (symbol-value hook)))
690 (set hook
691 (if append
692 (append (symbol-value hook) (list function))
693 (cons function (symbol-value hook)))))
694 ;; Alter the global value (which is also the only value,
695 ;; if the hook doesn't have a local value).
1fa0de2c 696 (or (if (or (consp function) (byte-code-function-p function))
0e4d378b
RS
697 (member function (default-value hook))
698 (memq function (default-value hook)))
699 (set-default hook
700 (if append
701 (append (default-value hook) (list function))
702 (cons function (default-value hook)))))))
703
704(defun remove-hook (hook function &optional local)
24980d16
RS
705 "Remove from the value of HOOK the function FUNCTION.
706HOOK should be a symbol, and FUNCTION may be any valid function. If
707FUNCTION isn't the value of HOOK, or, if FUNCTION doesn't appear in the
0e4d378b
RS
708list of hooks to run in HOOK, then nothing is done. See `add-hook'.
709
710The optional third argument, LOCAL, if non-nil, says to modify
711the hook's buffer-local value rather than its default value.
712This makes no difference if the hook is not buffer-local.
713To make a hook variable buffer-local, always use
714`make-local-hook', not `make-local-variable'."
24980d16 715 (if (or (not (boundp hook)) ;unbound symbol, or
d46490e3 716 (not (default-boundp hook))
24980d16
RS
717 (null (symbol-value hook)) ;value is nil, or
718 (null function)) ;function is nil, then
719 nil ;Do nothing.
f4e5bca5
RS
720 (if (or local
721 ;; Detect the case where make-local-variable was used on a hook
722 ;; and do what we used to do.
723 (and (local-variable-p hook)
cf4a60a3
DL
724 (consp (symbol-value hook))
725 (not (memq t (symbol-value hook)))))
0e4d378b
RS
726 (let ((hook-value (symbol-value hook)))
727 (if (consp hook-value)
728 (if (member function hook-value)
729 (setq hook-value (delete function (copy-sequence hook-value))))
730 (if (equal hook-value function)
731 (setq hook-value nil)))
732 (set hook hook-value))
733 (let ((hook-value (default-value hook)))
cf4a60a3 734 (if (and (consp hook-value) (not (functionp hook-value)))
0e4d378b
RS
735 (if (member function hook-value)
736 (setq hook-value (delete function (copy-sequence hook-value))))
737 (if (equal hook-value function)
738 (setq hook-value nil)))
739 (set-default hook hook-value)))))
6e3af630
RS
740
741(defun add-to-list (list-var element)
8851c1f0 742 "Add to the value of LIST-VAR the element ELEMENT if it isn't there yet.
9f0b1f09 743The test for presence of ELEMENT is done with `equal'.
508bcbca
RS
744If ELEMENT is added, it is added at the beginning of the list.
745
8851c1f0
RS
746If you want to use `add-to-list' on a variable that is not defined
747until a certain package is loaded, you should put the call to `add-to-list'
748into a hook function that will be run only after loading the package.
749`eval-after-load' provides one way to do this. In some cases
750other hooks, such as major mode hooks, can do the job."
15171a06
KH
751 (if (member element (symbol-value list-var))
752 (symbol-value list-var)
753 (set list-var (cons element (symbol-value list-var)))))
be9b65ac 754\f
9a5336ae
JB
755;;;; Specifying things to do after certain files are loaded.
756
757(defun eval-after-load (file form)
758 "Arrange that, if FILE is ever loaded, FORM will be run at that time.
759This makes or adds to an entry on `after-load-alist'.
90914938 760If FILE is already loaded, evaluate FORM right now.
12c7071c 761It does nothing if FORM is already on the list for FILE.
9a5336ae 762FILE should be the name of a library, with no directory name."
90914938 763 ;; Make sure there is an element for FILE.
9a5336ae
JB
764 (or (assoc file after-load-alist)
765 (setq after-load-alist (cons (list file) after-load-alist)))
90914938 766 ;; Add FORM to the element if it isn't there.
12c7071c
RS
767 (let ((elt (assoc file after-load-alist)))
768 (or (member form (cdr elt))
90914938
RS
769 (progn
770 (nconc elt (list form))
771 ;; If the file has been loaded already, run FORM right away.
772 (and (assoc file load-history)
773 (eval form)))))
9a5336ae
JB
774 form)
775
776(defun eval-next-after-load (file)
777 "Read the following input sexp, and run it whenever FILE is loaded.
778This makes or adds to an entry on `after-load-alist'.
779FILE should be the name of a library, with no directory name."
780 (eval-after-load file (read)))
781
782\f
783;;;; Input and display facilities.
784
77a5664f 785(defvar read-quoted-char-radix 8
1ba764de 786 "*Radix for \\[quoted-insert] and other uses of `read-quoted-char'.
77a5664f
RS
787Legitimate radix values are 8, 10 and 16.")
788
789(custom-declare-variable-early
790 'read-quoted-char-radix 8
791 "*Radix for \\[quoted-insert] and other uses of `read-quoted-char'.
1ba764de
RS
792Legitimate radix values are 8, 10 and 16."
793 :type '(choice (const 8) (const 10) (const 16))
794 :group 'editing-basics)
795
9a5336ae 796(defun read-quoted-char (&optional prompt)
2444730b
RS
797 "Like `read-char', but do not allow quitting.
798Also, if the first character read is an octal digit,
799we read any number of octal digits and return the
569b03f2 800specified character code. Any nondigit terminates the sequence.
1ba764de 801If the terminator is RET, it is discarded;
2444730b
RS
802any other terminator is used itself as input.
803
569b03f2
RS
804The optional argument PROMPT specifies a string to use to prompt the user.
805The variable `read-quoted-char-radix' controls which radix to use
806for numeric input."
2444730b
RS
807 (let ((message-log-max nil) done (first t) (code 0) char)
808 (while (not done)
809 (let ((inhibit-quit first)
42e636f0
KH
810 ;; Don't let C-h get the help message--only help function keys.
811 (help-char nil)
812 (help-form
813 "Type the special character you want to use,
2444730b 814or the octal character code.
1ba764de 815RET terminates the character code and is discarded;
2444730b 816any other non-digit terminates the character code and is then used as input."))
b7de4d62 817 (setq char (read-event (and prompt (format "%s-" prompt)) t))
9a5336ae 818 (if inhibit-quit (setq quit-flag nil)))
4867f7b2
RS
819 ;; Translate TAB key into control-I ASCII character, and so on.
820 (and char
821 (let ((translated (lookup-key function-key-map (vector char))))
bf896a1b 822 (if (arrayp translated)
4867f7b2 823 (setq char (aref translated 0)))))
9a5336ae 824 (cond ((null char))
1ba764de
RS
825 ((not (integerp char))
826 (setq unread-command-events (list char)
827 done t))
bf896a1b
RS
828 ((/= (logand char ?\M-\^@) 0)
829 ;; Turn a meta-character into a character with the 0200 bit set.
830 (setq code (logior (logand char (lognot ?\M-\^@)) 128)
831 done t))
1ba764de
RS
832 ((and (<= ?0 char) (< char (+ ?0 (min 10 read-quoted-char-radix))))
833 (setq code (+ (* code read-quoted-char-radix) (- char ?0)))
834 (and prompt (setq prompt (message "%s %c" prompt char))))
835 ((and (<= ?a (downcase char))
836 (< (downcase char) (+ ?a -10 (min 26 read-quoted-char-radix))))
92304bc8
RS
837 (setq code (+ (* code read-quoted-char-radix)
838 (+ 10 (- (downcase char) ?a))))
91a6acc3 839 (and prompt (setq prompt (message "%s %c" prompt char))))
1ba764de 840 ((and (not first) (eq char ?\C-m))
2444730b
RS
841 (setq done t))
842 ((not first)
843 (setq unread-command-events (list char)
844 done t))
845 (t (setq code char
846 done t)))
847 (setq first nil))
bf896a1b 848 code))
9a5336ae 849
44071d6b
RS
850(defun read-passwd (prompt &optional confirm default)
851 "Read a password, prompting with PROMPT. Echo `.' for each character typed.
e0e4cb7a 852End with RET, LFD, or ESC. DEL or C-h rubs out. C-u kills line.
44071d6b
RS
853Optional argument CONFIRM, if non-nil, then read it twice to make sure.
854Optional DEFAULT is a default password to use instead of empty input."
855 (if confirm
856 (let (success)
857 (while (not success)
858 (let ((first (read-passwd prompt nil default))
859 (second (read-passwd "Confirm password: " nil default)))
860 (if (equal first second)
861 (setq success first)
862 (message "Password not repeated accurately; please start over")
863 (sit-for 1))))
864 success)
8723b7f3 865 (clear-this-command-keys)
44071d6b
RS
866 (let ((pass nil)
867 (c 0)
868 (echo-keystrokes 0)
869 (cursor-in-echo-area t))
870 (while (progn (message "%s%s"
871 prompt
872 (make-string (length pass) ?.))
acc81368 873 (setq c (read-char nil t))
44071d6b
RS
874 (and (/= c ?\r) (/= c ?\n) (/= c ?\e)))
875 (if (= c ?\C-u)
876 (setq pass "")
877 (if (and (/= c ?\b) (/= c ?\177))
878 (setq pass (concat pass (char-to-string c)))
879 (if (> (length pass) 0)
880 (setq pass (substring pass 0 -1))))))
881 (message nil)
882 (or pass default ""))))
e0e4cb7a 883\f
9a5336ae
JB
884(defun force-mode-line-update (&optional all)
885 "Force the mode-line of the current buffer to be redisplayed.
7ec2a18c 886With optional non-nil ALL, force redisplay of all mode-lines."
9a5336ae
JB
887 (if all (save-excursion (set-buffer (other-buffer))))
888 (set-buffer-modified-p (buffer-modified-p)))
889
be9b65ac
DL
890(defun momentary-string-display (string pos &optional exit-char message)
891 "Momentarily display STRING in the buffer at POS.
892Display remains until next character is typed.
893If the char is EXIT-CHAR (optional third arg, default is SPC) it is swallowed;
894otherwise it is then available as input (as a command if nothing else).
895Display MESSAGE (optional fourth arg) in the echo area.
896If MESSAGE is nil, instructions to type EXIT-CHAR are displayed there."
897 (or exit-char (setq exit-char ?\ ))
c306e0e0 898 (let ((inhibit-read-only t)
ca2ec1c5
RS
899 ;; Don't modify the undo list at all.
900 (buffer-undo-list t)
be9b65ac
DL
901 (modified (buffer-modified-p))
902 (name buffer-file-name)
903 insert-end)
904 (unwind-protect
905 (progn
906 (save-excursion
907 (goto-char pos)
908 ;; defeat file locking... don't try this at home, kids!
909 (setq buffer-file-name nil)
910 (insert-before-markers string)
3eec84bf
RS
911 (setq insert-end (point))
912 ;; If the message end is off screen, recenter now.
024ae2c6 913 (if (< (window-end nil t) insert-end)
3eec84bf
RS
914 (recenter (/ (window-height) 2)))
915 ;; If that pushed message start off the screen,
916 ;; scroll to start it at the top of the screen.
917 (move-to-window-line 0)
918 (if (> (point) pos)
919 (progn
920 (goto-char pos)
921 (recenter 0))))
be9b65ac
DL
922 (message (or message "Type %s to continue editing.")
923 (single-key-description exit-char))
3547c855 924 (let ((char (read-event)))
be9b65ac 925 (or (eq char exit-char)
dbc4e1c1 926 (setq unread-command-events (list char)))))
be9b65ac
DL
927 (if insert-end
928 (save-excursion
929 (delete-region pos insert-end)))
930 (setq buffer-file-name name)
931 (set-buffer-modified-p modified))))
932
9a5336ae
JB
933\f
934;;;; Miscellanea.
935
448b61c9
RS
936;; A number of major modes set this locally.
937;; Give it a global value to avoid compiler warnings.
938(defvar font-lock-defaults nil)
939
4fb17037
RS
940(defvar suspend-hook nil
941 "Normal hook run by `suspend-emacs', before suspending.")
942
943(defvar suspend-resume-hook nil
944 "Normal hook run by `suspend-emacs', after Emacs is continued.")
945
448b61c9
RS
946;; Avoid compiler warnings about this variable,
947;; which has a special meaning on certain system types.
948(defvar buffer-file-type nil
949 "Non-nil if the visited file is a binary file.
950This variable is meaningful on MS-DOG and Windows NT.
951On those systems, it is automatically local in every buffer.
952On other systems, this variable is normally always nil.")
953
a860d25f 954;; This should probably be written in C (i.e., without using `walk-windows').
63503b24 955(defun get-buffer-window-list (buffer &optional minibuf frame)
a860d25f 956 "Return windows currently displaying BUFFER, or nil if none.
63503b24 957See `walk-windows' for the meaning of MINIBUF and FRAME."
43c5ac8c 958 (let ((buffer (if (bufferp buffer) buffer (get-buffer buffer))) windows)
a860d25f
SM
959 (walk-windows (function (lambda (window)
960 (if (eq (window-buffer window) buffer)
961 (setq windows (cons window windows)))))
63503b24 962 minibuf frame)
a860d25f
SM
963 windows))
964
f9269e19
RS
965(defun ignore (&rest ignore)
966 "Do nothing and return nil.
967This function accepts any number of arguments, but ignores them."
c0f1a4f6 968 (interactive)
9a5336ae
JB
969 nil)
970
971(defun error (&rest args)
aa308ce2
RS
972 "Signal an error, making error message by passing all args to `format'.
973In Emacs, the convention is that error messages start with a capital
974letter but *do not* end with a period. Please follow this convention
975for the sake of consistency."
9a5336ae
JB
976 (while t
977 (signal 'error (list (apply 'format args)))))
978
cef7ae6e 979(defalias 'user-original-login-name 'user-login-name)
9a5336ae 980
be9b65ac
DL
981(defun start-process-shell-command (name buffer &rest args)
982 "Start a program in a subprocess. Return the process object for it.
983Args are NAME BUFFER COMMAND &rest COMMAND-ARGS.
984NAME is name for process. It is modified if necessary to make it unique.
985BUFFER is the buffer or (buffer-name) to associate with the process.
986 Process output goes at end of that buffer, unless you specify
987 an output stream or filter function to handle the output.
988 BUFFER may be also nil, meaning that this process is not associated
989 with any buffer
990Third arg is command name, the name of a shell command.
991Remaining arguments are the arguments for the command.
4f1d6310 992Wildcards and redirection are handled as usual in the shell."
a247bf21
KH
993 (cond
994 ((eq system-type 'vax-vms)
995 (apply 'start-process name buffer args))
b59f6d7a
RS
996 ;; We used to use `exec' to replace the shell with the command,
997 ;; but that failed to handle (...) and semicolon, etc.
a247bf21
KH
998 (t
999 (start-process name buffer shell-file-name shell-command-switch
b59f6d7a 1000 (mapconcat 'identity args " ")))))
a7ed4c2a 1001\f
a7f284ec
RS
1002(defmacro with-current-buffer (buffer &rest body)
1003 "Execute the forms in BODY with BUFFER as the current buffer.
a2fdb55c
EN
1004The value returned is the value of the last form in BODY.
1005See also `with-temp-buffer'."
ce87039d
SM
1006 (cons 'save-current-buffer
1007 (cons (list 'set-buffer buffer)
1008 body)))
a7f284ec 1009
e5bb8a8c
SM
1010(defmacro with-temp-file (file &rest body)
1011 "Create a new buffer, evaluate BODY there, and write the buffer to FILE.
1012The value returned is the value of the last form in BODY.
a2fdb55c 1013See also `with-temp-buffer'."
a7ed4c2a 1014 (let ((temp-file (make-symbol "temp-file"))
a2fdb55c
EN
1015 (temp-buffer (make-symbol "temp-buffer")))
1016 `(let ((,temp-file ,file)
1017 (,temp-buffer
1018 (get-buffer-create (generate-new-buffer-name " *temp file*"))))
1019 (unwind-protect
1020 (prog1
1021 (with-current-buffer ,temp-buffer
e5bb8a8c 1022 ,@body)
a2fdb55c
EN
1023 (with-current-buffer ,temp-buffer
1024 (widen)
1025 (write-region (point-min) (point-max) ,temp-file nil 0)))
1026 (and (buffer-name ,temp-buffer)
1027 (kill-buffer ,temp-buffer))))))
1028
e5bb8a8c 1029(defmacro with-temp-message (message &rest body)
a600effe 1030 "Display MESSAGE temporarily if non-nil while BODY is evaluated.
e5bb8a8c
SM
1031The original message is restored to the echo area after BODY has finished.
1032The value returned is the value of the last form in BODY.
a600effe
SM
1033MESSAGE is written to the message log buffer if `message-log-max' is non-nil.
1034If MESSAGE is nil, the echo area and message log buffer are unchanged.
1035Use a MESSAGE of \"\" to temporarily clear the echo area."
110201c8
SM
1036 (let ((current-message (make-symbol "current-message"))
1037 (temp-message (make-symbol "with-temp-message")))
1038 `(let ((,temp-message ,message)
1039 (,current-message))
e5bb8a8c
SM
1040 (unwind-protect
1041 (progn
110201c8
SM
1042 (when ,temp-message
1043 (setq ,current-message (current-message))
aadf7ff3 1044 (message "%s" ,temp-message))
e5bb8a8c 1045 ,@body)
75545902
KH
1046 (and ,temp-message ,current-message
1047 (message "%s" ,current-message))))))
e5bb8a8c
SM
1048
1049(defmacro with-temp-buffer (&rest body)
1050 "Create a temporary buffer, and evaluate BODY there like `progn'.
a2fdb55c
EN
1051See also `with-temp-file' and `with-output-to-string'."
1052 (let ((temp-buffer (make-symbol "temp-buffer")))
1053 `(let ((,temp-buffer
1054 (get-buffer-create (generate-new-buffer-name " *temp*"))))
1055 (unwind-protect
1056 (with-current-buffer ,temp-buffer
e5bb8a8c 1057 ,@body)
a2fdb55c
EN
1058 (and (buffer-name ,temp-buffer)
1059 (kill-buffer ,temp-buffer))))))
1060
5db7925d
RS
1061(defmacro with-output-to-string (&rest body)
1062 "Execute BODY, return the text it sent to `standard-output', as a string."
a2fdb55c
EN
1063 `(let ((standard-output
1064 (get-buffer-create (generate-new-buffer-name " *string-output*"))))
5db7925d
RS
1065 (let ((standard-output standard-output))
1066 ,@body)
a2fdb55c
EN
1067 (with-current-buffer standard-output
1068 (prog1
1069 (buffer-string)
1070 (kill-buffer nil)))))
2ec9c94e
RS
1071
1072(defmacro combine-after-change-calls (&rest body)
1073 "Execute BODY, but don't call the after-change functions till the end.
1074If BODY makes changes in the buffer, they are recorded
1075and the functions on `after-change-functions' are called several times
1076when BODY is finished.
31aa282e 1077The return value is the value of the last form in BODY.
2ec9c94e
RS
1078
1079If `before-change-functions' is non-nil, then calls to the after-change
1080functions can't be deferred, so in that case this macro has no effect.
1081
1082Do not alter `after-change-functions' or `before-change-functions'
1083in BODY."
1084 `(unwind-protect
1085 (let ((combine-after-change-calls t))
1086 . ,body)
1087 (combine-after-change-execute)))
1088
7e8539cc
RS
1089(defmacro with-syntax-table (table &rest body)
1090 "Evaluate BODY with syntax table of current buffer set to a copy of TABLE.
1091The syntax table of the current buffer is saved, BODY is evaluated, and the
1092saved table is restored, even in case of an abnormal exit.
1093Value is what BODY returns."
1094 (let ((old-table (gensym))
1095 (old-buffer (gensym)))
1096 `(let ((,old-table (syntax-table))
1097 (,old-buffer (current-buffer)))
1098 (unwind-protect
1099 (progn
1100 (set-syntax-table (copy-syntax-table ,table))
1101 ,@body)
1102 (save-current-buffer
1103 (set-buffer ,old-buffer)
1104 (set-syntax-table ,old-table))))))
a2fdb55c 1105\f
c7ca41e6
RS
1106(defvar save-match-data-internal)
1107
1108;; We use save-match-data-internal as the local variable because
1109;; that works ok in practice (people should not use that variable elsewhere).
1110;; We used to use an uninterned symbol; the compiler handles that properly
1111;; now, but it generates slower code.
9a5336ae
JB
1112(defmacro save-match-data (&rest body)
1113 "Execute the BODY forms, restoring the global value of the match data."
64ed733a
PE
1114 ;; It is better not to use backquote here,
1115 ;; because that makes a bootstrapping problem
1116 ;; if you need to recompile all the Lisp files using interpreted code.
1117 (list 'let
1118 '((save-match-data-internal (match-data)))
1119 (list 'unwind-protect
1120 (cons 'progn body)
1121 '(set-match-data save-match-data-internal))))
993713ce 1122
cd323f89 1123(defun match-string (num &optional string)
993713ce
SM
1124 "Return string of text matched by last search.
1125NUM specifies which parenthesized expression in the last regexp.
1126 Value is nil if NUMth pair didn't match, or there were less than NUM pairs.
1127Zero means the entire text matched by the whole regexp or whole string.
1128STRING should be given if the last search was by `string-match' on STRING."
cd323f89
SM
1129 (if (match-beginning num)
1130 (if string
1131 (substring string (match-beginning num) (match-end num))
1132 (buffer-substring (match-beginning num) (match-end num)))))
58f950b4 1133
bb760c71
RS
1134(defun match-string-no-properties (num &optional string)
1135 "Return string of text matched by last search, without text properties.
1136NUM specifies which parenthesized expression in the last regexp.
1137 Value is nil if NUMth pair didn't match, or there were less than NUM pairs.
1138Zero means the entire text matched by the whole regexp or whole string.
1139STRING should be given if the last search was by `string-match' on STRING."
1140 (if (match-beginning num)
1141 (if string
1142 (let ((result
1143 (substring string (match-beginning num) (match-end num))))
1144 (set-text-properties 0 (length result) nil result)
1145 result)
1146 (buffer-substring-no-properties (match-beginning num)
1147 (match-end num)))))
1148
edce3654
RS
1149(defun split-string (string &optional separators)
1150 "Splits STRING into substrings where there are matches for SEPARATORS.
1151Each match for SEPARATORS is a splitting point.
1152The substrings between the splitting points are made into a list
1153which is returned.
b222b786
RS
1154If SEPARATORS is absent, it defaults to \"[ \\f\\t\\n\\r\\v]+\".
1155
1156If there is match for SEPARATORS at the beginning of STRING, we do not
1157include a null substring for that. Likewise, if there is a match
1158at the end of STRING, we don't include a null substring for that."
edce3654
RS
1159 (let ((rexp (or separators "[ \f\t\n\r\v]+"))
1160 (start 0)
b222b786 1161 notfirst
edce3654 1162 (list nil))
b222b786
RS
1163 (while (and (string-match rexp string
1164 (if (and notfirst
1165 (= start (match-beginning 0))
1166 (< start (length string)))
1167 (1+ start) start))
1168 (< (match-beginning 0) (length string)))
1169 (setq notfirst t)
7eb47123 1170 (or (eq (match-beginning 0) 0)
b222b786
RS
1171 (and (eq (match-beginning 0) (match-end 0))
1172 (eq (match-beginning 0) start))
edce3654
RS
1173 (setq list
1174 (cons (substring string start (match-beginning 0))
1175 list)))
1176 (setq start (match-end 0)))
1177 (or (eq start (length string))
1178 (setq list
1179 (cons (substring string start)
1180 list)))
1181 (nreverse list)))
1ccaea52
AI
1182
1183(defun subst-char-in-string (fromchar tochar string &optional inplace)
1184 "Replace FROMCHAR with TOCHAR in STRING each time it occurs.
1185Unless optional argument INPLACE is non-nil, return a new string."
1186 (let ((i (length string))
1187 (newstr (if inplace string (copy-sequence string))))
1188 (while (> i 0)
1189 (setq i (1- i))
1190 (if (eq (aref newstr i) fromchar)
1191 (aset newstr i tochar)))
1192 newstr))
a7ed4c2a 1193\f
8af7df60
RS
1194(defun shell-quote-argument (argument)
1195 "Quote an argument for passing as argument to an inferior shell."
c1c74b43 1196 (if (eq system-type 'ms-dos)
8ee75d03
EZ
1197 ;; Quote using double quotes, but escape any existing quotes in
1198 ;; the argument with backslashes.
1199 (let ((result "")
1200 (start 0)
1201 end)
1202 (if (or (null (string-match "[^\"]" argument))
1203 (< (match-end 0) (length argument)))
1204 (while (string-match "[\"]" argument start)
1205 (setq end (match-beginning 0)
1206 result (concat result (substring argument start end)
1207 "\\" (substring argument end (1+ end)))
1208 start (1+ end))))
1209 (concat "\"" result (substring argument start) "\""))
c1c74b43
RS
1210 (if (eq system-type 'windows-nt)
1211 (concat "\"" argument "\"")
e1b65a6b
RS
1212 (if (equal argument "")
1213 "''"
1214 ;; Quote everything except POSIX filename characters.
1215 ;; This should be safe enough even for really weird shells.
1216 (let ((result "") (start 0) end)
1217 (while (string-match "[^-0-9a-zA-Z_./]" argument start)
1218 (setq end (match-beginning 0)
1219 result (concat result (substring argument start end)
1220 "\\" (substring argument end (1+ end)))
1221 start (1+ end)))
1222 (concat result (substring argument start)))))))
8af7df60 1223
297d863b 1224(defun make-syntax-table (&optional oldtable)
984f718a 1225 "Return a new syntax table.
888eb98e
RS
1226If OLDTABLE is non-nil, copy OLDTABLE.
1227Otherwise, create a syntax table which inherits
1228all letters and control characters from the standard syntax table;
1229other characters are copied from the standard syntax table."
297d863b
KH
1230 (if oldtable
1231 (copy-syntax-table oldtable)
1232 (let ((table (copy-syntax-table))
1233 i)
1234 (setq i 0)
1235 (while (<= i 31)
a6889c57 1236 (aset table i nil)
297d863b
KH
1237 (setq i (1+ i)))
1238 (setq i ?A)
1239 (while (<= i ?Z)
a6889c57 1240 (aset table i nil)
297d863b
KH
1241 (setq i (1+ i)))
1242 (setq i ?a)
1243 (while (<= i ?z)
a6889c57 1244 (aset table i nil)
297d863b
KH
1245 (setq i (1+ i)))
1246 (setq i 128)
1247 (while (<= i 255)
a6889c57 1248 (aset table i nil)
297d863b
KH
1249 (setq i (1+ i)))
1250 table)))
31aa282e
KH
1251
1252(defun add-to-invisibility-spec (arg)
1253 "Add elements to `buffer-invisibility-spec'.
1254See documentation for `buffer-invisibility-spec' for the kind of elements
1255that can be added."
1256 (cond
1257 ((or (null buffer-invisibility-spec) (eq buffer-invisibility-spec t))
1258 (setq buffer-invisibility-spec (list arg)))
1259 (t
11d431ad
KH
1260 (setq buffer-invisibility-spec
1261 (cons arg buffer-invisibility-spec)))))
31aa282e
KH
1262
1263(defun remove-from-invisibility-spec (arg)
1264 "Remove elements from `buffer-invisibility-spec'."
e93b8cbb 1265 (if (consp buffer-invisibility-spec)
071a2a71 1266 (setq buffer-invisibility-spec (delete arg buffer-invisibility-spec))))
baed0109
RS
1267\f
1268(defun global-set-key (key command)
1269 "Give KEY a global binding as COMMAND.
7bba1895
KH
1270COMMAND is the command definition to use; usually it is
1271a symbol naming an interactively-callable function.
1272KEY is a key sequence; noninteractively, it is a string or vector
1273of characters or event types, and non-ASCII characters with codes
1274above 127 (such as ISO Latin-1) can be included if you use a vector.
1275
1276Note that if KEY has a local binding in the current buffer,
1277that local binding will continue to shadow any global binding
1278that you make with this function."
baed0109
RS
1279 (interactive "KSet key globally: \nCSet key %s to command: ")
1280 (or (vectorp key) (stringp key)
1281 (signal 'wrong-type-argument (list 'arrayp key)))
ff663bbe 1282 (define-key (current-global-map) key command))
baed0109
RS
1283
1284(defun local-set-key (key command)
1285 "Give KEY a local binding as COMMAND.
7bba1895
KH
1286COMMAND is the command definition to use; usually it is
1287a symbol naming an interactively-callable function.
1288KEY is a key sequence; noninteractively, it is a string or vector
1289of characters or event types, and non-ASCII characters with codes
1290above 127 (such as ISO Latin-1) can be included if you use a vector.
1291
baed0109
RS
1292The binding goes in the current buffer's local map,
1293which in most cases is shared with all other buffers in the same major mode."
1294 (interactive "KSet key locally: \nCSet key %s locally to command: ")
1295 (let ((map (current-local-map)))
1296 (or map
1297 (use-local-map (setq map (make-sparse-keymap))))
1298 (or (vectorp key) (stringp key)
1299 (signal 'wrong-type-argument (list 'arrayp key)))
ff663bbe 1300 (define-key map key command)))
984f718a 1301
baed0109
RS
1302(defun global-unset-key (key)
1303 "Remove global binding of KEY.
1304KEY is a string representing a sequence of keystrokes."
1305 (interactive "kUnset key globally: ")
1306 (global-set-key key nil))
1307
db2474b8 1308(defun local-unset-key (key)
baed0109
RS
1309 "Remove local binding of KEY.
1310KEY is a string representing a sequence of keystrokes."
1311 (interactive "kUnset key locally: ")
1312 (if (current-local-map)
db2474b8 1313 (local-set-key key nil))
baed0109
RS
1314 nil)
1315\f
4809d0dd
KH
1316;; We put this here instead of in frame.el so that it's defined even on
1317;; systems where frame.el isn't loaded.
1318(defun frame-configuration-p (object)
1319 "Return non-nil if OBJECT seems to be a frame configuration.
1320Any list whose car is `frame-configuration' is assumed to be a frame
1321configuration."
1322 (and (consp object)
1323 (eq (car object) 'frame-configuration)))
1324
a9a44ed1 1325(defun functionp (object)
77a5664f 1326 "Non-nil if OBJECT is a type of object that can be called as a function."
c029995c 1327 (or (subrp object) (byte-code-function-p object)
a9a44ed1
RS
1328 (eq (car-safe object) 'lambda)
1329 (and (symbolp object) (fboundp object))))
1330
9a5336ae
JB
1331;; now in fns.c
1332;(defun nth (n list)
1333; "Returns the Nth element of LIST.
1334;N counts from zero. If LIST is not that long, nil is returned."
1335; (car (nthcdr n list)))
1336;
1337;(defun copy-alist (alist)
1338; "Return a copy of ALIST.
1339;This is a new alist which represents the same mapping
1340;from objects to objects, but does not share the alist structure with ALIST.
1341;The objects mapped (cars and cdrs of elements of the alist)
1342;are shared, however."
1343; (setq alist (copy-sequence alist))
1344; (let ((tail alist))
1345; (while tail
1346; (if (consp (car tail))
1347; (setcar tail (cons (car (car tail)) (cdr (car tail)))))
1348; (setq tail (cdr tail))))
1349; alist)
630cc463 1350
a62d6695
DL
1351(defun assoc-delete-all (key alist)
1352 "Delete from ALIST all elements whose car is KEY.
1353Return the modified alist."
1354 (setq alist (copy-sequence alist))
1355 (let ((tail alist))
1356 (while tail
1357 (if (eq (car (car tail)) key)
1358 (setq alist (delq (car tail) alist)))
1359 (setq tail (cdr tail)))
1360 alist))
1361
cdd9f643
RS
1362(defun make-temp-file (prefix &optional dir-flag)
1363 "Create a temporary file.
1364The returned file name (created by appending some random characters at the end
1365of PREFIX, and expanding against `temporary-file-directory' if necessary,
1366is guaranteed to point to a newly created empty file.
1367You can then use `write-region' to write new data into the file.
1368
1369If DIR-FLAG is non-nil, create a new empty directory instead of a file."
1370 (let (file)
1371 (while (condition-case ()
1372 (progn
1373 (setq file
1374 (make-temp-name
1375 (expand-file-name prefix temporary-file-directory)))
1376 (if dir-flag
1377 (make-directory file)
1378 (write-region "" nil file nil 'silent nil 'excl))
1379 nil)
1380 (file-already-exists t))
1381 ;; the file was somehow created by someone else between
1382 ;; `make-temp-name' and `write-region', let's try again.
1383 nil)
1384 file))
1385
630cc463 1386;;; subr.el ends here