Switch to Double Quotes

Closes #108
This commit is contained in:
Josh Johnson 2017-06-23 21:06:53 -04:00
parent 6eb35d0a37
commit 93b3083bbf
14 changed files with 129 additions and 129 deletions

View File

@ -1,9 +1,9 @@
var gulp = require('gulp');
var gulp = require("gulp");
var shell = require('gulp-shell');
var shell = require("gulp-shell");
gulp.task('compile-typescript', function () {
gulp.src('package.json').pipe(shell('tsc'));
gulp.task("compile-typescript", function () {
gulp.src("package.json").pipe(shell("tsc"));
});
gulp.task('build', ['compile-typescript']);
gulp.task("build", ["compile-typescript"]);

View File

@ -1,14 +1,14 @@
import * as vsc from 'vscode';
import * as ext from './Extension';
import * as xpath from 'xpath';
import { RangeUtil } from './utils/RangeUtil';
import { XmlFormatter } from './services/XmlFormatter';
import { XPathFeatureProvider } from './providers/XPath';
import { XQueryExecutionProvider } from './providers/Execution';
import { XmlFormattingEditProvider } from './providers/Formatting';
import * as vsc from "vscode";
import * as ext from "./Extension";
import * as xpath from "xpath";
import { RangeUtil } from "./utils/RangeUtil";
import { XmlFormatter } from "./services/XmlFormatter";
import { XPathFeatureProvider } from "./providers/XPath";
import { XQueryExecutionProvider } from "./providers/Execution";
import { XmlFormattingEditProvider } from "./providers/Formatting";
const CFG_SECTION: string = 'xmlTools';
const CFG_REMOVE_COMMENTS: string = 'removeCommentsOnMinify';
const CFG_SECTION: string = "xmlTools";
const CFG_REMOVE_COMMENTS: string = "removeCommentsOnMinify";
export class TextEditorCommands {
static minifyXml(editor: vsc.TextEditor, edit: vsc.TextEditorEdit): void {
@ -54,13 +54,13 @@ export class TextEditorCommands {
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: "left",
by: "character"
});
await vsc.commands.executeCommand('cursorMove', {
to: 'right',
by: 'character'
await vsc.commands.executeCommand("cursorMove", {
to: "right",
by: "character"
});
});
}

View File

@ -1,30 +1,30 @@
import * as vsc from 'vscode';
import { TextEditorCommands } from './Commands';
import { XmlFormattingEditProvider } from './providers/Formatting';
import { XQueryLintingFeatureProvider } from './providers/Linting';
import { XQueryCompletionItemProvider } from './providers/Completion';
import * as vsc from "vscode";
import { TextEditorCommands } from "./Commands";
import { XmlFormattingEditProvider } from "./providers/Formatting";
import { XQueryLintingFeatureProvider } from "./providers/Linting";
import { XQueryCompletionItemProvider } from "./providers/Completion";
import { XmlTreeViewDataProvider } from "./providers/XmlTreeView";
export var GlobalState: vsc.Memento;
export var WorkspaceState: vsc.Memento;
const LANG_XML: string = 'xml';
const LANG_XSL: string = 'xsl';
const LANG_XQUERY: string = 'xquery;'
const MEM_QUERY_HISTORY: string = 'xpathQueryHistory';
const LANG_XML: string = "xml";
const LANG_XSL: string = "xsl";
const LANG_XQUERY: string = "xquery;"
const MEM_QUERY_HISTORY: string = "xpathQueryHistory";
export function activate(ctx: vsc.ExtensionContext) {
console.log('activate extension');
console.log("activate extension");
// expose global and workspace state to the entire extension
GlobalState = ctx.globalState;
WorkspaceState = ctx.workspaceState;
// register palette commands
ctx.subscriptions.push(
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.formatAsXml', TextEditorCommands.formatAsXml)
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.formatAsXml", TextEditorCommands.formatAsXml)
);
// register language feature providers
@ -32,7 +32,7 @@ export function activate(ctx: vsc.ExtensionContext) {
vsc.languages.registerDocumentFormattingEditProvider([LANG_XML, LANG_XSL], new XmlFormattingEditProvider()),
vsc.languages.registerDocumentRangeFormattingEditProvider([LANG_XML, LANG_XSL], new XmlFormattingEditProvider()),
vsc.languages.registerCompletionItemProvider(LANG_XQUERY, new XQueryCompletionItemProvider(), ':', '$')
vsc.languages.registerCompletionItemProvider(LANG_XQUERY, new XQueryCompletionItemProvider(), ":", "$")
);
// listen to editor events (for linting)
@ -61,7 +61,7 @@ function _handleContextChange(editor: vsc.TextEditor): void {
}
switch (editor.document.languageId) {
case 'xquery':
case "xquery":
XQueryLintingFeatureProvider.provideXQueryDiagnostics(editor);
break;
}

View File

@ -1,5 +1,5 @@
import * as vsc from 'vscode';
import { XQueryCompleter, XQueryCompletionItem } from '../services/XQueryCompleter';
import * as vsc from "vscode";
import { XQueryCompleter, XQueryCompletionItem } from "../services/XQueryCompleter";
export class XQueryCompletionItemProvider implements vsc.CompletionItemProvider {
provideCompletionItems(document: vsc.TextDocument, position: vsc.Position): vsc.CompletionItem[] {
@ -14,20 +14,20 @@ export class XQueryCompletionItemProvider implements vsc.CompletionItemProvider
switch (completion.meta) {
// functions (always qualified with a colon)
case 'function':
case "function":
item.kind = vsc.CompletionItemKind.Function;
let funcStart = (completion.value.indexOf(':') + 1);
let funcEnd = completion.value.indexOf('(');
let funcStart = (completion.value.indexOf(":") + 1);
let funcEnd = completion.value.indexOf("(");
item.insertText = completion.value.substring(funcStart, funcEnd);
break;
// variables and parameters (always qualified with a dollar sign)
case 'Let binding':
case 'Local variable':
case 'Window variable':
case 'Function parameter':
case "Let binding":
case "Local variable":
case "Window variable":
case "Function parameter":
item.kind = vsc.CompletionItemKind.Variable;
item.insertText = completion.value.substring(1);
break;

View File

@ -1,41 +1,41 @@
import * as vsc from 'vscode';
import { ChildProcess } from '../services/ChildProcess';
import * as vsc from "vscode";
import { ChildProcess } from "../services/ChildProcess";
const CFG_SECTION: string = 'xmlTools';
const CFG_XQEXEC: string = 'xqueryExecutionEngine';
const CFG_XQARGS: string = 'xqueryExecutionArguments';
const CFG_SECTION: string = "xmlTools";
const CFG_XQEXEC: string = "xqueryExecutionEngine";
const CFG_XQARGS: string = "xqueryExecutionArguments";
export class XQueryExecutionProvider {
static async executeXQueryAsync(editor: vsc.TextEditor): Promise<void> {
// this disposable will be used for creating status bar messages
let disposable: vsc.Disposable;
if (editor.document.languageId !== 'xquery') {
vsc.window.showErrorMessage('This action can only be performed on an XQuery file.');
if (editor.document.languageId !== "xquery") {
vsc.window.showErrorMessage("This action can only be performed on an XQuery file.");
return;
}
let executable = vsc.workspace.getConfiguration(CFG_SECTION).get<string>(CFG_XQEXEC, null);
let args = vsc.workspace.getConfiguration(CFG_SECTION).get<string[]>(CFG_XQARGS, []);
if (!executable || executable == '') {
let action = await vsc.window.showWarningMessage('An XQuery execution engine has not been defined.', 'Define Now');
if (!executable || executable == "") {
let action = await vsc.window.showWarningMessage("An XQuery execution engine has not been defined.", "Define Now");
if (action == 'Define Now') {
vsc.commands.executeCommand('workbench.action.openGlobalSettings');
if (action == "Define Now") {
vsc.commands.executeCommand("workbench.action.openGlobalSettings");
}
return;
}
let inputFile: vsc.Uri;
disposable = vsc.window.setStatusBarMessage('Searching for XML files in folder...');
let files: vsc.Uri[] = await vsc.workspace.findFiles('**/*.xml', '', 100);
disposable = vsc.window.setStatusBarMessage("Searching for XML files in folder...");
let files: vsc.Uri[] = await vsc.workspace.findFiles("**/*.xml", "", 100);
disposable.dispose();
// user does not have a folder open - prompt for file name
if (typeof files === 'undefined') {
vsc.window.showErrorMessage('You must have a folder opened in VS Code to use this feature.');
if (typeof files === "undefined") {
vsc.window.showErrorMessage("You must have a folder opened in VS Code to use this feature.");
return;
}
@ -45,16 +45,16 @@ export class XQueryExecutionProvider {
let qpItems: any[] = new Array<any>();
files.forEach((file) => {
let filename: string = file.fsPath.replace('\\', '/');
let filename: string = file.fsPath.replace("\\", "/");
qpItems.push({ // must implement vscode.QuickPickItem
label: filename.substring(filename.lastIndexOf('/') + 1),
label: filename.substring(filename.lastIndexOf("/") + 1),
description: file.fsPath,
file: file
});
});
let selection = await vsc.window.showQuickPick(qpItems, { placeHolder: 'Please select an input file.' });
let selection = await vsc.window.showQuickPick(qpItems, { placeHolder: "Please select an input file." });
if (!selection) {
return;
@ -82,8 +82,8 @@ export class XQueryExecutionProvider {
if (outputPath) {
outputPath = await vsc.window.showInputBox({
placeHolder: 'ex. C:\\TEMP\XQueryOutput\\MyOutputFile.xml',
prompt: 'Please specify the output file path. Existing file behavior is determined by the execution engine you have specified.',
placeHolder: "ex. C:\\TEMP\XQueryOutput\\MyOutputFile.xml",
prompt: "Please specify the output file path. Existing file behavior is determined by the execution engine you have specified.",
value: outputPath
});
@ -91,12 +91,12 @@ export class XQueryExecutionProvider {
}
// call out to the execution engine
disposable = vsc.window.setStatusBarMessage('Executing XQuery Script...');
disposable = vsc.window.setStatusBarMessage("Executing XQuery Script...");
args = args.map<string>((value: string) => {
return value
.replace('$(script)', editor.document.uri.fsPath)
.replace('$(input)', inputFile.fsPath)
.replace('$(project)', vsc.workspace.rootPath);
.replace("$(script)", editor.document.uri.fsPath)
.replace("$(input)", inputFile.fsPath)
.replace("$(project)", vsc.workspace.rootPath);
});
try {
@ -106,7 +106,7 @@ export class XQueryExecutionProvider {
catch (error) {
if (error.message.search(/[Ll]ine:?\s*\d+/gm) > -1) {
let match: RegExpExecArray = /[Ll]ine:?\s*\d+/gm.exec(error.message);
let line: number = (Number.parseInt(match[0].replace(/([Ll]ine:?\s*)|\s/, '')) - 1);
let line: number = (Number.parseInt(match[0].replace(/([Ll]ine:?\s*)|\s/, "")) - 1);
let selection: string = await vsc.window.showErrorMessage(error.message, `Go to Line ${line}`);

View File

@ -1,9 +1,9 @@
import * as vsc from 'vscode';
import { RangeUtil } from '../utils/RangeUtil';
import { XmlFormatter, IXmlFormatterOptions } from '../services/XmlFormatter';
import * as vsc from "vscode";
import { RangeUtil } from "../utils/RangeUtil";
import { XmlFormatter, IXmlFormatterOptions } from "../services/XmlFormatter";
const CFG_SECTION: string = 'xmlTools';
const CFG_SPLIT_NAMESPACES: string = 'splitXmlnsOnFormat';
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[] {

View File

@ -1,12 +1,12 @@
import * as vsc from 'vscode';
import { XQueryLinter, XQueryDiagnostic } from '../services/XQueryLinter';
import * as vsc from "vscode";
import { XQueryLinter, XQueryDiagnostic } from "../services/XQueryLinter";
export class XQueryLintingFeatureProvider {
private static _coreDiagnostics: vsc.DiagnosticCollection;
static get coreDiagnostics(): vsc.DiagnosticCollection {
if (!XQueryLintingFeatureProvider._coreDiagnostics) {
XQueryLintingFeatureProvider._coreDiagnostics = vsc.languages.createDiagnosticCollection('XQueryDiagnostics');
XQueryLintingFeatureProvider._coreDiagnostics = vsc.languages.createDiagnosticCollection("XQueryDiagnostics");
}
return XQueryLintingFeatureProvider._coreDiagnostics;

View File

@ -1,13 +1,13 @@
import * as vsc from 'vscode';
import * as ext from '../Extension';
import { XPathEvaluator, EvaluatorResult, EvaluatorResultType } from '../services/XPathEvaluator';
import * as vsc from "vscode";
import * as ext from "../Extension";
import { XPathEvaluator, EvaluatorResult, EvaluatorResultType } from "../services/XPathEvaluator";
const CFG_SECTION: string = 'xmlTools';
const CFG_PERSIST_QUERY: string = 'persistXPathQuery';
const CFG_IGNORE_DEFAULT_XMLNS: string = 'ignoreDefaultNamespace';
const MEM_QUERY_HISTORY: string = 'xpathQueryHistory';
const MEM_QUERY_LAST: string = 'xPathQueryLast';
const OUTPUT_CHANNEL: string = 'XPath Results';
const CFG_SECTION: string = "xmlTools";
const CFG_PERSIST_QUERY: string = "persistXPathQuery";
const CFG_IGNORE_DEFAULT_XMLNS: string = "ignoreDefaultNamespace";
const MEM_QUERY_HISTORY: string = "xpathQueryHistory";
const MEM_QUERY_LAST: string = "xPathQueryLast";
const OUTPUT_CHANNEL: string = "XPath Results";
export class XPathFeatureProvider {
static async evaluateXPathAsync(editor: vsc.TextEditor, edit: vsc.TextEditorEdit): Promise<void> {
@ -21,7 +21,7 @@ export class XPathFeatureProvider {
// if not, try pulling the last query ran, regardless of document
// NOTE: if the user has focus on the output channel when opening the xquery prompt, the channel is the "active" document
let history: HistoricQuery[] = memento.get<HistoricQuery[]>(MEM_QUERY_HISTORY, new Array<HistoricQuery>());
let globalLastQuery: string = memento.get<string>(MEM_QUERY_LAST, '');
let globalLastQuery: string = memento.get<string>(MEM_QUERY_LAST, "");
let lastQuery: HistoricQuery = history.find((item: HistoricQuery) => {
if (item.uri == editor.document.uri.toString()) {
@ -32,7 +32,7 @@ export class XPathFeatureProvider {
});
// set the inital display value and prompt the user
let query: string = '';
let query: string = "";
if (persistQueries) {
if (lastQuery) {
@ -45,8 +45,8 @@ export class XPathFeatureProvider {
}
query = await vsc.window.showInputBox({
placeHolder: 'XPath Query',
prompt: 'Please enter an XPath query to evaluate.',
placeHolder: "XPath Query",
prompt: "Please enter an XPath query to evaluate.",
value: query
});
@ -73,7 +73,7 @@ export class XPathFeatureProvider {
outputChannel.clear();
outputChannel.appendLine(`XPath Query: ${query}`);
outputChannel.append('\n');
outputChannel.append("\n");
if (evalResult.type === EvaluatorResultType.NODE_COLLECTION) {
(evalResult.result as Node[]).forEach((node: XmlNode) => {

View File

@ -1,22 +1,22 @@
let child_process = require('child_process');
let child_process = require("child_process");
export class ChildProcess {
static async spawnAsync(executable: string, args: string[]): Promise<void> {
return new Promise<void>((resolve, reject) => {
let output: string = '';
let output: string = "";
let handle = child_process.spawn(executable, args);
handle.stdout.on('data', (data: string) => {
handle.stdout.on("data", (data: string) => {
output += data;
});
handle.stderr.on('data', (data: string) => {
handle.stderr.on("data", (data: string) => {
output += data;
});
handle.on('close', (code: string) => {
if (code == '0') {
handle.on("close", (code: string) => {
if (code == "0") {
resolve();
}

View File

@ -1,6 +1,6 @@
import * as xpath from 'xpath';
import * as xpath from "xpath";
let DOMParser = require('xmldom').DOMParser;
let DOMParser = require("xmldom").DOMParser;
export class EvaluatorResult {
type: EvaluatorResultType;
@ -16,13 +16,13 @@ export class XPathEvaluator {
static evaluate(query: string, xml: string, ignoreDefaultNamespace: boolean): EvaluatorResult {
if (ignoreDefaultNamespace) {
xml = xml.replace(/xmlns=".+"/g, (match: string) => {
return match.replace(/xmlns/g, 'xmlns:default');
return match.replace(/xmlns/g, "xmlns:default");
});
}
let nodes: Node[] = new Array<Node>();
let xdoc: Document = new DOMParser().parseFromString(xml, 'text/xml');
let xdoc: Document = new DOMParser().parseFromString(xml, "text/xml");
let resolver: xpath.XPathNSResolver = xpath.createNSResolver(xdoc);
let result: xpath.XPathResult = xpath.evaluate(

View File

@ -1,4 +1,4 @@
let XQLint = require('xqlint').XQLint;
let XQLint = require("xqlint").XQLint;
export class XQueryCompleter {
constructor(script: string) {

View File

@ -1,4 +1,4 @@
let XQLint = require('xqlint').XQLint;
let XQLint = require("xqlint").XQLint;
export class XQueryLinter {
static SEVERITY_WARNING: number = 1;

View File

@ -3,19 +3,19 @@ export class XmlFormatter {
constructor(options?: IXmlFormatterOptions) {
options = options || {};
if (typeof options.preferSpaces === 'undefined') {
if (typeof options.preferSpaces === "undefined") {
options.preferSpaces = false;
}
if (typeof options.splitNamespaces === 'undefined') {
if (typeof options.splitNamespaces === "undefined") {
options.splitNamespaces = true;
}
options.tabSize = options.tabSize || 4;
options.newLine = options.newLine || '\n';
options.newLine = options.newLine || "\n";
this.newLine = options.newLine || '\n';
this.indentPattern = (options.preferSpaces) ? ' '.repeat(options.tabSize) : '\t';
this.newLine = options.newLine || "\n";
this.indentPattern = (options.preferSpaces) ? " ".repeat(options.tabSize) : "\t";
this.splitNamespaces = options.splitNamespaces;
}
@ -25,19 +25,19 @@ export class XmlFormatter {
format(xml: string): string {
xml = this.minify(xml, false);
xml = xml.replace(/</g, '~::~<');
xml = xml.replace(/</g, "~::~<");
if (this.splitNamespaces) {
xml = xml
.replace(/xmlns\:/g, '~::~xmlns:')
.replace(/xmlns\=/g, '~::~xmlns=');
.replace(/xmlns\:/g, "~::~xmlns:")
.replace(/xmlns\=/g, "~::~xmlns=");
}
let parts: string[] = xml.split('~::~');
let parts: string[] = xml.split("~::~");
console.log(parts);
let inComment: boolean = false;
let level: number = 0;
let output: string = '';
let output: string = "";
for (let i = 0; i < parts.length; i++) {
// <!
@ -59,7 +59,7 @@ export class XmlFormatter {
// <elm></elm>
else if (/^<(\w|:)/.test(parts[i - 1]) && /^<\/(\w|:)/.test(parts[i])
&& /^<[\w:\-\.\,\/]+/.exec(parts[i - 1])[0] == /^<\/[\w:\-\.\,]+/.exec(parts[i])[0].replace('/', '')) {
&& /^<[\w:\-\.\,\/]+/.exec(parts[i - 1])[0] == /^<\/[\w:\-\.\,]+/.exec(parts[i])[0].replace("/", "")) {
output += parts[i];
if (!inComment) level--;
@ -118,31 +118,31 @@ export class XmlFormatter {
}
minify(xml: string, removeComments?: boolean): string {
if (typeof removeComments === 'undefined') {
if (typeof removeComments === "undefined") {
removeComments = false;
}
xml = this._stripLineBreaks(xml); // all line breaks outside of CDATA elements
xml = (removeComments) ? xml.replace(/\<![ \r\n\t]*(--([^\-]|[\r\n]|-[^\-])*--[ \r\n\t]*)\>/g, '') : xml;
xml = xml.replace(/>\s{0,}</g, '><'); // insignificant whitespace between tags
xml = xml.replace(/"\s+(?=[^\s]+=)/g, '" '); // spaces between attributes
xml = xml.replace(/"\s+(?=>)/g, '"'); // spaces between the last attribute and tag close (>)
xml = xml.replace(/"\s+(?=\/>)/g, '" '); // spaces between the last attribute and tag close (/>)
xml = (removeComments) ? xml.replace(/\<![ \r\n\t]*(--([^\-]|[\r\n]|-[^\-])*--[ \r\n\t]*)\>/g, "") : xml;
xml = xml.replace(/>\s{0,}</g, "><"); // insignificant whitespace between tags
xml = xml.replace(/"\s+(?=[^\s]+=)/g, "\" "); // spaces between attributes
xml = xml.replace(/"\s+(?=>)/g, "\""); // spaces between the last attribute and tag close (>)
xml = xml.replace(/"\s+(?=\/>)/g, "\" "); // spaces between the last attribute and tag close (/>)
xml = xml.replace(/[^ <>="]\s+[^ <>="]+=/g, (match: string) => { // spaces between the node name and the first attribute
return match.replace(/\s+/g, ' ');
return match.replace(/\s+/g, " ");
});
return xml;
}
private _getIndent(level: number, trailingValue?: string): string {
trailingValue = trailingValue || '';
trailingValue = trailingValue || "";
return `${this.newLine}${this.indentPattern.repeat(level)}${trailingValue}`;
}
private _stripLineBreaks(xml: string): string {
let output: string = '';
let output: string = "";
let inTag: boolean = false;
let inTagName: boolean = false;
let inCdata: boolean = false;
@ -153,15 +153,15 @@ export class XmlFormatter {
let prev: string = xml.charAt(i - 1);
let next: string = xml.charAt(i + 1);
if (char == '!' && (xml.substr(i, 8) == '![CDATA[' || xml.substr(i, 3) == '!--')) {
if (char == "!" && (xml.substr(i, 8) == "![CDATA[" || xml.substr(i, 3) == "!--")) {
inCdata = true;
}
else if (char == ']' && (xml.substr(i, 3) == ']]>')) {
else if (char == "]" && (xml.substr(i, 3) == "]]>")) {
inCdata = false;
}
else if (char == '-' && (xml.substr(i, 3) == '-->')) {
else if (char == "-" && (xml.substr(i, 3) == "-->")) {
inCdata = false;
}

View File

@ -1,4 +1,4 @@
import * as vsc from 'vscode';
import * as vsc from "vscode";
export class RangeUtil {
static getRangeForDocument(document: vsc.TextDocument): vsc.Range {