Reputation: 670
I'm doing some markdown editing in vim on a file. I'm trying to convert it to markdown with code highlighting, etc.
- Arithmetic operators:`+,−,*, /`
- Constants: `e`, `pi`
- Functions: (abs x), (max x y... ), (ceiling x) (expt x y), (exp x),
(cos x), ...
I want to select only the things that are in parantheses (including the parantheses) in the following using visual mode (so they would be disjoint by the commas):
(abs x), (max x y... ), (ceiling x) (expt x y), (exp x),
(cos x), ...
And then do S`
to surround the each piece of text with backticks. How can I do this without selcting each one, then doing S`
repeatedly?
Upvotes: 0
Views: 134
Reputation: 198304
How can I do this without selcting each one, then doing S` repeatedly?
This is actually what works best in Vim. With a bit of help from macros:
Interactive version:
/(.\{-})<CR>
qqysa)`nnq
@q
@@
@@
... till you do them all and wrap around to where you started.
Non-interactive "just do it" version:
:set nows<CR>
gg
/(.\{-})<CR>
qqqqqysa)`nn@qq@q
You'll probably want to go back to :set ns
afterwards.
Of course, if you know that there are no nested parentheses, then the simplest answer is using :s
, like the other answerer suggested.
EDIT with the explanation of the macro:
qqqqq...@qq@q
is a loop. Here's how it works:
qq
followed by q
clears the q
register. This will be important later.qq
starts the macro recording.ysa)
surrounds around the parentheses with `
.nn
goes to the next match. We have to do it twice, because surround jumps to before the paren, and n
will match the same parentheses again.@q
invokes the q
macro. It is empty, so this does nothing... now. However, read further...q
stops the macro recording, and stores it to the q
register.q
is not empty any more, we can execute it with @q
. However, during the execution q
will still not be empty, so when we get to the point in the macro that did nothing during the recording, the macro will relaunch, giving us a primitive, but functioning, recursion loop.:set nows
to make sure we don't continue infinitely adding backticks to all parentheses.After a bit of thought, you can actually rewrite the pattern so that :set nows
(and additional n
) is not needed:
/`\@<!(.\{-})<CR>
qqqqqysa)`n@qq@q
This matches a pair of parentheses not preceded by a backtick, so that after all matches have been dealt with there is no match for n
, naturally breaking the loop.
If anyone thinks this is complex... note that most editors plain can't do it (since this takes into account proper parenthesis nesting, whereas I haven't yet seen an editor with search-replace robust enough to be able to pull it off).
Upvotes: 2
Reputation: 4673
Using a global command (assuming `S`` comes from surround.vim):
:global/(/normal f(ysab`
(This affects the whole file, and may only do one change at a time. Repeat with @:
)
With a macro:
qqf(ysab`q
Repeat with @q
and then @@
Or with substitute:
:substitute/([^)]\+)/`&`/g
Upvotes: 0