mirror of
https://github.com/Microsoft/vscode
synced 2024-10-30 13:10:43 +00:00
extract some parts into preview and live strategies
This commit is contained in:
parent
9567c0cea0
commit
bb08d3697e
3 changed files with 123 additions and 47 deletions
|
@ -124,25 +124,6 @@ export class StopRequestAction extends AbstractInteractiveEditorAction {
|
|||
}
|
||||
}
|
||||
|
||||
export class CancelSessionAction extends AbstractInteractiveEditorAction {
|
||||
|
||||
constructor() {
|
||||
super({
|
||||
id: 'interactiveEditor.cancel',
|
||||
title: localize('cancel', 'Cancel'),
|
||||
precondition: CTX_INTERACTIVE_EDITOR_VISIBLE,
|
||||
keybinding: {
|
||||
weight: KeybindingWeight.EditorContrib - 1,
|
||||
primary: KeyCode.Escape
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
runInteractiveEditorCommand(_accessor: ServicesAccessor, ctrl: InteractiveEditorController, _editor: ICodeEditor, ..._args: any[]): void {
|
||||
ctrl.cancelSession();
|
||||
}
|
||||
}
|
||||
|
||||
export class ArrowOutUpAction extends AbstractInteractiveEditorAction {
|
||||
constructor() {
|
||||
super({
|
||||
|
@ -380,7 +361,7 @@ export class ToggleInlineDiff extends AbstractInteractiveEditorAction {
|
|||
id: MENU_INTERACTIVE_EDITOR_WIDGET_STATUS,
|
||||
when: CTX_INTERACTIVE_EDITOR_EDIT_MODE.isEqualTo('direct'),
|
||||
group: '0_main',
|
||||
order: 1
|
||||
order: 10
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -397,10 +378,14 @@ export class ApplyPreviewEdits extends AbstractInteractiveEditorAction {
|
|||
id: 'interactiveEditor.applyEdits',
|
||||
title: localize('applyEdits', 'Apply Changes'),
|
||||
icon: Codicon.check,
|
||||
precondition: ContextKeyExpr.and(CTX_INTERACTIVE_EDITOR_VISIBLE, CTX_INTERACTIVE_EDITOR_EDIT_MODE.isEqualTo('preview')),
|
||||
precondition: ContextKeyExpr.and(CTX_INTERACTIVE_EDITOR_VISIBLE),
|
||||
keybinding: {
|
||||
weight: KeybindingWeight.EditorContrib + 10,
|
||||
primary: KeyMod.CtrlCmd | KeyCode.Enter
|
||||
},
|
||||
menu: {
|
||||
id: MENU_INTERACTIVE_EDITOR_WIDGET_STATUS,
|
||||
when: CTX_INTERACTIVE_EDITOR_EDIT_MODE.isEqualTo('preview'),
|
||||
// when: CTX_INTERACTIVE_EDITOR_EDIT_MODE.isEqualTo('preview'),
|
||||
group: '0_main',
|
||||
order: 0
|
||||
}
|
||||
|
@ -415,7 +400,6 @@ export class ApplyPreviewEdits extends AbstractInteractiveEditorAction {
|
|||
logService.warn('FAILED to apply changes, no edit response');
|
||||
return;
|
||||
}
|
||||
ctrl.cancelSession();
|
||||
if (edit.singleCreateFileEdit) {
|
||||
editorService.openEditor({ resource: edit.singleCreateFileEdit.uri }, SIDE_GROUP);
|
||||
}
|
||||
|
@ -423,6 +407,32 @@ export class ApplyPreviewEdits extends AbstractInteractiveEditorAction {
|
|||
}
|
||||
}
|
||||
|
||||
export class CancelSessionAction extends AbstractInteractiveEditorAction {
|
||||
|
||||
constructor() {
|
||||
super({
|
||||
id: 'interactiveEditor.cancel',
|
||||
title: localize('cancel', 'Cancel'),
|
||||
icon: Codicon.clearAll,
|
||||
precondition: CTX_INTERACTIVE_EDITOR_VISIBLE,
|
||||
keybinding: {
|
||||
weight: KeybindingWeight.EditorContrib - 1,
|
||||
primary: KeyCode.Escape
|
||||
},
|
||||
menu: {
|
||||
id: MENU_INTERACTIVE_EDITOR_WIDGET_STATUS,
|
||||
// when: CTX_INTERACTIVE_EDITOR_EDIT_MODE.isEqualTo('preview'),
|
||||
group: '0_main',
|
||||
order: 1
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
runInteractiveEditorCommand(_accessor: ServicesAccessor, ctrl: InteractiveEditorController, _editor: ICodeEditor, ..._args: any[]): void {
|
||||
ctrl.cancelSession();
|
||||
}
|
||||
}
|
||||
|
||||
export class CopyRecordings extends AbstractInteractiveEditorAction {
|
||||
|
||||
constructor() {
|
||||
|
|
|
@ -225,7 +225,7 @@ class LastEditorState {
|
|||
) { }
|
||||
}
|
||||
|
||||
type EditMode = 'preview' | 'livePreview' | 'direct';
|
||||
type EditMode = 'live' | 'livePreview' | 'preview';
|
||||
|
||||
export class InteractiveEditorController implements IEditorContribution {
|
||||
|
||||
|
@ -261,6 +261,7 @@ export class InteractiveEditorController implements IEditorContribution {
|
|||
private readonly _ctxLastFeedbackKind: IContextKey<'helpful' | 'unhelpful' | ''>;
|
||||
|
||||
private _lastEditState?: LastEditorState;
|
||||
private _strategy?: LiveStrategy | PreviewStrategy;
|
||||
private _lastInlineDecorations?: InlineDiffDecorations;
|
||||
private _inlineDiffEnabled: boolean = false;
|
||||
|
||||
|
@ -271,7 +272,6 @@ export class InteractiveEditorController implements IEditorContribution {
|
|||
private readonly _editor: ICodeEditor,
|
||||
@IInstantiationService private readonly _instaService: IInstantiationService,
|
||||
@IInteractiveEditorService private readonly _interactiveEditorService: IInteractiveEditorService,
|
||||
@IBulkEditService private readonly _bulkEditService: IBulkEditService,
|
||||
@IEditorWorkerService private readonly _editorWorkerService: IEditorWorkerService,
|
||||
@ILogService private readonly _logService: ILogService,
|
||||
@ITelemetryService private readonly _telemetryService: ITelemetryService,
|
||||
|
@ -299,9 +299,13 @@ export class InteractiveEditorController implements IEditorContribution {
|
|||
return InteractiveEditorController.ID;
|
||||
}
|
||||
|
||||
private _getMode(): EditMode {
|
||||
return this._configurationService.getValue('interactiveEditor.editMode');
|
||||
}
|
||||
|
||||
async run(initialRange?: Range): Promise<void> {
|
||||
|
||||
const editMode: EditMode = this._configurationService.getValue('interactiveEditor.editMode');
|
||||
const editMode = this._getMode();
|
||||
|
||||
this._ctsSession.dispose(true);
|
||||
|
||||
|
@ -336,6 +340,8 @@ export class InteractiveEditorController implements IEditorContribution {
|
|||
undos: ''
|
||||
};
|
||||
|
||||
this._strategy = this._instaService.createInstance(editMode === 'preview' ? PreviewStrategy : LiveStrategy, textModel, textModel.getAlternativeVersionId());
|
||||
|
||||
this._inlineDiffEnabled = this._storageService.getBoolean(InteractiveEditorController._inlineDiffStorageKey, StorageScope.PROFILE, false);
|
||||
const inlineDiffDecorations = new InlineDiffDecorations(this._editor, this._inlineDiffEnabled);
|
||||
this._lastInlineDecorations = inlineDiffDecorations;
|
||||
|
@ -525,9 +531,8 @@ export class InteractiveEditorController implements IEditorContribution {
|
|||
|
||||
const editResponse = new EditResponse(textModel.uri, reply);
|
||||
|
||||
if (editResponse.workspaceEdits && (!editResponse.singleCreateFileEdit || editMode === 'direct')) {
|
||||
this._bulkEditService.apply(editResponse.workspaceEdits, { editor: this._editor, label: localize('ie', "{0}", input), showPreview: true });
|
||||
// todo@jrieken keep interactive editor?
|
||||
const canContinue = this._strategy.update(editResponse);
|
||||
if (!canContinue) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -583,7 +588,9 @@ export class InteractiveEditorController implements IEditorContribution {
|
|||
ignoreModelChanges = false;
|
||||
}
|
||||
|
||||
inlineDiffDecorations.update();
|
||||
if (editMode === 'live') {
|
||||
inlineDiffDecorations.update();
|
||||
}
|
||||
|
||||
// line count
|
||||
const lineSet = new Set<number>();
|
||||
|
@ -664,10 +671,6 @@ export class InteractiveEditorController implements IEditorContribution {
|
|||
this._ctsRequest?.cancel();
|
||||
}
|
||||
|
||||
cancelSession() {
|
||||
this._ctsSession.cancel();
|
||||
}
|
||||
|
||||
arrowOut(up: boolean): void {
|
||||
if (this._zone.position && this._editor.hasModel()) {
|
||||
const { column } = this._editor.getPosition();
|
||||
|
@ -730,22 +733,87 @@ export class InteractiveEditorController implements IEditorContribution {
|
|||
if (!this._lastEditState) {
|
||||
return undefined;
|
||||
}
|
||||
const { response } = this._lastEditState;
|
||||
await this._strategy?.apply();
|
||||
this._ctsSession.cancel();
|
||||
return response;
|
||||
}
|
||||
|
||||
const { model, modelVersionId, response } = this._lastEditState;
|
||||
cancelSession() {
|
||||
this._ctsSession.cancel();
|
||||
this._strategy?.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
class PreviewStrategy {
|
||||
|
||||
private _lastResponse?: EditResponse;
|
||||
|
||||
constructor(
|
||||
private readonly _model: ITextModel,
|
||||
private readonly _versionId: number,
|
||||
@IBulkEditService private readonly _bulkEditService: IBulkEditService,
|
||||
) { }
|
||||
|
||||
update(response: EditResponse): boolean {
|
||||
this._lastResponse = response;
|
||||
if (!response.workspaceEdits || response.singleCreateFileEdit) {
|
||||
// preview stategy can handle simple workspace edit (single file create)
|
||||
return true;
|
||||
}
|
||||
this._bulkEditService.apply(response.workspaceEdits, { showPreview: true });
|
||||
return false;
|
||||
}
|
||||
|
||||
async apply() {
|
||||
|
||||
const response = this._lastResponse;
|
||||
if (!response) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (response.workspaceEdits) {
|
||||
await this._bulkEditService.apply(response.workspaceEdits);
|
||||
|
||||
} else if (!response.workspaceEditsIncludeLocalEdits) {
|
||||
if (model.getAlternativeVersionId() === modelVersionId) {
|
||||
model.pushStackElement();
|
||||
if (this._model.getAlternativeVersionId() === this._versionId) {
|
||||
this._model.pushStackElement();
|
||||
const edits = response.localEdits.map(edit => EditOperation.replace(Range.lift(edit.range), edit.text));
|
||||
model.pushEditOperations(null, edits, () => null);
|
||||
model.pushStackElement();
|
||||
this._model.pushEditOperations(null, edits, () => null);
|
||||
this._model.pushStackElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return response;
|
||||
cancel(): void {
|
||||
// nothing to do
|
||||
}
|
||||
}
|
||||
|
||||
class LiveStrategy {
|
||||
|
||||
constructor(
|
||||
private readonly _model: ITextModel,
|
||||
private readonly _versionId: number,
|
||||
@IBulkEditService private readonly _bulkEditService: IBulkEditService,
|
||||
) { }
|
||||
|
||||
update(response: EditResponse): boolean {
|
||||
if (response.workspaceEdits) {
|
||||
this._bulkEditService.apply(response.workspaceEdits, { showPreview: true });
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
async apply() {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
cancel(): void {
|
||||
while (this._model.getAlternativeVersionId() !== this._versionId) {
|
||||
this._model.undo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ import { ITextModel } from 'vs/editor/common/model';
|
|||
import { localize } from 'vs/nls';
|
||||
import { MenuId, MenuRegistry } from 'vs/platform/actions/common/actions';
|
||||
import { Extensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { ContextKeyExpr, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { RawContextKey } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { editorHoverHighlight, editorWidgetBorder, focusBorder, inputBackground, inputPlaceholderForeground, registerColor, widgetShadow } from 'vs/platform/theme/common/colorRegistry';
|
||||
|
@ -105,9 +105,7 @@ export const CTX_INTERACTIVE_EDITOR_HAS_RESPONSE = new RawContextKey<boolean>('i
|
|||
export const CTX_INTERACTIVE_EDITOR_INLNE_DIFF = new RawContextKey<boolean>('interactiveEditorInlineDiff', false, localize('interactiveEditorInlineDiff', "Whether interactive editor show inline diffs for changes"));
|
||||
export const CTX_INTERACTIVE_EDITOR_LAST_EDIT_TYPE = new RawContextKey<'simple' | ''>('interactiveEditorLastEditKind', '', localize('interactiveEditorLastEditKind', "The last kind of edit that was performed"));
|
||||
export const CTX_INTERACTIVE_EDITOR_LAST_FEEDBACK = new RawContextKey<'unhelpful' | 'helpful' | ''>('interactiveEditorLastFeedbackKind', '', localize('interactiveEditorLastFeedbackKind', "The last kind of feedback that was provided"));
|
||||
|
||||
export const CTX_VALUE_INTERACTIVE_EDITOR_EDIT_MODE_YOLO = ContextKeyExpr.equals('config.interactiveEditor.editMode', 'direct');
|
||||
export const CTX_INTERACTIVE_EDITOR_EDIT_MODE = new RawContextKey<'direct' | 'preview'>('config.interactiveEditor.editMode', 'direct');
|
||||
export const CTX_INTERACTIVE_EDITOR_EDIT_MODE = new RawContextKey<'live' | 'livePreview' | 'preview'>('config.interactiveEditor.editMode', 'live');
|
||||
|
||||
// --- menus
|
||||
|
||||
|
@ -119,7 +117,7 @@ MenuRegistry.appendMenuItem(MENU_INTERACTIVE_EDITOR_WIDGET_STATUS, {
|
|||
title: localize('undo', "Undo..."),
|
||||
icon: Codicon.discard,
|
||||
group: '0_main',
|
||||
order: 0,
|
||||
order: 2,
|
||||
when: CTX_INTERACTIVE_EDITOR_EDIT_MODE.isEqualTo('direct')
|
||||
});
|
||||
|
||||
|
@ -140,9 +138,9 @@ Registry.as<IConfigurationRegistry>(Extensions.Configuration).registerConfigurat
|
|||
properties: {
|
||||
'interactiveEditor.editMode': {
|
||||
description: localize('editMode', "Configure if changes crafted in the interactive editor are applied directly or previewed first"),
|
||||
default: 'direct',
|
||||
default: 'live',
|
||||
type: 'string',
|
||||
enum: ['preview', 'livePreview', 'direct']
|
||||
enum: ['live', 'livePreview', 'preview']
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue