branch: externals/matlab-mode commit 60665e66df72880da9b1ef60778a719decbce7c1 Author: John Ciolfi <john.ciolfi...@gmail.com> Commit: John Ciolfi <john.ciolfi...@gmail.com>
Add doc/matlab-tree-sitter.org --- doc/matlab-tree-sitter.org | 160 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) diff --git a/doc/matlab-tree-sitter.org b/doc/matlab-tree-sitter.org new file mode 100644 index 0000000000..b7070b3f5d --- /dev/null +++ b/doc/matlab-tree-sitter.org @@ -0,0 +1,160 @@ +# File: doc/matlab-tree-sitter.org + +# Copyright 2016-2025 Free Software Foundation, Inc. + +#+startup: showall +#+options: toc:nil + +#+title: MATLAB and Tree-Sitter +#+date: Jun-7-2025 + +If you search the web for tree-sitter Emacs, you'll see conflicting information on tree-sitter +because it is evolving quickly. tree-sitter is built into Emacs 30.1 and some of the older links are +for earlier versions. [[https://tree-sitter.github.io/tree-sitter/][tree-sitter]] shared libraries, libtree-sitter-LANGUAGE.so (.so on Linux, .dll +on Windows, .dylib on Mac) provide a syntax tree for Emacs: + +#+begin_example + + +---------+ +----------------------------+ + | | | | + | Emacs |<=========>| libtree-sitter-LANUGAGE.so | + | | | | + +---------+ +----------------------------+ + +#+end_example + +A syntax tree is a formal representation of the MATLAB program, e.g. + +#+begin_example + MATLAB program Syntax Tree + + c = a + b = + / \ + c + + a b +#+end_example + +*We need a matlab-ts-mode*. The current matlab-mode is classic Emacs major mode that uses Emacs' +built-in mechanisms for syntax highlighting, indentation, and other language-specific features, +relying on regular expressions and Emacs' internal parsing capabilities. Creating a new +matlab-ts=mode based on tree-sitter will enable improved color syntax for the language elements +(improved font-lock), improved editing/cursor movement, code folding, improved indentation, +etc. Howwever, to leverage the syntax tree, we need to create a new matlab-ts-mode, see [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Tree_002dsitter-Major-Modes.html][Emacs +manual, Developing major modes with tree-sitter]] and [[https://www.masteringemacs.org/article/lets-write-a-treesitter-major-mode][this article]]. matlab-ts-mode should also be +faster than the classic matlab-mode. The cost of using tree-sitter is that it will take more memory +for each matlab file, approximately 10 times the size of the file. The other cost will be in +deploying libtree-sitter-matlab.so, which at present is best built from source and this requires a +C11 compiler. + +* Using tree-sitter in Emacs 30.1 with matlab-mode + +We can use tree-sitter in Emacs to get improved font-lock and code-folding, though this is not +ideal. As mentioned above, creating a new matlab-ts-mode would be better. + +1. Install matlab tree-sitter + + Note to Windows Emacs users, see + + #+begin_example + 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): + #+end_example + + Notice, that I specified the =abi/14= branch. Emacs is using application binary interface, ABI, + version 14 and the current state of tree-sitter is version 15. If you install from the main + branch, you'll see /"Warning (treesit): The installed language grammar for matlab cannot be + located or has problems (version-mismatch): 15"/. The ABI version used by Emacs is obtained via + =M-: (treesit-library-abi-version)=. See + https://github.com/acristoffers/tree-sitter-matlab/issues/24 + + After installing matlab tree-sitter open a =*.m= and run =M-: (treesit-available-p)= which + should return =t=. + + +1. Make sure you have melpa available, i.e. your =~/.emacs= should contain: + + #+begin_src emacs-lisp + (require 'package) + (add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/")) + #+end_src + +2. Install the older tree-sitter package (needed to get tree-sitter-hl-mode and ts-fold), =M-x + list-packages= and then click on the following and install them: + + - tree-sitter + - tree-sitter-langs + + and these which are needed for ts-fold: + + - s + - fringe-helper + +3. Install ts-fold. The install uses https://github.com/radian-software/straight.el which isn't + provided with Emacs 30. To manually install, download the zip file and extract to some location, + e.g. ~/emacs-ts-fold, in Emacs + + #+begin_example + M-: (add-to-list 'load-path "~/emacs-ts-fold") + M-: (byte-recompile-directory "~/emacs-ts-fold" 0) + M-: (require 'ts-fold) + #+end_example + + and add to =~/.emacs= + + #+begin_src emacs-lisp + (add-to-list 'load-path "~/emacs-ts-fold") + (require 'ts-fold) + #+end_src + +4. Now the tree-sitter capabilities are available. For example, + + - Visit some_file.m + - M-x tree-sitter-mode + - M-x tree-sitter-hl-mode (for improved font-lock) + - Place the point on a 'function' keyword and then =M-x ts-fold-close= and + then =M-x ts-fold-open=. + +* treesit-fold with matlab-mode in Emacs 30.1 doesn't work + +1. Start with no customizations + + #+begin_src bash + rm -rf ~/.emacs.d + rm ~/.emacs + #+end_src + +3. Install tree-sitter-matlab + + #+begin_example + 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): + #+end_example + +4. Install treesit-fold + + treesit-fold from M-x list-packages + +5. Visit foo.m containing: + + #+begin_src matlab + function out = foo(in) + out = in + end + #+end_src + +Running =M-x treesit-fold-close= on the function keyword results in error: "Ignored, no tree-sitter + parser in current buffer"