use undo-loop instead of undo-edit when discarding chat session (#184063)

* use undo-loop instead of undo-edit when discarding chat session

fixes https://github.com/microsoft/vscode-internalbacklog/issues/4118

* fix tests, wait for correct state
This commit is contained in:
Johannes Rieken 2023-06-01 16:22:31 +02:00 committed by GitHub
parent 402b28f04a
commit ce729a5a1a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 15 additions and 32 deletions

View file

@ -8,7 +8,7 @@ import { URI } from 'vs/base/common/uri';
import { Event } from 'vs/base/common/event';
import { ResourceEdit, ResourceFileEdit, ResourceTextEdit } from 'vs/editor/browser/services/bulkEditService';
import { TextEdit } from 'vs/editor/common/languages';
import { ITextModel, ITextSnapshot } from 'vs/editor/common/model';
import { ITextModel } from 'vs/editor/common/model';
import { EditMode, IInteractiveEditorSessionProvider, IInteractiveEditorSession, IInteractiveEditorBulkEditResponse, IInteractiveEditorEditResponse, IInteractiveEditorMessageResponse, IInteractiveEditorResponse, IInteractiveEditorService } from 'vs/workbench/contrib/interactiveEditor/common/interactiveEditor';
import { IRange, Range } from 'vs/editor/common/core/range';
import { IActiveCodeEditor, ICodeEditor } from 'vs/editor/browser/editorBrowser';
@ -60,12 +60,14 @@ export class Session {
private _lastInput: string | undefined;
private _lastExpansionState: boolean | undefined;
private _lastTextModelChanges: LineRangeMapping[] | undefined;
private _lastSnapshot: ITextSnapshot | undefined;
private _isUnstashed: boolean = false;
private readonly _exchange: SessionExchange[] = [];
private readonly _startTime = new Date();
private readonly _teldata: Partial<TelemetryData>;
readonly textModelNAltVersion: number;
private _textModelNSnapshotAltVersion: number | undefined;
constructor(
readonly editMode: EditMode,
readonly editor: ICodeEditor,
@ -75,6 +77,7 @@ export class Session {
readonly session: IInteractiveEditorSession,
private readonly _wholeRangeMarkerId: string
) {
this.textModelNAltVersion = textModelN.getAlternativeVersionId();
this._teldata = {
extension: provider.debugName,
startTime: this._startTime.toISOString(),
@ -109,8 +112,8 @@ export class Session {
this._lastExpansionState = state;
}
get lastSnapshot(): ITextSnapshot | undefined {
return this._lastSnapshot;
get textModelNSnapshotAltVersion(): number | undefined {
return this._textModelNSnapshotAltVersion;
}
get wholeRange(): Range {
@ -119,7 +122,7 @@ export class Session {
}
createSnapshot(): void {
this._lastSnapshot = this.textModelN.createSnapshot();
this._textModelNSnapshotAltVersion = this.textModelN.getAlternativeVersionId();
}
addExchange(exchange: SessionExchange): void {

View file

@ -24,7 +24,6 @@ import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storag
import { InteractiveEditorFileCreatePreviewWidget, InteractiveEditorLivePreviewWidget } from 'vs/workbench/contrib/interactiveEditor/browser/interactiveEditorLivePreviewWidget';
import { EditResponse, Session } from 'vs/workbench/contrib/interactiveEditor/browser/interactiveEditorSession';
import { InteractiveEditorWidget } from 'vs/workbench/contrib/interactiveEditor/browser/interactiveEditorWidget';
import { getValueFromSnapshot } from 'vs/workbench/contrib/interactiveEditor/browser/utils';
import { CTX_INTERACTIVE_EDITOR_SHOWING_DIFF, CTX_INTERACTIVE_EDITOR_DOCUMENT_CHANGED } from 'vs/workbench/contrib/interactiveEditor/common/interactiveEditor';
import { IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService';
@ -278,19 +277,13 @@ export class LiveStrategy extends EditModeStrategy {
}
async cancel() {
const { textModelN: modelN, textModel0: model0, lastSnapshot } = this._session;
if (modelN.isDisposed() || (model0.isDisposed() && !lastSnapshot)) {
const { textModelN: modelN, textModelNAltVersion, textModelNSnapshotAltVersion } = this._session;
if (modelN.isDisposed()) {
return;
}
const newText = lastSnapshot
? getValueFromSnapshot(lastSnapshot)
: model0.getValue();
const edits = await this._editorWorkerService.computeMoreMinimalEdits(modelN.uri, [{ range: modelN.getFullModelRange(), text: newText }]);
if (edits) {
const operations = edits.map(e => EditOperation.replace(Range.lift(e.range), e.text));
modelN.pushEditOperations(null, operations, () => null);
const targetAltVersion = textModelNSnapshotAltVersion ?? textModelNAltVersion;
while (targetAltVersion < modelN.getAlternativeVersionId() && modelN.canUndo()) {
modelN.undo();
}
}

View file

@ -5,7 +5,7 @@
import { LineRange } from 'vs/editor/common/core/lineRange';
import { Range } from 'vs/editor/common/core/range';
import { ITextModel, ITextSnapshot } from 'vs/editor/common/model';
import { ITextModel } from 'vs/editor/common/model';
export function invertLineRange(range: LineRange, model: ITextModel): LineRange[] {
if (range.isEmpty) {
@ -20,15 +20,3 @@ export function invertLineRange(range: LineRange, model: ITextModel): LineRange[
export function lineRangeAsRange(r: LineRange): Range {
return new Range(r.startLineNumber, 1, r.endLineNumberExclusive - 1, 1);
}
export function getValueFromSnapshot(snapshot: ITextSnapshot): string {
let result = '';
while (true) {
const chunk = snapshot.read();
if (chunk === null) {
break;
}
result += chunk;
}
return result;
}

View file

@ -115,9 +115,8 @@ suite('InteractiveEditorController', function () {
ctrl = instaService.createInstance(TestController, editor);
const run = ctrl.run({ message: 'Hello', autoSend: true });
await Event.toPromise(Event.filter(ctrl.onDidChangeState, e => e === State.SHOW_RESPONSE));
await Event.toPromise(Event.filter(ctrl.onDidChangeState, e => e === State.WAIT_FOR_INPUT));
assert.ok(ctrl.getWidgetPosition() !== undefined);
await ctrl.cancelSession();
await run;