Skip to content

Commit e6a4f1b

Browse files
authored
separate added/removed lines (#260626)
1 parent 7721b26 commit e6a4f1b

File tree

5 files changed

+37
-9
lines changed

5 files changed

+37
-9
lines changed

src/vs/workbench/api/common/extHostTypeConverters.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3336,7 +3336,9 @@ export namespace ChatAgentUserActionEvent {
33363336
outcome: outcomes.get(event.action.outcome) ?? types.ChatEditingSessionActionOutcome.Rejected,
33373337
uri: URI.revive(event.action.uri),
33383338
hasRemainingEdits: event.action.hasRemainingEdits,
3339-
lineCount: event.action.lineCount
3339+
lineCount: event.action.lineCount,
3340+
linesAdded: event.action.linesAdded,
3341+
linesRemoved: event.action.linesRemoved
33403342
}, result: ehResult
33413343
};
33423344
} else {

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,12 @@ export class ChatEditingModifiedDocumentEntry extends AbstractChatEditingModifie
103103
}));
104104

105105
this._register(this._textModelChangeService.onDidAcceptOrRejectLines(action => {
106-
this._notifyAction({ kind: 'chatEditingHunkAction', uri: this.modifiedURI, outcome: action.state, lineCount: action.lineCount, hasRemainingEdits: action.hasRemainingEdits });
106+
this._notifyAction({
107+
kind: 'chatEditingHunkAction',
108+
uri: this.modifiedURI,
109+
outcome: action.state,
110+
...action
111+
});
107112
}));
108113

109114
// Create a reference to this model to avoid it being disposed from under our nose

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

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ import { IChatResponseModel } from '../../common/chatModel.js';
3333
import { IDocumentDiff2 } from './chatEditingCodeEditorIntegration.js';
3434
import { pendingRewriteMinimap } from './chatEditingModifiedFileEntry.js';
3535

36-
type acceptedOrRejectedLines = { state: 'accepted' | 'rejected'; lineCount: number; hasRemainingEdits: boolean };
36+
type affectedLines = { linesAdded: number; linesRemoved: number; lineCount: number; hasRemainingEdits: boolean };
37+
type acceptedOrRejectedLines = affectedLines & { state: 'accepted' | 'rejected' };
3738

