Vimでのリファクタリング


98

もちろん、IDEでリファクタリングできるという事実は多くの人にとって貴重です。私がコーディングしているときはほとんどそうしませんが、他の誰かのソースを編集しているときはそうするかもしれません。Vimの複数のファイルにまたがって、このような簡単なタスクをどのように達成しますか

Rubyをリファクタリングするためのこのプラグインを見つけましたが、「任意の」言語はどうですか?


2
リファクタリングは非常に言語固有です。興味のある言語ごとに特定のアドオンを探す必要があります。おそらく、一部のアドオンは見つかりますが、他のアドオンは見つかりません。必要なものがあり、見つからない場合は、野心的であると感じたら、出発点として別の類似言語の既存のアドオンを使用して作成してみてください。
Steve Jorgensen

2
VIMは、単一のファイルの編集を中心に設計されていますプロジェクトではなく、ディレクトリの下のファイルを編集することもできます。IDEでサポートされている多くのリファクタリングは、プロジェクト全体のファイルに影響します(クラスの名前を変更するなど)。(g)VI(m)のようなエディターでこれを「正しく」行うことは、会社または大きなプロジェクトがそれを引き受けなければならなくなると思うまで、難しいと思います。基本的に各言語を解析して、単純な文字列置換を行わないようにし、エラーが発生しやすくなるようにします(ctagsがこれの一部を提供します)。また、対応するプロジェクトタイプ(編集するファイルを知るため)。
Merlyn Morgan-Graham 2012

1
コメントをありがとう、これは物事が難しくなり始め、VIMをIDEに曲げようとするのは、1つのプログラムだけを使用して複数の言語を編集するための洗練されたソリューションのようなものではないと思います。IDEで利用できる「高度な」機能のいくつかのため、私は本当にVIMをあきらめたくありません。
Helmut Granda 2012年

@ MerlynMorgan-Graham-一部の人々は、コードを少数の(大きい、それである可能性がある)ファイルに保持します。この問題を完全に回避します。
ルーク

7
@ldigas:問題を回避できます。ただし、一部の言語(Javaなど)で推奨される方法にはまったく反対です。基本的に、コードはツールのニーズに合わせて曲がりますが、実際にはそれが逆でなければなりません。
Merlyn Morgan-Graham

回答:


76

「VimはIDEではない」というパラダイムに同意します。ただし、IDEがない場合もあります。ここでは、これらの状況で使用するものを示します。

:grep、:vimgrep、:Ag、:Ggrep

定期的な置換に関連するリファクタリング私は通常、プロジェクトツリーで:grepを使用してから、マクロ記録してリファクタリングを実行します-:gと:sは簡単です。通常は、ほとんど手間をかけずに多数のファイルをすばやく変更できます。正直なところ、私は他のどの方法よりもこの方法を使用しています。

ワークフローによっては、組み込みコマンドが遅くなるか不便になる場合があります。gitを使用する場合は、優れたFugitiveプラグインとその:Ggrepコマンドを使用して、gitにチェックインされたファイルのみを検索します。シルバーサーチャーのスピード感も気に入っています。

:argdo、:cdo、および:bufdo

:cdo:argdoは、一連のファイルに対してvimコマンドを実行するのに便利です。

コマンドライン

変更が必要なファイルのリストを特定するのが難しい場合:vimgrepは、コマンドラインのgrep / findコマンドを使用して、リファクタリングが必要なファイルのリストをより厳密にキュレートします。リストをテキストファイルに保存し、:eマクロ記録のマッシュアップを使用して、必要な変更を加えます。

さびしくないほど、マクロ記録スキルを維持する方が、Vimのリファクタリングに役立ちます。レジスタからの保存/復元、レジスタカウンタ変数のインクリメント/デクリメント、マクロ記録のクリーニング/ファイルへの保存など、後で使用できるようになります。


更新

この記事を書いて以来、私が説明する方法のビデオキャストはvimcasts.orgで公開されています(すべてのVimcastを視聴することをお勧めします)。リファクタリングについては、これらを監視します。

Vimgolfも練習するのに最適な方法です。

