I have a elisp script for Emacs that I want to do some clean up in if a user hits Ctrl+G. I use 'read-event' to catch all events, but this does not catch the Ctrl+G. When Ctrl+G is hit, it just stops execution.
In XEmacs, when you call next-command-event it will give you all events including when a user hits Ctrl+G. There must be some equivalent in Emacs.
You can use with-local-quit
to determine if C-g
was pressed:
Edited solution to swallow quit as suggested by efunneko.
(defun my-c-g-test ()
"test catching control-g"
(interactive)
(let ((inhibit-quit t))
(unless (with-local-quit
(y-or-n-p "arg you gonna type C-g?")
t)
(progn
(message "you hit C-g")
(setq quit-flag nil)))))
Note: with-local-quit returns the value of the last expression, or nil
if C-g
is pressed, so be sure to return something non-nil when no C-g
is pressed. I found the elisp documentation on quitting useful. A related area is nonlocal exits, and specifically unwind-protect
, which applies to more than just quit.
condition-case
and unwind-protect
are helpful here. condition-case
lets you "catch" "exceptions", of which quit is one:
(condition-case
(while t) ; never terminates
(quit (message "C-g was pressed")))
You can also catch other errors, like "error".
unwind-protect
is like finally; it will execute "body forms" and then "unwind forms". However, the "unwind forms" are executed regardless of whether the "body forms" ran successfully:
(unwind-protect
(while t)
(message "Done with infinite loop"))
You want unwind-protect
in your case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With