Coder Social home page Coder Social logo

davidvarga / mbeautifier Goto Github PK

View Code? Open in Web Editor NEW
460.0 11.0 75.0 270 KB

MBeautifier is a MATLAB source code formatter, beautifier. It can be used directly in the MATLAB Editor and it is configurable.

License: GNU General Public License v3.0

MATLAB 100.00%
matlab sourcecode formatter beautifier beautify matlab-source matlab-editor code-formatter

mbeautifier's Introduction

MBeautifier

MBeautifier is a lightweight M-Script based MATLAB source code formatter usable directly in the MATLAB Editor.

Basic working

Main features

  • Padding operators and keywords with white spaces
  • Configurable indentation character and level. Indentation using the Smart Indent functionality of the MATLAB Editor
  • Removal/addition of continuous empty lines
  • Inserting missing element separators (commas) in matrix and cell array initializations
  • Insert missing continuous symbol line in matrix and cell array initializations
  • In-lining continuous lines
  • Formats the current page of the MATLAB Editor or only a selection in the MATLAB Editor or file(s)
  • While everything above is configurable in a single XML file

Deployment and Configuration

Simply add the root directory to the MATLAB path.

Configuration

The configuration can be modified by editing the MBeautifier\resources\settings\MBeautyConfigurationRules.xml file.

Configuration rules

Currently three types of configuration rules are implemented: Operator padding rule, Keyword padding rule and Special rule.

Operator padding rules

Each OperatorPaddingRule represents the formatting rules for one single operator and consists of a key, the string that should be replaced and a string that should be used for the replacement.

<OperatorPaddingRule>
    <Key>NotEquals</Key>
    <ValueFrom>~=</ValueFrom>
    <ValueTo> ~= </ValueTo>
</OperatorPaddingRule>

The example above shows the rule for the "not equals" operator. The ValueFrom node stores the operator ~= and the ValueTo node stores the expected format: the operator should be preceded and followed by a white-space character.

Keyword padding rules

Each KeyworPaddingRule represents the formatting rules for one single keyword and consists the keyword itself, and a numeric value of the needed white-space padding on the right side.

<KeyworPaddingRule>
	<Keyword>properties</Keyword>
	<RightPadding>1</RightPadding>
</KeyworPaddingRule>

The example above shows the rule for the keyword "properties". The RightPadding node stores the expected right padding white space amount: the keyword should be preceded by one white space character.

Note: Not all of the keywords are listed - only the ones where controlling padding makes sense.

Special rules

These rules are basically switches for certain functionalities of MBeautifier.

The current list of special rules:

Special rules regarding new lines
  • MaximalNewLines: Integer value. MBeautifier will remove continuous empty lines. This rule can be used to specify the maximal number of maximal continuous empty lines.
  • SectionPrecedingNewlineCount: Integer value. Defines how many empty lines should precede the section comments (%% ). Negative values mean no special formatting is needed (the final format is defined by the input and the MaximalNewLines rule). For any number "X" bigger or equal to zero: section comments will be preceded exactly by X empty lines.
  • SectionTrailingNewlineCount: Integer value. Defines how many empty lines should follow the section comments (%% ). Negative values mean no special formatting is needed (the final format is defined by the input and the MaximalNewLines rule). For any number "X" bigger or equal to zero: section comments will be followed exactly by X empty lines.
  • EndingNewlineCount: Integer value. Defines how many empty lines should be placed on the end of the input. Negative values mean no special formatting is needed (the final format is defined by the input and the MaximalNewLines rule). For any number "X" bigger or equal to zero: input will trailed exactly by X empty lines.
  • AllowMultipleStatementsPerLine: [1|0]. If set to 1, MBeautifier will allow multiple statements per line (a = 1; b = 2;), otherwise it will break every statement into a new line. Defaults to "0".
Special rules regarding matrix and cell array separators
  • AddCommasToMatrices: [1|0]. Indicates whether the missing element separator commas in matrices should be inserted. For example: [1 2 3] will be formatted as [1, 2, 3].
  • AddCommasToCellArrays: [1|0]. Indicates whether the missing element separator commas in cell arrays should be inserted. For example: {1 2 3} will be formatted as {1, 2, 3}.
Special rules arithmetic operators
  • MatrixIndexing_ArithmeticOperatorPadding: [1|0]. Indicates whether the arithmetic operators should be padded by white spaces (using the operator padding rules), when they are used to index matrices. For example: matrix(end+1) = 1 can be formatted as matrix(end+1) = 1 when value is set to 0, or as matrix(end + 1) = 1 if value is set to 1.
  • CellArrayIndexing_ArithmeticOperatorPadding: [1|0]. Indicates the same as MatrixIndexing_ArithmeticOperatorPadding but for cell arrays.
