Subject: bug#78754: Tree-sitter started versioning their shared library filenames

From: Peter Oliver <[email-masked]>
Date: Wed, 11 Jun 2025 13:34:11 +0100 (BST)

On Wed, 11 Jun 2025, Stéphane Marks wrote:

> On Wed, Jun 11, 2025 at 7:48 AM Yuan Fu <[email-masked]> wrote:
>
>       > On Jun 10, 2025, at 11:52 AM, Peter Oliver
>       <[email-masked]> wrote:
>       >
>       > Recent Makefiles instead install to
>       /usr/lib/libtree-sitter-foo.so.14.0 or
>       /usr/lib/libtree-sitter-foo.so.15.0 (where 14 or 15 is the
>       Tree-sitter ABI version, taken from LANGUAGE_VERSION in the
>       parser’s src/parser.c).  Emacs should look in these places as
>       well.
>       >
>
>       Thanks for the heads-up! I pushed a change to emacs-30 to look
>       for all supported versions. Eg, if the tree-sitter library
>       supports language version 13 to 15, Emacs will try to look for
>       libtree-sitter-foo.so.13.0, libtree-sitter-foo.so.14.0, and
>       libtree-sitter-foo.so.15.0.
> 
> This is indeed a welcome improvement.  Unless I'm reading it wrong, it looks
> like the ABI tests go 0.0 forward through 15 (modulo what's intrinsically
> supported).  Should the tests be reversed so the most recent ABI takes
> precedence?

Seems reasonable to me.

Additionally, I think we only need to check .0 only if
TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION is less than 15.  Anything
newer than that should be using the new file-naming scheme.

See attached patch.

-- 
Peter Oliver

From ead8a0d68226d7d8f0bc7a4602a4a1321782af0b Mon Sep 17 00:00:00 2001
From: Peter Oliver <[email-masked]>
Date: Wed, 11 Jun 2025 13:00:41 +0100
Subject: [PATCH] Search for Tree-sitter parsers in descending language version
 order

* src/treesit.c (treesit_load_language_push_for_each_suffix): Reverse
order of checked parser library versions.  Additionally, skip version
0 if parsers that could plausibly use it are no-longer compatible with
our libtree-sitter.  Never try 0.0.
---
 src/treesit.c | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/src/treesit.c b/src/treesit.c
index 45d1bc58b06..3ae265d168f 100644
--- a/src/treesit.c
+++ b/src/treesit.c
@@ -603,22 +603,13 @@ treesit_load_language_push_for_each_suffix (Lisp_Object lib_base_name,
       Lisp_Object candidate1 = concat2 (lib_base_name, XCAR (suffixes));
 #ifndef WINDOWSNT
       /* On Posix hosts, support libraries named with ABI version
-         numbers.  Originally tree-sitter grammars are always versioned
-         at 0.0, so we first try that.  For more details, see
-         https://lists.gnu.org/archive/html/emacs-devel/2023-04/msg00386.html.  */
-      Lisp_Object candidate2 = concat2 (candidate1, Vtreesit_str_dot_0);
-      Lisp_Object candidate3 = concat2 (candidate2, Vtreesit_str_dot_0);
-
-      *path_candidates = Fcons (candidate3, *path_candidates);
-      *path_candidates = Fcons (candidate2, *path_candidates);
-
-      /* Since 2025, tree-sitter grammars use their supported
-         TREE_SITTER_LANGUAGE_VERSION as the major version.  So we need
-         to try all the version supported by the tree-sitter library
-         too.  (See bug#78754)  */
-      for (int version = TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION;
-	   version <= TREE_SITTER_LANGUAGE_VERSION;
-	   version++)
+         numbers.  Since 2025, tree-sitter grammars use their supported
+         TREE_SITTER_LANGUAGE_VERSION as the major version, so first try
+         all the version supported by the tree-sitter library.  (See
+         bug#78754) */
+      for (int version = TREE_SITTER_LANGUAGE_VERSION;
+	   version >= TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION;
+	   version--)
 	{
 	  char ext[16]; // 16 should be enough until the end of universe.
 	  snprintf ((char *) &ext, 16, ".%d.0", version);
@@ -626,6 +617,15 @@ treesit_load_language_push_for_each_suffix (Lisp_Object lib_base_name,
 						     build_string (ext));
 	  *path_candidates = Fcons (versioned_candidate, *path_candidates);
 	}
+
+  /* Originally, tree-sitter grammars ware always versioned at 0, so
+     also try that.  For more details, see
+     https://lists.gnu.org/archive/html/emacs-devel/2023-04/msg00386.html.  */
+      if (TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION < 15)
+	{
+	  Lisp_Object candidate2 = concat2 (candidate1, Vtreesit_str_dot_0);
+	  *path_candidates = Fcons (candidate2, *path_candidates);
+	}
 #endif
       *path_candidates = Fcons (candidate1, *path_candidates);
     }
-- 
2.49.0