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

    matlab-ts-mode: add M-q fill paragraph tests
---
 contributing/treesit-mode-how-to.org               |  42 ++-
 .../fill_paragraph_comments.m                      |  45 ++++
 .../fill_paragraph_comments_expected.org           | 282 +++++++++++++++++++++
 .../fill_paragraph_indent.m                        |  14 +
 .../fill_paragraph_indent_expected.org             |  49 ++++
 tests/test-matlab-ts-mode-fill-paragraph.el        |  58 +++++
 6 files changed, 486 insertions(+), 4 deletions(-)

diff --git a/contributing/treesit-mode-how-to.org 
b/contributing/treesit-mode-how-to.org
index 3df78b0f7b..013d76cb30 100644
--- a/contributing/treesit-mode-how-to.org
+++ b/contributing/treesit-mode-how-to.org
@@ -31,9 +31,9 @@
 #+latex_header: \advance\cftsubsecindent 0.5em\relax
 #+latex_header: \advance\cftsubsecnumwidth 0.5em\relax
 
-#+title: How to Create an Emacs Tree-Sitter Major Mode
+#+title: How to Create and Test an Emacs Tree-Sitter Major Mode
 #+author: John Ciolfi
-#+date: Jun-25-2025
+#+date: Jun-30-2025
 
 * TODO
 
@@ -753,7 +753,7 @@ where test-LANGUAGE-ts-mode-indent.el contains:
 
 #+end_src
 
-* Syntax Table and Comments
+* Syntax Table
 
 The Emacs "syntax table" is not related to the syntax tree created by 
tree-sitter. A syntax tree
 represents the hierarchical structure of your source code, giving a structural 
blueprint of your
@@ -991,7 +991,30 @@ We follow a similar pattern for writing syntax table tests.
 
 #+end_src
 