Special rules regarding continous lines
  • InlineContinousLines: [1|0]. If set to 1, MBeautifier will in-line continuous line operators ("...") everywhere except in matrices (inside [] brackets) and in curly brackets ({}) - these cases are handled by the next two options. In-lining means: the "..." operator will be removed and the next line will be copied into its place.
  • InlineContinousLinesInMatrixes: [1|0]. Same as InlineContinousLines, but only has effect inside brackets ("[]").
  • InlineContinousLinesInCurlyBracket: [1|0]. Same as InlineContinousLines, but only has effect inside curly brackets ("{}").
Special rules regarding indentation
  • IndentationCharacter: [white-space|tab]. Specifies which character should be used for auto-indentation: white space or tabulator. Defaults to "white-space".
  • IndentationCount: Integer value. Specifies the level of auto-indentation (how many IndentationCharacter means one level of indentation). Defaults to "4".
  • Indentation_TrimBlankLines: [1|0]. Specifies if blank lines (lines containing only white space characters - as result of auto-indentation) should be trimmed (made empty) by MBeautifier. Defaults to "1" as it can lead to smaller file sizes.
  • Indentation_Strategy: ['AllFunctions'|'NestedFunctions'|'NoIndent']. Controls the "Function indenting format" preference of the MATLAB editor used by MBeautifier: changes the indentation level of the functions' body. Possible values: "AllFunctions" - indent the body of each function, "NestedFunctions" - indent the body of nested functions only, "NoIndent" - all of the functions' body will be indented the same amount as the function keyword itself.

Directives

MBeautifier directives are special constructs which can be used in the source code to control MBeautifier during the formatting process. The example below controls the directive named Format and sets its value to on and then later to off.

a =  1;
% MBeautifierDirective:Format:Off
longVariableName = 'where the assigement is';
aligned          = 'with the next assignment';
% MBD:Format:On
someMatrix  =  [1 2 3];

The standard format of a directive line is:

  • following the pattern: <ws>%<ws>MBeautifierDirective<ws>:<ws>:NAME<ws>:<ws>VALUE<ws>[NEWLINE] or : <ws>%<ws>MBD<ws>:<ws>:NAME<ws>:<ws>VALUE<ws>[NEWLINE]where
    • <ws> means zero or more optional white space characters
    • NAME means the directive name (only latin letters, case insensitive)
    • VALUE means the directive value (only latin letters, case insensitive)
  • must not contain any code or any trailing comment (only the directive comment above)
  • must not be inside a block comment
  • must not be inside any line continousment
  • the keyword MBeautifierDirective is freely interchangable with MBD

Note: Directive names which are not present in the list below, or directive values which are not applicable to the specified directive will be ignored together with a MATLAB warning.

Directive List
Format

Directive to generally control the formatting process. Possible values:

  • on - Enable formatting
  • off - Disable formatting

Example: In the code-snippet below MBeautifier is formatting the first line using the configuration currently active, but will not format the lines 2,3,4,5. The last line will be beautified again using the current configuration.

a =  1;
% MBeautifierDirective:Format:Off
longVariableName = 'where the assigement is';
aligned          = 'with the next assignment';
% MBeautifierDirective:Format:On
someMatrix  =  [1 2 3];

The formatted code will look like (configuration dependently):

a = 1;
% MBeautifierDirective:Format:Off
longVariableName = 'where the assigement is';
aligned          = 'with the next assignment';
% MBeautifierDirective:Format:On
someMatrix = [1, 2, 3];

Usage

From MATLAB Command Window

Currently four approaches are supported:

  • Perform formatting on the currently active page of MATLAB Editor. Command: MBeautify.formatCurrentEditorPage(). By default the file is not saved, but it remains opened modified in the editor. Optionally the formatted file can be saved using the MBeautify.formatCurrentEditorPage(true) syntax.
  • Perform formatting on the currently selected text of the active page of MATLAB Editor. Command: MBeautify.formatEditorSelection(). An optional saving mechanism as above exists also in this case. Useful in case of large files, but in any case MBeautify.formatCurrentEditorPage() is suggested.
  • Perform formatting on a file. Command: MBeautify.formatFile(file). Can be used with (1)one argument: the input file is formatted and remains open in the MATLAB editor unsaved; (2)two arguments as MBeautify.formatFile(file, outFile): the formatted file is saved to the specified output file if possible. Output can be the same as input.
  • Perform formatting on several files in a directory. Command: MBeautify.formatFiles(directory, fileFilter). The first argument is an absolute path to a directory, the second one is a wildcard expression (used for dir command) to filter files in the target directory. The files will be formatted in-place (overwritten).

