如何重复调用上一次 hydra 命令?

通过hydra调用某个函数后,有没有办法类似于last-ivy-command'把最近的一次函数找出来啊?比如通过hydra调用swiper后,这个last-ivy-command’就是swiper。通过hydra调用find-file后,`last-ivy-command’就是find-file。

我查了变量 ‘last-command’。一般通过hydra调用后都是存的’ivy-done’,'keyboard-quit’这样的函数,并不是我想要的。

这是比较高级的 Emacs 技巧。

谢谢。不过这个满足不了我的需求。

你可能想要的是 hydra-repeat:

参考作者的博客:

https://oremacs.com/2015/02/28/hydra-repeat/

(BTW:作者的博客上的文章都值得一看)

谢谢山人,我试用了一下,它需要在hydra-xxx/body被调用的时候才有效。我是希望能找到上一次通过hydra调用的操作命令。然后在任何状态下重新调用它。然后绑定到一个全局按键上。

这个可能要查看 hydra 的代码了,看看有没有变量记录了上一次操作的命令。

自己写个 hydra-redo 函数:

(defvar last-hydra-command nil)

(defun before-hydra-disable ()
  (setq last-hydra-command last-command))

(advice-add #'hydra-disable :before #'before-hydra-disable)

(defun hydra-redo ()
  (interactive)
  (when last-hydra-command
    (funcall-interactively last-hydra-command)))

(define-key global-map (kbd "<f3>") #'hydra-redo)

hydra-disable是在什么是时候调用的?我试了一下。

我的hydra是nested的。redo只能调用到第一层的命令。

不明白你说的嵌套是什么意思,最终产生效果的不就只有最末端的命令吗?

(defhydra hydra-a ()
  ("b" hydra-b/body :exit t)
  ("c" hydra-c/body :exit t)
  )

(defhydra hydra-b ()
  ("b" swiper :exit t)
  )

(defhydra hydra-c ()
  ("c" find-file :exit t)
  )

hydra-a作为所有按键的入口,绑定到某个好按的按键上。然后再根据不同的按键来调用对的hyra或都直接调函数。

hydra-redo这个方案,只用调到hydra-a的这一层。

我知道问题所在了,前面我测试的 vi 按键,在 hydra 结束之后是可以正常 redo 的:

(defhydra hydra-vi (:pre (set-cursor-color "#40e0d0")
                    :post (progn
                            (set-cursor-color "#ffffff")
                            (message
                             "Thank you, come again.")))
  "vi"
  ("l" forward-char)
  ("h" backward-char)
  ("j" next-line)
  ("k" previous-line)
  ("q" nil "quit"))

但是如果方法后面加上 :exit 情况就不同了,在 hydra-disable 记录到的是 xxx/body.

hydra 麻烦的在于,它大部分工作都在宏里面做了,每次调用 defhydra 产生一堆新的变量&方法(比如xxx/body),比较难找到一个明显比较合适加 hook/advice 的地方。

简单测了一下前面的 hydra-vi 和嵌套的 hydra-a/b/c,这个 hydra--call-interactively-remap-maybe 函数应该是可以用的:

(defvar last-hydra-command nil)

(defun hydra-redo ()
  (interactive)
  (when last-hydra-command
    (funcall-interactively last-hydra-command)))

(defun hydra-redo--set-last-command (cmd)
  (setq last-hydra-command cmd))

(advice-add #'hydra--call-interactively-remap-maybe :before #'hydra-redo--set-last-command)
1 个赞

是的hydra是这样的。干脆我还是不使用nested了。这个函数可以满足条件了。非常感谢啊。