Skip to content

Commit

Permalink
Merge pull request #151566 from justschen/justin/refactor-fix
Browse files Browse the repository at this point in the history
Refactoring Preview option in Command Palette (part of #151140)
  • Loading branch information
justschen committed Jun 9, 2022
2 parents 84e4f76 + 86ea71d commit a38448d
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 36 deletions.
1 change: 1 addition & 0 deletions src/vs/editor/contrib/codeAction/browser/codeAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeat

export const codeActionCommandId = 'editor.action.codeAction';
export const refactorCommandId = 'editor.action.refactor';
export const refactorPreviewCommandId = 'editor.action.refactor.preview';
export const sourceActionCommandId = 'editor.action.sourceAction';
export const organizeImportsCommandId = 'editor.action.organizeImports';
export const fixAllCommandId = 'editor.action.fixAll';
Expand Down
86 changes: 57 additions & 29 deletions src/vs/editor/contrib/codeAction/browser/codeActionCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ 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 { codeActionCommandId, CodeActionItem, CodeActionSet, fixAllCommandId, organizeImportsCommandId, refactorCommandId, sourceActionCommandId } from 'vs/editor/contrib/codeAction/browser/codeAction';
import { codeActionCommandId, CodeActionItem, CodeActionSet, fixAllCommandId, organizeImportsCommandId, refactorCommandId, refactorPreviewCommandId, sourceActionCommandId } from 'vs/editor/contrib/codeAction/browser/codeAction';
import { CodeActionUi } from 'vs/editor/contrib/codeAction/browser/codeActionUi';
import { MessageController } from 'vs/editor/contrib/message/browser/messageController';
import * as nls from 'vs/nls';
Expand All @@ -27,8 +27,8 @@ import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/commo
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { IMarkerService } from 'vs/platform/markers/common/markers';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { IEditorProgressService } from 'vs/platform/progress/common/progress';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { CodeActionModel, CodeActionsState, SUPPORTED_CODE_ACTIONS } from './codeActionModel';
import { CodeActionAutoApply, CodeActionCommandArgs, CodeActionFilter, CodeActionKind, CodeActionTrigger } from './types';
Expand All @@ -39,6 +39,26 @@ function contextKeyForSupportedActions(kind: CodeActionKind) {
new RegExp('(\\s|^)' + escapeRegExpCharacters(kind.value) + '\\b'));
}

function RefactorTrigger(editor: ICodeEditor, userArgs: any, preview: boolean) {
const args = CodeActionCommandArgs.fromUser(userArgs, {
kind: CodeActionKind.Refactor,
apply: CodeActionAutoApply.Never
});
return triggerCodeActionsForEditorSelection(editor,
typeof userArgs?.kind === 'string'
? args.preferred
? nls.localize('editor.action.refactor.noneMessage.preferred.kind', "No preferred refactorings for '{0}' available", userArgs.kind)
: nls.localize('editor.action.refactor.noneMessage.kind', "No refactorings for '{0}' available", userArgs.kind)
: args.preferred
? nls.localize('editor.action.refactor.noneMessage.preferred', "No preferred refactorings available")
: nls.localize('editor.action.refactor.noneMessage', "No refactorings available"),
{
include: CodeActionKind.Refactor.contains(args.kind) ? args.kind : CodeActionKind.None,
onlyIncludePreferredActions: args.preferred
},
args.apply, preview);
}

