pockestrap

Web Programmer's memo

VimConf 2017 で Syntax highlighter の話をした

speakerdeck.com

また、作成に使っていたGoogle Slidesへのリンクはこちら。 The new syntax highlighter for Vim - VimConf2017 - Google スライド ボツになったスライドとか、メモとかが見れます。

何を話したのか

私が作っている、新しいVimのSyntax HighlighterであるIro.vimについて話しました。

Iro.vimは従来のSyntax Highlighterとは違い、ハイライトに言語が提供するパーサーを使用します。 例えばRubyにはRipperというパーサが提供されていますが、Iro.vimはRipperを使用してパースを行います。 これにより正規表現を用いてsyntax定義を行ったのとは違い、完璧なハイライトを行うことが出来るようになっています。

補足

Iro.vimは実はtodesking/ruby_hl_lvar.vimにinspireされて(というかこれをベースに)作った、という話を入れ忘れていました。 ruby_hl_lvar.vimは本当によいプラグインで、Iro.vimはこれをlvarだけではなく全てに押し広げたものになっています。

時間の都合上削ってしまったけど、Vimにはじめてパッチを投げてmergeされたよ!みたいな話もするつもりでした。https://github.com/vim/vim/pull/2143

またこれも時間の都合上削ってしまったけど、Vimには「1行が長い場合」以外にも、「パースしている場所のcontextが上の方の行によって変化する場合」などでもハイライトがぶっ壊れます。こちらの問題の方が体感したことがある人が多いかも知れないです。
わかりやすい例として、HTML内のscriptタグや、markdown内のcode blockなどが挙げられます。Vimは「現在の行がHTMLかJavaScriptか」を判定する際にある程度行を巻き戻って判定を行うのですが、これを行う際にファイルの先頭まで巻き戻っていてはパフォーマンスが厳しくなるので、一定行で諦めます。 そのため、大きいscriptタグがあると、それがJavaScriptだと判定されずハイライトがうまく動かない、といった現象が発生します。

懇親会で@onkさんから「SQLMarkdownもあるとよいよねー」みたいな話がありました。 Markdownはめっちゃやりたいのだけど、何のパーサーを使うか問題が大きくて大変そう……。markdownが出来ると、その中のcode blockはまたその言語でハイライトする、といったことが可能となりめちゃくちゃ便利そう。

パフォーマンス問題はmatchaddpos()しまくると遅い、というのが多分正解。 これについてはIro.vim側で「画面内のみmatchaddpos()を発行して、CursorMovedとかで適当にrefreshする」といった戦略で行こうかなーと思っていました。 ですが、よくよく考えるとそんなことをIro.vimが実装しなくてもVim本体がmatchaddpos()されたハイライトを賢く管理すべきでは、と思い直しました(が、Vimのコードわからないので難易度は高い……)。 まあ現状1,000行程度であれば快適に使えて、10,000行となると死ぬ〜〜〜😇といった状態なので、すぐに問題に着手するほど差し迫ってはいませんが、そのうちなんとかしたいと思っています。

またIro.vimの現状ですが、現状自分の環境ではRubyYAMLは常に有効になっています。私はRubyが母国語であるため、これはつまりRubyに関しては実用に耐えうるという話です。 Pythonも実装されていますが、これは私自信がPythonに詳しくないのと、tokenizeした結果だけだといい感じのハイライトが出来るだけのメタデータはなかったのとでまだ実用的とは言えない状態だと思います。

また、懇親会で「Ruby 2.5からはtokenizeした結果にlex_stateがのってくる」という便利情報をいただきました。 これを使うとS式を取るまでやらなくてもより楽にhighlightの情報を作ることが出来そうです。 またRDoc内では便利ラッパーが存在しているらしい。便利そう。

感想

VimConf前からTwitterで「これはIro.vim案件では」と思うような発言を観測したり、VimConf当日も「この話題今日これから話すことだ…!」となるような話が私の発表とは無関係のところから上がっていて、ちょうど面白い情報を提供出来たのではないかなーと思っています。

あと、今までは気がついていなかったのですが、実はLSPを使うと似たようなことが出来るのでは?と思ったりしています。どうなんだろう。

最後に。とても楽しいVimConfを運営して頂いたスタッフの方々には本当に感謝しています。来年も楽しみにしています…!!!