この記事は、Vim駅伝の2024年5月29日の記事です。
22日の記事でH/LとPageUp/PageDownを共存させる設定の紹介がありました。
H
とL
は通常では、表示領域内の最初の行や最後の行にカーソルを移動させるコマンドです。
連打しやすい割に、連打する意味がない、惜しい存在ですが、スクロール機能も持たせるのは良いアイデアですね。
というわけで、似たようなことを、疑似サブモードを利用して実現してみました。
以下のマッピングを定義すると、H
単発でウィンドウ上端へのカーソル移動、連打で<PageUp>
に変身します。
難読な気もしますが、たった4行で実現できるのが凄いですね。
nnoremap H H<Plug>(H)
nnoremap L L<Plug>(L)
nnoremap <Plug>(H)H <PageUp><Plug>(H)
nnoremap <Plug>(L)L <PageDown><Plug>(L)
挙動としては以下のような流れ。
H
を入力すると、オリジナルのH
として動作した後、<Plug>(H)
を入力した状態になる- Vimは、
<Plug>(H)
をprefixに持つマッピングがくるのを一定時間待機する - 待機中に
H
を入力すると、<Plug>(H)H
扱いになり、<PageUp>
した後、もう一度<Plug>(H)
をprefixとした待機状態になる
なお、<PageUp>
の直後にH
を、<PageDown>
の直後にLzb
を仕込んでおくと、カーソル位置が良い感じに調整されると思います。
nnoremap H H<Plug>(H)
nnoremap L L<Plug>(L)
nnoremap <Plug>(H)H <PageUp>H<Plug>(H)
nnoremap <Plug>(L)L <PageDown>Lzb<Plug>(L)
<PageUp>H
や<PageDown>L
をすると、連打中のカーソル位置が常にウィンドウの上端か下端に固定されます。
また、バッファ最終行で<PageDown>
すると、ウィンドウに表示される内容が最終行だけになってしまいスクロールし過ぎな感じになります。<PageDown>Lzb
のようにzb
を含めると、カーソル位置をウィンドウの下端に寄せることができ、情報量が多くて良い感じになります。
2024-05-30追記
上記のマッピングの場合、belloff
オプション次第でサブモードの待機時間経過後にベルが鳴るそうです。
Neovimではset belloff=all
が既定値なので問題ありませんが、Vimはset belloff=
が既定値なので、うるさいかもしれません。
自前でbelloff
を設定するか、以下のようにサブモード離脱時の挙動を<Nop>
に設定しておくといいです。
情報提供頂いたthincaさんに感謝。
nnoremap <Plug>(H) <Nop>
nnoremap <Plug>(L) <Nop>
それから、サブモードの待機時間はtimeoutlen
オプションに依存します。
使い勝手に合わせて調整してみてもいいかもしれません。
ENJOY