Mercurial > emacs
annotate lisp/emacs-lisp/eval-reg.el @ 24618:b18f51ec1b6c
Trap X errors so that Emacs doesn't die
by them.
author | Kenichi Handa <handa@m17n.org> |
---|---|
date | Tue, 13 Apr 1999 00:51:52 +0000 |
parents | bb42066bb94a |
children | 69699e7e8e81 |
rev | line source |
---|---|
6807
13fc66bc7472
Renamed from eval-region.el. Fix the `provide' call.
Richard M. Stallman <rms@gnu.org>
parents:
6781
diff
changeset
|
1 ;;; eval-reg.el --- Redefine eval-region, and subrs that use it, in Lisp |
6781 | 2 |
22549
bb42066bb94a
Change copyright notice.
Richard M. Stallman <rms@gnu.org>
parents:
22464
diff
changeset
|
3 ;; Copyright (C) 1994, 1996 Free Software Foundation, Inc. |
6491 | 4 |
6781 | 5 ;; Author: Daniel LaLiberte <liberte@cs.uiuc.edu> |
6 ;; Keywords: lisp | |
7 | |
6685 | 8 ;; This file is part of GNU Emacs. |
6491 | 9 |
10 ;; GNU Emacs is free software; you can redistribute it and/or modify | |
11 ;; it under the terms of the GNU General Public License as published by | |
6685 | 12 ;; the Free Software Foundation; either version 2, or (at your option) |
6491 | 13 ;; any later version. |
14 | |
15 ;; GNU Emacs is distributed in the hope that it will be useful, | |
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 ;; GNU General Public License for more details. | |
19 | |
20 ;; You should have received a copy of the GNU General Public License | |
21 ;; along with GNU Emacs; see the file COPYING. If not, write to | |
14182 | 22 ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
23 ;; Boston, MA 02111-1307, USA. | |
6491 | 24 |
14169 | 25 ;;; Commentary: |
6491 | 26 |
14169 | 27 ;; eval-region, eval-buffer, and eval-current-buffer are redefined in |
28 ;; Lisp to allow customizations by Lisp code. eval-region calls | |
29 ;; `read', `eval', and `prin1', so Lisp replacements of these | |
30 ;; functions will affect eval-region and anything else that calls it. | |
31 ;; eval-buffer and eval-current-buffer are redefined in Lisp to call | |
32 ;; eval-region on the buffer. | |
6491 | 33 |
14169 | 34 ;; Because of dynamic binding, all local variables are protected from |
35 ;; being seen by eval by giving them funky names. But variables in | |
36 ;; routines that call eval-region are similarly exposed. | |
6491 | 37 |
14169 | 38 ;; Perhaps this should be one of several files in an `elisp' package |
39 ;; that replaces Emacs Lisp subroutines with Lisp versions of the | |
40 ;; same. | |
6491 | 41 |
14169 | 42 ;; Eval-region may be installed, after loading, by calling: |
43 ;; (elisp-eval-region-install). Installation can be undone with: | |
44 ;; (elisp-eval-region-uninstall). | |
45 | |
46 ;;; Code: | |
6491 | 47 |
48 '(defpackage "elisp-eval-region" | |
49 (:nicknames "elisp") | |
50 (:use "elisp") | |
51 (:export | |
6667
569c3687217f
Change install- to ... to ...-install.
Daniel LaLiberte <liberte@gnu.org>
parents:
6491
diff
changeset
|
52 elisp-eval-region-install |
569c3687217f
Change install- to ... to ...-install.
Daniel LaLiberte <liberte@gnu.org>
parents:
6491
diff
changeset
|
53 elisp-eval-region-uninstall |
6491 | 54 elisp-eval-region-level |
55 with-elisp-eval-region | |
6781 | 56 eval-region |
57 eval-buffer | |
58 eval-current-buffer | |
6491 | 59 )) |
60 '(in-package elisp-eval-region) | |
61 | |
62 ;; Save standard versions. | |
63 (if (not (fboundp 'original-eval-region)) | |
64 (defalias 'original-eval-region (symbol-function 'eval-region))) | |
65 (if (not (fboundp 'original-eval-buffer)) | |
66 (defalias 'original-eval-buffer | |
67 (if (fboundp 'eval-buffer) ;; only in Emacs 19 | |
68 (symbol-function 'eval-buffer) | |
69 'undefined))) | |
70 (if (not (fboundp 'original-eval-current-buffer)) | |
71 (defalias 'original-eval-current-buffer | |
72 (symbol-function 'eval-current-buffer))) | |
73 | |
74 (defvar elisp-eval-region-level 0 | |
6807
13fc66bc7472
Renamed from eval-region.el. Fix the `provide' call.
Richard M. Stallman <rms@gnu.org>
parents:
6781
diff
changeset
|
75 "If the value is 0, use the original version of `elisp-eval-region'. |
13fc66bc7472
Renamed from eval-region.el. Fix the `provide' call.
Richard M. Stallman <rms@gnu.org>
parents:
6781
diff
changeset
|
76 Callers of `elisp-eval-region' should increment `elisp-eval-region-level' |
13fc66bc7472
Renamed from eval-region.el. Fix the `provide' call.
Richard M. Stallman <rms@gnu.org>
parents:
6781
diff
changeset
|
77 while the Lisp version should be used. Installing `elisp-eval-region' |
6491 | 78 increments it once, and uninstalling decrements it.") |
79 | |
6667
569c3687217f
Change install- to ... to ...-install.
Daniel LaLiberte <liberte@gnu.org>
parents:
6491
diff
changeset
|
80 ;; Installing and uninstalling should always be used in pairs, |
569c3687217f
Change install- to ... to ...-install.
Daniel LaLiberte <liberte@gnu.org>
parents:
6491
diff
changeset
|
81 ;; or just install once and never uninstall. |
569c3687217f
Change install- to ... to ...-install.
Daniel LaLiberte <liberte@gnu.org>
parents:
6491
diff
changeset
|
82 (defun elisp-eval-region-install () |
6491 | 83 (interactive) |
84 (defalias 'eval-region 'elisp-eval-region) | |
85 (defalias 'eval-buffer 'elisp-eval-buffer) | |
86 (defalias 'eval-current-buffer 'elisp-eval-current-buffer) | |
87 (setq elisp-eval-region-level (1+ elisp-eval-region-level))) | |
88 | |
6667
569c3687217f
Change install- to ... to ...-install.
Daniel LaLiberte <liberte@gnu.org>
parents:
6491
diff
changeset
|
89 (defun elisp-eval-region-uninstall () |
6491 | 90 (interactive) |
91 (if (> 1 elisp-eval-region-level) | |
92 (setq elisp-eval-region-level (1- elisp-eval-region-level)) | |
93 (setq elisp-eval-region-level 0) | |
94 (defalias 'eval-region (symbol-function 'original-eval-region)) | |
95 (defalias 'eval-buffer (symbol-function 'original-eval-buffer)) | |
96 (defalias 'eval-current-buffer | |
97 (symbol-function 'original-eval-current-buffer)) | |
98 )) | |
99 | |
100 (put 'with-elisp-eval-region 'lisp-indent-function 1) | |
101 (put 'with-elisp-eval-region 'lisp-indent-hook 1) | |
102 (put 'with-elisp-eval-region 'edebug-form-spec t) | |
103 | |
104 (defmacro with-elisp-eval-region (flag &rest body) | |
6807
13fc66bc7472
Renamed from eval-region.el. Fix the `provide' call.
Richard M. Stallman <rms@gnu.org>
parents:
6781
diff
changeset
|
105 "If FLAG is nil, decrement `eval-region-level' while executing BODY. |
6491 | 106 The effect of decrementing all the way to zero is that `eval-region' |
6807
13fc66bc7472
Renamed from eval-region.el. Fix the `provide' call.
Richard M. Stallman <rms@gnu.org>
parents:
6781
diff
changeset
|
107 will use the original `eval-region', which may be the Emacs subr or some |
6491 | 108 previous redefinition. Before calling this macro, this package should |
6667
569c3687217f
Change install- to ... to ...-install.
Daniel LaLiberte <liberte@gnu.org>
parents:
6491
diff
changeset
|
109 already have been installed, using `elisp-eval-region-install', which |
6491 | 110 increments the count once. So if another package still requires the |
6807
13fc66bc7472
Renamed from eval-region.el. Fix the `provide' call.
Richard M. Stallman <rms@gnu.org>
parents:
6781
diff
changeset
|
111 Lisp version of the code, the count will still be non-zero. |
6491 | 112 |
113 The count is not bound locally by this macro, so changes by BODY to | |
114 its value will not be lost." | |
115 (` (let ((elisp-code (function (lambda () (,@ body))))) | |
116 (if (not (, flag)) | |
117 (unwind-protect | |
118 (progn | |
119 (setq elisp-eval-region-level (1- elisp-eval-region-level)) | |
120 (funcall elisp-code)) | |
121 (setq elisp-eval-region-level (1+ elisp-eval-region-level))) | |
122 (funcall elisp-code))))) | |
123 | |
124 | |
22464
fc8109f5d8f5
(elisp-eval-region): Accept new arg read-function; also handle
Richard M. Stallman <rms@gnu.org>
parents:
19893
diff
changeset
|
125 (defun elisp-eval-region (elisp-start elisp-end &optional elisp-output |
fc8109f5d8f5
(elisp-eval-region): Accept new arg read-function; also handle
Richard M. Stallman <rms@gnu.org>
parents:
19893
diff
changeset
|
126 elisp-read-function) |
6491 | 127 "Execute the region as Lisp code. |
128 When called from programs, expects two arguments, | |
129 giving starting and ending indices in the current buffer | |
130 of the text to be executed. | |
131 Programs can pass third argument PRINTFLAG which controls printing of output: | |
132 nil means discard it; anything else is stream for print. | |
133 | |
22464
fc8109f5d8f5
(elisp-eval-region): Accept new arg read-function; also handle
Richard M. Stallman <rms@gnu.org>
parents:
19893
diff
changeset
|
134 Also the fourth argument READ-FUNCTION, if non-nil, is used |
fc8109f5d8f5
(elisp-eval-region): Accept new arg read-function; also handle
Richard M. Stallman <rms@gnu.org>
parents:
19893
diff
changeset
|
135 instead of `read' to read each expression. It gets one argument |
fc8109f5d8f5
(elisp-eval-region): Accept new arg read-function; also handle
Richard M. Stallman <rms@gnu.org>
parents:
19893
diff
changeset
|
136 which is the input stream for reading characters. |
fc8109f5d8f5
(elisp-eval-region): Accept new arg read-function; also handle
Richard M. Stallman <rms@gnu.org>
parents:
19893
diff
changeset
|
137 |
6807
13fc66bc7472
Renamed from eval-region.el. Fix the `provide' call.
Richard M. Stallman <rms@gnu.org>
parents:
6781
diff
changeset
|
138 This version, from `eval-reg.el', allows Lisp customization of read, |
6491 | 139 eval, and the printer." |
140 | |
14040 | 141 ;; Because this doesn't narrow to the region, one other difference |
6491 | 142 ;; concerns inserting whitespace after the expression being evaluated. |
143 | |
144 (interactive "r") | |
145 (if (= 0 elisp-eval-region-level) | |
146 (original-eval-region elisp-start elisp-end elisp-output) | |
147 (let ((elisp-pnt (point)) | |
148 (elisp-buf (current-buffer));; Outside buffer | |
14040 | 149 (elisp-inside-buf (current-buffer));; Buffer current while evalling |
6491 | 150 ;; Mark the end because it may move. |
151 (elisp-end-marker (set-marker (make-marker) elisp-end)) | |
152 elisp-form | |
153 elisp-val) | |
154 (goto-char elisp-start) | |
155 (elisp-skip-whitespace) | |
156 (while (< (point) elisp-end-marker) | |
22464
fc8109f5d8f5
(elisp-eval-region): Accept new arg read-function; also handle
Richard M. Stallman <rms@gnu.org>
parents:
19893
diff
changeset
|
157 (setq elisp-form |
fc8109f5d8f5
(elisp-eval-region): Accept new arg read-function; also handle
Richard M. Stallman <rms@gnu.org>
parents:
19893
diff
changeset
|
158 (cond (elisp-read-function |
fc8109f5d8f5
(elisp-eval-region): Accept new arg read-function; also handle
Richard M. Stallman <rms@gnu.org>
parents:
19893
diff
changeset
|
159 (funcall elisp-read-function elisp-buf)) |
fc8109f5d8f5
(elisp-eval-region): Accept new arg read-function; also handle
Richard M. Stallman <rms@gnu.org>
parents:
19893
diff
changeset
|
160 (load-read-function |
fc8109f5d8f5
(elisp-eval-region): Accept new arg read-function; also handle
Richard M. Stallman <rms@gnu.org>
parents:
19893
diff
changeset
|
161 (funcall load-read-function elisp-buf)) |
fc8109f5d8f5
(elisp-eval-region): Accept new arg read-function; also handle
Richard M. Stallman <rms@gnu.org>
parents:
19893
diff
changeset
|
162 (t |
fc8109f5d8f5
(elisp-eval-region): Accept new arg read-function; also handle
Richard M. Stallman <rms@gnu.org>
parents:
19893
diff
changeset
|
163 (read elisp-buf)))) |
6491 | 164 |
165 (let ((elisp-current-buffer (current-buffer))) | |
166 ;; Restore the inside current-buffer. | |
167 (set-buffer elisp-inside-buf) | |
168 (setq elisp-val (eval elisp-form)) | |
169 ;; Remember current buffer for next time. | |
170 (setq elisp-inside-buf (current-buffer)) | |
171 ;; Should this be protected? | |
172 (set-buffer elisp-current-buffer)) | |
173 | |
174 (if elisp-output | |
175 (let ((standard-output (or elisp-output t))) | |
176 (setq values (cons elisp-val values)) | |
177 (if (eq standard-output t) | |
178 (prin1 elisp-val) | |
179 (princ "\n") | |
180 (prin1 elisp-val) | |
181 (princ "\n") | |
182 ))) | |
183 (goto-char (min (max elisp-end-marker (point)) | |
184 (progn (elisp-skip-whitespace) (point)))) | |
185 ) ; while | |
186 (if elisp-output nil | |
187 ;; like save-excursion recovery, but done only if no error occurs | |
188 ;; but mark is not restored | |
189 (set-buffer elisp-buf) | |
190 (goto-char elisp-pnt)) | |
191 nil))) | |
192 | |
193 | |
194 (defun elisp-skip-whitespace () | |
195 ;; Leave point before the next token, skipping white space and comments. | |
196 (skip-chars-forward " \t\r\n\f") | |
197 (while (= (following-char) ?\;) | |
198 (skip-chars-forward "^\n\r") ; skip the comment | |
199 (skip-chars-forward " \t\r\n\f"))) | |
200 | |
201 | |
202 (defun elisp-eval-current-buffer (&optional elisp-output) | |
203 "Execute the current buffer as Lisp code. | |
204 Programs can pass argument PRINTFLAG which controls printing of output: | |
205 nil means discard it; anything else is stream for print. | |
206 | |
6807
13fc66bc7472
Renamed from eval-region.el. Fix the `provide' call.
Richard M. Stallman <rms@gnu.org>
parents:
6781
diff
changeset
|
207 This version calls `eval-region' on the whole buffer." |
6491 | 208 ;; The standard eval-current-buffer doesn't use eval-region. |
209 (interactive) | |
210 (eval-region (point-min) (point-max) elisp-output)) | |
211 | |
212 | |
19893
14e5e43d8626
(elisp-eval-buffer): New arg FILENAME is ignored.
Richard M. Stallman <rms@gnu.org>
parents:
14182
diff
changeset
|
213 (defun elisp-eval-buffer (&optional elisp-bufname elisp-printflag filename) |
6491 | 214 "Execute BUFFER as Lisp code. Use current buffer if BUFFER is nil. |
215 Programs can pass argument PRINTFLAG which controls printing of | |
216 output: nil means discard it; anything else is stream for print. | |
217 | |
19893
14e5e43d8626
(elisp-eval-buffer): New arg FILENAME is ignored.
Richard M. Stallman <rms@gnu.org>
parents:
14182
diff
changeset
|
218 The argument FILENAME is accepted and ignored, just to avoid |
14e5e43d8626
(elisp-eval-buffer): New arg FILENAME is ignored.
Richard M. Stallman <rms@gnu.org>
parents:
14182
diff
changeset
|
219 crashes. |
14e5e43d8626
(elisp-eval-buffer): New arg FILENAME is ignored.
Richard M. Stallman <rms@gnu.org>
parents:
14182
diff
changeset
|
220 |
6807
13fc66bc7472
Renamed from eval-region.el. Fix the `provide' call.
Richard M. Stallman <rms@gnu.org>
parents:
6781
diff
changeset
|
221 This version calls `eval-region' on the whole buffer." |
6491 | 222 (interactive) |
223 (if (null elisp-bufname) | |
224 (setq elisp-bufname (current-buffer))) | |
225 (save-excursion | |
226 (set-buffer (or (get-buffer elisp-bufname) | |
227 (error "No such buffer: %s" elisp-bufname))) | |
228 (eval-region (point-min) (point-max) elisp-printflag))) | |
229 | |
230 | |
6807
13fc66bc7472
Renamed from eval-region.el. Fix the `provide' call.
Richard M. Stallman <rms@gnu.org>
parents:
6781
diff
changeset
|
231 (provide 'eval-reg) |
6781 | 232 |
11035 | 233 ;;; eval-reg.el ends here |