const argsSchema: IJSONSchema = {
type: 'object',
defaultSnippets: [{ body: { kind: '' } }],
Expand Down Expand Up @@ -92,11 +112,12 @@ export class QuickFixController extends Disposable implements IEditorContributio
this._model = this._register(new CodeActionModel(this._editor, languageFeaturesService.codeActionProvider, markerService, contextKeyService, progressService));
this._register(this._model.onDidChangeState(newState => this.update(newState)));


this._ui = new Lazy(() =>
this._register(new CodeActionUi(editor, QuickFixAction.Id, AutoFixAction.Id, {
applyCodeAction: async (action, retrigger) => {
applyCodeAction: async (action, retrigger, preview) => {
try {
await this._applyCodeAction(action);
await this._applyCodeAction(action, preview);
} finally {
if (retrigger) {
this._trigger({ type: CodeActionTriggerType.Auto, filter: {} });
Expand All @@ -118,30 +139,31 @@ export class QuickFixController extends Disposable implements IEditorContributio
public manualTriggerAtCurrentPosition(
notAvailableMessage: string,
filter?: CodeActionFilter,
autoApply?: CodeActionAutoApply
autoApply?: CodeActionAutoApply,
preview?: boolean
): void {
if (!this._editor.hasModel()) {
return;
}

MessageController.get(this._editor)?.closeMessage();
const triggerPosition = this._editor.getPosition();
this._trigger({ type: CodeActionTriggerType.Invoke, filter, autoApply, context: { notAvailableMessage, position: triggerPosition } });
this._trigger({ type: CodeActionTriggerType.Invoke, filter, autoApply, context: { notAvailableMessage, position: triggerPosition }, preview });
}

private _trigger(trigger: CodeActionTrigger) {
return this._model.trigger(trigger);
}

private _applyCodeAction(action: CodeActionItem): Promise<void> {
return this._instantiationService.invokeFunction(applyCodeAction, action, this._editor);
private _applyCodeAction(action: CodeActionItem, preview: boolean): Promise<void> {
return this._instantiationService.invokeFunction(applyCodeAction, action, { preview, editor: this._editor });
}
}

export async function applyCodeAction(
accessor: ServicesAccessor,
item: CodeActionItem,
editor?: ICodeEditor,
options?: { preview?: boolean; editor?: ICodeEditor }
): Promise<void> {
const bulkEditService = accessor.get(IBulkEditService);
const commandService = accessor.get(ICommandService);
Expand Down Expand Up @@ -171,11 +193,12 @@ export async function applyCodeAction(

if (item.action.edit) {
await bulkEditService.apply(ResourceEdit.convert(item.action.edit), {
editor,
editor: options?.editor,
label: item.action.title,
quotableLabel: item.action.title,
code: 'undoredo.codeAction',
respectAutoSaveConfig: true
respectAutoSaveConfig: true,
showPreview: options?.preview,
});
}

Expand Down Expand Up @@ -206,12 +229,13 @@ function triggerCodeActionsForEditorSelection(
editor: ICodeEditor,
notAvailableMessage: string,
filter: CodeActionFilter | undefined,
autoApply: CodeActionAutoApply | undefined
autoApply: CodeActionAutoApply | undefined,
preview: boolean = false
): void {
if (editor.hasModel()) {
const controller = QuickFixController.get(editor);
if (controller) {
controller.manualTriggerAtCurrentPosition(notAvailableMessage, filter, autoApply);
controller.manualTriggerAtCurrentPosition(notAvailableMessage, filter, autoApply, preview);
}
}
}
Expand Down Expand Up @@ -306,23 +330,27 @@ export class RefactorAction extends EditorAction {
}

public run(_accessor: ServicesAccessor, editor: ICodeEditor, userArgs: any): void {
const args = CodeActionCommandArgs.fromUser(userArgs, {
kind: CodeActionKind.Refactor,
apply: CodeActionAutoApply.Never
return RefactorTrigger(editor, userArgs, false);
}
}

export class RefactorPreview extends EditorAction {

constructor() {
super({
id: refactorPreviewCommandId,
label: nls.localize('refactor.preview.label', "Refactor with Preview..."),
alias: 'Refactor Preview...',
precondition: ContextKeyExpr.and(EditorContextKeys.writable, EditorContextKeys.hasCodeActionsProvider),
description: {
description: 'Refactor Preview...',
args: [{ name: 'args', schema: argsSchema }]
}
});
return triggerCodeActionsForEditorSelection(editor,
typeof userArgs?.kind === 'string'
? args.preferred
? nls.localize('editor.action.refactor.noneMessage.preferred.kind', "No preferred refactorings for '{0}' available", userArgs.kind)
: nls.localize('editor.action.refactor.noneMessage.kind', "No refactorings for '{0}' available", userArgs.kind)
: args.preferred
? nls.localize('editor.action.refactor.noneMessage.preferred', "No preferred refactorings available")
: nls.localize('editor.action.refactor.noneMessage', "No refactorings available"),
{
include: CodeActionKind.Refactor.contains(args.kind) ? args.kind : CodeActionKind.None,
onlyIncludePreferredActions: args.preferred,
},
args.apply);
}

public run(_accessor: ServicesAccessor, editor: ICodeEditor, userArgs: any): void {
return RefactorTrigger(editor, userArgs, true);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
*--------------------------------------------------------------------------------------------*/

import { registerEditorAction, registerEditorCommand, registerEditorContribution } from 'vs/editor/browser/editorExtensions';
import { AutoFixAction, CodeActionCommand, FixAllAction, OrganizeImportsAction, QuickFixAction, QuickFixController, RefactorAction, SourceAction } from 'vs/editor/contrib/codeAction/browser/codeActionCommands';
import { AutoFixAction, CodeActionCommand, FixAllAction, OrganizeImportsAction, QuickFixAction, QuickFixController, RefactorAction, RefactorPreview, SourceAction } from 'vs/editor/contrib/codeAction/browser/codeActionCommands';


registerEditorContribution(QuickFixController.ID, QuickFixController);
registerEditorAction(QuickFixAction);
registerEditorAction(RefactorAction);
registerEditorAction(RefactorPreview);
registerEditorAction(SourceAction);
registerEditorAction(OrganizeImportsAction);
registerEditorAction(AutoFixAction);
Expand Down
4 changes: 2 additions & 2 deletions src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { ResolvedKeybindingItem } from 'vs/platform/keybinding/common/resolvedKeybindingItem';

interface CodeActionWidgetDelegate {
onSelectCodeAction: (action: CodeActionItem) => Promise<any>;
onSelectCodeAction: (action: CodeActionItem, trigger: CodeActionTrigger) => Promise<any>;
}

interface ResolveCodeActionKeybinding {
Expand Down Expand Up @@ -115,7 +115,7 @@ export class CodeActionMenu extends Disposable {
actionsToShow: readonly CodeActionItem[],
documentation: readonly Command[]
): IAction[] {
const toCodeActionAction = (item: CodeActionItem): CodeActionAction => new CodeActionAction(item.action, () => this._delegate.onSelectCodeAction(item));
const toCodeActionAction = (item: CodeActionItem): CodeActionAction => new CodeActionAction(item.action, () => this._delegate.onSelectCodeAction(item, trigger));

const result: IAction[] = actionsToShow
.map(toCodeActionAction);
Expand Down
8 changes: 4 additions & 4 deletions src/vs/editor/contrib/codeAction/browser/codeActionUi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,16 @@ export class CodeActionUi extends Disposable {
quickFixActionId: string,
preferredFixActionId: string,
private readonly delegate: {
applyCodeAction: (action: CodeActionItem, regtriggerAfterApply: boolean) => Promise<void>;
applyCodeAction: (action: CodeActionItem, regtriggerAfterApply: boolean, preview: boolean) => Promise<void>;
},
@IInstantiationService instantiationService: IInstantiationService,
) {
super();

this._codeActionWidget = new Lazy(() => {
return this._register(instantiationService.createInstance(CodeActionMenu, this._editor, {
onSelectCodeAction: async (action) => {
this.delegate.applyCodeAction(action, /* retrigger */ true);
onSelectCodeAction: async (action, trigger) => {
this.delegate.applyCodeAction(action, /* retrigger */ true, Boolean(trigger.preview));
}
}));
});
Expand Down Expand Up @@ -85,7 +85,7 @@ export class CodeActionUi extends Disposable {
if (validActionToApply) {
try {
this._lightBulbWidget.getValue().hide();
await this.delegate.applyCodeAction(validActionToApply, false);
await this.delegate.applyCodeAction(validActionToApply, false, false);
} finally {
actions.dispose();
}
Expand Down
1 change: 1 addition & 0 deletions src/vs/editor/contrib/codeAction/browser/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ export interface CodeActionTrigger {
readonly notAvailableMessage: string;
readonly position: Position;
};
readonly preview?: boolean;
}

export class CodeActionCommandArgs {
Expand Down

0 comments on commit a38448d

Please sign in to comment.