音を置き去りにした
カーソル移動について考える
N番煎じというか、人類は一生同じこと考えてるなって思いますが
カーソル移動をいかに最適化するかはQOLに直結します(諸説あり)
人生の満足度あげていきましょう
移動
みなさんのうちにVSCodeユーザなんていないと思いますが
VSCodeユーザがもしいれば、基本的にマウス操作か
vimプラグインを入れてjkhlしているでしょう。
世の中には視線入力なんてものがあるらしいですが、大衆が一般導入するにはまだ早いでしょう。
ここはおとなしくvim操作をベースに考えるしかありませんね。いやぁしかたないなぁ。
まずは縦移動、横移動で分けて考える。
vimにおけるカーソル移動はデフォルトだと
縦移動
おおきめの移動 / 細かい移動
キー | 移動先 |
---|---|
H | 上のほう |
M | まんなか |
L | 下のほう |
{ | 段落上に |
} | 段落下に |
キー | 移動先 |
---|---|
j | 1行上 |
k | 1行下 |
gj | 表示行で1行上 |
gk | 表示行で1行下 |
※私はnnoremap j gj
してます
横移動
※他にもありますが、私はだいたいこの辺しか使ってないです
おおざっぱに移動 / 細かい移動
キー | 移動先 |
---|---|
0 | いちばん左 |
^ | 行頭 |
$ | 行末 |
w | 単語ごと移動 先頭文字に |
e | 単語ごと移動 単語末文字に |
b | 単語ごと移動 戻る |
W E B | 単語とみなす文字をおおざっぱに |
キー | 移動先 |
---|---|
h | ひとつ左 |
l | ひとつ右 |
f{char} | カーソルから見て右に、最初の{char}に飛ぶ |
F{char} | fの左向き |
tT | fと同じで、{char}の一つ手前に飛ぶ |
; | fFtT移動の繰り返し用 |
: | ;の逆向き |
さて、このようにデフォルトでも十分思考のスピードですが
やはり今ひとつ細かい移動が足りない
と感じます。このままではマウスを使った方が早い。非常にまずい。
改善案
縦移動
おおきめの移動
H
M
L
はとてもいいが、1ページに表示される行数はだいたい多くても50行。
私は46行です。
ここでHML移動だと、1行目、24行目、46行目に飛べますが
例えば1-24
行目の間のどこかに飛びたい場合、最大でも12行目まで移動する11回の縦移動
が必要となる。または
H
で1行目に飛んだのちに11j
とする必要があるが、
数字を数えるくらいならj連打や長押ししたい。
プログラミング中に行数数える脳のリソースを割きたくない。
ここで
set scrolloff=5
この設定を入れることで、H
とした時1行目でなく、5行目に飛ぶ。
ページの上下5行までにしか、カーソルが行かないようになるのだ。
1行目に飛びたい場合こそH5k
になるが、12行目に飛びたい場合はH5j
と、少し幅が狭まった。
そして、set scrolloff=5
を入れるとだいたい
H M L
の後に5行移動すれば、あと1,2行でゴール、まで行ける。だいたいね。
なので
nnoremap <Tab> 5j
nnoremap <S-Tab> 5k
この設定が活躍する。<Tab>
キーで5行移動するのだ。
これによりH M L <Tab> <S-Tab>
で、あたまからっぽでほぼゴールに辿り着ける。
細かい移動
流石に1,2行の移動はjkでいいが、後述するf移動
によりそれすら不要となるのでご期待ください。
横移動
おおざっぱに移動
やはり改善すべきはf移動
。とても強力なジャンプ機能だが、飛びたい文字がカーソルからみて最初に出てきる文字なのかどうかがわからないので
f{char}
の{char}が何かを見るために一瞬遅れる。非常によろしくない。
ので、
一撃でf移動できる文字をハイライトする
ことによりこれを改善する。後述します。
細かい移動
これは不要と断言できる。なぜならvimのテキストオブジェクトは、カーソルが単語に上にさえいれば良いようにできているから。やっぱvimって神なんだなって思います。
現存するプラグイン
さて、これらをすでに解決しているプラグインが多数あります。人によって好みが分かれるので、お好きなものをお使いください。
vim-easymotion
2次元に移動する。
そもそも縦横でなく、飛びたい場所に一撃で飛ぶもの。
神なので入れてるが、個人的には視差が大きいので、ほんのわずかに集中力途切れるのが好ましくない。神プラグイン機能であることは間違いないしめっちゃ好きな機能ではあります。
vim-edgemotion
縦移動の大幅改善。ExcelとかでCtrl + ↑
とかと同じように、上下に文字がある行まで飛べる。easymotionと同じ作者なので、やはり神プラグイン。
私は主戦力として使ってます。
なお、edgemotionをフル活用するために
set virtualedit=all
clever-f.vim
横移動のf移動
の連打;
をより頭空っぽにするためのもの。
;
とか:
ってちょっと打ちにくいじゃないですか。。
f連打で繰り返しできるようになる上、行をまたいでf移動できます。
quick-scope
f移動先の、一撃で行ける文字を剪定
してハイライトしてくれるもの。
ただ単語の先頭文字をハイライトしてるだけじゃないです。何も考えずに
色ついてる文字に対してf{char}
すればいいだけになる。
clever-fもあれば、本当に頭使わずに瞬間移動できる。
ほかにも多数ありますが、いったんここまでとします。
より、あたまを空っぽに
さて、実はこれでもまだ弱いです。
横移動において、その行までいかないと移動できないのです。
当たり前かと思いますが、だいたい近い行
まで来たらそのまま移動しきりたい。
これは
- quick-scopeが現在行しかハイライトしないこと
- それに対しclever-fが行をまたいでf移動できること
の噛み合わせの悪さにあります。
いくらclever-fで行をまたいで移動できようと、移動先の行にいかなければハイライトされないので
行跨ぎ機能 がいまいち生きていない。そこで
前後n行のfな文字をハイライトする機能
および冒頭で紹介したタブで5行移動
のプラグインを作成しました。
vim-anchor5
これあ5行移動するだけでなく、前後5行にマークをつけてくれるので
行きたい行まで行けてるのかどうかがぱっと見でわかります。
vim-fscope-around
そして、マークのアンカーがある行内で、現在行の前後5行にquick-scopeをする。
さすがに全部の行で文字に色がつくと目がしんどいので
現在行以外は下線が引かれます。
もちろんハイライトを即座にオンオフできます。
↑のgifは
vim-anchor5, fscope-aroundに加えて
edgemotion, clever-f
の組み合わせなどで実現できます。
HML
や}{
やタブ、edgemotion
でだいたい縦に移動し、行きたい場所にハイライトがついたらf{char}
し、たどり着くまでf連打するだけ。
これらによりあたま空っぽで光速移動できるようになりました。