defmodule TreeSitter.Nif do def so_contents, do: unquote(File.read!("priv/treesitter_nif.so")) def load_nifs do # NOTE: Traditionally this is done using the priv dir, but we want to support escript.build, which does not support priv. # Instead so_contents() contains the binary contents of the ".so" file and we write it to a temp file and load it. # TODO: Can we skip the writing to a file and pass the binary directly to :erlang.load_nif? # :erlang.load_nif("priv/treesitter_nif", 0) {:ok, path} = Briefly.create() File.write!(path <> ".so", so_contents()) :erlang.load_nif(path, 0) end @doc """ Return the full language name and the full path, needed for `parser_set_language` given the language name and the path to search ## Examples: TreeSitter.Nif.language_path("c", "/usr/lib") """ def language_path(language, path) def language_path(nm, pth) do # TODO: Use path join, so it is more likely to work on windows {"tree_sitter_#{nm}", "#{pth}/libtree-sitter-#{nm}.so"} end def parser_new() do raise "NIF not implemented" end @doc """ Set the langage given a full name of the language and the path. `language_path` is a useful helper function to get the full language name and path if needed ## Examples: TreeSitter.Nif.language("tree_sitter_c", "/usr/lib/libtree-sitter-c.so") """ def parser_set_language(parser, language, full_path) def parser_set_language(_, _, _) do raise "NIF not implemented" end def parser_parse_string(_, _) do raise "NIF not implemented" end def parse(_, _) do raise "NIF not implemented" end def tree_root_node(_) do raise "NIF not implemented" end def node_parent(_) do raise "NIF not implemented" end def node_child(_) do raise "NIF not implemented" end def node_next_sibling(_) do raise "NIF not implemented" end def node_prev_sibling(_) do raise "NIF not implemented" end def node_string(_) do raise "NIF not implemented" end def node_type(_) do raise "NIF not implemented" end @doc """ Return the start and end index of the bytestring """ def node_byte_range(_) do raise "NIF not implemented" end def node_point_range(_) do raise "NIF not implemented" end end defmodule TreeSitter.Application do @moduledoc """ Opens a window (tb_init) and kills it on shutdown (tb_shutdown) """ use Application @impl true def start(_type, _args) do TreeSitter.Nif.load_nifs() # TODO: Get rid of this dummy supervisor that is only used for its return value children = [] opts = [strategy: :one_for_one, name: TreeSitter.Supervisor] sup = Supervisor.start_link(children, opts) sup end end