Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/src/extension/onboardDebug/vscode-node/copilotDebugCommandSession.ts
13399 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import * as l10n from '@vscode/l10n';
7
import * as vscode from 'vscode';
8
import { DisposableStore } from '../../../util/vs/base/common/lifecycle';
9
import { generateUuid } from '../../../util/vs/base/common/uuid';
10
import { ILaunchConfigService } from '../common/launchConfigService';
11
import { IStartOptions } from '../node/copilotDebugWorker/shared';
12
import { CopilotDebugCommandHandle } from './copilotDebugCommandHandle';
13
14
const TRACKED_SESSION_KEY = '__copilotTrackedSession';
15
16
export const handleDebugSession = (
17
launchConfigService: ILaunchConfigService,
18
workspaceFolder: vscode.WorkspaceFolder | undefined,
19
config: vscode.DebugConfiguration,
20
handle: CopilotDebugCommandHandle,
21
once: boolean,
22
startAgain: (opts: Partial<IStartOptions>) => Promise<void>,
23
) => {
24
const trackedId = generateUuid();
25
const store = new DisposableStore();
26
27
let gotRoot = false;
28
const sessions = new Set<vscode.DebugSession>();
29
30
async function ended(code: number, message?: string) {
31
if (store.isDisposed) {
32
return;
33
}
34
35
let color: 'red' | 'blue';
36
37
if (code !== 0) {
38
color = 'red';
39
message ??= l10n.t('Debug session errored');
40
} else {
41
color = 'blue';
42
message ??= l10n.t('Session ended');
43
}
44
45
handle.printLabel(color, message);
46
store.dispose();
47
followup();
48
}
49
50
async function followup() {
51
switch (once ? 'Q' : await handle.getFollowupKeys(CopilotDebugCommandHandle.COPILOT_LABEL.length + 3)) {
52
case 'Enter':
53
handleDebugSession(launchConfigService, workspaceFolder, config, handle, once, startAgain);
54
break;
55
case 'R':
56
startAgain({ forceNew: true });
57
break;
58
case 'S':
59
await launchConfigService.add(workspaceFolder?.uri, { configurations: [config] });
60
if (workspaceFolder) {
61
await launchConfigService.show(workspaceFolder.uri, config.name);
62
}
63
handle.exit(0);
64
break;
65
case 'V':
66
await handle.printJson(config);
67
followup();
68
break;
69
case 'Q':
70
default:
71
handle.exit(0);
72
}
73
}
74
75
handle.ended.then(() => {
76
if (!store.isDisposed) {
77
sessions.forEach(s => vscode.debug.stopDebugging(s));
78
}
79
});
80
81
store.add(vscode.debug.registerDebugAdapterTrackerFactory('*', {
82
createDebugAdapterTracker(session) {
83
if (session.configuration[TRACKED_SESSION_KEY] !== trackedId && (!session.parentSession || !sessions.has(session.parentSession))) {
84
return;
85
}
86
87
// handle nested sessions:
88
const isRoot = !gotRoot;
89
gotRoot = true;
90
sessions.add(session);
91
92
return {
93
onWillStartSession() {
94
if (isRoot) {
95
handle.printLabel('blue', l10n.t('Debug session starting...'));
96
}
97
},
98
onDidSendMessage(message) {
99
if (message.type === 'event' && message.event === 'output' && message.body.output) {
100
handle.output(message.body.category, message.body.output);
101
}
102
},
103
onExit(code, signal) {
104
if (isRoot) {
105
ended(code ?? 0, signal);
106
}
107
},
108
onWillStopSession() {
109
if (isRoot) {
110
ended(0);
111
}
112
},
113
};
114
},
115
}));
116
117
vscode.debug.startDebugging(workspaceFolder, { ...config, [TRACKED_SESSION_KEY]: trackedId }).then(ok => {
118
if (!ok) {
119
// error will be displayed to user by vscode
120
ended(1);
121
}
122
});
123
};
124
125