Skip to content

Commit 76b31a1

Browse files
committed
using a different widget position strategy
1 parent a9cf4fb commit 76b31a1

File tree

3 files changed

+39
-31
lines changed

3 files changed

+39
-31
lines changed

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/c
2828
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
2929
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
3030
import { ILogService } from 'vs/platform/log/common/log';
31-
import { EditResponse, EmptyResponse, ErrorResponse, ExpansionState, IInlineChatSessionService, MarkdownResponse, Session, SessionExchange } from 'vs/workbench/contrib/inlineChat/browser/inlineChatSession';
31+
import { EditResponse, EmptyResponse, ErrorResponse, ExpansionState, IInlineChatSessionService, MarkdownResponse, Session, SessionExchange, SessionResponse } from 'vs/workbench/contrib/inlineChat/browser/inlineChatSession';
3232
import { EditModeStrategy, LivePreviewStrategy, LiveStrategy, PreviewStrategy } from 'vs/workbench/contrib/inlineChat/browser/inlineChatStrategies';
3333
import { InlineChatZoneWidget } from 'vs/workbench/contrib/inlineChat/browser/inlineChatWidget';
3434
import { CTX_INLINE_CHAT_HAS_ACTIVE_REQUEST, CTX_INLINE_CHAT_LAST_FEEDBACK, IInlineChatRequest, IInlineChatResponse, INLINE_CHAT_ID, EditMode, InlineChatResponseFeedbackKind, CTX_INLINE_CHAT_LAST_RESPONSE_TYPE, InlineChatResponseType, CTX_INLINE_CHAT_DID_EDIT, CTX_INLINE_CHAT_HAS_STASHED_SESSION } from 'vs/workbench/contrib/inlineChat/common/inlineChat';
@@ -193,10 +193,10 @@ export class InlineChatController implements IEditorContribution {
193193

194194
// ---- state machine
195195

196-
private _showWidget(initialRender: boolean = false, hasEditResponse: boolean = false) {
196+
private _showWidget(initialRender: boolean = false, response?: SessionResponse) {
197197
assertType(this._activeSession);
198198
const selectionRange = this._activeSession.wholeRange.value;
199-
const widgetPosition = this._strategy?.getWidgetPosition(initialRender, selectionRange, hasEditResponse);
199+
const widgetPosition = this._strategy?.getWidgetPosition(initialRender, selectionRange, response);
200200
this._zone.value.show(widgetPosition ?? selectionRange.getEndPosition());
201201
}
202202

@@ -544,7 +544,7 @@ export class InlineChatController implements IEditorContribution {
544544
assertType(this._strategy);
545545

546546
const { response } = this._activeSession.lastExchange!;
547-
this._showWidget(false, response instanceof EditResponse);
547+
this._showWidget(false, response);
548548

549549
this._ctxLastResponseType.set(response instanceof EditResponse || response instanceof MarkdownResponse
550550
? response.raw.type

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,11 +236,12 @@ export class Session {
236236
}
237237
}
238238

239+
export type SessionResponse = EditResponse | MarkdownResponse | ErrorResponse | EmptyResponse;
239240

240241
export class SessionExchange {
241242
constructor(
242243
readonly prompt: string,
243-
readonly response: MarkdownResponse | EditResponse | EmptyResponse | ErrorResponse
244+
readonly response: SessionResponse
244245
) { }
245246
}
246247

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

Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/c
2121
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
2222
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
2323
import { InlineChatFileCreatePreviewWidget, InlineChatLivePreviewWidget } from 'vs/workbench/contrib/inlineChat/browser/inlineChatLivePreviewWidget';
24-
import { EditResponse, Session } from 'vs/workbench/contrib/inlineChat/browser/inlineChatSession';
24+
import { EditResponse, Session, SessionResponse } from 'vs/workbench/contrib/inlineChat/browser/inlineChatSession';
2525
import { InlineChatWidget } from 'vs/workbench/contrib/inlineChat/browser/inlineChatWidget';
2626
import { CTX_INLINE_CHAT_SHOWING_DIFF, CTX_INLINE_CHAT_DOCUMENT_CHANGED } from 'vs/workbench/contrib/inlineChat/common/inlineChat';
2727
import { IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService';
@@ -46,7 +46,7 @@ export abstract class EditModeStrategy {
4646

4747
abstract hasFocus(): boolean;
4848

49-
abstract getWidgetPosition(initialRender: boolean, range: Range, hasEditResponse: boolean | undefined): Position | undefined;
49+
abstract getWidgetPosition(initialRender: boolean, range?: Range, response?: SessionResponse): Position | undefined;
5050
}
5151

5252
export class PreviewStrategy extends EditModeStrategy {
@@ -135,15 +135,13 @@ export class PreviewStrategy extends EditModeStrategy {
135135
// nothing to do
136136
}
137137

138-
getWidgetPosition(initialRender: boolean, range: Range, hasEditResponse: boolean | undefined): Position | undefined {
138+
getWidgetPosition(initialRender: boolean, _range: Range, _response: SessionResponse): Position | undefined {
139139
const viewModel = this._editor._getViewModel();
140140
assertType(viewModel);
141141
if (initialRender) {
142142
this._initialPosition = viewModel.getPrimaryCursorState().viewState.position;
143-
return this._initialPosition;
144-
} else {
145-
return minimalJumpPosition(this._editor, this._initialPosition, range, hasEditResponse);
146143
}
144+
return this._initialPosition;
147145
}
148146

149147
hasFocus(): boolean {
@@ -342,14 +340,39 @@ export class LiveStrategy extends EditModeStrategy {
342340
this._widget.updateStatus(message);
343341
}
344342

345-
override getWidgetPosition(initialRender: boolean, range: Range, hasEditResponse: boolean | undefined): Position | undefined {
343+
private _findEditsMaxLineNumber(response: EditResponse): number | void {
344+
const edits = response.localEdits;
345+
if (edits.length) {
346+
let editsMaxLineNumber = 0;
347+
for (const edit of edits) {
348+
const editStartLine = edit.range.startLineNumber;
349+
const editNumberOfLines = (edit.text.match(/\n/g) || []).length;
350+
const endLine = editStartLine + editNumberOfLines - 1;
351+
if (endLine > editsMaxLineNumber) {
352+
editsMaxLineNumber = endLine;
353+
}
354+
}
355+
return editsMaxLineNumber;
356+
}
357+
}
358+
359+
override getWidgetPosition(initialRender: boolean, _range: Range, response: SessionResponse): Position | undefined {
346360
const viewModel = this._editor._getViewModel();
347361
assertType(viewModel);
348362
if (initialRender) {
349363
this._initialPosition = viewModel.getPrimaryCursorState().viewState.position;
350364
return this._initialPosition;
351365
} else {
352-
return minimalJumpPosition(this._editor, this._initialPosition, range, hasEditResponse);
366+
if (response instanceof EditResponse) {
367+
const editsMaxLineNumber = this._findEditsMaxLineNumber(response);
368+
if (editsMaxLineNumber) {
369+
return new Position(editsMaxLineNumber, 1);
370+
} else {
371+
return this._initialPosition;
372+
}
373+
} else {
374+
return this._initialPosition;
375+
}
353376
}
354377
}
355378

@@ -411,14 +434,14 @@ export class LivePreviewStrategy extends LiveStrategy {
411434
scrollState.restore(this._editor);
412435
}
413436

414-
override getWidgetPosition(initialRender: boolean, range: Range, hasEditResponse: boolean | undefined): Position | undefined {
437+
override getWidgetPosition(initialRender: boolean, range: Range, response: SessionResponse): Position | undefined {
415438
if (initialRender) {
416439
const viewModel = this._editor._getViewModel();
417440
assertType(viewModel);
418441
this._initialPosition = viewModel.getPrimaryCursorState().viewState.position;
419442
return this._initialPosition;
420443
} else {
421-
if (hasEditResponse) {
444+
if (range && response instanceof EditResponse) {
422445
return range.getEndPosition();
423446
} else {
424447
return this._initialPosition;
@@ -437,19 +460,3 @@ function showSingleCreateFile(accessor: ServicesAccessor, edit: EditResponse) {
437460
editorService.openEditor({ resource: edit.singleCreateFileEdit.uri }, SIDE_GROUP);
438461
}
439462
}
440-
441-
function minimalJumpPosition(editor: ICodeEditor, initialPosition: Position | undefined, range: Range, hasEditResponse: boolean | undefined): Position | undefined {
442-
const viewModel = editor._getViewModel();
443-
assertType(viewModel);
444-
if (hasEditResponse) {
445-
const endPosition = range.getEndPosition();
446-
const visibleRange = viewModel.getCompletelyVisibleViewRange();
447-
if (visibleRange.containsPosition(endPosition)) {
448-
return endPosition;
449-
} else {
450-
return initialPosition;
451-
}
452-
} else {
453-
return initialPosition;
454-
}
455-
}

0 commit comments

Comments
 (0)