Search code examples
emacselisp

How do I intercept Ctrl-G in Emacs


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.


Solution

  • 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.