Skip to content

Commit

Permalink
Provide basic experimental formatter which supports invalid XML
Browse files Browse the repository at this point in the history
See eclipse/lemminx#1195

Signed-off-by: azerr <[email protected]>
  • Loading branch information
angelozerr committed Jun 20, 2022
1 parent 1d87692 commit 33cacdb
Show file tree
Hide file tree
Showing 3 changed files with 212 additions and 43 deletions.
15 changes: 1 addition & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,20 +86,6 @@ The following settings are supported:
* `xml.downloadExternalResources.enabled`: Download external resources like referenced DTD, XSD. Default is `true`.
* [`xml.fileAssociations`](https://github.com/redhat-developer/vscode-xml/blob/master/docs/Preferences.md#file-associations): Allows XML schemas/ DTD to be associated to file name patterns.
* [`xml.foldings.includeClosingTagInFold`](https://github.com/redhat-developer/vscode-xml/blob/master/docs/Folding.md#xmlfoldingincludeClosingTagInFold): Minimize the closing tag after folding. Default is `false`.
* [`xml.format.enabled`](https://github.com/redhat-developer/vscode-xml/blob/master/docs/Formatting.md#xmlformatenabled): Enable/disable ability to format document. Default is `true`.
* [`xml.format.emptyElements`](https://github.com/redhat-developer/vscode-xml/blob/master/docs/Formatting.md#xmlformatemptyelements): Expand/collapse empty elements. Default is `ignore`.
* [`xml.format.enforceQuoteStyle`](https://github.com/redhat-developer/vscode-xml/blob/master/docs/Formatting.md#xmlformatenforcequotestyle): Enforce `preferred` quote style (set by `xml.preferences.quoteStyle`) or `ignore` quote style when formatting. Default is `ignore`.
* [`xml.format.joinCDATALines`](https://github.com/redhat-developer/vscode-xml/blob/master/docs/Formatting.md#xmlformatjoincdatalines): Set to `true` to join lines in CDATA content during formatting. Default is `false`.
* [`xml.format.joinCommentLines`](https://github.com/redhat-developer/vscode-xml/blob/master/docs/Formatting.md#xmlformatjoincommentlines): Set to `true` to join lines in comments during formatting. Default is `false`.
* [`xml.format.joinContentLines`](https://github.com/redhat-developer/vscode-xml/blob/master/docs/Formatting.md#xmlformatjoincontentlines): Normalize the whitespace of content inside an element. Newlines and excess whitespace are removed. Default is `false`.
* [`xml.format.preserveAttributeLineBreaks`](https://github.com/redhat-developer/vscode-xml/blob/master/docs/Formatting.md#xmlformatpreserveattributelinebreaks): Preserve line breaks that appear before and after attributes. Default is `false`.
**IMPORTANT**: This setting is overridden if `xml.format.splitAttributes` is set to `true`.
* [`xml.format.preserveEmptyContent`](https://github.com/redhat-developer/vscode-xml/blob/master/docs/Formatting.md#xmlformatpreserveemptycontent): Preserve empty content/whitespace in a tag. Default is `false`.
* [`xml.format.preservedNewLines`](https://github.com/redhat-developer/vscode-xml/blob/master/docs/Formatting.md#xmlformatpreservednewlines): Preserve new lines that separate tags. The value represents the maximum number of new lines per section. A value of 0 removes all new lines. Default is `2`.
* [`xml.format.spaceBeforeEmptyCloseTag`](https://github.com/redhat-developer/vscode-xml/blob/master/docs/Formatting.md#xmlformatspacebeforeemptyclosetag): Insert space before end of self closing tag.
Example: ```<tag/> -> <tag />```. Default is `true`.
* [`xml.format.splitAttributes`](https://github.com/redhat-developer/vscode-xml/blob/master/docs/Formatting.md#xmlformatsplitattributes): Split multiple attributes each onto a new line. Default is `false`.
* [`xml.format.splitAttributesIndentSize`](https://github.com/redhat-developer/vscode-xml/blob/master/docs/Formatting.md#xmlformatsplitattributesindentsize): How many levels to indent the attributes by when `xml.format.splitAttributes` is `true`. Default value is `2`.
* `xml.preferences.quoteStyle`: Preferred quote style to use for completion: `single` quotes, `double` quotes. Default is `double`.
* `xml.autoCloseTags.enabled` : Enable/disable autoclosing of XML tags. Default is `true`.
**IMPORTANT**: The following settings must be turned of for this to work: `editor.autoClosingTags`, `editor.autoClosingBrackets`.
Expand All @@ -117,6 +103,7 @@ The following settings are supported:
* [`xml.symbols.showReferencedGrammars`](https://github.com/redhat-developer/vscode-xml/blob/master/docs/Symbols.md#xmlsymbolsshowreferencedgrammars): Show referenced grammars in the Outline. Default is `true`.
* [`xml.symbols.filters`](https://github.com/redhat-developer/vscode-xml/blob/master/docs/Symbols.md#xmlsymbolsfilters): Allows XML symbols filter to be associated to file name patterns.
* `files.trimTrailingWhitespace`: Now affects XML formatting. Enable/disable trailing whitespace trimming when formatting an XML document. Default is `false`.
* See [`Formatting settings`](https://github.com/redhat-developer/vscode-xml/blob/master/docs/Formatting.md) for a detailed list of the formatting settings.

## Telemetry

Expand Down
181 changes: 163 additions & 18 deletions docs/Formatting.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,91 @@

***

### xml.format.enforceQuoteStyle
### xml.format.experimental

Set to `true` to enable experimental formatter. Defaults to `false`.

As we have more and more issues with our current XML formatter, we have decided to redo our formatter to try to fix them. This new formatter is in experimental state because it doesn't support all current formatter settings and it could have some bugs. To enable this experimental formatter you can set the setting `xml.format.experimental` to true.

Once we have enough good feedback and we support all current formatting settings, we will replace the current formatter with the experimental formatter. Don't hesitate to [create issues](https://github.com/redhat-developer/vscode-xml/issues) to give us feedback with this experimental formatter.

The current formatter uses the DOM document and rewrite the XML document or a fragment of XML (when range formatting is processed). This strategy provides a lot of bugs if XML is not valid (ex : <% will format with <null).

The new strategy is to format the current XML by adding or removing some spaces without updating the XML content. The experimental formatter categorizes each element as :

* `ignore space`
* `normalize space`
* `mixed content`
* and `preserve space`. Also, you can use `xml:space="preserve"` to preserve spaces in some elements or use `xml.format.preserveSpace` to add a given tag element which must preserve spaces.

Once the element is categorized, the element content is formatted according the category:

* `ignore space` :

Enforce `preferred` quote style (set by `xml.preferences.quoteStyle`) or `ignore` quote style when formatting.
```xml
<foo>
<bar></bar> </foo>
```

For instance, when set to `preferred` with `xml.preferences.quoteStyle` set to `single`, the following document:
Here `foo` is categorized as `ignore space`, because all children are tag elements and only spaces. it means that it removes all spaces . After formatting you should see this result:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<root>
<child attribute='value' otherAttribute="otherValue"></child>
</root>
```
```xml
<foo>
<bar></bar>
</foo>
```

will be formatted to:
* `normalize space` :

```xml
<foo>
abc
def
</foo>
```

```xml
<?xml version='1.0' encoding='UTF-8'?>
<root>
<child attribute='value' otherAttribute='otherValue'></child>
</root>
```
Here `foo` is categorized as `normalize space`, it means that it removes all spaces with one space. After formatting you should see this result:

No changes to quotes will occur during formatting if `xml.format.enforceQuoteStyle` is set to `ignore`.
```xml
<foo> abc def </foo>
```

* `preserve space`

If you want to preserve space, you can use `xml:space="preserve"` to preserve spaces in some elements or use `xml.format.preserveSpace`

```xml
<foo xml:space="preserve" >
abc
def
</foo>
```

Here `foo` is categorized as `preserve space`, after formatting you should see this result:

```xml
<foo xml:space="preserve" >
abc
def
</foo>
```

* `mixed content`

```xml
<foo>
<bar></bar>
abc
def
</foo>
```

Here `foo` is categorized as `mixed content` (it contains text and tag element), it means that it removes all spaces with one space. After formatting you should see this result:

```xml
<foo>
<bar></bar> abc def </foo>
```

***

Expand Down Expand Up @@ -58,6 +120,36 @@ Set to `expand` to expand empty elements during formatting.
```
***

**Not supported by the experimental formatter.**

### xml.format.enforceQuoteStyle

Enforce `preferred` quote style (set by `xml.preferences.quoteStyle`) or `ignore` quote style when formatting.

For instance, when set to `preferred` with `xml.preferences.quoteStyle` set to `single`, the following document:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<root>
<child attribute='value' otherAttribute="otherValue"></child>
</root>
```

will be formatted to:

```xml
<?xml version='1.0' encoding='UTF-8'?>
<root>
<child attribute='value' otherAttribute='otherValue'></child>
</root>
```

No changes to quotes will occur during formatting if `xml.format.enforceQuoteStyle` is set to `ignore`.

**Not supported by the experimental formatter.**

***

### xml.format.preserveAttributeLineBreaks

Preserve line breaks that appear before and after attributes. This setting is overridden if [xml.format.splitAttributes](#xmlformatsplitattributes) is set to `true`. Default is `false`.
Expand Down Expand Up @@ -143,6 +235,8 @@ If this value is set to 0, then all blank lines will be removed during formattin
</root>
```

**Not supported by the experimental formatter.**

***

### xml.format.splitAttributes
Expand Down Expand Up @@ -178,6 +272,9 @@ If this value is set to 0, then all blank lines will be removed during formattin
```xml
<![CDATA[This is a test ]]>
```

**Not supported by the experimental formatter.**

***

### xml.format.preserveEmptyContent
Expand All @@ -194,6 +291,9 @@ If this value is set to 0, then all blank lines will be removed during formattin
<a> </a>
```
***

**Not supported by the experimental formatter.**

### xml.format.joinCommentLines

Set to `true` to join lines in comments during formatting. Defaults to `false`.
Expand All @@ -209,6 +309,8 @@ If this value is set to 0, then all blank lines will be removed during formattin
<!-- This is my comment -->
```

**Not supported by the experimental formatter.**

***

### xml.format.joinContentLines
Expand Down Expand Up @@ -236,6 +338,8 @@ If it is set to `true`, the above document becomes:
<root>Interesting text content values and 1234 numbers</root>
```

**Not supported by the experimental formatter.**

***

### xml.format.spaceBeforeEmptyCloseTag
Expand All @@ -249,6 +353,8 @@ If it is set to `true`, the above document becomes:
<tag />
```

**Not supported by the experimental formatter.**

***

### files.insertFinalNewline
Expand Down Expand Up @@ -332,7 +438,10 @@ If it is set to `true`, the above document becomes:
</ROOT:root>
```

**Not supported by the experimental formatter.**

***

### xml.format.splitAttributesIndentSize

Use to configure how many levels to indent the attributes by when [xml.format.splitAttributes](#xmlformatsplitAttributes) is set to `true`.
Expand Down Expand Up @@ -396,6 +505,7 @@ If it is set to `true`, the above document becomes:
</robot>
```
***

### xml.format.closingBracketNewLine

If set to `true`, the closing bracket (`>` or `/>`) of a tag with at least 2 attributes will be put on a new line.
Expand All @@ -409,10 +519,45 @@ Defaults to `false`.
```xml
<a b="" c="" />
```

becomes
```xml
<a
b=""
c=""
/>
```
```

**Not supported by the experimental formatter.**

### xml.format.preserveSpace

Element names for which spaces will be preserved. Defaults is the following array:

```json
[
"xsl:text",
"xsl:comment",
"xsl:processing-instruction",
"literallayout",
"programlisting",
"screen",
"synopsis",
"pre",
"xd:pre"
]
```

This settings is only available with experimental formatter.

### xml.format.maxLineWidth

Max line width. Default is `80`.

This settings is only available with experimental formatter.

### xml.format.grammarAwareFormatting

Use Schema/DTD grammar information while formatting. Default is `true`.

This settings is only available with experimental formatter.
Loading

0 comments on commit 33cacdb

Please sign in to comment.