monaco-editor
monaco-editor copied to clipboard
Add an XML formatter
I am trying to use Manaco Editor for XML language, but XML string is not getting formatted while editor being rendered, where as its working fine for JSON.
I either don't find "Format Document" option in Context Menu of Editor(if it is opened with XML language). Doesn't Monaco editor support XML formatting by default?
Running into the same issue. "Format Document" doesn't exist in the command template, and the calling of formatting by JS doesn't do anything.
Hello, Is there a new update regarding this issue? I am trying to use the XML format and highlighting as well but unfortunately, it doesn't work for me, however, it works perfectly with JSON format.
Running into the same issue. "Format Document" doesn't exist in the command template, and the calling of formatting by JS doesn't do anything.
same issue using react-monaco-editor
with version 0.34.0
same problem here.
+1
with version 0.25.2, i'm using workaround of registering xml in html language service.
monaco.languages.html.registerHTMLLanguageService('xml', {}, { documentFormattingEdits: true })
+1
Seems like monaco would ship with an xml formatter but for those landing here looking for an alternative to registering the html worker as suggested above (which absolutely works btw)
Register a format provider for xml
monaco.languages.registerDocumentFormattingEditProvider('xml', {
async provideDocumentFormattingEdits(model, options, token) {
return [
{
range: model.getFullModelRange(),
text: formatXml(model.getValue()),
},
];
},
});
choose your own format function/lib but here is shared by a SO posts that works fine for me.
function formatXml(xml) {
// https://stackoverflow.com/questions/57039218/doesnt-monaco-editor-support-xml-language-by-default
const PADDING = ' '.repeat(2);
const reg = /(>)(<)(\/*)/g;
let pad = 0;
xml = xml.replace(reg, '$1\r\n$2$3');
return xml.split('\r\n').map((node, index) => {
let indent = 0;
if (node.match(/.+<\/\w[^>]*>$/)) {
indent = 0;
} else if (node.match(/^<\/\w/) && pad > 0) {
pad -= 1;
} else if (node.match(/^<\w[^>]*[^/]>.*$/)) {
indent = 1;
} else {
indent = 0;
}
pad += indent;
return PADDING.repeat(pad - indent) + node;
}).join('\r\n');
}
We closed this issue because we don't plan to address it in the foreseeable future. If you disagree and feel that this issue is crucial: we are happy to listen and to reconsider.
If you wonder what we are up to, please see our roadmap and issue reporting guidelines.
Thanks for your understanding, and happy coding!