⌨️

Vimのデフォルトキーマップをどのように上書きするか(ノーマルモード)

2023/12/09に公開

この記事はVim Advent Calendar 2023 シリーズ1の12/09の記事です。

Vimにはキーマップを定義する機能があります。Vimに慣れてきた頃、この操作をどこかのキーに割り当てたい。そういう場面は多かれ少なかれ出てくるものと思います。

そして、ここで直面する問題として、キーのほとんどが定義済みのキーマップで埋まっていて、デフォルトキーマップを上書きしないことには新しくキーマップを定義できない問題があります。

なのでどうするかといえば、デフォルトキーマップを上書きするしかないんですが[1]
デフォルトキーマップもよくできているので、無暗に上書きすると今度はVim標準の機能が活かせなくなってしまいます。また、自分のものでないVimを使ったとき、操作がもたつくことにもなります。

とはいえ、そういった裏目を軽減する術が無いこともありません。
この記事では、上書きの裏目を軽減するキーマップの仕方、また、デフォルトキーマップを上書きする候補についてまとめます。

上書きの裏目を軽減するキーマップの仕方

キーマップの上書きをすると、元の操作が使えなくなるほか、
キーマップが未定義の環境で作業をして、意図せず元の操作が発火する、等の裏目があります。

その裏目を軽減する方法として、次のようなものがあります。

  1. 定義済みのキーマップが無いものを利用する
  2. キーマップが未定義のときに入力してしまっても問題無いものを利用する
  3. いくつかのキーをプレフィックスキーとして使う
  4. 上書き前後で概念を一致させる形でキーマップを行う
  5. 他のソフトウェアによって提供されているキーマップに合わせる形でキーマップを行う
  6. 裏目を気にしない

それぞれ見ていきましょう。

定義済みのキーマップが無いものを利用する

数は少ないですが、定義済みのキーマップが無いキーがあります。
単一のキーで見たとき、次のキーが空いています。

英語配列空き状況

いや、見ての通りほとんど空いてないです。定義済みの濃灰色、環境によっては利用できないときがある薄灰色を除くと、残るキーは\、<C-k>の2つしかありません。とはいえ、この2つについてであれば、元の操作を上書きすることなく割り当てが可能です。

もう少し広く見てみましょう。プレフィックスキーとしてある5つのキー、g、Z、Z、[、]、<C-w>の5つに続くキーマップであれば、もう少しだけ空いています。プレフィックスキーごとで見たとき、次のキーが空いています。

プレフィックスキー空き状況

それぞれについて、

プレフィックスキー
g キーがいくつか空いており、好きに使える
z 表示位置調整系、折り畳み調整系の2種でキーマップがまとめられており、キーもそこまで空いていない。どちらかに2種に属するなら可、それ以外は非推奨
Z ZZとZQだけなのでかなり空いており、好きに使える。ただ、その2つ、ZZとZQはどちらも間違って打つと困る(が便利)なキーマップであるため、そこのケアを考える必要はある
[ ] ジャンプ系でキーマップがまとめられているが、キーは結構空いている。ジャンプ系に属するものが推奨だが、それ以外も可
<C-w> ウインドウ調整系でキーマップがまとめられており、キーもそこまで空いていない。ウィンドウ調整系に属するなら可、それ以外は非推奨

キーマップが未定義のときに入力してしまっても問題無いものを利用する

デフォルトキーマップのほとんどはどれも欠かせないものですが、利用する場面が少ないものについては、上書きしてしまってもそこまで支障はありません。特に、キーマップが未定義のときに入力してしまっても問題無いキーマップについては、間違って打ってしまっても何も起きないため、安心して割り当てが可能です。

ここは後述のデフォルトキーマップを上書きする候補にて触れます。

いくつかのキーをプレフィックスキーとして使う

これは上書きに限った話では無いですが、1でも触れた通り、使えるキーには限りがあります。そのため、キーマップをある程度節約して割り当てる必要があります。

