Vimのテキストオブジェクトの使い方と関連プラグイン

今日チームのVimmerの人が小さい勉強会を開いてくれました。そこで学んだ内容をメモに残しておこうと思います。

テキストオブジェクト

Vimではある程度のテキストのまとまりをかたまりとして扱う機能が標準でついています。
これを「テキストオブジェクト」というそうです。
指定の方法は「i + (文字)」か「a + (文字)」です。例えば、「i"」だとカーソル位置から見て「"」で囲まれた部分を指定でき(「"」を含まない)、「a"」だと「"」も含んだ部分の指定が出来ます。iはinside、aはaroundだとか。
これはvimでよく使うv(範囲選択)やd(削除)と組み合わせることができます。
例えば、「"I use MacVim."」というテキストがあるとき、テキスト上で「vi"」とうつと「I use MacVim.」が選択でき、「va"」とうつと「"I use MacVim."」が選択出来ます。
あまり詳しくは調べていませんが、「]」や「)」で括弧も扱うことができ、「s」や「p」で或る程度のかたまりを扱うことも出来るようです(sentenceとparagraph?)

これだけでも便利ですが、テキストオブジェクトを扱うプラグインをいくつか紹介します。

テキストオブジェクトを増やすプラグイン

https://github.com/kana/vim-textobj-user
https://github.com/kana/vim-textobj-entire
https://github.com/kana/vim-textobj-line

userでテキストオブジェクトの独自定義、entireでバッファ全体、lineで行を扱うことが出来ます。
他にもいくつかあるようです。

surround.vim

https://github.com/tpope/vim-surround

テキストオブジェクトを用いて括弧などの変更や削除が簡単にできるようになります。
例えば「ds"」で"abc"をabcにしたり、「cs])」で[param]を(param)にしたり。

expand-region

https://github.com/terryma/vim-expand-region

Emacsのexpand-regionみたいなやつないかなーと思ってたら見事にありました。
しかもさらに細かい設定が可能。
このプラグインを使うとルールに従って動的に選択範囲を広げたり縮めたりすることができます。

僕は括弧に囲まれた文章がある時に
括弧内を選択 → 括弧も含めて選択
という風にしたかったので、以下のような設定にしました。

" テキストオブジェクト
" 値に1が設定されていればマップを展開する

let g:expand_region_text_objects = {
\   'i"' : 1,
\   'a"' : 1,
\   'i)' : 1,
\   'a)' : 1,
\   'i}' : 1,
\   'a}' : 1,
\   'i]'  :1,
\   'a]'  :1,
\   'i''' :1,
\   'a''' :1,
\   'ip' : 1,
\   'is' : 1,
\   'iw'  :0,
\   'il'  :1,
\   'ie'  :1
\}

今までなんでテキストオブジェクトもこれも知らなかったのだろう・・・。
作業効率が段違いになりました。
Emacsよりも範囲選択が楽になったかもしれない。もしかしたらEmacsからVimに移行するかも・・・

おまけ

Vimでペーストする時に周りの文脈に合わせてペーストする

「]p」でいいそうです。これをpにマップ。

nnoremap p ]p
nnoremap ]p p
Vim + Chrome

VimキーバインドChromeを扱えるChrome拡張機能「Vimium」がいい感じ。
他に「Vrome」や「Vichrome」もあるけど、今のところVimiumが一番いいかな?
Vimiumは「/」で日本語が使えないのが残念だけど、機能豊富。
Vromeは機能満点だけど「/」の検索が遅いのと、ブックマークや検索などのChrome標準機能が使えなくなっちゃうのが難点。
Vichromeはややあとの2つに機能が劣る感じ?