Function: treesit-parser-create
treesit-parser-create is a function defined in treesit.c.
Signature
(treesit-parser-create LANGUAGE &optional BUFFER NO-REUSE TAG)
Documentation
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 with TAG, return that parser, but if
NO-REUSE is non-nil, always create a new parser.
TAG can be any symbol except t, 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.
Other relevant functions are documented in the treesit group.
Shortdoc
;; treesit
(treesit-parser-create 'c)
e.g. => #<treesit-parser for c>
Source Code
// Defined in /usr/src/emacs/src/treesit.c
{
treesit_initialize ();
CHECK_SYMBOL (language);
CHECK_SYMBOL (tag);
struct buffer *buf;
Lisp_Object buf_orig;
if (NILP (buffer))
{
buf = current_buffer;
XSETBUFFER (buf_orig, current_buffer);
}
else
{
CHECK_BUFFER (buffer);
buf = XBUFFER (buffer);
buf_orig = buffer;
}
if (buf->base_buffer)
buf = buf->base_buffer;
if (EQ (tag, Qt))
xsignal2(Qwrong_type_argument, list2(Qnot, Qt), Qt);
treesit_check_buffer_size (buf);
Lisp_Object remapped_lang = resolve_language_symbol (language);
CHECK_SYMBOL (remapped_lang);
/* See if we can reuse a parser. */
if (NILP (no_reuse))
{
Lisp_Object tail = BVAR (buf, ts_parser_list);
FOR_EACH_TAIL (tail)
{
struct Lisp_TS_Parser *parser = XTS_PARSER (XCAR (tail));
if (EQ (parser->tag, tag)
&& EQ (parser->language_symbol, language)
&& EQ (parser->buffer, buf_orig))
return XCAR (tail);
}
}
/* Load language. */
Lisp_Object signal_symbol = Qnil;
Lisp_Object signal_data = Qnil;
TSParser *parser = ts_parser_new ();
struct treesit_loaded_lang loaded_lang
= treesit_load_language (remapped_lang, &signal_symbol, &signal_data);
TSLanguage *lang = loaded_lang.lang;
if (lang == NULL)
xsignal (signal_symbol, signal_data);
/* We check language version when loading a language, so this should
always succeed. */
ts_parser_set_language (parser, lang);
const bool lang_need_linecol_tracking
= !NILP (Fmemq (remapped_lang,
Vtreesit_languages_require_line_column_tracking));
/* Create parser. Use the unmapped LANGUAGE symbol, so the nodes
created by this parser (and the parser itself) identify themselves
as the unmapped language. This makes the grammar mapping
completely transparent. */
Lisp_Object lisp_parser = make_treesit_parser (buf_orig,
parser, NULL,
language, tag,
lang_need_linecol_tracking);
/* Enable line-column tracking if this language requires it. */
if (lang_need_linecol_tracking && !treesit_buf_tracks_linecol_p (buf))
{
/* We can use TREESIT_BOB_LINECOL for begv and zv since these
cache doesn't need to be always in sync with BEGV and ZV. */
SET_BUF_TS_LINECOL_BEGV (buf, TREESIT_BOB_LINECOL);
SET_BUF_TS_LINECOL_POINT (buf, TREESIT_BOB_LINECOL);
SET_BUF_TS_LINECOL_ZV (buf, TREESIT_BOB_LINECOL);
}
/* Update parser-list. */
BVAR (buf, ts_parser_list) = Fcons (lisp_parser, BVAR (buf, ts_parser_list));
return lisp_parser;
}