From 5faadfb29ec8f38bb2f575375e9cb1925697a296 Mon Sep 17 00:00:00 2001 From: Yuan Fu Date: Sat, 27 Jul 2024 16:18:13 -0700 Subject: [PATCH] New variable treesit-language-remap-alist (bug#72388) * doc/lispref/parsing.texi (Using Parser): Manual entry for the new variable. * src/treesit.c (resolve_language_symbol): New function. (Ftreesit_parser_create, Ftreesit_parser_list): Resolve language before using it. (Vtreesit_language_remap_alist): New variable. (cherry picked from commit a7e3181e2f7adb928d63a8878a11849818ba321c) --- doc/lispref/parsing.texi | 24 ++++++++++++++++++++++++ src/treesit.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/doc/lispref/parsing.texi b/doc/lispref/parsing.texi index a3d2a5ac71c..ddf02d9283b 100644 --- a/doc/lispref/parsing.texi +++ b/doc/lispref/parsing.texi @@ -531,6 +531,30 @@ symbol, rather than a lambda function. This function returns the list of @var{parser}'s notifier functions. @end defun +@heading Substitute parser for another language +@cindex remap language grammar, tree-sitter +@cindex replace language grammar, tree-sitter +@cindex replace parser language, tree-sitter +@cindex extended grammar, tree-sitter + +Sometimes, a grammar for language B is a strict superset of the grammar +of another language A. Then it makes sense to reuse configurations +(font-lock rules, indentation rules, etc.) of language A for language B. +For that purpose, @var{treesit-language-remap-alist} allows users to +remap language A into language B. + +@defvar treesit-language-remap-alist +The value of this variable should be an alist of +@w{@code{(@var{language-a} . @var{language-b})}}. When such pair exists +in the alist, creating a parser for @var{language-a} actually creates a +parser for @var{language-b}. By extension, anything that creates a node +or makes a query of @var{language-a} will be redirected to use +@var{language-b} instead. + +Note that calling @code{treesit-parser-language} on a parser for +@var{language-a} still returns @var{language-a}. +@end defvar + @node Retrieving Nodes @section Retrieving Nodes @cindex retrieve node, tree-sitter diff --git a/src/treesit.c b/src/treesit.c index 513d0d22c7f..27779692923 100644 --- a/src/treesit.c +++ b/src/treesit.c @@ -1326,6 +1326,17 @@ treesit_ensure_query_compiled (Lisp_Object query, Lisp_Object *signal_symbol, return treesit_query; } +/* Resolve language symbol LANG according to + treesit-language-remap-alist. */ +static +Lisp_Object resolve_language_symbol (Lisp_Object lang) +{ + Lisp_Object res = Fassoc (lang, Vtreesit_language_remap_alist, Qeq); + if (NILP (res)) + return lang; + return Fcdr (res); +} + /* Lisp definitions. */ @@ -1442,6 +1453,9 @@ an indirect buffer. */) treesit_check_buffer_size (buf); + language = resolve_language_symbol (language); + CHECK_SYMBOL (language); + /* See if we can reuse a parser. */ if (NILP (no_reuse)) { @@ -1531,6 +1545,8 @@ tag. */) if (buf->base_buffer) buf = buf->base_buffer; + language = resolve_language_symbol (language); + /* Return a fresh list so messing with that list doesn't affect our internal data. */ Lisp_Object return_list = Qnil; @@ -4157,6 +4173,19 @@ Finally, PRED can refer to other THINGs defined in this list by using the symbol of that THING. For example, (or sexp sentence). */); Vtreesit_thing_settings = Qnil; + DEFVAR_LISP ("treesit-language-remap-alist", + Vtreesit_language_remap_alist, + doc: + /* An alist remapping language symbols. + +The value should be an alist of (LANGUAGE-A . LANGUAGE-B). When such +pair exists in the alist, creating a parser for LANGUAGE-A actually +creates a parser for LANGUAGE-B. Basically, anything that requires or +applies to LANGUAGE-A will be redirected to LANGUAGE-B instead. */); + Vtreesit_language_remap_alist = Qnil; + DEFSYM (Qtreesit_language_remap_alist, "treesit-language-remap-alist"); + Fmake_variable_buffer_local (Qtreesit_language_remap_alist); + staticpro (&Vtreesit_str_libtree_sitter); Vtreesit_str_libtree_sitter = build_pure_c_string ("libtree-sitter-"); staticpro (&Vtreesit_str_tree_sitter); -- 2.39.5