]> git.eshelyaron.com Git - emacs.git/commitdiff
Add tag to tree-sitter parsers
authorYuan Fu <casouri@gmail.com>
Mon, 4 Sep 2023 22:33:19 +0000 (15:33 -0700)
committerYuan Fu <casouri@gmail.com>
Wed, 6 Sep 2023 04:03:37 +0000 (21:03 -0700)
* 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.

doc/lispref/parsing.texi
lisp/treesit.el
src/treesit.c
src/treesit.h

index 36b3c19df0165cf7dacbaa4aea4c51031f0118a2..87c381b161dc69c44fa65bc80de7de9427ff3fa9 100644 (file)
@@ -400,14 +400,17 @@ when deciding whether to enable tree-sitter features.
 
 @cindex creating tree-sitter parsers
 @cindex tree-sitter parser, creating
-@defun treesit-parser-create language &optional buffer no-reuse
+@defun treesit-parser-create language &optional buffer no-reuse tag
 Create a parser for the specified @var{buffer} and @var{language}
-(@pxref{Language Grammar}).  If @var{buffer} is omitted or
-@code{nil}, it stands for the current buffer.
+(@pxref{Language Grammar}), with @var{tag}.  If @var{buffer} is
+omitted or @code{nil}, it stands for the current buffer.
 
 By default, this function reuses a parser if one already exists for
-@var{language} in @var{buffer}, but if @var{no-reuse} is
-non-@code{nil}, this function always creates a new parser.
+@var{language} with @var{tag} in @var{buffer}, but if @var{no-reuse}
+is non-@code{nil}, this function always creates a new parser.
+
+@var{tag} should be a symbol and defaults to @code{nil}.  Different
+parsers can have the same tag.
 
 If that buffer is an indirect buffer, its base buffer is used instead.
 That is, indirect buffers use their base buffer's parsers.  If the
index 1eccede436e443af5532004a20475792f7d920c5..2c0361a8873dc4310b1d61224e63619a3a3a1368 100644 (file)
@@ -263,15 +263,17 @@ If INCLUDE-NODE is non-nil, return NODE if it satisfies PRED."
              do (setq result cursor))
     result))
 
