Skip to content

Commit 454ddfd

Browse files
authored
Merge pull request microsoft#185236 from microsoft/joh/used-dog
joh/used dog
2 parents dc5fe33 + 4c91264 commit 454ddfd

File tree

4 files changed

+46
-35
lines changed

4 files changed

+46
-35
lines changed

src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ export class PreviousFromHistory extends AbstractInlineChatAction {
274274

275275
constructor() {
276276
super({
277-
id: 'inlineCat.previousFromHistory',
277+
id: 'inlineChat.previousFromHistory',
278278
title: localize('previousFromHistory', 'Previous From History'),
279279
precondition: CTX_INLINE_CHAT_FOCUSED,
280280
keybinding: {

src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ export class InlineChatController implements IEditorContribution {
171171
return this._zone.value.position;
172172
}
173173

174-
async run(options: InlineChatRunOptions | undefined): Promise<void> {
174+
async run(options: InlineChatRunOptions | undefined = {}): Promise<void> {
175175
this._log('session starting');
176176
await this._finishExistingSession();
177177
this._stashedSession.clear();
@@ -195,15 +195,15 @@ export class InlineChatController implements IEditorContribution {
195195
// ---- state machine
196196

197197
private _showWidget(initialRender: boolean = false) {
198-
assertType(this._activeSession);
199-
assertType(this._strategy);
200198
assertType(this._editor.hasModel());
201199

202-
let widgetPosition: Position | undefined;
200+
let widgetPosition: Position;
203201
if (initialRender) {
204202
widgetPosition = this._editor.getSelection().getEndPosition();
205203
this._zone.value.setMargins(widgetPosition);
206204
} else {
205+
assertType(this._activeSession);
206+
assertType(this._strategy);
207207
widgetPosition = this._strategy.getWidgetPosition() ?? this._zone.value.position ?? this._activeSession.wholeRange.value.getEndPosition();
208208
const needsMargin = this._strategy.needsMargin();
209209
if (!needsMargin) {
@@ -213,39 +213,50 @@ export class InlineChatController implements IEditorContribution {
213213
this._zone.value.show(widgetPosition);
214214
}
215215

216-
protected async _nextState(state: State, options: InlineChatRunOptions | undefined): Promise<void> {
217-
this._log('setState to ', state);
218-
const nextState = await this[state](options);
219-
if (nextState) {
220-
await this._nextState(nextState, options);
216+
protected async _nextState(state: State, options: InlineChatRunOptions): Promise<void> {
217+
let nextState: State | void = state;
218+
while (nextState) {
219+
this._log('setState to ', nextState);
220+
nextState = await this[nextState](options);
221221
}
222222
}
223223

224-
private async [State.CREATE_SESSION](options: InlineChatRunOptions | undefined): Promise<State.CANCEL | State.INIT_UI> {
224+
private async [State.CREATE_SESSION](options: InlineChatRunOptions): Promise<State.CANCEL | State.INIT_UI> {
225225
assertType(this._activeSession === undefined);
226226
assertType(this._editor.hasModel());
227227

228-
let session: Session | undefined = options?.existingSession;
228+
let session: Session | undefined = options.existingSession;
229+
230+
this._showWidget(true);
231+
this._zone.value.widget.updateInfo(localize('welcome.1', "AI-generated code may be incorrect"));
232+
this._zone.value.widget.placeholder = this._getPlaceholderText();
229233

230234
if (!session) {
231235
const createSessionCts = new CancellationTokenSource();
232236
const msgListener = Event.once(this._messages.event)(m => {
233237
this._log('state=_createSession) message received', m);
234-
createSessionCts.cancel();
238+
if (m === Message.ACCEPT_INPUT) {
239+
// user accepted the input before having a session
240+
options.autoSend = true;
241+
this._zone.value.widget.updateProgress(true);
242+
this._zone.value.widget.updateInfo(localize('welcome.2', "Getting ready..."));
243+
} else {
244+
createSessionCts.cancel();
245+
}
235246
});
236247

237248
session = await this._inlineChatSessionService.createSession(
238249
this._editor,
239-
{ editMode: this._getMode(), wholeRange: options?.initialRange },
250+
{ editMode: this._getMode(), wholeRange: options.initialRange },
240251
createSessionCts.token
241252
);
242253

243254
createSessionCts.dispose();
244255
msgListener.dispose();
245256
}
246257

247-
delete options?.initialRange;
248-
delete options?.existingSession;
258+
delete options.initialRange;
259+
delete options.existingSession;
249260

250261
if (!session) {
251262
this._dialogService.info(localize('create.fail', "Failed to start editor chat"), localize('create.fail.detail', "Please consult the error log and try again later."));
@@ -269,7 +280,7 @@ export class InlineChatController implements IEditorContribution {
269280
return State.INIT_UI;
270281
}
271282

272-
private async [State.INIT_UI](options: InlineChatRunOptions | undefined): Promise<State.WAIT_FOR_INPUT | State.SHOW_RESPONSE | State.APPLY_RESPONSE> {
283+
private async [State.INIT_UI](options: InlineChatRunOptions): Promise<State.WAIT_FOR_INPUT | State.SHOW_RESPONSE | State.APPLY_RESPONSE> {
273284
assertType(this._activeSession);
274285

275286
// hide/cancel inline completions when invoking IE
@@ -287,10 +298,9 @@ export class InlineChatController implements IEditorContribution {
287298

288299
this._zone.value.widget.updateSlashCommands(this._activeSession.session.slashCommands ?? []);
289300
this._zone.value.widget.placeholder = this._getPlaceholderText();
290-
this._zone.value.widget.value = this._activeSession.lastInput?.value ?? '';
301+
this._zone.value.widget.value = this._activeSession.lastInput?.value ?? this._zone.value.widget.value;
291302
this._zone.value.widget.updateInfo(this._activeSession.session.message ?? localize('welcome.1', "AI-generated code may be incorrect"));
292303
this._zone.value.widget.preferredExpansionState = this._activeSession.lastExpansionState;
293-
this._showWidget(true);
294304

295305
this._sessionStore.add(this._editor.onDidChangeModel((e) => {
296306
const msg = this._activeSession?.lastExchange
@@ -321,7 +331,7 @@ export class InlineChatController implements IEditorContribution {
321331

322332
if (!this._activeSession.lastExchange) {
323333
return State.WAIT_FOR_INPUT;
324-
} else if (options?.isUnstashed) {
334+
} else if (options.isUnstashed) {
325335
delete options.isUnstashed;
326336
return State.APPLY_RESPONSE;
327337
} else {
@@ -330,10 +340,7 @@ export class InlineChatController implements IEditorContribution {
330340
}
331341

332342
private _getPlaceholderText(): string {
333-
if (!this._activeSession) {
334-
return '';
335-
}
336-
let result = this._activeSession.session.placeholder ?? localize('default.placeholder', "Ask a question");
343+
let result = this._activeSession?.session.placeholder ?? localize('default.placeholder', "Ask a question");
337344
if (InlineChatController._promptHistory.length > 0) {
338345
const kb1 = this._keybindingService.lookupKeybinding('inlineChat.previousFromHistory')?.getLabel();
339346
const kb2 = this._keybindingService.lookupKeybinding('inlineChat.nextFromHistory')?.getLabel();
@@ -375,22 +382,22 @@ export class InlineChatController implements IEditorContribution {
375382
}
376383
}
377384

378-
private async [State.WAIT_FOR_INPUT](options: InlineChatRunOptions | undefined): Promise<State.ACCEPT | State.CANCEL | State.PAUSE | State.WAIT_FOR_INPUT | State.MAKE_REQUEST> {
385+
private async [State.WAIT_FOR_INPUT](options: InlineChatRunOptions): Promise<State.ACCEPT | State.CANCEL | State.PAUSE | State.WAIT_FOR_INPUT | State.MAKE_REQUEST> {
379386
assertType(this._activeSession);
380387
assertType(this._strategy);
381388

382389
this._zone.value.widget.placeholder = this._getPlaceholderText();
383390

384-
if (options?.message) {
385-
this._zone.value.widget.value = options?.message;
391+
if (options.message) {
392+
this._zone.value.widget.value = options.message;
386393
this._zone.value.widget.selectAll();
387-
delete options?.message;
394+
delete options.message;
388395
}
389396

390397
let message = Message.NONE;
391-
if (options?.autoSend) {
398+
if (options.autoSend) {
392399
message = Message.ACCEPT_INPUT;
393-
delete options?.autoSend;
400+
delete options.autoSend;
394401

395402
} else {
396403
const barrier = new Barrier();

src/vs/workbench/contrib/inlineChat/browser/inlineChatLivePreviewWidget.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import { IModelService } from 'vs/editor/common/services/model';
3232
import { EditOperation } from 'vs/editor/common/core/editOperation';
3333
import { Session } from 'vs/workbench/contrib/inlineChat/browser/inlineChatSession';
3434
import { ILanguageService } from 'vs/editor/common/languages/language';
35+
import { FoldingController } from 'vs/editor/contrib/folding/browser/folding';
3536

3637
export class InlineChatLivePreviewWidget extends ZoneWidget {
3738

@@ -61,7 +62,7 @@ export class InlineChatLivePreviewWidget extends ZoneWidget {
6162

6263
const diffContributions = EditorExtensionsRegistry
6364
.getEditorContributions()
64-
.filter(c => c.id !== INLINE_CHAT_ID);
65+
.filter(c => c.id !== INLINE_CHAT_ID && c.id !== FoldingController.ID);
6566

6667
this._diffEditor = instantiationService.createInstance(EmbeddedDiffEditorWidget, this._elements.domNode, {
6768
scrollbar: { useShadows: false, alwaysConsumeMouseWheel: false },

src/vs/workbench/contrib/inlineChat/test/browser/inlineChatController.test.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,13 @@ suite('InteractiveChatontroller', function () {
5757
});
5858
}
5959

60-
protected override _nextState(state: State, options: InlineChatRunOptions | undefined): Promise<void> {
61-
this._onDidChangeState.fire(state);
62-
(<State[]>this.states).push(state);
63-
return super._nextState(state, options);
60+
protected override async _nextState(state: State, options: InlineChatRunOptions): Promise<void> {
61+
let nextState: State | void = state;
62+
while (nextState) {
63+
this._onDidChangeState.fire(nextState);
64+
(<State[]>this.states).push(nextState);
65+
nextState = await this[nextState](options);
66+
}
6467
}
6568

6669
override dispose() {

0 commit comments

Comments
 (0)