節約には一部のキーをプレフィックスキーとして使うことが有効です。次のようにキーマップを定義することで、\、gbをプレフィックスキーとしてキーをまとめることができます。近いものはまとめるといいでしょう。キーの連続は3文字以上でも可能です。

キーマップ 操作
\a 操作1
\b 操作2
gba 操作3
gbb 操作4

とはいえ、1文字、2文字、3文字だと、それぞれ打つ手間が違います。特に3文字は頻繁に打つには大変です。そのため、1文字のキーマップをある程度厳選して割り当て、それ以外をプレフィックスキー付きのキーマップとしたほうがいいです。また、プレフィックスキーは可能な限り修飾キーが無いほうが打つのが楽です。

上書き前後で概念を一致させる形でキーマップを行う

元の操作を概念として捉え、上書き前後で概念から外れないように割り当てをすることで、キーマップが定義済み、未定義、とちらであっても混乱することなく操作ができます。

これは少し分かりづらいかもしれないので、例を見てみましょう。

キーマップ 概念
K ドキュメントを参照する
gd 定義元に飛ぶ

Kは元々カーソル位置のワードについて、keywordprgに設定されたコマンドでドキュメントを確認するキーマップですが、割り当て後の操作がドキュメントを参照する類の操作であれば混乱が少ないです。gdは元々カーソル位置のワードについて、スコープ内での定義元にジャンプするキーマップですが、割り当て後の操作が定義元にジャンプする類の操作であれば混乱が少ないです。

できるケースとしては少なめですが、混乱を軽減する方法の一つです。

他のソフトウェアによって提供されているキーマップに合わせる形でキーマップを行う

他のテキストエディタ・IDE(VSCode、IntelliJ IDEA)、それらのVimエミュレーション(Evil、VSCodeVim、IdaeVim等)は独自のキーマップを提供しています。それらのキーを逆輸入して割り当てることで、環境が変わっても混乱することなく操作ができます。

こちらも例を見てみましょう。

キーマップ 操作 輸入元
gh ホバー VSCodeVim
<C-p> ファイル検索 VSCode

ghは元のVimだとセレクトモードに入るキーマップですが、VSCode+VSCodeVimではホバーとして定義されています。<C-p>はVimだと上に移動するキーマップですが、VSCodeではファイル検索として定義されています。VSCode+VSCodeVimあわせ、VSCodeあわせにVimを設定することで、交互に使ったときの混乱を軽減できます。[2]

こちらも4と同じで、できるケースとしては少なめですが、混乱を軽減する方法の一つです。

裏目を気にしない

裏目裏目と、後ろ向きに考えすぎるのも考えもの。裏目があったとして、それが気にならなければ問題にはなりません。気にせずどんどん上書きしたらいいです。

裏目を気にする場面としては、他の人のVimを使う、コンテナやサーバーに入ってVimを使う、別のテキストエディタにVimエミュレーションプラグインを入れて使う、等の場面でしょうか。これらの場面が無いのであれば、そこまで裏目を気にする必要も無いとも思います。

デフォルトキーマップを上書きする候補

上書きは多少必要だとして、ではどこを上書きしたらよいか、
ということで上書き候補を表にしたものが次の画像になります。[3][4]

英語配列キーマップ候補

薄青色のキー、濃青色のキー、薄黄色のキー、が上書き候補、
濃黄色のキー、薄灰色のキー、濃灰色のキーが上書きを避けたほうがいいものになります。

薄青色のキー、薄黄色のキーの2つは利用する場面が少なく、かつキーマップが未定義のときに入力してしまっても問題無いもので、割り当てに特におすすめです。

それぞれについて、

