(whitespace-unload-hook): Set the variable.
[bpt/emacs.git] / lisp / subr.el
CommitLineData
c88ab9ce 1;;; subr.el --- basic lisp subroutines for Emacs
630cc463 2
a8a64811
SM
3;; Copyright (C) 1985, 1986, 1992, 1994, 1995, 1999, 2000, 2001, 2002, 2003,
4;; 2004 Free Software Foundation, Inc.
be9b65ac 5
30764597
PJ
6;; Maintainer: FSF
7;; Keywords: internal
8
be9b65ac
DL
9;; This file is part of GNU Emacs.
10
11;; GNU Emacs is free software; you can redistribute it and/or modify
12;; it under the terms of the GNU General Public License as published by
492878e4 13;; the Free Software Foundation; either version 2, or (at your option)
be9b65ac
DL
14;; any later version.
15
16;; GNU Emacs is distributed in the hope that it will be useful,
17;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19;; GNU General Public License for more details.
20
21;; You should have received a copy of the GNU General Public License
b578f267
EN
22;; along with GNU Emacs; see the file COPYING. If not, write to the
23;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24;; Boston, MA 02111-1307, USA.
be9b65ac 25
60370d40
PJ
26;;; Commentary:
27
630cc463 28;;; Code:
77a5664f
RS
29(defvar custom-declare-variable-list nil
30 "Record `defcustom' calls made before `custom.el' is loaded to handle them.
31Each element of this list holds the arguments to one call to `defcustom'.")
32
68e3e5f5 33;; Use this, rather than defcustom, in subr.el and other files loaded
77a5664f
RS
34;; before custom.el.
35(defun custom-declare-variable-early (&rest arguments)
36 (setq custom-declare-variable-list
37 (cons arguments custom-declare-variable-list)))
2c642c03
GM
38
39\f
40(defun macro-declaration-function (macro decl)
41 "Process a declaration found in a macro definition.
42This is set as the value of the variable `macro-declaration-function'.
43MACRO is the name of the macro being defined.
44DECL is a list `(declare ...)' containing the declarations.
45The return value of this function is not used."
b6a1ce0b
SM
46 ;; We can't use `dolist' or `cadr' yet for bootstrapping reasons.
47 (let (d)
48 ;; Ignore the first element of `decl' (it's always `declare').
49 (while (setq decl (cdr decl))
50 (setq d (car decl))
51 (cond ((and (consp d) (eq (car d) 'indent))
52 (put macro 'lisp-indent-function (car (cdr d))))
53 ((and (consp d) (eq (car d) 'debug))
54 (put macro 'edebug-form-spec (car (cdr d))))
55 (t
56 (message "Unknown declaration %s" d))))))
2c642c03
GM
57
58(setq macro-declaration-function 'macro-declaration-function)
59
9a5336ae
JB
60\f
61;;;; Lisp language features.
62
0764e16f
SM
63(defalias 'not 'null)
64
1116910a
JY
65(defmacro noreturn (form)
66 "Evaluates FORM, with the expectation that the evaluation will signal an error
67instead of returning to its caller. If FORM does return, an error is
a6d2eef7 68signalled."
1116910a
JY
69 `(prog1 ,form
70 (error "Form marked with `noreturn' did return")))
71
72(defmacro 1value (form)
73 "Evaluates FORM, with the expectation that all the same value will be returned
74from all evaluations of FORM. This is the global do-nothing
75version of `1value'. There is also `testcover-1value' that
76complains if FORM ever does return differing values."
77 form)
78
9a5336ae
JB
79(defmacro lambda (&rest cdr)
80 "Return a lambda expression.
81A call of the form (lambda ARGS DOCSTRING INTERACTIVE BODY) is
82self-quoting; the result of evaluating the lambda expression is the
83expression itself. The lambda expression may then be treated as a
bec0d7f9
RS
84function, i.e., stored as the function value of a symbol, passed to
85funcall or mapcar, etc.
86
9a5336ae 87ARGS should take the same form as an argument list for a `defun'.
8fd68088
RS
88DOCSTRING is an optional documentation string.
89 If present, it should describe how to call the function.
90 But documentation strings are usually not useful in nameless functions.
9a5336ae
JB
91INTERACTIVE should be a call to the function `interactive', which see.
92It may also be omitted.
a478f3e1
JB
93BODY should be a list of Lisp expressions.
94
95\(fn ARGS [DOCSTRING] [INTERACTIVE] BODY)"
9a5336ae
JB
96 ;; Note that this definition should not use backquotes; subr.el should not
97 ;; depend on backquote.el.
98 (list 'function (cons 'lambda cdr)))
99
1be152fc 100(defmacro push (newelt listname)
fa65505b 101 "Add NEWELT to the list stored in the symbol LISTNAME.
1be152fc 102This is equivalent to (setq LISTNAME (cons NEWELT LISTNAME)).
d270117a 103LISTNAME must be a symbol."
f30e0cd8 104 (declare (debug (form sexp)))
22d85d00
DL
105 (list 'setq listname
106 (list 'cons newelt listname)))
d270117a
RS
107
108(defmacro pop (listname)
109 "Return the first element of LISTNAME's value, and remove it from the list.
110LISTNAME must be a symbol whose value is a list.
111If the value is nil, `pop' returns nil but does not actually
112change the list."
f30e0cd8 113 (declare (debug (sexp)))
54993fa4
MB
114 (list 'car
115 (list 'prog1 listname
116 (list 'setq listname (list 'cdr listname)))))
d270117a 117
debff3c3 118(defmacro when (cond &rest body)
b021ef18 119 "If COND yields non-nil, do BODY, else return nil."
d47f7515 120 (declare (indent 1) (debug t))
debff3c3 121 (list 'if cond (cons 'progn body)))
9a5336ae 122
debff3c3 123(defmacro unless (cond &rest body)
b021ef18 124 "If COND yields nil, do BODY, else return nil."
d47f7515 125 (declare (indent 1) (debug t))
debff3c3 126 (cons 'if (cons cond (cons nil body))))
d370591d 127
a0b0756a 128(defmacro dolist (spec &rest body)
d47f7515 129 "Loop over a list.
a0b0756a 130Evaluate BODY with VAR bound to each car from LIST, in turn.
d47f7515
SM
131Then evaluate RESULT to get return value, default nil.
132
d775d486 133\(fn (VAR LIST [RESULT]) BODY...)"
d47f7515 134 (declare (indent 1) (debug ((symbolp form &optional form) body)))
e4295aa1 135 (let ((temp (make-symbol "--dolist-temp--")))
d47f7515
SM
136 `(let ((,temp ,(nth 1 spec))
137 ,(car spec))
138 (while ,temp
139 (setq ,(car spec) (car ,temp))
140 (setq ,temp (cdr ,temp))
141 ,@body)
142 ,@(if (cdr (cdr spec))
143 `((setq ,(car spec) nil) ,@(cdr (cdr spec)))))))
a0b0756a
RS
144
145(defmacro dotimes (spec &rest body)
d47f7515 146 "Loop a certain number of times.
a0b0756a
RS
147Evaluate BODY with VAR bound to successive integers running from 0,
148inclusive, to COUNT, exclusive. Then evaluate RESULT to get
d47f7515
SM
149the return value (nil if RESULT is omitted).
150
d775d486 151\(fn (VAR COUNT [RESULT]) BODY...)"
d47f7515
SM
152 (declare (indent 1) (debug dolist))
153 (let ((temp (make-symbol "--dotimes-temp--"))
154 (start 0)
155 (end (nth 1 spec)))
156 `(let ((,temp ,end)
157 (,(car spec) ,start))
158 (while (< ,(car spec) ,temp)
159 ,@body
160 (setq ,(car spec) (1+ ,(car spec))))
161 ,@(cdr (cdr spec)))))
a0b0756a 162
a6d2eef7
LT
163(defmacro declare (&rest specs)
164 "Do not evaluate any arguments and return nil.
165Treated as a declaration when used at the right place in a
a478f3e1 166`defmacro' form. \(See Info anchor `(elisp)Definition of declare'.)"
a6d2eef7
LT
167 nil)
168
d370591d
RS
169(defsubst caar (x)
170 "Return the car of the car of X."
171 (car (car x)))
172
173(defsubst cadr (x)
174 "Return the car of the cdr of X."
175 (car (cdr x)))
176
177(defsubst cdar (x)
178 "Return the cdr of the car of X."
179 (cdr (car x)))
180
181(defsubst cddr (x)
182 "Return the cdr of the cdr of X."
183 (cdr (cdr x)))
e8c32c99 184
a478f3e1
JB
185(defun last (list &optional n)
186 "Return the last link of LIST. Its car is the last element.
187If LIST is nil, return nil.
188If N is non-nil, return the Nth-to-last link of LIST.
189If N is bigger than the length of LIST, return LIST."
369fba5f 190 (if n
a478f3e1 191 (let ((m 0) (p list))
369fba5f
RS
192 (while (consp p)
193 (setq m (1+ m) p (cdr p)))
194 (if (<= n 0) p
a478f3e1
JB
195 (if (< n m) (nthcdr (- m n) list) list)))
196 (while (consp (cdr list))
197 (setq list (cdr list)))
198 list))
526d204e 199
a478f3e1 200(defun butlast (list &optional n)
a3111ae4 201 "Return a copy of LIST with the last N elements removed."
a478f3e1
JB
202 (if (and n (<= n 0)) list
203 (nbutlast (copy-sequence list) n)))
1c1c65de 204
a478f3e1 205(defun nbutlast (list &optional n)
1c1c65de 206 "Modifies LIST to remove the last N elements."
a478f3e1 207 (let ((m (length list)))
1c1c65de
KH
208 (or n (setq n 1))
209 (and (< n m)
210 (progn
a478f3e1
JB
211 (if (> n 0) (setcdr (nthcdr (- (1- m) n) list) nil))
212 list))))
1c1c65de 213
01682756 214(defun delete-dups (list)
1f3e4f92
EZ
215 "Destructively remove `equal' duplicates from LIST.
216Store the result in LIST and return it. LIST must be a proper list.
217Of several `equal' occurrences of an element in LIST, the first
218one is kept."
01682756
LT
219 (let ((tail list))
220 (while tail
1f3e4f92
EZ
221 (setcdr tail (delete (car tail) (cdr tail)))
222 (setq tail (cdr tail))))
01682756
LT
223 list)
224
0ed2c9b6 225(defun number-sequence (from &optional to inc)
abd9177a 226 "Return a sequence of numbers from FROM to TO (both inclusive) as a list.
2c1385ed
LT
227INC is the increment used between numbers in the sequence and defaults to 1.
228So, the Nth element of the list is \(+ FROM \(* N INC)) where N counts from
229zero. TO is only included if there is an N for which TO = FROM + N * INC.
230If TO is nil or numerically equal to FROM, return \(FROM).
231If INC is positive and TO is less than FROM, or INC is negative
232and TO is larger than FROM, return nil.
233If INC is zero and TO is neither nil nor numerically equal to
234FROM, signal an error.
235
236This function is primarily designed for integer arguments.
237Nevertheless, FROM, TO and INC can be integer or float. However,
238floating point arithmetic is inexact. For instance, depending on
239the machine, it may quite well happen that
240\(number-sequence 0.4 0.6 0.2) returns the one element list \(0.4),
241whereas \(number-sequence 0.4 0.8 0.2) returns a list with three
242elements. Thus, if some of the arguments are floats and one wants
243to make sure that TO is included, one may have to explicitly write
244TO as \(+ FROM \(* N INC)) or use a variable whose value was
245computed with this exact expression. Alternatively, you can,
246of course, also replace TO with a slightly larger value
247\(or a slightly more negative value if INC is negative)."
248 (if (or (not to) (= from to))
0ed2c9b6
VJL
249 (list from)
250 (or inc (setq inc 1))
2c1385ed
LT
251 (when (zerop inc) (error "The increment can not be zero"))
252 (let (seq (n 0) (next from))
253 (if (> inc 0)
254 (while (<= next to)
255 (setq seq (cons next seq)
256 n (1+ n)
257 next (+ from (* n inc))))
258 (while (>= next to)
259 (setq seq (cons next seq)
260 n (1+ n)
261 next (+ from (* n inc)))))
0ed2c9b6 262 (nreverse seq))))
abd9177a 263
13157efc 264(defun remove (elt seq)
963f49a2 265 "Return a copy of SEQ with all occurrences of ELT removed.
13157efc
GM
266SEQ must be a list, vector, or string. The comparison is done with `equal'."
267 (if (nlistp seq)
268 ;; If SEQ isn't a list, there's no need to copy SEQ because
269 ;; `delete' will return a new object.
270 (delete elt seq)
271 (delete elt (copy-sequence seq))))
272
273(defun remq (elt list)
d47f7515
SM
274 "Return LIST with all occurrences of ELT removed.
275The comparison is done with `eq'. Contrary to `delq', this does not use
276side-effects, and the argument LIST is not modified."
13157efc
GM
277 (if (memq elt list)
278 (delq elt (copy-sequence list))
279 list))
280
a176c9eb
CW
281(defun copy-tree (tree &optional vecp)
282 "Make a copy of TREE.
283If TREE is a cons cell, this recursively copies both its car and its cdr.
cfebd4db 284Contrast to `copy-sequence', which copies only along the cdrs. With second
a176c9eb
CW
285argument VECP, this copies vectors as well as conses."
286 (if (consp tree)
cfebd4db
RS
287 (let (result)
288 (while (consp tree)
289 (let ((newcar (car tree)))
290 (if (or (consp (car tree)) (and vecp (vectorp (car tree))))
291 (setq newcar (copy-tree (car tree) vecp)))
292 (push newcar result))
293 (setq tree (cdr tree)))
68b08950 294 (nconc (nreverse result) tree))
a176c9eb
CW
295 (if (and vecp (vectorp tree))
296 (let ((i (length (setq tree (copy-sequence tree)))))
297 (while (>= (setq i (1- i)) 0)
cfebd4db
RS
298 (aset tree i (copy-tree (aref tree i) vecp)))
299 tree)
300 tree)))
a176c9eb 301
8a288450
RS
302(defun assoc-default (key alist &optional test default)
303 "Find object KEY in a pseudo-alist ALIST.
304ALIST is a list of conses or objects. Each element (or the element's car,
305if it is a cons) is compared with KEY by evaluating (TEST (car elt) KEY).
306If that is non-nil, the element matches;
307then `assoc-default' returns the element's cdr, if it is a cons,
526d204e 308or DEFAULT if the element is not a cons.
8a288450
RS
309
310If no element matches, the value is nil.
311If TEST is omitted or nil, `equal' is used."
312 (let (found (tail alist) value)
313 (while (and tail (not found))
314 (let ((elt (car tail)))
315 (when (funcall (or test 'equal) (if (consp elt) (car elt) elt) key)
316 (setq found t value (if (consp elt) (cdr elt) default))))
317 (setq tail (cdr tail)))
318 value))
98aae5f6 319
617631c0 320(make-obsolete 'assoc-ignore-case 'assoc-string)
98aae5f6
KH
321(defun assoc-ignore-case (key alist)
322 "Like `assoc', but ignores differences in case and text representation.
323KEY must be a string. Upper-case and lower-case letters are treated as equal.
324Unibyte strings are converted to multibyte for comparison."
617631c0 325 (assoc-string key alist t))
98aae5f6 326
617631c0 327(make-obsolete 'assoc-ignore-representation 'assoc-string)
98aae5f6
KH
328(defun assoc-ignore-representation (key alist)
329 "Like `assoc', but ignores differences in text representation.
264ef586 330KEY must be a string.
98aae5f6 331Unibyte strings are converted to multibyte for comparison."
617631c0 332 (assoc-string key alist nil))
cbbc3205
GM
333
334(defun member-ignore-case (elt list)
335 "Like `member', but ignores differences in case and text representation.
336ELT must be a string. Upper-case and lower-case letters are treated as equal.
d86a3084
RS
337Unibyte strings are converted to multibyte for comparison.
338Non-strings in LIST are ignored."
339 (while (and list
340 (not (and (stringp (car list))
341 (eq t (compare-strings elt 0 nil (car list) 0 nil t)))))
242c13e8
MB
342 (setq list (cdr list)))
343 list)
cbbc3205 344
9a5336ae 345\f
9a5336ae 346;;;; Keymap support.
be9b65ac
DL
347
348(defun undefined ()
349 (interactive)
350 (ding))
351
352;Prevent the \{...} documentation construct
353;from mentioning keys that run this command.
354(put 'undefined 'suppress-keymap t)
355
356(defun suppress-keymap (map &optional nodigits)
357 "Make MAP override all normally self-inserting keys to be undefined.
358Normally, as an exception, digits and minus-sign are set to make prefix args,
359but optional second arg NODIGITS non-nil treats them like other chars."
098ba983 360 (define-key map [remap self-insert-command] 'undefined)
be9b65ac
DL
361 (or nodigits
362 (let (loop)
363 (define-key map "-" 'negative-argument)
364 ;; Make plain numbers do numeric args.
365 (setq loop ?0)
366 (while (<= loop ?9)
367 (define-key map (char-to-string loop) 'digit-argument)
368 (setq loop (1+ loop))))))
369
f14dbba7
KH
370(defvar key-substitution-in-progress nil
371 "Used internally by substitute-key-definition.")
372
7f2c2edd 373(defun substitute-key-definition (olddef newdef keymap &optional oldmap prefix)
be9b65ac
DL
374 "Replace OLDDEF with NEWDEF for any keys in KEYMAP now defined as OLDDEF.
375In other words, OLDDEF is replaced with NEWDEF where ever it appears.
4656b314 376Alternatively, if optional fourth argument OLDMAP is specified, we redefine
18c2e791
KS
377in KEYMAP as NEWDEF those keys which are defined as OLDDEF in OLDMAP.
378
379For most uses, it is simpler and safer to use command remappping like this:
380 \(define-key KEYMAP [remap OLDDEF] NEWDEF)"
739f2672
GM
381 ;; Don't document PREFIX in the doc string because we don't want to
382 ;; advertise it. It's meant for recursive calls only. Here's its
383 ;; meaning
264ef586 384
739f2672
GM
385 ;; If optional argument PREFIX is specified, it should be a key
386 ;; prefix, a string. Redefined bindings will then be bound to the
387 ;; original key, with PREFIX added at the front.
7f2c2edd
RS
388 (or prefix (setq prefix ""))
389 (let* ((scan (or oldmap keymap))
9166dbf6 390 (prefix1 (vconcat prefix [nil]))
f14dbba7
KH
391 (key-substitution-in-progress
392 (cons scan key-substitution-in-progress)))
7f2c2edd
RS
393 ;; Scan OLDMAP, finding each char or event-symbol that
394 ;; has any definition, and act on it with hack-key.
9166dbf6
SM
395 (map-keymap
396 (lambda (char defn)
397 (aset prefix1 (length prefix) char)
398 (substitute-key-definition-key defn olddef newdef prefix1 keymap))
399 scan)))
400
401(defun substitute-key-definition-key (defn olddef newdef prefix keymap)
402 (let (inner-def skipped menu-item)
403 ;; Find the actual command name within the binding.
404 (if (eq (car-safe defn) 'menu-item)
405 (setq menu-item defn defn (nth 2 defn))
406 ;; Skip past menu-prompt.
407 (while (stringp (car-safe defn))
408 (push (pop defn) skipped))
409 ;; Skip past cached key-equivalence data for menu items.
410 (if (consp (car-safe defn))
411 (setq defn (cdr defn))))
412 (if (or (eq defn olddef)
413 ;; Compare with equal if definition is a key sequence.
414 ;; That is useful for operating on function-key-map.
415 (and (or (stringp defn) (vectorp defn))
416 (equal defn olddef)))
417 (define-key keymap prefix
418 (if menu-item
419 (let ((copy (copy-sequence menu-item)))
420 (setcar (nthcdr 2 copy) newdef)
421 copy)
422 (nconc (nreverse skipped) newdef)))
423 ;; Look past a symbol that names a keymap.
424 (setq inner-def
425 (condition-case nil (indirect-function defn) (error defn)))
426 ;; For nested keymaps, we use `inner-def' rather than `defn' so as to
427 ;; avoid autoloading a keymap. This is mostly done to preserve the
428 ;; original non-autoloading behavior of pre-map-keymap times.
429 (if (and (keymapp inner-def)
430 ;; Avoid recursively scanning
431 ;; where KEYMAP does not have a submap.
432 (let ((elt (lookup-key keymap prefix)))
433 (or (null elt) (natnump elt) (keymapp elt)))
434 ;; Avoid recursively rescanning keymap being scanned.
435 (not (memq inner-def key-substitution-in-progress)))
436 ;; If this one isn't being scanned already, scan it now.
437 (substitute-key-definition olddef newdef keymap inner-def prefix)))))
9a5336ae 438
4ced66fd 439(defun define-key-after (keymap key definition &optional after)
4434d61b
RS
440 "Add binding in KEYMAP for KEY => DEFINITION, right after AFTER's binding.
441This is like `define-key' except that the binding for KEY is placed
442just after the binding for the event AFTER, instead of at the beginning
c34a9d34
RS
443of the map. Note that AFTER must be an event type (like KEY), NOT a command
444\(like DEFINITION).
445
4ced66fd 446If AFTER is t or omitted, the new binding goes at the end of the keymap.
08b1f8a1 447AFTER should be a single event type--a symbol or a character, not a sequence.
c34a9d34 448
4ced66fd 449Bindings are always added before any inherited map.
c34a9d34 450
4ced66fd
DL
451The order of bindings in a keymap matters when it is used as a menu."
452 (unless after (setq after t))
4434d61b
RS
453 (or (keymapp keymap)
454 (signal 'wrong-type-argument (list 'keymapp keymap)))
08b1f8a1
GM
455 (setq key
456 (if (<= (length key) 1) (aref key 0)
457 (setq keymap (lookup-key keymap
458 (apply 'vector
459 (butlast (mapcar 'identity key)))))
460 (aref key (1- (length key)))))
461 (let ((tail keymap) done inserted)
4434d61b
RS
462 (while (and (not done) tail)
463 ;; Delete any earlier bindings for the same key.
08b1f8a1 464 (if (eq (car-safe (car (cdr tail))) key)
4434d61b 465 (setcdr tail (cdr (cdr tail))))
08b1f8a1
GM
466 ;; If we hit an included map, go down that one.
467 (if (keymapp (car tail)) (setq tail (car tail)))
4434d61b
RS
468 ;; When we reach AFTER's binding, insert the new binding after.
469 ;; If we reach an inherited keymap, insert just before that.
113d28a8 470 ;; If we reach the end of this keymap, insert at the end.
c34a9d34
RS
471 (if (or (and (eq (car-safe (car tail)) after)
472 (not (eq after t)))
113d28a8
RS
473 (eq (car (cdr tail)) 'keymap)
474 (null (cdr tail)))
4434d61b 475 (progn
113d28a8
RS
476 ;; Stop the scan only if we find a parent keymap.
477 ;; Keep going past the inserted element
478 ;; so we can delete any duplications that come later.
479 (if (eq (car (cdr tail)) 'keymap)
480 (setq done t))
481 ;; Don't insert more than once.
482 (or inserted
08b1f8a1 483 (setcdr tail (cons (cons key definition) (cdr tail))))
113d28a8 484 (setq inserted t)))
4434d61b
RS
485 (setq tail (cdr tail)))))
486
51fa3961 487
d128fe85
RS
488(defmacro kbd (keys)
489 "Convert KEYS to the internal Emacs key representation.
490KEYS should be a string constant in the format used for
a14b195b 491saving keyboard macros (see `edmacro-mode')."
d128fe85
RS
492 (read-kbd-macro keys))
493
8bed5e3d
RS
494(put 'keyboard-translate-table 'char-table-extra-slots 0)
495
9a5336ae
JB
496(defun keyboard-translate (from to)
497 "Translate character FROM to TO at a low level.
498This function creates a `keyboard-translate-table' if necessary
499and then modifies one entry in it."
8bed5e3d
RS
500 (or (char-table-p keyboard-translate-table)
501 (setq keyboard-translate-table
502 (make-char-table 'keyboard-translate-table nil)))
9a5336ae
JB
503 (aset keyboard-translate-table from to))
504
505\f
264ef586 506;;;; The global keymap tree.
9a5336ae
JB
507
508;;; global-map, esc-map, and ctl-x-map have their values set up in
509;;; keymap.c; we just give them docstrings here.
510
511(defvar global-map nil
512 "Default global keymap mapping Emacs keyboard input into commands.
513The value is a keymap which is usually (but not necessarily) Emacs's
514global map.")
515
516(defvar esc-map nil
517 "Default keymap for ESC (meta) commands.
518The normal global definition of the character ESC indirects to this keymap.")
519
520(defvar ctl-x-map nil
521 "Default keymap for C-x commands.
522The normal global definition of the character C-x indirects to this keymap.")
523
524(defvar ctl-x-4-map (make-sparse-keymap)
03eeb110 525 "Keymap for subcommands of C-x 4.")
059184dd 526(defalias 'ctl-x-4-prefix ctl-x-4-map)
9a5336ae
JB
527(define-key ctl-x-map "4" 'ctl-x-4-prefix)
528
529(defvar ctl-x-5-map (make-sparse-keymap)
530 "Keymap for frame commands.")
059184dd 531(defalias 'ctl-x-5-prefix ctl-x-5-map)
9a5336ae
JB
532(define-key ctl-x-map "5" 'ctl-x-5-prefix)
533
0f03054a 534\f
9a5336ae
JB
535;;;; Event manipulation functions.
536
da16e648
KH
537;; The call to `read' is to ensure that the value is computed at load time
538;; and not compiled into the .elc file. The value is negative on most
539;; machines, but not on all!
540(defconst listify-key-sequence-1 (logior 128 (read "?\\M-\\^@")))
114137b8 541
cde6d7e3
RS
542(defun listify-key-sequence (key)
543 "Convert a key sequence to a list of events."
544 (if (vectorp key)
545 (append key nil)
546 (mapcar (function (lambda (c)
547 (if (> c 127)
114137b8 548 (logxor c listify-key-sequence-1)
cde6d7e3 549 c)))
d47f7515 550 key)))
cde6d7e3 551
53e5a4e8
RS
552(defsubst eventp (obj)
553 "True if the argument is an event object."
7a2937ce
SM
554 (or (and (integerp obj)
555 ;; Filter out integers too large to be events.
556 ;; M is the biggest modifier.
557 (zerop (logand obj (lognot (1- (lsh ?\M-\^@ 1)))))
558 (char-valid-p (event-basic-type obj)))
53e5a4e8
RS
559 (and (symbolp obj)
560 (get obj 'event-symbol-elements))
561 (and (consp obj)
562 (symbolp (car obj))
563 (get (car obj) 'event-symbol-elements))))
564
565(defun event-modifiers (event)
a3111ae4 566 "Return a list of symbols representing the modifier keys in event EVENT.
53e5a4e8 567The elements of the list may include `meta', `control',
32295976 568`shift', `hyper', `super', `alt', `click', `double', `triple', `drag',
0e91dc92
LT
569and `down'.
570EVENT may be an event or an event type. If EVENT is a symbol
571that has never been used in an event that has been read as input
572in the current Emacs session, then this function can return nil,
573even when EVENT actually has modifiers."
53e5a4e8
RS
574 (let ((type event))
575 (if (listp type)
576 (setq type (car type)))
577 (if (symbolp type)
578 (cdr (get type 'event-symbol-elements))
5572c97f
RS
579 (let ((list nil)
580 (char (logand type (lognot (logior ?\M-\^@ ?\C-\^@ ?\S-\^@
581 ?\H-\^@ ?\s-\^@ ?\A-\^@)))))
582 (if (not (zerop (logand type ?\M-\^@)))
9166dbf6 583 (push 'meta list))
5572c97f
RS
584 (if (or (not (zerop (logand type ?\C-\^@)))
585 (< char 32))
9166dbf6 586 (push 'control list))
5572c97f
RS
587 (if (or (not (zerop (logand type ?\S-\^@)))
588 (/= char (downcase char)))
9166dbf6 589 (push 'shift list))
da16e648 590 (or (zerop (logand type ?\H-\^@))
9166dbf6 591 (push 'hyper list))
da16e648 592 (or (zerop (logand type ?\s-\^@))
9166dbf6 593 (push 'super list))
da16e648 594 (or (zerop (logand type ?\A-\^@))
9166dbf6 595 (push 'alt list))
53e5a4e8
RS
596 list))))
597
d63de416 598(defun event-basic-type (event)
a3111ae4 599 "Return the basic type of the given event (all modifiers removed).
0e91dc92
LT
600The value is a printing character (not upper case) or a symbol.
601EVENT may be an event or an event type. If EVENT is a symbol
602that has never been used in an event that has been read as input
603in the current Emacs session, then this function may return nil."
2b0f4ba5
JB
604 (if (consp event)
605 (setq event (car event)))
d63de416
RS
606 (if (symbolp event)
607 (car (get event 'event-symbol-elements))
a8a64811 608 (let ((base (logand event (1- ?\A-\^@))))
d63de416
RS
609 (downcase (if (< base 32) (logior base 64) base)))))
610
0f03054a
RS
611(defsubst mouse-movement-p (object)
612 "Return non-nil if OBJECT is a mouse movement event."
9166dbf6 613 (eq (car-safe object) 'mouse-movement))
0f03054a
RS
614
615(defsubst event-start (event)
616 "Return the starting position of EVENT.
17f53ffa 617If EVENT is a mouse or key press or a mouse click, this returns the location
0f03054a
RS
618of the event.
619If EVENT is a drag, this returns the drag's starting position.
620The return value is of the form
4385264a
KS
621 (WINDOW AREA-OR-POS (X . Y) TIMESTAMP OBJECT POS (COL . ROW)
622 IMAGE (DX . DY) (WIDTH . HEIGHT))
0f03054a 623The `posn-' functions access elements of such lists."
5ef6a86d
SM
624 (if (consp event) (nth 1 event)
625 (list (selected-window) (point) '(0 . 0) 0)))
0f03054a
RS
626
627(defsubst event-end (event)
17f53ffa
SM
628 "Return the ending location of EVENT.
629EVENT should be a click, drag, or key press event.
0f03054a
RS
630If EVENT is a click event, this function is the same as `event-start'.
631The return value is of the form
4385264a
KS
632 (WINDOW AREA-OR-POS (X . Y) TIMESTAMP OBJECT POS (COL . ROW)
633 IMAGE (DX . DY) (WIDTH . HEIGHT))
0f03054a 634The `posn-' functions access elements of such lists."
5ef6a86d
SM
635 (if (consp event) (nth (if (consp (nth 2 event)) 2 1) event)
636 (list (selected-window) (point) '(0 . 0) 0)))
0f03054a 637
32295976
RS
638(defsubst event-click-count (event)
639 "Return the multi-click count of EVENT, a click or drag event.
640The return value is a positive integer."
5ef6a86d 641 (if (and (consp event) (integerp (nth 2 event))) (nth 2 event) 1))
32295976 642
0f03054a
RS
643(defsubst posn-window (position)
644 "Return the window in POSITION.
79bcefe2 645POSITION should be a list of the form returned by the `event-start'
a6d2eef7 646and `event-end' functions."
0f03054a
RS
647 (nth 0 position))
648
79bcefe2
KS
649(defsubst posn-area (position)
650 "Return the window area recorded in POSITION, or nil for the text area.
651POSITION should be a list of the form returned by the `event-start'
a6d2eef7 652and `event-end' functions."
79bcefe2
KS
653 (let ((area (if (consp (nth 1 position))
654 (car (nth 1 position))
655 (nth 1 position))))
656 (and (symbolp area) area)))
657
0f03054a
RS
658(defsubst posn-point (position)
659 "Return the buffer location in POSITION.
79bcefe2 660POSITION should be a list of the form returned by the `event-start'
a6d2eef7 661and `event-end' functions."
79bcefe2
KS
662 (or (nth 5 position)
663 (if (consp (nth 1 position))
664 (car (nth 1 position))
665 (nth 1 position))))
0f03054a 666
17f53ffa
SM
667(defun posn-set-point (position)
668 "Move point to POSITION.
669Select the corresponding window as well."
3affc0c7 670 (if (not (windowp (posn-window position)))
17f53ffa 671 (error "Position not in text area of window"))
3affc0c7
JPW
672 (select-window (posn-window position))
673 (if (numberp (posn-point position))
674 (goto-char (posn-point position))))
17f53ffa 675
e55c21be
RS
676(defsubst posn-x-y (position)
677 "Return the x and y coordinates in POSITION.
79bcefe2 678POSITION should be a list of the form returned by the `event-start'
a6d2eef7 679and `event-end' functions."
0f03054a
RS
680 (nth 2 position))
681
ed627e08 682(defun posn-col-row (position)
79bcefe2
KS
683 "Return the nominal column and row in POSITION, measured in characters.
684The column and row values are approximations calculated from the x
685and y coordinates in POSITION and the frame's default character width
a6d2eef7 686and height.
ed627e08 687For a scroll-bar event, the result column is 0, and the row
79bcefe2
KS
688corresponds to the vertical position of the click in the scroll bar.
689POSITION should be a list of the form returned by the `event-start'
a6d2eef7 690and `event-end' functions."
79bcefe2
KS
691 (let* ((pair (posn-x-y position))
692 (window (posn-window position))
693 (area (posn-area position)))
694 (cond
695 ((null window)
696 '(0 . 0))
697 ((eq area 'vertical-scroll-bar)
698 (cons 0 (scroll-bar-scale pair (1- (window-height window)))))
699 ((eq area 'horizontal-scroll-bar)
700 (cons (scroll-bar-scale pair (window-width window)) 0))
701 (t
702 (let* ((frame (if (framep window) window (window-frame window)))
703 (x (/ (car pair) (frame-char-width frame)))
704 (y (/ (cdr pair) (+ (frame-char-height frame)
705 (or (frame-parameter frame 'line-spacing)
706 default-line-spacing
707 0)))))
708 (cons x y))))))
709
710(defun posn-actual-col-row (position)
711 "Return the actual column and row in POSITION, measured in characters.
712These are the actual row number in the window and character number in that row.
713Return nil if POSITION does not contain the actual position; in that case
714`posn-col-row' can be used to get approximate values.
715POSITION should be a list of the form returned by the `event-start'
a6d2eef7 716and `event-end' functions."
79bcefe2 717 (nth 6 position))
e55c21be 718
0f03054a
RS
719(defsubst posn-timestamp (position)
720 "Return the timestamp of POSITION.
79bcefe2 721POSITION should be a list of the form returned by the `event-start'
a6d2eef7 722and `event-end' functions."
0f03054a 723 (nth 3 position))
9a5336ae 724
4385264a
KS
725(defsubst posn-string (position)
726 "Return the string object of POSITION, or nil if a buffer position.
79bcefe2 727POSITION should be a list of the form returned by the `event-start'
a6d2eef7 728and `event-end' functions."
79bcefe2
KS
729 (nth 4 position))
730
4385264a
KS
731(defsubst posn-image (position)
732 "Return the image object of POSITION, or nil if a not an image.
733POSITION should be a list of the form returned by the `event-start'
a6d2eef7 734and `event-end' functions."
4385264a
KS
735 (nth 7 position))
736
737(defsubst posn-object (position)
738 "Return the object (image or string) of POSITION.
739POSITION should be a list of the form returned by the `event-start'
a6d2eef7 740and `event-end' functions."
4385264a
KS
741 (or (posn-image position) (posn-string position)))
742
e08f9a0d
KS
743(defsubst posn-object-x-y (position)
744 "Return the x and y coordinates relative to the object of POSITION.
745POSITION should be a list of the form returned by the `event-start'
a6d2eef7 746and `event-end' functions."
4385264a
KS
747 (nth 8 position))
748
749(defsubst posn-object-width-height (position)
750 "Return the pixel width and height of the object of POSITION.
751POSITION should be a list of the form returned by the `event-start'
a6d2eef7 752and `event-end' functions."
4385264a 753 (nth 9 position))
e08f9a0d 754
0f03054a 755\f
9a5336ae
JB
756;;;; Obsolescent names for functions.
757
059184dd
ER
758(defalias 'dot 'point)
759(defalias 'dot-marker 'point-marker)
760(defalias 'dot-min 'point-min)
761(defalias 'dot-max 'point-max)
762(defalias 'window-dot 'window-point)
763(defalias 'set-window-dot 'set-window-point)
764(defalias 'read-input 'read-string)
765(defalias 'send-string 'process-send-string)
766(defalias 'send-region 'process-send-region)
767(defalias 'show-buffer 'set-window-buffer)
768(defalias 'buffer-flush-undo 'buffer-disable-undo)
769(defalias 'eval-current-buffer 'eval-buffer)
770(defalias 'compiled-function-p 'byte-code-function-p)
ae1cc031 771(defalias 'define-function 'defalias)
be9b65ac 772
0cba3a0f 773(defalias 'sref 'aref)
2598a293 774(make-obsolete 'sref 'aref "20.4")
1c12af5c 775(make-obsolete 'char-bytes "now always returns 1." "20.4")
9af6aa14 776(make-obsolete 'chars-in-region "use (abs (- BEG END))." "20.3")
b4591b37
JB
777(make-obsolete 'dot 'point "before 19.15")
778(make-obsolete 'dot-max 'point-max "before 19.15")
779(make-obsolete 'dot-min 'point-min "before 19.15")
780(make-obsolete 'dot-marker 'point-marker "before 19.15")
781(make-obsolete 'buffer-flush-undo 'buffer-disable-undo "before 19.15")
faa79da6 782(make-obsolete 'baud-rate "use the `baud-rate' variable instead." "before 19.15")
b4591b37
JB
783(make-obsolete 'compiled-function-p 'byte-code-function-p "before 19.15")
784(make-obsolete 'define-function 'defalias "20.1")
faa79da6
JB
785(make-obsolete 'focus-frame "it does nothing." "19.32")
786(make-obsolete 'unfocus-frame "it does nothing." "19.32")
6bb762b3 787
676927b7
PJ
788(defun insert-string (&rest args)
789 "Mocklisp-compatibility insert function.
790Like the function `insert' except that any argument that is a number
791is converted into a string by expressing it in decimal."
792 (dolist (el args)
793 (insert (if (integerp el) (number-to-string el) el))))
9e028368
SM
794(make-obsolete 'insert-string 'insert "21.4")
795(defun makehash (&optional test) (make-hash-table :test (or test 'eql)))
796(make-obsolete 'makehash 'make-hash-table "21.4")
676927b7 797
9a5336ae
JB
798;; Some programs still use this as a function.
799(defun baud-rate ()
8eb93953 800 "Return the value of the `baud-rate' variable."
9a5336ae
JB
801 baud-rate)
802
faa79da6
JB
803(defalias 'focus-frame 'ignore "")
804(defalias 'unfocus-frame 'ignore "")
bd292357
JB
805
806\f
807;;;; Obsolescence declarations for variables.
808
809(make-obsolete-variable 'directory-sep-char "do not use it." "21.1")
810(make-obsolete-variable 'mode-line-inverse-video "use the appropriate faces instead." "21.1")
811(make-obsolete-variable 'unread-command-char
812 "use `unread-command-events' instead. That variable is a list of events to reread, so it now uses nil to mean `no event', instead of -1."
813 "before 19.15")
814(make-obsolete-variable 'executing-macro 'executing-kbd-macro "before 19.34")
815(make-obsolete-variable 'post-command-idle-hook
816 "use timers instead, with `run-with-idle-timer'." "before 19.34")
817(make-obsolete-variable 'post-command-idle-delay
818 "use timers instead, with `run-with-idle-timer'." "before 19.34")
819
9a5336ae
JB
820\f
821;;;; Alternate names for functions - these are not being phased out.
822
059184dd
ER
823(defalias 'string= 'string-equal)
824(defalias 'string< 'string-lessp)
825(defalias 'move-marker 'set-marker)
059184dd
ER
826(defalias 'rplaca 'setcar)
827(defalias 'rplacd 'setcdr)
eb8c3be9 828(defalias 'beep 'ding) ;preserve lingual purity
059184dd
ER
829(defalias 'indent-to-column 'indent-to)
830(defalias 'backward-delete-char 'delete-backward-char)
831(defalias 'search-forward-regexp (symbol-function 're-search-forward))
832(defalias 'search-backward-regexp (symbol-function 're-search-backward))
833(defalias 'int-to-string 'number-to-string)
024ae2c6 834(defalias 'store-match-data 'set-match-data)
112f332f 835(defalias 'make-variable-frame-localizable 'make-variable-frame-local)
d6c22d46 836;; These are the XEmacs names:
475fb2fb
KH
837(defalias 'point-at-eol 'line-end-position)
838(defalias 'point-at-bol 'line-beginning-position)
37f6661a
JB
839
840;;; Should this be an obsolete name? If you decide it should, you get
841;;; to go through all the sources and change them.
059184dd 842(defalias 'string-to-int 'string-to-number)
be9b65ac 843\f
9a5336ae 844;;;; Hook manipulation functions.
be9b65ac 845
0e4d378b
RS
846(defun make-local-hook (hook)
847 "Make the hook HOOK local to the current buffer.
71c78f01
RS
848The return value is HOOK.
849
c344cf32
SM
850You never need to call this function now that `add-hook' does it for you
851if its LOCAL argument is non-nil.
852
0e4d378b
RS
853When a hook is local, its local and global values
854work in concert: running the hook actually runs all the hook
855functions listed in *either* the local value *or* the global value
856of the hook variable.
857
08b1f8a1 858This function works by making t a member of the buffer-local value,
7dd1926e
RS
859which acts as a flag to run the hook functions in the default value as
860well. This works for all normal hooks, but does not work for most
861non-normal hooks yet. We will be changing the callers of non-normal
862hooks so that they can handle localness; this has to be done one by
863one.
864
865This function does nothing if HOOK is already local in the current
866buffer.
0e4d378b
RS
867
868Do not use `make-local-variable' to make a hook variable buffer-local."
869 (if (local-variable-p hook)
870 nil
871 (or (boundp hook) (set hook nil))
872 (make-local-variable hook)
71c78f01
RS
873 (set hook (list t)))
874 hook)
8eb93953 875(make-obsolete 'make-local-hook "not necessary any more." "21.1")
0e4d378b
RS
876
877(defun add-hook (hook function &optional append local)
32295976
RS
878 "Add to the value of HOOK the function FUNCTION.
879FUNCTION is not added if already present.
880FUNCTION is added (if necessary) at the beginning of the hook list
881unless the optional argument APPEND is non-nil, in which case
882FUNCTION is added at the end.
883
0e4d378b
RS
884The optional fourth argument, LOCAL, if non-nil, says to modify
885the hook's buffer-local value rather than its default value.
61a3d8c4
RS
886This makes the hook buffer-local if needed, and it makes t a member
887of the buffer-local value. That acts as a flag to run the hook
888functions in the default value as well as in the local value.
0e4d378b 889
32295976
RS
890HOOK should be a symbol, and FUNCTION may be any valid function. If
891HOOK is void, it is first set to nil. If HOOK's value is a single
aa09b5ca 892function, it is changed to a list of functions."
be9b65ac 893 (or (boundp hook) (set hook nil))
0e4d378b 894 (or (default-boundp hook) (set-default hook nil))
08b1f8a1
GM
895 (if local (unless (local-variable-if-set-p hook)
896 (set (make-local-variable hook) (list t)))
8947a5e2
SM
897 ;; Detect the case where make-local-variable was used on a hook
898 ;; and do what we used to do.
552eb607 899 (unless (and (consp (symbol-value hook)) (memq t (symbol-value hook)))
8947a5e2
SM
900 (setq local t)))
901 (let ((hook-value (if local (symbol-value hook) (default-value hook))))
902 ;; If the hook value is a single function, turn it into a list.
903 (when (or (not (listp hook-value)) (eq (car hook-value) 'lambda))
2248c40d 904 (setq hook-value (list hook-value)))
8947a5e2
SM
905 ;; Do the actual addition if necessary
906 (unless (member function hook-value)
907 (setq hook-value
908 (if append
909 (append hook-value (list function))
910 (cons function hook-value))))
911 ;; Set the actual variable
912 (if local (set hook hook-value) (set-default hook hook-value))))
0e4d378b
RS
913
914(defun remove-hook (hook function &optional local)
24980d16
RS
915 "Remove from the value of HOOK the function FUNCTION.
916HOOK should be a symbol, and FUNCTION may be any valid function. If
917FUNCTION isn't the value of HOOK, or, if FUNCTION doesn't appear in the
0e4d378b
RS
918list of hooks to run in HOOK, then nothing is done. See `add-hook'.
919
920The optional third argument, LOCAL, if non-nil, says to modify
b7a1c900 921the hook's buffer-local value rather than its default value."
8947a5e2
SM
922 (or (boundp hook) (set hook nil))
923 (or (default-boundp hook) (set-default hook nil))
b7a1c900
RS
924 ;; Do nothing if LOCAL is t but this hook has no local binding.
925 (unless (and local (not (local-variable-p hook)))
8947a5e2
SM
926 ;; Detect the case where make-local-variable was used on a hook
927 ;; and do what we used to do.
b7a1c900
RS
928 (when (and (local-variable-p hook)
929 (not (and (consp (symbol-value hook))
930 (memq t (symbol-value hook)))))
931 (setq local t))
932 (let ((hook-value (if local (symbol-value hook) (default-value hook))))
933 ;; Remove the function, for both the list and the non-list cases.
934 (if (or (not (listp hook-value)) (eq (car hook-value) 'lambda))
935 (if (equal hook-value function) (setq hook-value nil))
936 (setq hook-value (delete function (copy-sequence hook-value))))
937 ;; If the function is on the global hook, we need to shadow it locally
938 ;;(when (and local (member function (default-value hook))
939 ;; (not (member (cons 'not function) hook-value)))
940 ;; (push (cons 'not function) hook-value))
941 ;; Set the actual variable
942 (if (not local)
943 (set-default hook hook-value)
944 (if (equal hook-value '(t))
945 (kill-local-variable hook)
946 (set hook hook-value))))))
6e3af630 947
c8bfa689 948(defun add-to-list (list-var element &optional append)
8851c1f0 949 "Add to the value of LIST-VAR the element ELEMENT if it isn't there yet.
9f0b1f09 950The test for presence of ELEMENT is done with `equal'.
c8bfa689
MB
951If ELEMENT is added, it is added at the beginning of the list,
952unless the optional argument APPEND is non-nil, in which case
953ELEMENT is added at the end.
508bcbca 954
daebae3d
PJ
955The return value is the new value of LIST-VAR.
956
8851c1f0
RS
957If you want to use `add-to-list' on a variable that is not defined
958until a certain package is loaded, you should put the call to `add-to-list'
959into a hook function that will be run only after loading the package.
960`eval-after-load' provides one way to do this. In some cases
961other hooks, such as major mode hooks, can do the job."
15171a06
KH
962 (if (member element (symbol-value list-var))
963 (symbol-value list-var)
c8bfa689
MB
964 (set list-var
965 (if append
966 (append (symbol-value list-var) (list element))
967 (cons element (symbol-value list-var))))))
448a0170
MB
968
969\f
970;;; Load history
971
a2c4ae01
RS
972;;; (defvar symbol-file-load-history-loaded nil
973;;; "Non-nil means we have loaded the file `fns-VERSION.el' in `exec-directory'.
974;;; That file records the part of `load-history' for preloaded files,
975;;; which is cleared out before dumping to make Emacs smaller.")
976
977;;; (defun load-symbol-file-load-history ()
978;;; "Load the file `fns-VERSION.el' in `exec-directory' if not already done.
979;;; That file records the part of `load-history' for preloaded files,
980;;; which is cleared out before dumping to make Emacs smaller."
981;;; (unless symbol-file-load-history-loaded
982;;; (load (expand-file-name
983;;; ;; fns-XX.YY.ZZ.el does not work on DOS filesystem.
984;;; (if (eq system-type 'ms-dos)
985;;; "fns.el"
986;;; (format "fns-%s.el" emacs-version))
987;;; exec-directory)
988;;; ;; The file name fns-%s.el already has a .el extension.
989;;; nil nil t)
990;;; (setq symbol-file-load-history-loaded t)))
448a0170
MB
991
992(defun symbol-file (function)
993 "Return the input source from which FUNCTION was loaded.
994The value is normally a string that was passed to `load':
995either an absolute file name, or a library name
996\(with no directory name and no `.el' or `.elc' at the end).
997It can also be nil, if the definition is not associated with any file."
e9f13a95
SM
998 (if (and (symbolp function) (fboundp function)
999 (eq 'autoload (car-safe (symbol-function function))))
1000 (nth 1 (symbol-function function))
1001 (let ((files load-history)
cb21744e 1002 file)
e9f13a95 1003 (while files
12320833 1004 (if (member function (cdr (car files)))
e9f13a95
SM
1005 (setq file (car (car files)) files nil))
1006 (setq files (cdr files)))
1007 file)))
448a0170 1008
be9b65ac 1009\f
9a5336ae
JB
1010;;;; Specifying things to do after certain files are loaded.
1011
1012(defun eval-after-load (file form)
1013 "Arrange that, if FILE is ever loaded, FORM will be run at that time.
1014This makes or adds to an entry on `after-load-alist'.
90914938 1015If FILE is already loaded, evaluate FORM right now.
12c7071c 1016It does nothing if FORM is already on the list for FILE.
19594307
DL
1017FILE must match exactly. Normally FILE is the name of a library,
1018with no directory or extension specified, since that is how `load'
a2d7836f
SM
1019is normally called.
1020FILE can also be a feature (i.e. a symbol), in which case FORM is
1021evaluated whenever that feature is `provide'd."
12c7071c 1022 (let ((elt (assoc file after-load-alist)))
a2d7836f
SM
1023 ;; Make sure there is an element for FILE.
1024 (unless elt (setq elt (list file)) (push elt after-load-alist))
1025 ;; Add FORM to the element if it isn't there.
1026 (unless (member form (cdr elt))
1027 (nconc elt (list form))
1028 ;; If the file has been loaded already, run FORM right away.
1029 (if (if (symbolp file)
1030 (featurep file)
1031 ;; Make sure `load-history' contains the files dumped with
1032 ;; Emacs for the case that FILE is one of them.
e9f13a95 1033 ;; (load-symbol-file-load-history)
a2d7836f
SM
1034 (assoc file load-history))
1035 (eval form))))
9a5336ae
JB
1036 form)
1037
1038(defun eval-next-after-load (file)
1039 "Read the following input sexp, and run it whenever FILE is loaded.
1040This makes or adds to an entry on `after-load-alist'.
1041FILE should be the name of a library, with no directory name."
1042 (eval-after-load file (read)))
7aaacaff
RS
1043\f
1044;;; make-network-process wrappers
1045
1046(if (featurep 'make-network-process)
1047 (progn
1048
1049(defun open-network-stream (name buffer host service)
1050 "Open a TCP connection for a service to a host.
1051Returns a subprocess-object to represent the connection.
1052Input and output work as for subprocesses; `delete-process' closes it.
a478f3e1 1053
7aaacaff
RS
1054Args are NAME BUFFER HOST SERVICE.
1055NAME is name for process. It is modified if necessary to make it unique.
54ce7cbf 1056BUFFER is the buffer (or buffer name) to associate with the process.
7aaacaff
RS
1057 Process output goes at end of that buffer, unless you specify
1058 an output stream or filter function to handle the output.
1059 BUFFER may be also nil, meaning that this process is not associated
54ce7cbf
JB
1060 with any buffer.
1061HOST is name of the host to connect to, or its IP address.
1062SERVICE is name of the service desired, or an integer specifying
1063 a port number to connect to."
7aaacaff
RS
1064 (make-network-process :name name :buffer buffer
1065 :host host :service service))
1066
1067(defun open-network-stream-nowait (name buffer host service &optional sentinel filter)
1068 "Initiate connection to a TCP connection for a service to a host.
1069It returns nil if non-blocking connects are not supported; otherwise,
1070it returns a subprocess-object to represent the connection.
1071
54ce7cbf
JB
1072This function is similar to `open-network-stream', except that it
1073returns before the connection is established. When the connection
1074is completed, the sentinel function will be called with second arg
1075matching `open' (if successful) or `failed' (on error).
7aaacaff
RS
1076
1077Args are NAME BUFFER HOST SERVICE SENTINEL FILTER.
1078NAME, BUFFER, HOST, and SERVICE are as for `open-network-stream'.
54ce7cbf 1079Optional args SENTINEL and FILTER specify the sentinel and filter
7aaacaff
RS
1080functions to be used for this network stream."
1081 (if (featurep 'make-network-process '(:nowait t))
1082 (make-network-process :name name :buffer buffer :nowait t
1083 :host host :service service
1084 :filter filter :sentinel sentinel)))
1085
1086(defun open-network-stream-server (name buffer service &optional sentinel filter)
1087 "Create a network server process for a TCP service.
1088It returns nil if server processes are not supported; otherwise,
1089it returns a subprocess-object to represent the server.
1090
1091When a client connects to the specified service, a new subprocess
1092is created to handle the new connection, and the sentinel function
1093is called for the new process.
1094
1095Args are NAME BUFFER SERVICE SENTINEL FILTER.
1096NAME is name for the server process. Client processes are named by
54ce7cbf
JB
1097 appending the ip-address and port number of the client to NAME.
1098BUFFER is the buffer (or buffer name) to associate with the server
1099 process. Client processes will not get a buffer if a process filter
1100 is specified or BUFFER is nil; otherwise, a new buffer is created for
1101 the client process. The name is similar to the process name.
7aaacaff 1102Third arg SERVICE is name of the service desired, or an integer
54ce7cbf
JB
1103 specifying a port number to connect to. It may also be t to select
1104 an unused port number for the server.
1105Optional args SENTINEL and FILTER specify the sentinel and filter
1106 functions to be used for the client processes; the server process
1107 does not use these function."
7aaacaff
RS
1108 (if (featurep 'make-network-process '(:server t))
1109 (make-network-process :name name :buffer buffer
1110 :service service :server t :noquery t
1111 :sentinel sentinel :filter filter)))
1112
1113)) ;; (featurep 'make-network-process)
1114
1115
1116;; compatibility
1117
a478f3e1 1118(make-obsolete 'process-kill-without-query
faa79da6 1119 "use `process-query-on-exit-flag' or `set-process-query-on-exit-flag'."
845aa1ef 1120 "21.4")
7aaacaff
RS
1121(defun process-kill-without-query (process &optional flag)
1122 "Say no query needed if PROCESS is running when Emacs is exited.
1123Optional second argument if non-nil says to require a query.
a478f3e1 1124Value is t if a query was formerly required."
7aaacaff
RS
1125 (let ((old (process-query-on-exit-flag process)))
1126 (set-process-query-on-exit-flag process nil)
1127 old))
9a5336ae 1128
34368d12
KS
1129;; process plist management
1130
1131(defun process-get (process propname)
1132 "Return the value of PROCESS' PROPNAME property.
1133This is the last value stored with `(process-put PROCESS PROPNAME VALUE)'."
1134 (plist-get (process-plist process) propname))
1135
1136(defun process-put (process propname value)
1137 "Change PROCESS' PROPNAME property to VALUE.
1138It can be retrieved with `(process-get PROCESS PROPNAME)'."
f1180544 1139 (set-process-plist process
34368d12
KS
1140 (plist-put (process-plist process) propname value)))
1141
9a5336ae
JB
1142\f
1143;;;; Input and display facilities.
1144
77a5664f 1145(defvar read-quoted-char-radix 8
1ba764de 1146 "*Radix for \\[quoted-insert] and other uses of `read-quoted-char'.
77a5664f
RS
1147Legitimate radix values are 8, 10 and 16.")
1148
1149(custom-declare-variable-early
264ef586 1150 'read-quoted-char-radix 8
77a5664f 1151 "*Radix for \\[quoted-insert] and other uses of `read-quoted-char'.
1ba764de
RS
1152Legitimate radix values are 8, 10 and 16."
1153 :type '(choice (const 8) (const 10) (const 16))
1154 :group 'editing-basics)
1155
9a5336ae 1156(defun read-quoted-char (&optional prompt)
2444730b
RS
1157 "Like `read-char', but do not allow quitting.
1158Also, if the first character read is an octal digit,
1159we read any number of octal digits and return the
569b03f2 1160specified character code. Any nondigit terminates the sequence.
1ba764de 1161If the terminator is RET, it is discarded;
2444730b
RS
1162any other terminator is used itself as input.
1163
569b03f2
RS
1164The optional argument PROMPT specifies a string to use to prompt the user.
1165The variable `read-quoted-char-radix' controls which radix to use
1166for numeric input."
c83256a0 1167 (let ((message-log-max nil) done (first t) (code 0) char translated)
2444730b
RS
1168 (while (not done)
1169 (let ((inhibit-quit first)
42e636f0
KH
1170 ;; Don't let C-h get the help message--only help function keys.
1171 (help-char nil)
1172 (help-form
1173 "Type the special character you want to use,
2444730b 1174or the octal character code.
1ba764de 1175RET terminates the character code and is discarded;
2444730b 1176any other non-digit terminates the character code and is then used as input."))
3f0161d0 1177 (setq char (read-event (and prompt (format "%s-" prompt)) t))
9a5336ae 1178 (if inhibit-quit (setq quit-flag nil)))
3f0161d0
SM
1179 ;; Translate TAB key into control-I ASCII character, and so on.
1180 ;; Note: `read-char' does it using the `ascii-character' property.
1181 ;; We could try and use read-key-sequence instead, but then C-q ESC
1182 ;; or C-q C-x might not return immediately since ESC or C-x might be
1183 ;; bound to some prefix in function-key-map or key-translation-map.
c83256a0
RS
1184 (setq translated char)
1185 (let ((translation (lookup-key function-key-map (vector char))))
1186 (if (arrayp translation)
1187 (setq translated (aref translation 0))))
1188 (cond ((null translated))
1189 ((not (integerp translated))
1190 (setq unread-command-events (list char)
1ba764de 1191 done t))
c83256a0 1192 ((/= (logand translated ?\M-\^@) 0)
bf896a1b 1193 ;; Turn a meta-character into a character with the 0200 bit set.
c83256a0 1194 (setq code (logior (logand translated (lognot ?\M-\^@)) 128)
bf896a1b 1195 done t))
c83256a0
RS
1196 ((and (<= ?0 translated) (< translated (+ ?0 (min 10 read-quoted-char-radix))))
1197 (setq code (+ (* code read-quoted-char-radix) (- translated ?0)))
1198 (and prompt (setq prompt (message "%s %c" prompt translated))))
1199 ((and (<= ?a (downcase translated))
d47f7515 1200 (< (downcase translated) (+ ?a -10 (min 36 read-quoted-char-radix))))
92304bc8 1201 (setq code (+ (* code read-quoted-char-radix)
c83256a0
RS
1202 (+ 10 (- (downcase translated) ?a))))
1203 (and prompt (setq prompt (message "%s %c" prompt translated))))
1204 ((and (not first) (eq translated ?\C-m))
2444730b
RS
1205 (setq done t))
1206 ((not first)
c83256a0 1207 (setq unread-command-events (list char)
2444730b 1208 done t))
c83256a0 1209 (t (setq code translated
2444730b
RS
1210 done t)))
1211 (setq first nil))
bf896a1b 1212 code))
9a5336ae 1213
44071d6b
RS
1214(defun read-passwd (prompt &optional confirm default)
1215 "Read a password, prompting with PROMPT. Echo `.' for each character typed.
e0e4cb7a 1216End with RET, LFD, or ESC. DEL or C-h rubs out. C-u kills line.
cba61075 1217If optional CONFIRM is non-nil, read password twice to make sure.
44071d6b
RS
1218Optional DEFAULT is a default password to use instead of empty input."
1219 (if confirm
1220 (let (success)
1221 (while (not success)
1222 (let ((first (read-passwd prompt nil default))
1223 (second (read-passwd "Confirm password: " nil default)))
1224 (if (equal first second)
fe10cef0 1225 (progn
f0491f76 1226 (and (arrayp second) (clear-string second))
fe10cef0 1227 (setq success first))
f0491f76
RS
1228 (and (arrayp first) (clear-string first))
1229 (and (arrayp second) (clear-string second))
44071d6b
RS
1230 (message "Password not repeated accurately; please start over")
1231 (sit-for 1))))
1232 success)
1233 (let ((pass nil)
1234 (c 0)
1235 (echo-keystrokes 0)
1236 (cursor-in-echo-area t))
1237 (while (progn (message "%s%s"
1238 prompt
1239 (make-string (length pass) ?.))
42ccb7c8 1240 (setq c (read-char-exclusive nil t))
44071d6b 1241 (and (/= c ?\r) (/= c ?\n) (/= c ?\e)))
719349f6 1242 (clear-this-command-keys)
44071d6b 1243 (if (= c ?\C-u)
fe10cef0 1244 (progn
f0491f76 1245 (and (arrayp pass) (clear-string pass))
fe10cef0 1246 (setq pass ""))
44071d6b 1247 (if (and (/= c ?\b) (/= c ?\177))
fe10cef0
GM
1248 (let* ((new-char (char-to-string c))
1249 (new-pass (concat pass new-char)))
f0491f76
RS
1250 (and (arrayp pass) (clear-string pass))
1251 (clear-string new-char)
fe10cef0
GM
1252 (setq c ?\0)
1253 (setq pass new-pass))
44071d6b 1254 (if (> (length pass) 0)
fe10cef0 1255 (let ((new-pass (substring pass 0 -1)))
f0491f76 1256 (and (arrayp pass) (clear-string pass))
fe10cef0 1257 (setq pass new-pass))))))
44071d6b
RS
1258 (message nil)
1259 (or pass default ""))))
9bf2aa6a
SM
1260
1261;; This should be used by `call-interactively' for `n' specs.
1262(defun read-number (prompt &optional default)
1263 (let ((n nil))
1264 (when default
1265 (setq prompt
2d14d61e
MB
1266 (if (string-match "\\(\\):[ \t]*\\'" prompt)
1267 (replace-match (format " (default %s)" default) t t prompt 1)
1268 (replace-regexp-in-string "[ \t]*\\'"
1269 (format " (default %s) " default)
f8cf33b1 1270 prompt t t))))
9bf2aa6a
SM
1271 (while
1272 (progn
1273 (let ((str (read-from-minibuffer prompt nil nil nil nil
c7863346
SM
1274 (and default
1275 (number-to-string default)))))
9bf2aa6a
SM
1276 (setq n (cond
1277 ((zerop (length str)) default)
1278 ((stringp str) (read str)))))
1279 (unless (numberp n)
1280 (message "Please enter a number.")
1281 (sit-for 1)
1282 t)))
1283 n))
e0e4cb7a 1284\f
2493767e
RS
1285;;; Atomic change groups.
1286
69cae2d4
RS
1287(defmacro atomic-change-group (&rest body)
1288 "Perform BODY as an atomic change group.
1289This means that if BODY exits abnormally,
1290all of its changes to the current buffer are undone.
b9ab4064 1291This works regardless of whether undo is enabled in the buffer.
69cae2d4
RS
1292
1293This mechanism is transparent to ordinary use of undo;
1294if undo is enabled in the buffer and BODY succeeds, the
1295user can undo the change normally."
1296 (let ((handle (make-symbol "--change-group-handle--"))
1297 (success (make-symbol "--change-group-success--")))
1298 `(let ((,handle (prepare-change-group))
1299 (,success nil))
1300 (unwind-protect
1301 (progn
1302 ;; This is inside the unwind-protect because
1303 ;; it enables undo if that was disabled; we need
1304 ;; to make sure that it gets disabled again.
1305 (activate-change-group ,handle)
1306 ,@body
1307 (setq ,success t))
1308 ;; Either of these functions will disable undo
1309 ;; if it was disabled before.
1310 (if ,success
1311 (accept-change-group ,handle)
1312 (cancel-change-group ,handle))))))
1313
62ea1306 1314(defun prepare-change-group (&optional buffer)
69cae2d4 1315 "Return a handle for the current buffer's state, for a change group.
62ea1306 1316If you specify BUFFER, make a handle for BUFFER's state instead.
69cae2d4
RS
1317
1318Pass the handle to `activate-change-group' afterward to initiate
1319the actual changes of the change group.
1320
1321To finish the change group, call either `accept-change-group' or
1322`cancel-change-group' passing the same handle as argument. Call
1323`accept-change-group' to accept the changes in the group as final;
1324call `cancel-change-group' to undo them all. You should use
1325`unwind-protect' to make sure the group is always finished. The call
1326to `activate-change-group' should be inside the `unwind-protect'.
1327Once you finish the group, don't use the handle again--don't try to
1328finish the same group twice. For a simple example of correct use, see
1329the source code of `atomic-change-group'.
1330
1331The handle records only the specified buffer. To make a multibuffer
1332change group, call this function once for each buffer you want to
1333cover, then use `nconc' to combine the returned values, like this:
1334
1335 (nconc (prepare-change-group buffer-1)
1336 (prepare-change-group buffer-2))
1337
1338You can then activate that multibuffer change group with a single
1339call to `activate-change-group' and finish it with a single call
1340to `accept-change-group' or `cancel-change-group'."
1341
62ea1306
RS
1342 (if buffer
1343 (list (cons buffer (with-current-buffer buffer buffer-undo-list)))
1344 (list (cons (current-buffer) buffer-undo-list))))
69cae2d4
RS
1345
1346(defun activate-change-group (handle)
1347 "Activate a change group made with `prepare-change-group' (which see)."
1348 (dolist (elt handle)
1349 (with-current-buffer (car elt)
1350 (if (eq buffer-undo-list t)
1351 (setq buffer-undo-list nil)))))
1352
1353(defun accept-change-group (handle)
1354 "Finish a change group made with `prepare-change-group' (which see).
1355This finishes the change group by accepting its changes as final."
1356 (dolist (elt handle)
1357 (with-current-buffer (car elt)
1358 (if (eq elt t)
1359 (setq buffer-undo-list t)))))
1360
1361(defun cancel-change-group (handle)
1362 "Finish a change group made with `prepare-change-group' (which see).
1363This finishes the change group by reverting all of its changes."
1364 (dolist (elt handle)
1365 (with-current-buffer (car elt)
1366 (setq elt (cdr elt))
264ef586 1367 (let ((old-car
69cae2d4
RS
1368 (if (consp elt) (car elt)))
1369 (old-cdr
1370 (if (consp elt) (cdr elt))))
1371 ;; Temporarily truncate the undo log at ELT.
1372 (when (consp elt)
1373 (setcar elt nil) (setcdr elt nil))
1374 (unless (eq last-command 'undo) (undo-start))
1375 ;; Make sure there's no confusion.
1376 (when (and (consp elt) (not (eq elt (last pending-undo-list))))
1377 (error "Undoing to some unrelated state"))
1378 ;; Undo it all.
1379 (while pending-undo-list (undo-more 1))
1380 ;; Reset the modified cons cell ELT to its original content.
1381 (when (consp elt)
1382 (setcar elt old-car)
1383 (setcdr elt old-cdr))
1384 ;; Revert the undo info to what it was when we grabbed the state.
1385 (setq buffer-undo-list elt)))))
1386\f
a9d956be
RS
1387;; For compatibility.
1388(defalias 'redraw-modeline 'force-mode-line-update)
1389
9a5336ae 1390(defun force-mode-line-update (&optional all)
926dd40c
LK
1391 "Force redisplay of the current buffer's mode line and header line.
1392With optional non-nil ALL, force redisplay of all mode lines and
1393header lines. This function also forces recomputation of the
1394menu bar menus and the frame title."
9a5336ae
JB
1395 (if all (save-excursion (set-buffer (other-buffer))))
1396 (set-buffer-modified-p (buffer-modified-p)))
1397
aa3b4ded 1398(defun momentary-string-display (string pos &optional exit-char message)
be9b65ac 1399 "Momentarily display STRING in the buffer at POS.
12092fb3
EZ
1400Display remains until next event is input.
1401Optional third arg EXIT-CHAR can be a character, event or event
1402description list. EXIT-CHAR defaults to SPC. If the input is
1403EXIT-CHAR it is swallowed; otherwise it is then available as
1404input (as a command if nothing else).
be9b65ac
DL
1405Display MESSAGE (optional fourth arg) in the echo area.
1406If MESSAGE is nil, instructions to type EXIT-CHAR are displayed there."
1407 (or exit-char (setq exit-char ?\ ))
c306e0e0 1408 (let ((inhibit-read-only t)
ca2ec1c5
RS
1409 ;; Don't modify the undo list at all.
1410 (buffer-undo-list t)
be9b65ac
DL
1411 (modified (buffer-modified-p))
1412 (name buffer-file-name)
1413 insert-end)
1414 (unwind-protect
1415 (progn
1416 (save-excursion
1417 (goto-char pos)
1418 ;; defeat file locking... don't try this at home, kids!
1419 (setq buffer-file-name nil)
1420 (insert-before-markers string)
3eec84bf
RS
1421 (setq insert-end (point))
1422 ;; If the message end is off screen, recenter now.
024ae2c6 1423 (if (< (window-end nil t) insert-end)
3eec84bf
RS
1424 (recenter (/ (window-height) 2)))
1425 ;; If that pushed message start off the screen,
1426 ;; scroll to start it at the top of the screen.
1427 (move-to-window-line 0)
1428 (if (> (point) pos)
1429 (progn
1430 (goto-char pos)
1431 (recenter 0))))
be9b65ac
DL
1432 (message (or message "Type %s to continue editing.")
1433 (single-key-description exit-char))
12092fb3
EZ
1434 (let (char)
1435 (if (integerp exit-char)
1436 (condition-case nil
1437 (progn
1438 (setq char (read-char))
1439 (or (eq char exit-char)
1440 (setq unread-command-events (list char))))
1441 (error
1442 ;; `exit-char' is a character, hence it differs
1443 ;; from char, which is an event.
1444 (setq unread-command-events (list char))))
1445 ;; `exit-char' can be an event, or an event description
1446 ;; list.
1447 (setq char (read-event))
1448 (or (eq char exit-char)
1449 (eq char (event-convert-list exit-char))
1450 (setq unread-command-events (list char))))))
be9b65ac
DL
1451 (if insert-end
1452 (save-excursion
1453 (delete-region pos insert-end)))
1454 (setq buffer-file-name name)
1455 (set-buffer-modified-p modified))))
1456
9a5336ae 1457\f
aa3b4ded
SM
1458;;;; Overlay operations
1459
1460(defun copy-overlay (o)
1461 "Return a copy of overlay O."
1462 (let ((o1 (make-overlay (overlay-start o) (overlay-end o)
1463 ;; FIXME: there's no easy way to find the
1464 ;; insertion-type of the two markers.
1465 (overlay-buffer o)))
1466 (props (overlay-properties o)))
1467 (while props
1468 (overlay-put o1 (pop props) (pop props)))
1469 o1))
1470
f24485f1 1471(defun remove-overlays (&optional beg end name val)
aa3b4ded 1472 "Clear BEG and END of overlays whose property NAME has value VAL.
cba61075
JB
1473Overlays might be moved and/or split.
1474BEG and END default respectively to the beginning and end of buffer."
f24485f1
MY
1475 (unless beg (setq beg (point-min)))
1476 (unless end (setq end (point-max)))
aa3b4ded
SM
1477 (if (< end beg)
1478 (setq beg (prog1 end (setq end beg))))
1479 (save-excursion
1480 (dolist (o (overlays-in beg end))
1481 (when (eq (overlay-get o name) val)
1482 ;; Either push this overlay outside beg...end
1483 ;; or split it to exclude beg...end
1484 ;; or delete it entirely (if it is contained in beg...end).
1485 (if (< (overlay-start o) beg)
1486 (if (> (overlay-end o) end)
1487 (progn
1488 (move-overlay (copy-overlay o)
1489 (overlay-start o) beg)
1490 (move-overlay o end (overlay-end o)))
1491 (move-overlay o (overlay-start o) beg))
1492 (if (> (overlay-end o) end)
1493 (move-overlay o end (overlay-end o))
1494 (delete-overlay o)))))))
c5802acf 1495\f
9a5336ae
JB
1496;;;; Miscellanea.
1497
448b61c9
RS
1498;; A number of major modes set this locally.
1499;; Give it a global value to avoid compiler warnings.
1500(defvar font-lock-defaults nil)
1501
4fb17037
RS
1502(defvar suspend-hook nil
1503 "Normal hook run by `suspend-emacs', before suspending.")
1504
1505(defvar suspend-resume-hook nil
1506 "Normal hook run by `suspend-emacs', after Emacs is continued.")
1507
784bc7cd
RS
1508(defvar temp-buffer-show-hook nil
1509 "Normal hook run by `with-output-to-temp-buffer' after displaying the buffer.
1510When the hook runs, the temporary buffer is current, and the window it
1511was displayed in is selected. This hook is normally set up with a
1512function to make the buffer read only, and find function names and
1513variable names in it, provided the major mode is still Help mode.")
1514
1515(defvar temp-buffer-setup-hook nil
1516 "Normal hook run by `with-output-to-temp-buffer' at the start.
1517When the hook runs, the temporary buffer is current.
1518This hook is normally set up with a function to put the buffer in Help
1519mode.")
1520
448b61c9
RS
1521;; Avoid compiler warnings about this variable,
1522;; which has a special meaning on certain system types.
1523(defvar buffer-file-type nil
1524 "Non-nil if the visited file is a binary file.
1525This variable is meaningful on MS-DOG and Windows NT.
1526On those systems, it is automatically local in every buffer.
1527On other systems, this variable is normally always nil.")
1528
a860d25f 1529;; This should probably be written in C (i.e., without using `walk-windows').
63503b24 1530(defun get-buffer-window-list (buffer &optional minibuf frame)
3ac08e99
LT
1531 "Return list of all windows displaying BUFFER, or nil if none.
1532BUFFER can be a buffer or a buffer name.
63503b24 1533See `walk-windows' for the meaning of MINIBUF and FRAME."
43c5ac8c 1534 (let ((buffer (if (bufferp buffer) buffer (get-buffer buffer))) windows)
a860d25f
SM
1535 (walk-windows (function (lambda (window)
1536 (if (eq (window-buffer window) buffer)
1537 (setq windows (cons window windows)))))
63503b24 1538 minibuf frame)
a860d25f
SM
1539 windows))
1540
f9269e19
RS
1541(defun ignore (&rest ignore)
1542 "Do nothing and return nil.
1543This function accepts any number of arguments, but ignores them."
c0f1a4f6 1544 (interactive)
9a5336ae
JB
1545 nil)
1546
1547(defun error (&rest args)
aa308ce2
RS
1548 "Signal an error, making error message by passing all args to `format'.
1549In Emacs, the convention is that error messages start with a capital
1550letter but *do not* end with a period. Please follow this convention
1551for the sake of consistency."
9a5336ae
JB
1552 (while t
1553 (signal 'error (list (apply 'format args)))))
1554
cef7ae6e 1555(defalias 'user-original-login-name 'user-login-name)
9a5336ae 1556
2493767e
RS
1557(defvar yank-excluded-properties)
1558
8ed59ad5
KS
1559(defun remove-yank-excluded-properties (start end)
1560 "Remove `yank-excluded-properties' between START and END positions.
1561Replaces `category' properties with their defined properties."
1562 (let ((inhibit-read-only t))
1563 ;; Replace any `category' property with the properties it stands for.
1564 (unless (memq yank-excluded-properties '(t nil))
1565 (save-excursion
1566 (goto-char start)
1567 (while (< (point) end)
1568 (let ((cat (get-text-property (point) 'category))
1569 run-end)
8ed59ad5
KS
1570 (setq run-end
1571 (next-single-property-change (point) 'category nil end))
ebaa3349
RS
1572 (when cat
1573 (let (run-end2 original)
1574 (remove-list-of-text-properties (point) run-end '(category))
1575 (while (< (point) run-end)
1576 (setq run-end2 (next-property-change (point) nil run-end))
1577 (setq original (text-properties-at (point)))
1578 (set-text-properties (point) run-end2 (symbol-plist cat))
1579 (add-text-properties (point) run-end2 original)
1580 (goto-char run-end2))))
1581 (goto-char run-end)))))
8ed59ad5
KS
1582 (if (eq yank-excluded-properties t)
1583 (set-text-properties start end nil)
ebaa3349 1584 (remove-list-of-text-properties start end yank-excluded-properties))))
8ed59ad5 1585
e0e80ec9
KS
1586(defvar yank-undo-function)
1587
1588(defun insert-for-yank (string)
529c9409
EZ
1589 "Calls `insert-for-yank-1' repetitively for each `yank-handler' segment.
1590
1591See `insert-for-yank-1' for more details."
1592 (let (to)
1593 (while (setq to (next-single-property-change 0 'yank-handler string))
1594 (insert-for-yank-1 (substring string 0 to))
1595 (setq string (substring string to))))
1596 (insert-for-yank-1 string))
1597
1598(defun insert-for-yank-1 (string)
e0e80ec9 1599 "Insert STRING at point, stripping some text properties.
529c9409 1600
e0e80ec9
KS
1601Strip text properties from the inserted text according to
1602`yank-excluded-properties'. Otherwise just like (insert STRING).
1603
374d3fe7 1604If STRING has a non-nil `yank-handler' property on the first character,
e0e80ec9
KS
1605the normal insert behaviour is modified in various ways. The value of
1606the yank-handler property must be a list with one to five elements
9dd10e25 1607with the following format: (FUNCTION PARAM NOEXCLUDE UNDO).
e0e80ec9
KS
1608When FUNCTION is present and non-nil, it is called instead of `insert'
1609 to insert the string. FUNCTION takes one argument--the object to insert.
1610If PARAM is present and non-nil, it replaces STRING as the object
1611 passed to FUNCTION (or `insert'); for example, if FUNCTION is
1612 `yank-rectangle', PARAM may be a list of strings to insert as a
1613 rectangle.
1614If NOEXCLUDE is present and non-nil, the normal removal of the
1615 yank-excluded-properties is not performed; instead FUNCTION is
1616 responsible for removing those properties. This may be necessary
1617 if FUNCTION adjusts point before or after inserting the object.
1618If UNDO is present and non-nil, it is a function that will be called
1619 by `yank-pop' to undo the insertion of the current object. It is
f1180544 1620 called with two arguments, the start and end of the current region.
9dd10e25 1621 FUNCTION may set `yank-undo-function' to override the UNDO value."
57596fb6
KS
1622 (let* ((handler (and (stringp string)
1623 (get-text-property 0 'yank-handler string)))
1624 (param (or (nth 1 handler) string))
e0e80ec9 1625 (opoint (point)))
57596fb6
KS
1626 (setq yank-undo-function t)
1627 (if (nth 0 handler) ;; FUNCTION
1628 (funcall (car handler) param)
e0e80ec9 1629 (insert param))
57596fb6 1630 (unless (nth 2 handler) ;; NOEXCLUDE
e0e80ec9 1631 (remove-yank-excluded-properties opoint (point)))
57596fb6
KS
1632 (if (eq yank-undo-function t) ;; not set by FUNCTION
1633 (setq yank-undo-function (nth 3 handler))) ;; UNDO
1634 (if (nth 4 handler) ;; COMMAND
1635 (setq this-command (nth 4 handler)))))
f1180544 1636
a478f3e1
JB
1637(defun insert-buffer-substring-no-properties (buffer &optional start end)
1638 "Insert before point a substring of BUFFER, without text properties.
3b8690f6 1639BUFFER may be a buffer or a buffer name.
f8cf33b1
JB
1640Arguments START and END are character positions specifying the substring.
1641They default to the values of (point-min) and (point-max) in BUFFER."
3b8690f6 1642 (let ((opoint (point)))
a478f3e1 1643 (insert-buffer-substring buffer start end)
3b8690f6
KS
1644 (let ((inhibit-read-only t))
1645 (set-text-properties opoint (point) nil))))
1646
a478f3e1
JB
1647(defun insert-buffer-substring-as-yank (buffer &optional start end)
1648 "Insert before point a part of BUFFER, stripping some text properties.
1649BUFFER may be a buffer or a buffer name.
f8cf33b1
JB
1650Arguments START and END are character positions specifying the substring.
1651They default to the values of (point-min) and (point-max) in BUFFER.
a478f3e1
JB
1652Strip text properties from the inserted text according to
1653`yank-excluded-properties'."
0e874d89
RS
1654 ;; Since the buffer text should not normally have yank-handler properties,
1655 ;; there is no need to handle them here.
3b8690f6 1656 (let ((opoint (point)))
a478f3e1 1657 (insert-buffer-substring buffer start end)
8ed59ad5 1658 (remove-yank-excluded-properties opoint (point))))
3b8690f6 1659
2493767e
RS
1660\f
1661;; Synchronous shell commands.
1662
be9b65ac
DL
1663(defun start-process-shell-command (name buffer &rest args)
1664 "Start a program in a subprocess. Return the process object for it.
be9b65ac 1665NAME is name for process. It is modified if necessary to make it unique.
54ce7cbf 1666BUFFER is the buffer (or buffer name) to associate with the process.
be9b65ac
DL
1667 Process output goes at end of that buffer, unless you specify
1668 an output stream or filter function to handle the output.
1669 BUFFER may be also nil, meaning that this process is not associated
1670 with any buffer
54ce7cbf 1671COMMAND is the name of a shell command.
be9b65ac 1672Remaining arguments are the arguments for the command.
54ce7cbf
JB
1673Wildcards and redirection are handled as usual in the shell.
1674
1675\(fn NAME BUFFER COMMAND &rest COMMAND-ARGS)"
a247bf21
KH
1676 (cond
1677 ((eq system-type 'vax-vms)
1678 (apply 'start-process name buffer args))
b59f6d7a
RS
1679 ;; We used to use `exec' to replace the shell with the command,
1680 ;; but that failed to handle (...) and semicolon, etc.
a247bf21
KH
1681 (t
1682 (start-process name buffer shell-file-name shell-command-switch
b59f6d7a 1683 (mapconcat 'identity args " ")))))
93aca633
MB
1684
1685(defun call-process-shell-command (command &optional infile buffer display
1686 &rest args)
1687 "Execute the shell command COMMAND synchronously in separate process.
1688The remaining arguments are optional.
1689The program's input comes from file INFILE (nil means `/dev/null').
1690Insert output in BUFFER before point; t means current buffer;
1691 nil for BUFFER means discard it; 0 means discard and don't wait.
1692BUFFER can also have the form (REAL-BUFFER STDERR-FILE); in that case,
1693REAL-BUFFER says what to do with standard output, as above,
1694while STDERR-FILE says what to do with standard error in the child.
1695STDERR-FILE may be nil (discard standard error output),
1696t (mix it with ordinary output), or a file name string.
1697
1698Fourth arg DISPLAY non-nil means redisplay buffer as output is inserted.
1699Remaining arguments are strings passed as additional arguments for COMMAND.
1700Wildcards and redirection are handled as usual in the shell.
1701
1702If BUFFER is 0, `call-process-shell-command' returns immediately with value nil.
1703Otherwise it waits for COMMAND to terminate and returns a numeric exit
1704status or a signal description string.
1705If you quit, the process is killed with SIGINT, or SIGKILL if you quit again."
1706 (cond
1707 ((eq system-type 'vax-vms)
1708 (apply 'call-process command infile buffer display args))
1709 ;; We used to use `exec' to replace the shell with the command,
1710 ;; but that failed to handle (...) and semicolon, etc.
1711 (t
1712 (call-process shell-file-name
1713 infile buffer display
1714 shell-command-switch
1715 (mapconcat 'identity (cons command args) " ")))))
a7ed4c2a 1716\f
a7f284ec
RS
1717(defmacro with-current-buffer (buffer &rest body)
1718 "Execute the forms in BODY with BUFFER as the current buffer.
a2fdb55c
EN
1719The value returned is the value of the last form in BODY.
1720See also `with-temp-buffer'."
d47f7515
SM
1721 (declare (indent 1) (debug t))
1722 `(save-current-buffer
1723 (set-buffer ,buffer)
1724 ,@body))
1725
1726(defmacro with-selected-window (window &rest body)
1727 "Execute the forms in BODY with WINDOW as the selected window.
1728The value returned is the value of the last form in BODY.
4df623c0 1729This does not alter the buffer list ordering.
01df0a6d
LT
1730This function saves and restores the selected window, as well as
1731the selected window in each frame. If the previously selected
1732window of some frame is no longer live at the end of BODY, that
1733frame's selected window is left alone. If the selected window is
1734no longer live, then whatever window is selected at the end of
1735BODY remains selected.
d47f7515
SM
1736See also `with-temp-buffer'."
1737 (declare (indent 1) (debug t))
3f71ad3a
RS
1738 ;; Most of this code is a copy of save-selected-window.
1739 `(let ((save-selected-window-window (selected-window))
1740 ;; It is necessary to save all of these, because calling
1741 ;; select-window changes frame-selected-window for whatever
1742 ;; frame that window is in.
1743 (save-selected-window-alist
1744 (mapcar (lambda (frame) (list frame (frame-selected-window frame)))
1745 (frame-list))))
4df623c0
RS
1746 (unwind-protect
1747 (progn (select-window ,window 'norecord)
1748 ,@body)
3f71ad3a
RS
1749 (dolist (elt save-selected-window-alist)
1750 (and (frame-live-p (car elt))
1751 (window-live-p (cadr elt))
1752 (set-frame-selected-window (car elt) (cadr elt))))
4df623c0 1753 (if (window-live-p save-selected-window-window)
ec589b78 1754 (select-window save-selected-window-window 'norecord)))))
a7f284ec 1755
e5bb8a8c
SM
1756(defmacro with-temp-file (file &rest body)
1757 "Create a new buffer, evaluate BODY there, and write the buffer to FILE.
1758The value returned is the value of the last form in BODY.
a2fdb55c 1759See also `with-temp-buffer'."
f30e0cd8 1760 (declare (debug t))
a7ed4c2a 1761 (let ((temp-file (make-symbol "temp-file"))
a2fdb55c
EN
1762 (temp-buffer (make-symbol "temp-buffer")))
1763 `(let ((,temp-file ,file)
1764 (,temp-buffer
1765 (get-buffer-create (generate-new-buffer-name " *temp file*"))))
1766 (unwind-protect
1767 (prog1
1768 (with-current-buffer ,temp-buffer
e5bb8a8c 1769 ,@body)
a2fdb55c
EN
1770 (with-current-buffer ,temp-buffer
1771 (widen)
1772 (write-region (point-min) (point-max) ,temp-file nil 0)))
1773 (and (buffer-name ,temp-buffer)
1774 (kill-buffer ,temp-buffer))))))
1775
e5bb8a8c 1776(defmacro with-temp-message (message &rest body)
a600effe 1777 "Display MESSAGE temporarily if non-nil while BODY is evaluated.
e5bb8a8c
SM
1778The original message is restored to the echo area after BODY has finished.
1779The value returned is the value of the last form in BODY.
a600effe
SM
1780MESSAGE is written to the message log buffer if `message-log-max' is non-nil.
1781If MESSAGE is nil, the echo area and message log buffer are unchanged.
1782Use a MESSAGE of \"\" to temporarily clear the echo area."
f30e0cd8 1783 (declare (debug t))
110201c8
SM
1784 (let ((current-message (make-symbol "current-message"))
1785 (temp-message (make-symbol "with-temp-message")))
1786 `(let ((,temp-message ,message)
1787 (,current-message))
e5bb8a8c
SM
1788 (unwind-protect
1789 (progn
110201c8
SM
1790 (when ,temp-message
1791 (setq ,current-message (current-message))
aadf7ff3 1792 (message "%s" ,temp-message))
e5bb8a8c 1793 ,@body)
cad84646
RS
1794 (and ,temp-message
1795 (if ,current-message
1796 (message "%s" ,current-message)
1797 (message nil)))))))
e5bb8a8c
SM
1798
1799(defmacro with-temp-buffer (&rest body)
1800 "Create a temporary buffer, and evaluate BODY there like `progn'.
a2fdb55c 1801See also `with-temp-file' and `with-output-to-string'."
d47f7515 1802 (declare (indent 0) (debug t))
a2fdb55c 1803 (let ((temp-buffer (make-symbol "temp-buffer")))
9166dbf6 1804 `(let ((,temp-buffer (generate-new-buffer " *temp*")))
a2fdb55c
EN
1805 (unwind-protect
1806 (with-current-buffer ,temp-buffer
e5bb8a8c 1807 ,@body)
a2fdb55c
EN
1808 (and (buffer-name ,temp-buffer)
1809 (kill-buffer ,temp-buffer))))))
1810
5db7925d
RS
1811(defmacro with-output-to-string (&rest body)
1812 "Execute BODY, return the text it sent to `standard-output', as a string."
d47f7515 1813 (declare (indent 0) (debug t))
a2fdb55c
EN
1814 `(let ((standard-output
1815 (get-buffer-create (generate-new-buffer-name " *string-output*"))))
5db7925d
RS
1816 (let ((standard-output standard-output))
1817 ,@body)
a2fdb55c
EN
1818 (with-current-buffer standard-output
1819 (prog1
1820 (buffer-string)
1821 (kill-buffer nil)))))
2ec9c94e 1822
0764e16f 1823(defmacro with-local-quit (&rest body)
53a7160c
RS
1824 "Execute BODY, allowing quits to terminate BODY but not escape further.
1825When a quit terminates BODY, `with-local-quit' requests another quit when
1826it finishes. That quit will be processed in turn, the next time quitting
1827is again allowed."
12320833 1828 (declare (debug t) (indent 0))
0764e16f
SM
1829 `(condition-case nil
1830 (let ((inhibit-quit nil))
1831 ,@body)
1832 (quit (setq quit-flag t))))
1833
2ec9c94e
RS
1834(defmacro combine-after-change-calls (&rest body)
1835 "Execute BODY, but don't call the after-change functions till the end.
1836If BODY makes changes in the buffer, they are recorded
1837and the functions on `after-change-functions' are called several times
1838when BODY is finished.
31aa282e 1839The return value is the value of the last form in BODY.
2ec9c94e
RS
1840
1841If `before-change-functions' is non-nil, then calls to the after-change
1842functions can't be deferred, so in that case this macro has no effect.
1843
1844Do not alter `after-change-functions' or `before-change-functions'
1845in BODY."
d47f7515 1846 (declare (indent 0) (debug t))
2ec9c94e
RS
1847 `(unwind-protect
1848 (let ((combine-after-change-calls t))
1849 . ,body)
1850 (combine-after-change-execute)))
1851
c834b52c 1852
a13fe4c5
SM
1853(defvar delay-mode-hooks nil
1854 "If non-nil, `run-mode-hooks' should delay running the hooks.")
1855(defvar delayed-mode-hooks nil
1856 "List of delayed mode hooks waiting to be run.")
1857(make-variable-buffer-local 'delayed-mode-hooks)
617631c0 1858(put 'delay-mode-hooks 'permanent-local t)
a13fe4c5 1859
a8693086 1860(defvar after-change-major-mode-hook nil
a0c3bd3e 1861 "Normal hook run at the very end of major mode functions.")
a8693086 1862
a13fe4c5
SM
1863(defun run-mode-hooks (&rest hooks)
1864 "Run mode hooks `delayed-mode-hooks' and HOOKS, or delay HOOKS.
1865Execution is delayed if `delay-mode-hooks' is non-nil.
6d9ac082
LT
1866If `delay-mode-hooks' is nil, run `after-change-major-mode-hook'
1867after running the mode hooks.
a13fe4c5
SM
1868Major mode functions should use this."
1869 (if delay-mode-hooks
1870 ;; Delaying case.
1871 (dolist (hook hooks)
1872 (push hook delayed-mode-hooks))
1873 ;; Normal case, just run the hook as before plus any delayed hooks.
1874 (setq hooks (nconc (nreverse delayed-mode-hooks) hooks))
1875 (setq delayed-mode-hooks nil)
6d9ac082
LT
1876 (apply 'run-hooks hooks)
1877 (run-hooks 'after-change-major-mode-hook)))
a13fe4c5
SM
1878
1879(defmacro delay-mode-hooks (&rest body)
1880 "Execute BODY, but delay any `run-mode-hooks'.
1e6c82a1
LT
1881These hooks will be executed by the first following call to
1882`run-mode-hooks' that occurs outside any `delayed-mode-hooks' form.
a13fe4c5 1883Only affects hooks run in the current buffer."
f30e0cd8 1884 (declare (debug t))
a13fe4c5
SM
1885 `(progn
1886 (make-local-variable 'delay-mode-hooks)
1887 (let ((delay-mode-hooks t))
1888 ,@body)))
1889
31ca596b
RS
1890;; PUBLIC: find if the current mode derives from another.
1891
1892(defun derived-mode-p (&rest modes)
1893 "Non-nil if the current major mode is derived from one of MODES.
1894Uses the `derived-mode-parent' property of the symbol to trace backwards."
1895 (let ((parent major-mode))
1896 (while (and (not (memq parent modes))
1897 (setq parent (get parent 'derived-mode-parent))))
1898 parent))
1899
a0d84262
RS
1900(defun find-tag-default ()
1901 "Determine default tag to search for, based on text at point.
1902If there is no plausible default, return nil."
1903 (save-excursion
1904 (while (looking-at "\\sw\\|\\s_")
1905 (forward-char 1))
1906 (if (or (re-search-backward "\\sw\\|\\s_"
1907 (save-excursion (beginning-of-line) (point))
1908 t)
1909 (re-search-forward "\\(\\sw\\|\\s_\\)+"
1910 (save-excursion (end-of-line) (point))
1911 t))
1912 (progn (goto-char (match-end 0))
1913 (buffer-substring-no-properties
1914 (point)
1915 (progn (forward-sexp -1)
1916 (while (looking-at "\\s'")
1917 (forward-char 1))
1918 (point))))
1919 nil)))
1920
7e8539cc 1921(defmacro with-syntax-table (table &rest body)
7ec51784 1922 "Evaluate BODY with syntax table of current buffer set to TABLE.
7e8539cc
RS
1923The syntax table of the current buffer is saved, BODY is evaluated, and the
1924saved table is restored, even in case of an abnormal exit.
1925Value is what BODY returns."
f30e0cd8 1926 (declare (debug t))
b3f07093
RS
1927 (let ((old-table (make-symbol "table"))
1928 (old-buffer (make-symbol "buffer")))
7e8539cc
RS
1929 `(let ((,old-table (syntax-table))
1930 (,old-buffer (current-buffer)))
1931 (unwind-protect
1932 (progn
7ec51784 1933 (set-syntax-table ,table)
7e8539cc
RS
1934 ,@body)
1935 (save-current-buffer
1936 (set-buffer ,old-buffer)
1937 (set-syntax-table ,old-table))))))
dd929b41
RS
1938
1939(defmacro dynamic-completion-table (fun)
1940 "Use function FUN as a dynamic completion table.
1941FUN is called with one argument, the string for which completion is required,
1942and it should return an alist containing all the intended possible
4df623c0
RS
1943completions. This alist may be a full list of possible completions so that FUN
1944can ignore the value of its argument. If completion is performed in the
dd929b41 1945minibuffer, FUN will be called in the buffer from which the minibuffer was
4df623c0
RS
1946entered.
1947
1948The result of the `dynamic-completion-table' form is a function
1949that can be used as the ALIST argument to `try-completion' and
1950`all-completion'. See Info node `(elisp)Programmed Completion'."
dd929b41
RS
1951 (let ((win (make-symbol "window"))
1952 (string (make-symbol "string"))
1953 (predicate (make-symbol "predicate"))
1954 (mode (make-symbol "mode")))
1955 `(lambda (,string ,predicate ,mode)
1956 (with-current-buffer (let ((,win (minibuffer-selected-window)))
1957 (if (window-live-p ,win) (window-buffer ,win)
1958 (current-buffer)))
1959 (cond
1960 ((eq ,mode t) (all-completions ,string (,fun ,string) ,predicate))
1961 ((not ,mode) (try-completion ,string (,fun ,string) ,predicate))
1962 (t (test-completion ,string (,fun ,string) ,predicate)))))))
1963
1964(defmacro lazy-completion-table (var fun &rest args)
1965 "Initialize variable VAR as a lazy completion table.
1966If the completion table VAR is used for the first time (e.g., by passing VAR
1967as an argument to `try-completion'), the function FUN is called with arguments
4df623c0
RS
1968ARGS. FUN must return the completion table that will be stored in VAR.
1969If completion is requested in the minibuffer, FUN will be called in the buffer
1970from which the minibuffer was entered. The return value of
dd929b41
RS
1971`lazy-completion-table' must be used to initialize the value of VAR."
1972 (let ((str (make-symbol "string")))
1973 `(dynamic-completion-table
1974 (lambda (,str)
1975 (unless (listp ,var)
1976 (setq ,var (funcall ',fun ,@args)))
1977 ,var))))
a2fdb55c 1978\f
2493767e
RS
1979;;; Matching and substitution
1980
c7ca41e6
RS
1981(defvar save-match-data-internal)
1982
1983;; We use save-match-data-internal as the local variable because
1984;; that works ok in practice (people should not use that variable elsewhere).
1985;; We used to use an uninterned symbol; the compiler handles that properly
1986;; now, but it generates slower code.
9a5336ae 1987(defmacro save-match-data (&rest body)
e4d03691
JB
1988 "Execute the BODY forms, restoring the global value of the match data.
1989The value returned is the value of the last form in BODY."
64ed733a
PE
1990 ;; It is better not to use backquote here,
1991 ;; because that makes a bootstrapping problem
1992 ;; if you need to recompile all the Lisp files using interpreted code.
d47f7515 1993 (declare (indent 0) (debug t))
64ed733a
PE
1994 (list 'let
1995 '((save-match-data-internal (match-data)))
1996 (list 'unwind-protect
1997 (cons 'progn body)
1998 '(set-match-data save-match-data-internal))))
993713ce 1999
cd323f89 2000(defun match-string (num &optional string)
993713ce
SM
2001 "Return string of text matched by last search.
2002NUM specifies which parenthesized expression in the last regexp.
2003 Value is nil if NUMth pair didn't match, or there were less than NUM pairs.
2004Zero means the entire text matched by the whole regexp or whole string.
2005STRING should be given if the last search was by `string-match' on STRING."
cd323f89
SM
2006 (if (match-beginning num)
2007 (if string
2008 (substring string (match-beginning num) (match-end num))
2009 (buffer-substring (match-beginning num) (match-end num)))))
58f950b4 2010
bb760c71
RS
2011(defun match-string-no-properties (num &optional string)
2012 "Return string of text matched by last search, without text properties.
2013NUM specifies which parenthesized expression in the last regexp.
2014 Value is nil if NUMth pair didn't match, or there were less than NUM pairs.
2015Zero means the entire text matched by the whole regexp or whole string.
2016STRING should be given if the last search was by `string-match' on STRING."
2017 (if (match-beginning num)
2018 (if string
6a6d7c34
EZ
2019 (substring-no-properties string (match-beginning num)
2020 (match-end num))
bb760c71
RS
2021 (buffer-substring-no-properties (match-beginning num)
2022 (match-end num)))))
2023
f30e0cd8
SM
2024(defun looking-back (regexp &optional limit)
2025 "Return non-nil if text before point matches regular expression REGEXP.
2026Like `looking-at' except backwards and slower.
2027LIMIT if non-nil speeds up the search by specifying how far back the
2028match can start."
498535fb 2029 (save-excursion
f30e0cd8 2030 (re-search-backward (concat "\\(?:" regexp "\\)\\=") limit t)))
498535fb 2031
6a646626
JB
2032(defconst split-string-default-separators "[ \f\t\n\r\v]+"
2033 "The default value of separators for `split-string'.
2034
2035A regexp matching strings of whitespace. May be locale-dependent
2036\(as yet unimplemented). Should not match non-breaking spaces.
2037
2038Warning: binding this to a different value and using it as default is
2039likely to have undesired semantics.")
2040
2041;; The specification says that if both SEPARATORS and OMIT-NULLS are
2042;; defaulted, OMIT-NULLS should be treated as t. Simplifying the logical
2043;; expression leads to the equivalent implementation that if SEPARATORS
2044;; is defaulted, OMIT-NULLS is treated as t.
2045(defun split-string (string &optional separators omit-nulls)
203998e5 2046 "Split STRING into substrings bounded by matches for SEPARATORS.
6a646626
JB
2047
2048The beginning and end of STRING, and each match for SEPARATORS, are
2049splitting points. The substrings matching SEPARATORS are removed, and
2050the substrings between the splitting points are collected as a list,
edce3654 2051which is returned.
b222b786 2052
6a646626
JB
2053If SEPARATORS is non-nil, it should be a regular expression matching text
2054which separates, but is not part of, the substrings. If nil it defaults to
2055`split-string-default-separators', normally \"[ \\f\\t\\n\\r\\v]+\", and
2056OMIT-NULLS is forced to t.
2057
a478f3e1 2058If OMIT-NULLS is t, zero-length substrings are omitted from the list \(so
6a646626
JB
2059that for the default value of SEPARATORS leading and trailing whitespace
2060are effectively trimmed). If nil, all zero-length substrings are retained,
2061which correctly parses CSV format, for example.
2062
2063Note that the effect of `(split-string STRING)' is the same as
2064`(split-string STRING split-string-default-separators t)'). In the rare
2065case that you wish to retain zero-length substrings when splitting on
2066whitespace, use `(split-string STRING split-string-default-separators)'.
b021ef18
DL
2067
2068Modifies the match data; use `save-match-data' if necessary."
6a646626
JB
2069 (let ((keep-nulls (not (if separators omit-nulls t)))
2070 (rexp (or separators split-string-default-separators))
edce3654 2071 (start 0)
b222b786 2072 notfirst
edce3654 2073 (list nil))
b222b786
RS
2074 (while (and (string-match rexp string
2075 (if (and notfirst
2076 (= start (match-beginning 0))
2077 (< start (length string)))
2078 (1+ start) start))
6a646626 2079 (< start (length string)))
b222b786 2080 (setq notfirst t)
6a646626 2081 (if (or keep-nulls (< start (match-beginning 0)))
edce3654
RS
2082 (setq list
2083 (cons (substring string start (match-beginning 0))
2084 list)))
2085 (setq start (match-end 0)))
6a646626 2086 (if (or keep-nulls (< start (length string)))
edce3654
RS
2087 (setq list
2088 (cons (substring string start)
2089 list)))
2090 (nreverse list)))
1ccaea52
AI
2091
2092(defun subst-char-in-string (fromchar tochar string &optional inplace)
2093 "Replace FROMCHAR with TOCHAR in STRING each time it occurs.
2094Unless optional argument INPLACE is non-nil, return a new string."
e6e71807
SM
2095 (let ((i (length string))
2096 (newstr (if inplace string (copy-sequence string))))
2097 (while (> i 0)
2098 (setq i (1- i))
2099 (if (eq (aref newstr i) fromchar)
2100 (aset newstr i tochar)))
2101 newstr))
b021ef18 2102
1697159c 2103(defun replace-regexp-in-string (regexp rep string &optional
6a646626 2104 fixedcase literal subexp start)
b021ef18
DL
2105 "Replace all matches for REGEXP with REP in STRING.
2106
2107Return a new string containing the replacements.
2108
2109Optional arguments FIXEDCASE, LITERAL and SUBEXP are like the
2110arguments with the same names of function `replace-match'. If START
2111is non-nil, start replacements at that index in STRING.
2112
2113REP is either a string used as the NEWTEXT arg of `replace-match' or a
2114function. If it is a function it is applied to each match to generate
2115the replacement passed to `replace-match'; the match-data at this
2116point are such that match 0 is the function's argument.
2117
1697159c
DL
2118To replace only the first match (if any), make REGEXP match up to \\'
2119and replace a sub-expression, e.g.
c9bcb507 2120 (replace-regexp-in-string \"\\\\(foo\\\\).*\\\\'\" \"bar\" \" foo foo\" nil nil 1)
1697159c
DL
2121 => \" bar foo\"
2122"
b021ef18
DL
2123
2124 ;; To avoid excessive consing from multiple matches in long strings,
2125 ;; don't just call `replace-match' continually. Walk down the
2126 ;; string looking for matches of REGEXP and building up a (reversed)
2127 ;; list MATCHES. This comprises segments of STRING which weren't
2128 ;; matched interspersed with replacements for segments that were.
08b1f8a1 2129 ;; [For a `large' number of replacements it's more efficient to
b021ef18
DL
2130 ;; operate in a temporary buffer; we can't tell from the function's
2131 ;; args whether to choose the buffer-based implementation, though it
2132 ;; might be reasonable to do so for long enough STRING.]
2133 (let ((l (length string))
2134 (start (or start 0))
2135 matches str mb me)
2136 (save-match-data
2137 (while (and (< start l) (string-match regexp string start))
2138 (setq mb (match-beginning 0)
2139 me (match-end 0))
a9853251
SM
2140 ;; If we matched the empty string, make sure we advance by one char
2141 (when (= me mb) (setq me (min l (1+ mb))))
2142 ;; Generate a replacement for the matched substring.
2143 ;; Operate only on the substring to minimize string consing.
2144 ;; Set up match data for the substring for replacement;
2145 ;; presumably this is likely to be faster than munging the
2146 ;; match data directly in Lisp.
2147 (string-match regexp (setq str (substring string mb me)))
2148 (setq matches
2149 (cons (replace-match (if (stringp rep)
2150 rep
2151 (funcall rep (match-string 0 str)))
2152 fixedcase literal str subexp)
6a646626 2153 (cons (substring string start mb) ; unmatched prefix
a9853251
SM
2154 matches)))
2155 (setq start me))
b021ef18
DL
2156 ;; Reconstruct a string from the pieces.
2157 (setq matches (cons (substring string start l) matches)) ; leftover
2158 (apply #'concat (nreverse matches)))))
a7ed4c2a 2159\f
8af7df60
RS
2160(defun shell-quote-argument (argument)
2161 "Quote an argument for passing as argument to an inferior shell."
c1c74b43 2162 (if (eq system-type 'ms-dos)
8ee75d03
EZ
2163 ;; Quote using double quotes, but escape any existing quotes in
2164 ;; the argument with backslashes.
2165 (let ((result "")
2166 (start 0)
2167 end)
2168 (if (or (null (string-match "[^\"]" argument))
2169 (< (match-end 0) (length argument)))
2170 (while (string-match "[\"]" argument start)
2171 (setq end (match-beginning 0)
2172 result (concat result (substring argument start end)
2173 "\\" (substring argument end (1+ end)))
2174 start (1+ end))))
2175 (concat "\"" result (substring argument start) "\""))
c1c74b43
RS
2176 (if (eq system-type 'windows-nt)
2177 (concat "\"" argument "\"")
e1b65a6b
RS
2178 (if (equal argument "")
2179 "''"
2180 ;; Quote everything except POSIX filename characters.
2181 ;; This should be safe enough even for really weird shells.
2182 (let ((result "") (start 0) end)
2183 (while (string-match "[^-0-9a-zA-Z_./]" argument start)
2184 (setq end (match-beginning 0)
2185 result (concat result (substring argument start end)
2186 "\\" (substring argument end (1+ end)))
2187 start (1+ end)))
2188 (concat result (substring argument start)))))))
8af7df60 2189
297d863b 2190(defun make-syntax-table (&optional oldtable)
984f718a 2191 "Return a new syntax table.
0764e16f
SM
2192Create a syntax table which inherits from OLDTABLE (if non-nil) or
2193from `standard-syntax-table' otherwise."
2194 (let ((table (make-char-table 'syntax-table nil)))
2195 (set-char-table-parent table (or oldtable (standard-syntax-table)))
2196 table))
31aa282e 2197
e9f13a95
SM
2198(defun syntax-after (pos)
2199 "Return the syntax of the char after POS."
2200 (unless (or (< pos (point-min)) (>= pos (point-max)))
2201 (let ((st (if parse-sexp-lookup-properties
2202 (get-char-property pos 'syntax-table))))
2203 (if (consp st) st
2204 (aref (or st (syntax-table)) (char-after pos))))))
2205
31aa282e
KH
2206(defun add-to-invisibility-spec (arg)
2207 "Add elements to `buffer-invisibility-spec'.
2208See documentation for `buffer-invisibility-spec' for the kind of elements
2209that can be added."
c525c13c
RS
2210 (if (eq buffer-invisibility-spec t)
2211 (setq buffer-invisibility-spec (list t)))
2212 (setq buffer-invisibility-spec
2213 (cons arg buffer-invisibility-spec)))
31aa282e
KH
2214
2215(defun remove-from-invisibility-spec (arg)
2216 "Remove elements from `buffer-invisibility-spec'."
e93b8cbb 2217 (if (consp buffer-invisibility-spec)
071a2a71 2218 (setq buffer-invisibility-spec (delete arg buffer-invisibility-spec))))
baed0109
RS
2219\f
2220(defun global-set-key (key command)
2221 "Give KEY a global binding as COMMAND.
7bba1895
KH
2222COMMAND is the command definition to use; usually it is
2223a symbol naming an interactively-callable function.
2224KEY is a key sequence; noninteractively, it is a string or vector
2225of characters or event types, and non-ASCII characters with codes
2226above 127 (such as ISO Latin-1) can be included if you use a vector.
2227
2228Note that if KEY has a local binding in the current buffer,
2229that local binding will continue to shadow any global binding
2230that you make with this function."
baed0109 2231 (interactive "KSet key globally: \nCSet key %s to command: ")
a2f9aa84 2232 (or (vectorp key) (stringp key)
baed0109 2233 (signal 'wrong-type-argument (list 'arrayp key)))
ff663bbe 2234 (define-key (current-global-map) key command))
baed0109
RS
2235
2236(defun local-set-key (key command)
2237 "Give KEY a local binding as COMMAND.
7bba1895
KH
2238COMMAND is the command definition to use; usually it is
2239a symbol naming an interactively-callable function.
2240KEY is a key sequence; noninteractively, it is a string or vector
2241of characters or event types, and non-ASCII characters with codes
2242above 127 (such as ISO Latin-1) can be included if you use a vector.
2243
baed0109
RS
2244The binding goes in the current buffer's local map,
2245which in most cases is shared with all other buffers in the same major mode."
2246 (interactive "KSet key locally: \nCSet key %s locally to command: ")
2247 (let ((map (current-local-map)))
2248 (or map
2249 (use-local-map (setq map (make-sparse-keymap))))
a2f9aa84 2250 (or (vectorp key) (stringp key)
baed0109 2251 (signal 'wrong-type-argument (list 'arrayp key)))
ff663bbe 2252 (define-key map key command)))
984f718a 2253
baed0109
RS
2254(defun global-unset-key (key)
2255 "Remove global binding of KEY.
572fc345 2256KEY is a string or vector representing a sequence of keystrokes."
baed0109
RS
2257 (interactive "kUnset key globally: ")
2258 (global-set-key key nil))
2259
db2474b8 2260(defun local-unset-key (key)
baed0109 2261 "Remove local binding of KEY.
572fc345 2262KEY is a string or vector representing a sequence of keystrokes."
baed0109
RS
2263 (interactive "kUnset key locally: ")
2264 (if (current-local-map)
db2474b8 2265 (local-set-key key nil))
baed0109
RS
2266 nil)
2267\f
4809d0dd
KH
2268;; We put this here instead of in frame.el so that it's defined even on
2269;; systems where frame.el isn't loaded.
2270(defun frame-configuration-p (object)
2271 "Return non-nil if OBJECT seems to be a frame configuration.
2272Any list whose car is `frame-configuration' is assumed to be a frame
2273configuration."
2274 (and (consp object)
2275 (eq (car object) 'frame-configuration)))
2276
a9a44ed1 2277(defun functionp (object)
756bb736
LT
2278 "Non-nil if OBJECT is any kind of function or a special form.
2279Also non-nil if OBJECT is a symbol and its function definition is
2280\(recursively) a function or special form. This does not include
2281macros."
a2d7836f 2282 (or (and (symbolp object) (fboundp object)
d7d563e3
RS
2283 (condition-case nil
2284 (setq object (indirect-function object))
2285 (error nil))
0764e16f 2286 (eq (car-safe object) 'autoload)
f1d37f3c 2287 (not (car-safe (cdr-safe (cdr-safe (cdr-safe (cdr-safe object)))))))
0764e16f 2288 (subrp object) (byte-code-function-p object)
60ab6064 2289 (eq (car-safe object) 'lambda)))
a9a44ed1 2290
d3a61a11 2291(defun assq-delete-all (key alist)
a62d6695 2292 "Delete from ALIST all elements whose car is KEY.
d87a4a45
RS
2293Return the modified alist.
2294Elements of ALIST that are not conses are ignored."
a62d6695
DL
2295 (let ((tail alist))
2296 (while tail
d87a4a45 2297 (if (and (consp (car tail)) (eq (car (car tail)) key))
a62d6695
DL
2298 (setq alist (delq (car tail) alist)))
2299 (setq tail (cdr tail)))
2300 alist))
2301
10cf1ba8 2302(defun make-temp-file (prefix &optional dir-flag suffix)
cdd9f643
RS
2303 "Create a temporary file.
2304The returned file name (created by appending some random characters at the end
5ef6a86d 2305of PREFIX, and expanding against `temporary-file-directory' if necessary),
cdd9f643
RS
2306is guaranteed to point to a newly created empty file.
2307You can then use `write-region' to write new data into the file.
2308
10cf1ba8
RS
2309If DIR-FLAG is non-nil, create a new empty directory instead of a file.
2310
2311If SUFFIX is non-nil, add that at the end of the file name."
1c12af5c
SM
2312 (let ((umask (default-file-modes))
2313 file)
2314 (unwind-protect
2315 (progn
2316 ;; Create temp files with strict access rights. It's easy to
2317 ;; loosen them later, whereas it's impossible to close the
2318 ;; time-window of loose permissions otherwise.
2319 (set-default-file-modes ?\700)
2320 (while (condition-case ()
2321 (progn
2322 (setq file
2323 (make-temp-name
2324 (expand-file-name prefix temporary-file-directory)))
2325 (if suffix
2326 (setq file (concat file suffix)))
2327 (if dir-flag
2328 (make-directory file)
2329 (write-region "" nil file nil 'silent nil 'excl))
2330 nil)
2331 (file-already-exists t))
2332 ;; the file was somehow created by someone else between
2333 ;; `make-temp-name' and `write-region', let's try again.
2334 nil)
2335 file)
2336 ;; Reset the umask.
2337 (set-default-file-modes umask))))
cdd9f643 2338
d7d47268 2339\f
7dde432d
RS
2340;; If a minor mode is not defined with define-minor-mode,
2341;; add it here explicitly.
2342;; isearch-mode is deliberately excluded, since you should
2343;; not call it yourself.
2344(defvar minor-mode-list '(auto-save-mode auto-fill-mode abbrev-mode
3813f0c5
TTN
2345 overwrite-mode view-mode
2346 hs-minor-mode)
7dde432d
RS
2347 "List of all minor mode functions.")
2348
c94f4677 2349(defun add-minor-mode (toggle name &optional keymap after toggle-fun)
d7d47268 2350 "Register a new minor mode.
c94f4677 2351
0b2cf11f
SM
2352This is an XEmacs-compatibility function. Use `define-minor-mode' instead.
2353
c94f4677
GM
2354TOGGLE is a symbol which is the name of a buffer-local variable that
2355is toggled on or off to say whether the minor mode is active or not.
2356
2357NAME specifies what will appear in the mode line when the minor mode
2358is active. NAME should be either a string starting with a space, or a
2359symbol whose value is such a string.
2360
2361Optional KEYMAP is the keymap for the minor mode that will be added
2362to `minor-mode-map-alist'.
2363
2364Optional AFTER specifies that TOGGLE should be added after AFTER
2365in `minor-mode-alist'.
2366
0b2cf11f
SM
2367Optional TOGGLE-FUN is an interactive function to toggle the mode.
2368It defaults to (and should by convention be) TOGGLE.
2369
2370If TOGGLE has a non-nil `:included' property, an entry for the mode is
2371included in the mode-line minor mode menu.
2372If TOGGLE has a `:menu-tag', that is used for the menu item's label."
7dde432d
RS
2373 (unless (memq toggle minor-mode-list)
2374 (push toggle minor-mode-list))
6a646626 2375
0b2cf11f 2376 (unless toggle-fun (setq toggle-fun toggle))
0b2cf11f 2377 ;; Add the name to the minor-mode-alist.
c94f4677 2378 (when name
0b2cf11f 2379 (let ((existing (assq toggle minor-mode-alist)))
0b2cf11f
SM
2380 (if existing
2381 (setcdr existing (list name))
2382 (let ((tail minor-mode-alist) found)
2383 (while (and tail (not found))
2384 (if (eq after (caar tail))
2385 (setq found tail)
2386 (setq tail (cdr tail))))
2387 (if found
2388 (let ((rest (cdr found)))
2389 (setcdr found nil)
2390 (nconc found (list (list toggle name)) rest))
2391 (setq minor-mode-alist (cons (list toggle name)
2392 minor-mode-alist)))))))
69cae2d4
RS
2393 ;; Add the toggle to the minor-modes menu if requested.
2394 (when (get toggle :included)
2395 (define-key mode-line-mode-menu
2396 (vector toggle)
2397 (list 'menu-item
2398 (concat
2399 (or (get toggle :menu-tag)
2400 (if (stringp name) name (symbol-name toggle)))
1c12af5c
SM
2401 (let ((mode-name (if (symbolp name) (symbol-value name))))
2402 (if (and (stringp mode-name) (string-match "[^ ]+" mode-name))
2403 (concat " (" (match-string 0 mode-name) ")"))))
69cae2d4
RS
2404 toggle-fun
2405 :button (cons :toggle toggle))))
2406
1c12af5c 2407 ;; Add the map to the minor-mode-map-alist.
c94f4677
GM
2408 (when keymap
2409 (let ((existing (assq toggle minor-mode-map-alist)))
0b2cf11f
SM
2410 (if existing
2411 (setcdr existing keymap)
2412 (let ((tail minor-mode-map-alist) found)
2413 (while (and tail (not found))
2414 (if (eq after (caar tail))
2415 (setq found tail)
2416 (setq tail (cdr tail))))
2417 (if found
2418 (let ((rest (cdr found)))
2419 (setcdr found nil)
2420 (nconc found (list (cons toggle keymap)) rest))
2421 (setq minor-mode-map-alist (cons (cons toggle keymap)
2422 minor-mode-map-alist))))))))
2493767e 2423\f
a13fe4c5
SM
2424;; Clones ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2425
2426(defun text-clone-maintain (ol1 after beg end &optional len)
2427 "Propagate the changes made under the overlay OL1 to the other clones.
2428This is used on the `modification-hooks' property of text clones."
2429 (when (and after (not undo-in-progress) (overlay-start ol1))
2430 (let ((margin (if (overlay-get ol1 'text-clone-spreadp) 1 0)))
2431 (setq beg (max beg (+ (overlay-start ol1) margin)))
2432 (setq end (min end (- (overlay-end ol1) margin)))
2433 (when (<= beg end)
2434 (save-excursion
2435 (when (overlay-get ol1 'text-clone-syntax)
2436 ;; Check content of the clone's text.
2437 (let ((cbeg (+ (overlay-start ol1) margin))
2438 (cend (- (overlay-end ol1) margin)))
2439 (goto-char cbeg)
2440 (save-match-data
2441 (if (not (re-search-forward
2442 (overlay-get ol1 'text-clone-syntax) cend t))
2443 ;; Mark the overlay for deletion.
2444 (overlay-put ol1 'text-clones nil)
2445 (when (< (match-end 0) cend)
2446 ;; Shrink the clone at its end.
2447 (setq end (min end (match-end 0)))
2448 (move-overlay ol1 (overlay-start ol1)
2449 (+ (match-end 0) margin)))
2450 (when (> (match-beginning 0) cbeg)
2451 ;; Shrink the clone at its beginning.
2452 (setq beg (max (match-beginning 0) beg))
2453 (move-overlay ol1 (- (match-beginning 0) margin)
2454 (overlay-end ol1)))))))
2455 ;; Now go ahead and update the clones.
2456 (let ((head (- beg (overlay-start ol1)))
2457 (tail (- (overlay-end ol1) end))
2458 (str (buffer-substring beg end))
2459 (nothing-left t)
2460 (inhibit-modification-hooks t))
2461 (dolist (ol2 (overlay-get ol1 'text-clones))
2462 (let ((oe (overlay-end ol2)))
2463 (unless (or (eq ol1 ol2) (null oe))
2464 (setq nothing-left nil)
2465 (let ((mod-beg (+ (overlay-start ol2) head)))
2466 ;;(overlay-put ol2 'modification-hooks nil)
2467 (goto-char (- (overlay-end ol2) tail))
2468 (unless (> mod-beg (point))
2469 (save-excursion (insert str))
2470 (delete-region mod-beg (point)))
2471 ;;(overlay-put ol2 'modification-hooks '(text-clone-maintain))
2472 ))))
2473 (if nothing-left (delete-overlay ol1))))))))
2474
2475(defun text-clone-create (start end &optional spreadp syntax)
2476 "Create a text clone of START...END at point.
2477Text clones are chunks of text that are automatically kept identical:
2478changes done to one of the clones will be immediately propagated to the other.
2479
2480The buffer's content at point is assumed to be already identical to
2481the one between START and END.
2482If SYNTAX is provided it's a regexp that describes the possible text of
2483the clones; the clone will be shrunk or killed if necessary to ensure that
2484its text matches the regexp.
2485If SPREADP is non-nil it indicates that text inserted before/after the
2486clone should be incorporated in the clone."
2487 ;; To deal with SPREADP we can either use an overlay with `nil t' along
2488 ;; with insert-(behind|in-front-of)-hooks or use a slightly larger overlay
2489 ;; (with a one-char margin at each end) with `t nil'.
2490 ;; We opted for a larger overlay because it behaves better in the case
2491 ;; where the clone is reduced to the empty string (we want the overlay to
2492 ;; stay when the clone's content is the empty string and we want to use
2493 ;; `evaporate' to make sure those overlays get deleted when needed).
264ef586 2494 ;;
a13fe4c5
SM
2495 (let* ((pt-end (+ (point) (- end start)))
2496 (start-margin (if (or (not spreadp) (bobp) (<= start (point-min)))
2497 0 1))
2498 (end-margin (if (or (not spreadp)
2499 (>= pt-end (point-max))
2500 (>= start (point-max)))
2501 0 1))
2502 (ol1 (make-overlay (- start start-margin) (+ end end-margin) nil t))
2503 (ol2 (make-overlay (- (point) start-margin) (+ pt-end end-margin) nil t))
2504 (dups (list ol1 ol2)))
2505 (overlay-put ol1 'modification-hooks '(text-clone-maintain))
2506 (when spreadp (overlay-put ol1 'text-clone-spreadp t))
2507 (when syntax (overlay-put ol1 'text-clone-syntax syntax))
2508 ;;(overlay-put ol1 'face 'underline)
2509 (overlay-put ol1 'evaporate t)
2510 (overlay-put ol1 'text-clones dups)
264ef586 2511 ;;
a13fe4c5
SM
2512 (overlay-put ol2 'modification-hooks '(text-clone-maintain))
2513 (when spreadp (overlay-put ol2 'text-clone-spreadp t))
2514 (when syntax (overlay-put ol2 'text-clone-syntax syntax))
2515 ;;(overlay-put ol2 'face 'underline)
2516 (overlay-put ol2 'evaporate t)
2517 (overlay-put ol2 'text-clones dups)))
27c079eb 2518
324cd947
PJ
2519(defun play-sound (sound)
2520 "SOUND is a list of the form `(sound KEYWORD VALUE...)'.
2521The following keywords are recognized:
2522
2523 :file FILE - read sound data from FILE. If FILE isn't an
2524absolute file name, it is searched in `data-directory'.
2525
2526 :data DATA - read sound data from string DATA.
2527
2528Exactly one of :file or :data must be present.
2529
2530 :volume VOL - set volume to VOL. VOL must an integer in the
2531range 0..100 or a float in the range 0..1.0. If not specified,
2532don't change the volume setting of the sound device.
2533
2534 :device DEVICE - play sound on DEVICE. If not specified,
2535a system-dependent default device name is used."
2536 (unless (fboundp 'play-sound-internal)
2537 (error "This Emacs binary lacks sound support"))
2538 (play-sound-internal sound))
2539
27c079eb
SM
2540(defun define-mail-user-agent (symbol composefunc sendfunc
2541 &optional abortfunc hookvar)
2542 "Define a symbol to identify a mail-sending package for `mail-user-agent'.
2543
2544SYMBOL can be any Lisp symbol. Its function definition and/or
2545value as a variable do not matter for this usage; we use only certain
2546properties on its property list, to encode the rest of the arguments.
2547
2548COMPOSEFUNC is program callable function that composes an outgoing
2549mail message buffer. This function should set up the basics of the
2550buffer without requiring user interaction. It should populate the
2551standard mail headers, leaving the `to:' and `subject:' headers blank
2552by default.
2553
2554COMPOSEFUNC should accept several optional arguments--the same
2555arguments that `compose-mail' takes. See that function's documentation.
2556
2557SENDFUNC is the command a user would run to send the message.
2558
2559Optional ABORTFUNC is the command a user would run to abort the
2560message. For mail packages that don't have a separate abort function,
2561this can be `kill-buffer' (the equivalent of omitting this argument).
2562
2563Optional HOOKVAR is a hook variable that gets run before the message
2564is actually sent. Callers that use the `mail-user-agent' may
2565install a hook function temporarily on this hook variable.
2566If HOOKVAR is nil, `mail-send-hook' is used.
2567
2568The properties used on SYMBOL are `composefunc', `sendfunc',
2569`abortfunc', and `hookvar'."
2570 (put symbol 'composefunc composefunc)
2571 (put symbol 'sendfunc sendfunc)
2572 (put symbol 'abortfunc (or abortfunc 'kill-buffer))
2573 (put symbol 'hookvar (or hookvar 'mail-send-hook)))
2574
b4329caa
EZ
2575;; Standardized progress reporting
2576
2577;; Progress reporter has the following structure:
2578;;
2579;; (NEXT-UPDATE-VALUE . [NEXT-UPDATE-TIME
2580;; MIN-VALUE
2581;; MAX-VALUE
2582;; MESSAGE
2583;; MIN-CHANGE
2584;; MIN-TIME])
2585;;
2586;; This weirdeness is for optimization reasons: we want
2587;; `progress-reporter-update' to be as fast as possible, so
2588;; `(car reporter)' is better than `(aref reporter 0)'.
2589;;
2590;; NEXT-UPDATE-TIME is a float. While `float-time' loses a couple
2591;; digits of precision, it doesn't really matter here. On the other
2592;; hand, it greatly simplifies the code.
2593
c85152fc
KS
2594(defsubst progress-reporter-update (reporter value)
2595 "Report progress of an operation in the echo area.
2596However, if the change since last echo area update is too small
2597or not enough time has passed, then do nothing (see
2598`make-progress-reporter' for details).
2599
2600First parameter, REPORTER, should be the result of a call to
2601`make-progress-reporter'. Second, VALUE, determines the actual
2602progress of operation; it must be between MIN-VALUE and MAX-VALUE
2603as passed to `make-progress-reporter'.
2604
2605This function is very inexpensive, you may not bother how often
2606you call it."
2607 (when (>= value (car reporter))
2608 (progress-reporter-do-update reporter value)))
2609
b4329caa
EZ
2610(defun make-progress-reporter (message min-value max-value
2611 &optional current-value
2612 min-change min-time)
c85152fc 2613 "Return progress reporter object usage with `progress-reporter-update'.
b4329caa
EZ
2614
2615MESSAGE is shown in the echo area. When at least 1% of operation
2616is complete, the exact percentage will be appended to the
2617MESSAGE. When you call `progress-reporter-done', word \"done\"
2618is printed after the MESSAGE. You can change MESSAGE of an
2619existing progress reporter with `progress-reporter-force-update'.
2620
2621MIN-VALUE and MAX-VALUE designate starting (0% complete) and
2622final (100% complete) states of operation. The latter should be
2623larger; if this is not the case, then simply negate all values.
2624Optional CURRENT-VALUE specifies the progress by the moment you
2625call this function. You should omit it or set it to nil in most
2626cases since it defaults to MIN-VALUE.
2627
2628Optional MIN-CHANGE determines the minimal change in percents to
2629report (default is 1%.) Optional MIN-TIME specifies the minimal
2630time before echo area updates (default is 0.2 seconds.) If
2631`float-time' function is not present, then time is not tracked
2632at all. If OS is not capable of measuring fractions of seconds,
2633then this parameter is effectively rounded up."
2634
2635 (unless min-time
2636 (setq min-time 0.2))
2637 (let ((reporter
2638 (cons min-value ;; Force a call to `message' now
2639 (vector (if (and (fboundp 'float-time)
2640 (>= min-time 0.02))
2641 (float-time) nil)
2642 min-value
2643 max-value
2644 message
2645 (if min-change (max (min min-change 50) 1) 1)
2646 min-time))))
2647 (progress-reporter-update reporter (or current-value min-value))
2648 reporter))
2649
b4329caa
EZ
2650(defun progress-reporter-force-update (reporter value &optional new-message)
2651 "Report progress of an operation in the echo area unconditionally.
2652
2653First two parameters are the same as for
2654`progress-reporter-update'. Optional NEW-MESSAGE allows you to
2655change the displayed message."
2656 (let ((parameters (cdr reporter)))
2657 (when new-message
2658 (aset parameters 3 new-message))
2659 (when (aref parameters 0)
2660 (aset parameters 0 (float-time)))
2661 (progress-reporter-do-update reporter value)))
2662
2663(defun progress-reporter-do-update (reporter value)
2664 (let* ((parameters (cdr reporter))
2665 (min-value (aref parameters 1))
2666 (max-value (aref parameters 2))
2667 (one-percent (/ (- max-value min-value) 100.0))
2668 (percentage (truncate (/ (- value min-value) one-percent)))
2669 (update-time (aref parameters 0))
2670 (current-time (float-time))
2671 (enough-time-passed
2672 ;; See if enough time has passed since the last update.
2673 (or (not update-time)
2674 (when (>= current-time update-time)
2675 ;; Calculate time for the next update
2676 (aset parameters 0 (+ update-time (aref parameters 5)))))))
2677 ;;
2678 ;; Calculate NEXT-UPDATE-VALUE. If we are not going to print
2679 ;; message this time because not enough time has passed, then use
2680 ;; 1 instead of MIN-CHANGE. This makes delays between echo area
2681 ;; updates closer to MIN-TIME.
2682 (setcar reporter
2683 (min (+ min-value (* (+ percentage
2684 (if enough-time-passed
2685 (aref parameters 4) ;; MIN-CHANGE
2686 1))
2687 one-percent))
2688 max-value))
2689 (when (integerp value)
2690 (setcar reporter (ceiling (car reporter))))
2691 ;;
2692 ;; Only print message if enough time has passed
2693 (when enough-time-passed
2694 (if (> percentage 0)
2695 (message "%s%d%%" (aref parameters 3) percentage)
2696 (message "%s" (aref parameters 3))))))
2697
2698(defun progress-reporter-done (reporter)
2699 "Print reporter's message followed by word \"done\" in echo area."
2700 (message "%sdone" (aref (cdr reporter) 3)))
2701
a8a64811 2702;; arch-tag: f7e0e6e5-70aa-4897-ae72-7a3511ec40bc
630cc463 2703;;; subr.el ends here