Skip to content
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 ActionWidgetService #164096

Merged
merged 115 commits into from Nov 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
115 commits
Select commit Hold shift + click to select a range
819c937
refactor widget
meganrogge Oct 19, 2022
f8188bb
lots of work before trying something
meganrogge Oct 19, 2022
759570a
extend quickFixWidget
meganrogge Oct 19, 2022
b49711e
add fix list property
meganrogge Oct 20, 2022
eb81514
use proper container
meganrogge Oct 20, 2022
4aac3a5
Merge branch 'main' into merogge/widget-comb
meganrogge Oct 24, 2022
b2f53ac
Merge branch 'main' into merogge/widget-comb
meganrogge Oct 25, 2022
2be2ddd
quick fix widget -> base action widget
meganrogge Oct 20, 2022
fd70494
revert a bunch of changes
meganrogge Oct 24, 2022
20ef806
revert changes
meganrogge Oct 24, 2022
0426933
closer
meganrogge Oct 25, 2022
4065e61
save changes
meganrogge Oct 25, 2022
d67aa99
Merge branch 'main' into merogge/widget-comb
meganrogge Oct 26, 2022
262d6ca
revert change
meganrogge Oct 26, 2022
2816ebc
Merge branch 'main' into merogge/widget-comb
meganrogge Oct 26, 2022
c440f0b
Merge
meganrogge Oct 26, 2022
7abc848
fix issues
meganrogge Oct 26, 2022
9e45387
tidy
meganrogge Oct 26, 2022
23657d9
pass in accept selected actino command
meganrogge Oct 26, 2022
8fe1c94
terminal quick fix
meganrogge Oct 26, 2022
444caa7
need specific renderer
meganrogge Oct 27, 2022
9b94792
get editor actions to render
meganrogge Oct 27, 2022
a1f7d87
add actionrenderer
meganrogge Oct 27, 2022
13aa36e
get it pretty close
meganrogge Oct 27, 2022
8368608
Merge branch 'main' into merogge/widget-comb
meganrogge Oct 27, 2022
59648d6
get it to work except for click
meganrogge Oct 27, 2022
af157f8
check if udf
meganrogge Oct 27, 2022
08c3bc7
fix error
meganrogge Oct 27, 2022
8fb3e6f
rm redundant
meganrogge Oct 27, 2022
f94111f
Merge branch 'main' into merogge/widget-comb
meganrogge Oct 28, 2022
5a1b692
Update src/vs/editor/contrib/codeAction/browser/codeActionCommands.ts
meganrogge Oct 28, 2022
d5830cf
clean up
meganrogge Oct 28, 2022
4fac614
working now, just soome styling needed
meganrogge Oct 28, 2022
267f9a0
Merge branch 'main' into merogge/widget-comb
meganrogge Oct 31, 2022
32d2d29
Merge branch 'main' into merogge/widget-comb
meganrogge Oct 31, 2022
13a7794
get keyboard nav to work
meganrogge Oct 31, 2022
8f8f269
action -> code-action
meganrogge Oct 31, 2022
c199e66
fix compilation error
meganrogge Oct 31, 2022
f207c65
Merge branch 'main' into merogge/widget-comb
meganrogge Nov 1, 2022
5721763
Merge branch 'main' into merogge/widget-comb
meganrogge Nov 2, 2022
4c20068
streamline
meganrogge Nov 2, 2022
ba578dd
add actionWidget and move codeaction widget over to that
meganrogge Nov 2, 2022
eb5013f
remove references to code in action widget
meganrogge Nov 2, 2022
c10c4db
fix list selection
meganrogge Nov 2, 2022
83a1650
migrate quick fix widget
meganrogge Nov 2, 2022
3527a09
remove more code
meganrogge Nov 2, 2022
ee3b609
consolidate further
meganrogge Nov 3, 2022
9350fc9
Merge branch 'main' into merogge/widget-comb
meganrogge Nov 3, 2022
835d154
remove code from action info
meganrogge Nov 3, 2022
73b1cf2
fix lightbulb color for terminal quick fix
meganrogge Nov 3, 2022
3d0a57f
use color
meganrogge Nov 3, 2022
77ce8ea
fix #165434
meganrogge Nov 3, 2022
6c72e76
options -> preview
meganrogge Nov 3, 2022
360c31a
more consolidation
meganrogge Nov 4, 2022
716d15a
move onWidgetClosed to action widget
meganrogge Nov 4, 2022
e843fb7
move render widget to action widget
meganrogge Nov 4, 2022
180138d
code action -> action
meganrogge Nov 4, 2022
b7aee48
remove abstract
meganrogge Nov 4, 2022
5443728
move base action widget into action widget
meganrogge Nov 8, 2022
003ef6f
delete base action widget
meganrogge Nov 9, 2022
1db9afe
move action widget to platform
meganrogge Nov 9, 2022
d1dfdf8
revert terminal.css changes
meganrogge Nov 9, 2022
17c2d53
Update src/vs/workbench/contrib/terminal/browser/media/terminal.css
meganrogge Nov 9, 2022
326fcbb
Merge branch 'main' into merogge/widget-comb
meganrogge Nov 9, 2022
cbd199e
Update src/vs/editor/contrib/codeAction/common/types.ts
meganrogge Nov 9, 2022
822ee53
code action set
meganrogge Nov 9, 2022
e54cc45
fix css
meganrogge Nov 9, 2022
5afc041
combine keybindings
meganrogge Nov 9, 2022
1498d42
Revert "combine keybindings"
meganrogge Nov 9, 2022
01a9fc5
fix compile error
meganrogge Nov 9, 2022
db7d43b
add action widget service
meganrogge Nov 9, 2022
adf1ee8
add service brand
meganrogge Nov 9, 2022
bcb6dac
add implements interface
meganrogge Nov 9, 2022
f63b4f0
further consolidate
meganrogge Nov 9, 2022
d1a81e6
trim interface
meganrogge Nov 9, 2022
a5b164a
remove unused args
meganrogge Nov 9, 2022
2f405ff
actionWidget -> action-widget css
meganrogge Nov 9, 2022
011f152
enforce I prefix for interfaces in actionWidget
meganrogge Nov 9, 2022
4aa3f97
const enum
meganrogge Nov 9, 2022
ebb4ec5
base -> platform/common
meganrogge Nov 9, 2022
5bdd9fb
update imports
meganrogge Nov 9, 2022
2b54add
rename custom widget -> custom list
meganrogge Nov 9, 2022
0927068
pass disabled string in as label if item is disabled
meganrogge Nov 9, 2022
0a57faa
adjust action id
meganrogge Nov 9, 2022
6a4eea0
rename
meganrogge Nov 9, 2022
5aa6fa6
deal w keybinding resolver
meganrogge Nov 9, 2022
53543ec
switch order
meganrogge Nov 9, 2022
eb3061f
use item
meganrogge Nov 9, 2022
88996f1
check if actions have keybindings before setting title
meganrogge Nov 9, 2022
37f1112
don't use variable in localize
meganrogge Nov 9, 2022
bea6335
Merge branch 'main' into merogge/widget-comb
meganrogge Nov 9, 2022
3dbc58f
Update src/vs/platform/actionWidget/browser/actionWidget.ts
meganrogge Nov 10, 2022
fa2d813
remove trigger
meganrogge Nov 10, 2022
99e1e74
Update src/vs/platform/actionWidget/browser/actionWidget.ts
meganrogge Nov 10, 2022
a8cb359
rename
meganrogge Nov 10, 2022
231773c
make resolver more specific than any
meganrogge Nov 10, 2022
95dcfda
actionWidgetContextKeys
meganrogge Nov 10, 2022
7ca9036
clean up
meganrogge Nov 10, 2022
6c3813d
use icon depending on action id
meganrogge Nov 10, 2022
edd218d
fix delegate issues
meganrogge Nov 10, 2022
bff6070
add some types to group
meganrogge Nov 10, 2022
3fd83a3
static css
meganrogge Nov 10, 2022
8b69367
try any
meganrogge Nov 10, 2022
0a6cfaa
remove code from comments
meganrogge Nov 10, 2022
295a841
keybinding resolver
meganrogge Nov 10, 2022
5da95f3
use old command ids
meganrogge Nov 10, 2022
dabfdce
return codicons
meganrogge Nov 10, 2022
762995d
make vars private again
meganrogge Nov 10, 2022
654a3a5
more vars private
meganrogge Nov 10, 2022
4293d6c
construct the list in the action widget service
meganrogge Nov 10, 2022
047f453
change name of action
meganrogge Nov 10, 2022
5cc78e0
fix css
meganrogge Nov 10, 2022
b93ec15
make list item kind strict and mandatory
meganrogge Nov 10, 2022
023e008
delete unused file
meganrogge Nov 11, 2022
8799f4d
Merge branch 'main' into merogge/widget-comb
meganrogge Nov 15, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 0 additions & 3 deletions src/vs/editor/contrib/codeAction/browser/codeAction.ts
Expand Up @@ -33,9 +33,6 @@ export const sourceActionCommandId = 'editor.action.sourceAction';
export const organizeImportsCommandId = 'editor.action.organizeImports';
export const fixAllCommandId = 'editor.action.fixAll';

