これを論理的に見てみましょう。ほぼ同じコマンドをC-f2
andにバインドしたいとしC-f3
ます。これらのコマンドの唯一の違いは、ポイント内の物をf2
メモリに保存するか、メモリに保存するかf3
です。次に、さまざまなコマンドを作成するか、バインドされているキーに応じて動作が異なる単一のコマンドを用意する必要があります。
バインディングの作成時に作成されたコマンドにキーをバインドできます。define-key
and friends へのコマンド引数は、シンボルの形式のコマンド名である必要はありません。ラムダ式にすることができます。
(global-set-key [C-f3] (lambda ()
(interactive)
…))
これは機能しますが、あまり良くありません。たとえば、ヘルプコマンドとコマンド履歴では、コマンド名は表示されません。
コードの大部分を関数に入れ、小さなラッパー関数を定義できます。大量のコードを繰り返さないようにするには、関数またはマクロでラッパー関数を生成します。
(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)
または、機能ごとに1つのコマンドを定義することもできます(最初の検索、前方への繰り返し、後方への繰り返し)。これはやや柔軟性が低くなりますが(たとえば、 `search-thing-at-point-f2 'をH-s空想が必要な場合に再バインドすることはできません)、冗長性ははるかに低くなります。
コマンドは、それを呼び出したキーを見つけることができます。変数を使用するのが最も簡単な方法です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)
私はあなたの提案されたインターフェースがEmacsへの特に有用な追加だとは思いません。Emacsの基本的な組み込み検索には、事物をその時点で検索し、過去の検索を繰り返す簡単な方法があります。