Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Option to Preserve Whitespace Between Attributes on Format #342

Merged
merged 3 commits into from
Nov 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,12 @@
"default": "**/*.xml",
"description": "The pattern used to search for input XML files when executing XQuery scripts.",
"scope": "window"
},
"xmlTools.preserveSpacesBetweenAttributes": {
"type": "boolean",
"default": false,
"description": "Preserves any spaces between attributes during formatting.",
"scope": "resource"
}
}
},
Expand Down
6 changes: 5 additions & 1 deletion src/common/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,15 @@ export class Configuration {
return this._getForResource<boolean>("splitXmlnsOnFormat", resource);
}

static preserveSpacesBetweenAttributes(resource: Uri): boolean {
return this._getForResource<boolean>("preserveSpacesBetweenAttributes", resource);
}

private static _getForResource<T>(section: string, resource: Uri): T {
return workspace.getConfiguration(ExtensionTopLevelSection, resource).get<T>(section);
}

private static _getForWindow<T>(section: string): T {
private static _getForWindow<T>(section: string): T {
return workspace.getConfiguration(ExtensionTopLevelSection).get<T>(section);
}
}
14 changes: 10 additions & 4 deletions src/formatting/formatters/v2-xml-formatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,18 @@ export class V2XmlFormatter implements XmlFormatter {
});

// do some light minification to get rid of insignificant whitespace
xml = xml.replace(/"\s+(?=[^\s]+=)/g, "\" "); // spaces between attributes
if (!options.preserveSpacesBetweenAttributes) {
xml = xml.replace(/"\s+(?=[^\s]+=)/g, "\" "); // spaces between attributes
}

xml = xml.replace(/"\s+(?=>)/g, "\""); // spaces between the last attribute and tag close (>)
xml = xml.replace(/"\s+(?=\/>)/g, "\" "); // spaces between the last attribute and tag close (/>)
xml = xml.replace(/(?!<!\[CDATA\[)[^ <>="]\s+[^ <>="]+=(?![^<]*?\]\]>)/g, (match: string) => { // spaces between the node name and the first attribute
return match.replace(/\s+/g, " ");
});

if (!options.preserveSpacesBetweenAttributes) {
xml = xml.replace(/(?!<!\[CDATA\[)[^ <>="]\s+[^ <>="]+=(?![^<]*?\]\]>)/g, (match: string) => { // spaces between the node name and the first attribute
return match.replace(/\s+/g, " ");
});
}

// the coast is clear - we can drop those "<" brackets back in
xml = this._unsanitizeCommentsAndCDATA(xml);
Expand Down
5 changes: 3 additions & 2 deletions src/formatting/xml-formatting-options.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { EndOfLine, FormattingOptions, TextDocument } from "vscode";

import { Configuration } from "../common";
import * as constants from "../constants";

export interface XmlFormattingOptions {
editorOptions: FormattingOptions;
Expand All @@ -11,6 +10,7 @@ export interface XmlFormattingOptions {
splitAttributesOnFormat: boolean;
splitXmlnsOnFormat: boolean;
initialIndentLevel?: number;
preserveSpacesBetweenAttributes: boolean;
}

export class XmlFormattingOptionsFactory {
Expand All @@ -22,7 +22,8 @@ export class XmlFormattingOptionsFactory {
removeCommentsOnMinify: Configuration.removeCommentsOnMinify(document.uri),
splitAttributesOnFormat: Configuration.splitAttributesOnFormat(document.uri),
splitXmlnsOnFormat: Configuration.splitXmlnsOnFormat(document.uri),
initialIndentLevel: 0
initialIndentLevel: 0,
preserveSpacesBetweenAttributes: Configuration.preserveSpacesBetweenAttributes(document.uri)
};
}
}
14 changes: 12 additions & 2 deletions src/test/extension.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ describe("V2XmlFormatter", () => {
newLine: "\r\n",
removeCommentsOnMinify: false,
splitAttributesOnFormat: false,
splitXmlnsOnFormat: true
splitXmlnsOnFormat: true,
preserveSpacesBetweenAttributes: false
};

it("should handle basic XML", () => {
Expand Down Expand Up @@ -111,6 +112,14 @@ describe("V2XmlFormatter", () => {
it("should handle mixed content on the same line as another element without error", () => {
testFormatter(xmlFormatter, options, "issue-294");
});

it("should optionally preserve whitespace between attributes", () => {
options.preserveSpacesBetweenAttributes = true;

testFormatter(xmlFormatter, options, "issue-308");

options.preserveSpacesBetweenAttributes = false;
});
});

describe("#minifyXml(xml, options)", () => {
Expand All @@ -124,7 +133,8 @@ describe("V2XmlFormatter", () => {
newLine: "\r\n",
removeCommentsOnMinify: false,
splitAttributesOnFormat: false,
splitXmlnsOnFormat: true
splitXmlnsOnFormat: true,
preserveSpacesBetweenAttributes: false
};

it("should preserve whitespace on minify if xml:space is set to 'preserve-whitespace'", () => {
Expand Down
11 changes: 11 additions & 0 deletions src/test/test-data/issue-308.formatted.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<object type="output parameters">
<!-- output directory -->
<param name="output directory" type="string" default="output"></param>
<!-- output files -->
<param name="crystal file" required="false" type="string" default="Slime_-_crystals"></param>
<param name="macrocell file" required="false" type="string" default="Slime_-_macrocells"></param>
<param name="macrolayer file" required="false" type="string" default="Slime_-_macrolayers"></param>
<param name="area file" required="false" type="string" default="Nerd_-_Area"></param>
<param name="final stack file" required="false" type="string" default="Mads_-_Final_Stack"></param>
<param name="all stacks file" required="false" type="string" default="Mads_-_All_Stacks"></param>
</object>
11 changes: 11 additions & 0 deletions src/test/test-data/issue-308.unformatted.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<object type="output parameters">
<!-- output directory -->
<param name="output directory" type="string" default="output"></param>
<!-- output files -->
<param name="crystal file" required="false" type="string" default="Slime_-_crystals"></param>
<param name="macrocell file" required="false" type="string" default="Slime_-_macrocells"></param>
<param name="macrolayer file" required="false" type="string" default="Slime_-_macrolayers"></param>
<param name="area file" required="false" type="string" default="Nerd_-_Area"></param>
<param name="final stack file" required="false" type="string" default="Mads_-_Final_Stack"></param>
<param name="all stacks file" required="false" type="string" default="Mads_-_All_Stacks"></param>
</object>