denopsでVimのGhostTextプラグインを実装した
追記(2021/09/06)
WIP外しました。
本文
お久し振りです。
前回はジョークプラグインでお茶を濁しましたが、今回はしっかりプラグインを作ってきました。
denopsでGhostTextを実装したものになります。
GhostTextとは
WebSocketを用いてブラウザ上のテキストエリアを任意のテキストエディタで編集するブラウザ向け拡張機能(とそのプロトコル)です。
VSCodeを始めとしてAtomやEmacs、もちろんVimにもGhostTextを実装した拡張機能が存在します。
動機
そんな便利なGhostTextですが、現在確認できるVim向けのGhostText実装はPython(pynvim)を利用したものしかありません。
別にPythonを使うのが悪いという訳ではないのですが、やはりPythonのライブラリをわざわざ入れるのは面倒という層も存在するかと思います。
(ちなみに僕のNeovimは少しだけdark poweredなのでpynvimも入ってます)
そこで、denoランタイムさえ入っていれば依存を考える事なく使えるdenopsでGhostTextを実装する事にしました。
実装
GhostTextはWebSocketを利用するので、サーバを実装する必要があります。
ここではWebSocket及びネゴシエーションで使用するhttpサーバに servestを利用する事にしました。(この為だけにservestにPR出したりした) 今はDenoのビルトインAPI使ってます。(2021/09/06追記)
~実はここでWebSocket用のポートをランダムに確保してあげる必要があるのですが、そのfallback的な実装がめんどくさくて後回しになってます。(なのでうっかりするとすぐ例外吐いて死ぬ)~
ちゃんとランダム確保するようにしました。(2021/09/06追記)
後はいい感じにバッファ番号とソケットをプラグイン内で管理しつつ、autocmdでよしなにpushしてあげてます。
GhostTextの規格上では選択範囲もやり取りするようですが、まだ実装できてないです。(一応動くのでまあヨシ!)
URL(ドメイン名)とファイルタイプの対応は g:dps_ghosttext#ftmap
で管理してます。
let g:dps_ghosttext#ftmap["qiita.com"] = "markdown"
↑こんな感じ。(デフォルトではgithub.comとmarkdownが紐付いてます)
実際に使う時は :GhostStart
でサーバを起動します。
g:dps_ghosttext#enable_autostart
を v:true
にすれば自動で起動するようにもできます。(最初に起動したVimのみ)
課題
- 複数セッションの扱いなど、まだまだバグの温床になってる感じがある(Issue/PR歓迎)
- 選択範囲の扱いなど、まだまだGhostTextの規格的には足りてないものが多いかも(今のところは困ってないので気にしてない)
- そもそもどこまでがGhostTextの規格上必要なものなのか分からないのでちゃんと調べる必要がある
まとめ
とりあえず課題まみれなので本気で実用するならもう少し手を加える必要があります。 とりあえず動きそうな気配はするのでWIP外しました(2021/09/06追記)
Issue・PRお待ちしております。
Discussion