mirror of
https://github.com/Microsoft/vscode
synced 2024-08-27 21:09:43 +00:00
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:
parent
402b28f04a
commit
ce729a5a1a
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue