今更ながらvimチートシート

# 私家版 Vim標準キーバインド表
基本的なキーバインドは指が覚えているが、たまに使いたいうろ覚えのvimキーバインドについての覚書です。
モーションや繰り返し回数Nの説明は省き、対となる機能はまとめて１つにしました。
完全な解説はこちらです→ http://vim-jp.org/vimdoc-ja/vimindex.html
わからないキーバインドは <kbd>:h キーバインド</kbd> で調べましょう。

## ファイル選択、表示分割、タブ分割、バッファ、文字エンコードコード変換

| insert    | normal   | 機能 |
|:----------|:---------|:-----|
| ***       | :h              | ヘルプファイルを開く
| ***       | :e {file}       | ファイルを開く ※{file}を手打ちするかわりに CTRL-RF と入力するとカーソル位置のファイル名を貼り付け
| ***       | :e ++enc=utf-8  | UTF-8でファイルを開き直す
| ***       | :e ++enc=sjis   | Shift_JISでファイルを開き直す
| ***       | gf/gF           | カーソル位置の文字列をファイル名/ファイル名+行番号として開く
| ***       | :r {file}       | ファイルを読み込む
| ***       | :r! {command}   | コマンド出力を読み込む
| ***       | :w {file}       | ファイルを上書きする
| ***       | :sp {file}      | 画面を上下分割して別のファイルを開く (vim -o files..)
| ***       | CTRL-WJ/WK      | 分割画面の上/下へ切り替える
| ***       | :vsp {file}     | 画面を左右分割して別のファイルを開く (vim -O files..)
| ***       | CTRL-WH/WL      | 分割画面の左/右へ切り替える
| ***       | CTRL-WW/WP      | 分割画面の次/前へ切り替える
| ***       | CTRL-WO         | 他の分割画面を閉じる
| ***       | :tabe {file}    | タブを追加して別のファイルを開く (vim -p files..)
| ***       | gt/gT           | 次/前のタブへ切り替える
| ***       | :ls             | バッファ(開いているファイル)の一覧を見る
| ***       | :b{N}/:bn/:bp   | N番目/次/前のバッファへ切り替える
| ***       | :sb{N}          | 画面を上下分割してN番目のバッファへ切り替える
| ***       | ZZ / :x         | 変更を保存して現在のファイルを閉じる
| ***       | ZQ / :q!        | 変更を捨てて現在のファイルを閉じる
| ***       | :qa!            | 変更を捨てて全てのファイルを閉じる

## マウス操作

下記コマンドにより、マウス操作が可能とする

- マウスクリック：カーソル位置、ウィンドウ選択、タブ選択
- マウスドラッグ：範囲選択、ウィンドウサイズ変更、タブ移動
- マウススクロール：ウィンドウ内スクロール

```vim:~/.vimrc
"=== mouse
set mouse=a
set ttymouse=sgr
```

## 入力、削除、ヤンク

| insert    | normal   | 機能 |
|:----------|:---------|:-----|
| ***       | i/I      | 現在位置直前/現在行頭にてinsertモードに入る.
| ***       | a/A      | 現在位置直後/現在行末にてinsertモードに入る
| ***       | o/O      | 現在行直後/現在行直前に新規行を設けてinsertモードに入る
| ***       | r        | 現在位置N文字を1入力文字で上書きする
| ***       | R        | 現在位置にて上書きinsertモードに入る
| ***       | s/cw/cb<br>/ciw/caw<br>/ci'/cib/ciB<br>/C/cc | 現在位置にて<br>N文字/単語末尾まで/単語先頭まで<br>/単語全体/単語全体と前後空白<br>/引用符内/()括弧内/{}括弧内<br>/行末まで/行全体<br>を削除してinsertモードに入る
| ESC       | ***      | insertモードを抜けて、入力内容をN回分挿入する.
| CTRL-C    | ***      | insertモードを抜ける
| CTRL-O    | ***      | normalモードで1コマンド実行する
| CTRL-E/Y  | ***      | 1行下/上の文字を現在行に入力する
| CTRL-U    | ***      | 現在行の入力文字を削除する
| CTRL-W    | db       | 現在位置から単語先頭までを削除する
| Delete    | x        | 現在位置のN文字を削除する
| ***       | D        | 現在位置から行末まで削除する
| ***       | J        | 現在行からN行を連結する
| ***       | dd       | 現在行からN行を削除する
| ***       | dw/de    | 現在位置からN単語/単語末までを削除する
| ***       | yy       | 現在行からN行をヤンクする
| ***       | yw/ye    | 現在位置からN単語/単語末までをヤンクする
| ***       | P/p      | 現在位置の直前/直後へ貼り付ける
| ***       | : CTRL-R CTRL-F/P/W/L | 現在位置のファイル名/パス名/単語/行をコマンドラインへ貼り付ける
| ***       | : CTRL-R % | 現在のファイル名をコマンドラインへ貼り付ける
| ***       | : CTRL-R / | 現在の検索パターンをコマンドラインへ貼り付ける
| ***       | : CTRL-R - | 現在の削除単語をコマンドラインへ貼り付ける
| ***       | : CTRL-R " | 現在のyankをコマンドラインへ貼り付ける