-(defun treesit-buffer-root-node (&optional language)
+(defun treesit-buffer-root-node (&optional language tag)
   "Return the root node of the current buffer.
 
 Use the first parser in the parser list if LANGUAGE is omitted.
-If LANGUAGE is non-nil, use the first parser for LANGUAGE in the
-parser list, or create one if none exists."
+
+If LANGUAGE is non-nil, use the first parser for LANGUAGE with
+TAG in the parser list, or create one if none exists.  TAG
+defaults to nil."
   (if-let ((parser
             (if language
-                (treesit-parser-create language)
+                (treesit-parser-create language nil nil tag)
               (or (car (treesit-parser-list))
                   (signal 'treesit-no-parser (list (current-buffer)))))))
       (treesit-parser-root-node parser)))
index 9f0e0e94186f6fe8ae1569f7fe513125d16edf6a..13be95949630c6be83ef03d6cc12d2705387965f 100644 (file)
@@ -1153,7 +1153,8 @@ treesit_read_buffer (void *parser, uint32_t byte_index,
    machine.  */
 Lisp_Object
 make_treesit_parser (Lisp_Object buffer, TSParser *parser,
-                    TSTree *tree, Lisp_Object language_symbol)
+                    TSTree *tree, Lisp_Object language_symbol,
+                    Lisp_Object tag)
 {
   struct Lisp_TS_Parser *lisp_parser;
 
@@ -1162,6 +1163,7 @@ make_treesit_parser (Lisp_Object buffer, TSParser *parser,
 
   lisp_parser->language_symbol = language_symbol;
   lisp_parser->after_change_functions = Qnil;
+  lisp_parser->tag = tag;
   lisp_parser->buffer = buffer;
   lisp_parser->parser = parser;
   lisp_parser->tree = tree;
@@ -1379,24 +1381,29 @@ DEFUN ("treesit-node-parser",
 
 DEFUN ("treesit-parser-create",
        Ftreesit_parser_create, Streesit_parser_create,
-       1, 3, 0,
-       doc: /* Create and return a parser in BUFFER for LANGUAGE.
+       1, 4, 0,
+       doc: /* Create and return a parser in BUFFER for LANGUAGE with TAG.
 
 The parser is automatically added to BUFFER's parser list, as returned
 by `treesit-parser-list'.  LANGUAGE is a language symbol.  If BUFFER
 is nil or omitted, it defaults to the current buffer.  If BUFFER
-already has a parser for LANGUAGE, return that parser, but if NO-REUSE
-is non-nil, always create a new parser.
+already has a parser for LANGUAGE with TAG, return that parser, but if
+NO-REUSE is non-nil, always create a new parser.
+
+TAG should be a symbol and defaults to nil.  Different parsers can
+have the same tag.
 
 If that buffer is an indirect buffer, its base buffer is used instead.
 That is, indirect buffers use their base buffer's parsers.  Lisp
 programs should widen as necessary should they want to use a parser in
 an indirect buffer.  */)
-  (Lisp_Object language, Lisp_Object buffer, Lisp_Object no_reuse)
+  (Lisp_Object language, Lisp_Object buffer, Lisp_Object no_reuse,
+   Lisp_Object tag)
 {
   treesit_initialize ();
 
   CHECK_SYMBOL (language);
+  CHECK_SYMBOL (tag);
   struct buffer *buf;
   if (NILP (buffer))
     buf = current_buffer;
@@ -1417,7 +1424,8 @@ an indirect buffer.  */)
       FOR_EACH_TAIL (tail)
       {
        struct Lisp_TS_Parser *parser = XTS_PARSER (XCAR (tail));
-       if (EQ (parser->language_symbol, language))
+       if (EQ (parser->tag, tag)
+           && EQ (parser->language_symbol, language))
          return XCAR (tail);
       }
     }
@@ -1437,7 +1445,7 @@ an indirect buffer.  */)
   /* Create parser.  */
   Lisp_Object lisp_parser = make_treesit_parser (Fcurrent_buffer (),
                                                 parser, NULL,
-                                                language);
+                                                language, tag);
 
   /* Update parser-list.  */
   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)
   else if (SYMBOLP (obj))
     {
       Lisp_Object parser
-       = Ftreesit_parser_create (obj, Fcurrent_buffer (), Qnil);
+       = Ftreesit_parser_create (obj, Fcurrent_buffer (), Qnil, Qnil);
       return Ftreesit_parser_root_node (parser);
     }
   else
index 5382bc5881734f47bec22ba10ca73c11404bf77d..ed5bab18733ffad963b7d24fc2c9c03951098abe 100644 (file)
@@ -34,13 +34,17 @@ INLINE_HEADER_BEGIN
 struct Lisp_TS_Parser
 {
   union vectorlike_header header;
-  /* A symbol representing the language this parser uses.  See the
+    /* A symbol representing the language this parser uses.  See the
      manual for more explanation.  */
   Lisp_Object language_symbol;
   /* A list of functions to call after re-parse.  Every function is
      called with the changed ranges and the parser.  The changed
      ranges is a list of (BEG . END).  */
   Lisp_Object after_change_functions;
+  /* A tag (symbol) for the parser.  Different parsers can have the
+     same tag.  A tag is primarily used to differentiate between
+     parsers for the same language.  */
+  Lisp_Object tag;
   /* The buffer associated with this parser.  */
   Lisp_Object buffer;
   /* The pointer to the tree-sitter parser.  Never NULL.  */
@@ -183,7 +187,7 @@ INLINE_HEADER_END
 
 extern void treesit_record_change (ptrdiff_t, ptrdiff_t, ptrdiff_t);
 extern Lisp_Object make_treesit_parser (Lisp_Object, TSParser *, TSTree *,
-                                       Lisp_Object);
+                                       Lisp_Object, Lisp_Object);
 extern Lisp_Object make_treesit_node (Lisp_Object, TSNode);
 
 extern bool treesit_node_uptodate_p (Lisp_Object);