簡體   English   中英

在 Vim 中重構

[英]Refactoring in Vim

當然,您可以在 IDE 上重構這一事實對許多人來說是無價的,我在編碼時幾乎從不這樣做,但在編輯其他人的源代碼時我可能會嘗試這樣做。 你如何在 Vim 中跨多個文件完成這樣一個微不足道的任務?

我找到了這個用於重構 Ruby 的插件,但是“任何”語言呢?

我同意“Vim 不是 IDE”的范式。 但有時沒有 IDE。 這是我在這些情況下使用的:

免責聲明:自從我寫下這個答案以來,語言服務器協議服務器、linter 和修復程序的無處不在也為 Vim(和其他編輯器)帶來了一些很棒的重構功能。 IMO 與您在專用 IDE 中看到的功能相比,它們還有很長的路要走(我更喜歡ALEnvim-lspconfig這些功能)。 有關更多信息,請參閱有關此問題的其他答案!

:grep, :vimgrep, :GrepperAg, :Ggrep

與常規替換有更多關系的重構我通常在我的項目樹上使用:grep ,然后錄制一個宏來進行重構 - :g 和 :s 是沒有腦子的。 通常它會讓我不費吹灰之力就快速修改大量文件。 老實說,我使用這種方法比其他任何方法都多。

根據您的工作流程,內置命令可能會很慢/不方便。 如果您使用 git,那么您將需要使用優秀的Fugitive插件及其:Ggrep命令來僅搜索簽入 git 的文件。 我也喜歡vim-grepper,因為它速度快且與搜索無關(支持 ag、sift 等)。

:argdo、:cdo 和 :bufdo

:cdo:argdo可以方便地在一組文件上執行 vim 命令。

命令行

當很難通過:vimgrep確定需要更改的文件列表時,我會使用命令行 grep/find 命令來更仔細地:vimgrep需要重構的文件列表。 將列表保存到文本文件並使用:e和宏錄制混搭進行我需要進行的更改。

我發現我的宏錄制技巧越不生疏,我發現 Vim 在重構方面越有用:從寄存器中保存/恢復感覺很舒服,增加/減少寄存器計數器變量,清理/保存宏錄制以供以后使用等。


更新

自從為我描述的方法編寫了更多的視頻廣播以來,vimcasts.org 上已經發布了(我鼓勵你觀看所有的 Vimcasts! )。 對於重構看這些:

Vimgolf也是一種很好的練習方式。

語言服務器協議(LSP)

語言服務器協議包含在項目中智能重命名符號的功能:

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

例如以下語言服務器支持:

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

維姆

在 vim 中使用它們需要一個 vim 編輯器客戶端。 存在以下選項:

  1. LanguageClient-neovim (需要 rust)建議映射:

     nnoremap <silent> <F2> :call LanguageClient_textDocument_rename()<CR>
  2. coc.nvim (需要 node.js)建議映射:

     " Remap for rename current word nmap <leader>rn <Plug>(coc-rename)
  3. 艾爾

     nnoremap <silent> <Plug>(ale_rename) :ALERename<Return>

    Ale 沒有定義任何鍵綁定。 這必須由用戶完成。

  4. vim-lsp提供以下命令

     :LspRename

    與 Ale 類似,不建議映射。 但是,當然你可以定義一個如下

     nmap <leader>r <plug>(lsp-rename)

    <leader>r將被您的選擇所取代;我不知道大多數插件都同意哪個)

  5. vim-lsc有一個默認映射:

     'Rename': 'gR'

另請參閱YouCompleteMe ,它也有助於 LSP。

新維姆

Neovim從此對LSP最初的內置支持2019年11月13日

有關 LSP 的常見配置,請參閱項目nvim-lspconfig ,其中建議<space>rn作為vim.lsp.buf.rename()的映射。

其他重構

我不知道 LSP 協議是否有計划支持更復雜的重構,例如更改類結構,向方法/函數添加參數或將方法移動到不同的類。 有關重構列表,請參閱https://refactoring.com/catalog/

Python

對於python語言,以下插件為 vim 提供了“智能”重命名功能:

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

