GitHubのシンタックスハイライトを直した話

GitHubは自動でシンタックスハイライトがされるが、言語仕様が今も変わっていくような言語(大体の使われている言語はそうだ。Goのように意図的に固定している例外を除いて)ではたまにそれが古いままで、公式ページのハイライトがおかしいことがある。

TOMLがその良い例で、TOML v0.5.0で追加された一部の機能が真っ赤にハイライトされていた。例えば、dotted keys(キーを繋いで階層構造を作る)や整数プレフィックス0x0bなど)、特殊な浮動小数点数infnan)などだ。

ところで私は既にv0.5.0対応のTOMLライブラリを一つ書いており(toml11は書き換え中)、それを使ったツールのサンプルが真っ赤になるのは悲しかった。

github.com

なので直したいと思い立ち、調べてみることにした。有名エンジニアである犬さんのブログが真っ先に引っかかる。

rhysd.hatenablog.com

これによると、GitHubシンタックスハイライトは以下のレポジトリによって行われている。

github.com

このレポジトリはエディタ用の文法定義を再利用するようになっている。TextMateAtomSublimeや……といったエディタの設定ファイルをメンテしているレポジトリを覚えておいて、数週間かおきにpullしてきてアップデートしつつ使うというようになっている。それぞれのシンタックス定義は別レポジトリになっているので、linguist自体にPRが山ほど飛んでくるという事態を避けることができる。

このディレクトリにそのモジュールの一覧がある。

linguist/vendor at master · github/linguist · GitHub

ここから直したいレポジトリに飛んで、そこにPRを投げればいいわけだ。今回はTOMLなので、TextMateなるエディタの設定ファイルを編集することになる。

github.com

ところで私はTextMateというものを使ったことがない。ちらりとTOML用のレポジトリの中身を見てみたが、正規表現でマッチした部分に名前を付け、名前によってハイライトしていくものであるようだ。XMLで書かれているので読めないこともないが、つらい。

動作確認のこともあり、TextMateが必要だろうと思った。まず、ググるmacOS用のエディタだということがわかる。私はWindowsマシンは持っていないがmacは持っているので、インストールできた。

TextMate: Text editor for macOS

上のメニューからバンドルを開いて追加すればよいと書かれているのでやってみる。ちなみにやったのが数週間前(後述するがPRが閉じられるまでそれくらいかかった)なのでよく覚えていない。

インストール後、TextMateの Bundles > Edit Bundles > TOML > Language Grammers > TOML と開いていくと、別ウインドウでシンタックスの定義ファイルを編集しながら結果を見ることができるではないか。しかもXMLではなくJSONっぽい(けど少し違う)形式を使っているので、より目にやさしい。Ctrl-Sを押すごとにハイライトが更新されるので、保存のタイミングでこの形式からXMLに変換しているのだろう。実際、Applications/みたいなディレクトリにXML形式のファイルがある。

さて、書き方はわかったが、次は何を編集したらどういう影響が出るのか調べねばならない。以下は試しながらの憶測だったが、まあ多少の編集を経たとはいえマージされたので大外しはしていなかったのだろう。上記のようにして開くと以下のような設定が見える。以下のコードは(TextMateによる変換を経たとはいえ)https://github.com/textmate/toml.tmbundleからの引用になる。

patterns = (
    {   begin = ‘([A-Za-z0-9_-]+)\s*(=)\s*‘;
        end = ‘(?<=\S)(?<!=)|$’;
        captures = {
            1 = { name = ‘variable.other.key.toml’; };
            2 = { name = ‘punctuation.separator.key-value.toml’; };
        };
        patterns = ( { include = ‘#primatives’; } );
    })

ここでbeginend正規表現がある。これらによって囲まれた領域にマッチするものと思われる。基本重要な部分は大抵beginに書いてあったのでそこをいじった。で、そのグループの登場順序によって番号が振られ、capturesの中の番号に対応する名前を書いておくと、その名前としてハイライトされるようである。多分、カラースキームのようなものが別にあって、実際の色はそちらで構文要素の名前から決められるのだろう。この例では、bare-keyに対応する1つめのグループ([A-Za-z0-9_-]+)variable.other.key.tomlという名前が割り振られ、次のグループ=punctuation.separator.key-value.tomlなる名前がついている。

つまり、正規表現を拡張して新機能にマッチするようにして、グループ毎の名前を適切につければよいわけだ。そのような方針で編集して動くことを確認し、内容をPRにまとめて送りつけた。以下がそれだ。

allow dotted keys by ToruNiina · Pull Request #9 · textmate/toml.tmbundle · GitHub

allow nan, inf, hex, oct, bin values by ToruNiina · Pull Request #10 · textmate/toml.tmbundle · GitHub

数週間ほど放置されていて少しやきもきしたが、今日晴れてマージされた。いや正確にはマージされたというより、いくらかの編集を経てコミットが追加され、クローズされた。

追加された変更は、例えば数値にマッチする正規表現が長すぎたので分割する(最初は整数と浮動小数点数が同じくくりでマッチされていたので、そういう方針なのかと思って尊重していたのだが、単に短いから構わないという扱いだったのだろうか)とか、ハイライト時の分類を直すとか(ここは純粋にどうするべきかわかっていなかった)、いくつかのエッジケースを直す(ありがたい)などだった。

というわけで、しばらくすればGitHubのハイライトも修正されるだろう。今までもそれなりに使ってもらえるツールは作っていたが、これまでとは比べ物にならない規模の人数が目撃するソフトウェアの端っこに自分の小さな爪痕を残したというのは、結構気分がいいものだ。

これでtoml.tmbundleのレポジトリのコントリビュータは3人になった。プライマリ作者と、TOMLそのものの作者Tom Preston-Werner(@mojombo)と、私である。ヤバい人々でビビるが、それ故に嬉しさもひとしおというところだ。

みなさんもGitHubのハイライトに不満があれば、PRを投げつけてみてはいかがだろうか。