Emacs Lisp: Exit Loop or Function (throw, catch, break, exit, return)
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. - use
seq-some
for iteration. [see Emacs Lisp: Sequence Functions]
catch
-
(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
-
(throw 'tagName passValue)
Jump to a outer
(catch 'tagName)
and continue there, passing the value of passValue to it. Both tagName passValue are evaluated.;; 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))))
Exit a Function
Here is a example using throw to exit a function. Throw is like simulating the return statement in other langs.
;; demo using catch/throw to exit function. (defun xx-test-exit (x) "if x is greater than 5, return string yes, else return no" ;; here, throw is similar to the return in other langs (catch 'aaa (if (> x 5) (progn (throw 'aaa "yes")) (progn "no" )))) (string-equal (xx-test-exit 2) "no") (string-equal (xx-test-exit 6) "yes")
Exit by Error
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 Iteration
You can also use throw
to exit a map or loop.
Tip: you can also use seq-some
.
[see Emacs Lisp: Sequence Functions]
;; demo using throw catch to exit a mapping (let ((xseq [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))) xseq) nil ))