forked from external/vscode-xml
		
	Fix #21
This commit is contained in:
		
							parent
							
								
									5d8c285b06
								
							
						
					
					
						commit
						bc4e7823bc
					
				
					 4 changed files with 111 additions and 22 deletions
				
			
		| 
						 | 
					@ -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…
	
	Add table
		
		Reference in a new issue