xah-fly-keys 使用总结

我是从 evil 切换到 xah-fly-keys 的。 导致这个切换的原因我在之前刚使用xah-fly-keys的时候也简单写过一篇文章来记录 从evil到xah-fly-keys ,简单来说就是代码写多了手痛。

xah-fly-keys是 Xah Lee 根据函数的使用频率,重新设置的一套快捷键绑定方式。 而evil,是一个在Emacs中模拟vim操作的插件。

xah-fly-keys和evil对比

evil功能在xah-fly-keys中的对应

Evil Feature Xah-fly-keys Replacement
A 光标移动到到行尾,进入insert模式 ;f
I 光标移动到到行尾,进入insert模式 hf
C 清除当前光标至行尾内容并进入insert模式 SPC g fkill-line先删除当前光标到行尾内容,然后进入insert模式
f[char] 在当前行找到[char]字符然后把光标移动到字符上 使用`isearch-forward'或者直接光标左右移动,u,o一个word一个word移动出很快
t 在当前行找到[char]字符然后把光标移动到字符之前 使用`isearch-forward'或者直接光标左右移动,u,o一个word一个word移动出很快
dd 删除当前行 x(xah-cut-line-or-region)
df[char] 删除光标到最近一个[char]中的内容,包括char 暂时选中删除,或者使用e,r删除word
df[char] 删除光标到最近一个[char]中的内容,不包括char 暂时选中删除,或者使用e,r删除word
vi",vi(,vi{ 选中",() , {}这些包住的内容 我使用 thing-edit 直接选中都不需要了
Ctrl v 矩形选择和编辑 SPC o SPC(rectangle-mark-mode)
% 在相互匹配的括号之间跳转 /(xah-goto-matching-bracket)括号,双引号,引号等等都要以跳转。
Evil在xah-fly-keys中的对应功能

xah-fly-keys中一些好用的功能

定制xah-fly-keys

根据模式定制按键绑定

command模式下的按键大部分都是根据使用频率来制定的,最常用的都绑定在一个按键上,大部份都在leader-key后再敲两下。

具体的定制方法 杀哥写的: xah-fly-keys_customization讲得很清楚了。

我最需要的功能是根据不同的模式把command模式下的一些按键绑定到不同的功能。比如我常用的 SPC SPC 按键,我就喜欢在org-mode和c-mode中绑定不同的按键。

在和Xah咨询后,终于找到正确的方法:定义一个函数,该函数在不同的模式中使用 call-interactively 来调用来同的功能。比如我的f8就是绑定到这个函数的:

(defun peng-xah-fly-dot-key ()
        "key `.'"
        (interactive)
        (cond
        ((eq major-mode 'c-mode) (call-interactively 'hydra-cscope/body))
        ((eq major-mode 'Info-mode) (call-interactively 'hydra-info/body))
        ((eq major-mode 'dired-mode) (call-interactively 'hydra-dired/body))
        ((eq major-mode 'mhtml-mode) (call-interactively 'hydra-html/body))
        ((eq major-mode 'picture-mode) (call-interactively 'hydra-artist-mode-menu/body))
        ((eq major-mode 'artist-mode) (call-interactively 'hydra-artist-mode-menu/body))
        ((eq major-mode 'ibuffer-mode) (call-interactively 'hydra-ibuffer-main/body))
        (t nil)))
              

xah-fly-keys中有两个很重要的函数:xah-fly-command-mode-initxah-fly-insert-mode-init。 前者在进入command mode时调用,后者在进入insert mode时调用。 command mode中绑定到一个按键的函数都在 xah-fly-command-mode-init 中重新绑定。

所以,直接使用define-key来修改xah-fly-key-map中的绑定是不行的,因为下次进入command-mode时, xah-fly-command-mode-init 又会修改这个map。

最直接的方式就是改 xah-fly-command-mode-init 函数。我就是把这块代码拷贝出来直接在后面添加我的自定义绑定的。

