Mercurial > hg > xemacs-beta
comparison lisp/subr.el @ 209:41ff10fd062f r20-4b3
Import from CVS: tag r20-4b3
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:04:58 +0200 |
parents | |
children | c5d627a313b1 |
comparison
equal
deleted
inserted
replaced
208:f427b8ec4379 | 209:41ff10fd062f |
---|---|
1 ;;; subr.el --- basic lisp subroutines for XEmacs | |
2 | |
3 ;; Copyright (C) 1985, 1986, 1992, 1994-5, 1997 Free Software Foundation, Inc. | |
4 ;; Copyright (C) 1995 Tinker Systems and INS Engineering Corp. | |
5 ;; Copyright (C) 1995 Sun Microsystems. | |
6 | |
7 ;; Maintainer: XEmacs Development Team | |
8 ;; Keywords: extensions, dumped | |
9 | |
10 ;; This file is part of XEmacs. | |
11 | |
12 ;; XEmacs is free software; you can redistribute it and/or modify it | |
13 ;; under the terms of the GNU General Public License as published by | |
14 ;; the Free Software Foundation; either version 2, or (at your option) | |
15 ;; any later version. | |
16 | |
17 ;; XEmacs is distributed in the hope that it will be useful, but | |
18 ;; WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
20 ;; General Public License for more details. | |
21 | |
22 ;; You should have received a copy of the GNU General Public License | |
23 ;; along with XEmacs; see the file COPYING. If not, write to the Free | |
24 ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | |
25 ;; 02111-1307, USA. | |
26 | |
27 ;;; Synched up with: FSF 19.34. | |
28 | |
29 ;;; Commentary: | |
30 | |
31 ;; This file is dumped with XEmacs. | |
32 | |
33 ;; There's not a whole lot in common now with the FSF version, | |
34 ;; be wary when applying differences. I've left in a number of lines | |
35 ;; of commentary just to give diff(1) something to synch itself with to | |
36 ;; provide useful context diffs. -sb | |
37 | |
38 ;;; Code: | |
39 | |
40 | |
41 ;;;; Lisp language features. | |
42 | |
43 (defmacro lambda (&rest cdr) | |
44 "Return a lambda expression. | |
45 A call of the form (lambda ARGS DOCSTRING INTERACTIVE BODY) is | |
46 self-quoting; the result of evaluating the lambda expression is the | |
47 expression itself. The lambda expression may then be treated as a | |
48 function, i.e., stored as the function value of a symbol, passed to | |
49 funcall or mapcar, etc. | |
50 | |
51 ARGS should take the same form as an argument list for a `defun'. | |
52 DOCSTRING is an optional documentation string. | |
53 If present, it should describe how to call the function. | |
54 But documentation strings are usually not useful in nameless functions. | |
55 INTERACTIVE should be a call to the function `interactive', which see. | |
56 It may also be omitted. | |
57 BODY should be a list of lisp expressions." | |
58 `(function (lambda ,@cdr))) | |
59 | |
60 (defmacro defun-when-void (&rest args) | |
61 "Define a function, just like `defun', unless it's already defined. | |
62 Used for compatibility among different emacs variants." | |
63 `(if (fboundp ',(car args)) | |
64 nil | |
65 (defun ,@args))) | |
66 | |
67 (defmacro define-function-when-void (&rest args) | |
68 "Define a function, just like `define-function', unless it's already defined. | |
69 Used for compatibility among different emacs variants." | |
70 `(if (fboundp ,(car args)) | |
71 nil | |
72 (define-function ,@args))) | |
73 | |
74 | |
75 ;;;; Keymap support. | |
76 ;; XEmacs: removed to keymap.el | |
77 | |
78 ;;;; The global keymap tree. | |
79 | |
80 ;;; global-map, esc-map, and ctl-x-map have their values set up in | |
81 ;;; keymap.c; we just give them docstrings here. | |
82 | |
83 ;;;; Event manipulation functions. | |
84 | |
85 ;; The call to `read' is to ensure that the value is computed at load time | |
86 ;; and not compiled into the .elc file. The value is negative on most | |
87 ;; machines, but not on all! | |
88 (defconst listify-key-sequence-1 (logior 128 (read "?\\M-\\^@"))) | |
89 | |
90 (defun listify-key-sequence (key) | |
91 "Convert a key sequence to a list of events." | |
92 (if (vectorp key) | |
93 (append key nil) | |
94 (mapcar (function (lambda (c) | |
95 (if (> c 127) | |
96 (logxor c listify-key-sequence-1) | |
97 c))) | |
98 (append key nil)))) | |
99 ;; XEmacs: This stuff is done in C Code. | |
100 | |
101 ;;;; Obsolescent names for functions. | |
102 ;; XEmacs: not used. | |
103 | |
104 ;; XEmacs: | |
105 (define-function 'not 'null) | |
106 (define-function-when-void 'numberp 'integerp) ; different when floats | |
107 | |
108 (defun local-variable-if-set-p (sym buffer) | |
109 "Return t if SYM would be local to BUFFER after it is set. | |
110 A nil value for BUFFER is *not* the same as (current-buffer), but | |
111 can be used to determine whether `make-variable-buffer-local' has been | |
112 called on SYM." | |
113 (local-variable-p sym buffer t)) | |
114 | |
115 | |
116 ;;;; Hook manipulation functions. | |
117 | |
118 ;; (defconst run-hooks 'run-hooks ...) | |
119 | |
120 (defun make-local-hook (hook) | |
121 "Make the hook HOOK local to the current buffer. | |
122 When a hook is local, its local and global values | |
123 work in concert: running the hook actually runs all the hook | |
124 functions listed in *either* the local value *or* the global value | |
125 of the hook variable. | |
126 | |
127 This function works by making `t' a member of the buffer-local value, | |
128 which acts as a flag to run the hook functions in the default value as | |
129 well. This works for all normal hooks, but does not work for most | |
130 non-normal hooks yet. We will be changing the callers of non-normal | |
131 hooks so that they can handle localness; this has to be done one by | |
132 one. | |
133 | |
134 This function does nothing if HOOK is already local in the current | |
135 buffer. | |
136 | |
137 Do not use `make-local-variable' to make a hook variable buffer-local." | |
138 (if (local-variable-p hook (current-buffer)) ; XEmacs | |
139 nil | |
140 (or (boundp hook) (set hook nil)) | |
141 (make-local-variable hook) | |
142 (set hook (list t)))) | |
143 | |
144 (defun add-hook (hook function &optional append local) | |
145 "Add to the value of HOOK the function FUNCTION. | |
146 FUNCTION is not added if already present. | |
147 FUNCTION is added (if necessary) at the beginning of the hook list | |
148 unless the optional argument APPEND is non-nil, in which case | |
149 FUNCTION is added at the end. | |
150 | |
151 The optional fourth argument, LOCAL, if non-nil, says to modify | |
152 the hook's buffer-local value rather than its default value. | |
153 This makes no difference if the hook is not buffer-local. | |
154 To make a hook variable buffer-local, always use | |
155 `make-local-hook', not `make-local-variable'. | |
156 | |
157 HOOK should be a symbol, and FUNCTION may be any valid function. If | |
158 HOOK is void, it is first set to nil. If HOOK's value is a single | |
159 function, it is changed to a list of functions." | |
160 (or (boundp hook) (set hook nil)) | |
161 (or (default-boundp hook) (set-default hook nil)) | |
162 ;; If the hook value is a single function, turn it into a list. | |
163 (let ((old (symbol-value hook))) | |
164 (if (or (not (listp old)) (eq (car old) 'lambda)) | |
165 (set hook (list old)))) | |
166 (if (or local | |
167 ;; Detect the case where make-local-variable was used on a hook | |
168 ;; and do what we used to do. | |
169 (and (local-variable-if-set-p hook (current-buffer)) ; XEmacs | |
170 (not (memq t (symbol-value hook))))) | |
171 ;; Alter the local value only. | |
172 (or (if (consp function) | |
173 (member function (symbol-value hook)) | |
174 (memq function (symbol-value hook))) | |
175 (set hook | |
176 (if append | |
177 (append (symbol-value hook) (list function)) | |
178 (cons function (symbol-value hook))))) | |
179 ;; Alter the global value (which is also the only value, | |
180 ;; if the hook doesn't have a local value). | |
181 (or (if (consp function) | |
182 (member function (default-value hook)) | |
183 (memq function (default-value hook))) | |
184 (set-default hook | |
185 (if append | |
186 (append (default-value hook) (list function)) | |
187 (cons function (default-value hook))))))) | |
188 | |
189 (defun remove-hook (hook function &optional local) | |
190 "Remove from the value of HOOK the function FUNCTION. | |
191 HOOK should be a symbol, and FUNCTION may be any valid function. If | |
192 FUNCTION isn't the value of HOOK, or, if FUNCTION doesn't appear in the | |
193 list of hooks to run in HOOK, then nothing is done. See `add-hook'. | |
194 | |
195 The optional third argument, LOCAL, if non-nil, says to modify | |
196 the hook's buffer-local value rather than its default value. | |
197 This makes no difference if the hook is not buffer-local. | |
198 To make a hook variable buffer-local, always use | |
199 `make-local-hook', not `make-local-variable'." | |
200 (if (or (not (boundp hook)) ;unbound symbol, or | |
201 (not (default-boundp 'hook)) | |
202 (null (symbol-value hook)) ;value is nil, or | |
203 (null function)) ;function is nil, then | |
204 nil ;Do nothing. | |
205 (if (or local | |
206 ;; Detect the case where make-local-variable was used on a hook | |
207 ;; and do what we used to do. | |
208 (and (local-variable-p hook (current-buffer)) | |
209 (not (memq t (symbol-value hook))))) | |
210 (let ((hook-value (symbol-value hook))) | |
211 (if (consp hook-value) | |
212 (if (member function hook-value) | |
213 (setq hook-value (delete function (copy-sequence hook-value)))) | |
214 (if (equal hook-value function) | |
215 (setq hook-value nil))) | |
216 (set hook hook-value)) | |
217 (let ((hook-value (default-value hook))) | |
218 (if (consp hook-value) | |
219 (if (member function hook-value) | |
220 (setq hook-value (delete function (copy-sequence hook-value)))) | |
221 (if (equal hook-value function) | |
222 (setq hook-value nil))) | |
223 (set-default hook hook-value))))) | |
224 | |
225 (defun add-to-list (list-var element) | |
226 "Add to the value of LIST-VAR the element ELEMENT if it isn't there yet. | |
227 The test for presence of ELEMENT is done with `equal'. | |
228 If you want to use `add-to-list' on a variable that is not defined | |
229 until a certain package is loaded, you should put the call to `add-to-list' | |
230 into a hook function that will be run only after loading the package. | |
231 `eval-after-load' provides one way to do this. In some cases | |
232 other hooks, such as major mode hooks, can do the job." | |
233 (or (member element (symbol-value list-var)) | |
234 (set list-var (cons element (symbol-value list-var))))) | |
235 | |
236 ;; XEmacs additions | |
237 ;; called by Fkill_buffer() | |
238 (defvar kill-buffer-hook nil | |
239 "Function or functions to be called when a buffer is killed. | |
240 The value of this variable may be buffer-local. | |
241 The buffer about to be killed is current when this hook is run.") | |
242 | |
243 ;; in C in FSFmacs | |
244 (defvar kill-emacs-hook nil | |
245 "Function or functions to be called when `kill-emacs' is called, | |
246 just before emacs is actually killed.") | |
247 | |
248 ;; not obsolete. | |
249 ;; #### These are a bad idea, because the CL RPLACA and RPLACD | |
250 ;; return the cons cell, not the new CAR/CDR. -hniksic | |
251 ;; The proper definition would be: | |
252 ;; (defun rplaca (conscell newcar) | |
253 ;; (setcar conscell newcar) | |
254 ;; conscell) | |
255 ;; ...and analogously for RPLACD. | |
256 (define-function 'rplaca 'setcar) | |
257 (define-function 'rplacd 'setcdr) | |
258 | |
259 ;;;; String functions. | |
260 | |
261 ;; XEmacs | |
262 (defun replace-in-string (str regexp newtext &optional literal) | |
263 "Replaces all matches in STR for REGEXP with NEWTEXT string, | |
264 and returns the new string. | |
265 Optional LITERAL non-nil means do a literal replacement. | |
266 Otherwise treat \\ in NEWTEXT string as special: | |
267 \\& means substitute original matched text, | |
268 \\N means substitute match for \(...\) number N, | |
269 \\\\ means insert one \\." | |
270 (check-argument-type 'stringp str) | |
271 (check-argument-type 'stringp newtext) | |
272 (let ((rtn-str "") | |
273 (start 0) | |
274 (special) | |
275 match prev-start) | |
276 (while (setq match (string-match regexp str start)) | |
277 (setq prev-start start | |
278 start (match-end 0) | |
279 rtn-str | |
280 (concat | |
281 rtn-str | |
282 (substring str prev-start match) | |
283 (cond (literal newtext) | |
284 (t (mapconcat | |
285 (lambda (c) | |
286 (if special | |
287 (progn | |
288 (setq special nil) | |
289 (cond ((eq c ?\\) "\\") | |
290 ((eq c ?&) | |
291 (substring str | |
292 (match-beginning 0) | |
293 (match-end 0))) | |
294 ((and (>= c ?0) (<= c ?9)) | |
295 (if (> c (+ ?0 (length | |
296 (match-data)))) | |
297 ;; Invalid match num | |
298 (error "Invalid match num: %c" c) | |
299 (setq c (- c ?0)) | |
300 (substring str | |
301 (match-beginning c) | |
302 (match-end c)))) | |
303 (t (char-to-string c)))) | |
304 (if (eq c ?\\) (progn (setq special t) nil) | |
305 (char-to-string c)))) | |
306 newtext "")))))) | |
307 (concat rtn-str (substring str start)))) | |
308 | |
309 (defun split-string (string &optional pattern) | |
310 "Return a list of substrings of STRING which are separated by PATTERN. | |
311 If PATTERN is omitted, it defaults to \"[ \\f\\t\\n\\r\\v]+\"." | |
312 (or pattern | |
313 (setq pattern "[ \f\t\n\r\v]+")) | |
314 ;; The FSF version of this function takes care not to cons in case | |
315 ;; of infloop. Maybe we should synch? | |
316 (let (parts (start 0)) | |
317 (while (string-match pattern string start) | |
318 (setq parts (cons (substring string start (match-beginning 0)) parts) | |
319 start (match-end 0))) | |
320 (nreverse (cons (substring string start) parts)))) | |
321 | |
322 (defmacro with-output-to-string (&rest forms) | |
323 "Collect output to `standard-output' while evaluating FORMS and return | |
324 it as a string." | |
325 ;; by "William G. Dubuque" <wgd@zurich.ai.mit.edu> w/ mods from Stig | |
326 `(with-current-buffer (get-buffer-create " *string-output*") | |
327 (setq buffer-read-only nil) | |
328 (buffer-disable-undo (current-buffer)) | |
329 (erase-buffer) | |
330 (let ((standard-output (current-buffer))) | |
331 ,@forms) | |
332 (prog1 | |
333 (buffer-string) | |
334 (erase-buffer)))) | |
335 | |
336 (defmacro with-current-buffer (buffer &rest body) | |
337 "Execute the forms in BODY with BUFFER as the current buffer. | |
338 The value returned is the value of the last form in BODY. | |
339 See also `with-temp-buffer'." | |
340 `(save-current-buffer | |
341 (set-buffer ,buffer) | |
342 ,@body)) | |
343 | |
344 (defmacro with-temp-file (file &rest forms) | |
345 "Create a new buffer, evaluate FORMS there, and write the buffer to FILE. | |
346 The value of the last form in FORMS is returned, like `progn'. | |
347 See also `with-temp-buffer'." | |
348 (let ((temp-file (make-symbol "temp-file")) | |
349 (temp-buffer (make-symbol "temp-buffer"))) | |
350 `(let ((,temp-file ,file) | |
351 (,temp-buffer | |
352 (get-buffer-create (generate-new-buffer-name " *temp file*")))) | |
353 (unwind-protect | |
354 (prog1 | |
355 (with-current-buffer ,temp-buffer | |
356 ,@forms) | |
357 (with-current-buffer ,temp-buffer | |
358 (widen) | |
359 (write-region (point-min) (point-max) ,temp-file nil 0))) | |
360 (and (buffer-name ,temp-buffer) | |
361 (kill-buffer ,temp-buffer)))))) | |
362 | |
363 (defmacro with-temp-buffer (&rest forms) | |
364 "Create a temporary buffer, and evaluate FORMS there like `progn'. | |
365 See also `with-temp-file' and `with-output-to-string'." | |
366 (let ((temp-buffer (make-symbol "temp-buffer"))) | |
367 `(let ((,temp-buffer | |
368 (get-buffer-create (generate-new-buffer-name " *temp*")))) | |
369 (unwind-protect | |
370 (with-current-buffer ,temp-buffer | |
371 ,@forms) | |
372 (and (buffer-name ,temp-buffer) | |
373 (kill-buffer ,temp-buffer)))))) | |
374 | |
375 ;; Moved from mule-coding.el. | |
376 (defmacro with-string-as-buffer-contents (str &rest body) | |
377 "With the contents of the current buffer being STR, run BODY. | |
378 Returns the new contents of the buffer, as modified by BODY. | |
379 The original current buffer is restored afterwards." | |
380 `(let ((tempbuf (get-buffer-create " *string-as-buffer-contents*"))) | |
381 (with-current-buffer tempbuf | |
382 (unwind-protect | |
383 (progn | |
384 (buffer-disable-undo (current-buffer)) | |
385 (erase-buffer) | |
386 (insert ,str) | |
387 ,@body | |
388 (buffer-string)) | |
389 (erase-buffer tempbuf))))) | |
390 | |
391 (defun insert-face (string face) | |
392 "Insert STRING and highlight with FACE. Returns the extent created." | |
393 (let ((p (point)) ext) | |
394 (insert string) | |
395 (setq ext (make-extent p (point))) | |
396 (set-extent-face ext face) | |
397 ext)) | |
398 | |
399 ;; not obsolete. | |
400 (define-function 'string= 'string-equal) | |
401 (define-function 'string< 'string-lessp) | |
402 (define-function 'int-to-string 'number-to-string) | |
403 (define-function 'string-to-int 'string-to-number) | |
404 | |
405 ;; These two names are a bit awkward, as they conflict with the normal | |
406 ;; foo-to-bar naming scheme, but CLtL2 has them, so they stay. | |
407 (define-function 'char-int 'char-to-int) | |
408 (define-function 'int-char 'int-to-char) | |
409 | |
410 | |
411 ;; alist/plist functions | |
412 (defun plist-to-alist (plist) | |
413 "Convert property list PLIST into the equivalent association-list form. | |
414 The alist is returned. This converts from | |
415 | |
416 \(a 1 b 2 c 3) | |
417 | |
418 into | |
419 | |
420 \((a . 1) (b . 2) (c . 3)) | |
421 | |
422 The original plist is not modified. See also `destructive-plist-to-alist'." | |
423 (let (alist) | |
424 (while plist | |
425 (setq alist (cons (cons (car plist) (cadr plist)) alist)) | |
426 (setq plist (cddr plist))) | |
427 (nreverse alist))) | |
428 | |
429 (defun destructive-plist-to-alist (plist) | |
430 "Convert property list PLIST into the equivalent association-list form. | |
431 The alist is returned. This converts from | |
432 | |
433 \(a 1 b 2 c 3) | |
434 | |
435 into | |
436 | |
437 \((a . 1) (b . 2) (c . 3)) | |
438 | |
439 The original plist is destroyed in the process of constructing the alist. | |
440 See also `plist-to-alist'." | |
441 (let ((head plist) | |
442 next) | |
443 (while plist | |
444 ;; remember the next plist pair. | |
445 (setq next (cddr plist)) | |
446 ;; make the cons holding the property value into the alist element. | |
447 (setcdr (cdr plist) (cadr plist)) | |
448 (setcar (cdr plist) (car plist)) | |
449 ;; reattach into alist form. | |
450 (setcar plist (cdr plist)) | |
451 (setcdr plist next) | |
452 (setq plist next)) | |
453 head)) | |
454 | |
455 (defun alist-to-plist (alist) | |
456 "Convert association list ALIST into the equivalent property-list form. | |
457 The plist is returned. This converts from | |
458 | |
459 \((a . 1) (b . 2) (c . 3)) | |
460 | |
461 into | |
462 | |
463 \(a 1 b 2 c 3) | |
464 | |
465 The original alist is not modified. See also `destructive-alist-to-plist'." | |
466 (let (plist) | |
467 (while alist | |
468 (let ((el (car alist))) | |
469 (setq plist (cons (cdr el) (cons (car el) plist)))) | |
470 (setq alist (cdr alist))) | |
471 (nreverse plist))) | |
472 | |
473 ;; getf, remf in cl*.el. | |
474 | |
475 (defmacro putf (plist prop val) | |
476 "Add property PROP to plist PLIST with value VAL. | |
477 Analogous to (setq PLIST (plist-put PLIST PROP VAL))." | |
478 `(setq ,plist (plist-put ,plist ,prop ,val))) | |
479 | |
480 (defmacro laxputf (lax-plist prop val) | |
481 "Add property PROP to lax plist LAX-PLIST with value VAL. | |
482 Analogous to (setq LAX-PLIST (lax-plist-put LAX-PLIST PROP VAL))." | |
483 `(setq ,lax-plist (lax-plist-put ,lax-plist ,prop ,val))) | |
484 | |
485 (defmacro laxremf (lax-plist prop) | |
486 "Remove property PROP from lax plist LAX-PLIST. | |
487 Analogous to (setq LAX-PLIST (lax-plist-remprop LAX-PLIST PROP))." | |
488 `(setq ,lax-plist (lax-plist-remprop ,lax-plist ,prop))) | |
489 | |
490 ;;; Error functions | |
491 | |
492 (defun error (&rest args) | |
493 "Signal an error, making error message by passing all args to `format'. | |
494 This error is not continuable: you cannot continue execution after the | |
495 error using the debugger `r' command. See also `cerror'." | |
496 (while t | |
497 (apply 'cerror args))) | |
498 | |
499 (defun cerror (&rest args) | |
500 "Like `error' but signals a continuable error." | |
501 (signal 'error (list (apply 'format args)))) | |
502 | |
503 (defmacro check-argument-type (predicate argument) | |
504 "Check that ARGUMENT satisfies PREDICATE. | |
505 If not, signal a continuable `wrong-type-argument' error until the | |
506 returned value satisfies PREDICATE, and assign the returned value | |
507 to ARGUMENT." | |
508 `(if (not (,(eval predicate) ,argument)) | |
509 (setq ,argument | |
510 (wrong-type-argument ,predicate ,argument)))) | |
511 | |
512 (defun signal-error (error-symbol data) | |
513 "Signal a non-continuable error. Args are ERROR-SYMBOL, and associated DATA. | |
514 An error symbol is a symbol defined using `define-error'. | |
515 DATA should be a list. Its elements are printed as part of the error message. | |
516 If the signal is handled, DATA is made available to the handler. | |
517 See also `signal', and the functions to handle errors: `condition-case' | |
518 and `call-with-condition-handler'." | |
519 (while t | |
520 (signal error-symbol data))) | |
521 | |
522 (defun define-error (error-sym doc-string &optional inherits-from) | |
523 "Define a new error, denoted by ERROR-SYM. | |
524 DOC-STRING is an informative message explaining the error, and will be | |
525 printed out when an unhandled error occurs. | |
526 ERROR-SYM is a sub-error of INHERITS-FROM (which defaults to `error'). | |
527 | |
528 \[`define-error' internally works by putting on ERROR-SYM an `error-message' | |
529 property whose value is DOC-STRING, and an `error-conditions' property | |
530 that is a list of ERROR-SYM followed by each of its super-errors, up | |
531 to and including `error'. You will sometimes see code that sets this up | |
532 directly rather than calling `define-error', but you should *not* do this | |
533 yourself.]" | |
534 (check-argument-type 'symbolp error-sym) | |
535 (check-argument-type 'stringp doc-string) | |
536 (put error-sym 'error-message doc-string) | |
537 (or inherits-from (setq inherits-from 'error)) | |
538 (let ((conds (get inherits-from 'error-conditions))) | |
539 (or conds (signal-error 'error (list "Not an error symbol" error-sym))) | |
540 (put error-sym 'error-conditions (cons error-sym conds)))) | |
541 | |
542 ;;;; Miscellanea. | |
543 | |
544 (defun buffer-substring-no-properties (beg end) | |
545 "Return the text from BEG to END, without text properties, as a string." | |
546 (let ((string (buffer-substring beg end))) | |
547 (set-text-properties 0 (length string) nil string) | |
548 string)) | |
549 | |
550 ;; This should probably be written in C (i.e., without using `walk-windows'). | |
551 (defun get-buffer-window-list (buffer &optional minibuf frame) | |
552 "Return windows currently displaying BUFFER, or nil if none. | |
553 See `walk-windows' for the meaning of MINIBUF and FRAME." | |
554 (let ((buffer (if (bufferp buffer) buffer (get-buffer buffer))) windows) | |
555 (walk-windows (function (lambda (window) | |
556 (if (eq (window-buffer window) buffer) | |
557 (setq windows (cons window windows))))) | |
558 minibuf frame) | |
559 windows)) | |
560 | |
561 (defun ignore (&rest ignore) | |
562 "Do nothing and return nil. | |
563 This function accepts any number of arguments, but ignores them." | |
564 (interactive) | |
565 nil) | |
566 | |
567 (define-function 'mapc-internal 'mapc) | |
568 (make-obsolete 'mapc-internal 'mapc) | |
569 | |
570 (define-function 'eval-in-buffer 'with-current-buffer) | |
571 (make-obsolete 'eval-in-buffer 'with-current-buffer) | |
572 | |
573 ;;; The real defn is in abbrev.el but some early callers | |
574 ;;; (eg lisp-mode-abbrev-table) want this before abbrev.el is loaded... | |
575 | |
576 (if (not (fboundp 'define-abbrev-table)) | |
577 (progn | |
578 (setq abbrev-table-name-list '()) | |
579 (fset 'define-abbrev-table (function (lambda (name defs) | |
580 ;; These are fixed-up when abbrev.el loads. | |
581 (setq abbrev-table-name-list | |
582 (cons (cons name defs) | |
583 abbrev-table-name-list))))))) | |
584 | |
585 (defun functionp (object) | |
586 "Non-nil if OBJECT can be called as a function." | |
587 (or (and (symbolp object) (fboundp object)) | |
588 (subrp object) | |
589 (compiled-function-p object) | |
590 (eq (car-safe object) 'lambda))) | |
591 | |
592 | |
593 | |
594 (defun function-interactive (function) | |
595 "Returns the interactive specification of FUNCTION. | |
596 FUNCTION can be any funcallable object. | |
597 The specification will be returned as the list of the symbol `interactive' | |
598 and the specs. | |
599 If FUNCTION is not interactive, nil will be returned." | |
600 (setq function (indirect-function function)) | |
601 (cond ((compiled-function-p function) | |
602 (compiled-function-interactive function)) | |
603 ((subrp function) | |
604 (subr-interactive function)) | |
605 ((eq (car-safe function) 'lambda) | |
606 (let ((spec (if (stringp (nth 2 function)) | |
607 (nth 3 function) | |
608 (nth 2 function)))) | |
609 (and (eq (car-safe spec) 'interactive) | |
610 spec))) | |
611 (t | |
612 (error "Non-funcallable object: %s" function)))) | |
613 | |
614 ;; This was not present before. I think Jamie had some objections | |
615 ;; to this, so I'm leaving this undefined for now. --ben | |
616 | |
617 ;;; The objection is this: there is more than one way to load the same file. | |
618 ;;; "foo", "foo.elc", "foo.el", and "/some/path/foo.elc" are all different | |
619 ;;; ways to load the exact same code. `eval-after-load' is too stupid to | |
620 ;;; deal with this sort of thing. If this sort of feature is desired, then | |
621 ;;; it should work off of a hook on `provide'. Features are unique and | |
622 ;;; the arguments to (load) are not. --Stig | |
623 | |
624 ;; We provide this for FSFmacs compatibility, at least until we devise | |
625 ;; something better. | |
626 | |
627 ;;;; Specifying things to do after certain files are loaded. | |
628 | |
629 (defun eval-after-load (file form) | |
630 "Arrange that, if FILE is ever loaded, FORM will be run at that time. | |
631 This makes or adds to an entry on `after-load-alist'. | |
632 If FILE is already loaded, evaluate FORM right now. | |
633 It does nothing if FORM is already on the list for FILE. | |
634 FILE should be the name of a library, with no directory name." | |
635 ;; Make sure there is an element for FILE. | |
636 (or (assoc file after-load-alist) | |
637 (setq after-load-alist (cons (list file) after-load-alist))) | |
638 ;; Add FORM to the element if it isn't there. | |
639 (let ((elt (assoc file after-load-alist))) | |
640 (or (member form (cdr elt)) | |
641 (progn | |
642 (nconc elt (list form)) | |
643 ;; If the file has been loaded already, run FORM right away. | |
644 (and (assoc file load-history) | |
645 (eval form))))) | |
646 form) | |
647 (make-compatible 'eval-after-load "") | |
648 | |
649 (defun eval-next-after-load (file) | |
650 "Read the following input sexp, and run it whenever FILE is loaded. | |
651 This makes or adds to an entry on `after-load-alist'. | |
652 FILE should be the name of a library, with no directory name." | |
653 (eval-after-load file (read))) | |
654 (make-compatible 'eval-next-after-load "") | |
655 | |
656 ; alternate names (not obsolete) | |
657 (if (not (fboundp 'mod)) (define-function 'mod '%)) | |
658 (define-function 'move-marker 'set-marker) | |
659 (define-function 'beep 'ding) ; preserve lingual purity | |
660 (define-function 'indent-to-column 'indent-to) | |
661 (define-function 'backward-delete-char 'delete-backward-char) | |
662 (define-function 'search-forward-regexp (symbol-function 're-search-forward)) | |
663 (define-function 'search-backward-regexp (symbol-function 're-search-backward)) | |
664 (define-function 'remove-directory 'delete-directory) | |
665 (define-function 'set-match-data 'store-match-data) | |
666 (define-function 'send-string-to-terminal 'external-debugging-output) | |
667 (define-function 'buffer-string 'buffer-substring) | |
668 | |
669 ;;; subr.el ends here |