如何在Emacs中拦截Ctrl-G

时间:2022-05-06 23:52:45

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.

我有一个Emacs的elisp脚本,如果用户点击Ctrl + G,我想要清理一下。我使用'read-event'来捕获所有事件,但这并没有捕获Ctrl + G.当按下Ctrl + G时,它会停止执行。

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.

在XEmacs中,当您调用next-command-event时,它将为您提供所有事件,包括用户按Ctrl + G时的事件。在Emacs中必须有一些等价物。

2 个解决方案

#1


You can use with-local-quit to determine if C-g was pressed:

您可以使用with-local-quit来确定是否按下了C-g:

Edited solution to swallow quit as suggested by efunneko.

根据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.

注意:with-local-quit返回最后一个表达式的值,如果按下C-g则返回nil,因此当没有按下C-g时,请务必返回非零值。我发现退出的elisp文档很有用。相关区域是非本地退出,特别是解除保护,这不仅适用于退出。

#2


condition-case and unwind-protect are helpful here. condition-case lets you "catch" "exceptions", of which quit is one:

条件 - 案例和放松 - 保护在这里很有帮助。 condition-case让你“捕获”“异常”,其中quit是一个:

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

您希望在您的情况下放松保护。

#1


You can use with-local-quit to determine if C-g was pressed:

您可以使用with-local-quit来确定是否按下了C-g:

Edited solution to swallow quit as suggested by efunneko.

根据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.

注意:with-local-quit返回最后一个表达式的值,如果按下C-g则返回nil,因此当没有按下C-g时,请务必返回非零值。我发现退出的elisp文档很有用。相关区域是非本地退出,特别是解除保护,这不仅适用于退出。

#2


condition-case and unwind-protect are helpful here. condition-case lets you "catch" "exceptions", of which quit is one:

条件 - 案例和放松 - 保护在这里很有帮助。 condition-case让你“捕获”“异常”,其中quit是一个:

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

您希望在您的情况下放松保护。