VSCode でも使える『実践Vim』で紹介された便利な操作・コマンドまとめ


# VSCode でも使える『実践Vim』で紹介された便利コマンドリスト

# 概要

名著と名高い『[実践Vim](https://tatsu-zine.com/books/practical-vim)』で紹介されていたコマンドのうち、VSCode に Vim キーバインドを導入している状態の操作でも使用できるものを簡単にまとめました。
本書で説明ごと見返しやすようにTIP番号ごとに記載しています。また、一部の表だけで分かりづらいものには補足を加えています。

※書籍ではファイルを操作する演習も行いながら解説しているので、本リストは一度書籍を読んだ後に見直し程度に読むのがオススメです

# TIP2 : DRY (Don't Repeat Yourself)

## 複合コマンド一覧

|複合コマンド|同じことをする長いコマンド|
|:--|:--|
|C|c$|
|I|^i|
|A|$a|
|o|A\<CR>|
|O|ko|

# TIP4 : 実行して、繰り返して、元に戻す

## 繰り返しが可能な操作と対になる操作

|やりたいこと|操作|繰り返し|対となる操作|
|:--|:--|:--|:--|
|変更する|{edit}|.|u|
|行内で文字を前方検索|f{char}/t{char}|;|,|
|行内で文字を後方検索|F{char}/T{char}|;|,|
|ドキュメント内で前方検索|/pattern\<CR>|n|N|
|ドキュメント内で後方検索|?pattern\<CR>|n|N|
|置換の実行|:s/target/replacement|&|u|
|一連の変更を実行[^1]|qx{changes}q|@x|u|

[^1]: マクロによるもの

# TIP12 : 統合して統治せよ

## Vim のオペレータコマンド

|トリガー|動作|
|:--|:--|
|c|変更|
|d|削除|
|y|レジスタにヤンク|
|~|大文字小文字の入れ替え|
|gu|小文字化|
|gU|大文字化|
|>|インデントを深くする|
|<|インデントを浅くする|
|=|自動インデント|

# TIP14: ノーマルモードへの復帰

## ノーマルモードに戻る

|キーストローク|結果|
|:--|:--|
|\<Esc>|ノーマルモードに切り替え|
|\<C-[>|ノーマルモードに切り替え|
|\<C-o>|挿入ノーマルモード[^2]に切り替え|

[^2]: 挿入モードで1度だけノーマルモードのコマンドを打てる状態のこと

# TIP21 : ビジュアルな選択範囲の定義

## ビジュアルモードの有効化

|コマンド|結果|
|:--|:--|
|v|文字指向のビジュアルモードを有効にする|
|V|行指向のビジュアルモードを有効にする|
|\<C-v>|ブロック指向のビジュアルモードを有効にする|
|gv|直前のビジュアルな選択範囲を再度選択する|

## ビジュアルモード間の切り替え

|コマンド|結果|
|:--|:--|
|\<Esc>または\<C-[>|ノーマルモードに切り替え|
|v,V,\<C-v>|文字指向のビジュアルモード/行指向のビジュアルモード/ブロック指向のビジュアルモードからノーマルモードに切り替え|
|v|文字指向のビジュアルモードに切り替え|
|V|行指向のビジュアルモードに切り替え|
|\<C-v>|ブロック指向のビジュアルモードに切り替え|
|o|強調表示されているテキストのもう一方の端点に移動|

# TIP39 : ワークスペースを分割ウィンドウにする

## 分割ウィンドウの作成

|コマンド|動作|
|:--|:--|
|\<C-w>s|現在のウィンドウを水平分割し、現在のバッファの内容を新しいウィンドウでも利用する|
|\<C-w>v|現在のウィンドウを垂直分割し、現在のバッファの内容を新しいウィンドウでも利用する|
|:sp[lit] {file}|現在のウィンドウを水平分割し、{file}を新しいウィンドウに読み込む|
|:vsp[lit] {file}|現在のウィンドウを垂直分割し、{file}を新しいウィンドウに読み込む|

## ウィンドウ間のフォーカスを変更する[^3]

|コマンド|動作|
|:--|:--|
|\<C-w>w|オープンされているウィンドウでフォーカスを順次切り替えていく|
|\<C-w>h|左のウィンドウにフォーカス|
|\<C-w>j|下のウィンドウにフォーカス|
|\<C-w>k|上のウィンドウにフォーカス|
|\<C-w>l|右のウィンドウにフォーカス|

[^3]: VSCodeでは移動先にサイドバーも含まれる

## ウィンドウを閉じる

|コマンド|動作|
|:--|:--|
|\<C-w>c|アクティブなウィンドウを閉じる|
|\<C-w>o|アクティブなウィンドウだけを残し、他のウィンドウをすべて閉じる|

## ウィンドウのサイズ変更と位置変更

|コマンド|動作|
|:--|:--|
|\<C-w>=|すべてのウィンドウの幅と高さを同じにする|

# TIP40 : タブページを使ってウィンドウのレイアウトを管理

## タブのオープンとクローズ

|コマンド|動作|
|:--|:--|
|tabe[dit] {filename}|{filename}を新しいタブでオープンする[^4]|
|tabc[lose]|現在のタブページを閉じる|
|tabo[nly]|アクティブなタブページを残し、それ以外のタブページをすべて閉じる|

[^4]: 開いているフォルダの最上位階層が参照される。現在の階層から開く場合は「:e[dit]」コマンドを使用

## タブの切り替え

|Ex コマンド|ノーマルコマンド|動作|
|:--|:--|:--|
|tabn[ext] {N}|{N}gt|番号{N}のタブページに切り替え|
|tabn[ext]|gt|次のタブページに切り替え|
|tabp[revious]|gT|前のタブページに切り替え|

# TIP47 : 論理行と表示行を区別しよう[^5]

## 論理行・表示行それぞれでの移動

|コマンド|カーソル移動|
|:--|:--|
|j|論理行で1行下に移動|
|gj|表示行で1行下に移動|
|k|論理行で1行上に移動|
|gk|表示行で1行上に移動|
|0|論理行の先頭の文字に移動|
|g0|表示行の先頭の文字に移動|
|^|論理行で空白以外の先頭の文字に移動|
|g^|表示行で空白以外の先頭の文字に移動|
|$|論理行の末尾に移動|
|g$|表示行の末尾に移動|

[^5]: バッファ内で改行コードで区切られる1行のことを「論理行」、ウィンドウ幅を超過し折り返されて表示される行のことを「表示行」としている

# TIP48 : 単語単位での移動

## word単位での移動[^6]

|コマンド|カーソル移動|
|:--|:--|
|w|次の単語の先頭に前進(word単位)|
|b|現在の単語もしくは前の単語の先頭に後退(word単位)|
|e|現在の単語もしくは次の単語の末尾に前進(word単位)|
|ge|前の単語の末尾に後退(word単位)|

[^6]: wordは英文字、数字、アンダースコアが連続したもの、もしくはその他の非空白文字が連続したもので、ホワイトスペース文字によって区切られる

## WORD単位での移動[^7]

|コマンド|カーソル移動|
|:--|:--|
|W|次の単語の先頭に前進(WORD単位)|
|B|現在の単語もしくは前の単語の先頭に後退(WORD単位)|
|E|現在の単語もしくは次の単語の末尾に前進(WORD単位)|
|gE|前の単語の末尾に後退(WORD単位)|

[^7]: WORDは非空白文字が連続したもので、ホワイトスペースで区切られる

## 末尾移動とセットで使えると便利な操作

|操作|結果|
|:--|:--|
|ea|現在の単語の末尾に追加|
|gea|前の単語の末尾に追加|

# TIP49 : 文字を検索

## 文字検索コマンド

|コマンド|動作|
|:--|:--|
|f{char}|次にある{char}までカーソルを末尾方向に移動|
|F{char}|前にある{char}までカーソルを先頭方向に移動|
|t{char}|次にある{char}の直前の文字までカーソルを末尾方向に移動|
|T{char}|前にある{char}の直前の文字までカーソルを先頭方向に移動|
|;|直前の文字検索コマンドを繰り返す|
|,|直前の文字検索コマンドを逆方向に繰り返す|

# TIP51 : 高精度なテキストオブジェクトを使って選択範囲をトレース

## デミリタ区切りのテキストオブジェクト

|テキストオブジェクト|選択範囲|
|:--|:--|
|a)もしくはab|カッコで囲まれた範囲（カッコを含む）|
|i)もしくはib|カッコの内側の範囲（カッコを含まない）|
|a}もしくはaB|波カッコで囲まれた範囲（波カッコを含む）|
|i)もしくはiB|波カッコの内側の範囲（波カッコを含まない）|
|a]|角カッコで囲まれた範囲（角カッコを含む）|
|i]|角カッコの内側の範囲（角カッコを含まない）|
|a>|山カッコで囲まれた範囲（山カッコを含む）|
|i>|山カッコの内側の範囲（山カッコを含まない）|
|a'|シングルクォートで囲まれた範囲（シングルクォートを含む）|
|i'|シングルクォートの内側の範囲（シングルクォートを含まない）|
|a"|ダブルクォートで囲まれた範囲（ダブルクォートを含む）|
|i"|ダブルクォートの内側の範囲（ダブルクォートを含まない）|
|a`|バッククォートで囲まれた範囲（バッククォートを含む）|
|i`|バッククォートの内側の範囲（バッククォートを含まない）|
|at|タグで囲まれた範囲（タグを含む）|
|it|タグの内側の範囲（タグを含まない）|

