【Vim/Neovimキーマップ】map/noremapやLeaderキー

VimやNeovimを使っていくにあたって、
どのようなキーマップを設定するかは、
その人の個性であり、答えのない探求です。

それぐらい、キーマップの設定は、
Vimを使いこなす上で必須の設定と言えます。

しかし、そうした探求をするためにも、
そもそもどのようにしてキーマップを設定するのか知る必要があるでしょう。

本記事では、.vimrcやinit.vimのキーマップの設定方法は、
もちろん、map系やのnoremap系など基本的なマッピングの種類についても解説します。

また、キーマップを設定する上で、Leaderキーというものを設定することも
多いので、そちらについても併せて解説します。

それ以外にも、ユーザ定義コマンドなど、短縮入力に役立つ設定方法も解説します。

記事ではなく、動画で視聴したいという人は、
下記が本記事の該当動画です。

また、Vimの基本的な操作がまだ良くわからないという人や、
これからVimに入門するという人は、
下記の動画でVimについて完全解説しているので、
よろしければご覧ください。

VimやNeovimのマッピングの種類

VimやNeovimには、
マッピングコマンドが複数存在しています。

そして、意外と複雑です。
軽く表にまとめてみますと、下記のようになります。

map系noremap系モード
mapnoremapノーマルモード、ビジュアルモード
nmapnnoremapノーマルモード
vmapvnoremapビジュアルモード
imapinoremapインサートモード
cmapcnoremapコマンドラインモード
tmaptnoremapターミナルモード

上記の表の説明としては、
mapとか、noremapというのがコマンドであり、
それぞれ、表に対応するモードにおいて、
設定したマッピングが有効になるという感じです。

例えば、

map tt i

と設定すると、
ノーマルモードか、ビジュアルモードのどちらかで、
ttと入力すると、iが入力されたことになるという感じです。

この文法自体は、他のマッピングコマンドでも同様で、
左に入力するもの、右に実行するものという風にします。

※ちなみに、上記の表はやや簡易版で、他のモードとして選択、オペレータ待機などが
ありますが、使用頻度は高くない気がしたので、省略しています。気になる人は、
こちらのサイトが詳しいので参考にしてください。
map - Vim日本語ドキュメント (vim-jp.org)

map系とnoremap系の違い

さて、説明ではmapで説明しましたが、
例えばmapコマンドには、対応するものとして、
noremapがありました。

これらの違いは、再帰的なマッピングかどうかということです。

はい、これじゃ意味分かんないですよね。
具体例をあげると、

map o i
map ss o " ssを入力するとiが入力されたことになり、挿入モードに

noremap o i
noremap ss o " ssを入力するとoが入力されたことになり、新しい行を追加し挿入モードに

つまり、map系の場合、
実行コマンドのマッピングも再帰的にたどっていくのに対し、
noremap系は辿らず、設定されたコマンド文字通りの意味で解釈されるということですね。

おそらく、noremap系の方が挙動としては直感的だと思うので、
基本的には、noremap系を使えばいいかなと思います。

私の感覚では、このmapとnoremapの特徴の違いをクリティカルに利用して、
キーマップの設定をする機会は、あまりない気がするので、
ややこしければ、片方だけ使うとかでも良いと思います。

マッピングの設定例

試しにマッピングの設定例について、
紹介したいと思います。

