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

Reply via email to