aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorYuan Fu2022-12-07 14:50:16 -0800
committerYuan Fu2022-12-09 17:24:08 -0800
commitebef8905b0df9572e80e20fdc8da7829b9270e3f (patch)
tree05f3b264babb0edf4d1a4d6985eca3f7aac1ed3d /src
parent8f53fa10d9453f36aa601e5943cb903adeacc7fe (diff)
downloademacs-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.c61
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
697treesit_record_change (ptrdiff_t start_byte, ptrdiff_t old_end_byte, 708treesit_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
1255The parser is automatically added to BUFFER's parser list, as 1267The parser is automatically added to BUFFER's parser list, as returned
1256returned by `treesit-parser-list'. 1268by `treesit-parser-list'. LANGUAGE is a language symbol. If BUFFER
1257LANGUAGE is a language symbol. If BUFFER is nil or omitted, it 1269is nil or omitted, it defaults to the current buffer. If BUFFER
1258defaults to the current buffer. If BUFFER already has a parser for 1270already has a parser for LANGUAGE, return that parser, but if NO-REUSE
1259LANGUAGE, return that parser, but if NO-REUSE is non-nil, always 1271is non-nil, always create a new parser.
1260create a new parser. */) 1272
1273If that buffer is an indirect buffer, its base buffer is used instead.
1274That is, indirect buffers use their base buffer's parsers. Lisp
1275programs should widen as necessary should they want to use a parser in
1276an 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.
1332BUFFER defaults to the current buffer. */) 1353
1354BUFFER defaults to the current buffer. If that buffer is an indirect
1355buffer, its base buffer is used instead. That is, indirect buffers
1356use 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;