## インデント、補完入力、Undo

| insert    | normal   | 機能 |
|:----------|:---------|:-----|
| CTRL-D/T  | << / >>    | インデントを減らす/増やす
| 0 CTRL-D  | ***      | インデントを無くす
| ***       | ==       | 自動インデントする
| CTRL-N/P  | ***      | カーソル前方/後方にある単語で補完入力する
| CTRL-XO   | ***      | オムニ補完入力する
| CTRL-XL   | ***      | 行全体を補完入力する
| ***       | u/CTRL-R | Undo/Redo
| ***       | U        | 現在行を編集開始時点の内容に戻す
| ***       | ~        | カーソル位置の大文字小文字を切り替える
| ***       | guw/gUw  | 単語を小文字化する/大文字化する
| ***       | CTRL-A/X | カーソル上の数値文字列を加算/減算する
| ***       | .        | 直前の変更操作を繰り返す

## クリップボード操作

| insert       | visual      | 機能 |
|:-------------|:------------|:-----|
| SHIFT-Insert |             | 現在位置へクリップボードから貼り付ける
|              | CTRL-Insert | 現在選択テキストをクリップボードへコピーする
|              | CTRL-Delete | 現在選択テキストをクリップボードへカットする

ただし、コピーとカットは、vim が +clipboard でビルドされている必要あり。
-clipboard なら +clipboard のvimパッケージを入れれば良い(※未確認)
```sudo apt install vim-gnome```

```vim:~/.vimrc
" ヤンクをクリップボードと同期する.
set clipboard=unnamedplus
```

## カーソル移動、マーク、ジャンプ

