noctuid / evil-guide

Draft of a guide for using emacs with evil
GNU General Public License v3.0
1.26k stars 61 forks source link

evil repeat for hydra? #5

Closed wbolster closed 7 years ago

wbolster commented 7 years ago

awesome text, thanks a lot for putting this online, even if you consider it a draft.

since you mention both the repeat system and hydras... any chance you know how to get those to play well together? e.g. i have , c (comma followed by c) bound to a hydra (i use comma as my "leader" key), but pressing . to repeat the hydra command after use does not work.

i tried this:

(evil-declare-repeat 'my-hydra/body)

... which unfortunately does not work.

noctuid commented 7 years ago

Just to clarify, do you want to have the hydra brought up again (this works for me) or have some/all of the commands run in the hydra repeated? If you want to do the latter, what do you want repeated? The keystrokes (e.g. you run multiple commands in the hydra)? The final command? You can set the repeat property of a command to a function to customize how the repeat is recorded. I could maybe add an example of this.

wbolster commented 7 years ago

i use many of my hydras as a "mini modal menu" to reach commands that would otherwise have been invisibly hidden behind multiple key presses in some keymap.

what i would like to have is a repeat of the last executed command, e.g. i have a hydra with one of the heads invoking string-inflection-all-cycle and i would like to have it repeatable outside the hydra, which means binding another head of the hydra to hydra-repeat or setting :exit nil is not what i want.

also, how do you get the hydra to repeat? i just get this:

After 0 kbd macro iterations: evil-motion-range: Wrong type argument: commandp, (keymap (keymap ...
noctuid commented 7 years ago

In this case, declaring a custom repeat function doesn't work well, since recording ends while you are still in the hydra. A simple way to record the last command would be to use hydra's :before-exit keyword, giving it the following:

(progn
  (evil-repeat-start)
  (setq evil-repeat-info `((call-interactively ,this-command)))
  (evil-repeat-stop))

You could record prefix arguments as well if you needed to I guess. This works in the basic case for me though.

As for repeating the invocation of the hydra, I haven't done anything. It just works for me.

wbolster commented 7 years ago

thanks, @noctuid. wondering how i can make this generic for reuse in multiple hydras. (or even request support in hydra itself via :evil-repeat or something like that.)

wbolster commented 7 years ago

ping @abo-abo (of hydra fame), maybe you have ideas/opinions?

abo-abo commented 7 years ago

@wbolster You can reuse last-command. See also hydra-pause-resume.

noctuid commented 7 years ago

You could make it into a function and use real-this-command instead (then you just have to put :before-exit my-hydra-evil-repeat. I don't think it's a good idea to add support to hydra for this; this is just a workaround to support one specific way to repeat a hydra with evil.