Miremos esto lógicamente: desea tener comandos casi idénticos vinculados a C-f2
y C-f3
. La única diferencia entre estos comandos es si almacenan la cosa en cuestión en la f2
memoria o en la f3
memoria. Entonces, o necesita construir diferentes comandos, o necesita tener un solo comando cuyo comportamiento depende de la clave a la que está vinculado.
Puede vincular una clave a un comando que se construye en el momento en que crea el enlace. El argumento de comando para define-key
y amigos no tiene que ser un nombre de comando en forma de símbolo, puede ser una expresión lambda.
(global-set-key [C-f3] (lambda ()
(interactive)
…))
Esto funciona, pero no es muy agradable. Por ejemplo, los comandos de ayuda y los historiales de comandos no le mostrarán un nombre de comando.
Puede colocar la mayor parte del código en una función y definir pequeñas funciones de contenedor. Para evitar repetir mucho código, haga que una función o macro genere las funciones del contenedor.
(defun repeat-search-thing-at-point-forward (memory)
(search-forward (symbol-value memory)))
(defun repeat-search-thing-at-point-backward (memory)
(search-backward (symbol-value memory)))
(defun search-thing-at-point (memory)
"Search the thing at point.
Store the thing in MEMORY for a future search with
`repeat-search-thing-at-point-forward' and
`repeat-search-thing-at-point-backward'."
(set memory (thing-at-point 'word))
(repeat-search-thing-at-point-forward memory))
(defun define-search-thing-at-point (map key)
"Define commands to search a thing at point "
(let* ((memory-variable (intern (format "search-memory-%s" key)))
(set-function (intern (format "search-thing-at-point-%s" key)))
(forward-function (intern (format "repeat-search-thing-at-point-forward-%s" key)))
(backward-function (intern (format "repeat-search-thing-at-point-backward-%s" key)))
(forward-key (vector key))
(backward-key (vector (list 'shift key)))
(set-key (vector (list 'control key))))
(eval `(progn
(defvar ,memory-variable nil
,(format "The last thing searched with \\[%s]." set-function))
(defun ,set-function ()
,(format "Search the thing at point.
Use \\[%s] and \\[%s] to repeat the search forward and backward
respectively." forward-function backward-function)
(interactive "@")
(search-thing-at-point ',memory-variable))
(defun ,forward-function ()
,(format "Search forward for the last thing searched with \\[%s]." set-function)
(interactive "@")
(repeat-search-thing-at-point-forward ',memory-variable))
(defun ,backward-function ()
,(format "Search backward for the last thing searched with \\[%s]." set-function)
(interactive "@")
(repeat-search-thing-at-point-backward ',memory-variable))
(define-key map ',set-key #',set-function)
(define-key map ',forward-key #',forward-function)
(define-key map ',backward-key #',backward-function)
t))))
(define-search-thing-at-point global-map 'f2)
(define-search-thing-at-point global-map 'f3)
(define-search-thing-at-point global-map 'f4)
Alternativamente, puede definir un solo comando para cada funcionalidad (primera búsqueda, repetir hacia adelante, repetir hacia atrás). Esto es un poco menos flexible (por ejemplo, no puede volver a vincular `search-thing-at-point-f2 a H-ssi lo desea), pero es mucho menos detallado.
Un comando puede encontrar qué tecla lo invocó. La forma más fácil para usted es usar la variable last-command-event
.
(defvar search-thing-memory nil
"History of things searched with `search-thing-at-point'.")
(defun search-thing-at-point (key)
"Search the thing at point.
Store the thing in MEMORY for a future search with
`repeat-search-thing-at-point-forward' and
`repeat-search-thing-at-point-backward'."
(interactive (list (event-basic-type last-command-event)))
(let ((thing (thing-at-point 'word))
(memory (assq key search-thing-memory)))
(if memory
(setcdr memory thing)
(setq search-thing-memory (cons (cons key thing)
search-thing-memory)))
(search-forward thing)))
(defun repeat-search-thing-at-point-forward (key)
"Repeat the last thing searched with `search-thing-at-point'
with a matching key binding."
(interactive (list (event-basic-type last-command-event)))
(search-forward (cdr (assq key search-thing-memory))))
(defun repeat-search-thing-at-point-backward (key)
"Repeat the last thing searched with `search-thing-at-point'
with a matching key binding."
(interactive (list (event-basic-type last-command-event)))
(search-backward (cdr (assq key search-thing-memory))))
(global-set-key [C-f2] 'search-thing-at-point)
(global-set-key [C-f3] 'search-thing-at-point)
(global-set-key [C-f4] 'search-thing-at-point)
(global-set-key [f2] 'repeat-search-thing-at-point-forward)
(global-set-key [f3] 'repeat-search-thing-at-point-forward)
(global-set-key [f4] 'repeat-search-thing-at-point-forward)
(global-set-key [S-f2] 'repeat-search-thing-at-point-backward)
(global-set-key [S-f3] 'repeat-search-thing-at-point-backward)
(global-set-key [S-f4] 'repeat-search-thing-at-point-backward)
No creo que su interfaz propuesta sea una adición particularmente útil a Emacs. La búsqueda incorporada básica de Emacs tiene formas fáciles de buscar la cosa en el punto y repetir búsquedas pasadas.