Reputation: 11687
Is it possible to provide some parameter when recording a macro in vim via prompt or some other ways?
Edit: I have such code:
foo
bar
And I would like to surround each with ruby block:
expect do
foo
end.to raise_error(CustomClass)
expect do
foo
end.to raise_error(OtherCustomClass)
So, it is easy to create a macro that will result with: expect do foo end.to raise_error()
expect do
foo
end.to raise_error()
But it will be nice to have prompt that will be used to set raise_error method parameter. In each use of macro this parameter will be different.
Upvotes: 8
Views: 6275
Reputation: 18029
Very particularly in the OP's situation, where you really only have precisely two variable pieces of content, I find the easiest method to be a bastardisation of @mkomitee's approach above.
Instead of manually saving the two ‘parameters’ into registers before each usage of the macro, I prefer to type the “first parameter,” visual-select it, evaluate the macro, then type the “second parameter.” To achieve this, I start the macro with a deletion command (a simple d, assuming you're always going to invoke the macro in visual-mode, for instance); then finish it with a command that switches to insert mode (like c or i), and finally, while still in insert mode, a Ctrl-O q to cause the macro to also leave Vim in insert mode when it's done.
As a slightly simple example, if the two “parameters” are single words, here's the keystrokes to create (and then invoke) a macro to manipulate widget.snog()
to a parameterised widgetFoo.fooSnog(bar)
:
foob qq "zdw — we're now recording to the
q
register, with the first ‘argument’ inz
‸
"aP — prefix-paste from a fixed register used elsewhere in the document
widget.snog()‸
^ea␣Ctrl-rEscb~hx — paste the first arg, and capitalize
widget‸Foo.snog()
2w~b"zP — capitalize existing word, then paste the first arg again
widgetFoo.fo‸oSnog()
$Ctrl-Oq — move to the last position, enter insert-mode, and end the macro
widgetFoo.fooSnog(‸)
After finishing the first instance with
bar
, we can now use it several times:
obazEscb — set up our first ‘argument’,
widgetFoo.fooSnog(bar) ‸baz
@qquuxEsc — invoke the macro, and finish with the second one
widgetFoo.fooSnog(bar) widgetBaz.bazSnog(quux‸)
ocorgeEscb@@graultEsc — repeat a third time
widgetFoo.fooSnog(bar) widgetBaz.bazSnog(quux) widgetCorge.corgeSnog(grault‸)
ogarplyEscb@@waldoEsc — … and so on
widgetFoo.fooSnog(bar) widgetBaz.bazSnog(quux) widgetCorge.corgeSnog(grault) widgetGarply.garplySnog(waldo‸)
Of course, it looks laborious, typed out in such a long fashion — but it's surprisingly few key-strokes in practice, and very easy to train into your fingers.
tl;dr: type the first argument; enter macro-recording before deleting it into a register; manipulate your text as desired; then leave vim in insert-mode at the position of the second argument with Ctrl-Oq.
Upvotes: 2
Reputation: 1041
If you need to generate a code, which is the case, the best way for this is to use vim snippets. You can configure snippet to put cursor where you need when you [tab].
Upvotes: 0
Reputation: 760
While I agree with everyone else that if you need this feature, you're probably going about things inefficiently, it is possible to insert a variable text string into a document as part of a macro. The trick is to store the text you want to use in your macro in a register.
"xyw
to yank a word into the x registerqq
, when you want to place the variable text, put it, for example "xp
to put the text in the x register into the document where the cursor is@q
, it will use whatever is currently in the x register, so you can yank different text into the x register, play your q macro, and the newly yanked text will be used. Upvotes: 9
Reputation: 79175
If you are talking about recording a macro with qx...q
, this is not possible.
However you could still do : :let @y = substitute(@x, 'old_pattern', 'replacement', 'g')
and then use @y
.
You could also define a function:
function Play(myArg)
execute 'normal sequence_of_characters' . a:myArg . 'other_sequence_of_characters'
endfunction
call Play('foo')
Upvotes: 6