🦍

Vimにおけるカーソル移動の効率化

2022/01/29に公開

初めに

最近Vimにおけるカーソル移動の効率化について少し考えていて、自分なりに

  1. どんなカーソル移動方法があるのか?
  2. それぞれのメリット・デメリットは何か?

について整理&改善をしたくて、この記事を書きました。
後半にカーソル移動の改善のために作ったプラグインの紹介もあるのでぜひ最後まで読んでみてください。

テキストの編集の動作について

基本、どんなエディタでもテキストを編集するのに次の動作を繰り返すと思います。

  1. 移動先の座標を認識(目で見て脳で認識)
  2. キーボード・マウスを使ってカーソルを対象の座標に移動
  3. 対象のテキストを編集(カット・置き換え・削除など)

これらの動作を前提、どんなカーソル移動の方法があるかについて整理していきます。

マウスによるカーソル移動

多くの人はマウスを使用しているかと思うので、こちらの方法はもっとも一般的といえるでしょう。
個人的に、マウスにおける最大のメリットは「目を動かさず、カーソルを縦横無尽に移動できること」と思っています。
まぁ、要は直感的にカーソルを動かせる点ですね。

Vimの場合、デフォルトではマウスは使用できないが、:set mouse=aでマウスが使用可能になります。
もちろんスクロールもできます。

カーソル移動だけなら、正直マウスが最適なのではないかなと思っていますが、移動後のテキスト編集も加えると少々不便と感じることがあります。
たとえば、""で囲っている文字列を削除したり置き換えたりする場合、マウスだと少々時間ロスが発生します。(個人の体感)
Vimの場合、textobjとoperatorを使えばci"を使うと""で囲っている文字を削除しインサートモードに移行できるのですぐに入力が可能になります。

ですので、カーソル移動はマウス、編集はtextobjやoperatorという使い分けが最適と思っています。
しかし、マウスを使う場合、次の課題があるかなと思っています。

  1. キーボードから手を離してしまうため、カーソル移動 => テキスト編集のシームレスな操作ができない
  2. マウスが常にエディタの画面にあるわけではないので、エディタまでカーソルを移動させる必要がある

1に関してトラックパッド・ポイントがついているキーボード(orノートPC)、またはトラックボールがついている自作キーボードを使うといった対策をすれば問題ないと思います。

2に関してはPCの画面を1つにして、エディタを使うとき前面に出せばカーソルの移動距離は減るので、ほぼ問題ないと思います。

上記2点を満たした環境であればテキスト編集は最適化されるかなと思いますが、残念ながら次の課題があるため、難しいかなと考えています。

  • ディスプレイが1つだけ使うことは少ないこと(自分の観測範囲内では)
  • 自作キーボードのハードルがちょっと高い
  • トラックパッド・ポイントによる一度の移動距離に限界がある

要は、ハードウェア依存のカーソル移動の最適化は課題があり、難しいというのが自分の結論です。

視線によるカーソル移動

個人的に一番の理想は目線とカーソルの同期です。
つまり、目を使ったカーソル移動です。

ちょっと調べたところ、技術として存在していて製品も発売されている様です。
詳細はこちらのブログを参照してください。

ブログを読む限り、挙動は理想に近いなと思っていますが、導入ハードルが高いのと移動の精度に難がありそうかなと感じました。
特に精度に関しては、文字単位での移動は難しそうという印象があります。
よほど訓練しないと難しいだろうし、ディスプレイが何枚もあると制御も難しいかなと推測しています。

上記の点を踏まえると、やはりハードウェアによるカーソル移動の最適化は難しいかなと思います。

キーボードによるカーソル移動

基本、Vimは縦と横の直角移動しかできないですが、移動の方法が何種類かあります。
あらめてVimにおけるカーソル移動の方法についておさらいしていきます。

横移動

横移動でよく使われるのはwe^fFtTなどがあります。
詳細は省きますが、いくつかスクショを載せておきます。
横移動だけでいろいろな方法があるので、使いこなせると編集が快適になると思います。

正直、横移動だけなら標準機能で物足りているかなと思っています。

縦移動

横移動と同様で、縦移動の方法もいくつかあります。

  1. {count}Gによる行指定の移動
  2. {count}j{count}kによる差分の移動
  3. {}による段落の移動
  4. /?による移動

