Skip to content

Commit

Permalink
use undo-loop instead of undo-edit when discarding chat session (#184063
Browse files Browse the repository at this point in the history
)

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

fixes microsoft/vscode-internalbacklog#4118

* fix tests, wait for correct state
  • Loading branch information
jrieken committed Jun 1, 2023
1 parent 402b28f commit ce729a5
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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,
Expand All @@ -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(),
Expand Down Expand Up @@ -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 {
Expand All @@ -119,7 +122,7 @@ export class Session {
}

createSnapshot(): void {
this._lastSnapshot = this.textModelN.createSnapshot();
this._textModelNSnapshotAltVersion = this.textModelN.getAlternativeVersionId();
}

addExchange(exchange: SessionExchange): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -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();
}
}

Expand Down
14 changes: 1 addition & 13 deletions src/vs/workbench/contrib/interactiveEditor/browser/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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;
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit ce729a5

Please sign in to comment.