From 802adea71926b7d34a73700d80f02ab4509b1785 Mon Sep 17 00:00:00 2001 From: Josh Johnson Date: Thu, 1 Jun 2017 21:52:09 -0400 Subject: [PATCH] Add "Format As XML" Command This command can be invoked from any document, regardless of what language is selected. It supports selection-only formatting as well. closes #97 --- package.json | 7 ++++++- src/Commands.ts | 38 ++++++++++++++++++++++++++++++++++++++ src/Extension.ts | 3 ++- 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 2a6797f..96d8946 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,10 @@ { "command": "xmlTools.viewXmlTree", "title": "XML Tools: View XML Tree" + }, + { + "command": "xmlTools.formatAsXml", + "title": "XML Tools: Format as XML" } ], "configuration": { @@ -120,7 +124,8 @@ "onCommand:xmlTools.minifyXml", "onCommand:xmlTools.evaluateXPath", "onCommand:xmlTools.executeXQuery", - "onCommand:xmlTools.viewXmlTree" + "onCommand:xmlTools.viewXmlTree", + "onCommand:xmlTools.formatAsXml" ], "devDependencies": { "vscode": "^0.11.8", diff --git a/src/Commands.ts b/src/Commands.ts index 0941d26..7a5d6f9 100644 --- a/src/Commands.ts +++ b/src/Commands.ts @@ -8,6 +8,7 @@ import { XmlFormatter } from './services/XmlFormatter'; import { XPathFeatureProvider } from './providers/XPath'; import { XQueryExecutionProvider } from './providers/Execution'; import { XmlTreeDocumentContentProvider } from './providers/Content'; +import { XmlFormattingEditProvider } from './providers/Formatting'; const CFG_SECTION: string = 'xmlTools'; const CFG_REMOVE_COMMENTS: string = 'removeCommentsOnMinify'; @@ -44,4 +45,41 @@ export class TextEditorCommands { vsc.window.showErrorMessage(`The XML Tree could not be created: ${error}`); } } + + static formatAsXml(editor: vsc.TextEditor, edit: vsc.TextEditorEdit): void { + let edits: vsc.TextEdit[]; + let formattingEditProvider = new XmlFormattingEditProvider(); + let formattingOptions: vsc.FormattingOptions = { + insertSpaces: editor.options.insertSpaces, + tabSize: editor.options.tabSize + }; + + // if the user has selected text, only format what is selected + // otherwise, attempt to format the entire document + if (!editor.selection.isEmpty) { + edits = formattingEditProvider.provideDocumentRangeFormattingEdits(editor.document, editor.selection, formattingOptions); + } + + else { + edits = formattingEditProvider.provideDocumentFormattingEdits(editor.document, formattingOptions); + } + + if (edits) { + for (let i = 0; i < edits.length; i++) { + editor.edit(async (editBuilder) => { + editBuilder.replace(edits[i].range, edits[i].newText); + + // wiggle the cursor to deselect the formatted XML (is there a non-hacky way to go about this?) + await vsc.commands.executeCommand('cursorMove', { + to: 'left', + by: 'character' + }); + await vsc.commands.executeCommand('cursorMove', { + to: 'right', + by: 'character' + }); + }); + } + } + } } \ No newline at end of file diff --git a/src/Extension.ts b/src/Extension.ts index fd23a79..727ccc7 100644 --- a/src/Extension.ts +++ b/src/Extension.ts @@ -26,7 +26,8 @@ export function activate(ctx: vsc.ExtensionContext) { vsc.commands.registerTextEditorCommand('xmlTools.minifyXml', TextEditorCommands.minifyXml), vsc.commands.registerTextEditorCommand('xmlTools.evaluateXPath', TextEditorCommands.evaluateXPath), vsc.commands.registerTextEditorCommand('xmlTools.executeXQuery', TextEditorCommands.executeXQuery), - vsc.commands.registerTextEditorCommand('xmlTools.viewXmlTree', TextEditorCommands.viewXmlTree) + vsc.commands.registerTextEditorCommand('xmlTools.viewXmlTree', TextEditorCommands.viewXmlTree), + vsc.commands.registerTextEditorCommand('xmlTools.formatAsXml', TextEditorCommands.formatAsXml) ); // register language feature providers