Blog

Work

Formatting Handlebars in the Monaco Editor with Prettier

Work

The following outlines the process required to user prettier to format handlebar code within the Monaco Editor, a requirement we had when migrating from CodeMirror to Monaco. Out of the box, Monaco has formatting for JavaScript and CSS, & HTML, but not for handlebars.

Our first step is to clone the prettier repository.

git clone https://github.com/prettier/prettier.git

After this is complete, run the following commands to install dependencies and start the build process.

yarn && yarn build

This process might take a while as it's going to build the entire prettier package with each parser. If you encounter issues, or are short on time you can alter the configuration in scripts/build/config.js and remove each parser you won't be using or reorder them so glimmer gets build first.

Once complete you should have at miniumum two files standalone.js and parser-glimmer.js. Copy these two files into your project.

I'll be using AMD to load the files along side Monaco, which I'll be integrating the formatter into.

Note: I've defined the paths of Monaco, prettier, & glimmer in a require configuration, and can therefore reference them via there name instead of path. In addition, it is written in typescript but can easily be written in JavaScript by removing the type notation.

require(['monaco', 'prettier', 'glimmer'], (monaco, prettier, ...plugins) => {

            /* Adds Prettier Formatting to Monaco for Handlebars */
            const PrettierHandlebarsFormatter: monaco.languages.DocumentFormattingEditProvider = {
                provideDocumentFormattingEdits: function(
                    document: monaco.editor.ITextModel, 
                    options: monaco.languages.FormattingOptions, 
                    token: monaco.CancellationToken): monaco.languages.TextEdit[] {
                        const text = document.getValue();
                        const formatted = prettier.format(text, {parser: "glimmer", plugins});
                        return [{
                            range: document.getFullModelRange(),
                            text: formatted,
                        }];
                    }
            }

            monaco.languages.registerDocumentFormattingEditProvider("handlebars", PrettierHandlebarsFormatter);

...

The following code creates a DocumentFormattingEditProvider with the provideDocumentFormattingEdits function required by monaco. It then assigns this to the handlebars language by calling registerDocumentFormattingEditProvider.

Any instance of the editor created after this registration has occurred will use prettier to format the code.