aboutsummaryrefslogtreecommitdiffstats
path: root/src/treesit.c
diff options
context:
space:
mode:
authorYuan Fu2024-08-27 22:31:42 -0700
committerYuan Fu2024-09-12 01:04:11 -0700
commit2a75693f24a631b0a2a366bdce1ca5cb0c38d215 (patch)
tree75fa8b78ee467aa729632ec9169d03aac83d6350 /src/treesit.c
parentf283144658259f209efdef78c576b43832c9c479 (diff)
downloademacs-2a75693f24a631b0a2a366bdce1ca5cb0c38d215.tar.gz
emacs-2a75693f24a631b0a2a366bdce1ca5cb0c38d215.zip
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.
Diffstat (limited to 'src/treesit.c')
-rw-r--r--src/treesit.c71
1 files changed, 58 insertions, 13 deletions
diff --git a/src/treesit.c b/src/treesit.c
index 0ba6c733d64..8c586109b2d 100644
--- a/src/treesit.c
+++ b/src/treesit.c
@@ -22,6 +22,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
22#include <config.h> 22#include <config.h>
23#include "lisp.h" 23#include "lisp.h"
24#include "buffer.h" 24#include "buffer.h"
25#include "coding.h"
25 26
26#include "treesit.h" 27#include "treesit.h"
27 28
@@ -541,6 +542,15 @@ treesit_debug_print_parser_list (char *msg, Lisp_Object parser)
541 542
542/*** Loading language library */ 543/*** Loading language library */
543 544
545struct treesit_loaded_lang
546{
547 /* The language object, or NULL if the language failed to load. */
548 TSLanguage *lang;
549 /* The absolute file name of the shared library, or NULL if access
550 failed. */
551 const char *filename;
552};
553
544/* Translate a symbol treesit-<lang> to a C name treesit_<lang>. */ 554/* Translate a symbol treesit-<lang> to a C name treesit_<lang>. */
545static void 555static void
546treesit_symbol_to_c_name (char *symbol_name) 556treesit_symbol_to_c_name (char *symbol_name)
@@ -625,7 +635,7 @@ treesit_load_language_push_for_each_suffix (Lisp_Object lib_base_name,
625 635
626 If error occurs, return NULL and fill SIGNAL_SYMBOL and SIGNAL_DATA 636 If error occurs, return NULL and fill SIGNAL_SYMBOL and SIGNAL_DATA
627 with values suitable for xsignal. */ 637 with values suitable for xsignal. */
628static TSLanguage * 638static struct treesit_loaded_lang
629treesit_load_language (Lisp_Object language_symbol, 639treesit_load_language (Lisp_Object language_symbol,
630 Lisp_Object *signal_symbol, Lisp_Object *signal_data) 640 Lisp_Object *signal_symbol, Lisp_Object *signal_data)
631{ 641{
@@ -676,6 +686,7 @@ treesit_load_language (Lisp_Object language_symbol,
676 dynlib_handle_ptr handle; 686 dynlib_handle_ptr handle;
677 const char *error; 687 const char *error;
678 Lisp_Object error_list = Qnil; 688 Lisp_Object error_list = Qnil;
689 struct treesit_loaded_lang loaded_lang = { NULL, NULL };
679 690
680 tail = path_candidates; 691 tail = path_candidates;
681 error = NULL; 692 error = NULL;
@@ -700,7 +711,7 @@ treesit_load_language (Lisp_Object language_symbol,
700 mismatch. */ 711 mismatch. */
701 *signal_symbol = Qtreesit_load_language_error; 712 *signal_symbol = Qtreesit_load_language_error;
702 *signal_data = Fcons (Qnot_found, Fnreverse (error_list)); 713 *signal_data = Fcons (Qnot_found, Fnreverse (error_list));
703 return NULL; 714 return loaded_lang;
704 } 715 }
705 716
706 /* Load TSLanguage. */ 717 /* Load TSLanguage. */
@@ -722,7 +733,7 @@ treesit_load_language (Lisp_Object language_symbol,
722 { 733 {
723 *signal_symbol = Qtreesit_load_language_error; 734 *signal_symbol = Qtreesit_load_language_error;
724 *signal_data = list2 (Qsymbol_error, build_string (error)); 735 *signal_data = list2 (Qsymbol_error, build_string (error));
725 return NULL; 736 return loaded_lang;
726 } 737 }
727 TSLanguage *lang = (*langfn) (); 738 TSLanguage *lang = (*langfn) ();
728 739
@@ -735,9 +746,14 @@ treesit_load_language (Lisp_Object language_symbol,
735 *signal_symbol = Qtreesit_load_language_error; 746 *signal_symbol = Qtreesit_load_language_error;
736 *signal_data = list2 (Qversion_mismatch, 747 *signal_data = list2 (Qversion_mismatch,
737 make_fixnum (ts_language_version (lang))); 748 make_fixnum (ts_language_version (lang)));
738 return NULL; 749 return loaded_lang;
739 } 750 }
740 return lang; 751
752 const char *sym;
753 dynlib_addr ((void (*)) langfn, &loaded_lang.filename, &sym);
754
755 loaded_lang.lang = lang;
756 return loaded_lang;
741} 757}
742 758
743DEFUN ("treesit-language-available-p", Ftreesit_language_available_p, 759DEFUN ("treesit-language-available-p", Ftreesit_language_available_p,
@@ -754,7 +770,9 @@ If DETAIL is non-nil, return (t . nil) when LANGUAGE is available,
754 treesit_initialize (); 770 treesit_initialize ();
755 Lisp_Object signal_symbol = Qnil; 771 Lisp_Object signal_symbol = Qnil;
756 Lisp_Object signal_data = Qnil; 772 Lisp_Object signal_data = Qnil;
757 if (treesit_load_language (language, &signal_symbol, &signal_data) == NULL) 773 struct treesit_loaded_lang loaded_lang
774 = treesit_load_language (language, &signal_symbol, &signal_data);
775 if (loaded_lang.lang == NULL)
758 { 776 {
759 if (NILP (detail)) 777 if (NILP (detail))
760 return Qnil; 778 return Qnil;
@@ -800,9 +818,9 @@ Return nil if a grammar library for LANGUAGE is not available. */)
800 { 818 {
801 Lisp_Object signal_symbol = Qnil; 819 Lisp_Object signal_symbol = Qnil;
802 Lisp_Object signal_data = Qnil; 820 Lisp_Object signal_data = Qnil;
803 TSLanguage *ts_language = treesit_load_language (language, 821 struct treesit_loaded_lang lang
804 &signal_symbol, 822 = treesit_load_language (language, &signal_symbol, &signal_data);
805 &signal_data); 823 TSLanguage *ts_language = lang.lang;
806 if (ts_language == NULL) 824 if (ts_language == NULL)
807 return Qnil; 825 return Qnil;
808 uint32_t version = ts_language_version (ts_language); 826 uint32_t version = ts_language_version (ts_language);
@@ -810,6 +828,30 @@ Return nil if a grammar library for LANGUAGE is not available. */)
810 } 828 }
811} 829}
812 830
831/* This function isn't documented in the manual since it's mainly for
832 debugging. */
833DEFUN ("treesit-grammar-location", Ftreesit_grammar_location,
834 Streesit_grammar_location,
835 1, 1, 0,
836 doc: /* Return the absolute file name of the grammar file for LANGUAGE.
837
838If LANGUAGE isn't loaded yet, load it first. If the language can't be
839loaded or the file name couldn't be determined, return nil. */)
840 (Lisp_Object language)
841{
842 CHECK_SYMBOL (language);
843
844 Lisp_Object signal_symbol = Qnil;
845 Lisp_Object signal_data = Qnil;
846 struct treesit_loaded_lang lang
847 = treesit_load_language (language, &signal_symbol, &signal_data);
848
849 if (!lang.lang || !lang.filename) return Qnil;
850
851 return DECODE_FILE (make_unibyte_string (lang.filename,
852 strlen (lang.filename)));
853}
854
813 855
814/*** Parsing functions */ 856/*** Parsing functions */
815 857
@@ -1401,8 +1443,9 @@ treesit_ensure_query_compiled (Lisp_Object query, Lisp_Object *signal_symbol,
1401 Lisp_Object language = XTS_COMPILED_QUERY (query)->language; 1443 Lisp_Object language = XTS_COMPILED_QUERY (query)->language;
1402 /* This is the main reason why we compile query lazily: to avoid 1444 /* This is the main reason why we compile query lazily: to avoid
1403 loading languages early. */ 1445 loading languages early. */
1404 TSLanguage *treesit_lang = treesit_load_language (language, signal_symbol, 1446 struct treesit_loaded_lang lang
1405 signal_data); 1447 = treesit_load_language (language, signal_symbol, signal_data);
1448 TSLanguage *treesit_lang = lang.lang;
1406 if (treesit_lang == NULL) 1449 if (treesit_lang == NULL)
1407 return NULL; 1450 return NULL;
1408 1451
@@ -1573,8 +1616,9 @@ an indirect buffer. */)
1573 Lisp_Object signal_symbol = Qnil; 1616 Lisp_Object signal_symbol = Qnil;
1574 Lisp_Object signal_data = Qnil; 1617 Lisp_Object signal_data = Qnil;
1575 TSParser *parser = ts_parser_new (); 1618 TSParser *parser = ts_parser_new ();
1576 TSLanguage *lang = treesit_load_language (language, &signal_symbol, 1619 struct treesit_loaded_lang loaded_lang
1577 &signal_data); 1620 = treesit_load_language (language, &signal_symbol, &signal_data);
1621 TSLanguage *lang = loaded_lang.lang;
1578 if (lang == NULL) 1622 if (lang == NULL)
1579 xsignal (signal_symbol, signal_data); 1623 xsignal (signal_symbol, signal_data);
1580 /* We check language version when loading a language, so this should 1624 /* 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. */);
4369 defsubr (&Streesit_language_available_p); 4413 defsubr (&Streesit_language_available_p);
4370 defsubr (&Streesit_library_abi_version); 4414 defsubr (&Streesit_library_abi_version);
4371 defsubr (&Streesit_language_abi_version); 4415 defsubr (&Streesit_language_abi_version);
4416 defsubr (&Streesit_grammar_location);
4372 4417
4373 defsubr (&Streesit_parser_p); 4418 defsubr (&Streesit_parser_p);
4374 defsubr (&Streesit_node_p); 4419 defsubr (&Streesit_node_p);