MBeautifier icon indicating copy to clipboard operation
MBeautifier copied to clipboard

Add option to run without opening the MATLAB editor

Open cszczepaniak opened this issue 4 years ago • 8 comments

I use this as part of a pre-commit git hook and also sometimes in large batches of files, so it would be nice to have the option of passing in a filename and have the formatter run without opening the editor for performance reasons. A couple of possibilities for the calling syntax:

An optional parameter: MBeautify.formatFile('someFile.m', 'someFile.m', 'UseEditor', false);

An optional positional argument: MBeautify.formatFile('someFile.m', 'someFile.m', '--no-editor');

A new method: MBeautify.formatFileSilently('someFile.m', 'someFile.m');

cszczepaniak avatar Sep 26 '19 18:09 cszczepaniak

This feature would be awesome! Then I could integrate it in my CI pipeline.

mriesch-tum avatar Oct 16 '19 15:10 mriesch-tum

The only problem is that I am using the smart indent feature provided by the undocumented API of the MATLAB Editor. I don't know if there was a way to use the underlying implementation without opening the Editor physically.

Personally I did not find one which does not mean that there isn't any (on other issues others helped me out on some undocumentes magic from Mathworks ... :) ). If anyone can find a way to do so, it is a trivial implementation to have it integrated.

Other possibility to re-implement the smart indent functionality and drop the usage of the one provided by the editor.

davidvarga avatar Oct 16 '19 15:10 davidvarga

Other possibility to re-implement the smart indent functionality and drop the usage of the one provided by the editor.

This would help a lot in making this nice toolbox Octave-compatible, which would be great for people that cannot (or doesn't want) to pay a Matlab license. But I understand it won't be easy and fast to implement.

kupiqu avatar Oct 16 '19 15:10 kupiqu

Not sure how MBeautifier works today, but it sounds like this feature would essentially require a scanner/parser that can tokenize the code and create a full blown AST. Certainly no small task.

cszczepaniak avatar Oct 16 '19 22:10 cszczepaniak

Played around a bit just for fun and ended up with the following script featuring a poor man's tokenizer:

clear all;
close all;
file = fullfile(pwd, 'mylittletestfunction.m');
document = matlab.desktop.editor.openDocument(file);
lines = splitlines(document.Text);

layer = 0;
layer_next = 0;
ind = '    ';
delimiters = {' ','\f','\n','\r','\t','\v', '(', ')', '[', ']', '{', '}' };
keywords = { 'function', 'class', 'if', 'for', 'while' };

for linect = 1:numel(lines)

    layer = layer_next;

    % remove existing indentation and whitespace
    lines{linect} = strtrim(lines{linect});

    % split line in words
    words = split(lines{linect}, delimiters);

    % ignore empty lines and comments
    if ((length(lines{linect}) ~= 0) && (lines{linect}(1) ~= '%'))
        % find keywords and adjust indent
        for wordct = 1:numel(words)
            % look for keywords that increase indent
            if (sum(strcmp(words{wordct}, keywords)))
                layer_next = layer_next + 1;
            end

            % look for end that decreases the indent
            if (sum(strcmp(words{wordct}, { 'end', 'end;' })))
                if (wordct == 1)
                    % end at the beginning decreases indent of this line
                    layer = layer - 1;
                end
                % inline end may alter the indent of the next line
                layer_next = layer_next - 1;
            end
        end
    end

    % add correct indentation
    for ict = 1:layer
        lines{linect} = [ ind, lines{linect} ];
    end
end

complete = join(lines, newline);
document.Text = complete{1};
document.save();

The script assumes that there is a file called mylittlefunction.m in the same directory, of course.

At least simple scripts can processed correctly. Naturally, different keywords are missing and it needs thorough testing but maybe we can come up with something.

mriesch-tum avatar Oct 16 '19 23:10 mriesch-tum

At the risk of spamming in every ticket here; writing a fully working MATLAB lexer is an insane activity. Please refer to this for my analysis on this, if you want to know more: https://github.com/florianschanda/miss_hit/blob/master/LEXING_ISSUES.md

florianschanda avatar Apr 08 '21 09:04 florianschanda

I use this as part of a pre-commit git hook

Is it possible to support it by https://pre-commit.com/? It can be integrated to CI/CD of https://pre-commit.ci/. Currently pre-commit doesn't support octave/matlab directly.

Freed-Wu avatar Aug 27 '23 10:08 Freed-Wu

@Freed-Wu there is MISS_HIT integration into pre-commit as described here https://florianschanda.github.io/miss_hit/configuration.html

florianschanda avatar Aug 28 '23 06:08 florianschanda