branch: externals/matlab-mode commit 2a75ba07a451eeaf8f75babb9a9f3fc54c3287be Author: John Ciolfi <john.ciolfi...@gmail.com> Commit: John Ciolfi <john.ciolfi...@gmail.com>
matlab-ts-mode: add syntax-table and comment setup --- contributing/treesit-mode-how-to.org | 51 +++- matlab-ts-mode.el | 269 ++++++++++++++------- tests/test-matlab-ts-mode-font-lock.el | 2 +- tests/test-matlab-ts-mode-indent.el | 12 +- .../syntax_table_test1.m | 14 ++ .../syntax_table_test1_expected.txt | 252 +++++++++++++++++++ tests/test-matlab-ts-mode-syntax-table.el | 114 +++++++++ 7 files changed, 615 insertions(+), 99 deletions(-) diff --git a/contributing/treesit-mode-how-to.org b/contributing/treesit-mode-how-to.org index bc2b747d12..d26f94ce22 100644 --- a/contributing/treesit-mode-how-to.org +++ b/contributing/treesit-mode-how-to.org @@ -20,19 +20,53 @@ #+title: Tree-Sitter How To #+author: John Ciolfi -#+date: Jun-13-2025 +#+date: Jun-22-2025 * TODO - [ ] Add how to setup comments and syntax table - [ ] Add indent assert rule - [ ] Add font-lock test -- [ ] Add indent test +- [ ] Add indent tests +- [ ] Add feature-based test for indent + - (directory-files-recursively DIR "\\.m$") + - On each file, check parse tree for ERROR nodes and see if it really has an error by running + matlab/bin/arch/mlint and looking for "Parse error". If no parse error, then flag these as + issues with the matlab tree-sitter. + - Indent the file to see if matlab-ts-mode--indent-assert-rule fires * Guide to building a tree-sitter mode -This is a set of notes that I'm taking as I develop matlab-ts-mode.el with the goal of this -becoming a guide for writting a tree-sitter mode for Emacs 30 or later. +This is a set of notes that I'm taking as I develop matlab-ts-mode.el with the goal of this becoming +a guide for writting a tree-sitter mode. + +This guide assumes was written when using Emacs 30.1 and the goal is to create *LANGUAGE-ts-mode* +for /file.lang/ files. + +In creating a tree-sitter mode for a programming lanugage, you have two options. Releverage an +old-style existing mode via =(define-derived-mode LANGUAGE-ts-mode OLD-LANGUAGE-mode "LANGUAGE" +...)= and overriding items such as font-lock and indent. The other approach is +to create a new LANGUAGE-ts-mode based on prog-mode which we recommend to eliminate coupling between +the old-style mode and the new tree-sitter mode. + +#+begin_src emacs-lisp + (define-derived-mode LANGUAGE-ts-mode prog-mode "LANGUAGE" ...) +#+end_src + +To create the mode, we recommend following this order: + +1. *Font-lock*. We suggest doing this first, so that /file.lang/ is syntatically colored when + viewing it. +2. *Indent*. Next we setup indentation so that you can edit /file.lang/ easily. +3. *Syntax table and comments*. +4. *Navigation*. Setup treesit-defun-type-regexp and treesit-defun-name-function to enable navigation + features like beginning-of-defun and end-of-defun +5. *Imenu* + +** Documentation + + - [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Parsing-Program-Source.html][Emacs manual: Parsing Program Source]] + - [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Parser_002dbased-Indentation.html][Emacs manual: Parser-based Indentation]] * Syntax trees and queries @@ -71,11 +105,6 @@ tree is roughly 10 times the text size of the program being analyzed. However, t tree sitter are highly accuracte and fast syntax coloring (font-lock), indentation, code navigation via syntatic expressions, etc. -* Documentation - - - [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Parsing-Program-Source.html][Emacs manual: Parsing Program Source]] - - [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Parser_002dbased-Indentation.html][Emacs manual: Parser-based Indentation]] - * libtree-sitter-LANGUAGE.EXT Place the tree-sitter language library in =~/.emacs.d/tree-sitter/libtree-sitter-LANGUAGE.EXT= @@ -154,8 +183,8 @@ You should now be able to use: * Font-lock -Queries are needed to identify syntax tree nodes to fontify. See -https://www.gnu.org/software/emacs/manual/html_node/elisp/Pattern-Matching.html +Queries are needed to identify syntax tree nodes to fontify. See [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Pattern-Matching.html][Emacs manual - Pattern Matching +Tree-sitter Nodes]]. You can use =M-x treesit-explore-mode= to see the nodes of the syntax tree. diff --git a/matlab-ts-mode.el b/matlab-ts-mode.el index 95ad09ca0c..c88f89801c 100644 --- a/matlab-ts-mode.el +++ b/matlab-ts-mode.el @@ -70,6 +70,103 @@ (const :tag "Standard" 3) (const :tag "Standard plus parse errors" 4))) +;;-----------------------;; +;; Section: Syntax table ;; +;;-----------------------;; + +(defvar matlab-ts-mode--syntax-table + (let ((st (make-syntax-table (standard-syntax-table)))) + ;; Comment Handling: + ;; 1. Single line comments: % text (single char start), + ;; note includes "%{ text" + ;; 2. Multiline comments: %{ + ;; lines + ;; %} + ;; 3. Ellipsis line continuations comments: "... optional text" + ;; are handled in `matlab-ts-mode--syntax-propertize' + (modify-syntax-entry ?% "< 13" st) + (modify-syntax-entry ?{ "(} 2c" st) + (modify-syntax-entry ?} "){ 4c" st) + (modify-syntax-entry ?\n ">" st) + + ;; String Handling: + ;; Single quoted string (character vector): 'text' + ;; Double-quoted string: "text" + ;; Transpose: varname' + ;; Quoted quotes: ' don''t ' or " this "" " + ;; Unterminated Char V: ' text + (modify-syntax-entry ?' "\"" st) + (modify-syntax-entry ?\" "\"" st) + + ;; Words and Symbols: + (modify-syntax-entry ?_ "_" st) + + ;; Punctuation: + (modify-syntax-entry ?\\ "." st) + (modify-syntax-entry ?\t " " st) + (modify-syntax-entry ?+ "." st) + (modify-syntax-entry ?- "." st) + (modify-syntax-entry ?* "." st) + (modify-syntax-entry ?/ "." st) + (modify-syntax-entry ?= "." st) + (modify-syntax-entry ?< "." st) + (modify-syntax-entry ?> "." st) + (modify-syntax-entry ?& "." st) + (modify-syntax-entry ?| "." st) + + ;; Parenthetical blocks: + ;; Note: these are in standard syntax table, repeated here for completeness. + (modify-syntax-entry ?\( "()" st) + (modify-syntax-entry ?\) ")(" st) + (modify-syntax-entry ?\[ "(]" st) + (modify-syntax-entry ?\] ")[" st) + (modify-syntax-entry ?{ "(}" st) + (modify-syntax-entry ?} "){" st) + + st) + "The matlab-ts-mode syntax table.") + +(defun matlab-ts-mode--put-char-category (pos category) + "At character POS, put text proerty CATEGORY." + (when (not (eobp)) + (put-text-property pos (1+ pos) 'category category) + (put-text-property pos (1+ pos) 'mcm t))) + +(defmacro matlab-ts-mode--syntax-symbol (symbol syntax doc) + "Create a new SYMBOL with DOC used as a text property category with SYNTAX." + (declare (indent defvar) (debug (sexp form sexp)) (doc-string 3)) + `(progn (defconst ,symbol ,syntax ,doc) + (put ',symbol 'syntax-table ,symbol))) + +;; In the Syntax Table descriptors, "<" is for comments +(matlab-ts-mode--syntax-symbol matlab-ts-mode--ellipsis-syntax (string-to-syntax "<") + "Syntax placed on ellipsis to treat them as comments.") + +(defun matlab-ts-mode--syntax-propertize (&optional start end) + "Scan region between START and END to add properties. +If region is not specified, scan the whole buffer. +This will mark ellipsis line continuation's + ... optional text +as comments which is how they are treated by MATLAB." + (save-match-data ;; avoid 'Syntax Checking transmuted the match-data' + (save-excursion + ;; Scan region, but always expand to beginning of line + (goto-char (or start (point-min))) + (beginning-of-line) + + ;; Edits can change what properties characters can have so remove ours and reapply + (remove-text-properties (point) (save-excursion (goto-char (or end (point-max))) + (end-of-line) (point)) + '(category nil mcm nil)) + + ;; Tell Emacs that ellipsis (...) line continuations are comments. + (while (and (not (>= (point) (or end (point-max)))) (not (eobp))) + (if (treesit-search-forward-goto (treesit-node-at (point)) + (rx bol "line_continuation" eol) + t) ;; goto start of: ... optional text + (matlab-ts-mode--put-char-category (point) 'matlab-ts-mode--ellipsis-syntax) + (goto-char (point-max))))))) + ;;--------------------;; ;; Section: font-lock ;; ;;--------------------;; @@ -187,13 +284,13 @@ START and END specify the region to be fontified." (defvar matlab-ts-mode--font-lock-settings (treesit-font-lock-rules - ;; Comments and line continuation: ... optional text + ;; F-Rule: Comments and line continuation: ... optional text :language 'matlab :feature 'comment '((comment) @font-lock-comment-face (line_continuation) @font-lock-comment-face) - ;; Special comments that override normal comment font + ;; F-Rule: special comments that override normal comment font :language 'matlab :feature 'comment :override t @@ -203,12 +300,12 @@ START and END specify the region to be fontified." (function_definition (comment) @matlab-ts-mode--doc-comment-capture) ;; doc help comments (class_definition (comment) @matlab-ts-mode--doc-comment-capture)) ;; doc help comments - ;; ;; Keywords: if, else, etc. + ;; F-Rule: keywords: if, else, etc. :language 'matlab :feature 'keyword `([,@matlab-ts-mode--keywords] @font-lock-keyword-face) - ;; function/classdef + ;; F-Rule: function/classdef and items definiting them, e.g. the function arguments :language 'matlab :feature 'definition '((function_definition name: (identifier) @font-lock-function-name-face) @@ -237,21 +334,21 @@ START and END specify the region to be fontified." (attribute (identifier) @font-lock-type-face "=" (identifier) @font-lock-builtin-face) (attribute (identifier) @font-lock-type-face)) - ;; Strings + ;; F-Rule: strings "double quote" and 'single quote' :language 'matlab :feature 'string '((string_content) @font-lock-string-face ((string_content) ["\"" "'"]) @matlab-ts-string-delimiter-face (string ["\"" "'"] @matlab-ts-string-delimiter-face)) - ;; Transpose uses "'" after an identifier, e.g. for matrix A we tranpose it via: A' since "'" is - ;; also used as a string, we use a different face for transpose and put it under the string - ;; category. + ;; F-Rule: transpose uses "'" after an identifier, e.g. for matrix A we tranpose it via: A' + ;; since "'" is also used as a string, we use a different face for transpose and put it under + ;; the string category. :language 'matlab :feature 'string '((postfix_operator "'" @font-lock-function-name-face)) - ;; Types, e.g. int32() + ;; F-Rule: Types, e.g. int32() :language 'matlab :feature 'type `((function_call name: (identifier) @@ -262,24 +359,24 @@ START and END specify the region to be fontified." eol)) @font-lock-type-face))) - ;; Constant numbers + ;; F-Rule: Constant literal numbers, e.g. 1234 :language 'matlab :feature 'number '((number) @font-lock-constant-face) - ;; Brackets + ;; F-Rule: Brackets :language 'matlab :feature 'bracket '((["(" ")" "[" "]" "{" "}"]) @font-lock-bracket-face) - ;; Delimiters + ;; F-Rule: Delimiters, e.g. semicolon :language 'matlab :feature 'delimiter '((["," "." ";" ":" "@" "?"]) @font-lock-delimiter-face) - ;; Syntax errors + ;; F-Rule: Syntax errors :language 'matlab - :feature 'error + :feature 'syntax-error :override t '((ERROR) @font-lock-warning-face) @@ -328,7 +425,7 @@ expression." (p-node (treesit-node-at prev-real-line-bol))) (string-match-p prev-real-line-node-type (or (treesit-node-type p-node) "")))))) -(defvar tmp-debug-indent-rule +(defvar matlab-ts--indent-debug-rule '((lambda (node parent bol) (message "-->N:%S P:%S BOL:%S GP:%S NPS:%S" node parent bol @@ -355,12 +452,10 @@ expression." (defvar matlab-ts-mode--indent-rules `((matlab - ;; ,tmp-debug-indent-rule - - ;; Rule: classdef's, function's, or code for a script that is at the top-level + ;; I-Rule: classdef's, function's, or code for a script that is at the top-level ((parent-is ,(rx bol "source_file" eol)) column-0 0) - ;; Rule: within a function/classdef doc block comment "%{ ... %}"? + ;; I-Rule: within a function/classdef doc block comment "%{ ... %}"? ((lambda (node parent bol &rest _) (and (not node) (string= "comment" (treesit-node-type parent)) @@ -369,7 +464,7 @@ expression." (matlab-ts-mode--is-doc-comment parent (treesit-node-parent parent)))) parent 2) - ;; Rule: function/classdef doc comment? + ;; I-Rule: function/classdef doc comment? ((lambda (node parent &rest _) (or (and (string= "comment" (or (treesit-node-type node) "")) (matlab-ts-mode--is-doc-comment node parent)) @@ -378,7 +473,7 @@ expression." (matlab-ts-mode--is-doc-comment parent (treesit-node-parent parent))))) parent 0) - ;; Rule: within a code block comment "%{ ... %}"? + ;; I-Rule: within a code block comment "%{ ... %}"? ((lambda (node parent bol &rest _) (and (not node) (string= "comment" (treesit-node-type parent)) @@ -387,7 +482,7 @@ expression." parent 2) - ;; Rule: last line of code block coment "%{ ... %}"? + ;; I-Rule: last line of code block coment "%{ ... %}"? ((lambda (node parent bol &rest _) (and (not node) (string= "comment" (treesit-node-type parent)) @@ -396,141 +491,141 @@ expression." parent 0) - ;; Rule: switch case and otherwise statements + ;; I-Rule: switch case and otherwise statements ((node-is ,(rx bol (or "case_clause" "otherwise_clause") eol)) parent ,matlab-ts-mode--switch-indent-level) - ;; Rule: first line of code witin a switch case or otherwise statement, node is block + ;; I-Rule: first line of code witin a switch case or otherwise statement, node is block ((parent-is ,(rx bol (or "case_clause" "otherwise_clause") eol)) parent ,matlab-ts-mode--switch-indent-level) - ;; Rule: nested functions + ;; I-Rule: nested functions ((n-p-gp ,(rx bol "function_definition" eol) ,(rx bol "block" eol) ,(rx bol "function_definition" eol)) parent 0) - ;; Rule: constructs within classdef or function's. + ;; I-Rule: constructs within classdef or function's. ((node-is ,(rx bol (or "arguments_statement" "block" "enumeration" "enum" "methods" "events" "function_definition" "property" "properties") eol)) parent ,matlab-ts-mode--indent-level) - ;; Rule: elseif, else, catch, end statements go back to parent level + ;; I-Rule: elseif, else, catch, end statements go back to parent level ((node-is ,(rx bol (or "elseif_clause" "else_clause" "catch_clause" "end") eol)) parent 0) - ;; Rule: code in if, for, methods, function, arguments statements + ;; I-Rule: code in if, for, methods, function, arguments statements ((parent-is ,(rx bol (or "if_statement" "for_statement" "while_statement" "methods" "events" "enumeration" "function_definition" "arguments_statement") eol)) parent ,matlab-ts-mode--indent-level) - ;; Rule: function a<RET> - ;; end + ;; I-Rule: function a<RET> + ;; end ((n-p-gp nil ,(rx bol "\n" eol) ,(rx bol (or "function_definition") eol)) grand-parent ,matlab-ts-mode--indent-level) - ;; Rule: case 10<RET> + ;; I-Rule: case 10<RET> ((n-p-gp nil ,(rx bol "\n" eol) ,(rx bol (or "switch_statement" "case_clause" "otherwise_clause") eol)) grand-parent ,matlab-ts-mode--switch-indent-level) - ;; Rule: if condition1 || ... | if condition1 + condition2 == ... - ;; <TAB> condition2 || ... | 2770000 ... + ;; I-Rule: if condition1 || ... | if condition1 + condition2 == ... + ;; <TAB> condition2 || ... | 2770000 ... ((parent-is ,(rx bol (or "boolean_operator" "comparison_operator") eol)) parent 0) - ;; Rule: elseif ... - ;; <TAB> condition2 || ... + ;; I-Rule: elseif ... + ;; <TAB> condition2 || ... ((parent-is ,(rx bol (or "else_clause" "elseif_clause") eol)) parent ,matlab-ts-mode--indent-level) - - ;; Rule: if a ... + + ;; I-Rule: if a ... ;; <TAB> ((n-p-gp nil ,(rx bol "\n" eol) ,(rx bol (or "if_statement" "else_clause" "elseif_clause" ) eol)) grand-parent ,matlab-ts-mode--indent-level) - ;; Rule: disp(myMatrix(1: ... - ;; <TAB> end)); + ;; I-Rule: disp(myMatrix(1: ... + ;; <TAB> end)); ((parent-is ,(rx bol "range" eol)) parent 0) - ;; Rule: try<RET> | catch<RET> + ;; I-Rule: try<RET> | catch<RET> ((parent-is ,(rx bol (or "try_statement" "catch_clause") eol)) parent ,matlab-ts-mode--indent-level) - ;; Rule: function a - ;; x = 1; - ;; <TAB> y = 2; + ;; I-Rule: function a + ;; x = 1; + ;; <TAB> y = 2; ((parent-is ,(rx bol "block" eol)) parent 0) - ;; Rule: "switch var" and we type RET after the var + ;; I-Rule: "switch var" and we type RET after the var (,(matlab-ts-mode--prev-real-line-is (rx bol "\n" eol) (rx bol "switch" eol)) ,#'matlab-ts-mode--prev-real-line ,matlab-ts-mode--switch-indent-level) - ;; Rule: "function foo()" and we type RET after the ")" + ;; I-Rule: "function foo()" and we type RET after the ")" (,(matlab-ts-mode--prev-real-line-is nil (rx bol "function" eol)) ,#'matlab-ts-mode--prev-real-line ,matlab-ts-mode--indent-level) - ;; Rule: a = ... - ;; <TAB> 1; + ;; I-Rule: a = ... + ;; <TAB> 1; ((parent-is ,(rx bol "assignment" eol)) parent ,matlab-ts-mode--indent-level) - ;; Rule: a = 2 * ... - ;; <TAB> 1; + ;; I-Rule: a = 2 * ... + ;; <TAB> 1; ((parent-is ,(rx bol "binary_operator" eol)) parent 0) - ;; Rule: a = ( ... | a = [ ... | a = { ... - ;; 1 ... | 1 ... | 1 ... - ;; <TAB> ); | ]; | }; + ;; I-Rule: a = ( ... | a = [ ... | a = { ... + ;; 1 ... | 1 ... | 1 ... + ;; <TAB> ); | ]; | }; ((node-is ,(rx bol (or ")" "]" "}") eol)) parent 0) - ;; Rule: a = ( ... - ;; <TAB> 1 ... + ;; I-Rule: a = ( ... + ;; <TAB> 1 ... ((parent-is ,(rx bol "parenthesis" eol)) parent 1) - ;; Rule: a = [ ... | a = { ... - ;; <TAB> 2 ... | 2 ... + ;; I-Rule: a = [ ... | a = { ... + ;; <TAB> 2 ... | 2 ... ((parent-is ,(rx bol (or "matrix" "cell") eol)) parent ,matlab-ts-mode--array-indent-level) - ;; Rule: function [ ... | function name ( ... - ;; <TAB> a, ... % comment | a, ... % comment + ;; I-Rule: function [ ... | function name ( ... + ;; <TAB> a, ... % comment | a, ... % comment ((parent-is ,(rx bol (or "multioutput_variable" "function_arguments") eol)) parent 1) - ;; Rule: a = [ 2 ... | function a ... - ;; <TAB> 1 ... | = fcn + ;; I-Rule: a = [ 2 ... | function a ... + ;; <TAB> 1 ... | = fcn ((parent-is ,(rx bol (or "row" "function_output") eol)) parent 0) - ;; Rule: a = ... - ;; <TAB> 1; + ;; I-Rule: a = ... + ;; <TAB> 1; ((n-p-gp nil nil ,(rx bol "assignment" eol)) grand-parent ,matlab-ts-mode--indent-level) - ;; Rule: a = my_function(1, ... - ;; <TAB> 2, ... + ;; I-Rule: a = my_function(1, ... + ;; <TAB> 2, ... ((parent-is ,(rx bol "arguments" eol)) parent 0) - ;; Rule: my_function( ... - ;; <TAB> 1, ... + ;; I-Rule: my_function( ... + ;; <TAB> 1, ... ((node-is ,(rx bol "arguments" eol)) parent ,matlab-ts-mode--indent-level) - ;; Rule: function indent_tab_between_fcns | function indent_tab_in_fcn - ;; end | disp('here') - ;; <TAB> | - ;; function b | end - ;; end | + ;; I-Rule: function indent_tab_between_fcns | function indent_tab_in_fcn + ;; end | disp('here') + ;; <TAB> | + ;; function b | end + ;; end | ((lambda (node parent bol) (and (not node) (string= (treesit-node-type parent) "\n"))) grand-parent 0) - ;; Rule: In an empty line, string, etc. just maintain indent - ;; switch in - ;; case 10 - ;; disp('11'); + ;; I-Rule: In an empty line, string, etc. just maintain indent + ;; switch in + ;; case 10 + ;; disp('11'); ;; <TAB> (no-node ,#'matlab-ts-mode--prev-real-line 0) - ;; Rule: Assert if no rule matched and asserts are enabled. + ;; I-Rule: Assert if no rule matched and asserts are enabled. ,matlab-ts-mode--indent-assert-rule )) "Tree-sitter indent rules for `matlab-ts-mode'.") @@ -542,12 +637,19 @@ expression." (when (treesit-ready-p 'matlab) (treesit-parser-create 'matlab) + ;; Syntax table - think of this as a "language character descriptor". It tells us what + ;; characters belong to word like things giving us movement commands e.g. C-M-f, matching + ;; parens, `show-paren-mode', etc. + (set-syntax-table matlab-ts-mode--syntax-table) + (setq-local syntax-propertize-function #'matlab-ts-mode--syntax-propertize) + ;; TODO: check other items in matlab--syntax-propertize, i.e. command-dual + ;; Comments - ;; TODO: M-; on code comments, then a 2nd M-; doesn't uncomment - ;; likely need to also set up the syntax table. (setq-local comment-start "%") (setq-local comment-end "") (setq-local comment-start-skip "%\\s-+") + ;; TODO - page-delimiter, paragraph-start, etc. from matlab-mode + ;; TODO function end handling ;; TODO add strings to syntax table? @@ -571,11 +673,16 @@ expression." '((comment definition) (keyword string type) (number bracket delimiter) - ( error))) + (syntax-error))) ;; Indent - (setq-local indent-tabs-mode nil ;; for consistency between Unix and Windows we don't use TABs. - treesit-simple-indent-rules matlab-ts-mode--indent-rules) + (setq-local indent-tabs-mode nil) ;; for consistency between Unix and Windows we don't use TABs. + (setq-local treesit-simple-indent-rules + (if treesit--indent-verbose ;; add debugging print as first rule? + (list (append `,(list (caar matlab-ts-mode--indent-rules)) + (list matlab-ts--indent-debug-rule) + (cdar matlab-ts-mode--indent-rules))) + matlab-ts-mode--indent-rules)) (treesit-major-mode-setup))) diff --git a/tests/test-matlab-ts-mode-font-lock.el b/tests/test-matlab-ts-mode-font-lock.el index 6a5a514b4f..2809c29e22 100644 --- a/tests/test-matlab-ts-mode-font-lock.el +++ b/tests/test-matlab-ts-mode-font-lock.el @@ -1,6 +1,6 @@ ;;; test-matlab-ts-mode-font-lock.el --- Test matlab-ts-mode font-lock -*- lexical-binding: t -*- ;; -;; Copyright Free Software Foundation +;; Copyright 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 diff --git a/tests/test-matlab-ts-mode-indent.el b/tests/test-matlab-ts-mode-indent.el index 60e87a631e..f1d744eb74 100644 --- a/tests/test-matlab-ts-mode-indent.el +++ b/tests/test-matlab-ts-mode-indent.el @@ -48,7 +48,7 @@ (defvar test-matlab-ts-mode-indent (cons "test-matlab-ts-mode-indent" (test-matlab-ts-mode-indent-files))) -(defun trim () +(defun test-matlab-ts-mode-indent--trim () "Trim trailing whitespace and lines." (setq buffer-file-coding-system 'utf-8-unix) (let ((delete-trailing-lines t)) @@ -87,7 +87,7 @@ EXPECTED content in EXPECTED-FILE." (parent (and node (treesit-node-parent node)))) (when (string= (treesit-node-type parent) "ERROR") (insert " "))) - + (call-interactively #'indent-for-tab-command) ;; TAB on code just added ;; While next line in our original contents is a newline insert "\n" @@ -101,7 +101,7 @@ EXPECTED content in EXPECTED-FILE." (call-interactively #'indent-for-tab-command)) (forward-line)) - (trim) + (test-matlab-ts-mode-indent--trim) (let ((typing-got (buffer-substring (point-min) (point-max)))) (set-buffer-modified-p nil) @@ -123,7 +123,7 @@ If M-FILE (NAME.m) is not provided, loop comparing all For debugging, you can run with a specified NAME.m, M-: (test-matlab-ts-mode-font-lock \"test-matlab-ts-mode-indent-files/NAME.m\")" - + (let* ((m-files (if m-file (progn (setq m-file (file-truename m-file)) @@ -142,7 +142,7 @@ For debugging, you can run with a specified NAME.m, (message "START: test-matlab-ts-mode-indent %s" m-file) (find-file m-file) (indent-region (point-min) (point-max)) - (trim) + (test-matlab-ts-mode-indent--trim) (let ((got (buffer-substring (point-min) (point-max))) (got-file (concat expected-file "~"))) (set-buffer-modified-p nil) @@ -158,7 +158,7 @@ For debugging, you can run with a specified NAME.m, (when expected ;; expected-file exists? (test-matlab-ts-mode-indent--typing m-file expected expected-file))) - + (message "PASS: test-matlab-ts-mode-indent %s" m-file))) "success") diff --git a/tests/test-matlab-ts-mode-syntax-table-files/syntax_table_test1.m b/tests/test-matlab-ts-mode-syntax-table-files/syntax_table_test1.m new file mode 100644 index 0000000000..97fb8d9075 --- /dev/null +++ b/tests/test-matlab-ts-mode-syntax-table-files/syntax_table_test1.m @@ -0,0 +1,14 @@ +function syntax_table_test1 +% help comment + + % code comment + x = "double quote string"; + y = 'double quote string'; + x = [ + 1 2; ... + 3 4; ... comment + ]; + x = x'; + x = x''; + y = x(2, 2); +end diff --git a/tests/test-matlab-ts-mode-syntax-table-files/syntax_table_test1_expected.txt b/tests/test-matlab-ts-mode-syntax-table-files/syntax_table_test1_expected.txt new file mode 100644 index 0000000000..7f92a8d4c7 --- /dev/null +++ b/tests/test-matlab-ts-mode-syntax-table-files/syntax_table_test1_expected.txt @@ -0,0 +1,252 @@ +Line:1: function syntax_table_test1 + f: (0 nil nil nil nil nil 0 nil nil nil nil) + u: (0 nil 1 nil nil nil 0 nil nil nil nil) + n: (0 nil 1 nil nil nil 0 nil nil nil nil) + c: (0 nil 1 nil nil nil 0 nil nil nil nil) + t: (0 nil 1 nil nil nil 0 nil nil nil nil) + i: (0 nil 1 nil nil nil 0 nil nil nil nil) + o: (0 nil 1 nil nil nil 0 nil nil nil nil) + n: (0 nil 1 nil nil nil 0 nil nil nil nil) + : (0 nil 1 nil nil nil 0 nil nil nil nil) + s: (0 nil 1 nil nil nil 0 nil nil nil nil) + y: (0 nil 10 nil nil nil 0 nil nil nil nil) + n: (0 nil 10 nil nil nil 0 nil nil nil nil) + t: (0 nil 10 nil nil nil 0 nil nil nil nil) + a: (0 nil 10 nil nil nil 0 nil nil nil nil) + x: (0 nil 10 nil nil nil 0 nil nil nil nil) + _: (0 nil 10 nil nil nil 0 nil nil nil nil) + t: (0 nil 10 nil nil nil 0 nil nil nil nil) + a: (0 nil 10 nil nil nil 0 nil nil nil nil) + b: (0 nil 10 nil nil nil 0 nil nil nil nil) + l: (0 nil 10 nil nil nil 0 nil nil nil nil) + e: (0 nil 10 nil nil nil 0 nil nil nil nil) + _: (0 nil 10 nil nil nil 0 nil nil nil nil) + t: (0 nil 10 nil nil nil 0 nil nil nil nil) + e: (0 nil 10 nil nil nil 0 nil nil nil nil) + s: (0 nil 10 nil nil nil 0 nil nil nil nil) + t: (0 nil 10 nil nil nil 0 nil nil nil nil) + 1: (0 nil 10 nil nil nil 0 nil nil nil nil) + \n: (0 nil 10 nil nil nil 0 nil nil nil nil) +Line:2: % help comment + %: (0 nil 10 nil nil nil 0 nil nil nil nil) + : (0 nil 10 nil t nil 0 nil 29 nil 327691) + h: (0 nil 10 nil t nil 0 nil 29 nil nil) + e: (0 nil 10 nil t nil 0 nil 29 nil nil) + l: (0 nil 10 nil t nil 0 nil 29 nil nil) + p: (0 nil 10 nil t nil 0 nil 29 nil nil) + : (0 nil 10 nil t nil 0 nil 29 nil nil) + c: (0 nil 10 nil t nil 0 nil 29 nil nil) + o: (0 nil 10 nil t nil 0 nil 29 nil nil) + m: (0 nil 10 nil t nil 0 nil 29 nil nil) + m: (0 nil 10 nil t nil 0 nil 29 nil nil) + e: (0 nil 10 nil t nil 0 nil 29 nil nil) + n: (0 nil 10 nil t nil 0 nil 29 nil nil) + t: (0 nil 10 nil t nil 0 nil 29 nil nil) + \n: (0 nil 10 nil t nil 0 nil 29 nil nil) +Line:3: + \n: (0 nil 10 nil nil nil 0 nil nil nil nil) +Line:4: % code comment + : (0 nil 10 nil nil nil 0 nil nil nil nil) + : (0 nil 10 nil nil nil 0 nil nil nil nil) + : (0 nil 10 nil nil nil 0 nil nil nil nil) + : (0 nil 10 nil nil nil 0 nil nil nil nil) + %: (0 nil 10 nil nil nil 0 nil nil nil nil) + : (0 nil 10 nil t nil 0 nil 49 nil 327691) + c: (0 nil 10 nil t nil 0 nil 49 nil nil) + o: (0 nil 10 nil t nil 0 nil 49 nil nil) + d: (0 nil 10 nil t nil 0 nil 49 nil nil) + e: (0 nil 10 nil t nil 0 nil 49 nil nil) + : (0 nil 10 nil t nil 0 nil 49 nil nil) + c: (0 nil 10 nil t nil 0 nil 49 nil nil) + o: (0 nil 10 nil t nil 0 nil 49 nil nil) + m: (0 nil 10 nil t nil 0 nil 49 nil nil) + m: (0 nil 10 nil t nil 0 nil 49 nil nil) + e: (0 nil 10 nil t nil 0 nil 49 nil nil) + n: (0 nil 10 nil t nil 0 nil 49 nil nil) + t: (0 nil 10 nil t nil 0 nil 49 nil nil) + \n: (0 nil 10 nil t nil 0 nil 49 nil nil) +Line:5: x = "double quote string"; + : (0 nil 10 nil nil nil 0 nil nil nil nil) + : (0 nil 10 nil nil nil 0 nil nil nil nil) + : (0 nil 10 nil nil nil 0 nil nil nil nil) + : (0 nil 10 nil nil nil 0 nil nil nil nil) + x: (0 nil 10 nil nil nil 0 nil nil nil nil) + : (0 nil 68 nil nil nil 0 nil nil nil nil) + =: (0 nil 68 nil nil nil 0 nil nil nil nil) + : (0 nil 68 nil nil nil 0 nil nil nil nil) + ": (0 nil 68 nil nil nil 0 nil nil nil nil) + d: (0 nil 68 34 nil nil 0 nil 72 nil nil) + o: (0 nil 68 34 nil nil 0 nil 72 nil nil) + u: (0 nil 68 34 nil nil 0 nil 72 nil nil) + b: (0 nil 68 34 nil nil 0 nil 72 nil nil) + l: (0 nil 68 34 nil nil 0 nil 72 nil nil) + e: (0 nil 68 34 nil nil 0 nil 72 nil nil) + : (0 nil 68 34 nil nil 0 nil 72 nil nil) + q: (0 nil 68 34 nil nil 0 nil 72 nil nil) + u: (0 nil 68 34 nil nil 0 nil 72 nil nil) + o: (0 nil 68 34 nil nil 0 nil 72 nil nil) + t: (0 nil 68 34 nil nil 0 nil 72 nil nil) + e: (0 nil 68 34 nil nil 0 nil 72 nil nil) + : (0 nil 68 34 nil nil 0 nil 72 nil nil) + s: (0 nil 68 34 nil nil 0 nil 72 nil nil) + t: (0 nil 68 34 nil nil 0 nil 72 nil nil) + r: (0 nil 68 34 nil nil 0 nil 72 nil nil) + i: (0 nil 68 34 nil nil 0 nil 72 nil nil) + n: (0 nil 68 34 nil nil 0 nil 72 nil nil) + g: (0 nil 68 34 nil nil 0 nil 72 nil nil) + ": (0 nil 68 34 nil nil 0 nil 72 nil nil) + ;: (0 nil 72 nil nil nil 0 nil nil nil nil) + \n: (0 nil 72 nil nil nil 0 nil nil nil nil) +Line:6: y = 'double quote string'; + : (0 nil 72 nil nil nil 0 nil nil nil nil) + : (0 nil 72 nil nil nil 0 nil nil nil nil) + : (0 nil 72 nil nil nil 0 nil nil nil nil) + : (0 nil 72 nil nil nil 0 nil nil nil nil) + y: (0 nil 72 nil nil nil 0 nil nil nil nil) + : (0 nil 99 nil nil nil 0 nil nil nil nil) + =: (0 nil 99 nil nil nil 0 nil nil nil nil) + : (0 nil 99 nil nil nil 0 nil nil nil nil) + ': (0 nil 99 nil nil nil 0 nil nil nil nil) + d: (0 nil 99 39 nil nil 0 nil 103 nil nil) + o: (0 nil 99 39 nil nil 0 nil 103 nil nil) + u: (0 nil 99 39 nil nil 0 nil 103 nil nil) + b: (0 nil 99 39 nil nil 0 nil 103 nil nil) + l: (0 nil 99 39 nil nil 0 nil 103 nil nil) + e: (0 nil 99 39 nil nil 0 nil 103 nil nil) + : (0 nil 99 39 nil nil 0 nil 103 nil nil) + q: (0 nil 99 39 nil nil 0 nil 103 nil nil) + u: (0 nil 99 39 nil nil 0 nil 103 nil nil) + o: (0 nil 99 39 nil nil 0 nil 103 nil nil) + t: (0 nil 99 39 nil nil 0 nil 103 nil nil) + e: (0 nil 99 39 nil nil 0 nil 103 nil nil) + : (0 nil 99 39 nil nil 0 nil 103 nil nil) + s: (0 nil 99 39 nil nil 0 nil 103 nil nil) + t: (0 nil 99 39 nil nil 0 nil 103 nil nil) + r: (0 nil 99 39 nil nil 0 nil 103 nil nil) + i: (0 nil 99 39 nil nil 0 nil 103 nil nil) + n: (0 nil 99 39 nil nil 0 nil 103 nil nil) + g: (0 nil 99 39 nil nil 0 nil 103 nil nil) + ': (0 nil 99 39 nil nil 0 nil 103 nil nil) + ;: (0 nil 103 nil nil nil 0 nil nil nil nil) + \n: (0 nil 103 nil nil nil 0 nil nil nil nil) +Line:7: x = [ + : (0 nil 103 nil nil nil 0 nil nil nil nil) + : (0 nil 103 nil nil nil 0 nil nil nil nil) + : (0 nil 103 nil nil nil 0 nil nil nil nil) + : (0 nil 103 nil nil nil 0 nil nil nil nil) + x: (0 nil 103 nil nil nil 0 nil nil nil nil) + : (0 nil 130 nil nil nil 0 nil nil nil nil) + =: (0 nil 130 nil nil nil 0 nil nil nil nil) + : (0 nil 130 nil nil nil 0 nil nil nil nil) + [: (0 nil 130 nil nil nil 0 nil nil nil nil) + \n: (1 134 nil nil nil nil 0 nil nil (134) nil) +Line:8: 1 2; ... + : (1 134 nil nil nil nil 0 nil nil (134) nil) + : (1 134 nil nil nil nil 0 nil nil (134) nil) + : (1 134 nil nil nil nil 0 nil nil (134) nil) + : (1 134 nil nil nil nil 0 nil nil (134) nil) + : (1 134 nil nil nil nil 0 nil nil (134) nil) + : (1 134 nil nil nil nil 0 nil nil (134) nil) + : (1 134 nil nil nil nil 0 nil nil (134) nil) + : (1 134 nil nil nil nil 0 nil nil (134) nil) + : (1 134 nil nil nil nil 0 nil nil (134) nil) + : (1 134 nil nil nil nil 0 nil nil (134) nil) + 1: (1 134 nil nil nil nil 0 nil nil (134) nil) + : (1 134 146 nil nil nil 0 nil nil (134) nil) + 2: (1 134 146 nil nil nil 0 nil nil (134) nil) + ;: (1 134 148 nil nil nil 0 nil nil (134) nil) + : (1 134 148 nil nil nil 0 nil nil (134) nil) + .: (1 134 148 nil nil nil 0 nil nil (134) nil) + .: (1 134 148 nil t nil 0 nil 151 (134) nil) + .: (1 134 148 nil t nil 0 nil 151 (134) nil) + \n: (1 134 148 nil t nil 0 nil 151 (134) nil) +Line:9: 3 4; ... comment + : (1 134 148 nil nil nil 0 nil nil (134) nil) + : (1 134 148 nil nil nil 0 nil nil (134) nil) + : (1 134 148 nil nil nil 0 nil nil (134) nil) + : (1 134 148 nil nil nil 0 nil nil (134) nil) + : (1 134 148 nil nil nil 0 nil nil (134) nil) + : (1 134 148 nil nil nil 0 nil nil (134) nil) + : (1 134 148 nil nil nil 0 nil nil (134) nil) + : (1 134 148 nil nil nil 0 nil nil (134) nil) + : (1 134 148 nil nil nil 0 nil nil (134) nil) + : (1 134 148 nil nil nil 0 nil nil (134) nil) + 3: (1 134 148 nil nil nil 0 nil nil (134) nil) + : (1 134 165 nil nil nil 0 nil nil (134) nil) + 4: (1 134 165 nil nil nil 0 nil nil (134) nil) + ;: (1 134 167 nil nil nil 0 nil nil (134) nil) + : (1 134 167 nil nil nil 0 nil nil (134) nil) + .: (1 134 167 nil nil nil 0 nil nil (134) nil) + .: (1 134 167 nil t nil 0 nil 170 (134) nil) + .: (1 134 167 nil t nil 0 nil 170 (134) nil) + : (1 134 167 nil t nil 0 nil 170 (134) nil) + c: (1 134 167 nil t nil 0 nil 170 (134) nil) + o: (1 134 167 nil t nil 0 nil 170 (134) nil) + m: (1 134 167 nil t nil 0 nil 170 (134) nil) + m: (1 134 167 nil t nil 0 nil 170 (134) nil) + e: (1 134 167 nil t nil 0 nil 170 (134) nil) + n: (1 134 167 nil t nil 0 nil 170 (134) nil) + t: (1 134 167 nil t nil 0 nil 170 (134) nil) + \n: (1 134 167 nil t nil 0 nil 170 (134) nil) +Line:10: ]; + : (1 134 167 nil nil nil 0 nil nil (134) nil) + : (1 134 167 nil nil nil 0 nil nil (134) nil) + : (1 134 167 nil nil nil 0 nil nil (134) nil) + : (1 134 167 nil nil nil 0 nil nil (134) nil) + : (1 134 167 nil nil nil 0 nil nil (134) nil) + : (1 134 167 nil nil nil 0 nil nil (134) nil) + : (1 134 167 nil nil nil 0 nil nil (134) nil) + : (1 134 167 nil nil nil 0 nil nil (134) nil) + ]: (1 134 167 nil nil nil 0 nil nil (134) nil) + ;: (0 nil 134 nil nil nil 0 nil nil nil nil) + \n: (0 nil 134 nil nil nil 0 nil nil nil nil) +Line:11: x = x'; + : (0 nil 134 nil nil nil 0 nil nil nil nil) + : (0 nil 134 nil nil nil 0 nil nil nil nil) + : (0 nil 134 nil nil nil 0 nil nil nil nil) + : (0 nil 134 nil nil nil 0 nil nil nil nil) + x: (0 nil 134 nil nil nil 0 nil nil nil nil) + : (0 nil 197 nil nil nil 0 nil nil nil nil) + =: (0 nil 197 nil nil nil 0 nil nil nil nil) + : (0 nil 197 nil nil nil 0 nil nil nil nil) + x: (0 nil 197 nil nil nil 0 nil nil nil nil) + ': (0 nil 201 nil nil nil 0 nil nil nil nil) + ;: (0 nil 201 nil nil nil 0 nil nil nil nil) + \n: (0 nil 201 nil nil nil 0 nil nil nil nil) +Line:12: x = x''; + : (0 nil 201 nil nil nil 0 nil nil nil nil) + : (0 nil 201 nil nil nil 0 nil nil nil nil) + : (0 nil 201 nil nil nil 0 nil nil nil nil) + : (0 nil 201 nil nil nil 0 nil nil nil nil) + x: (0 nil 201 nil nil nil 0 nil nil nil nil) + : (0 nil 209 nil nil nil 0 nil nil nil nil) + =: (0 nil 209 nil nil nil 0 nil nil nil nil) + : (0 nil 209 nil nil nil 0 nil nil nil nil) + x: (0 nil 209 nil nil nil 0 nil nil nil nil) + ': (0 nil 213 nil nil nil 0 nil nil nil nil) + ': (0 nil 213 nil nil nil 0 nil nil nil nil) + ;: (0 nil 213 t nil nil 0 nil 215 nil nil) + \n: (0 nil 213 t nil nil 0 nil 215 nil nil) +Line:13: y = x(2, 2); + : (0 nil 215 nil nil nil 0 nil nil nil nil) + : (0 nil 215 nil nil nil 0 nil nil nil nil) + : (0 nil 215 nil nil nil 0 nil nil nil nil) + : (0 nil 215 nil nil nil 0 nil nil nil nil) + y: (0 nil 215 nil nil nil 0 nil nil nil nil) + : (0 nil 222 nil nil nil 0 nil nil nil nil) + =: (0 nil 222 nil nil nil 0 nil nil nil nil) + : (0 nil 222 nil nil nil 0 nil nil nil nil) + x: (0 nil 222 nil nil nil 0 nil nil nil nil) + (: (0 nil 226 nil nil nil 0 nil nil nil nil) + 2: (1 227 nil nil nil nil 0 nil nil (227) nil) + ,: (1 227 228 nil nil nil 0 nil nil (227) nil) + : (1 227 228 nil nil nil 0 nil nil (227) nil) + 2: (1 227 228 nil nil nil 0 nil nil (227) nil) + ): (1 227 231 nil nil nil 0 nil nil (227) nil) + ;: (0 nil 227 nil nil nil 0 nil nil nil nil) + \n: (0 nil 227 nil nil nil 0 nil nil nil nil) +Line:14: end + e: (0 nil 227 nil nil nil 0 nil nil nil nil) + n: (0 nil 235 nil nil nil 0 nil nil nil nil) + d: (0 nil 235 nil nil nil 0 nil nil nil nil) + \n: (0 nil 235 nil nil nil 0 nil nil nil nil) diff --git a/tests/test-matlab-ts-mode-syntax-table.el b/tests/test-matlab-ts-mode-syntax-table.el new file mode 100644 index 0000000000..4832d1e4a2 --- /dev/null +++ b/tests/test-matlab-ts-mode-syntax-table.el @@ -0,0 +1,114 @@ +;;; test-matlab-ts-mode-syntax-table.el --- -*- lexical-binding: t -*- +;; +;; Copyright 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: +;; +;; Validate matlab-ts-mode syntax faces. +;; Load ../matlab-ts-mode.el via require and run syntax table tests using +;; ./test-matlab-ts-mode-syntax-table-files/NAME.m comparing against +;; ./test-matlab-ts-mode-syntax-table-files/NAME_expected.txt +;; + +;;; Code: + +(require 'cl-macs) + +;; Add abs-path of ".." to load-path so we can (require 'matlab-ts-mode) +(let* ((lf (or load-file-name (buffer-file-name (current-buffer)))) + (d1 (file-name-directory lf)) + (parent-dir (expand-file-name (file-name-directory (directory-file-name d1))))) + (add-to-list 'load-path parent-dir t)) + +(require 'matlab-ts-mode) + +(defun test-matlab-ts-mode-syntax-table-files () + "Return list of full paths to each test-matlab-ts-mode-syntax-table-files/*.m." + (directory-files "test-matlab-ts-mode-syntax-table-files" t "\\.m$")) + +(defvar test-matlab-ts-mode-syntax-table + (cons "test-matlab-ts-mode-syntax-table" (test-matlab-ts-mode-syntax-table-files))) + +(cl-defun test-matlab-ts-mode-syntax-table (&optional m-file) + "Test syntax-table using ./test-matlab-ts-mode-syntax-table-files/NAME.m. +Compare ./test-matlab-ts-mode-syntax-table-files/NAME.m against +./test-matlab-ts-mode-syntax-table-files/NAME_expected.txt, where +NAME_expected.txt gives the `syntax-ppss` value of each character in NAME.m + +If M-FILE NAME.m is not provided, loop comparing all +./test-matlab-ts-mode-syntax-table-files/NAME.m files. + +For debugging, you can run with a specified NAME.m, + M-: (test-matlab-ts-mode-syntax-table \"test-matlab-ts-mode-syntax-table-files/NAME.m\")" + + (when (or (< emacs-major-version 30) + (not (progn + (require 'treesit) + (when (fboundp 'treesit-ready-p) + (treesit-ready-p 'matlab t))))) + (message "skipping-test: test-matlab-ts-mode-syntax-table.el - tree sitter not available.") + (cl-return-from test-matlab-ts-mode-syntax-table)) + + (let ((m-files (if m-file + (progn + (setq m-file (file-truename m-file)) + (when (not (file-exists-p m-file)) + (error "File %s does not exist" m-file)) + (list m-file)) + (test-matlab-ts-mode-syntax-table-files)))) + (dolist (m-file m-files) + (save-excursion + (message "START: test-matlab-ts-mode-syntax-table %s" m-file) + + (find-file m-file) + (goto-char (point-min)) + + (let* ((got "") + (expected-file (replace-regexp-in-string "\\.m$" "_expected.txt" m-file)) + (got-file (concat expected-file "~")) + (expected (when (file-exists-p expected-file) + (with-temp-buffer + (insert-file-contents-literally expected-file) + (buffer-string))))) + (while (not (eobp)) + (when (looking-at "^") + (setq got (concat got (format "Line:%d: %s\n" + (line-number-at-pos) + (buffer-substring-no-properties (point) + (line-end-position)))))) + + (let ((char (buffer-substring-no-properties (point) (1+ (point))))) + (when (string= char "\n") + (setq char "\\n")) + (setq got (concat got (format " %2s: %S\n" char (syntax-ppss (point)))))) + + (forward-char)) + + (when (not (string= got expected)) + (let ((coding-system-for-write 'raw-text-unix)) + (write-region got nil got-file)) + (when (not expected) + (error "Baseline for %s does not exists. \ +See %s and if it looks good rename it to %s" + m-file got-file expected-file)) + (error "Baseline for %s does not match, got: %s, expected: %s" + m-file got-file expected-file)) + (kill-buffer))) + (message "PASS: test-matlab-ts-mode-syntax-table %s" m-file))) + "success") + +(provide 'test-matlab-ts-mode-syntax-table) +;;; test-matlab-ts-mode-syntax-table.el ends here