export const acceptSelectedCodeActionCommand = 'acceptSelectedCodeAction';
export const previewSelectedCodeActionCommand = 'previewSelectedCodeAction';

class ManagedCodeActionSet extends Disposable implements CodeActionSet {

private static codeActionsPreferredComparator(a: languages.CodeAction, b: languages.CodeAction): number {
Expand Down
120 changes: 2 additions & 118 deletions src/vs/editor/contrib/codeAction/browser/codeActionCommands.ts
Expand Up @@ -16,12 +16,10 @@ import { IEditorContribution } from 'vs/editor/common/editorCommon';
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
import { CodeActionTriggerType } from 'vs/editor/common/languages';
import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures';
import { acceptSelectedCodeActionCommand, applyCodeAction, ApplyCodeActionReason, codeActionCommandId, fixAllCommandId, organizeImportsCommandId, previewSelectedCodeActionCommand, refactorCommandId, refactorPreviewCommandId, sourceActionCommandId } from 'vs/editor/contrib/codeAction/browser/codeAction';
import { applyCodeAction, ApplyCodeActionReason, codeActionCommandId, fixAllCommandId, organizeImportsCommandId, refactorCommandId, refactorPreviewCommandId, sourceActionCommandId } from 'vs/editor/contrib/codeAction/browser/codeAction';
import { CodeActionUi } from 'vs/editor/contrib/codeAction/browser/codeActionUi';
import { CodeActionWidget, Context } from 'vs/editor/contrib/codeAction/browser/codeActionWidget';
import { MessageController } from 'vs/editor/contrib/message/browser/messageController';
import * as nls from 'vs/nls';
import { Action2, registerAction2 } from 'vs/platform/actions/common/actions';
import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
Expand Down Expand Up @@ -102,7 +100,7 @@ export class CodeActionController extends Disposable implements IEditorContribut
@IContextKeyService contextKeyService: IContextKeyService,
@IEditorProgressService progressService: IEditorProgressService,
@IInstantiationService private readonly _instantiationService: IInstantiationService,
@ILanguageFeaturesService languageFeaturesService: ILanguageFeaturesService,
@ILanguageFeaturesService languageFeaturesService: ILanguageFeaturesService
) {
super();

Expand Down Expand Up @@ -416,117 +414,3 @@ export class AutoFixAction extends EditorAction {
CodeActionAutoApply.IfSingle, undefined, CodeActionTriggerSource.AutoFix);
}
}

