2009-02-17 7 views
12

EDIT: entiendo que es dejar de fumar teclado (que normalmente está unido a C-g); pero estoy más interesado en saber cómo lidiar con las funciones de edición que vienen con Emacs (como en este caso). Me encuentro con este tipo de situaciones de vez en cuando cuando quiero cambiar solo un poco de algunas funciones incorporadas.en Emacs, ¿cuál es la mejor manera para teclado-escape-quit no destruir otras ventanas?

En emacs, cuando presionas M-ESC ESC (o ESC tres veces), puedes salir de un montón de situaciones como la marca transitoria, etc. Pero habitualmente presiono la tecla de escape (de hecho, reasigné esto a un solo golpe de la tecla de escape) más de lo que pretendía, y eso termina matando la configuración de mi ventana, lo cual es bastante molesto. La función de teclado de escape dejar de fumar se define en simple.el:

(defun keyboard-escape-quit() 
    "Exit the current \"mode\" (in a generalized sense of the word). 
This command can exit an interactive command such as `query-replace', 
can clear out a prefix argument or a region, 
can get out of the minibuffer or other recursive edit, 
cancel the use of the current buffer (for special-purpose buffers), 
or go back to just one window (by deleting all but the selected window)." 
    (interactive) 
    (cond ((eq last-command 'mode-exited) nil) 
    ((> (minibuffer-depth) 0) 
    (abort-recursive-edit)) 
    (current-prefix-arg 
    nil) 
    ((and transient-mark-mode mark-active) 
    (deactivate-mark)) 
    ((> (recursion-depth) 0) 
    (exit-recursive-edit)) 
    (buffer-quit-function 
    (funcall buffer-quit-function)) 
    ((not (one-window-p t)) 
    (delete-other-windows)) 
    ((string-match "^ \\*" (buffer-name (current-buffer))) 
    (bury-buffer)))) 

y puedo ver que yo no quiero las líneas:

((not (one-window-p t)) 
    (delete-other-windows)) 

pero ¿cuál es la mejor manera de modificar esta ¿función? Solo puedo ver dos formas: 1) modificar simple.el 2) copiar esta función en mi archivo .emacs y hacer las modificaciones allí. Ambas formas no son realmente buena; idealmente me gustaría ver algo en la línea de defadvice, pero no veo cómo puedo hacerlo en este caso.

Respuesta

14

se podría utilizar alrededor de asesoramiento y redefinir la función problemática a hacer lo que quiere (es decir, una sola ventana-p siempre debe devolver t):

(defadvice keyboard-escape-quit (around my-keyboard-escape-quit activate) 
    (let (orig-one-window-p) 
    (fset 'orig-one-window-p (symbol-function 'one-window-p)) 
    (fset 'one-window-p (lambda (&optional nomini all-frames) t)) 
    (unwind-protect 
     ad-do-it 
     (fset 'one-window-p (symbol-function 'orig-one-window-p))))) 

Este tipo de actos como un (let ...) pero tiene que ser más complicado porque necesita anular una función para un alcance limitado en lugar de una variable.

+4

Una mejor versión de una sola línea usando flet (es decir, la versión de función de LET): (para dejar de teclado de escape defadvice (alrededor de mi-teclado de escape salga de activación) (flet ((one-window-p (y todos los marcos nomini opcionales) t)) ad-do-it)) – polyglot

+0

La extensión cl es necesaria para que funcione el flet. – Alan

+0

Es posible que también deba cambiar 'flet' por' cl-flet'. – Alan

7

Por lo general encontramos que 'teclado de dejar de fumar (C-g) trabaja para salir de todas esas situaciones.

Sin embargo, si realmente quieres tener una variante de esta función, creo que copiar en tu archivo .emacs (y cambiar el nombre, suelo usar un prefijo de bp) y hacer las ediciones allí es probablemente la mejor opción.

EDITAR, en respuesta a editar: En general, siempre que lo desee una versión editada de una función de emacs, ya sea que escribo yo mismo, o copiarlo en mi .emacs, cambie su nombre por BP-whotever y luego hacer las modificaciones apropiadas.

La desventaja de esto es que mis .emacs es enorme, y probablemente extra-enrevesada con funciones antiguos que se utilizan nolonger ... la ventaja es que cada vez que tengo que escribir algo nuevo, tengo toneladas de la muestra código para mirar ...

0

Una sola pulsación de la tecla Escape, por defecto, actúa como una tecla prefijo Meta; es decir, una combinación de teclas que implica la tecla Meta.

-Triple pulsando la tecla Escape se ejecutará teclado de escape dejar de fumar, que es como teclado de dejar de fumar, pero con más de un comportamiento "hago lo que quiero decir".

Este código puede ayudar con su caso de uso.Usted puede utilizar esto en su archivo de inicio de Emacs:

;;; esc always quits 
(define-key minibuffer-local-map [escape] 'minibuffer-keyboard-quit) 
(define-key minibuffer-local-ns-map [escape] 'minibuffer-keyboard-quit) 
(define-key minibuffer-local-completion-map [escape] 'minibuffer-keyboard-quit) 
(define-key minibuffer-local-must-match-map [escape] 'minibuffer-keyboard-quit) 
(define-key minibuffer-local-isearch-map [escape] 'minibuffer-keyboard-quit) 
(global-set-key [escape] 'keyboard-quit) 
1

Aquí hay otro, la pieza más simple consejo que se aprovecha del hecho de que keyboard-escape-quit llamadas buffer-quit-function antes de cerrar ventanas:

(defadvice keyboard-escape-quit 
    (around keyboard-escape-quit-dont-close-windows activate) 
    (let ((buffer-quit-function (lambda()()))) 
    ad-do-it)) 

Funciona con Emacs 25.1. (He usado originalmente @ consejo de scottfrazer, pero es infeliz en 25.1. No se han molestado depuración todavía.)

1

estoy más interesado en saber acerca de cómo uno se ocupa de las funciones de edición que vienen con Emacs (como en este caso). Me encuentro con este tipo de situaciones de vez en cuando cuando quiero cambiar solo un poco de algunas funciones incorporadas.

Este es exactamente el propósito para el que creé la biblioteca el-patch. Se podría poner esto en su init-file:

(el-patch-defun keyboard-escape-quit() 
    "Exit the current \"mode\" (in a generalized sense of the word). 
This command can exit an interactive command such as `query-replace', 
can clear out a prefix argument or a region, 
can get out of the minibuffer or other recursive edit, 
cancel the use of the current buffer (for special-purpose buffers), 
or go back to just one window (by deleting all but the selected window)." 
    (interactive) 
    (cond ((eq last-command 'mode-exited) nil) 
    ((> (minibuffer-depth) 0) 
    (abort-recursive-edit)) 
    (current-prefix-arg 
    nil) 
    ((and transient-mark-mode mark-active) 
    (deactivate-mark)) 
    ((> (recursion-depth) 0) 
    (exit-recursive-edit)) 
    (buffer-quit-function 
    (funcall buffer-quit-function)) 
    (el-patch-remove 
     ((not (one-window-p t)) 
     (delete-other-windows))) 
    ((string-match "^ \\*" (buffer-name (current-buffer))) 
    (bury-buffer)))) 
Cuestiones relacionadas