当然,对于许多人而言,可以在IDE上进行重构的事实是无价的,我在编码时几乎不会这样做,但是在编辑其他人的源代码时可能会尝试这样做。如何在Vim中的多个文件中完成如此琐碎的任务?
我找到了用于重构Ruby的插件,但是“任何”语言怎么样?
当然,对于许多人而言,可以在IDE上进行重构的事实是无价的,我在编码时几乎不会这样做,但是在编辑其他人的源代码时可能会尝试这样做。如何在Vim中的多个文件中完成如此琐碎的任务?
我找到了用于重构Ruby的插件,但是“任何”语言怎么样?
Answers:
我同意“ Vim不是IDE”范式。但是有时候没有IDE。在这些情况下,我将使用以下方法:
重构与常规替换有更多关系,我通常在项目树上使用:grep,然后记录一个宏进行重构-:g和:s毫不费力。通常,它可以让我毫不费力地快速修改大量文件。老实说,我比其他任何人都使用这种方法。
根据您的工作流程,内置命令可能会很慢/不便。如果您使用git,那么您将要使用出色的Fugitive插件及其:Ggrep
命令来仅搜索签入git的文件。我也喜欢Silver Searcher的快速性。
:cdo和:argdo可以方便地在一组文件上执行vim命令。
当更难通过:vimgrep
我确定需要更改的文件列表时,请使用命令行grep / find命令来更紧密地整理我需要重构的文件列表。将列表保存到文本文件并使用:e
和宏录制的混搭来进行我需要进行的更改。
我发现保持宏录制技能的生锈程度越小,发现Vim重构就越有用:可以轻松地从寄存器保存/恢复,递增/递减寄存器计数器变量,清理/保存宏记录以备以后使用等。
更新资料
自从为我描述的方法编写了更多的视频广播以来,已经在vimcasts.org上发布了(我鼓励您观看所有的Vimcasts!)。要进行重构,请注意以下内容:
Vimgolf也是练习的好方法。
自从我写了这个答案以来,语言服务器协议服务器的普及还为Vim(和其他编辑器)带来了一些重构能力。IMO,它们与您在专用IDE中看到的重构功能(要使用重构功能,我确实会使用它们,并且更喜欢使用coc和ALE)相提并论。有关更多信息,请参见此问题的其他答案!
语言服务器协议包含用于在项目中智能重命名符号的功能:
例如,以下语言服务器对此提供支持:
您可以在https://langserver.org/下找到更多语言服务器。
要在vim中使用它们,必须有一个vim编辑器客户端。存在以下选项:
LanguageClient-neovim(需要防锈)建议映射:
nnoremap <silent> <F2> :call LanguageClient_textDocument_rename()<CR>
coc.nvim(需要node.js)建议映射:
" Remap for rename current word
nmap <leader>rn <Plug>(coc-rename)
啤酒有
nnoremap <silent> <Plug>(ale_rename) :ALERename<Return>
Ale没有定义任何键绑定。这必须由用户完成。
vim-lsp提供以下命令
:LspRename
与Ale相似,不建议任何映射。但是,您当然可以定义如下
nmap <leader>r <plug>(lsp-rename)
(<leader>r
将由您选择;我不知道大多数插件都同意)
vim-lsc具有默认映射:
'Rename': 'gR'
另请参见YouCompleteMe,它也促进LSP。
自2000年以来,Neovim已初步支持lsp。 二○一九年十一月一十三日
有关LSP的常见配置,请参见 https://github.com/neovim/nvim-lsp
但是,我不知道智能重命名是如何工作的。如果有人知道这一点,请更新此部分。
我不知道LSP协议是否有计划支持更复杂的重构,例如更改类结构,向方法/功能添加参数或将方法移至其他类。有关重构的列表,请参见https://refactoring.com/catalog/。
coc-rename
仅适用于当前缓冲区。它没有在项目中(跨文件)全局更新导出名称的使用。
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
默认情况下,没有映射。
为了进行重构,如果您正在使用Unite(并且应该这样做),则可以使用vim-qfreplace并使其变得非常容易。检查此视频演示它是如何工作的。设置好工作流程后,您可以进行一些映射来对其进行优化(而不是像视频中那样键入大多数内容)。
两个插件的组合:vim-ripgrep,可在文件中查找并将结果放入quickfix窗口中,而quickfix-reflector 则可将更改保存在quickfix窗口中,并自动将所有更改保存在文件中。
我会考虑使用emacs的spacemacs版本。它使用与Vim相同的模式和大多数击键功能,但由于其简洁的特性而具有更多的附加组件。如果要使用C ++编程,则只需添加c ++层,并且大多数IDE都已为您设置好。对于其他解释语言(例如python或bash),您无需离开spacemacs即可使用它们。他们甚至可以直接在您的文本中运行代码块,这对于将代码和数据放在同一文件中的识字编程或可再现编程非常有用。两者均以文本形式完成。
Spacemacs的初始负载繁重得多,但是您可以使用它完成的其他工作仅值几秒钟的启动成本。一层组织模式值得一试。这是我用过的最好的大纲,程序员,日定时器/待办事项列表。
- 改名
- 提取功能
- 提取局部变量
- 切换var⇔:=
- 添加Godoc存根
有一个vim插件https://github.com/godoctor/godoctor.vim,使它们可用
将光标放在要重命名的东西中:
:Rename <newname>
突出显示要提取的块:
:Refactor extract newfunc
:GoRename
。语言服务器 gopls