2012-03-26 Vimでprefixキーを持つkey mappingについて
Vimでprefixキーを持つkey mappingについて書く。
Vimではkey mappingという機能がある。この機能は入力キーの動作を変更できる。例えば既定の動作ではノーマルモードでiキーを押したとき挿入モードに移るが、この動作が気に食わないならoキーの動作に変更できる。キーを別のキーの動作にするだけではなく、一連のキー操作にすることもできる。iキーを押したときに:execute 'help' expand('
簡単な例を挙げる。
" 1. 基本的なkey mapping
nnoremap <Space> <Nop>
nnoremap <Space>w :setlocal wrap!<C-m>
nnoremap <Space>h :nohlsearch<C-m>
3つのkey mappingを定義している。
- ノーマルモードで「<Space>」を入力しても何もしないkey mapping
- ノーマルモードで「<Space>w」を入力することで'wrap'を切り替えるkey mapping
- ノーマルモードで「<Space>h」を入力することで:nohlsearchを実行するkey mapping
ノーマルモードの「<Space>」は「l」と同じ動作なので無くなっても困らない動作である。そこで<Space>キーをつぶしてprefixキーとして使い、<Space>に続くwキーとhキーに別の機能を割り当てている。
上記の例は改善できる。実際に動かしてみると分かるが、<Space>は入力しても入力されているのかどうかが確認しづらい。そこで次のような設定をすることで改善できる。
" 2. <Space>を可視化する
nnoremap [Space] <Nop>
nnoremap [Space]w :setlocal wrap!<C-m>
nnoremap [Space]h :nohlsearch<C-m>
nmap <Space> [Space]
この技法は「Vim: <Space>で始まるkey mappingの可視化」で紹介されている。いち早くこの高みに到達している。さすがkana神である。
また、この技法には<Space>を可視化する以外の利点もある。「Vim Hacks #59」で紹介されているとおり、「prefixキーを抽象化し明示できること」、「prefixキーの変更が容易になること」がこの方法の利点である。
<Space>だけに限らず、幅広くこの技法は適用できる。
実は上記の例をさらに改善できる。上記の例では「[Space]」というグローバルなkey mappingを設定しているためにkey mappingの定義によっては待ち時間が発生するという問題がある。そこで次のような設定をすることで改善できる。
" 3. [Space]をscript-localに閉じ込める
nnoremap <SID>[Space] <Nop>
nnoremap <SID>[Space]w :setlocal wrap!<C-m>
nnoremap <SID>[Space]h :nohlsearch<C-m>
nnoremap <script> <Space> <SID>[Space]
この技法は「Vim Hacks #144」で紹介されている。
また最後のkey mappingで「script」オプションを使用している。これはkey mappingの右辺({rhs})で
ここまでやれば十分なのだが中には怠け者が居る。怠け者はこう考えるのだ。「
" 4. prefixedmap.vimを使用する
call prefixedmap#load()
nnoremap <SID>[Space] <Nop>
PrefixedMapBegin <SID>[Space]
Pnnoremap w :setlocal wrap!<C-m>
Pnnoremap h :nohlsearch<C-m>
PrefixedMapEnd
nnoremap <script> <Space> <SID>[Space]
「prefixedmap」プラグインである。emanon001に書かれたプラグインであり、「Vim でのプレフィックスキーを用いたキーマッピングの定義方法を改善する」で紹介されている。詳細な説明はそちらを参照してほしい。
上記の例では、prefixキーに対して定義しているkey mappingが少ないため、余計に複雑になってしまう。しかし、この方法はprefixキーをコマンドごとにくり返し書く必要がないし、prefixキーの開始終了が明示され、より美しいだろう。(公開されたばかりのプラグインであり、「<Nop>」が醜いので、改善要望を出すつもりだ。)
現時点でぼくが知るprefixキーを使ったkey mappingについて書いた。参考にしてほしい。
55 min.