必要な時のみ cursorline cursorcolumn する (denops.vim で!)

5 min read読了の目安(約4700字

https://github.com/vim-denops/denops.vim

たのしい!

ってことで、また作ってみました。

https://github.com/yukimemi/dps-autocursor

asciicast

Vim には cursorline cursorcolumn というオプションがあり、それぞれ、カーソルがある位置を示してくれる。
しかしながら、常時これを ON にしているとなかなか処理も重くなるし、見た目もうざったい。
そこで、必要なときのみ ON にするっていう方法が、 thinca さんの超有名な記事に記載されている。

https://thinca.hatenablog.com/entry/20090530/1243615055

これを少し変えて、 denops.vim 使ってかいてみた。

thinca さんの記事では、 WintEnter CursorHold などのイベント時に set cursorline 設定され、 CursorMoved などで set nocursorline されるが、どのイベント発生時に設定を X 秒ウェイトして設定する、しないというのを設定できるようにすればいいのでは?
と思い、以下の設計にしている。

例えば・・・

イベント名 ウェイト 設定
CursorHold 500 true
CursorMoved 0 false
WinEnter 0 true

こんな設定だと、

  • CursorHold 発生時

    500 ms 後に set cursorline

  • CursorMoved 発生時

    0 ms 後に set nocursorline

  • WinEnter 発生時

    0 ms 後に set cursorline

ということになる。

そしてこれは、 denops.vim だと setTimeout を使用してめちゃ簡単にかけるのでは?
と思い作成にいたりました。(実際簡単だった)

インストール

インストールは dein.vim だとこんな感じ。

  • dein.toml
[[plugins]]
repo = 'vim-denops/denops.vim'

[[plugins]]
repo = 'yukimemi/dps-autocursor'
hook_add = '''
" let g:autocursor_debug = v:true
let g:autocursor_cursorline = {
  \ "enable": v:true,
  \ "events": [
  \   {
  \     "name": "FocusGained",
  \     "set": v:true,
  \     "wait": 0,
  \   },
  \   {
  \     "name": "CursorHold",
  \     "set": v:true,
  \     "wait": 100,
  \   },
  \   {
  \     "name": "TextYankPost",
  \     "set": v:true,
  \     "wait": 0,
  \   },
  \   {
  \     "name": "CursorMoved",
  \     "set": v:false,
  \     "wait": 500,
  \   }
  \  ]
  \ }
let g:autocursor_cursorcolumn = {
  \ "enable": v:true,
  \ "events": [
  \   {
  \     "name": "FocusGained",
  \     "set": v:true,
  \     "wait": 0,
  \   },
  \   {
  \     "name": "CursorHold",
  \     "set": v:true,
  \     "wait": 200,
  \   },
  \   {
  \     "name": "TextYankPost",
  \     "set": v:true,
  \     "wait": 0,
  \   },
  \   {
  \     "name": "CursorMoved",
  \     "set": v:false,
  \     "wait": 500,
  \   }
  \  ]
  \ }

hook_add の設定はなくても問題ない。
依存として、 denops.vim が必要。(もちろん Deno も。)

hook_add に記載があるように、 cursorline, cursorcolumn それぞれでどのタイミングで設定をする、しないを定義することができる。

let g:autocursor_cursorline = {
  \ "enable": v:true,            // cursorline 設定をするかどうか。
  \ "events": [                  // (cursorline だけ設定して cursorcolumn は設定したくない、等の場合に設定する)
  \   {
  \     "name": "CursorMoved",   // 設定するイベント名
  \     "set": v:false,          // cursorline or nocursorline
  \     "wait": 500,             // 設定するまでのウェイト時間 (ms)
  \   }
  \  ]
  \ }

デフォルトだと以下の設定になっている。

  • cursorline
イベント名 ウェイト 設定
CursorHold 500 true
CursorHoldI 500 true
WinEnter 0 true
BufEnter 0 true
CmdwinLeave 0 true
CursorMoved 0 false
CursorMovedI 0 false
  • cursorcolumn
イベント名 ウェイト 設定
CursorHold 500 true
CursorHoldI 500 true
WinEnter 0 true
BufEnter 0 true
CmdwinLeave 0 true
CursorMoved 0 false
CursorMovedI 0 false

上書きしたい場合は、先程の hook_add 記載のように設定を行う。
例えば上記の設定だと、 cursorlinecursorhold で別の wait を設定しているので CursorHold イベント時 100ms 後に cursorline200ms 後に set cursorcolumn となる。
グランドクロス!!
みたいな感じでかっこいい!(よくわからん)

また、解除も 500ms ウェイトを設けているので、 CursorMoved イベント発生ですぐ消えるのではなく動かすとしばらくしてから cursorline cursorcolumn 消えるっていう面白い動きなる。

コマンド

コマンドとして設定、解除するのを設けている。

:EnableAutoCursorLine    " cursorline 設定を有効化
:EnableAutoCursorColumn  " cursorcolumn 設定を有効化
:DisableAutoCursorLine   " cursorline 設定を無効化
:DisableAutoCursorColumn " cursorcolumn 設定を無効化

参考