const weight = KeybindingWeight.EditorContrib + 1000;

registerAction2(class extends Action2 {
constructor() {
super({
id: 'hideCodeActionWidget',
title: {
value: nls.localize('hideCodeActionWidget.title', "Hide code action widget"),
original: 'Hide code action widget'
},
precondition: Context.Visible,
keybinding: {
weight,
primary: KeyCode.Escape,
secondary: [KeyMod.Shift | KeyCode.Escape]
},
});
}

run(): void {
CodeActionWidget.INSTANCE?.hide();
}
});

registerAction2(class extends Action2 {
constructor() {
super({
id: 'selectPrevCodeAction',
title: {
value: nls.localize('selectPrevCodeAction.title', "Select previous code action"),
original: 'Select previous code action'
},
precondition: Context.Visible,
keybinding: {
weight,
primary: KeyCode.UpArrow,
secondary: [KeyMod.CtrlCmd | KeyCode.UpArrow],
mac: { primary: KeyCode.UpArrow, secondary: [KeyMod.CtrlCmd | KeyCode.UpArrow, KeyMod.WinCtrl | KeyCode.KeyP] },
}
});
}

run(): void {
CodeActionWidget.INSTANCE?.focusPrevious();
}
});

registerAction2(class extends Action2 {
constructor() {
super({
id: 'selectNextCodeAction',
title: {
value: nls.localize('selectNextCodeAction.title', "Select next code action"),
original: 'Select next code action'
},
precondition: Context.Visible,
keybinding: {
weight,
primary: KeyCode.DownArrow,
secondary: [KeyMod.CtrlCmd | KeyCode.DownArrow],
mac: { primary: KeyCode.DownArrow, secondary: [KeyMod.CtrlCmd | KeyCode.DownArrow, KeyMod.WinCtrl | KeyCode.KeyN] }
}
});
}

run(): void {
CodeActionWidget.INSTANCE?.focusNext();
}
});

