大人の text-object トレーニングDS

あー、これ text-object 使えたら一発なのに・・・
と思いながら、なかなか覚えずに (f とかを使って) 今日まで来てしまいました。
なぜ、text-object は覚えにくいかと考えると、
それは多分記号のようだからだと思います。
意味さえ分かれば覚えることができるはず!
ということで自分用にまとめてみる。


基本的な考え方

  • オブジェクト単位で選択する。
  • 基本的な文法は operator + selector + object となる。
  • selector (と呼んでいいのかは分からないけど) は a(a), i(inner) しかない。

追記 - 基本的な考え方

selectorなどというものは存在しない。Vimが標準で提供しているtext objectsは大まかに「a系」と「i系」に分けられるが、それはたまたまそうなっているだけであって、その枠組みに納まらないものはいくらでも定義できる(例: textobj-datetime / textobj-lastpat)。

基本は「{operator}{motion}」であり、text objectはmotionの変化形に過ぎない。

while ("im the true Vim master"); - vimグループ

ありがたいことに指摘していただきました。
text objectはmotionの変化形に過ぎない。
なるほど。そう考えるのかー。

a と inner の違い

The commands that start with "a" select "a"n object
including white space, the commands starting with "i" select an "inner" object
without white space, or just the white space. Thus the "inner" commands
always select less text than the "a" commands.


a はホワイトスペースを含む。i は ホワイトスペースを含まずに選択するか、
もしくはホワイトスペースのみを選択する。i のほうが a より常に少なく選択する。

aw は a word
as は a sentense

iw は inner word
is は inner sentense

と考えればよさげ。

object(help に載っているもの全て)

w   word
W   WORD
s   sentense
p   paragraph
[]  [] block
()b block         * b はエイリアス
<>  <> block
t   tag block
{}B Block         * B はエイリアス
"'` quoted string

operator

selector + object を visual mode(も operator なのかな?) で、実行するか、
普段使っている operator と組み合わせて使う。

        |c|     c       change
        |d|     d       delete
        |y|     y       yank into register (does not change the text)
        |~|     ~       swap case (only if 'tildeop' is set)
        |g~|    g~      swap case
        |gu|    gu      make lowercase
        |gU|    gU      make uppercase
        |!|     !       filter through an external program
        |=|     =       filter through 'equalprg' or C-indenting if empty
        |gq|    gq      text formatting
        |g?|    g?      ROT13 encoding
        |>|     >       shift right
        |<|     <       shift left
        |zf|    zf      define a fold
        |g@|    g@      call function set with the 'operatorfunc' option

text-object の例

page = agent.get('h*ttp://www.google.com/')

cib (change inner block) と入力すれば insert mode に移って

page = agent.get()

となり、また ci' (change inner quoted string) とすれば、

page = agent.get('')

となる。

text-object のまとめ

なんかすごい分かった気がする。
あとは使っていこう。

発展編 surround.vim

  • 基本的な文法は operator + selector + object か operator + selector + subject + replacement
  • selector に s (surround) を指定して使う

MAPPINGS

Delete surroundings is *ds* .
ds + (target to delete)

  Old text                  Command     New text
  "Hello *world!"           ds"         Hello world!

Change surroundings is *cs* .
cs + subject(検索する文字列) + replacement(置換後の文字列)

  Old text                  Command     New text ~
  "Hello *world!"           cs"'        'Hello world!'
  "Hello *world!"           cs"<q>      <q>Hello world!</q>
  (123+4*56)/2              cs)]        [123+456]/2
  (123+4*56)/2              cs)[        [ 123+456 ]/2
  <div>Yo!*</div>           cst<p>      <p>Yo!</p>

*ys* takes an valid Vim motion or text object as the first object, and wraps
it using the second argument as with |cs|.  (Unfortunately there's no good
mnemonic for "ys".)

  Old text                  Command     New text ~
  Hello w*orld!             ysiw)       Hello (world)!

なるほど。surround.vim の y は yank とは関係ないのか。
ys は 第一引数に text-object を渡して、第二引数 でそれを wrap したいものを渡す感じか。

As a special case, *yss* operates on the current line, ignoring leading
whitespace.

  Old text                  Command     New text ~
      Hello w*orld!         yssB            {Hello world!}

surround.vim のまとめ

surround.vim はやっぱり、surround 脳ですね。
脳味噌の転換が必要な気がします。後半 surround.vim の help を
ただ貼り付けただけの感がありますが、それでもやっぱり少しは分かった気がします。
あとは少しずつ使いながら慣れていきたいです。

参照

http://www.vim.org/scripts/script.php?script_id=1697
http://project-p.jp/halt/wiki/vim/plugin/surround
http://d.hatena.ne.jp/goryugo/20090422/1240364593