diff options
| author | Yuan Fu | 2022-12-07 14:50:16 -0800 |
|---|---|---|
| committer | Yuan Fu | 2022-12-09 17:24:08 -0800 |
| commit | ebef8905b0df9572e80e20fdc8da7829b9270e3f (patch) | |
| tree | 05f3b264babb0edf4d1a4d6985eca3f7aac1ed3d /src | |
| parent | 8f53fa10d9453f36aa601e5943cb903adeacc7fe (diff) | |
| download | emacs-ebef8905b0df9572e80e20fdc8da7829b9270e3f.tar.gz emacs-ebef8905b0df9572e80e20fdc8da7829b9270e3f.zip | |
Make indirect buffers use tree-sitter parsers of their base buffer
Fix the problem described in bug#59693.
* src/treesit.c (treesit_record_change): Always use the base buffer.
(Ftreesit_parser_create): Always use the base buffer. Also change the
for loop into FOR_EACH_TAIL (stylistic change).
(Ftreesit_parser_list): Always use the base buffer.
* doc/lispref/parsing.texi (Using Parser): Update manual.
* test/src/treesit-tests.el (treesit-indirect-buffer): New test.
Diffstat (limited to 'src')
| -rw-r--r-- | src/treesit.c | 61 |
1 files changed, 44 insertions, 17 deletions
diff --git a/src/treesit.c b/src/treesit.c index 8b485ca4ece..d361a3da932 100644 --- a/src/treesit.c +++ b/src/treesit.c | |||
| @@ -384,7 +384,18 @@ init_treesit_functions (void) | |||
| 384 | mysteriously drops. 3) what if a user uses so many stuff that the | 384 | mysteriously drops. 3) what if a user uses so many stuff that the |
| 385 | default cache size (20) is not enough and we end up thrashing? | 385 | default cache size (20) is not enough and we end up thrashing? |
| 386 | These are all imaginary scenarios but they are not impossible | 386 | These are all imaginary scenarios but they are not impossible |
| 387 | :-) */ | 387 | :-) |
| 388 | |||
| 389 | Parsers in indirect buffers: We make indirect buffers to share the | ||
| 390 | parser of its base buffer. Indirect buffers and their base buffer | ||
| 391 | share the same buffer content but not other buffer attributes. If | ||
| 392 | they have separate parser lists, changes made in an indirect buffer | ||
| 393 | will only update parsers of that indirect buffer, and not parsers | ||
| 394 | in the base buffer or other indirect buffers, and vice versa. We | ||
| 395 | could keep track of all the base and indirect buffers, and update | ||
| 396 | all of their parsers, but ultimately decide to take a simpler | ||
| 397 | approach, which is to make indirect buffers share their base | ||
| 398 | buffer's parser list. The discussion can be found in bug#59693. */ | ||
| 388 | 399 | ||
| 389 | 400 | ||
| 390 | /*** Initialization */ | 401 | /*** Initialization */ |
| @@ -697,9 +708,10 @@ void | |||
| 697 | treesit_record_change (ptrdiff_t start_byte, ptrdiff_t old_end_byte, | 708 | treesit_record_change (ptrdiff_t start_byte, ptrdiff_t old_end_byte, |
| 698 | ptrdiff_t new_end_byte) | 709 | ptrdiff_t new_end_byte) |
| 699 | { | 710 | { |
| 700 | Lisp_Object parser_list; | 711 | struct buffer *base_buffer = current_buffer; |
| 701 | 712 | if (current_buffer->base_buffer) | |
| 702 | parser_list = BVAR (current_buffer, ts_parser_list); | 713 | base_buffer = current_buffer->base_buffer; |
| 714 | Lisp_Object parser_list = BVAR (base_buffer, ts_parser_list); | ||
| 703 | 715 | ||
| 704 | FOR_EACH_TAIL_SAFE (parser_list) | 716 | FOR_EACH_TAIL_SAFE (parser_list) |
| 705 | { | 717 | { |
| @@ -1252,12 +1264,16 @@ DEFUN ("treesit-parser-create", | |||
| 1252 | 1, 3, 0, | 1264 | 1, 3, 0, |
| 1253 | doc: /* Create and return a parser in BUFFER for LANGUAGE. | 1265 | doc: /* Create and return a parser in BUFFER for LANGUAGE. |
| 1254 | 1266 | ||
| 1255 | The parser is automatically added to BUFFER's parser list, as | 1267 | The parser is automatically added to BUFFER's parser list, as returned |
| 1256 | returned by `treesit-parser-list'. | 1268 | by `treesit-parser-list'. LANGUAGE is a language symbol. If BUFFER |
| 1257 | LANGUAGE is a language symbol. If BUFFER is nil or omitted, it | 1269 | is nil or omitted, it defaults to the current buffer. If BUFFER |
| 1258 | defaults to the current buffer. If BUFFER already has a parser for | 1270 | already has a parser for LANGUAGE, return that parser, but if NO-REUSE |
| 1259 | LANGUAGE, return that parser, but if NO-REUSE is non-nil, always | 1271 | is non-nil, always create a new parser. |
| 1260 | create a new parser. */) | 1272 | |
| 1273 | If that buffer is an indirect buffer, its base buffer is used instead. | ||
| 1274 | That is, indirect buffers use their base buffer's parsers. Lisp | ||
| 1275 | programs should widen as necessary should they want to use a parser in | ||
| 1276 | an indirect buffer. */) | ||
| 1261 | (Lisp_Object language, Lisp_Object buffer, Lisp_Object no_reuse) | 1277 | (Lisp_Object language, Lisp_Object buffer, Lisp_Object no_reuse) |
| 1262 | { | 1278 | { |
| 1263 | treesit_initialize (); | 1279 | treesit_initialize (); |
| @@ -1271,16 +1287,21 @@ create a new parser. */) | |||
| 1271 | CHECK_BUFFER (buffer); | 1287 | CHECK_BUFFER (buffer); |
| 1272 | buf = XBUFFER (buffer); | 1288 | buf = XBUFFER (buffer); |
| 1273 | } | 1289 | } |
| 1290 | if (buf->base_buffer) | ||
| 1291 | buf = buf->base_buffer; | ||
| 1292 | |||
| 1274 | treesit_check_buffer_size (buf); | 1293 | treesit_check_buffer_size (buf); |
| 1275 | 1294 | ||
| 1276 | /* See if we can reuse a parser. */ | 1295 | /* See if we can reuse a parser. */ |
| 1277 | for (Lisp_Object tail = BVAR (buf, ts_parser_list); | 1296 | if (NILP (no_reuse)) |
| 1278 | NILP (no_reuse) && !NILP (tail); | ||
| 1279 | tail = XCDR (tail)) | ||
| 1280 | { | 1297 | { |
| 1281 | struct Lisp_TS_Parser *parser = XTS_PARSER (XCAR (tail)); | 1298 | Lisp_Object tail = BVAR (buf, ts_parser_list); |
| 1282 | if (EQ (parser->language_symbol, language)) | 1299 | FOR_EACH_TAIL (tail) |
| 1283 | return XCAR (tail); | 1300 | { |
| 1301 | struct Lisp_TS_Parser *parser = XTS_PARSER (XCAR (tail)); | ||
| 1302 | if (EQ (parser->language_symbol, language)) | ||
| 1303 | return XCAR (tail); | ||
| 1304 | } | ||
| 1284 | } | 1305 | } |
| 1285 | 1306 | ||
| 1286 | /* Load language. */ | 1307 | /* Load language. */ |
| @@ -1329,7 +1350,10 @@ DEFUN ("treesit-parser-list", | |||
| 1329 | Ftreesit_parser_list, Streesit_parser_list, | 1350 | Ftreesit_parser_list, Streesit_parser_list, |
| 1330 | 0, 1, 0, | 1351 | 0, 1, 0, |
| 1331 | doc: /* Return BUFFER's parser list. | 1352 | doc: /* Return BUFFER's parser list. |
| 1332 | BUFFER defaults to the current buffer. */) | 1353 | |
| 1354 | BUFFER defaults to the current buffer. If that buffer is an indirect | ||
| 1355 | buffer, its base buffer is used instead. That is, indirect buffers | ||
| 1356 | use their base buffer's parsers. */) | ||
| 1333 | (Lisp_Object buffer) | 1357 | (Lisp_Object buffer) |
| 1334 | { | 1358 | { |
| 1335 | struct buffer *buf; | 1359 | struct buffer *buf; |
| @@ -1340,6 +1364,9 @@ BUFFER defaults to the current buffer. */) | |||
| 1340 | CHECK_BUFFER (buffer); | 1364 | CHECK_BUFFER (buffer); |
| 1341 | buf = XBUFFER (buffer); | 1365 | buf = XBUFFER (buffer); |
| 1342 | } | 1366 | } |
| 1367 | if (buf->base_buffer) | ||
| 1368 | buf = buf->base_buffer; | ||
| 1369 | |||
| 1343 | /* Return a fresh list so messing with that list doesn't affect our | 1370 | /* Return a fresh list so messing with that list doesn't affect our |
| 1344 | internal data. */ | 1371 | internal data. */ |
| 1345 | Lisp_Object return_list = Qnil; | 1372 | Lisp_Object return_list = Qnil; |