registerAction2(class extends Action2 {
constructor() {
super({
id: acceptSelectedCodeActionCommand,
title: {
value: nls.localize('acceptSelected.title', "Accept selected code action"),
original: 'Accept selected code action'
},
precondition: Context.Visible,
keybinding: {
weight,
primary: KeyCode.Enter,
secondary: [KeyMod.CtrlCmd | KeyCode.Period],
}
});
}

run(): void {
CodeActionWidget.INSTANCE?.acceptSelected();
}
});

registerAction2(class extends Action2 {
constructor() {
super({
id: previewSelectedCodeActionCommand,
title: {
value: nls.localize('previewSelected.title', "Preview selected code action"),
original: 'Preview selected code action'
},
precondition: Context.Visible,
keybinding: {
weight,
primary: KeyMod.CtrlCmd | KeyCode.Enter,
}
});
}

run(): void {
CodeActionWidget.INSTANCE?.acceptSelected({ preview: true });
}
});

Expand Up @@ -8,6 +8,7 @@ import { Lazy } from 'vs/base/common/lazy';
import { CodeAction } from 'vs/editor/common/languages';
import { codeActionCommandId, fixAllCommandId, organizeImportsCommandId, refactorCommandId, sourceActionCommandId } from 'vs/editor/contrib/codeAction/browser/codeAction';
import { CodeActionAutoApply, CodeActionCommandArgs, CodeActionKind } from 'vs/editor/contrib/codeAction/common/types';
import { IActionKeybindingResolver } from 'vs/platform/actionWidget/common/actionWidget';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';

