diff options
| author | Yuan Fu | 2023-09-04 15:33:19 -0700 |
|---|---|---|
| committer | Yuan Fu | 2023-09-05 21:03:37 -0700 |
| commit | 722daf6fffe42f82323ed45a380fcccd322da69f (patch) | |
| tree | a2a7fa6ed81ad48e2f801e87b4c4af9a86e68042 | |
| parent | aa872f2540377ae5c5e054a55cdd789934a56a47 (diff) | |
| download | emacs-722daf6fffe42f82323ed45a380fcccd322da69f.tar.gz emacs-722daf6fffe42f82323ed45a380fcccd322da69f.zip | |
Add tag to tree-sitter parsers
* doc/lispref/parsing.texi (Using Parser): Update manual.
* lisp/treesit.el (treesit-buffer-root-node)
* src/treesit.c (make_treesit_parser)
* src/treesit.c (Ftreesit_parser_create): Add TAG parameter.
(treesit_resolve_node): Create a parser with nil tag.
* src/treesit.h (Lisp_TS_Parser): Add TAG field.
| -rw-r--r-- | doc/lispref/parsing.texi | 13 | ||||
| -rw-r--r-- | lisp/treesit.el | 10 | ||||
| -rw-r--r-- | src/treesit.c | 26 | ||||
| -rw-r--r-- | src/treesit.h | 8 |
4 files changed, 37 insertions, 20 deletions
diff --git a/doc/lispref/parsing.texi b/doc/lispref/parsing.texi index 36b3c19df01..87c381b161d 100644 --- a/doc/lispref/parsing.texi +++ b/doc/lispref/parsing.texi | |||
| @@ -400,14 +400,17 @@ when deciding whether to enable tree-sitter features. | |||
| 400 | 400 | ||
| 401 | @cindex creating tree-sitter parsers | 401 | @cindex creating tree-sitter parsers |
| 402 | @cindex tree-sitter parser, creating | 402 | @cindex tree-sitter parser, creating |
| 403 | @defun treesit-parser-create language &optional buffer no-reuse | 403 | @defun treesit-parser-create language &optional buffer no-reuse tag |
| 404 | Create a parser for the specified @var{buffer} and @var{language} | 404 | Create a parser for the specified @var{buffer} and @var{language} |
| 405 | (@pxref{Language Grammar}). If @var{buffer} is omitted or | 405 | (@pxref{Language Grammar}), with @var{tag}. If @var{buffer} is |
| 406 | @code{nil}, it stands for the current buffer. | 406 | omitted or @code{nil}, it stands for the current buffer. |
| 407 | 407 | ||
| 408 | By default, this function reuses a parser if one already exists for | 408 | By default, this function reuses a parser if one already exists for |
| 409 | @var{language} in @var{buffer}, but if @var{no-reuse} is | 409 | @var{language} with @var{tag} in @var{buffer}, but if @var{no-reuse} |
| 410 | non-@code{nil}, this function always creates a new parser. | 410 | is non-@code{nil}, this function always creates a new parser. |
| 411 | |||
| 412 | @var{tag} should be a symbol and defaults to @code{nil}. Different | ||
| 413 | parsers can have the same tag. | ||
| 411 | 414 | ||
| 412 | If that buffer is an indirect buffer, its base buffer is used instead. | 415 | If that buffer is an indirect buffer, its base buffer is used instead. |
| 413 | That is, indirect buffers use their base buffer's parsers. If the | 416 | That is, indirect buffers use their base buffer's parsers. If the |
diff --git a/lisp/treesit.el b/lisp/treesit.el index 1eccede436e..2c0361a8873 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el | |||
| @@ -263,15 +263,17 @@ If INCLUDE-NODE is non-nil, return NODE if it satisfies PRED." | |||
| 263 | do (setq result cursor)) | 263 | do (setq result cursor)) |
| 264 | result)) | 264 | result)) |
| 265 | 265 | ||
| 266 | (defun treesit-buffer-root-node (&optional language) | 266 | (defun treesit-buffer-root-node (&optional language tag) |
| 267 | "Return the root node of the current buffer. | 267 | "Return the root node of the current buffer. |
| 268 | 268 | ||
| 269 | Use the first parser in the parser list if LANGUAGE is omitted. | 269 | Use the first parser in the parser list if LANGUAGE is omitted. |
| 270 | If LANGUAGE is non-nil, use the first parser for LANGUAGE in the | 270 | |
| 271 | parser list, or create one if none exists." | 271 | If LANGUAGE is non-nil, use the first parser for LANGUAGE with |
| 272 | TAG in the parser list, or create one if none exists. TAG | ||
| 273 | defaults to nil." | ||
| 272 | (if-let ((parser | 274 | (if-let ((parser |
| 273 | (if language | 275 | (if language |
| 274 | (treesit-parser-create language) | 276 | (treesit-parser-create language nil nil tag) |
| 275 | (or (car (treesit-parser-list)) | 277 | (or (car (treesit-parser-list)) |
| 276 | (signal 'treesit-no-parser (list (current-buffer))))))) | 278 | (signal 'treesit-no-parser (list (current-buffer))))))) |
| 277 | (treesit-parser-root-node parser))) | 279 | (treesit-parser-root-node parser))) |
diff --git a/src/treesit.c b/src/treesit.c index 9f0e0e94186..13be9594963 100644 --- a/src/treesit.c +++ b/src/treesit.c | |||
| @@ -1153,7 +1153,8 @@ treesit_read_buffer (void *parser, uint32_t byte_index, | |||
| 1153 | machine. */ | 1153 | machine. */ |
| 1154 | Lisp_Object | 1154 | Lisp_Object |
| 1155 | make_treesit_parser (Lisp_Object buffer, TSParser *parser, | 1155 | make_treesit_parser (Lisp_Object buffer, TSParser *parser, |
| 1156 | TSTree *tree, Lisp_Object language_symbol) | 1156 | TSTree *tree, Lisp_Object language_symbol, |
| 1157 | Lisp_Object tag) | ||
| 1157 | { | 1158 | { |
| 1158 | struct Lisp_TS_Parser *lisp_parser; | 1159 | struct Lisp_TS_Parser *lisp_parser; |
| 1159 | 1160 | ||
| @@ -1162,6 +1163,7 @@ make_treesit_parser (Lisp_Object buffer, TSParser *parser, | |||
| 1162 | 1163 | ||
| 1163 | lisp_parser->language_symbol = language_symbol; | 1164 | lisp_parser->language_symbol = language_symbol; |
| 1164 | lisp_parser->after_change_functions = Qnil; | 1165 | lisp_parser->after_change_functions = Qnil; |
| 1166 | lisp_parser->tag = tag; | ||
| 1165 | lisp_parser->buffer = buffer; | 1167 | lisp_parser->buffer = buffer; |
| 1166 | lisp_parser->parser = parser; | 1168 | lisp_parser->parser = parser; |
| 1167 | lisp_parser->tree = tree; | 1169 | lisp_parser->tree = tree; |
| @@ -1379,24 +1381,29 @@ DEFUN ("treesit-node-parser", | |||
| 1379 | 1381 | ||
| 1380 | DEFUN ("treesit-parser-create", | 1382 | DEFUN ("treesit-parser-create", |
| 1381 | Ftreesit_parser_create, Streesit_parser_create, | 1383 | Ftreesit_parser_create, Streesit_parser_create, |
| 1382 | 1, 3, 0, | 1384 | 1, 4, 0, |
| 1383 | doc: /* Create and return a parser in BUFFER for LANGUAGE. | 1385 | doc: /* Create and return a parser in BUFFER for LANGUAGE with TAG. |
| 1384 | 1386 | ||
| 1385 | The parser is automatically added to BUFFER's parser list, as returned | 1387 | The parser is automatically added to BUFFER's parser list, as returned |
| 1386 | by `treesit-parser-list'. LANGUAGE is a language symbol. If BUFFER | 1388 | by `treesit-parser-list'. LANGUAGE is a language symbol. If BUFFER |
| 1387 | is nil or omitted, it defaults to the current buffer. If BUFFER | 1389 | is nil or omitted, it defaults to the current buffer. If BUFFER |
| 1388 | already has a parser for LANGUAGE, return that parser, but if NO-REUSE | 1390 | already has a parser for LANGUAGE with TAG, return that parser, but if |
| 1389 | is non-nil, always create a new parser. | 1391 | NO-REUSE is non-nil, always create a new parser. |
| 1392 | |||
| 1393 | TAG should be a symbol and defaults to nil. Different parsers can | ||
| 1394 | have the same tag. | ||
| 1390 | 1395 | ||
| 1391 | If that buffer is an indirect buffer, its base buffer is used instead. | 1396 | If that buffer is an indirect buffer, its base buffer is used instead. |
| 1392 | That is, indirect buffers use their base buffer's parsers. Lisp | 1397 | That is, indirect buffers use their base buffer's parsers. Lisp |
| 1393 | programs should widen as necessary should they want to use a parser in | 1398 | programs should widen as necessary should they want to use a parser in |
| 1394 | an indirect buffer. */) | 1399 | an indirect buffer. */) |
| 1395 | (Lisp_Object language, Lisp_Object buffer, Lisp_Object no_reuse) | 1400 | (Lisp_Object language, Lisp_Object buffer, Lisp_Object no_reuse, |
| 1401 | Lisp_Object tag) | ||
| 1396 | { | 1402 | { |
| 1397 | treesit_initialize (); | 1403 | treesit_initialize (); |
| 1398 | 1404 | ||
| 1399 | CHECK_SYMBOL (language); | 1405 | CHECK_SYMBOL (language); |
| 1406 | CHECK_SYMBOL (tag); | ||
| 1400 | struct buffer *buf; | 1407 | struct buffer *buf; |
| 1401 | if (NILP (buffer)) | 1408 | if (NILP (buffer)) |
| 1402 | buf = current_buffer; | 1409 | buf = current_buffer; |
| @@ -1417,7 +1424,8 @@ an indirect buffer. */) | |||
| 1417 | FOR_EACH_TAIL (tail) | 1424 | FOR_EACH_TAIL (tail) |
| 1418 | { | 1425 | { |
| 1419 | struct Lisp_TS_Parser *parser = XTS_PARSER (XCAR (tail)); | 1426 | struct Lisp_TS_Parser *parser = XTS_PARSER (XCAR (tail)); |
| 1420 | if (EQ (parser->language_symbol, language)) | 1427 | if (EQ (parser->tag, tag) |
| 1428 | && EQ (parser->language_symbol, language)) | ||
| 1421 | return XCAR (tail); | 1429 | return XCAR (tail); |
| 1422 | } | 1430 | } |
| 1423 | } | 1431 | } |
| @@ -1437,7 +1445,7 @@ an indirect buffer. */) | |||
| 1437 | /* Create parser. */ | 1445 | /* Create parser. */ |
| 1438 | Lisp_Object lisp_parser = make_treesit_parser (Fcurrent_buffer (), | 1446 | Lisp_Object lisp_parser = make_treesit_parser (Fcurrent_buffer (), |
| 1439 | parser, NULL, | 1447 | parser, NULL, |
| 1440 | language); | 1448 | language, tag); |
| 1441 | 1449 | ||
| 1442 | /* Update parser-list. */ | 1450 | /* Update parser-list. */ |
| 1443 | BVAR (buf, ts_parser_list) = Fcons (lisp_parser, BVAR (buf, ts_parser_list)); | 1451 | BVAR (buf, ts_parser_list) = Fcons (lisp_parser, BVAR (buf, ts_parser_list)); |
| @@ -2775,7 +2783,7 @@ static Lisp_Object treesit_resolve_node (Lisp_Object obj) | |||
| 2775 | else if (SYMBOLP (obj)) | 2783 | else if (SYMBOLP (obj)) |
| 2776 | { | 2784 | { |
| 2777 | Lisp_Object parser | 2785 | Lisp_Object parser |
| 2778 | = Ftreesit_parser_create (obj, Fcurrent_buffer (), Qnil); | 2786 | = Ftreesit_parser_create (obj, Fcurrent_buffer (), Qnil, Qnil); |
| 2779 | return Ftreesit_parser_root_node (parser); | 2787 | return Ftreesit_parser_root_node (parser); |
| 2780 | } | 2788 | } |
| 2781 | else | 2789 | else |
diff --git a/src/treesit.h b/src/treesit.h index 5382bc58817..ed5bab18733 100644 --- a/src/treesit.h +++ b/src/treesit.h | |||
| @@ -34,13 +34,17 @@ INLINE_HEADER_BEGIN | |||
| 34 | struct Lisp_TS_Parser | 34 | struct Lisp_TS_Parser |
| 35 | { | 35 | { |
| 36 | union vectorlike_header header; | 36 | union vectorlike_header header; |
| 37 | /* A symbol representing the language this parser uses. See the | 37 | /* A symbol representing the language this parser uses. See the |
| 38 | manual for more explanation. */ | 38 | manual for more explanation. */ |
| 39 | Lisp_Object language_symbol; | 39 | Lisp_Object language_symbol; |
| 40 | /* A list of functions to call after re-parse. Every function is | 40 | /* A list of functions to call after re-parse. Every function is |
| 41 | called with the changed ranges and the parser. The changed | 41 | called with the changed ranges and the parser. The changed |
| 42 | ranges is a list of (BEG . END). */ | 42 | ranges is a list of (BEG . END). */ |
| 43 | Lisp_Object after_change_functions; | 43 | Lisp_Object after_change_functions; |
| 44 | /* A tag (symbol) for the parser. Different parsers can have the | ||
| 45 | same tag. A tag is primarily used to differentiate between | ||
| 46 | parsers for the same language. */ | ||
| 47 | Lisp_Object tag; | ||
| 44 | /* The buffer associated with this parser. */ | 48 | /* The buffer associated with this parser. */ |
| 45 | Lisp_Object buffer; | 49 | Lisp_Object buffer; |
| 46 | /* The pointer to the tree-sitter parser. Never NULL. */ | 50 | /* The pointer to the tree-sitter parser. Never NULL. */ |
| @@ -183,7 +187,7 @@ INLINE_HEADER_END | |||
| 183 | 187 | ||
| 184 | extern void treesit_record_change (ptrdiff_t, ptrdiff_t, ptrdiff_t); | 188 | extern void treesit_record_change (ptrdiff_t, ptrdiff_t, ptrdiff_t); |
| 185 | extern Lisp_Object make_treesit_parser (Lisp_Object, TSParser *, TSTree *, | 189 | extern Lisp_Object make_treesit_parser (Lisp_Object, TSParser *, TSTree *, |
| 186 | Lisp_Object); | 190 | Lisp_Object, Lisp_Object); |
| 187 | extern Lisp_Object make_treesit_node (Lisp_Object, TSNode); | 191 | extern Lisp_Object make_treesit_node (Lisp_Object, TSNode); |
| 188 | 192 | ||
| 189 | extern bool treesit_node_uptodate_p (Lisp_Object); | 193 | extern bool treesit_node_uptodate_p (Lisp_Object); |