Support to run the selected script in the editor

This commit is contained in:
Erich Gamma 2018-07-18 12:57:26 +02:00
parent c82766c068
commit 5c5f93cdbc
5 changed files with 95 additions and 2 deletions

View file

@ -4,6 +4,8 @@
## Features
### Task Running
This extension supports running npm scripts defined in the `package.json` as [tasks](https://code.visualstudio.com/docs/editor/tasks). Scripts with the name 'build', 'compile', or 'watch'
are treated as build tasks.
@ -11,6 +13,14 @@ To run scripts as tasks, use the **Tasks** menu.
For more information about auto detection of Tasks, see the [documentation](https://code.visualstudio.com/Docs/editor/tasks#_task-autodetection).
### Script Explorer
The Npm Script Explorer shows the npm scripts found in your workspace. The explorer view is enabled by the setting `npm.enableScriptExplorer`.
### Run Scripts from the Editor
The extension provides commands to run the script containing the selection.
## Settings
- `npm.autoDetect` - Enable detecting scripts as tasks, the default is `on`.

View file

@ -59,6 +59,10 @@
"dark": "resources/dark/continue.svg"
}
},
{
"command": "npm.runScriptFromSource",
"title": "%command.runScriptFromSource%"
},
{
"command": "npm.debugScript",
"title": "%command.debug%",
@ -94,6 +98,10 @@
"command": "npm.runScript",
"when": "false"
},
{
"command": "npm.runScriptFromSource",
"when": "false"
},
{
"command": "npm.debugScript",
"when": "false"
@ -114,6 +122,13 @@
"group": "navigation"
}
],
"editor/context": [
{
"command": "npm.runScriptFromSource",
"when": "resourceFilename == 'package.json'",
"group": "navigation@+1"
}
],
"view/item/context": [
{
"command": "npm.openScript",

View file

@ -15,5 +15,6 @@
"command.run": "Run",
"command.debug": "Debug",
"command.openScript": "Open",
"command.runInstall": "Run Install"
"command.runInstall": "Run Install",
"command.runScriptFromSource": "Run Script"
}

View file

@ -9,10 +9,14 @@ import * as vscode from 'vscode';
import { addJSONProviders } from './features/jsonContributions';
import { NpmScriptsTreeDataProvider } from './npmView';
import { provideNpmScripts, invalidateScriptsCache } from './tasks';
import { provideNpmScripts, invalidateScriptsCache, findScriptAtPosition, createTask } from './tasks';
import * as nls from 'vscode-nls';
let taskProvider: vscode.Disposable | undefined;
const localize = nls.loadMessageBundle();
export async function activate(context: vscode.ExtensionContext): Promise<void> {
taskProvider = registerTaskProvider(context);
const treeDataProvider = registerExplorer(context);
@ -32,6 +36,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
}
});
context.subscriptions.push(addJSONProviders(httpRequest.xhr));
context.subscriptions.push(vscode.commands.registerCommand('npm.runScriptFromSource', runScriptFromSource));
}
function registerTaskProvider(context: vscode.ExtensionContext): vscode.Disposable | undefined {
@ -70,6 +75,29 @@ function configureHttpRequest() {
httpRequest.configure(httpSettings.get<string>('proxy', ''), httpSettings.get<boolean>('proxyStrictSSL', true));
}
async function runScriptFromSource() {
let editor = vscode.window.activeTextEditor;
if (!editor) {
return;
}
let document = editor.document;
let contents = document.getText();
let selection = editor.selection;
let offset = document.offsetAt(selection.anchor);
let script = findScriptAtPosition(contents, offset);
if (script) {
let uri = document.uri;
let folder = vscode.workspace.getWorkspaceFolder(uri);
if (folder) {
let task = createTask(script, `run ${script}`, folder, uri);
vscode.tasks.executeTask(task);
}
} else {
let message = localize('noScriptFound', 'Could not find a script at the selection.');
vscode.window.showErrorMessage(message);
}
}
export function deactivate(): void {
if (taskProvider) {
taskProvider.dispose();

View file

@ -304,6 +304,45 @@ async function findAllScripts(buffer: string): Promise<StringMap> {
return scripts;
}
export function findScriptAtPosition(buffer: string, offset: number): string | undefined {
let script: string | undefined = undefined;
let inScripts = false;
let scriptStart: number | undefined;
let visitor: JSONVisitor = {
onError(_error: ParseErrorCode, _offset: number, _length: number) {
// TODO: inform user about the parse error
},
onObjectEnd() {
if (inScripts) {
inScripts = false;
scriptStart = undefined;
}
},
onLiteralValue(value: any, nodeOffset: number, nodeLength: number) {
if (inScripts && scriptStart) {
if (offset >= scriptStart && offset < nodeOffset + nodeLength) {
// found the script
inScripts = false;
} else {
script = undefined;
}
}
},
onObjectProperty(property: string, nodeOffset: number, nodeLength: number) {
if (property === 'scripts') {
inScripts = true;
}
else if (inScripts) {
scriptStart = nodeOffset;
script = property;
}
}
};
visit(buffer, visitor);
return script;
}
export async function getScripts(packageJsonUri: Uri): Promise<StringMap | undefined> {
if (packageJsonUri.scheme !== 'file') {