diff --git a/extensions/tasks/package.json b/extensions/tasks/package.json
new file mode 100644
index 00000000000..d19603aadad
--- /dev/null
+++ b/extensions/tasks/package.json
@@ -0,0 +1,21 @@
+{
+ "name": "tasks",
+ "description": "Extension to add support for tasks.json files",
+ "displayName": "Tasks.json support for VSCode",
+ "version": "0.10.1",
+ "author": "Microsoft Corporation",
+ "license": "MIT",
+ "publisher": "vscode",
+ "engines": {
+ "vscode": "*"
+ },
+ "scripts": {
+ "vscode:prepublish": "node ../../node_modules/gulp/bin/gulp.js --gulpfile ../../gulpfile.plugins.js compile-plugin:tasks ./src/tsconfig.json"
+ },
+ "activationEvents": [
+ "onLanguage:json"
+ ],
+ "main": "./out/tasksMain",
+ "contributes": {
+ }
+}
\ No newline at end of file
diff --git a/extensions/tasks/src/tasksMain.ts b/extensions/tasks/src/tasksMain.ts
new file mode 100644
index 00000000000..d011264653b
--- /dev/null
+++ b/extensions/tasks/src/tasksMain.ts
@@ -0,0 +1,101 @@
+/*---------------------------------------------------------------------------------------------
+ * 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 path from 'path';
+
+import { languages, workspace, ExtensionContext, TextDocument, Position, CancellationToken, CompletionItem, CompletionItemKind, DocumentFilter } from 'vscode';
+
+export function activate(context: ExtensionContext): void {
+ // We can't use a pattern here since it disables the normal json code complete
+ // which we don't want. Do the filtering in the actual suggest
+ let selector: DocumentFilter = { language: 'json' };
+ let taskFileName = workspace.rootPath ? path.join(workspace.rootPath, '.vscode/tasks.json') : null;
+ let items = taskFileName ? createCompletionItems() : [];
+
+ languages.registerCompletionItemProvider(selector, {
+ provideCompletionItems: (document: TextDocument, position: Position, token: CancellationToken): CompletionItem[] => {
+ if (document.fileName === taskFileName) {
+ return items;
+ } else {
+ return [];
+ }
+ }
+ });
+}
+
+function createCompletionItems(): CompletionItem[] {
+ let result: CompletionItem[] = [];
+ let item: CompletionItem;
+
+ item = new CompletionItem('tsc');
+ item.kind = CompletionItemKind.Snippet;
+ item.detail = 'Use the tsc compiler on a specific file.';
+ item.filterText = 'ts-tsc';
+ item.insertText = [
+ '"version": "0.1.0",',
+ '"command": "tsc",',
+ '"isShellCommand": true,',
+ '"showOutput": "silent",',
+ '"args": ["HelloWorld.ts"],',
+ '"problemMatcher": "$tsc"'
+ ].join('\n');
+ result.push(item);
+
+ item = new CompletionItem('tsc - tsconfig.json');
+ item.kind = CompletionItemKind.Snippet;
+ item.detail = 'Use the tsc compiler with a tsconfig.json file.';
+ item.filterText = 'ts-tsc - tsconfig.json';
+ item.insertText = [
+ '"version": "0.1.0",',
+ '"command": "tsc",',
+ '"isShellCommand": true,',
+ '"showOutput": "silent",',
+ '"args": ["-p", "."],',
+ '"problemMatcher": "$tsc"'
+ ].join('\n');
+ result.push(item);
+
+ item = new CompletionItem('tsc - watch');
+ item.kind = CompletionItemKind.Snippet;
+ item.detail = 'Use the tsc compiler in watch mode.';
+ item.filterText = 'ts-tsc - watch';
+ item.insertText = [
+ '"version": "0.1.0",',
+ '"command": "tsc",',
+ '"isShellCommand": true,',
+ '"showOutput": "silent",',
+ '"args": ["-w", "-p", "."],',
+ '"problemMatcher": "$tsc-watch"'
+ ].join('\n');
+ result.push(item);
+
+ item = new CompletionItem('msbuild');
+ item.kind = CompletionItemKind.Snippet;
+ item.detail = 'Use msbuild to compile your project.';
+ item.filterText = 'ts-msbuild';
+ item.insertText = [
+ '"version": "0.1.0",',
+ '"command": "msbuild",',
+ '"args": [',
+ '\t// Ask msbuild to generate full paths for file names.',
+ '\t"/property:GenerateFullPaths=true"',
+ '],',
+ '"taskSelector": "/t:",',
+ '"showOutput": "silent",',
+ '"tasks": [',
+ '\t{',
+ '\t\t"taskName": "build",',
+ '\t\t// Show the output window only if unrecognized errors occur.',
+ '\t\t"showOutput": "silent",',
+ '\t\t// Use the standard MS compiler pattern to detect errors, warnings and infos',
+ '\t\t"problemMatcher": "$msCompile"',
+ '\t}',
+ ']'
+ ].join('\n');
+ result.push(item);
+
+ return result;
+}
\ No newline at end of file
diff --git a/extensions/tasks/src/tsconfig.json b/extensions/tasks/src/tsconfig.json
new file mode 100644
index 00000000000..e51744d35f4
--- /dev/null
+++ b/extensions/tasks/src/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "compilerOptions": {
+ "module": "commonjs",
+ "target": "es5",
+ "noLib": true,
+ "sourceMap": true,
+ "outDir": "../out"
+ }
+}
\ No newline at end of file
diff --git a/extensions/tasks/src/typings/node.additions.d.ts b/extensions/tasks/src/typings/node.additions.d.ts
new file mode 100644
index 00000000000..3ae7322bc8a
--- /dev/null
+++ b/extensions/tasks/src/typings/node.additions.d.ts
@@ -0,0 +1,28 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+declare function setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer;
+declare function clearTimeout(timeoutId: NodeJS.Timer): void;
+declare function setInterval(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer;
+declare function clearInterval(intervalId: NodeJS.Timer): void;
+declare function setImmediate(callback: (...args: any[]) => void, ...args: any[]): any;
+declare function clearImmediate(immediateId: any): void;
+
+interface Console {
+ assert(test?: boolean, message?: string, ...optionalParams: any[]): void;
+ dir(value?: any, ...optionalParams: any[]): void;
+ error(message?: any, ...optionalParams: any[]): void;
+ info(message?: any, ...optionalParams: any[]): void;
+ log(message?: any, ...optionalParams: any[]): void;
+ time(timerName?: string): void;
+ timeEnd(timerName?: string): void;
+ trace(message?: any, ...optionalParams: any[]): void;
+ warn(message?: any, ...optionalParams: any[]): void;
+}
+
+declare var Console: {
+ prototype: Console;
+ new(): Console;
+};
\ No newline at end of file
diff --git a/extensions/tasks/src/typings/refs.d.ts b/extensions/tasks/src/typings/refs.d.ts
new file mode 100644
index 00000000000..6b027cbfa31
--- /dev/null
+++ b/extensions/tasks/src/typings/refs.d.ts
@@ -0,0 +1,9 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+///
+///
+///
+///
\ No newline at end of file
diff --git a/extensions/typescript/src/typescriptServiceClient.ts b/extensions/typescript/src/typescriptServiceClient.ts
index 05303aee4cd..40512e7900e 100644
--- a/extensions/typescript/src/typescriptServiceClient.ts
+++ b/extensions/typescript/src/typescriptServiceClient.ts
@@ -184,7 +184,7 @@ export default class TypeScriptServiceClient implements ITypescriptServiceClient
return unknown;
}
let contents = fs.readFileSync(fileName).toString();
- let desc = null;
+ let desc:any = null;
try {
desc = JSON.parse(contents);
} catch(err) {
diff --git a/extensions/typescript/src/typings/node.additions.d.ts b/extensions/typescript/src/typings/node.additions.d.ts
index 0dccea79121..3ae7322bc8a 100644
--- a/extensions/typescript/src/typings/node.additions.d.ts
+++ b/extensions/typescript/src/typings/node.additions.d.ts
@@ -8,4 +8,21 @@ declare function clearTimeout(timeoutId: NodeJS.Timer): void;
declare function setInterval(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer;
declare function clearInterval(intervalId: NodeJS.Timer): void;
declare function setImmediate(callback: (...args: any[]) => void, ...args: any[]): any;
-declare function clearImmediate(immediateId: any): void;
\ No newline at end of file
+declare function clearImmediate(immediateId: any): void;
+
+interface Console {
+ assert(test?: boolean, message?: string, ...optionalParams: any[]): void;
+ dir(value?: any, ...optionalParams: any[]): void;
+ error(message?: any, ...optionalParams: any[]): void;
+ info(message?: any, ...optionalParams: any[]): void;
+ log(message?: any, ...optionalParams: any[]): void;
+ time(timerName?: string): void;
+ timeEnd(timerName?: string): void;
+ trace(message?: any, ...optionalParams: any[]): void;
+ warn(message?: any, ...optionalParams: any[]): void;
+}
+
+declare var Console: {
+ prototype: Console;
+ new(): Console;
+};
\ No newline at end of file
diff --git a/src/vs/workbench/parts/tasks/common/taskSampleConfig.json b/src/vs/workbench/parts/tasks/common/taskSampleConfig.json
index 1f312158d75..19c92397b15 100644
--- a/src/vs/workbench/parts/tasks/common/taskSampleConfig.json
+++ b/src/vs/workbench/parts/tasks/common/taskSampleConfig.json
@@ -1,190 +1,6 @@
-// Available variables which can be used inside of strings.
-// ${workspaceRoot}: the root folder of the team
-// ${file}: the current opened file
-// ${fileBasename}: the current opened file's basename
-// ${fileDirname}: the current opened file's dirname
-// ${fileExtname}: the current opened file's extension
-// ${cwd}: the current working directory of the spawned process
-
-// A task runner that calls the Typescript compiler (tsc) and
-// Compiles a HelloWorld.ts program
{
- "version": "0.1.0",
-
- // The command is tsc. Assumes that tsc has been installed using npm install -g typescript
- "command": "tsc",
-
- // The command is a shell script
- "isShellCommand": true,
-
- // Show the output window only if unrecognized errors occur.
- "showOutput": "silent",
-
- // args is the HelloWorld program to compile.
- "args": ["HelloWorld.ts"],
-
- // use the standard tsc problem matcher to find compile problems
- // in the output.
- "problemMatcher": "$tsc"
-}
-
-// A task runner that calls the Typescript compiler (tsc) and
-// compiles based on a tsconfig.json file that is present in
-// the root of the folder open in VSCode
-/*
-{
- "version": "0.1.0",
-
- // The command is tsc. Assumes that tsc has been installed using npm install -g typescript
- "command": "tsc",
-
- // The command is a shell script
- "isShellCommand": true,
-
- // Show the output window only if unrecognized errors occur.
- "showOutput": "silent",
-
- // Tell the tsc compiler to use the tsconfig.json from the open folder.
- "args": ["-p", "."],
-
- // use the standard tsc problem matcher to find compile problems
- // in the output.
- "problemMatcher": "$tsc"
-}
-*/
-
-// A task runner configuration for gulp. Gulp provides a less task
-// which compiles less to css.
-/*
-{
- "version": "0.1.0",
- "command": "gulp",
- "isShellCommand": true,
- "tasks": [
- {
- "taskName": "less",
- // Make this the default build command.
- "isBuildCommand": true,
- // Show the output window only if unrecognized errors occur.
- "showOutput": "silent",
- // Use the standard less compilation problem matcher.
- "problemMatcher": "$lessCompile"
- }
- ]
-}
-*/
-
-// Uncomment the following section to use jake to build a workspace
-// cloned from https://github.com/Microsoft/TypeScript.git
-/*
-{
- "version": "0.1.0",
- // Task runner is jake
- "command": "jake",
- // Need to be executed in shell / cmd
- "isShellCommand": true,
- "showOutput": "silent",
- "tasks": [
- {
- // TS build command is local.
- "taskName": "local",
- // Make this the default build command.
- "isBuildCommand": true,
- // Show the output window only if unrecognized errors occur.
- "showOutput": "silent",
- // Use the redefined Typescript output problem matcher.
- "problemMatcher": [
- "$tsc"
- ]
- }
- ]
-}
-*/
-
-// Uncomment the section below to use msbuild and generate problems
-// for csc, cpp, tsc and vb. The configuration assumes that msbuild
-// is available on the path and a solution file exists in the
-// workspace folder root.
-/*
-{
- "version": "0.1.0",
- "command": "msbuild",
- "args": [
- // Ask msbuild to generate full paths for file names.
- "/property:GenerateFullPaths=true"
- ],
- "taskSelector": "/t:",
- "showOutput": "silent",
- "tasks": [
- {
- "taskName": "build",
- // Show the output window only if unrecognized errors occur.
- "showOutput": "silent",
- // Use the standard MS compiler pattern to detect errors, warnings
- // and infos in the output.
- "problemMatcher": "$msCompile"
- }
- ]
-}
-*/
-
-// Uncomment the following section to use msbuild which compiles Typescript
-// and less files.
-/*
-{
- "version": "0.1.0",
- "command": "msbuild",
- "args": [
- // Ask msbuild to generate full paths for file names.
- "/property:GenerateFullPaths=true"
- ],
- "taskSelector": "/t:",
- "showOutput": "silent",
- "tasks": [
- {
- "taskName": "build",
- // Show the output window only if unrecognized errors occur.
- "showOutput": "silent",
- // Use the standard MS compiler pattern to detect errors, warnings
- // and infos in the output.
- "problemMatcher": [
- "$msCompile",
- "$lessCompile"
- ]
- }
- ]
-}
-*/
-// A task runner example that defines a problemMatcher inline instead of using
-// a predefined one.
-/*
-{
- "version": "0.1.0",
- "command": "tsc",
- "isShellCommand": true,
- "args": ["HelloWorld.ts"],
- "showOutput": "silent",
- "problemMatcher": {
- // The problem is owned by the typescript language service. Ensure that the problems
- // are merged with problems produced by Visual Studio's language service.
- "owner": "typescript",
- // The file name for reported problems is relative to the current working directory.
- "fileLocation": ["relative", "${cwd}"],
- // The actual pattern to match problems in the output.
- "pattern": {
- // The regular expression. Matches HelloWorld.ts(2,10): error TS2339: Property 'logg' does not exist on type 'Console'.
- "regexp": "^([^\\s].*)\\((\\d+|\\d+,\\d+|\\d+,\\d+,\\d+,\\d+)\\):\\s+(error|warning|info)\\s+(TS\\d+)\\s*:\\s*(.*)$",
- // The match group that denotes the file containing the problem.
- "file": 1,
- // The match group that denotes the problem location.
- "location": 2,
- // The match group that denotes the problem's severity. Can be omitted.
- "severity": 3,
- // The match group that denotes the problem code. Can be omitted.
- "code": 4,
- // The match group that denotes the problem's message.
- "message": 5
- }
- }
-}
-*/
\ No newline at end of file
+ // See http://code.visualstudio.com/docs/editor/tasks
+ // for the documentation about the tasks.json format
+ // Use IntelliSense to insert predefined task snippets
+ ts
+}
\ No newline at end of file
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 baab42c50f2..d81bc16384d 100644
--- a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts
+++ b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts
@@ -39,10 +39,13 @@ import { IConfigurationService, ConfigurationServiceEventTypes } from 'vs/platfo
import { IFileService, FileChangesEvent, FileChangeType, EventType as FileEventType } from 'vs/platform/files/common/files';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IPluginService } from 'vs/platform/plugins/common/plugins';
+import { IKeybindingService } from 'vs/platform/keybinding/common/keybindingService';
import { IModeService } from 'vs/editor/common/services/modeService';
import { IModelService } from 'vs/editor/common/services/modelService';
+import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
+
import jsonContributionRegistry = require('vs/platform/jsonschemas/common/jsonContributionRegistry');
import { IJSONSchema } from 'vs/base/common/jsonSchema';
@@ -148,11 +151,12 @@ class ConfigureTaskRunnerAction extends Action {
private contextService: IWorkspaceContextService;
private outputService: IOutputService;
private messageService: IMessageService;
+ private keybindingService: IKeybindingService
constructor(id: string, label: string, @IConfigurationService configurationService: IConfigurationService,
@IWorkbenchEditorService editorService: IWorkbenchEditorService, @IFileService fileService: IFileService,
@IWorkspaceContextService contextService: IWorkspaceContextService, @IOutputService outputService: IOutputService,
- @IMessageService messageService: IMessageService) {
+ @IMessageService messageService: IMessageService, @IKeybindingService keybindingService: IKeybindingService) {
super(id, label);
this.configurationService = configurationService;
@@ -161,11 +165,13 @@ class ConfigureTaskRunnerAction extends Action {
this.contextService = contextService;
this.outputService = outputService;
this.messageService = messageService;
+ this.keybindingService = keybindingService;
}
public run(event?:any): Promise {
let sideBySide = !!(event && (event.ctrlKey || event.metaKey));
let autoDetectFailed = false;
+ let fileCreated = false;
return this.fileService.resolveFile(this.contextService.toResource('.vscode/tasks.json')).then((success) => {
return success;
}, (err:any) => {
@@ -198,6 +204,7 @@ class ConfigureTaskRunnerAction extends Action {
});
}
return contentPromise.then((content) => {
+ fileCreated = true;
return this.fileService.createFile(this.contextService.toResource('.vscode/tasks.json'), content);
});
});
@@ -208,9 +215,19 @@ class ConfigureTaskRunnerAction extends Action {
options: {
forceOpen: true
}
- }, sideBySide).then((value) => {
+ }, sideBySide).then((editor) => {
+ if (fileCreated) {
+ let codeEditor: ICodeEditor = editor.getControl() as ICodeEditor;
+ let position = { lineNumber: 5, column: 4 };
+ codeEditor.revealPosition(position);
+ codeEditor.setPosition(position);
+ // Workaround for: https://github.com/Microsoft/vscode/issues/3121
+ setTimeout(() => {
+ this.keybindingService.executeCommand('editor.action.triggerSuggest');
+ }, 300);
+ }
this.outputService.showOutput(TaskService.OutputChannel, true);
- return value;
+ return editor;
});
}, (error) => {
throw new Error(nls.localize('ConfigureTaskRunnerAction.failed', "Unable to create the 'tasks.json' file inside the '.vscode' folder. Consult the task output for details."));
@@ -453,6 +470,7 @@ class TaskService extends EventEmitter implements ITaskService {
private eventService: IEventService;
private modelService: IModelService;
private pluginService: IPluginService;
+ private keybindingService: IKeybindingService;
private _taskSystemPromise: TPromise;
private _taskSystem: ITaskSystem;
@@ -467,7 +485,8 @@ class TaskService extends EventEmitter implements ITaskService {
@IFileService fileService:IFileService, @IWorkspaceContextService contextService: IWorkspaceContextService,
@ITelemetryService telemetryService: ITelemetryService, @ITextFileService textFileService:ITextFileService,
@ILifecycleService lifecycleService: ILifecycleService, @IEventService eventService: IEventService,
- @IModelService modelService: IModelService, @IPluginService pluginService: IPluginService) {
+ @IModelService modelService: IModelService, @IPluginService pluginService: IPluginService,
+ @IKeybindingService keybindingService: IKeybindingService) {
super();
this.modeService = modeService;
@@ -483,6 +502,7 @@ class TaskService extends EventEmitter implements ITaskService {
this.eventService = eventService;
this.modelService = modelService;
this.pluginService = pluginService;
+ this.keybindingService = keybindingService;
this.taskSystemListeners = [];
this.clearTaskSystemPromise = false;
@@ -621,7 +641,7 @@ class TaskService extends EventEmitter implements ITaskService {
public configureAction(): Action {
return new ConfigureTaskRunnerAction(ConfigureTaskRunnerAction.ID, ConfigureTaskRunnerAction.TEXT,
this.configurationService, this.editorService, this.fileService, this.contextService,
- this.outputService, this.messageService);
+ this.outputService, this.messageService, this.keybindingService);
}
public build(): TPromise {
@@ -750,7 +770,7 @@ class TaskService extends EventEmitter implements ITaskService {
if (needsConfig || needsTerminate) {
let closeAction = new CloseMessageAction();
let action = needsConfig
- ? new ConfigureTaskRunnerAction(ConfigureTaskRunnerAction.ID, ConfigureTaskRunnerAction.TEXT, this.configurationService, this.editorService, this.fileService, this.contextService, this.outputService, this.messageService)
+ ? this.configureAction()
: new TerminateAction(TerminateAction.ID, TerminateAction.TEXT, this, this.telemetryService);
closeAction.closeFunction = this.messageService.show(buildError.severity, { message: buildError.message, actions: [closeAction, action ] });