interface ResolveCodeActionKeybinding {
Expand All @@ -16,7 +17,7 @@ interface ResolveCodeActionKeybinding {
readonly resolvedKeybinding: ResolvedKeybinding;
}

export class CodeActionKeybindingResolver {
export class CodeActionKeybindingResolver implements IActionKeybindingResolver {
private static readonly codeActionCommands: readonly string[] = [
refactorCommandId,
codeActionCommandId,
Expand Down
68 changes: 68 additions & 0 deletions src/vs/editor/contrib/codeAction/browser/codeActionMenuItems.ts
@@ -0,0 +1,68 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import 'vs/base/browser/ui/codicons/codiconStyles'; // The codicon symbol styles are defined here and must be loaded
import { Codicon } from 'vs/base/common/codicons';
import { ActionListItemKind, IListMenuItem } from 'vs/platform/actionWidget/browser/actionWidget';
import { CodeActionItem, CodeActionKind } from 'vs/editor/contrib/codeAction/common/types';
import 'vs/editor/contrib/symbolIcons/browser/symbolIcons'; // The codicon symbol colors are defined here and must be loaded to get colors
import { localize } from 'vs/nls';

export interface ActionGroup {
readonly kind: CodeActionKind;
readonly title: string;
readonly icon?: { readonly codicon: Codicon; readonly color?: string };
}

const uncategorizedCodeActionGroup = Object.freeze<ActionGroup>({ kind: CodeActionKind.Empty, title: localize('codeAction.widget.id.more', 'More Actions...') });

const codeActionGroups = Object.freeze<ActionGroup[]>([
{ kind: CodeActionKind.QuickFix, title: localize('codeAction.widget.id.quickfix', 'Quick Fix...') },
{ kind: CodeActionKind.RefactorExtract, title: localize('codeAction.widget.id.extract', 'Extract...'), icon: { codicon: Codicon.wrench } },
{ kind: CodeActionKind.RefactorInline, title: localize('codeAction.widget.id.inline', 'Inline...'), icon: { codicon: Codicon.wrench } },
{ kind: CodeActionKind.RefactorRewrite, title: localize('codeAction.widget.id.convert', 'Rewrite...'), icon: { codicon: Codicon.wrench } },
{ kind: CodeActionKind.RefactorMove, title: localize('codeAction.widget.id.move', 'Move...'), icon: { codicon: Codicon.wrench } },
{ kind: CodeActionKind.SurroundWith, title: localize('codeAction.widget.id.surround', 'Surround With...'), icon: { codicon: Codicon.symbolSnippet } },
{ kind: CodeActionKind.Source, title: localize('codeAction.widget.id.source', 'Source Action...'), icon: { codicon: Codicon.symbolFile } },
uncategorizedCodeActionGroup,
]);

export function toMenuItems(inputCodeActions: readonly CodeActionItem[], showHeaders: boolean): IListMenuItem<CodeActionItem>[] {
if (!showHeaders) {
return inputCodeActions.map((action): IListMenuItem<CodeActionItem> => {
return {
kind: ActionListItemKind.Action,
item: action,
group: uncategorizedCodeActionGroup,
disabled: !!action.action.disabled,
label: action.action.disabled || action.action.title
};
});
}

// Group code actions
const menuEntries = codeActionGroups.map(group => ({ group, actions: [] as CodeActionItem[] }));

for (const action of inputCodeActions) {
const kind = action.action.kind ? new CodeActionKind(action.action.kind) : CodeActionKind.None;
for (const menuEntry of menuEntries) {
if (menuEntry.group.kind.contains(kind)) {
menuEntry.actions.push(action);
break;
}
}
}

const allMenuItems: IListMenuItem<CodeActionItem>[] = [];
for (const menuEntry of menuEntries) {
if (menuEntry.actions.length) {
allMenuItems.push({ kind: ActionListItemKind.Header, group: menuEntry.group });
for (const action of menuEntry.actions) {
allMenuItems.push({ kind: ActionListItemKind.Action, item: action, group: menuEntry.group, label: action.action.title, disabled: !!action.action.disabled });
}
}
}
return allMenuItems;
}
35 changes: 22 additions & 13 deletions src/vs/editor/contrib/codeAction/browser/codeActionUi.ts
Expand Up @@ -12,14 +12,14 @@ import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { IPosition, Position } from 'vs/editor/common/core/position';
import { ScrollType } from 'vs/editor/common/editorCommon';
import { CodeActionTriggerType } from 'vs/editor/common/languages';
import { IActionShowOptions, IActionWidgetService, IRenderDelegate } from 'vs/platform/actionWidget/browser/actionWidget';
import { MessageController } from 'vs/editor/contrib/message/browser/messageController';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { CodeActionAutoApply, CodeActionItem, CodeActionSet, CodeActionTrigger } from '../common/types';
import { CodeActionsState } from './codeActionModel';
import { CodeActionShowOptions, CodeActionWidget } from './codeActionWidget';
import { LightBulbWidget } from './lightBulbWidget';
import { toMenuItems } from 'vs/editor/contrib/codeAction/browser/codeActionMenuItems';

export class CodeActionUi extends Disposable {
private readonly _lightBulbWidget: Lazy<LightBulbWidget>;
Expand All @@ -35,19 +35,19 @@ export class CodeActionUi extends Disposable {
applyCodeAction: (action: CodeActionItem, regtriggerAfterApply: boolean, preview: boolean) => Promise<void>;
},
@IConfigurationService private readonly _configurationService: IConfigurationService,
@IContextKeyService private readonly _contextKeyService: IContextKeyService,
@IInstantiationService private readonly _instantiationService: IInstantiationService,
@IInstantiationService readonly instantiationService: IInstantiationService,
meganrogge marked this conversation as resolved.
Show resolved Hide resolved
meganrogge marked this conversation as resolved.
Show resolved Hide resolved
@IActionWidgetService private readonly _actionWidgetService: IActionWidgetService
) {
super();


this._lightBulbWidget = new Lazy(() => {
const widget = this._register(_instantiationService.createInstance(LightBulbWidget, this._editor, quickFixActionId, preferredFixActionId));
const widget = this._register(instantiationService.createInstance(LightBulbWidget, this._editor, quickFixActionId, preferredFixActionId));
this._register(widget.onClick(e => this.showCodeActionList(e.trigger, e.actions, e, { includeDisabledActions: false, fromLightbulb: true, showHeaders: this.shouldShowHeaders() })));
return widget;
});

this._register(this._editor.onDidLayoutChange(() => CodeActionWidget.INSTANCE?.hide()));
this._register(this._editor.onDidLayoutChange(() => this._actionWidgetService.hide()));
}

override dispose() {
Expand Down Expand Up @@ -115,7 +115,7 @@ export class CodeActionUi extends Disposable {
this.showCodeActionList(newState.trigger, actions, this.toCoords(newState.position), { includeDisabledActions, fromLightbulb: false, showHeaders: this.shouldShowHeaders() });
} else {
// auto magically triggered
if (CodeActionWidget.INSTANCE?.isVisible) {
if (this._actionWidgetService.isVisible) {
// TODO: Figure out if we should update the showing menu?
actions.dispose();
} else {
Expand Down Expand Up @@ -152,22 +152,31 @@ export class CodeActionUi extends Disposable {
return undefined;
}

public async showCodeActionList(trigger: CodeActionTrigger, actions: CodeActionSet, at: IAnchor | IPosition, options: CodeActionShowOptions): Promise<void> {
public async showCodeActionList(trigger: CodeActionTrigger, actions: CodeActionSet, at: IAnchor | IPosition, options: IActionShowOptions): Promise<void> {
const editorDom = this._editor.getDomNode();
if (!editorDom) {
return;
}

const anchor = Position.isIPosition(at) ? this.toCoords(at) : at;

CodeActionWidget.getOrCreateInstance(this._instantiationService).show(trigger, actions, anchor, editorDom, { ...options, showHeaders: this.shouldShowHeaders() }, {
onSelectCodeAction: async (action, trigger, options) => {
this.delegate.applyCodeAction(action, /* retrigger */ true, Boolean(options.preview || trigger.preview));
const delegate: IRenderDelegate<CodeActionItem> = {
onSelect: async (action: CodeActionItem, preview?: boolean) => {
this.delegate.applyCodeAction(action, /* retrigger */ true, !!preview ? preview : false);
this._actionWidgetService.hide();
},
onHide: () => {
this._editor?.focus();
},
}, this._contextKeyService);
}
};
this._actionWidgetService.show(
'codeActionWidget',
toMenuItems,
delegate,
actions,
anchor,
editorDom,
{ ...options, showHeaders: this.shouldShowHeaders() });
}

private toCoords(position: IPosition): IAnchor {
Expand Down