inoremap { {}<LEFT> 
inoremap [ []<LEFT>
inoremap ( ()<LEFT>
inoremap " ""<LEFT>
inoremap ' ''<LEFT>
inoremap jj <ESC>
nnoremap <ESC><ESC> :nohlsearch<CR>
noremap ss ^
noremap ;; $
nnoremap <C-t> :NERDTreeToggle<CR>

<LEFT>は、矢印キーで、
<Up>,<Down>,<Right>などもあります。

上記の場合、{ などと入力したあと、{}の左矢印なので、
{}の中に入るという感じだ。

つまり、{ と入力したら、
自動的に閉じカッコも補完するようにするマッピングという感じですね。

<C-t>は、Control + tで、
<CR>はenterです。

<C-でControlを表すので、
たとえば、<C-s>とかは、
Control + sになります。

このあたりは、NerdTreeの解説のときにも説明したので、
こちらの記事も参考にしていただけると。

[st-card myclass="st-no-shadow" id="93" label="参考" pc_height="" name="" bgcolor="#cccccc" color="#ffffff" webicon="st-svg-file-text-o" readmore="on" thumbnail="on" type="text"]

現時点では、まだ10行ほどですが、
プラグインを導入した際などは、
いやでもキーマップを設定したくなると思うので、
キーマップの設定は徐々に増えていくでしょう。

自分だけのカスタムキーマップを定義してみてください。

Leaderキーとユーザー定義コマンド

上記で、基本的なキーマップについて、
紹介しましたが、今度は上記以外で、
キー入力を楽にする手伝いをしてくれるものを
2つ紹介します。

Leaderキー

Leaderキーとは、自分で好きなキーを設定して、
マッピング定義などの際に使用できる、
いわばカスタムキーのようなものです。

例えば、

map <leader>p i

という風にして、
設定の自由度を上げることができます。

デフォルトでは、Leaderキーはバックスラッシュ( \ )ですが、
めちゃくちゃ押しづらいので、基本変更するでしょう。

変更の仕方としては、

let mapleader = "\<space>"

のようにします。

この場合、spaceキーがleaderキーに割り当てられます。

これで、上記のマッピングでは、
spaceキーとpで挿入モードに入ることになります。

Leader キーにどのキーが設定されているか調べたいときは、

:echo mapleader

でも確認できます。

デフォルトのままで、何も設定していない場合は、
undefined variable mapleaderのようなエラーが出るかと思います。

上記のように、spaceキーにLeaderキーを設定した場合は、
echo 空白のような感じになるので、実際にはなにも表示されないような感じになるかと思います。

spaceキーに設定した場合、空白文字がechoされて、
ちゃんと設定できているか、わかりにくいので、
適当にleaderキーのマッピングを設定して試した方が手っ取り早い気もします。

ユーザ定義コマンド

キーマップに関連したものとして、
leaderキー以外にも、
ユーザー定義コマンドというものがあります。

皆さんは、コマンドラインモードで、
いつでも自分の好きな言葉を呼び出せたらいいと思ったことはないでしょうか?
ちなみに、私が好きな言葉は、人生字を識るは憂患の始まりという、言葉です。

Vimで作業しているとき、
ふとこの文字が見たくなったとき、
コマンドラインモードでいちいち

:echo '人生字を識るは憂患の始まり'

などと打つのは、あまりにもかったるいですよね。

もちろん、上記で設定したキーマップを設定して、
例えば、Leaderキーで、

nmap <Leader>a :echo '人生字を識るは憂患の始まり'<CR>

のように設定するのもありでしょう。

ただ、このようにして、
好きな言葉を無数にキーマップしていたら、
名前が衝突したり、デフォルトのキーバインドと重複したりと、
メンテナンスが大変になります。

その場合、キーマップにするよりも、
コマンドラインモードで直接呼び出せた方が便利だったりします。

そこで、コマンドのショットカット的なものを設定したいとき、
Vimだとどうするのか、

command!を使えば解決です。

command! Solitary :echo '人生字を識るは憂患の始まり'

これで、コマンドラインモードでSolitaryと打てば、
いつでも我が座右の銘を召喚できます。

あとは、もっと実用的なコマンドとしては、.vimrcをいちいち再読み込みするのが
面倒なので、そちらもコマンドにしてしまうのもいいでしょう。

command! SS :so ~/.vimrc

:soは:sourceの略であり、.vimrcを再読み込みする。
ちなみに、すでに.vimrcを開いているときは、
:so %でも同様。

キーマップの設定のサンプルコード(.vimrc)

最後に前回までの記事とと本記事の設定を反映した、
.vimrcを紹介します。

前回の記事は下記で、
setのオプションについての記事です。

[st-card myclass="st-no-shadow" id="104" label="参考" pc_height="" name="" bgcolor="#cccccc" color="#ffffff" webicon="st-svg-file-text-o" readmore="on" thumbnail="on" type="text"]

下記の部分で、setの詳しい意味について、
知りたい方は、上記の前回の記事をご参考ください。

let mapleader = "\<space>"
set number
set showmode
set shiftwidth=2
set cursorline
set cursorcolumn
set incsearch
set hlsearch
map <leader>p i
inoremap { {}<LEFT>
inoremap [ []<LEFT>
inoremap ( ()<LEFT>
inoremap " ""<LEFT>
inoremap ' ''<LEFT>
inoremap jj <ESC>
nnoremap <ESC><ESC> :nohlsearch<CR>
noremap ss ^
noremap ;; $
nnoremap <C-t> :NERDTreeToggle<CR>
command! Solitary :echo '人生字を識るは憂患の始まり'
command! SS :so ~/.vimrc
call plug#begin()
  Plug 'https://github.com/preservim/nerdtree'
call plug#end()