Mercurial > emacs
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.") |