Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/vim/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
高效的vim regex切换多行函数调用_Regex_Vim - Fatal编程技术网

高效的vim regex切换多行函数调用

高效的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,

由于我使用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, 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
    
  • 使用交互式替换将一些逗号+空格更改为逗号+cr

    :.,/);/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)