Add Ftreesit_grammar_location
* src/treesit.c (treesit_loaded_lang): New struct. (treesit_load_language): Return a struct instead of just the language object. The struct contains both the language object and the path to the shared library. (Ftreesit_language_available_p, Ftreesit_language_abi_version) (treesit_ensure_query_compiled, Ftreesit_parser_create): Update call of treesit_load_language. (Ftreesit_grammar_location): New function.
This commit is contained in:
parent
f283144658
commit
2a75693f24
1 changed files with 58 additions and 13 deletions
|
@ -22,6 +22,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include <config.h>
|
||||
#include "lisp.h"
|
||||
#include "buffer.h"
|
||||
#include "coding.h"
|
||||
|
||||
#include "treesit.h"
|
||||
|
||||
|
@ -541,6 +542,15 @@ treesit_debug_print_parser_list (char *msg, Lisp_Object parser)
|
|||
|
||||
/*** Loading language library */
|
||||
|
||||
struct treesit_loaded_lang
|
||||
{
|
||||
/* The language object, or NULL if the language failed to load. */
|
||||
TSLanguage *lang;
|
||||
/* The absolute file name of the shared library, or NULL if access
|
||||
failed. */
|
||||
const char *filename;
|
||||
};
|
||||
|
||||
/* Translate a symbol treesit-<lang> to a C name treesit_<lang>. */
|
||||
static void
|
||||
treesit_symbol_to_c_name (char *symbol_name)
|
||||
|
@ -625,7 +635,7 @@ treesit_load_language_push_for_each_suffix (Lisp_Object lib_base_name,
|
|||
|
||||
If error occurs, return NULL and fill SIGNAL_SYMBOL and SIGNAL_DATA
|
||||
with values suitable for xsignal. */
|
||||
static TSLanguage *
|
||||
static struct treesit_loaded_lang
|
||||
treesit_load_language (Lisp_Object language_symbol,
|
||||
Lisp_Object *signal_symbol, Lisp_Object *signal_data)
|
||||
{
|
||||
|
@ -676,6 +686,7 @@ treesit_load_language (Lisp_Object language_symbol,
|
|||
dynlib_handle_ptr handle;
|
||||
const char *error;
|
||||
Lisp_Object error_list = Qnil;
|
||||
struct treesit_loaded_lang loaded_lang = { NULL, NULL };
|
||||
|
||||
tail = path_candidates;
|
||||
error = NULL;
|
||||
|
@ -700,7 +711,7 @@ treesit_load_language (Lisp_Object language_symbol,
|
|||
mismatch. */
|
||||
*signal_symbol = Qtreesit_load_language_error;
|
||||
*signal_data = Fcons (Qnot_found, Fnreverse (error_list));
|
||||
return NULL;
|
||||
return loaded_lang;
|
||||
}
|
||||
|
||||
/* Load TSLanguage. */
|
||||
|
@ -722,7 +733,7 @@ treesit_load_language (Lisp_Object language_symbol,
|
|||
{
|
||||
*signal_symbol = Qtreesit_load_language_error;
|
||||
*signal_data = list2 (Qsymbol_error, build_string (error));
|
||||
return NULL;
|
||||
return loaded_lang;
|
||||
}
|
||||
TSLanguage *lang = (*langfn) ();
|
||||
|
||||
|
@ -735,9 +746,14 @@ treesit_load_language (Lisp_Object language_symbol,
|
|||
*signal_symbol = Qtreesit_load_language_error;
|
||||
*signal_data = list2 (Qversion_mismatch,
|
||||
make_fixnum (ts_language_version (lang)));
|
||||
return NULL;
|
||||
return loaded_lang;
|
||||
}
|
||||
return lang;
|
||||
|
||||
const char *sym;
|
||||
dynlib_addr ((void (*)) langfn, &loaded_lang.filename, &sym);
|
||||
|
||||
loaded_lang.lang = lang;
|
||||
return loaded_lang;
|
||||
}
|
||||
|
||||
DEFUN ("treesit-language-available-p", Ftreesit_language_available_p,
|
||||
|
@ -754,7 +770,9 @@ If DETAIL is non-nil, return (t . nil) when LANGUAGE is available,
|
|||
treesit_initialize ();
|
||||
Lisp_Object signal_symbol = Qnil;
|
||||
Lisp_Object signal_data = Qnil;
|
||||
if (treesit_load_language (language, &signal_symbol, &signal_data) == NULL)
|
||||
struct treesit_loaded_lang loaded_lang
|
||||
= treesit_load_language (language, &signal_symbol, &signal_data);
|
||||
if (loaded_lang.lang == NULL)
|
||||
{
|
||||
if (NILP (detail))
|
||||
return Qnil;
|
||||
|
@ -800,9 +818,9 @@ Return nil if a grammar library for LANGUAGE is not available. */)
|
|||
{
|
||||
Lisp_Object signal_symbol = Qnil;
|
||||
Lisp_Object signal_data = Qnil;
|
||||
TSLanguage *ts_language = treesit_load_language (language,
|
||||
&signal_symbol,
|
||||
&signal_data);
|
||||
struct treesit_loaded_lang lang
|
||||
= treesit_load_language (language, &signal_symbol, &signal_data);
|
||||
TSLanguage *ts_language = lang.lang;
|
||||
if (ts_language == NULL)
|
||||
return Qnil;
|
||||
uint32_t version = ts_language_version (ts_language);
|
||||
|
@ -810,6 +828,30 @@ Return nil if a grammar library for LANGUAGE is not available. */)
|
|||
}
|
||||
}
|
||||
|
||||
/* This function isn't documented in the manual since it's mainly for
|
||||
debugging. */
|
||||
DEFUN ("treesit-grammar-location", Ftreesit_grammar_location,
|
||||
Streesit_grammar_location,
|
||||
1, 1, 0,
|
||||
doc: /* Return the absolute file name of the grammar file for LANGUAGE.
|
||||
|
||||
If LANGUAGE isn't loaded yet, load it first. If the language can't be
|
||||
loaded or the file name couldn't be determined, return nil. */)
|
||||
(Lisp_Object language)
|
||||
{
|
||||
CHECK_SYMBOL (language);
|
||||
|
||||
Lisp_Object signal_symbol = Qnil;
|
||||
Lisp_Object signal_data = Qnil;
|
||||
struct treesit_loaded_lang lang
|
||||
= treesit_load_language (language, &signal_symbol, &signal_data);
|
||||
|
||||
if (!lang.lang || !lang.filename) return Qnil;
|
||||
|
||||
return DECODE_FILE (make_unibyte_string (lang.filename,
|
||||
strlen (lang.filename)));
|
||||
}
|
||||
|
||||
|
||||
/*** Parsing functions */
|
||||
|
||||
|
@ -1401,8 +1443,9 @@ treesit_ensure_query_compiled (Lisp_Object query, Lisp_Object *signal_symbol,
|
|||
Lisp_Object language = XTS_COMPILED_QUERY (query)->language;
|
||||
/* This is the main reason why we compile query lazily: to avoid
|
||||
loading languages early. */
|
||||
TSLanguage *treesit_lang = treesit_load_language (language, signal_symbol,
|
||||
signal_data);
|
||||
struct treesit_loaded_lang lang
|
||||
= treesit_load_language (language, signal_symbol, signal_data);
|
||||
TSLanguage *treesit_lang = lang.lang;
|
||||
if (treesit_lang == NULL)
|
||||
return NULL;
|
||||
|
||||
|
@ -1573,8 +1616,9 @@ an indirect buffer. */)
|
|||
Lisp_Object signal_symbol = Qnil;
|
||||
Lisp_Object signal_data = Qnil;
|
||||
TSParser *parser = ts_parser_new ();
|
||||
TSLanguage *lang = treesit_load_language (language, &signal_symbol,
|
||||
&signal_data);
|
||||
struct treesit_loaded_lang loaded_lang
|
||||
= treesit_load_language (language, &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
|
||||
|
@ -4369,6 +4413,7 @@ applies to LANGUAGE-A will be redirected to LANGUAGE-B instead. */);
|
|||
defsubr (&Streesit_language_available_p);
|
||||
defsubr (&Streesit_library_abi_version);
|
||||
defsubr (&Streesit_language_abi_version);
|
||||
defsubr (&Streesit_grammar_location);
|
||||
|
||||
defsubr (&Streesit_parser_p);
|
||||
defsubr (&Streesit_node_p);
|
||||
|
|
Loading…
Add table
Reference in a new issue