2

Given:

https://stackoverflow.com/questions/ask

From normal mode at the first character, typing in qaqqaf/xb@aq@a clears all of the forward slashes.

  1. qaq clears the a register
  2. qa starts recording to a
  3. f/x deletes the next forward slash
  4. @a re-runs the macro
  5. q ends the recording

But running normal qaqqaf/xb@aq@a stops after b -- it seems to bail at the recursive call. The same happens if you try to use map the command.

Is there something wrong with my syntax? Or is it impossible to record a recursive macro with normal?


Note: I know it's possible to write a recursive macro with let. I'm wondering if this is the only way to write a recursive macro without recording it manually:

let @a = "f/xb@a"
normal @a

(I ask because of this answer: Remove everything except regex match in Vim )

Community
  • 1
  • 1
idbrii
  • 10,975
  • 5
  • 66
  • 107
  • Vim can execute anything in a register as a macro. So however you get your commands into a register would be a way, like yanking in text. I believe `let` to be the best way to do this for a mapping. – Peter Rincker Jan 07 '11 at 23:58
  • Right, but is it possible to record a recursive macro **with `normal`**? – idbrii Jan 09 '11 at 03:21
  • it seems that `normal` does not handle recursive macros well. I cannot seem to get one to record properly. However you can use `execute` and `feedkeys()` together like so: `exe feedkeys("qaqqar_l@aq@a", 't')` to both record and execute the macro. – Peter Rincker Jan 11 '11 at 21:33

1 Answers1

3

If you want to create a map to a recursive macro I suggest you start by doing something like so:

nmap <f2> :let @a = "f/xb@a"|normal @a

Of course this clobbers the @a register and if you find you self doing many of these kinds of mappings maybe a function would better suit your needs.

Here is a safer alternative to making recursive macro mappings:

function! RecMacroExe(cmds)
  let a = @a
  let @a = a:cmds . "@a"
  try
    normal @a
  finally
    let @a = a
  endtry
endfunction

nmap <f2> :call RecMacroExe("f/xb")<cr>

Edit: Changed function according to @Luc Hermitte comment

Peter Rincker
  • 43,539
  • 9
  • 74
  • 101