設定したキーマッピングの一覧を確認する(:map / :verbose map)
あるキーを押したら想定と違う動作をして、どこで設定したマッピングか分からず困ったことがあります。ただ、:mapを打っただけでは探しているマッピングが出てこないこともあります。どのコマンドが何を見せるのか、一覧の記号が何を意味するのか、定義元をどう突き止めるのかを、実際の出力を貼りながら順に見ていきます。
検証環境:macOS 26.4.1 / Vim 9.1.1752(/usr/bin/vim)/ Neovim 0.12.4。出力はすべて実機のものです。既定のマッピングは起動オプションで変わるため、出力ごとに起動条件を添えました。ユーザーの設定を混ぜないよう、HOMEを空の一時ディレクトリに向けて検証しています。
| コマンド | これだけ覚える |
|---|---|
:map / :map! | 前者はノーマル系、後者は挿入・コマンドライン |
:verbose map {キー} | そのキーの定義元ファイルと行番号を出す |
:filter /語/ nmap | キーが特定できないときに絞り込む |
:unmap {キー} | マッピングを削除する |
:mapに出ないマッピングがある
:mapは「全部」を見せるコマンドではありません。:help map-listingのモード一覧を読むと、:mapが受け持つのはノーマル・ビジュアル・選択・オペレータ待機の4モードで、挿入モードとコマンドラインモードは:map!の担当だと分かります。検証用のvimrcを1枚だけ用意して確かめます。
" ~/vrc.vim
nmap \y :echo "nmap"<CR>
nnoremap \x :echo "nnoremap"<CR>
nnoremap <script> \s :echo "script"<CR>
nnoremap <buffer> \z :echo "buffer"<CR>
vmap \v :echo "vmap"<CR>
imap \i xyz
cmap \k foo
これをvim -n -i NONE -u ~/vrc.vimで読ませ、:mapと:map!を続けて実行した結果です。
:map
n \z *@:echo "buffer"<CR>
v \v :echo "vmap"<CR>
n \s & :echo "script"<CR>
n \x * :echo "nnoremap"<CR>
n \y :echo "nmap"<CR>
:map!
c \k foo
i \i xyz
定義した7本のうち:mapに並んだのは5本で、\iと\kは:map!のほうに出ています。「設定したはずなのに一覧に無い」の多くはこれが原因です。さらに:lmapという別枠があり、こちらはどちらにも出ません。なお上の2つからは、こちらが定義していない6本を省いてあります。macOS版のVimには<D-v>のようなクリップボード用のマッピングが組み込まれていて(:help mac-standard-mappings)、-u NONEを付けても消えないためです。モードごとのコマンドは次のとおりで、一覧の1文字目がそのままモードを表します。
| コマンド | 対象モード | 一覧の1文字目 |
|---|---|---|
:map | ノーマル+ビジュアル+選択+オペレータ待機 | 空白 |
:nmap | ノーマルモード | n |
:vmap | ビジュアル+選択モード | v |
:xmap | ビジュアルモードのみ | x |
:smap | 選択モードのみ | s |
:omap | オペレータ待機モード | o |
:map! | 挿入+コマンドライン | ! |
:imap | インサートモード | i |
:cmap | コマンドラインモード | c |
:lmap | 言語マッピング | l |
:tmap | 端末ジョブモード(:terminalの中) | t |
それぞれ:nm・:vmのように省略できます。ビジュアル系だけは3つに分かれていて、vがビジュアルと選択の両方、xがビジュアルだけ、sが選択だけです。上のvimrcはvmapで定義していますが、:xmapと:smapのどちらから引いても同じ1本が出ます。
:xmap \v
v \v :echo "vmap"<CR>
:smap \v
v \v :echo "vmap"<CR>
1文字目がvのままなので、:xmapの結果にvが混ざっていたら「:vmapで定義されたもので選択モードにも効いている」と読めます。スニペットの展開で選択モードを使うプラグインとぶつかるのがこの形なので、視覚的な選択だけに効かせたいときは:xmapで定義し直します。
Leaderは展開後の姿で並ぶ
一覧は<Leader>という表記を保持しません。上の出力で先頭が\になっているのは、mapleaderが未設定のときの既定値がバックスラッシュだからです。<Space>をLeaderにしている環境なら<Space>から始まる形で並びます。<Leader>という文字列では見つからないので、mapleaderの設定と展開のタイミングを押さえたうえで展開後のキーで探してください。
キーがVimまで届いていないとき
一覧には出ているのに押しても反応しない場合は、マッピングではなく端末を疑います。挿入モードでCtrl-vを押してから目的のキーを押すと、端末が実際に送っているバイト列がそのままバッファに入ります。tmux上のxterm-256colorでCtrl-vに続けて↑とF1を押した結果です。
^[OA
^[OP
^[はEscなので、F1がEsc・O・Pの3バイトとして届いていると分かります。ここで何も入力されないなら、そのキーは端末側で握られていてVimまで届いていません。マッピングをいくら直しても解決しないので、先に端末の設定を見ることになります。
一覧の左端と記号を読む
左端の1文字がモード、{rhs}の直前に付く記号がマッピングの性質を表します。先ほどの出力を記号の部分だけ抜き出すと3種類が並んでいて、意味は公式ヘルプ(:help map-listing)が定義しています。
n \z *@:echo "buffer"<CR>
n \s & :echo "script"<CR>
n \x * :echo "nnoremap"<CR>
n \y :echo "nmap"<CR>
* indicates that it is not remappable
& indicates that only script-local mappings are remappable
@ indicates a buffer-local mapping
| 記号 | 意味 | 定義に使ったコマンド |
|---|---|---|
| * | 再マップされない | :nnoremapなどのnoremap系 |
& | スクリプトローカルなマッピングだけが再マップされる | :nnoremap <script> |
@ | バッファローカル | :nnoremap <buffer> |
| 無印 | 再マップされる | :nmapなどのmap系 |
上の出力では\yだけ印が無く、これがnmapで定義されたものだと分かります。自分の設定が:nmapのまま残っていないかは一覧で確かめられます(使い分けの理由は未割り当てキーの選び方で扱っています)。なお:help map-listingではモード一覧の見出し行に~が付いていますが、これはヘルプ文書が見出しを色分けするための印で、一覧に出る記号ではありません。
定義元のファイルを突き止める
:verbose map
:verbose nmap
verboseを先頭に付けると、そのマッピングがどのファイルの何行目で定義されたかまで表示されます。先ほどのvimrcを読ませた状態で引いた結果です。
:verbose nmap \x
n \x * :echo "nnoremap"<CR>
Last set from ~/vrc.vim line 2
プラグインが定義したものなら、そのプラグインのファイルパスがそのまま出ます。vimrcを読ませずにvim -n -i NONEで起動した素の状態でgxを引くと、Vim 9.1に同梱された標準プラグインが答えとして返ってきました。
:verbose nmap gx
n gx <Plug>(open-word-under-cursor)
Last set from /usr/share/vim/vim91/plugin/openPlugin.vim line 38
このgxは-u NONEを付けると消えます。-uにファイルを指定した場合も標準プラグインは読まれないので、上のvimrcを読ませた出力には現れませんでした。既定のマッピングを調べるときに-u NONEで起動すると、本当は入っているものが「無い」と見えてしまいます。逆にLast set fromが出ないマッピングもあり、コマンドラインで直接打った直後のものと、先ほどのmacOS標準の6本がそれです。定義元が出ないときは、その場で打ったかVim本体に組み込まれているかの二択になります。読み込み順そのものは:scriptnamesで読み込み済みスクリプトを見るほうで追えます。
:verboseには:12verboseのように数字を前置きできますが、マッピングの一覧については数字を変えても出力は変わりません。手元で:verboseと:12verboseの結果は完全に同じで、:0verboseにするとLast set fromの行だけが消えました。数字は'verbose'オプションの値で、9以上なら自動コマンド、15以上ならスクリプト内のExコマンドといった別種の情報を出すためのものです。
キーを特定できないときは絞り込む
:verbose map <Esc>
:verbose nmap <Leader>a
全部を一覧表示すると量が多すぎることがあるので、疑わしいキーだけを指定すると効率的です。マッピングを追加する前に「本当に空いているか」を確認する用途にも使えます。キーを1つに特定できないときは:filterで絞り込みます。
:filter /nnoremap/ nmap
n \x * :echo "nnoremap"<CR>
この例で当たっているのは左辺ではなく右辺です。:filterは{lhs}と{rhs}の両方を見るので、キー名が分からなくても「そのマッピングが呼んでいるコマンド名」から逆に引けます。プラグインが提供するコマンド名で引くのが実用的な使い方になります。
Neovimでは一覧の見え方が変わる
同じ:mapでも、Neovimでは出力の量も形も違います。ユーザーの設定を一切置かない状態で数えると、Vim 9.1.1752の:mapが9本だったのに対しNeovim 0.12.4は92本ありました(どちらも-n -i NONEだけを付け、-u NONEは付けていません)。診断のジャンプやコメントのトグルを標準で持っているぶん、初期状態の一覧が長くなります。
n Y * y$
:help Y-default
n gcc * <Lua 14: vim/_core/defaults:185>
Toggle comment line
n ]d * <Lua 30: vim/_core/defaults:263>
Jump to the next diagnostic in the current buffer
Vimと違って2行で出るものがあります。2行目はNeovim独自の説明文で、vim.keymap.setのdescに渡した文字列がそのまま出ます。既定の92本を数えたところ2行だったのは66本で、残る26本は説明文を持たず1行のままでした。右辺が<Lua 14: …>のものはLuaの関数が割り当てられていて中身が読めないため、この説明文が実質的な手がかりになります。自分で書いたLuaのマッピングも、descを渡していれば同じ形になります。
:verbose nmap <Leader>f
n \f * <Lua 71: ~/.config/nvim/init.lua:1>
Lua関数を呼ぶ
Last set from ~/.config/nvim/init.lua (run Nvim with -V1 for more details)
ここがVimと割れます。NeovimのLast set fromはファイル名までしか出さず、行番号の代わりに-V1を勧める文言が付きます。Luaの関数を割り当てた場合だけは右辺の<Lua 71: ~/.config/nvim/init.lua:1>に行番号が入っていますが、文字列を割り当てたマッピングでは行番号がどこにも出ません。行番号まで欲しいときは-V1を付けて起動し直します。
nvim -V1
:verbose nmap <Leader>g
n \g * :echo "lua string"<CR>
Last set from ~/.config/nvim/init.lua line 2
起動後に:set verbose=1としても行番号は出ませんでした。設定ファイルを読み込んでいる最中に記録する必要があるので、-V1は起動時に渡すしかありません。なお、キーワードで探すだけならプラグインを入れなくても足ります。Neovimの:filterは説明文も対象にするので、キー名を知らなくても用途から引けます。
:filter /diagnostic/ nmap
n [d * <Lua 31: vim/_core/defaults:267>
Jump to the previous diagnostic in the current buffer
n ]d * <Lua 30: vim/_core/defaults:263>
Jump to the next diagnostic in the current buffer
(ほかに [D ]D <C-W><C-D> <C-W>d の4本が並びます)
右辺の<Lua 31: …>は「diagnostic」を含みませんから、当たっているのは説明文のほうです。一覧を自分で加工したいならvim.api.nvim_get_keymap('n')が使えて、lhs・rhs・descを持つテーブルの配列が返ります。
バッファローカルなマッピングと削除
@が付いているものは今開いているバッファ限定なので、別のファイルを開くと消えます。「さっきまで効いていたのに効かない」ときはこれを疑ってください。ファイルタイプごとの設定(ftplugin)やLSPが付けるキーはたいていこの形です。
:unmap {キー}
:unmap! {キー}
不要なマッピングだと分かったら:unmapで削除できます。:unmapが:mapと同じ4モード、:unmap!が:map!と同じ2モードを受け持ち、:nunmapや:iunmapのようにモード別のものもそろっています。ここで引っかかるのがバッファローカルで、@付きは<buffer>を付けないと消せません。
:nunmap \z
E31: No such mapping
:nunmap <buffer> \z
(消える)
一覧には出ているのにE31が返るときは、この付け忘れがほぼ確実です。まとめて消す:mapclearも同じで、:mapclear <buffer>はバッファローカルなものだけを消します。実行したあと:nmapを引くと、\zだけが消えて自分で定義した3本は残りました。macOSの組み込みマッピングも残りますが、ここでは省いています。
:mapclear <buffer>
:nmap
n \s & :echo "script"<CR>
n \x * :echo "nnoremap"<CR>
n \y :echo "nmap"<CR>
どちらの削除も、その場のVimからマッピングを外すだけです。設定ファイルやプラグインで定義されているものは再読み込みや再起動で復活するので、恒久的に消すには:verbose mapが指した行を編集することになります。
:mapに出ないときは:map!、それでも出ないときは:lmapを見ます。定義元は:verbose map {キー}で、Vimは行番号まで、Neovimは-V1付きで起動したときだけ行番号まで出ます。
Leaderに割り当てたはずのキーが一覧から見つからず、しばらく設定ファイルのほうを疑っていたことがあります。原因は単純で、一覧が<Leader>ではなく展開後の\で並んでいたためでした。
まとめ
キーマッピングの調査は、:mapと:map!で範囲を押さえ、左端の1文字と*・@・&の印で性質を読み、:verbose map {キー}で定義元まで降りる順に進めると迷いません。キー名が分からないときは:filterで右辺から引けます。既定のマッピングを調べるときだけは起動オプションに注意してください。-u NONEを付けると標準プラグインが読まれず、素で起動したときには存在するマッピングが消えます。