私がこの回答を書いて以来、Language Server Protocolサーバーが広く普及していることで、Vim(およびその他のエディター)にもリファクタリング機能が提供されました。IMOそれらは、専用のIDEで見られるリファクタリング機能の同等化とはかなり異なります(私はそれらを使用しており、cocとALEを好みます)。詳細については、この質問の他の回答をご覧ください。


12
リファクタリングはパターンマッチング以上の方法であるため、これを安全に自動化するにはIDEが必要です。明らかに、手動で行うことができますが、利用可能なオプションを考慮すると、ほとんどの場合手動で行う方が安全ですが、なぜ他のオプションを検討するのでしょうか?
Cutberto Ocampo

1
@CutbertoOcampo私はある程度あなたに同意します:プロジェクトの無数の側面(例としては、構造、言語、スタッフのスキルとリソース)に応じて、問題に適用できる優れたリファクタリングツールがあるかもしれません。私の答えは、それが真実ではなく、Vimで問題に取り組みたい状況に当てはまります。
dsummersl 2015

2
それは結構です、私は人々が彼らの長い間好まれたツールを使用して物事を行うことをより快適に感じるかもしれないこと、そしておそらくそこにあるどのIDEよりも優れているが、 -boxソリューション実際のIDEは、ほとんどのユーザーにとってパフォーマンスが優れていると思います。私は80〜20%の種類の状況(さらに、IDEに有利なバランスで)について考えています。
Cutberto Ocampo

1
事実上すべての言語にアイデアがあります。vimやregexを使ってリファクタリングしようとすることは、まったく正気に聞こえません。なぜあなたも試しますか?
2017

1
@rollsは、同僚の必要なマシンをnot-your-ideや他のcfgと一緒に使用して周囲に良い印象を残すのに十分なほど強力です(「単なる印象」ではなく、評判と将来の位置付けのため)。
血まみれ

23

言語サーバープロトコル (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>
    
  2. coc.nvim(node.jsが必要)は、マッピングを提案します。

    " Remap for rename current word
    nmap <leader>rn <Plug>(coc-rename)
    
  3. エール

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

    エールはキーバインドを定義していません。これはユーザーが行う必要があります。

  4. vim-lspは次のコマンドを提供します

    :LspRename
    

    エールと同様に、マッピングは提案されていません。ただし、もちろん次のように定義できます。

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

    <leader>rあなたの選択に置き換えられるべきです;ほとんどのプラグインが同意するものは知りません)

  5. vim-lscにはデフォルトのマッピングがあります。

    'Rename': 'gR'
    

LSPを容易にするYouCompleteMeも参照してください。

ネオビム

Neovimは、201911月13日以降、lspの最初の組み込みサポートを備えています。

LSPの一般的な構成については、https://github.com/neovim/nvim-lspを参照してください。

しかし、スマートな名前変更がどのように機能するのか理解できませんでした。誰かがこれを知っている場合は、このセクションを更新してください。

その他のリファクタリング

クラス構造の変更、メソッド/関数へのパラメーターの追加、メソッドの別のクラスへの移動など、より複雑なリファクタリングをサポートするLSPプロトコルの計画があるかどうかはわかりません。リファクタリングのリストについては、https: //refactoring.com/catalog/を参照してください


残念ながら、LSPでのリファクタリングのサポートは、現在のところ、最新のものと比較するとかなり弱いです。github.com/Microsoft/language-server-protocol/issues/61
Mickael

名前を変更するAFAIK coc-renameは現在のバッファでのみ機能します。プロジェクト内でグローバルに(ファイル全体で)エクスポートされた名前の使用が更新されませんでした。
オリゴフレン

15

パイソン

Python言語の場合、次のプラグインはvimに「スマート」な名前変更機能を提供します。

  • jedi-vimgithub<leader>r
  • ropevimgithubCTRL-c r r
  • python-modegithub:h pymode-rope-refactoring

13

