🌳

tree-sitter-cli を入れてみた。

2024/08/31に公開

特に何かの役に立ったわけではなく、なんとなくおもしろそうだったので手順まとめ。

インストール

$ cargo install tree-sitter-cli
or
$ npm install tree-sitter-cli

その後、以下コマンドで設定ファイルを生成します。

$ tree-sitter init-config

設定ファイルは、~/.config/tree-sitter/config.json に生成されます。

参考

言語の追加

フォルダの作成・定義

まず、上記で生成した設定ファイルの parser-directories を確認します。
追加する言語のリポジトリを落とすフォルダになるので、
わかりやすく tree-sitter 用のフォルダ(ここでは ~/_tree-sitter)を作成して追記します。

~/.config/tree-sitter/config.json
{
  "parser-directories": [
    "/home/<your_name>/github",
    "/home/<your_name>/src",
    "/home/<your_name>/source",
    "/home/<your_name>/projects",
    "/home/<your_name>/dev",
    "/home/<your_name>/git",
    "/home/<your_name>/_tree-sitter" // ←追加
  ],
(略)

クローン

上記フォルダに移動して、各言語の tree-sitter 用の定義リポジトリをクローンします。
(ここではRubyを追加。 https://github.com/tree-sitter/tree-sitter-ruby)

$ cd ~/_tree-sitter
$ git clone --depth 1 git@github.com:tree-sitter/tree-sitter-ruby.git

コマンド

test.rb
# Test
class Foo
  attr_accessor :bar

  def initialize
    self.bar = 0
  end
end

上記のようなファイルがあった場合

$ tree-sitter parse file

パース結果の出力

$ tree-sitter parse test.rb
(program [0, 0] - [8, 0]
  (comment [0, 0] - [0, 6])
  (class [1, 0] - [7, 3]
    name: (constant [1, 6] - [1, 9])
    body: (body_statement [2, 2] - [6, 5]
      (call [2, 2] - [2, 20]
        method: (identifier [2, 2] - [2, 15])
        arguments: (argument_list [2, 16] - [2, 20]
          (simple_symbol [2, 16] - [2, 20])))
      (method [4, 2] - [6, 5]
        name: (identifier [4, 6] - [4, 16])
        body: (body_statement [5, 4] - [5, 16]
          (assignment [5, 4] - [5, 16]
            left: (call [5, 4] - [5, 12]
              receiver: (self [5, 4] - [5, 8])
              method: (identifier [5, 9] - [5, 12]))
            right: (integer [5, 15] - [5, 16])))))))

$ tree-sitter tags file

ソースコードに対応した情報の出力

$ tree-sitter tags test.rb
Foo              | class        def (1, 6) - (1, 9) `class Foo`    "Test"
attr_accessor    | call         ref (2, 2) - (2, 15) `attr_accessor :bar`
initialize       | method       def (4, 6) - (4, 16) `def initialize`
bar              | call         ref (5, 9) - (5, 12) `self.bar = 0`

$ tree-sitter highlight file

ハイライト結果の出力
色は設定ファイル(~/.config/tree-sitter/config.json)で設定するようです。
highlight

$ tree-sitter highlight test.rb --html

<!doctype HTML>
<head>
  <title>Tree-sitter Highlighting</title>
  <style>
    body {
      font-family: monospace
    }
    .line-number {
      user-select: none;
      text-align: right;
      color: rgba(27,31,35,.3);
      padding: 0 10px;
    }
    .line {
      white-space: pre;
    }
  </style>
</head>
<body>

<table>
<tr><td class=line-number>1</td><td class=line><span style='font-style: italic;color: #8a8a8a'># Test</span>
</td></tr>
<tr><td class=line-number>2</td><td class=line><span style='color: #5f00d7'>class</span> <span style='color: #af8700'>Foo</span>
</td></tr>
<tr><td class=line-number>3</td><td class=line>  <span style='color: #005fd7'>attr_accessor</span> <span style='color: #008787'>:bar</span>
</td></tr>
<tr><td class=line-number>4</td><td class=line>
</td></tr>
<tr><td class=line-number>5</td><td class=line>  <span style='color: #5f00d7'>def</span> <span style='color: #005fd7'>initialize</span>
</td></tr>
<tr><td class=line-number>6</td><td class=line>    <span style='font-weight: bold;'>self</span><span style='color: #4e4e4e'>.</span><span style='color: #005fd7'>bar</span> <span style='font-weight: bold;color: #4e4e4e'>=</span> <span style='font-weight: bold;color: #875f00'>0</span>  
</td></tr>
<tr><td class=line-number>7</td><td class=line>  <span style='color: #5f00d7'>end</span>       
</td></tr>
<tr><td class=line-number>8</td><td class=line><span style='color: #5f00d7'>end</span>
</td></tr>
</table>

</body>

何かに使えそうな気がしましたが、いまのところは思いつかず。
とりあえずのまとめでした。

以上

Discussion