ハイパーマッスルエンジニア

Vim、ShellScriptについてよく書く

Neovim: VirtualTextを使ってVim上に注釈を出す

VirtualTextとは

NeoVim 3.2で導入された注釈機能。行の最後にバッファとは別にテキストを表示することができる。

https://camo.githubusercontent.com/de52369c7356b9121f6983fd574c329470836e28/687474703a2f2f692e696d6775722e636f6d2f384167726449332e676966

github.com

使い方

nvim_buf_set_virtual_text({buffer}, {ns_id}, {line}, {chunks}, {opts})
Column Column
buffer Buffer番号、カレントバッファなら0を指定
ns_id NamespaceId、任意の数値または0を指定すると適当に割り振られる。nvim_create_namespace()で作るのがベター。
line VirtualTextを出したい行
chunks VirtualTextに出したい文字列とハイライトグループをセットにした配列
opts 現在使われていない

とりあえず試してみる。

" VirtualTextを作成
:let ns_id = nvim_buf_set_virtual_text(0, 0, 0, [['Hello World']], {})

" 作成したVirtualTextを消す
:call nvim_buf_clear_namespace(0, ns_id, 0, -1)

f:id:rasukarusan:20210111174045p:plain
画像では伝わりづらいが"Hello World"の部分がVirtualText

ちゃんと書くとこんな感じ。

" カレントバッファの現在行にVirtualTextを作成
let line = line('.')
let buffer = bufnr('')
" ns_idは重複等避けるためnvim_create_namespace()で作成
let ns_id = nvim_create_namespace('my-virtual')

call nvim_buf_set_virtual_text(buffer, ns_id, line-1, [['Hello World']], {})

色を付ける、ハイライトグループを指定。

ハイライトグループの一覧はこちらが参考になる。

" ハイライトグループである'ErrorMsg'を指定
call nvim_buf_set_virtual_text(buffer, ns_id, line-1, [['Hello World', 'ErrorMsg']], {})

f:id:rasukarusan:20210111174523p:plain
'ErrorMsg'の色になる

自分で作成したハイライトグループも指定可能。

hi Hoge guibg=#123456
call nvim_buf_set_virtual_text(buffer, ns_id, line-1, [['Hello World', 'Hoge']], {})

f:id:rasukarusan:20210111174705p:plain
自分で作成したグループの色(#123456)になる

複数のテキストを表示する。

call nvim_buf_set_virtual_text(buffer, ns_id, line-1, [['Hello', 'ErrorMsg'], ['World', 'Hoge']], {})

f:id:rasukarusan:20210111174850p:plain
'Hello'と'World'で別のハイライトを指定

VirtualTextの使いみち

Syntaxチェック

https://github.com/Rasukarusan/blog-assets/blob/master/nvim-virtual-text/ale.gif?raw=true
ale + textlintでシンタックスエラーをリアルタイムに表示
github.com

オプションであるg:ale_virtualtext_cursor1にするとVirtualTextが有効になる。

" VirtualTextを有効にする
let g:ale_virtualtext_cursor = 1
" prefixの文字列
let g:ale_virtualtext_prefix = ' --> '

カーソルを合わせるだけでどんなエラーが出ているのかわかるので便利っちゃ便利。

カラーコード表示

https://camo.githubusercontent.com/cfc61743d38e4e166546d004d07bf9cc853d72a282f2c19a56576f0f030bb7bc/68747470733a2f2f6d656469612e67697068792e636f6d2f6d656469612f50696b5169616b6a324e597846446d63646c2f67697068792e676966
カラーコードを視覚的に表示

github.com

カラーコードのビジュアルをVirtualTextとして表示する。これはめっちゃいい。

VirtualTextの特徴

  • EOL(行の最後)に表示される
  • テキストの折返しはされず、途中で見切れる
  • Bufferではないので:ls!には残らない

なので長文は適しておらず、行によってはVirtualTextが表示できない可能性もある。
行の最後に表示されるので、フォーマットが決まっている場合や、色表示のようにピンポイントで表示するようなことに適している感じ。

ただFloatingWindowとは違い、Bufferではないので複数表示させたとしても動作が重くならない点は利点。

https://github.com/Rasukarusan/blog-assets/blob/master/nvim-virtual-text/floatingWindow_vs_virtualText.gif?raw=true
左:VirtualText、右:FloatingWindow。どちらも同じタイミングで作成/削除を行った。VirtualTextは作成も削除も一瞬。

終わり

今の所どうやって使うかはあまり思い浮かばないけど、ピンポイントで使う場面がありそう。
使い方が簡単なのもいい。リアルタイム翻訳とかに使うとビジュアル的に良さそう。