mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-28 04:23:32 +01:00
uses /edit editor UX for "Apply In Editor" (#237944)
* WIP * uses /edit editor UX for "Apply In Editor" fixes https://github.com/microsoft/vscode-copilot/issues/8577
This commit is contained in:
@@ -12,6 +12,7 @@ import { Emitter, Event } from '../../../../base/common/event.js';
|
||||
import { Lazy } from '../../../../base/common/lazy.js';
|
||||
import { DisposableStore, MutableDisposable, toDisposable } from '../../../../base/common/lifecycle.js';
|
||||
import { MovingAverage } from '../../../../base/common/numbers.js';
|
||||
import { autorun } from '../../../../base/common/observable.js';
|
||||
import { isEqual } from '../../../../base/common/resources.js';
|
||||
import { StopWatch } from '../../../../base/common/stopwatch.js';
|
||||
import { assertType } from '../../../../base/common/types.js';
|
||||
@@ -40,6 +41,7 @@ import { showChatView } from '../../chat/browser/chat.js';
|
||||
import { IChatWidgetLocationOptions } from '../../chat/browser/chatWidget.js';
|
||||
import { ChatAgentLocation } from '../../chat/common/chatAgents.js';
|
||||
import { ChatContextKeys } from '../../chat/common/chatContextKeys.js';
|
||||
import { IChatEditingService, WorkingSetEntryState } from '../../chat/common/chatEditingService.js';
|
||||
import { ChatModel, ChatRequestRemovalReason, IChatRequestModel, IChatTextEditGroup, IChatTextEditGroupState, IResponse } from '../../chat/common/chatModel.js';
|
||||
import { IChatService } from '../../chat/common/chatService.js';
|
||||
import { INotebookEditorService } from '../../notebook/browser/services/notebookEditorService.js';
|
||||
@@ -144,6 +146,7 @@ export class InlineChatController implements IEditorContribution {
|
||||
@IDialogService private readonly _dialogService: IDialogService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@IChatService private readonly _chatService: IChatService,
|
||||
@IChatEditingService private readonly _chatEditingService: IChatEditingService,
|
||||
@IEditorService private readonly _editorService: IEditorService,
|
||||
@INotebookEditorService notebookEditorService: INotebookEditorService,
|
||||
) {
|
||||
@@ -1134,44 +1137,56 @@ export class InlineChatController implements IEditorContribution {
|
||||
return this._currentRun;
|
||||
}
|
||||
|
||||
async reviewEdits(anchor: IRange, stream: AsyncIterable<TextEdit[]>, token: CancellationToken) {
|
||||
async reviewEdits(stream: AsyncIterable<TextEdit[]>, token: CancellationToken) {
|
||||
if (!this._editor.hasModel()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const session = await this._inlineChatSessionService.createSession(this._editor, { wholeRange: anchor, headless: true }, token);
|
||||
if (!session) {
|
||||
const uri = this._editor.getModel().uri;
|
||||
const chatModel = this._chatService.startSession(ChatAgentLocation.Editor, token);
|
||||
|
||||
if (!chatModel) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const request = session.chatModel.addRequest({ text: 'DUMMY', parts: [] }, { variables: [] }, 0);
|
||||
const run = this.run({
|
||||
existingSession: session,
|
||||
headless: true
|
||||
const editSession = await this._chatEditingService.createAdhocEditingSession(chatModel.sessionId);
|
||||
|
||||
//
|
||||
const store = new DisposableStore();
|
||||
store.add(chatModel);
|
||||
store.add(editSession);
|
||||
|
||||
// STREAM
|
||||
const chatRequest = chatModel?.addRequest({ text: '', parts: [] }, { variables: [] }, 0);
|
||||
assertType(chatRequest.response);
|
||||
chatRequest.response.updateContent({ kind: 'textEdit', uri, edits: [], done: false });
|
||||
for await (const chunk of stream) {
|
||||
|
||||
if (token.isCancellationRequested) {
|
||||
chatRequest.response.cancel();
|
||||
break;
|
||||
}
|
||||
|
||||
chatRequest.response.updateContent({ kind: 'textEdit', uri, edits: chunk, done: false });
|
||||
}
|
||||
chatRequest.response.updateContent({ kind: 'textEdit', uri, edits: [], done: true });
|
||||
|
||||
if (!token.isCancellationRequested) {
|
||||
chatRequest.response.complete();
|
||||
}
|
||||
|
||||
const whenDecided = new Promise(resolve => {
|
||||
store.add(autorun(r => {
|
||||
if (!editSession.entries.read(r).some(e => e.state.read(r) === WorkingSetEntryState.Modified)) {
|
||||
resolve(undefined);
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
await Event.toPromise(Event.filter(this._onDidEnterState.event, candidate => candidate === State.SHOW_REQUEST));
|
||||
await raceCancellation(whenDecided, token);
|
||||
|
||||
for await (const chunk of stream) {
|
||||
session.chatModel.acceptResponseProgress(request, { kind: 'textEdit', uri: this._editor.getModel()!.uri, edits: chunk });
|
||||
}
|
||||
store.dispose();
|
||||
|
||||
if (token.isCancellationRequested) {
|
||||
session.chatModel.cancelRequest(request);
|
||||
} else {
|
||||
session.chatModel.completeResponse(request);
|
||||
}
|
||||
|
||||
await Event.toPromise(Event.filter(this._onDidEnterState.event, candidate => candidate === State.WAIT_FOR_INPUT));
|
||||
|
||||
if (session.hunkData.pending === 0) {
|
||||
// no real changes, just cancel
|
||||
this.cancelSession();
|
||||
}
|
||||
|
||||
const dispo = token.onCancellationRequested(() => this.cancelSession());
|
||||
await raceCancellation(run, token);
|
||||
dispo.dispose();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user