その他
    ホーム技術発信DoRubysurround.vim のつかいかた

    surround.vim のつかいかた

    この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

    surround.vim のつかいかたです。Vim ライトユーザにもおすすめしたいので、にほんごで簡単につかいかたを書いてみます。

     導入

    例により、vim.org から ダウンドードしてきます。

    つい最近、バージョン 1.9 がでています。vim.org では Vim のバージョンが 6.0 対象と書かれていますが、ヘルプをみると Vim 7 以降がオススメとあるので、Vim 7以上でも安心です。

    適当に展開して plugin, doc にファイルを置き、:helptags path/to/help(ヘルプの置いてあるパス) などとしてヘルプを引けるようにしておきます。

     テキストオブジェクトおさらい

    surround.vim は vim のテキストオブジェクトに対する操作を拡張するプラグインです。テキストオブジェクトをざっくりおさらいです。

    テキストオブジェクトはとてもおおざっぱに言えば、あるまとまりのテキストをのことです。このまとまりに対し操作を行なうことができます。

    とりあえず見れば、ああ、あれか、と思うようなものなので、とりあえず見てみます。

    # before
    
    moji1    retu
    

    というテキストがある場面で、moji1 のどこかの文字の上にノーマルモードでカーソルがあたっているとします。

    そのときに diw とコマンド入力すると、”moji1″ というひとまとまりのテキストが削除されます(ここでは、単語という単位のひとまとまりのテキスト)。

    # after
    
        retu
    

    また、同じ場面で daw とすると “moji1 ” というひとまとまりのテキスト+次の単語までの空白文字が削除されます(ここでは単語と、それに付随している空白というまとまり)。

    # after
    
    retu
    

    上で出てきた diw, daw のうちの、iw や、aw がテキストオブジェクトにあたります。diw の d は削除コマンド d のことで、テキストオブジェクト iw に対する操作コマンドになります。削除してインサートモードになる c や、ビジュアルモードの v などのコマンドが使えます。

    テキストオブジェクトは iw, aw のほかにも以下のようなものがあります(見た目で、うごきがわかりやすいのをあげてみます。詳しくは :help text-objects)。

    iw (単語)
    aw (単語+次の文字までの空白)
    
    it (タグの内部 <strong>hoge</strong> の hoge)
    at (直近の外側にあるタグ含む文字列 <p><strong>hoge</strong></p> の場合、
        hoge や、strong 上でコマンドを入力すれば、<strong>hoge</strong> が対象になる)
    
    i( (括弧内を以下略。 ib でも可。)
    a( (括弧含め以下略。 ab でも可。 b は多分ブラケットの b です)
    
    :h text-objects (ヘルプを見ましょう)
    

    ということで、テキストオブジェクトはこんな感じのものでした。

     surround.vim について

    surround.vim の基本的な概念

    surround.vim での編集方法はざっくりで二種類の分けかたができます。

    1. 既に囲んでいるものに対する編集
    2. 新たにテキストオブジェクトを囲む編集
    1. 既に囲んでいるものに対する編集

    何かの記号やタグなどの、囲んでいるものに対して行なう編集です。そのまんまです。

    ex:
    'hoge'            (囲んでいるもの: ' )
    "hoge"            (囲んでいるもの: " )
    (hoge)            (囲んでいるもの: ())
    <tag>hoge</tag>   (囲んでいるもの: <tag> )
    

    [hoge]

    {hoge}

    といった文字列に対して利用できます。この「囲んでいるもの」たちを、削除したり、違うものに変えたりする、という操作ができます。

    以下のコマンドの組みあわせで実現できます。

    編集コマンド(d, c) + s(surround の s) + 囲んでるもの(‘ とか ” とか <tag> とか)

    囲んでいるものを削除する場合は以下のようになります。

    d + s + 囲んでるもの
    ds'     (今カーソルのある文字列を囲んでいる ' を消す)
    ds"     (" を)
    ds(     (() を)
    dst     (<tag> を)
    

    囲んでいるものを変える場合は以下のようになります。

    c + s + 囲んでるもの, + 変更したいもの
    cs'"            (今囲んでいる ' を " に変える)
    cs"<tag>        (今囲んでいる " を <tag> に変える)
    cst<tag>        (直近で囲まれてるタグを <tag> に)
    
    2. 新たにテキストオブジェクトを囲む編集

    word に対する iw とかのテキストオブジェクトを、新たに囲む編集です。そのまんまです。

    hoge
    { :foo => 'bar' }
    he said, i am a pen.
    hogehogehogehoge
    yahhooooo konnichiha-
    

    といった文字列を囲むという操作です。

    以下のコマンドの組みあわせで実現できます。

    ys + 範囲 + 囲む文字列

    ※ 以下では ‘*’ で、今カーソルのある位置を示し、||で囲まれた範囲はビジュアルモードで選択されているものとします。

    befor                   →  after                     # コマンド
    
    h*oge                   →  "hoge"                    # ysiw"
    "↑ カーソル位置の単語を " で囲う
    
    { *:foo => 'bar' }      →  ( { :foo => 'bar' } )     # ysa{( or ysaBb
    "↑ カーソル位置の {} で囲まれた文字列を () で囲う
    
    he said, *i am a pen.   →  he said, "i am a pen."    # ys$"
    "↑ カーソル位置がら行末までを " で囲う
    
    hogehoge|hoge|hoge      →  hogehoge"hoge"hoge        # s"
    "↑ 選択範囲を " で囲う
    
    yahho*oooo konnichiha-  →  'yahhooooo konnichiha-'   # yss'
    "↑ 行全体を ' で囲う。行指向操作。
    

    以上が、surround.vim の機能、「既に囲んでいるものに対する編集」と「新たにテキストオブジェクトを囲む編集」です。

    ほか

    インサートモードでも使う

    <C-G>s でインサートモードでも使えます。インサートモードで、以下のようなコマンドで操作します。

    入力:
      <C-G>s<tag>
    結果:
      <tag>*</tag> (* はカーソル位置。タグに囲まれた状態になる。)
    
    入力:
      <C-G>s"
    結果:
      "*"
    
    自動でインデント(yS, S)

    ys を yS に変えると囲うと同時にインデントもしてくれます。<div> などのタグで囲ったとき使うと少し便利かもしれません。

    hello
    

    という文字列のある行に対して、ySS<div> という操作をすると以下のようになります。

    <div>
      hello
    </div>
    
    カスタマイズ

    囲う文字列は自分で追加できます。vimrc とかに書いとくと使えるようになります。

    let g:surround_コマンド = "開始 \r 終了"
    
    let g:surround_45 = "<% \r %>"
    "↑ 45 は - をコマンドに使うという意味。
    
    let g:surround_61 = "<%= \r %>"
    "↑ 61 は = のこと。この数値は、- とか = の上で :ascii すればわかります。
    
    " 以下のように書くこともできます(直感的な書きかた)
    let g:surround_{char2nr("-")} = "<% \r %>
    let g:surround_{char2nr("=")} = "<%= \r %>
    

    こう書いておくと、新たな – とか = の囲うコマンドが使えるようになります。

    befor       →  after               # コマンド
    
    'hoge'      →  <%= hoge %>         # cs'=
    " ↑' で囲まれている文字列を <%=  %> で囲う
    
    @hoge.name  →  <%= @hoge.name %>   # yss=
    "↑ カーソルのある行を <%=  %> で囲う
    

    ちなみに、上記の – とか = は、rails.vim + surround.vim という環境では、erb ファイルの編集時に使えるよう、はじめから定義されています。

    もっとカスタマイズ

    プロンプトでいろいろ尋ねながら入力した文字列を、囲うものの要素としてつかうことができます。

    	let g:surround_{char2nr("d")} = "<div\1id: \r..*\r id=\"&\"\1>\r</div>"
    	" hoge に ysiwd とかすると
    	" id: というのが下のコマンドラインにでてくるので何かいれると
    	" (たとえば main とか)
    	" <div id="main">hoge</div>
    	" というふうになります。
    	
    	let g:surround_{char2nr("a")} = "<a href=\"\r\">\1link_text: \r..*\r&\1</a>"
    	" http://doruby.com という文字列に yssa などとすると、
    	" link_text: などというプロンプトがでてくるので、何かいれると
    	" (たとえば ナイスブログ とか)
    	" <a href="http://doruby.com">ナイスブログ</a>
    	" というふうになります。
    	

    プロンプトで尋ねるのは7つまで使えます。

    もとからある t をツブすとタグを入力するとき残念なことになるので空いてる文字をさがして適当にわりあてましょう。

    大変長くなってきました。長いのでもう終わりです。

    快適 vim ライフをすごしましょう!