Skip to content

Commit f2529aa

Browse files
authored
Merge pull request microsoft#273106 from microsoft/benibenj/scattered-sailfish
Add jumpToEdit support for inline completions
2 parents 73e370d + 9e29017 commit f2529aa

File tree

9 files changed

+42
-18
lines changed

9 files changed

+42
-18
lines changed

src/vs/editor/common/languages.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -854,6 +854,7 @@ export interface InlineCompletionDisplayLocation {
854854
range: IRange;
855855
kind: InlineCompletionDisplayLocationKind;
856856
label: string;
857+
jumpToEdit: boolean;
857858
}
858859

859860
/**

src/vs/editor/contrib/inlineCompletions/browser/model/inlineCompletionsModel.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -73,14 +73,7 @@ export class InlineCompletionsModel extends Disposable {
7373
return false;
7474
}
7575

76-
const targetRange = state.inlineCompletion.targetRange;
77-
const visibleRanges = this._editorObs.editor.getVisibleRanges();
78-
if (visibleRanges.length < 1) {
79-
return false;
80-
}
81-
82-
const viewportRange = new Range(visibleRanges[0].startLineNumber, visibleRanges[0].startColumn, visibleRanges[visibleRanges.length - 1].endLineNumber, visibleRanges[visibleRanges.length - 1].endColumn);
83-
return viewportRange.containsRange(targetRange);
76+
return isSuggestionInViewport(this._editor, state.inlineCompletion);
8477
});
8578
public get isAcceptingPartially() { return this._isAcceptingPartially; }
8679

@@ -828,7 +821,7 @@ export class InlineCompletionsModel extends Disposable {
828821
if (this._tabShouldIndent.read(reader)) {
829822
return false;
830823
}
831-
if (this._inAcceptFlow.read(reader) && this._appearedInsideViewport.read(reader)) {
824+
if (this._inAcceptFlow.read(reader) && this._appearedInsideViewport.read(reader) && !s.inlineCompletion.displayLocation?.jumpToEdit) {
832825
return true;
833826
}
834827
if (s.inlineCompletion.targetRange.startLineNumber === this._editorObs.cursorLineNumber.read(reader)) {
@@ -1120,6 +1113,8 @@ export class InlineCompletionsModel extends Disposable {
11201113
this._editor.revealRange(revealRange, ScrollType.Immediate);
11211114
}
11221115

1116+
s.inlineCompletion.identity.setJumpTo(tx);
1117+
11231118
this._editor.focus();
11241119
});
11251120
}
@@ -1210,3 +1205,14 @@ class FadeoutDecoration extends Disposable {
12101205
}));
12111206
}
12121207
}
1208+
1209+
function isSuggestionInViewport(editor: ICodeEditor, suggestion: InlineSuggestionItem): boolean {
1210+
const targetRange = suggestion.targetRange;
1211+
const visibleRanges = editor.getVisibleRanges();
1212+
if (visibleRanges.length < 1) {
1213+
return false;
1214+
}
1215+
1216+
const viewportRange = new Range(visibleRanges[0].startLineNumber, visibleRanges[0].startColumn, visibleRanges[visibleRanges.length - 1].endLineNumber, visibleRanges[visibleRanges.length - 1].endColumn);
1217+
return viewportRange.containsRange(targetRange);
1218+
}

src/vs/editor/contrib/inlineCompletions/browser/model/inlineCompletionsSource.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ export class InlineCompletionsSource extends Disposable {
268268
const result = suggestions.map(c => ({
269269
range: c.editRange.toString(),
270270
text: c.insertText,
271+
displayLocation: c.displayLocation ? { label: c.displayLocation.label, range: c.displayLocation.range.toString(), kind: c.displayLocation.kind, jumpToEdit: c.displayLocation.jumpToEdit } : undefined,
271272
isInlineEdit: c.isInlineEdit,
272273
showInlineEditMenu: c.showInlineEditMenu,
273274
providerId: c.source.provider.providerId?.toString(),

src/vs/editor/contrib/inlineCompletions/browser/model/inlineSuggestionItem.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import { BugIndicatingError } from '../../../../../base/common/errors.js';
77
import { matchesSubString } from '../../../../../base/common/filters.js';
8-
import { IObservable, observableSignal } from '../../../../../base/common/observable.js';
8+
import { IObservable, ITransaction, observableSignal, observableValue } from '../../../../../base/common/observable.js';
99
import { commonPrefixLength, commonSuffixLength, splitLines } from '../../../../../base/common/strings.js';
1010
import { ICommandService } from '../../../../../platform/commands/common/commands.js';
1111
import { ISingleEditOperation } from '../../../../common/core/editOperation.js';
@@ -57,7 +57,7 @@ abstract class InlineSuggestionItemBase {
5757
public get isFromExplicitRequest(): boolean { return this._data.context.triggerKind === InlineCompletionTriggerKind.Explicit; }
5858
public get forwardStable(): boolean { return this.source.inlineSuggestions.enableForwardStability ?? false; }
5959
public get editRange(): Range { return this.getSingleTextEdit().range; }
60-
public get targetRange(): Range { return this.displayLocation?.range ?? this.editRange; }
60+
public get targetRange(): Range { return this.displayLocation?.range && !this.displayLocation.jumpToEdit ? this.displayLocation?.range : this.editRange; }
6161
public get insertText(): string { return this.getSingleTextEdit().text; }
6262
public get semanticId(): string { return this.hash; }
6363
public get action(): Command | undefined { return this._sourceInlineCompletion.action; }
@@ -143,6 +143,11 @@ export class InlineSuggestionIdentity {
143143
private readonly _onDispose = observableSignal(this);
144144
public readonly onDispose: IObservable<void> = this._onDispose;
145145

146+
private readonly _jumpedTo = observableValue(this, false);
147+
public get jumpedTo(): IObservable<boolean> {
148+
return this._jumpedTo;
149+
}
150+
146151
private _refCount = 1;
147152
public readonly id = 'InlineCompletionIdentity' + InlineSuggestionIdentity.idCounter++;
148153

@@ -156,6 +161,10 @@ export class InlineSuggestionIdentity {
156161
this._onDispose.trigger(undefined);
157162
}
158163
}
164+
165+
setJumpTo(tx: ITransaction | undefined): void {
166+
this._jumpedTo.set(true, tx);
167+
}
159168
}
160169

161170
class InlineSuggestDisplayLocation implements IDisplayLocation {
@@ -164,14 +173,16 @@ class InlineSuggestDisplayLocation implements IDisplayLocation {
164173
return new InlineSuggestDisplayLocation(
165174
displayLocation.range,
166175
displayLocation.label,
167-
displayLocation.kind
176+
displayLocation.kind,
177+
displayLocation.jumpToEdit
168178
);
169179
}
170180

171181
private constructor(
172182
public readonly range: Range,
173183
public readonly label: string,
174-
public readonly kind: InlineCompletionDisplayLocationKind
184+
public readonly kind: InlineCompletionDisplayLocationKind,
185+
public readonly jumpToEdit: boolean,
175186
) { }
176187

177188
public withEdit(edit: StringEdit, positionOffsetTransformer: PositionOffsetTransformerBase): InlineSuggestDisplayLocation | undefined {
@@ -187,7 +198,7 @@ class InlineSuggestDisplayLocation implements IDisplayLocation {
187198

188199
const newRange = positionOffsetTransformer.getRange(newOffsetRange);
189200

190-
return new InlineSuggestDisplayLocation(newRange, this.label, this.kind);
201+
return new InlineSuggestDisplayLocation(newRange, this.label, this.kind, this.jumpToEdit);
191202
}
192203
}
193204

src/vs/editor/contrib/inlineCompletions/browser/model/provideInlineCompletions.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,8 @@ function toInlineSuggestData(
231231
const displayLocation = inlineCompletion.displayLocation ? {
232232
range: Range.lift(inlineCompletion.displayLocation.range),
233233
label: inlineCompletion.displayLocation.label,
234-
kind: inlineCompletion.displayLocation.kind
234+
kind: inlineCompletion.displayLocation.kind,
235+
jumpToEdit: inlineCompletion.displayLocation.jumpToEdit,
235236
} : undefined;
236237

237238
return new InlineSuggestData(
@@ -476,6 +477,7 @@ export interface IDisplayLocation {
476477
range: Range;
477478
label: string;
478479
kind: InlineCompletionDisplayLocationKind;
480+
jumpToEdit: boolean;
479481
}
480482

481483
export enum InlineCompletionEditorType {

src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsView.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export class InlineEditsView extends Disposable {
4646

4747
private readonly _tabAction;
4848

49-
private _previousView: {
49+
private _previousView: { // TODO, move into identity
5050
id: string;
5151
view: ReturnType<typeof InlineEditsView.prototype.determineView>;
5252
editorWidth: number;
@@ -384,7 +384,7 @@ export class InlineEditsView extends Disposable {
384384
private determineView(model: IInlineEditModel, reader: IReader, diff: DetailedLineRangeMapping[], newText: StringText): InlineCompletionViewKind {
385385
// Check if we can use the previous view if it is the same InlineCompletion as previously shown
386386
const inlineEdit = model.inlineEdit;
387-
const canUseCache = this._previousView?.id === this.getCacheId(model);
387+
const canUseCache = this._previousView?.id === this.getCacheId(model) && !model.displayLocation?.jumpToEdit;
388388
const reconsiderViewEditorWidthChange = this._previousView?.editorWidth !== this._editorObs.layoutInfoWidth.read(reader) &&
389389
(
390390
this._previousView?.view === InlineCompletionViewKind.SideBySide ||
@@ -395,7 +395,7 @@ export class InlineEditsView extends Disposable {
395395
return this._previousView!.view;
396396
}
397397

398-
if (model.displayLocation) {
398+
if (model.displayLocation && !model.inlineEdit.inlineCompletion.identity.jumpedTo.read(reader)) {
399399
return InlineCompletionViewKind.Custom;
400400
}
401401

src/vs/monaco.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7566,6 +7566,7 @@ declare namespace monaco.languages {
75667566
range: IRange;
75677567
kind: InlineCompletionDisplayLocationKind;
75687568
label: string;
7569+
jumpToEdit: boolean;
75697570
}
75707571

75717572
/**

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1440,6 +1440,7 @@ class InlineCompletionAdapter {
14401440
range: typeConvert.Range.from(item.displayLocation.range),
14411441
label: item.displayLocation.label,
14421442
kind: item.displayLocation.kind ? typeConvert.InlineCompletionDisplayLocationKind.from(item.displayLocation.kind) : InlineCompletionDisplayLocationKind.Code,
1443+
jumpToEdit: item.displayLocation.jumpToEdit ?? false,
14431444
} : undefined,
14441445
warning: (item.warning && this._isAdditionsProposedApiEnabled) ? {
14451446
message: typeConvert.MarkdownString.from(item.warning.message),

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ declare module 'vscode' {
7878
range: Range;
7979
kind: InlineCompletionDisplayLocationKind;
8080
label: string;
81+
jumpToEdit?: boolean;
8182
}
8283

8384
export interface InlineCompletionWarning {

0 commit comments

Comments
 (0)