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

joh/remarkable egret #182507

Merged
merged 2 commits into from May 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
21 changes: 13 additions & 8 deletions src/vs/platform/actions/browser/menuEntryActionViewItem.ts
Expand Up @@ -320,14 +320,15 @@ export class SubmenuEntryActionViewItem extends DropdownMenuActionViewItem {

export interface IDropdownWithDefaultActionViewItemOptions extends IDropdownMenuActionViewItemOptions {
renderKeybindingWithDefaultActionLabel?: boolean;
persistLastActionId?: boolean;
}

export class DropdownWithDefaultActionViewItem extends BaseActionViewItem {
private readonly _options: IDropdownWithDefaultActionViewItemOptions | undefined;
private _defaultAction: ActionViewItem;
private _dropdown: DropdownMenuActionViewItem;
private readonly _dropdown: DropdownMenuActionViewItem;
private _container: HTMLElement | null = null;
private _storageKey: string;
private readonly _storageKey: string;

get onDidChangeDropdownVisibility(): Event<boolean> {
return this._dropdown.onDidChangeVisibility;
Expand All @@ -349,7 +350,7 @@ export class DropdownWithDefaultActionViewItem extends BaseActionViewItem {

// determine default action
let defaultAction: IAction | undefined;
const defaultActionId = _storageService.get(this._storageKey, StorageScope.WORKSPACE);
const defaultActionId = options?.persistLastActionId ? _storageService.get(this._storageKey, StorageScope.WORKSPACE) : undefined;
if (defaultActionId) {
defaultAction = submenuAction.actions.find(a => defaultActionId === a.id);
}
Expand All @@ -359,11 +360,13 @@ export class DropdownWithDefaultActionViewItem extends BaseActionViewItem {

this._defaultAction = this._instaService.createInstance(MenuEntryActionViewItem, <MenuItemAction>defaultAction, { keybinding: this._getDefaultActionKeybindingLabel(defaultAction) });

const dropdownOptions = Object.assign({}, options ?? Object.create(null), {
const dropdownOptions: IDropdownMenuActionViewItemOptions = {
keybindingProvider: action => this._keybindingService.lookupKeybinding(action.id),
...options,
menuAsChild: options?.menuAsChild ?? true,
classNames: options?.classNames ?? ['codicon', 'codicon-chevron-down'],
actionRunner: options?.actionRunner ?? new ActionRunner()
});
actionRunner: options?.actionRunner ?? new ActionRunner(),
};

this._dropdown = new DropdownMenuActionViewItem(submenuAction, submenuAction.actions, this._contextMenuService, dropdownOptions);
this._dropdown.actionRunner.onDidRun((e: IRunEvent) => {
Expand All @@ -374,7 +377,9 @@ export class DropdownWithDefaultActionViewItem extends BaseActionViewItem {
}

private update(lastAction: MenuItemAction): void {
this._storageService.store(this._storageKey, lastAction.id, StorageScope.WORKSPACE, StorageTarget.MACHINE);
if (this._options?.persistLastActionId) {
this._storageService.store(this._storageKey, lastAction.id, StorageScope.WORKSPACE, StorageTarget.MACHINE);
}

this._defaultAction.dispose();
this._defaultAction = this._instaService.createInstance(MenuEntryActionViewItem, lastAction, { keybinding: this._getDefaultActionKeybindingLabel(lastAction) });
Expand Down Expand Up @@ -505,7 +510,7 @@ export function createActionViewItem(instaService: IInstantiationService, action
return instaService.createInstance(SubmenuEntrySelectActionViewItem, action);
} else {
if (action.item.rememberDefaultAction) {
return instaService.createInstance(DropdownWithDefaultActionViewItem, action, options);
return instaService.createInstance(DropdownWithDefaultActionViewItem, action, { ...options, persistLastActionId: true });
} else {
return instaService.createInstance(SubmenuEntryActionViewItem, action, options);
}
Expand Down
Expand Up @@ -20,7 +20,11 @@ registerEditorContribution(INTERACTIVE_EDITOR_ID, InteractiveEditorController, E
registerAction2(interactiveEditorActions.StartSessionAction);
registerAction2(interactiveEditorActions.MakeRequestAction);
registerAction2(interactiveEditorActions.StopRequestAction);
registerAction2(interactiveEditorActions.DicardAction);
registerAction2(interactiveEditorActions.DiscardToClipboardAction);
registerAction2(interactiveEditorActions.DiscardUndoToNewFileAction);
registerAction2(interactiveEditorActions.CancelSessionAction);

registerAction2(interactiveEditorActions.ArrowOutUpAction);
registerAction2(interactiveEditorActions.ArrowOutDownAction);
registerAction2(interactiveEditorActions.FocusInteractiveEditor);
Expand All @@ -30,9 +34,6 @@ registerAction2(interactiveEditorActions.ViewInChatAction);
registerAction2(interactiveEditorActions.ExpandMessageAction);
registerAction2(interactiveEditorActions.ContractMessageAction);

registerAction2(interactiveEditorActions.UndoToClipboard);
registerAction2(interactiveEditorActions.UndoToNewFile);
registerAction2(interactiveEditorActions.UndoCommand);
registerAction2(interactiveEditorActions.ToggleInlineDiff);
registerAction2(interactiveEditorActions.FeebackHelpfulCommand);
registerAction2(interactiveEditorActions.FeebackUnhelpfulCommand);
Expand Down
Expand Up @@ -10,7 +10,7 @@ import { EditorAction2 } from 'vs/editor/browser/editorExtensions';
import { EmbeddedCodeEditorWidget, EmbeddedDiffEditorWidget } from 'vs/editor/browser/widget/embeddedCodeEditorWidget';
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
import { InteractiveEditorController, InteractiveEditorRunOptions } from 'vs/workbench/contrib/interactiveEditor/browser/interactiveEditorController';
import { CTX_INTERACTIVE_EDITOR_FOCUSED, CTX_INTERACTIVE_EDITOR_HAS_ACTIVE_REQUEST, CTX_INTERACTIVE_EDITOR_HAS_PROVIDER, CTX_INTERACTIVE_EDITOR_INNER_CURSOR_FIRST, CTX_INTERACTIVE_EDITOR_INNER_CURSOR_LAST, CTX_INTERACTIVE_EDITOR_EMPTY, CTX_INTERACTIVE_EDITOR_OUTER_CURSOR_POSITION, CTX_INTERACTIVE_EDITOR_VISIBLE, MENU_INTERACTIVE_EDITOR_WIDGET, CTX_INTERACTIVE_EDITOR_LAST_EDIT_TYPE, MENU_INTERACTIVE_EDITOR_WIDGET_UNDO, MENU_INTERACTIVE_EDITOR_WIDGET_STATUS, CTX_INTERACTIVE_EDITOR_LAST_FEEDBACK, CTX_INTERACTIVE_EDITOR_INLNE_DIFF, CTX_INTERACTIVE_EDITOR_EDIT_MODE, EditMode, CTX_INTERACTIVE_EDITOR_LAST_RESPONSE_TYPE, MENU_INTERACTIVE_EDITOR_WIDGET_MARKDOWN_MESSAGE, CTX_INTERACTIVE_EDITOR_MESSAGE_CROP_STATE, CTX_INTERACTIVE_EDITOR_DOCUMENT_CHANGED } from 'vs/workbench/contrib/interactiveEditor/common/interactiveEditor';
import { CTX_INTERACTIVE_EDITOR_FOCUSED, CTX_INTERACTIVE_EDITOR_HAS_ACTIVE_REQUEST, CTX_INTERACTIVE_EDITOR_HAS_PROVIDER, CTX_INTERACTIVE_EDITOR_INNER_CURSOR_FIRST, CTX_INTERACTIVE_EDITOR_INNER_CURSOR_LAST, CTX_INTERACTIVE_EDITOR_EMPTY, CTX_INTERACTIVE_EDITOR_OUTER_CURSOR_POSITION, CTX_INTERACTIVE_EDITOR_VISIBLE, MENU_INTERACTIVE_EDITOR_WIDGET, MENU_INTERACTIVE_EDITOR_WIDGET_DISCARD, MENU_INTERACTIVE_EDITOR_WIDGET_STATUS, CTX_INTERACTIVE_EDITOR_LAST_FEEDBACK, CTX_INTERACTIVE_EDITOR_INLNE_DIFF, CTX_INTERACTIVE_EDITOR_EDIT_MODE, EditMode, CTX_INTERACTIVE_EDITOR_LAST_RESPONSE_TYPE, MENU_INTERACTIVE_EDITOR_WIDGET_MARKDOWN_MESSAGE, CTX_INTERACTIVE_EDITOR_MESSAGE_CROP_STATE, CTX_INTERACTIVE_EDITOR_DOCUMENT_CHANGED, CTX_INTERACTIVE_EDITOR_DID_EDIT } from 'vs/workbench/contrib/interactiveEditor/common/interactiveEditor';
import { localize } from 'vs/nls';
import { IAction2Options } from 'vs/platform/actions/common/actions';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
Expand All @@ -20,7 +20,6 @@ import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegis
import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput';
import { IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService';
import { IUntitledTextResourceEditorInput } from 'vs/workbench/common/editor';
import { ILogService } from 'vs/platform/log/common/log';
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
import { Range } from 'vs/editor/common/core/range';
import { fromNow } from 'vs/base/common/date';
Expand Down Expand Up @@ -251,86 +250,79 @@ export class NextFromHistory extends AbstractInteractiveEditorAction {
}
}


export class UndoToClipboard extends AbstractInteractiveEditorAction {
export class DicardAction extends AbstractInteractiveEditorAction {

constructor() {
super({
id: 'interactiveEditor.undoToClipboard',
title: localize('undo.clipboard', 'Undo to Clipboard'),
precondition: ContextKeyExpr.and(CTX_INTERACTIVE_EDITOR_VISIBLE, CTX_INTERACTIVE_EDITOR_LAST_EDIT_TYPE.isEqualTo('simple')),
keybinding: {
weight: KeybindingWeight.EditorContrib + 10,
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyZ,
mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KeyZ },
},
id: 'interactiveEditor.discard',
title: localize('discard', 'Discard'),
icon: Codicon.discard,
precondition: CTX_INTERACTIVE_EDITOR_VISIBLE,
// keybinding: {
// weight: KeybindingWeight.EditorContrib - 1,
// primary: KeyCode.Escape
// },
menu: {
when: CTX_INTERACTIVE_EDITOR_LAST_EDIT_TYPE.isEqualTo('simple'),
id: MENU_INTERACTIVE_EDITOR_WIDGET_UNDO,
group: '1_undo',
order: 1
id: MENU_INTERACTIVE_EDITOR_WIDGET_DISCARD,
order: 0
}
});
}

override runInteractiveEditorCommand(accessor: ServicesAccessor, ctrl: InteractiveEditorController): void {
const clipboardService = accessor.get(IClipboardService);
const lastText = ctrl.undoLast();
if (lastText !== undefined) {
clipboardService.writeText(lastText);
}
async runInteractiveEditorCommand(_accessor: ServicesAccessor, ctrl: InteractiveEditorController, _editor: ICodeEditor, ..._args: any[]): Promise<void> {
await ctrl.cancelSession();
}
}

export class UndoToNewFile extends AbstractInteractiveEditorAction {
export class DiscardToClipboardAction extends AbstractInteractiveEditorAction {

constructor() {
super({
id: 'interactiveEditor.undoToFile',
title: localize('undo.newfile', 'Undo to New File'),
precondition: ContextKeyExpr.and(CTX_INTERACTIVE_EDITOR_VISIBLE, CTX_INTERACTIVE_EDITOR_LAST_EDIT_TYPE.isEqualTo('simple')),
id: 'interactiveEditor.discardToClipboard',
title: localize('undo.clipboard', 'Discard to Clipboard'),
precondition: ContextKeyExpr.and(CTX_INTERACTIVE_EDITOR_VISIBLE, CTX_INTERACTIVE_EDITOR_DID_EDIT),
// keybinding: {
// weight: KeybindingWeight.EditorContrib + 10,
// primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyZ,
// mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KeyZ },
// },
menu: {
when: CTX_INTERACTIVE_EDITOR_LAST_EDIT_TYPE.isEqualTo('simple'),
id: MENU_INTERACTIVE_EDITOR_WIDGET_UNDO,
group: '1_undo',
order: 2
id: MENU_INTERACTIVE_EDITOR_WIDGET_DISCARD,
order: 1
}
});
}

override runInteractiveEditorCommand(accessor: ServicesAccessor, ctrl: InteractiveEditorController, editor: ICodeEditor, ..._args: any[]): void {
const editorService = accessor.get(IEditorService);
const lastText = ctrl.undoLast();
if (lastText !== undefined) {
const input: IUntitledTextResourceEditorInput = { forceUntitled: true, resource: undefined, contents: lastText, languageId: editor.getModel()?.getLanguageId() };
editorService.openEditor(input, SIDE_GROUP);
override async runInteractiveEditorCommand(accessor: ServicesAccessor, ctrl: InteractiveEditorController): Promise<void> {
const clipboardService = accessor.get(IClipboardService);
const changedText = await ctrl.cancelSession();
if (changedText !== undefined) {
clipboardService.writeText(changedText);
}
}
}

export class UndoCommand extends AbstractInteractiveEditorAction {
export class DiscardUndoToNewFileAction extends AbstractInteractiveEditorAction {

constructor() {
super({
id: 'interactiveEditor.undo',
title: localize('undo', 'Undo'),
icon: Codicon.commentDiscussion,
precondition: ContextKeyExpr.and(CTX_INTERACTIVE_EDITOR_VISIBLE, CTX_INTERACTIVE_EDITOR_LAST_EDIT_TYPE.isEqualTo('simple')),
// keybinding: {
// weight: KeybindingWeight.EditorContrib + 10,
// primary: KeyMod.CtrlCmd | KeyCode.KeyZ,
// },
id: 'interactiveEditor.discardToFile',
title: localize('undo.newfile', 'Discard to New File'),
precondition: ContextKeyExpr.and(CTX_INTERACTIVE_EDITOR_VISIBLE, CTX_INTERACTIVE_EDITOR_DID_EDIT),
menu: {
when: CTX_INTERACTIVE_EDITOR_LAST_EDIT_TYPE.isEqualTo('simple'),
id: MENU_INTERACTIVE_EDITOR_WIDGET_UNDO,
group: '1_undo',
order: 3
id: MENU_INTERACTIVE_EDITOR_WIDGET_DISCARD,
order: 2
}
});
}

override runInteractiveEditorCommand(_accessor: ServicesAccessor, ctrl: InteractiveEditorController): void {
ctrl.undoLast();
override async runInteractiveEditorCommand(accessor: ServicesAccessor, ctrl: InteractiveEditorController, editor: ICodeEditor, ..._args: any[]): Promise<void> {
const editorService = accessor.get(IEditorService);
const changedText = await ctrl.cancelSession();
if (changedText !== undefined) {
const input: IUntitledTextResourceEditorInput = { forceUntitled: true, resource: undefined, contents: changedText, languageId: editor.getModel()?.getLanguageId() };
editorService.openEditor(input, SIDE_GROUP);
}
}
}

Expand Down Expand Up @@ -409,30 +401,25 @@ export class ApplyPreviewEdits extends AbstractInteractiveEditorAction {
title: localize('applyEdits', 'Apply Changes'),
icon: Codicon.check,
precondition: ContextKeyExpr.and(CTX_INTERACTIVE_EDITOR_VISIBLE, ContextKeyExpr.or(CTX_INTERACTIVE_EDITOR_DOCUMENT_CHANGED.toNegated(), CTX_INTERACTIVE_EDITOR_EDIT_MODE.notEqualsTo(EditMode.Preview))),
keybinding: {
keybinding: [{
weight: KeybindingWeight.EditorContrib + 10,
primary: KeyMod.CtrlCmd | KeyCode.Enter
},
primary: KeyMod.CtrlCmd | KeyCode.Enter,
}, {
weight: KeybindingWeight.EditorContrib + 10,
primary: KeyCode.Escape,
when: CTX_INTERACTIVE_EDITOR_EDIT_MODE.notEqualsTo(EditMode.Preview)
}],
menu: {
id: MENU_INTERACTIVE_EDITOR_WIDGET_STATUS,
when: CTX_INTERACTIVE_EDITOR_EDIT_MODE.isEqualTo(EditMode.Preview),
group: '0_main',
order: 0
}
});
}

override async runInteractiveEditorCommand(accessor: ServicesAccessor, ctrl: InteractiveEditorController): Promise<void> {
const logService = accessor.get(ILogService);
const editorService = accessor.get(IEditorService);
const edit = await ctrl.applyChanges();
if (!edit) {
logService.warn('FAILED to apply changes, no edit response');
return;
}
if (edit.singleCreateFileEdit) {
editorService.openEditor({ resource: edit.singleCreateFileEdit.uri }, SIDE_GROUP);
}

override async runInteractiveEditorCommand(_accessor: ServicesAccessor, ctrl: InteractiveEditorController): Promise<void> {
await ctrl.applyChanges();
}
}

Expand All @@ -441,15 +428,16 @@ export class CancelSessionAction extends AbstractInteractiveEditorAction {
constructor() {
super({
id: 'interactiveEditor.cancel',
title: localize('discard', 'Discard Changes'),
title: localize('cancel', 'Cancel'),
icon: Codicon.clearAll,
precondition: CTX_INTERACTIVE_EDITOR_VISIBLE,
precondition: ContextKeyExpr.and(CTX_INTERACTIVE_EDITOR_VISIBLE, CTX_INTERACTIVE_EDITOR_EDIT_MODE.isEqualTo(EditMode.Preview)),
keybinding: {
weight: KeybindingWeight.EditorContrib - 1,
primary: KeyCode.Escape
},
menu: {
id: MENU_INTERACTIVE_EDITOR_WIDGET_STATUS,
when: CTX_INTERACTIVE_EDITOR_EDIT_MODE.isEqualTo(EditMode.Preview),
group: '0_main',
order: 1
}
Expand All @@ -468,7 +456,8 @@ export class CopyRecordings extends AbstractInteractiveEditorAction {
id: 'interactiveEditor.copyRecordings',
f1: true,
title: {
value: localize('copyRecordings', '(Developer) Write Exchange to Clipboard'), original: '(Developer) Write Exchange to Clipboard'
value: localize('copyRecordings', '(Developer) Write Exchange to Clipboard'),
original: '(Developer) Write Exchange to Clipboard'
}
});
}
Expand Down