Mercurial > hg > xemacs-beta
comparison lisp/subr.el @ 428:3ecd8885ac67 r21-2-22
Import from CVS: tag r21-2-22
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:28:15 +0200 |
parents | |
children | abe6d1db359e |
comparison
equal
deleted
inserted
replaced
427:0a0253eac470 | 428:3ecd8885ac67 |
---|---|
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 ;; XEmacs: This stuff is done in C Code. | |
86 | |
87 ;;;; Obsolescent names for functions. | |
88 ;; XEmacs: not used. | |
89 | |
90 ;; XEmacs: | |
91 (defun local-variable-if-set-p (sym buffer) | |
92 "Return t if SYM would be local to BUFFER after it is set. | |
93 A nil value for BUFFER is *not* the same as (current-buffer), but | |
94 can be used to determine whether `make-variable-buffer-local' has been | |
95 called on SYM." | |
96 (local-variable-p sym buffer t)) | |
97 | |
98 | |
99 ;;;; Hook manipulation functions. | |
100 | |
101 ;; (defconst run-hooks 'run-hooks ...) | |
102 | |
103 (defun make-local-hook (hook) | |
104 "Make the hook HOOK local to the current buffer. | |
105 When a hook is local, its local and global values | |
106 work in concert: running the hook actually runs all the hook | |
107 functions listed in *either* the local value *or* the global value | |
108 of the hook variable. | |
109 | |
110 This function works by making `t' a member of the buffer-local value, | |
111 which acts as a flag to run the hook functions in the default value as | |
112 well. This works for all normal hooks, but does not work for most | |
113 non-normal hooks yet. We will be changing the callers of non-normal | |
114 hooks so that they can handle localness; this has to be done one by | |
115 one. | |
116 | |
117 This function does nothing if HOOK is already local in the current | |
118 buffer. | |
119 | |
120 Do not use `make-local-variable' to make a hook variable buffer-local." | |
121 (if (local-variable-p hook (current-buffer)) ; XEmacs | |
122 nil | |
123 (or (boundp hook) (set hook nil)) | |
124 (make-local-variable hook) | |
125 (set hook (list t)))) | |
126 | |
127 (defun add-hook (hook function &optional append local) | |
128 "Add to the value of HOOK the function FUNCTION. | |
129 FUNCTION is not added if already present. | |
130 FUNCTION is added (if necessary) at the beginning of the hook list | |
131 unless the optional argument APPEND is non-nil, in which case | |
132 FUNCTION is added at the end. | |
133 | |
134 The optional fourth argument, LOCAL, if non-nil, says to modify | |
135 the hook's buffer-local value rather than its default value. | |
136 This makes no difference if the hook is not buffer-local. | |
137 To make a hook variable buffer-local, always use | |
138 `make-local-hook', not `make-local-variable'. | |
139 | |
140 HOOK should be a symbol, and FUNCTION may be any valid function. If | |
141 HOOK is void, it is first set to nil. If HOOK's value is a single | |
142 function, it is changed to a list of functions." | |
143 (or (boundp hook) (set hook nil)) | |
144 (or (default-boundp hook) (set-default hook nil)) | |
145 ;; If the hook value is a single function, turn it into a list. | |
146 (let ((old (symbol-value hook))) | |
147 (if (or (not (listp old)) (eq (car old) 'lambda)) | |
148 (set hook (list old)))) | |
149 (if (or local | |
150 ;; Detect the case where make-local-variable was used on a hook | |
151 ;; and do what we used to do. | |
152 (and (local-variable-if-set-p hook (current-buffer)) ; XEmacs | |
153 (not (memq t (symbol-value hook))))) | |
154 ;; Alter the local value only. | |
155 (or (if (consp function) | |
156 (member function (symbol-value hook)) | |
157 (memq function (symbol-value hook))) | |
158 (set hook | |
159 (if append | |
160 (append (symbol-value hook) (list function)) | |
161 (cons function (symbol-value hook))))) | |
162 ;; Alter the global value (which is also the only value, | |
163 ;; if the hook doesn't have a local value). | |
164 (or (if (consp function) | |
165 (member function (default-value hook)) | |
166 (memq function (default-value hook))) | |
167 (set-default hook | |
168 (if append | |
169 (append (default-value hook) (list function)) | |
170 (cons function (default-value hook))))))) | |
171 | |
172 (defun remove-hook (hook function &optional local) | |
173 "Remove from the value of HOOK the function FUNCTION. | |
174 HOOK should be a symbol, and FUNCTION may be any valid function. If | |
175 FUNCTION isn't the value of HOOK, or, if FUNCTION doesn't appear in the | |
176 list of hooks to run in HOOK, then nothing is done. See `add-hook'. | |
177 | |
178 The optional third argument, LOCAL, if non-nil, says to modify | |
179 the hook's buffer-local value rather than its default value. | |
180 This makes no difference if the hook is not buffer-local. | |
181 To make a hook variable buffer-local, always use | |
182 `make-local-hook', not `make-local-variable'." | |
183 (if (or (not (boundp hook)) ;unbound symbol, or | |
184 (not (default-boundp 'hook)) | |
185 (null (symbol-value hook)) ;value is nil, or | |
186 (null function)) ;function is nil, then | |
187 nil ;Do nothing. | |
188 (if (or local | |
189 ;; Detect the case where make-local-variable was used on a hook | |
190 ;; and do what we used to do. | |
191 (and (local-variable-p hook (current-buffer)) | |
192 (not (memq t (symbol-value hook))))) | |
193 (let ((hook-value (symbol-value hook))) | |
194 (if (and (consp hook-value) (not (functionp hook-value))) | |
195 (if (member function hook-value) | |
196 (setq hook-value (delete function (copy-sequence hook-value)))) | |
197 (if (equal hook-value function) | |
198 (setq hook-value nil))) | |
199 (set hook hook-value)) | |
200 (let ((hook-value (default-value hook))) | |
201 (if (and (consp hook-value) (not (functionp hook-value))) | |
202 (if (member function hook-value) | |
203 (setq hook-value (delete function (copy-sequence hook-value)))) | |
204 (if (equal hook-value function) | |
205 (setq hook-value nil))) | |
206 (set-default hook hook-value))))) | |
207 | |
208 (defun add-to-list (list-var element) | |
209 "Add to the value of LIST-VAR the element ELEMENT if it isn't there yet. | |
210 The test for presence of ELEMENT is done with `equal'. | |
211 If you want to use `add-to-list' on a variable that is not defined | |
212 until a certain package is loaded, you should put the call to `add-to-list' | |
213 into a hook function that will be run only after loading the package. | |
214 `eval-after-load' provides one way to do this. In some cases | |
215 other hooks, such as major mode hooks, can do the job." | |
216 (or (member element (symbol-value list-var)) | |
217 (set list-var (cons element (symbol-value list-var))))) | |
218 | |
219 ;; XEmacs additions | |
220 ;; called by Fkill_buffer() | |
221 (defvar kill-buffer-hook nil | |
222 "Function or functions to be called when a buffer is killed. | |
223 The value of this variable may be buffer-local. | |
224 The buffer about to be killed is current when this hook is run.") | |
225 | |
226 ;; called by Frecord_buffer() | |
227 (defvar record-buffer-hook nil | |
228 "Function or functions to be called when a buffer is recorded. | |
229 The value of this variable may be buffer-local. | |
230 The buffer being recorded is passed as an argument to the hook.") | |
231 | |
232 ;; in C in FSFmacs | |
233 (defvar kill-emacs-hook nil | |
234 "Function or functions to be called when `kill-emacs' is called, | |
235 just before emacs is actually killed.") | |
236 | |
237 ;; not obsolete. | |
238 ;; #### These are a bad idea, because the CL RPLACA and RPLACD | |
239 ;; return the cons cell, not the new CAR/CDR. -hniksic | |
240 ;; The proper definition would be: | |
241 ;; (defun rplaca (conscell newcar) | |
242 ;; (setcar conscell newcar) | |
243 ;; conscell) | |
244 ;; ...and analogously for RPLACD. | |
245 (define-function 'rplaca 'setcar) | |
246 (define-function 'rplacd 'setcdr) | |
247 | |
248 (defun copy-symbol (symbol &optional copy-properties) | |
249 "Return a new uninterned symbol with the same name as SYMBOL. | |
250 If COPY-PROPERTIES is non-nil, the new symbol will have a copy of | |
251 SYMBOL's value, function, and property lists." | |
252 (let ((new (make-symbol (symbol-name symbol)))) | |
253 (when copy-properties | |
254 ;; This will not copy SYMBOL's chain of forwarding objects, but | |
255 ;; I think that's OK. Callers should not expect such magic to | |
256 ;; keep working in the copy in the first place. | |
257 (and (boundp symbol) | |
258 (set new (symbol-value symbol))) | |
259 (and (fboundp symbol) | |
260 (fset new (symbol-function symbol))) | |
261 (setplist new (copy-list (symbol-plist symbol)))) | |
262 new)) | |
263 | |
264 ;;;; String functions. | |
265 | |
266 ;; XEmacs | |
267 (defun replace-in-string (str regexp newtext &optional literal) | |
268 "Replace all matches in STR for REGEXP with NEWTEXT string, | |
269 and returns the new string. | |
270 Optional LITERAL non-nil means do a literal replacement. | |
271 Otherwise treat \\ in NEWTEXT string as special: | |
272 \\& means substitute original matched text, | |
273 \\N means substitute match for \(...\) number N, | |
274 \\\\ means insert one \\." | |
275 (check-argument-type 'stringp str) | |
276 (check-argument-type 'stringp newtext) | |
277 (let ((rtn-str "") | |
278 (start 0) | |
279 (special) | |
280 match prev-start) | |
281 (while (setq match (string-match regexp str start)) | |
282 (setq prev-start start | |
283 start (match-end 0) | |
284 rtn-str | |
285 (concat | |
286 rtn-str | |
287 (substring str prev-start match) | |
288 (cond (literal newtext) | |
289 (t (mapconcat | |
290 (lambda (c) | |
291 (if special | |
292 (progn | |
293 (setq special nil) | |
294 (cond ((eq c ?\\) "\\") | |
295 ((eq c ?&) | |
296 (substring str | |
297 (match-beginning 0) | |
298 (match-end 0))) | |
299 ((and (>= c ?0) (<= c ?9)) | |
300 (if (> c (+ ?0 (length | |
301 (match-data)))) | |
302 ;; Invalid match num | |
303 (error "Invalid match num: %c" c) | |
304 (setq c (- c ?0)) | |
305 (substring str | |
306 (match-beginning c) | |
307 (match-end c)))) | |
308 (t (char-to-string c)))) | |
309 (if (eq c ?\\) (progn (setq special t) nil) | |
310 (char-to-string c)))) | |
311 newtext "")))))) | |
312 (concat rtn-str (substring str start)))) | |
313 | |
314 (defun split-string (string &optional pattern) | |
315 "Return a list of substrings of STRING which are separated by PATTERN. | |
316 If PATTERN is omitted, it defaults to \"[ \\f\\t\\n\\r\\v]+\"." | |
317 (or pattern | |
318 (setq pattern "[ \f\t\n\r\v]+")) | |
319 (let (parts (start 0) (len (length string))) | |
320 (if (string-match pattern string) | |
321 (setq parts (cons (substring string 0 (match-beginning 0)) parts) | |
322 start (match-end 0))) | |
323 (while (and (< start len) | |
324 (string-match pattern string (if (> start (match-beginning 0)) | |
325 start | |
326 (1+ start)))) | |
327 (setq parts (cons (substring string start (match-beginning 0)) parts) | |
328 start (match-end 0))) | |
329 (nreverse (cons (substring string start) parts)))) | |
330 | |
331 ;; #### #### #### AAaargh! Must be in C, because it is used insanely | |
332 ;; early in the bootstrap process. | |
333 ;(defun split-path (path) | |
334 ; "Explode a search path into a list of strings. | |
335 ;The path components are separated with the characters specified | |
336 ;with `path-separator'." | |
337 ; (while (or (not stringp path-separator) | |
338 ; (/= (length path-separator) 1)) | |
339 ; (setq path-separator (signal 'error (list "\ | |
340 ;`path-separator' should be set to a single-character string" | |
341 ; path-separator)))) | |
342 ; (split-string-by-char path (aref separator 0))) | |
343 | |
344 (defmacro with-output-to-string (&rest forms) | |
345 "Collect output to `standard-output' while evaluating FORMS and return | |
346 it as a string." | |
347 ;; by "William G. Dubuque" <wgd@zurich.ai.mit.edu> w/ mods from Stig | |
348 `(with-current-buffer (get-buffer-create " *string-output*") | |
349 (setq buffer-read-only nil) | |
350 (buffer-disable-undo (current-buffer)) | |
351 (erase-buffer) | |
352 (let ((standard-output (current-buffer))) | |
353 ,@forms) | |
354 (prog1 | |
355 (buffer-string) | |
356 (erase-buffer)))) | |
357 | |
358 (defmacro with-current-buffer (buffer &rest body) | |
359 "Temporarily make BUFFER the current buffer and execute the forms in BODY. | |
360 The value returned is the value of the last form in BODY. | |
361 See also `with-temp-buffer'." | |
362 `(save-current-buffer | |
363 (set-buffer ,buffer) | |
364 ,@body)) | |
365 | |
366 (defmacro with-temp-file (file &rest forms) | |
367 "Create a new buffer, evaluate FORMS there, and write the buffer to FILE. | |
368 The value of the last form in FORMS is returned, like `progn'. | |
369 See also `with-temp-buffer'." | |
370 (let ((temp-file (make-symbol "temp-file")) | |
371 (temp-buffer (make-symbol "temp-buffer"))) | |
372 `(let ((,temp-file ,file) | |
373 (,temp-buffer | |
374 (get-buffer-create (generate-new-buffer-name " *temp file*")))) | |
375 (unwind-protect | |
376 (prog1 | |
377 (with-current-buffer ,temp-buffer | |
378 ,@forms) | |
379 (with-current-buffer ,temp-buffer | |
380 (widen) | |
381 (write-region (point-min) (point-max) ,temp-file nil 0))) | |
382 (and (buffer-name ,temp-buffer) | |
383 (kill-buffer ,temp-buffer)))))) | |
384 | |
385 (defmacro with-temp-buffer (&rest forms) | |
386 "Create a temporary buffer, and evaluate FORMS there like `progn'. | |
387 See also `with-temp-file' and `with-output-to-string'." | |
388 (let ((temp-buffer (make-symbol "temp-buffer"))) | |
389 `(let ((,temp-buffer | |
390 (get-buffer-create (generate-new-buffer-name " *temp*")))) | |
391 (unwind-protect | |
392 (with-current-buffer ,temp-buffer | |
393 ,@forms) | |
394 (and (buffer-name ,temp-buffer) | |
395 (kill-buffer ,temp-buffer)))))) | |
396 | |
397 ;; Moved from mule-coding.el. | |
398 (defmacro with-string-as-buffer-contents (str &rest body) | |
399 "With the contents of the current buffer being STR, run BODY. | |
400 Returns the new contents of the buffer, as modified by BODY. | |
401 The original current buffer is restored afterwards." | |
402 `(let ((tempbuf (get-buffer-create " *string-as-buffer-contents*"))) | |
403 (with-current-buffer tempbuf | |
404 (unwind-protect | |
405 (progn | |
406 (buffer-disable-undo (current-buffer)) | |
407 (erase-buffer) | |
408 (insert ,str) | |
409 ,@body | |
410 (buffer-string)) | |
411 (erase-buffer tempbuf))))) | |
412 | |
413 (defun insert-face (string face) | |
414 "Insert STRING and highlight with FACE. Return the extent created." | |
415 (let ((p (point)) ext) | |
416 (insert string) | |
417 (setq ext (make-extent p (point))) | |
418 (set-extent-face ext face) | |
419 ext)) | |
420 | |
421 ;; not obsolete. | |
422 (define-function 'string= 'string-equal) | |
423 (define-function 'string< 'string-lessp) | |
424 (define-function 'int-to-string 'number-to-string) | |
425 (define-function 'string-to-int 'string-to-number) | |
426 | |
427 ;; These two names are a bit awkward, as they conflict with the normal | |
428 ;; foo-to-bar naming scheme, but CLtL2 has them, so they stay. | |
429 (define-function 'char-int 'char-to-int) | |
430 (define-function 'int-char 'int-to-char) | |
431 | |
432 | |
433 ;; alist/plist functions | |
434 (defun plist-to-alist (plist) | |
435 "Convert property list PLIST into the equivalent association-list form. | |
436 The alist is returned. This converts from | |
437 | |
438 \(a 1 b 2 c 3) | |
439 | |
440 into | |
441 | |
442 \((a . 1) (b . 2) (c . 3)) | |
443 | |
444 The original plist is not modified. See also `destructive-plist-to-alist'." | |
445 (let (alist) | |
446 (while plist | |
447 (setq alist (cons (cons (car plist) (cadr plist)) alist)) | |
448 (setq plist (cddr plist))) | |
449 (nreverse alist))) | |
450 | |
451 (defun destructive-plist-to-alist (plist) | |
452 "Convert property list PLIST into the equivalent association-list form. | |
453 The alist is returned. This converts from | |
454 | |
455 \(a 1 b 2 c 3) | |
456 | |
457 into | |
458 | |
459 \((a . 1) (b . 2) (c . 3)) | |
460 | |
461 The original plist is destroyed in the process of constructing the alist. | |
462 See also `plist-to-alist'." | |
463 (let ((head plist) | |
464 next) | |
465 (while plist | |
466 ;; remember the next plist pair. | |
467 (setq next (cddr plist)) | |
468 ;; make the cons holding the property value into the alist element. | |
469 (setcdr (cdr plist) (cadr plist)) | |
470 (setcar (cdr plist) (car plist)) | |
471 ;; reattach into alist form. | |
472 (setcar plist (cdr plist)) | |
473 (setcdr plist next) | |
474 (setq plist next)) | |
475 head)) | |
476 | |
477 (defun alist-to-plist (alist) | |
478 "Convert association list ALIST into the equivalent property-list form. | |
479 The plist is returned. This converts from | |
480 | |
481 \((a . 1) (b . 2) (c . 3)) | |
482 | |
483 into | |
484 | |
485 \(a 1 b 2 c 3) | |
486 | |
487 The original alist is not modified. See also `destructive-alist-to-plist'." | |
488 (let (plist) | |
489 (while alist | |
490 (let ((el (car alist))) | |
491 (setq plist (cons (cdr el) (cons (car el) plist)))) | |
492 (setq alist (cdr alist))) | |
493 (nreverse plist))) | |
494 | |
495 ;; getf, remf in cl*.el. | |
496 | |
497 (defmacro putf (plist prop val) | |
498 "Add property PROP to plist PLIST with value VAL. | |
499 Analogous to (setq PLIST (plist-put PLIST PROP VAL))." | |
500 `(setq ,plist (plist-put ,plist ,prop ,val))) | |
501 | |
502 (defmacro laxputf (lax-plist prop val) | |
503 "Add property PROP to lax plist LAX-PLIST with value VAL. | |
504 Analogous to (setq LAX-PLIST (lax-plist-put LAX-PLIST PROP VAL))." | |
505 `(setq ,lax-plist (lax-plist-put ,lax-plist ,prop ,val))) | |
506 | |
507 (defmacro laxremf (lax-plist prop) | |
508 "Remove property PROP from lax plist LAX-PLIST. | |
509 Analogous to (setq LAX-PLIST (lax-plist-remprop LAX-PLIST PROP))." | |
510 `(setq ,lax-plist (lax-plist-remprop ,lax-plist ,prop))) | |
511 | |
512 ;;; Error functions | |
513 | |
514 (defun error (&rest args) | |
515 "Signal an error, making error message by passing all args to `format'. | |
516 This error is not continuable: you cannot continue execution after the | |
517 error using the debugger `r' command. See also `cerror'." | |
518 (while t | |
519 (apply 'cerror args))) | |
520 | |
521 (defun cerror (&rest args) | |
522 "Like `error' but signals a continuable error." | |
523 (signal 'error (list (apply 'format args)))) | |
524 | |
525 (defmacro check-argument-type (predicate argument) | |
526 "Check that ARGUMENT satisfies PREDICATE. | |
527 If not, signal a continuable `wrong-type-argument' error until the | |
528 returned value satisfies PREDICATE, and assign the returned value | |
529 to ARGUMENT." | |
530 `(if (not (,(eval predicate) ,argument)) | |
531 (setq ,argument | |
532 (wrong-type-argument ,predicate ,argument)))) | |
533 | |
534 (defun signal-error (error-symbol data) | |
535 "Signal a non-continuable error. Args are ERROR-SYMBOL, and associated DATA. | |
536 An error symbol is a symbol defined using `define-error'. | |
537 DATA should be a list. Its elements are printed as part of the error message. | |
538 If the signal is handled, DATA is made available to the handler. | |
539 See also `signal', and the functions to handle errors: `condition-case' | |
540 and `call-with-condition-handler'." | |
541 (while t | |
542 (signal error-symbol data))) | |
543 | |
544 (defun define-error (error-sym doc-string &optional inherits-from) | |
545 "Define a new error, denoted by ERROR-SYM. | |
546 DOC-STRING is an informative message explaining the error, and will be | |
547 printed out when an unhandled error occurs. | |
548 ERROR-SYM is a sub-error of INHERITS-FROM (which defaults to `error'). | |
549 | |
550 \[`define-error' internally works by putting on ERROR-SYM an `error-message' | |
551 property whose value is DOC-STRING, and an `error-conditions' property | |
552 that is a list of ERROR-SYM followed by each of its super-errors, up | |
553 to and including `error'. You will sometimes see code that sets this up | |
554 directly rather than calling `define-error', but you should *not* do this | |
555 yourself.]" | |
556 (check-argument-type 'symbolp error-sym) | |
557 (check-argument-type 'stringp doc-string) | |
558 (put error-sym 'error-message doc-string) | |
559 (or inherits-from (setq inherits-from 'error)) | |
560 (let ((conds (get inherits-from 'error-conditions))) | |
561 (or conds (signal-error 'error (list "Not an error symbol" error-sym))) | |
562 (put error-sym 'error-conditions (cons error-sym conds)))) | |
563 | |
564 ;;;; Miscellanea. | |
565 | |
566 ;; This is now in C. | |
567 ;(defun buffer-substring-no-properties (beg end) | |
568 ; "Return the text from BEG to END, without text properties, as a string." | |
569 ; (let ((string (buffer-substring beg end))) | |
570 ; (set-text-properties 0 (length string) nil string) | |
571 ; string)) | |
572 | |
573 (defun get-buffer-window-list (&optional buffer minibuf frame) | |
574 "Return windows currently displaying BUFFER, or nil if none. | |
575 BUFFER defaults to the current buffer. | |
576 See `walk-windows' for the meaning of MINIBUF and FRAME." | |
577 (cond ((null buffer) | |
578 (setq buffer (current-buffer))) | |
579 ((not (bufferp buffer)) | |
580 (setq buffer (get-buffer buffer)))) | |
581 (let (windows) | |
582 (walk-windows (lambda (window) | |
583 (if (eq (window-buffer window) buffer) | |
584 (push window windows))) | |
585 minibuf frame) | |
586 windows)) | |
587 | |
588 (defun ignore (&rest ignore) | |
589 "Do nothing and return nil. | |
590 This function accepts any number of arguments, but ignores them." | |
591 (interactive) | |
592 nil) | |
593 | |
594 (define-function 'eval-in-buffer 'with-current-buffer) | |
595 (make-obsolete 'eval-in-buffer 'with-current-buffer) | |
596 | |
597 ;;; The real defn is in abbrev.el but some early callers | |
598 ;;; (eg lisp-mode-abbrev-table) want this before abbrev.el is loaded... | |
599 | |
600 (if (not (fboundp 'define-abbrev-table)) | |
601 (progn | |
602 (setq abbrev-table-name-list '()) | |
603 (fset 'define-abbrev-table (function (lambda (name defs) | |
604 ;; These are fixed-up when abbrev.el loads. | |
605 (setq abbrev-table-name-list | |
606 (cons (cons name defs) | |
607 abbrev-table-name-list))))))) | |
608 | |
609 ;;; `functionp' has been moved into C. | |
610 | |
611 ;;(defun functionp (object) | |
612 ;; "Non-nil if OBJECT can be called as a function." | |
613 ;; (or (and (symbolp object) (fboundp object)) | |
614 ;; (subrp object) | |
615 ;; (compiled-function-p object) | |
616 ;; (eq (car-safe object) 'lambda))) | |
617 | |
618 | |
619 | |
620 (defun function-interactive (function) | |
621 "Return the interactive specification of FUNCTION. | |
622 FUNCTION can be any funcallable object. | |
623 The specification will be returned as the list of the symbol `interactive' | |
624 and the specs. | |
625 If FUNCTION is not interactive, nil will be returned." | |
626 (setq function (indirect-function function)) | |
627 (cond ((compiled-function-p function) | |
628 (compiled-function-interactive function)) | |
629 ((subrp function) | |
630 (subr-interactive function)) | |
631 ((eq (car-safe function) 'lambda) | |
632 (let ((spec (if (stringp (nth 2 function)) | |
633 (nth 3 function) | |
634 (nth 2 function)))) | |
635 (and (eq (car-safe spec) 'interactive) | |
636 spec))) | |
637 (t | |
638 (error "Non-funcallable object: %s" function)))) | |
639 | |
640 ;; This function used to be an alias to `buffer-substring', except | |
641 ;; that FSF Emacs 20.4 added a BUFFER argument in an incompatible way. | |
642 ;; The new FSF's semantics makes more sense, but we try to support | |
643 ;; both for backward compatibility. | |
644 (defun buffer-string (&optional buffer old-end old-buffer) | |
645 "Return the contents of the current buffer as a string. | |
646 If narrowing is in effect, this function returns only the visible part | |
647 of the buffer. | |
648 | |
649 If BUFFER is specified, the contents of that buffer are returned. | |
650 | |
651 The arguments OLD-END and OLD-BUFFER are supported for backward | |
652 compatibility with pre-21.2 XEmacsen times when arguments to this | |
653 function were (buffer-string &optional START END BUFFER)." | |
654 (cond | |
655 ((or (stringp buffer) (bufferp buffer)) | |
656 ;; Most definitely the new way. | |
657 (buffer-substring nil nil buffer)) | |
658 ((or (stringp old-buffer) (bufferp old-buffer) | |
659 (natnump buffer) (natnump old-end)) | |
660 ;; Definitely the old way. | |
661 (buffer-substring buffer old-end old-buffer)) | |
662 (t | |
663 ;; Probably the old way. | |
664 (buffer-substring buffer old-end old-buffer)))) | |
665 | |
666 ;; This was not present before. I think Jamie had some objections | |
667 ;; to this, so I'm leaving this undefined for now. --ben | |
668 | |
669 ;;; The objection is this: there is more than one way to load the same file. | |
670 ;;; "foo", "foo.elc", "foo.el", and "/some/path/foo.elc" are all different | |
671 ;;; ways to load the exact same code. `eval-after-load' is too stupid to | |
672 ;;; deal with this sort of thing. If this sort of feature is desired, then | |
673 ;;; it should work off of a hook on `provide'. Features are unique and | |
674 ;;; the arguments to (load) are not. --Stig | |
675 | |
676 ;; We provide this for FSFmacs compatibility, at least until we devise | |
677 ;; something better. | |
678 | |
679 ;;;; Specifying things to do after certain files are loaded. | |
680 | |
681 (defun eval-after-load (file form) | |
682 "Arrange that, if FILE is ever loaded, FORM will be run at that time. | |
683 This makes or adds to an entry on `after-load-alist'. | |
684 If FILE is already loaded, evaluate FORM right now. | |
685 It does nothing if FORM is already on the list for FILE. | |
686 FILE should be the name of a library, with no directory name." | |
687 ;; Make sure there is an element for FILE. | |
688 (or (assoc file after-load-alist) | |
689 (setq after-load-alist (cons (list file) after-load-alist))) | |
690 ;; Add FORM to the element if it isn't there. | |
691 (let ((elt (assoc file after-load-alist))) | |
692 (or (member form (cdr elt)) | |
693 (progn | |
694 (nconc elt (list form)) | |
695 ;; If the file has been loaded already, run FORM right away. | |
696 (and (assoc file load-history) | |
697 (eval form))))) | |
698 form) | |
699 (make-compatible 'eval-after-load "") | |
700 | |
701 (defun eval-next-after-load (file) | |
702 "Read the following input sexp, and run it whenever FILE is loaded. | |
703 This makes or adds to an entry on `after-load-alist'. | |
704 FILE should be the name of a library, with no directory name." | |
705 (eval-after-load file (read))) | |
706 (make-compatible 'eval-next-after-load "") | |
707 | |
708 ; alternate names (not obsolete) | |
709 (if (not (fboundp 'mod)) (define-function 'mod '%)) | |
710 (define-function 'move-marker 'set-marker) | |
711 (define-function 'beep 'ding) ; preserve lingual purity | |
712 (define-function 'indent-to-column 'indent-to) | |
713 (define-function 'backward-delete-char 'delete-backward-char) | |
714 (define-function 'search-forward-regexp (symbol-function 're-search-forward)) | |
715 (define-function 'search-backward-regexp (symbol-function 're-search-backward)) | |
716 (define-function 'remove-directory 'delete-directory) | |
717 (define-function 'set-match-data 'store-match-data) | |
718 (define-function 'send-string-to-terminal 'external-debugging-output) | |
719 | |
720 ;;; subr.el ends here |