diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index e4d6cfa09117479327733e66300e23d56db5b654..942579406ae31c6f536ff36fe8418fe185adb6a8 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -743,26 +743,32 @@ declare module 'vscode' { //#region Tasks /** - * A task handle represents a task in the system. It can be used to - * present task and to execute them. + * A task item represents a task in the system. It can be used to + * present task information in the user interface or to execute the + * underlying task. */ - export interface TaskHandle { + export interface TaskItem { /** - * A unique ID. + * A unique ID representing the underlying task. */ - id: string; + readonly id: string; /** * A human readable label of the task. */ - label: string; + readonly label: string; + + /** + * The task definition. + */ + readonly definition: TaskDefinition; /** * The workspace folder the task belongs to. Is undefined * to tasks that aren't scoped to a workspace folder. */ - workspaceFolder: WorkspaceFolder | undefined; + readonly workspaceFolder: WorkspaceFolder | undefined; } //#endregion diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 95a283b53b4f9948c88a4d30665d1f5ebe1a99d5..4d1319843ec80f5f2927330257f17409b98fbf00 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -132,7 +132,7 @@ export function createApiFactory( const extHostLanguages = new ExtHostLanguages(rpcProtocol); // Register API-ish commands - ExtHostApiCommands.register(extHostCommands); + ExtHostApiCommands.register(extHostCommands, extHostWorkspace); return function (extension: IExtensionDescription): typeof vscode { diff --git a/src/vs/workbench/api/node/extHostApiCommands.ts b/src/vs/workbench/api/node/extHostApiCommands.ts index 4406a22b1533dd1522e879e4a2c69315fbd8ccab..9239a90a5f29b42ddaf7d24f2cf3f718e15374bc 100644 --- a/src/vs/workbench/api/node/extHostApiCommands.ts +++ b/src/vs/workbench/api/node/extHostApiCommands.ts @@ -6,6 +6,7 @@ import URI from 'vs/base/common/uri'; import { TPromise } from 'vs/base/common/winjs.base'; +import * as Objects from 'vs/base/common/objects'; import { IDisposable } from 'vs/base/common/lifecycle'; import * as vscode from 'vscode'; import * as typeConverters from 'vs/workbench/api/node/extHostTypeConverters'; @@ -18,18 +19,21 @@ import { IWorkspaceSymbolProvider } from 'vs/workbench/parts/search/common/searc import { Position as EditorPosition, ITextEditorOptions } from 'vs/platform/editor/common/editor'; import { CustomCodeAction } from 'vs/workbench/api/node/extHostLanguageFeatures'; import * as TaskSystem from 'vs/workbench/parts/tasks/common/tasks'; +import { ExtHostWorkspace } from './extHostWorkspace'; export class ExtHostApiCommands { - static register(commands: ExtHostCommands) { - return new ExtHostApiCommands(commands).registerCommands(); + static register(commands: ExtHostCommands, workspace: ExtHostWorkspace) { + return new ExtHostApiCommands(commands, workspace).registerCommands(); } private _commands: ExtHostCommands; + private _workspace: ExtHostWorkspace; private _disposables: IDisposable[] = []; - private constructor(commands: ExtHostCommands) { + private constructor(commands: ExtHostCommands, workspace: ExtHostWorkspace) { this._commands = commands; + this._workspace = workspace; } registerCommands() { @@ -472,16 +476,25 @@ export class ExtHostApiCommands { .then(tryMapWith(typeConverters.DocumentLink.to)); } - private _executeTaskProvider(): Thenable { - return this._commands.executeCommand('_executeTaskProvider').then((values) => { + private _executeTaskProvider(): Thenable { + return this._commands.executeCommand('_executeTaskProvider').then((values) => { + let workspace = this._workspace; return values.map(handle => { - return { - id: handle.id, - label: handle.label, - workspaceFolder: { - name: handle.workspaceFolder.name, - index: handle.workspaceFolder.index, - uri: URI.revive(handle.workspaceFolder.uri) + let definition: vscode.TaskDefinition = Objects.assign(Object.create(null), handle.definition); + delete definition._key; + let uri = URI.revive(handle.workspaceFolderUri); + return new class { + get id(): string { + return handle.id; + } + get label(): string { + return handle.label; + } + get definition(): vscode.TaskDefinition { + return definition; + } + get workspaceFolder(): vscode.WorkspaceFolder { + return uri ? workspace.resolveWorkspaceFolder(uri) : undefined; } }; }); diff --git a/src/vs/workbench/api/node/extHostWorkspace.ts b/src/vs/workbench/api/node/extHostWorkspace.ts index dfbc1acc3ee2eb493514dffe66bc25727ef37773..61b0e73992f24fb72f2d83b4b9bf38ac6bd47468 100644 --- a/src/vs/workbench/api/node/extHostWorkspace.ts +++ b/src/vs/workbench/api/node/extHostWorkspace.ts @@ -125,6 +125,10 @@ class ExtHostWorkspaceImpl extends Workspace { } return this._structure.findSubstr(uri.toString()); } + + resolveWorkspaceFolder(uri: URI): vscode.WorkspaceFolder { + return this._structure.get(uri.toString()); + } } export class ExtHostWorkspace implements ExtHostWorkspaceShape { @@ -239,6 +243,13 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape { return this._actualWorkspace.getWorkspaceFolder(uri, resolveParent); } + resolveWorkspaceFolder(uri: vscode.Uri): vscode.WorkspaceFolder { + if (!this._actualWorkspace) { + return undefined; + } + return this._actualWorkspace.resolveWorkspaceFolder(uri); + } + getPath(): string { // this is legacy from the days before having diff --git a/src/vs/workbench/parts/tasks/common/tasks.ts b/src/vs/workbench/parts/tasks/common/tasks.ts index bcefab54238243030335c8c174e0b0243a89bbfe..08640b0476c857bf76e0cef2648376e30e48e47b 100644 --- a/src/vs/workbench/parts/tasks/common/tasks.ts +++ b/src/vs/workbench/parts/tasks/common/tasks.ts @@ -4,14 +4,15 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import { UriComponents } from 'vs/base/common/uri'; +import URI, { UriComponents } from 'vs/base/common/uri'; import * as Types from 'vs/base/common/types'; import { IJSONSchemaMap } from 'vs/base/common/jsonSchema'; import * as Objects from 'vs/base/common/objects'; import { IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; import { ProblemMatcher } from 'vs/workbench/parts/tasks/common/problemMatcher'; -import { IWorkspaceFolder, IWorkspaceFolderData } from 'vs/platform/workspace/common/workspace'; +import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; +import { generateUuid } from '../../../../base/common/uuid'; export enum ShellQuoting { @@ -335,6 +336,7 @@ export type TaskSource = WorkspaceTaskSource | ExtensionTaskSource | InMemoryTas export interface TaskIdentifier { _key: string; type: string; + [name: string]: any; } export interface TaskDependency { @@ -439,6 +441,22 @@ export namespace CustomTask { let candidate: CustomTask = value; return candidate && candidate.type === 'custom'; } + export function getDefinition(task: CustomTask): TaskIdentifier { + if (task.command === void 0) { + return undefined; + } + if (task.command.runtime === RuntimeType.Shell) { + return { + _key: generateUuid(), + type: 'shell' + }; + } else { + return { + _key: generateUuid(), + type: 'process' + }; + } + } } export interface ConfiguringTask extends CommonTask, ConfigurationProperties { @@ -594,10 +612,11 @@ export namespace Task { } } -export interface TaskHandleTransfer { +export interface TaskItemTransfer { id: string; label: string; - workspaceFolder: IWorkspaceFolderData; + definition: TaskIdentifier; + workspaceFolderUri: URI; } export enum ExecutionEngine { diff --git a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts index e1e8dbc4e9a7aa40cbab8823540fbaa738cfbfb4..ea1627866a5a5cab632e41aad27840c8405da2d3 100644 --- a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts +++ b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts @@ -62,7 +62,7 @@ import Constants from 'vs/workbench/parts/markers/electron-browser/constants'; import { IPartService } from 'vs/workbench/services/part/common/partService'; import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; -import { IWorkspaceContextService, WorkbenchState, IWorkspaceFolder, IWorkspaceFolderData } from 'vs/platform/workspace/common/workspace'; +import { IWorkspaceContextService, WorkbenchState, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { IOutputService, IOutputChannelRegistry, Extensions as OutputExt, IOutputChannel } from 'vs/workbench/parts/output/common/output'; @@ -74,7 +74,7 @@ import { ITaskSystem, ITaskResolver, ITaskSummary, TaskExecuteKind, TaskError, T import { Task, CustomTask, ConfiguringTask, ContributedTask, InMemoryTask, TaskEvent, TaskEventKind, TaskSet, TaskGroup, GroupType, ExecutionEngine, JsonSchemaVersion, TaskSourceKind, - TaskIdentifier, TaskSorter, TaskHandleTransfer + TaskIdentifier, TaskSorter, TaskItemTransfer } from 'vs/workbench/parts/tasks/common/tasks'; import { ITaskService, ITaskProvider, RunOptions, CustomizationProperties } from 'vs/workbench/parts/tasks/common/taskService'; import { getTemplates as getTaskTemplates } from 'vs/workbench/parts/tasks/common/taskTemplates'; @@ -582,18 +582,21 @@ class TaskService implements ITaskService { CommandsRegistry.registerCommand('_executeTaskProvider', (accessor, args) => { return this.tasks().then((tasks) => { - let result: TaskHandleTransfer[] = []; + let result: TaskItemTransfer[] = []; for (let task of tasks) { - let folder = Task.getWorkspaceFolder(task); - let folderData: IWorkspaceFolderData = folder ? { - name: folder.name, - uri: folder.uri, - index: folder.index - } : undefined; - let handle: TaskHandleTransfer = { + let folder: IWorkspaceFolder = Task.getWorkspaceFolder(task); + let folderUri = folder ? folder.uri : undefined; + let definition: TaskIdentifier; + if (ContributedTask.is(task)) { + definition = task.defines; + } else if (CustomTask.is(task) && task.command !== void 0) { + definition = CustomTask.getDefinition(task); + } + let handle: TaskItemTransfer = { id: task._id, label: task._label, - workspaceFolder: folderData + definition: definition, + workspaceFolderUri: folderUri }; result.push(handle); } diff --git a/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts b/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts index 11189793c55005e6eee9f91da9bbe90bdc853c66..133e9d9667c4ab2ac9bcf9d467b480faa406e4f9 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts @@ -33,6 +33,8 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import 'vs/workbench/parts/search/electron-browser/search.contribution'; import { NullLogService } from 'vs/platform/log/common/log'; import { ITextModel } from 'vs/editor/common/model'; +import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace'; +import { generateUuid } from 'vs/base/common/uuid'; const defaultSelector = { scheme: 'far' }; const model: ITextModel = EditorModel.createFromString( @@ -49,6 +51,7 @@ let rpcProtocol: TestRPCProtocol; let extHost: ExtHostLanguageFeatures; let mainThread: MainThreadLanguageFeatures; let commands: ExtHostCommands; +let workspace: ExtHostWorkspace; let disposables: vscode.Disposable[] = []; let originalErrorHandler: (e: any) => any; @@ -115,9 +118,10 @@ suite('ExtHostLanguageFeatureCommands', function () { const heapService = new ExtHostHeapService(); commands = new ExtHostCommands(rpcProtocol, heapService, new NullLogService()); + workspace = new ExtHostWorkspace(rpcProtocol, { id: generateUuid(), name: 'Test', folders: [] }, new NullLogService()); rpcProtocol.set(ExtHostContext.ExtHostCommands, commands); rpcProtocol.set(MainContext.MainThreadCommands, inst.createInstance(MainThreadCommands, rpcProtocol)); - ExtHostApiCommands.register(commands); + ExtHostApiCommands.register(commands, workspace); const diagnostics = new ExtHostDiagnostics(rpcProtocol); rpcProtocol.set(ExtHostContext.ExtHostDiagnostics, diagnostics);