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])