| insert      | normal | 機能 |
|:------------|:-------|:-----|
| ←/→         | h/l    | 1文字左/右へ移動する
| SHIFT-←/→   | b/w    | 1単語左/右へ移動する
|             | e      | 単語末尾文字へ移動する
| ***         | F{c}/f{c} | 左/右の 文字 {c} へ移動する  
| ***         | T{c}/t{c} | 左/右の 文字 {c} の直前へ移動する  
| ***         | ;         | 直前のf/t/F/T移動操作を同方向へ繰り返す
| ***         | ,         | 直前のf/t/F/T移動操作を逆方向へ繰り返す
| Home/End    | 0/$    | 行頭/行末へ移動する  
| ↑/↓         | k/j    | 1行上/下へ移動する
| SHIFT-↑/↓   |        | 1ページ進む/戻る
| PageDown/Up | CTRL-F/B | 1ページ進む/戻る
| ***         | CTRL-D/U | 半ページ進む/戻る
| CTRL-XE/XY  | CTRL-E/Y | N行上/下方向スクロール
| ***         | gg/G     | ファイルN行目/ファイル末尾行にカーソルを移動する
| ***         | (/)/{/}  | 文頭/文末/節頭/節末にカーソルを移動する
| ***         | M/H/L    | 画面中央/先頭/末尾にカーソルを移動する
| ***         | zz/zt/zb | 現在行を画面中央/先頭/末尾にして再表示する
| ***         | gd/gD    | カーソル位置の単語の定義を関数内/ファイル内で探してカーソルを移動する
| ***         | CTRL-]/T | カーソル位置の単語をタグジャンプする/タグリストに沿って戻る
| ***         | g;/g,    | 変更リストに沿って進む/戻る
| ***         | m{a-zA-Z} | カーソル位置をマークする
| ***         | `{a-zA-Z} | マーク位置へジャンブする ※ ` のかわりに ' にするとマーク位置行頭へジャンプ
| ***         | ``       | 直前のマーク位置へジャンブする
| ***         | [\` / ]\`  | カーソル位置より後方(先頭)/前方(末尾)のマーク位置へジャンブする
| ***         | :marks   | マーク位置を一覧表示する
| ***         | CTRL-I/O | マーク&ジャンプリストに沿って進む/戻る
| ***         | %        | カーソル右にある括弧の対位置へ移動する
| ***         | CTRL-g   | ファイル内の現在位置をステータス表示する

## 検索置換

| insert      | normal | 機能 |
|:------------|:-------|:-----|
| ***         | :{range}s/{pat}/{to}/{flag} | 文字列置き換え. range=%でファイル全体
| ***         | &      | 再度置き換え
| ***         | ?{pat} | 後方(先頭)へ検索する
| ***         | /{pat} | 前方(末尾)へ検索する
| ***         | */#    | カーソル位置の単語を前方/後方検索する
| ***         | n/N    | 同方向へ再検索する/逆方向へ再検索する
| ***         | [I     | カーソル位置の単語を含む行を一覧表示する(簡易grep)

下記コマンドで検索機能をお好みで調整する

```vim:~/.vimrc
" 小文字の検索でも大文字も見つかるようにする
set ignorecase
" ただし大文字も含めた検索の場合はその通りに検索する
set smartcase
" インクリメンタルサーチを行う
set incsearch
" 検索結果をハイライト表示
set hlsearch
```

## grep

| insert    | normal   | 機能 |
|:----------|:---------|:-----|
| ***       | :vim PAT {file} <br/>:copen | ファイルに対して内部grep実行して結果を一覧表示する
| ***       | :grep PAT {file} <br/>:copen | ファイルに対して外部grep実行して結果を一覧表示する

https://qiita.com/kaitat/items/14eb32b0793ff13eeea8

## vimdiffモード

| insert      | normal | 機能 |
|:------------|:-------|:-----|
| ***         | [c     | 後方(先頭)の変更箇所へ
| ***         | ]c     | 前方(末尾)の変更箇所へ
| ***         | do     | 相手のウィンドウの差分を取り込む(obtain)
| ***         | dp     | 相手のウィンドウへ差分を押し込む(push)

## terminalモード(VIM8以降)

:terminal にて端末ウィンドウが開いて、端末ジョブモードが始まる

| 端末ジョブ | 端末ノーマル | 機能 |
|:----------|:------------|:-----|
| CTRL-\N   | ****        | 端末ノーマルモードへ移行する
| ***       | i/a         | 端末ジョブモードへ移行する

## タブインデントの扱い

| 名前 略称 | 初期値 | 機能 |
|:----------|:------------|:-----|
| tabstop ts       | 8    | ハードタブ幅
| softtabstop sts  | 0    | TABキー入力に対するスペース幅
| shiftwidth sw    | 8    | <<,>>によるインデントスペース幅
| expandtab et / noexpandtab  noet | noet  | ハードタブ文字を複数スペース文字に展開する / 複数スペース文字を可能な限りハードタブ文字に置き換える。
| smarttab sta / nosmarttab nosta  | nosta | TABキー入力でshiftwidthのインデントをする / しない

`:retab[!] [N]` コマンドにて、tabstopをNに変更し、et/noet設定に従いファイル全体に対するハードタブ文字とスペース文字の展開・置き換えが可能。ただし文法構造は考慮されないので、コメント内や文字列定数内であっても一律に変換されてしまうので注意！

### 設定例

ファイルの先頭行付近に下記を書いておくと、vimが設定を読み込んで処理してくれます。

```vim:インデントに幅4のハードタブを使う
# vim: set shiftwidth=4 tabstop=4 noexpandtab nosmarttab:
```

```vim:インデント幅は4、幅8以上はハードタブに変換する
# vim: set shiftwidth=4 tapstop=8 noexpandtab smarttab:
```

```vim:インデント幅は2、ハードタブ変換しない
# vim: set shiftwidth=2 expandtab smarttab:
```

## (おまけ) vimのカスタムコマンドで、ブラウザでこのページを開く

カスタムコマンド ":Q" を追加して、このページを開く外部コマンドを実行させるようにしてみた。
macについてはmac使いではないので未実装です。誰か編集リクエストで教えてください。

```vim:~/.vimrc
"=== OS dependant
if     has("mac")
elseif has("win64")
  command! Q call system('start https://qiita.com/hkuno/items/4557f3f8d6b27d2884f2')
elseif has("win32")	" win32/win64
  command! Q call system('start https://qiita.com/hkuno/items/4557f3f8d6b27d2884f2')
elseif has("win32unix")	" msys/cygwin
  command! Q call system('start https://qiita.com/hkuno/items/4557f3f8d6b27d2884f2')
elseif has("unix")	" msys/WSL/Linux
  command! Q call system('xdg-open https://qiita.com/hkuno/items/4557f3f8d6b27d2884f2')
endif
```

## (おまけ) bash行編集の標準キーバインド

vim と直接関係はないが、シェルの行編集キーバインドについても、ついでにまとめておく.

```bash
# 行編集モード設定.
set -o emacs
set -o vi
# キーバインド表示.
bind -p
```

| emacsモード | viモード | 機能 |
|:------------|:--------|:-----|
| CTRL-B/F    | h/l     | 1文字左/右へ移動する.
| ESC B/F     | b/w     | 1単語左/右へ移動する.
| CTRL-A/E    | 0/$     | 行頭/行末へ移動する.
| BS/DEL      | BS/DEL  | 左/右の1文字を削除する.
| CTRL-D      | x       | 1文字削除する.
| CTRL-V      | CTRL-V  | 次のキー入力値を制御ではなく入力値とする.
| CTRL-T      | | 左右の文字を入れ替えて右に進む.
| ESC U/L     | | 右の単語を大/小文字化する.
| ESC C       | | 右の単語先頭を大文字化する.
| ESC BS/D    | db/dw   | 左/右の1単語をヤンクして削除する.
| CTRL-U/K    | d0/D    | 行頭/行末までヤンクして削除する.
| CTRL-Y      | p       | ヤンクを貼り付ける.
| ESC .       | | 直前コマンドの最後の単語を貼り付ける.
| CTRL-P/N    | k/j    | コマンド履歴の後方(先頭)/前方(末尾)へ移動する.
| ESC </>     |        | コマンド履歴の先頭/末尾へ移動する.
| CTRL-R      | /      | コマンド履歴サーチ.
| TAB, CTRL-I | \      | 補完.
| CTRL-G      | | 中止.
| Enter       | | 決定.

# END