branch: externals/matlab-mode
commit 1a4d64ce89e7b153b989ee53e8fef74f4cd2f20f
Author: John Ciolfi <[email protected]>
Commit: John Ciolfi <[email protected]>
matlab-ts-mode: fix indent for two matrices next to each other
---
matlab-ts-mode--ei.el | 22 +++--
matlab-ts-mode.el | 100 ++++++++++++---------
.../electric_indent_two_matrices.m | 14 +++
.../electric_indent_two_matrices_expected.m | 14 +++
.../electric_indent_two_matrices_expected_msgs.m | 14 +++
5 files changed, 114 insertions(+), 50 deletions(-)
diff --git a/matlab-ts-mode--ei.el b/matlab-ts-mode--ei.el
index b27975e6d5..a31d1e88f0 100644
--- a/matlab-ts-mode--ei.el
+++ b/matlab-ts-mode--ei.el
@@ -635,9 +635,11 @@ when on the 2nd continuation only line, nil is returned."
(defun matlab-ts-mode--ei-indent-matrix-in-tmp-buf (assign-node)
"Insert ASSIGN-NODE in to current tmp-buf and indent.
-Point is left at beginning of line containing the ASSIGN-NODE text."
+Point is left at beginning of line containing the ASSIGN-NODE text.
+Returns the line number after the ASSIGN-NODE in the tmp-buf."
(let (assign-str
- n-levels)
+ n-levels
+ end-linenum)
(with-current-buffer (treesit-node-buffer assign-node)
(let* ((assign-start-pos (save-excursion (goto-char (treesit-node-start
assign-node))
(line-beginning-position)))
@@ -656,6 +658,8 @@ Point is left at beginning of line containing the
ASSIGN-NODE text."
(insert assign-str "\n")
+ (setq end-linenum (line-number-at-pos))
+
(cl-loop for level from 1 to n-levels do
(insert "end\n"))
@@ -671,7 +675,8 @@ Point is left at beginning of line containing the
ASSIGN-NODE text."
(goto-char (point-min))
(when (> n-levels 0)
- (forward-line n-levels))))
+ (forward-line n-levels))
+ end-linenum))
(cl-defun matlab-ts-mode--ei-align-line-in-m-matrix (assign-node ei-info)
"Align current line with EI-INFO in a multi-line matrix of ASSIGN-NODE.
@@ -686,9 +691,10 @@ See `matlab-ts-mode--ei-get-new-line' for EI-INFO
contents."
(let* ((assign-start-linenum (line-number-at-pos (treesit-node-start
assign-node)))
(tmp-buf-ei-linenum (1+ (- (line-number-at-pos)
assign-start-linenum)))
(tmp-buf-row-linenum (if matlab-ts-mode--ei-align-matrix-alist 1
tmp-buf-ei-linenum))
- (matrix-alist matlab-ts-mode--ei-align-matrix-alist))
+ (matrix-alist matlab-ts-mode--ei-align-matrix-alist)
+ end-linenum)
(with-temp-buffer
- (matlab-ts-mode--ei-indent-matrix-in-tmp-buf assign-node)
+ (setq end-linenum (matlab-ts-mode--ei-indent-matrix-in-tmp-buf
assign-node))
(let* ((matrix-node (treesit-node-parent (treesit-search-subtree
(treesit-buffer-root-node) (rx
bos "[" eos) nil t)))
@@ -701,7 +707,7 @@ See `matlab-ts-mode--ei-get-new-line' for EI-INFO contents."
(> tmp-buf-ei-linenum 1))
(forward-line (1- tmp-buf-ei-linenum)))
- (while (not (eobp)) ;; Adjust column widths
+ (while (< (line-number-at-pos) end-linenum) ;; Adjust column widths
(back-to-indentation)
(let* ((row-node (matlab-ts-mode--ei-get-m-matrix-row-in-line))
(indent-start-pt (point))
@@ -1155,7 +1161,7 @@ start-node is the identifier node for width and
start-offset is 2."
(eol-pt (line-end-position)))
(save-excursion
(back-to-indentation)
-
+
(while (< (point) eol-pt)
(let ((node (if (looking-at "[ \t]")
(if (re-search-forward "[^ \t]" (line-end-position) t)
@@ -1194,7 +1200,7 @@ When IS-INDENT-REGION is nil, we restore the point to
it's logical
location when the line is updated. Returns t if line was updated."
(matlab-ts-mode--ei-workaround-143)
-
+
;; If line was indented (nth 0 ei-info) is not same as current line, then
update the buffer
(let* ((start-pair (when (not is-indent-region)
(matlab-ts-mode--ei-get-start-info)))
diff --git a/matlab-ts-mode.el b/matlab-ts-mode.el
index a7e39588dc..83181f645c 100644
--- a/matlab-ts-mode.el
+++ b/matlab-ts-mode.el
@@ -1006,8 +1006,6 @@ Example, disp variable is overriding the disp builtin
function:
;; line should convey the operation being performed by the line. Adding
unrelated concepts on a
;; give line hurts readability. Hence the recommendation that lines are not
too long.
;;
-;; The indent engine should NOT automatically re-flow lines to fit within
100 columns.
-;;
;; Consider the following where the row content causes the column width to
be 105.
;; Re-flowing would hurt readability.
;;
@@ -1018,7 +1016,7 @@ Example, disp variable is overriding the disp builtin
function:
;; <row-N>;
;; ]
;;
-;; Consider the following where the model/path/to/block causes the line to
be greater than
+;; Consider the following where a very long model/path/to/block causes the
line to be greater than
;; 100. Re-flowing will hurt readability.
;;
;; set_param(...
@@ -1031,10 +1029,10 @@ Example, disp variable is overriding the disp builtin
function:
;; 3. Use 2-space offset for case labels.
;; [Implemented in the indent engine]
;;
-;;; The code under case or otherwise statements is one
-;; condition and hence should have the same indent level anchored from the
switch statement.
-;; The level of complexity of the following two statements is the same
which is clear from
-;; the level of indent of the doIt function call.
+;; The code under switch case or otherwise statements is one condition and
hence should have the
+;; same indent level anchored from the switch statement. The level of
complexity of the
+;; following two statements is the same which is clear from the level of
indent of the doIt
+;; function call.
;;
;; if condition1 == 1 | switch condition1
;; doIt | case 1
@@ -1109,17 +1107,22 @@ Example, disp variable is overriding the disp builtin
function:
;; [Implemented in the indent engine]
;;
;; - On a single line
-;; function [out1, out2] = myFunction(in1, in2)
+;; function [out1, out2] = myFunction(in1, in2)
;;
;; - Aligned on multiple lines
;;
-;; function ...
-;; [out1, ... % comment
-;; out2] ... % comment
-;; = myFunction ...
-;; (in1, ... % comment
-;; in2) % comment
-;;
+;; function ...
+;; [ ...
+;; out1, ... comment about out1
+;; out2 ... comment about out2
+;; ] ...
+;; = myFunction ...
+;; ( ...
+;; in1, ... comment about in1
+;; in2 ... comment about in2
+;; )
+;; end
+;; ;;
;; 8. Expressions
;; [Guidance - not implemented in the indent engine]
;;
@@ -1131,25 +1134,27 @@ Example, disp variable is overriding the disp builtin
function:
;; the expression continues. For example the && is at the end of the 1st
line
;; and not the start of the 2nd line:
;;
-;; if (thisOneThing > thisOtherLongLongLongLongLongLongThing &&
+;; if (thisOneThing > thisOtherLongLongLongLongLongLongThing && ...
;; aThirdThing == aFourthLongLongLongLongLongLongThing)
;;
;; % code
;; end
;;
-;; You can use extra newlines when it helps with readability, e.g.
+;; You can use extra newlines when it helps with readability. For example,
suppose
+;; the following conditions are more readable when on separate lines.
;;
-;; if (c > 30 && % is cost per unit must be high?
-;; d > 40) % and distance traveled high?
+;; if c > 30 && ...
+;; d > 40
;;
-;; // code
+;; % code
;; end
;;
-;; Use parentheses to clarify the intended precedence of "&&" and "||".
+;; Use parentheses to clarify the precedence of "&&" and "||", even when
not strictly necessary
+;; because it is common to forget that "&&" has higher precedence than "||".
;; For example:
;;
-;; if (c > 30 || (a > 10 && b > 20))
-;;
+;; if c > 30 || (a > 10 && b > 20)
+;; % code
;; end
;;
;; Do not overuse parentheses. Don't add them when they are not needed.
Overuse of parentheses
@@ -1157,13 +1162,13 @@ Example, disp variable is overriding the disp builtin
function:
;; operator precedence rules are not in use, for example, "a = b * (c + d)"
indicates to the
;; reader that standard operator precedence is not in use.
;;
-;; As a guideline, use the minimum number of parentheses, except for
-;; parenthesis to clarify the precedence of "&&" and "||" or more
-;; generally, if in doubt about operator precedence, parenthesize.
+;; As a guideline, use the minimum number of parentheses, except for
parenthesis to clarify the
+;; precedence of "&&" and "||" or more generally, if in doubt about
operator precedence,
+;; parenthesize.
;;
;; Examples:
;;
-;; % Good % Bad: too many parens
+;; % Good % Bad: too many parentheses
;; if (c > 30 && d > 40) || e if (((c > 30) && (d > 40)) || e)
;; end end
;;
@@ -1171,29 +1176,29 @@ Example, disp variable is overriding the disp builtin
function:
;; [Implemented in the indent engine]
;;
;; Example:
-;; width = 5;
-;; length = 10;
-;; area = width * length;
+;; width1 = 5;
+;; length1 = 10;
+;; area1 = width1 * length1;
;;
;; 10. Align properties and arguments
;; [Implemented in the indent engine]
;;
;; Example:
-;; classdef c1
-;; properties
-;; foo (1,3)
-;; foobar (1,1)
-;; x {mustBeReal}
-;; end
-;; end
+;; classdef c1
+;; properties
+;; foo (1,3)
+;; foobar (1,1)
+;; x {mustBeReal}
+;; end
+;; end
;;
;; 11. Align consecutive trailing comments
;; [Implemented in the indent engine]
;;
;; Example:
-;; width = 5; % width of rectangle
-;; length = 10; % length of rectangle
-;; area = width * length; % area of rectangle
+;; width1 = 5; % width of rectangle one
+;; length1 = 10; % length of rectangle one
+;; area1 = width1 * length1; % area of rectangle one
;;
;; 12. Function/classdef doc help should be aligned with the function/classdef
keyword.
;; [Implemented in the indent engine]
@@ -1493,7 +1498,7 @@ For optional _NODE, PARENT, and _BOL see
`treesit-simple-indent-rules'."
(defvar matlab-ts-mode--indent-assert-rule
'((lambda (node parent bol)
(when matlab-ts-mode--indent-assert
- (error "Assert no indent rule for: N:%S P:%S BOL:%S GP:%S NPS:%S
BUF:%S"
+ (error "Assert: no indent rule for: N:%S P:%S BOL:%S GP:%S NPS:%S
BUF:%S"
node parent bol
(treesit-node-parent parent)
(treesit-node-prev-sibling node)
@@ -2425,6 +2430,17 @@ Example:
"Return anchor for `matlab-ts-mode--i-arg-namespace-fcn-prop-matcher'."
matlab-ts-mode--i-arg-namespace-fcn-prop-anchor-value)
+(defun matlab-ts-mode--i-matrix-element ()
+ "Get the matrix element node at point."
+ (let* ((node (treesit-node-at (point)))
+ (parent (treesit-node-parent node)))
+ (while (and parent
+ (not (string= (treesit-node-type parent) "row")))
+ (setq node parent
+ parent (treesit-node-parent parent)))
+ (cl-assert parent)
+ node))
+
(defvar matlab-ts-mode--i-row-matcher-pair nil)
(cl-defun matlab-ts-mode--i-row-matcher (node parent _bol &rest _)
@@ -2448,7 +2464,7 @@ Example:
(column-widths (matlab-ts-mode--ei-m-matrix-col-widths parent
first-col-extra t))
(el-width (save-excursion
(goto-char (treesit-node-start node))
- (let ((el (treesit-node-at (point))))
+ (let ((el (matlab-ts-mode--i-matrix-element)))
(- (treesit-node-end el) (treesit-node-start el)))))
(el-spaces (- (alist-get 1 column-widths) el-width)))
(setq matlab-ts-mode--i-row-matcher-pair (cons (treesit-node-start
parent) (1+ el-spaces)))
diff --git
a/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_two_matrices.m
b/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_two_matrices.m
new file mode 100644
index 0000000000..97bdfae5a9
--- /dev/null
+++
b/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_two_matrices.m
@@ -0,0 +1,14 @@
+% -*- matlab-ts -*-
+
+% t-utils-test-indent: no-line-by-line-indent - when typing matrix
line-by-line, there are
+% error nodes and thus the matrix alignment doesn't occur
+
+% The following two matrices do not have blank lines between them. This
validates that
+% the indent-region of the matrix in the temporary buffer doesn't pickup
invalid content.
+
+if 1
+ tp_taper_BorderVertices = [neg_BorderVertices;...
+ topcover_taper_Face_BV];
+ tp_taper_Polygons = [neg_Polygons;...
+ topcover_taper_Face_poly{1} + max(max(neg_Polygons))];
+end
diff --git
a/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_two_matrices_expected.m
b/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_two_matrices_expected.m
new file mode 100644
index 0000000000..2a8bb8875a
--- /dev/null
+++
b/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_two_matrices_expected.m
@@ -0,0 +1,14 @@
+% -*- matlab-ts -*-
+
+% t-utils-test-indent: no-line-by-line-indent - when typing matrix
line-by-line, there are
+% error nodes and thus the matrix alignment doesn't occur
+
+% The following two matrices do not have blank lines between them. This
validates that
+% the indent-region of the matrix in the temporary buffer doesn't pickup
invalid content.
+
+if 1
+ tp_taper_BorderVertices = [ neg_BorderVertices; ...
+ topcover_taper_Face_BV];
+ tp_taper_Polygons = [ neg_Polygons;
...
+ topcover_taper_Face_poly{1} + max(max(neg_Polygons))];
+end
diff --git
a/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_two_matrices_expected_msgs.m
b/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_two_matrices_expected_msgs.m
new file mode 100644
index 0000000000..a1bc935664
--- /dev/null
+++
b/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_two_matrices_expected_msgs.m
@@ -0,0 +1,14 @@
+% -*- 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 - when typing matrix
line-by-line, there are % <{Matched rule: (matlab-ts-mode--i-top-level
matlab-ts-mode--column-0 0)}>
+% error nodes and thus the matrix alignment doesn't occur % <{Matched rule:
(matlab-ts-mode--i-block-comment-end-matcher parent 0)}>
+
+% The following two matrices do not have blank lines between them. This
validates that % <{Matched rule: (matlab-ts-mode--i-top-level
matlab-ts-mode--column-0 0)}>
+% the indent-region of the matrix in the temporary buffer doesn't pickup
invalid content. % <{Matched rule:
(matlab-ts-mode--i-block-comment-end-matcher parent 0)}>
+
+if 1 % <{Matched rule: (matlab-ts-mode--i-top-level matlab-ts-mode--column-0
0)}>
+ tp_taper_BorderVertices = [ neg_BorderVertices; ... % <{Matched rule:
((node-is
"\\`\\(?:arguments_statement\\|block\\|e\\(?:num\\(?:eration\\)?\\|vents\\)\\|function_definition\\|methods\\|propert\\(?:ies\\|y\\)\\)\\'")
parent 4)}>
+ topcover_taper_Face_BV]; % <{Matched rule:
(matlab-ts-mode--i-row-matcher matlab-ts-mode--i-row-matcher-anchor
matlab-ts-mode--i-row-matcher-offset)}>
+ tp_taper_Polygons = [ neg_Polygons;
... % <{Matched rule: ((parent-is "\\`block\\'") parent 0)}>
+ topcover_taper_Face_poly{1} +
max(max(neg_Polygons))]; % <{Matched rule: (matlab-ts-mode--i-row-matcher
matlab-ts-mode--i-row-matcher-anchor matlab-ts-mode--i-row-matcher-offset)}>
+end % <{Matched rule: ((node-is
"\\`\\(?:catch_clause\\|e\\(?:lse\\(?:\\(?:if\\)?_clause\\)\\|nd\\)\\)\\'")
parent 0)}>