At Red Hat, we look forward to creating and updating tools to improve the developer experience for users of various language servers. Visual Studio Code is one of the most popular tools for developers. The rich ecosystem of multiple extensions makes it more powerful.
We are excited to announce the release of VSCode XML Extension 0.22.0 in Visual Studio Code Marketplace and OpenVSX Registry and the addition of more improvements and features to work with XML and improve the overall developer experience.
A little VSCode XML history
The VSCode team has continuously worked with the community and received user feedback and requests. It is interesting to see the evolution of the software based on these requests. The extension was originally created to manage pom.xml files of maven projects with the VSCode Java extension and provide XML and XSD support.
VSCode XML uses the LemMinx language server written in Java to provide the various language features. However, this required Java installation. Over time, we received more and more requests from users to use the extension without Java. That's why we provided the binary feature to run the language server without Java.
Because of multiple feature requests for RelaxNG support, we integrated Jing to implement RelaxNG support in the VSCode XML extension. This has been a great addition to the extension's feature list and has shown an upward trend in usage after the release.
Since then, we have made multiple improvements. In this blog, we will focus on two important features added to the current release.
- RelaxNG support provides completion, hover, and validation in XML files based on RelaxNG schemas.
- We have made improvements to our experimental XML formatter.
1. RelaxNG support
RelaxNG support provides completion, hover, and validation in XML files based on RelaxNG schemas (XML syntax and compact syntax). Figure 1 explains the workflow:
Validation
XML validation based on RelaxNG (rng
and rnc
) is supported as shown in Figure 2:
Completion
It supports XML completion based on RelaxNG (rng
, rnc
). The completion for rng
displays the documentation in Figure 3:
Hover
Hover based on RelaxNG rng
shows the documentation in Figure 4:
Go to type definition
From the XML document, you can go to the type definition to navigate to the element/attribute declaration for rnc
and
To do this, select an XML element/attribute and use the contextual menu Go to Type Definition
as shown in Figure 5.
When you click on this menu item, VS Code will open the rng
or rnc
grammar file and place the cursor on the proper element/attribute
declaration as shown in Figure 6.
2. The experimental formatter
The current XML formatter works correctly when XML is valid. For instance, given the following XML content:
<foo><bar></bar></foo>
The XML is formatted like this:
<foo>
<bar></bar>
</foo>
But when XML content is invalid, as in the following example:
<foo><bar'</bar></foo>
The XML is formatted like the following:
<foo>
<bar
The formatter will lose all the invalid content, which can be extremely annoying. It is one reason we re-implemented a formatter from scratch with a new strategy. Here is the invalid content from above reformatted with the new experimental formatter:
<foo>
<bar'</bar></foo>
To activate the experimental formatter, set “xml > Format: Experimental” to “true” on the VS Code Settings Page or add the following to your settings.json:
"xml.format.experimental": true
This also opens the extension to the possibility of supporting XML with various embedded content within XML documents (eg. EJS).
Our goal is to make this new formatter the default once it supports all features of the current formatter. Please don’t hesitate to create any issues to improve the experimental formatter.
How the new formatter works
The current formatter gets the DOM document, the abstract representation of the XML document that vscode-xml
uses and rewrites the content of the document in one text edit:
[
{
"range": {
"start": {
"line": 0,
"character": 0
},
"end": {
"line": 0,
"character": 22
}
},
"newText": "<foo>\r\n\t<bar></bar>\r\n</foo>"
}
]
The new experimental formatter preserves all non-whitespace content and inserts or removes spaces to correctly indent the XML content. In the following sample, two TextEdit are generated. The insert/replace characters avoid losing invalid content.
[
{
"range": {
"start": {
"line": 0,
"character": 5
},
"end": {
"line": 0,
"character": 5
}
},
"newText": "\r\n\t"
},
{
"range": {
"start": {
"line": 0,
"character": 16
},
"end": {
"line": 0,
"character": 16
}
},
"newText": "\r\n"
}
]
New experimental formatter settings
In addition to a list of default elements where whitespace will be preserved, users may choose to modify this with their own set of elements. Refer to the documentation preserve space page for more information.
The following example shows two ways in which whitespaces will be preserved.
(Note: XML remains the same after formatting.)
Method #1: Figure 7 shows literallayout
in the list of default elements where whitespaces will be preserved.
Method #2: Figure 8 shows that any element with xml:space = “preserve”
will preserve whitespaces.
Support for the ability to set a maximum line width has been requested and upvoted by many users. Currently, this setting works with text content and comments. We are on track to extend this feature to cover other use cases such as attributes and ensure its behavior is consistent when applied in combination with other settings. Refer to the documentation for maximum line width formatting.
The example in Figure 9 shows formatting with maxLineWidth
set to the default value of 80.
There are a growing number of use cases supported with this setting. This option enables the formatter to consider XML Schema/DTD grammar information when making decisions. For instance, an element defined as “xs:string
” in the schema will preserve any whitespace in the content when formatting.
For more information on the specific use cases, visit the official VSCode XML GitHub page.
Contribute and get support
This is an open-source project available to anyone. Contributions are extremely welcome! To get started, refer to the contributing instructions.
If you encounter any bugs, confusing commands, or unclear documentation, or if you would like to propose a feature request, you can:
- File a bug in GitHub Issues.
- Chat with us on Gitter.
- Review documentation on GitHub.
- Refer to the Release Notes.
We are actively working to improve the developer experience with XML. Stay tuned for more features coming soon!
Last updated: November 8, 2023