2010-03-22 8 views
9

Tengo un modo menor. Si ese modo está activo y el usuario toca DEL, I desea realizar alguna acción, pero solo si se cumple alguna condición. Si se cumple la condición y se ejecuta la acción, no quiero hacer nada más después de eso. . Pero si la condición falla, no quiero hacer nada y dejar que se ejecute la acción DEL predeterminada.Reposición de enlace de teclas de Emacs

No estoy seguro de cómo podría resolver esto. Pero supongo que podría hacerlo de dos maneras:

1) pude volver a enlazar la tecla DEL para una función en el modo menor y luego verificación si las condiciones no sostiene OT. Pero entonces, ¿cómo sé cuál es el comando predeterminado para DEL?

2) Podría agregar un gancho de precomandos como este. Ejecute el comando y luego rompa la cadena. ¿Pero cómo rompo la cadena?

(add-hook 'pre-command-hook 
      (lambda() 
      (when (equal last-input-event 'backspace) 
       ;; Do something and then stop (do not execute the 
       ;; command that backspace is bound to) 
      ))) 

¿De qué manera lo resolverías? ¡Gracias!

+0

¿Están del y retroceso lo mismo? – Amos

Respuesta

12

La forma de hacer esto es deshabilitar temporalmente su modo secundario y luego buscar el enlace de la clave.

Supongamos que ha vinculado 'do-thingy a DEL. Entonces esto sería hacer el truco (suponiendo que la condición que desea desencadenar es (equal last-input-event 'backspace):

(defun do-thingy() 
    "Do something, unless last event was backspace." 
    (interactive) 
    (if (equal last-input-event 'backspace) 
     (let* ((my-minor-mode nil) 
      (original-func (key-binding (kbd "DEL")))) 
     ;; original-func is whatever DEL would be if 
     ;; my-minor-mode were disabled 
     (call-interactively original-func)) 
    (message "Here's my minor mode behavior!"))) 

Nota: Este comportamiento se asume que ha configurado su key bindings la standard way a minor-mode would En concreto, se debe añadir el mapa de teclas a la variable minor-mode-map-alist. mediante la adición de un elemento (my-minor-mode . my-minor-mode-keymap). así es como funciona el let declaración anterior, se busca la unión que quiera con su modo desactivado temporalmente.

Si utiliza define-minor-mode para definir su modo menor, el mapa de teclas se creó la "forma correcta "automáticamente.

+0

Perfecto, gracias! – rejeep

+2

¿Qué tal una alternativa arbitraria, donde no se sabe de antemano cuál es la clave a la que desea vincularse? ¿Cómo se puede buscar programáticamente el enlace que se utilizará para el valor de func original? (no importa: parece que uno usa this-command-keys-vector). –

-3

No parece haber una manera de hacer lo que quiere de manera confiable. Si su nuevo comando está obligado a DEL, entonces lo que estaba obligado a DEL antes en el mapa de teclas actual ya no está allí. El otro enfoque que propuso no funcionará porque los pre-comandos-ganchos no impiden que se produzca la siguiente acción. También podría pensar en interrumpir la ejecución posterior con^G (Keyboard-Quit), pero esa es una interrupción no controlada que podría detener más cosas de las que desea.

Incluso si hace que el proceso de configuración de la nueva encuadernación sea un poco más sofisticado que si volviera a encuadernar, y recuerda lo que estaba vinculado anteriormente, para poder llamar después, realmente no tiene lo que busca para. Si alguien desea volver a vincular la acción "predeterminada", tiene que hacerlo modificando su función en lugar de reemplazar la vinculación de la clave.

Lo que quiere hacer no se ajusta al modelo de Emacs de cómo funciona el enlace de claves.

2

Esto es lo que uso para mi paquete smart-tab que hace exactamente eso.

(defun smart-tab-default() 
    "Indents region if mark is active, or current line otherwise." 
    (interactive) 
    (if mark-active 
     (indent-region (region-beginning) 
        (region-end)) 

    (call-interactively 
    (or 
     ;; Minor mode maps for tab (without smart-tab-mode) 
     (cdar (assq-delete-all 'smart-tab-mode (minor-mode-key-binding "\t"))) 
     (cdar (assq-delete-all 'smart-tab-mode (minor-mode-key-binding [(tab)]))) 
     (local-key-binding "\t") 
     (local-key-binding [(tab)]) 
     (global-key-binding "\t") 
     (global-key-binding [(tab)]))))) 

Y en el comando smart-tab (que es el de un salto a la pestaña en el modo menor ), se tiene lo siguiente:

(if (smart-tab-must-expand prefix) 
    ;; use smart tab 
    (smart-tab-default)) 

En primer lugar comprueba si hay atascamientos en modo menor para pestaña (sin incluir smart-tab-mode), luego local, y finalmente combinaciones de teclas globales.

Cuestiones relacionadas