Current section
6 Versions
Jump to
Current section
6 Versions
Compare versions
4
files changed
+145
additions
-27
deletions
| @@ -2,14 +2,14 @@ | |
| 2 2 | [{<<"issues">>,<<"https://codeberg.org/edwinvanl/treesitter_elixir/issues">>}, |
| 3 3 | {<<"source">>,<<"https://codeberg.org/edwinvanl/treesitter_elixir">>}]}. |
| 4 4 | {<<"name">>,<<"treesitter_elixir">>}. |
| 5 | - {<<"version">>,<<"0.1.4">>}. |
| 5 | + {<<"version">>,<<"0.1.6">>}. |
| 6 6 | {<<"description">>, |
| 7 7 | <<"Tree-sitter bindings (nif) for elixir. Currently small subset of the tree-sitter api is supported, but happy to accept merge requests/patches">>}. |
| 8 8 | {<<"elixir">>,<<"~> 1.18">>}. |
| 9 9 | {<<"app">>,<<"treesitter_elixir">>}. |
| 10 10 | {<<"files">>, |
| 11 | - [<<"lib">>,<<"lib/treesitter">>,<<"lib/treesitter/node.ex">>, |
| 12 | - <<"lib/treesitter/querycursor.ex">>,<<"lib/treesitter.ex">>, |
| 11 | + [<<"lib">>,<<"lib/treesitter.ex">>,<<"lib/treesitter">>, |
| 12 | + <<"lib/treesitter/querycursor.ex">>,<<"lib/treesitter/node.ex">>, |
| 13 13 | <<".formatter.exs">>,<<"mix.exs">>,<<"README.md">>,<<"LICENSE">>,<<"src">>, |
| 14 14 | <<"src/treesitter_nif.c">>,<<"Makefile">>]}. |
| 15 15 | {<<"licenses">>,[<<"MIT">>]}. |
| @@ -78,6 +78,14 @@ defmodule TreeSitter.Nif do | |
| 78 78 | :erlang.nif_error(:nif_not_loaded) |
| 79 79 | end |
| 80 80 | |
| 81 | + def node_descendant_for_byte_range(_, _, _) do |
| 82 | + :erlang.nif_error(:nif_not_loaded) |
| 83 | + end |
| 84 | + |
| 85 | + def node_descendant_for_point_range(_, _, _) do |
| 86 | + :erlang.nif_error(:nif_not_loaded) |
| 87 | + end |
| 88 | + |
| 81 89 | def node_string(_) do |
| 82 90 | :erlang.nif_error(:nif_not_loaded) |
| 83 91 | end |
| @@ -139,6 +147,18 @@ defmodule TreeSitter.Nif do | |
| 139 147 | def query_cursor_set_byte_range(_, _, _) do |
| 140 148 | :erlang.nif_error(:nif_not_loaded) |
| 141 149 | end |
| 150 | + |
| 151 | + def query_cursor_set_containing_point_range(query, from, to) |
| 152 | + |
| 153 | + def query_cursor_set_containing_point_range(_, _, _) do |
| 154 | + :erlang.nif_error(:nif_not_loaded) |
| 155 | + end |
| 156 | + |
| 157 | + def query_cursor_set_containing_byte_range(query, from, to) |
| 158 | + |
| 159 | + def query_cursor_set_containing_byte_range(_, _, _) do |
| 160 | + :erlang.nif_error(:nif_not_loaded) |
| 161 | + end |
| 142 162 | end |
| 143 163 | |
| 144 164 | defmodule TreeSitter.Application do |
| @@ -6,7 +6,7 @@ defmodule Treesitter.MixProject do | |
| 6 6 | app: :treesitter_elixir, |
| 7 7 | description: |
| 8 8 | "Tree-sitter bindings (nif) for elixir. Currently small subset of the tree-sitter api is supported, but happy to accept merge requests/patches", |
| 9 | - version: "0.1.4", |
| 9 | + version: "0.1.6", |
| 10 10 | elixir: "~> 1.18", |
| 11 11 | compilers: [:elixir_make] ++ Mix.compilers(), |
| 12 12 | start_permanent: Mix.env() == :prod, |
| @@ -121,6 +121,28 @@ ERL_NIF_TERM to_ok_term(ErlNifEnv *env, ERL_NIF_TERM value) { | |
| 121 121 | return enif_make_tuple2(env, enif_make_atom(env, "ok"), value); |
| 122 122 | } |
| 123 123 | |
| 124 | + TSPoint point_from_map(ErlNifEnv *env, ERL_NIF_TERM map) { |
| 125 | + TSPoint pt; |
| 126 | + ERL_NIF_TERM row_term, column_term; |
| 127 | + |
| 128 | + // Get the row and column terms from the map |
| 129 | + if (!enif_get_map_value(env, map, enif_make_atom(env, "row"), &row_term) || |
| 130 | + !enif_get_map_value(env, map, enif_make_atom(env, "column"), |
| 131 | + &column_term)) { |
| 132 | + // TODO: Handle error: keys not found in the map |
| 133 | + // You might want to return a default value or raise an error |
| 134 | + pt.row = 0; |
| 135 | + pt.column = 0; |
| 136 | + return pt; |
| 137 | + } |
| 138 | + |
| 139 | + // Get the integer values from the terms |
| 140 | + enif_get_uint(env, row_term, &pt.row); |
| 141 | + enif_get_uint(env, column_term, &pt.column); |
| 142 | + |
| 143 | + return pt; |
| 144 | + } |
| 145 | + |
| 124 146 | static ERL_NIF_TERM parser_new(ErlNifEnv *env, int argc, |
| 125 147 | const ERL_NIF_TERM argv[]) { |
| 126 148 | WRParser *wrap = enif_alloc_resource(parser_resource_type, sizeof(WRParser)); |
| @@ -252,6 +274,59 @@ static ERL_NIF_TERM node_child(ErlNifEnv *env, int argc, | |
| 252 274 | } |
| 253 275 | } |
| 254 276 | |
| 277 | + /** |
| 278 | + * Get the smallest node within this node that spans the given range of bytes |
| 279 | + * or (row, column) positions. |
| 280 | + */ |
| 281 | + static ERL_NIF_TERM node_descendant_for_byte_range(ErlNifEnv *env, int argc, |
| 282 | + const ERL_NIF_TERM argv[]) { |
| 283 | + WRNode *wrap; |
| 284 | + if (!enif_get_resource(env, argv[0], node_resource_type, (void **)&wrap)) { |
| 285 | + return to_error_string(env, "Unable to unwrap node"); |
| 286 | + } |
| 287 | + |
| 288 | + uint32_t start_byte; |
| 289 | + uint32_t end_byte; |
| 290 | + enif_get_uint(env, argv[1], &start_byte); |
| 291 | + enif_get_uint(env, argv[2], &end_byte); |
| 292 | + |
| 293 | + TSNode node = |
| 294 | + ts_node_descendant_for_byte_range(wrap->data, start_byte, end_byte); |
| 295 | + |
| 296 | + if (ts_node_is_null(node)) { |
| 297 | + return to_error_nil(env); |
| 298 | + } else { |
| 299 | + WRNode *wrapnode = enif_alloc_resource(node_resource_type, sizeof(WRNode)); |
| 300 | + wrapnode->data = node; |
| 301 | + return to_ok_term(env, enif_make_resource(env, wrapnode)); |
| 302 | + } |
| 303 | + } |
| 304 | + |
| 305 | + /** |
| 306 | + * Get the smallest node within this node that spans the given range of bytes |
| 307 | + * or (row, column) positions. |
| 308 | + */ |
| 309 | + static ERL_NIF_TERM node_descendant_for_point_range(ErlNifEnv *env, int argc, |
| 310 | + const ERL_NIF_TERM argv[]) { |
| 311 | + WRNode *wrap; |
| 312 | + if (!enif_get_resource(env, argv[0], node_resource_type, (void **)&wrap)) { |
| 313 | + return to_error_string(env, "Unable to unwrap node"); |
| 314 | + } |
| 315 | + |
| 316 | + TSPoint start_point = point_from_map(env, argv[1]); |
| 317 | + TSPoint end_point = point_from_map(env, argv[2]); |
| 318 | + |
| 319 | + TSNode node = |
| 320 | + ts_node_descendant_for_point_range(wrap->data, start_point, end_point); |
| 321 | + |
| 322 | + if (ts_node_is_null(node)) { |
| 323 | + return to_error_nil(env); |
| 324 | + } else { |
| 325 | + WRNode *wrapnode = enif_alloc_resource(node_resource_type, sizeof(WRNode)); |
| 326 | + wrapnode->data = node; |
| 327 | + return to_ok_term(env, enif_make_resource(env, wrapnode)); |
| 328 | + } |
| 329 | + } |
| 255 330 | static ERL_NIF_TERM node_next_sibling(ErlNifEnv *env, int argc, |
| 256 331 | const ERL_NIF_TERM argv[]) { |
| 257 332 | WRNode *wrap; |
| @@ -337,28 +412,6 @@ ERL_NIF_TERM point_to_map(ErlNifEnv *env, TSPoint point) { | |
| 337 412 | return map; |
| 338 413 | } |
| 339 414 | |
| 340 | - TSPoint point_from_map(ErlNifEnv *env, ERL_NIF_TERM map) { |
| 341 | - TSPoint pt; |
| 342 | - ERL_NIF_TERM row_term, column_term; |
| 343 | - |
| 344 | - // Get the row and column terms from the map |
| 345 | - if (!enif_get_map_value(env, map, enif_make_atom(env, "row"), &row_term) || |
| 346 | - !enif_get_map_value(env, map, enif_make_atom(env, "column"), |
| 347 | - &column_term)) { |
| 348 | - // TODO: Handle error: keys not found in the map |
| 349 | - // You might want to return a default value or raise an error |
| 350 | - pt.row = 0; |
| 351 | - pt.column = 0; |
| 352 | - return pt; |
| 353 | - } |
| 354 | - |
| 355 | - // Get the integer values from the terms |
| 356 | - enif_get_uint(env, row_term, &pt.row); |
| 357 | - enif_get_uint(env, column_term, &pt.column); |
| 358 | - |
| 359 | - return pt; |
| 360 | - } |
| 361 | - |
| 362 415 | static ERL_NIF_TERM node_point_range(ErlNifEnv *env, int argc, |
| 363 416 | const ERL_NIF_TERM argv[]) { |
| 364 417 | WRNode *wrap; |
| @@ -557,6 +610,45 @@ static ERL_NIF_TERM query_cursor_set_byte_range(ErlNifEnv *env, int argc, | |
| 557 610 | } |
| 558 611 | } |
| 559 612 | |
| 613 | + static ERL_NIF_TERM |
| 614 | + query_cursor_set_containing_point_range(ErlNifEnv *env, int argc, |
| 615 | + const ERL_NIF_TERM argv[]) { |
| 616 | + WRQueryCursor *querycursor_wrap; |
| 617 | + if (!enif_get_resource(env, argv[0], querycursor_resource_type, |
| 618 | + (void **)&querycursor_wrap)) { |
| 619 | + return to_error_string(env, "Unable to unwrap querycursor"); |
| 620 | + } |
| 621 | + TSPoint start_point = point_from_map(env, argv[1]); |
| 622 | + TSPoint end_point = point_from_map(env, argv[2]); |
| 623 | + if (ts_query_cursor_set_containing_point_range(querycursor_wrap->data, |
| 624 | + start_point, end_point)) { |
| 625 | + return enif_make_atom(env, "ok"); |
| 626 | + } else { |
| 627 | + return to_error_string(env, "Invalid range"); |
| 628 | + } |
| 629 | + } |
| 630 | + |
| 631 | + static ERL_NIF_TERM |
| 632 | + query_cursor_set_containing_byte_range(ErlNifEnv *env, int argc, |
| 633 | + const ERL_NIF_TERM argv[]) { |
| 634 | + WRQueryCursor *querycursor_wrap; |
| 635 | + if (!enif_get_resource(env, argv[0], querycursor_resource_type, |
| 636 | + (void **)&querycursor_wrap)) { |
| 637 | + return to_error_string(env, "Unable to unwrap querycursor"); |
| 638 | + } |
| 639 | + |
| 640 | + uint32_t start_byte; |
| 641 | + uint32_t end_byte; |
| 642 | + enif_get_uint(env, argv[1], &start_byte); |
| 643 | + enif_get_uint(env, argv[2], &end_byte); |
| 644 | + if (ts_query_cursor_set_containing_byte_range(querycursor_wrap->data, |
| 645 | + start_byte, end_byte)) { |
| 646 | + return enif_make_atom(env, "ok"); |
| 647 | + } else { |
| 648 | + return to_error_string(env, "Invalid range"); |
| 649 | + } |
| 650 | + } |
| 651 | + |
| 560 652 | static ErlNifFunc nif_funcs[] = { |
| 561 653 | {"parser_new", 0, parser_new, 0}, |
| 562 654 | {"language", 2, language, 0}, |
| @@ -567,6 +659,8 @@ static ErlNifFunc nif_funcs[] = { | |
| 567 659 | {"node_child", 1, node_child, 0}, |
| 568 660 | {"node_next_sibling", 1, node_next_sibling, 0}, |
| 569 661 | {"node_prev_sibling", 1, node_prev_sibling, 0}, |
| 662 | + {"node_descendant_for_byte_range", 3, node_descendant_for_byte_range, 0}, |
| 663 | + {"node_descendant_for_point_range", 3, node_descendant_for_point_range, 0}, |
| 570 664 | {"node_string", 1, node_string, 0}, |
| 571 665 | {"node_type", 1, node_type, 0}, |
| 572 666 | {"node_byte_range", 1, node_byte_range, 0}, |
| @@ -577,6 +671,10 @@ static ErlNifFunc nif_funcs[] = { | |
| 577 671 | {"query_pattern_byte_range", 2, query_pattern_byte_range, 0}, |
| 578 672 | {"query_capture_name_for_id", 2, query_capture_name_for_id, 0}, |
| 579 673 | {"query_cursor_set_byte_range", 3, query_cursor_set_byte_range, 0}, |
| 580 | - {"query_cursor_set_point_range", 3, query_cursor_set_point_range, 0}}; |
| 674 | + {"query_cursor_set_point_range", 3, query_cursor_set_point_range, 0}, |
| 675 | + {"query_cursor_set_containing_byte_range", 3, |
| 676 | + query_cursor_set_containing_byte_range, 0}, |
| 677 | + {"query_cursor_set_containing_point_range", 3, |
| 678 | + query_cursor_set_containing_point_range, 0}}; |
| 581 679 | |
| 582 680 | ERL_NIF_INIT(Elixir.TreeSitter.Nif, nif_funcs, load, NULL, NULL, NULL) |