Hãy xem xét điều này một cách logic: bạn muốn có các lệnh gần giống nhau bị ràng buộc C-f2
và C-f3
. Sự khác biệt duy nhất giữa các lệnh này là liệu chúng lưu trữ vật dưới điểm trong f2
bộ nhớ hay trong f3
bộ nhớ. Sau đó, bạn cần phải xây dựng các lệnh khác nhau hoặc bạn cần phải có một lệnh duy nhất có hành vi phụ thuộc vào khóa nào được ràng buộc.
Bạn có thể liên kết một khóa với một lệnh được xây dựng tại thời điểm bạn tạo liên kết. Đối số lệnh define-key
và bạn bè không phải là tên lệnh dưới dạng ký hiệu, nó có thể là biểu thức lambda.
(global-set-key [C-f3] (lambda ()
(interactive)
…))
Điều này hoạt động, nhưng nó không phải là rất tốt đẹp. Ví dụ: các lệnh trợ giúp và lịch sử lệnh sẽ không hiển thị cho bạn một tên lệnh.
Bạn có thể đặt phần lớn mã trong một hàm và xác định các hàm bao bọc nhỏ. Để tránh lặp lại nhiều mã, có một hàm hoặc macro tạo các hàm bao bọc.
(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)
Ngoài ra, bạn có thể xác định một lệnh duy nhất cho từng chức năng (tìm kiếm đầu tiên, lặp lại tiến, lặp lại lùi). Điều này hơi kém linh hoạt (ví dụ: bạn không thể rebind `search-thing-at-point-f2 thành H-snếu nó ưa thích của bạn) nhưng ít dài dòng hơn.
Một lệnh có thể tìm thấy khóa nào được gọi nó. Cách dễ nhất cho bạn là sử dụng biến 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)
Tôi không nghĩ giao diện được đề xuất của bạn là một bổ sung đặc biệt hữu ích cho Emacs. Tìm kiếm tích hợp cơ bản của Emacs có những cách dễ dàng để tìm kiếm điểm đó và lặp lại các tìm kiếm trong quá khứ.