我尝试去看了一下evil-escape 的代码,但那个太复杂没完全看懂。 我想只到怎么delay > 0.1s 就输出 原来的 j 而不是卡在输入提示上 k -> evil-normal-state 我想知道相当的文档在哪?
只会evil-escape,
;; {{ https://github.com/syl20bnr/evil-escape
(setq-default evil-escape-delay 0.3)
(setq evil-escape-excluded-major-modes '(dired-mode))
(setq-default evil-escape-key-sequence "kj")
;; disable evil-escape when input method is on
(evil-escape-mode 1)
;; }}
如果是别的插件我就不懂了。
general.el 是这样:
(general-def 'insert
"k" (general-key-dispatch 'self-insert-command
:timeout 0.2
"j" 'evil-normal-state)
"j" (general-key-dispatch 'self-insert-command
:timeout 0.2
"k" 'evil-normal-state))
本质上好象是借助key-chord
只绑定 jk 的话,这样:
(global-set-key [key-chord ?j ?k] #'evil-normal-state)
(setq input-method-function
#'(lambda (first-char)
(if (and (memq first-char '(?j ?k))
(not (sit-for 0.05 'no-redisplay)))
(let* ((input-method-function nil)
(next-char (read-event)))
(if (and (memq next-char '(?j ?k))
(not (eq first-char next-char)))
(list 'key-chord ?j ?k)
(push next-char unread-command-events)
(list first-char)))
(list first-char))))
通用性更广一点的 key-chord
,这个实际上是从 key-chord 精简而来,用法很简单,将下面代码单独放在一个文件里 require 了之后, (key-chord-define "jk" #'evil-normal-state)
即可,不支持两个键位相同以及键盘宏中使用,想用更多功能还是直接使用 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)
1 个赞
这个代码用不了,我直接下了key-chord了,可以用key-chord解决了,但是有了key-chord为什么还有evil-escape ? 它们有什么不同 ? 我明白了evil-escape的用途了,key-chord会影响normal 和 viusual 模式,会让它变慢,如何只在insert模式定义这个快捷键?
没有用过 evil-escape,不清楚有什么区别。
只在insert模式定义:
(key-chord-define evil-insert-state-map "jk" #'evil-normal-state)
2 个赞
就是这个主题贴来着,好像也是楼上这位仁兄回答的
我推荐用general和keychord配合,方便舒服
1 个赞
试了下evil-escape,能用jk
退出minibuffer和一些special-mode的buffer,比用general.el方便点
我想加点别的比如用 jj 来代替emacs 的 C-f
(general-def 'insert C-j对应的keymap
"j" (general-key-dispatch 'self-insert-command
:timeout 0.2
"j" 'C-j原来绑定的函数)
或者用general-translate-key,建议看下general.el的文档,doom-emacs用来绑定按键的宏map!就是基于general.el的,功能很多
PS:这里绑定到evil-insert-state-map,实际上根据需要可以绑定到其他evil-state对应的map