高效的vim regex切换多行函数调用
由于我使用vim的经验非常有限,我在编写正则表达式和编辑vimrc时遇到了困难。 我有一个很长的函数调用:高效的vim regex切换多行函数调用,regex,vim,Regex,Vim,由于我使用vim的经验非常有限,我在编写正则表达式和编辑vimrc时遇到了困难。 我有一个很长的函数调用: dothis(123, [1, 2], [2, [7,8]], 'text (), []', [], fn([123], 'abc, def', [[], [123]])); 我经常需要改为跟随,反之亦然 dothis( 123, [1, 2], [2, [7,8]], 'text (), []', [], fn([123], 'abc,
dothis(123, [1, 2], [2, [7,8]], 'text (), []', [], fn([123], 'abc, def', [[], [123]]));
我经常需要改为跟随,反之亦然
dothis(
123,
[1, 2],
[2, [7,8]],
'text (), []',
[],
fn([123], 'abc, def', [[], [123]])
);
我是否可以使用:%s/search/replace/
语法执行此操作
或者这应该是我的vimrc中的ToggleFnCall函数,被称为:call ToggleFnCall()
还是应该将其作为记录的宏而不是正则表达式
每个人都是从头开始写效率脚本的吗?或者我不知道几乎每个vim用户都在扩展什么?匹配(嵌套)括号需要vim没有的正则表达式扩展,请参阅
相反,您最好依靠内置的%
命令转到匹配的括号。此外,()在您的示例中也非常有效
有了它,我将编写一个函数(作为进入下一个参数的逻辑,并检查停止的位置将相当复杂),然后由映射调用该函数。但是如果您是Vimscript新手,请注意这并不是一件小事,您最好使用上面提到的插件来加速手动重新格式化。(另一方面,如果您成功地将其转换为插件并发布,它肯定会受到其他Vim用户的欢迎。)这并不好,我也不保证它不会坏,也不保证它在所有情况下都能工作(“未经良好测试”是一种轻描淡写的说法;我也不是VimL专家),但这可能会起作用:
function! SplayFnCall()
let magic = &magic
set magic
exe "normal _f(vi(\<Esc>a\<CR>\<Esc>gvo\<Esc>i\<CR>\<Esc>"
while 1
norm "zyl
if (@z =~ "[a-zA-Z0-9_]")
exe "norm /[^a-zA-Z0-9_ ]\<CR>\"zyl``"
endif
if (@z == "[" || @z == "(" || @z == "{" || @z == "'" || @z == '"')
exe "norm va".@z."\<Esc>"
endif
norm f,
norm "zyl
if (@z == ",")
exe "norm a\<CR>\<Esc>_"
else
let &magic = magic
return
endif
endwhile
endfunction
nmap <leader>fs :call SplayFnCall()<CR>
nmap <leader>fu va(J%l"_x
函数!SplayFnCall()
让魔法=&魔法
设置魔法
exe“正常(vi)(\a\\gvo\i\\”
而1
标准“zyl
如果(@z=~“[a-zA-Z0-9_307;]”)
exe“norm/[^a-zA-Z0-9\\\“zyl`”
恩迪夫
如果(@z==”[“| |@z==”(“| |@z==”{“| |@z==”””“|@z==”)
exe“norm va”。@z.“\”
恩迪夫
范数f,
标准“zyl
如果(@z==”,“”)
exe“规范a\\\”
其他的
让&魔术=魔术
返回
恩迪夫
循环结束
端功能
nmap fs:call-SplayFnCall()
nmap fu va(J%l“\u x
尽量不要在子括号内,点击\fs
展开,点击\fu
取消播放(除非重新定义引线,然后进行相应调整)。显然,您可以更改映射
正如Ingo所说,不可能将其编写为regexp(因为嵌套分隔符),也不可能在简单的宏中编写(因为分支逻辑)。您确实需要编程语言的全部功能
另外,我并没有把它作为一个切换,因为我不太确定什么时候需要展开,什么时候需要取消展开,所以有两个不同的映射。我不认为花时间来找到正确的替换/宏是值得的 如果没有外部格式化程序,我将如何处理此任务:
f(
ci(
<CR>
<C-r>"
<CR>
<Esc>
k
ci(
"
K
:.,/);/s/, /,\r/gc<CR>
:,/);/s/,/,\r/gc
:'{,'}norm ==<CR>
:“{,”}范数==
function! Foo()
normal! 0f(
" ^M is obtained with <C-v><CR> and ^R with <C-v><C-r>
normal! ci(^M^R"^M
normal! k
.,/);/s/, /,\r/gc
'{,'}normal! ==
endfunction
function!Foo()
正常!0f(
“^M是用获得的,^R是用
正常!ci(^M^R“^M
正常!k
,/);/s/,/,\r/gc
{,}正常==
端功能
并为其指定映射:
nnoremap <key> :call Foo()<CR>
nnoremap:callfoo()
要恢复为单线版本,请选择块并按
J
至于你的最后一个问题,经验丰富的vimmer从不寻找适合所有可能场景的唯一银弹。相反,他/她从Vim提供的大量小部件中构建小型、专业化的解决方案。一些特殊解决方案可以轻松、快速地变为通用和可重用的解决方案,如上文所述 我建议演示如何首先将重复性任务转换为专用宏,然后转换为通用映射
我采用了同样的方法来回答这个问题。是的,我喜欢你的方法和它的简单性。PS:那个家伙确实很快。我已经在插件中进行了逻辑处理,以进入下一个参数边界。例如,
],
映射。我通常的做法是从(
并执行一个宏,如],age
。然后根据需要多次重复该宏。它并不完美,但它确实尊重嵌套参数。带有双反勾号的行可以替换为:执行“normal/[^a-zA-Z0-9\\\“zyl”if(@z==”,”)。normal``endif
允许它格式化f1(a,f2(),b)
。