vimで単語の置換を一発でやる関数を作ってみる
vimを使い始めて2ヶ月ちょっとか。感覚的には半年くらい使ってる気がするな。 もはや日々の仕事に欠かせないツールになっている。 プラグインの方もも欲しいと思ってたものをいくつか入れて、IDE相当なリッチな環境になってきた。
プラグインも各々使いこなしがまだまだで、慣れればもっと効率が飛躍しそう。 (なんかプラグインもそれぞれ作者の世界観があって面白い)
今使っているのは、
- Gtags
- CtrlP
- vim-bookmark
この3つでソースコード編集&読解がだいぶ楽になった。 もちろん、:makeとQuickFixは言うまでもない。
CtrlPはまだよく分かってなくて、慣れてきたら整理したいところだ。
さて、単語の置換の話
たとえばCでコードを書いてて良くあるのは、一回マジックナンバーを入れて書いたところに、 マクロ名に置換したいときだ。
たとえば、
char buf[256]; int i; for(i = 0; i< 256; i++) { ... }
とかの、256をBUF_SIZEとかに置換する。どうするか?
たかだか一関数内の数カ所の置換なので、:%s/256/BUF_SIZE/gc
とかは、ちと大げさかな。と。
vimのコマンドでやろうとすると、ひとつめの256にカーソルを合わせておいて、
ciw
てやってBUF_SIZEを入れて[ESC]
、2つ目の256で.
か。
でも、とりあえずどっかのヘッダファイルに、
#define BUF_SIZE 256
と書いた後には、このBUF_SIZEをyiw
して、256と置換したいよな。
この時は、256にカーソルをあてて、まずは256を消さなきゃいけない。
普通にdiw
とかで消すと、直前ヤンクした内容が消えてしまう。
ので、
とすればよいと。まあ、続けて書けば"_diwhp
ですね。
上記の例は問題ないが、置換したい単語が行の先頭にある場合だと、 一文字後ろにずれてしまう。
置換前: 256 置換後 BUF_SIZE
この場合は、"_diwP
と大文字のP
でペーストする必要がある。
(左には移動できないのでh
は意味をなさない)
p
の場合はカーソルの後ろにペーストするので、どうして空白が一個できるからだ。
また、行末の単語の場合は削除した場合も、勝手にいっこ左移動になるので、h
はいらない。
さて、場合よって使い分けるというのもあるが、"_diwhp
の入力が面倒。
比較的頻繁に行う操作なので、自分でキーマップを作ってしまいたい。
と思って作ったのが以下のvimscript。
function! ReplaceWord() execute ":normal \"_diw" if col('.') == 1 execute ":normal P" elseif col('.') == col('$')-1 && getline('.')[col('.')-1] == ' ' execute ":normal p" else execute ":normal hp" endif endfunction :command! ReplaceWord call ReplaceWord() nmap <C-y> :ReplaceWord<CR>
これを.vimrcに放り込んだ後にvimを実行すれば、 任意の単語の上にカーソルを当てた状態でCtrl-yを押すと、 直前にコピーした文字列に置換される。行頭、行末の場合もOK。