/* Header file for the tree-sitter integration. Copyright (C) 2021 Free Software Foundation, Inc. This file is part of GNU Emacs. GNU Emacs is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. GNU Emacs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Emacs. If not, see . */ #ifndef EMACS_TREE_SITTER_H #define EMACS_TREE_SITTER_H #include "lisp.h" #include INLINE_HEADER_BEGIN /* A wrapper for a tree-sitter parser, but also contains a parse tree and other goodies for convenience. */ struct Lisp_TS_Parser { union vectorlike_header header; /* A parser's name is just a convenient tag, see docstring for 'tree-sitter-make-parser', and 'tree-sitter-get-parser'. */ Lisp_Object name; struct buffer *buffer; TSParser *parser; TSTree *tree; TSInput input; /* Re-parsing an unchanged buffer is not free for tree-sitter, so we only make it re-parse when need_reparse == true. That usually means some change is made in the buffer. But others could set this field to true to force tree-sitter to re-parse. */ bool need_reparse; /* This two positions record the byte position of the "visible region" that tree-sitter sees. Unlike markers, These two positions do not change as the user inserts and deletes text around them. Before re-parse, we move these positions to match BUF_BEGV_BYTE and BUF_ZV_BYTE. */ ptrdiff_t visible_beg; ptrdiff_t visible_end; }; /* A wrapper around a tree-sitter node. */ struct Lisp_TS_Node { union vectorlike_header header; /* This should prevent the gc from collecting the parser before the node is done with it. TSNode contains a pointer to the tree it belongs to, and the parser object, when collected by gc, will free that tree. */ Lisp_Object parser; TSNode node; }; INLINE bool TS_PARSERP (Lisp_Object x) { return PSEUDOVECTORP (x, PVEC_TS_PARSER); } INLINE struct Lisp_TS_Parser * XTS_PARSER (Lisp_Object a) { eassert (TS_PARSERP (a)); return XUNTAG (a, Lisp_Vectorlike, struct Lisp_TS_Parser); } INLINE bool TS_NODEP (Lisp_Object x) { return PSEUDOVECTORP (x, PVEC_TS_NODE); } INLINE struct Lisp_TS_Node * XTS_NODE (Lisp_Object a) { eassert (TS_NODEP (a)); return XUNTAG (a, Lisp_Vectorlike, struct Lisp_TS_Node); } INLINE void CHECK_TS_PARSER (Lisp_Object parser) { CHECK_TYPE (TS_PARSERP (parser), Qtree_sitter_parser_p, parser); } INLINE void CHECK_TS_NODE (Lisp_Object node) { CHECK_TYPE (TS_NODEP (node), Qtree_sitter_node_p, node); } void ts_record_change (ptrdiff_t start_byte, ptrdiff_t old_end_byte, ptrdiff_t new_end_byte); Lisp_Object make_ts_parser (struct buffer *buffer, TSParser *parser, TSTree *tree, Lisp_Object name); Lisp_Object make_ts_node (Lisp_Object parser, TSNode node); extern void syms_of_tree_sitter (void); INLINE_HEADER_END #endif /* EMACS_TREE_SITTER_H */