【问题标题】:Split the global arguments of a function?拆分函数的全局参数?
【发布时间】:2016-06-29 21:51:29
【问题描述】:

vim中是否有任何命令可以拆分这个函数的参数并将它们放在一个列表中:

qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));

得到

["void *base", "size_t nmemb", "size_t size", "int (*compar)(const void *, const void *)"]

问题在于最后一个参数。

【问题讨论】:

    标签: regex list vim split


    【解决方案1】:

    使用argumentative.vim 循环遍历每个参数。在每个循环中,您可以将参数附加到数组,然后移动到下一个参数边界。

    command! GetArguments echo GetArguments()
    function! GetArguments()
      let reg = @@
      let arr = []
      let view = winsaveview()
      while getline('.')[col('.')-1] != ')'
        normal yi,
        call add(arr, @@)
        normal ],
      endwhile
      let @@ = reg
      call winrestview(view)
      redraw!
      return string(arr)
    endfunction
    

    只需将光标放在第一个参数的 void 中的 v 上,然后运行 ​​:GetArguments。如果要将文本添加到缓冲区,请使用 :put=GetArguments()

    注意:除了你的测试文本,我没有测试过任何文本。您可能需要对其进行修改以满足您的需要。

    我是argumentative.vim 插件的作者,该插件可帮助处理参数/参数。论据提供以下内容:

    • 新的文本对象,i,a,
    • 通过>,<, 转换参数。
    • 分别通过],[, 移动到下一个/上一个参数边界

    我确信还有其他插件可以做类似的事情。

    【讨论】:

    • 我最终完成了自己的功能! +1
    • @Meninx,您可能想在帖子中分享您的功能,以帮助遇到类似问题的其他人
    • @Rincker 这是一个简单的功能,实际上做了我现在想要的,但需要改进!
    【解决方案2】:

    为了得到参数。我最终创建了函数GetArguments(),它拆分参数并将它们放入变量b:list

    function! GetArguments()
                    let l:str=getline(".")
                    let l:str=substitute(l:str,'^\(\s\|\w\)*\("\|[\|(\|<\|{\)','','')
                    let l:str=substitute(l:str,'\("\|]\|)\|>\|}\)\s*\({\|;\)*\s*$','','')
                    let l:i=''
                    let l:oparen=0
                    let l:Arg=""
                    let b:list=[]
                    for l:i in split(l:str,'\zs')
                            if matchstr(l:i , '\("\|[\|(\|<\|{\)' ) != ''
                                    let l:oparen+=1
                            elseif matchstr(l:i , '\("\|]\|)\|>\|}\)' ) != ''
                                    let l:oparen-=1
                            endif
                            if matchstr(l:i, ',\|;') == ''
                                    let l:Arg=l:Arg.l:i 
                            elseif matchstr(l:i, ',\|;') != '' && l:oparen != 0
                                    let l:Arg=l:Arg.l:i
                            elseif matchstr(l:i, ',\|;') != '' && l:oparen == 0
                                    if strlen(l:Arg) != 0
                                          call add(b:list,l:Arg)
                                    endif
                                    let l:Arg=""
                            endif
                    endfor
                    if strlen(l:Arg) != 0
                            call add(b:list,l:Arg)
                    endif 
    endfunction
    

    【讨论】: