The support for XML in Monaco is strange. As far as I know, there is no XML formatting enabled. I would suggest formatting XML only once on your backend and sending it already formatted. Client-side formatting can be a potential bottleneck in your app if you edit large texts.
But if you still prefer client-side formatting, it can be done using HTML formatter as suggested in this GitHub comment.
Actions Format Document and Reindent Lines will be enabled with the following configuration. Monaco will even follow XML indention as you type.
You can play around with this in Monaco editor playground. (just copy, paste, run):
// Monaco doesn't support XML formatting. But it's possible to use HTML formatting.
// https://github.com/microsoft/monaco-editor/issues/1509#issuecomment-864441191
monaco.languages.html.registerHTMLLanguageService(
"xml",
{
format: {
wrapLineLength: 0,
preserveNewLines: false,
}
},
{ documentFormattingEdits: true },
);
const editor = monaco.editor.create(document.getElementById('container'), {
value: "<group><content><value text=\"Text\"></value><!--\nPress Ctrl + Shift + F\nto reformat this XML\n--></content></group>",
language: "xml",
tabSize: 2,
autoIndent: "full",
detectIndentation: true,
formatOnType: true,
formatOnPaste: true,
});
monaco.languages.setLanguageConfiguration("xml", {
"indentationRules": {
"increaseIndentPattern": new RegExp("<(?!\\?|[^>]*\\/>)([-_.A-Za-z0-9]+)(?=\\s|>)\\b[^>]*>(?!.*<\\/\\1>)|<!--(?!.*-->)|\\{[^}\"']*$"),
"decreaseIndentPattern": new RegExp("^\\s*(<\\/(?!html)[-_.A-Za-z0-9]+\\b[^>]*>|-->|})"),
},
});
// Format document and reindned lines with Ctrl + Shift + F
editor.addAction({
id: "formatDocumentAndReindentLines",
label: "Format Document and Reindent Lines",
keybindings: [monaco.KeyMod.CtrlCmd | monaco.KeyMod.Shift | monaco.KeyCode.KeyF],
run: async (editor) => {
await editor.getAction("editor.action.formatDocument").run();
// Reindent is here for multiline comments
return editor.getAction("editor.action.reindentlines").run();
},
});
indentationRules
are borrowed from vscode HTML extension configuration and simplified. More information about it here.