Emacs Lisp: throw, catch, exit function
To exit a loop or exit a function:
- Use
catch
andthrow
to exit loop/function. These are like “break”, “goto” in other programing languages. - Use
error
oruser-error
to signal a error and exit.
Exit a Function
To exit a function, first wrap the function body by
(catch 'tagName body)
and put
(throw 'tagName value)
at the place you want to exit.
(catch 'tagName body)
-
Evaluates body and return body's last expression, but if body contains
(throw …)
and it is called, return the value throw passes. (throw 'tagName passValue)
-
Jump to a outer
(catch 'tagName)
and continue there, passing the value of passValue to it. Both tagName passValue are evaluated.
(info "(elisp) Catch and Throw")
example:
(defun test-exit-f () "example. using catch/throw to exit function" (interactive) (catch 'aaa (if (y-or-n-p "exit?") (progn (message "existing") (throw 'aaa 3) ; if yes, exit right away, return 3 to catch ) (progn ; else, go on (message "went on") 4 ; return 4 ))))
Exit by Error
You can exit by calling
error
or
user-error
.
(defun test-exit-f () "example" (interactive) (if (y-or-n-p "invoke user-error to exit?") (user-error "Error, because: %s" "you said so!") (progn ; else, go on (message "went on") )))
Exit a map
You can also use throw
and catch
to exit a map or loop.
(setq myList [0 1 2 3 4 5]) ;; map lambda onto a list. If value 3 is found, return 3, else nil (catch 'bbb (mapc (lambda (x) (message "%s" x) (when (equal x 3) (throw 'bbb x))) myList) nil )
Exit a While Loop
;; example of exit a while loop ;; prints a random integer between 0 to 10, inclusive ;; if 5 comes up, then exit after printing it (catch 'abc (while (setq xx (random 10)) (message "%s" xx) (when (eq 5 xx) (throw 'abc t))))