From 156e1ab43566a930e755dcbaeadb6b654403eab3 Mon Sep 17 00:00:00 2001 From: Josh Johnson Date: Tue, 29 May 2018 21:56:29 -0400 Subject: [PATCH] Pretty Self-Closing Tags Issue: #149 --- package.json | 6 ++++++ src/common/configuration.ts | 4 ++++ src/formatting/formatters/v2-xml-formatter.ts | 8 ++++++++ src/formatting/xml-formatting-options.ts | 2 ++ src/test/extension.test.ts | 5 +++++ 5 files changed, 25 insertions(+) diff --git a/package.json b/package.json index 62eeb1c..d2b93e4 100644 --- a/package.json +++ b/package.json @@ -86,6 +86,12 @@ "description": "Enables auto-reveal of elements in the XML Document view when a start tag is clicked in the editor.", "scope": "window" }, + "xmlTools.enforcePrettySelfClosingTagOnFormat": { + "type": "boolean", + "default": false, + "description": "Enforces a space before the forward slash at the end of a self-closing XML tag.", + "scope": "resource" + }, "xmlTools.ignoreDefaultNamespace": { "type": "boolean", "default": true, diff --git a/src/common/configuration.ts b/src/common/configuration.ts index 0a3ef1c..b1461d0 100644 --- a/src/common/configuration.ts +++ b/src/common/configuration.ts @@ -43,6 +43,10 @@ export class Configuration { return this._getForWindow("xqueryExecutionInputSearchPattern"); } + static enforcePrettySelfClosingTagOnFormat(resource: Uri): boolean { + return this._getForResource("enforcePrettySelfClosingTagOnFormat", resource); + } + static removeCommentsOnMinify(resource: Uri): boolean { return this._getForResource("removeCommentsOnMinify", resource); } diff --git a/src/formatting/formatters/v2-xml-formatter.ts b/src/formatting/formatters/v2-xml-formatter.ts index 647080f..c67b0c9 100644 --- a/src/formatting/formatters/v2-xml-formatter.ts +++ b/src/formatting/formatters/v2-xml-formatter.ts @@ -135,6 +135,14 @@ export class V2XmlFormatter implements XmlFormatter { location = Location.StartTag; } + // approaching the end of a self-closing tag where there was no whitespace (issue #149) + else if ((location === Location.StartTag || location === Location.StartTagName) + && cc === "/" + && pc !== " " + && options.enforcePrettySelfClosingTagOnFormat) { + output += " /"; + } + // exiting StartTag or StartTag.StartTagName, entering Text else if ((location === Location.StartTag || location === Location.StartTagName) && cc === ">") { // if this was a self-closing tag, we need to decrement the indent level and add a newLine diff --git a/src/formatting/xml-formatting-options.ts b/src/formatting/xml-formatting-options.ts index bcfdffd..06782a1 100644 --- a/src/formatting/xml-formatting-options.ts +++ b/src/formatting/xml-formatting-options.ts @@ -5,6 +5,7 @@ import * as constants from "../constants"; export interface XmlFormattingOptions { editorOptions: FormattingOptions; + enforcePrettySelfClosingTagOnFormat: boolean; newLine: string; removeCommentsOnMinify: boolean; splitAttributesOnFormat: boolean; @@ -15,6 +16,7 @@ export class XmlFormattingOptionsFactory { static getXmlFormattingOptions(formattingOptions: FormattingOptions, document: TextDocument): XmlFormattingOptions { return { editorOptions: formattingOptions, + enforcePrettySelfClosingTagOnFormat: Configuration.enforcePrettySelfClosingTagOnFormat(document.uri), newLine: (document.eol === EndOfLine.CRLF) ? "\r\n" : "\n", removeCommentsOnMinify: Configuration.removeCommentsOnMinify(document.uri), splitAttributesOnFormat: Configuration.splitAttributesOnFormat(document.uri), diff --git a/src/test/extension.test.ts b/src/test/extension.test.ts index c7c9439..50adb2b 100644 --- a/src/test/extension.test.ts +++ b/src/test/extension.test.ts @@ -17,6 +17,7 @@ describe("V2XmlFormatter", () => { insertSpaces: true, tabSize: 4 }, + enforcePrettySelfClosingTagOnFormat: false, newLine: "\r\n", removeCommentsOnMinify: false, splitAttributesOnFormat: false, @@ -60,7 +61,11 @@ describe("V2XmlFormatter", () => { }); it("should allow users to enforce space before self-closing tag slash", () => { + options.enforcePrettySelfClosingTagOnFormat = true; + testFormatter(xmlFormatter, options, "issue-149"); + + options.enforcePrettySelfClosingTagOnFormat = false; }); });