2009-05-19 90 views
6

我有一个Emacs的elisp脚本,我想在用户点击时进行一些清理工作Ctrl + G。我使用'阅读事件'来捕捉所有事件,但这并不赶上Ctrl + G。当Ctrl + G被击中时,它只是停止执行。如何拦截Emacs中的Ctrl-G

在XEmacs中,当你调用下一个命令事件,当用户点击按Ctrl +它会给你所有的活动,包括。 Emacs中必须有一些等价物。

回答

11

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

编辑解决方案吞下退出由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))))) 

注:与本地-quit返回最后一个表达式的值,或nil如果C-g被按下,所以一定要在没有按下C-g返回的东西非空。我发现有关quitting的elisp文档很有用。一个相关的领域是nonlocal exits,特别是unwind-protect,它不仅仅适用于退出。

+0

这解决了部分问题,但它并没有吞下控制 - 只是让你知道它发生了。如果你想防止control-g转义块,使用'inhibit-quit'和'quit-flag'变量。 – efunneko 2009-05-19 19:30:00

+1

这是可怕和脆弱的。我很确定,OP所需要的任何东西都可以通过`condition-case`或`unwind-protect`来更简单,更健壮地解决。 – Stefan 2017-12-12 14:30:22

5

condition-caseunwind-protect在这里很有帮助。 condition-case让你“捕获”,“例外”,它的退出是一个:

(condition-case 
    (while t) ; never terminates 
    (quit (message "C-g was pressed"))) 

您还可以赶上其他错误,像“错误”。

unwind-protect就像最后一样;它将执行“身体形式”,然后“放松形式”。然而,“开卷形式”都不管“体形式”是否成功运行执行:

(unwind-protect 
    (while t) 
    (message "Done with infinite loop")) 

你在你的情况要unwind-protect