|
| 1 | +# File: doc/matlab-tree-sitter.org |
| 2 | + |
| 3 | +# Copyright 2016-2025 Free Software Foundation, Inc. |
| 4 | + |
| 5 | +#+startup: showall |
| 6 | +#+options: toc:nil |
| 7 | + |
| 8 | +#+title: MATLAB and Tree-Sitter |
| 9 | +#+date: Jun-7-2025 |
| 10 | + |
| 11 | +If you search the web for tree-sitter Emacs, you'll see conflicting information on tree-sitter |
| 12 | +because it is evolving quickly. tree-sitter is built into Emacs 30.1 and some of the older links are |
| 13 | +for earlier versions. [[https://tree-sitter.github.io/tree-sitter/][tree-sitter]] shared libraries, libtree-sitter-LANGUAGE.so (.so on Linux, .dll |
| 14 | +on Windows, .dylib on Mac) provide a syntax tree for Emacs: |
| 15 | + |
| 16 | +#+begin_example |
| 17 | + |
| 18 | + +---------+ +----------------------------+ |
| 19 | + | | | | |
| 20 | + | Emacs |<=========>| libtree-sitter-LANUGAGE.so | |
| 21 | + | | | | |
| 22 | + +---------+ +----------------------------+ |
| 23 | + |
| 24 | +#+end_example |
| 25 | + |
| 26 | +A syntax tree is a formal representation of the MATLAB program, e.g. |
| 27 | + |
| 28 | +#+begin_example |
| 29 | + MATLAB program Syntax Tree |
| 30 | + |
| 31 | + c = a + b = |
| 32 | + / \ |
| 33 | + c + |
| 34 | + a b |
| 35 | +#+end_example |
| 36 | + |
| 37 | +*We need a matlab-ts-mode*. The current matlab-mode is classic Emacs major mode that uses Emacs' |
| 38 | +built-in mechanisms for syntax highlighting, indentation, and other language-specific features, |
| 39 | +relying on regular expressions and Emacs' internal parsing capabilities. Creating a new |
| 40 | +matlab-ts=mode based on tree-sitter will enable improved color syntax for the language elements |
| 41 | +(improved font-lock), improved editing/cursor movement, code folding, improved indentation, |
| 42 | +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 |
| 43 | +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 |
| 44 | +faster than the classic matlab-mode. The cost of using tree-sitter is that it will take more memory |
| 45 | +for each matlab file, approximately 10 times the size of the file. The other cost will be in |
| 46 | +deploying libtree-sitter-matlab.so, which at present is best built from source and this requires a |
| 47 | +C11 compiler. |
| 48 | + |
| 49 | +* Using tree-sitter in Emacs 30.1 with matlab-mode |
| 50 | + |
| 51 | +We can use tree-sitter in Emacs to get improved font-lock and code-folding, though this is not |
| 52 | +ideal. As mentioned above, creating a new matlab-ts-mode would be better. |
| 53 | + |
| 54 | +1. Install matlab tree-sitter |
| 55 | + |
| 56 | + Note to Windows Emacs users, see |
| 57 | + |
| 58 | + #+begin_example |
| 59 | + M-x treesit-install-language-grammar |
| 60 | + Language: matlab |
| 61 | + There is no recipe for matlab, do you want to build it interactively? (y or n) y |
| 62 | + Enter the URL of the Git repository of the language grammar: https://github.com/acristoffers/tree-sitter-matlab |
| 63 | + Enter the tag or branch (default: default branch): abi/14 |
| 64 | + Enter the subdirectory in which the parser.c file resides (default: "src"): |
| 65 | + Enter the C compiler to use (default: auto-detect): |
| 66 | + Enter the C++ compiler to use (default: auto-detect): |
| 67 | + Install to (default: ~/.emacs.d/tree-sitter): |
| 68 | + #+end_example |
| 69 | + |
| 70 | + Notice, that I specified the =abi/14= branch. Emacs is using application binary interface, ABI, |
| 71 | + version 14 and the current state of tree-sitter is version 15. If you install from the main |
| 72 | + branch, you'll see /"Warning (treesit): The installed language grammar for matlab cannot be |
| 73 | + located or has problems (version-mismatch): 15"/. The ABI version used by Emacs is obtained via |
| 74 | + =M-: (treesit-library-abi-version)=. See |
| 75 | + https://github.com/acristoffers/tree-sitter-matlab/issues/24 |
| 76 | + |
| 77 | + After installing matlab tree-sitter open a =*.m= and run =M-: (treesit-available-p)= which |
| 78 | + should return =t=. |
| 79 | + |
| 80 | + |
| 81 | +1. Make sure you have melpa available, i.e. your =~/.emacs= should contain: |
| 82 | + |
| 83 | + #+begin_src emacs-lisp |
| 84 | + (require 'package) |
| 85 | + (add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/")) |
| 86 | + #+end_src |
| 87 | + |
| 88 | +2. Install the older tree-sitter package (needed to get tree-sitter-hl-mode and ts-fold), =M-x |
| 89 | + list-packages= and then click on the following and install them: |
| 90 | + |
| 91 | + - tree-sitter |
| 92 | + - tree-sitter-langs |
| 93 | + |
| 94 | + and these which are needed for ts-fold: |
| 95 | + |
| 96 | + - s |
| 97 | + - fringe-helper |
| 98 | + |
| 99 | +3. Install ts-fold. The install uses https://github.com/radian-software/straight.el which isn't |
| 100 | + provided with Emacs 30. To manually install, download the zip file and extract to some location, |
| 101 | + e.g. ~/emacs-ts-fold, in Emacs |
| 102 | + |
| 103 | + #+begin_example |
| 104 | + M-: (add-to-list 'load-path "~/emacs-ts-fold") |
| 105 | + M-: (byte-recompile-directory "~/emacs-ts-fold" 0) |
| 106 | + M-: (require 'ts-fold) |
| 107 | + #+end_example |
| 108 | + |
| 109 | + and add to =~/.emacs= |
| 110 | + |
| 111 | + #+begin_src emacs-lisp |
| 112 | + (add-to-list 'load-path "~/emacs-ts-fold") |
| 113 | + (require 'ts-fold) |
| 114 | + #+end_src |
| 115 | + |
| 116 | +4. Now the tree-sitter capabilities are available. For example, |
| 117 | + |
| 118 | + - Visit some_file.m |
| 119 | + - M-x tree-sitter-mode |
| 120 | + - M-x tree-sitter-hl-mode (for improved font-lock) |
| 121 | + - Place the point on a 'function' keyword and then =M-x ts-fold-close= and |
| 122 | + then =M-x ts-fold-open=. |
| 123 | + |
| 124 | +* treesit-fold with matlab-mode in Emacs 30.1 doesn't work |
| 125 | + |
| 126 | +1. Start with no customizations |
| 127 | + |
| 128 | + #+begin_src bash |
| 129 | + rm -rf ~/.emacs.d |
| 130 | + rm ~/.emacs |
| 131 | + #+end_src |
| 132 | + |
| 133 | +3. Install tree-sitter-matlab |
| 134 | + |
| 135 | + #+begin_example |
| 136 | + M-x treesit-install-language-grammar |
| 137 | + Language: matlab |
| 138 | + There is no recipe for matlab, do you want to build it interactively? (y or n) y |
| 139 | + Enter the URL of the Git repository of the language grammar: https://github.com/acristoffers/tree-sitter-matlab |
| 140 | + Enter the tag or branch (default: default branch): abi/14 |
| 141 | + Enter the subdirectory in which the parser.c file resides (default: "src"): |
| 142 | + Enter the C compiler to use (default: auto-detect): |
| 143 | + Enter the C++ compiler to use (default: auto-detect): |
| 144 | + Install to (default: ~/.emacs.d/tree-sitter): |
| 145 | + #+end_example |
| 146 | + |
| 147 | +4. Install treesit-fold |
| 148 | + |
| 149 | + treesit-fold from M-x list-packages |
| 150 | + |
| 151 | +5. Visit foo.m containing: |
| 152 | + |
| 153 | + #+begin_src matlab |
| 154 | + function out = foo(in) |
| 155 | + out = in |
| 156 | + end |
| 157 | + #+end_src |
| 158 | + |
| 159 | +Running =M-x treesit-fold-close= on the function keyword results in error: "Ignored, no tree-sitter |
| 160 | + parser in current buffer" |
0 commit comments