forked from external/vscode-xml
Fix #21
This commit is contained in:
parent
5d8c285b06
commit
bc4e7823bc
@ -125,7 +125,8 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"xmldom": "DotJoshJohnson/xmldom#2794915",
|
"xmldom": "DotJoshJohnson/xmldom#2794915",
|
||||||
"xpath": "^0.0.9",
|
"xpath": "^0.0.9",
|
||||||
"xqlint": "^0.2.9"
|
"xqlint": "^0.2.9",
|
||||||
|
"opener": "^1.4.1"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"vscode:prepublish": "tsc"
|
"vscode:prepublish": "tsc"
|
||||||
|
@ -9,6 +9,9 @@ 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
|
||||||
|
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;
|
||||||
@ -27,33 +30,99 @@ export class XQueryExecutionProvider {
|
|||||||
return;
|
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);
|
let files: vsc.Uri[] = await vsc.workspace.findFiles('**/*.xml', '', 100);
|
||||||
|
disposable.dispose();
|
||||||
|
|
||||||
let qpItems: any[] = new Array<any>();
|
// user does not have a folder open - prompt for file name
|
||||||
|
if (typeof files === 'undefined') {
|
||||||
files.forEach((file) => {
|
vsc.window.showErrorMessage('You must have a folder opened in VS Code to use this feature.');
|
||||||
let filename: string = file.fsPath.replace('\\', '/');
|
|
||||||
|
|
||||||
qpItems.push({ // must implement vscode.QuickPickItem
|
|
||||||
label: filename.substring(filename.lastIndexOf('/') + 1),
|
|
||||||
description: file.fsPath,
|
|
||||||
file: file
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
let selection = await vsc.window.showQuickPick(qpItems, { placeHolder: 'Please select an input file.' });
|
|
||||||
|
|
||||||
if (!selection) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let disposable: vsc.Disposable = vsc.window.setStatusBarMessage('Executing XQuery Script...');
|
// if there is only one XML file, default it
|
||||||
|
// otherwise, prompt the user to select one from the open folder
|
||||||
|
if (files.length > 1) {
|
||||||
|
let qpItems: any[] = new Array<any>();
|
||||||
|
|
||||||
|
files.forEach((file) => {
|
||||||
|
let filename: string = file.fsPath.replace('\\', '/');
|
||||||
|
|
||||||
|
qpItems.push({ // must implement vscode.QuickPickItem
|
||||||
|
label: filename.substring(filename.lastIndexOf('/') + 1),
|
||||||
|
description: file.fsPath,
|
||||||
|
file: file
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
let selection = await vsc.window.showQuickPick(qpItems, { placeHolder: 'Please select an input file.' });
|
||||||
|
|
||||||
|
if (!selection) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
inputFile = selection.file;
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
inputFile = files[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// prompt for output file name
|
||||||
|
let outputPath: string = null;
|
||||||
|
let outputPathPos: number = -1;
|
||||||
|
|
||||||
|
for (let i = 0; i < args.length; i++) {
|
||||||
|
if (i > 0) {
|
||||||
|
if (args[i - 1].search(/out|result/)) {
|
||||||
|
outputPath = args[i];
|
||||||
|
outputPathPos = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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.',
|
||||||
|
value: outputPath
|
||||||
|
});
|
||||||
|
|
||||||
|
args[outputPathPos] = outputPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
// call out to the execution engine
|
||||||
|
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)', selection.file.fsPath);
|
.replace('$(input)', inputFile.fsPath);
|
||||||
});
|
});
|
||||||
await ChildProcess.spawnAsync(executable, args);
|
|
||||||
disposable.dispose();
|
try {
|
||||||
|
await ChildProcess.spawnAsync(executable, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 selection: string = await vsc.window.showErrorMessage(error.message, `Go to Line ${line}`);
|
||||||
|
|
||||||
|
if (selection == `Go to Line ${line}`) {
|
||||||
|
editor.revealRange(new vsc.Range(line, 0, line, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
vsc.window.showErrorMessage(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
finally {
|
||||||
|
disposable.dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -59,7 +59,17 @@ export class XPathFeatureProvider {
|
|||||||
|
|
||||||
// run the query
|
// run the query
|
||||||
let xml: string = editor.document.getText();
|
let xml: string = editor.document.getText();
|
||||||
let nodes: Node[] = XPathEvaluator.evaluate(query, xml, ignoreDefaultNamespace);
|
let nodes: Node[];
|
||||||
|
|
||||||
|
try {
|
||||||
|
nodes = XPathEvaluator.evaluate(query, xml, ignoreDefaultNamespace);
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
vsc.window.showErrorMessage(`Something went wrong while evaluating the XPath: ${error}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// show the results to the user
|
// show the results to the user
|
||||||
let outputChannel: vsc.OutputChannel = vsc.window.createOutputChannel(OUTPUT_CHANNEL);
|
let outputChannel: vsc.OutputChannel = vsc.window.createOutputChannel(OUTPUT_CHANNEL);
|
||||||
|
@ -6,15 +6,24 @@ 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 handle = child_process.spawn(executable, args);
|
let handle = child_process.spawn(executable, args);
|
||||||
|
|
||||||
|
handle.stdout.on('data', (data: string) => {
|
||||||
|
output += data;
|
||||||
|
});
|
||||||
|
|
||||||
|
handle.stderr.on('data', (data: string) => {
|
||||||
|
output += data;
|
||||||
|
});
|
||||||
|
|
||||||
handle.on('close', (code: string) => {
|
handle.on('close', (code: string) => {
|
||||||
if (code == '0') {
|
if (code == '0') {
|
||||||
resolve();
|
resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
reject(code);
|
reject({ code: code, message: output });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user