From 0b3f785c4a272b909108108cf7931779ae48cfba Mon Sep 17 00:00:00 2001 From: Yuan Fu Date: Wed, 12 Oct 2022 10:38:35 -0700 Subject: [PATCH] Better signal data for treesit-load-language-error * src/treesit.c (ts_load_language): Better formatted signal data, (Ftreesit_langauge_available_p): Optionally return the signal data if language not available. * doc/lispref/parsing.texi: Document the signal data in detail. --- doc/lispref/parsing.texi | 26 ++++++++++++++++++-------- src/treesit.c | 39 +++++++++++++++++++++++++++------------ 2 files changed, 45 insertions(+), 20 deletions(-) diff --git a/doc/lispref/parsing.texi b/doc/lispref/parsing.texi index d0bb642a3e0..c73175e3c37 100644 --- a/doc/lispref/parsing.texi +++ b/doc/lispref/parsing.texi @@ -70,16 +70,26 @@ Tree-sitter language definitions are distributed as dynamic libraries. In order to use a language definition in Emacs, you need to make sure that the dynamic library is installed on the system. Emacs looks for language definitions under load paths in -@code{treesit-extra-load-path}, @code{user-emacs-directory}/tree-sitter, -and system default locations for dynamic libraries, in that order. -Emacs tries each extensions in @code{treesit-load-suffixes}. If Emacs -cannot find the library or has problem loading it, Emacs signals -@code{treesit-load-language-error}. The signal data is a list of -specific error messages. +@code{treesit-extra-load-path}, +@code{user-emacs-directory}/tree-sitter, and system default locations +for dynamic libraries, in that order. Emacs tries each extensions in +@code{treesit-load-suffixes}. If Emacs cannot find the library or has +problem loading it, Emacs signals @code{treesit-load-language-error}. + +The signal data could be @code{(not-found @var{error-msg} ...)} if +Emacs cannot find the language definition, or @code{(symbol-error +@var{error-msg})} if the Emacs cannot find the correct symbol in the +language definition, or @code{(version_mismatch @var{error-msg})} if +the language definition's version does match that of the tree-sitter +library. @defun treesit-language-available-p language -This function checks whether the dynamic library for @var{language} is -present on the system, and return non-nil if it is. +This function returns non-nil if @var{language} exists and is +loadable. + +If @var{detail} is non-nil, return @code{(t . nil) when @var{language} +is available, @code{(nil . DATA)} when unavailable. @var{data} is the +signal data of @code{treesit-load-language-error}. @end defun @vindex treesit-load-name-override-list diff --git a/src/treesit.c b/src/treesit.c index 2565464deac..2b2e9c6d793 100644 --- a/src/treesit.c +++ b/src/treesit.c @@ -193,10 +193,7 @@ ts_load_language_push_for_each_suffix } /* Load the dynamic library of LANGUAGE_SYMBOL and return the pointer - to the language definition. Signals - Qtreesit_load_language_error if something goes wrong. - Qtreesit_load_language_error carries the error message from - trying to load the library with each extension. + to the language definition. If error occurs, return NULL and fill SIGNAL_SYMBOL and SIGNAL_DATA with values suitable for xsignal. */ @@ -267,7 +264,7 @@ ts_load_language (Lisp_Object language_symbol, if (error != NULL) { *signal_symbol = Qtreesit_load_language_error; - *signal_data = list2 (symbol_name, Fnreverse (error_list)); + *signal_data = Fcons (Qnot_found, Fnreverse (error_list)); return NULL; } @@ -279,7 +276,7 @@ ts_load_language (Lisp_Object language_symbol, if (error != NULL) { *signal_symbol = Qtreesit_load_language_error; - *signal_data = build_string (error); + *signal_data = list2 (Qsymbol_error, build_string (error)); return NULL; } TSLanguage *lang = (*langfn) (); @@ -291,7 +288,7 @@ ts_load_language (Lisp_Object language_symbol, if (!success) { *signal_symbol = Qtreesit_load_language_error; - *signal_data = list2 (build_pure_c_string ("Language version doesn't match tree-sitter version, language version:"), + *signal_data = list2 (Qversion_mismatch, make_fixnum (ts_language_version (lang))); return NULL; } @@ -301,18 +298,32 @@ ts_load_language (Lisp_Object language_symbol, DEFUN ("treesit-language-available-p", Ftreesit_langauge_available_p, Streesit_language_available_p, - 1, 1, 0, - doc: /* Return non-nil if LANGUAGE exists and is loadable. */) - (Lisp_Object language) + 1, 2, 0, + doc: /* Return non-nil if LANGUAGE exists and is loadable. + +If DETAIL is non-nil, return (t . nil) when LANGUAGE is available, +(nil . DATA) when unavailable. DATA is the signal data of +`treesit-load-language-error'. */) + (Lisp_Object language, Lisp_Object detail) { CHECK_SYMBOL (language); ts_initialize (); Lisp_Object signal_symbol = Qnil; Lisp_Object signal_data = Qnil; if (ts_load_language(language, &signal_symbol, &signal_data) == NULL) - return Qnil; + { + if (NILP (detail)) + return Qnil; + else + return Fcons (Qnil, signal_data); + } else - return Qt; + { + if (NILP (detail)) + return Qt; + else + return Fcons (Qt, Qnil); + } } DEFUN ("treesit-language-version", @@ -2299,6 +2310,10 @@ syms_of_treesit (void) DEFSYM (Qhas_changes, "has-changes"); DEFSYM (Qhas_error, "has-error"); + DEFSYM (Qnot_found, "not-found"); + DEFSYM (Qsymbol_error, "symbol-error"); + DEFSYM (Qversion_mismatch, "version-mismatch"); + DEFSYM (Qtreesit_error, "treesit-error"); DEFSYM (Qtreesit_query_error, "treesit-query-error"); DEFSYM (Qtreesit_parse_error, "treesit-parse-error"); -- 2.39.2