web-dev-qa-db-ja.com

Vimで変数名を変更する

多くの単一文字の変数名を含む多くのC/PerlコードをVimで読み取ろうとしています。

コードを読んでいる間に変数の名前をもっと意味のあるものに変更できるコマンドがあれば、残りの部分をより速く読むことができて嬉しいです。

Vimには、これをすぐに実行できるコマンドがありますか?

正規表現が機能するとは思わない:

  1. 同じ1文字の名前は、異なるスコープブロックで異なる目的を持つ場合があります

  2. 同じ文字の組み合わせが別のより大きな変数名の一部であるか、文字列またはコメント内にある可能性があります...それらを変更したくないでしょう

既知の解決策はありますか?

87
Aditya Mukherji

以下は、現在のスコープで定義されている変数の名前を変更する方法です{}

カーソルを変数usageに移動します。 Gdを押します。つまり、カーソルを定義に移動します。 [{-これにより、スコープの開始点が表示されます。 Vを押します-ビジュアルラインの選択を有効にします。押す %-反対のジャンプ}したがって、スコープ全体が選択されます。押す :s/-代替コマンドの開始。 <C-R>/-変数名(Gdを押す前の名前)に一致するパターンを挿入します。 /newname/gc<CR>-検索を開始し、一致するたびに確認に置き換えます。

今、あなたはマクロを記録するか、さらに良い-キーをマップする必要があります。

最終的なマッピングは次のとおりです。

" For local replace
nnoremap gr Gd[{V%::s/<C-R>///gc<left><left><left>

" For global replace
nnoremap gR Gd:%s/<C-R>///gc<left><left><left>

これを.vimrcまたは単に実行します。この後、ローカル変数でgrを押すと、:sコマンドは、単にnew_variable_nameを押して Enter

182
Mykola Golubyev

知る限り、VIMには実際のリファクタリングのサポートはありません。リファクタリングの目的で名前を変更するときは、通常、次の予防措置を講じます。

  1. マークを使用して、変更の範囲を制限します。
  2. 正規表現を入力するときは、名前を\ <と>で囲みます。これにより、Word全体に一致するようになり、発生する不正な名前変更の種類が減ります。
  3. 不良な置換の可能性を減らすために複数行の置換を行わないでください
  4. 小さな変更以外の場合は、コードの差分を注意深く調べてください。

私の最終的な変更は次のようになります

:'a,'bs/\<foo\>/bar

VIMのリファクタリングツールがないことについて間違っているのが大好きですが、私はそれを見ていません。

9
JaredPar

これを.vimrcに入れてください

_" Function to rename the variable under the cursor
function! Rnvar()
  let Word_to_replace = expand("<cword>")
  let replacement = input("new name: ")
  execute '%s/\(\W\)' . Word_to_replace . '\(\W\)/\1' . replacement . '\2/gc'
endfunction
_

:call Rnvar()で呼び出します

expand("<cword>")は、カーソルの下にあるWordを取得します。検索文字列はファイルスコープに_%_を使用し、\(\W\)パターンは置換するWordの境界で非Word文字を探し、変数_\1_に保存します。 _\2_。置換パターンに再挿入されます。

8
Mike

それは古い質問であり、@ mykola-golubyevの方法は明らかにISOP質問の特定のケースのベストアンサーです(これは、あなたが同じ変数名のブロックが複数ある可能性が高い);しかし、そのような質問名では、Google検索からここに来る多くの人々は、おそらくVIMで変数の名前を変更するより状況に固有の方法を探します-そしてそれらはより簡潔にすることができます

私は誰もこの方法を提案していないことに驚いています:

_*_ _:s//_[〜#〜] newname [〜#〜]_/gc_

_*_はgnと同じです-カーソルの下のWordの次の出現を検索し、最後に検索されたパターンになるため、代替コマンドで検索パターンを省略すると、VIMこれが検索するパターンであると仮定します。

少量のvarコピーの場合、さらに速いコピー:

_*_ cw[〜#〜] newname [〜#〜]_<esc>_その後、_n._を繰り返します発生

オカレンスを検索、cwchange Wordのコマンド、nは最後の検索で次のオカレンスに進み、_._は最後のコマンドを繰り返します( WordをNEWNAMEに変更)

(このすべてがRedditの @ doomedbunniesに行くことを知っている私のためのクレジット

別のクールなトリックはこれです:( credits to @ nobe4

_*_ cgn[〜#〜] newname [〜#〜]_<esc>_その後、_._を繰り返します発生

cgnは「(次の検索結果)の結果を変更する」です。これが最後のコマンドであるため、次のオカレンスに移動するのにnは必要ないので、ストロークが再び少なくなり、さらに重要なことに、nと_._。しかし、明らかに、これには発生をスキップする方法がないという欠点があります。

いくつかの利点があります:

  • マッピングも.vimrc(またはinit.vim)もありません。したがって、遭遇するVIMコピーで使用できます(たとえば、VPSまたは友人のマシンでのクイックタスクVIMあなたのやり方は「クイック」の目的に反するでしょう)
  • wordの選択に_*_またはgnを使用するのは非常に迅速です-たった1回のキーストローク(まあ、1.5としましょう)
  • _*_またはgnを使用すると、_:%s/<C-R>//gc_が行うように、他の単語内で一致が得られないことが保証されます。手動で_:%s/\<OLDNAME\>/NEWNAME/gc_を入力するのをやめる:個人的に_\<_を使用して、単語全体のみに一致を制限するのを忘れがちです。
  • スコープを使用しないと、不要な一致をスキップするためにnのいくつかの余分なストロークが発生します。おそらく、スコープを制限するために必要な余分なストロークよりもさらに少ないでしょう。通常の状況下では、変数はとにかく特定のコードブロックにある程度ローカライズされます。
7
Ivan Bartsov

グローバル検索および置換で「c」修飾子を使用して、置換ごとに確認を求めることができます。それにはもっと時間がかかりますが、非巨大なコードファイルではうまくいくかもしれません:

%s/\$var/\$foo/gc

Cは確認を表します。

2
Adnan

これが複数のファイルにまたがる場合は、sedを検討することを検討してください。 findを使用してファイルとxargsを取得し、sedを置き換えます。 * .cに一致するすべてのファイルでaをa_better_nameに置き換えたいとします。

見つける。 -name "* .c" | xargs sed -i -e 's/a/a_better_name/g'

これにより、aのすべての出現が置き換えられるため、より堅牢な正規表現が必要になる場合があることに注意してください。

0
Drew Olson

Cでは、cscopeを使用してある程度の進歩を遂げることができます。構文を理解しようとするため、文字がいつ変数であるかを知るチャンスがあります。

0
Kim Reece