branch: externals/matlab-mode
commit a6c8ed6df9f51677411098ce264b2203aeda3580
Author: John Ciolfi <[email protected]>
Commit: John Ciolfi <[email protected]>
matlab-ts-mode-ei: for struct alignment, handle multi-line field values
---
matlab-ts-mode--ei.el | 50 +++++++++++++---------
...ric_indent_struct_with_multiline_field_values.m | 10 +++++
...t_struct_with_multiline_field_values_expected.m | 10 +++++
...uct_with_multiline_field_values_expected_msgs.m | 10 +++++
...ric_indent_struct_with_multiline_field_values.m | 10 +++++
...struct_with_multiline_field_values_expected.txt | 38 ++++++++++++++++
6 files changed, 107 insertions(+), 21 deletions(-)
diff --git a/matlab-ts-mode--ei.el b/matlab-ts-mode--ei.el
index 5ea2acb034..1a0926ef32 100644
--- a/matlab-ts-mode--ei.el
+++ b/matlab-ts-mode--ei.el
@@ -947,14 +947,14 @@ column."
(cl-defun matlab-ts-mode--ei-is-m-struct (struct)
"Is function_call STRUCT node a multi-line struct that can be aligned?
-If so return the max field width of the struct."
+If so return `(max-field-width . arguments-node), else nil."
(let* ((start-linenum (line-number-at-pos (treesit-node-start struct)))
(cache-value (alist-get start-linenum
matlab-ts-mode--ei-is-m-struct-alist))
(max-field-width 0))
- (when cache-value ;; 0 or max-field-width
- (cl-return-from matlab-ts-mode--ei-is-m-struct (when (> cache-value 0)
cache-value)))
+ (when cache-value ;; '(0 . nil) or (max-field-width . assignment-node)
+ (cl-return-from matlab-ts-mode--ei-is-m-struct (when (> (car
cache-value) 0) cache-value)))
(let* ((end-line (line-number-at-pos (treesit-node-end struct)))
arguments-node
@@ -1000,18 +1000,21 @@ If so return the max field width of the struct."
(when (and n-args-on-tracking-line (= n-args-on-tracking-line 1)) ;;
0 or 2 is good
(setq is-m-struct nil))))
- (when matlab-ts-mode--ei-is-m-struct-alist
- ;; Use 1 or 0 so we can differentiate between nil and not a multi-line
struct
- (push `(,start-linenum . ,(if is-m-struct max-field-width 0))
- matlab-ts-mode--ei-is-m-struct-alist))
-
- (when (and is-m-struct (> max-field-width 0))
- max-field-width))))
+ (let ((ans (when (and is-m-struct (> max-field-width 0))
+ `(,max-field-width . ,arguments-node))))
+ (when matlab-ts-mode--ei-is-m-struct-alist
+ ;; Use 1 or 0 so we can differentiate between nil and not a
multi-line struct
+ (push `(,start-linenum . ,(if ans ans '(0 . nil)))
+ matlab-ts-mode--ei-is-m-struct-alist))
+ ans))))
-(cl-defun matlab-ts-mode--ei-align-line-in-m-struct (struct-assign-node
max-field-width ei-info)
- "Align multi-line struct in STRUCT-ASSIGN-NODE to MAX-FIELD-WIDTH.
+(cl-defun matlab-ts-mode--ei-align-line-in-m-struct (tuple ei-info)
+ "Align multi-line struct.
+TUPLE = (list struct-assign-node max-field-width arguments-node) where
See `matlab-ts-mode--ei-get-new-line' for EI-INFO."
(let* ((ei-line (nth 0 ei-info))
+ (struct-assign-node (nth 0 tuple))
+ (max-field-width (nth 1 tuple))
(assign-linenum (line-number-at-pos (treesit-node-start
struct-assign-node)))
comma-offset
new-comma-offset)
@@ -1033,7 +1036,12 @@ See `matlab-ts-mode--ei-get-new-line' for EI-INFO."
new-comma-offset (+ (string-match-p "[^ \t]" ei-line)
max-field-width))
(when (not comma-offset) ;; Ending ");" by itself on a line
;; TopTester: electric_indent_struct_in_prop2.m
- (cl-return-from matlab-ts-mode--ei-align-line-in-m-struct ei-info)))
+ (cl-return-from matlab-ts-mode--ei-align-line-in-m-struct ei-info))
+ (let ((first-node-in-line (nth 3 ei-info))
+ (arguments-node (nth 2 tuple)))
+ (when (not (equal (treesit-node-parent first-node-in-line)
arguments-node))
+ ;; TopTester: xxx
+ (cl-return-from matlab-ts-mode--ei-align-line-in-m-struct ei-info))))
(let ((n-spaces-to-add (- new-comma-offset comma-offset)))
(when (not (= n-spaces-to-add 0))
@@ -1057,7 +1065,7 @@ assignment node when A-TYPE is met, else nil. A-TYPE can
be:
- \\='m-struct : varName = struct(... % struct on multiple lines
\\='field1\\', value1, ...
\\='otherField2\\', value2);
-Note, \\='m-struct returns (cons assignment-node max-field-width) or nil."
+Note, \\='m-struct returns (list assignment-node max-field-width
arguments-node) or nil."
(when (not assign-node)
(setq assign-node (treesit-parent-until first-node (rx bos "assignment"
eos))))
@@ -1101,9 +1109,9 @@ Note, \\='m-struct returns (cons assignment-node
max-field-width) or nil."
(string= (treesit-node-text
(treesit-node-child-by-field-name
next-node "name"))
"struct"))
- (let ((max-field-width (matlab-ts-mode--ei-is-m-struct
next-node)))
- (when max-field-width
- (cons assign-node max-field-width)))))))))
+ (let ((pair (matlab-ts-mode--ei-is-m-struct next-node)))
;; cdr => arguments
+ (when (and pair (> (car pair) 0)) ;; max-field-width >
0?
+ (list assign-node (car pair) (cdr pair))))))))))
(t
(error "Assert: bad a-type %S" a-type)))))))))
@@ -1384,9 +1392,9 @@ See `matlab-ts-mode--ei-get-new-line' for EI-INFO
contents."
(let ((matrix-assign-node (matlab-ts-mode--ei-point-in-m-type ei-info
'm-matrix)))
(if matrix-assign-node
(setq ei-info (matlab-ts-mode--ei-align-line-in-m-matrix
matrix-assign-node ei-info))
- (let ((pair (matlab-ts-mode--ei-point-in-m-type ei-info 'm-struct)))
- (if pair
- (setq ei-info (matlab-ts-mode--ei-align-line-in-m-struct (car
pair) (cdr pair) ei-info))
+ (let ((tuple (matlab-ts-mode--ei-point-in-m-type ei-info 'm-struct)))
+ (if tuple
+ (setq ei-info (matlab-ts-mode--ei-align-line-in-m-struct tuple
ei-info))
;; else do single-line alignments
(setq ei-info (matlab-ts-mode--ei-align-assignments ei-info))
(setq ei-info (matlab-ts-mode--ei-align-properties ei-info))
@@ -1699,4 +1707,4 @@ This expansion of the region is done to simplify electric
indent."
;; LocalWords: SPDX gmail treesit defcustom bos eos isstring defun eol eobp
setq curr cdr xr progn
;; LocalWords: listp alist dolist setf tmp buf utils linenum nums bobp pcase
untabify SPC
-;; LocalWords: linenums reindent bol fubar
+;; LocalWords: linenums reindent bol fubar repeat:ans
diff --git
a/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_struct_with_multiline_field_values.m
b/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_struct_with_multiline_field_values.m
new file mode 100644
index 0000000000..d17ea1e5bd
--- /dev/null
+++
b/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_struct_with_multiline_field_values.m
@@ -0,0 +1,10 @@
+% -*- matlab-ts -*-
+
+% t-utils-test-indent: no-line-by-line-indent - line-by-line typing results in
error nodes
+
+foobar = struct('type' , {'one', 'two', ...
+'three', 'four'}, ...
+ 'fooport', {1, 2, 3, 4, 4, 4, 4, 4, 4, 1, 2}, ...
+ 't',1 , ...
+ 'x' , struct('a', 1, ...
+ 'foo', 10));
diff --git
a/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_struct_with_multiline_field_values_expected.m
b/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_struct_with_multiline_field_values_expected.m
new file mode 100644
index 0000000000..7d11eec04e
--- /dev/null
+++
b/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_struct_with_multiline_field_values_expected.m
@@ -0,0 +1,10 @@
+% -*- matlab-ts -*-
+
+% t-utils-test-indent: no-line-by-line-indent - line-by-line typing results in
error nodes
+
+foobar = struct('type' , {'one', 'two', ...
+ 'three', 'four'}, ...
+ 'fooport', {1, 2, 3, 4, 4, 4, 4, 4, 4, 1, 2}, ...
+ 't' , 1, ...
+ 'x' , struct('a', 1, ...
+ 'foo', 10));
diff --git
a/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_struct_with_multiline_field_values_expected_msgs.m
b/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_struct_with_multiline_field_values_expected_msgs.m
new file mode 100644
index 0000000000..425d78f48c
--- /dev/null
+++
b/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_struct_with_multiline_field_values_expected_msgs.m
@@ -0,0 +1,10 @@
+% -*- 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 - line-by-line typing results in
error nodes % <{Matched rule: (matlab-ts-mode--i-top-level
matlab-ts-mode--column-0 0)}>
+
+foobar = struct('type' , {'one', 'two', ... % <{Matched rule:
(matlab-ts-mode--i-top-level matlab-ts-mode--column-0 0)}>
+ 'three', 'four'}, ... % <{Matched rule:
((parent-is "\\`\\(?:function_output\\|row\\)\\'") parent 0)}>
+ 'fooport', {1, 2, 3, 4, 4, 4, 4, 4, 4, 1, 2}, ... % <{Matched
rule: ((parent-is "\\`arguments\\'") parent 0)}>
+ 't' , 1, ... % <{Matched rule: ((parent-is
"\\`arguments\\'") parent 0)}>
+ 'x' , struct('a', 1, ... % <{Matched rule: ((parent-is
"\\`arguments\\'") parent 0)}>
+ 'foo', 10)); % <{Matched rule: ((parent-is
"\\`arguments\\'") parent 0)}>
diff --git
a/tests/test-matlab-ts-mode-parser-files/copy-of-test-matlab-ts-mode-electric-indent-files/electric_indent_struct_with_multiline_field_values.m
b/tests/test-matlab-ts-mode-parser-files/copy-of-test-matlab-ts-mode-electric-indent-files/electric_indent_struct_with_multiline_field_values.m
new file mode 100644
index 0000000000..d17ea1e5bd
--- /dev/null
+++
b/tests/test-matlab-ts-mode-parser-files/copy-of-test-matlab-ts-mode-electric-indent-files/electric_indent_struct_with_multiline_field_values.m
@@ -0,0 +1,10 @@
+% -*- matlab-ts -*-
+
+% t-utils-test-indent: no-line-by-line-indent - line-by-line typing results in
error nodes
+
+foobar = struct('type' , {'one', 'two', ...
+'three', 'four'}, ...
+ 'fooport', {1, 2, 3, 4, 4, 4, 4, 4, 4, 1, 2}, ...
+ 't',1 , ...
+ 'x' , struct('a', 1, ...
+ 'foo', 10));
diff --git
a/tests/test-matlab-ts-mode-parser-files/copy-of-test-matlab-ts-mode-electric-indent-files/electric_indent_struct_with_multiline_field_values_expected.txt
b/tests/test-matlab-ts-mode-parser-files/copy-of-test-matlab-ts-mode-electric-indent-files/electric_indent_struct_with_multiline_field_values_expected.txt
new file mode 100644
index 0000000000..1aadb0798c
--- /dev/null
+++
b/tests/test-matlab-ts-mode-parser-files/copy-of-test-matlab-ts-mode-electric-indent-files/electric_indent_struct_with_multiline_field_values_expected.txt
@@ -0,0 +1,38 @@
+# -*- t-utils-ts-parse-tree -*-
+(source_file<1,369> (comment[1,20]@{% -*- matlab-ts -*-}@) (comment[22,112]@{%
t-utils-test-indent: no-line-by-line-indent - li...}@)
+ (assignment<114,367> left: (identifier[114,120]@{foobar}@) =[121,122]
+ right:
+ (function_call<123,367> name: (identifier[123,129]@{struct}@) ([129,130]
+ (arguments<130,366>
+ argument: (string<130,136> '[130,131] (string_content[131,135]@{type}@)
'[135,136])
+ ,[139,140]
+ (cell<141,176> {[141,142]
+ (row<142,175>
+ (string<142,147> '[142,143] (string_content[143,146]@{one}@) '[146,147])
+ ,[147,148]
+ (string<149,154> '[149,150] (string_content[150,153]@{two}@) '[153,154])
+ ,[154,155] (line_continuation[156,160]@{...\n}@)
+ (string<160,167> '[160,161] (string_content[161,166]@{three}@)
'[166,167])
+ ,[167,168]
+ (string<169,175> '[169,170] (string_content[170,174]@{four}@)
'[174,175]))
+ }[175,176])
+ ,[176,177] (line_continuation[178,182]@{...\n}@)
+ (string<201,210> '[201,202] (string_content[202,209]@{fooport}@)
'[209,210])
+ ,[210,211]
+ (cell<212,245> {[212,213]
+ (row<213,244> (number[213,214]@{1}@) ,[214,215] (number[216,217]@{2}@)
,[217,218] (number[219,220]@{3}@) ,[220,221] (number[222,223]@{4}@) ,[223,224]
(number[225,226]@{4}@) ,[226,227] (number[228,229]@{4}@) ,[229,230]
(number[231,232]@{4}@) ,[232,233] (number[234,235]@{4}@) ,[235,236]
(number[237,238]@{4}@) ,[238,239] (number[240,241]@{1}@) ,[241,242]
(number[243,244]@{2}@))
+ }[244,245])
+ ,[245,246] (line_continuation[247,251]@{...\n}@)
+ (string<260,263> '[260,261] (string_content[261,262]@{t}@) '[262,263])
+ ,[263,264] (number[264,265]@{1}@) ,[283,284]
(line_continuation[285,289]@{...\n}@)
+ (string<290,293> '[290,291] (string_content[291,292]@{x}@) '[292,293])
+ ,[299,300]
+ (function_call<304,366> name: (identifier[304,310]@{struct}@) ([310,311]
+ (arguments<311,365>
+ argument: (string<311,314> '[311,312] (string_content[312,313]@{a}@)
'[313,314])
+ ,[314,315] (number[316,317]@{1}@) ,[317,318]
(line_continuation[319,323]@{...\n}@)
+ (string<356,361> '[356,357] (string_content[357,360]@{foo}@) '[360,361])
+ ,[361,362] (number[363,365]@{10}@))
+ )[365,366]))
+ )[366,367]))
+ ;[367,368] \n[368,369])