annotate lisp/subr.el @ 1292:f3437b56874d

[xemacs-hg @ 2003-02-13 09:57:04 by ben] profile updates profile.c: Major reworking. Keep track of new information -- total function timing (includes descendants), GC usage, total GC usage (includes descendants). New functions to be called appropriately from eval.c, alloc.c to keep track of this information. Keep track of when we're actually in a function vs. in its profile, for more accurate timing counts. Track profile overhead separately. Create new mechanism for specifying "internal sections" that are tracked just like regular Lisp functions and even appear in the backtrace if `backtrace-with-internal-sections' is non-nil (t by default for error-checking builds). Add some KKCC information for the straight (non-Elisp) hash table used by profile, which contains Lisp objects in its keys -- but not used yet. Remove old ad-hoc methods for tracking garbage collection, redisplay (which was incorrect anyway when Lisp was called within these sections). Don't record any tick info when blocking under MS Windows, since the timer there is in real time rather than in process time. Make `start-profiling', `stop-profiling' interactive. Be consistent wrt. recursive functions and functions currently on the stack when starting or stopping -- together these make implementing the `total' values extremely difficult. When we start profiling, we act as if we just entered all the functions currently on the stack. Likewise when exiting. Create vars in_profile for tracking time spent inside of profiling, and profiling_lock for setting exclusive access to the main hash table when reading from it or modifying it. (protects against getting screwed up by the signal handle going off at the same time. profile.h: New file. Create macros for declaring internal profiling sections. lisp.h: Move profile-related stuff to profile.h. alloc.c: Keep track of total consing, for profile. Tell profile when we are consing. Use new profile-section method for noting garbage-collection. alloc.c: Abort if we attempt to call the allocator reentrantly. backtrace.h, eval.c: Add info for use by profile in the backtrace frame and transfer PUSH_BACKTRACE/POP_BACKTRACE from eval.c, for use with profile. elhash.c: Author comment. eval.c, lisp.h: New Lisp var `backtrace-with-internal-sections'. Set to t when error-checking is on. eval.c: When unwinding, eval.c: Report to profile when we are about-to-call and just-called wrt. a function. alloc.c, eval.c: Allow for "fake" backtrace frames, for internal sections (used by profile and `backtrace-with-internal-sections'. event-Xt.c, event-gtk.c, event-msw.c, event-tty.c: Record when we are actually blocking on an event, for profile's sake. event-stream.c: Record internal profiling sections for getting, dispatching events. extents.c: Record internal profiling sections for map_extents. hash.c, hash.h: Add pregrow_hash_table_if_necessary(). (Used in profile code since the signal handler is the main grower but can't allow a realloc(). We make sure, at critical points, that the table is large enough.) lread.c: Create internal profiling sections for `load' (which may be triggered internally by autoload, etc.). redisplay.c: Remove old profile_redisplay_flag. Use new macros to declare internal profiling section for redisplay. text.c: Use new macros to declare internal profiling sections for char-byte conversion and internal-external conversion. SEMI-UNRELATED CHANGES: ----------------------- text.c: Update the long comments.
author ben
date Thu, 13 Feb 2003 09:57:08 +0000
parents 3a01f3148bff
children 1b0339b048ce
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1 ;;; subr.el --- basic lisp subroutines for XEmacs
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3 ;; Copyright (C) 1985, 1986, 1992, 1994-5, 1997 Free Software Foundation, Inc.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
4 ;; Copyright (C) 1995 Tinker Systems and INS Engineering Corp.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
5 ;; Copyright (C) 1995 Sun Microsystems.
772
d682c0f82a71 [xemacs-hg @ 2002-03-13 10:00:06 by ben]
ben
parents: 771
diff changeset
6 ;; Copyright (C) 2000, 2001, 2002 Ben Wing.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
7
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
8 ;; Maintainer: XEmacs Development Team
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
9 ;; Keywords: extensions, dumped
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
10
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
11 ;; This file is part of XEmacs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
12
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
13 ;; XEmacs is free software; you can redistribute it and/or modify it
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
14 ;; under the terms of the GNU General Public License as published by
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
15 ;; the Free Software Foundation; either version 2, or (at your option)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
16 ;; any later version.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
17
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
18 ;; XEmacs is distributed in the hope that it will be useful, but
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
19 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
21 ;; General Public License for more details.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
22
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
23 ;; You should have received a copy of the GNU General Public License
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
24 ;; along with XEmacs; see the file COPYING. If not, write to the Free
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
25 ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
26 ;; 02111-1307, USA.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
27
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
28 ;;; Synched up with: FSF 19.34.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
29
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
30 ;;; Commentary:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
31
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
32 ;; This file is dumped with XEmacs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
33
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
34 ;; There's not a whole lot in common now with the FSF version,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
35 ;; be wary when applying differences. I've left in a number of lines
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
36 ;; of commentary just to give diff(1) something to synch itself with to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
37 ;; provide useful context diffs. -sb
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
38
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
39 ;;; Code:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
40
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
41
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
42 ;;;; Lisp language features.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
43
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
44 (defmacro lambda (&rest cdr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
45 "Return a lambda expression.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
46 A call of the form (lambda ARGS DOCSTRING INTERACTIVE BODY) is
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
47 self-quoting; the result of evaluating the lambda expression is the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
48 expression itself. The lambda expression may then be treated as a
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
49 function, i.e., stored as the function value of a symbol, passed to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
50 funcall or mapcar, etc.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
51
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
52 ARGS should take the same form as an argument list for a `defun'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
53 DOCSTRING is an optional documentation string.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
54 If present, it should describe how to call the function.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
55 But documentation strings are usually not useful in nameless functions.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
56 INTERACTIVE should be a call to the function `interactive', which see.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
57 It may also be omitted.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
58 BODY should be a list of lisp expressions."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
59 `(function (lambda ,@cdr)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
60
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
61 (defmacro defun-when-void (&rest args)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
62 "Define a function, just like `defun', unless it's already defined.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
63 Used for compatibility among different emacs variants."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
64 `(if (fboundp ',(car args))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
65 nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
66 (defun ,@args)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
67
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
68 (defmacro define-function-when-void (&rest args)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
69 "Define a function, just like `define-function', unless it's already defined.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
70 Used for compatibility among different emacs variants."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
71 `(if (fboundp ,(car args))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
72 nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
73 (define-function ,@args)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
74
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
75
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
76 ;;;; Keymap support.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
77 ;; XEmacs: removed to keymap.el
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
78
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
79 ;;;; The global keymap tree.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
80
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
81 ;;; global-map, esc-map, and ctl-x-map have their values set up in
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
82 ;;; keymap.c; we just give them docstrings here.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
83
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
84 ;;;; Event manipulation functions.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
85
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
86 ;; XEmacs: This stuff is done in C Code.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
87
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
88 ;;;; Obsolescent names for functions.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
89 ;; XEmacs: not used.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
90
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
91 ;; XEmacs:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
92 (defun local-variable-if-set-p (sym buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
93 "Return t if SYM would be local to BUFFER after it is set.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
94 A nil value for BUFFER is *not* the same as (current-buffer), but
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
95 can be used to determine whether `make-variable-buffer-local' has been
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
96 called on SYM."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
97 (local-variable-p sym buffer t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
98
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
99
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
100 ;;;; Hook manipulation functions.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
101
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
102 ;; (defconst run-hooks 'run-hooks ...)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
103
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
104 (defun make-local-hook (hook)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
105 "Make the hook HOOK local to the current buffer.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
106 When a hook is local, its local and global values
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
107 work in concert: running the hook actually runs all the hook
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
108 functions listed in *either* the local value *or* the global value
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
109 of the hook variable.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
110
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
111 This function works by making `t' a member of the buffer-local value,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
112 which acts as a flag to run the hook functions in the default value as
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
113 well. This works for all normal hooks, but does not work for most
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
114 non-normal hooks yet. We will be changing the callers of non-normal
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
115 hooks so that they can handle localness; this has to be done one by
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
116 one.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
117
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
118 This function does nothing if HOOK is already local in the current
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
119 buffer.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
120
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
121 Do not use `make-local-variable' to make a hook variable buffer-local.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
122
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
123 See also `add-local-hook' and `remove-local-hook'."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
124 (if (local-variable-p hook (current-buffer)) ; XEmacs
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
125 nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
126 (or (boundp hook) (set hook nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
127 (make-local-variable hook)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
128 (set hook (list t))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
129
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
130 (defun add-hook (hook function &optional append local)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
131 "Add to the value of HOOK the function FUNCTION.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
132 FUNCTION is not added if already present.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
133 FUNCTION is added (if necessary) at the beginning of the hook list
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
134 unless the optional argument APPEND is non-nil, in which case
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
135 FUNCTION is added at the end.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
136
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
137 The optional fourth argument, LOCAL, if non-nil, says to modify
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
138 the hook's buffer-local value rather than its default value.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
139 This makes no difference if the hook is not buffer-local.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
140 To make a hook variable buffer-local, always use
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
141 `make-local-hook', not `make-local-variable'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
142
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
143 HOOK should be a symbol, and FUNCTION may be any valid function. If
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
144 HOOK is void, it is first set to nil. If HOOK's value is a single
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
145 function, it is changed to a list of functions.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
146
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
147 You can remove this hook yourself using `remove-hook'.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
148
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
149 See also `add-local-hook' and `add-one-shot-hook'."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
150 (or (boundp hook) (set hook nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
151 (or (default-boundp hook) (set-default hook nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
152 ;; If the hook value is a single function, turn it into a list.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
153 (let ((old (symbol-value hook)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
154 (if (or (not (listp old)) (eq (car old) 'lambda))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
155 (set hook (list old))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
156 (if (or local
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
157 ;; Detect the case where make-local-variable was used on a hook
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
158 ;; and do what we used to do.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
159 (and (local-variable-if-set-p hook (current-buffer)) ; XEmacs
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
160 (not (memq t (symbol-value hook)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
161 ;; Alter the local value only.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
162 (or (if (consp function)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
163 (member function (symbol-value hook))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
164 (memq function (symbol-value hook)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
165 (set hook
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
166 (if append
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
167 (append (symbol-value hook) (list function))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
168 (cons function (symbol-value hook)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
169 ;; Alter the global value (which is also the only value,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
170 ;; if the hook doesn't have a local value).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
171 (or (if (consp function)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
172 (member function (default-value hook))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
173 (memq function (default-value hook)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
174 (set-default hook
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
175 (if append
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
176 (append (default-value hook) (list function))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
177 (cons function (default-value hook)))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
178
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
179 (defun remove-hook (hook function &optional local)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
180 "Remove from the value of HOOK the function FUNCTION.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
181 HOOK should be a symbol, and FUNCTION may be any valid function. If
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
182 FUNCTION isn't the value of HOOK, or, if FUNCTION doesn't appear in the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
183 list of hooks to run in HOOK, then nothing is done. See `add-hook'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
184
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
185 The optional third argument, LOCAL, if non-nil, says to modify
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
186 the hook's buffer-local value rather than its default value.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
187 This makes no difference if the hook is not buffer-local.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
188 To make a hook variable buffer-local, always use
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
189 `make-local-hook', not `make-local-variable'."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
190 (if (or (not (boundp hook)) ;unbound symbol, or
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
191 (not (default-boundp 'hook))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
192 (null (symbol-value hook)) ;value is nil, or
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
193 (null function)) ;function is nil, then
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
194 nil ;Do nothing.
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
195 (flet ((hook-remove
924
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
196 (function hook-value)
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
197 (flet ((hook-test
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
198 (fn hel)
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
199 (or (equal fn hel)
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
200 (and (symbolp hel)
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
201 (equal fn
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
202 (get hel 'one-shot-hook-fun))))))
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
203 (if (and (consp hook-value)
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
204 (not (functionp hook-value)))
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
205 (if (member* function hook-value :test 'hook-test)
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
206 (setq hook-value
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
207 (delete* function (copy-sequence hook-value)
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
208 :test 'hook-test)))
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
209 (if (equal hook-value function)
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
210 (setq hook-value nil)))
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
211 hook-value)))
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
212 (if (or local
924
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
213 ;; Detect the case where make-local-variable was used on a hook
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
214 ;; and do what we used to do.
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
215 (and (local-variable-p hook (current-buffer))
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
216 (not (memq t (symbol-value hook)))))
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
217 (set hook (hook-remove function (symbol-value hook)))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
218 (set-default hook (hook-remove function (default-value hook)))))))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
219
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
220 ;; XEmacs addition
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
221 ;; #### we need a coherent scheme for indicating compatibility info,
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
222 ;; so that it can be programmatically retrieved.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
223 (defun add-local-hook (hook function &optional append)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
224 "Add to the local value of HOOK the function FUNCTION.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
225 This modifies only the buffer-local value for the hook (which is
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
226 automatically make buffer-local, if necessary), not its default value.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
227 FUNCTION is not added if already present.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
228 FUNCTION is added (if necessary) at the beginning of the hook list
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
229 unless the optional argument APPEND is non-nil, in which case
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
230 FUNCTION is added at the end.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
231
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
232 HOOK should be a symbol, and FUNCTION may be any valid function. If
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
233 HOOK is void, it is first set to nil. If HOOK's value is a single
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
234 function, it is changed to a list of functions.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
235
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
236 You can remove this hook yourself using `remove-local-hook'.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
237
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
238 See also `add-hook' and `make-local-hook'."
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
239 (make-local-hook hook)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
240 (add-hook hook function append t))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
241
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
242 ;; XEmacs addition
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
243 (defun remove-local-hook (hook function)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
244 "Remove from the local value of HOOK the function FUNCTION.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
245 This modifies only the buffer-local value for the hook, not its default
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
246 value. (Nothing happens if the hook is not buffer-local.)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
247 HOOK should be a symbol, and FUNCTION may be any valid function. If
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
248 FUNCTION isn't the value of HOOK, or, if FUNCTION doesn't appear in the
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
249 list of hooks to run in HOOK, then nothing is done. See `add-hook'.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
250
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
251 See also `add-local-hook' and `make-local-hook'."
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
252 (if (local-variable-p hook (current-buffer))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
253 (remove-hook hook function t)))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
254
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
255 (defun add-one-shot-hook (hook function &optional append local)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
256 "Add to the value of HOOK the one-shot function FUNCTION.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
257 FUNCTION will automatically be removed from the hook the first time
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
258 after it runs (whether to completion or to an error).
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
259 FUNCTION is not added if already present.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
260 FUNCTION is added (if necessary) at the beginning of the hook list
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
261 unless the optional argument APPEND is non-nil, in which case
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
262 FUNCTION is added at the end.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
263
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
264 HOOK should be a symbol, and FUNCTION may be any valid function. If
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
265 HOOK is void, it is first set to nil. If HOOK's value is a single
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
266 function, it is changed to a list of functions.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
267
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
268 You can remove this hook yourself using `remove-hook'.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
269
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
270 See also `add-hook', `add-local-hook', and `add-local-one-shot-hook'."
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
271 (let ((sym (gensym)))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
272 (fset sym `(lambda (&rest args)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
273 (unwind-protect
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
274 (apply ',function args)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
275 (remove-hook ',hook ',sym ',local))))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
276 (put sym 'one-shot-hook-fun function)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
277 (add-hook hook sym append local)))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
278
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
279 (defun add-local-one-shot-hook (hook function &optional append)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
280 "Add to the local value of HOOK the one-shot function FUNCTION.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
281 FUNCTION will automatically be removed from the hook the first time
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
282 after it runs (whether to completion or to an error).
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
283 FUNCTION is not added if already present.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
284 FUNCTION is added (if necessary) at the beginning of the hook list
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
285 unless the optional argument APPEND is non-nil, in which case
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
286 FUNCTION is added at the end.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
287
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
288 The optional fourth argument, LOCAL, if non-nil, says to modify
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
289 the hook's buffer-local value rather than its default value.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
290 This makes no difference if the hook is not buffer-local.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
291 To make a hook variable buffer-local, always use
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
292 `make-local-hook', not `make-local-variable'.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
293
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
294 HOOK should be a symbol, and FUNCTION may be any valid function. If
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
295 HOOK is void, it is first set to nil. If HOOK's value is a single
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
296 function, it is changed to a list of functions.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
297
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
298 You can remove this hook yourself using `remove-local-hook'.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
299
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
300 See also `add-hook', `add-local-hook', and `add-local-one-shot-hook'."
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
301 (make-local-hook hook)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
302 (add-one-shot-hook hook function append t))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
303
878
64f38afaab2d [xemacs-hg @ 2002-06-23 22:03:32 by youngs]
youngs
parents: 872
diff changeset
304 (defun add-to-list (list-var element &optional append)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
305 "Add to the value of LIST-VAR the element ELEMENT if it isn't there yet.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
306 The test for presence of ELEMENT is done with `equal'.
878
64f38afaab2d [xemacs-hg @ 2002-06-23 22:03:32 by youngs]
youngs
parents: 872
diff changeset
307 If ELEMENT is added, it is added at the beginning of the list,
64f38afaab2d [xemacs-hg @ 2002-06-23 22:03:32 by youngs]
youngs
parents: 872
diff changeset
308 unless the optional argument APPEND is non-nil, in which case
64f38afaab2d [xemacs-hg @ 2002-06-23 22:03:32 by youngs]
youngs
parents: 872
diff changeset
309 ELEMENT is added at the end.
64f38afaab2d [xemacs-hg @ 2002-06-23 22:03:32 by youngs]
youngs
parents: 872
diff changeset
310
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
311 If you want to use `add-to-list' on a variable that is not defined
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
312 until a certain package is loaded, you should put the call to `add-to-list'
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
313 into a hook function that will be run only after loading the package.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
314 `eval-after-load' provides one way to do this. In some cases
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
315 other hooks, such as major mode hooks, can do the job."
878
64f38afaab2d [xemacs-hg @ 2002-06-23 22:03:32 by youngs]
youngs
parents: 872
diff changeset
316 (if (member element (symbol-value list-var))
64f38afaab2d [xemacs-hg @ 2002-06-23 22:03:32 by youngs]
youngs
parents: 872
diff changeset
317 (symbol-value list-var)
64f38afaab2d [xemacs-hg @ 2002-06-23 22:03:32 by youngs]
youngs
parents: 872
diff changeset
318 (set list-var
64f38afaab2d [xemacs-hg @ 2002-06-23 22:03:32 by youngs]
youngs
parents: 872
diff changeset
319 (if append
64f38afaab2d [xemacs-hg @ 2002-06-23 22:03:32 by youngs]
youngs
parents: 872
diff changeset
320 (append (symbol-value list-var) (list element))
64f38afaab2d [xemacs-hg @ 2002-06-23 22:03:32 by youngs]
youngs
parents: 872
diff changeset
321 (cons element (symbol-value list-var))))))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
322
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
323 ;; XEmacs additions
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
324 ;; called by Fkill_buffer()
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
325 (defvar kill-buffer-hook nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
326 "Function or functions to be called when a buffer is killed.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
327 The value of this variable may be buffer-local.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
328 The buffer about to be killed is current when this hook is run.")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
329
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
330 ;; in C in FSFmacs
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
331 (defvar kill-emacs-hook nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
332 "Function or functions to be called when `kill-emacs' is called,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
333 just before emacs is actually killed.")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
334
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
335 ;; not obsolete.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
336 ;; #### These are a bad idea, because the CL RPLACA and RPLACD
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
337 ;; return the cons cell, not the new CAR/CDR. -hniksic
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
338 ;; The proper definition would be:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
339 ;; (defun rplaca (conscell newcar)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
340 ;; (setcar conscell newcar)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
341 ;; conscell)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
342 ;; ...and analogously for RPLACD.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
343 (define-function 'rplaca 'setcar)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
344 (define-function 'rplacd 'setcdr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
345
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
346 (defun copy-symbol (symbol &optional copy-properties)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
347 "Return a new uninterned symbol with the same name as SYMBOL.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
348 If COPY-PROPERTIES is non-nil, the new symbol will have a copy of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
349 SYMBOL's value, function, and property lists."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
350 (let ((new (make-symbol (symbol-name symbol))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
351 (when copy-properties
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
352 ;; This will not copy SYMBOL's chain of forwarding objects, but
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
353 ;; I think that's OK. Callers should not expect such magic to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
354 ;; keep working in the copy in the first place.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
355 (and (boundp symbol)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
356 (set new (symbol-value symbol)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
357 (and (fboundp symbol)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
358 (fset new (symbol-function symbol)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
359 (setplist new (copy-list (symbol-plist symbol))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
360 new))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
361
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
362 (defun set-symbol-value-in-buffer (sym val buffer)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
363 "Set the value of SYM to VAL in BUFFER. Useful with buffer-local variables.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
364 If SYM has a buffer-local value in BUFFER, or will have one if set, this
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
365 function allows you to set the local value.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
366
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
367 NOTE: At some point, this will be moved into C and will be very fast."
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
368 (with-current-buffer buffer
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
369 (set sym val)))
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
370
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
371 ;;;; String functions.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
372
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
373 ;; XEmacs
801
2b676dc88c66 [xemacs-hg @ 2002-04-01 03:58:02 by ben]
ben
parents: 793
diff changeset
374 (defun string-equal-ignore-case (str1 str2)
2b676dc88c66 [xemacs-hg @ 2002-04-01 03:58:02 by ben]
ben
parents: 793
diff changeset
375 "Return t if two strings have identical contents, ignoring case differences.
2b676dc88c66 [xemacs-hg @ 2002-04-01 03:58:02 by ben]
ben
parents: 793
diff changeset
376 Case is not significant. Text properties and extents are ignored.
2b676dc88c66 [xemacs-hg @ 2002-04-01 03:58:02 by ben]
ben
parents: 793
diff changeset
377 Symbols are also allowed; their print names are used instead.
2b676dc88c66 [xemacs-hg @ 2002-04-01 03:58:02 by ben]
ben
parents: 793
diff changeset
378
2b676dc88c66 [xemacs-hg @ 2002-04-01 03:58:02 by ben]
ben
parents: 793
diff changeset
379 See also `equalp'."
2b676dc88c66 [xemacs-hg @ 2002-04-01 03:58:02 by ben]
ben
parents: 793
diff changeset
380 (if (symbolp str1)
2b676dc88c66 [xemacs-hg @ 2002-04-01 03:58:02 by ben]
ben
parents: 793
diff changeset
381 (setq str1 (symbol-name str1)))
2b676dc88c66 [xemacs-hg @ 2002-04-01 03:58:02 by ben]
ben
parents: 793
diff changeset
382 (if (symbolp str2)
2b676dc88c66 [xemacs-hg @ 2002-04-01 03:58:02 by ben]
ben
parents: 793
diff changeset
383 (setq str2 (symbol-name str2)))
2b676dc88c66 [xemacs-hg @ 2002-04-01 03:58:02 by ben]
ben
parents: 793
diff changeset
384 (eq t (compare-strings str1 nil nil str2 nil nil t)))
2b676dc88c66 [xemacs-hg @ 2002-04-01 03:58:02 by ben]
ben
parents: 793
diff changeset
385
2b676dc88c66 [xemacs-hg @ 2002-04-01 03:58:02 by ben]
ben
parents: 793
diff changeset
386 ;; XEmacs
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
387 (defun replace-in-string (str regexp newtext &optional literal)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
388 "Replace all matches in STR for REGEXP with NEWTEXT string,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
389 and returns the new string.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
390 Optional LITERAL non-nil means do a literal replacement.
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
391 Otherwise treat `\\' in NEWTEXT as special:
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
392 `\\&' in NEWTEXT means substitute original matched text.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
393 `\\N' means substitute what matched the Nth `\\(...\\)'.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
394 If Nth parens didn't match, substitute nothing.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
395 `\\\\' means insert one `\\'.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
396 `\\u' means upcase the next character.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
397 `\\l' means downcase the next character.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
398 `\\U' means begin upcasing all following characters.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
399 `\\L' means begin downcasing all following characters.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
400 `\\E' means terminate the effect of any `\\U' or `\\L'."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
401 (check-argument-type 'stringp str)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
402 (check-argument-type 'stringp newtext)
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
403 (if (> (length str) 50)
924
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
404 (let ((cfs case-fold-search))
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
405 (with-temp-buffer
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
406 (setq case-fold-search cfs)
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
407 (insert str)
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
408 (goto-char 1)
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
409 (while (re-search-forward regexp nil t)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
410 (replace-match newtext t literal))
924
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
411 (buffer-string)))
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
412 (let ((start 0) newstr)
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
413 (while (string-match regexp str start)
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
414 (setq newstr (replace-match newtext t literal str)
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
415 start (+ (match-end 0) (- (length newstr) (length str)))
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
416 str newstr))
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
417 str)))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
418
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
419 (defun split-string (string &optional pattern)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
420 "Return a list of substrings of STRING which are separated by PATTERN.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
421 If PATTERN is omitted, it defaults to \"[ \\f\\t\\n\\r\\v]+\"."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
422 (or pattern
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
423 (setq pattern "[ \f\t\n\r\v]+"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
424 (let (parts (start 0) (len (length string)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
425 (if (string-match pattern string)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
426 (setq parts (cons (substring string 0 (match-beginning 0)) parts)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
427 start (match-end 0)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
428 (while (and (< start len)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
429 (string-match pattern string (if (> start (match-beginning 0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
430 start
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
431 (1+ start))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
432 (setq parts (cons (substring string start (match-beginning 0)) parts)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
433 start (match-end 0)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
434 (nreverse (cons (substring string start) parts))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
435
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
436 ;; #### #### #### AAaargh! Must be in C, because it is used insanely
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
437 ;; early in the bootstrap process.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
438 ;(defun split-path (path)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
439 ; "Explode a search path into a list of strings.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
440 ;The path components are separated with the characters specified
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
441 ;with `path-separator'."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
442 ; (while (or (not stringp path-separator)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
443 ; (/= (length path-separator) 1))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
444 ; (setq path-separator (signal 'error (list "\
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
445 ;`path-separator' should be set to a single-character string"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
446 ; path-separator))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
447 ; (split-string-by-char path (aref separator 0)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
448
1037
3a01f3148bff [xemacs-hg @ 2002-10-08 03:24:18 by youngs]
youngs
parents: 924
diff changeset
449 (defmacro with-output-to-string (&rest body)
3a01f3148bff [xemacs-hg @ 2002-10-08 03:24:18 by youngs]
youngs
parents: 924
diff changeset
450 "Execute BODY, return the text it sent to `standard-output', as a string."
3a01f3148bff [xemacs-hg @ 2002-10-08 03:24:18 by youngs]
youngs
parents: 924
diff changeset
451 `(let ((standard-output
3a01f3148bff [xemacs-hg @ 2002-10-08 03:24:18 by youngs]
youngs
parents: 924
diff changeset
452 (get-buffer-create (generate-new-buffer-name " *string-output*"))))
3a01f3148bff [xemacs-hg @ 2002-10-08 03:24:18 by youngs]
youngs
parents: 924
diff changeset
453 (let ((standard-output standard-output))
3a01f3148bff [xemacs-hg @ 2002-10-08 03:24:18 by youngs]
youngs
parents: 924
diff changeset
454 ,@body)
3a01f3148bff [xemacs-hg @ 2002-10-08 03:24:18 by youngs]
youngs
parents: 924
diff changeset
455 (with-current-buffer standard-output
3a01f3148bff [xemacs-hg @ 2002-10-08 03:24:18 by youngs]
youngs
parents: 924
diff changeset
456 (prog1
3a01f3148bff [xemacs-hg @ 2002-10-08 03:24:18 by youngs]
youngs
parents: 924
diff changeset
457 (buffer-string)
3a01f3148bff [xemacs-hg @ 2002-10-08 03:24:18 by youngs]
youngs
parents: 924
diff changeset
458 (kill-buffer nil)))))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
459
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
460 (defmacro with-current-buffer (buffer &rest body)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
461 "Temporarily make BUFFER the current buffer and execute the forms in BODY.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
462 The value returned is the value of the last form in BODY.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
463 See also `with-temp-buffer'."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
464 `(save-current-buffer
924
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
465 (set-buffer ,buffer)
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
466 ,@body))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
467
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
468 (defmacro with-temp-file (filename &rest forms)
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
469 "Create a new buffer, evaluate FORMS there, and write the buffer to FILENAME.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
470 The value of the last form in FORMS is returned, like `progn'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
471 See also `with-temp-buffer'."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
472 (let ((temp-file (make-symbol "temp-file"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
473 (temp-buffer (make-symbol "temp-buffer")))
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
474 `(let ((,temp-file ,filename)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
475 (,temp-buffer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
476 (get-buffer-create (generate-new-buffer-name " *temp file*"))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
477 (unwind-protect
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
478 (prog1
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
479 (with-current-buffer ,temp-buffer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
480 ,@forms)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
481 (with-current-buffer ,temp-buffer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
482 (widen)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
483 (write-region (point-min) (point-max) ,temp-file nil 0)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
484 (and (buffer-name ,temp-buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
485 (kill-buffer ,temp-buffer))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
486
883
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
487 (defmacro with-temp-message (message &rest body)
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
488 "Display MESSAGE temporarily while BODY is evaluated.
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
489 The original message is restored to the echo area after BODY has finished.
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
490 The value returned is the value of the last form in BODY."
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
491 (let ((current-message (make-symbol "current-message"))
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
492 (temp-message (make-symbol "with-temp-message")))
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
493 `(let ((,temp-message ,message)
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
494 (,current-message))
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
495 (unwind-protect
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
496 (progn
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
497 (when ,temp-message
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
498 (setq ,current-message (current-message))
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
499 (message "%s" ,temp-message))
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
500 ,@body)
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
501 (and ,temp-message ,current-message
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
502 (message "%s" ,current-message))))))
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
503
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
504 (defmacro with-temp-buffer (&rest forms)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
505 "Create a temporary buffer, and evaluate FORMS there like `progn'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
506 See also `with-temp-file' and `with-output-to-string'."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
507 (let ((temp-buffer (make-symbol "temp-buffer")))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
508 `(let ((,temp-buffer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
509 (get-buffer-create (generate-new-buffer-name " *temp*"))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
510 (unwind-protect
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
511 (with-current-buffer ,temp-buffer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
512 ,@forms)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
513 (and (buffer-name ,temp-buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
514 (kill-buffer ,temp-buffer))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
515
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
516 ;; Moved from mule-coding.el.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
517 (defmacro with-string-as-buffer-contents (str &rest body)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
518 "With the contents of the current buffer being STR, run BODY.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
519 Returns the new contents of the buffer, as modified by BODY.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
520 The original current buffer is restored afterwards."
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
521 `(with-temp-buffer
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
522 (insert ,str)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
523 ,@body
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
524 (buffer-string)))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
525
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
526 (defun insert-face (string face)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
527 "Insert STRING and highlight with FACE. Return the extent created."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
528 (let ((p (point)) ext)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
529 (insert string)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
530 (setq ext (make-extent p (point)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
531 (set-extent-face ext face)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
532 ext))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
533
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
534 ;; not obsolete.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
535 (define-function 'string= 'string-equal)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
536 (define-function 'string< 'string-lessp)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
537 (define-function 'int-to-string 'number-to-string)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
538 (define-function 'string-to-int 'string-to-number)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
539
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
540 ;; These two names are a bit awkward, as they conflict with the normal
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
541 ;; foo-to-bar naming scheme, but CLtL2 has them, so they stay.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
542 (define-function 'char-int 'char-to-int)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
543 (define-function 'int-char 'int-to-char)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
544
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 563
diff changeset
545 (defun string-width (string)
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 563
diff changeset
546 "Return number of columns STRING occupies when displayed.
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 563
diff changeset
547 With international (Mule) support, uses the charset-columns attribute of
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 563
diff changeset
548 the characters in STRING, which may not accurately represent the actual
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 563
diff changeset
549 display width when using a window system. With no international support,
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 563
diff changeset
550 simply returns the length of the string."
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 563
diff changeset
551 (if (featurep 'mule)
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 563
diff changeset
552 (let ((col 0)
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 563
diff changeset
553 (len (length string))
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 563
diff changeset
554 (i 0))
772
d682c0f82a71 [xemacs-hg @ 2002-03-13 10:00:06 by ben]
ben
parents: 771
diff changeset
555 (with-fboundp '(charset-width char-charset)
d682c0f82a71 [xemacs-hg @ 2002-03-13 10:00:06 by ben]
ben
parents: 771
diff changeset
556 (while (< i len)
d682c0f82a71 [xemacs-hg @ 2002-03-13 10:00:06 by ben]
ben
parents: 771
diff changeset
557 (setq col (+ col (charset-width (char-charset (aref string i)))))
d682c0f82a71 [xemacs-hg @ 2002-03-13 10:00:06 by ben]
ben
parents: 771
diff changeset
558 (setq i (1+ i))))
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 563
diff changeset
559 col)
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 563
diff changeset
560 (length string)))
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 563
diff changeset
561
777
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
562 (defun char-width (character)
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
563 "Return number of columns a CHARACTER occupies when displayed."
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
564 (if (featurep 'mule)
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
565 (with-fboundp '(charset-width char-charset)
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
566 (charset-width (char-charset character)))
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
567 1))
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
568
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
569 ;; The following several functions are useful in GNU Emacs 20 because
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
570 ;; of the multibyte "characters" the internal representation of which
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
571 ;; leaks into Lisp. In XEmacs/Mule they are trivial and unnecessary.
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
572 ;; We provide them for compatibility reasons solely.
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
573
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
574 (defun string-to-sequence (string type)
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
575 "Convert STRING to a sequence of TYPE which contains characters in STRING.
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
576 TYPE should be `list' or `vector'."
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
577 (ecase type
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
578 (list
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
579 (mapcar #'identity string))
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
580 (vector
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
581 (mapvector #'identity string))))
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
582
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
583 (defun string-to-list (string)
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
584 "Return a list of characters in STRING."
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
585 (mapcar #'identity string))
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
586
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
587 (defun string-to-vector (string)
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
588 "Return a vector of characters in STRING."
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
589 (mapvector #'identity string))
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
590
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
591 (defun store-substring (string idx obj)
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
592 "Embed OBJ (string or character) at index IDX of STRING."
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
593 (let* ((str (cond ((stringp obj) obj)
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
594 ((characterp obj) (char-to-string obj))
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
595 (t (error
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
596 "Invalid argument (should be string or character): %s"
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
597 obj))))
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
598 (string-len (length string))
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
599 (len (length str))
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
600 (i 0))
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
601 (while (and (< i len) (< idx string-len))
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
602 (aset string idx (aref str i))
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
603 (setq idx (1+ idx) i (1+ i)))
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
604 string))
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
605
851
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
606 ;; From FSF 21.1; ELLIPSES is XEmacs addition.
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
607
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
608 (defun truncate-string-to-width (str end-column &optional start-column padding
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
609 ellipses)
777
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
610 "Truncate string STR to end at column END-COLUMN.
814
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 801
diff changeset
611 The optional 3rd arg START-COLUMN, if non-nil, specifies
777
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
612 the starting column; that means to return the characters occupying
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
613 columns START-COLUMN ... END-COLUMN of STR.
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
614
814
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 801
diff changeset
615 The optional 4th arg PADDING, if non-nil, specifies a padding character
777
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
616 to add at the end of the result if STR doesn't reach column END-COLUMN,
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
617 or if END-COLUMN comes in the middle of a character in STR.
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
618 PADDING is also added at the beginning of the result
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
619 if column START-COLUMN appears in the middle of a character in STR.
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
620
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
621 If PADDING is nil, no padding is added in these cases, so
851
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
622 the resulting string may be narrower than END-COLUMN.
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
623
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
624 BUG: Currently assumes that the padding character is of width one. You
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
625 will get weird results if not.
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
626
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
627 If ELLIPSES is non-nil, add ellipses (specified by ELLIPSES if a string,
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
628 else `...') if STR extends past END-COLUMN. The ellipses will be added in
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
629 such a way that the total string occupies no more than END-COLUMN columns
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
630 -- i.e. if the string goes past END-COLUMN, it will be truncated somewhere
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
631 short of END-COLUMN so that, with the ellipses added (and padding, if the
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
632 proper place to truncate the string would be in the middle of a character),
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
633 the string occupies exactly END-COLUMN columns."
777
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
634 (or start-column
e65d9cf16707 [xemacs-hg @ 2002-03-15 11:00:28 by ben]
ben
parents: 772
diff changeset
635 (setq start-column 0))
814
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 801
diff changeset
636 (let ((len (length str))
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 801
diff changeset
637 (idx 0)
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 801
diff changeset
638 (column 0)
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 801
diff changeset
639 (head-padding "") (tail-padding "")
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 801
diff changeset
640 ch last-column last-idx from-idx)
851
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
641
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
642 ;; find the index of START-COLUMN; bail out if end of string reached.
814
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 801
diff changeset
643 (condition-case nil
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 801
diff changeset
644 (while (< column start-column)
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 801
diff changeset
645 (setq ch (aref str idx)
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 801
diff changeset
646 column (+ column (char-width ch))
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 801
diff changeset
647 idx (1+ idx)))
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 801
diff changeset
648 (args-out-of-range (setq idx len)))
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 801
diff changeset
649 (if (< column start-column)
851
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
650 ;; if string ends before START-COLUMN, return either a blank string
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
651 ;; or a string entirely padded.
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
652 (if padding (make-string (- end-column start-column) padding) "")
814
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 801
diff changeset
653 (if (and padding (> column start-column))
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 801
diff changeset
654 (setq head-padding (make-string (- column start-column) padding)))
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 801
diff changeset
655 (setq from-idx idx)
851
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
656 ;; If END-COLUMN is before START-COLUMN, then bail out.
814
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 801
diff changeset
657 (if (< end-column column)
851
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
658 (setq idx from-idx ellipses "")
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
659
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
660 ;; handle ELLIPSES
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
661 (cond ((null ellipses) (setq ellipses ""))
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
662 ((if (<= (string-width str) end-column)
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
663 ;; string fits, no ellipses
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
664 (setq ellipses "")))
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
665 (t
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
666 ;; else, insert default value and ...
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
667 (or (stringp ellipses) (setq ellipses "..."))
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
668 ;; ... take away the width of the ellipses from the
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
669 ;; destination. do all computations with new, shorter
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
670 ;; width. the padding computed will get us exactly up to
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
671 ;; the shorted width, which is right -- it just gets added
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
672 ;; to the right of the ellipses.
924
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
673 (setq end-column (- end-column (string-width ellipses)))))
851
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
674
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
675 ;; find the index of END-COLUMN; bail out if end of string reached.
814
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 801
diff changeset
676 (condition-case nil
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 801
diff changeset
677 (while (< column end-column)
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 801
diff changeset
678 (setq last-column column
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 801
diff changeset
679 last-idx idx
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 801
diff changeset
680 ch (aref str idx)
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 801
diff changeset
681 column (+ column (char-width ch))
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 801
diff changeset
682 idx (1+ idx)))
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 801
diff changeset
683 (args-out-of-range (setq idx len)))
851
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
684 ;; if we went too far (stopped in middle of character), back up.
814
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 801
diff changeset
685 (if (> column end-column)
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 801
diff changeset
686 (setq column last-column idx last-idx))
851
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
687 ;; compute remaining padding
814
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 801
diff changeset
688 (if (and padding (< column end-column))
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 801
diff changeset
689 (setq tail-padding (make-string (- end-column column) padding))))
851
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
690 ;; get substring ...
814
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 801
diff changeset
691 (setq str (substring str from-idx idx))
851
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
692 ;; and construct result
814
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 801
diff changeset
693 (if padding
851
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
694 (concat head-padding str tail-padding ellipses)
e7ee5f8bde58 [xemacs-hg @ 2002-05-23 11:46:08 by ben]
ben
parents: 814
diff changeset
695 (concat str ellipses)))))
801
2b676dc88c66 [xemacs-hg @ 2002-04-01 03:58:02 by ben]
ben
parents: 793
diff changeset
696
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
697
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
698 ;; alist/plist functions
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
699 (defun plist-to-alist (plist)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
700 "Convert property list PLIST into the equivalent association-list form.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
701 The alist is returned. This converts from
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
702
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
703 \(a 1 b 2 c 3)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
704
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
705 into
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
706
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
707 \((a . 1) (b . 2) (c . 3))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
708
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
709 The original plist is not modified. See also `destructive-plist-to-alist'."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
710 (let (alist)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
711 (while plist
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
712 (setq alist (cons (cons (car plist) (cadr plist)) alist))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
713 (setq plist (cddr plist)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
714 (nreverse alist)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
715
783
6fadd0a2230b [xemacs-hg @ 2002-03-19 02:38:51 by ben]
ben
parents: 777
diff changeset
716 (defun map-plist (_mp_fun _mp_plist)
6fadd0a2230b [xemacs-hg @ 2002-03-19 02:38:51 by ben]
ben
parents: 777
diff changeset
717 "Map _MP_FUN (a function of two args) over each key/value pair in _MP_PLIST.
6fadd0a2230b [xemacs-hg @ 2002-03-19 02:38:51 by ben]
ben
parents: 777
diff changeset
718 Return a list of the results."
6fadd0a2230b [xemacs-hg @ 2002-03-19 02:38:51 by ben]
ben
parents: 777
diff changeset
719 (let (_mp_result)
6fadd0a2230b [xemacs-hg @ 2002-03-19 02:38:51 by ben]
ben
parents: 777
diff changeset
720 (while _mp_plist
6fadd0a2230b [xemacs-hg @ 2002-03-19 02:38:51 by ben]
ben
parents: 777
diff changeset
721 (push (funcall _mp_fun (car _mp_plist) (cadr _mp_plist)) _mp_result)
6fadd0a2230b [xemacs-hg @ 2002-03-19 02:38:51 by ben]
ben
parents: 777
diff changeset
722 (setq _mp_plist (cddr _mp_plist)))
6fadd0a2230b [xemacs-hg @ 2002-03-19 02:38:51 by ben]
ben
parents: 777
diff changeset
723 (nreverse _mp_result)))
6fadd0a2230b [xemacs-hg @ 2002-03-19 02:38:51 by ben]
ben
parents: 777
diff changeset
724
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
725 (defun destructive-plist-to-alist (plist)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
726 "Convert property list PLIST into the equivalent association-list form.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
727 The alist is returned. This converts from
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
728
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
729 \(a 1 b 2 c 3)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
730
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
731 into
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
732
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
733 \((a . 1) (b . 2) (c . 3))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
734
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
735 The original plist is destroyed in the process of constructing the alist.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
736 See also `plist-to-alist'."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
737 (let ((head plist)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
738 next)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
739 (while plist
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
740 ;; remember the next plist pair.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
741 (setq next (cddr plist))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
742 ;; make the cons holding the property value into the alist element.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
743 (setcdr (cdr plist) (cadr plist))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
744 (setcar (cdr plist) (car plist))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
745 ;; reattach into alist form.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
746 (setcar plist (cdr plist))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
747 (setcdr plist next)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
748 (setq plist next))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
749 head))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
750
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
751 (defun alist-to-plist (alist)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
752 "Convert association list ALIST into the equivalent property-list form.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
753 The plist is returned. This converts from
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
754
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
755 \((a . 1) (b . 2) (c . 3))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
756
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
757 into
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
758
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
759 \(a 1 b 2 c 3)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
760
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
761 The original alist is not modified. See also `destructive-alist-to-plist'."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
762 (let (plist)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
763 (while alist
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
764 (let ((el (car alist)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
765 (setq plist (cons (cdr el) (cons (car el) plist))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
766 (setq alist (cdr alist)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
767 (nreverse plist)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
768
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
769 ;; getf, remf in cl*.el.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
770
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
771 (defmacro putf (plist property value)
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
772 "Add property PROPERTY to plist PLIST with value VALUE.
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
773 Analogous to (setq PLIST (plist-put PLIST PROPERTY VALUE))."
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
774 `(setq ,plist (plist-put ,plist ,property ,value)))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
775
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
776 (defmacro laxputf (lax-plist property value)
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
777 "Add property PROPERTY to lax plist LAX-PLIST with value VALUE.
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
778 Analogous to (setq LAX-PLIST (lax-plist-put LAX-PLIST PROPERTY VALUE))."
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
779 `(setq ,lax-plist (lax-plist-put ,lax-plist ,property ,value)))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
780
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
781 (defmacro laxremf (lax-plist property)
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
782 "Remove property PROPERTY from lax plist LAX-PLIST.
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
783 Analogous to (setq LAX-PLIST (lax-plist-remprop LAX-PLIST PROPERTY))."
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
784 `(setq ,lax-plist (lax-plist-remprop ,lax-plist ,property)))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
785
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
786 ;;; Error functions
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
787
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
788 (defun error (datum &rest args)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
789 "Signal a non-continuable error.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
790 DATUM should normally be an error symbol, i.e. a symbol defined using
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
791 `define-error'. ARGS will be made into a list, and DATUM and ARGS passed
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
792 as the two arguments to `signal', the most basic error handling function.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
793
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
794 This error is not continuable: you cannot continue execution after the
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
795 error using the debugger `r' command. See also `cerror'.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
796
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
797 The correct semantics of ARGS varies from error to error, but for most
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
798 errors that need to be generated in Lisp code, the first argument
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
799 should be a string describing the *context* of the error (i.e. the
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
800 exact operation being performed and what went wrong), and the remaining
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
801 arguments or \"frobs\" (most often, there is one) specify the
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
802 offending object(s) and/or provide additional details such as the exact
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
803 error when a file error occurred, e.g.:
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
804
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
805 -- the buffer in which an editing error occurred.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
806 -- an invalid value that was encountered. (In such cases, the string
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
807 should describe the purpose or \"semantics\" of the value [e.g. if the
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
808 value is an argument to a function, the name of the argument; if the value
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
809 is the value corresponding to a keyword, the name of the keyword; if the
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
810 value is supposed to be a list length, say this and say what the purpose
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
811 of the list is; etc.] as well as specifying why the value is invalid, if
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
812 that's not self-evident.)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
813 -- the file in which an error occurred. (In such cases, there should be a
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
814 second frob, probably a string, specifying the exact error that occurred.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
815 This does not occur in the string that precedes the first frob, because
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
816 that frob describes the exact operation that was happening.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
817
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
818 For historical compatibility, DATUM can also be a string. In this case,
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
819 DATUM and ARGS are passed together as the arguments to `format', and then
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
820 an error is signalled using the error symbol `error' and formatted string.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
821 Although this usage of `error' is very common, it is deprecated because it
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
822 totally defeats the purpose of having structured errors. There is now
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
823 a rich set of defined errors you can use:
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
824
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
825 quit
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
826
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
827 error
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
828 invalid-argument
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
829 syntax-error
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
830 invalid-read-syntax
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
831 invalid-regexp
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
832 structure-formation-error
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
833 list-formation-error
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
834 malformed-list
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
835 malformed-property-list
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
836 circular-list
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
837 circular-property-list
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
838 invalid-function
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
839 no-catch
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
840 undefined-keystroke-sequence
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
841 invalid-constant
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
842 wrong-type-argument
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
843 args-out-of-range
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
844 wrong-number-of-arguments
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
845
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
846 invalid-state
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
847 void-function
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
848 cyclic-function-indirection
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
849 void-variable
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
850 cyclic-variable-indirection
509
68eb53e4b7e5 [xemacs-hg @ 2001-05-05 10:53:29 by ben]
ben
parents: 444
diff changeset
851 invalid-byte-code
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
852 stack-overflow
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
853 out-of-memory
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
854 invalid-key-binding
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
855 internal-error
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
856
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
857 invalid-operation
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
858 invalid-change
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
859 setting-constant
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
860 protected-field
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
861 editing-error
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
862 beginning-of-buffer
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
863 end-of-buffer
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
864 buffer-read-only
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
865 io-error
509
68eb53e4b7e5 [xemacs-hg @ 2001-05-05 10:53:29 by ben]
ben
parents: 444
diff changeset
866 file-error
68eb53e4b7e5 [xemacs-hg @ 2001-05-05 10:53:29 by ben]
ben
parents: 444
diff changeset
867 file-already-exists
68eb53e4b7e5 [xemacs-hg @ 2001-05-05 10:53:29 by ben]
ben
parents: 444
diff changeset
868 file-locked
68eb53e4b7e5 [xemacs-hg @ 2001-05-05 10:53:29 by ben]
ben
parents: 444
diff changeset
869 file-supersession
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
870 end-of-file
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
871 process-error
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
872 network-error
509
68eb53e4b7e5 [xemacs-hg @ 2001-05-05 10:53:29 by ben]
ben
parents: 444
diff changeset
873 tooltalk-error
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
874 gui-error
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
875 dialog-box-error
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
876 sound-error
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
877 conversion-error
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
878 text-conversion-error
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
879 image-conversion-error
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
880 base64-conversion-error
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
881 selection-conversion-error
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
882 arith-error
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
883 range-error
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
884 domain-error
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
885 singularity-error
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
886 overflow-error
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
887 underflow-error
509
68eb53e4b7e5 [xemacs-hg @ 2001-05-05 10:53:29 by ben]
ben
parents: 444
diff changeset
888 search-failed
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
889 printing-unreadable-object
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
890 unimplemented
509
68eb53e4b7e5 [xemacs-hg @ 2001-05-05 10:53:29 by ben]
ben
parents: 444
diff changeset
891
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
892 Note the semantic differences between some of the more common errors:
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
893
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
894 -- `invalid-argument' is for all cases where a bad value is encountered.
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
895 -- `invalid-constant' is for arguments where only a specific set of values
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
896 is allowed.
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
897 -- `syntax-error' is when complex structures (parsed strings, lists,
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
898 and the like) are badly formed. If the problem is just a single bad
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
899 value inside the structure, you should probably be using something else,
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
900 e.g. `invalid-constant', `wrong-type-argument', or `invalid-argument'.
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
901 -- `invalid-state' means that some settings have been changed in such a way
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
902 that their current state is unallowable. More and more, code is being
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
903 written more carefully, and catches the error when the settings are being
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
904 changed, rather than afterwards. This leads us to the next error:
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
905 -- `invalid-change' means that an attempt is being made to change some settings
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
906 into an invalid state. `invalid-change' is a type of `invalid-operation'.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
907 -- `invalid-operation' refers to all cases where code is trying to do something
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
908 that's disallowed, or when an error occurred during an operation. (These
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
909 two concepts are merged because there's no clear distinction between them.)
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
910 -- `io-error' refers to errors involving interaction with any external
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 510
diff changeset
911 components (files, other programs, the operating system, etc).
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
912
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
913 See also `cerror', `signal', and `signal-error'."
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
914 (while t (apply
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
915 'cerror datum args)))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
916
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
917 (defun cerror (datum &rest args)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
918 "Like `error' but signals a continuable error."
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
919 (cond ((stringp datum)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
920 (signal 'error (list (apply 'format datum args))))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
921 ((defined-error-p datum)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
922 (signal datum args))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
923 (t
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
924 (error 'invalid-argument "datum not string or error symbol" datum))))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
925
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
926 (defmacro check-argument-type (predicate argument)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
927 "Check that ARGUMENT satisfies PREDICATE.
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
928 This is a macro, and ARGUMENT is not evaluated. If ARGUMENT is an lvalue,
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
929 this function signals a continuable `wrong-type-argument' error until the
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
930 returned value satisfies PREDICATE, and assigns the returned value
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
931 to ARGUMENT. Otherwise, this function signals a non-continuable
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
932 `wrong-type-argument' error if the returned value does not satisfy PREDICATE."
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
933 (if (symbolp argument)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
934 `(if (not (,(eval predicate) ,argument))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
935 (setq ,argument
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
936 (wrong-type-argument ,predicate ,argument)))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
937 `(if (not (,(eval predicate) ,argument))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
938 (signal-error 'wrong-type-argument (list ,predicate ,argument)))))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
939
872
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 851
diff changeset
940 (defun args-out-of-range (value min max)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 851
diff changeset
941 "Signal an error until the correct in-range value is given by the user.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 851
diff changeset
942 This function loops, signalling a continuable `args-out-of-range' error
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 851
diff changeset
943 with VALUE, MIN and MAX as the data associated with the error and then
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 851
diff changeset
944 checking the returned value to make sure it's not outside the given
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 851
diff changeset
945 boundaries \(nil for either means no boundary on that side). At that
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 851
diff changeset
946 point, the gotten value is returned."
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 851
diff changeset
947 (loop
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 851
diff changeset
948 for newval = (signal 'args-out-of-range (list value min max))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 851
diff changeset
949 do (setq value newval)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 851
diff changeset
950 finally return value
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 851
diff changeset
951 while (not (argument-in-range-p value min max))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 851
diff changeset
952
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 851
diff changeset
953 (defun argument-in-range-p (argument min max)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 851
diff changeset
954 "Return true if ARGUMENT is within the range of [MIN, MAX].
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 851
diff changeset
955 This includes boundaries. nil for either value means no limit on that side."
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 851
diff changeset
956 (and (or (not min) (<= min argument))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 851
diff changeset
957 (or (not max) (<= argument max))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 851
diff changeset
958
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 851
diff changeset
959 (defmacro check-argument-range (argument min max)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 851
diff changeset
960 "Check that ARGUMENT is within the range [MIN, MAX].
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 851
diff changeset
961 This is a macro, and ARGUMENT is not evaluated. If ARGUMENT is an lvalue,
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 851
diff changeset
962 this function signals a continuable `args-out-of-range' error until the
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 851
diff changeset
963 returned value is within range, and assigns the returned value
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 851
diff changeset
964 to ARGUMENT. Otherwise, this function signals a non-continuable
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 851
diff changeset
965 `args-out-of-range' error if the returned value is out of range."
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 851
diff changeset
966 (if (symbolp argument)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 851
diff changeset
967 `(if (not (argument-in-range-p ,argument ,min ,max))
924
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
968 (setq ,argument
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
969 (args-out-of-range ,argument ,min ,max)))
872
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 851
diff changeset
970 (let ((newsym (gensym)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 851
diff changeset
971 `(let ((,newsym ,argument))
924
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
972 (if (not (argument-in-range-p ,newsym ,min ,max))
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
973 (signal-error 'args-out-of-range ,newsym ,min ,max))))))
872
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 851
diff changeset
974
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
975 (defun signal-error (error-symbol data)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
976 "Signal a non-continuable error. Args are ERROR-SYMBOL, and associated DATA.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
977 An error symbol is a symbol defined using `define-error'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
978 DATA should be a list. Its elements are printed as part of the error message.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
979 If the signal is handled, DATA is made available to the handler.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
980 See also `signal', and the functions to handle errors: `condition-case'
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
981 and `call-with-condition-handler'."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
982 (while t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
983 (signal error-symbol data)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
984
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
985 (defun define-error (error-sym doc-string &optional inherits-from)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
986 "Define a new error, denoted by ERROR-SYM.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
987 DOC-STRING is an informative message explaining the error, and will be
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
988 printed out when an unhandled error occurs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
989 ERROR-SYM is a sub-error of INHERITS-FROM (which defaults to `error').
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
990
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
991 \[`define-error' internally works by putting on ERROR-SYM an `error-message'
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
992 property whose value is DOC-STRING, and an `error-conditions' property
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
993 that is a list of ERROR-SYM followed by each of its super-errors, up
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
994 to and including `error'. You will sometimes see code that sets this up
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
995 directly rather than calling `define-error', but you should *not* do this
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
996 yourself.]"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
997 (check-argument-type 'symbolp error-sym)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
998 (check-argument-type 'stringp doc-string)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
999 (put error-sym 'error-message doc-string)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1000 (or inherits-from (setq inherits-from 'error))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1001 (let ((conds (get inherits-from 'error-conditions)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1002 (or conds (signal-error 'error (list "Not an error symbol" error-sym)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1003 (put error-sym 'error-conditions (cons error-sym conds))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1004
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
1005 (defun defined-error-p (sym)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
1006 "Returns non-nil if SYM names a currently-defined error."
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
1007 (and (symbolp sym) (not (null (get sym 'error-conditions)))))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
1008
793
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1009 (defun backtrace-in-condition-handler-eliminating-handler (handler-arg-name)
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1010 "Return a backtrace inside of a condition handler, eliminating the handler.
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1011 This is for use in the condition handler inside of call-with-condition-handler,
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1012 when written like this:
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1013
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1014 \(call-with-condition-handler
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1015 #'(lambda (__some_weird_arg__)
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1016 do the handling ...)
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1017 #'(lambda ()
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1018 do the stuff that might cause an error))
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1019
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1020 Pass in the name (a symbol) of the argument used in the lambda function
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1021 that specifies the handler, and make sure the argument name is unique, and
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1022 this function generates a backtrace and strips off the part above where the
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1023 error occurred (i.e. the handler itself)."
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1024 (let* ((bt (with-output-to-string (backtrace nil t)))
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1025 (bt (save-match-data
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1026 ;; Try to eliminate the part of the backtrace
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1027 ;; above where the error occurred.
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1028 (if (string-match
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1029 (concat "bind (\\(?:.* \\)?" (symbol-name handler-arg-name)
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1030 "\\(?:.* \\)?)[ \t\n]*\\(?:(lambda \\|#<compiled-function \\)("
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1031 (symbol-name handler-arg-name)
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1032 ").*\n\\(\\(?:.\\|\n\\)*\\)$")
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1033 bt) (match-string 1 bt) bt))))
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1034 bt))
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1035
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1036 (put 'with-trapping-errors 'lisp-indent-function 0)
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1037 (defmacro with-trapping-errors (&rest keys-body)
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1038 "Trap errors in BODY, outputting a warning and a backtrace.
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1039 Usage looks like
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1040
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1041 \(with-trapping-errors
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1042 [:operation OPERATION]
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1043 [:error-form ERROR-FORM]
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1044 [:no-backtrace NO-BACKTRACE]
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1045 [:class CLASS]
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1046 [:level LEVEL]
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1047 [:resignal RESIGNAL]
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1048 BODY)
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1049
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1050 Return value without error is whatever BODY returns. With error, return
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1051 result of ERROR-FORM (which will be evaluated only when the error actually
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1052 occurs), which defaults to nil. OPERATION is given in the warning message.
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1053 CLASS and LEVEL are the warning class and level (default to class
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1054 `general', level `warning'). If NO-BACKTRACE is given, no backtrace is
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1055 displayed. If RESIGNAL is given, the error is resignaled after the warning
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1056 is displayed and the ERROR-FORM is executed."
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1057 (let ((operation "unknown")
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1058 (error-form nil)
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1059 (no-backtrace nil)
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1060 (class ''general)
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1061 (level ''warning)
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1062 (resignal nil))
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1063 (let* ((keys '(operation error-form no-backtrace class level resignal))
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1064 (keys-with-colon
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1065 (mapcar #'(lambda (sym)
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1066 (intern (concat ":" (symbol-name sym)))) keys)))
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1067 (while (memq (car keys-body) keys-with-colon)
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1068 (let* ((key-with-colon (pop keys-body))
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1069 (key (intern (substring (symbol-name key-with-colon) 1))))
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1070 (set key (pop keys-body)))))
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1071 `(condition-case ,(if resignal '__cte_cc_var__ nil)
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1072 (call-with-condition-handler
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1073 #'(lambda (__call_trapping_errors_arg__)
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1074 (let ((errstr (error-message-string
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1075 __call_trapping_errors_arg__)))
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1076 ,(if no-backtrace
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1077 `(lwarn ,class ,level
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1078 (if (warning-level-<
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1079 ,level
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1080 display-warning-minimum-level)
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1081 "Error in %s: %s"
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1082 "Error in %s:\n%s\n")
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1083 ,operation errstr)
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1084 `(lwarn ,class ,level
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1085 "Error in %s: %s\n\nBacktrace follows:\n\n%s"
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1086 ,operation errstr
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1087 (backtrace-in-condition-handler-eliminating-handler
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1088 '__call_trapping_errors_arg__)))))
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1089 #'(lambda ()
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1090 (progn ,@keys-body)))
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1091 (error
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1092 ,error-form
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1093 ,@(if resignal '((signal (car __cte_cc_var__) (cdr __cte_cc_var__)))))
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1094 )))
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 783
diff changeset
1095
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1096 ;;;; Miscellanea.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1097
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1098 ;; This is now in C.
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
1099 ;(defun buffer-substring-no-properties (start end)
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
1100 ; "Return the text from START to END, without text properties, as a string."
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
1101 ; (let ((string (buffer-substring start end)))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1102 ; (set-text-properties 0 (length string) nil string)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1103 ; string))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1104
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1105 (defun get-buffer-window-list (&optional buffer minibuf frame)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1106 "Return windows currently displaying BUFFER, or nil if none.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1107 BUFFER defaults to the current buffer.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1108 See `walk-windows' for the meaning of MINIBUF and FRAME."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1109 (cond ((null buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1110 (setq buffer (current-buffer)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1111 ((not (bufferp buffer))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1112 (setq buffer (get-buffer buffer))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1113 (let (windows)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1114 (walk-windows (lambda (window)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1115 (if (eq (window-buffer window) buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1116 (push window windows)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1117 minibuf frame)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1118 windows))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1119
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1120 (defun ignore (&rest ignore)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1121 "Do nothing and return nil.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1122 This function accepts any number of arguments, but ignores them."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1123 (interactive)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1124 nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1125
883
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
1126 ;; defined in lisp/bindings.el in GNU Emacs.
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
1127 (defmacro bound-and-true-p (var)
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
1128 "Return the value of symbol VAR if it is bound, else nil."
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
1129 `(and (boundp (quote ,var)) ,var))
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
1130
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
1131 ;; `propertize' is a builtin in GNU Emacs 21.
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
1132 (defun propertize (string &rest properties)
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
1133 "Return a copy of STRING with text properties added.
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
1134 First argument is the string to copy.
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
1135 Remaining arguments form a sequence of PROPERTY VALUE pairs for text
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
1136 properties to add to the result."
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
1137 (let ((str (copy-sequence string)))
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
1138 (add-text-properties 0 (length str)
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
1139 properties
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
1140 str)
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
1141 str))
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
1142
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
1143 ;; `delete-and-extract-region' is a builtin in GNU Emacs 21.
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
1144 (defun delete-and-extract-region (start end)
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
1145 "Delete the text between START and END and return it."
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
1146 (let ((region (buffer-substring start end)))
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
1147 (delete-region start end)
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
1148 region))
1e9272790fe0 [xemacs-hg @ 2002-06-26 00:11:15 by youngs]
youngs
parents: 878
diff changeset
1149
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1150 (define-function 'eval-in-buffer 'with-current-buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1151 (make-obsolete 'eval-in-buffer 'with-current-buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1152
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1153 ;;; The real defn is in abbrev.el but some early callers
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1154 ;;; (eg lisp-mode-abbrev-table) want this before abbrev.el is loaded...
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1155
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1156 (if (not (fboundp 'define-abbrev-table))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1157 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1158 (setq abbrev-table-name-list '())
924
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
1159 (fset 'define-abbrev-table
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
1160 (function (lambda (name defs)
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
1161 ;; These are fixed-up when abbrev.el loads.
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
1162 (setq abbrev-table-name-list
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
1163 (cons (cons name defs)
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
1164 abbrev-table-name-list)))))))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1165
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1166 ;;; `functionp' has been moved into C.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1167
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1168 ;;(defun functionp (object)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1169 ;; "Non-nil if OBJECT can be called as a function."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1170 ;; (or (and (symbolp object) (fboundp object))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1171 ;; (subrp object)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1172 ;; (compiled-function-p object)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1173 ;; (eq (car-safe object) 'lambda)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1174
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1175 (defun function-interactive (function)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1176 "Return the interactive specification of FUNCTION.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1177 FUNCTION can be any funcallable object.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1178 The specification will be returned as the list of the symbol `interactive'
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1179 and the specs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1180 If FUNCTION is not interactive, nil will be returned."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1181 (setq function (indirect-function function))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1182 (cond ((compiled-function-p function)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1183 (compiled-function-interactive function))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1184 ((subrp function)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1185 (subr-interactive function))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1186 ((eq (car-safe function) 'lambda)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1187 (let ((spec (if (stringp (nth 2 function))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1188 (nth 3 function)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1189 (nth 2 function))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1190 (and (eq (car-safe spec) 'interactive)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1191 spec)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1192 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1193 (error "Non-funcallable object: %s" function))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1194
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
1195 (defun function-allows-args (function n)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
1196 "Return whether FUNCTION can be called with N arguments."
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
1197 (and (<= (function-min-args function) n)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
1198 (or (null (function-max-args function))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
1199 (<= n (function-max-args function)))))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
1200
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1201 ;; This function used to be an alias to `buffer-substring', except
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1202 ;; that FSF Emacs 20.4 added a BUFFER argument in an incompatible way.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1203 ;; The new FSF's semantics makes more sense, but we try to support
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1204 ;; both for backward compatibility.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1205 (defun buffer-string (&optional buffer old-end old-buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1206 "Return the contents of the current buffer as a string.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1207 If narrowing is in effect, this function returns only the visible part
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1208 of the buffer.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1209
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1210 If BUFFER is specified, the contents of that buffer are returned.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1211
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1212 The arguments OLD-END and OLD-BUFFER are supported for backward
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1213 compatibility with pre-21.2 XEmacsen times when arguments to this
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1214 function were (buffer-string &optional START END BUFFER)."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1215 (cond
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1216 ((or (stringp buffer) (bufferp buffer))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1217 ;; Most definitely the new way.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1218 (buffer-substring nil nil buffer))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1219 ((or (stringp old-buffer) (bufferp old-buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1220 (natnump buffer) (natnump old-end))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1221 ;; Definitely the old way.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1222 (buffer-substring buffer old-end old-buffer))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1223 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1224 ;; Probably the old way.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1225 (buffer-substring buffer old-end old-buffer))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1226
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1227 ;; This was not present before. I think Jamie had some objections
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1228 ;; to this, so I'm leaving this undefined for now. --ben
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1229
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1230 ;;; The objection is this: there is more than one way to load the same file.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1231 ;;; "foo", "foo.elc", "foo.el", and "/some/path/foo.elc" are all different
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1232 ;;; ways to load the exact same code. `eval-after-load' is too stupid to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1233 ;;; deal with this sort of thing. If this sort of feature is desired, then
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1234 ;;; it should work off of a hook on `provide'. Features are unique and
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1235 ;;; the arguments to (load) are not. --Stig
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1236
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1237 ;; We provide this for FSFmacs compatibility, at least until we devise
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1238 ;; something better.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1239
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1240 ;;;; Specifying things to do after certain files are loaded.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1241
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1242 (defun eval-after-load (file form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1243 "Arrange that, if FILE is ever loaded, FORM will be run at that time.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1244 This makes or adds to an entry on `after-load-alist'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1245 If FILE is already loaded, evaluate FORM right now.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1246 It does nothing if FORM is already on the list for FILE.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1247 FILE should be the name of a library, with no directory name."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1248 ;; Make sure there is an element for FILE.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1249 (or (assoc file after-load-alist)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1250 (setq after-load-alist (cons (list file) after-load-alist)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1251 ;; Add FORM to the element if it isn't there.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1252 (let ((elt (assoc file after-load-alist)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1253 (or (member form (cdr elt))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1254 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1255 (nconc elt (list form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1256 ;; If the file has been loaded already, run FORM right away.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1257 (and (assoc file load-history)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1258 (eval form)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1259 form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1260 (make-compatible 'eval-after-load "")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1261
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1262 (defun eval-next-after-load (file)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1263 "Read the following input sexp, and run it whenever FILE is loaded.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1264 This makes or adds to an entry on `after-load-alist'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1265 FILE should be the name of a library, with no directory name."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1266 (eval-after-load file (read)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1267 (make-compatible 'eval-next-after-load "")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1268
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1269 ; alternate names (not obsolete)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1270 (if (not (fboundp 'mod)) (define-function 'mod '%))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1271 (define-function 'move-marker 'set-marker)
924
1b114504fa80 [xemacs-hg @ 2002-07-16 08:18:35 by didierv]
didierv
parents: 883
diff changeset
1272 (define-function 'beep 'ding) ; preserve lingual purity
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1273 (define-function 'indent-to-column 'indent-to)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1274 (define-function 'backward-delete-char 'delete-backward-char)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1275 (define-function 'search-forward-regexp (symbol-function 're-search-forward))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1276 (define-function 'search-backward-regexp (symbol-function 're-search-backward))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1277 (define-function 'remove-directory 'delete-directory)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1278 (define-function 'set-match-data 'store-match-data)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1279 (define-function 'send-string-to-terminal 'external-debugging-output)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1280
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1281 ;;; subr.el ends here