comparison lisp/subr.el @ 66304:f754be327a7e

Much rearrangement of functions and division into pages. No code changes.
author Richard M. Stallman <rms@gnu.org>
date Sat, 22 Oct 2005 15:01:08 +0000
parents 366f80f966cb
children 138f9b1d6682
comparison
equal deleted inserted replaced
66303:b3dd2d3cab5d 66304:f754be327a7e
35 (defun custom-declare-variable-early (&rest arguments) 35 (defun custom-declare-variable-early (&rest arguments)
36 (setq custom-declare-variable-list 36 (setq custom-declare-variable-list
37 (cons arguments custom-declare-variable-list))) 37 (cons arguments custom-declare-variable-list)))
38 38
39 39
40 ;;;; Lisp language features. 40 ;;;; Basic Lisp macros.
41 41
42 (defalias 'not 'null) 42 (defalias 'not 'null)
43 43
44 (defmacro noreturn (form) 44 (defmacro noreturn (form)
45 "Evaluates FORM, with the expectation that the evaluation will signal an error 45 "Evaluates FORM, with the expectation that the evaluation will signal an error
142 (defmacro declare (&rest specs) 142 (defmacro declare (&rest specs)
143 "Do not evaluate any arguments and return nil. 143 "Do not evaluate any arguments and return nil.
144 Treated as a declaration when used at the right place in a 144 Treated as a declaration when used at the right place in a
145 `defmacro' form. \(See Info anchor `(elisp)Definition of declare'.)" 145 `defmacro' form. \(See Info anchor `(elisp)Definition of declare'.)"
146 nil) 146 nil)
147
148 ;;;; Basic Lisp functions.
149
150 (defun ignore (&rest ignore)
151 "Do nothing and return nil.
152 This function accepts any number of arguments, but ignores them."
153 (interactive)
154 nil)
155
156 (defun error (&rest args)
157 "Signal an error, making error message by passing all args to `format'.
158 In Emacs, the convention is that error messages start with a capital
159 letter but *do not* end with a period. Please follow this convention
160 for the sake of consistency."
161 (while t
162 (signal 'error (list (apply 'format args)))))
163
164 ;; We put this here instead of in frame.el so that it's defined even on
165 ;; systems where frame.el isn't loaded.
166 (defun frame-configuration-p (object)
167 "Return non-nil if OBJECT seems to be a frame configuration.
168 Any list whose car is `frame-configuration' is assumed to be a frame
169 configuration."
170 (and (consp object)
171 (eq (car object) 'frame-configuration)))
172
173 (defun functionp (object)
174 "Non-nil if OBJECT is any kind of function or a special form.
175 Also non-nil if OBJECT is a symbol and its function definition is
176 \(recursively) a function or special form. This does not include
177 macros."
178 (or (and (symbolp object) (fboundp object)
179 (condition-case nil
180 (setq object (indirect-function object))
181 (error nil))
182 (eq (car-safe object) 'autoload)
183 (not (car-safe (cdr-safe (cdr-safe (cdr-safe (cdr-safe object)))))))
184 (subrp object) (byte-code-function-p object)
185 (eq (car-safe object) 'lambda)))
186
187 ;; This should probably be written in C (i.e., without using `walk-windows').
188 (defun get-buffer-window-list (buffer &optional minibuf frame)
189 "Return list of all windows displaying BUFFER, or nil if none.
190 BUFFER can be a buffer or a buffer name.
191 See `walk-windows' for the meaning of MINIBUF and FRAME."
192 (let ((buffer (if (bufferp buffer) buffer (get-buffer buffer))) windows)
193 (walk-windows (function (lambda (window)
194 (if (eq (window-buffer window) buffer)
195 (setq windows (cons window windows)))))
196 minibuf frame)
197 windows))
198
199 ;;;; List functions.
147 200
148 (defsubst caar (x) 201 (defsubst caar (x)
149 "Return the car of the car of X." 202 "Return the car of the car of X."
150 (car (car x))) 203 (car (car x)))
151 204
238 (setq seq (cons next seq) 291 (setq seq (cons next seq)
239 n (1+ n) 292 n (1+ n)
240 next (+ from (* n inc))))) 293 next (+ from (* n inc)))))
241 (nreverse seq)))) 294 (nreverse seq))))
242 295
243 (defun remove (elt seq)
244 "Return a copy of SEQ with all occurrences of ELT removed.
245 SEQ must be a list, vector, or string. The comparison is done with `equal'."
246 (if (nlistp seq)
247 ;; If SEQ isn't a list, there's no need to copy SEQ because
248 ;; `delete' will return a new object.
249 (delete elt seq)
250 (delete elt (copy-sequence seq))))
251
252 (defun remq (elt list)
253 "Return LIST with all occurrences of ELT removed.
254 The comparison is done with `eq'. Contrary to `delq', this does not use
255 side-effects, and the argument LIST is not modified."
256 (if (memq elt list)
257 (delq elt (copy-sequence list))
258 list))
259
260 (defun copy-tree (tree &optional vecp) 296 (defun copy-tree (tree &optional vecp)
261 "Make a copy of TREE. 297 "Make a copy of TREE.
262 If TREE is a cons cell, this recursively copies both its car and its cdr. 298 If TREE is a cons cell, this recursively copies both its car and its cdr.
263 Contrast to `copy-sequence', which copies only along the cdrs. With second 299 Contrast to `copy-sequence', which copies only along the cdrs. With second
264 argument VECP, this copies vectors as well as conses." 300 argument VECP, this copies vectors as well as conses."
275 (let ((i (length (setq tree (copy-sequence tree))))) 311 (let ((i (length (setq tree (copy-sequence tree)))))
276 (while (>= (setq i (1- i)) 0) 312 (while (>= (setq i (1- i)) 0)
277 (aset tree i (copy-tree (aref tree i) vecp))) 313 (aset tree i (copy-tree (aref tree i) vecp)))
278 tree) 314 tree)
279 tree))) 315 tree)))
316
317 ;;;; Various list-search functions.
280 318
281 (defun assoc-default (key alist &optional test default) 319 (defun assoc-default (key alist &optional test default)
282 "Find object KEY in a pseudo-alist ALIST. 320 "Find object KEY in a pseudo-alist ALIST.
283 ALIST is a list of conses or objects. Each element (or the element's car, 321 ALIST is a list of conses or objects. Each element (or the element's car,
284 if it is a cons) is compared with KEY by evaluating (TEST (car elt) KEY). 322 if it is a cons) is compared with KEY by evaluating (TEST (car elt) KEY).
319 (not (and (stringp (car list)) 357 (not (and (stringp (car list))
320 (eq t (compare-strings elt 0 nil (car list) 0 nil t))))) 358 (eq t (compare-strings elt 0 nil (car list) 0 nil t)))))
321 (setq list (cdr list))) 359 (setq list (cdr list)))
322 list) 360 list)
323 361
362 (defun assq-delete-all (key alist)
363 "Delete from ALIST all elements whose car is `eq' to KEY.
364 Return the modified alist.
365 Elements of ALIST that are not conses are ignored."
366 (while (and (consp (car alist))
367 (eq (car (car alist)) key))
368 (setq alist (cdr alist)))
369 (let ((tail alist) tail-cdr)
370 (while (setq tail-cdr (cdr tail))
371 (if (and (consp (car tail-cdr))
372 (eq (car (car tail-cdr)) key))
373 (setcdr tail (cdr tail-cdr))
374 (setq tail tail-cdr))))
375 alist)
376
377 (defun rassq-delete-all (value alist)
378 "Delete from ALIST all elements whose cdr is `eq' to VALUE.
379 Return the modified alist.
380 Elements of ALIST that are not conses are ignored."
381 (while (and (consp (car alist))
382 (eq (cdr (car alist)) value))
383 (setq alist (cdr alist)))
384 (let ((tail alist) tail-cdr)
385 (while (setq tail-cdr (cdr tail))
386 (if (and (consp (car tail-cdr))
387 (eq (cdr (car tail-cdr)) value))
388 (setcdr tail (cdr tail-cdr))
389 (setq tail tail-cdr))))
390 alist)
391
392 (defun remove (elt seq)
393 "Return a copy of SEQ with all occurrences of ELT removed.
394 SEQ must be a list, vector, or string. The comparison is done with `equal'."
395 (if (nlistp seq)
396 ;; If SEQ isn't a list, there's no need to copy SEQ because
397 ;; `delete' will return a new object.
398 (delete elt seq)
399 (delete elt (copy-sequence seq))))
400
401 (defun remq (elt list)
402 "Return LIST with all occurrences of ELT removed.
403 The comparison is done with `eq'. Contrary to `delq', this does not use
404 side-effects, and the argument LIST is not modified."
405 (if (memq elt list)
406 (delq elt (copy-sequence list))
407 list))
324 408
325 ;;;; Keymap support. 409 ;;;; Keymap support.
410
411 (defmacro kbd (keys)
412 "Convert KEYS to the internal Emacs key representation.
413 KEYS should be a string constant in the format used for
414 saving keyboard macros (see `edmacro-mode')."
415 (read-kbd-macro keys))
326 416
327 (defun undefined () 417 (defun undefined ()
328 (interactive) 418 (interactive)
329 (ding)) 419 (ding))
330 420
331 ;Prevent the \{...} documentation construct 421 ;; Prevent the \{...} documentation construct
332 ;from mentioning keys that run this command. 422 ;; from mentioning keys that run this command.
333 (put 'undefined 'suppress-keymap t) 423 (put 'undefined 'suppress-keymap t)
334 424
335 (defun suppress-keymap (map &optional nodigits) 425 (defun suppress-keymap (map &optional nodigits)
336 "Make MAP override all normally self-inserting keys to be undefined. 426 "Make MAP override all normally self-inserting keys to be undefined.
337 Normally, as an exception, digits and minus-sign are set to make prefix args, 427 Normally, as an exception, digits and minus-sign are set to make prefix args,
343 ;; Make plain numbers do numeric args. 433 ;; Make plain numbers do numeric args.
344 (setq loop ?0) 434 (setq loop ?0)
345 (while (<= loop ?9) 435 (while (<= loop ?9)
346 (define-key map (char-to-string loop) 'digit-argument) 436 (define-key map (char-to-string loop) 'digit-argument)
347 (setq loop (1+ loop)))))) 437 (setq loop (1+ loop))))))
438
439 (defun define-key-after (keymap key definition &optional after)
440 "Add binding in KEYMAP for KEY => DEFINITION, right after AFTER's binding.
441 This is like `define-key' except that the binding for KEY is placed
442 just after the binding for the event AFTER, instead of at the beginning
443 of the map. Note that AFTER must be an event type (like KEY), NOT a command
444 \(like DEFINITION).
445
446 If AFTER is t or omitted, the new binding goes at the end of the keymap.
447 AFTER should be a single event type--a symbol or a character, not a sequence.
448
449 Bindings are always added before any inherited map.
450
451 The order of bindings in a keymap matters when it is used as a menu."
452 (unless after (setq after t))
453 (or (keymapp keymap)
454 (signal 'wrong-type-argument (list 'keymapp keymap)))
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)
462 (while (and (not done) tail)
463 ;; Delete any earlier bindings for the same key.
464 (if (eq (car-safe (car (cdr tail))) key)
465 (setcdr tail (cdr (cdr tail))))
466 ;; If we hit an included map, go down that one.
467 (if (keymapp (car tail)) (setq tail (car tail)))
468 ;; When we reach AFTER's binding, insert the new binding after.
469 ;; If we reach an inherited keymap, insert just before that.
470 ;; If we reach the end of this keymap, insert at the end.
471 (if (or (and (eq (car-safe (car tail)) after)
472 (not (eq after t)))
473 (eq (car (cdr tail)) 'keymap)
474 (null (cdr tail)))
475 (progn
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
483 (setcdr tail (cons (cons key definition) (cdr tail))))
484 (setq inserted t)))
485 (setq tail (cdr tail)))))
486
487 (defun map-keymap-internal (function keymap &optional sort-first)
488 "Implement `map-keymap' with sorting.
489 Don't call this function; it is for internal use only."
490 (if sort-first
491 (let (list)
492 (map-keymap (lambda (a b) (push (cons a b) list))
493 keymap)
494 (setq list (sort list
495 (lambda (a b)
496 (setq a (car a) b (car b))
497 (if (integerp a)
498 (if (integerp b) (< a b)
499 t)
500 (if (integerp b) t
501 (string< a b))))))
502 (dolist (p list)
503 (funcall function (car p) (cdr p))))
504 (map-keymap function keymap)))
505
506 (put 'keyboard-translate-table 'char-table-extra-slots 0)
507
508 (defun keyboard-translate (from to)
509 "Translate character FROM to TO at a low level.
510 This function creates a `keyboard-translate-table' if necessary
511 and then modifies one entry in it."
512 (or (char-table-p keyboard-translate-table)
513 (setq keyboard-translate-table
514 (make-char-table 'keyboard-translate-table nil)))
515 (aset keyboard-translate-table from to))
516
517 ;;;; Key binding commands.
518
519 (defun global-set-key (key command)
520 "Give KEY a global binding as COMMAND.
521 COMMAND is the command definition to use; usually it is
522 a symbol naming an interactively-callable function.
523 KEY is a key sequence; noninteractively, it is a string or vector
524 of characters or event types, and non-ASCII characters with codes
525 above 127 (such as ISO Latin-1) can be included if you use a vector.
526
527 Note that if KEY has a local binding in the current buffer,
528 that local binding will continue to shadow any global binding
529 that you make with this function."
530 (interactive "KSet key globally: \nCSet key %s to command: ")
531 (or (vectorp key) (stringp key)
532 (signal 'wrong-type-argument (list 'arrayp key)))
533 (define-key (current-global-map) key command))
534
535 (defun local-set-key (key command)
536 "Give KEY a local binding as COMMAND.
537 COMMAND is the command definition to use; usually it is
538 a symbol naming an interactively-callable function.
539 KEY is a key sequence; noninteractively, it is a string or vector
540 of characters or event types, and non-ASCII characters with codes
541 above 127 (such as ISO Latin-1) can be included if you use a vector.
542
543 The binding goes in the current buffer's local map,
544 which in most cases is shared with all other buffers in the same major mode."
545 (interactive "KSet key locally: \nCSet key %s locally to command: ")
546 (let ((map (current-local-map)))
547 (or map
548 (use-local-map (setq map (make-sparse-keymap))))
549 (or (vectorp key) (stringp key)
550 (signal 'wrong-type-argument (list 'arrayp key)))
551 (define-key map key command)))
552
553 (defun global-unset-key (key)
554 "Remove global binding of KEY.
555 KEY is a string or vector representing a sequence of keystrokes."
556 (interactive "kUnset key globally: ")
557 (global-set-key key nil))
558
559 (defun local-unset-key (key)
560 "Remove local binding of KEY.
561 KEY is a string or vector representing a sequence of keystrokes."
562 (interactive "kUnset key locally: ")
563 (if (current-local-map)
564 (local-set-key key nil))
565 nil)
566
567 ;;;; substitute-key-definition and its subroutines.
348 568
349 (defvar key-substitution-in-progress nil 569 (defvar key-substitution-in-progress nil
350 "Used internally by `substitute-key-definition'.") 570 "Used internally by `substitute-key-definition'.")
351 571
352 (defun substitute-key-definition (olddef newdef keymap &optional oldmap prefix) 572 (defun substitute-key-definition (olddef newdef keymap &optional oldmap prefix)
414 ;; Avoid recursively rescanning keymap being scanned. 634 ;; Avoid recursively rescanning keymap being scanned.
415 (not (memq inner-def key-substitution-in-progress))) 635 (not (memq inner-def key-substitution-in-progress)))
416 ;; If this one isn't being scanned already, scan it now. 636 ;; If this one isn't being scanned already, scan it now.
417 (substitute-key-definition olddef newdef keymap inner-def prefix))))) 637 (substitute-key-definition olddef newdef keymap inner-def prefix)))))
418 638
419 (defun define-key-after (keymap key definition &optional after)
420 "Add binding in KEYMAP for KEY => DEFINITION, right after AFTER's binding.
421 This is like `define-key' except that the binding for KEY is placed
422 just after the binding for the event AFTER, instead of at the beginning
423 of the map. Note that AFTER must be an event type (like KEY), NOT a command
424 \(like DEFINITION).
425
426 If AFTER is t or omitted, the new binding goes at the end of the keymap.
427 AFTER should be a single event type--a symbol or a character, not a sequence.
428
429 Bindings are always added before any inherited map.
430
431 The order of bindings in a keymap matters when it is used as a menu."
432 (unless after (setq after t))
433 (or (keymapp keymap)
434 (signal 'wrong-type-argument (list 'keymapp keymap)))
435 (setq key
436 (if (<= (length key) 1) (aref key 0)
437 (setq keymap (lookup-key keymap
438 (apply 'vector
439 (butlast (mapcar 'identity key)))))
440 (aref key (1- (length key)))))
441 (let ((tail keymap) done inserted)
442 (while (and (not done) tail)
443 ;; Delete any earlier bindings for the same key.
444 (if (eq (car-safe (car (cdr tail))) key)
445 (setcdr tail (cdr (cdr tail))))
446 ;; If we hit an included map, go down that one.
447 (if (keymapp (car tail)) (setq tail (car tail)))
448 ;; When we reach AFTER's binding, insert the new binding after.
449 ;; If we reach an inherited keymap, insert just before that.
450 ;; If we reach the end of this keymap, insert at the end.
451 (if (or (and (eq (car-safe (car tail)) after)
452 (not (eq after t)))
453 (eq (car (cdr tail)) 'keymap)
454 (null (cdr tail)))
455 (progn
456 ;; Stop the scan only if we find a parent keymap.
457 ;; Keep going past the inserted element
458 ;; so we can delete any duplications that come later.
459 (if (eq (car (cdr tail)) 'keymap)
460 (setq done t))
461 ;; Don't insert more than once.
462 (or inserted
463 (setcdr tail (cons (cons key definition) (cdr tail))))
464 (setq inserted t)))
465 (setq tail (cdr tail)))))
466
467 (defun map-keymap-internal (function keymap &optional sort-first)
468 "Implement `map-keymap' with sorting.
469 Don't call this function; it is for internal use only."
470 (if sort-first
471 (let (list)
472 (map-keymap (lambda (a b) (push (cons a b) list))
473 keymap)
474 (setq list (sort list
475 (lambda (a b)
476 (setq a (car a) b (car b))
477 (if (integerp a)
478 (if (integerp b) (< a b)
479 t)
480 (if (integerp b) t
481 (string< a b))))))
482 (dolist (p list)
483 (funcall function (car p) (cdr p))))
484 (map-keymap function keymap)))
485
486 (defmacro kbd (keys)
487 "Convert KEYS to the internal Emacs key representation.
488 KEYS should be a string constant in the format used for
489 saving keyboard macros (see `edmacro-mode')."
490 (read-kbd-macro keys))
491
492 (put 'keyboard-translate-table 'char-table-extra-slots 0)
493
494 (defun keyboard-translate (from to)
495 "Translate character FROM to TO at a low level.
496 This function creates a `keyboard-translate-table' if necessary
497 and then modifies one entry in it."
498 (or (char-table-p keyboard-translate-table)
499 (setq keyboard-translate-table
500 (make-char-table 'keyboard-translate-table nil)))
501 (aset keyboard-translate-table from to))
502
503 639
504 ;;;; The global keymap tree. 640 ;;;; The global keymap tree.
505 641
506 ;;; global-map, esc-map, and ctl-x-map have their values set up in 642 ;;; global-map, esc-map, and ctl-x-map have their values set up in
507 ;;; keymap.c; we just give them docstrings here. 643 ;;; keymap.c; we just give them docstrings here.
640 776
641 (defsubst event-click-count (event) 777 (defsubst event-click-count (event)
642 "Return the multi-click count of EVENT, a click or drag event. 778 "Return the multi-click count of EVENT, a click or drag event.
643 The return value is a positive integer." 779 The return value is a positive integer."
644 (if (and (consp event) (integerp (nth 2 event))) (nth 2 event) 1)) 780 (if (and (consp event) (integerp (nth 2 event))) (nth 2 event) 1))
781
782 ;;;; Extracting fields of the positions in an event.
645 783
646 (defsubst posn-window (position) 784 (defsubst posn-window (position)
647 "Return the window in POSITION. 785 "Return the window in POSITION.
648 POSITION should be a list of the form returned by the `event-start' 786 POSITION should be a list of the form returned by the `event-start'
649 and `event-end' functions." 787 and `event-end' functions."
829 (defalias 'make-variable-frame-localizable 'make-variable-frame-local) 967 (defalias 'make-variable-frame-localizable 'make-variable-frame-local)
830 ;; These are the XEmacs names: 968 ;; These are the XEmacs names:
831 (defalias 'point-at-eol 'line-end-position) 969 (defalias 'point-at-eol 'line-end-position)
832 (defalias 'point-at-bol 'line-beginning-position) 970 (defalias 'point-at-bol 'line-beginning-position)
833 971
972 (defalias 'user-original-login-name 'user-login-name)
973
834 974
835 ;;;; Hook manipulation functions. 975 ;;;; Hook manipulation functions.
836 976
837 (defun make-local-hook (hook) 977 (defun make-local-hook (hook)
838 "Make the hook HOOK local to the current buffer. 978 "Make the hook HOOK local to the current buffer.
989 (let ((oa (gethash a ordering)) 1129 (let ((oa (gethash a ordering))
990 (ob (gethash b ordering))) 1130 (ob (gethash b ordering)))
991 (if (and oa ob) 1131 (if (and oa ob)
992 (< oa ob) 1132 (< oa ob)
993 oa))))))) 1133 oa)))))))
994 1134
1135 ;;;; Mode hooks.
1136
1137 (defvar delay-mode-hooks nil
1138 "If non-nil, `run-mode-hooks' should delay running the hooks.")
1139 (defvar delayed-mode-hooks nil
1140 "List of delayed mode hooks waiting to be run.")
1141 (make-variable-buffer-local 'delayed-mode-hooks)
1142 (put 'delay-mode-hooks 'permanent-local t)
1143
1144 (defvar after-change-major-mode-hook nil
1145 "Normal hook run at the very end of major mode functions.")
1146
1147 (defun run-mode-hooks (&rest hooks)
1148 "Run mode hooks `delayed-mode-hooks' and HOOKS, or delay HOOKS.
1149 Execution is delayed if `delay-mode-hooks' is non-nil.
1150 If `delay-mode-hooks' is nil, run `after-change-major-mode-hook'
1151 after running the mode hooks.
1152 Major mode functions should use this."
1153 (if delay-mode-hooks
1154 ;; Delaying case.
1155 (dolist (hook hooks)
1156 (push hook delayed-mode-hooks))
1157 ;; Normal case, just run the hook as before plus any delayed hooks.
1158 (setq hooks (nconc (nreverse delayed-mode-hooks) hooks))
1159 (setq delayed-mode-hooks nil)
1160 (apply 'run-hooks hooks)
1161 (run-hooks 'after-change-major-mode-hook)))
1162
1163 (defmacro delay-mode-hooks (&rest body)
1164 "Execute BODY, but delay any `run-mode-hooks'.
1165 These hooks will be executed by the first following call to
1166 `run-mode-hooks' that occurs outside any `delayed-mode-hooks' form.
1167 Only affects hooks run in the current buffer."
1168 (declare (debug t) (indent 0))
1169 `(progn
1170 (make-local-variable 'delay-mode-hooks)
1171 (let ((delay-mode-hooks t))
1172 ,@body)))
1173
1174 ;; PUBLIC: find if the current mode derives from another.
1175
1176 (defun derived-mode-p (&rest modes)
1177 "Non-nil if the current major mode is derived from one of MODES.
1178 Uses the `derived-mode-parent' property of the symbol to trace backwards."
1179 (let ((parent major-mode))
1180 (while (and (not (memq parent modes))
1181 (setq parent (get parent 'derived-mode-parent))))
1182 parent))
1183
1184 ;;;; Minor modes.
1185
1186 ;; If a minor mode is not defined with define-minor-mode,
1187 ;; add it here explicitly.
1188 ;; isearch-mode is deliberately excluded, since you should
1189 ;; not call it yourself.
1190 (defvar minor-mode-list '(auto-save-mode auto-fill-mode abbrev-mode
1191 overwrite-mode view-mode
1192 hs-minor-mode)
1193 "List of all minor mode functions.")
1194
1195 (defun add-minor-mode (toggle name &optional keymap after toggle-fun)
1196 "Register a new minor mode.
1197
1198 This is an XEmacs-compatibility function. Use `define-minor-mode' instead.
1199
1200 TOGGLE is a symbol which is the name of a buffer-local variable that
1201 is toggled on or off to say whether the minor mode is active or not.
1202
1203 NAME specifies what will appear in the mode line when the minor mode
1204 is active. NAME should be either a string starting with a space, or a
1205 symbol whose value is such a string.
1206
1207 Optional KEYMAP is the keymap for the minor mode that will be added
1208 to `minor-mode-map-alist'.
1209
1210 Optional AFTER specifies that TOGGLE should be added after AFTER
1211 in `minor-mode-alist'.
1212
1213 Optional TOGGLE-FUN is an interactive function to toggle the mode.
1214 It defaults to (and should by convention be) TOGGLE.
1215
1216 If TOGGLE has a non-nil `:included' property, an entry for the mode is
1217 included in the mode-line minor mode menu.
1218 If TOGGLE has a `:menu-tag', that is used for the menu item's label."
1219 (unless (memq toggle minor-mode-list)
1220 (push toggle minor-mode-list))
1221
1222 (unless toggle-fun (setq toggle-fun toggle))
1223 (unless (eq toggle-fun toggle)
1224 (put toggle :minor-mode-function toggle-fun))
1225 ;; Add the name to the minor-mode-alist.
1226 (when name
1227 (let ((existing (assq toggle minor-mode-alist)))
1228 (if existing
1229 (setcdr existing (list name))
1230 (let ((tail minor-mode-alist) found)
1231 (while (and tail (not found))
1232 (if (eq after (caar tail))
1233 (setq found tail)
1234 (setq tail (cdr tail))))
1235 (if found
1236 (let ((rest (cdr found)))
1237 (setcdr found nil)
1238 (nconc found (list (list toggle name)) rest))
1239 (setq minor-mode-alist (cons (list toggle name)
1240 minor-mode-alist)))))))
1241 ;; Add the toggle to the minor-modes menu if requested.
1242 (when (get toggle :included)
1243 (define-key mode-line-mode-menu
1244 (vector toggle)
1245 (list 'menu-item
1246 (concat
1247 (or (get toggle :menu-tag)
1248 (if (stringp name) name (symbol-name toggle)))
1249 (let ((mode-name (if (symbolp name) (symbol-value name))))
1250 (if (and (stringp mode-name) (string-match "[^ ]+" mode-name))
1251 (concat " (" (match-string 0 mode-name) ")"))))
1252 toggle-fun
1253 :button (cons :toggle toggle))))
1254
1255 ;; Add the map to the minor-mode-map-alist.
1256 (when keymap
1257 (let ((existing (assq toggle minor-mode-map-alist)))
1258 (if existing
1259 (setcdr existing keymap)
1260 (let ((tail minor-mode-map-alist) found)
1261 (while (and tail (not found))
1262 (if (eq after (caar tail))
1263 (setq found tail)
1264 (setq tail (cdr tail))))
1265 (if found
1266 (let ((rest (cdr found)))
1267 (setcdr found nil)
1268 (nconc found (list (cons toggle keymap)) rest))
1269 (setq minor-mode-map-alist (cons (cons toggle keymap)
1270 minor-mode-map-alist))))))))
995 1271
996 ;;; Load history 1272 ;;; Load history
997 1273
998 ;;; (defvar symbol-file-load-history-loaded nil 1274 ;;; (defvar symbol-file-load-history-loaded nil
999 ;;; "Non-nil means we have loaded the file `fns-VERSION.el' in `exec-directory'. 1275 ;;; "Non-nil means we have loaded the file `fns-VERSION.el' in `exec-directory'.
1078 "Read the following input sexp, and run it whenever FILE is loaded. 1354 "Read the following input sexp, and run it whenever FILE is loaded.
1079 This makes or adds to an entry on `after-load-alist'. 1355 This makes or adds to an entry on `after-load-alist'.
1080 FILE should be the name of a library, with no directory name." 1356 FILE should be the name of a library, with no directory name."
1081 (eval-after-load file (read))) 1357 (eval-after-load file (read)))
1082 1358
1083 ;;; open-network-stream is a wrapper around make-network-process. 1359 ;;;; Process stuff.
1360
1361 ;; open-network-stream is a wrapper around make-network-process.
1084 1362
1085 (when (featurep 'make-network-process) 1363 (when (featurep 'make-network-process)
1086 (defun open-network-stream (name buffer host service) 1364 (defun open-network-stream (name buffer host service)
1087 "Open a TCP connection for a service to a host. 1365 "Open a TCP connection for a service to a host.
1088 Returns a subprocess-object to represent the connection. 1366 Returns a subprocess-object to represent the connection.
1378 (setcar elt old-car) 1656 (setcar elt old-car)
1379 (setcdr elt old-cdr)) 1657 (setcdr elt old-cdr))
1380 ;; Revert the undo info to what it was when we grabbed the state. 1658 ;; Revert the undo info to what it was when we grabbed the state.
1381 (setq buffer-undo-list elt))))) 1659 (setq buffer-undo-list elt)))))
1382 1660
1661 ;;;; Display-related functions.
1662
1383 ;; For compatibility. 1663 ;; For compatibility.
1384 (defalias 'redraw-modeline 'force-mode-line-update) 1664 (defalias 'redraw-modeline 'force-mode-line-update)
1385 1665
1386 (defun force-mode-line-update (&optional all) 1666 (defun force-mode-line-update (&optional all)
1387 "Force redisplay of the current buffer's mode line and header line. 1667 "Force redisplay of the current buffer's mode line and header line.
1515 (defvar buffer-file-type nil 1795 (defvar buffer-file-type nil
1516 "Non-nil if the visited file is a binary file. 1796 "Non-nil if the visited file is a binary file.
1517 This variable is meaningful on MS-DOG and Windows NT. 1797 This variable is meaningful on MS-DOG and Windows NT.
1518 On those systems, it is automatically local in every buffer. 1798 On those systems, it is automatically local in every buffer.
1519 On other systems, this variable is normally always nil.") 1799 On other systems, this variable is normally always nil.")
1520 1800
1521 ;; This should probably be written in C (i.e., without using `walk-windows'). 1801 ;;;; Misc. useful functions.
1522 (defun get-buffer-window-list (buffer &optional minibuf frame) 1802
1523 "Return list of all windows displaying BUFFER, or nil if none. 1803 (defun find-tag-default ()
1524 BUFFER can be a buffer or a buffer name. 1804 "Determine default tag to search for, based on text at point.
1525 See `walk-windows' for the meaning of MINIBUF and FRAME." 1805 If there is no plausible default, return nil."
1526 (let ((buffer (if (bufferp buffer) buffer (get-buffer buffer))) windows) 1806 (save-excursion
1527 (walk-windows (function (lambda (window) 1807 (while (looking-at "\\sw\\|\\s_")
1528 (if (eq (window-buffer window) buffer) 1808 (forward-char 1))
1529 (setq windows (cons window windows))))) 1809 (if (or (re-search-backward "\\sw\\|\\s_"
1530 minibuf frame) 1810 (save-excursion (beginning-of-line) (point))
1531 windows)) 1811 t)
1532 1812 (re-search-forward "\\(\\sw\\|\\s_\\)+"
1533 (defun ignore (&rest ignore) 1813 (save-excursion (end-of-line) (point))
1534 "Do nothing and return nil. 1814 t))
1535 This function accepts any number of arguments, but ignores them." 1815 (progn
1536 (interactive) 1816 (goto-char (match-end 0))
1537 nil) 1817 (condition-case nil
1538 1818 (buffer-substring-no-properties
1539 (defun error (&rest args) 1819 (point)
1540 "Signal an error, making error message by passing all args to `format'. 1820 (progn (forward-sexp -1)
1541 In Emacs, the convention is that error messages start with a capital 1821 (while (looking-at "\\s'")
1542 letter but *do not* end with a period. Please follow this convention 1822 (forward-char 1))
1543 for the sake of consistency." 1823 (point)))
1544 (while t 1824 (error nil)))
1545 (signal 'error (list (apply 'format args))))) 1825 nil)))
1546 1826
1547 (defalias 'user-original-login-name 'user-login-name) 1827 (defun play-sound (sound)
1828 "SOUND is a list of the form `(sound KEYWORD VALUE...)'.
1829 The following keywords are recognized:
1830
1831 :file FILE - read sound data from FILE. If FILE isn't an
1832 absolute file name, it is searched in `data-directory'.
1833
1834 :data DATA - read sound data from string DATA.
1835
1836 Exactly one of :file or :data must be present.
1837
1838 :volume VOL - set volume to VOL. VOL must an integer in the
1839 range 0..100 or a float in the range 0..1.0. If not specified,
1840 don't change the volume setting of the sound device.
1841
1842 :device DEVICE - play sound on DEVICE. If not specified,
1843 a system-dependent default device name is used."
1844 (if (fboundp 'play-sound-internal)
1845 (play-sound-internal sound)
1846 (error "This Emacs binary lacks sound support")))
1847
1848 (defun make-temp-file (prefix &optional dir-flag suffix)
1849 "Create a temporary file.
1850 The returned file name (created by appending some random characters at the end
1851 of PREFIX, and expanding against `temporary-file-directory' if necessary),
1852 is guaranteed to point to a newly created empty file.
1853 You can then use `write-region' to write new data into the file.
1854
1855 If DIR-FLAG is non-nil, create a new empty directory instead of a file.
1856
1857 If SUFFIX is non-nil, add that at the end of the file name."
1858 (let ((umask (default-file-modes))
1859 file)
1860 (unwind-protect
1861 (progn
1862 ;; Create temp files with strict access rights. It's easy to
1863 ;; loosen them later, whereas it's impossible to close the
1864 ;; time-window of loose permissions otherwise.
1865 (set-default-file-modes ?\700)
1866 (while (condition-case ()
1867 (progn
1868 (setq file
1869 (make-temp-name
1870 (expand-file-name prefix temporary-file-directory)))
1871 (if suffix
1872 (setq file (concat file suffix)))
1873 (if dir-flag
1874 (make-directory file)
1875 (write-region "" nil file nil 'silent nil 'excl))
1876 nil)
1877 (file-already-exists t))
1878 ;; the file was somehow created by someone else between
1879 ;; `make-temp-name' and `write-region', let's try again.
1880 nil)
1881 file)
1882 ;; Reset the umask.
1883 (set-default-file-modes umask))))
1884
1885 (defun shell-quote-argument (argument)
1886 "Quote an argument for passing as argument to an inferior shell."
1887 (if (eq system-type 'ms-dos)
1888 ;; Quote using double quotes, but escape any existing quotes in
1889 ;; the argument with backslashes.
1890 (let ((result "")
1891 (start 0)
1892 end)
1893 (if (or (null (string-match "[^\"]" argument))
1894 (< (match-end 0) (length argument)))
1895 (while (string-match "[\"]" argument start)
1896 (setq end (match-beginning 0)
1897 result (concat result (substring argument start end)
1898 "\\" (substring argument end (1+ end)))
1899 start (1+ end))))
1900 (concat "\"" result (substring argument start) "\""))
1901 (if (eq system-type 'windows-nt)
1902 (concat "\"" argument "\"")
1903 (if (equal argument "")
1904 "''"
1905 ;; Quote everything except POSIX filename characters.
1906 ;; This should be safe enough even for really weird shells.
1907 (let ((result "") (start 0) end)
1908 (while (string-match "[^-0-9a-zA-Z_./]" argument start)
1909 (setq end (match-beginning 0)
1910 result (concat result (substring argument start end)
1911 "\\" (substring argument end (1+ end)))
1912 start (1+ end)))
1913 (concat result (substring argument start)))))))
1914
1915 ;;;; Support for yanking and text properties.
1548 1916
1549 (defvar yank-excluded-properties) 1917 (defvar yank-excluded-properties)
1550 1918
1551 (defun remove-yank-excluded-properties (start end) 1919 (defun remove-yank-excluded-properties (start end)
1552 "Remove `yank-excluded-properties' between START and END positions. 1920 "Remove `yank-excluded-properties' between START and END positions.
1648 (let ((opoint (point))) 2016 (let ((opoint (point)))
1649 (insert-buffer-substring buffer start end) 2017 (insert-buffer-substring buffer start end)
1650 (remove-yank-excluded-properties opoint (point)))) 2018 (remove-yank-excluded-properties opoint (point))))
1651 2019
1652 2020
1653 ;; Synchronous shell commands. 2021 ;;;; Synchronous shell commands.
1654 2022
1655 (defun start-process-shell-command (name buffer &rest args) 2023 (defun start-process-shell-command (name buffer &rest args)
1656 "Start a program in a subprocess. Return the process object for it. 2024 "Start a program in a subprocess. Return the process object for it.
1657 NAME is name for process. It is modified if necessary to make it unique. 2025 NAME is name for process. It is modified if necessary to make it unique.
1658 BUFFER is the buffer (or buffer name) to associate with the process. 2026 BUFFER is the buffer (or buffer name) to associate with the process.
1704 (call-process shell-file-name 2072 (call-process shell-file-name
1705 infile buffer display 2073 infile buffer display
1706 shell-command-switch 2074 shell-command-switch
1707 (mapconcat 'identity (cons command args) " "))))) 2075 (mapconcat 'identity (cons command args) " ")))))
1708 2076
2077 ;;;; Lisp macros to do various things temporarily.
2078
1709 (defmacro with-current-buffer (buffer &rest body) 2079 (defmacro with-current-buffer (buffer &rest body)
1710 "Execute the forms in BODY with BUFFER as the current buffer. 2080 "Execute the forms in BODY with BUFFER as the current buffer.
1711 The value returned is the value of the last form in BODY. 2081 The value returned is the value of the last form in BODY.
1712 See also `with-temp-buffer'." 2082 See also `with-temp-buffer'."
1713 (declare (indent 1) (debug t)) 2083 (declare (indent 1) (debug t))
1856 (declare (indent 0) (debug t)) 2226 (declare (indent 0) (debug t))
1857 `(unwind-protect 2227 `(unwind-protect
1858 (let ((combine-after-change-calls t)) 2228 (let ((combine-after-change-calls t))
1859 . ,body) 2229 . ,body)
1860 (combine-after-change-execute))) 2230 (combine-after-change-execute)))
1861 2231
1862 2232 ;;;; Constructing completion tables.
1863 (defvar delay-mode-hooks nil
1864 "If non-nil, `run-mode-hooks' should delay running the hooks.")
1865 (defvar delayed-mode-hooks nil
1866 "List of delayed mode hooks waiting to be run.")
1867 (make-variable-buffer-local 'delayed-mode-hooks)
1868 (put 'delay-mode-hooks 'permanent-local t)
1869
1870 (defvar after-change-major-mode-hook nil
1871 "Normal hook run at the very end of major mode functions.")
1872
1873 (defun run-mode-hooks (&rest hooks)
1874 "Run mode hooks `delayed-mode-hooks' and HOOKS, or delay HOOKS.
1875 Execution is delayed if `delay-mode-hooks' is non-nil.
1876 If `delay-mode-hooks' is nil, run `after-change-major-mode-hook'
1877 after running the mode hooks.
1878 Major mode functions should use this."
1879 (if delay-mode-hooks
1880 ;; Delaying case.
1881 (dolist (hook hooks)
1882 (push hook delayed-mode-hooks))
1883 ;; Normal case, just run the hook as before plus any delayed hooks.
1884 (setq hooks (nconc (nreverse delayed-mode-hooks) hooks))
1885 (setq delayed-mode-hooks nil)
1886 (apply 'run-hooks hooks)
1887 (run-hooks 'after-change-major-mode-hook)))
1888
1889 (defmacro delay-mode-hooks (&rest body)
1890 "Execute BODY, but delay any `run-mode-hooks'.
1891 These hooks will be executed by the first following call to
1892 `run-mode-hooks' that occurs outside any `delayed-mode-hooks' form.
1893 Only affects hooks run in the current buffer."
1894 (declare (debug t) (indent 0))
1895 `(progn
1896 (make-local-variable 'delay-mode-hooks)
1897 (let ((delay-mode-hooks t))
1898 ,@body)))
1899
1900 ;; PUBLIC: find if the current mode derives from another.
1901
1902 (defun derived-mode-p (&rest modes)
1903 "Non-nil if the current major mode is derived from one of MODES.
1904 Uses the `derived-mode-parent' property of the symbol to trace backwards."
1905 (let ((parent major-mode))
1906 (while (and (not (memq parent modes))
1907 (setq parent (get parent 'derived-mode-parent))))
1908 parent))
1909
1910 (defun find-tag-default ()
1911 "Determine default tag to search for, based on text at point.
1912 If there is no plausible default, return nil."
1913 (save-excursion
1914 (while (looking-at "\\sw\\|\\s_")
1915 (forward-char 1))
1916 (if (or (re-search-backward "\\sw\\|\\s_"
1917 (save-excursion (beginning-of-line) (point))
1918 t)
1919 (re-search-forward "\\(\\sw\\|\\s_\\)+"
1920 (save-excursion (end-of-line) (point))
1921 t))
1922 (progn
1923 (goto-char (match-end 0))
1924 (condition-case nil
1925 (buffer-substring-no-properties
1926 (point)
1927 (progn (forward-sexp -1)
1928 (while (looking-at "\\s'")
1929 (forward-char 1))
1930 (point)))
1931 (error nil)))
1932 nil)))
1933
1934 (defmacro with-syntax-table (table &rest body)
1935 "Evaluate BODY with syntax table of current buffer set to TABLE.
1936 The syntax table of the current buffer is saved, BODY is evaluated, and the
1937 saved table is restored, even in case of an abnormal exit.
1938 Value is what BODY returns."
1939 (declare (debug t))
1940 (let ((old-table (make-symbol "table"))
1941 (old-buffer (make-symbol "buffer")))
1942 `(let ((,old-table (syntax-table))
1943 (,old-buffer (current-buffer)))
1944 (unwind-protect
1945 (progn
1946 (set-syntax-table ,table)
1947 ,@body)
1948 (save-current-buffer
1949 (set-buffer ,old-buffer)
1950 (set-syntax-table ,old-table))))))
1951 2233
1952 (defmacro dynamic-completion-table (fun) 2234 (defmacro dynamic-completion-table (fun)
1953 "Use function FUN as a dynamic completion table. 2235 "Use function FUN as a dynamic completion table.
1954 FUN is called with one argument, the string for which completion is required, 2236 FUN is called with one argument, the string for which completion is required,
1955 and it should return an alist containing all the intended possible 2237 and it should return an alist containing all the intended possible
2005 (try-completion string ,b predicate))) 2287 (try-completion string ,b predicate)))
2006 (t 2288 (t
2007 (or (test-completion string ,a predicate) 2289 (or (test-completion string ,a predicate)
2008 (test-completion string ,b predicate)))))) 2290 (test-completion string ,b predicate))))))
2009 2291
2010 ;;; Matching and substitution 2292 ;;; Matching and match data.
2011 2293
2012 (defvar save-match-data-internal) 2294 (defvar save-match-data-internal)
2013 2295
2014 ;; We use save-match-data-internal as the local variable because 2296 ;; We use save-match-data-internal as the local variable because
2015 ;; that works ok in practice (people should not use that variable elsewhere). 2297 ;; that works ok in practice (people should not use that variable elsewhere).
2079 (setq pos (1- pos))) 2361 (setq pos (1- pos)))
2080 (save-excursion 2362 (save-excursion
2081 (goto-char pos) 2363 (goto-char pos)
2082 (looking-at (concat "\\(?:" regexp "\\)\\'"))))) 2364 (looking-at (concat "\\(?:" regexp "\\)\\'")))))
2083 (not (null pos)))) 2365 (not (null pos))))
2084
2085
2086 (defconst split-string-default-separators "[ \f\t\n\r\v]+"
2087 "The default value of separators for `split-string'.
2088
2089 A regexp matching strings of whitespace. May be locale-dependent
2090 \(as yet unimplemented). Should not match non-breaking spaces.
2091
2092 Warning: binding this to a different value and using it as default is
2093 likely to have undesired semantics.")
2094
2095 ;; The specification says that if both SEPARATORS and OMIT-NULLS are
2096 ;; defaulted, OMIT-NULLS should be treated as t. Simplifying the logical
2097 ;; expression leads to the equivalent implementation that if SEPARATORS
2098 ;; is defaulted, OMIT-NULLS is treated as t.
2099 (defun split-string (string &optional separators omit-nulls)
2100 "Split STRING into substrings bounded by matches for SEPARATORS.
2101
2102 The beginning and end of STRING, and each match for SEPARATORS, are
2103 splitting points. The substrings matching SEPARATORS are removed, and
2104 the substrings between the splitting points are collected as a list,
2105 which is returned.
2106
2107 If SEPARATORS is non-nil, it should be a regular expression matching text
2108 which separates, but is not part of, the substrings. If nil it defaults to
2109 `split-string-default-separators', normally \"[ \\f\\t\\n\\r\\v]+\", and
2110 OMIT-NULLS is forced to t.
2111
2112 If OMIT-NULLS is t, zero-length substrings are omitted from the list \(so
2113 that for the default value of SEPARATORS leading and trailing whitespace
2114 are effectively trimmed). If nil, all zero-length substrings are retained,
2115 which correctly parses CSV format, for example.
2116
2117 Note that the effect of `(split-string STRING)' is the same as
2118 `(split-string STRING split-string-default-separators t)'). In the rare
2119 case that you wish to retain zero-length substrings when splitting on
2120 whitespace, use `(split-string STRING split-string-default-separators)'.
2121
2122 Modifies the match data; use `save-match-data' if necessary."
2123 (let ((keep-nulls (not (if separators omit-nulls t)))
2124 (rexp (or separators split-string-default-separators))
2125 (start 0)
2126 notfirst
2127 (list nil))
2128 (while (and (string-match rexp string
2129 (if (and notfirst
2130 (= start (match-beginning 0))
2131 (< start (length string)))
2132 (1+ start) start))
2133 (< start (length string)))
2134 (setq notfirst t)
2135 (if (or keep-nulls (< start (match-beginning 0)))
2136 (setq list
2137 (cons (substring string start (match-beginning 0))
2138 list)))
2139 (setq start (match-end 0)))
2140 (if (or keep-nulls (< start (length string)))
2141 (setq list
2142 (cons (substring string start)
2143 list)))
2144 (nreverse list)))
2145
2146 (defun subst-char-in-string (fromchar tochar string &optional inplace)
2147 "Replace FROMCHAR with TOCHAR in STRING each time it occurs.
2148 Unless optional argument INPLACE is non-nil, return a new string."
2149 (let ((i (length string))
2150 (newstr (if inplace string (copy-sequence string))))
2151 (while (> i 0)
2152 (setq i (1- i))
2153 (if (eq (aref newstr i) fromchar)
2154 (aset newstr i tochar)))
2155 newstr))
2156
2157 (defun replace-regexp-in-string (regexp rep string &optional
2158 fixedcase literal subexp start)
2159 "Replace all matches for REGEXP with REP in STRING.
2160
2161 Return a new string containing the replacements.
2162
2163 Optional arguments FIXEDCASE, LITERAL and SUBEXP are like the
2164 arguments with the same names of function `replace-match'. If START
2165 is non-nil, start replacements at that index in STRING.
2166
2167 REP is either a string used as the NEWTEXT arg of `replace-match' or a
2168 function. If it is a function, it is called with the actual text of each
2169 match, and its value is used as the replacement text. When REP is called,
2170 the match-data are the result of matching REGEXP against a substring
2171 of STRING.
2172
2173 To replace only the first match (if any), make REGEXP match up to \\'
2174 and replace a sub-expression, e.g.
2175 (replace-regexp-in-string \"\\\\(foo\\\\).*\\\\'\" \"bar\" \" foo foo\" nil nil 1)
2176 => \" bar foo\"
2177 "
2178
2179 ;; To avoid excessive consing from multiple matches in long strings,
2180 ;; don't just call `replace-match' continually. Walk down the
2181 ;; string looking for matches of REGEXP and building up a (reversed)
2182 ;; list MATCHES. This comprises segments of STRING which weren't
2183 ;; matched interspersed with replacements for segments that were.
2184 ;; [For a `large' number of replacements it's more efficient to
2185 ;; operate in a temporary buffer; we can't tell from the function's
2186 ;; args whether to choose the buffer-based implementation, though it
2187 ;; might be reasonable to do so for long enough STRING.]
2188 (let ((l (length string))
2189 (start (or start 0))
2190 matches str mb me)
2191 (save-match-data
2192 (while (and (< start l) (string-match regexp string start))
2193 (setq mb (match-beginning 0)
2194 me (match-end 0))
2195 ;; If we matched the empty string, make sure we advance by one char
2196 (when (= me mb) (setq me (min l (1+ mb))))
2197 ;; Generate a replacement for the matched substring.
2198 ;; Operate only on the substring to minimize string consing.
2199 ;; Set up match data for the substring for replacement;
2200 ;; presumably this is likely to be faster than munging the
2201 ;; match data directly in Lisp.
2202 (string-match regexp (setq str (substring string mb me)))
2203 (setq matches
2204 (cons (replace-match (if (stringp rep)
2205 rep
2206 (funcall rep (match-string 0 str)))
2207 fixedcase literal str subexp)
2208 (cons (substring string start mb) ; unmatched prefix
2209 matches)))
2210 (setq start me))
2211 ;; Reconstruct a string from the pieces.
2212 (setq matches (cons (substring string start l) matches)) ; leftover
2213 (apply #'concat (nreverse matches)))))
2214 2366
2215 (defun subregexp-context-p (regexp pos &optional start) 2367 (defun subregexp-context-p (regexp pos &optional start)
2216 "Return non-nil if POS is in a normal subregexp context in REGEXP. 2368 "Return non-nil if POS is in a normal subregexp context in REGEXP.
2217 A subregexp context is one where a sub-regexp can appear. 2369 A subregexp context is one where a sub-regexp can appear.
2218 A non-subregexp context is for example within brackets, or within a 2370 A non-subregexp context is for example within brackets, or within a
2250 ;; "\\|" class "\\|" braces "\\)*\\'")) 2402 ;; "\\|" class "\\|" braces "\\)*\\'"))
2251 ;; "Matches any prefix that corresponds to a normal subregexp context.") 2403 ;; "Matches any prefix that corresponds to a normal subregexp context.")
2252 ;; (string-match re-context-re (substring regexp (or start 0) pos)) 2404 ;; (string-match re-context-re (substring regexp (or start 0) pos))
2253 ) 2405 )
2254 2406
2255 (defun shell-quote-argument (argument) 2407 ;;;; split-string
2256 "Quote an argument for passing as argument to an inferior shell." 2408
2257 (if (eq system-type 'ms-dos) 2409 (defconst split-string-default-separators "[ \f\t\n\r\v]+"
2258 ;; Quote using double quotes, but escape any existing quotes in 2410 "The default value of separators for `split-string'.
2259 ;; the argument with backslashes. 2411
2260 (let ((result "") 2412 A regexp matching strings of whitespace. May be locale-dependent
2261 (start 0) 2413 \(as yet unimplemented). Should not match non-breaking spaces.
2262 end) 2414
2263 (if (or (null (string-match "[^\"]" argument)) 2415 Warning: binding this to a different value and using it as default is
2264 (< (match-end 0) (length argument))) 2416 likely to have undesired semantics.")
2265 (while (string-match "[\"]" argument start) 2417
2266 (setq end (match-beginning 0) 2418 ;; The specification says that if both SEPARATORS and OMIT-NULLS are
2267 result (concat result (substring argument start end) 2419 ;; defaulted, OMIT-NULLS should be treated as t. Simplifying the logical
2268 "\\" (substring argument end (1+ end))) 2420 ;; expression leads to the equivalent implementation that if SEPARATORS
2269 start (1+ end)))) 2421 ;; is defaulted, OMIT-NULLS is treated as t.
2270 (concat "\"" result (substring argument start) "\"")) 2422 (defun split-string (string &optional separators omit-nulls)
2271 (if (eq system-type 'windows-nt) 2423 "Split STRING into substrings bounded by matches for SEPARATORS.
2272 (concat "\"" argument "\"") 2424
2273 (if (equal argument "") 2425 The beginning and end of STRING, and each match for SEPARATORS, are
2274 "''" 2426 splitting points. The substrings matching SEPARATORS are removed, and
2275 ;; Quote everything except POSIX filename characters. 2427 the substrings between the splitting points are collected as a list,
2276 ;; This should be safe enough even for really weird shells. 2428 which is returned.
2277 (let ((result "") (start 0) end) 2429
2278 (while (string-match "[^-0-9a-zA-Z_./]" argument start) 2430 If SEPARATORS is non-nil, it should be a regular expression matching text
2279 (setq end (match-beginning 0) 2431 which separates, but is not part of, the substrings. If nil it defaults to
2280 result (concat result (substring argument start end) 2432 `split-string-default-separators', normally \"[ \\f\\t\\n\\r\\v]+\", and
2281 "\\" (substring argument end (1+ end))) 2433 OMIT-NULLS is forced to t.
2282 start (1+ end))) 2434
2283 (concat result (substring argument start))))))) 2435 If OMIT-NULLS is t, zero-length substrings are omitted from the list \(so
2436 that for the default value of SEPARATORS leading and trailing whitespace
2437 are effectively trimmed). If nil, all zero-length substrings are retained,
2438 which correctly parses CSV format, for example.
2439
2440 Note that the effect of `(split-string STRING)' is the same as
2441 `(split-string STRING split-string-default-separators t)'). In the rare
2442 case that you wish to retain zero-length substrings when splitting on
2443 whitespace, use `(split-string STRING split-string-default-separators)'.
2444
2445 Modifies the match data; use `save-match-data' if necessary."
2446 (let ((keep-nulls (not (if separators omit-nulls t)))
2447 (rexp (or separators split-string-default-separators))
2448 (start 0)
2449 notfirst
2450 (list nil))
2451 (while (and (string-match rexp string
2452 (if (and notfirst
2453 (= start (match-beginning 0))
2454 (< start (length string)))
2455 (1+ start) start))
2456 (< start (length string)))
2457 (setq notfirst t)
2458 (if (or keep-nulls (< start (match-beginning 0)))
2459 (setq list
2460 (cons (substring string start (match-beginning 0))
2461 list)))
2462 (setq start (match-end 0)))
2463 (if (or keep-nulls (< start (length string)))
2464 (setq list
2465 (cons (substring string start)
2466 list)))
2467 (nreverse list)))
2468
2469 ;;;; Replacement in strings.
2470
2471 (defun subst-char-in-string (fromchar tochar string &optional inplace)
2472 "Replace FROMCHAR with TOCHAR in STRING each time it occurs.
2473 Unless optional argument INPLACE is non-nil, return a new string."
2474 (let ((i (length string))
2475 (newstr (if inplace string (copy-sequence string))))
2476 (while (> i 0)
2477 (setq i (1- i))
2478 (if (eq (aref newstr i) fromchar)
2479 (aset newstr i tochar)))
2480 newstr))
2481
2482 (defun replace-regexp-in-string (regexp rep string &optional
2483 fixedcase literal subexp start)
2484 "Replace all matches for REGEXP with REP in STRING.
2485
2486 Return a new string containing the replacements.
2487
2488 Optional arguments FIXEDCASE, LITERAL and SUBEXP are like the
2489 arguments with the same names of function `replace-match'. If START
2490 is non-nil, start replacements at that index in STRING.
2491
2492 REP is either a string used as the NEWTEXT arg of `replace-match' or a
2493 function. If it is a function, it is called with the actual text of each
2494 match, and its value is used as the replacement text. When REP is called,
2495 the match-data are the result of matching REGEXP against a substring
2496 of STRING.
2497
2498 To replace only the first match (if any), make REGEXP match up to \\'
2499 and replace a sub-expression, e.g.
2500 (replace-regexp-in-string \"\\\\(foo\\\\).*\\\\'\" \"bar\" \" foo foo\" nil nil 1)
2501 => \" bar foo\"
2502 "
2503
2504 ;; To avoid excessive consing from multiple matches in long strings,
2505 ;; don't just call `replace-match' continually. Walk down the
2506 ;; string looking for matches of REGEXP and building up a (reversed)
2507 ;; list MATCHES. This comprises segments of STRING which weren't
2508 ;; matched interspersed with replacements for segments that were.
2509 ;; [For a `large' number of replacements it's more efficient to
2510 ;; operate in a temporary buffer; we can't tell from the function's
2511 ;; args whether to choose the buffer-based implementation, though it
2512 ;; might be reasonable to do so for long enough STRING.]
2513 (let ((l (length string))
2514 (start (or start 0))
2515 matches str mb me)
2516 (save-match-data
2517 (while (and (< start l) (string-match regexp string start))
2518 (setq mb (match-beginning 0)
2519 me (match-end 0))
2520 ;; If we matched the empty string, make sure we advance by one char
2521 (when (= me mb) (setq me (min l (1+ mb))))
2522 ;; Generate a replacement for the matched substring.
2523 ;; Operate only on the substring to minimize string consing.
2524 ;; Set up match data for the substring for replacement;
2525 ;; presumably this is likely to be faster than munging the
2526 ;; match data directly in Lisp.
2527 (string-match regexp (setq str (substring string mb me)))
2528 (setq matches
2529 (cons (replace-match (if (stringp rep)
2530 rep
2531 (funcall rep (match-string 0 str)))
2532 fixedcase literal str subexp)
2533 (cons (substring string start mb) ; unmatched prefix
2534 matches)))
2535 (setq start me))
2536 ;; Reconstruct a string from the pieces.
2537 (setq matches (cons (substring string start l) matches)) ; leftover
2538 (apply #'concat (nreverse matches)))))
2539
2540 ;;;; invisibility specs
2541
2542 (defun add-to-invisibility-spec (element)
2543 "Add ELEMENT to `buffer-invisibility-spec'.
2544 See documentation for `buffer-invisibility-spec' for the kind of elements
2545 that can be added."
2546 (if (eq buffer-invisibility-spec t)
2547 (setq buffer-invisibility-spec (list t)))
2548 (setq buffer-invisibility-spec
2549 (cons element buffer-invisibility-spec)))
2550
2551 (defun remove-from-invisibility-spec (element)
2552 "Remove ELEMENT from `buffer-invisibility-spec'."
2553 (if (consp buffer-invisibility-spec)
2554 (setq buffer-invisibility-spec (delete element buffer-invisibility-spec))))
2555
2556 ;;;; Syntax tables.
2557
2558 (defmacro with-syntax-table (table &rest body)
2559 "Evaluate BODY with syntax table of current buffer set to TABLE.
2560 The syntax table of the current buffer is saved, BODY is evaluated, and the
2561 saved table is restored, even in case of an abnormal exit.
2562 Value is what BODY returns."
2563 (declare (debug t))
2564 (let ((old-table (make-symbol "table"))
2565 (old-buffer (make-symbol "buffer")))
2566 `(let ((,old-table (syntax-table))
2567 (,old-buffer (current-buffer)))
2568 (unwind-protect
2569 (progn
2570 (set-syntax-table ,table)
2571 ,@body)
2572 (save-current-buffer
2573 (set-buffer ,old-buffer)
2574 (set-syntax-table ,old-table))))))
2284 2575
2285 (defun make-syntax-table (&optional oldtable) 2576 (defun make-syntax-table (&optional oldtable)
2286 "Return a new syntax table. 2577 "Return a new syntax table.
2287 Create a syntax table which inherits from OLDTABLE (if non-nil) or 2578 Create a syntax table which inherits from OLDTABLE (if non-nil) or
2288 from `standard-syntax-table' otherwise." 2579 from `standard-syntax-table' otherwise."
2301 2592
2302 (defun syntax-class (syntax) 2593 (defun syntax-class (syntax)
2303 "Return the syntax class part of the syntax descriptor SYNTAX. 2594 "Return the syntax class part of the syntax descriptor SYNTAX.
2304 If SYNTAX is nil, return nil." 2595 If SYNTAX is nil, return nil."
2305 (and syntax (logand (car syntax) 65535))) 2596 (and syntax (logand (car syntax) 65535)))
2306 2597
2307 (defun add-to-invisibility-spec (element) 2598 ;;;; Text clones
2308 "Add ELEMENT to `buffer-invisibility-spec'.
2309 See documentation for `buffer-invisibility-spec' for the kind of elements
2310 that can be added."
2311 (if (eq buffer-invisibility-spec t)
2312 (setq buffer-invisibility-spec (list t)))
2313 (setq buffer-invisibility-spec
2314 (cons element buffer-invisibility-spec)))
2315
2316 (defun remove-from-invisibility-spec (element)
2317 "Remove ELEMENT from `buffer-invisibility-spec'."
2318 (if (consp buffer-invisibility-spec)
2319 (setq buffer-invisibility-spec (delete element buffer-invisibility-spec))))
2320
2321 (defun global-set-key (key command)
2322 "Give KEY a global binding as COMMAND.
2323 COMMAND is the command definition to use; usually it is
2324 a symbol naming an interactively-callable function.
2325 KEY is a key sequence; noninteractively, it is a string or vector
2326 of characters or event types, and non-ASCII characters with codes
2327 above 127 (such as ISO Latin-1) can be included if you use a vector.
2328
2329 Note that if KEY has a local binding in the current buffer,
2330 that local binding will continue to shadow any global binding
2331 that you make with this function."
2332 (interactive "KSet key globally: \nCSet key %s to command: ")
2333 (or (vectorp key) (stringp key)
2334 (signal 'wrong-type-argument (list 'arrayp key)))
2335 (define-key (current-global-map) key command))
2336
2337 (defun local-set-key (key command)
2338 "Give KEY a local binding as COMMAND.
2339 COMMAND is the command definition to use; usually it is
2340 a symbol naming an interactively-callable function.
2341 KEY is a key sequence; noninteractively, it is a string or vector
2342 of characters or event types, and non-ASCII characters with codes
2343 above 127 (such as ISO Latin-1) can be included if you use a vector.
2344
2345 The binding goes in the current buffer's local map,
2346 which in most cases is shared with all other buffers in the same major mode."
2347 (interactive "KSet key locally: \nCSet key %s locally to command: ")
2348 (let ((map (current-local-map)))
2349 (or map
2350 (use-local-map (setq map (make-sparse-keymap))))
2351 (or (vectorp key) (stringp key)
2352 (signal 'wrong-type-argument (list 'arrayp key)))
2353 (define-key map key command)))
2354
2355 (defun global-unset-key (key)
2356 "Remove global binding of KEY.
2357 KEY is a string or vector representing a sequence of keystrokes."
2358 (interactive "kUnset key globally: ")
2359 (global-set-key key nil))
2360
2361 (defun local-unset-key (key)
2362 "Remove local binding of KEY.
2363 KEY is a string or vector representing a sequence of keystrokes."
2364 (interactive "kUnset key locally: ")
2365 (if (current-local-map)
2366 (local-set-key key nil))
2367 nil)
2368
2369 ;; We put this here instead of in frame.el so that it's defined even on
2370 ;; systems where frame.el isn't loaded.
2371 (defun frame-configuration-p (object)
2372 "Return non-nil if OBJECT seems to be a frame configuration.
2373 Any list whose car is `frame-configuration' is assumed to be a frame
2374 configuration."
2375 (and (consp object)
2376 (eq (car object) 'frame-configuration)))
2377
2378 (defun functionp (object)
2379 "Non-nil if OBJECT is any kind of function or a special form.
2380 Also non-nil if OBJECT is a symbol and its function definition is
2381 \(recursively) a function or special form. This does not include
2382 macros."
2383 (or (and (symbolp object) (fboundp object)
2384 (condition-case nil
2385 (setq object (indirect-function object))
2386 (error nil))
2387 (eq (car-safe object) 'autoload)
2388 (not (car-safe (cdr-safe (cdr-safe (cdr-safe (cdr-safe object)))))))
2389 (subrp object) (byte-code-function-p object)
2390 (eq (car-safe object) 'lambda)))
2391
2392 (defun assq-delete-all (key alist)
2393 "Delete from ALIST all elements whose car is `eq' to KEY.
2394 Return the modified alist.
2395 Elements of ALIST that are not conses are ignored."
2396 (while (and (consp (car alist))
2397 (eq (car (car alist)) key))
2398 (setq alist (cdr alist)))
2399 (let ((tail alist) tail-cdr)
2400 (while (setq tail-cdr (cdr tail))
2401 (if (and (consp (car tail-cdr))
2402 (eq (car (car tail-cdr)) key))
2403 (setcdr tail (cdr tail-cdr))
2404 (setq tail tail-cdr))))
2405 alist)
2406
2407 (defun rassq-delete-all (value alist)
2408 "Delete from ALIST all elements whose cdr is `eq' to VALUE.
2409 Return the modified alist.
2410 Elements of ALIST that are not conses are ignored."
2411 (while (and (consp (car alist))
2412 (eq (cdr (car alist)) value))
2413 (setq alist (cdr alist)))
2414 (let ((tail alist) tail-cdr)
2415 (while (setq tail-cdr (cdr tail))
2416 (if (and (consp (car tail-cdr))
2417 (eq (cdr (car tail-cdr)) value))
2418 (setcdr tail (cdr tail-cdr))
2419 (setq tail tail-cdr))))
2420 alist)
2421
2422 (defun make-temp-file (prefix &optional dir-flag suffix)
2423 "Create a temporary file.
2424 The returned file name (created by appending some random characters at the end
2425 of PREFIX, and expanding against `temporary-file-directory' if necessary),
2426 is guaranteed to point to a newly created empty file.
2427 You can then use `write-region' to write new data into the file.
2428
2429 If DIR-FLAG is non-nil, create a new empty directory instead of a file.
2430
2431 If SUFFIX is non-nil, add that at the end of the file name."
2432 (let ((umask (default-file-modes))
2433 file)
2434 (unwind-protect
2435 (progn
2436 ;; Create temp files with strict access rights. It's easy to
2437 ;; loosen them later, whereas it's impossible to close the
2438 ;; time-window of loose permissions otherwise.
2439 (set-default-file-modes ?\700)
2440 (while (condition-case ()
2441 (progn
2442 (setq file
2443 (make-temp-name
2444 (expand-file-name prefix temporary-file-directory)))
2445 (if suffix
2446 (setq file (concat file suffix)))
2447 (if dir-flag
2448 (make-directory file)
2449 (write-region "" nil file nil 'silent nil 'excl))
2450 nil)
2451 (file-already-exists t))
2452 ;; the file was somehow created by someone else between
2453 ;; `make-temp-name' and `write-region', let's try again.
2454 nil)
2455 file)
2456 ;; Reset the umask.
2457 (set-default-file-modes umask))))
2458
2459
2460 ;; If a minor mode is not defined with define-minor-mode,
2461 ;; add it here explicitly.
2462 ;; isearch-mode is deliberately excluded, since you should
2463 ;; not call it yourself.
2464 (defvar minor-mode-list '(auto-save-mode auto-fill-mode abbrev-mode
2465 overwrite-mode view-mode
2466 hs-minor-mode)
2467 "List of all minor mode functions.")
2468
2469 (defun add-minor-mode (toggle name &optional keymap after toggle-fun)
2470 "Register a new minor mode.
2471
2472 This is an XEmacs-compatibility function. Use `define-minor-mode' instead.
2473
2474 TOGGLE is a symbol which is the name of a buffer-local variable that
2475 is toggled on or off to say whether the minor mode is active or not.
2476
2477 NAME specifies what will appear in the mode line when the minor mode
2478 is active. NAME should be either a string starting with a space, or a
2479 symbol whose value is such a string.
2480
2481 Optional KEYMAP is the keymap for the minor mode that will be added
2482 to `minor-mode-map-alist'.
2483
2484 Optional AFTER specifies that TOGGLE should be added after AFTER
2485 in `minor-mode-alist'.
2486
2487 Optional TOGGLE-FUN is an interactive function to toggle the mode.
2488 It defaults to (and should by convention be) TOGGLE.
2489
2490 If TOGGLE has a non-nil `:included' property, an entry for the mode is
2491 included in the mode-line minor mode menu.
2492 If TOGGLE has a `:menu-tag', that is used for the menu item's label."
2493 (unless (memq toggle minor-mode-list)
2494 (push toggle minor-mode-list))
2495
2496 (unless toggle-fun (setq toggle-fun toggle))
2497 (unless (eq toggle-fun toggle)
2498 (put toggle :minor-mode-function toggle-fun))
2499 ;; Add the name to the minor-mode-alist.
2500 (when name
2501 (let ((existing (assq toggle minor-mode-alist)))
2502 (if existing
2503 (setcdr existing (list name))
2504 (let ((tail minor-mode-alist) found)
2505 (while (and tail (not found))
2506 (if (eq after (caar tail))
2507 (setq found tail)
2508 (setq tail (cdr tail))))
2509 (if found
2510 (let ((rest (cdr found)))
2511 (setcdr found nil)
2512 (nconc found (list (list toggle name)) rest))
2513 (setq minor-mode-alist (cons (list toggle name)
2514 minor-mode-alist)))))))
2515 ;; Add the toggle to the minor-modes menu if requested.
2516 (when (get toggle :included)
2517 (define-key mode-line-mode-menu
2518 (vector toggle)
2519 (list 'menu-item
2520 (concat
2521 (or (get toggle :menu-tag)
2522 (if (stringp name) name (symbol-name toggle)))
2523 (let ((mode-name (if (symbolp name) (symbol-value name))))
2524 (if (and (stringp mode-name) (string-match "[^ ]+" mode-name))
2525 (concat " (" (match-string 0 mode-name) ")"))))
2526 toggle-fun
2527 :button (cons :toggle toggle))))
2528
2529 ;; Add the map to the minor-mode-map-alist.
2530 (when keymap
2531 (let ((existing (assq toggle minor-mode-map-alist)))
2532 (if existing
2533 (setcdr existing keymap)
2534 (let ((tail minor-mode-map-alist) found)
2535 (while (and tail (not found))
2536 (if (eq after (caar tail))
2537 (setq found tail)
2538 (setq tail (cdr tail))))
2539 (if found
2540 (let ((rest (cdr found)))
2541 (setcdr found nil)
2542 (nconc found (list (cons toggle keymap)) rest))
2543 (setq minor-mode-map-alist (cons (cons toggle keymap)
2544 minor-mode-map-alist))))))))
2545
2546 ;; Clones ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2547 2599
2548 (defun text-clone-maintain (ol1 after beg end &optional len) 2600 (defun text-clone-maintain (ol1 after beg end &optional len)
2549 "Propagate the changes made under the overlay OL1 to the other clones. 2601 "Propagate the changes made under the overlay OL1 to the other clones.
2550 This is used on the `modification-hooks' property of text clones." 2602 This is used on the `modification-hooks' property of text clones."
2551 (when (and after (not undo-in-progress) (overlay-start ol1)) 2603 (when (and after (not undo-in-progress) (overlay-start ol1))
2635 (when spreadp (overlay-put ol2 'text-clone-spreadp t)) 2687 (when spreadp (overlay-put ol2 'text-clone-spreadp t))
2636 (when syntax (overlay-put ol2 'text-clone-syntax syntax)) 2688 (when syntax (overlay-put ol2 'text-clone-syntax syntax))
2637 ;;(overlay-put ol2 'face 'underline) 2689 ;;(overlay-put ol2 'face 'underline)
2638 (overlay-put ol2 'evaporate t) 2690 (overlay-put ol2 'evaporate t)
2639 (overlay-put ol2 'text-clones dups))) 2691 (overlay-put ol2 'text-clones dups)))
2640 2692
2641 (defun play-sound (sound) 2693 ;;;; Mail user agents.
2642 "SOUND is a list of the form `(sound KEYWORD VALUE...)'. 2694
2643 The following keywords are recognized: 2695 ;; Here we include just enough for other packages to be able
2644 2696 ;; to define them.
2645 :file FILE - read sound data from FILE. If FILE isn't an
2646 absolute file name, it is searched in `data-directory'.
2647
2648 :data DATA - read sound data from string DATA.
2649
2650 Exactly one of :file or :data must be present.
2651
2652 :volume VOL - set volume to VOL. VOL must an integer in the
2653 range 0..100 or a float in the range 0..1.0. If not specified,
2654 don't change the volume setting of the sound device.
2655
2656 :device DEVICE - play sound on DEVICE. If not specified,
2657 a system-dependent default device name is used."
2658 (if (fboundp 'play-sound-internal)
2659 (play-sound-internal sound)
2660 (error "This Emacs binary lacks sound support")))
2661 2697
2662 (defun define-mail-user-agent (symbol composefunc sendfunc 2698 (defun define-mail-user-agent (symbol composefunc sendfunc
2663 &optional abortfunc hookvar) 2699 &optional abortfunc hookvar)
2664 "Define a symbol to identify a mail-sending package for `mail-user-agent'. 2700 "Define a symbol to identify a mail-sending package for `mail-user-agent'.
2665 2701
2691 `abortfunc', and `hookvar'." 2727 `abortfunc', and `hookvar'."
2692 (put symbol 'composefunc composefunc) 2728 (put symbol 'composefunc composefunc)
2693 (put symbol 'sendfunc sendfunc) 2729 (put symbol 'sendfunc sendfunc)
2694 (put symbol 'abortfunc (or abortfunc 'kill-buffer)) 2730 (put symbol 'abortfunc (or abortfunc 'kill-buffer))
2695 (put symbol 'hookvar (or hookvar 'mail-send-hook))) 2731 (put symbol 'hookvar (or hookvar 'mail-send-hook)))
2696 2732
2697 ;; Standardized progress reporting 2733 ;;;; Progress reporters.
2698 2734
2699 ;; Progress reporter has the following structure: 2735 ;; Progress reporter has the following structure:
2700 ;; 2736 ;;
2701 ;; (NEXT-UPDATE-VALUE . [NEXT-UPDATE-TIME 2737 ;; (NEXT-UPDATE-VALUE . [NEXT-UPDATE-TIME
2702 ;; MIN-VALUE 2738 ;; MIN-VALUE
2849 (setq ,(car spec) (1+ ,(car spec))))) 2885 (setq ,(car spec) (1+ ,(car spec)))))
2850 (progress-reporter-done ,temp2) 2886 (progress-reporter-done ,temp2)
2851 nil ,@(cdr (cdr spec))))) 2887 nil ,@(cdr (cdr spec)))))
2852 2888
2853 2889
2854 ;;;; Compare Version Strings 2890 ;;;; Comparing version strings.
2855 2891
2856 (defvar version-separator "." 2892 (defvar version-separator "."
2857 "*Specify the string used to separate the version elements. 2893 "*Specify the string used to separate the version elements.
2858 2894
2859 Usually the separator is \".\", but it can be any other string.") 2895 Usually the separator is \".\", but it can be any other string.")