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", "type": "boolean",
"default": false, "default": false,
"description": "Remove XML comments when XML is minified." "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 * as vsc from 'vscode';
import { TextEditorCommands } from './Commands'; import { TextEditorCommands } from './Commands';
import { XmlDocumentFormattingEditProvider, XmlRangeFormattingEditProvider } from './providers/Formatting'; import { XmlFormattingEditProvider } from './providers/Formatting';
export var GlobalState: vsc.Memento; export var GlobalState: vsc.Memento;
export var WorkspaceState: vsc.Memento; export var WorkspaceState: vsc.Memento;
@ -24,8 +24,8 @@ export function activate(ctx: vsc.ExtensionContext) {
// register language feature providers // register language feature providers
ctx.subscriptions.push( ctx.subscriptions.push(
vsc.languages.registerDocumentFormattingEditProvider(LANG_XML, new XmlDocumentFormattingEditProvider()), vsc.languages.registerDocumentFormattingEditProvider(LANG_XML, new XmlFormattingEditProvider()),
vsc.languages.registerDocumentRangeFormattingEditProvider(LANG_XML, new XmlRangeFormattingEditProvider()) vsc.languages.registerDocumentRangeFormattingEditProvider(LANG_XML, new XmlFormattingEditProvider())
); );
} }

View File

@ -2,21 +2,32 @@
import * as vsc from 'vscode'; import * as vsc from 'vscode';
import { RangeUtil } from '../utils/RangeUtil'; 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[] { provideDocumentFormattingEdits(document: vsc.TextDocument, options: vsc.FormattingOptions): vsc.TextEdit[] {
let range = RangeUtil.getRangeForDocument(document); 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[] { 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()); let xml = formatter.format(document.getText());
return [ vsc.TextEdit.replace(range, xml) ]; return [ vsc.TextEdit.replace(range, xml) ];

View File

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