在以下代码中:
int return_int_func() { return 0; }
float fv = return_int_func();
显然,编译器会警告我fv
可能会因为自动转换而失去精确度。面对很多这样的事情,我想用替换命令替换所有的东西。简而言之,我想要这个:
float fv = static_cast<float>(return_int_func());
但真实代码有很多这样的形式:
float fv = obj.int_field;
float fv = obj->load_int_field("name");
float fv = xx.yy->zz;
我想选择我的目标(obj.int_field
,obj->load_int_field("name")
或xx.yy->zz
)并将其替换为static_cast<float>(\1)
。我试过这个:
:'<,'>s/\%V/static_cast<float>(&)/g
但是vim用static_cast...
替换所选单词中的所有字符,这根本不是我想要的。然后我尝试了这个:
:'<,'>s/\(\%V\)/static_cast<float>(\1)/g
Vim也做同样的事情。我不知道如何用我的模式替换整个内容(尽管有任何正则表达式字符)。有什么建议?
答案 0 :(得分:1)
让我试着解释一下你的问题:你想要Visual选择一些文本,然后执行替换,其中所选文本也是替换文本的一部分。
我认为在这种情况下,宏是一个更好的工具。
要创建宏,首先选择要在静态强制转换中包装的第一段文本。例如,选择return_int_func()
。 (对于每个步骤,我将显示缓冲区的样子。)
准备好后,按 qq
开始录制到注册q
,然后按 c
float fv = |;
键入包装文本的左侧部分static_cast<float>(
。
float fv = static_cast<float>(|;
按 CTRL-R "
(Control-R后跟"
):这将重新插入原始文本。
float fv = static_cast<float>(return_int_func()|;
键入)
以完成更改,然后退出以退出插入模式。
float fv = static_cast<float>(return_int_func()▉;
最后,按 q
停止录制。
此时您已进行了第一次更改,并将其记录为注册q
中的宏。
对于所有剩余的更改,只需选择obj->load_int_field("name")
等目标,然后按 @q
重复更改。
查找:help 10.1
以获取有关宏的更多信息。
答案 1 :(得分:1)
解决方案几乎太容易了!在这里。
:s/\%V.*\%V./static_cast<float>(&)/
这实际上与:help
中的示例几乎相同。我们可以忽略这一点,我们应该在早上第一件事:h /\%V
抬起头来......
\%V
是零宽度原子,匹配在可视模式下选择的内容。它可以在Visual区域的开头匹配。 .*
然后尽可能多地匹配(贪婪);它的贪婪是由最后的\%V.
控制的,它要求匹配的最后一个字符也位于可视区域内。
提示:如果您需要在多行上多次进行此更改,请定义以下映射(更好的是:永久地将它们放入vimrc中)。
nnoremap & :&&<CR>
xnoremap & :&&<CR>
然后,您可以通过简单地选择一些内容重复上面显示的替换,然后按&
来执行替换。
答案 2 :(得分:0)
\%V
设施实际上并非用于对所选文本进行整体操作;更多用于搜索该文本。
假设您将把它放入一个函数或者将它映射到一个组合键,这里有一个替代方法可以满足您的需求:
:exec 'normal! gv"adistatic_cast<float>('|exec 'normal! "apa)'
请注意,这将使用您的a
缓冲区,因此,如果您想使用其他缓冲区,则可以使用"a
更改"x
的两个实例,其中x
为你想要使用的缓冲区。
基本上,这将以编程方式抽取所选文本,插入static_cast<float>(
,粘贴所选文本,然后插入)
。
答案 3 :(得分:0)
你可以尝试
:%s/float fv =(.*)$/float fv = static_cast<float>(\1)/g
答案 4 :(得分:0)
如果我理解正确,您只想对所选文本进行文本替换。这不是那么容易做到的,至少没有:s
命令那么容易。因为,您的视觉选择可以是单行,可以跨越多行,也可以是明智的,逐行的,块状的。
但可以使用此功能完成:
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
你通过以下方式使用它:
v
,V
或Ctrl-V
完成):<ctrl-u>call SubVisualText(pattern, replacement, flag)<Enter>
<ctrl-u>
用于删除前导范围,因为该函数不需要范围。
当你运行它时,它看起来像:(我刚用Ctrl-V
选择测试)