Shortcuts

There is a possibility to create shortcuts for the first three approaches above, which shortcut buttons will appear under the "Shortcuts" tab of MATLAB's main window below Matlab R2019, and under "Favourites" and on the "Quick Access Toolbar" above.

To create these buttons, the following commands can be used:

  • MBeautify.createShortcut('editorpage'): Creates a shortcut for MBeautify.formatCurrentEditorPage()
  • MBeautify.createShortcut('editorselection'): Creates a shortcut for MBeautify.formatEditorSelection()
  • MBeautify.createShortcut('file'): Creates a shortcut for MBeautify.formatFile(sourceFile, destFile)

These shortcuts will add the MBeautifier root directory to the MATLAB path too, therefore no MATLAB path preparation is needed to use MBeautifier next time when a new Matlab instance is opened.

Supported Matlab versions

The oldest version of MATLAB to be used to test MBeautifier is R2013b.

Planned future versions

It is planned that the project is maintained until MATLAB is shipped with a code formatter with a similar functionality.

It is planned to make MBeautifier also usable in Octave, by starting a new development branch using Java/Kotlin (versions 2.). The MATLAB based branched will be developed in branch versions (1.).

mbeautifier's People

Contributors

aaronwebster avatar asmfstatoil avatar casperdcl avatar cnheying avatar davidvarga avatar maxgaukler avatar mkr3mer avatar mriesch-tum avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mbeautifier's Issues

Inconsistent spacing around minus sign

Hi,
[[I,Z];[h*(-K-L),I]] * [[I,Z];[h*(K-L),I]]
becomes
[[I, Z]; [h * (-K - L), I]] * [[I, Z]; [h * (K-L), I]]
with spaces added only in the first parenthesis.
Commit b931478, MATLAB 2016b.

Somewhat relevant config:

<SpecialRule>
<Key>CellArrayIndexing_ArithmeticOperatorPadding</Key>
<Value>0</Value>
</SpecialRule>
<SpecialRule>
<Key>MatrixIndexing_ArithmeticOperatorPadding</Key>
<Value>0</Value>
</SpecialRule>

New working modes: Editor selection and file

Currently the only stable working mode is to format the current page of Matlab Editor.
Two new working modes could be added:

  • Editor selection mode: Implemented but not stable
  • Format files (with and without saving)

Multi line matrices and cell arrays without ellipsis line continuation indicator

Currently, if matrices and cell arrays are declared using multiple lines, but no ellipsis line continuation indicator (...) is used, the elements of these containsers dont get formatted.

In these cases the ellipsis line continuation indicator (...) should be also inserted.

Example

c = { 1+2+3 1*2  -12  -10/5
   -1    -2    -3   -4
10*(6+5) 10 10 10}

b = [1+2 2 3
    4 5+4 6
    7 8+4 9
    10 11+4 12]

The expected formatting is

c = {1 + 2 + 3, 1 * 2, -12, -10 / 5; ...
    -1, -2, -3, -4; ...
    10 * (6 + 5), 10, 10, 10}

b = [1 + 2, 2, 3; ...
    4, 5 + 4, 6; ...
    7, 8 + 4, 9; ...
    10, 11 + 4, 12]

Token handling: Improvements

Getting tokens for String, Continuosment is implemented really badly now.
Think it over and implement a faster, more intelligent way.

Problem when using +/- signs in the first element of matrix assignments

[-1, 2, 3, 4] -> [-, 1, 2, 3, 4]
[+1, 2, 3, 4] -> [+, 1, 2, 3, 4]

If the +/- sign is on a later position it behaves fine
[1, -2, 3, 4] -> [1, - 2, 3, 4]
however, there is an additional withespace create between the +/- sign and the number
I think -2 is easier to read than - 2 in this case

Auto-wrapping long lines

It's probably a quite tricky thing to implement, but it would be nice if there was an option to autowrap long (e.g., > 79 chars) lines. Some sort of heuristics could be used to figure out where to break the lines, e.g., first try breaking at "=". Then if either of parts is still too long, break farthest down the line that puts the line (w/ added ...) under the line limit.

Expression, that MBeautifier can't handle

Hey, David.

Looks like Beautifier fails on the following code:

[out1, out2] = func([str1, str2], [str3, str4]);

it removes last ");" and code becomes non-compilable.

Denis

Performance improve, code simplification

The current codebase should be simplified and cleaned-up for the final Matlab based release. As it is planned - to avoid problems between different Matlab releases - a Java based (compilant with Java6) reimplementation will be done and release with version 2...

