Vim歴三か月にもなったので、そろそろ私的オススメマッピング集を紹介する

# Vim歴三か月にもなったので、私的オススメマッピング集を紹介する

（もう三か月だなんて、月日の流れは速い...）  
基本的にはプラグインに依存しないマッピングを紹介します  
おおよそ役に立ちそう＆一般的じゃなさそう順  

## `<Space>w`を`<C-w>`に
`:h ctrl-w`  
`<C-w>`プリフィックスのコマンドはたくさんありますが、個人的にはhjklでウィンドウフォーカスを移す、cで`:close`などをよく使います  

稀にそれらのみを単体で`nnoremap <Space>wh <C-w>h`などのようにマッピングされていることを見たような記憶がありますが、特に理由がないなら他のコマンドにも使えるように`<Space>w`ごとマッピングしてしまっていいと思います  
```vim
nnoremap <Space>w <C-w>
```
いずれにしろ、ヘルプを見たりすると必然的に使うことになるであろうキーなので設定しておいて損はないはずです。小指にやさしく。  

## `yp`を`yyp`に
yypは個人的によくする動作なのでypにマッピングしています（オペレータの後なので、通常はpしても何も起こらない）  
ここでは順当にnnoremapとしていますが、私の場合は統一感的な問題で obcat/vim-highlightedput を使いたいのでnmapにしています（どうでもいい）  
```vim
nnoremap yp yyp
```

## `<Space>y`, `<Space>p`でシステムのクリップボードにyank/put
`"*p`や`"*y`としたりするのは面倒なので、`<Space>`からのy/pでシステムのクリップボードを扱えると便利でしょう  
Linuxの`"*`と`"+`どっちがええんじゃいとかのあれはよく理解していないので、適宜よしなにやってください  
```vim
noremap <Space>y "*y
noremap <Space>p "*p
```

## バッファ移動のマッピング(`<Space>h`, `<Space>l`)を作成する
私の認識が正しければ、`:bn[ext]`や`:bp[reviews]`相当のマッピングコマンドは存在しないはずです（`[]`内は省略可能）  
なので、適当に`<Space>h`と`<Space>l`あたりに割り振っておくとよいでしょう  

バッファを閉じるのは`:bd[elete]`ですが、個人的にはこれはマッピングなしで苦労していません（あまり頻繁に使うわけでもないですし、`!`をつける必要がある場面もあるので）  
```vim
nnoremap <Space>l <Cmd>bnext<CR>
nnoremap <Space>h <Cmd>bprevious<CR>
```
それと、蛇足ですがバッファを使うなら`set hidden`しておくとよいでしょう（ヘルプを見るに、基本的には安易な`!`つきコマンド、要は安易な`:q!`とかに用心しろよって感じのオプションなのだと思う）  
（ちなみにタブページに関しては使ったことがない...）  

## `s`プリフィックスのタグジャンプ関連のマッピングを作成する
タグジャンプ（ヘルプ見るときによく使うやつ）関連のコマンドは`<C-]>`や`<C-t>`などのマッピングが既定ではありますが、少なくとも押しやすくはなく統一感がなくて覚えづらいように感じます  

`:tag`に関しては実質存在しないと言えますし（`<C-]>`では置き換えられない）、`<C-t>`は単純に覚えづらく押しづらいため、一般的にはマッピングすべきと言えるでしょう  

また、`s`は他の操作で比較的容易に代替可能な割に、単体のコマンドでしかなくぶんどっている位置も良すぎます  
確かに使えないというわけではないのですが押しやすさが段違いすぎますので、どこかに退避するか代わりに`cl`を使うなどし、もろもろの操作のプリフィックスにしてしまったほうが得策でしょう（私はバッファやスクリーン関連の操作を主に割り振っています）  
```vim
noremap s <Nop>
" tags jumping (tags-and-searches)
nnoremap s<Space> <C-]>
nnoremap sl <Cmd>tag<CR>
nnoremap sh <Cmd>pop<CR>
```