これらのメリット・デメリットについて、次のように考えています。

{count}Gによるカーソル移動

  • メリット
    • 対象行がわかっている場合すぐに移動できる
  • デメリット
    • 行番号を表示する領域があるため、画面の幅が狭くなる
    • 数字を入力しづらい(自分だけかもしれない)
    • 行番号と移動したい文字の間で目線の移動が発生するため少し時間ロス

デメリットの2つ目ですが、自分のように視野が極端に狭い人に起きる問題かなと思っています。
視野が広く、対象文字と行番号が同時に見えている場合、この移動方法がよいかなと思います。

{count}j/{count}kによるカーソル移動

  • メリット
    • 対象行との差分がわかっている場合、すぐ移動できる
  • デメリット
    • 行番号を表示する領域があるため、画面の幅が狭くなる
    • 数字を入力しづらい(自分だけかもしれない)
    • 行番号と移動したい文字の間で目線の移動が発生するため少し時間ロス

こちらのデメリットも{count}Gと同様、目の移動が必要という点で問題があると思っています。

/?によるカーソル移動

検索によるカーソル移動は、上記上げた移動方法の中で一番柔軟性があるかなと思っています。
行番号を気にしなくてよくなる分、目線移動による時間ロスは軽減できるかなと思っています。

しかし、この移動方法にも次の課題があります。

  1. 検索結果が多い場合、移動回数が増えるため、結局時間がかかってしまう
    上記のスクショ例ではeventの検索結果が多いので、Nを6回押すため時間がかかる
  2. キーストローク数が増える

1に関しては、後述するvim-searchxというプラグインで解消されますが、
2に関して残念ながら検索である以上解消は難しいかなと思います。

このように、検索によるカーソル移動はかなりよい線行っていますが、ちょっと課題があるかなといったところです。

プラグインによる移動手段の拡張

プラグインによる移動手段の拡張として、主に次のプラグインがあるかなと思います。

  1. vim-easymotion
  2. vim-searchx
  3. clever-f.vim

vim-easymotion

vim-easymotionはもっとも有名なプラグインかなと思います。公式のgifを見るとその柔軟性はすごいことがよくわかります。


vim-easymotionのREADMEより

カーソル移動したい文字への目線を動かさず、その文字を入力したあとにラベル文字を入力するだけで一発で飛びたい場所に移動できます。
しかし、検索likeの移動方法のためやはりストローク数が増えてしまうという問題は依然として残っています。

すばらしいプラグインですが、キーストローク数が増えてしまう問題は自分の中では許容できないため、使用するに至りませんでした。

vim-searchx

hrsh7thさんによる/?機能とvim-easymotionを足したようなプラグインです。
簡潔に説明すると、検索結果にラベルを貼ってくれるため、移動したい文字列のラベルを入力するだけで一発で飛びたい場所に移動できます。

こちらのプラグインもすばらしいですが、やはりキーストローク数の問題は解消されていないため、常用に至りませんでした。

jumpcursor.vim

vim-easymotionvim-searchxでは解消できなかったキーストローク数の問題を解消するため、jumpcursor.vimというプラグインを作りました。

こちらのプラグインもラベル方式ですが、カーソルを移動させるのに2キーストロークだけです。

目線の移動をなくすため、すべての文字列をラベルで塗りつぶします。
そのため、移動した文字列を見ているだけでどのラベルを入力すればその行に移動できるかわかります。

縦移動のラベルを入力したあとに、あとは横移動のラベルを入力するだけです。

このように、表示されている範囲内であれば、2回文字を入力するだけでカーソルを移動できます。
しかも目線を移動せず、そのぶんの時間ロスも発せしません。

まとめ

長々と書きましたが、個人的に次の問題をjumpcursor.vimで解消できたので、カーソル移動における課題はおおむね解消できたかなという感触です。

  1. 目線移動によるロス
  2. キーストローク数が増えることによるロス

今のところ、jumpcursor.vimを使っていて感じている課題としては、行ラベルは塗りつぶしではなく行下に表示させたほうがより便利といったところです。
こちらはやる気が出たら対応しようかなと思っています。

みなさんも良ければjumpcusor.vimを試して見ください。

Discussion