提交 b1a66b59 编写于 作者: I isidor

debug: dynamic launch configurations should be stored properly

fixes #96293
上级 89a2e78f
...@@ -11,7 +11,7 @@ import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; ...@@ -11,7 +11,7 @@ import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { SelectBox, ISelectOptionItem } from 'vs/base/browser/ui/selectBox/selectBox'; import { SelectBox, ISelectOptionItem } from 'vs/base/browser/ui/selectBox/selectBox';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ICommandService } from 'vs/platform/commands/common/commands'; import { ICommandService } from 'vs/platform/commands/common/commands';
import { IDebugService, IDebugSession, IDebugConfiguration, IConfig, ILaunch } from 'vs/workbench/contrib/debug/common/debug'; import { IDebugService, IDebugSession, IDebugConfiguration, IConfig, ILaunch, IDebugConfigurationProvider } from 'vs/workbench/contrib/debug/common/debug';
import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IThemeService } from 'vs/platform/theme/common/themeService';
import { attachSelectBoxStyler, attachStylerCallback } from 'vs/platform/theme/common/styler'; import { attachSelectBoxStyler, attachStylerCallback } from 'vs/platform/theme/common/styler';
import { selectBorder, selectBackground } from 'vs/platform/theme/common/colorRegistry'; import { selectBorder, selectBackground } from 'vs/platform/theme/common/colorRegistry';
...@@ -34,7 +34,7 @@ export class StartDebugActionViewItem implements IActionViewItem { ...@@ -34,7 +34,7 @@ export class StartDebugActionViewItem implements IActionViewItem {
private options: { label: string, handler: (() => Promise<boolean>) }[] = []; private options: { label: string, handler: (() => Promise<boolean>) }[] = [];
private toDispose: IDisposable[]; private toDispose: IDisposable[];
private selected = 0; private selected = 0;
private providers: { label: string, pick: () => Promise<{ launch: ILaunch, config: IConfig } | undefined> }[] = []; private providers: { label: string, provider: IDebugConfigurationProvider, pick: () => Promise<{ launch: ILaunch, config: IConfig } | undefined> }[] = [];
constructor( constructor(
private context: unknown, private context: unknown,
...@@ -182,7 +182,7 @@ export class StartDebugActionViewItem implements IActionViewItem { ...@@ -182,7 +182,7 @@ export class StartDebugActionViewItem implements IActionViewItem {
const label = inWorkspace ? `${name} (${launch.name})` : name; const label = inWorkspace ? `${name} (${launch.name})` : name;
this.options.push({ this.options.push({
label, handler: async () => { label, handler: async () => {
manager.selectConfiguration(launch, name); await manager.selectConfiguration(launch, name);
return true; return true;
} }
}); });
...@@ -196,7 +196,7 @@ export class StartDebugActionViewItem implements IActionViewItem { ...@@ -196,7 +196,7 @@ export class StartDebugActionViewItem implements IActionViewItem {
} }
this.providers.forEach(p => { this.providers.forEach(p => {
if (p.label === manager.selectedConfiguration.name) { if (p.provider.type === manager.selectedConfiguration.config?.type) {
this.selected = this.options.length; this.selected = this.options.length;
} }
...@@ -204,7 +204,7 @@ export class StartDebugActionViewItem implements IActionViewItem { ...@@ -204,7 +204,7 @@ export class StartDebugActionViewItem implements IActionViewItem {
label: `${p.label}...`, handler: async () => { label: `${p.label}...`, handler: async () => {
const picked = await p.pick(); const picked = await p.pick();
if (picked) { if (picked) {
manager.selectConfiguration(picked.launch, p.label, picked.config); await manager.selectConfiguration(picked.launch, picked.config.name, picked.config);
return true; return true;
} }
return false; return false;
......
...@@ -46,6 +46,8 @@ jsonRegistry.registerSchema(launchSchemaId, launchSchema); ...@@ -46,6 +46,8 @@ jsonRegistry.registerSchema(launchSchemaId, launchSchema);
const DEBUG_SELECTED_CONFIG_NAME_KEY = 'debug.selectedconfigname'; const DEBUG_SELECTED_CONFIG_NAME_KEY = 'debug.selectedconfigname';
const DEBUG_SELECTED_ROOT = 'debug.selectedroot'; const DEBUG_SELECTED_ROOT = 'debug.selectedroot';
// Debug type is only stored if a dynamic configuration is used for better restore
const DEBUG_SELECTED_TYPE = 'debug.selectedtype';
interface IDynamicPickItem { label: string, launch: ILaunch, config: IConfig } interface IDynamicPickItem { label: string, launch: ILaunch, config: IConfig }
...@@ -84,13 +86,15 @@ export class ConfigurationManager implements IConfigurationManager { ...@@ -84,13 +86,15 @@ export class ConfigurationManager implements IConfigurationManager {
this.initLaunches(); this.initLaunches();
this.registerListeners(); this.registerListeners();
const previousSelectedRoot = this.storageService.get(DEBUG_SELECTED_ROOT, StorageScope.WORKSPACE); const previousSelectedRoot = this.storageService.get(DEBUG_SELECTED_ROOT, StorageScope.WORKSPACE);
const previousSelectedType = this.storageService.get(DEBUG_SELECTED_TYPE, StorageScope.WORKSPACE);
const previousSelectedLaunch = this.launches.find(l => l.uri.toString() === previousSelectedRoot); const previousSelectedLaunch = this.launches.find(l => l.uri.toString() === previousSelectedRoot);
const previousSelectedName = this.storageService.get(DEBUG_SELECTED_CONFIG_NAME_KEY, StorageScope.WORKSPACE);
this.debugConfigurationTypeContext = CONTEXT_DEBUG_CONFIGURATION_TYPE.bindTo(contextKeyService); this.debugConfigurationTypeContext = CONTEXT_DEBUG_CONFIGURATION_TYPE.bindTo(contextKeyService);
this.debuggersAvailable = CONTEXT_DEBUGGERS_AVAILABLE.bindTo(contextKeyService); this.debuggersAvailable = CONTEXT_DEBUGGERS_AVAILABLE.bindTo(contextKeyService);
if (previousSelectedLaunch && previousSelectedLaunch.getConfigurationNames().length) { if (previousSelectedLaunch && previousSelectedLaunch.getConfigurationNames().length) {
this.selectConfiguration(previousSelectedLaunch, this.storageService.get(DEBUG_SELECTED_CONFIG_NAME_KEY, StorageScope.WORKSPACE)); this.selectConfiguration(previousSelectedLaunch, previousSelectedName, undefined, previousSelectedType);
} else if (this.launches.length > 0) { } else if (this.launches.length > 0) {
this.selectConfiguration(undefined); this.selectConfiguration(undefined, previousSelectedName, undefined, previousSelectedType);
} }
} }
...@@ -259,7 +263,7 @@ export class ConfigurationManager implements IConfigurationManager { ...@@ -259,7 +263,7 @@ export class ConfigurationManager implements IConfigurationManager {
return results.reduce((first, second) => first.concat(second), []); return results.reduce((first, second) => first.concat(second), []);
} }
async getDynamicProviders(): Promise<{ label: string, pick: () => Promise<{ launch: ILaunch, config: IConfig } | undefined> }[]> { async getDynamicProviders(): Promise<{ label: string, provider: IDebugConfigurationProvider, pick: () => Promise<{ launch: ILaunch, config: IConfig } | undefined> }[]> {
const extensions = await this.extensionService.getExtensions(); const extensions = await this.extensionService.getExtensions();
const onDebugDynamicConfigurationsName = 'onDebugDynamicConfigurations'; const onDebugDynamicConfigurationsName = 'onDebugDynamicConfigurations';
const debugDynamicExtensionsTypes = extensions.reduce((acc, e) => { const debugDynamicExtensionsTypes = extensions.reduce((acc, e) => {
...@@ -289,9 +293,12 @@ export class ConfigurationManager implements IConfigurationManager { ...@@ -289,9 +293,12 @@ export class ConfigurationManager implements IConfigurationManager {
return acc; return acc;
}, [] as string[]); }, [] as string[]);
await Promise.all(debugDynamicExtensionsTypes.map(type => this.activateDebuggers(onDebugDynamicConfigurationsName, type)));
return debugDynamicExtensionsTypes.map(type => { return debugDynamicExtensionsTypes.map(type => {
const provider = this.configProviders.find(p => p.type === type && p.triggerKind === DebugConfigurationProviderTriggerKind.Dynamic && p.provideDebugConfigurations)!;
return { return {
label: this.getDebuggerLabel(type)!, label: this.getDebuggerLabel(type)!,
provider,
pick: async () => { pick: async () => {
const disposables = new DisposableStore(); const disposables = new DisposableStore();
const input = disposables.add(this.quickInputService.createQuickPick<IDynamicPickItem>()); const input = disposables.add(this.quickInputService.createQuickPick<IDynamicPickItem>());
...@@ -308,15 +315,13 @@ export class ConfigurationManager implements IConfigurationManager { ...@@ -308,15 +315,13 @@ export class ConfigurationManager implements IConfigurationManager {
await launch.openConfigFile(false, config.type); await launch.openConfigFile(false, config.type);
// Only Launch have a pin trigger button // Only Launch have a pin trigger button
await (launch as Launch).writeConfiguration(config); await (launch as Launch).writeConfiguration(config);
this.selectConfiguration(launch, config.name); await this.selectConfiguration(launch, config.name);
})); }));
disposables.add(input.onDidHide(() => { chosenDidCancel = true; resolve(); })); disposables.add(input.onDidHide(() => { chosenDidCancel = true; resolve(); }));
}); });
await this.activateDebuggers(onDebugDynamicConfigurationsName, type);
const token = new CancellationTokenSource(); const token = new CancellationTokenSource();
const picks: Promise<IDynamicPickItem[]>[] = []; const picks: Promise<IDynamicPickItem[]>[] = [];
const provider = this.configProviders.filter(p => p.type === type && p.triggerKind === DebugConfigurationProviderTriggerKind.Dynamic && p.provideDebugConfigurations)[0];
this.getLaunches().forEach(launch => { this.getLaunches().forEach(launch => {
if (launch.workspace && provider) { if (launch.workspace && provider) {
picks.push(provider.provideDebugConfigurations!(launch.workspace.uri, token.token).then(configurations => configurations.map(config => ({ picks.push(provider.provideDebugConfigurations!(launch.workspace.uri, token.token).then(configurations => configurations.map(config => ({
...@@ -508,7 +513,7 @@ export class ConfigurationManager implements IConfigurationManager { ...@@ -508,7 +513,7 @@ export class ConfigurationManager implements IConfigurationManager {
return undefined; return undefined;
} }
selectConfiguration(launch: ILaunch | undefined, name?: string, config?: IConfig): void { async selectConfiguration(launch: ILaunch | undefined, name?: string, config?: IConfig, type?: string): Promise<void> {
if (typeof launch === 'undefined') { if (typeof launch === 'undefined') {
const rootUri = this.historyService.getLastActiveWorkspaceRoot(); const rootUri = this.historyService.getLastActiveWorkspaceRoot();
launch = this.getLaunch(rootUri); launch = this.getLaunch(rootUri);
...@@ -526,14 +531,31 @@ export class ConfigurationManager implements IConfigurationManager { ...@@ -526,14 +531,31 @@ export class ConfigurationManager implements IConfigurationManager {
} else { } else {
this.storageService.remove(DEBUG_SELECTED_ROOT, StorageScope.WORKSPACE); this.storageService.remove(DEBUG_SELECTED_ROOT, StorageScope.WORKSPACE);
} }
const names = launch ? launch.getConfigurationNames() : []; const names = launch ? launch.getConfigurationNames() : [];
if ((name && names.indexOf(name) >= 0) || config) { if ((name && names.indexOf(name) >= 0) || config) {
this.setSelectedLaunchName(name); this.setSelectedLaunchName(name);
} else if (!this.selectedName || names.indexOf(this.selectedName) === -1) { } else if (!this.selectedName || names.indexOf(this.selectedName) === -1) {
this.setSelectedLaunchName(names.length ? names[0] : undefined); // We could not find the previously used name. We should get all dynamic configurations from providers
// And potentially auto select the previously used dynamic configuration #96293
const providers = await this.getDynamicProviders();
const provider = providers.find(p => p.provider.type === type);
let nameToSet = names.length ? names[0] : undefined;
if (provider && launch && launch.workspace) {
const token = new CancellationTokenSource();
const dynamicConfigs = await provider.provider.provideDebugConfigurations!(launch.workspace.uri, token.token);
const dynamicConfig = dynamicConfigs.find(c => c.name === name);
if (dynamicConfig) {
config = dynamicConfig;
nameToSet = name;
}
}
this.setSelectedLaunchName(nameToSet);
} }
this.selectedConfig = config; this.selectedConfig = config;
this.storageService.store(DEBUG_SELECTED_TYPE, this.selectedConfig?.type, StorageScope.WORKSPACE);
const configForType = this.selectedConfig || (this.selectedLaunch && this.selectedName ? this.selectedLaunch.getConfiguration(this.selectedName) : undefined); const configForType = this.selectedConfig || (this.selectedLaunch && this.selectedName ? this.selectedLaunch.getConfiguration(this.selectedName) : undefined);
if (configForType) { if (configForType) {
this.debugConfigurationTypeContext.set(configForType.type); this.debugConfigurationTypeContext.set(configForType.type);
......
...@@ -64,7 +64,7 @@ export class StartDebugQuickAccessProvider extends PickerQuickAccessProvider<IPi ...@@ -64,7 +64,7 @@ export class StartDebugQuickAccessProvider extends PickerQuickAccessProvider<IPi
return TriggerAction.CLOSE_PICKER; return TriggerAction.CLOSE_PICKER;
}, },
accept: async () => { accept: async () => {
this.debugService.getConfigurationManager().selectConfiguration(config.launch, config.name); await this.debugService.getConfigurationManager().selectConfiguration(config.launch, config.name);
try { try {
await this.debugService.startDebugging(config.launch); await this.debugService.startDebugging(config.launch);
} catch (error) { } catch (error) {
......
...@@ -671,7 +671,7 @@ export interface IConfigurationManager { ...@@ -671,7 +671,7 @@ export interface IConfigurationManager {
name: string | undefined; name: string | undefined;
}; };
selectConfiguration(launch: ILaunch | undefined, name?: string, config?: IConfig): void; selectConfiguration(launch: ILaunch | undefined, name?: string, config?: IConfig): Promise<void>;
getLaunches(): ReadonlyArray<ILaunch>; getLaunches(): ReadonlyArray<ILaunch>;
...@@ -692,7 +692,7 @@ export interface IConfigurationManager { ...@@ -692,7 +692,7 @@ export interface IConfigurationManager {
isDebuggerInterestedInLanguage(language: string): boolean; isDebuggerInterestedInLanguage(language: string): boolean;
hasDebugConfigurationProvider(debugType: string): boolean; hasDebugConfigurationProvider(debugType: string): boolean;
getDynamicProviders(): Promise<{ label: string, pick: () => Promise<{ launch: ILaunch, config: IConfig } | undefined> }[]>; getDynamicProviders(): Promise<{ label: string, provider: IDebugConfigurationProvider, pick: () => Promise<{ launch: ILaunch, config: IConfig } | undefined> }[]>;
registerDebugConfigurationProvider(debugConfigurationProvider: IDebugConfigurationProvider): IDisposable; registerDebugConfigurationProvider(debugConfigurationProvider: IDebugConfigurationProvider): IDisposable;
unregisterDebugConfigurationProvider(debugConfigurationProvider: IDebugConfigurationProvider): void; unregisterDebugConfigurationProvider(debugConfigurationProvider: IDebugConfigurationProvider): void;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册