Make XMLNS Split Optional

New setting: xmlTools.slpitXmlnsOnFormat
This commit is contained in:
Josh Johnson 2016-01-08 09:19:27 -05:00
parent 721f50cc37
commit 08c81f7d16
4 changed files with 58 additions and 24 deletions

View File

@ -58,6 +58,11 @@
"type": "boolean",
"default": false,
"description": "Remove XML comments when XML is minified."
},
"xmlTools.splitXmlnsOnFormat": {
"type": "boolean",
"default": true,
"description": "Put each xmlns attribute on a new line when fromatting XML."
}
}
},

View File

@ -2,7 +2,7 @@
import * as vsc from 'vscode';
import { TextEditorCommands } from './Commands';
import { XmlDocumentFormattingEditProvider, XmlRangeFormattingEditProvider } from './providers/Formatting';
import { XmlFormattingEditProvider } from './providers/Formatting';
export var GlobalState: vsc.Memento;
export var WorkspaceState: vsc.Memento;
@ -24,8 +24,8 @@ export function activate(ctx: vsc.ExtensionContext) {
// register language feature providers
ctx.subscriptions.push(
vsc.languages.registerDocumentFormattingEditProvider(LANG_XML, new XmlDocumentFormattingEditProvider()),
vsc.languages.registerDocumentRangeFormattingEditProvider(LANG_XML, new XmlRangeFormattingEditProvider())
vsc.languages.registerDocumentFormattingEditProvider(LANG_XML, new XmlFormattingEditProvider()),
vsc.languages.registerDocumentRangeFormattingEditProvider(LANG_XML, new XmlFormattingEditProvider())
);
}

View File

@ -2,21 +2,32 @@
import * as vsc from 'vscode';
import { RangeUtil } from '../utils/RangeUtil';
import { XmlFormatter } from '../services/XmlFormatter';
import { XmlFormatter, IXmlFormatterOptions } from '../services/XmlFormatter';
export class XmlDocumentFormattingEditProvider implements vsc.DocumentFormattingEditProvider {
const CFG_SECTION: string = 'xmlTools';
const CFG_SPLIT_NAMESPACES: string = 'splitXmlnsOnFormat';
export class XmlFormattingEditProvider implements vsc.DocumentFormattingEditProvider, vsc.DocumentRangeFormattingEditProvider {
provideDocumentFormattingEdits(document: vsc.TextDocument, options: vsc.FormattingOptions): vsc.TextEdit[] {
let range = RangeUtil.getRangeForDocument(document);
let formatter = new XmlFormatter(options.insertSpaces, options.tabSize);
let xml = formatter.format(document.getText());
return [ vsc.TextEdit.replace(range, xml) ];
return this._provideFormattingEdits(document, range, options);
}
}
export class XmlRangeFormattingEditProvider implements vsc.DocumentRangeFormattingEditProvider {
provideDocumentRangeFormattingEdits(document: vsc.TextDocument, range: vsc.Range, options: vsc.FormattingOptions): vsc.TextEdit[] {
let formatter = new XmlFormatter(options.insertSpaces, options.tabSize);
return this._provideFormattingEdits(document, range, options);
}
private _provideFormattingEdits(document: vsc.TextDocument, range: vsc.Range, options: vsc.FormattingOptions): vsc.TextEdit[] {
let splitNamespaces: boolean = vsc.workspace.getConfiguration(CFG_SECTION).get<boolean>(CFG_SPLIT_NAMESPACES, true);
let formatterOptions: IXmlFormatterOptions = {
preferSpaces: options.insertSpaces,
tabSize: options.tabSize,
splitNamespaces: splitNamespaces
};
let formatter = new XmlFormatter(formatterOptions);
let xml = formatter.format(document.getText());
return [ vsc.TextEdit.replace(range, xml) ];

View File

@ -2,29 +2,40 @@
// Based on pretty-data (https://github.com/vkiryukhin/pretty-data)
export class XmlFormatter {
constructor(preferSpaces?: boolean, tabSize?: number, newLine?: string) {
if (typeof preferSpaces === 'undefined') {
preferSpaces = false;
constructor(options?: IXmlFormatterOptions) {
options = options || {};
if (typeof options.preferSpaces === 'undefined') {
options.preferSpaces = false;
}
tabSize = tabSize || 4;
newLine = newLine || '\n';
if (typeof options.splitNamespaces === 'undefined') {
options.splitNamespaces = true;
}
this.newLine = newLine || '\n';
this.indentPattern = (preferSpaces) ? ' '.repeat(tabSize) : '\t';
options.tabSize = options.tabSize || 4;
options.newLine = options.newLine || '\n';
this.newLine = options.newLine || '\n';
this.indentPattern = (options.preferSpaces) ? ' '.repeat(options.tabSize) : '\t';
this.splitNamespaces = options.splitNamespaces;
}
newLine: string;
indentPattern: string;
splitNamespaces: boolean;
format(xml: string): string {
xml = this.minify(xml, false);
xml = xml.replace(/</g, '~::~<');
let parts: string[] = xml
.replace(/</g,"~::~<")
.replace(/xmlns\:/g,"~::~xmlns:")
.replace(/xmlns\=/g,"~::~xmlns=")
.split('~::~');
if (this.splitNamespaces) {
xml = xml
.replace(/xmlns\:/g, '~::~xmlns:')
.replace(/xmlns\=/g, '~::~xmlns=');
}
let parts: string[] = xml.split('~::~');
let inComment: boolean = false;
let level: number = 0;
@ -119,4 +130,11 @@ export class XmlFormatter {
return `${this.newLine}${this.indentPattern.repeat(level)}${trailingValue}`;
}
}
export interface IXmlFormatterOptions {
preferSpaces?: boolean;
tabSize?: number;
newLine?: string;
splitNamespaces?: boolean;
}