Mercurial > hg > xemacs-beta
comparison lisp/subr.el @ 412:697ef44129c6 r21-2-14
Import from CVS: tag r21-2-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:20:41 +0200 |
parents | b8cc9ab3f761 |
children | da8ed4261e83 |
comparison
equal
deleted
inserted
replaced
411:12e008d41344 | 412:697ef44129c6 |
---|---|
1 ;;; subr.el --- basic lisp subroutines for XEmacs | 1 ;;; subr.el --- basic lisp subroutines for XEmacs |
2 | 2 |
3 ;; Copyright (C) 1985, 1986, 1992, 1994-5, 1997 Free Software Foundation, Inc. | 3 ;; Copyright (C) 1985, 1986, 1992, 1994-5, 1997 Free Software Foundation, Inc. |
4 ;; Copyright (C) 1995 Tinker Systems and INS Engineering Corp. | 4 ;; Copyright (C) 1995 Tinker Systems and INS Engineering Corp. |
5 ;; Copyright (C) 1995 Sun Microsystems. | 5 ;; Copyright (C) 1995 Sun Microsystems. |
6 ;; Copyright (C) 2000 Ben Wing. | |
7 | 6 |
8 ;; Maintainer: XEmacs Development Team | 7 ;; Maintainer: XEmacs Development Team |
9 ;; Keywords: extensions, dumped | 8 ;; Keywords: extensions, dumped |
10 | 9 |
11 ;; This file is part of XEmacs. | 10 ;; This file is part of XEmacs. |
116 one. | 115 one. |
117 | 116 |
118 This function does nothing if HOOK is already local in the current | 117 This function does nothing if HOOK is already local in the current |
119 buffer. | 118 buffer. |
120 | 119 |
121 Do not use `make-local-variable' to make a hook variable buffer-local. | 120 Do not use `make-local-variable' to make a hook variable buffer-local." |
122 | |
123 See also `add-local-hook' and `remove-local-hook'." | |
124 (if (local-variable-p hook (current-buffer)) ; XEmacs | 121 (if (local-variable-p hook (current-buffer)) ; XEmacs |
125 nil | 122 nil |
126 (or (boundp hook) (set hook nil)) | 123 (or (boundp hook) (set hook nil)) |
127 (make-local-variable hook) | 124 (make-local-variable hook) |
128 (set hook (list t)))) | 125 (set hook (list t)))) |
140 To make a hook variable buffer-local, always use | 137 To make a hook variable buffer-local, always use |
141 `make-local-hook', not `make-local-variable'. | 138 `make-local-hook', not `make-local-variable'. |
142 | 139 |
143 HOOK should be a symbol, and FUNCTION may be any valid function. If | 140 HOOK should be a symbol, and FUNCTION may be any valid function. If |
144 HOOK is void, it is first set to nil. If HOOK's value is a single | 141 HOOK is void, it is first set to nil. If HOOK's value is a single |
145 function, it is changed to a list of functions. | 142 function, it is changed to a list of functions." |
146 | |
147 You can remove this hook yourself using `remove-hook'. | |
148 | |
149 See also `add-local-hook' and `add-one-shot-hook'." | |
150 (or (boundp hook) (set hook nil)) | 143 (or (boundp hook) (set hook nil)) |
151 (or (default-boundp hook) (set-default hook nil)) | 144 (or (default-boundp hook) (set-default hook nil)) |
152 ;; If the hook value is a single function, turn it into a list. | 145 ;; If the hook value is a single function, turn it into a list. |
153 (let ((old (symbol-value hook))) | 146 (let ((old (symbol-value hook))) |
154 (if (or (not (listp old)) (eq (car old) 'lambda)) | 147 (if (or (not (listp old)) (eq (car old) 'lambda)) |
190 (if (or (not (boundp hook)) ;unbound symbol, or | 183 (if (or (not (boundp hook)) ;unbound symbol, or |
191 (not (default-boundp 'hook)) | 184 (not (default-boundp 'hook)) |
192 (null (symbol-value hook)) ;value is nil, or | 185 (null (symbol-value hook)) ;value is nil, or |
193 (null function)) ;function is nil, then | 186 (null function)) ;function is nil, then |
194 nil ;Do nothing. | 187 nil ;Do nothing. |
195 (flet ((hook-remove | 188 (if (or local |
196 (function hook-value) | 189 ;; Detect the case where make-local-variable was used on a hook |
197 (flet ((hook-test | 190 ;; and do what we used to do. |
198 (fn hel) | 191 (and (local-variable-p hook (current-buffer)) |
199 (or (equal fn hel) | 192 (not (memq t (symbol-value hook))))) |
200 (and (symbolp hel) | 193 (let ((hook-value (symbol-value hook))) |
201 (equal fn | 194 (if (and (consp hook-value) (not (functionp hook-value))) |
202 (get hel 'one-shot-hook-fun)))))) | 195 (if (member function hook-value) |
203 (if (and (consp hook-value) | 196 (setq hook-value (delete function (copy-sequence hook-value)))) |
204 (not (functionp hook-value))) | 197 (if (equal hook-value function) |
205 (if (member* function hook-value :test 'hook-test) | 198 (setq hook-value nil))) |
206 (setq hook-value | 199 (set hook hook-value)) |
207 (delete* function (copy-sequence hook-value) | 200 (let ((hook-value (default-value hook))) |
208 :test 'hook-test))) | 201 (if (and (consp hook-value) (not (functionp hook-value))) |
209 (if (equal hook-value function) | 202 (if (member function hook-value) |
210 (setq hook-value nil))) | 203 (setq hook-value (delete function (copy-sequence hook-value)))) |
211 hook-value))) | 204 (if (equal hook-value function) |
212 (if (or local | 205 (setq hook-value nil))) |
213 ;; Detect the case where make-local-variable was used on a hook | 206 (set-default hook hook-value))))) |
214 ;; and do what we used to do. | |
215 (and (local-variable-p hook (current-buffer)) | |
216 (not (memq t (symbol-value hook))))) | |
217 (set hook (hook-remove function (symbol-value hook))) | |
218 (set-default hook (hook-remove function (default-value hook))))))) | |
219 | |
220 ;; XEmacs addition | |
221 ;; #### we need a coherent scheme for indicating compatibility info, | |
222 ;; so that it can be programmatically retrieved. | |
223 (defun add-local-hook (hook function &optional append) | |
224 "Add to the local value of HOOK the function FUNCTION. | |
225 This modifies only the buffer-local value for the hook (which is | |
226 automatically make buffer-local, if necessary), not its default value. | |
227 FUNCTION is not added if already present. | |
228 FUNCTION is added (if necessary) at the beginning of the hook list | |
229 unless the optional argument APPEND is non-nil, in which case | |
230 FUNCTION is added at the end. | |
231 | |
232 HOOK should be a symbol, and FUNCTION may be any valid function. If | |
233 HOOK is void, it is first set to nil. If HOOK's value is a single | |
234 function, it is changed to a list of functions. | |
235 | |
236 You can remove this hook yourself using `remove-local-hook'. | |
237 | |
238 See also `add-hook' and `make-local-hook'." | |
239 (make-local-hook hook) | |
240 (add-hook hook function append t)) | |
241 | |
242 ;; XEmacs addition | |
243 (defun remove-local-hook (hook function) | |
244 "Remove from the local value of HOOK the function FUNCTION. | |
245 This modifies only the buffer-local value for the hook, not its default | |
246 value. (Nothing happens if the hook is not buffer-local.) | |
247 HOOK should be a symbol, and FUNCTION may be any valid function. If | |
248 FUNCTION isn't the value of HOOK, or, if FUNCTION doesn't appear in the | |
249 list of hooks to run in HOOK, then nothing is done. See `add-hook'. | |
250 | |
251 See also `add-local-hook' and `make-local-hook'." | |
252 (if (local-variable-p hook (current-buffer)) | |
253 (remove-hook hook function t))) | |
254 | |
255 (defun add-one-shot-hook (hook function &optional append local) | |
256 "Add to the value of HOOK the one-shot function FUNCTION. | |
257 FUNCTION will automatically be removed from the hook the first time | |
258 after it runs (whether to completion or to an error). | |
259 FUNCTION is not added if already present. | |
260 FUNCTION is added (if necessary) at the beginning of the hook list | |
261 unless the optional argument APPEND is non-nil, in which case | |
262 FUNCTION is added at the end. | |
263 | |
264 HOOK should be a symbol, and FUNCTION may be any valid function. If | |
265 HOOK is void, it is first set to nil. If HOOK's value is a single | |
266 function, it is changed to a list of functions. | |
267 | |
268 You can remove this hook yourself using `remove-hook'. | |
269 | |
270 See also `add-hook', `add-local-hook', and `add-local-one-shot-hook'." | |
271 (let ((sym (gensym))) | |
272 (fset sym `(lambda (&rest args) | |
273 (unwind-protect | |
274 (apply ',function args) | |
275 (remove-hook ',hook ',sym ',local)))) | |
276 (put sym 'one-shot-hook-fun function) | |
277 (add-hook hook sym append local))) | |
278 | |
279 (defun add-local-one-shot-hook (hook function &optional append) | |
280 "Add to the local value of HOOK the one-shot function FUNCTION. | |
281 FUNCTION will automatically be removed from the hook the first time | |
282 after it runs (whether to completion or to an error). | |
283 FUNCTION is not added if already present. | |
284 FUNCTION is added (if necessary) at the beginning of the hook list | |
285 unless the optional argument APPEND is non-nil, in which case | |
286 FUNCTION is added at the end. | |
287 | |
288 The optional fourth argument, LOCAL, if non-nil, says to modify | |
289 the hook's buffer-local value rather than its default value. | |
290 This makes no difference if the hook is not buffer-local. | |
291 To make a hook variable buffer-local, always use | |
292 `make-local-hook', not `make-local-variable'. | |
293 | |
294 HOOK should be a symbol, and FUNCTION may be any valid function. If | |
295 HOOK is void, it is first set to nil. If HOOK's value is a single | |
296 function, it is changed to a list of functions. | |
297 | |
298 You can remove this hook yourself using `remove-local-hook'. | |
299 | |
300 See also `add-hook', `add-local-hook', and `add-local-one-shot-hook'." | |
301 (make-local-hook hook) | |
302 (add-one-shot-hook hook function append t)) | |
303 | 207 |
304 (defun add-to-list (list-var element) | 208 (defun add-to-list (list-var element) |
305 "Add to the value of LIST-VAR the element ELEMENT if it isn't there yet. | 209 "Add to the value of LIST-VAR the element ELEMENT if it isn't there yet. |
306 The test for presence of ELEMENT is done with `equal'. | 210 The test for presence of ELEMENT is done with `equal'. |
307 If you want to use `add-to-list' on a variable that is not defined | 211 If you want to use `add-to-list' on a variable that is not defined |
332 ;; (setcar conscell newcar) | 236 ;; (setcar conscell newcar) |
333 ;; conscell) | 237 ;; conscell) |
334 ;; ...and analogously for RPLACD. | 238 ;; ...and analogously for RPLACD. |
335 (define-function 'rplaca 'setcar) | 239 (define-function 'rplaca 'setcar) |
336 (define-function 'rplacd 'setcdr) | 240 (define-function 'rplacd 'setcdr) |
337 | |
338 (defun copy-symbol (symbol &optional copy-properties) | |
339 "Return a new uninterned symbol with the same name as SYMBOL. | |
340 If COPY-PROPERTIES is non-nil, the new symbol will have a copy of | |
341 SYMBOL's value, function, and property lists." | |
342 (let ((new (make-symbol (symbol-name symbol)))) | |
343 (when copy-properties | |
344 ;; This will not copy SYMBOL's chain of forwarding objects, but | |
345 ;; I think that's OK. Callers should not expect such magic to | |
346 ;; keep working in the copy in the first place. | |
347 (and (boundp symbol) | |
348 (set new (symbol-value symbol))) | |
349 (and (fboundp symbol) | |
350 (fset new (symbol-function symbol))) | |
351 (setplist new (copy-list (symbol-plist symbol)))) | |
352 new)) | |
353 | 241 |
354 ;;;; String functions. | 242 ;;;; String functions. |
355 | 243 |
356 ;; XEmacs | 244 ;; XEmacs |
357 (defun replace-in-string (str regexp newtext &optional literal) | 245 (defun replace-in-string (str regexp newtext &optional literal) |
404 (defun split-string (string &optional pattern) | 292 (defun split-string (string &optional pattern) |
405 "Return a list of substrings of STRING which are separated by PATTERN. | 293 "Return a list of substrings of STRING which are separated by PATTERN. |
406 If PATTERN is omitted, it defaults to \"[ \\f\\t\\n\\r\\v]+\"." | 294 If PATTERN is omitted, it defaults to \"[ \\f\\t\\n\\r\\v]+\"." |
407 (or pattern | 295 (or pattern |
408 (setq pattern "[ \f\t\n\r\v]+")) | 296 (setq pattern "[ \f\t\n\r\v]+")) |
409 (let (parts (start 0) (len (length string))) | 297 ;; The FSF version of this function takes care not to cons in case |
410 (if (string-match pattern string) | 298 ;; of infloop. Maybe we should synch? |
411 (setq parts (cons (substring string 0 (match-beginning 0)) parts) | 299 (let (parts (start 0)) |
412 start (match-end 0))) | 300 (while (string-match pattern string start) |
413 (while (and (< start len) | |
414 (string-match pattern string (if (> start (match-beginning 0)) | |
415 start | |
416 (1+ start)))) | |
417 (setq parts (cons (substring string start (match-beginning 0)) parts) | 301 (setq parts (cons (substring string start (match-beginning 0)) parts) |
418 start (match-end 0))) | 302 start (match-end 0))) |
419 (nreverse (cons (substring string start) parts)))) | 303 (nreverse (cons (substring string start) parts)))) |
420 | 304 |
421 ;; #### #### #### AAaargh! Must be in C, because it is used insanely | 305 ;; #### #### #### AAaargh! Must be in C, because it is used insanely |
433 | 317 |
434 (defmacro with-output-to-string (&rest forms) | 318 (defmacro with-output-to-string (&rest forms) |
435 "Collect output to `standard-output' while evaluating FORMS and return | 319 "Collect output to `standard-output' while evaluating FORMS and return |
436 it as a string." | 320 it as a string." |
437 ;; by "William G. Dubuque" <wgd@zurich.ai.mit.edu> w/ mods from Stig | 321 ;; by "William G. Dubuque" <wgd@zurich.ai.mit.edu> w/ mods from Stig |
438 `(with-current-buffer (get-buffer-create | 322 `(with-current-buffer (get-buffer-create " *string-output*") |
439 (generate-new-buffer-name " *string-output*")) | |
440 (setq buffer-read-only nil) | 323 (setq buffer-read-only nil) |
441 (buffer-disable-undo (current-buffer)) | 324 (buffer-disable-undo (current-buffer)) |
442 (erase-buffer) | 325 (erase-buffer) |
443 (let ((standard-output (current-buffer))) | 326 (let ((standard-output (current-buffer))) |
444 ,@forms) | 327 ,@forms) |
445 (prog1 | 328 (prog1 |
446 (buffer-string) | 329 (buffer-string) |
447 (erase-buffer)))) | 330 (erase-buffer)))) |
448 | 331 |
449 (defmacro with-current-buffer (buffer &rest body) | 332 (defmacro with-current-buffer (buffer &rest body) |
450 "Temporarily make BUFFER the current buffer and execute the forms in BODY. | 333 "Execute the forms in BODY with BUFFER as the current buffer. |
451 The value returned is the value of the last form in BODY. | 334 The value returned is the value of the last form in BODY. |
452 See also `with-temp-buffer'." | 335 See also `with-temp-buffer'." |
453 `(save-current-buffer | 336 `(save-current-buffer |
454 (set-buffer ,buffer) | 337 (set-buffer ,buffer) |
455 ,@body)) | 338 ,@body)) |
488 ;; Moved from mule-coding.el. | 371 ;; Moved from mule-coding.el. |
489 (defmacro with-string-as-buffer-contents (str &rest body) | 372 (defmacro with-string-as-buffer-contents (str &rest body) |
490 "With the contents of the current buffer being STR, run BODY. | 373 "With the contents of the current buffer being STR, run BODY. |
491 Returns the new contents of the buffer, as modified by BODY. | 374 Returns the new contents of the buffer, as modified by BODY. |
492 The original current buffer is restored afterwards." | 375 The original current buffer is restored afterwards." |
493 `(with-temp-buffer | 376 `(let ((tempbuf (get-buffer-create " *string-as-buffer-contents*"))) |
494 (insert ,str) | 377 (with-current-buffer tempbuf |
495 ,@body | 378 (unwind-protect |
496 (buffer-string))) | 379 (progn |
380 (buffer-disable-undo (current-buffer)) | |
381 (erase-buffer) | |
382 (insert ,str) | |
383 ,@body | |
384 (buffer-string)) | |
385 (erase-buffer tempbuf))))) | |
497 | 386 |
498 (defun insert-face (string face) | 387 (defun insert-face (string face) |
499 "Insert STRING and highlight with FACE. Return the extent created." | 388 "Insert STRING and highlight with FACE. Return the extent created." |
500 (let ((p (point)) ext) | 389 (let ((p (point)) ext) |
501 (insert string) | 390 (insert string) |
673 (defun ignore (&rest ignore) | 562 (defun ignore (&rest ignore) |
674 "Do nothing and return nil. | 563 "Do nothing and return nil. |
675 This function accepts any number of arguments, but ignores them." | 564 This function accepts any number of arguments, but ignores them." |
676 (interactive) | 565 (interactive) |
677 nil) | 566 nil) |
567 | |
568 (define-function 'mapc-internal 'mapc) | |
569 (make-obsolete 'mapc-internal 'mapc) | |
678 | 570 |
679 (define-function 'eval-in-buffer 'with-current-buffer) | 571 (define-function 'eval-in-buffer 'with-current-buffer) |
680 (make-obsolete 'eval-in-buffer 'with-current-buffer) | 572 (make-obsolete 'eval-in-buffer 'with-current-buffer) |
681 | 573 |
682 ;;; The real defn is in abbrev.el but some early callers | 574 ;;; The real defn is in abbrev.el but some early callers |
720 (and (eq (car-safe spec) 'interactive) | 612 (and (eq (car-safe spec) 'interactive) |
721 spec))) | 613 spec))) |
722 (t | 614 (t |
723 (error "Non-funcallable object: %s" function)))) | 615 (error "Non-funcallable object: %s" function)))) |
724 | 616 |
725 (defun function-allows-args (function n) | |
726 "Return whether FUNCTION can be called with N arguments." | |
727 (and (<= (function-min-args function) n) | |
728 (or (null (function-max-args function)) | |
729 (<= n (function-max-args function))))) | |
730 | |
731 ;; This function used to be an alias to `buffer-substring', except | 617 ;; This function used to be an alias to `buffer-substring', except |
732 ;; that FSF Emacs 20.4 added a BUFFER argument in an incompatible way. | 618 ;; that FSF Emacs 20.4 added a BUFFER argument in an incompatible way. |
733 ;; The new FSF's semantics makes more sense, but we try to support | 619 ;; The new FSF's semantics makes more sense, but we try to support |
734 ;; both for backward compatibility. | 620 ;; both for backward compatibility. |
735 (defun buffer-string (&optional buffer old-end old-buffer) | 621 (defun buffer-string (&optional buffer old-end old-buffer) |
740 If BUFFER is specified, the contents of that buffer are returned. | 626 If BUFFER is specified, the contents of that buffer are returned. |
741 | 627 |
742 The arguments OLD-END and OLD-BUFFER are supported for backward | 628 The arguments OLD-END and OLD-BUFFER are supported for backward |
743 compatibility with pre-21.2 XEmacsen times when arguments to this | 629 compatibility with pre-21.2 XEmacsen times when arguments to this |
744 function were (buffer-string &optional START END BUFFER)." | 630 function were (buffer-string &optional START END BUFFER)." |
745 (cond | 631 (if (or (null buffer) |
746 ((or (stringp buffer) (bufferp buffer)) | 632 (bufferp buffer) |
747 ;; Most definitely the new way. | 633 (stringp buffer)) |
748 (buffer-substring nil nil buffer)) | 634 ;; The new way |
749 ((or (stringp old-buffer) (bufferp old-buffer) | 635 (buffer-substring nil nil buffer) |
750 (natnump buffer) (natnump old-end)) | 636 ;; The old way |
751 ;; Definitely the old way. | 637 (buffer-substring buffer old-end old-buffer))) |
752 (buffer-substring buffer old-end old-buffer)) | |
753 (t | |
754 ;; Probably the old way. | |
755 (buffer-substring buffer old-end old-buffer)))) | |
756 | 638 |
757 ;; This was not present before. I think Jamie had some objections | 639 ;; This was not present before. I think Jamie had some objections |
758 ;; to this, so I'm leaving this undefined for now. --ben | 640 ;; to this, so I'm leaving this undefined for now. --ben |
759 | 641 |
760 ;;; The objection is this: there is more than one way to load the same file. | 642 ;;; The objection is this: there is more than one way to load the same file. |