Reputation: 1380
In following code:
int return_int_func() { return 0; }
float fv = return_int_func();
Obviously, compiler will warn me fv
may lost precisions because of auto-casting. Face lots of those things, I want replace all stuffs with substitute command. In short, I want this:
float fv = static_cast<float>(return_int_func());
But real codes has lots of forms like that:
float fv = obj.int_field;
float fv = obj->load_int_field("name");
float fv = xx.yy->zz;
I want select my target (obj.int_field
,obj->load_int_field("name")
or xx.yy->zz
) and replace it with static_cast<float>(\1)
. I tried this:
:'<,'>s/\%V/static_cast<float>(&)/g
But vim replaces all characters in selected word with static_cast...
and that isn't what I want at all. Then I tried this:
:'<,'>s/\(\%V\)/static_cast<float>(\1)/g
Vim also do the same thing. I have no idea how to replace whole content (and despite any regex characters) with my pattern. Any suggestions?
Upvotes: 1
Views: 172
Reputation: 22684
The solution is almost too easy! Here it is.
:s/\%V.*\%V./static_cast<float>(&)/
This is actually almost the same as the example from the :help
. We can take away from this that we should all just have looked up :h /\%V
first thing in the morning ...
\%V
is a zero-width atom that matches stuff that is selected in Visual mode. Here it can match at the start of the Visual area. .*
then matches (greedily) as much as it can; its greediness is reined in by the final \%V.
, which requires the last character of the match also to lie within the Visual area.
Tip: If you need to make this change many times over many lines, define the following mappings (even better: put them in your vimrc permanently).
nnoremap & :&&<CR>
xnoremap & :&&<CR>
Then you can repeat the substitution shown above by simply selecting something, and then pressing &
to perform the substitution.
Upvotes: 1
Reputation: 22684
Let me try to paraphrase your question: You would like to Visual select some text, and then perform a substitution, where the selected text is also part of the replacement text.
I think in this case a macro is a much better tool.
To create the macro, first select the first piece of text that you want to wrap in the static cast. For example, select return_int_func()
. (For each step, I'll show what the buffer looks like.)
When you're ready, press qq
to start recording into register q
, then press c
.
float fv = |;
Type the left part of your wrapper text, static_cast<float>(
.
float fv = static_cast<float>(|;
Press CTRL-R "
(Control-R followed by "
): this will reinsert the original text.
float fv = static_cast<float>(return_int_func()|;
Type )
to complete the change, and then Escape to leave insert mode.
float fv = static_cast<float>(return_int_func()▉;
Finally, press q
to stop recording.
At this point you have made the first change and also recorded it as a macro in register q
.
For all remaining changes, simply select a target such as obj->load_int_field("name")
and press @q
to repeat the change.
Look up :help 10.1
for more information about macros.
Upvotes: 1
Reputation: 195029
if I understood you right, you want to do text substitution only on selected text. This is not so easy to do, at least no so easy as a :s
command can do. Because, your visual selection can be in single line, can cross multi lines, also it could char-wise, line-wise, block-wise..
but it can be done with this function:
function! SubVisualText(pat, repl,flag)
try
let v_save = @v
normal! gv"vy
let s = @v
let s = substitute(s, a:pat, a:repl,a:flag)
call setreg('v',s,visualmode())
normal! gv"vp
finally
let @v = v_save
endtry
endfunction
you use it by:
v
, V
or Ctrl-V
):<ctrl-u>call SubVisualText(pattern, replacement, flag)<Enter>
the <ctrl-u>
is for removing the leading range, since the function doesn't need the range.
when you run it, it looks like:(I just tested with Ctrl-V
selection)
Upvotes: 0
Reputation: 57899
The \%V
facility is really not for acting on the selected text as a whole; more for searching inside of that text.
Assuming that you are going to be putting this into a function or maybe mapping this to a key combination, here is an alternative approach that does what you are looking for:
:exec 'normal! gv"adistatic_cast<float>('|exec 'normal! "apa)'
Note that this will use your a
buffer, so if you want to use another buffer you can change the two instances of "a
with "x
, where x
is the buffer you wish to use.
Basically this is going to programmatically yank the selected text, insert static_cast<float>(
, paste the text that was selected, and then insert )
.
Upvotes: 0