vim の text-object をより便利に使えるプラグイン - surround.vim
http://www.vim.org/scripts/script.php?script_id=1697
vim7 から追加された text-object は大変便利で、今や手放せなくなっています。その text-object をより便利に使えるプラグイン、surround.vim が便利すぎるので紹介します。
いままで、text-object では (以下では、コードの『*』の位置に現在カーソルがあると考えてください。)
foo 'b*ar' baz
の位置にカーソルがあるとき、i' でシングルクオーテーションの中身を選択できたり、a' でシングルクオート含む部分を選択できました。しかし『'』そのものを削除したり、置換したりはできなく、ちょっと不便でした。しかし、surround.vim では
- ds
- cs
- ys
- vs
それぞれにコマンドを割り当てて、様々なことができるようになってます。たとえば
foo 'b*ar' baz
で『'』を削除したければ、ds' でできます。『'』を『"』に置換したければ、cs'" で、『'』を() に置換したければ cs') でできます。ruby 使ってると文字列リテラルを『'』を『"』に変える必要が結構出てくるんですが、この機能のおかげで簡単にできるようになりました。
ys を使うと、様々な位置から『'』や『()』などで囲むことができます。
a = Array.new *foo, bar
上記カーソル位置の時に、ys$) ( 『$)』で行末まで() で囲えと命令)すると、
a = Array.new *(foo, bar)
となって、後からでも『()』や『'』ですぐ囲うことができてかなり便利です。yss を使った場合、行全体がターゲットになるため、
foo b*ar baz
で yss' を押すと
'foo bar baz'
と行が『'』で囲われます。
また Visual Mode 時の選択範囲の外側を囲うことができるため、
my $foo = $self->method;
$foo->bar;
を選択して S{ で(大文字の S だとインデントも有効)
{
my $foo = $self->method;
$foo->bar;
}
となります。
XML タグの追加、削除
text-object には t でタグの選択機能がありますが、やはりこれもタグの内側のみ選択、などの機能でした。
しかし、surround.vim を使うと現在囲っているタグの削除ができます。
<div><p class="comment"><strong>f*oo</strong> bar</p></div>
の時に、dst を押すと
<div><p class="comment">*foo bar</p></div>
となります。ここでもう一度 dst を押すと
<div>*foo bar</div>
となります。もちろん外側のタグの置換もできて、ここで cst
と押すと
<p>*foo bar</p>
となります。またタグの追加簡単で、v で foo を範囲選択して、st で
<p>*<strong>foo</strong> bar</p>
になりますし、ys を利用して、ysst
<div class="foo"><p><strong>foo</strong> bar</p></div>
と割と自在にタグで囲むことができるようになります。
insert-mode で使う
insert-mode でも
<html>
<head>
*
</head>
</html>
ときちんと閉じタグが自動で入力され、されてさくさく書き始めることができます。
rhtml や php のタグの入力
surround.vim を拡張することで、簡単に rhtml でよく使うタグや php タグの入力ができるようになります。rails.vim を入れると勝手に rhtml 編集時に拡張してくれて、たとえば
link_to '/', *'top'
な時に yss= で
<%= link_to '/', 'top' %>
になったり、insert-mode で Se で
<% * -%>
<% end -%>
と非常によく使うひな形をすぐ入力できたりして便利です。php のタグの場合、~/.vimrc に
autocmd FileType php let b:surround_45 = "<?php \r ?>"
とか書いておくと、php の編集時に、たとえば
foo echo $bar baz
の echo $bar を範囲選択して s- で
foo <?php echo $bar;?> baz
とすることができます。
surround.vim を拡張する (gettext篇)
それでは、自分がよく使う入力を、surround.vim に登録してみましょう。上の rhtml や php の入力も拡張して行ってます。
surround.vim を拡張するには、グローバル変数 g:surround_アスキーコード にテンプレートを書き込めばOKです。vim でアスキーコードを調べるには、調べたい文字の上にカーソルをあわせて :ascii と押すと調べられます。
最近 gettext を使う機会が増えてきて、 'foo' を _('foo') に、 "foo" を _("foo") に変更したいことがよくあるので、早速そのような動作をするように拡張してみましょう。
~/.vimrc に
let g:surround_103 = "_('\r')" " 103 = g
let g:surround_71 = "_(\"\r\")" " 71 = G
これだけで完了です。これで、
foo 'b*ar' baz
が cs'g で
foo *_('bar') baz
などと簡単に gettext な syntax に置き換えることができます。それでもどばーと gettext に置換したいときは面倒なので利用してない g", g' *1 を nmap で定義しちゃいます。
nmap g' cs'g
nmap g" cs"G
これで、g' や g" で簡単に文字列リテラルを gettext な形式に置き換えることが可能になりました。
終わりに
surround.vim は久しぶりに Life Changing な plugin だったので、気に入ったら plugin の rate this script で Life Changing を押すと良いと思いました。
*1:g' はデフォルトで利用されているが使っていない