Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to run without opening the MATLAB editor #74

Open
cszczepaniak opened this issue Sep 26, 2019 · 8 comments
Open

Add option to run without opening the MATLAB editor #74

cszczepaniak opened this issue Sep 26, 2019 · 8 comments

Comments

@cszczepaniak
Copy link

cszczepaniak commented Sep 26, 2019

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');

@mriesch-tum
Copy link
Contributor

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

@davidvarga
Copy link
Owner

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.

@kupiqu
Copy link

kupiqu commented Oct 16, 2019

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.

@cszczepaniak
Copy link
Author

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.

@mriesch-tum
Copy link
Contributor

mriesch-tum commented Oct 16, 2019

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.

@florianschanda
Copy link

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

@Freed-Wu
Copy link

Freed-Wu commented Aug 27, 2023

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.

@florianschanda
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants