通用性更广一点的 key-chord
,这个实际上是从 key-chord 精简而来(应该是这个,我也不记得是不是这个了) 用法很简单,将下面代码单独放在一个文件里 require 了之后, (key-chord-define "xf" #'foo)
即可,不支持两个键位相同以及键盘宏中使用,想用更多功能还是直接使用 key-chord 比较好。
(defvar key-chord-last-unmatched nil)
;;;###autoload
(defun key-chord-define (keys command)
"定义由两个连续按键启动的 COMMAND.
KEYS: string 或 vector of two elements, elements: 32~126 之间的 ascii codes."
;; Exotic chars in a string are >255 but define-key wants 128..255 for those
(setq input-method-function #'key-chord-input-method)
(let ((key1 (logand 255 (aref keys 0)))
(key2 (logand 255 (aref keys 1))))
(global-set-key (vector 'key-chord key1 key2) command)
(global-set-key (vector 'key-chord key2 key1) command)))
(defsubst key-chord-lookup-key (key)
"查找 KEY 的非数字定义,为数字则返回 nil."
(let ((res (lookup-key (current-global-map) key)))
(if (numberp res)
nil
res)))
(defun key-chord-input-method (first-char)
"FIRST-CHAR 为每次输入时字符."
(if (and (not (eq first-char key-chord-last-unmatched))
(key-chord-lookup-key (vector 'key-chord first-char)))
(if (sit-for 0.05 'no-redisplay)
(progn
(setq key-chord-last-unmatched nil)
(list first-char))
;; else input-pending-p
(let* ((input-method-function nil)
(next-char (read-event)))
(if (key-chord-lookup-key (vector 'key-chord first-char next-char))
(list 'key-chord first-char next-char)
;; 吐出 (read-event) 吞掉的字符?
(setq unread-command-events (cons next-char unread-command-events))
(when (eq first-char next-char)
(setq key-chord-last-unmatched first-char))
(list first-char))))
;; else no key-chord keymap
(setq key-chord-last-unmatched first-char)
(list first-char)))
(provide 'key-chord)