Vimのsとcの違い sは実質cl
ヘルプを読んでもsとcの違いがいまいちピンときませんでした。実際に動かしてみると、この2つの関係は驚くほどシンプルだと分かります。
目次(7項目)
| キー | これだけ覚える |
|---|---|
| s | 1文字削除して挿入モードへ(clと同じ) |
| S | 行全体を削除して挿入モードへ(ccと同じ) |
| ビジュアルモードでs | 選択範囲を削除して挿入モードへ(cと同義) |
結論:s は c と l を合わせたもの
s " カーソル位置の1文字を削除して挿入モードへ
cl " 同上(cオペレータ + lモーション)
cat
at
sは「1文字削除して、そのままインサートモードに入る」というコマンドで、これはcl(変更のオペレータcとカーソル右1文字のモーションlの組み合わせ)とまったく同じ動作になります。sはclの便利な省略形と考えると分かりやすいです。
cは「次の操作を待つ」オペレータ
c単体では何も起きません。cの後にモーション(wや$など)やテキストオブジェクト(iwなど)を続けて初めて、対象範囲が確定して変更が実行されます。一方sは対象範囲が「カーソル位置の1文字」に固定されているため、モーションを待たずにいきなり削除・挿入が始まります。この「範囲を待つかどうか」が2つの本質的な違いです。
行全体を対象にする版もある
S " 行全体を削除して挿入モードへ
cc " 同上(ccと同じ)
S(大文字)は行単位版で、ccと同じ動作になります。s/Sはどちらも「範囲固定のショートカット」という位置づけで理解すると覚えやすくなります。
置換コマンドとの役割の違い
s/cはあくまでカーソル位置を起点にした直接編集で、対象は自分でモーションやテキストオブジェクトを使って指定します。パターンにマッチする文字列をファイル全体から探して置き換えたいなら、:substituteコマンドのほうが向いています。カーソル操作で狭い範囲を素早く直したいか、パターンでファイル全体を機械的に置き換えたいかで住み分けると考えると分かりやすいです。
使い分けの実際
対象範囲が広い変更はcとモーション・テキストオブジェクトの組み合わせでまかなえるため、多くのVimmerは範囲を柔軟に指定できるc系を多用する傾向があります。一方で1文字だけをサッと変えたい場面では、モーションを打つ手間すらいらないsのほうが速いです。VimGolfのようにキー数を競う場面では、この1手の差が意味を持つこともあります。
最初はsとcを別物として個別に覚えようとして混乱していましたが、s=clという対応に気づいてからは一気に整理できました。仕組みを丸暗記するより、既知のコマンドの組み合わせとして理解したほうが記憶に残りやすいと実感した出来事でした。
ビジュアルモードのsも同じ発想
v{範囲選択}s
ビジュアルモードでsを押すと、選択範囲を削除してインサートモードに入ります。これはcと同じ動作で、ビジュアルモードにおいてはsとcが完全に同義になります。ノーマルモードでのs=clという対応と混同しないよう、モードによって意味が変わる点は覚えておくと安心です。
まとめ
s/Sはc系オペレータの特殊なショートカットにすぎません。仕組みを理解してしまえば、新しいコマンドとして覚え直す必要はなくなります。同じ「置き換える」でも行内をまとめて直したいときは行内の置換4パターンに選択肢が並んでいます。