;; redefine command init
(defun xah-fly-command-mode-init ()
  "Set command mode keys.
Version 2017-01-21"
  (interactive)
  (xah-fly--define-keys
   xah-fly-key-map
   '(

     ;; IMPORTANT, These keys are all dvorak keys
     ("~" . nil)
     (":" . nil)

     ("SPC" . xah-fly-leader-key-map)
     ("DEL" . xah-fly-leader-key-map)

     ;; ("'" . xah-reformat-lines)
     ("," . xah-shrink-whitespaces)
     ("-" . xah-cycle-hyphen-underscore-space)
     ("." . xah-backward-kill-word)
     (";" . xah-comment-dwim)
     ("/" . hippie-expand)
     ("\\" . nil)
     ("=" . xah-forward-equal-sign)
     ("[" . xah-backward-punct )
     ("]" . xah-forward-punct)

     ("1" . xah-extend-selection)
     ("2" . xah-select-line)
     ("3" . delete-other-windows)
     ("4" . split-window-below)
     ("5" . delete-char)
     ("6" . xah-select-block)
     ("7" . xah-select-line)
     ("8" . xah-extend-selection)
     ("9" . xah-select-text-in-quote)
     ("0" . xah-pop-local-mark-ring)

     ("a" . execute-extended-command)
     ("b" . isearch-forward)
     ("c" . previous-line)
     ("d" . xah-beginning-of-line-or-block)
     ("e" . xah-delete-backward-char-or-bracket-text)
     ("f" . undo)
     ("g" . backward-word)
     ("h" . backward-char)
     ("i" . xah-delete-current-text-block)
     ("j" . xah-copy-line-or-region)
     ("k" . xah-paste-or-paste-previous)
     ("l" . xah-fly-insert-mode-activate-space-before)
     ("m" . xah-backward-left-bracket)
     ("n" . forward-char)
     ("o" . open-line)
     ("p" . xah-kill-word)
     ("q" . xah-cut-line-or-region)
     ("r" . forward-word)
     ("s" . xah-end-of-line-or-block)
     ("t" . next-line)
     ("u" . xah-fly-insert-mode-activate)
     ("v" . xah-forward-right-bracket)
     ("w" . xah-next-window-or-frame)
     ("x" . xah-toggle-letter-case)
     ("y" . set-mark-command)
     ("z" . xah-goto-matching-bracket)))

  (define-key xah-fly-key-map (kbd "a") (if (fboundp 'counsel-M-x) 'counsel-M-x 'execute-extended-command ))

  ;; add by pengpengxp the key here is 'qwerty' keys.
  (define-key xah-fly-key-map (kbd "C-a") 'peng-xah-fly-C-a-key)
  (define-key xah-fly-key-map (kbd "C-e") 'peng-xah-fly-C-e-key)
  (define-key xah-fly-key-map (kbd "C-n") 'next-line)
  (define-key xah-fly-key-map (kbd "C-p") 'previous-line)
  (define-key xah-fly-key-map (kbd "<C-tab>") '(lambda () (interactive) (switch-to-buffer (other-buffer))))
  (define-key xah-fly-key-map (kbd "C-`") 'counsel-ibuffer)
  (define-key xah-fly-key-map (kbd "<C-S-tab>") '(lambda () (interactive) (switch-to-buffer (other-buffer))))
  (define-key xah-fly-key-map (kbd "<home>") 'beginning-of-defun)
  (define-key xah-fly-key-map (kbd "<end>") 'end-of-defun)
  (define-key xah-fly-key-map (kbd "C-o") 'counsel-find-file)

  (define-key xah-fly-key-map (kbd "DEL") 'peng-xah-fly-backspace-key)
  (define-key xah-fly-key-map (kbd "<backspace>") 'peng-xah-fly-backspace-key)

  (define-key xah-fly-key-map (kbd "m") 'ivy-switch-buffer)
  (define-key xah-fly-key-map (kbd "p") 'peng-counsel-git-fast)
  (define-key xah-fly-key-map (kbd "d") 'counsel-find-file)
  (define-key xah-fly-key-map (kbd "s") peng-thing-edit-map)
  (define-key xah-fly-key-map (kbd "x") 'peng-xah-fly-x-key)

  (define-key xah-fly-key-map (kbd "0") 'xah-open-file-fast-ivy)
  (define-key xah-fly-key-map (kbd "1") 'peng-yank-symbol-name)
  (define-key xah-fly-key-map (kbd "2") 'peng-replace-current-symbol-with-kill-ring)

  (define-key xah-fly-key-map (kbd ".") 'peng-xah-fly-dot-key)
  (define-key xah-fly-key-map (kbd "`") 'xref-pop-marker-stack)
  (define-key xah-fly-key-map (kbd "<f8>") 'peng-xah-fly-f8-key)

  (progn
    (setq xah-fly-insert-state-q nil )
    (modify-all-frames-parameters (list (cons 'cursor-type 'box))))

  (setq mode-line-front-space "C")
  (force-mode-line-update)
  ;;
  )

如果你觉得本文不错,欢迎 donate 哦:)