diff options
| author | Yuan Fu | 2022-11-03 22:14:50 -0700 |
|---|---|---|
| committer | Yuan Fu | 2022-11-03 22:14:50 -0700 |
| commit | b86deb617b109bcb40e9c95b10a033a209c1d8fd (patch) | |
| tree | 57ccdf73fe3c3eafbda814abe52fac7bf968da57 /src | |
| parent | c5f24f76eb1653d64c2ae90764e395cf6e050657 (diff) | |
| download | emacs-b86deb617b109bcb40e9c95b10a033a209c1d8fd.tar.gz emacs-b86deb617b109bcb40e9c95b10a033a209c1d8fd.zip | |
Fix treesit-parser-set-included-ranges
Track whether a parser has ranges set ourselves. See comment in
Ftreesit_parser_included_ranges for detail.
* src/treesit.c (make_treesit_parser): Initialize has_range.
(Ftreesit_parser_set_included_ranges): Set has_range. Fill docstring.
(Ftreesit_parser_included_ranges): Check has_range.
* src/treesit.h (Lisp_TS_Parser): Add has_range.
Diffstat (limited to 'src')
| -rw-r--r-- | src/treesit.c | 24 | ||||
| -rw-r--r-- | src/treesit.h | 3 |
2 files changed, 21 insertions, 6 deletions
diff --git a/src/treesit.c b/src/treesit.c index addd308d21a..48d650f1fc9 100644 --- a/src/treesit.c +++ b/src/treesit.c | |||
| @@ -955,6 +955,7 @@ make_treesit_parser (Lisp_Object buffer, TSParser *parser, | |||
| 955 | lisp_parser->visible_end = BUF_ZV (XBUFFER (buffer)); | 955 | lisp_parser->visible_end = BUF_ZV (XBUFFER (buffer)); |
| 956 | lisp_parser->timestamp = 0; | 956 | lisp_parser->timestamp = 0; |
| 957 | lisp_parser->deleted = false; | 957 | lisp_parser->deleted = false; |
| 958 | lisp_parser->has_range = false; | ||
| 958 | eassert (lisp_parser->visible_beg <= lisp_parser->visible_end); | 959 | eassert (lisp_parser->visible_beg <= lisp_parser->visible_end); |
| 959 | return make_lisp_ptr (lisp_parser, Lisp_Vectorlike); | 960 | return make_lisp_ptr (lisp_parser, Lisp_Vectorlike); |
| 960 | } | 961 | } |
| @@ -1340,13 +1341,15 @@ DEFUN ("treesit-parser-set-included-ranges", | |||
| 1340 | 1341 | ||
| 1341 | RANGES is a list of (BEG . END), each (BEG . END) defines a region in | 1342 | RANGES is a list of (BEG . END), each (BEG . END) defines a region in |
| 1342 | which the parser should operate. Regions must not overlap, and the | 1343 | which the parser should operate. Regions must not overlap, and the |
| 1343 | regions should come in order in the list. Signal `treesit-set-range-error' | 1344 | regions should come in order in the list. Signal |
| 1344 | if the argument is invalid, or something else went wrong. If RANGES | 1345 | `treesit-set-range-error' if the argument is invalid, or something |
| 1345 | is nil, the PARSER is to parse the whole buffer. */) | 1346 | else went wrong. If RANGES is nil, the PARSER is to parse the whole |
| 1347 | buffer. */) | ||
| 1346 | (Lisp_Object parser, Lisp_Object ranges) | 1348 | (Lisp_Object parser, Lisp_Object ranges) |
| 1347 | { | 1349 | { |
| 1348 | treesit_check_parser (parser); | 1350 | treesit_check_parser (parser); |
| 1349 | CHECK_CONS (ranges); | 1351 | if (!NILP (ranges)) |
| 1352 | CHECK_CONS (ranges); | ||
| 1350 | treesit_check_range_argument (ranges); | 1353 | treesit_check_range_argument (ranges); |
| 1351 | 1354 | ||
| 1352 | treesit_initialize (); | 1355 | treesit_initialize (); |
| @@ -1357,6 +1360,7 @@ is nil, the PARSER is to parse the whole buffer. */) | |||
| 1357 | bool success; | 1360 | bool success; |
| 1358 | if (NILP (ranges)) | 1361 | if (NILP (ranges)) |
| 1359 | { | 1362 | { |
| 1363 | XTS_PARSER (parser)->has_range = false; | ||
| 1360 | /* If RANGES is nil, make parser to parse the whole document. | 1364 | /* If RANGES is nil, make parser to parse the whole document. |
| 1361 | To do that we give tree-sitter a 0 length, the range is a | 1365 | To do that we give tree-sitter a 0 length, the range is a |
| 1362 | dummy. */ | 1366 | dummy. */ |
| @@ -1367,6 +1371,7 @@ is nil, the PARSER is to parse the whole buffer. */) | |||
| 1367 | else | 1371 | else |
| 1368 | { | 1372 | { |
| 1369 | /* Set ranges for PARSER. */ | 1373 | /* Set ranges for PARSER. */ |
| 1374 | XTS_PARSER (parser)->has_range = true; | ||
| 1370 | 1375 | ||
| 1371 | if (list_length (ranges) > UINT32_MAX) | 1376 | if (list_length (ranges) > UINT32_MAX) |
| 1372 | xsignal (Qargs_out_of_range, list2 (ranges, Flength (ranges))); | 1377 | xsignal (Qargs_out_of_range, list2 (ranges, Flength (ranges))); |
| @@ -1420,11 +1425,18 @@ return nil. */) | |||
| 1420 | { | 1425 | { |
| 1421 | treesit_check_parser (parser); | 1426 | treesit_check_parser (parser); |
| 1422 | treesit_initialize (); | 1427 | treesit_initialize (); |
| 1428 | |||
| 1429 | /* When the parser doesn't have a range set and we call | ||
| 1430 | ts_parser_included_ranges on it, it doesn't return an empty list, | ||
| 1431 | but rather return some garbled data. (A single range where | ||
| 1432 | start_byte = 0, end_byte = UINT32_MAX). So we need to track | ||
| 1433 | whether the parser is ranged ourselves. */ | ||
| 1434 | if (!XTS_PARSER (parser)->has_range) | ||
| 1435 | return Qnil; | ||
| 1436 | |||
| 1423 | uint32_t len; | 1437 | uint32_t len; |
| 1424 | const TSRange *ranges | 1438 | const TSRange *ranges |
| 1425 | = ts_parser_included_ranges (XTS_PARSER (parser)->parser, &len); | 1439 | = ts_parser_included_ranges (XTS_PARSER (parser)->parser, &len); |
| 1426 | if (len == 0) | ||
| 1427 | return Qnil; | ||
| 1428 | 1440 | ||
| 1429 | /* Our return value depends on the buffer state (BUF_BEGV_BYTE, | 1441 | /* Our return value depends on the buffer state (BUF_BEGV_BYTE, |
| 1430 | etc), so we need to sync up. */ | 1442 | etc), so we need to sync up. */ |
diff --git a/src/treesit.h b/src/treesit.h index d6bada5b360..169d8819d77 100644 --- a/src/treesit.h +++ b/src/treesit.h | |||
| @@ -65,6 +65,9 @@ struct Lisp_TS_Parser | |||
| 65 | /* If this field is true, parser functions raises | 65 | /* If this field is true, parser functions raises |
| 66 | treesit-parser-deleted signal. */ | 66 | treesit-parser-deleted signal. */ |
| 67 | bool deleted; | 67 | bool deleted; |
| 68 | /* If this field is true, the parser has ranges set. See | ||
| 69 | Ftreesit_parser_included_ranges for why we need this. */ | ||
| 70 | bool has_range; | ||
| 68 | }; | 71 | }; |
| 69 | 72 | ||
| 70 | /* A wrapper around a tree-sitter node. */ | 73 | /* A wrapper around a tree-sitter node. */ |