From fb674c7430663400f581cc411033e14016a645c1 Mon Sep 17 00:00:00 2001 From: Eric Ludlam Date: Mon, 22 Mar 2021 21:11:50 -0400 Subject: [PATCH] matlab.el: (matlab-array-continuation-indent-level): New config variable. (matlab-calculate-indentation-1): When selecting indentation for within parens, add logic for 2 indent styles depending on what kind of array continuation we find ourselves in. Use new array-continuation indent level for inside arrays. functions, arrays w/ open paren on a line by itself, and nested arrays indent under their parens. tests/indents.m: Add examples of differnet kinds of array continuations. --- matlab.el | 92 ++++++++++++++++++++++++++++++------------------- tests/indents.m | 42 +++++++++++++++------- 2 files changed, 86 insertions(+), 48 deletions(-) diff --git a/matlab.el b/matlab.el index 4afed34..b090402 100644 --- a/matlab.el +++ b/matlab.el @@ -92,6 +92,11 @@ nil (never) means that new *.m files will not enter :group 'matlab :type 'integer) +(defcustom matlab-array-continuation-indent-level 2 + "*Basic indentation after continuation within an array if no other methods are found." + :group 'matlab + :type 'integer) + (defcustom matlab-cont-requires-ellipsis t "*Specify if ellipses are required at the end of a line for continuation. Future versions of Matlab may not require ellipses ... , so a heuristic @@ -116,6 +121,39 @@ should be ok." :group 'matlab :type 'sexp) +(defcustom matlab-indent-past-arg1-functions + "[sg]et\\(_param\\)?\\|waitfor\\|notify" + "*Regex describing functions whose first arg is special. +This specialness means that all following parameters which appear on +continued lines should appear indented to line up with the second +argument, not the first argument." + :group 'matlab + :type 'string) + +(defcustom matlab-arg1-max-indent-length 15 + "*The maximum length to indent when indenting past arg1. +If arg1 is exceptionally long, then only this number of characters +will be indented beyond the open paren starting the parameter list." + :group 'matlab + :type 'integer) + +(defcustom matlab-maximum-indents '(;; = is a convenience. Don't go too far + (?= . (10 . 4)) + ;; Fns should provide hard limits + (?\( . 50) + ;; Matrix/Cell arrays + (?\[ . 20) + (?\{ . 20)) + "Alist of maximum indentations when lining up code. +Each element is of the form (CHAR . INDENT) where char is a character +the indent engine is using, and INDENT is the maximum indentation +allowed. Indent could be of the form (MAXIMUM . INDENT), where +MAXIMUM is the maximum allowed calculated indent, and INDENT is the +amount to use if MAXIMUM is reached." + :group 'matlab + :type '(repeat (cons (character :tag "Open List Character") + (sexp :tag "Number (max) or cons (max indent)")))) + (defcustom matlab-align-to-paren t "*Whether continuation lines should be aligned to the opening parenthesis. When non-nil, continuation lines are aligned to the opening parenthesis if the @@ -262,39 +300,6 @@ See `matlab-indent-function-body' variable." ;; Else, just return the variable. matlab-indent-function-body)) -(defcustom matlab-indent-past-arg1-functions - "[sg]et\\(_param\\)?\\|waitfor\\|notify" - "*Regex describing functions whose first arg is special. -This specialness means that all following parameters which appear on -continued lines should appear indented to line up with the second -argument, not the first argument." - :group 'matlab - :type 'string) - -(defcustom matlab-arg1-max-indent-length 15 - "*The maximum length to indent when indenting past arg1. -If arg1 is exceptionally long, then only this number of characters -will be indented beyond the open paren starting the parameter list." - :group 'matlab - :type 'integer) - -(defcustom matlab-maximum-indents '(;; = is a convenience. Don't go too far - (?= . (10 . 4)) - ;; Fns should provide hard limits - (?\( . 50) - ;; Matrix/Cell arrays - (?\[ . 20) - (?\{ . 20)) - "Alist of maximum indentations when lining up code. -Each element is of the form (CHAR . INDENT) where char is a character -the indent engine is using, and INDENT is the maximum indentation -allowed. Indent could be of the form (MAXIMUM . INDENT), where -MAXIMUM is the maximum allowed calculated indent, and INDENT is the -amount to use if MAXIMUM is reached." - :group 'matlab - :type '(repeat (cons (character :tag "Open List Character") - (sexp :tag "Number (max) or cons (max indent)")))) - (defcustom matlab-fill-fudge 10 "Number of characters around `fill-column' we can fudge filling. Basically, there are places that are very convenient to fill at, but @@ -1951,11 +1956,18 @@ LVL2 is a level 2 scan context with info from previous lines." (parencol (matlab-line-close-paren-inner-col lvl1)) (parenchar (matlab-line-close-paren-inner-char lvl1)) (parenpt (matlab-line-close-paren-inner-point lvl1)) + (parenindent (when parenpt + (save-excursion (goto-char parenpt) + (current-indentation)))) + (parenopt (matlab-line-close-paren-outer-point lvl1)) + ;; What shall we use to describe this for debugging? (indent-type (cond ((matlab-line-empty-p lvl1) 'empty) ((and parenchar (= parenchar ?\()) 'function-call-cont) - ((matlab-line-close-paren-outer-point lvl1) 'array-cont) + ((and parencol (= parenindent parencol)) 'array-solo-cont) + ((and parenpt (/= parenpt parenopt)) 'nested-array-cont) + (parenpt 'array-cont) (t 'code-cont))) (found-column nil) @@ -2007,7 +2019,17 @@ LVL2 is a level 2 scan context with info from previous lines." ;; indent. (if (or (not matlab-align-to-paren) (looking-at "\\.\\.\\.\\|$")) - (+ ci-boc matlab-continuation-indent-level) + (if (or (eq indent-type 'function-call-cont) + (and (not (eq indent-type 'array-solo-cont)) + (not (eq indent-type 'nested-array-cont)))) + ;; functions or an array ending on a EOL should + ;; do normal code indentation from beginning of cmd + (+ ci-boc matlab-continuation-indent-level) + ;; If in an array in an array ending on EOL should + ;; indent a wee bit + (+ parencol matlab-array-continuation-indent-level)) + ;; current column is location on original line where + ;; first bit of text is, so line up with that. (current-column) ;; TODO - this disables indentation MAXs ;; if we really want to be rid of this diff --git a/tests/indents.m b/tests/indents.m index 9c4fc9c..55974d8 100644 --- a/tests/indents.m +++ b/tests/indents.m @@ -19,7 +19,7 @@ function indents(a,b,stuff,cmddual1fake,cmddual2fake) global var2 % !!4 persistent var3 % !!4 - + locala = a; %#ok localb = b; %#ok localstuff = stuff; %#ok @@ -40,9 +40,9 @@ function indents(a,b,stuff,cmddual1fake,cmddual2fake) % $$$ !!0 % $$$ special ignore comments - + has_nested_fcn(); % !!4 - + % !!4 - after ignore comments end % Comment with end in it @@ -83,23 +83,23 @@ function B = ends_in_comments_and_strings() % !!4 E = B; - + if baz A = C; end; B = [ 1 2 ... % is this the end? 3 4 ]; % !!15 - + % !!4 - + if foo A = E; end ... the other end % !! 4 - + B = [ B A ]; % !!4 str = 'This is a char array with ... in it'; @@ -133,7 +133,7 @@ function out = array_constant_decls() 3 4; %!!14 ]; %!!12 - Csep = [ + Csep = [ 1 2; %!!8 3 4; %!!8 ]; %!!11 @@ -148,7 +148,21 @@ function out = array_constant_decls() [ 13 14; %!!26 15 16 ]) %!!28 } ; %!!16 - + + nest = { ... %!!4 + 1 %!!8 + [ ... %!!8 + 2 3 %!!10 + ] ... %!!8 + 3 %!!8 + }; %!!11 + + cascade_long_name = ... %!!4 + { ... %!!8 + 1 %!!10 + 2 %!!10 + }; %!!8 + % TODO % I don't know why the below indents this way. % It should either do all max indent, or all lined up with parens. @@ -184,7 +198,9 @@ function out = array_constant_decls() out = { A %!!4 Blong %!!12 Csep %!!12 + nest %!!12 multinest%!!12 + cascade_long_name%!!12 Closures%!!12 dep %!!12 }; %!!10 @@ -243,7 +259,7 @@ function B = continuations_and_block_comments % !!0 %{ - !!2 + !!2 { } !!2 %} @@ -272,9 +288,9 @@ function B = continuations_and_block_comments 3 4 ]; % !!10 foo(['this is a very long string' ... %!!4 - 'with a continution to do something very exciting'])%!!9 + 'with a continution to do something very exciting']);%!!9 - set(gcf,'Position',[ 1 2 3 4],... !!4 + set(gcf,'Position',[ 1 2 3 4], ... !!4 'Color', 'red'); % !!12 B = A + 1 + 4 ... @@ -288,7 +304,7 @@ function B = continuations_and_block_comments if condition1 || ... % !!4 fcn_call(arg1, ... % !!12 - arg2) % !!21 + arg2); % !!21 line_in_if(); end % !!4