Skip to content

Commit 05ab239

Browse files
author
amunger
committed
wait for diffing to stop before initializing, fix indexing
1 parent 222fa26 commit 05ab239

File tree

2 files changed

+34
-31
lines changed

2 files changed

+34
-31
lines changed

src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingModifiedNotebookEntry.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,12 @@ export class ChatEditingModifiedNotebookEntry extends AbstractChatEditingModifie
6666
*/
6767
override initialContent: string;
6868
/**
69-
* Whether we're in the process of applying edits.
69+
* Whether we're still generating diffs from a response.
7070
*/
71+
private _isProcessingResponse = observableValue<boolean>('isProcessingResponse', false);
72+
get isProcessingResponse(): IObservable<boolean> {
73+
return this._isProcessingResponse;
74+
}
7175
private _isEditFromUs: boolean = false;
7276
/**
7377
* Whether all edits are from us, e.g. is possible a user has made edits, then this will be false.
@@ -216,6 +220,7 @@ export class ChatEditingModifiedNotebookEntry extends AbstractChatEditingModifie
216220
}
217221
const cellsDiffInfo: CellDiffInfo[] = [];
218222
try {
223+
this._isProcessingResponse.set(true, undefined);
219224
const notebookDiff = await this.notebookEditorWorkerService.computeDiff(this.originalURI, this.modifiedURI);
220225
if (id !== this.computeRequestId) {
221226
return;
@@ -226,6 +231,8 @@ export class ChatEditingModifiedNotebookEntry extends AbstractChatEditingModifie
226231
}
227232
} catch (ex) {
228233
this.loggingService.error('Notebook Chat', 'Error computing diff:\n' + ex);
234+
} finally {
235+
this._isProcessingResponse.set(false, undefined);
229236
}
230237
this.initializeModelsFromDiffImpl(cellsDiffInfo);
231238
}

src/vs/workbench/contrib/chat/browser/chatEditing/notebook/chatEditingNotebookEditorIntegration.ts

+26-30
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import { assertType } from '../../../../../../base/common/types.js';
1111
import { LineRange } from '../../../../../../editor/common/core/lineRange.js';
1212
import { Range } from '../../../../../../editor/common/core/range.js';
1313
import { nullDocumentDiff } from '../../../../../../editor/common/diff/documentDiffProvider.js';
14-
import { PrefixSumComputer } from '../../../../../../editor/common/model/prefixSumComputer.js';
1514
import { localize } from '../../../../../../nls.js';
1615
import { MenuId } from '../../../../../../platform/actions/common/actions.js';
1716
import { IInstantiationService } from '../../../../../../platform/instantiation/common/instantiation.js';
@@ -25,15 +24,16 @@ import { INotebookEditorService } from '../../../../notebook/browser/services/no
2524
import { NotebookCellTextModel } from '../../../../notebook/common/model/notebookCellTextModel.js';
2625
import { NotebookTextModel } from '../../../../notebook/common/model/notebookTextModel.js';
2726
import { ChatAgentLocation, IChatAgentService } from '../../../common/chatAgents.js';
28-
import { IModifiedFileEntry, IModifiedFileEntryChangeHunk, IModifiedFileEntryEditorIntegration } from '../../../common/chatEditingService.js';
27+
import { IModifiedFileEntryChangeHunk, IModifiedFileEntryEditorIntegration } from '../../../common/chatEditingService.js';
2928
import { ChatEditingCodeEditorIntegration, IDocumentDiff2 } from '../chatEditingCodeEditorIntegration.js';
29+
import { ChatEditingModifiedNotebookEntry } from '../chatEditingModifiedNotebookEntry.js';
3030
import { countChanges, ICellDiffInfo, sortCellChanges } from './notebookCellChanges.js';
3131

3232
export class ChatEditingNotebookEditorIntegration extends Disposable implements IModifiedFileEntryEditorIntegration {
3333
private integration: ChatEditingNotebookEditorWidgetIntegration;
3434
private notebookEditor: INotebookEditor;
3535
constructor(
36-
_entry: IModifiedFileEntry,
36+
_entry: ChatEditingModifiedNotebookEntry,
3737
editor: IEditorPane,
3838
notebookModel: NotebookTextModel,
3939
originalModel: NotebookTextModel,
@@ -88,14 +88,12 @@ class ChatEditingNotebookEditorWidgetIntegration extends Disposable implements I
8888
private readonly _currentChange = observableValue<{ change: ICellDiffInfo; index: number } | undefined>(this, undefined);
8989
readonly currentChange: IObservable<{ change: ICellDiffInfo; index: number } | undefined> = this._currentChange;
9090

91-
private diffIndexPrefixSum: PrefixSumComputer = new PrefixSumComputer(new Uint32Array());
92-
9391
private readonly cellEditorIntegrations = new Map<NotebookCellTextModel, { integration: ChatEditingCodeEditorIntegration; diff: ISettableObservable<IDocumentDiff2> }>();
9492

9593
private readonly insertDeleteDecorators: IObservable<{ insertedCellDecorator: NotebookInsertedCellDecorator; deletedCellDecorator: NotebookDeletedCellDecorator } | undefined>;
9694

9795
constructor(
98-
private readonly _entry: IModifiedFileEntry,
96+
private readonly _entry: ChatEditingModifiedNotebookEntry,
9997
private readonly notebookEditor: INotebookEditor,
10098
private readonly notebookModel: NotebookTextModel,
10199
originalModel: NotebookTextModel,
@@ -130,28 +128,15 @@ class ChatEditingNotebookEditorWidgetIntegration extends Disposable implements I
130128
}
131129
}));
132130

133-
// INIT when not streaming anymore, once per request, and when having changes
131+
// INIT when not streaming nor diffing the response anymore, once per request, and when having changes
134132
let lastModifyingRequestId: string | undefined;
135133
this._store.add(autorun(r => {
136134

137135
if (!_entry.isCurrentlyBeingModifiedBy.read(r)
136+
&& !_entry.isProcessingResponse.read(r)
138137
&& lastModifyingRequestId !== _entry.lastModifyingRequestId
139138
&& cellChanges.read(r).some(c => c.type !== 'unchanged' && !c.diff.read(r).identical)
140139
) {
141-
lastModifyingRequestId = _entry.lastModifyingRequestId;
142-
143-
const sortedCellChanges = sortCellChanges(cellChanges.read(r));
144-
const values = new Uint32Array(sortedCellChanges.length);
145-
for (let i = 0; i < sortedCellChanges.length; i++) {
146-
const change = sortedCellChanges[i];
147-
values[i] = change.type === 'insert' ? 1
148-
: change.type === 'delete' ? 1
149-
: change.type === 'modified' ? change.diff.read(r).changes.length
150-
: 0;
151-
}
152-
153-
this.diffIndexPrefixSum = new PrefixSumComputer(values);
154-
155140
this.reveal(true);
156141
}
157142
}));
@@ -224,17 +209,28 @@ class ChatEditingNotebookEditorWidgetIntegration extends Disposable implements I
224209

225210
this._register(autorun(r => {
226211
const currentChange = this.currentChange.read(r);
227-
if (currentChange) {
228-
const indexInChange = currentChange.index;
229-
const cellIndex = currentChange.change.modifiedCellIndex ?? currentChange.change.originalCellIndex;
230-
231-
const changesBeforeCell = cellIndex !== undefined && cellIndex > 0 ?
232-
this.diffIndexPrefixSum.getPrefixSum(cellIndex - 1) : 0;
233-
234-
this._currentIndex.set(changesBeforeCell + indexInChange, undefined);
235-
} else {
212+
if (!currentChange) {
236213
this._currentIndex.set(-1, undefined);
214+
return;
237215
}
216+
217+
let index = 0;
218+
const sortedCellChanges = sortCellChanges(cellChanges.read(r));
219+
for (const change of sortedCellChanges) {
220+
if (currentChange && currentChange.change === change) {
221+
if (change.type === 'modified') {
222+
index += currentChange.index;
223+
}
224+
break;
225+
}
226+
if (change.type === 'insert' || change.type === 'delete') {
227+
index++;
228+
} else if (change.type === 'modified') {
229+
index += change.diff.read(r).changes.length;
230+
}
231+
}
232+
233+
this._currentIndex.set(index, undefined);
238234
}));
239235

240236
this.insertDeleteDecorators = derivedWithStore((r, store) => {

0 commit comments

Comments
 (0)