重复命令的新思路

最近对重复命令有了一些思考,想和大家分享一下。 Vim 体系的重复只是对编辑的重复,emacs现有的重复是对上一条可重复命令的重复。 而我觉得还可以有一种重复,是对移动的重复。即与编辑区分,又是对操作的简化。 比如我按了spc 1,选中了窗口1,这时候用 ,来表达继续往下选窗口,选到了窗口2,再按一次 , 就会选到窗口3。然后我想往回选,就按spc , 表示调头的意思。就会选中窗口2,这时候再按, 就会选中窗口1 除了选窗口,还有往前定位一个函数这种类似的移动都可以用这个操作重复。还有切tab, 切buffer等

Emacs 28 里有 repeat-mode ,默认定义了很多实用的重复键位,这里分享一些我自己定义的 repeat-map :

(defvar buffer-switch-repeat-map ; C-x <left> 或 <right>
      (let ((map (make-sparse-keymap)))
        (define-key map (kbd "<left>") #'previous-buffer)
        (define-key map (kbd "<right>") #'next-buffer)
        (dolist (it '(previous-buffer next-buffer))
          (put it 'repeat-map 'buffer-switch-repeat-map))
        map)
      "Keymap to repeat window buffer navigation key sequences.  Used in `repeat-mode'.")

(defvar python-indent-repeat-map ;; python-mode C-c < 或 >
    (let ((map (make-sparse-keymap)))
      (define-key map (kbd "<") #'python-indent-shift-left)
      (define-key map (kbd ">") #'python-indent-shift-right)
      (dolist (it '(python-indent-shift-left python-indent-shift-right)) (put it 'repeat-map 'python-indent-repeat-map))
      map)
    "Keymap to repeat Python indentation key sequences.  Used in `repeat-mode'.")

(defvar org-mode-navigation-repeat-map ;; org-mode C-c C-n 或 C-p 或 C-f 或 C-b 或 C-i 或 C-u 
  (let ((map (make-sparse-keymap)))
    (define-key map (kbd "C-n") #'org-next-visible-heading)
    (define-key map (kbd "C-p") #'org-previous-visible-heading)
    (define-key map (kbd "C-f") #'org-forward-heading-same-level)
    (define-key map (kbd "C-b") #'org-backward-heading-same-level)
    (define-key map (kbd "C-u") #'org-up-heading)
    (define-key map (kbd "C-i") #'org-down-heading)
    (--each '(org-next-visible-heading org-previous-visible-heading org-forward-heading-same-level org-backward-heading-same-level org-up-heading org-down-heading) (put it 'repeat-map 'org-mode-navigation-repeat-map))
    map)
  "Keymap to repeat `org-mode' navigation key sequences.  Used in `repeat-mode'.")
3 个赞

感谢提示,我先去了解看看有哪些适合我用的

  (defvar resize-window-repeat-map
    (let ((map (make-sparse-keymap)))
      (define-key map "^" 'enlarge-window)
      (define-key map "}" 'enlarge-window-horizontally)
      (define-key map "{" 'shrink-window-horizontally)
      (define-key map "v" 'shrink-window)
      map)
    "Keymap to repeat window resizing commands.  Used in `repeat-mode'.")
  (put 'enlarge-window 'repeat-map 'resize-window-repeat-map)
  (put 'enlarge-window-horizontally 'repeat-map 'resize-window-repeat-map)
  (put 'shrink-window-horizontally 'repeat-map 'resize-window-repeat-map)
  (put 'shrink-window 'repeat-map 'resize-window-repeat-map)

结合 ~repeat-mode~ 可以很方便的控制窗口的大小。通过 ~C-x~ 触发。此设置来自 [[https://github.com/protesilaos/dotfiles/blob/master/emacs/.emacs.d/prot-emacs.org][protesilaos]] 。

1 个赞

这个不就是 emacs-hydra 键绑定的主要思路吗?

对的,完全就是hydra。比如Centaur中的窗口管理(红色按键就是可重复的,蓝色是单次的)

3 个赞