Cファミリ

  1. Cファミリの名前変更リファクタリングにプラグインClighterを試してください。これはclangに基づいていますが、制限があり、プラグインは非推奨としてマークされています。

    Clighterによる推奨マッピングは

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

    後継プラグインclighter8は、コミット24927db42の名前変更機能を削除したことに注意してください

  2. あなたがneovimを使用する場合は、プラグインを見てとることができ、クランプ。それは示唆している

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


4

おそらく最もエレガントなソリューションではないかもしれませんが、とても便利だと思いました。ECLIMを使用してVIMとEclipseを接続しています。もちろん、すべてのソースコード編集はVIMで行われますが、リファクタリングするときは、Eclipseの優れた機能を利用できます。

試してみる。


3

プラグインFactorus

Factorusと呼ばれるリファクタリング専用の別のvimプラグインがあり、githubで入手できます。

現在(2017-12)、言語をサポートしています

  • c、
  • java、および
  • python。

3

プラグインYouCompleteMe(YCM)(Githubに2万個のスター)

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

デフォルトではマッピングはありません。


今のところ、これはjavascript、typescript、javaでのみ機能しますか?
SR

2

名前にカーソルを置いてリファクタリングして入力します

gd(またはgDグローバル変数をリファクタリングしている場合)。

その後

cgn 新しい名前 esc

そして

. 次の発生をリファクタリングするために1回以上

または

:%norm . バッファ内のすべてのオカレンスを一度にリファクタリングします。


1

vimで多くのC / C ++コードを記述しています。私が行う最も一般的なリファクタリングは、変数、クラス名などの名前を変更することです。通常、:bufdo :%s/source/dest/gファイル内で検索/置換を行うために使用します。これは、大きなIDEによって提供される名前変更とほぼ同じです。
ただし、私の場合、通常は同じエンティティの名前を変更し、さまざまなケース(CamelCase、snake_caseなど)で綴ったため、この種の「スマートケース」検索を支援する小さなユーティリティを作成することにしました/置き換え、それはここでホストされています。これはコマンドラインユーティリティであり、vimのプラグインではありません。役立つことを願っています。


0

リファクタリングについては、Uniteを使用している場合(そして使用する必要がある場合)、vim-qfreplaceを使用して非常に簡単にすることができます。それがどのように機能するかを示すこのビデオをチェックしてください。ワークフローが設定されたら、マッピングを作成して最適化できます(ビデオのようにほとんどのものを入力する代わりに)。


0

2つのプラグインの組み合わせ:vim-ripgrepは、ファイル全体を検索して結果をQuickFixウィンドウに表示し、QuickFix- ReflectorはQuickFixウィンドウに変更を保存し、ファイル全体の各変更を自動的に保存します。


0

emacsのspacemacsバージョンの使用を検討します。Vimと同じモードとほとんどのキーストロークを使用しますが、Lispの性質のため、アドオンはさらに多くあります。C ++でプログラミングする場合は、c ++レイヤーを追加するだけで、ほとんどのIDEがすでに設定されています。pythonやbashなどの他のインタープリター型言語の場合、それらを使用するためにspacemacsを離れる必要はありません。テキスト内でコードのブロックを直接実行する方法さえあります。これは、読み書き可能なプログラミングや、コードとデータが同じファイルにある再現可能なプログラミングに最適です。どちらもテキストとして行われます。

Spacemacsは、初期ロードの方がはるかに重いですが、それを使用して実行できる追加機能には、数秒の起動コストの価値があります。1つのレイヤーの組織モードは、チェックする価値があります。それは私が今まで使った中で最高のアウトライナー、プログラマー、デイタイマー/ ToDoリストです。


0

行く

  1. ツールgodoctorgithub)は、いくつかのリファクタリング機能をサポートしています
  • 名前を変更
  • 関数の抽出
  • ローカル変数を抽出
  • 変数を切り替え⇔:=
  • Godocスタブを追加する

それらを利用可能にするvimプラグインhttps://github.com/godoctor/godoctor.vimがあります

名前を変更するものにカーソルがある場合:

:Rename <newname>

抽出するブロックを強調表示:

:Refactor extract newfunc
  1. vim-go

    • を使用した識別子の正確なタイプセーフな名前変更:GoRename
  2. 言語サーバー gopls

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.