如何设置较长的evil快捷键?

我希望设置在normal模式下设置“c r s”作为某个命令的快捷键, 但我发现

(define-key evil-normal-state-map (kbd "c r s") 'string-inflection-underscore)

并不能做到。求解正确方案。

不能简单地这样修改按键,因为 c 是 evil 里面的 operator,你需要自己定义 operator ,我看看能否帮你搞定。

如果你安装了 evil-surround 可以用下面的代码达到你的需求:


(evil-define-command my-command (operation)
  (interactive (evil-surround-interactive-setup))
  (cond
   ((eq operation 'change)
    (call-interactively 'string-inflection-underscore))
   ))

(evil-define-key 'normal evil-surround-mode-map "rs" 'my-command)

不过貌似这个方法不是特别好,先用着吧。

1 个赞

也可以自己定义一个 minor-mode 专门来处理你这种扩展 operator 按键:

(defun my-command ()
  (interactive )
  (setq evil-inhibit-operator t)
  (call-interactively 'string-inflection-underscore))


(define-minor-mode test-evil-mode
  "Buffer-local minor mode to emulate surround.vim."
  :keymap (make-sparse-keymap))

(test-evil-mode)

(evil-define-key 'operator test-evil-mode-map "rs" 'my-command)

Great!耦合低,易扩展

最终方案:

(setq self-evil-play-operator-alist
      '((evil-change . c) (evil-delete . d)))

(define-minor-mode self-evil-play-mode
  "Buffer-local minor mode to define self evil keyboard."
  :keymap (make-sparse-keymap))

(define-globalized-minor-mode global-self-evil-play-mode
  self-evil-play-mode (lambda () (self-evil-play-mode 1))
  "Global minor mode to define self evil keyboard.")

(global-self-evil-play-mode)

(defun self-evil-play-interactive-setup ()
  (setq evil-inhibit-operator t)
  (list (assoc-default evil-this-operator
                       self-evil-play-operator-alist)))

(defmacro self-evil-play-define-key (key-sequence func)
  "Binding evil operator with the func."
  (let ((func-name (intern (format "self-evil-play/%s" (nth 1 func)))))
    `(progn
       (evil-define-command ,func-name (operation)
         ,(format "Define %s for evil operator!" (nth 1 func))
         (interactive (self-evil-play-interactive-setup))
         (cond
          ((eq operation (quote ,(intern (substring key-sequence 0 1))))
           (call-interactively ,func))
          ))
       (evil-define-key 'operator self-evil-play-mode-map ,(substring key-sequence 1) (quote ,func-name)))
    )
  )

(defun mp-hacking/init-string-inflection ()
  "Bind keys for string inflection,Want to turn fooBar into foo_bar? Press crs
(coerce to snake_case). MixedCase (sim), camelCase (sic), snake_case (sis), lisp_case (sil)
and UPPER_CASE (siu) are all just 3 keystrokes away."
  ;;TODO: let lisp case could back to snake_case or others.
  (use-package string-inflection
    :defer t
    :init
    (self-evil-play-define-key "crs" 'string-inflection-underscore)
    (self-evil-play-define-key "crm" 'string-inflection-camelcase)
    (self-evil-play-define-key "crc" 'string-inflection-lower-camelcase)
    (self-evil-play-define-key "cru" 'string-inflection-upcase)
    (self-evil-play-define-key "crl" 'string-inflection-lisp)
    )
  )

emacs 新手, 有问题的地方,待优化的地方欢迎大家指出

1 个赞

是不是有点绕远了。。默认只要没绑定的键就可以作leader-key的,spacemacs+evil下,SPCgz下面都还有不少空间,还有完全空闲的RZRET\TAB等等可以用。。(比如这里crsgrsRET r s之类的)

理由有3:

  1. vim中留下的习惯,能统一不是很好吗
  2. 能按自己的习惯绑定不觉得很爽吗
  3. 我给你讲个笑话:我比较爱惜我的 空格键:laughing: