Skip to content

Commit e07de5b

Browse files
committed
support debuging more than one extension; fixes microsoft#71081
1 parent 0bce369 commit e07de5b

17 files changed

Lines changed: 173 additions & 38 deletions

File tree

src/bootstrap-window.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,16 @@ exports.load = function (modulePaths, resultCallback, options) {
3030
const path = require('path');
3131

3232
const args = parseURLQueryArgs();
33+
/**
34+
* // configuration: IWindowConfiguration
35+
* @type {{
36+
* zoomLevel?: number,
37+
* extensionDevelopmentPath?: string | string[],
38+
* extensionTestsPath?: string,
39+
* userEnv?: { [key: string]: string | undefined },
40+
* appRoot?: string,
41+
* nodeCachedDataDir?: string
42+
* }} */
3343
const configuration = JSON.parse(args['config'] || '{}') || {};
3444

3545
// Apply zoom level early to avoid glitches

src/vs/code/electron-browser/workbench/workbench.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,14 @@ bootstrapWindow.load([
4949
});
5050

5151
/**
52-
* @param {object} configuration
52+
* // configuration: IWindowConfiguration
53+
* @param {{
54+
* partsSplashPath?: string,
55+
* highContrast?: boolean,
56+
* extensionDevelopmentPath?: string | string[],
57+
* folderUri?: object,
58+
* workspace?: object
59+
* }} configuration
5360
*/
5461
function showPartsSplash(configuration) {
5562
perf.mark('willShowPartsSplash');

src/vs/code/electron-main/window.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import { endsWith } from 'vs/base/common/strings';
3030

3131
export interface IWindowCreationOptions {
3232
state: IWindowState;
33-
extensionDevelopmentPath?: string;
33+
extensionDevelopmentPath?: string | string[];
3434
isExtensionTestHost?: boolean;
3535
}
3636

@@ -217,9 +217,11 @@ export class CodeWindow extends Disposable implements ICodeWindow {
217217
return !!this.config.extensionTestsPath;
218218
}
219219

220-
get extensionDevelopmentPath(): string | undefined {
220+
/*
221+
get extensionDevelopmentPaths(): string | string[] | undefined {
221222
return this.config.extensionDevelopmentPath;
222223
}
224+
*/
223225

224226
get config(): IWindowConfiguration {
225227
return this.currentConfig;

src/vs/code/electron-main/windows.ts

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1153,7 +1153,7 @@ export class WindowsManager implements IWindowsMainService {
11531153
return { openFolderInNewWindow: !!openFolderInNewWindow, openFilesInNewWindow };
11541154
}
11551155

1156-
openExtensionDevelopmentHostWindow(extensionDevelopmentPath: string, openConfig: IOpenConfiguration): void {
1156+
openExtensionDevelopmentHostWindow(extensionDevelopmentPath: string | string[], openConfig: IOpenConfiguration): void {
11571157

11581158
// Reload an existing extension development host window on the same path
11591159
// We currently do not allow more than one extension development window
@@ -1207,9 +1207,30 @@ export class WindowsManager implements IWindowsMainService {
12071207
openConfig.cli['folder-uri'] = folderUris;
12081208
openConfig.cli['file-uri'] = fileUris;
12091209

1210-
const match = extensionDevelopmentPath.match(/^vscode-remote:\/\/([^\/]+)/);
1211-
if (match) {
1212-
openConfig.cli['remote'] = URI.parse(extensionDevelopmentPath).authority;
1210+
if (Array.isArray(extensionDevelopmentPath)) {
1211+
let authority: string | undefined = undefined;
1212+
for (let p of extensionDevelopmentPath) {
1213+
const match = p.match(/^vscode-remote:\/\/([^\/]+)/);
1214+
if (match) {
1215+
const auth = URI.parse(p).authority;
1216+
if (authority) {
1217+
if (auth !== authority) {
1218+
console.log('more than one authority');
1219+
}
1220+
} else {
1221+
authority = auth;
1222+
}
1223+
}
1224+
}
1225+
if (authority) {
1226+
openConfig.cli['remote'] = authority;
1227+
}
1228+
1229+
} else {
1230+
const match = extensionDevelopmentPath.match(/^vscode-remote:\/\/([^\/]+)/);
1231+
if (match) {
1232+
openConfig.cli['remote'] = URI.parse(extensionDevelopmentPath).authority;
1233+
}
12131234
}
12141235

12151236
// Open it

src/vs/code/node/windowsFinder.ts

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export interface ISimpleWindow {
1414
openedWorkspace?: IWorkspaceIdentifier;
1515
openedFolderUri?: URI;
1616

17-
extensionDevelopmentPath?: string;
17+
extensionDevelopmentPath?: string | string[];
1818
lastFocusTime: number;
1919
}
2020

@@ -95,13 +95,33 @@ export function findWindowOnWorkspace<W extends ISimpleWindow>(windows: W[], wor
9595
return null;
9696
}
9797

98-
export function findWindowOnExtensionDevelopmentPath<W extends ISimpleWindow>(windows: W[], extensionDevelopmentPath: string): W | null {
98+
export function findWindowOnExtensionDevelopmentPath<W extends ISimpleWindow>(windows: W[], extensionDevelopmentPath: string | string[]): W | null {
99+
100+
const matches = (uriString: string): boolean => {
101+
if (Array.isArray(extensionDevelopmentPath)) {
102+
return extensionDevelopmentPath.some(p => extpath.isEqual(p, uriString, !platform.isLinux /* ignorecase */));
103+
} else if (extensionDevelopmentPath) {
104+
return extpath.isEqual(extensionDevelopmentPath, uriString, !platform.isLinux /* ignorecase */);
105+
}
106+
return false;
107+
};
108+
99109
for (const window of windows) {
100-
// match on extension development path. The path can be a path or uri string, using paths.isEqual is not 100% correct but good enough
101-
if (window.extensionDevelopmentPath && extpath.isEqual(window.extensionDevelopmentPath, extensionDevelopmentPath, !platform.isLinux /* ignorecase */)) {
102-
return window;
110+
// match on extension development path. The path can be one or more paths or uri strings, using paths.isEqual is not 100% correct but good enough
111+
112+
if (window.extensionDevelopmentPath) {
113+
if (Array.isArray(window.extensionDevelopmentPath)) {
114+
if (window.extensionDevelopmentPath.some(p => matches(p))) {
115+
return window;
116+
}
117+
} else if (window.extensionDevelopmentPath) {
118+
if (matches(window.extensionDevelopmentPath)) {
119+
return window;
120+
}
121+
}
103122
}
104123
}
124+
105125
return null;
106126
}
107127

src/vs/platform/environment/common/environment.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export interface ParsedArgs {
3737
logExtensionHostCommunication?: boolean;
3838
'extensions-dir'?: string;
3939
'builtin-extensions-dir'?: string;
40-
extensionDevelopmentPath?: string; // either a local path or a URI
40+
extensionDevelopmentPath?: string | string[]; // one or more local paths or URIs
4141
extensionTestsPath?: string; // either a local path or a URI
4242
'inspect-extensions'?: string;
4343
'inspect-brk-extensions'?: string;
@@ -116,7 +116,7 @@ export interface IEnvironmentService {
116116
disableExtensions: boolean | string[];
117117
builtinExtensionsPath: string;
118118
extensionsPath: string;
119-
extensionDevelopmentLocationURI?: URI;
119+
extensionDevelopmentLocationURI?: URI | URI[];
120120
extensionTestsLocationURI?: URI;
121121

122122
debugExtensionHost: IExtensionHostDebugParams;

src/vs/platform/environment/node/environmentService.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,16 @@ export class EnvironmentService implements IEnvironmentService {
172172
}
173173

174174
@memoize
175-
get extensionDevelopmentLocationURI(): URI | undefined {
175+
get extensionDevelopmentLocationURI(): URI | URI[] | undefined {
176176
const s = this._args.extensionDevelopmentPath;
177-
if (s) {
177+
if (Array.isArray(s)) {
178+
return s.map(p => {
179+
if (/^[^:/?#]+?:\/\//.test(p)) {
180+
return URI.parse(p);
181+
}
182+
return URI.file(path.normalize(p));
183+
});
184+
} else if (s) {
178185
if (/^[^:/?#]+?:\/\//.test(s)) {
179186
return URI.parse(s);
180187
}

src/vs/platform/windows/electron-main/windows.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ export interface IWindowsMainService {
9797
enterWorkspace(win: ICodeWindow, path: URI): Promise<IEnterWorkspaceResult | undefined>;
9898
closeWorkspace(win: ICodeWindow): void;
9999
open(openConfig: IOpenConfiguration): ICodeWindow[];
100-
openExtensionDevelopmentHostWindow(extensionDevelopmentPath: string, openConfig: IOpenConfiguration): void;
100+
openExtensionDevelopmentHostWindow(extensionDevelopmentPath: string | string[], openConfig: IOpenConfiguration): void;
101101
pickFileFolderAndOpen(options: INativeOpenDialogOptions): Promise<void>;
102102
pickFolderAndOpen(options: INativeOpenDialogOptions): Promise<void>;
103103
pickFileAndOpen(options: INativeOpenDialogOptions): Promise<void>;

src/vs/workbench/api/common/extHost.protocol.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export interface IEnvironment {
5151
isExtensionDevelopmentDebug: boolean;
5252
appRoot?: URI;
5353
appSettingsHome?: URI;
54-
extensionDevelopmentLocationURI?: URI;
54+
extensionDevelopmentLocationURI?: URI | URI[];
5555
extensionTestsLocationURI?: URI;
5656
globalStorageHome: URI;
5757
userHome: URI;

src/vs/workbench/browser/nodeless.simpleservices.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ export class SimpleEnvironmentService implements IEnvironmentService {
251251
disableExtensions: boolean | string[];
252252
builtinExtensionsPath: string;
253253
extensionsPath: string;
254-
extensionDevelopmentLocationURI?: URI;
254+
extensionDevelopmentLocationURI?: URI | URI[];
255255
extensionTestsPath?: string;
256256
debugExtensionHost: IExtensionHostDebugParams;
257257
debugSearch: IDebugParams;

0 commit comments

Comments
 (0)