← Vim研究所

Vimで括弧・引用符の中身を書き換える(ci" / ci( / ci{ / ci[)

2019-12-01 公開 ・ 更新: 2026-08-20

文字列リテラルの中身や関数の引数を書き換えるとき、範囲をビジュアル選択してから削除するのは手数が多いです。ci系のコマンドを使えば、カーソルがブロックのどこにあっても、囲みの中身だけを一発で書き換えられます。

目次(10項目)
キーこれだけ覚える
ci" / ci( / ci{ / ci[囲みの中身をカーソル位置に関係なく書き換え
di(中身を削除するだけ(インサートモードに入らない)
ca(記号自体も含めて書き換え
2ci(1つ外側のブロックを対象にする

基本の考え方:オペレータ+テキストオブジェクト

ci"は「変更」のオペレータcと、カーソルのある"ブロックの中身を指すテキストオブジェクトi"の組み合わせです。カーソルが"ブロックの中のどこにあっても、その内側全体が対象になります。

BEFORE
foo(a, b)
ci(
AFTER
foo(x)
ci"   " "..."の中身を変更
ci(   " (...)の中身を変更
ci{   " {...}の中身を変更
ci[   " [...]の中身を変更

丸括弧はci)、波括弧はciBのような別名でも同じ範囲を指せます。どの記法を使っても結果は同じなので、押しやすいほうを選べば十分です。

要点:カーソルがブロック内のどこにあっても、ci{記号}で中身全体を対象にできます。位置合わせに気を遣わなくてよいのが最大の利点です。

用途別の例

コマンド使いどころ
ci"文字列リテラルの中身を丸ごと書き換える
ci(関数呼び出しの引数を丸ごと入れ替える
ci{JSON/オブジェクトリテラルの中身を書き換える
ci[配列・リストの要素を書き換える
設定オブジェクトのpath行でci二重引用符を実行し、新しいパスを打ち込んだ直後の画面。引用符は残ったまま中身だけが置き換わっている
Vim 9.1.1752。path: の値の上で ci" を押し、新しいパスを打ったところ。引用符そのものは残る

削除だけしたい場合はdi

di"
di(
di{
di[

cdに変えれば、中身を削除するだけでインサートモードには入りません。書き換えず消すだけでよいときはこちらを使います。

ネストしている場合の挙動

括弧が入れ子になっている場合、ci(はカーソルに最も近い(内側の)括弧を対象にします。外側の括弧全体を対象にしたいときは、カーソルを外側の括弧の位置まで動かしてから実行する必要があります。ネストが深いコードでは、対応する括弧を目で追う%コマンドと組み合わせて、まず外側の位置を確認してから編集すると確実です。

カウントを前置きすると、階層を1段ずつ外側へ広げられます。

2ci(   " 1つ外側の()ブロックの中身を変更

入れ子の深いコードでカーソルを動かさずに範囲を広げたいときは、この数値指定のほうがカーソル移動より速いことが多いです。

a系との違い

i(inner)は記号自体を含まない中身だけが対象ですが、a(around)に変えると記号自体も含めて対象になります。

ca"   " "を含めて丸ごと削除・変更
ca(   " (と)を含めて丸ごと削除・変更

記号ごと消してしまいたいときはa系、中身だけ書き換えたいときはi系、と使い分けます。

使ってみて

Pythonの辞書リテラルを書き換えるとき、以前は中身を目で選択してから削除していましたが、ci{を覚えてからはカーソルがブロック内のどこにあっても一発で書き換えられるようになりました。特にci(は関数の引数を丸ごと差し替えるときに使用頻度が高く、手が勝手に動くレベルまで身についています。

カッコの中にいなくても効く場合がある

クォートのテキストオブジェクトには、カッコとは違う癖があります。ci" はカーソルがクォートの外にあっても、その行の右側にあるクォートを見つけて中身を対象にします。行頭から ci" と打っても、その行で最初に見つかった引用符の中身が書き換わります。

いっぽうカッコのテキストオブジェクトは、実際に囲まれている必要があります。カッコの外で ci( を押しても何も起きません。同じ「中身」でも探し方が違うので、クォートのほうが少しだけ緩いと覚えておいてください。

もう1つ、クォートのテキストオブジェクトは行の中しか見ません。複数行にまたがった文字列では期待どおりに動かないので、その場合はビジュアルモードで範囲を選ぶことになります。

カッコには別名がある

丸カッコは i( でも i) でも同じで、ib という別名もあります。波カッコは i{ i} iB のどれでも構いません。

ci(  ci)  cib   " すべて同じ
ci{  ci}  ciB   " すべて同じ

開きと閉じのどちらを打っても同じという点が地味に効きます。Shift を押したまま ci) と打っても意図どおりに動くので、キーの押し間違いで失敗しません。

周りの記号ごと変えたいとき

クォートをバッククォートに変える、カッコを波カッコに変える、といった「囲みだけを変える」操作は、素の機能では2か所を触ることになります。ca( で丸ごと消すと中身も消えるので、書き直す量が増えます。

頻度が高いなら vim-surround を入れる価値があります。cs"' でダブルクォートをシングルクォートに、ds( でカッコだけを外す、といった操作が数キーで済みます。中身を保ったまま囲みだけを扱うという発想は素のVimには無いので、必要になった時点で検討してください。HTMLタグの場合はタグの書き換えにまとめています。

まとめ

括弧・引用符の中身を書き換えるならci"/ci(/ci{/ci[。カーソルの位置合わせが不要になる分、ビジュアル選択より速く正確に編集できます。HTMLタグの中身を対象にしたい場合は専用のcitコマンドを使います。対応する括弧まで飛ぶ%や、外側へ広げるカウント指定を併用すると、入れ子の深い場所でも目的の階層を狙えます。同じテキストオブジェクトの考え方そのものはcwとciwの違いで説明しています。カーソルが囲みの外にあっても、後ろに括弧が控えていればci(は効きます。行頭からでも、括弧が次の行にあっても、前方を探しに行って中身を掴みます。効かないのは括弧を通り過ぎたとき、つまり閉じ括弧より後ろにカーソルがある場合です。反応しないと感じたら、行き過ぎていないかを疑うと早く切り分けられます。

ここで扱ったキーは、ブラウザ上で動くVim道場の中身をまとめて狙うでそのまま試せます。インストールもログインも要りません。

関連記事

← Vim研究所 トップへ戻る