C-家庭

  1. 嘗試使用插件Clighter對 c 系列進行重命名重構。 它基於 clang,但存在限制,並且該插件被標記為已棄用。

    Clighter建議的映射是

     nmap <silent> <Leader>r :call clighter#Rename()<CR>

    請注意,后續插件clighter8已刪除提交 24927db42 中的重命名功能。

  2. 如果你使用neovim,你可以看看插件 它建議

     nmap <silent> <Leader>r :call ClampRename()<CR>

我為通用重構編寫了這個插件 它仍然需要許多改進。 將來的某個時候,我將嘗試放棄 ctags,轉而使用 clang 進行 C&C++ 重構。

也許不是最優雅的解決方案,但我發現它非常方便:我使用ECLIM連接 VIM 和 Eclipse。 當然,我所有的源代碼編輯都是在 VIM 中完成的,但是當需要重構時,可以利用 Eclipse 在這方面的卓越能力。

試試看。

插件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

默認情況下沒有映射。

插件因素

還有另一個專門用於重構的 vim 插件,稱為factorus ,可在github 上找到

目前(2017-12),它支持的語言

  • C,
  • 爪哇,和
  • Python。

將光標放在名稱上以重構並鍵入

gd (或gD,如果您要重構全局變量)。

然后

cgn new_name esc

. 一次或多次重構下一次出現

要么

:%范數。 一次重構緩沖區中的所有事件。

我在 vim 中寫了很多 C/C++ 代碼。 我做的最常見的重構是重命名變量、類名等。 通常,我使用:bufdo :%s/source/dest/g在文件中進行搜索/替換,這與 big 提供的重命名幾乎相同IDE的。
然而,就我而言,我發現我通常會重命名類似的實體,拼寫不同的案例(即 CamelCase、snake_case 等),所以我決定編寫一個小實用程序來幫助這種“智能案例”搜索/替換,它托管在這里 它是一個命令行實用程序,而不是 vim 的插件,我希望你能發現它有用。

  1. 工具godoctor ( github ) 支持多種重構能力
  • 改名
  • 提取函數
  • 提取局部變量
  • 切換變量 ⇔ :=
  • 添加 Godoc 存根

有一個 vim 插件https://github.com/godoctor/godoctor.vim使它們可用

將光標置於要重命名的事物中:

 :Rename <newname>

要提取的突出顯示塊:

 :Refactor extract newfunc
  1. vim-go

    • 使用:GoRename對標識符進行精確的類型安全重命名。
  2. 語言服務器gopls

對於重構,如果您正在使用Unite (並且您應該使用),那么您可以使用vim-qfreplace並使其變得非常簡單。 觀看演示其工作原理的視頻 設置好工作流程后,您可以進行一些映射以對其進行優化(而不是像視頻中那樣輸入大多數內容)。

兩個插件的組合: vim-ripgrep ,用於跨文件查找並將結果放在 quickfix 窗口中,以及quickfix-reflector用於在 quickfix 窗口中保存更改並讓它自動保存跨文件的每個更改。

我會考慮使用 emacs 的 spacemacs 版本。 它使用與 Vim 相同的模式和大多數擊鍵,但由於它的 lisp 特性,它具有更多的附加組件。 如果你想用 C++ 編程,你只需添加 C++ 層,大部分 IDE 已經為你設置好了。 對於其他解釋性語言,如 python 或 bash,您不需要離開 spacemacs 來使用它們。 他們甚至有一種方法可以直接在您的文本中運行代碼塊,這對於代碼和數據位於同一文件中的文學編程或可復制編程非常有用。 兩者都作為文本完成。

Spacemacs 在它的初始負載中處理得更重,但是你可以用它做的其他事情值得花幾秒鍾的啟動成本。 一層組織模式值得一試。 這是我用過的最好的大綱、程序員、日間計時器/待辦事項列表。

CoC 插件具有(除其他功能外)重命名變量的能力。

https://github.com/neoclide/coc.nvim

" Symbol renaming.
nmap <leader>rn <Plug>(coc-rename)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM