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

    matlab-ts-mode--ei: handle missing comma in array before ellipsis
---
 matlab-ts-mode--ei.el                              | 107 +++++++++++++++------
 ...electric_indent_cell_no_comma_before_ellipsis.m |   6 ++
 ...indent_cell_no_comma_before_ellipsis_expected.m |   6 ++
 ...t_cell_no_comma_before_ellipsis_expected_msgs.m |   6 ++
 ...ectric_indent_m_matrix_strings_comma_expected.m |   2 +-
 ...c_indent_m_matrix_strings_comma_expected_msgs.m |   2 +-
 .../electric_indent_range_expected.m               |   2 +-
 .../electric_indent_range_expected_msgs.m          |   2 +-
 ...electric_indent_cell_no_comma_before_ellipsis.m |   6 ++
 ...dent_cell_no_comma_before_ellipsis_expected.txt |  17 ++++
 10 files changed, 121 insertions(+), 35 deletions(-)

diff --git a/matlab-ts-mode--ei.el b/matlab-ts-mode--ei.el
index fe5e169b55..c25d6c80e0 100644
--- a/matlab-ts-mode--ei.el
+++ b/matlab-ts-mode--ei.el
@@ -321,14 +321,17 @@ is used in `matlab-ts-mode--ei-spacing'"
   ;; Move point to first non-whitespace char
   (let ((eol-pt (pos-eol)))
 
-    (let ((node (treesit-node-at (point))))
+    (let (node)
 
       ;; If next node is a array comma node return that. Examples:
       ;;    x1 = [(3*(2+1))   2]
-      ;;                   ^     <== point here (next node is invisible comma 
node w/start=end pt)
+      ;;                   ^      <== point here (next node is invisible comma 
node w/start=end pt)
       ;;    x2 = [1, 2]
-      ;;           ^             <== point here (next node is comma node)
-      (when (looking-at "[ \t]" (point))
+      ;;           ^              <== point here (next node is comma node)
+      ;;    x3 = {'one' 'two'...
+      ;;                     ^    <== point here (next node is invisible comma 
node w/start=end pt)
+      (when (looking-at "\\(?:[ \t]\\|\\.\\.\\.\\)" (point))
+        (setq node (treesit-node-at (point)))
         (let ((candidate node)) ;; candidate will be the array element
           (while (= (treesit-node-end candidate) (point)) ;; lookup to find 
our array element
             (let* ((next-node (treesit-node-next-sibling candidate))
@@ -347,6 +350,9 @@ is used in `matlab-ts-mode--ei-spacing'"
         (backward-char)
         (setq node (treesit-node-at (point))))
 
+      (when (not node)
+        (setq node (treesit-node-at (point))))
+
       ;; Consider [[1,2];[3,4]] when point is on semicolon, node will be the 
prior "]" because the
       ;; semicolon is an ignored node, so move forward to get to the "[" after 
the semicolon.
       (while (and (not (eobp))
@@ -383,13 +389,32 @@ is used in `matlab-ts-mode--ei-spacing'"
 (defun matlab-ts-mode--ei-concat-line (ei-line node extra-chars &optional 
n-spaces-to-append)
   "Return concat EI-LINE with NODE text.
 NODE-END is the NODE end accounting for ignored nodes (semicolons).
-EXTRA-CHARS are appended to EL-LINE.
+EXTRA-CHARS string is appended to EL-LINE after NODE text.
+EXTRA-CHARS, when \\='(string), the string is appended to last
+non-whitspace in EL-LINE, then NODE text is appended.
 N-SPACES-TO-APPEND is the number of spaces to append between nodes."
 
   (let* ((node-end (treesit-node-end node))
          (eol-pt (pos-eol))
-         (last-pt (if (< node-end eol-pt) node-end eol-pt)))
+         (last-pt (if (< node-end eol-pt) node-end eol-pt))
+         extra-chars-before-node)
+    (when (listp extra-chars)
+      ;; Consier: foo1 = {'one', 'two' ...
+      ;;                  ...
+      ;;              'three' 'four' 'five'};
+      ;; After the 'two' node, we have two line_continuation's, then the 
invisible comma (",")
+      ;; This is detected and extra-chars will be '(",")
+      ;; TopTester: electric_indent_cell_no_comma_before_ellipsis.m
+      (if (string-match "\\`\\(.*[^ ]\\)\\([ ]+\\)\\'" ei-line)
+          (let ((first-part (match-string 1 ei-line))
+                (trailing-spaces (match-string 2 ei-line)))
+            (setq ei-line first-part
+                  extra-chars-before-node (concat (car extra-chars) 
trailing-spaces)))
+        (setq  extra-chars-before-node (car extra-chars)))
+      (setq extra-chars nil))
+
     (concat ei-line
+            extra-chars-before-node
             (buffer-substring (treesit-node-start node) last-pt)
             extra-chars
             (if (not n-spaces-to-append) ;; last node?
@@ -448,33 +473,53 @@ Assumes that current point is at `back-to-indentation'."
 (defun matlab-ts-mode--ei-node-extra-chars (node node-end next-node-start)
   "Get extra chars for NODE after NODE-END and before NEXT-NODE-START."
 
-  (if (and (string= (treesit-node-type node) ",")
+  (let ((node-type (treesit-node-type node)))
+    (cond
+
+     ;; Case: invisible comma, make it visible by returning the comma (",")
+     ((and (string= node-type ",")
            (= (treesit-node-start node) (treesit-node-end node)))
       ;; Make invisible comma visible by returning it.
-      ","
-    (let ((extra-chars ""))
-      ;; Handle ignored characters, e.g. ";" in matrices where node="]", 
next-node="["
-      ;;   [[1, 2]; [3, 4]]
-      ;;         ^  ^
-      (goto-char node-end)
-      (when (or ;; [[1,2];[3,4]]?
-             (and (< node-end next-node-start)
-                  (looking-at "[^ \t]"))
-             ;; [[1,2] ; [3,4]]?
-             ;; or a multiline matrix:
-             ;; x = [ 1 , 2 ;
-             (save-excursion (and (when (re-search-forward "[^ \t]" 
next-node-start t)
-                                    (backward-char)
-                                    t)
-                                  (< (point) next-node-start))))
-        (while (< (point) next-node-start)
-          (while (and (< (point) next-node-start)
-                      (looking-at "[^ \t]"))
-            (setq extra-chars (concat extra-chars (match-string 0)))
-            (forward-char)
-            (setq node-end (point)))
-          (re-search-forward "[ \t]+" next-node-start t)))
-      extra-chars)))
+      ",")
+
+     ;; Case: invisble at end of array row
+     ;;           foo = {'one', 'two' ...
+     ;;                              ^   missing comma, return a comma to have 
it inserted
+     ((string= node-type "line_continuation")
+      (let ((next-node (treesit-node-next-sibling node))
+            next-type)
+        (while (and next-node
+                    (string= (setq next-type (treesit-node-type next-node)) 
"line_continuation"))
+          (setq next-node (treesit-node-next-sibling next-node)))
+        (if (and (equal next-type ",")
+                 (= (treesit-node-start next-node) (treesit-node-end 
next-node)))
+            '(",") ;; list means prefix to NODE text
+          "")))
+
+     ;; Case: Handle ignored characters, e.g. ";" in matrices where node="]", 
next-node="["
+     ;;   [[1, 2]; [3, 4]]
+     ;;         ^  ^
+     (t
+      (let ((extra-chars ""))
+        (goto-char node-end)
+        (when (or ;; [[1,2];[3,4]]?
+               (and (< node-end next-node-start)
+                    (looking-at "[^ \t]"))
+               ;; [[1,2] ; [3,4]]?
+               ;; or a multiline matrix:
+               ;; x = [ 1 , 2 ;
+               (save-excursion (and (when (re-search-forward "[^ \t]" 
next-node-start t)
+                                      (backward-char)
+                                      t)
+                                    (< (point) next-node-start))))
+          (while (< (point) next-node-start)
+            (while (and (< (point) next-node-start)
+                        (looking-at "[^ \t]"))
+              (setq extra-chars (concat extra-chars (match-string 0)))
+              (forward-char)
+              (setq node-end (point)))
+            (re-search-forward "[ \t]+" next-node-start t)))
+        extra-chars)))))
 
 (defun matlab-ts-mode--ei-update-line-node-types (line-node-types node 
node-type)
   "Append NODE-TYPE of NODE to LINE-NODE-TYPES."
diff --git 
a/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_cell_no_comma_before_ellipsis.m
 
b/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_cell_no_comma_before_ellipsis.m
new file mode 100644
index 0000000000..d210f4d0dd
--- /dev/null
+++ 
b/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_cell_no_comma_before_ellipsis.m
@@ -0,0 +1,6 @@
+% -*- matlab-ts -*-
+
+% t-utils-test-indent: no-line-by-line-indent - need valid parse to see the 
hidden comma after 'two'
+
+foo1 = {'one', 'two' ...
+'three' 'four' 'five'};
diff --git 
a/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_cell_no_comma_before_ellipsis_expected.m
 
b/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_cell_no_comma_before_ellipsis_expected.m
new file mode 100644
index 0000000000..cca91c7052
--- /dev/null
+++ 
b/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_cell_no_comma_before_ellipsis_expected.m
@@ -0,0 +1,6 @@
+% -*- matlab-ts -*-
+
+% t-utils-test-indent: no-line-by-line-indent - need valid parse to see the 
hidden comma after 'two'
+
+foo1 = {'one', 'two', ...
+        'three', 'four', 'five'};
diff --git 
a/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_cell_no_comma_before_ellipsis_expected_msgs.m
 
b/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_cell_no_comma_before_ellipsis_expected_msgs.m
new file mode 100644
index 0000000000..8e4f3fbdf5
--- /dev/null
+++ 
b/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_cell_no_comma_before_ellipsis_expected_msgs.m
@@ -0,0 +1,6 @@
+% -*- matlab-ts -*- %  <{Matched rule: (matlab-ts-mode--i-top-level 
matlab-ts-mode--column-0 0)}>
+
+% t-utils-test-indent: no-line-by-line-indent - need valid parse to see the 
hidden comma after 'two' %  <{Matched rule: (matlab-ts-mode--i-top-level 
matlab-ts-mode--column-0 0)}>
+
+foo1 = {'one', 'two', ... %  <{Matched rule: (matlab-ts-mode--i-top-level 
matlab-ts-mode--column-0 0)}>
+        'three', 'four', 'five'}; %  <{Matched rule: ((parent-is 
"\\`\\(?:function_output\\|row\\)\\'") parent 0)}>
diff --git 
a/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_m_matrix_strings_comma_expected.m
 
b/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_m_matrix_strings_comma_expected.m
index 2061768048..c77ef351c5 100644
--- 
a/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_m_matrix_strings_comma_expected.m
+++ 
b/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_m_matrix_strings_comma_expected.m
@@ -8,5 +8,5 @@ s2 = ["ab", "cd"];
 
 abc = 'foo';
 
-s3 = ['  ', abc, ' with properties:', 10, 10 ...
+s3 = ['  ', abc, ' with properties:', 10, 10, ...
       '                       type: {', 10];
diff --git 
a/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_m_matrix_strings_comma_expected_msgs.m
 
b/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_m_matrix_strings_comma_expected_msgs.m
index d20ea0112a..7160139ed6 100644
--- 
a/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_m_matrix_strings_comma_expected_msgs.m
+++ 
b/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_m_matrix_strings_comma_expected_msgs.m
@@ -8,5 +8,5 @@ s2 = ["ab", "cd"]; %  <{Matched rule: 
(matlab-ts-mode--i-top-level matlab-ts-mod
 
 abc = 'foo'; %  <{Matched rule: (matlab-ts-mode--i-top-level 
matlab-ts-mode--column-0 0)}>
 
-s3 = ['  ', abc, ' with properties:', 10, 10 ... %  <{Matched rule: 
(matlab-ts-mode--i-top-level matlab-ts-mode--column-0 0)}>
+s3 = ['  ', abc, ' with properties:', 10, 10, ... %  <{Matched rule: 
(matlab-ts-mode--i-top-level matlab-ts-mode--column-0 0)}>
       '                       type: {', 10]; %  <{Matched rule: ((parent-is 
"\\`\\(?:function_output\\|row\\)\\'") parent 0)}>
diff --git 
a/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_range_expected.m
 
b/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_range_expected.m
index cdeed9a1ec..433790d2c6 100644
--- 
a/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_range_expected.m
+++ 
b/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_range_expected.m
@@ -3,5 +3,5 @@
 % t-utils-test-indent: no-line-by-line-indent - when we type line-by-line, the 
continuation lines
 % have a syntax error because the continued portion isn't there.
 
-dataTbl = [dataTbl(:, 1 : varColNumbers(1) - 1) ...
+dataTbl = [dataTbl(:, 1 : varColNumbers(1) - 1), ...
            tableWithDateColumnOnly, dataTbl(:, varColNumbers(1) + 1 : end)];
diff --git 
a/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_range_expected_msgs.m
 
b/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_range_expected_msgs.m
index 35aa777b03..56bfab7d03 100644
--- 
a/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_range_expected_msgs.m
+++ 
b/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_range_expected_msgs.m
@@ -3,5 +3,5 @@
 % t-utils-test-indent: no-line-by-line-indent - when we type line-by-line, the 
continuation lines %  <{Matched rule: (matlab-ts-mode--i-top-level 
matlab-ts-mode--column-0 0)}>
 % have a syntax error because the continued portion isn't there. %  <{Matched 
rule: (matlab-ts-mode--i-block-comment-end-matcher 
matlab-ts-mode--i-block-comment-end-anchor 0)}>
 
-dataTbl = [dataTbl(:, 1 : varColNumbers(1) - 1) ... %  <{Matched rule: 
(matlab-ts-mode--i-top-level matlab-ts-mode--column-0 0)}>
+dataTbl = [dataTbl(:, 1 : varColNumbers(1) - 1), ... %  <{Matched rule: 
(matlab-ts-mode--i-top-level matlab-ts-mode--column-0 0)}>
            tableWithDateColumnOnly, dataTbl(:, varColNumbers(1) + 1 : end)]; % 
 <{Matched rule: ((parent-is "\\`\\(?:function_output\\|row\\)\\'") parent 0)}>
diff --git 
a/tests/test-matlab-ts-mode-parser-files/copy-of-test-matlab-ts-mode-electric-indent-files/electric_indent_cell_no_comma_before_ellipsis.m
 
b/tests/test-matlab-ts-mode-parser-files/copy-of-test-matlab-ts-mode-electric-indent-files/electric_indent_cell_no_comma_before_ellipsis.m
new file mode 100644
index 0000000000..d210f4d0dd
--- /dev/null
+++ 
b/tests/test-matlab-ts-mode-parser-files/copy-of-test-matlab-ts-mode-electric-indent-files/electric_indent_cell_no_comma_before_ellipsis.m
@@ -0,0 +1,6 @@
+% -*- matlab-ts -*-
+
+% t-utils-test-indent: no-line-by-line-indent - need valid parse to see the 
hidden comma after 'two'
+
+foo1 = {'one', 'two' ...
+'three' 'four' 'five'};
diff --git 
a/tests/test-matlab-ts-mode-parser-files/copy-of-test-matlab-ts-mode-electric-indent-files/electric_indent_cell_no_comma_before_ellipsis_expected.txt
 
b/tests/test-matlab-ts-mode-parser-files/copy-of-test-matlab-ts-mode-electric-indent-files/electric_indent_cell_no_comma_before_ellipsis_expected.txt
new file mode 100644
index 0000000000..90e6130697
--- /dev/null
+++ 
b/tests/test-matlab-ts-mode-parser-files/copy-of-test-matlab-ts-mode-electric-indent-files/electric_indent_cell_no_comma_before_ellipsis_expected.txt
@@ -0,0 +1,17 @@
+# -*- t-utils-ts-parse-tree -*-
+(source_file<1,173> (comment[1,20]@{% -*- matlab-ts -*-}@) (comment[22,122]@{% 
t-utils-test-indent: no-line-by-line-indent - ne...}@)
+ (assignment<124,171> left: (identifier[124,128]@{foo1}@) =[129,130]
+  right: 
+   (cell<131,171> {[131,132]
+    (row<132,170>
+     (string<132,137> '[132,133] (string_content[133,136]@{one}@) '[136,137])
+     ,[137,138]
+     (string<139,144> '[139,140] (string_content[140,143]@{two}@) '[143,144])
+     (line_continuation[145,149]@{...\n}@) ,[149,149]
+     (string<149,156> '[149,150] (string_content[150,155]@{three}@) '[155,156])
+     ,[157,157]
+     (string<157,163> '[157,158] (string_content[158,162]@{four}@) '[162,163])
+     ,[164,164]
+     (string<164,170> '[164,165] (string_content[165,169]@{five}@) '[169,170]))
+    }[170,171]))
+ ;[171,172] \n[172,173])

Reply via email to