From 54ff41c736ef5753028d4c4fce110fbb5ff217de Mon Sep 17 00:00:00 2001 From: Josh Johnson Date: Sat, 15 Sep 2018 22:39:27 -0400 Subject: [PATCH 1/2] Expose Initial Indent Level --- src/formatting/formatters/v2-xml-formatter.ts | 4 ++-- src/formatting/xml-formatting-options.ts | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/formatting/formatters/v2-xml-formatter.ts b/src/formatting/formatters/v2-xml-formatter.ts index 1a91e43..a22feac 100644 --- a/src/formatting/formatters/v2-xml-formatter.ts +++ b/src/formatting/formatters/v2-xml-formatter.ts @@ -29,7 +29,7 @@ export class V2XmlFormatter implements XmlFormatter { let output = ""; - let indentLevel = 0; + let indentLevel = options.initialIndentLevel; let attributeQuote = ""; let lineBreakSpree = false; let lastWordCharacter: string | undefined; @@ -194,7 +194,7 @@ export class V2XmlFormatter implements XmlFormatter { && cc === "/" && pc !== " " && options.enforcePrettySelfClosingTagOnFormat) { - output += " /"; + output += " /"; } // exiting StartTag or StartTag.StartTagName, entering Text diff --git a/src/formatting/xml-formatting-options.ts b/src/formatting/xml-formatting-options.ts index 06782a1..818d6e3 100644 --- a/src/formatting/xml-formatting-options.ts +++ b/src/formatting/xml-formatting-options.ts @@ -10,6 +10,7 @@ export interface XmlFormattingOptions { removeCommentsOnMinify: boolean; splitAttributesOnFormat: boolean; splitXmlnsOnFormat: boolean; + initialIndentLevel: number; } export class XmlFormattingOptionsFactory { @@ -20,7 +21,8 @@ export class XmlFormattingOptionsFactory { newLine: (document.eol === EndOfLine.CRLF) ? "\r\n" : "\n", removeCommentsOnMinify: Configuration.removeCommentsOnMinify(document.uri), splitAttributesOnFormat: Configuration.splitAttributesOnFormat(document.uri), - splitXmlnsOnFormat: Configuration.splitXmlnsOnFormat(document.uri) + splitXmlnsOnFormat: Configuration.splitXmlnsOnFormat(document.uri), + initialIndentLevel: 0 }; } } From 66b2bc3de2b52705a4a81fda21dfebe0b63ed8aa Mon Sep 17 00:00:00 2001 From: Josh Johnson Date: Sat, 15 Sep 2018 23:05:36 -0400 Subject: [PATCH 2/2] Preserve Indent Context Fixes #131 --- src/formatting/formatters/v2-xml-formatter.ts | 2 +- .../xml-formatting-edit-provider.ts | 39 +++++++++++++++++-- src/formatting/xml-formatting-options.ts | 2 +- 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/formatting/formatters/v2-xml-formatter.ts b/src/formatting/formatters/v2-xml-formatter.ts index a22feac..d28a731 100644 --- a/src/formatting/formatters/v2-xml-formatter.ts +++ b/src/formatting/formatters/v2-xml-formatter.ts @@ -29,7 +29,7 @@ export class V2XmlFormatter implements XmlFormatter { let output = ""; - let indentLevel = options.initialIndentLevel; + let indentLevel = options.initialIndentLevel || 0; let attributeQuote = ""; let lineBreakSpree = false; let lastWordCharacter: string | undefined; diff --git a/src/formatting/xml-formatting-edit-provider.ts b/src/formatting/xml-formatting-edit-provider.ts index 6a7f9f2..a64c05c 100644 --- a/src/formatting/xml-formatting-edit-provider.ts +++ b/src/formatting/xml-formatting-edit-provider.ts @@ -22,10 +22,43 @@ export class XmlFormattingEditProvider implements DocumentFormattingEditProvider } provideDocumentRangeFormattingEdits(document: TextDocument, range: Range, options: FormattingOptions, token: CancellationToken): ProviderResult { - let xml = document.getText(range); + const allXml = document.getText(); + let selectedXml = document.getText(range); + const extFormattingOptions = XmlFormattingOptionsFactory.getXmlFormattingOptions(options, document); - xml = this.xmlFormatter.formatXml(xml, XmlFormattingOptionsFactory.getXmlFormattingOptions(options, document)); + const selectionStartOffset = document.offsetAt(range.start); + let tabCount = 0; + let spaceCount = 0; - return [ TextEdit.replace(range, xml) ]; + for (let i = (selectionStartOffset - 1); i >= 0; i--) { + const cc = allXml.charAt(i); + + if (/\t/.test(cc)) { + tabCount++; + } + + else if (/ /.test(cc)) { + spaceCount++; + } + + else { + break; + } + } + + if (options.insertSpaces) { + extFormattingOptions.initialIndentLevel = Math.ceil(spaceCount / (options.tabSize || 1)); + } + + else { + extFormattingOptions.initialIndentLevel = tabCount; + } + + selectedXml = this.xmlFormatter.formatXml(selectedXml, extFormattingOptions); + + // we need to remove the leading whitespace because the formatter will add an indent before the first element + selectedXml = selectedXml.replace(/^\s+/, ""); + + return [TextEdit.replace(range, selectedXml)]; } } diff --git a/src/formatting/xml-formatting-options.ts b/src/formatting/xml-formatting-options.ts index 818d6e3..7c5185a 100644 --- a/src/formatting/xml-formatting-options.ts +++ b/src/formatting/xml-formatting-options.ts @@ -10,7 +10,7 @@ export interface XmlFormattingOptions { removeCommentsOnMinify: boolean; splitAttributesOnFormat: boolean; splitXmlnsOnFormat: boolean; - initialIndentLevel: number; + initialIndentLevel?: number; } export class XmlFormattingOptionsFactory {