## `sj`, `sk`で画面を一行ずつ上下スクロールする(`<C-e>`, `<C-y>`)
元の`<C-e>`, `<C-y>`自体もそこまで押しづらいというわけではないのですが、なんとなく小指にやさしくなさそうな印象を受けます。連打する（ctrlキーを長押しする）となると特に（実際に使ったことはほとんどないので何とも言えないけど...）  

とはいえ、修飾キー以外でやるとなると今度はプリフィックスキーごと連打しなければならなくなるという問題が発生しますが、これは[この記事](https://zenn.dev/mattn/articles/83c2d4c7645faa)を参考にすれば解決できます  
```vim
" Screen Up/Down
nmap sj <C-e><SID>s
nmap sk <C-y><SID>s
nnoremap <script> <SID>sj <C-e><SID>s
nnoremap <script> <SID>sk <C-y><SID>s
```
とはいえ意図も何も知らない人がいきなり見てわかりやすいマップとは言えないと思いますので、こういったものを多用つつも可読性も確保したいという場合には kana/vim-submode を導入するのも手かもしれません  

## `<Space>k`, `<Space>j`で画面と現在行を一行ずつ上下スクロールする(`<C-e>`+`j`, `<C-y>`+`k`)
上に書いたものとやっていることはほぼほぼ同じです  
ただプリフィックスを`s`から`<Space>`に変更し、画面スクロールと同時にカーソル行もスクロールするようにしただけです（こればかりはマップを見て見比べたほうが早いでしょう）  
```vim
nmap <Space>j <C-e>j<SID><Space>
nmap <Space>k <C-y>k<SID><Space>
nnoremap <script> <SID><Space>j <C-e>j<SID><Space>
nnoremap <script> <SID><Space>k <C-y>k<SID><Space>
```

## `<Space><CR>`で空行を下に挿入する`
誰しも、ただただ空行を挿入したいという場面が少なからずあったりすると思います  
それ自体は`o<Esc>`などをどこかしらにマッピングしてしまえばいい話ではありますが、一部の人や場面においては現在行のインデント状況、コメントかどうか否かなどに左右されずただ空行を挿入したいと思うかもしれません  
そんな時にはこのようにするといいらしいです。[この記事](https://vim-jp.org/vim-users-jp/2009/08/15/Hack-57.html)を参照ください  
```vim
nnoremap <Space><CR> <Cmd>call append(expand('.'), '')<CR>
```
私はHelixエディタインスパイア（後述）のマッピングを結構入れているのですが、それに倣って現在行の前に挿入する設定らも入れておきましょう  
```vim
nnoremap ]<Space> <Cmd>call append(expand('.'), '')<CR>
nnoremap [<Space> <Cmd>call append((line('.') - 1), '')<CR>
```
ちなみに、インスパイア元のインスパイア元と思われる tpope/vim-unimpaired では、このロジックは`<Cmd>put! =nr2char(10)<CR>`的な感じで実装されていたような憶えがあります  

あと、今更ですが`<Cmd>`は[Vim 8.2.1978](https://github.com/vim/vim/releases/tag/v8.2.1978)（2020年11月12日）で追加された機能のようです（[参考](https://github.com/vim-jp/reading-vimrc/wiki/vimrc%E3%82%A2%E3%83%B3%E3%83%81%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3#%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%AE%E3%83%9E%E3%83%83%E3%83%94%E3%83%B3%E3%82%B0)）  
以前試したところ`:<C-u>`と`<silent>`を使った状態と一致するっぽかった気がする。ヘルプを見る限り、内部的には結構根本的に違ったりするのだろうか（モード遷移をしないから結果的にそうなるし、`<Cmd>`を使った状態的にはそもそもそれが自然みたいな感じか...?）  

## `gh`, `gl`で行頭行末に移動する
行頭・行末への移動はわりと個人差が出る部分だと思います  
`<C-h>`, `<C-l>`であったり、`<Space>h`, `<Space>l`であったり、`H`, `L`であったりと  

私は`gh`, `gl`を使います  
以外にも、`gh`は「文字選択モード」などという個人的によくわからない機能筆頭（かつマッピングとしても覚えづらい）に割り当てられているため容易に潰すことができ、`gl`に関してはそもそもマッピングが存在しません。これは利用せざるを得ないでしょう  
```vim
noremap gh ^
noremap gl $
```
確かにマッピングすることにより格段と押しやすくはなるのですが、いくら押しやすいからといって`I`や`A`を使わないともなると却って効率が悪くなってしまうため、濫用には気を付けましょう  

## `U`をリドゥ(`<C-r>`)に
一般的だと思います。が、便利です（標準の`<C-r>`も案外悪くはないんですけどね）  
ちなみに、もともとの`U`の機能に関しては未だによく理解していません（が、それで不便を感じるわけでもなく...）  
```vim
nnoremap U <C-r>
```
付随する話として、`R`（置換モード）を不要になった`<C-r>`に割り振ってしまい、`R`は kana/vim-operator-replace などのReplace系オペレータに割り振ってしまうと使い勝手が良いです  
（`R`に関しては`gR`もありますし、個人的に言えばむしろそちらのほうをメインで使うのでおおよそ問題にならないと考えます）  

## まとめ
```vim
nnoremap <Space>w <C-w>

nnoremap yp yyp

noremap <Space>y "*y
noremap <Space>p "*p

nnoremap <Space>l <Cmd>bnext<CR>
nnoremap <Space>h <Cmd>bprevious<CR>

noremap s <Nop>
" tags jumping (tags-and-searches)
nnoremap s<Space> <C-]>
nnoremap sl <Cmd>tag<CR>
nnoremap sh <Cmd>pop<CR>

" Screen Up/Down
nmap sj <C-e><SID>s
nmap sk <C-y><SID>s
nnoremap <script> <SID>sj <C-e><SID>s
nnoremap <script> <SID>sk <C-y><SID>s

nmap <Space>j <C-e>j<SID><Space>
nmap <Space>k <C-y>k<SID><Space>
nnoremap <script> <SID><Space>j <C-e>j<SID><Space>
nnoremap <script> <SID><Space>k <C-y>k<SID><Space>

nnoremap <Space><CR> <Cmd>call append(expand('.'), '')<CR>
nnoremap ]<Space> <Cmd>call append(expand('.'), '')<CR>
nnoremap [<Space> <Cmd>call append((line('.') - 1), '')<CR>

noremap gh ^
noremap gl $
```
プラグインなしでもそれなりにこだわりようがあるということがわかって頂けたかと思います（もちろん今回紹介したものだってマッピングというものの中の一部に過ぎません）  
そしてその先にもプラグインの森があります。わくわくですね  

ちなみになんですが、`<Space>y/p`と`<Space>w`と`<Space><CR>`と`gh/gl`と`U`は、HelixというVim-likeなエディタからインスパイアされたマッピングです（もともとあったVimのいい感じの設定を既定として取り入れた、みたいな感じのものなんだと思う）  

## おまけのコーナー
`` `<C-w>` `` とか`` `<Space>` ``とか入力するのがしんどかったのでちょいとマクロに頼ることにしました  
`` `<>` ``で囲いたいところを選択して`@k`とかします（sandwich.vimが必要）  
もちろん、用途を`<C-...>`に限ってしまって`vll`とマクロの最初に入れてしまい、`<Space>`は他の手段（abbrevや他のマクロ）で対処としてしまってもいいと思います（やっつけだったのでこうはなったけど、実際これでも面倒ではあったのでそのようにしたほうがよかったかもしれない）  

こういうのを手軽にできるのもVimの強みであり、ちゃんとやろうと思えばきっちりとしたスクリプトを書いてやっていけるのもVimの強みなんじゃないかなぁと思います（素人並の感想）  
```vim
let @k = "sa<saab`l~"
" こっちのがわかりやすくはあるか
let @k = "sa<vabsa`l~"
```