diff --git a/extensions/npm/README.md b/extensions/npm/README.md index f4b85999742a23b85f035d1b16b7d20aaa5fb157..a24a7d69d6e00ffa80ddaf5841bb6a5225f2c5cf 100644 --- a/extensions/npm/README.md +++ b/extensions/npm/README.md @@ -19,7 +19,8 @@ The Npm Script Explorer shows the npm scripts found in your workspace. The explo ### Run Scripts from the Editor -The extension provides code lense actions to run or debug a script from the editor. +The extension supports to run the selected script as a task when editing the `package.json`file. You can either run a script from +the hover shown on a script or using the command `Run Selected Npm Script`. ### Others diff --git a/extensions/npm/package.json b/extensions/npm/package.json index d5647618a81e4e5cad2be67cb761a14fa23894b1..2052b7a8228fd3c14e94fd5a111e851810ff20ab 100644 --- a/extensions/npm/package.json +++ b/extensions/npm/package.json @@ -82,6 +82,10 @@ "light": "resources/light/refresh.svg", "dark": "resources/dark/refresh.svg" } + }, + { + "command": "npm.runSelectedScript", + "title": "%command.runSelectedScript%" } ], "menus": { diff --git a/extensions/npm/package.nls.json b/extensions/npm/package.nls.json index 3a59c27cad1daac60a23764fc4859d67b84a8e1d..b3800cd96e40fa46559f991a044dcfc17f1ac990 100644 --- a/extensions/npm/package.nls.json +++ b/extensions/npm/package.nls.json @@ -16,5 +16,6 @@ "command.run": "Run", "command.debug": "Debug", "command.openScript": "Open", - "command.runInstall": "Run Install" + "command.runInstall": "Run Install", + "command.runSelectedScript": "Run Selected Npm Script" } diff --git a/extensions/npm/src/commands.ts b/extensions/npm/src/commands.ts new file mode 100644 index 0000000000000000000000000000000000000000..509d536db92c2f271dabd26b0e2c61bcdcb9c1fa --- /dev/null +++ b/extensions/npm/src/commands.ts @@ -0,0 +1,32 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +import * as vscode from 'vscode'; +import { + runScript, findScriptAtPosition +} from './tasks'; +import * as nls from 'vscode-nls'; + +const localize = nls.loadMessageBundle(); + +export function runSelectedScript() { + 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) { + runScript(script, document); + } else { + let message = localize('noScriptFound', 'Could not find an npm script at the selection.'); + vscode.window.showErrorMessage(message); + } +} \ No newline at end of file diff --git a/extensions/npm/src/main.ts b/extensions/npm/src/main.ts index 116852100dc992519ddca70958b754e7dac251f9..02e22490fd765e056a1cc1278aaa50055590dce6 100644 --- a/extensions/npm/src/main.ts +++ b/extensions/npm/src/main.ts @@ -10,6 +10,7 @@ import { addJSONProviders } from './features/jsonContributions'; import { NpmScriptsTreeDataProvider } from './npmView'; import { invalidateTasksCache, NpmTaskProvider } from './tasks'; import { invalidateHoverScriptsCache, NpmScriptHoverProvider } from './scriptHover'; +import { runSelectedScript } from './commands'; export async function activate(context: vscode.ExtensionContext): Promise { const taskProvider = registerTaskProvider(context); @@ -37,7 +38,7 @@ export async function activate(context: vscode.ExtensionContext): Promise invalidateHoverScriptsCache(e.document); }); context.subscriptions.push(d); - + context.subscriptions.push(vscode.commands.registerCommand('npm.runSelectedScript', runSelectedScript)); context.subscriptions.push(addJSONProviders(httpRequest.xhr)); } diff --git a/extensions/npm/src/tasks.ts b/extensions/npm/src/tasks.ts index 3060cce1ed6fee099eaf6824e2902c56ef30b0d2..189fd98baec195387ebfc8f9bb3b84bbae5039cd 100644 --- a/extensions/npm/src/tasks.ts +++ b/extensions/npm/src/tasks.ts @@ -6,7 +6,7 @@ import { TaskDefinition, Task, TaskGroup, WorkspaceFolder, RelativePattern, ShellExecution, Uri, workspace, - DebugConfiguration, debug, TaskProvider, ExtensionContext + DebugConfiguration, debug, TaskProvider, ExtensionContext, TextDocument, tasks } from 'vscode'; import * as path from 'path'; import * as fs from 'fs'; @@ -288,6 +288,15 @@ async function readFile(file: string): Promise { }); } +export function runScript(script: string, document: TextDocument) { + let uri = document.uri; + let folder = workspace.getWorkspaceFolder(uri); + if (folder) { + let task = createTask(script, `run ${script}`, folder, uri); + tasks.executeTask(task); + } +} + export function extractDebugArgFromScript(scriptValue: string): [string, number] | undefined { // matches --debug, --debug=1234, --debug-brk, debug-brk=1234, --inspect, // --inspect=1234, --inspect-brk, --inspect-brk=1234, @@ -405,6 +414,42 @@ export function findAllScriptRanges(buffer: string): Map= 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 {