branch: externals/matlab-mode
commit 207e4e379a3d537e6612fc80d677b0f91f4af141
Author: John Ciolfi <[email protected]>
Commit: John Ciolfi <[email protected]>

    Add matlab-ts-grammar-install
---
 doc/install-matlab-tree-sitter-grammar.org | 194 +++++++++++++++--------------
 matlab-ts-grammar-install.el               | 133 ++++++++++++++++++++
 2 files changed, 231 insertions(+), 96 deletions(-)

diff --git a/doc/install-matlab-tree-sitter-grammar.org 
b/doc/install-matlab-tree-sitter-grammar.org
index b2ff7de3cf..0769b44163 100644
--- a/doc/install-matlab-tree-sitter-grammar.org
+++ b/doc/install-matlab-tree-sitter-grammar.org
@@ -49,143 +49,145 @@ For Emacs 30, you need to build the MATLAB tree-sitter 
grammar for ABI 14 becaus
 version 14 of the tree-sitter application binary interface and as of Sep-2025, 
the latest
 tree-sitter ABI is 15. There are different methods for installing this.
 
-** Method 1 - Install from abi/14 branch
+** Method 1 - Install the Emacs-MATLAB-Mode pre-built matlab tree-sitter 
grammar
 
-  Oct-29-2025 matlab-ts-mode is known to work with matlab tree-sitter v1.2.3 
branch 
[[https://github.com/acristoffers/tree-sitter-matlab/tree/abi/14][abi/14]] at 
[[https://github.com/acristoffers/tree-sitter-matlab/tree/9a4e65df4bb08e2b019ca2ef16b2d8f3d95ce978][9a4e65d]].
+After installing the Emacs-MATLAB-Mode package,
 
-  + _Unix_
+: M-x matlab-ts-grammar-install
 
-    Install the C compiler if not installed.  When installing from source, you 
need to use the correct
-    compiler.
+This will download the pre-build matlab tree-sitter grammar from
+https://github.com/mathworks/Emacs-MATLAB-Mode/matlab-ts-bin and save to the
+tree-sitter subdirectory of `user-emacs-directory'. For example,
+=~/.emacs.d/tree-sitter/libtree-sitter-matlab.so= (=.dylib= on Mac, =.dll= on 
Windows).
 
-    Debian Emacs was built using gcc and you can get gcc via:
+Visit https://github.com/mathworks/Emacs-MATLAB-Mode/matlab-ts-bin to see what 
source was
+used to produce these binaries.
 
-    #+begin_src bash
-      sudo apt install gcc
-      gcc --version
-       # gcc (Debian 12.2.0-14+deb12u1) 12.2.0
-    #+end_src
+** Method 2 - Install from abi/14 branch
 
-    Next, ask Emacs to build the grammar using the ABI 14 branch
+Oct-29-2025 matlab-ts-mode is known to work with matlab tree-sitter v1.2.3 
branch 
[[https://github.com/acristoffers/tree-sitter-matlab/tree/abi/14][abi/14]] at 
[[https://github.com/acristoffers/tree-sitter-matlab/tree/9a4e65df4bb08e2b019ca2ef16b2d8f3d95ce978][9a4e65d]].
 
-    : emacs
-    : M-x treesit-install-language-grammar
-    : Language: matlab
-    : There is no recipe for matlab, do you want to build it interactively? (y 
or n) y
-    : Enter the URL of the Git repository of the language grammar: 
https://github.com/acristoffers/tree-sitter-matlab
-    : Enter the tag or branch (default: default branch): abi/14
-    : Enter the subdirectory in which the parser.c file resides (default: 
"src"):
-    : Enter the C compiler to use (default: auto-detect):
-    : Enter the C++ compiler to use (default: auto-detect):
-    : Install to (default: ~/.emacs.d/tree-sitter):
++ _Unix_
 
-  + _Windows_
+  Install the C compiler if not installed.  When installing from source, you 
need to use the correct
+  compiler.
 
-    Here we assume you've set HOME=C:\Users\YourUserName (corresponding to ~ 
within filenames in Emacs).
+  Debian Emacs was built using gcc and you can get gcc via:
 
-    1. Create %HOME%\emacs-projects\tree-sitter-matlab on the abi/14 branch:
+  #+begin_src bash
+    sudo apt install gcc
+    gcc --version
+     # gcc (Debian 12.2.0-14+deb12u1) 12.2.0
+  #+end_src
 
-       #+begin_src bash
-         cd %HOME%\emacs-projects
-         git clone https://github.com/acristoffers/tree-sitter-matlab.git
-         cd tree-sitter-matlab
-         git checkout abi/14
-       #+end_src
+  Next, ask Emacs to build the grammar using the ABI 14 branch
 
-    2. Install Visual Studio. The 
[[https://visualstudio.microsoft.com/vs/community/][community version]] should 
work. Select "Desktop development with C++".
+  : emacs
+  : M-x treesit-install-language-grammar
+  : Language: matlab
+  : There is no recipe for matlab, do you want to build it interactively? (y 
or n) y
+  : Enter the URL of the Git repository of the language grammar: 
https://github.com/acristoffers/tree-sitter-matlab
+  : Enter the tag or branch (default: default branch): abi/14
+  : Enter the subdirectory in which the parser.c file resides (default: "src"):
+  : Enter the C compiler to use (default: auto-detect):
+  : Enter the C++ compiler to use (default: auto-detect):
+  : Install to (default: ~/.emacs.d/tree-sitter):
 
-    3. Build
++ _Windows_
 
-       We run vcvars64.bat to put the compiler, cl.exe on the path. Adjust the 
location to vcvars64.bat
-       as needed per your installation.
+  Here we assume you've set HOME=C:\Users\YourUserName (corresponding to ~ 
within filenames in Emacs).
 
-       #+begin_src bash
-         mkdir %HOME%\.emacs.d\tree-sitter
-         cd %HOME%\emacs-projects\tree-sitter-matlab
-         "C:\Program Files\Microsoft Visual 
Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat"
-         cl /LD /I src\tree_sitter src\parser.c src\scanner.c /link 
/out:%HOME%\.emacs.d\tree-sitter\libtree-sitter-matlab.dll
-       #+end_src
+  1. Create %HOME%\emacs-projects\tree-sitter-matlab on the abi/14 branch:
 
-** Method 2 - Generate the grammar for ABI 14 and install
+     #+begin_src bash
+       cd %HOME%\emacs-projects
+       git clone https://github.com/acristoffers/tree-sitter-matlab.git
+       cd tree-sitter-matlab
+       git checkout abi/14
+     #+end_src
 
-  1. Install C/C++ compiler if not installed. See Method 2 for tips on 
installing the C/C++ compiler.
+  2. Install Visual Studio. The 
[[https://visualstudio.microsoft.com/vs/community/][community version]] should 
work. Select "Desktop development with C++".
 
-  2. Install JavaScript Node.js and npm
+  3. Build
 
-     - _Debian_
+     We run vcvars64.bat to put the compiler, cl.exe on the path. Adjust the 
location to vcvars64.bat
+     as needed per your installation.
 
-       #+begin_src bash
-         sudo apt update
-         sudo apt install nodejs npm
-         node --version
-         # v18.19.0
-       #+end_src
+     #+begin_src bash
+       mkdir %HOME%\.emacs.d\tree-sitter
+       cd %HOME%\emacs-projects\tree-sitter-matlab
+       "C:\Program Files\Microsoft Visual 
Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat"
+       cl /LD /I src\tree_sitter src\parser.c src\scanner.c /link 
/out:%HOME%\.emacs.d\tree-sitter\libtree-sitter-matlab.dll
+     #+end_src
 
-     - _Windows_
+** Method 3 - Generate the grammar for ABI 14 and install
 
-       See https://nodejs.org/ to install Node.js and npm.
+1. Install C/C++ compiler if not installed. See Method 2 for tips on 
installing the C/C++ compiler.
 
-  3. Download and extract the tree-sitter CLI, 
https://github.com/tree-sitter/tree-sitter/releases into some
-     location. For example, place it in:
+2. Install JavaScript Node.js and npm
 
-     : ~/emacs-projects/tree-sitter-cli/            (Linux)
-     : %HOME%\emacs-projects\tree-sitter-cli\       (Windows)
+   - _Debian_
 
-     Here we assume you've set HOME=C:\Users\YourUserName (corresponding to ~ 
within filenames in Emacs).
+     #+begin_src bash
+       sudo apt update
+       sudo apt install nodejs npm
+       node --version
+       # v18.19.0
+     #+end_src
 
-  4. Generate the grammar for ABI 14:
+   - _Windows_
 
-     #+begin_src bash
-       cd ~/emacs-projects           # Unix
-       cd %HOME%\emacs-projects      # Windows
-       git clone https://github.com/acristoffers/tree-sitter-matlab.git
+     See https://nodejs.org/ to install Node.js and npm.
 
-       cd tree-sitter-matlab
-       ~/emacs-projects/tree-sitter-cli/tree-sitter generate --abi 14          
  # Unix
-       %HOME%/emacs-projects/tree-sitter-cli/tree-sitter generate --abi 14     
  # Windows
-     #+end_src
+3. Download and extract the tree-sitter CLI, 
https://github.com/tree-sitter/tree-sitter/releases into some
+   location. For example, place it in:
 
-  5. Build
+   : ~/emacs-projects/tree-sitter-cli/            (Linux)
+   : %HOME%\emacs-projects\tree-sitter-cli\       (Windows)
 
-     - _Unix_
+   Here we assume you've set HOME=C:\Users\YourUserName (corresponding to ~ 
within filenames in Emacs).
 
-       Ask Emacs to build it:
+4. Generate the grammar for ABI 14:
 
-       : emacs
-       : M-x treesit-install-language-grammar
-       : Language: matlab
-       : There is no recipe for matlab, do you want to build it interactively? 
(y or n) y
-       : Enter the URL of the Git repository of the language grammar: 
~/emacs-projects/tree-sitter-matlab
-       : Enter the tag or branch (default: default branch):
-       : Enter the subdirectory in which the parser.c file resides (default: 
"src"):
-       : Enter the C compiler to use (default: auto-detect):
-       : Enter the C++ compiler to use (default: auto-detect):
-       : Install to (default: ~/.emacs.d/tree-sitter):
+   #+begin_src bash
+     cd ~/emacs-projects           # Unix
+     cd %HOME%\emacs-projects      # Windows
+     git clone https://github.com/acristoffers/tree-sitter-matlab.git
 
-       Alternatively, you can manually build it. For example, on Linux
+     cd tree-sitter-matlab
+     ~/emacs-projects/tree-sitter-cli/tree-sitter generate --abi 14            
# Unix
+     %HOME%/emacs-projects/tree-sitter-cli/tree-sitter generate --abi 14       
# Windows
+   #+end_src
 
-       #+begin_src bash
-       cd tree-sitter-matlab/src
-       cc -fPIC -O -c -I. parser.c
-       cc -fPIC -O -c -I. scanner.c
-       cc -fPIC -shared parser.o scanner.o -o 
~/.emacs.d/tree-sitter/libtree-sitter-matlab.so
-       #+end_src
+5. Build
 
-     - _Windows_
+   - _Unix_
 
-       Follow the same Windows build step as in Method 2.
+     Ask Emacs to build it:
 
-** Method 3 - Install pre-built binaries
+     : emacs
+     : M-x treesit-install-language-grammar
+     : Language: matlab
+     : There is no recipe for matlab, do you want to build it interactively? 
(y or n) y
+     : Enter the URL of the Git repository of the language grammar: 
~/emacs-projects/tree-sitter-matlab
+     : Enter the tag or branch (default: default branch):
+     : Enter the subdirectory in which the parser.c file resides (default: 
"src"):
+     : Enter the C compiler to use (default: auto-detect):
+     : Enter the C++ compiler to use (default: auto-detect):
+     : Install to (default: ~/.emacs.d/tree-sitter):
 
-  *Does not work* as of Sep-2025 because the grammar build is too old. Please 
use one of the other
-  methods.
+     Alternatively, you can manually build it. For example, on Linux
 
-  Install the pre-built binaries from 
http://github.com/emacs-tree-sitter/tree-sitter-langs
-  using the following after installing the MATLAB package from 
[[file:../README.org][MELPA]]:
+     #+begin_src bash
+     cd tree-sitter-matlab/src
+     cc -fPIC -O -c -I. parser.c
+     cc -fPIC -O -c -I. scanner.c
+     cc -fPIC -shared parser.o scanner.o -o 
~/.emacs.d/tree-sitter/libtree-sitter-matlab.so
+     #+end_src
 
-  :  M-x matlab-ts-langs-install
+   - _Windows_
 
-  and install matlab (and other languages tree-sitter shared objects if you'd 
like).
+     Follow the same Windows build step as in Method 2.
 
 * Setup Emacs to use the MATLAB tree-sitter grammar
 
diff --git a/matlab-ts-grammar-install.el b/matlab-ts-grammar-install.el
new file mode 100644
index 0000000000..d315dff295
--- /dev/null
+++ b/matlab-ts-grammar-install.el
@@ -0,0 +1,133 @@
+;;; matlab-ts-langs-install.el --- -*- lexical-binding: t -*-
+
+;; Copyright (C) 2025 Free Software Foundation, Inc.
+;;
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License
+;; as published by the Free Software Foundation; either version 3
+;; of the License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses>.
+
+;;; Commentary:
+;;
+;; Download
+;;   ~/.emacs.d/tree-sitter/libtree-sitter-LANGUAGES.so (or .dll or .dylib)
+;; from
+;;   https://github.com/mathworks/Emacs-MATLAB-Mode/matlab-ts-bin/
+;;
+
+;;; Code:
+
+(require 'url)
+
+(defun matlab--ts-grammar-arch-and-shared-lib ()
+  "Return ARCH/libtree-sitter-matlab.SLIB_EXT.
+ARCH is the same as the MATLAB computer('arch') command result."
+  (let ((result (pcase system-type
+                 ('darwin (cond
+                            ((string-prefix-p "aarch64" system-configuration)
+                             "maca64/libtree-sitter-matlab.dylib")
+                            ((string-prefix-p "x86_64" system-configuration)
+                             "maca64/libtree-sitter-matlab.dylib")))
+                 ('gnu/linux (cond
+                               ((string-prefix-p "x86_64" system-configuration)
+                                "glnxa64/libtree-sitter-matlab.so")))
+                  ('windows-nt "win64/libtree-sitter-matlab.dll"))))
+    (when (not result)
+      (error "Unsupported system-type %s, system-configuration %s" system-type
+             system-configuration))
+    result))
+
+(defun matlab--ts-grammar-download-url (branch)
+  "Get the download tree-sitter-matlab URL for BRANCH."
+
+  ;; Use GitHub REST API to get the download URL
+  (let* ((bin-url (concat 
"https://api.github.com/repos/mathworks/Emacs-MATLAB-mode/contents/";
+                          "matlab-ts-bin?ref=" branch))
+         (raw-url-start (concat 
"https://raw.githubusercontent.com/mathworks/Emacs-MATLAB-Mode/";
+                                branch "/matlab-ts-bin"))
+          
+        (bin-buf (url-retrieve-synchronously bin-url))
+         (versions '())
+         latest-ver-date-num
+         latest-ver
+        download-url)
+
+    (with-current-buffer bin-buf
+      (let ((entries (json-read-from-string (cadr (split-string 
(buffer-string) "\n\n" t)))))
+        (cl-loop for entry across entries do
+                 (let ((rel-file (alist-get 'path entry))) ;; 
matlab-ts-bin/FILE
+                   ;; Have YYYYMMDD-SHA1
+                   (when (string-match 
"^matlab-ts-bin/\\(\\([0-9]+\\)-[0-9a-z]+\\)$" rel-file)
+                     (let ((ver (match-string 1 rel-file))
+                           (date-num (string-to-number (match-string 2 
rel-file))))
+                       (when (or (not latest-ver)
+                                 (> date-num latest-ver-date-num))
+                         (setq latest-ver ver
+                               latest-ver-date-num date-num))
+                       (push ver versions)))))))
+
+    (when (not latest-ver)
+      (error "Failed to get release versions from %s" bin-url))
+
+    (let ((ver-to-download (completing-read (concat
+                                             "Version to download (" 
latest-ver " is latest): ")
+                                            versions nil t latest-ver))
+         (arch-slib (matlab--ts-grammar-arch-and-shared-lib)))
+
+      (setq download-url (concat raw-url-start "/" ver-to-download "/" 
arch-slib)))
+      
+    (kill-buffer bin-buf)
+    download-url))
+
+;;;###autoload
+(defun matlab-ts-grammar-install (&optional dir branch)
+  "Download the latest matlab tree-sitter grammar build to DIR.
+
+Optional BRANCH defaults to \"default\".
+
+This will create
+   DIR/libtree-sitter-matlab.SLIB-EXT
+shared libraries where SLIB-EXT = so on Linux, dll on Windows, or dylib on Mac.
+
+DIR defaults to tree-sitter subdirectory of `user-emacs-directory' which is
+typically ~/.emacs.d/tree-sitter/.
+
+The matlab tree-sitter grammar is required for `matlab-ts-mode'."
+
+  (interactive)
+
+  (when (< emacs-major-version 30)
+    (error "Unsupported Emacs version, %d" emacs-major-version))
+
+  (when (not branch)
+    (setq branch "default"))
+  
+  (if (not dir)
+      (progn
+        (setq dir (concat user-emacs-directory "tree-sitter"))
+        (when (not (file-directory-p dir))
+          (make-directory dir t)))
+    ;; Else dir was provided and it must exist
+    (when (not (file-directory-p dir))
+      (error "%s is not an existing directory" dir)))
+
+  (setq dir (file-name-as-directory (file-truename dir)))
+
+  (let* ((download-url (matlab--ts-grammar-download-url branch))
+         (grammar-slib (concat dir (file-name-nondirectory download-url))))
+    (when (y-or-n-p (format "Download %s\nto %s/? " download-url grammar-slib))
+      (url-copy-file download-url grammar-slib t)
+      (message "Downloaded %s" grammar-slib))))
+
+(provide 'matlab-ts-grammar-install)
+;;; matlab-ts-grammar-install.el ends here
+
+

Reply via email to