Prettier code formatter for monkey-c

[EDIT]

The plugin seems to be working well (ok, there's room for debate, but it does for monkeyc what prettier does for javascript).

 - if you're already using npm, you can 'npm install --save-dev @markw65/prettier-plugin-monkeyc', and install the VSCode Prettier plugin.

 - if you just want to use prettier for monkeyc code, and only want to use it inside of vscode, and dont want to mess around with npm, you can just install https://marketplace.visualstudio.com/items?itemName=markw65.prettier-extension-monkeyc and it should just work.

[/EDIT] 

So far there doesn't seem to be a code formatter for monkey-c. I've been writing quite a lot of monkey-c code recently, and I've really missed the auto-formatting provided by prettier for javascript (and many other languages).

A few days ago I decided to look into how to extend prettier. javascript isn't too different from monkey-c (or at least, monkey-c maps fairly cleanly onto a subset of javascript/typescript), so it seemed like it should be doable. I found a parser generator which already had a javascript grammar which produced an ast in the format prettier expects. In fact, the ast was fully compatible with prettier's estree printer. So I started from there, and modified it to parse monkey-c instead. Then I was able to delegate most of the printing to the existing estree printer in prettier. So after a couple of days of fiddling around I have something that prettifies all of my code in an acceptable way, and the code still works...

I've attempted to test it more thoroughly by running it on all of the Garmin sdk samples. It took a while to get everything to run through without errors (I guess there are a lot of features I don't use in my own code), and then a bit longer to get it to produce compilable code(!). But finally everything compiles, and if I compile in release mode, the prettified binaries are identical to those produced by the original code - so I didn't change the meaning of the code.

I created a GitHub repo to show what it does to the Garmin samples. There's a branch, original, pointing to the code as it was in the sdk. Then I prettified everything (branch pretty). You can browse the code, or just look at the actual changes.

I need to do a bit more cleanup and testing on my code, but I hope to publish the it on GitHub and npm as a Prettier extension within a few days - then it will be usable in VSCode via the Prettier extension. Meanwhile, feedback on the changes it made to the Garmin sample code would be appreciated.

Top Replies

All Replies

  • So I've put the project up on GitHub: https://github.com/markw65/prettier-plugin-monkeyc .

    I'll figure out how to turn it into a proper npm project soon, but for now you can clone the repo, cd into the checked out directory, run "npm run build-release", then from your monkey-c project directory install it via: "npm install --save-dev <path-to-your-checkout>". You'll also need to "npm install --save-dev prettier", and you'll probably want to install the Prettier vscode extension, and put "prettier.prettierPath": "./node_modules/prettier" in your .vscode/settings.json file so that the extension actually uses the local version of prettier rather than its built in version.

  • I've managed to put an initial project on npm: https://www.npmjs.com/package/@markw65/prettier-plugin-monkeyc

    I'll get to the documentation later, but for now you can install it via npm install --save-dev @markw65/prettier-plugin-monkeyc . The best way to use it is to install the vscode Prettier extension, and put "prettier.prettierPath": "./node_modules/prettier" in your .vscode/settings.json file. You can also run it from the command line via "npx prettier <filename>" (which will just print the prettified file), or "npx prettier --write <list of files>" which will overwrite the files with the prettified versions (take care with this!).

  • You probably should turn it into a proper vs code extension and publish it in the market place, if you want it to be easier to install/more popular

  • I quickly looked at the changes produced and adding brackets/removing brackets is not something i would expect (or like), imho a code formatter should just format the code, not add artifacts

  • imho a code formatter should just format the code, not add artifacts

    Thanks for the feedback. I understand where you're coming from.

    When I first tried prettier (for javascript code), after it had been highly recommended to me, I hated it. Then a few months later, I was working on a project that required prettier formatting for every commit, and after being forced to work with it for a while, it grew on me. Now, I really like it, and use it for everything I can (which includes monkey c as of the last few days).

    If you read the prettier docs, you'll see their philosophy: you don't want code where sometimes its a + (b * c), and sometimes its a + b * c, and you don't even want to have to make the decision; so prettier makes it for you. This is pretty much baked into prettier, and not something I can (or even want to) change. On the other hand there are definitely layout issues that I'm hoping to improve - mainly by figuring out how to delegate more of the formatting directly to the estree printer.

  • You probably should turn it into a proper vs code extension

    So... I'd write yet-another Prettier extension for vscode? That doesn't really make sense. There is already a really good Prettier extension.

    The installation right now should just be a case of installing the Prettier extension for vscode, and then running npm install --save-dev @markw65/prettier-plugin-monkeyc . There seems to be an issue with the Prettier extension not finding the plugin without also setting one of its options; the docs say that shouldn't be necessary, so I'm looking into why it seems to be necessary for me.

  • You probably should turn it into a proper vs code extension

    Ok - it turns out you can have one extension depend on another. So I wrote a minimal extension that depends on the Prettier VSCode extension. All it does is copy my plugin into the Prettier Extension's node_modules folder, which is enough to make that extension recognize it.

    So if you install https://marketplace.visualstudio.com/items?itemName=markw65.prettier-extension-monkeyc, it will auto-install both the Prettier VSCode extension, and the Garmin Monkey C extension (if they're not already installed), and then copy my prettier plugin so that everything just works.

  • Thanks for your great work. I have been used it for more than 6 monthes. I wonder if it is possible to analyse the unused string automatically. If adequate, I will be happy to make some contributions for this project.

  • I assume you're talking about the optimizer, rather than the formatter here, but I'm not quite sure what you're asking? What's an unused string in this context? Do you mean something like

    var x = "foo";

    with no uses of x? I think that should already be eliminated if x is a local variable. I don't think it currently works if x is a global or module scope variable, but that should be easy to fix.

    Or do you mean eliminate unused string resources? Currently, the optimizer does very little analysis of resources, and doesn't rewrite them at all. Fixing that would involve building some kind of AST for the resources, and then doing some form of mark and sweep across the code and resources to identify things that are definitely not referenced. It's certainly doable, but not something I've been inclined to try so far.

  • Not string literals. 

    unused string resources?

    Yes. I know it is not that easy. OK

    <string id="ps3">aMecMdfreix6Ffghb2FM2bF2inep10MobdecZ</string>

    Rez.Strings.ps3 is not used so it will take up some extra space. I wanna a compiler warnning (looks like CIQ team's job) or a curved line highlight can be shown.
    Probably a feature request to CIQ team is better