Skip to content

Commit

Permalink
Support debug/createConfiguration proposed menu API
Browse files Browse the repository at this point in the history
fixes #14114

contributed on behalf of STMicroelectronics

Signed-off-by: Remi Schnekenburger <[email protected]>
  • Loading branch information
rschnekenbu committed Sep 24, 2024
1 parent 1a7486e commit 8b2a407
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

<!-- ## Unreleased
- [debug] support 'debug/createConfiguration' menu extension [14215](https://github.com/eclipse-theia/theia/pull/14215) - Contributed on behalf of STMicroelectronics
- [plugin] move stubbed API TerminalShellIntegration into main API [#14168](https://github.com/eclipse-theia/theia/pull/14168) - Contributed on behalf of STMicroelectronics
- [plugin] support evolution on proposed API extensionAny [#14199](https://github.com/eclipse-theia/theia/pull/14199) - Contributed on behalf of STMicroelectronics
- [plugin] updated TreeView reveal options to be readonly [#14198](https://github.com/eclipse-theia/theia/pull/14198) - Contributed on behalf of STMicroelectronics
Expand Down
77 changes: 74 additions & 3 deletions packages/debug/src/browser/debug-configuration-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { Emitter, Event, WaitUntilEvent } from '@theia/core/lib/common/event';
import { EditorManager, EditorWidget } from '@theia/editor/lib/browser';
import { MonacoEditor } from '@theia/monaco/lib/browser/monaco-editor';
import { LabelProvider, PreferenceScope, PreferenceService, QuickPickValue, StorageService } from '@theia/core/lib/browser';
import { QuickPickService } from '@theia/core/lib/common/quick-pick-service';
import { QuickPickItem, QuickPickItemOrSeparator, QuickPickService } from '@theia/core/lib/common/quick-pick-service';
import { WorkspaceService } from '@theia/workspace/lib/browser/workspace-service';
import { DebugConfigurationModel } from './debug-configuration-model';
import { DebugSessionOptions, DynamicDebugConfigurationSessionOptions } from './debug-session-options';
Expand All @@ -40,12 +40,15 @@ import { MonacoTextModelService } from '@theia/monaco/lib/browser/monaco-text-mo
import * as monaco from '@theia/monaco-editor-core';
import { ICommandService } from '@theia/monaco-editor-core/esm/vs/platform/commands/common/commands';
import { StandaloneServices } from '@theia/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneServices';
import { nls } from '@theia/core';
import { ActionMenuNode, CommandService, MenuCommandExecutor, MenuModelRegistry, MenuPath, nls } from '@theia/core';
import { DebugCompound } from '../common/debug-compound';

import { IReference } from '@theia/monaco-editor-core/esm/vs/base/common/lifecycle';
import { MonacoEditorModel } from '@theia/monaco/lib/browser/monaco-editor-model';
export interface WillProvideDebugConfiguration extends WaitUntilEvent {
}

export const DEBUG_CREATE_CONFIGURATION_MENU: MenuPath = ['debug-create-configuration'];

@injectable()
export class DebugConfigurationManager {

Expand Down Expand Up @@ -76,6 +79,15 @@ export class DebugConfigurationManager {
@inject(WorkspaceVariableContribution)
protected readonly workspaceVariables: WorkspaceVariableContribution;

@inject(MenuModelRegistry)
protected readonly menuRegistry: MenuModelRegistry;

@inject(MenuCommandExecutor)
protected readonly menuCommandExecutor: MenuCommandExecutor;

@inject(CommandService)
protected readonly commandService: CommandService;

protected readonly onDidChangeEmitter = new Emitter<void>();
readonly onDidChange: Event<void> = this.onDidChangeEmitter.event;

Expand Down Expand Up @@ -453,13 +465,72 @@ export class DebugConfigurationManager {
} catch {
// Just keep going
}

// no configuration yet. Proceed to create the file or use any action registered on the `debug/createConfiguration` menu.
const debugType = await this.selectDebugType();
const configurations = debugType ? await this.provideDebugConfigurations(debugType, model.workspaceFolderUri) : [];
const commandQuickPicks = this.buildItemsFromMenu();

if (commandQuickPicks.length > 0) {
const quickPickItems: QuickPickItemOrSeparator[] = [];
const GENERATE_FILE_ID = 'debug-generate-file';
const item: QuickPickItem = {
// basic action to provide a launch.json skeleton and user can edit it.
label: nls.localize('theia/debug/generateLaunchFile', 'generate launch.json'),
id: GENERATE_FILE_ID
};
quickPickItems.push(item);
quickPickItems.push({ type: 'separator' });
quickPickItems.push(...commandQuickPicks);

const selected = await this.quickPickService.show(quickPickItems, { canSelectMany: false });
if (selected && selected.id) {
if (selected.id === GENERATE_FILE_ID) {
await this.updateTextModel(textModel, configurations);
} else {
await this.commandService.executeCommand(selected.id);
}
}
} else {
await this.updateTextModel(textModel, configurations);
}
}

protected async updateTextModel(textModel: IReference<MonacoEditorModel>, configurations: DebugConfiguration[]): Promise<void> {
const content = this.getInitialConfigurationContent(configurations);
textModel.object.textEditorModel.setValue(content); // Will clobber anything the user has entered!
await textModel.object.save();
}

protected buildItemsFromMenu(): QuickPickItemOrSeparator[] {
const menu = this.menuRegistry.getMenu(DEBUG_CREATE_CONFIGURATION_MENU);
const quickPickItems = [];
for (const child of menu.children) {
if (child.children) {
for (const grandchild of child.children) {
if (grandchild instanceof ActionMenuNode) {
const { command, label, when } = grandchild;
if (this.menuCommandExecutor.isVisible(DEBUG_CREATE_CONFIGURATION_MENU, command) && (!when || this.contextKeyService.match(when))) {
quickPickItems.push({
label: label,
id: command
});
}
}
}
} else if (child instanceof ActionMenuNode) {
const { command, label, when } = child;
if (this.menuCommandExecutor.isVisible(DEBUG_CREATE_CONFIGURATION_MENU, command) && (!when || this.contextKeyService.match(when))) {
quickPickItems.push({
label: label,
id: command
});
}
}
}
return quickPickItems;
}

protected async provideDebugConfigurations(debugType: string, workspaceFolderUri: string | undefined): Promise<DebugConfiguration[]> {
await this.fireWillProvideDebugConfiguration();
return this.debug.provideDebugConfigurations(debugType, workspaceFolderUri);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { Navigatable } from '@theia/core/lib/browser/navigatable';
import { injectable } from '@theia/core/shared/inversify';
import { URI as CodeUri } from '@theia/core/shared/vscode-uri';
import { DebugStackFramesWidget } from '@theia/debug/lib/browser/view/debug-stack-frames-widget';
import { DEBUG_CREATE_CONFIGURATION_MENU } from '@theia/debug/lib/browser/debug-configuration-manager';
import { DebugThreadsWidget } from '@theia/debug/lib/browser/view/debug-threads-widget';
import { DebugToolBar } from '@theia/debug/lib/browser/view/debug-toolbar-widget';
import { DebugVariablesWidget } from '@theia/debug/lib/browser/view/debug-variables-widget';
Expand All @@ -46,6 +47,7 @@ export const implementedVSCodeContributionPoints = [
'comments/comment/title',
'comments/commentThread/context',
'debug/callstack/context',
'debug/createConfiguration',
'debug/variables/context',
'debug/toolBar',
'editor/context',
Expand Down Expand Up @@ -79,6 +81,7 @@ export const codeToTheiaMappings = new Map<ContributionPoint, MenuPath[]>([
['comments/comment/title', [COMMENT_TITLE]],
['comments/commentThread/context', [COMMENT_THREAD_CONTEXT]],
['debug/callstack/context', [DebugStackFramesWidget.CONTEXT_MENU, DebugThreadsWidget.CONTEXT_MENU]],
['debug/createConfiguration', [DEBUG_CREATE_CONFIGURATION_MENU]],
['debug/variables/context', [DebugVariablesWidget.CONTEXT_MENU]],
['debug/toolBar', [DebugToolBar.MENU]],
['editor/context', [EDITOR_CONTEXT_MENU]],
Expand Down

0 comments on commit 8b2a407

Please sign in to comment.