3839
export class ChatEditingTextModelChangeService extends Disposable {
3940

@@ -101,9 +102,9 @@ export class ChatEditingTextModelChangeService extends Disposable {
101102
private readonly _didAcceptOrRejectLines = this._register(new Emitter<acceptedOrRejectedLines>());
102103
public readonly onDidAcceptOrRejectLines = this._didAcceptOrRejectLines.event;
103104

104-
private notifyHunkAction(state: 'accepted' | 'rejected', lineCount: number, hasRemainingEdits: boolean) {
105-
if (lineCount > 0) {
106-
this._didAcceptOrRejectLines.fire({ state, lineCount, hasRemainingEdits });
105+
private notifyHunkAction(state: 'accepted' | 'rejected', affectedLines: affectedLines) {
106+
if (affectedLines.lineCount > 0) {
107+
this._didAcceptOrRejectLines.fire({ state, ...affectedLines });
107108
}
108109
}
109110

@@ -113,6 +114,8 @@ export class ChatEditingTextModelChangeService extends Disposable {
113114
private _originalToModifiedEdit: StringEdit = StringEdit.empty;
114115

115116
private lineChangeCount: number = 0;
117+
private linesAdded: number = 0;
118+
private linesRemoved: number = 0;
116119

117120
constructor(
118121
private readonly originalModel: ITextModel,
@@ -135,9 +138,15 @@ export class ChatEditingTextModelChangeService extends Disposable {
135138

136139
private updateLineChangeCount(diff: IDocumentDiff) {
137140
this.lineChangeCount = 0;
141+
this.linesAdded = 0;
142+
this.linesRemoved = 0;
143+
138144
for (const change of diff.changes) {
139145
const modifiedRange = change.modified.endLineNumberExclusive - change.modified.startLineNumber;
146+
this.linesAdded += Math.max(0, modifiedRange);
140147
const originalRange = change.original.endLineNumberExclusive - change.original.startLineNumber;
148+
this.linesRemoved += Math.max(0, originalRange);
149+
141150
this.lineChangeCount += Math.max(modifiedRange, originalRange);
142151
}
143152
}
@@ -257,7 +266,7 @@ export class ChatEditingTextModelChangeService extends Disposable {
257266
* Keeps the current modified document as the final contents.
258267
*/
259268
public keep() {
260-
this.notifyHunkAction('accepted', this.lineChangeCount, false);
269+
this.notifyHunkAction('accepted', { linesAdded: this.linesAdded, linesRemoved: this.linesRemoved, lineCount: this.lineChangeCount, hasRemainingEdits: false });
261270
this.originalModel.setValue(this.modifiedModel.createSnapshot());
262271
this._diffInfo.set(nullDocumentDiff, undefined);
263272
this._originalToModifiedEdit = StringEdit.empty;
@@ -267,7 +276,7 @@ export class ChatEditingTextModelChangeService extends Disposable {
267276
* Undoes the current modified document as the final contents.
268277
*/
269278
public undo() {
270-
this.notifyHunkAction('rejected', this.lineChangeCount, false);
279+
this.notifyHunkAction('rejected', { linesAdded: this.linesAdded, linesRemoved: this.linesRemoved, lineCount: this.lineChangeCount, hasRemainingEdits: false });
271280
this.modifiedModel.pushStackElement();
272281
this._applyEdits([(EditOperation.replace(this.modifiedModel.getFullModelRange(), this.originalModel.getValue()))], EditSources.chatUndoEdits());
273282
this.modifiedModel.pushStackElement();
@@ -379,12 +388,20 @@ export class ChatEditingTextModelChangeService extends Disposable {
379388
const myDiffOperationId = ++this._diffOperationIds;
380389
await Promise.resolve(this._diffOperation);
381390
const previousCount = this.lineChangeCount;
391+
const previousAdded = this.linesAdded;
392+
const previousRemoved = this.linesRemoved;
382393
if (this._diffOperationIds === myDiffOperationId) {
383394
const thisDiffOperation = this._updateDiffInfo();
384395
this._diffOperation = thisDiffOperation;
385396
await thisDiffOperation;
386397
if (notifyAction) {
387-
this.notifyHunkAction(notifyAction, previousCount - this.lineChangeCount, this.lineChangeCount > 0);
398+
const affectedLines = {
399+
linesAdded: previousAdded - this.linesAdded,
400+
linesRemoved: previousRemoved - this.linesRemoved,
401+
lineCount: previousCount - this.lineChangeCount,
402+
hasRemainingEdits: this.lineChangeCount > 0
403+
};
404+
this.notifyHunkAction(notifyAction, affectedLines);
388405
}
389406
}
390407
}

src/vs/workbench/contrib/chat/common/chatService.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,8 @@ export interface IChatEditingHunkAction {
525525
kind: 'chatEditingHunkAction';
526526
uri: URI;
527527
lineCount: number;
528+
linesAdded: number;
529+
linesRemoved: number;
528530
outcome: 'accepted' | 'rejected';
529531
hasRemainingEdits: boolean;
530532
}

src/vscode-dts/vscode.proposed.chatParticipantAdditions.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,8 @@ declare module 'vscode' {
553553
kind: 'chatEditingHunkAction';
554554
uri: Uri;
555555
lineCount: number;
556+
linesAdded: number;
557+
linesRemoved: number;
556558
outcome: ChatEditingSessionActionOutcome;
557559
hasRemainingEdits: boolean;
558560
}

0 commit comments

Comments
 (0)