振り分け
割り当てられないときがある:
濃灰色
環境によってはキーマップが定義できない。とはいえ、割り当てられている操作は何も無く、完全にフリー
上書きすることはない:
薄灰色
基本といえる操作が割り当てられており、上書きすると支障が出る。とはいえ、絶対に上書きしてはだめということもない。落としどころを見つけられれば割り当ててしまってもいい。打ちやすいものも多い
上書きは避けたいが不可ではない:
濃青色
どのような操作を割り当ててもいいが。元のキーマップは利用する場面がある、または打ちづらいもの。とはいえ、キーマップが未定義の状態でキー間違って打ってしまってもテキストに影響が出ず、操作には支障が出づらい
上書き候補(汎用):
薄青色
どのような操作を割り当ててもいい。元のキーマップは利用する場面が少なく、かつキーマップが未定義の状態で間違って打ってしまってたときにテキストに影響が出ず、操作に支障が出づらい
上書きは避けたいが不可ではない(アクション限定):
濃黄色
何かの実行を操作を割り当てるのであれば候補となるが、それでも基本的には非推奨。元のキーマップは利用する場面があり、テキストに影響が出たり、別のファイルを開いたりするもの、または打ちづらく副作用が小さいながらもあるもの。キーマップが未定義の状態でキー間違って打ってしまったときテキストに影響が出るため、操作に支障が出る
上書き候補(アクション限定):
薄黄色
何かの実行を操作に割り当てる分には薄青色と同じくらい良い。元のキーマップは利用する場面が少なく、かつキーマップが未定義の状態で間違って打ってしまってもウインドウが開いたり、モードの切り替えが発生したりする程度で、単体ではテキストに影響が出ず、操作に支障が出づらい

各候補をどういう理由で振り分けたかについては次の通り。バイアスは結構かかっています。

割り当てられないときがある: 濃灰色

