-
Notifications
You must be signed in to change notification settings - Fork 30.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add terminalGroup to tasks to allow running them in split panes #65973
Add terminalGroup to tasks to allow running them in split panes #65973
Conversation
src/vs/vscode.d.ts
Outdated
/** | ||
* Controls whether the task is executed in a specific terminal group using split panes. | ||
*/ | ||
terminalGroup?: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will need to go into vscode.proposed.d.ts. Once the API change has gone through our review process I'll move it to vscode.d.ts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made a comment on the request about this #47265 (comment), I'd like to be in the API call when it happens (I should be in the next one).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't even realize I was changing the API 😄 Moved it into vscode.proposed.d.ts
as requested.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried out this change with 2 tasks in terminal group
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See comments above.
Thank you for testing; I could reproduce the error. It was caused by me accidentally using |
// Search for any idle terminal used previously by a task of the same terminalGroup | ||
// (or, if the task has no terminalGroup, a terminal used by a task without terminalGroup). | ||
for (const taskId of this.idleTaskTerminals.keys()) { | ||
const idleTerminalId = this.idleTaskTerminals.get(taskId)!; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This loop needs to access both key and value of the idleTaskTerminals
LinkedMap. Maybe it is worth adding an entries(): [V, K][]
method to the LinkedMap class to avoid usage of the !
operator? WDYT?
https://github.com/Microsoft/vscode/blob/ac2c2922dc1ce64e694c0b6d024b68af42333020/src/vs/base/common/map.ts#L499
entries(): [V, K][] {
let result: [V, K][] = [];
let current = this._head;
while (current) {
result.push([current.value, current.key]);
current = current.next;
}
return result;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the idea but I can't justify it. I don't see that there would be a noticable performance gain with adding entries and in my opinion it wouldn't significantly improve the readability either.
src/vs/vscode.proposed.d.ts
Outdated
/** | ||
* Controls whether the task is executed in a specific terminal group using split panes. | ||
*/ | ||
terminalGroup?: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm leaning more towards calling this group
. That way we aren't tied to any specific presenter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@alexr00 I don't think you can call it group
. There's already a group
property for tasks. It's used to specify if the task is the default build task or default test task. I'm assuming they would conflict? See this link for details,
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"type": "typescript",
"tsconfig": "tsconfig.json",
"problemMatcher": [
"$tsc"
],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nevermind...I skimmed the PR and hadn't realized the "group" property was placed into "presentation"
. Ignore me. :D
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have now renamed terminalGroup
to just group
.
@cmfcmf, thanks for the updates! I should have more API feedback for you this week. |
Looks good to me! The API change is ok to merge into vscode.proposed.d.ts too. We will leave it there for a bit and make sure we don't want to make any changes to it before moving it to vscode.d.ts. @Tyriar do you have any feedback on the terminal changes before I merge? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm 👍
@cmfcmf I did some more testing before merging and I found another issue. My test tasks: {
"version": "2.0.0",
"tasks": [
{
"label": "Task A",
"type": "shell",
"command": "echo A && sleep 5000",
"problemMatcher": [],
"presentation": {
"group": "groupA"
}
},
{
"label": "Task B",
"type": "shell",
"command": "echo B",
"problemMatcher": [],
"presentation": {
"group": "groupA"
}
},
{
"label": "Task C",
"type": "shell",
"command": "echo C && sleep 5000",
"problemMatcher": [],
"presentation": {
"group": "groupC"
}
},
{
"label": "Task D",
"type": "shell",
"command": "echo D && sleep 5000",
"problemMatcher": [],
"presentation": {
"group": "groupC"
}
},
{
"label": "Task E",
"type": "shell",
"command": "echo E && sleep 5000",
"problemMatcher": []
},
{
"label": "Task F",
"type": "shell",
"command": "echo F && sleep 5000",
"problemMatcher": []
},
]
} I ran Task B. After it finished I left it's terminal open and ran Task A. Task A failed to run with a message about being unable to create a terminal. |
@alexr00 I'm afraid I can't reproduce the issue. I tried yours and a range of other possible combinations and it worked fine. |
…rminals if the terminal is not disposed
Good catch @alexr00! I forgot to test the trash can icon up until now and was able to reproduce the behavior and fix it in 708aa4c. This was actually a problem related to the existing code: When a terminal is killed / disposed using the trash icon, its id was still added to This implicitly avoided accessing disposed terminals. I, however, made the assumption that all ids referenced in if (this.terminals[idleTerminalId].group === group) { |
src/vs/workbench/parts/tasks/electron-browser/terminalTaskSystem.ts
Outdated
Show resolved
Hide resolved
Nice feature, thank you @cmfcmf! |
* Return splitted instance from ITerminalService::splitInstance * Add support for terminalGroup to tasks * Early-exit when the tab could not be split https://github.com/Microsoft/vscode/pull/65973/files/42e3171a71ae4b6963e47318fd289a66eb48a96a#r245762395 * Use .get()! instead of the unsupported [] to access LinkedMap * Move api changes into `vscode.proposed.d.ts` * Rename "terminalGroup" to "group" * Only keep references to terminals in sameTaskTerminals and idleTaskTerminals if the terminal is not disposed * Type result variable Fixes #47265
This is an implementation of #47265, which is currently assigned to @dbaeumer. It adds a new field
terminalGroup
to the presentation option of the.vscode/tasks.json
file. When supplied, all tasks of the sameterminalGroup
open as split panes in the same tab. Tasks withoutterminalGroup
are not allowed to reuse terminals created by tasks which have aterminalGroup
.I haven't written tests yet, but can add them if you think the general direction of this PR is fine.
Example `tasks.json`