Schauen wir uns das logisch an: Sie möchten nahezu identische Befehle an C-f2
und gebunden haben C-f3
. Der einzige Unterschied zwischen diesen Befehlen besteht darin, ob sie das Objekt unter Punkt im f2
Speicher oder im f3
Speicher speichern. Dann müssen Sie entweder verschiedene Befehle erstellen oder einen einzelnen Befehl haben, dessen Verhalten davon abhängt, an welchen Schlüssel er gebunden ist.
Sie können einen Schlüssel an einen Befehl binden, der zum Zeitpunkt der Erstellung der Bindung erstellt wurde. Das Befehlsargument an define-key
und Freunde muss kein Befehlsname in Form eines Symbols sein, sondern kann ein Lambda-Ausdruck sein.
(global-set-key [C-f3] (lambda ()
(interactive)
…))
Das funktioniert, ist aber nicht sehr schön. Beispielsweise zeigen Hilfebefehle und Befehlsverläufe keinen Befehlsnamen an.
Sie können den Großteil des Codes in eine Funktion einfügen und kleine Wrapper-Funktionen definieren. Lassen Sie die Wrapper-Funktionen von einer Funktion oder einem Makro generieren, um zu vermeiden, dass viel Code wiederholt wird.
(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)
Alternativ können Sie für jede Funktionalität einen einzelnen Befehl definieren (erste Suche, Vorwärts wiederholen, Rückwärts wiederholen). Dies ist etwas weniger flexibel (z. B. können Sie `search-thing-at-point-f2 nicht neu binden, H-swenn es Ihnen gefällt), aber viel weniger ausführlich.
Ein Befehl kann herausfinden, welcher Schlüssel ihn aufgerufen hat. Der einfachste Weg für Sie ist die Verwendung der Variablen 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)
Ich denke nicht, dass Ihre vorgeschlagene Schnittstelle eine besonders nützliche Ergänzung zu Emacs ist. Die in Emacs integrierte integrierte Suche bietet einfache Möglichkeiten, um das Objekt punktgenau zu durchsuchen und frühere Suchvorgänge zu wiederholen.