キー
<C-`> <C-1> <C-2> <C-3> <C-4> <C-5> <C-6> <C-7> <C-8> <C-9> <C-0> <C--> <C-=> <C-s> <C-;> <C-:> <C-'> <C-,> <C-.> <C-/> その他 環境によっては使えなかったりするのであまりおすすめできないが、キーマップ自体は未定義で空いており、数も多い

上書きすることはない: 薄灰色

キー
h j k l 基本の左下上右移動。いかにこれらの使用回数を減らすかが素早い移動の肝ではあるものの、移動の最小単位のため無いと困る。必須
w b e 単語移動。普段の移動にちょうどいい。必須
W B E 大振りの単語移動。w b eと使い分ける場面が多くある。特に日本語のテキストを編集しているときに役立つ。必須
f F t T 文字検索移動。w b eとは違った使いやすさがある。必須
0 ^ $ 行頭移動・行末移動。I Aで文字を足すとき以外はこちらで移動して編集する。どちらも外せない。必須
{ } ブロック移動。数少ない縦移動で、w b eと同じ感覚で使える。必須
G 一番下への移動。ファイルの末尾を確認したい場面は多々ある。必須
/ ? n N 検索・次へ・前へ。全体の検索に限らず、中規模以上の縦移動にも使う。必須
* # カーソル下のワードでの検索。ワードでの検索をする場面は多くあり、/ ?での入力を大きく省略できる。必須
<C-i> <C-o> <Tab> 履歴移動。大きな移動の後に戻りたい場面は多くある。必須。<C-i>と<Tab>は片方にマッピングすると片方も更新される
x 1文字限定のカット。dlで代用は可能だが、小気味よく、かつ利用する場面も多い。回数指定との相性もいい。必須
d カット。必須
y ヤンク。必須
p P ペースト。必須
r 1文字置換。c、Rで代用は可能だが、小気味よく、かつ利用する場面も多い。必須
R 複数文字置換。cで代用は可能だが、行の文字数がぶれず、元の内容を見ての修正がしやすい。必須
J 行連結。必須
< > = インデント調整。微調整にもまとまった操作にも使う。必須
<C-a> <C-x> インクリメント・デクリメント。連番の作成、カウントのずらし、簡易的な計算等、使い道が幅広い。必須
u <C-r> アンドゥ・リドゥ。必須
i I a A o O 挿入モードへの移行。どれも状況に応じて使う。必須
c カットしつつ挿入モードへの移行。使いやすく、かつ幅広く使う場面がある。必須
S 行全体をカットしつつ挿入モードへの移行。ccで代用できるが、これまた使いやすい。必須
v V <C-v> ビジュアルモードへの移行。どれも状況に応じて使う。必須
: コマンドモードへの移行。必須
! !コマンドを指定してのコマンドモードへの移行。!コマンドは外部コマンドの活用の要で、これも処理範囲の指定に役立つ。必須
. ドットリピート。小規模の連続操作の要。必須
q @ マクロの記録・再生。中規模の連続操作の要。必須
1 2 3 4 5 6 7 8 9 回数指定。あらゆる操作とセットで使う。必須
<C-l> 再レンダリング。あまり使う場面は無いが、意図せず表示が崩れたときに直す手段なので上書きせず残しておきたい。必須
<C-c> コマンドや検索を止める。間違って時間のかかる処理を実行してしまったときに止める手段なので上書きせず残しておきたい。必須
<C-z> 一時停止。Vimを抜けてターミナルで作業したい場面は多々ある。必須
g z Z [ ] <C-w> プレフィックスキー。必須。Zだけぎりぎり上書きのしようがあるかもしれない
" レジスタ参照。レジスタはときどき2つ以上欲しくなるほか、特殊なレジスタを参照する場面もある。必須
' ` マーク参照。直接はあまり使わないが、プラグインが参照することがあるため、上書きせず残しておきたい
<ESC> <C-[> ノーマルモードへの移行。EmacsのC-gと同じ。連打して通常の状態に戻したいときがあるため、上書きせず残しておきたい。<C-[>と<ESC>は片方にマッピングすると片方も更新される

上書きは避けたいが不可ではない: 濃青色

キー
<Left> <Down> <Up> <Right> <Home> <End> <PageUp> <PageDown> キーマップ定義済みでかつ、キーが遠い。使うことが無いともいえないため、上書きせず残しておいたほうが無難
<C-m> <Enter> <C-h> <BS> 次行への移動・1文字前移動。それぞれhとjで代用はできるが、<C-m>は変えると<Enter>も変わり、<C-h>は変えると<BS>も変わる。間違って打ってしまいやすいため、上書きせず残しておいたほうが無難
; , 文字検索移動での検索の次へ・前へ。連続した修正を行うときや、fFtTで狙った場所に一度で飛べなかったときにも打つ。一度覚えると手放せないが、fFtTの連打でなんとかできなくもなく、知らなかったら知らなかったでなんとかなるので、ある種試さずに最初からキーマップに使うのも一つかもしれない
+ - 次行・前行の行頭への移動。jkと^0で代用できないこともないが、小気味良い操作で使う場面も多いため、上書きせず済むならそのほうがいい
% 対応する括弧への移動。移動に役立つ場面が多くあるため、上書きせず済むならそのほうがいい
H M L 画面表示上での最上部・中央・最下部への移動。貴重な縦移動で使いやすいため、上書きせず済むならそのほうがいい
<C-f> <C-b> <C-d> <C-u> スクロール。便利だが無くても割となんとかはなる。ただ片方は残しておきたい
m マーク。人によって使用状況が異なる。マーク機能を試してみて、スタイル上使う場面が無さそうであれば上書きしても問題無い
<C-g> 開いているファイルの情報を確認。ときどき使うため、上書きせず済むならそのほうがいい

上書き候補(汎用): 薄青色

キー
\ <C-k> <F2~> 貴重なキーマップ未定義キー。\、<F2~>は少し遠く、<C-k>も修飾キーを必要とするので、キーを定義するなら1キーにしておきたい
<Space> <C-n> <C-j> <C-p> 1文字右、下、下、上へ移動。jklで代用できるためあまり使う場面がない。<Space>はかなり打ちやすく、キーマップに特におすすめの一つ
( ) 文節移動。英語の文章では便利だが、それ以外の場面では変なところで止まるのもあってあまり使わない。ある程度打ちやすくキーマップに特におすすめの一つ
_ 回数指定-1の行数だけ下に移動して行頭へ移動。^で代用できるためあまり使う場面がない。キーとしては少し遠い
| 表示上の列位置を指定しての移動。0 h lで代用できるためあまり使う場面がない。キーとしては少し遠い
<C-e> <C-y> 1行分スクロール。<C-f>、<C-b>、<C-d>、<C-u>と比較したときに使う場面が少ない
Y 1行ヤンク。yyで代用できるためあまり使わない。Sに近いが、こちらは副作用が抑えめでキーマップをしやすい。比較的打ちやすくキーマップに特におすすめの一つ
<C-\> insertmodeのとき限定のキーであり、実質キーマップ未定義。ただ、キーが遠い。キーマップを定義するなら1キーにしておきたい

上書きは避けたいが不可ではない(アクション限定): 濃黄色

キー
<Del> 1文字限定のカット。キーが遠いため、上書きせずに残しておいたほうが無難
X カーソル位置の前の1文字をカット。xで間に合うとこがあるため、あまり使う場面が無いが、かといって上書きするには事故が怖い
D カーソル位置から右をカット。結構使う場面がある
~ ケースの入れ替え。ケースの調整に便利
& 置換の繰り返し。ただ、必要な場面では最初から:s///gとするので、あまり使う場面が無いが、かといって上書きするには事故が怖い
<C-@> 前回入力した内容の貼り付け。あまり使う場面が無いが、かといって上書きするには事故が怖い。上書き関係無く日本語配列と英語配列を行き来するとこのキーで事故する
U 1行分のアンドゥ。uで間に合うことが多いためあまり使わないが、かといって上書きするには事故が怖い
<Insert> 挿入モードへの移行。キーが遠いため、上書きせずに残しておいたほうが無難
C カーソル位置から右をカットしながら挿入モードへの移行。Dと似た場面で使う
s 1文字カットしての挿入モードへの移行。xと同じくらい使いやすい。xと同じく回数指定との相性がいい
<C-^> 直前に開いていたファイルへ移動。ファイラ系のプラグインとの相性が良い。<C-o>、<C-i>とよく使い分ける
<C-]> tagsから得られた定義箇所への移動。ctagsを直接使っていなくとも、helpページ内の行き来で使う

上書き候補(アクション限定): 薄黄色

キー
<C-q> ビジュアルブロックモードへの移行、<C-v>で移行するため使う場面が無い。ESCですぐ戻れ、事故で困りづらい
Q Exモードへの移行。あまり使う場面が無い。間違って打ってもvi<Enter>ですぐ戻れ、事故で困りづらい。比較的打ちやすくキーマップに特におすすめの一つ
K カーソル下のワードをmanualprgで調べる。ちょくちょく使いはするが、ドキュメント引きとして上書きする分には問題無い。未定義でも事故で困りづらい。比較的打ちやすくキーマップに特におすすめの一つ
<F1> ヘルプページを開く。:hでヘルプを引くため使う場面が無い。ヘルプページが開かれるだけのため、事故で困りづらい

まとめ

デフォルトキーマップを上書きする候補の表にある、薄青色のキー、薄黄色のキーが割り当てにおすすめです。また、上書き時のTIPSとして、上書きの裏目を軽減するキーマップの仕方の6項目が参考になると思います。

記事内の表は次のリンクにあります。

https://docs.google.com/spreadsheets/d/18b2dB68X-xDh_fVAkcfwqzlJ2IXceA9yLAWlcFFPuuQ/edit?usp=sharing

キーマップは多用する操作の短縮に有効な手段の一つですが、あればあるほどいいもの、ということもありません。必要な場面で必要な分だけ設定しましょう。

脚注
  1. 後述しますが、\、<C-k>等、デフォルトキーマップの無いキーもあります。とはいえ数が少なく、これらだけではどうしても大変です。 ↩︎

  2. 手元のVim、サーバーのVimとの間で混乱するのでは、と思うかもしれませんが、それは実際そうです。そこは微妙な点ではあります。なので、個人的な対策としてgd、gh等は開発用のキーマップとして覚える、として混乱を軽減しています。うーん ↩︎

  3. 表は個人的観点からまとめたもので、かつあくまでも目安なので、必ずしもこの表に沿う必要はありません。 ↩︎

  4. 濃灰色(割り当てられないときがある)については正確かあまり自信がありません。もし違ってたら教えていただけたら… ↩︎

Discussion