2009-05-19 10 views
6

Tengo un script elisp para Emacs que quiero hacer algo de limpiar en la primera si un usuario pulsa Ctrl +G. Yo uso 'leer-evento' para atrapar todos los eventos, pero esto no captura el Ctrl + G. Cuando se activa Ctrl + G, simplemente detiene la ejecución.¿Cómo intercepto Ctrl-G en Emacs

En XEmacs, cuando se llama al lado de orden de eventos que le dará todos los eventos, incluyendo cuando un usuario pulsa Ctrl +G. Debe haber algún equivalente en Emacs.

Respuesta

11

Puede utilizar with-local-quit para determinar si se ha pulsado C-g:

solución Editado dejar de tragar como lo sugiere 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))))) 

Nota: con local-quit devuelve el valor de la última expresión, o si nilC-g se presiona, así que asegúrese de devolver algo no nula cuando se pulsa ninguna C-g. Encontré útil la documentación de elisp en quitting. Un área relacionada es nonlocal exits, y específicamente unwind-protect, que se aplica a algo más que dejar de fumar.

+0

Esto resuelve parte del problema, pero no se traga el control-g, solo le informa que sucedió. Si desea evitar que el control-g escape del bloque, use las variables 'inhibit-quit' y 'quit-flag'. – efunneko

+1

Esto es espantoso y quebradizo. Estoy bastante seguro de que lo que sea que OP desee puede ser resuelto más simple y robustamente con 'condición-caso' o' desenrollar-proteger'. – Stefan

5

condition-case y unwind-protect son útiles aquí. condition-case le permite "capturar" "excepciones", de los que dejan de fumar es uno:

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

También se puede coger otros errores, como "error".

unwind-protect es como finalmente; ejecutará "formas del cuerpo" y luego "desenrollará formas". Sin embargo, las "formas de desenrollado" se ejecutan independientemente de si las "formas del cuerpo" se han ejecutado correctamente:

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

¿Quieres unwind-protect en su caso.

+1

'condition-case' requiere un argumento" var "antes del cuerpo (al menos en Emacs 24). No edité tu respuesta porque no estoy seguro de qué valor querías pasar allí. (Gracias por la respuesta por cierto!) – Dogbert