parent
6eb35d0a37
commit
93b3083bbf
14 changed files with 129 additions and 129 deletions
10
gulpfile.js
10
gulpfile.js
|
@ -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.task("compile-typescript", function () {
|
||||||
gulp.src('package.json').pipe(shell('tsc'));
|
gulp.src("package.json").pipe(shell("tsc"));
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('build', ['compile-typescript']);
|
gulp.task("build", ["compile-typescript"]);
|
|
@ -1,14 +1,14 @@
|
||||||
import * as vsc from 'vscode';
|
import * as vsc from "vscode";
|
||||||
import * as ext from './Extension';
|
import * as ext from "./Extension";
|
||||||
import * as xpath from 'xpath';
|
import * as xpath from "xpath";
|
||||||
import { RangeUtil } from './utils/RangeUtil';
|
import { RangeUtil } from "./utils/RangeUtil";
|
||||||
import { XmlFormatter } from './services/XmlFormatter';
|
import { XmlFormatter } from "./services/XmlFormatter";
|
||||||
import { XPathFeatureProvider } from './providers/XPath';
|
import { XPathFeatureProvider } from "./providers/XPath";
|
||||||
import { XQueryExecutionProvider } from './providers/Execution';
|
import { XQueryExecutionProvider } from "./providers/Execution";
|
||||||
import { XmlFormattingEditProvider } from './providers/Formatting';
|
import { XmlFormattingEditProvider } from "./providers/Formatting";
|
||||||
|
|
||||||
const CFG_SECTION: string = 'xmlTools';
|
const CFG_SECTION: string = "xmlTools";
|
||||||
const CFG_REMOVE_COMMENTS: string = 'removeCommentsOnMinify';
|
const CFG_REMOVE_COMMENTS: string = "removeCommentsOnMinify";
|
||||||
|
|
||||||
export class TextEditorCommands {
|
export class TextEditorCommands {
|
||||||
static minifyXml(editor: vsc.TextEditor, edit: vsc.TextEditorEdit): void {
|
static minifyXml(editor: vsc.TextEditor, edit: vsc.TextEditorEdit): void {
|
||||||
|
@ -54,13 +54,13 @@ export class TextEditorCommands {
|
||||||
editBuilder.replace(edits[i].range, edits[i].newText);
|
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?)
|
// wiggle the cursor to deselect the formatted XML (is there a non-hacky way to go about this?)
|
||||||
await vsc.commands.executeCommand('cursorMove', {
|
await vsc.commands.executeCommand("cursorMove", {
|
||||||
to: 'left',
|
to: "left",
|
||||||
by: 'character'
|
by: "character"
|
||||||
});
|
});
|
||||||
await vsc.commands.executeCommand('cursorMove', {
|
await vsc.commands.executeCommand("cursorMove", {
|
||||||
to: 'right',
|
to: "right",
|
||||||
by: 'character'
|
by: "character"
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,30 +1,30 @@
|
||||||
import * as vsc from 'vscode';
|
import * as vsc from "vscode";
|
||||||
import { TextEditorCommands } from './Commands';
|
import { TextEditorCommands } from "./Commands";
|
||||||
import { XmlFormattingEditProvider } from './providers/Formatting';
|
import { XmlFormattingEditProvider } from "./providers/Formatting";
|
||||||
import { XQueryLintingFeatureProvider } from './providers/Linting';
|
import { XQueryLintingFeatureProvider } from "./providers/Linting";
|
||||||
import { XQueryCompletionItemProvider } from './providers/Completion';
|
import { XQueryCompletionItemProvider } from "./providers/Completion";
|
||||||
import { XmlTreeViewDataProvider } from "./providers/XmlTreeView";
|
import { XmlTreeViewDataProvider } from "./providers/XmlTreeView";
|
||||||
|
|
||||||
export var GlobalState: vsc.Memento;
|
export var GlobalState: vsc.Memento;
|
||||||
export var WorkspaceState: vsc.Memento;
|
export var WorkspaceState: vsc.Memento;
|
||||||
|
|
||||||
const LANG_XML: string = 'xml';
|
const LANG_XML: string = "xml";
|
||||||
const LANG_XSL: string = 'xsl';
|
const LANG_XSL: string = "xsl";
|
||||||
const LANG_XQUERY: string = 'xquery;'
|
const LANG_XQUERY: string = "xquery;"
|
||||||
const MEM_QUERY_HISTORY: string = 'xpathQueryHistory';
|
const MEM_QUERY_HISTORY: string = "xpathQueryHistory";
|
||||||
|
|
||||||
export function activate(ctx: vsc.ExtensionContext) {
|
export function activate(ctx: vsc.ExtensionContext) {
|
||||||
console.log('activate extension');
|
console.log("activate extension");
|
||||||
// expose global and workspace state to the entire extension
|
// expose global and workspace state to the entire extension
|
||||||
GlobalState = ctx.globalState;
|
GlobalState = ctx.globalState;
|
||||||
WorkspaceState = ctx.workspaceState;
|
WorkspaceState = ctx.workspaceState;
|
||||||
|
|
||||||
// register palette commands
|
// register palette commands
|
||||||
ctx.subscriptions.push(
|
ctx.subscriptions.push(
|
||||||
vsc.commands.registerTextEditorCommand('xmlTools.minifyXml', TextEditorCommands.minifyXml),
|
vsc.commands.registerTextEditorCommand("xmlTools.minifyXml", TextEditorCommands.minifyXml),
|
||||||
vsc.commands.registerTextEditorCommand('xmlTools.evaluateXPath', TextEditorCommands.evaluateXPath),
|
vsc.commands.registerTextEditorCommand("xmlTools.evaluateXPath", TextEditorCommands.evaluateXPath),
|
||||||
vsc.commands.registerTextEditorCommand('xmlTools.executeXQuery', TextEditorCommands.executeXQuery),
|
vsc.commands.registerTextEditorCommand("xmlTools.executeXQuery", TextEditorCommands.executeXQuery),
|
||||||
vsc.commands.registerTextEditorCommand('xmlTools.formatAsXml', TextEditorCommands.formatAsXml)
|
vsc.commands.registerTextEditorCommand("xmlTools.formatAsXml", TextEditorCommands.formatAsXml)
|
||||||
);
|
);
|
||||||
|
|
||||||
// register language feature providers
|
// 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.registerDocumentFormattingEditProvider([LANG_XML, LANG_XSL], new XmlFormattingEditProvider()),
|
||||||
vsc.languages.registerDocumentRangeFormattingEditProvider([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)
|
// listen to editor events (for linting)
|
||||||
|
@ -61,7 +61,7 @@ function _handleContextChange(editor: vsc.TextEditor): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (editor.document.languageId) {
|
switch (editor.document.languageId) {
|
||||||
case 'xquery':
|
case "xquery":
|
||||||
XQueryLintingFeatureProvider.provideXQueryDiagnostics(editor);
|
XQueryLintingFeatureProvider.provideXQueryDiagnostics(editor);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import * as vsc from 'vscode';
|
import * as vsc from "vscode";
|
||||||
import { XQueryCompleter, XQueryCompletionItem } from '../services/XQueryCompleter';
|
import { XQueryCompleter, XQueryCompletionItem } from "../services/XQueryCompleter";
|
||||||
|
|
||||||
export class XQueryCompletionItemProvider implements vsc.CompletionItemProvider {
|
export class XQueryCompletionItemProvider implements vsc.CompletionItemProvider {
|
||||||
provideCompletionItems(document: vsc.TextDocument, position: vsc.Position): vsc.CompletionItem[] {
|
provideCompletionItems(document: vsc.TextDocument, position: vsc.Position): vsc.CompletionItem[] {
|
||||||
|
@ -14,20 +14,20 @@ export class XQueryCompletionItemProvider implements vsc.CompletionItemProvider
|
||||||
|
|
||||||
switch (completion.meta) {
|
switch (completion.meta) {
|
||||||
// functions (always qualified with a colon)
|
// functions (always qualified with a colon)
|
||||||
case 'function':
|
case "function":
|
||||||
item.kind = vsc.CompletionItemKind.Function;
|
item.kind = vsc.CompletionItemKind.Function;
|
||||||
|
|
||||||
let funcStart = (completion.value.indexOf(':') + 1);
|
let funcStart = (completion.value.indexOf(":") + 1);
|
||||||
let funcEnd = completion.value.indexOf('(');
|
let funcEnd = completion.value.indexOf("(");
|
||||||
|
|
||||||
item.insertText = completion.value.substring(funcStart, funcEnd);
|
item.insertText = completion.value.substring(funcStart, funcEnd);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// variables and parameters (always qualified with a dollar sign)
|
// variables and parameters (always qualified with a dollar sign)
|
||||||
case 'Let binding':
|
case "Let binding":
|
||||||
case 'Local variable':
|
case "Local variable":
|
||||||
case 'Window variable':
|
case "Window variable":
|
||||||
case 'Function parameter':
|
case "Function parameter":
|
||||||
item.kind = vsc.CompletionItemKind.Variable;
|
item.kind = vsc.CompletionItemKind.Variable;
|
||||||
item.insertText = completion.value.substring(1);
|
item.insertText = completion.value.substring(1);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1,41 +1,41 @@
|
||||||
import * as vsc from 'vscode';
|
import * as vsc from "vscode";
|
||||||
import { ChildProcess } from '../services/ChildProcess';
|
import { ChildProcess } from "../services/ChildProcess";
|
||||||
|
|
||||||
const CFG_SECTION: string = 'xmlTools';
|
const CFG_SECTION: string = "xmlTools";
|
||||||
const CFG_XQEXEC: string = 'xqueryExecutionEngine';
|
const CFG_XQEXEC: string = "xqueryExecutionEngine";
|
||||||
const CFG_XQARGS: string = 'xqueryExecutionArguments';
|
const CFG_XQARGS: string = "xqueryExecutionArguments";
|
||||||
|
|
||||||
export class XQueryExecutionProvider {
|
export class XQueryExecutionProvider {
|
||||||
static async executeXQueryAsync(editor: vsc.TextEditor): Promise<void> {
|
static async executeXQueryAsync(editor: vsc.TextEditor): Promise<void> {
|
||||||
// this disposable will be used for creating status bar messages
|
// this disposable will be used for creating status bar messages
|
||||||
let disposable: vsc.Disposable;
|
let disposable: vsc.Disposable;
|
||||||
|
|
||||||
if (editor.document.languageId !== 'xquery') {
|
if (editor.document.languageId !== "xquery") {
|
||||||
vsc.window.showErrorMessage('This action can only be performed on an XQuery file.');
|
vsc.window.showErrorMessage("This action can only be performed on an XQuery file.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let executable = vsc.workspace.getConfiguration(CFG_SECTION).get<string>(CFG_XQEXEC, null);
|
let executable = vsc.workspace.getConfiguration(CFG_SECTION).get<string>(CFG_XQEXEC, null);
|
||||||
let args = vsc.workspace.getConfiguration(CFG_SECTION).get<string[]>(CFG_XQARGS, []);
|
let args = vsc.workspace.getConfiguration(CFG_SECTION).get<string[]>(CFG_XQARGS, []);
|
||||||
|
|
||||||
if (!executable || executable == '') {
|
if (!executable || executable == "") {
|
||||||
let action = await vsc.window.showWarningMessage('An XQuery execution engine has not been defined.', 'Define Now');
|
let action = await vsc.window.showWarningMessage("An XQuery execution engine has not been defined.", "Define Now");
|
||||||
|
|
||||||
if (action == 'Define Now') {
|
if (action == "Define Now") {
|
||||||
vsc.commands.executeCommand('workbench.action.openGlobalSettings');
|
vsc.commands.executeCommand("workbench.action.openGlobalSettings");
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let inputFile: vsc.Uri;
|
let inputFile: vsc.Uri;
|
||||||
disposable = vsc.window.setStatusBarMessage('Searching for XML files in folder...');
|
disposable = vsc.window.setStatusBarMessage("Searching for XML files in folder...");
|
||||||
let files: vsc.Uri[] = await vsc.workspace.findFiles('**/*.xml', '', 100);
|
let files: vsc.Uri[] = await vsc.workspace.findFiles("**/*.xml", "", 100);
|
||||||
disposable.dispose();
|
disposable.dispose();
|
||||||
|
|
||||||
// user does not have a folder open - prompt for file name
|
// user does not have a folder open - prompt for file name
|
||||||
if (typeof files === 'undefined') {
|
if (typeof files === "undefined") {
|
||||||
vsc.window.showErrorMessage('You must have a folder opened in VS Code to use this feature.');
|
vsc.window.showErrorMessage("You must have a folder opened in VS Code to use this feature.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,16 +45,16 @@ export class XQueryExecutionProvider {
|
||||||
let qpItems: any[] = new Array<any>();
|
let qpItems: any[] = new Array<any>();
|
||||||
|
|
||||||
files.forEach((file) => {
|
files.forEach((file) => {
|
||||||
let filename: string = file.fsPath.replace('\\', '/');
|
let filename: string = file.fsPath.replace("\\", "/");
|
||||||
|
|
||||||
qpItems.push({ // must implement vscode.QuickPickItem
|
qpItems.push({ // must implement vscode.QuickPickItem
|
||||||
label: filename.substring(filename.lastIndexOf('/') + 1),
|
label: filename.substring(filename.lastIndexOf("/") + 1),
|
||||||
description: file.fsPath,
|
description: file.fsPath,
|
||||||
file: file
|
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) {
|
if (!selection) {
|
||||||
return;
|
return;
|
||||||
|
@ -82,8 +82,8 @@ export class XQueryExecutionProvider {
|
||||||
|
|
||||||
if (outputPath) {
|
if (outputPath) {
|
||||||
outputPath = await vsc.window.showInputBox({
|
outputPath = await vsc.window.showInputBox({
|
||||||
placeHolder: 'ex. C:\\TEMP\XQueryOutput\\MyOutputFile.xml',
|
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.',
|
prompt: "Please specify the output file path. Existing file behavior is determined by the execution engine you have specified.",
|
||||||
value: outputPath
|
value: outputPath
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -91,12 +91,12 @@ export class XQueryExecutionProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
// call out to the execution engine
|
// 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) => {
|
args = args.map<string>((value: string) => {
|
||||||
return value
|
return value
|
||||||
.replace('$(script)', editor.document.uri.fsPath)
|
.replace("$(script)", editor.document.uri.fsPath)
|
||||||
.replace('$(input)', inputFile.fsPath)
|
.replace("$(input)", inputFile.fsPath)
|
||||||
.replace('$(project)', vsc.workspace.rootPath);
|
.replace("$(project)", vsc.workspace.rootPath);
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -106,7 +106,7 @@ export class XQueryExecutionProvider {
|
||||||
catch (error) {
|
catch (error) {
|
||||||
if (error.message.search(/[Ll]ine:?\s*\d+/gm) > -1) {
|
if (error.message.search(/[Ll]ine:?\s*\d+/gm) > -1) {
|
||||||
let match: RegExpExecArray = /[Ll]ine:?\s*\d+/gm.exec(error.message);
|
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}`);
|
let selection: string = await vsc.window.showErrorMessage(error.message, `Go to Line ${line}`);
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import * as vsc from 'vscode';
|
import * as vsc from "vscode";
|
||||||
import { RangeUtil } from '../utils/RangeUtil';
|
import { RangeUtil } from "../utils/RangeUtil";
|
||||||
import { XmlFormatter, IXmlFormatterOptions } from '../services/XmlFormatter';
|
import { XmlFormatter, IXmlFormatterOptions } from "../services/XmlFormatter";
|
||||||
|
|
||||||
const CFG_SECTION: string = 'xmlTools';
|
const CFG_SECTION: string = "xmlTools";
|
||||||
const CFG_SPLIT_NAMESPACES: string = 'splitXmlnsOnFormat';
|
const CFG_SPLIT_NAMESPACES: string = "splitXmlnsOnFormat";
|
||||||
|
|
||||||
export class XmlFormattingEditProvider implements vsc.DocumentFormattingEditProvider, vsc.DocumentRangeFormattingEditProvider {
|
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[] {
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import * as vsc from 'vscode';
|
import * as vsc from "vscode";
|
||||||
import { XQueryLinter, XQueryDiagnostic } from '../services/XQueryLinter';
|
import { XQueryLinter, XQueryDiagnostic } from "../services/XQueryLinter";
|
||||||
|
|
||||||
export class XQueryLintingFeatureProvider {
|
export class XQueryLintingFeatureProvider {
|
||||||
private static _coreDiagnostics: vsc.DiagnosticCollection;
|
private static _coreDiagnostics: vsc.DiagnosticCollection;
|
||||||
|
|
||||||
static get coreDiagnostics(): vsc.DiagnosticCollection {
|
static get coreDiagnostics(): vsc.DiagnosticCollection {
|
||||||
if (!XQueryLintingFeatureProvider._coreDiagnostics) {
|
if (!XQueryLintingFeatureProvider._coreDiagnostics) {
|
||||||
XQueryLintingFeatureProvider._coreDiagnostics = vsc.languages.createDiagnosticCollection('XQueryDiagnostics');
|
XQueryLintingFeatureProvider._coreDiagnostics = vsc.languages.createDiagnosticCollection("XQueryDiagnostics");
|
||||||
}
|
}
|
||||||
|
|
||||||
return XQueryLintingFeatureProvider._coreDiagnostics;
|
return XQueryLintingFeatureProvider._coreDiagnostics;
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import * as vsc from 'vscode';
|
import * as vsc from "vscode";
|
||||||
import * as ext from '../Extension';
|
import * as ext from "../Extension";
|
||||||
import { XPathEvaluator, EvaluatorResult, EvaluatorResultType } from '../services/XPathEvaluator';
|
import { XPathEvaluator, EvaluatorResult, EvaluatorResultType } from "../services/XPathEvaluator";
|
||||||
|
|
||||||
const CFG_SECTION: string = 'xmlTools';
|
const CFG_SECTION: string = "xmlTools";
|
||||||
const CFG_PERSIST_QUERY: string = 'persistXPathQuery';
|
const CFG_PERSIST_QUERY: string = "persistXPathQuery";
|
||||||
const CFG_IGNORE_DEFAULT_XMLNS: string = 'ignoreDefaultNamespace';
|
const CFG_IGNORE_DEFAULT_XMLNS: string = "ignoreDefaultNamespace";
|
||||||
const MEM_QUERY_HISTORY: string = 'xpathQueryHistory';
|
const MEM_QUERY_HISTORY: string = "xpathQueryHistory";
|
||||||
const MEM_QUERY_LAST: string = 'xPathQueryLast';
|
const MEM_QUERY_LAST: string = "xPathQueryLast";
|
||||||
const OUTPUT_CHANNEL: string = 'XPath Results';
|
const OUTPUT_CHANNEL: string = "XPath Results";
|
||||||
|
|
||||||
export class XPathFeatureProvider {
|
export class XPathFeatureProvider {
|
||||||
static async evaluateXPathAsync(editor: vsc.TextEditor, edit: vsc.TextEditorEdit): Promise<void> {
|
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
|
// 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
|
// 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 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) => {
|
let lastQuery: HistoricQuery = history.find((item: HistoricQuery) => {
|
||||||
if (item.uri == editor.document.uri.toString()) {
|
if (item.uri == editor.document.uri.toString()) {
|
||||||
|
@ -32,7 +32,7 @@ export class XPathFeatureProvider {
|
||||||
});
|
});
|
||||||
|
|
||||||
// set the inital display value and prompt the user
|
// set the inital display value and prompt the user
|
||||||
let query: string = '';
|
let query: string = "";
|
||||||
|
|
||||||
if (persistQueries) {
|
if (persistQueries) {
|
||||||
if (lastQuery) {
|
if (lastQuery) {
|
||||||
|
@ -45,8 +45,8 @@ export class XPathFeatureProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
query = await vsc.window.showInputBox({
|
query = await vsc.window.showInputBox({
|
||||||
placeHolder: 'XPath Query',
|
placeHolder: "XPath Query",
|
||||||
prompt: 'Please enter an XPath query to evaluate.',
|
prompt: "Please enter an XPath query to evaluate.",
|
||||||
value: query
|
value: query
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ export class XPathFeatureProvider {
|
||||||
outputChannel.clear();
|
outputChannel.clear();
|
||||||
|
|
||||||
outputChannel.appendLine(`XPath Query: ${query}`);
|
outputChannel.appendLine(`XPath Query: ${query}`);
|
||||||
outputChannel.append('\n');
|
outputChannel.append("\n");
|
||||||
|
|
||||||
if (evalResult.type === EvaluatorResultType.NODE_COLLECTION) {
|
if (evalResult.type === EvaluatorResultType.NODE_COLLECTION) {
|
||||||
(evalResult.result as Node[]).forEach((node: XmlNode) => {
|
(evalResult.result as Node[]).forEach((node: XmlNode) => {
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
let child_process = require('child_process');
|
let child_process = require("child_process");
|
||||||
|
|
||||||
export class ChildProcess {
|
export class ChildProcess {
|
||||||
static async spawnAsync(executable: string, args: string[]): Promise<void> {
|
static async spawnAsync(executable: string, args: string[]): Promise<void> {
|
||||||
return new Promise<void>((resolve, reject) => {
|
return new Promise<void>((resolve, reject) => {
|
||||||
|
|
||||||
let output: string = '';
|
let output: string = "";
|
||||||
let handle = child_process.spawn(executable, args);
|
let handle = child_process.spawn(executable, args);
|
||||||
|
|
||||||
handle.stdout.on('data', (data: string) => {
|
handle.stdout.on("data", (data: string) => {
|
||||||
output += data;
|
output += data;
|
||||||
});
|
});
|
||||||
|
|
||||||
handle.stderr.on('data', (data: string) => {
|
handle.stderr.on("data", (data: string) => {
|
||||||
output += data;
|
output += data;
|
||||||
});
|
});
|
||||||
|
|
||||||
handle.on('close', (code: string) => {
|
handle.on("close", (code: string) => {
|
||||||
if (code == '0') {
|
if (code == "0") {
|
||||||
resolve();
|
resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
export class EvaluatorResult {
|
||||||
type: EvaluatorResultType;
|
type: EvaluatorResultType;
|
||||||
|
@ -16,13 +16,13 @@ export class XPathEvaluator {
|
||||||
static evaluate(query: string, xml: string, ignoreDefaultNamespace: boolean): EvaluatorResult {
|
static evaluate(query: string, xml: string, ignoreDefaultNamespace: boolean): EvaluatorResult {
|
||||||
if (ignoreDefaultNamespace) {
|
if (ignoreDefaultNamespace) {
|
||||||
xml = xml.replace(/xmlns=".+"/g, (match: string) => {
|
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 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 resolver: xpath.XPathNSResolver = xpath.createNSResolver(xdoc);
|
||||||
let result: xpath.XPathResult = xpath.evaluate(
|
let result: xpath.XPathResult = xpath.evaluate(
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
let XQLint = require('xqlint').XQLint;
|
let XQLint = require("xqlint").XQLint;
|
||||||
|
|
||||||
export class XQueryCompleter {
|
export class XQueryCompleter {
|
||||||
constructor(script: string) {
|
constructor(script: string) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
let XQLint = require('xqlint').XQLint;
|
let XQLint = require("xqlint").XQLint;
|
||||||
|
|
||||||
export class XQueryLinter {
|
export class XQueryLinter {
|
||||||
static SEVERITY_WARNING: number = 1;
|
static SEVERITY_WARNING: number = 1;
|
||||||
|
|
|
@ -3,19 +3,19 @@ export class XmlFormatter {
|
||||||
constructor(options?: IXmlFormatterOptions) {
|
constructor(options?: IXmlFormatterOptions) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
if (typeof options.preferSpaces === 'undefined') {
|
if (typeof options.preferSpaces === "undefined") {
|
||||||
options.preferSpaces = false;
|
options.preferSpaces = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof options.splitNamespaces === 'undefined') {
|
if (typeof options.splitNamespaces === "undefined") {
|
||||||
options.splitNamespaces = true;
|
options.splitNamespaces = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
options.tabSize = options.tabSize || 4;
|
options.tabSize = options.tabSize || 4;
|
||||||
options.newLine = options.newLine || '\n';
|
options.newLine = options.newLine || "\n";
|
||||||
|
|
||||||
this.newLine = options.newLine || '\n';
|
this.newLine = options.newLine || "\n";
|
||||||
this.indentPattern = (options.preferSpaces) ? ' '.repeat(options.tabSize) : '\t';
|
this.indentPattern = (options.preferSpaces) ? " ".repeat(options.tabSize) : "\t";
|
||||||
this.splitNamespaces = options.splitNamespaces;
|
this.splitNamespaces = options.splitNamespaces;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,19 +25,19 @@ export class XmlFormatter {
|
||||||
|
|
||||||
format(xml: string): string {
|
format(xml: string): string {
|
||||||
xml = this.minify(xml, false);
|
xml = this.minify(xml, false);
|
||||||
xml = xml.replace(/</g, '~::~<');
|
xml = xml.replace(/</g, "~::~<");
|
||||||
|
|
||||||
if (this.splitNamespaces) {
|
if (this.splitNamespaces) {
|
||||||
xml = xml
|
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);
|
console.log(parts);
|
||||||
let inComment: boolean = false;
|
let inComment: boolean = false;
|
||||||
let level: number = 0;
|
let level: number = 0;
|
||||||
let output: string = '';
|
let output: string = "";
|
||||||
|
|
||||||
for (let i = 0; i < parts.length; i++) {
|
for (let i = 0; i < parts.length; i++) {
|
||||||
// <!
|
// <!
|
||||||
|
@ -59,7 +59,7 @@ export class XmlFormatter {
|
||||||
|
|
||||||
// <elm></elm>
|
// <elm></elm>
|
||||||
else if (/^<(\w|:)/.test(parts[i - 1]) && /^<\/(\w|:)/.test(parts[i])
|
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];
|
output += parts[i];
|
||||||
if (!inComment) level--;
|
if (!inComment) level--;
|
||||||
|
@ -118,31 +118,31 @@ export class XmlFormatter {
|
||||||
}
|
}
|
||||||
|
|
||||||
minify(xml: string, removeComments?: boolean): string {
|
minify(xml: string, removeComments?: boolean): string {
|
||||||
if (typeof removeComments === 'undefined') {
|
if (typeof removeComments === "undefined") {
|
||||||
removeComments = false;
|
removeComments = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
xml = this._stripLineBreaks(xml); // all line breaks outside of CDATA elements
|
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 = (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{0,}</g, "><"); // insignificant whitespace between tags
|
||||||
xml = xml.replace(/"\s+(?=[^\s]+=)/g, '" '); // spaces between attributes
|
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, '" '); // 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
|
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;
|
return xml;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _getIndent(level: number, trailingValue?: string): string {
|
private _getIndent(level: number, trailingValue?: string): string {
|
||||||
trailingValue = trailingValue || '';
|
trailingValue = trailingValue || "";
|
||||||
|
|
||||||
return `${this.newLine}${this.indentPattern.repeat(level)}${trailingValue}`;
|
return `${this.newLine}${this.indentPattern.repeat(level)}${trailingValue}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _stripLineBreaks(xml: string): string {
|
private _stripLineBreaks(xml: string): string {
|
||||||
let output: string = '';
|
let output: string = "";
|
||||||
let inTag: boolean = false;
|
let inTag: boolean = false;
|
||||||
let inTagName: boolean = false;
|
let inTagName: boolean = false;
|
||||||
let inCdata: boolean = false;
|
let inCdata: boolean = false;
|
||||||
|
@ -153,15 +153,15 @@ export class XmlFormatter {
|
||||||
let prev: string = xml.charAt(i - 1);
|
let prev: string = xml.charAt(i - 1);
|
||||||
let next: 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;
|
inCdata = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (char == ']' && (xml.substr(i, 3) == ']]>')) {
|
else if (char == "]" && (xml.substr(i, 3) == "]]>")) {
|
||||||
inCdata = false;
|
inCdata = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (char == '-' && (xml.substr(i, 3) == '-->')) {
|
else if (char == "-" && (xml.substr(i, 3) == "-->")) {
|
||||||
inCdata = false;
|
inCdata = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import * as vsc from 'vscode';
|
import * as vsc from "vscode";
|
||||||
|
|
||||||
export class RangeUtil {
|
export class RangeUtil {
|
||||||
static getRangeForDocument(document: vsc.TextDocument): vsc.Range {
|
static getRangeForDocument(document: vsc.TextDocument): vsc.Range {
|
||||||
|
|
Loading…
Add table
Reference in a new issue