0

The problem I wish to solve, first of all, is when you want do do the same editing on multiple lines, but they are not aligned so you can't use Ctrl + V, maybe the lines are not even adjacent. In these cases I tend to use q to record, and then I reproduce with @, but I would like to know if I can do both at the same time.

I want to know if it is possible to craft a more practical and volatile version of the recording feature (:h recording).

Ideally, I would like to press:

  • {count} as any number, becomes 1 by default
  • [ key
  • Any key sequence, for example, $F)i, 0<esc>2j
  • ] key

And the behaviour I would like to see is the key sequence I pressed being simulated {count} times.

2 Answers 2

0

You could accomplish that with a mapping that stores the count (for example, in a buffer-local, script-local or even global variable) and start recording a macro (say qa), and then a second mapping for ] that stops recording the macro and executes it the number of times passed as the count (minus one, since the recording itself also counts!)

In short:

nnoremap <silent> [ :<C-U>let b:recording_count = v:count1<CR>qa
nnoremap <expr> ] 'q' . (b:recording_count > 1 ? (b:recording_count - 1).'@a' : '')

This is not super robust, you might run into issues if you use ] before [ or otherwise while you're not recording...

You can maybe come up with something a bit more advanced, for example by installing the mapping for the end of recording just when you start recording. You could use q for the end mapping in that case, since that's how you otherwise end a recording.

This is also using a fixed register (@a) which could also be addressed (e.g. using v:register to allow the user to pick a different one.)

In general though, I'm not sure I like this idea that much, given it makes it hard to fix a mistake during recording the macro, and isn't really gaining much, since all you need to do is do the (count-1)@a at the end of recording anyway...

1

One other option is to use the expression register = together with the macro replay operator @.

When you type @=, Vim will let you enter a Vimscript expression (i.e. a string) and will execute that string as a macro. You can pass @= a count and it will repeat the execution {count} times.

In your case, start with, say, 7@= (to run it seven times), then in the prompt enter "$F)i, 0\<esc>2j" and press Enter. This will execute that string as a macro seven times. Note that you need the quotes "..." to turn the expression into a string, and that you can use key names such as <esc>, but you need to escape them with a backslash so that Vim knows it's a special character (this escaping of key names only works in double quoted strings, not single quoted '...' ones.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.