-** Comment tests
+* Fill paragraph, M-q
+
+=M-q= is bound to =prog-fill-reindent-defun= from =prog-mode=, which when the 
point is in a comment
+will fill the comment. If the point is in code it will indent the code. If the 
point is in a string,
+M-q will fill the string like it's plain text, which can result in syntax 
errors. This is expected
+behavior because one can then fix the syntax behaviors by adding appropriate 
string
+continuations. There's no way to alter the string filling behavior besides 
using defadvice, which
+you should not do.
+
+If your syntax table correctly identifies comments and strings, then it M-q 
just works, though you
+should still add tests to validate it works.  If you'd like tree-sitter nodes 
other than comments
+and strings to be filled like plain text, you should add a =text= entry to 
=treesit-thing-settings=,
+e.g. if nodeName1 and nodeName2 should be filled like plain text, use:
+
+ #+begin_src emacs-lisp
+ (defvar LANGAUAGE-ts-mode--thing-settings
+  `((LANGUAGE
+     (text ,(rx (or "nodeName1" "nodeName2"))))))
+ #+end_src
+
+and in defun of LANGUAGE-ts-mode, add =(setq-local treesit-thing-settings
+LANGUAGE-ts-mode--thing-settings)= after you've setup your syntax table.
+
+** Fill paragraph tests
 
 TODO
 
@@ -1489,3 +1512,14 @@ well worth writing a tree-sitter mode.
                          (skip-chars-forward " \t")
                          (point))))
   #+end_src
+
+- [ ] M-q (prog-fill-reindent-defun), when the point is in a string and you 
type M-q it will
+  split long strings into multiple lies which results in syntax errors in some 
languages, e.g. C.
+
+  : char * str = "a very long string a very long string a very long string a 
very long string a very long string a very long string a very long string a 
very long string ";
+
+  TODO validate this occurs with c-ts-mode.
+
+  Would like an option to have M-q indent or fill comments. When in a string 
it should indent.
+  Though ideally, it should correctly break the string into multiple lines so 
there's no semantic
+  difference.
diff --git 
a/tests/test-matlab-ts-mode-fill-paragraph-files/fill_paragraph_comments.m 
b/tests/test-matlab-ts-mode-fill-paragraph-files/fill_paragraph_comments.m
new file mode 100644
index 0000000000..d89ffae451
--- /dev/null
+++ b/tests/test-matlab-ts-mode-fill-paragraph-files/fill_paragraph_comments.m
@@ -0,0 +1,45 @@
+% -*- matlab-ts -*-
+function b = fill_paragraph_basic(a)
+%
+% Setup test to use a small fill column
+% (t-utils-xr (set-fill-column 60))
+%
+% Test of fill paragraph
+% (t-utils-xr "C-n" "C-n" "M-q")
+%
+% A very long comment. A very long comment. A very long comment. A very long 
comment. A very long comment. A very long comment. A very long comment. A very 
long comment. A very long comment. A  very long comment. A very long comment. A 
very long comment.
+%
+% Test of fill paragraph on a numbered list
+% (t-utils-xr "C-n" "C-n" "M-q")
+% 
+% 1. Item one that is long. Item one that is long. Item one that is long. Item 
one that is long. Item one that is long. Item one that is long.
+%    And has multiple lines
+%
+% Test of fill paragraph on a numbered list
+% (t-utils-xr "C-n" "C-n" "M-q")
+%
+% 2. Item two that is long. Item two that is long. Item two that is long. Item 
two that is long. Item two that is long. Item two that is long.
+%
+% Test of fill paragraph on a bullet item.
+% (t-utils-xr "C-n" "C-n" "M-q")
+%
+% - Item three that is long. Item three that is long. Item three that is long. 
Item three that is long. Item three that is long. Item three that is long. Item 
three that is long.
+%
+
+% Test of fill paragraph on a regular comment
+% (t-utils-xr "C-n" "C-n" "M-q")
+%
+% foo bar foo barfoo bar foo barfoo bar foo bar foo barfoo bar foo barfoo bar 
foo bar foo barfoo bar foo barfoo bar
+%
+
+    if a > 1
+        % Test of fill paragraph on a regular comment after a statement from 
column 1
+        % (t-utils-xr "C-n" "M-q")
+        b = a * 2; % A long comment at the end of a statement.  A long comment 
at the end of a statement.  A long comment at the end of a statement.  A long 
comment at the end of a statement.
+        b = x * 1;
+    else
+        % Test of fill paragraph on a regular comment after a statement when 
in comment
+        % (t-utils-xr "C-n" "C-a" "M-;" "M-q")
+        b = c * d; % A long comment at the end of a statement.  A long comment 
at the end of a statement.  A long comment at the end of a statement.  A long 
comment at the end of a statement.
+    end
+end
diff --git 
a/tests/test-matlab-ts-mode-fill-paragraph-files/fill_paragraph_comments_expected.org
 
b/tests/test-matlab-ts-mode-fill-paragraph-files/fill_paragraph_comments_expected.org
new file mode 100644
index 0000000000..8d97268f56
--- /dev/null
+++ 
b/tests/test-matlab-ts-mode-fill-paragraph-files/fill_paragraph_comments_expected.org
@@ -0,0 +1,282 @@
+#+startup: showall
+
+* Executing commands from fill_paragraph_comments.m:5:2:
+
+  (t-utils-xr (set-fill-column 60))
+
+- Invoking      : (set-fill-column 60)
+  Start point   :  135
+  No point movement
+  No buffer modifications
+
+* Executing commands from fill_paragraph_comments.m:8:2:
+
+  (t-utils-xr "C-n" "C-n" "M-q")
+
+- Invoking      : "C-n" = next-line
+  Start point   :  195
+  Moved to point:  197
+  : 9:1: %
+  :       ^
+  No buffer modifications
+
+- Invoking      : "C-n" = next-line
+  Start point   :  197
+  Moved to point:  199
+  : 10:1: % A very long comment. A very long comment. A very long comment. A 
very long comment. A very long comment. A very long comment. A very long 
comment. A very long comment. A very long comment. A  very long comment. A very 
long comment. A very long comment.
+  :        ^
+  No buffer modifications
+
+- Invoking      : "M-q" = prog-fill-reindent-defun
+  Start point   :  199
+  No point movement
+  Buffer modified:
+  #+begin_src diff
+--- start_contents
++++ end_contents
+@@ -7,7 +7,11 @@
+ % Test of fill paragraph
+ % (t-utils-xr "C-n" "C-n" "M-q")
+ %
+-% A very long comment. A very long comment. A very long comment. A very long 
comment. A very long comment. A very long comment. A very long comment. A very 
long comment. A very long comment. A  very long comment. A very long comment. A 
very long comment.
++% A very long comment. A very long comment. A very long
++% comment. A very long comment. A very long comment. A very
++% long comment. A very long comment. A very long comment. A
++% very long comment. A very long comment. A very long
++% comment. A very long comment.
+ %
+ % Test of fill paragraph on a numbered list
+ % (t-utils-xr "C-n" "C-n" "M-q")
+  #+end_src diff
+
+* Executing commands from fill_paragraph_comments.m:17:2:
+
+  (t-utils-xr "C-n" "C-n" "M-q")
+
+- Invoking      : "C-n" = next-line
+  Start point   :  538
+  Moved to point:  541
+  : 18:2: % 
+  :         ^
+  No buffer modifications
+
+- Invoking      : "C-n" = next-line
+  Start point   :  541
+  Moved to point:  544
+  : 19:2: % 1. Item one that is long. Item one that is long. Item one that is 
long. Item one that is long. Item one that is long. Item one that is long.
+  :         ^
+  No buffer modifications
+
+- Invoking      : "M-q" = prog-fill-reindent-defun
+  Start point   :  544
+  No point movement
+  Buffer modified:
+  #+begin_src diff
+--- start_contents
++++ end_contents
+@@ -16,8 +16,9 @@
+ % Test of fill paragraph on a numbered list
+ % (t-utils-xr "C-n" "C-n" "M-q")
+ % 
+-% 1. Item one that is long. Item one that is long. Item one that is long. 
Item one that is long. Item one that is long. Item one that is long.
+-%    And has multiple lines
++% 1. Item one that is long. Item one that is long. Item one
++%    that is long. Item one that is long. Item one that is
++%    long. Item one that is long.  And has multiple lines
+ %
+ % Test of fill paragraph on a numbered list
+ % (t-utils-xr "C-n" "C-n" "M-q")
+  #+end_src diff
+
+* Executing commands from fill_paragraph_comments.m:24:2:
+
+  (t-utils-xr "C-n" "C-n" "M-q")
+
+- Invoking      : "C-n" = next-line
+  Start point   :  797
+  Moved to point:  799
+  : 25:1: %
+  :        ^
+  No buffer modifications
+
+- Invoking      : "C-n" = next-line
+  Start point   :  799
+  Moved to point:  801
+  : 26:1: % 2. Item two that is long. Item two that is long. Item two that is 
long. Item two that is long. Item two that is long. Item two that is long.
+  :        ^
+  No buffer modifications
+
+- Invoking      : "M-q" = prog-fill-reindent-defun
+  Start point   :  801
+  No point movement
+  Buffer modified:
+  #+begin_src diff
+--- start_contents
++++ end_contents
+@@ -23,7 +23,9 @@
+ % Test of fill paragraph on a numbered list
+ % (t-utils-xr "C-n" "C-n" "M-q")
+ %
+-% 2. Item two that is long. Item two that is long. Item two that is long. 
Item two that is long. Item two that is long. Item two that is long.
++% 2. Item two that is long. Item two that is long. Item two
++% that is long. Item two that is long. Item two that is
++% long. Item two that is long.
+ %
+ % Test of fill paragraph on a bullet item.
+ % (t-utils-xr "C-n" "C-n" "M-q")
+  #+end_src diff
+
+* Executing commands from fill_paragraph_comments.m:31:2:
+
+  (t-utils-xr "C-n" "C-n" "M-q")
+
+- Invoking      : "C-n" = next-line
+  Start point   : 1024
+  Moved to point: 1026
+  : 32:1: %
+  :        ^
+  No buffer modifications
+
+- Invoking      : "C-n" = next-line
+  Start point   : 1026
+  Moved to point: 1028
+  : 33:1: % - Item three that is long. Item three that is long. Item three 
that is long. Item three that is long. Item three that is long. Item three that 
is long. Item three that is long.
+  :        ^
+  No buffer modifications
+
+- Invoking      : "M-q" = prog-fill-reindent-defun
+  Start point   : 1028
+  No point movement
+  Buffer modified:
+  #+begin_src diff
+--- start_contents
++++ end_contents
+@@ -30,7 +30,10 @@
+ % Test of fill paragraph on a bullet item.
+ % (t-utils-xr "C-n" "C-n" "M-q")
+ %
+-% - Item three that is long. Item three that is long. Item three that is 
long. Item three that is long. Item three that is long. Item three that is 
long. Item three that is long.
++% - Item three that is long. Item three that is long. Item
++% - three that is long. Item three that is long. Item three
++% - that is long. Item three that is long. Item three that
++% - is long.
+ %
+ 
+ % Test of fill paragraph on a regular comment
+  #+end_src diff
+
+* Executing commands from fill_paragraph_comments.m:40:2:
+
+  (t-utils-xr "C-n" "C-n" "M-q")
+
+- Invoking      : "C-n" = next-line
+  Start point   : 1299
+  Moved to point: 1301
+  : 41:1: %
+  :        ^
+  No buffer modifications
+
+- Invoking      : "C-n" = next-line
+  Start point   : 1301
+  Moved to point: 1303
+  : 42:1: % foo bar foo barfoo bar foo barfoo bar foo bar foo barfoo bar foo 
barfoo bar foo bar foo barfoo bar foo barfoo bar
+  :        ^
+  No buffer modifications
+
+- Invoking      : "M-q" = prog-fill-reindent-defun
+  Start point   : 1303
+  No point movement
+  Buffer modified:
+  #+begin_src diff
+--- start_contents
++++ end_contents
+@@ -39,7 +39,8 @@
+ % Test of fill paragraph on a regular comment
+ % (t-utils-xr "C-n" "C-n" "M-q")
+ %
+-% foo bar foo barfoo bar foo barfoo bar foo bar foo barfoo bar foo barfoo bar 
foo bar foo barfoo bar foo barfoo bar
++% foo bar foo barfoo bar foo barfoo bar foo bar foo barfoo
++% bar foo barfoo bar foo bar foo barfoo bar foo barfoo bar
+ %
+ 
+     if a > 1
+  #+end_src diff
+
+* Executing commands from fill_paragraph_comments.m:48:10:
+
+  (t-utils-xr "C-n" "M-q")
+
+- Invoking      : "C-n" = next-line
+  Start point   : 1556
+  Moved to point: 1591
+  : 49:34:         b = a * 2; % A long comment at the end of a statement.  A 
long comment at the end of a statement.  A long comment at the end of a 
statement.  A long comment at the end of a statement.
+  :                                          ^
+  No buffer modifications
+
+- Invoking      : "M-q" = prog-fill-reindent-defun
+  Start point   : 1591
+  No point movement
+  Buffer modified:
+  #+begin_src diff
+--- start_contents
++++ end_contents
+@@ -46,7 +46,11 @@
+     if a > 1
+         % Test of fill paragraph on a regular comment after a statement from 
column 1
+         % (t-utils-xr "C-n" "M-q")
+-        b = a * 2; % A long comment at the end of a statement.  A long 
comment at the end of a statement.  A long comment at the end of a statement.  
A long comment at the end of a statement.
++        b = a * 2; % A long comment at the end of a
++                   % statement.  A long comment at the end
++                   % of a statement.  A long comment at the
++                   % end of a statement.  A long comment at
++                   % the end of a statement.
+         b = x * 1;
+     else
+         % Test of fill paragraph on a regular comment after a statement when 
in comment
+  #+end_src diff
+
+* Executing commands from fill_paragraph_comments.m:57:10:
+
+  (t-utils-xr "C-n" "C-a" "M-;" "M-q")
+
+- Invoking      : "C-n" = next-line
+  Start point   : 1995
+  Moved to point: 2042
+  : 58:46:         b = c * d; % A long comment at the end of a statement.  A 
long comment at the end of a statement.  A long comment at the end of a 
statement.  A long comment at the end of a statement.
+  :                                                      ^
+  No buffer modifications
+
+- Invoking      : "C-a" = move-beginning-of-line
+  Start point   : 2042
+  Moved to point: 1996
+  : 58:0:         b = c * d; % A long comment at the end of a statement.  A 
long comment at the end of a statement.  A long comment at the end of a 
statement.  A long comment at the end of a statement.
+  :       ^
+  No buffer modifications
+
+- Invoking      : "M-;" = comment-dwim
+  Start point   : 1996
+  Moved to point: 2017
+  : 58:21:         b = c * d; % A long comment at the end of a statement.  A 
long comment at the end of a statement.  A long comment at the end of a 
statement.  A long comment at the end of a statement.
+  :                             ^
+  No buffer modifications
+
+- Invoking      : "M-q" = prog-fill-reindent-defun
+  Start point   : 2017
+  No point movement
+  Buffer modified:
+  #+begin_src diff
+--- start_contents
++++ end_contents
+@@ -55,6 +55,10 @@
+     else
+         % Test of fill paragraph on a regular comment after a statement when 
in comment
+         % (t-utils-xr "C-n" "C-a" "M-;" "M-q")
+-        b = c * d; % A long comment at the end of a statement.  A long 
comment at the end of a statement.  A long comment at the end of a statement.  
A long comment at the end of a statement.
++        b = c * d; % A long comment at the end of a
++                   % statement.  A long comment at the end
++                   % of a statement.  A long comment at the
++                   % end of a statement.  A long comment at
++                   % the end of a statement.
+     end
+ end
+  #+end_src diff
diff --git 
a/tests/test-matlab-ts-mode-fill-paragraph-files/fill_paragraph_indent.m 
b/tests/test-matlab-ts-mode-fill-paragraph-files/fill_paragraph_indent.m
new file mode 100644
index 0000000000..b62f6db38d
--- /dev/null
+++ b/tests/test-matlab-ts-mode-fill-paragraph-files/fill_paragraph_indent.m
@@ -0,0 +1,14 @@
+% -*- matlab-ts -*-
+function b = fill_paragraph_indent
+
+    % (t-utils-xr (set-fill-column 60) "C-n" "M-q")
+ if a > 2
+b= 1;
+      end
+s1 = "a long string a long string a long string a long string a long string a 
long string a long string a long string a long string a long string a long 
string a long string a long string a long string a long string a long string a 
long string a long string ";
+              disp(s1);
+
+   s2 = "foo"; % a long comment  a long comment  a long comment  a long 
comment  a long comment  a long comment  a long comment  a long comment  a long 
comment  a long comment  a long comment  a long comment  a long comment  a long 
comment  a long comment  a long comment
+
+       disp(s2);
+end
diff --git 
a/tests/test-matlab-ts-mode-fill-paragraph-files/fill_paragraph_indent_expected.org
 
b/tests/test-matlab-ts-mode-fill-paragraph-files/fill_paragraph_indent_expected.org
new file mode 100644
index 0000000000..cb23a6ac66
--- /dev/null
+++ 
b/tests/test-matlab-ts-mode-fill-paragraph-files/fill_paragraph_indent_expected.org
@@ -0,0 +1,49 @@
+#+startup: showall
+
+* Executing commands from fill_paragraph_indent.m:4:6:
+
+  (t-utils-xr (set-fill-column 60) "C-n" "M-q")
+
+- Invoking      : (set-fill-column 60)
+  Start point   :  108
+  No point movement
+  No buffer modifications
+
+- Invoking      : "C-n" = next-line
+  Start point   :  108
+  Moved to point:  118
+  : 5:9:  if a > 2
+  :               ^
+  No buffer modifications
+
+- Invoking      : "M-q" = prog-fill-reindent-defun
+  Start point   :  118
+  Moved to point:  121
+  : 5:12:     if a > 2
+  :                   ^
+  Buffer modified:
+  #+begin_src diff
+--- start_contents
++++ end_contents
+@@ -2,13 +2,13 @@
+ function b = fill_paragraph_indent
+ 
+     % (t-utils-xr (set-fill-column 60) "C-n" "M-q")
+- if a > 2
+-b= 1;
+-      end
+-s1 = "a long string a long string a long string a long string a long string a 
long string a long string a long string a long string a long string a long 
string a long string a long string a long string a long string a long string a 
long string a long string ";
+-              disp(s1);
++    if a > 2
++        b= 1;
++    end
++    s1 = "a long string a long string a long string a long string a long 
string a long string a long string a long string a long string a long string a 
long string a long string a long string a long string a long string a long 
string a long string a long string ";
++    disp(s1);
+ 
+-   s2 = "foo"; % a long comment  a long comment  a long comment  a long 
comment  a long comment  a long comment  a long comment  a long comment  a long 
comment  a long comment  a long comment  a long comment  a long comment  a long 
comment  a long comment  a long comment
++    s2 = "foo"; % a long comment  a long comment  a long comment  a long 
comment  a long comment  a long comment  a long comment  a long comment  a long 
comment  a long comment  a long comment  a long comment  a long comment  a long 
comment  a long comment  a long comment
+ 
+-       disp(s2);
++    disp(s2);
+ end
+  #+end_src diff
diff --git a/tests/test-matlab-ts-mode-fill-paragraph.el 
b/tests/test-matlab-ts-mode-fill-paragraph.el
new file mode 100644
index 0000000000..d4e3a1d6a3
--- /dev/null
+++ b/tests/test-matlab-ts-mode-fill-paragraph.el
@@ -0,0 +1,58 @@
+;;; test-matlab-ts-mode-fill-paragraph.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, 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 GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+;;
+
+;;; Commentary:
+;;
+;; Validate matlab-ts-mode indent.
+;; Load ../matlab-ts-mode.el via require and run indent tests using
+;; ./test-matlab-ts-mode-fill-paragraph-files/NAME.m comparing against
+;; ./test-matlab-ts-mode-fill-paragraph-files/NAME_expected.org
+;;
+
+;;; Code:
+
+(require 't-utils)
+(require 'matlab-ts-mode)
+
+(cl-defun test-matlab-ts-mode-fill-paragraph (&optional m-file)
+  "Test defun movement using ./test-matlab-ts-mode-fill-paragraph-files/NAME.m.
+Using ./test-matlab-ts-mode-fill-paragraph-files/NAME.m, compare comment
+keybindings against
+./test-matlab-ts-mode-fill-paragraph-files/NAME_expected.org.  If M-FILE is
+not provided, loop comparing all
+./test-matlab-ts-mode-fill-paragraph-files/NAME.m files.
+
+To add a test, create
+  ./test-matlab-ts-mode-fill-paragraph-files/NAME.m
+and run this function.  The baseline is saved for you as
+  ./test-matlab-ts-mode-fill-paragraph-files/NAME_expected.org~
+after validating it, rename it to
+  ./test-matlab-ts-mode-fill-paragraph-files/NAME_expected.org"
+
+  (let ((test-name "test-matlab-ts-mode-fill-paragraph"))
+
+    (when (not (t-utils-is-treesit-available 'matlab test-name))
+      (cl-return-from test-matlab-ts-mode-font-lock))
+
+    (let ((m-files (t-utils-get-files (concat test-name "-files") "\\.m$" nil 
m-file)))
+      (t-utils-test-xr test-name m-files)))
+    "success")
+
+(provide 'test-matlab-ts-mode-fill-paragraph)
+;;; test-matlab-ts-mode-fill-paragraph.el ends here

Reply via email to