forked from external/vscode-xml
Add Format As XML Command
This commit is contained in:
parent
33535163c1
commit
d37a8b70fd
@ -1,10 +1,9 @@
|
|||||||
import { languages, window, workspace } from "vscode";
|
import { languages, window, workspace, commands } from "vscode";
|
||||||
import { ExtensionContext, TextEditor, TextEditorSelectionChangeEvent, WorkspaceConfiguration } from "vscode";
|
import { ExtensionContext, TextEditor, TextEditorSelectionChangeEvent, WorkspaceConfiguration } from "vscode";
|
||||||
|
|
||||||
import { XmlFormatter } from "./formatting/xml-formatter";
|
import { FormatAsXmlCommandName, formatAsXml } from "./formatting/commands/formatAsXml";
|
||||||
|
import { XmlFormatterFactory } from "./formatting/xml-formatter";
|
||||||
import { XmlFormattingEditProvider } from "./formatting/xml-formatting-edit-provider";
|
import { XmlFormattingEditProvider } from "./formatting/xml-formatting-edit-provider";
|
||||||
import { ClassicXmlFormatter } from "./formatting/formatters/classic-xml-formatter";
|
|
||||||
import { V2XmlFormatter } from "./formatting/formatters/v2-xml-formatter";
|
|
||||||
import { XQueryLinter } from "./linting/xquery-linter";
|
import { XQueryLinter } from "./linting/xquery-linter";
|
||||||
|
|
||||||
import * as constants from "./constants";
|
import * as constants from "./constants";
|
||||||
@ -13,17 +12,10 @@ export function activate(context: ExtensionContext) {
|
|||||||
const config = workspace.getConfiguration(constants.extensionPrefix);
|
const config = workspace.getConfiguration(constants.extensionPrefix);
|
||||||
|
|
||||||
/* Formatting Features */
|
/* Formatting Features */
|
||||||
const xmlFormatterImplementationSetting = config.get<string>("xmlFormatterImplementation");
|
const xmlFormattingEditProvider = new XmlFormattingEditProvider(config, XmlFormatterFactory.getXmlFormatter());
|
||||||
let xmlFormatterImplementation: XmlFormatter;
|
|
||||||
|
|
||||||
switch (xmlFormatterImplementationSetting) {
|
|
||||||
case "v2": xmlFormatterImplementation = new V2XmlFormatter(); break;
|
|
||||||
case "classic": default: xmlFormatterImplementation = new ClassicXmlFormatter(); break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const xmlFormattingEditProvider = new XmlFormattingEditProvider(config, xmlFormatterImplementation);
|
|
||||||
|
|
||||||
context.subscriptions.push(
|
context.subscriptions.push(
|
||||||
|
commands.registerTextEditorCommand(FormatAsXmlCommandName, formatAsXml),
|
||||||
languages.registerDocumentFormattingEditProvider("xml", xmlFormattingEditProvider),
|
languages.registerDocumentFormattingEditProvider("xml", xmlFormattingEditProvider),
|
||||||
languages.registerDocumentRangeFormattingEditProvider("xml", xmlFormattingEditProvider)
|
languages.registerDocumentRangeFormattingEditProvider("xml", xmlFormattingEditProvider)
|
||||||
);
|
);
|
||||||
|
53
src/formatting/commands/formatAsXml.ts
Normal file
53
src/formatting/commands/formatAsXml.ts
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import { commands, workspace } from "vscode";
|
||||||
|
import { ProviderResult, Range, TextEdit, TextEditor, TextEditorEdit } from "vscode";
|
||||||
|
|
||||||
|
import * as constants from "../../constants";
|
||||||
|
|
||||||
|
import { XmlFormatterFactory } from "../xml-formatter";
|
||||||
|
import { XmlFormattingEditProvider } from "../xml-formatting-edit-provider";
|
||||||
|
import { XmlFormattingOptionsFactory } from "../xml-formatting-options";
|
||||||
|
|
||||||
|
export const FormatAsXmlCommandName = "formatAsXml";
|
||||||
|
|
||||||
|
export function formatAsXml(editor: TextEditor, edit: TextEditorEdit): void {
|
||||||
|
const xmlFormattingEditProvider = new XmlFormattingEditProvider(workspace.getConfiguration(constants.extensionPrefix), XmlFormatterFactory.getXmlFormatter());
|
||||||
|
const formattingOptions = {
|
||||||
|
insertSpaces: <boolean>editor.options.insertSpaces,
|
||||||
|
tabSize: <number>editor.options.tabSize
|
||||||
|
};
|
||||||
|
|
||||||
|
let edits: ProviderResult<TextEdit[]>;
|
||||||
|
|
||||||
|
if (!editor.selection.isEmpty) {
|
||||||
|
edits = xmlFormattingEditProvider.provideDocumentRangeFormattingEdits(
|
||||||
|
editor.document,
|
||||||
|
new Range(editor.selection.start, editor.selection.end),
|
||||||
|
formattingOptions,
|
||||||
|
null);
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
edits = xmlFormattingEditProvider.provideDocumentFormattingEdits(
|
||||||
|
editor.document,
|
||||||
|
formattingOptions,
|
||||||
|
null);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < (edits as TextEdit[]).length; i++) {
|
||||||
|
const textEdit = (edits as TextEdit[])[i];
|
||||||
|
|
||||||
|
editor.edit(async (editBuilder) => {
|
||||||
|
editBuilder.replace(textEdit.range, textEdit.newText);
|
||||||
|
|
||||||
|
// wiggle the cursor to deselect the formatted XML (is there a non-hacky way to go about this?)
|
||||||
|
await commands.executeCommand("cursorMove", {
|
||||||
|
to: "left",
|
||||||
|
by: "character"
|
||||||
|
});
|
||||||
|
await commands.executeCommand("cursorMove", {
|
||||||
|
to: "right",
|
||||||
|
by: "character"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,32 @@
|
|||||||
|
import { workspace } from "vscode";
|
||||||
|
|
||||||
|
import * as constants from "../constants";
|
||||||
|
import { ClassicXmlFormatter } from "./formatters/classic-xml-formatter";
|
||||||
|
import { V2XmlFormatter } from "./formatters/v2-xml-formatter";
|
||||||
|
|
||||||
import { XmlFormattingOptions } from "./xml-formatting-options";
|
import { XmlFormattingOptions } from "./xml-formatting-options";
|
||||||
|
|
||||||
export interface XmlFormatter {
|
export interface XmlFormatter {
|
||||||
formatXml(xml: string, options: XmlFormattingOptions): string;
|
formatXml(xml: string, options: XmlFormattingOptions): string;
|
||||||
minifyXml(xml: string, options: XmlFormattingOptions): string;
|
minifyXml(xml: string, options: XmlFormattingOptions): string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class XmlFormatterFactory {
|
||||||
|
private static _xmlFormatter: XmlFormatter;
|
||||||
|
|
||||||
|
static getXmlFormatter(): XmlFormatter {
|
||||||
|
if (XmlFormatterFactory._xmlFormatter) {
|
||||||
|
return XmlFormatterFactory._xmlFormatter;
|
||||||
|
}
|
||||||
|
|
||||||
|
const xmlFormatterImplementationSetting = workspace.getConfiguration(constants.extensionPrefix).get<string>("xmlFormatterImplementation");
|
||||||
|
let xmlFormatterImplementation: XmlFormatter;
|
||||||
|
|
||||||
|
switch (xmlFormatterImplementationSetting) {
|
||||||
|
case "classic": xmlFormatterImplementation = new ClassicXmlFormatter(); break;
|
||||||
|
case "v2": default: xmlFormatterImplementation = new V2XmlFormatter(); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (XmlFormatterFactory._xmlFormatter = xmlFormatterImplementation);
|
||||||
|
}
|
||||||
|
}
|
@ -6,6 +6,7 @@ import {
|
|||||||
|
|
||||||
import * as constants from "../constants";
|
import * as constants from "../constants";
|
||||||
import { XmlFormatter } from "./xml-formatter";
|
import { XmlFormatter } from "./xml-formatter";
|
||||||
|
import { XmlFormattingOptionsFactory } from "./xml-formatting-options";
|
||||||
|
|
||||||
export class XmlFormattingEditProvider implements DocumentFormattingEditProvider, DocumentRangeFormattingEditProvider {
|
export class XmlFormattingEditProvider implements DocumentFormattingEditProvider, DocumentRangeFormattingEditProvider {
|
||||||
|
|
||||||
@ -27,13 +28,7 @@ export class XmlFormattingEditProvider implements DocumentFormattingEditProvider
|
|||||||
|
|
||||||
let xml = document.getText(range);
|
let xml = document.getText(range);
|
||||||
|
|
||||||
xml = this.xmlFormatter.formatXml(xml, {
|
xml = this.xmlFormatter.formatXml(xml, XmlFormattingOptionsFactory.getXmlFormattingOptions(options, document.eol));
|
||||||
editorOptions: options,
|
|
||||||
newLine: (document.eol === EndOfLine.CRLF) ? "\r\n" : "\n",
|
|
||||||
removeCommentsOnMinify: this.workspaceConfiguration.get<boolean>("removeCommentsOnMinify"),
|
|
||||||
splitAttributesOnFormat: this.workspaceConfiguration.get<boolean>("splitAttributesOnFormat"),
|
|
||||||
splitXmlnsOnFormat: this.workspaceConfiguration.get<boolean>("splitXmlnsOnFormat")
|
|
||||||
});
|
|
||||||
|
|
||||||
return [ TextEdit.replace(range, xml) ];
|
return [ TextEdit.replace(range, xml) ];
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
import { FormattingOptions } from "vscode";
|
import { workspace } from "vscode";
|
||||||
|
import { EndOfLine, FormattingOptions } from "vscode";
|
||||||
|
|
||||||
|
import * as constants from "../constants";
|
||||||
|
|
||||||
export interface XmlFormattingOptions {
|
export interface XmlFormattingOptions {
|
||||||
editorOptions: FormattingOptions;
|
editorOptions: FormattingOptions;
|
||||||
@ -7,3 +10,17 @@ export interface XmlFormattingOptions {
|
|||||||
splitAttributesOnFormat: boolean;
|
splitAttributesOnFormat: boolean;
|
||||||
splitXmlnsOnFormat: boolean;
|
splitXmlnsOnFormat: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class XmlFormattingOptionsFactory {
|
||||||
|
static getXmlFormattingOptions(formattingOptions: FormattingOptions, eol: EndOfLine): XmlFormattingOptions {
|
||||||
|
const config = workspace.getConfiguration(constants.extensionPrefix);
|
||||||
|
|
||||||
|
return {
|
||||||
|
editorOptions: formattingOptions,
|
||||||
|
newLine: (eol === EndOfLine.CRLF) ? "\r\n" : "\n",
|
||||||
|
removeCommentsOnMinify: config.get<boolean>("removeCommentsOnMinify"),
|
||||||
|
splitAttributesOnFormat: config.get<boolean>("splitAttributesOnFormat"),
|
||||||
|
splitXmlnsOnFormat: config.get<boolean>("splitXmlnsOnFormat")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user