emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 722daf6fffe 1/7: Add tag to tree-sitter parsers


From: Yuan Fu
Subject: master 722daf6fffe 1/7: Add tag to tree-sitter parsers
Date: Wed, 6 Sep 2023 00:03:49 -0400 (EDT)

branch: master
commit 722daf6fffe42f82323ed45a380fcccd322da69f
Author: Yuan Fu <casouri@gmail.com>
Commit: Yuan Fu <casouri@gmail.com>

    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.
---
 doc/lispref/parsing.texi | 13 ++++++++-----
 lisp/treesit.el          | 10 ++++++----
 src/treesit.c            | 26 +++++++++++++++++---------
 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.
 
 @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
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."
              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)))
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,
    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
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
 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);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]