*** empty log message ***
[bpt/emacs.git] / lisp / subr.el
CommitLineData
c88ab9ce 1;;; subr.el --- basic lisp subroutines for Emacs
630cc463 2
b021ef18 3;; Copyright (C) 1985, 86, 92, 94, 95, 99, 2000 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 69(defmacro when (cond &rest body)
b021ef18 70 "If COND yields non-nil, do BODY, else return nil."
debff3c3 71 (list 'if cond (cons 'progn body)))
9a5336ae 72
debff3c3 73(defmacro unless (cond &rest body)
b021ef18 74 "If COND yields nil, do BODY, else return nil."
debff3c3 75 (cons 'if (cons cond (cons nil body))))
d370591d 76
a0b0756a
RS
77(defmacro dolist (spec &rest body)
78 "(dolist (VAR LIST [RESULT]) BODY...): loop over a list.
79Evaluate BODY with VAR bound to each car from LIST, in turn.
80Then evaluate RESULT to get return value, default nil."
e4295aa1
RS
81 (let ((temp (make-symbol "--dolist-temp--")))
82 (list 'let (list (list temp (nth 1 spec)) (car spec))
83 (list 'while temp
84 (list 'setq (car spec) (list 'car temp))
85 (cons 'progn
86 (append body
87 (list (list 'setq temp (list 'cdr temp))))))
88 (if (cdr (cdr spec))
89 (cons 'progn
90 (cons (list 'setq (car spec) nil) (cdr (cdr spec))))))))
a0b0756a
RS
91
92(defmacro dotimes (spec &rest body)
93 "(dotimes (VAR COUNT [RESULT]) BODY...): loop a certain number of times.
94Evaluate BODY with VAR bound to successive integers running from 0,
95inclusive, to COUNT, exclusive. Then evaluate RESULT to get
96the return value (nil if RESULT is omitted)."
e4295aa1
RS
97 (let ((temp (make-symbol "--dotimes-temp--")))
98 (list 'let (list (list temp (nth 1 spec)) (list (car spec) 0))
99 (list 'while (list '< (car spec) temp)
100 (cons 'progn
101 (append body (list (list 'setq (car spec)
102 (list '1+ (car spec)))))))
103 (if (cdr (cdr spec))
104 (car (cdr (cdr spec)))
105 nil))))
a0b0756a 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
4ced66fd 342(defun define-key-after (keymap key definition &optional 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
4ced66fd 349If AFTER is t or omitted, the new binding goes at the end of the keymap.
c34a9d34 350
4ced66fd
DL
351KEY must contain just one event type--that is to say, it must be a
352string or vector of length 1, but AFTER should be a single event
353type--a symbol or a character, not a sequence.
c34a9d34 354
4ced66fd 355Bindings are always added before any inherited map.
c34a9d34 356
4ced66fd
DL
357The order of bindings in a keymap matters when it is used as a menu."
358 (unless after (setq after t))
4434d61b
RS
359 (or (keymapp keymap)
360 (signal 'wrong-type-argument (list 'keymapp keymap)))
ab375e6c 361 (if (> (length key) 1)
626f67f3 362 (error "multi-event key specified in `define-key-after'"))
113d28a8 363 (let ((tail keymap) done inserted
4434d61b
RS
364 (first (aref key 0)))
365 (while (and (not done) tail)
366 ;; Delete any earlier bindings for the same key.
367 (if (eq (car-safe (car (cdr tail))) first)
368 (setcdr tail (cdr (cdr tail))))
369 ;; When we reach AFTER's binding, insert the new binding after.
370 ;; If we reach an inherited keymap, insert just before that.
113d28a8 371 ;; If we reach the end of this keymap, insert at the end.
c34a9d34
RS
372 (if (or (and (eq (car-safe (car tail)) after)
373 (not (eq after t)))
113d28a8
RS
374 (eq (car (cdr tail)) 'keymap)
375 (null (cdr tail)))
4434d61b 376 (progn
113d28a8
RS
377 ;; Stop the scan only if we find a parent keymap.
378 ;; Keep going past the inserted element
379 ;; so we can delete any duplications that come later.
380 (if (eq (car (cdr tail)) 'keymap)
381 (setq done t))
382 ;; Don't insert more than once.
383 (or inserted
384 (setcdr tail (cons (cons (aref key 0) definition) (cdr tail))))
385 (setq inserted t)))
4434d61b
RS
386 (setq tail (cdr tail)))))
387
d128fe85
RS
388(defmacro kbd (keys)
389 "Convert KEYS to the internal Emacs key representation.
390KEYS should be a string constant in the format used for
391saving keyboard macros (see `insert-kbd-macro')."
392 (read-kbd-macro keys))
393
8bed5e3d
RS
394(put 'keyboard-translate-table 'char-table-extra-slots 0)
395
9a5336ae
JB
396(defun keyboard-translate (from to)
397 "Translate character FROM to TO at a low level.
398This function creates a `keyboard-translate-table' if necessary
399and then modifies one entry in it."
8bed5e3d
RS
400 (or (char-table-p keyboard-translate-table)
401 (setq keyboard-translate-table
402 (make-char-table 'keyboard-translate-table nil)))
9a5336ae
JB
403 (aset keyboard-translate-table from to))
404
405\f
406;;;; The global keymap tree.
407
408;;; global-map, esc-map, and ctl-x-map have their values set up in
409;;; keymap.c; we just give them docstrings here.
410
411(defvar global-map nil
412 "Default global keymap mapping Emacs keyboard input into commands.
413The value is a keymap which is usually (but not necessarily) Emacs's
414global map.")
415
416(defvar esc-map nil
417 "Default keymap for ESC (meta) commands.
418The normal global definition of the character ESC indirects to this keymap.")
419
420(defvar ctl-x-map nil
421 "Default keymap for C-x commands.
422The normal global definition of the character C-x indirects to this keymap.")
423
424(defvar ctl-x-4-map (make-sparse-keymap)
425 "Keymap for subcommands of C-x 4")
059184dd 426(defalias 'ctl-x-4-prefix ctl-x-4-map)
9a5336ae
JB
427(define-key ctl-x-map "4" 'ctl-x-4-prefix)
428
429(defvar ctl-x-5-map (make-sparse-keymap)
430 "Keymap for frame commands.")
059184dd 431(defalias 'ctl-x-5-prefix ctl-x-5-map)
9a5336ae
JB
432(define-key ctl-x-map "5" 'ctl-x-5-prefix)
433
0f03054a 434\f
9a5336ae
JB
435;;;; Event manipulation functions.
436
da16e648
KH
437;; The call to `read' is to ensure that the value is computed at load time
438;; and not compiled into the .elc file. The value is negative on most
439;; machines, but not on all!
440(defconst listify-key-sequence-1 (logior 128 (read "?\\M-\\^@")))
114137b8 441
cde6d7e3
RS
442(defun listify-key-sequence (key)
443 "Convert a key sequence to a list of events."
444 (if (vectorp key)
445 (append key nil)
446 (mapcar (function (lambda (c)
447 (if (> c 127)
114137b8 448 (logxor c listify-key-sequence-1)
cde6d7e3
RS
449 c)))
450 (append key nil))))
451
53e5a4e8
RS
452(defsubst eventp (obj)
453 "True if the argument is an event object."
454 (or (integerp obj)
455 (and (symbolp obj)
456 (get obj 'event-symbol-elements))
457 (and (consp obj)
458 (symbolp (car obj))
459 (get (car obj) 'event-symbol-elements))))
460
461(defun event-modifiers (event)
462 "Returns a list of symbols representing the modifier keys in event EVENT.
463The elements of the list may include `meta', `control',
32295976
RS
464`shift', `hyper', `super', `alt', `click', `double', `triple', `drag',
465and `down'."
53e5a4e8
RS
466 (let ((type event))
467 (if (listp type)
468 (setq type (car type)))
469 (if (symbolp type)
470 (cdr (get type 'event-symbol-elements))
471 (let ((list nil))
da16e648 472 (or (zerop (logand type ?\M-\^@))
53e5a4e8 473 (setq list (cons 'meta list)))
da16e648 474 (or (and (zerop (logand type ?\C-\^@))
53e5a4e8
RS
475 (>= (logand type 127) 32))
476 (setq list (cons 'control list)))
da16e648 477 (or (and (zerop (logand type ?\S-\^@))
53e5a4e8
RS
478 (= (logand type 255) (downcase (logand type 255))))
479 (setq list (cons 'shift list)))
da16e648 480 (or (zerop (logand type ?\H-\^@))
53e5a4e8 481 (setq list (cons 'hyper list)))
da16e648 482 (or (zerop (logand type ?\s-\^@))
53e5a4e8 483 (setq list (cons 'super list)))
da16e648 484 (or (zerop (logand type ?\A-\^@))
53e5a4e8
RS
485 (setq list (cons 'alt list)))
486 list))))
487
d63de416
RS
488(defun event-basic-type (event)
489 "Returns the basic type of the given event (all modifiers removed).
490The value is an ASCII printing character (not upper case) or a symbol."
2b0f4ba5
JB
491 (if (consp event)
492 (setq event (car event)))
d63de416
RS
493 (if (symbolp event)
494 (car (get event 'event-symbol-elements))
495 (let ((base (logand event (1- (lsh 1 18)))))
496 (downcase (if (< base 32) (logior base 64) base)))))
497
0f03054a
RS
498(defsubst mouse-movement-p (object)
499 "Return non-nil if OBJECT is a mouse movement event."
500 (and (consp object)
501 (eq (car object) 'mouse-movement)))
502
503(defsubst event-start (event)
504 "Return the starting position of EVENT.
505If EVENT is a mouse press or a mouse click, this returns the location
506of the event.
507If EVENT is a drag, this returns the drag's starting position.
508The return value is of the form
e55c21be 509 (WINDOW BUFFER-POSITION (X . Y) TIMESTAMP)
0f03054a
RS
510The `posn-' functions access elements of such lists."
511 (nth 1 event))
512
513(defsubst event-end (event)
514 "Return the ending location of EVENT. EVENT should be a click or drag event.
515If EVENT is a click event, this function is the same as `event-start'.
516The return value is of the form
e55c21be 517 (WINDOW BUFFER-POSITION (X . Y) TIMESTAMP)
0f03054a 518The `posn-' functions access elements of such lists."
69b95560 519 (nth (if (consp (nth 2 event)) 2 1) event))
0f03054a 520
32295976
RS
521(defsubst event-click-count (event)
522 "Return the multi-click count of EVENT, a click or drag event.
523The return value is a positive integer."
524 (if (integerp (nth 2 event)) (nth 2 event) 1))
525
0f03054a
RS
526(defsubst posn-window (position)
527 "Return the window in POSITION.
528POSITION should be a list of the form
e55c21be 529 (WINDOW BUFFER-POSITION (X . Y) TIMESTAMP)
0f03054a
RS
530as returned by the `event-start' and `event-end' functions."
531 (nth 0 position))
532
533(defsubst posn-point (position)
534 "Return the buffer location in POSITION.
535POSITION should be a list of the form
e55c21be 536 (WINDOW BUFFER-POSITION (X . Y) TIMESTAMP)
0f03054a 537as returned by the `event-start' and `event-end' functions."
15db4e0e
JB
538 (if (consp (nth 1 position))
539 (car (nth 1 position))
540 (nth 1 position)))
0f03054a 541
e55c21be
RS
542(defsubst posn-x-y (position)
543 "Return the x and y coordinates in POSITION.
0f03054a 544POSITION should be a list of the form
e55c21be 545 (WINDOW BUFFER-POSITION (X . Y) TIMESTAMP)
0f03054a
RS
546as returned by the `event-start' and `event-end' functions."
547 (nth 2 position))
548
ed627e08 549(defun posn-col-row (position)
dbbcac56 550 "Return the column and row in POSITION, measured in characters.
e55c21be
RS
551POSITION should be a list of the form
552 (WINDOW BUFFER-POSITION (X . Y) TIMESTAMP)
ed627e08
RS
553as returned by the `event-start' and `event-end' functions.
554For a scroll-bar event, the result column is 0, and the row
555corresponds to the vertical position of the click in the scroll bar."
556 (let ((pair (nth 2 position))
557 (window (posn-window position)))
dbbcac56
KH
558 (if (eq (if (consp (nth 1 position))
559 (car (nth 1 position))
560 (nth 1 position))
ed627e08
RS
561 'vertical-scroll-bar)
562 (cons 0 (scroll-bar-scale pair (1- (window-height window))))
dbbcac56
KH
563 (if (eq (if (consp (nth 1 position))
564 (car (nth 1 position))
565 (nth 1 position))
ed627e08
RS
566 'horizontal-scroll-bar)
567 (cons (scroll-bar-scale pair (window-width window)) 0)
9ba60df9
RS
568 (let* ((frame (if (framep window) window (window-frame window)))
569 (x (/ (car pair) (frame-char-width frame)))
570 (y (/ (cdr pair) (frame-char-height frame))))
ed627e08 571 (cons x y))))))
e55c21be 572
0f03054a
RS
573(defsubst posn-timestamp (position)
574 "Return the timestamp of POSITION.
575POSITION should be a list of the form
e55c21be 576 (WINDOW BUFFER-POSITION (X . Y) TIMESTAMP)
f415c00c 577as returned by the `event-start' and `event-end' functions."
0f03054a 578 (nth 3 position))
9a5336ae 579
0f03054a 580\f
9a5336ae
JB
581;;;; Obsolescent names for functions.
582
059184dd
ER
583(defalias 'dot 'point)
584(defalias 'dot-marker 'point-marker)
585(defalias 'dot-min 'point-min)
586(defalias 'dot-max 'point-max)
587(defalias 'window-dot 'window-point)
588(defalias 'set-window-dot 'set-window-point)
589(defalias 'read-input 'read-string)
590(defalias 'send-string 'process-send-string)
591(defalias 'send-region 'process-send-region)
592(defalias 'show-buffer 'set-window-buffer)
593(defalias 'buffer-flush-undo 'buffer-disable-undo)
594(defalias 'eval-current-buffer 'eval-buffer)
595(defalias 'compiled-function-p 'byte-code-function-p)
ae1cc031 596(defalias 'define-function 'defalias)
be9b65ac 597
0cba3a0f
KH
598(defalias 'sref 'aref)
599(make-obsolete 'sref 'aref)
600(make-obsolete 'char-bytes "Now this function always returns 1")
6bb762b3 601
9a5336ae
JB
602;; Some programs still use this as a function.
603(defun baud-rate ()
bcacc42c
RS
604 "Obsolete function returning the value of the `baud-rate' variable.
605Please convert your programs to use the variable `baud-rate' directly."
9a5336ae
JB
606 baud-rate)
607
0a5c0893
MB
608(defalias 'focus-frame 'ignore)
609(defalias 'unfocus-frame 'ignore)
9a5336ae
JB
610\f
611;;;; Alternate names for functions - these are not being phased out.
612
059184dd
ER
613(defalias 'string= 'string-equal)
614(defalias 'string< 'string-lessp)
615(defalias 'move-marker 'set-marker)
059184dd
ER
616(defalias 'not 'null)
617(defalias 'rplaca 'setcar)
618(defalias 'rplacd 'setcdr)
eb8c3be9 619(defalias 'beep 'ding) ;preserve lingual purity
059184dd
ER
620(defalias 'indent-to-column 'indent-to)
621(defalias 'backward-delete-char 'delete-backward-char)
622(defalias 'search-forward-regexp (symbol-function 're-search-forward))
623(defalias 'search-backward-regexp (symbol-function 're-search-backward))
624(defalias 'int-to-string 'number-to-string)
024ae2c6 625(defalias 'store-match-data 'set-match-data)
475fb2fb
KH
626(defalias 'point-at-eol 'line-end-position)
627(defalias 'point-at-bol 'line-beginning-position)
37f6661a
JB
628
629;;; Should this be an obsolete name? If you decide it should, you get
630;;; to go through all the sources and change them.
059184dd 631(defalias 'string-to-int 'string-to-number)
be9b65ac 632\f
9a5336ae 633;;;; Hook manipulation functions.
be9b65ac 634
0e4d378b
RS
635(defun make-local-hook (hook)
636 "Make the hook HOOK local to the current buffer.
71c78f01
RS
637The return value is HOOK.
638
0e4d378b
RS
639When a hook is local, its local and global values
640work in concert: running the hook actually runs all the hook
641functions listed in *either* the local value *or* the global value
642of the hook variable.
643
7dd1926e
RS
644This function works by making `t' a member of the buffer-local value,
645which acts as a flag to run the hook functions in the default value as
646well. This works for all normal hooks, but does not work for most
647non-normal hooks yet. We will be changing the callers of non-normal
648hooks so that they can handle localness; this has to be done one by
649one.
650
651This function does nothing if HOOK is already local in the current
652buffer.
0e4d378b
RS
653
654Do not use `make-local-variable' to make a hook variable buffer-local."
655 (if (local-variable-p hook)
656 nil
657 (or (boundp hook) (set hook nil))
658 (make-local-variable hook)
71c78f01
RS
659 (set hook (list t)))
660 hook)
0e4d378b
RS
661
662(defun add-hook (hook function &optional append local)
32295976
RS
663 "Add to the value of HOOK the function FUNCTION.
664FUNCTION is not added if already present.
665FUNCTION is added (if necessary) at the beginning of the hook list
666unless the optional argument APPEND is non-nil, in which case
667FUNCTION is added at the end.
668
0e4d378b
RS
669The optional fourth argument, LOCAL, if non-nil, says to modify
670the hook's buffer-local value rather than its default value.
671This makes no difference if the hook is not buffer-local.
672To make a hook variable buffer-local, always use
673`make-local-hook', not `make-local-variable'.
674
32295976
RS
675HOOK should be a symbol, and FUNCTION may be any valid function. If
676HOOK is void, it is first set to nil. If HOOK's value is a single
aa09b5ca 677function, it is changed to a list of functions."
be9b65ac 678 (or (boundp hook) (set hook nil))
0e4d378b 679 (or (default-boundp hook) (set-default hook nil))
32295976
RS
680 ;; If the hook value is a single function, turn it into a list.
681 (let ((old (symbol-value hook)))
682 (if (or (not (listp old)) (eq (car old) 'lambda))
683 (set hook (list old))))
f4e5bca5
RS
684 (if (or local
685 ;; Detect the case where make-local-variable was used on a hook
686 ;; and do what we used to do.
cd2db344 687 (and (local-variable-if-set-p hook)
f4e5bca5 688 (not (memq t (symbol-value hook)))))
0e4d378b 689 ;; Alter the local value only.
1fa0de2c 690 (or (if (or (consp function) (byte-code-function-p function))
0e4d378b
RS
691 (member function (symbol-value hook))
692 (memq function (symbol-value hook)))
693 (set hook
694 (if append
695 (append (symbol-value hook) (list function))
696 (cons function (symbol-value hook)))))
697 ;; Alter the global value (which is also the only value,
698 ;; if the hook doesn't have a local value).
1fa0de2c 699 (or (if (or (consp function) (byte-code-function-p function))
0e4d378b
RS
700 (member function (default-value hook))
701 (memq function (default-value hook)))
702 (set-default hook
703 (if append
704 (append (default-value hook) (list function))
705 (cons function (default-value hook)))))))
706
707(defun remove-hook (hook function &optional local)
24980d16
RS
708 "Remove from the value of HOOK the function FUNCTION.
709HOOK should be a symbol, and FUNCTION may be any valid function. If
710FUNCTION isn't the value of HOOK, or, if FUNCTION doesn't appear in the
0e4d378b
RS
711list of hooks to run in HOOK, then nothing is done. See `add-hook'.
712
713The optional third argument, LOCAL, if non-nil, says to modify
714the hook's buffer-local value rather than its default value.
715This makes no difference if the hook is not buffer-local.
716To make a hook variable buffer-local, always use
717`make-local-hook', not `make-local-variable'."
24980d16 718 (if (or (not (boundp hook)) ;unbound symbol, or
d46490e3 719 (not (default-boundp hook))
24980d16
RS
720 (null (symbol-value hook)) ;value is nil, or
721 (null function)) ;function is nil, then
722 nil ;Do nothing.
f4e5bca5
RS
723 (if (or local
724 ;; Detect the case where make-local-variable was used on a hook
725 ;; and do what we used to do.
726 (and (local-variable-p hook)
cf4a60a3
DL
727 (consp (symbol-value hook))
728 (not (memq t (symbol-value hook)))))
0e4d378b
RS
729 (let ((hook-value (symbol-value hook)))
730 (if (consp hook-value)
731 (if (member function hook-value)
732 (setq hook-value (delete function (copy-sequence hook-value))))
733 (if (equal hook-value function)
734 (setq hook-value nil)))
735 (set hook hook-value))
736 (let ((hook-value (default-value hook)))
cf4a60a3 737 (if (and (consp hook-value) (not (functionp hook-value)))
0e4d378b
RS
738 (if (member function hook-value)
739 (setq hook-value (delete function (copy-sequence hook-value))))
740 (if (equal hook-value function)
741 (setq hook-value nil)))
742 (set-default hook hook-value)))))
6e3af630
RS
743
744(defun add-to-list (list-var element)
8851c1f0 745 "Add to the value of LIST-VAR the element ELEMENT if it isn't there yet.
9f0b1f09 746The test for presence of ELEMENT is done with `equal'.
508bcbca
RS
747If ELEMENT is added, it is added at the beginning of the list.
748
8851c1f0
RS
749If you want to use `add-to-list' on a variable that is not defined
750until a certain package is loaded, you should put the call to `add-to-list'
751into a hook function that will be run only after loading the package.
752`eval-after-load' provides one way to do this. In some cases
753other hooks, such as major mode hooks, can do the job."
15171a06
KH
754 (if (member element (symbol-value list-var))
755 (symbol-value list-var)
756 (set list-var (cons element (symbol-value list-var)))))
be9b65ac 757\f
9a5336ae
JB
758;;;; Specifying things to do after certain files are loaded.
759
760(defun eval-after-load (file form)
761 "Arrange that, if FILE is ever loaded, FORM will be run at that time.
762This makes or adds to an entry on `after-load-alist'.
90914938 763If FILE is already loaded, evaluate FORM right now.
12c7071c 764It does nothing if FORM is already on the list for FILE.
9a5336ae 765FILE should be the name of a library, with no directory name."
90914938 766 ;; Make sure there is an element for FILE.
9a5336ae
JB
767 (or (assoc file after-load-alist)
768 (setq after-load-alist (cons (list file) after-load-alist)))
90914938 769 ;; Add FORM to the element if it isn't there.
12c7071c
RS
770 (let ((elt (assoc file after-load-alist)))
771 (or (member form (cdr elt))
90914938
RS
772 (progn
773 (nconc elt (list form))
774 ;; If the file has been loaded already, run FORM right away.
775 (and (assoc file load-history)
776 (eval form)))))
9a5336ae
JB
777 form)
778
779(defun eval-next-after-load (file)
780 "Read the following input sexp, and run it whenever FILE is loaded.
781This makes or adds to an entry on `after-load-alist'.
782FILE should be the name of a library, with no directory name."
783 (eval-after-load file (read)))
784
785\f
786;;;; Input and display facilities.
787
77a5664f 788(defvar read-quoted-char-radix 8
1ba764de 789 "*Radix for \\[quoted-insert] and other uses of `read-quoted-char'.
77a5664f
RS
790Legitimate radix values are 8, 10 and 16.")
791
792(custom-declare-variable-early
793 'read-quoted-char-radix 8
794 "*Radix for \\[quoted-insert] and other uses of `read-quoted-char'.
1ba764de
RS
795Legitimate radix values are 8, 10 and 16."
796 :type '(choice (const 8) (const 10) (const 16))
797 :group 'editing-basics)
798
9a5336ae 799(defun read-quoted-char (&optional prompt)
2444730b
RS
800 "Like `read-char', but do not allow quitting.
801Also, if the first character read is an octal digit,
802we read any number of octal digits and return the
569b03f2 803specified character code. Any nondigit terminates the sequence.
1ba764de 804If the terminator is RET, it is discarded;
2444730b
RS
805any other terminator is used itself as input.
806
569b03f2
RS
807The optional argument PROMPT specifies a string to use to prompt the user.
808The variable `read-quoted-char-radix' controls which radix to use
809for numeric input."
2444730b
RS
810 (let ((message-log-max nil) done (first t) (code 0) char)
811 (while (not done)
812 (let ((inhibit-quit first)
42e636f0
KH
813 ;; Don't let C-h get the help message--only help function keys.
814 (help-char nil)
815 (help-form
816 "Type the special character you want to use,
2444730b 817or the octal character code.
1ba764de 818RET terminates the character code and is discarded;
2444730b 819any other non-digit terminates the character code and is then used as input."))
b7de4d62 820 (setq char (read-event (and prompt (format "%s-" prompt)) t))
9a5336ae 821 (if inhibit-quit (setq quit-flag nil)))
4867f7b2
RS
822 ;; Translate TAB key into control-I ASCII character, and so on.
823 (and char
824 (let ((translated (lookup-key function-key-map (vector char))))
bf896a1b 825 (if (arrayp translated)
4867f7b2 826 (setq char (aref translated 0)))))
9a5336ae 827 (cond ((null char))
1ba764de
RS
828 ((not (integerp char))
829 (setq unread-command-events (list char)
830 done t))
bf896a1b
RS
831 ((/= (logand char ?\M-\^@) 0)
832 ;; Turn a meta-character into a character with the 0200 bit set.
833 (setq code (logior (logand char (lognot ?\M-\^@)) 128)
834 done t))
1ba764de
RS
835 ((and (<= ?0 char) (< char (+ ?0 (min 10 read-quoted-char-radix))))
836 (setq code (+ (* code read-quoted-char-radix) (- char ?0)))
837 (and prompt (setq prompt (message "%s %c" prompt char))))
838 ((and (<= ?a (downcase char))
839 (< (downcase char) (+ ?a -10 (min 26 read-quoted-char-radix))))
92304bc8
RS
840 (setq code (+ (* code read-quoted-char-radix)
841 (+ 10 (- (downcase char) ?a))))
91a6acc3 842 (and prompt (setq prompt (message "%s %c" prompt char))))
1ba764de 843 ((and (not first) (eq char ?\C-m))
2444730b
RS
844 (setq done t))
845 ((not first)
846 (setq unread-command-events (list char)
847 done t))
848 (t (setq code char
849 done t)))
850 (setq first nil))
bf896a1b 851 code))
9a5336ae 852
44071d6b
RS
853(defun read-passwd (prompt &optional confirm default)
854 "Read a password, prompting with PROMPT. Echo `.' for each character typed.
e0e4cb7a 855End with RET, LFD, or ESC. DEL or C-h rubs out. C-u kills line.
44071d6b
RS
856Optional argument CONFIRM, if non-nil, then read it twice to make sure.
857Optional DEFAULT is a default password to use instead of empty input."
858 (if confirm
859 (let (success)
860 (while (not success)
861 (let ((first (read-passwd prompt nil default))
862 (second (read-passwd "Confirm password: " nil default)))
863 (if (equal first second)
864 (setq success first)
865 (message "Password not repeated accurately; please start over")
866 (sit-for 1))))
867 success)
868 (let ((pass nil)
869 (c 0)
870 (echo-keystrokes 0)
871 (cursor-in-echo-area t))
872 (while (progn (message "%s%s"
873 prompt
874 (make-string (length pass) ?.))
acc81368 875 (setq c (read-char nil t))
44071d6b
RS
876 (and (/= c ?\r) (/= c ?\n) (/= c ?\e)))
877 (if (= c ?\C-u)
878 (setq pass "")
879 (if (and (/= c ?\b) (/= c ?\177))
880 (setq pass (concat pass (char-to-string c)))
881 (if (> (length pass) 0)
882 (setq pass (substring pass 0 -1))))))
b021ef18 883 (clear-this-command-keys)
44071d6b
RS
884 (message nil)
885 (or pass default ""))))
e0e4cb7a 886\f
9a5336ae
JB
887(defun force-mode-line-update (&optional all)
888 "Force the mode-line of the current buffer to be redisplayed.
7ec2a18c 889With optional non-nil ALL, force redisplay of all mode-lines."
9a5336ae
JB
890 (if all (save-excursion (set-buffer (other-buffer))))
891 (set-buffer-modified-p (buffer-modified-p)))
892
be9b65ac
DL
893(defun momentary-string-display (string pos &optional exit-char message)
894 "Momentarily display STRING in the buffer at POS.
895Display remains until next character is typed.
896If the char is EXIT-CHAR (optional third arg, default is SPC) it is swallowed;
897otherwise it is then available as input (as a command if nothing else).
898Display MESSAGE (optional fourth arg) in the echo area.
899If MESSAGE is nil, instructions to type EXIT-CHAR are displayed there."
900 (or exit-char (setq exit-char ?\ ))
c306e0e0 901 (let ((inhibit-read-only t)
ca2ec1c5
RS
902 ;; Don't modify the undo list at all.
903 (buffer-undo-list t)
be9b65ac
DL
904 (modified (buffer-modified-p))
905 (name buffer-file-name)
906 insert-end)
907 (unwind-protect
908 (progn
909 (save-excursion
910 (goto-char pos)
911 ;; defeat file locking... don't try this at home, kids!
912 (setq buffer-file-name nil)
913 (insert-before-markers string)
3eec84bf
RS
914 (setq insert-end (point))
915 ;; If the message end is off screen, recenter now.
024ae2c6 916 (if (< (window-end nil t) insert-end)
3eec84bf
RS
917 (recenter (/ (window-height) 2)))
918 ;; If that pushed message start off the screen,
919 ;; scroll to start it at the top of the screen.
920 (move-to-window-line 0)
921 (if (> (point) pos)
922 (progn
923 (goto-char pos)
924 (recenter 0))))
be9b65ac
DL
925 (message (or message "Type %s to continue editing.")
926 (single-key-description exit-char))
3547c855 927 (let ((char (read-event)))
be9b65ac 928 (or (eq char exit-char)
dbc4e1c1 929 (setq unread-command-events (list char)))))
be9b65ac
DL
930 (if insert-end
931 (save-excursion
932 (delete-region pos insert-end)))
933 (setq buffer-file-name name)
934 (set-buffer-modified-p modified))))
935
9a5336ae
JB
936\f
937;;;; Miscellanea.
938
448b61c9
RS
939;; A number of major modes set this locally.
940;; Give it a global value to avoid compiler warnings.
941(defvar font-lock-defaults nil)
942
4fb17037
RS
943(defvar suspend-hook nil
944 "Normal hook run by `suspend-emacs', before suspending.")
945
946(defvar suspend-resume-hook nil
947 "Normal hook run by `suspend-emacs', after Emacs is continued.")
948
448b61c9
RS
949;; Avoid compiler warnings about this variable,
950;; which has a special meaning on certain system types.
951(defvar buffer-file-type nil
952 "Non-nil if the visited file is a binary file.
953This variable is meaningful on MS-DOG and Windows NT.
954On those systems, it is automatically local in every buffer.
955On other systems, this variable is normally always nil.")
956
a860d25f 957;; This should probably be written in C (i.e., without using `walk-windows').
63503b24 958(defun get-buffer-window-list (buffer &optional minibuf frame)
a860d25f 959 "Return windows currently displaying BUFFER, or nil if none.
63503b24 960See `walk-windows' for the meaning of MINIBUF and FRAME."
43c5ac8c 961 (let ((buffer (if (bufferp buffer) buffer (get-buffer buffer))) windows)
a860d25f
SM
962 (walk-windows (function (lambda (window)
963 (if (eq (window-buffer window) buffer)
964 (setq windows (cons window windows)))))
63503b24 965 minibuf frame)
a860d25f
SM
966 windows))
967
f9269e19
RS
968(defun ignore (&rest ignore)
969 "Do nothing and return nil.
970This function accepts any number of arguments, but ignores them."
c0f1a4f6 971 (interactive)
9a5336ae
JB
972 nil)
973
974(defun error (&rest args)
aa308ce2
RS
975 "Signal an error, making error message by passing all args to `format'.
976In Emacs, the convention is that error messages start with a capital
977letter but *do not* end with a period. Please follow this convention
978for the sake of consistency."
9a5336ae
JB
979 (while t
980 (signal 'error (list (apply 'format args)))))
981
cef7ae6e 982(defalias 'user-original-login-name 'user-login-name)
9a5336ae 983
be9b65ac
DL
984(defun start-process-shell-command (name buffer &rest args)
985 "Start a program in a subprocess. Return the process object for it.
986Args are NAME BUFFER COMMAND &rest COMMAND-ARGS.
987NAME is name for process. It is modified if necessary to make it unique.
988BUFFER is the buffer or (buffer-name) to associate with the process.
989 Process output goes at end of that buffer, unless you specify
990 an output stream or filter function to handle the output.
991 BUFFER may be also nil, meaning that this process is not associated
992 with any buffer
993Third arg is command name, the name of a shell command.
994Remaining arguments are the arguments for the command.
4f1d6310 995Wildcards and redirection are handled as usual in the shell."
a247bf21
KH
996 (cond
997 ((eq system-type 'vax-vms)
998 (apply 'start-process name buffer args))
b59f6d7a
RS
999 ;; We used to use `exec' to replace the shell with the command,
1000 ;; but that failed to handle (...) and semicolon, etc.
a247bf21
KH
1001 (t
1002 (start-process name buffer shell-file-name shell-command-switch
b59f6d7a 1003 (mapconcat 'identity args " ")))))
a7ed4c2a 1004\f
a7f284ec
RS
1005(defmacro with-current-buffer (buffer &rest body)
1006 "Execute the forms in BODY with BUFFER as the current buffer.
a2fdb55c
EN
1007The value returned is the value of the last form in BODY.
1008See also `with-temp-buffer'."
ce87039d
SM
1009 (cons 'save-current-buffer
1010 (cons (list 'set-buffer buffer)
1011 body)))
a7f284ec 1012
e5bb8a8c
SM
1013(defmacro with-temp-file (file &rest body)
1014 "Create a new buffer, evaluate BODY there, and write the buffer to FILE.
1015The value returned is the value of the last form in BODY.
a2fdb55c 1016See also `with-temp-buffer'."
a7ed4c2a 1017 (let ((temp-file (make-symbol "temp-file"))
a2fdb55c
EN
1018 (temp-buffer (make-symbol "temp-buffer")))
1019 `(let ((,temp-file ,file)
1020 (,temp-buffer
1021 (get-buffer-create (generate-new-buffer-name " *temp file*"))))
1022 (unwind-protect
1023 (prog1
1024 (with-current-buffer ,temp-buffer
e5bb8a8c 1025 ,@body)
a2fdb55c
EN
1026 (with-current-buffer ,temp-buffer
1027 (widen)
1028 (write-region (point-min) (point-max) ,temp-file nil 0)))
1029 (and (buffer-name ,temp-buffer)
1030 (kill-buffer ,temp-buffer))))))
1031
e5bb8a8c 1032(defmacro with-temp-message (message &rest body)
a600effe 1033 "Display MESSAGE temporarily if non-nil while BODY is evaluated.
e5bb8a8c
SM
1034The original message is restored to the echo area after BODY has finished.
1035The value returned is the value of the last form in BODY.
a600effe
SM
1036MESSAGE is written to the message log buffer if `message-log-max' is non-nil.
1037If MESSAGE is nil, the echo area and message log buffer are unchanged.
1038Use a MESSAGE of \"\" to temporarily clear the echo area."
110201c8
SM
1039 (let ((current-message (make-symbol "current-message"))
1040 (temp-message (make-symbol "with-temp-message")))
1041 `(let ((,temp-message ,message)
1042 (,current-message))
e5bb8a8c
SM
1043 (unwind-protect
1044 (progn
110201c8
SM
1045 (when ,temp-message
1046 (setq ,current-message (current-message))
aadf7ff3 1047 (message "%s" ,temp-message))
e5bb8a8c 1048 ,@body)
75545902
KH
1049 (and ,temp-message ,current-message
1050 (message "%s" ,current-message))))))
e5bb8a8c
SM
1051
1052(defmacro with-temp-buffer (&rest body)
1053 "Create a temporary buffer, and evaluate BODY there like `progn'.
a2fdb55c
EN
1054See also `with-temp-file' and `with-output-to-string'."
1055 (let ((temp-buffer (make-symbol "temp-buffer")))
1056 `(let ((,temp-buffer
1057 (get-buffer-create (generate-new-buffer-name " *temp*"))))
1058 (unwind-protect
1059 (with-current-buffer ,temp-buffer
e5bb8a8c 1060 ,@body)
a2fdb55c
EN
1061 (and (buffer-name ,temp-buffer)
1062 (kill-buffer ,temp-buffer))))))
1063
5db7925d
RS
1064(defmacro with-output-to-string (&rest body)
1065 "Execute BODY, return the text it sent to `standard-output', as a string."
a2fdb55c
EN
1066 `(let ((standard-output
1067 (get-buffer-create (generate-new-buffer-name " *string-output*"))))
5db7925d
RS
1068 (let ((standard-output standard-output))
1069 ,@body)
a2fdb55c
EN
1070 (with-current-buffer standard-output
1071 (prog1
1072 (buffer-string)
1073 (kill-buffer nil)))))
2ec9c94e
RS
1074
1075(defmacro combine-after-change-calls (&rest body)
1076 "Execute BODY, but don't call the after-change functions till the end.
1077If BODY makes changes in the buffer, they are recorded
1078and the functions on `after-change-functions' are called several times
1079when BODY is finished.
31aa282e 1080The return value is the value of the last form in BODY.
2ec9c94e
RS
1081
1082If `before-change-functions' is non-nil, then calls to the after-change
1083functions can't be deferred, so in that case this macro has no effect.
1084
1085Do not alter `after-change-functions' or `before-change-functions'
1086in BODY."
1087 `(unwind-protect
1088 (let ((combine-after-change-calls t))
1089 . ,body)
1090 (combine-after-change-execute)))
1091
7e8539cc
RS
1092(defmacro with-syntax-table (table &rest body)
1093 "Evaluate BODY with syntax table of current buffer set to a copy of TABLE.
1094The syntax table of the current buffer is saved, BODY is evaluated, and the
1095saved table is restored, even in case of an abnormal exit.
1096Value is what BODY returns."
b3f07093
RS
1097 (let ((old-table (make-symbol "table"))
1098 (old-buffer (make-symbol "buffer")))
7e8539cc
RS
1099 `(let ((,old-table (syntax-table))
1100 (,old-buffer (current-buffer)))
1101 (unwind-protect
1102 (progn
1103 (set-syntax-table (copy-syntax-table ,table))
1104 ,@body)
1105 (save-current-buffer
1106 (set-buffer ,old-buffer)
1107 (set-syntax-table ,old-table))))))
a2fdb55c 1108\f
c7ca41e6
RS
1109(defvar save-match-data-internal)
1110
1111;; We use save-match-data-internal as the local variable because
1112;; that works ok in practice (people should not use that variable elsewhere).
1113;; We used to use an uninterned symbol; the compiler handles that properly
1114;; now, but it generates slower code.
9a5336ae
JB
1115(defmacro save-match-data (&rest body)
1116 "Execute the BODY forms, restoring the global value of the match data."
64ed733a
PE
1117 ;; It is better not to use backquote here,
1118 ;; because that makes a bootstrapping problem
1119 ;; if you need to recompile all the Lisp files using interpreted code.
1120 (list 'let
1121 '((save-match-data-internal (match-data)))
1122 (list 'unwind-protect
1123 (cons 'progn body)
1124 '(set-match-data save-match-data-internal))))
993713ce 1125
cd323f89 1126(defun match-string (num &optional string)
993713ce
SM
1127 "Return string of text matched by last search.
1128NUM specifies which parenthesized expression in the last regexp.
1129 Value is nil if NUMth pair didn't match, or there were less than NUM pairs.
1130Zero means the entire text matched by the whole regexp or whole string.
1131STRING should be given if the last search was by `string-match' on STRING."
cd323f89
SM
1132 (if (match-beginning num)
1133 (if string
1134 (substring string (match-beginning num) (match-end num))
1135 (buffer-substring (match-beginning num) (match-end num)))))
58f950b4 1136
bb760c71
RS
1137(defun match-string-no-properties (num &optional string)
1138 "Return string of text matched by last search, without text properties.
1139NUM specifies which parenthesized expression in the last regexp.
1140 Value is nil if NUMth pair didn't match, or there were less than NUM pairs.
1141Zero means the entire text matched by the whole regexp or whole string.
1142STRING should be given if the last search was by `string-match' on STRING."
1143 (if (match-beginning num)
1144 (if string
1145 (let ((result
1146 (substring string (match-beginning num) (match-end num))))
1147 (set-text-properties 0 (length result) nil result)
1148 result)
1149 (buffer-substring-no-properties (match-beginning num)
1150 (match-end num)))))
1151
edce3654
RS
1152(defun split-string (string &optional separators)
1153 "Splits STRING into substrings where there are matches for SEPARATORS.
1154Each match for SEPARATORS is a splitting point.
1155The substrings between the splitting points are made into a list
1156which is returned.
b222b786
RS
1157If SEPARATORS is absent, it defaults to \"[ \\f\\t\\n\\r\\v]+\".
1158
1159If there is match for SEPARATORS at the beginning of STRING, we do not
1160include a null substring for that. Likewise, if there is a match
b021ef18
DL
1161at the end of STRING, we don't include a null substring for that.
1162
1163Modifies the match data; use `save-match-data' if necessary."
edce3654
RS
1164 (let ((rexp (or separators "[ \f\t\n\r\v]+"))
1165 (start 0)
b222b786 1166 notfirst
edce3654 1167 (list nil))
b222b786
RS
1168 (while (and (string-match rexp string
1169 (if (and notfirst
1170 (= start (match-beginning 0))
1171 (< start (length string)))
1172 (1+ start) start))
1173 (< (match-beginning 0) (length string)))
1174 (setq notfirst t)
7eb47123 1175 (or (eq (match-beginning 0) 0)
b222b786
RS
1176 (and (eq (match-beginning 0) (match-end 0))
1177 (eq (match-beginning 0) start))
edce3654
RS
1178 (setq list
1179 (cons (substring string start (match-beginning 0))
1180 list)))
1181 (setq start (match-end 0)))
1182 (or (eq start (length string))
1183 (setq list
1184 (cons (substring string start)
1185 list)))
1186 (nreverse list)))
1ccaea52
AI
1187
1188(defun subst-char-in-string (fromchar tochar string &optional inplace)
1189 "Replace FROMCHAR with TOCHAR in STRING each time it occurs.
1190Unless optional argument INPLACE is non-nil, return a new string."
1191 (let ((i (length string))
1192 (newstr (if inplace string (copy-sequence string))))
1193 (while (> i 0)
1194 (setq i (1- i))
1195 (if (eq (aref newstr i) fromchar)
1196 (aset newstr i tochar)))
1197 newstr))
b021ef18 1198
1697159c
DL
1199(defun replace-regexp-in-string (regexp rep string &optional
1200 fixedcase literal subexp start)
b021ef18
DL
1201 "Replace all matches for REGEXP with REP in STRING.
1202
1203Return a new string containing the replacements.
1204
1205Optional arguments FIXEDCASE, LITERAL and SUBEXP are like the
1206arguments with the same names of function `replace-match'. If START
1207is non-nil, start replacements at that index in STRING.
1208
1209REP is either a string used as the NEWTEXT arg of `replace-match' or a
1210function. If it is a function it is applied to each match to generate
1211the replacement passed to `replace-match'; the match-data at this
1212point are such that match 0 is the function's argument.
1213
1697159c
DL
1214To replace only the first match (if any), make REGEXP match up to \\'
1215and replace a sub-expression, e.g.
1216 (replace-regexp-in-string \"\\(foo\\).*\\'\" \"bar\" \" foo foo\" nil nil 1)
1217 => \" bar foo\"
1218"
b021ef18
DL
1219
1220 ;; To avoid excessive consing from multiple matches in long strings,
1221 ;; don't just call `replace-match' continually. Walk down the
1222 ;; string looking for matches of REGEXP and building up a (reversed)
1223 ;; list MATCHES. This comprises segments of STRING which weren't
1224 ;; matched interspersed with replacements for segments that were.
1225 ;; [For a `large' number of replacments it's more efficient to
1226 ;; operate in a temporary buffer; we can't tell from the function's
1227 ;; args whether to choose the buffer-based implementation, though it
1228 ;; might be reasonable to do so for long enough STRING.]
1229 (let ((l (length string))
1230 (start (or start 0))
1231 matches str mb me)
1232 (save-match-data
1233 (while (and (< start l) (string-match regexp string start))
1234 (setq mb (match-beginning 0)
1235 me (match-end 0))
a9853251
SM
1236 ;; If we matched the empty string, make sure we advance by one char
1237 (when (= me mb) (setq me (min l (1+ mb))))
1238 ;; Generate a replacement for the matched substring.
1239 ;; Operate only on the substring to minimize string consing.
1240 ;; Set up match data for the substring for replacement;
1241 ;; presumably this is likely to be faster than munging the
1242 ;; match data directly in Lisp.
1243 (string-match regexp (setq str (substring string mb me)))
1244 (setq matches
1245 (cons (replace-match (if (stringp rep)
1246 rep
1247 (funcall rep (match-string 0 str)))
1248 fixedcase literal str subexp)
1249 (cons (substring string start mb) ; unmatched prefix
1250 matches)))
1251 (setq start me))
b021ef18
DL
1252 ;; Reconstruct a string from the pieces.
1253 (setq matches (cons (substring string start l) matches)) ; leftover
1254 (apply #'concat (nreverse matches)))))
a7ed4c2a 1255\f
8af7df60
RS
1256(defun shell-quote-argument (argument)
1257 "Quote an argument for passing as argument to an inferior shell."
c1c74b43 1258 (if (eq system-type 'ms-dos)
8ee75d03
EZ
1259 ;; Quote using double quotes, but escape any existing quotes in
1260 ;; the argument with backslashes.
1261 (let ((result "")
1262 (start 0)
1263 end)
1264 (if (or (null (string-match "[^\"]" argument))
1265 (< (match-end 0) (length argument)))
1266 (while (string-match "[\"]" argument start)
1267 (setq end (match-beginning 0)
1268 result (concat result (substring argument start end)
1269 "\\" (substring argument end (1+ end)))
1270 start (1+ end))))
1271 (concat "\"" result (substring argument start) "\""))
c1c74b43
RS
1272 (if (eq system-type 'windows-nt)
1273 (concat "\"" argument "\"")
e1b65a6b
RS
1274 (if (equal argument "")
1275 "''"
1276 ;; Quote everything except POSIX filename characters.
1277 ;; This should be safe enough even for really weird shells.
1278 (let ((result "") (start 0) end)
1279 (while (string-match "[^-0-9a-zA-Z_./]" argument start)
1280 (setq end (match-beginning 0)
1281 result (concat result (substring argument start end)
1282 "\\" (substring argument end (1+ end)))
1283 start (1+ end)))
1284 (concat result (substring argument start)))))))
8af7df60 1285
297d863b 1286(defun make-syntax-table (&optional oldtable)
984f718a 1287 "Return a new syntax table.
888eb98e
RS
1288If OLDTABLE is non-nil, copy OLDTABLE.
1289Otherwise, create a syntax table which inherits
1290all letters and control characters from the standard syntax table;
1291other characters are copied from the standard syntax table."
297d863b
KH
1292 (if oldtable
1293 (copy-syntax-table oldtable)
1294 (let ((table (copy-syntax-table))
1295 i)
1296 (setq i 0)
1297 (while (<= i 31)
a6889c57 1298 (aset table i nil)
297d863b
KH
1299 (setq i (1+ i)))
1300 (setq i ?A)
1301 (while (<= i ?Z)
a6889c57 1302 (aset table i nil)
297d863b
KH
1303 (setq i (1+ i)))
1304 (setq i ?a)
1305 (while (<= i ?z)
a6889c57 1306 (aset table i nil)
297d863b
KH
1307 (setq i (1+ i)))
1308 (setq i 128)
1309 (while (<= i 255)
a6889c57 1310 (aset table i nil)
297d863b
KH
1311 (setq i (1+ i)))
1312 table)))
31aa282e
KH
1313
1314(defun add-to-invisibility-spec (arg)
1315 "Add elements to `buffer-invisibility-spec'.
1316See documentation for `buffer-invisibility-spec' for the kind of elements
1317that can be added."
1318 (cond
1319 ((or (null buffer-invisibility-spec) (eq buffer-invisibility-spec t))
1320 (setq buffer-invisibility-spec (list arg)))
1321 (t
11d431ad
KH
1322 (setq buffer-invisibility-spec
1323 (cons arg buffer-invisibility-spec)))))
31aa282e
KH
1324
1325(defun remove-from-invisibility-spec (arg)
1326 "Remove elements from `buffer-invisibility-spec'."
e93b8cbb 1327 (if (consp buffer-invisibility-spec)
071a2a71 1328 (setq buffer-invisibility-spec (delete arg buffer-invisibility-spec))))
baed0109
RS
1329\f
1330(defun global-set-key (key command)
1331 "Give KEY a global binding as COMMAND.
7bba1895
KH
1332COMMAND is the command definition to use; usually it is
1333a symbol naming an interactively-callable function.
1334KEY is a key sequence; noninteractively, it is a string or vector
1335of characters or event types, and non-ASCII characters with codes
1336above 127 (such as ISO Latin-1) can be included if you use a vector.
1337
1338Note that if KEY has a local binding in the current buffer,
1339that local binding will continue to shadow any global binding
1340that you make with this function."
baed0109
RS
1341 (interactive "KSet key globally: \nCSet key %s to command: ")
1342 (or (vectorp key) (stringp key)
1343 (signal 'wrong-type-argument (list 'arrayp key)))
ff663bbe 1344 (define-key (current-global-map) key command))
baed0109
RS
1345
1346(defun local-set-key (key command)
1347 "Give KEY a local binding as COMMAND.
7bba1895
KH
1348COMMAND is the command definition to use; usually it is
1349a symbol naming an interactively-callable function.
1350KEY is a key sequence; noninteractively, it is a string or vector
1351of characters or event types, and non-ASCII characters with codes
1352above 127 (such as ISO Latin-1) can be included if you use a vector.
1353
baed0109
RS
1354The binding goes in the current buffer's local map,
1355which in most cases is shared with all other buffers in the same major mode."
1356 (interactive "KSet key locally: \nCSet key %s locally to command: ")
1357 (let ((map (current-local-map)))
1358 (or map
1359 (use-local-map (setq map (make-sparse-keymap))))
1360 (or (vectorp key) (stringp key)
1361 (signal 'wrong-type-argument (list 'arrayp key)))
ff663bbe 1362 (define-key map key command)))
984f718a 1363
baed0109
RS
1364(defun global-unset-key (key)
1365 "Remove global binding of KEY.
1366KEY is a string representing a sequence of keystrokes."
1367 (interactive "kUnset key globally: ")
1368 (global-set-key key nil))
1369
db2474b8 1370(defun local-unset-key (key)
baed0109
RS
1371 "Remove local binding of KEY.
1372KEY is a string representing a sequence of keystrokes."
1373 (interactive "kUnset key locally: ")
1374 (if (current-local-map)
db2474b8 1375 (local-set-key key nil))
baed0109
RS
1376 nil)
1377\f
4809d0dd
KH
1378;; We put this here instead of in frame.el so that it's defined even on
1379;; systems where frame.el isn't loaded.
1380(defun frame-configuration-p (object)
1381 "Return non-nil if OBJECT seems to be a frame configuration.
1382Any list whose car is `frame-configuration' is assumed to be a frame
1383configuration."
1384 (and (consp object)
1385 (eq (car object) 'frame-configuration)))
1386
a9a44ed1 1387(defun functionp (object)
77a5664f 1388 "Non-nil if OBJECT is a type of object that can be called as a function."
c029995c 1389 (or (subrp object) (byte-code-function-p object)
a9a44ed1
RS
1390 (eq (car-safe object) 'lambda)
1391 (and (symbolp object) (fboundp object))))
1392
9a5336ae
JB
1393;; now in fns.c
1394;(defun nth (n list)
1395; "Returns the Nth element of LIST.
1396;N counts from zero. If LIST is not that long, nil is returned."
1397; (car (nthcdr n list)))
1398;
1399;(defun copy-alist (alist)
1400; "Return a copy of ALIST.
1401;This is a new alist which represents the same mapping
1402;from objects to objects, but does not share the alist structure with ALIST.
1403;The objects mapped (cars and cdrs of elements of the alist)
1404;are shared, however."
1405; (setq alist (copy-sequence alist))
1406; (let ((tail alist))
1407; (while tail
1408; (if (consp (car tail))
1409; (setcar tail (cons (car (car tail)) (cdr (car tail)))))
1410; (setq tail (cdr tail))))
1411; alist)
630cc463 1412
d3a61a11 1413(defun assq-delete-all (key alist)
a62d6695
DL
1414 "Delete from ALIST all elements whose car is KEY.
1415Return the modified alist."
a62d6695
DL
1416 (let ((tail alist))
1417 (while tail
1418 (if (eq (car (car tail)) key)
1419 (setq alist (delq (car tail) alist)))
1420 (setq tail (cdr tail)))
1421 alist))
1422
cdd9f643
RS
1423(defun make-temp-file (prefix &optional dir-flag)
1424 "Create a temporary file.
1425The returned file name (created by appending some random characters at the end
1426of PREFIX, and expanding against `temporary-file-directory' if necessary,
1427is guaranteed to point to a newly created empty file.
1428You can then use `write-region' to write new data into the file.
1429
1430If DIR-FLAG is non-nil, create a new empty directory instead of a file."
1431 (let (file)
1432 (while (condition-case ()
1433 (progn
1434 (setq file
1435 (make-temp-name
1436 (expand-file-name prefix temporary-file-directory)))
1437 (if dir-flag
1438 (make-directory file)
1439 (write-region "" nil file nil 'silent nil 'excl))
1440 nil)
1441 (file-already-exists t))
1442 ;; the file was somehow created by someone else between
1443 ;; `make-temp-name' and `write-region', let's try again.
1444 nil)
1445 file))
1446
630cc463 1447;;; subr.el ends here