在Vim中重构

Hel*_*nda 83 vim refactoring

当然,你可以在IDE上进行重构的事实对于许多人来说是无价的,我在编码时几乎没有这样做但我可能会在编辑其他人的源代码时尝试这样做.你如何在Vim中的多个文件中完成这样一个微不足道的任务?

我发现这个用于重构Ruby的插件,但"任何"语言怎么样?

dsu*_*rsl 68

我同意'Vim不是IDE'的范例.但有时候没有IDE.这是我在这些情况下使用的内容:

:grep,:vimgrep,:Ag,:Ggrep

重构更多与常规替换有关我通常使用:grep在我的项目树上,然后记录一个宏来做重构 - :g和:s不是脑子.通常它会让我快速修改大量文件.老实说,我使用这种方法比任何其他方法更多.

根据您的工作流程,内置命令可能很慢/不方便.如果您使用git,那么您将需要使用优秀的Fugitive插件及其:Ggrep命令来仅搜索已检入git的文件.我也喜欢Silver Searcher的速度.

:argdo,:cdo,和:bufdo

:cdo:argdo可以方便地对一组文件执行vim命令.

命令行

当我更难确定需要更改的文件列表时,:vimgrep我使用命令行grep/find命令来更仔细地调整我需要重构的文件列表.将列表保存到文本文件并使用:e宏录制的混搭来进行我需要进行的更改.

我发现我保持宏观记录技能的不那么生锈我发现Vim用于重构更有用:感觉舒适地从寄存器保存/恢复,递增/递减寄存器计数器变量,清理/保存宏记录到文件供以后使用,等等.


更新

因为为我描述的方法编写这些更多的视频播放已经发布在vimcasts.org上(我鼓励你观看所有的Vimcasts!).对于重构观看这些:

Vimgolf也是一种很好的练习方式.

  • 重构比模式匹配更重要,这就是为什么需要IDE以安全的方式自动化它.显然,您可以手动执行此操作,但考虑到可用选项,并且大多数情况下手动操作更安全,为什么还要考虑其他选项? (11认同)
  • @CutbertoOcampo 我在某种程度上同意你的观点:根据项目的各个方面(结构、语言、员工技能和资源等),可能有一个很棒的重构工具适用于你的问题。我的回答适用于情况并非如此,并且您想在 Vim 中解决该问题。 (3认同)
  • 几乎每种语言都有一个 ide。尝试使用 vim 或 regex 进行重构听起来绝对是疯狂的。你为什么要尝试? (3认同)
  • @rolls 足够强大,可以用非您的 ide 或任何您只能忍受的 cfg 随机抓取同事需要的机器,并留下良好的印象(不是为了“只是印象”,而是为了声誉和未来的职位)。 (3认同)
  • 这很好,我知道人们可能会觉得使用他们的长期首选工具做得更舒服,并且有一些黑客可以表现得非常好,可能比那里的任何IDE更好,但对于一个不合适的-box解决方案我会说实际的IDE对大多数用户来说效果会更好.我会考虑80-20%的情况(甚至更多,有利于IDE的平衡). (2认同)

小智 12

C系列

  1. 尝试使用插件Clighter重命名为c系列重构.它基于clang,但有一些限制,插件被标记为已弃用.

    Clighter建议的映射是

    nmap <silent> <Leader>r :call clighter#Rename()<CR>
    
    Run Code Online (Sandbox Code Playgroud)

    注意,后继插件clighter8已删除了提交24927db42中的重命名功能.

  2. 如果你使用neovim,你可以看一下插件.它表明

    nmap <silent> <Leader>r :call ClampRename()<CR>
    
    Run Code Online (Sandbox Code Playgroud)


Hot*_*hke 12

蟒蛇

对于python语言,以下插件为vim提供了"智能"重命名功能:

  • jedi-vim(github)<leader>r
  • ropevim(github)CTRL-c r r
  • python-mode(github):h pymode-rope-refactoring


Hot*_*hke 9

语言服务器协议 (LSP)

语言服务器协议包含用于在项目中智能重命名符号的功能:

https://microsoft.github.io//language-server-protocol/specifications/specification-3-14/#textDocument_rename

例如,以下语言服务器对此提供支持:

您可以在https://langserver.org/下找到更多语言服务器。

Vim

要在vim中使用它们,必须有一个vim编辑器客户端。存在以下选项:

  1. LanguageClient-neovim(需要防锈)建议映射:

    nnoremap <silent> <F2> :call LanguageClient_textDocument_rename()<CR>
    
    Run Code Online (Sandbox Code Playgroud)
  2. coc.nvim(需要node.js)建议映射:

    " Remap for rename current word
    nmap <leader>rn <Plug>(coc-rename)
    
    Run Code Online (Sandbox Code Playgroud)
  3. 啤酒

    nnoremap <silent> <Plug>(ale_rename) :ALERename<Return>
    
    Run Code Online (Sandbox Code Playgroud)

    Ale没有定义任何键绑定。这必须由用户完成。

  4. vim-lsp提供以下命令

    :LspRename
    
    Run Code Online (Sandbox Code Playgroud)

    与Ale类似,不建议使用任何映射。但是,您当然可以定义以下内容

    nmap <leader>r <plug>(lsp-rename)
    
    Run Code Online (Sandbox Code Playgroud)

    <leader>r将由您选择;我不知道大多数插件都同意)

  5. vim-lsc具有默认映射:

    'Rename': 'gR'
    
    Run Code Online (Sandbox Code Playgroud)

另请参阅YouCompleteMe,它也促进LSP。

新病毒

Neovim从此对LSP最初的内置支持2019年11月13日

请参阅LSP的常见配置https://github.com/neovim/nvim-lsp

但是,我不知道智能重命名是如何工作的。如果有人知道这一点,请更新此部分。

其他重构

我不知道LSP协议是否计划支持更复杂的重构,例如更改类结构,向方法/函数添加参数或将方法移至其他类。有关重构的列表,请参见https://refactoring.com/catalog/

  • AFAIK 重命名`coc-rename` 仅适用于当前缓冲区。它没有更新项目中全局导出名称的使用(跨文件)。 (2认同)

Luc*_*tte 5

我为通用重构编写了这个插件.它仍然需要很多改进.在未来的某个时候,我会尝试放弃ctags,转而采用Cng和C++重构的方法.


小智 5

也许不是最优雅的解决方案,但我发现它非常方便:我使用ECLIM连接 VIM 和 Eclipse。当然,我所有的源代码编辑都是在 VIM 中完成的,但是当需要重构时,可以利用 Eclipse 在这方面的卓越功能。

试一试。


Hot*_*hke 5

插件YouCompleteMe (YCM)(github 上的 20k 星)

http://ycm-core.github.io/YouCompleteMe/#the-refactorrename-new-name-subcommand

:h RefactorRename-new-name

在支持的文件类型中,此命令尝试对光标下的标识符执行语义重命名。这包括重命名标识符的声明、定义和用法,或任何其他适合语言的操作。具体行为由使用中的语义引擎定义。

与 类似FixIt,此命令对源文件应用自动修改。重命名操作可能涉及对多个文件的更改,这些文件可能会或可能不会在 Vim 缓冲区中打开。YouCompleteMe 为您处理所有这些。以下部分描述了该行为。

支持的文件类型:c、cpp、objc、objcpp、cuda、java、javascript、typescript、rust、cs

默认情况下没有映射。