🌟

vimで「カーソルを包むカッコの中で色々したい」と思うとき

2021/05/12に公開

tl;dr

  • 今自分がいるカッコの中の要素を、末尾まで削除したい → それvim標準のmotion ]) でやれるよ
  • 今自分がいる関数呼び出しの引数リストの中で、n個の引数を削除したい → vim-swapのオプション使うと便利だよ

今のカッコの中で末尾まで○○したい

背景

たまによくあるのが、関数の呼び出しの中で「ここから後いらねんだよなぁ」となったとき。

    foo(arg1, arg2, arg3, arg4)
//cursor:---^

こういう場合は単に dt) としてしまえば、 , arg2, arg3, arg4 が消せます。

:help t
t{char}      右に向かって [count] 番目に現れる {char} まで移動しま
             す。カーソルは {char} の左側の文字に置かれます
             inclusive。
             {char} は f コマンドと同様に入力できます。

ですが、引数にカッコが含まれてる場合もたまによくあります。

    foo(arg1, arg2, bar(baz(qux())), quux())
//cursor:---^

これをとっさに d5t) ってやれるの、レインマンくらいでしょう。

解決策

そんな時、 ]) を使うと便利です

])    [count] 次のマッチするものがない ')' に移動します。
      |exclusive|。

上の例だと、カーソル位置から見ると、 bar(〜)baz(〜) も(以下同文)マッチするので、
最後に foo( の片割れである ) が引っかかります。
で、 exclusive motionなので、その手前までが対象になりますね。

注意点

じゃあ、今のカッコの中で始点まで…と思って「逆だし [( じゃね?」と思って使うと、
ちょっと失望します。

    foo(bar(), arg2, arg3, arg4)
//cursor:-----------^

この状態で d[( とやると、

    foo arg3, arg4)

こうなります。なぜか始点の ( が消えるんですね。なぜだ。

aside: 引数リストのn個を○○したい

一方で、 末尾だの始点だのじゃなくて、引数n個消したいんだけど という場合もあると思いますが、
その場合は machakann/vim-swap を使うと、

map <Plug>(swap-textobject-i)
map <Plug>(swap-textobject-a)

があるので、omapとxmapでi,a,に割り当てると便利です。

i.e.

omap i, <Plug>(swap-textobject-i)
xmap i, <Plug>(swap-textobject-i)
omap a, <Plug>(swap-textobject-a)
xmap a, <Plug>(swap-textobject-a)

Discussion