The performance of the current implementation should be analyzed and the bottlenecks should be removed.

Index exceeds matrix dimensions.

When applied to testfile.m the following errors appear in MATLAB 2016a on Linux:

Index exceeds matrix dimensions.

Error in MBeautify/performFormatting>processContainer (line 559)
    indexes = find([containerBorderIndexes{:, 2}] == maxDepth, 2);

Error in MBeautify/performFormatting>performReplacementsSingleLine (line 362)
[data, arrayMapCell] = processContainer(data, settingConf);

Error in MBeautify/performFormatting>performReplacements (line 151)
actCodeTemp = performReplacementsSingleLine(actCodeTemp, settingConf);

Error in MBeautify/performFormatting (line 91)
    actCodeFinal = performReplacements(actCode, settingConf);

Error in MBeautify.beautify (line 18)
formattedSource = MBeautify.performFormatting(codeToFormat, settingConf);

Suggestion: power operator should not be separated

I suggest that power operators ^ and .^ should not be separated by default.
The reason is that in function calls (seems they are affected by matrix indexing settings) it becomes barely readable:
sqrt(a+b^2) becomes sqrt(a+b ^ 2)
While better variants are:
sqrt(a+b^2) or sqrt(a + b^2)

MatrixIndexing and CellArrayIndexing setting not respected

Despite having MatrixIndexing_ArithmeticOperatorPadding and CellArrayIndexing_ArithmeticOperatorPadding set to 0 in both the m and xml configuration files, code such as

b = a(1:end-2);
c = a(end-1);
e = d{1:end-2};
f = d{end-1};

is converted to

b = a(1:end - 2);
c = a(end - 1);
e = d{1:end - 2};
f = d{end - 1};

The configuration files are the default ones, have not been edited.

Tested on both R2016a and R2017a

Indentation in multiline condition.

I assume that in the case of a condition, it is better to align to condition on previous line.
I think this code:

if a + b > 0 && ...
   a * b > 0
    a = b;
end   

better than generated by MBeautifier:

if a + b > 0 && ...
        a * b > 0
    a = b;
end

So, this is true for while too.

Handling of containers: matrices and cell arrays

Problems covered in this issue

  • At the moment embedded matrices [[],[]] are not processed property
  • New option to add commas also for cell arrays
  • With this new option, embeded cell arrays should be also processed

AddCommasToMatrices=0 doesn't affect some matrices

Hi!
[[I, Z]; [h * (K-L), I]]changes to [[I, Z]; [h, * (K-L), I]] while

<SpecialRule>
<Key>AddCommasToMatrices</Key>
<Value>0</Value>
</SpecialRule>
<SpecialRule>
<Key>AddCommasToCellArrays</Key>
<Value>0</Value>
</SpecialRule>
<SpecialRule>

Commit b931478, MATLAB 2016b.

Inconsistencies in formatting within braces

The latest version with default settings produces this output:

length(x) + 1;
a(length(x)+1);

a(b:b+n-1);
b + n - 1;

So the sameexpressions gets formatted in different ways depending on where it appears. This was not the case in older versions; is this by design now?

Single indent with multiple lines of comment

MBeautify add a single indent every line of multiple lines comment after run command MBeautify.formatCurrentEditorPage(). This isn't happening with single line comment.

Before call command:

%This is one line comment
%{
This is
multiline
comment
%}

After call MBeautify.formatCurrentEditorPage() 10 times.

%This is one line comment
%{
          This is
          multiline
          comment
%}

New configuration setting: operators in case of indexing ( (), {})

The purpose of this issue to provide addtional settings for replacing operators when they are used in indexing (matrixes and cell arrays) like:

namesCell{ind+1} = 'Andy'; rather than namesCell{ind + 1} = 'Andy';

Two new configuration rule could be introduced:

  • CellArrayIndexing_ArithmeticOperatorPadding
  • MatrixIndexing_ArithmeticOperatorPadding

Both contains a boolean value, and indicates wheter in case of cell-array/matrix indexing (cellArray{ind+1} and matrix(ind+1)) te arithmetic operators (+, -, *, /) should be padded with white spaces (using the configuration rules of these operators) or not.

Based on these configuration rules, the example output can be

% Both set to false
cellArray{end+1} = 'dog';
matric(end+1) = 11;

% Both set to true
cellArray{end + 1} = 'dog';
matric(end + 1) = 11;

Special arithmetic operator cases

Formatting of arithmetic operators needs to address special cases.

Two cases I have found were:

  • [1 -1] becomes [1 - 1] which has a whole different meaning
  • 7E+5 becomes 7E + 5 which is invalid

I have just used it on one file so there might be more cases that have to be considered.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.