# TIP52 : デミリタを含めて削除したり、デミリタの内側を変更したり

## 境界で分けられるテキストオブジェクト

|キーストローク|選択範囲|
|:--|:--|
|iw|現在の単語（word）|
|aw|現在の単語（word）＋前後どちらかの空白|
|iW|現在の単語（WORD）|
|aW|現在の単語（WORD）＋前後どちらかの空白|
|is|現在の文|
|as|現在の文＋前後どちらかの空白|
|ip|現在の段落|
|ap|現在の段落＋前後どちらかの空行|

# TIP53 : 場所をマークして、そこにサッと戻る

## 自動マーク

|キーストローク|バッファの内容|
|:--|:--|
|``|現在のファイルで直前に行われたジャンプ以前にいた場所|
|`.|直前に変更された場所|
|`[|直前に変更もしくはヤンクが行われた先頭|
|`]|直前に変更もしくはヤンクが行われた末尾|

# TIP55 : ジャンプリストの移動

## ジャンプリスト

|コマンド|動作|
|:--|:--|
|[count]G|指定した行番号の行にジャンプ|
|/pattern\<CR>、?pattern\<CR>、n、N|次もしくは前にある pattern にジャンプ|
|%|マッチするカッコにジャンプ|
|(、)|前の文（(）もしくは次の文（)）の先頭にジャンプ|
|{、}|前の段落（{）もしくは次の段落（}）の先頭にジャンプ|
|H、M、L|画面の先頭/真ん中/末尾にジャンプ|
|gf|カーソル位置に記述されているファイル名にジャンプ|
|\<C-]>|カーソル位置に記述されているキーワードの定義位置にジャンプ|
|'{mark}、`{mark}|マーク[^8]にジャンプ|

[^8]: マークは「m{a-zA-Z}」コマンドを入力することで、現在の位置に指定された文字で設定される

# TIP79 : 検索コマンドを使ってみよう

## 検索を繰り返すときのやり方

|コマンド|動作|
|:--|:--|
|n|次のマッチにジャンプ。検索の方向とオフセットは以前のまま|
|N|前のマッチにジャンプ。検索の方向とオフセットは以前のまま|
|/\<CR>|同じパターンの次のマッチに前方ジャンプ|
|?\<CR>|同じパターンの前のマッチに後方ジャンプ|

# TIP89 : 置換のたびに確認する

## 置換コマンド実行時にcフラグをつけた場合の動作リスト

|トリガ|動作|
|:--|:--|
|y|このマッチを置換|
|n|このマッチをスキップ|
|q|置換を終了|
|l|「last」: このマッチを置換して終了|
|a|「all」: このマッチとこれ以降のすべてのマッチを置換|