aboutsummaryrefslogtreecommitdiffstats
path: root/test/src
diff options
context:
space:
mode:
authorStefan Monnier2023-12-25 22:32:17 -0500
committerStefan Monnier2024-01-04 16:32:53 -0500
commit5ba75e183c60aff50949587c21066e876dabfbda (patch)
treedb29f1ea2ef53d51ebb7ed1b8be999a664498f89 /test/src
parent225710ba79c10b53b6ba320327ca31192ca72387 (diff)
downloademacs-5ba75e183c60aff50949587c21066e876dabfbda.tar.gz
emacs-5ba75e183c60aff50949587c21066e876dabfbda.zip
New special form `handler-bind`
AFAIK, this provides the same semantics as Common Lisp's `handler-bind`, modulo the differences about how error objects and conditions are represented. * lisp/subr.el (handler-bind): New macro. * src/eval.c (pop_handler): New function. (Fhandler_Bind_1): New function. (signal_or_quit): Handle new handlertypes `HANDLER` and `SKIP_CONDITIONS`. (find_handler_clause): Simplify. (syms_of_eval): Defsubr `Fhandler_bind_1`. * doc/lispref/control.texi (Handling Errors): Add `handler-bind`. * test/src/eval-tests.el (eval-tests--handler-bind): New test. * lisp/emacs-lisp/lisp-mode.el (lisp-font-lock-keywords): Move 'handler-bind' from CL-only to generic Lisp. (handler-bind): Remove indentation setting, it now lives in the macro definition.
Diffstat (limited to 'test/src')
-rw-r--r--test/src/eval-tests.el37
1 files changed, 37 insertions, 0 deletions
diff --git a/test/src/eval-tests.el b/test/src/eval-tests.el
index e4b18ec7849..9ac117859dd 100644
--- a/test/src/eval-tests.el
+++ b/test/src/eval-tests.el
@@ -303,4 +303,41 @@ expressions works for identifiers starting with period."
303 (should (eq 'bar (default-value 'eval-tests/buffer-local-var))) 303 (should (eq 'bar (default-value 'eval-tests/buffer-local-var)))
304 (should (eq 'bar eval-tests/buffer-local-var))))) 304 (should (eq 'bar eval-tests/buffer-local-var)))))
305 305
306(ert-deftest eval-tests--handler-bind ()
307 ;; A `handler-bind' has no effect if no error is signaled.
308 (should (equal (catch 'tag
309 (handler-bind ((error (lambda (_err) (throw 'tag 'wow))))
310 'noerror))
311 'noerror))
312 ;; The handler is called from within the dynamic extent where the
313 ;; error is signaled, unlike `condition-case'.
314 (should (equal (catch 'tag
315 (handler-bind ((error (lambda (_err) (throw 'tag 'err))))
316 (list 'inner-catch
317 (catch 'tag
318 (user-error "hello")))))
319 '(inner-catch err)))
320 ;; But inner condition handlers are temporarily muted.
321 (should (equal (condition-case nil
322 (handler-bind
323 ((error (lambda (_err)
324 (signal 'wrong-type-argument nil))))
325 (list 'result
326 (condition-case nil
327 (user-error "hello")
328 (wrong-type-argument 'inner-handler))))
329 (wrong-type-argument 'wrong-type-argument))
330 'wrong-type-argument))
331 ;; Handlers do not apply to the code run within the handlers.
332 (should (equal (condition-case nil
333 (handler-bind
334 ((error (lambda (_err)
335 (signal 'wrong-type-argument nil)))
336 (wrong-type-argument
337 (lambda (_err) (user-error "wrong-type-argument"))))
338 (user-error "hello"))
339 (wrong-type-argument 'wrong-type-argument)
340 (error 'plain-error))
341 'wrong-type-argument)))
342
306;;; eval-tests.el ends here 343;;; eval-tests.el ends here