Как мне перехватить Ctrl-G в Emacs - PullRequest
7 голосов
/ 19 мая 2009

У меня есть сценарий elisp для Emacs, в котором я хочу выполнить некоторую очистку, если пользователь нажмет Ctrl + G . Я использую 'read-event', чтобы перехватить все события, но это не перехватывает Ctrl + G . При нажатии Ctrl + G выполнение просто прекращается.

В XEmacs, когда вы вызываете next-command-event, он выдаст вам все события, в том числе, когда пользователь нажмет Ctrl + G . В Emacs должен быть какой-то эквивалент.

Ответы [ 2 ]

14 голосов
/ 19 мая 2009

Вы можете использовать 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)))))

Примечание: with-local-quit возвращает значение последнего выражения или nil, если нажата C-g, поэтому обязательно верните что-то не ноль, если нет C-g нажат. Я нашел полезную документацию по elisp для quitting . Смежной областью является нелокальные выходы , в частности unwind-protect, что относится не только к выходу.

6 голосов
/ 09 июля 2009

condition-case и unwind-protect полезны здесь. condition-case позволяет вам "ловить" "исключения", одним из которых является выход:

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

Вы также можете отлавливать другие ошибки, например «error».

unwind-protect похоже наконец; он выполнит «формы тела», а затем «раскрутит формы». Однако «формы раскручивания» выполняются независимо от того, успешно ли выполнялись «формы тела»:

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

Вы хотите unwind-protect в вашем случае.

...