VS 代码扩展:所有定义的任务都使用 vscode.CustomExecution return 最后定义任务的结果
VS Code Extension: All defined tasks using vscode.CustomExecution return result of last defined task
进入
我创建了一个简单的 VS 代码扩展,它定义了多个任务:
ExamplePseudoterminal1 Task 1, ExamplePseudoterminal1 Task 2, ExamplePseudoterminal1 Task 3
ExamplePseudoterminal2 Task 1, ExamplePseudoterminal2 Task 2, ExamplePseudoterminal2 Task 3
ExamplePseudoterminal1 Task <number>
任务接受一个参数 <number>
并在终端上打印出 <number>
。
ExamplePseudoterminal2 Task <number>
任务接收参数 <number>
并向终端打印 2 *<number>
。
问题
当我运行一个任务(Terminal -> Run Task... -> "MyTask"
)时,上面列出的所有任务都显示出来了。
但是,every 其中一项任务的结果是最后添加的任务(即 ExamplePseudoterminal2 Task 3
-> 6
).
我做错了什么?
我忘记了什么吗?
示例代码
>>> yo code
? What type of extension do you want to create? New Extension (TypeScript)
? What's the name of your extension? ExampleExt
? What's the identifier of your extension? exampleext
? What's the description of your extension? Example extension
? Initialize a git repository? No
? Bundle the source code with webpack? No
? Which package manager to use? npm
更改的文件:
src/extension.ts
import * as vscode from 'vscode';
export function activate(context: vscode.ExtensionContext) {
console.log('Congratulations, your extension "exampleext" is now active!');
const use_type: string = "MyTask"
const myTask_TaskProvider: vscode.Disposable = vscode.tasks.registerTaskProvider(use_type, {
provideTasks(token?: vscode.CancellationToken) {
const output_taks: vscode.Task[] = [];
const use_type: string = "MyTask"
for (const entry of [1, 2, 3]){
console.log(`Processing ${entry}`);
const new_task_1: vscode.Task = new vscode.Task(
{type: use_type}, vscode.TaskScope.Workspace,
`ExamplePseudoterminal1 Task ${entry}`, use_type,
new vscode.CustomExecution(
async function(resolvedDefinition: vscode.TaskDefinition): Promise<vscode.Pseudoterminal> {
return new ExamplePseudoterminal1(entry);
}),
[""]
);
output_taks.push(new_task_1);
const new_task_2: vscode.Task = new vscode.Task(
{type: use_type}, vscode.TaskScope.Workspace,
`ExamplePseudoterminal2 Task ${entry}`, use_type,
new vscode.CustomExecution(
async function(resolvedDefinition: vscode.TaskDefinition): Promise<vscode.Pseudoterminal> {
return new ExamplePseudoterminal2(entry);
}),
[""]
);
output_taks.push(new_task_2);
}
return output_taks;
},
resolveTask(task: vscode.Task, token?: vscode.CancellationToken) {
return task;
}
});
context.subscriptions.push(myTask_TaskProvider);
}
export function deactivate() {
}
class ExamplePseudoterminal1 implements vscode.Pseudoterminal {
private readonly writeEmitter = new vscode.EventEmitter<string>();
public onDidWrite: vscode.Event<string> = this.writeEmitter.event;
private readonly closeEmitter = new vscode.EventEmitter<void>();
public onDidClose?: vscode.Event<void> = this.closeEmitter.event;
private value: number;
public constructor(in_number: number) {
this.value = in_number;
console.log(`this.value: ${this.value}`);
}
public open(initialDimensions: vscode.TerminalDimensions | undefined) {
console.log("open");
this.writeEmitter.fire(`${this.value}`);
this.closeEmitter.fire();
}
close(): void {
console.log("close");
}
}
class ExamplePseudoterminal2 implements vscode.Pseudoterminal {
private readonly writeEmitter = new vscode.EventEmitter<string>();
public onDidWrite: vscode.Event<string> = this.writeEmitter.event;
private readonly closeEmitter = new vscode.EventEmitter<void>();
public onDidClose?: vscode.Event<void> = this.closeEmitter.event;
private value: number;
public constructor(in_number: number) {
this.value = in_number * 2;
console.log(`this.value: ${this.value}`);
}
public open(initialDimensions: vscode.TerminalDimensions | undefined) {
console.log("open");
this.writeEmitter.fire(`${this.value}`);
this.closeEmitter.fire();
}
close(): void {
console.log("close");
}
}
包-lock.json
{
"name": "exampleext",
"displayName": "ExampleExt",
"description": "Example extension",
"version": "0.0.1",
"engines": {
"vscode": "^1.46.0"
},
"categories": [
"Other"
],
"activationEvents": [
"onCommand:workbench.action.tasks.runTask"
],
"main": "./out/extension.js",
"contributes": {
"taskDefinitions": [
{
"type": "MyTask"
}
]
},
"scripts": {
"vscode:prepublish": "npm run compile",
"compile": "tsc -p ./",
"watch": "tsc -watch -p ./",
"pretest": "npm run compile && npm run lint",
"lint": "eslint src --ext ts",
"test": "node ./out/test/runTest.js"
},
"devDependencies": {
"@types/glob": "^7.1.3",
"@types/mocha": "^8.0.4",
"@types/node": "^12.11.7",
"@types/vscode": "^1.46.0",
"@typescript-eslint/eslint-plugin": "^4.14.1",
"@typescript-eslint/parser": "^4.14.1",
"eslint": "^7.19.0",
"glob": "^7.1.6",
"mocha": "^8.2.1",
"typescript": "^4.1.3",
"vscode-test": "^1.5.0"
}
}
系统
- VS 代码版本:1.55.1
- VS 代码提交:08a217c4d27a02a5bcde898fd7981bda5b49391b
- Node.js: 12.18.3
- OS: macOS 11.2.3
基于 github: microsoft/vscode-extension-samples 示例的解决方案。
这使用了 vscode.TaskProvider
的更完整定义。重要的部分似乎是:interface CustomBuildTaskDefinition extends vscode.TaskDefinition
和 package.json
中的完整 taskDefinitions
。
src/extension.ts
import * as vscode from 'vscode';
export function activate(context: vscode.ExtensionContext) {
console.log('Congratulations, your extension "exampleext" is now active!');
const myTask_TaskProvider: vscode.Disposable = vscode.tasks.registerTaskProvider(
CustomBuildTaskProvider.TaskType, new CustomBuildTaskProvider()
);
context.subscriptions.push(myTask_TaskProvider)
}
export function deactivate() {
}
interface CustomBuildTaskDefinition extends vscode.TaskDefinition {
number: number;
}
export class CustomBuildTaskProvider implements vscode.TaskProvider {
static TaskType = 'custombuildscript';
private tasks: vscode.Task[] | undefined;
constructor() { }
public async provideTasks(): Promise<vscode.Task[]> {
return this.getTasks();
}
public resolveTask(_task: vscode.Task): vscode.Task | undefined {
const type: string = _task.definition.type;
if (type === CustomBuildTaskProvider.TaskType) {
const definition: CustomBuildTaskDefinition = <any>_task.definition;
return this.getTask(definition);
}
return undefined;
}
private getTasks(): vscode.Task[] {
if (this.tasks !== undefined) {
return this.tasks;
}
const in_values: number[] = [1, 2, 3];
this.tasks = [];
in_values.forEach(value => {
const active_def: CustomBuildTaskDefinition = {
type: CustomBuildTaskProvider.TaskType,
number: value
}
this.tasks!.push(this.getTask(active_def));
});
return this.tasks;
}
private getTask(definition: CustomBuildTaskDefinition): vscode.Task {
return new vscode.Task(
definition,
vscode.TaskScope.Workspace,
`TestTask ${definition.number}`,
definition.type, new vscode.CustomExecution(
async (): Promise<vscode.Pseudoterminal> => {
return new ExamplePseudoterminal1(definition.number);
}
),
[""]
);
}
}
class ExamplePseudoterminal1 implements vscode.Pseudoterminal {
private readonly writeEmitter = new vscode.EventEmitter<string>();
public onDidWrite: vscode.Event<string> = this.writeEmitter.event;
private readonly closeEmitter = new vscode.EventEmitter<void>();
public onDidClose?: vscode.Event<void> = this.closeEmitter.event;
private value: number;
public constructor(in_number: number) {
this.value = in_number;
console.log(`this.value: ${this.value}`);
}
public open(initialDimensions: vscode.TerminalDimensions | undefined) {
console.log("open");
this.writeEmitter.fire(`${this.value}`);
this.closeEmitter.fire();
}
close(): void {
console.log("close");
}
}
包-lock.json
{
"name": "exampleext",
"displayName": "ExampleExt",
"description": "Example extension",
"version": "0.0.1",
"engines": {
"vscode": "^1.46.0"
},
"categories": [
"Other"
],
"activationEvents": [
"onCommand:workbench.action.tasks.runTask"
],
"main": "./out/extension.js",
"contributes": {
"taskDefinitions": [
{
"type": "MyTask",
<< -- Complete (and matching) definition ----------- >>
"required": ["number"],
"properties": {
"number": {
"type": "number",
"description": "Input number"
}
}
<< --------------------------------------------------- >>
}
]
},
"scripts": {
"vscode:prepublish": "npm run compile",
"compile": "tsc -p ./",
"watch": "tsc -watch -p ./",
"pretest": "npm run compile && npm run lint",
"lint": "eslint src --ext ts",
"test": "node ./out/test/runTest.js"
},
"devDependencies": {
"@types/glob": "^7.1.3",
"@types/mocha": "^8.0.4",
"@types/node": "^12.11.7",
"@types/vscode": "^1.46.0",
"@typescript-eslint/eslint-plugin": "^4.14.1",
"@typescript-eslint/parser": "^4.14.1",
"eslint": "^7.19.0",
"glob": "^7.1.6",
"mocha": "^8.2.1",
"typescript": "^4.1.3",
"vscode-test": "^1.5.0"
}
}
进入
我创建了一个简单的 VS 代码扩展,它定义了多个任务:
ExamplePseudoterminal1 Task 1, ExamplePseudoterminal1 Task 2, ExamplePseudoterminal1 Task 3
ExamplePseudoterminal2 Task 1, ExamplePseudoterminal2 Task 2, ExamplePseudoterminal2 Task 3
ExamplePseudoterminal1 Task <number>
任务接受一个参数 <number>
并在终端上打印出 <number>
。
ExamplePseudoterminal2 Task <number>
任务接收参数 <number>
并向终端打印 2 *<number>
。
问题
当我运行一个任务(Terminal -> Run Task... -> "MyTask"
)时,上面列出的所有任务都显示出来了。
但是,every 其中一项任务的结果是最后添加的任务(即 ExamplePseudoterminal2 Task 3
-> 6
).
我做错了什么?
我忘记了什么吗?
示例代码
>>> yo code
? What type of extension do you want to create? New Extension (TypeScript)
? What's the name of your extension? ExampleExt
? What's the identifier of your extension? exampleext
? What's the description of your extension? Example extension
? Initialize a git repository? No
? Bundle the source code with webpack? No
? Which package manager to use? npm
更改的文件:
src/extension.ts
import * as vscode from 'vscode';
export function activate(context: vscode.ExtensionContext) {
console.log('Congratulations, your extension "exampleext" is now active!');
const use_type: string = "MyTask"
const myTask_TaskProvider: vscode.Disposable = vscode.tasks.registerTaskProvider(use_type, {
provideTasks(token?: vscode.CancellationToken) {
const output_taks: vscode.Task[] = [];
const use_type: string = "MyTask"
for (const entry of [1, 2, 3]){
console.log(`Processing ${entry}`);
const new_task_1: vscode.Task = new vscode.Task(
{type: use_type}, vscode.TaskScope.Workspace,
`ExamplePseudoterminal1 Task ${entry}`, use_type,
new vscode.CustomExecution(
async function(resolvedDefinition: vscode.TaskDefinition): Promise<vscode.Pseudoterminal> {
return new ExamplePseudoterminal1(entry);
}),
[""]
);
output_taks.push(new_task_1);
const new_task_2: vscode.Task = new vscode.Task(
{type: use_type}, vscode.TaskScope.Workspace,
`ExamplePseudoterminal2 Task ${entry}`, use_type,
new vscode.CustomExecution(
async function(resolvedDefinition: vscode.TaskDefinition): Promise<vscode.Pseudoterminal> {
return new ExamplePseudoterminal2(entry);
}),
[""]
);
output_taks.push(new_task_2);
}
return output_taks;
},
resolveTask(task: vscode.Task, token?: vscode.CancellationToken) {
return task;
}
});
context.subscriptions.push(myTask_TaskProvider);
}
export function deactivate() {
}
class ExamplePseudoterminal1 implements vscode.Pseudoterminal {
private readonly writeEmitter = new vscode.EventEmitter<string>();
public onDidWrite: vscode.Event<string> = this.writeEmitter.event;
private readonly closeEmitter = new vscode.EventEmitter<void>();
public onDidClose?: vscode.Event<void> = this.closeEmitter.event;
private value: number;
public constructor(in_number: number) {
this.value = in_number;
console.log(`this.value: ${this.value}`);
}
public open(initialDimensions: vscode.TerminalDimensions | undefined) {
console.log("open");
this.writeEmitter.fire(`${this.value}`);
this.closeEmitter.fire();
}
close(): void {
console.log("close");
}
}
class ExamplePseudoterminal2 implements vscode.Pseudoterminal {
private readonly writeEmitter = new vscode.EventEmitter<string>();
public onDidWrite: vscode.Event<string> = this.writeEmitter.event;
private readonly closeEmitter = new vscode.EventEmitter<void>();
public onDidClose?: vscode.Event<void> = this.closeEmitter.event;
private value: number;
public constructor(in_number: number) {
this.value = in_number * 2;
console.log(`this.value: ${this.value}`);
}
public open(initialDimensions: vscode.TerminalDimensions | undefined) {
console.log("open");
this.writeEmitter.fire(`${this.value}`);
this.closeEmitter.fire();
}
close(): void {
console.log("close");
}
}
包-lock.json
{
"name": "exampleext",
"displayName": "ExampleExt",
"description": "Example extension",
"version": "0.0.1",
"engines": {
"vscode": "^1.46.0"
},
"categories": [
"Other"
],
"activationEvents": [
"onCommand:workbench.action.tasks.runTask"
],
"main": "./out/extension.js",
"contributes": {
"taskDefinitions": [
{
"type": "MyTask"
}
]
},
"scripts": {
"vscode:prepublish": "npm run compile",
"compile": "tsc -p ./",
"watch": "tsc -watch -p ./",
"pretest": "npm run compile && npm run lint",
"lint": "eslint src --ext ts",
"test": "node ./out/test/runTest.js"
},
"devDependencies": {
"@types/glob": "^7.1.3",
"@types/mocha": "^8.0.4",
"@types/node": "^12.11.7",
"@types/vscode": "^1.46.0",
"@typescript-eslint/eslint-plugin": "^4.14.1",
"@typescript-eslint/parser": "^4.14.1",
"eslint": "^7.19.0",
"glob": "^7.1.6",
"mocha": "^8.2.1",
"typescript": "^4.1.3",
"vscode-test": "^1.5.0"
}
}
系统
- VS 代码版本:1.55.1
- VS 代码提交:08a217c4d27a02a5bcde898fd7981bda5b49391b
- Node.js: 12.18.3
- OS: macOS 11.2.3
基于 github: microsoft/vscode-extension-samples 示例的解决方案。
这使用了 vscode.TaskProvider
的更完整定义。重要的部分似乎是:interface CustomBuildTaskDefinition extends vscode.TaskDefinition
和 package.json
中的完整 taskDefinitions
。
src/extension.ts
import * as vscode from 'vscode';
export function activate(context: vscode.ExtensionContext) {
console.log('Congratulations, your extension "exampleext" is now active!');
const myTask_TaskProvider: vscode.Disposable = vscode.tasks.registerTaskProvider(
CustomBuildTaskProvider.TaskType, new CustomBuildTaskProvider()
);
context.subscriptions.push(myTask_TaskProvider)
}
export function deactivate() {
}
interface CustomBuildTaskDefinition extends vscode.TaskDefinition {
number: number;
}
export class CustomBuildTaskProvider implements vscode.TaskProvider {
static TaskType = 'custombuildscript';
private tasks: vscode.Task[] | undefined;
constructor() { }
public async provideTasks(): Promise<vscode.Task[]> {
return this.getTasks();
}
public resolveTask(_task: vscode.Task): vscode.Task | undefined {
const type: string = _task.definition.type;
if (type === CustomBuildTaskProvider.TaskType) {
const definition: CustomBuildTaskDefinition = <any>_task.definition;
return this.getTask(definition);
}
return undefined;
}
private getTasks(): vscode.Task[] {
if (this.tasks !== undefined) {
return this.tasks;
}
const in_values: number[] = [1, 2, 3];
this.tasks = [];
in_values.forEach(value => {
const active_def: CustomBuildTaskDefinition = {
type: CustomBuildTaskProvider.TaskType,
number: value
}
this.tasks!.push(this.getTask(active_def));
});
return this.tasks;
}
private getTask(definition: CustomBuildTaskDefinition): vscode.Task {
return new vscode.Task(
definition,
vscode.TaskScope.Workspace,
`TestTask ${definition.number}`,
definition.type, new vscode.CustomExecution(
async (): Promise<vscode.Pseudoterminal> => {
return new ExamplePseudoterminal1(definition.number);
}
),
[""]
);
}
}
class ExamplePseudoterminal1 implements vscode.Pseudoterminal {
private readonly writeEmitter = new vscode.EventEmitter<string>();
public onDidWrite: vscode.Event<string> = this.writeEmitter.event;
private readonly closeEmitter = new vscode.EventEmitter<void>();
public onDidClose?: vscode.Event<void> = this.closeEmitter.event;
private value: number;
public constructor(in_number: number) {
this.value = in_number;
console.log(`this.value: ${this.value}`);
}
public open(initialDimensions: vscode.TerminalDimensions | undefined) {
console.log("open");
this.writeEmitter.fire(`${this.value}`);
this.closeEmitter.fire();
}
close(): void {
console.log("close");
}
}
包-lock.json
{
"name": "exampleext",
"displayName": "ExampleExt",
"description": "Example extension",
"version": "0.0.1",
"engines": {
"vscode": "^1.46.0"
},
"categories": [
"Other"
],
"activationEvents": [
"onCommand:workbench.action.tasks.runTask"
],
"main": "./out/extension.js",
"contributes": {
"taskDefinitions": [
{
"type": "MyTask",
<< -- Complete (and matching) definition ----------- >>
"required": ["number"],
"properties": {
"number": {
"type": "number",
"description": "Input number"
}
}
<< --------------------------------------------------- >>
}
]
},
"scripts": {
"vscode:prepublish": "npm run compile",
"compile": "tsc -p ./",
"watch": "tsc -watch -p ./",
"pretest": "npm run compile && npm run lint",
"lint": "eslint src --ext ts",
"test": "node ./out/test/runTest.js"
},
"devDependencies": {
"@types/glob": "^7.1.3",
"@types/mocha": "^8.0.4",
"@types/node": "^12.11.7",
"@types/vscode": "^1.46.0",
"@typescript-eslint/eslint-plugin": "^4.14.1",
"@typescript-eslint/parser": "^4.14.1",
"eslint": "^7.19.0",
"glob": "^7.1.6",
"mocha": "^8.2.1",
"typescript": "^4.1.3",
"vscode-test": "^1.5.0"
}
}