Skip to content

Commit 13197dc

Browse files
authored
Allows insertText to be empty, introduces URI and renames DisplayLocation to Hint. (microsoft#273125)
* Allows insertText to be empty, introduces URI and renames DisplayLocation to Hint. * Fixes CI * Fixes CI
1 parent 23b5892 commit 13197dc

17 files changed

Lines changed: 165 additions & 143 deletions

src/vs/editor/common/languages.ts

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -788,30 +788,34 @@ export interface InlineCompletion {
788788
* The text can also be a snippet. In that case, a preview with default parameters is shown.
789789
* When accepting the suggestion, the full snippet is inserted.
790790
*/
791-
readonly insertText: string | { snippet: string };
791+
readonly insertText: string | { snippet: string } | undefined;
792792

793793
/**
794-
* A text that is used to decide if this inline completion should be shown.
795-
* An inline completion is shown if the text to replace is a subword of the filter text.
796-
*/
797-
readonly filterText?: string;
794+
* The range to replace.
795+
* Must begin and end on the same line.
796+
* Refers to the current document or `uri` if provided.
797+
*/
798+
readonly range?: IRange;
798799

799800
/**
800801
* An optional array of additional text edits that are applied when
801802
* selecting this completion. Edits must not overlap with the main edit
802803
* nor with themselves.
804+
* Refers to the current document or `uri` if provided.
803805
*/
804806
readonly additionalTextEdits?: ISingleEditOperation[];
805807

806808
/**
807-
* The range to replace.
808-
* Must begin and end on the same line.
809+
* The file for which the edit applies to.
809810
*/
810-
readonly range?: IRange;
811+
readonly uri?: UriComponents;
811812

813+
/**
814+
* A command that is run upon acceptance of this item.
815+
*/
812816
readonly command?: Command;
813817

814-
readonly action?: Command;
818+
readonly gutterMenuLinkAction?: Command;
815819

816820
/**
817821
* Is called the first time an inline completion is shown.
@@ -828,11 +832,12 @@ export interface InlineCompletion {
828832
readonly isInlineEdit?: boolean;
829833
readonly showInlineEditMenu?: boolean;
830834

835+
/** Only show the inline suggestion when the cursor is in the showRange. */
831836
readonly showRange?: IRange;
832837

833838
readonly warning?: InlineCompletionWarning;
834839

835-
readonly displayLocation?: InlineCompletionDisplayLocation;
840+
readonly hint?: InlineCompletionHint;
836841

837842
/**
838843
* Used for telemetry.
@@ -845,21 +850,20 @@ export interface InlineCompletionWarning {
845850
icon?: IconPath;
846851
}
847852

848-
export enum InlineCompletionDisplayLocationKind {
853+
export enum InlineCompletionHintStyle {
849854
Code = 1,
850855
Label = 2
851856
}
852857

853-
export interface InlineCompletionDisplayLocation {
858+
export interface InlineCompletionHint {
859+
/** Refers to the current document. */
854860
range: IRange;
855-
kind: InlineCompletionDisplayLocationKind;
856-
label: string;
861+
style: InlineCompletionHintStyle;
862+
content: string;
857863
jumpToEdit: boolean;
858864
}
859865

860-
/**
861-
* TODO: add `| URI | { light: URI; dark: URI }`.
862-
*/
866+
// TODO: add `| URI | { light: URI; dark: URI }`.
863867
export type IconPath = ThemeIcon;
864868

865869
export interface InlineCompletions<TItem extends InlineCompletion = InlineCompletion> {

src/vs/editor/common/standalone/standaloneEnums.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -437,17 +437,17 @@ export enum InlayHintKind {
437437
Parameter = 2
438438
}
439439

440-
export enum InlineCompletionDisplayLocationKind {
441-
Code = 1,
442-
Label = 2
443-
}
444-
445440
export enum InlineCompletionEndOfLifeReasonKind {
446441
Accepted = 0,
447442
Rejected = 1,
448443
Ignored = 2
449444
}
450445

446+
export enum InlineCompletionHintStyle {
447+
Code = 1,
448+
Label = 2
449+
}
450+
451451
/**
452452
* How an {@link InlineCompletionsProvider inline completion provider} was triggered.
453453
*/

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -753,7 +753,7 @@ export class InlineCompletionsModel extends Disposable {
753753
return false;
754754
}
755755

756-
if (state.inlineCompletion.displayLocation) {
756+
if (state.inlineCompletion.hint) {
757757
return false;
758758
}
759759

@@ -803,7 +803,7 @@ export class InlineCompletionsModel extends Disposable {
803803
return true;
804804
}
805805

806-
if (this._inAcceptFlow.read(reader) && this._appearedInsideViewport.read(reader) && !s.inlineCompletion.displayLocation?.jumpToEdit) {
806+
if (this._inAcceptFlow.read(reader) && this._appearedInsideViewport.read(reader) && !s.inlineCompletion.hint?.jumpToEdit) {
807807
return false;
808808
}
809809

@@ -821,7 +821,7 @@ export class InlineCompletionsModel extends Disposable {
821821
if (this._tabShouldIndent.read(reader)) {
822822
return false;
823823
}
824-
if (this._inAcceptFlow.read(reader) && this._appearedInsideViewport.read(reader) && !s.inlineCompletion.displayLocation?.jumpToEdit) {
824+
if (this._inAcceptFlow.read(reader) && this._appearedInsideViewport.read(reader) && !s.inlineCompletion.hint?.jumpToEdit) {
825825
return true;
826826
}
827827
if (s.inlineCompletion.targetRange.startLineNumber === this._editorObs.cursorLineNumber.read(reader)) {
@@ -925,7 +925,7 @@ export class InlineCompletionsModel extends Disposable {
925925

926926
editor.edit(edit, this._getMetadata(completion, this.textModel.getLanguageId()));
927927

928-
if (completion.displayLocation === undefined) {
928+
if (completion.hint === undefined) {
929929
// do not move the cursor when the completion is displayed in a different location
930930
editor.setSelections(state.kind === 'inlineEdit' ? selections.slice(-1) : selections, 'inlineCompletionAccept');
931931
}
@@ -1105,7 +1105,7 @@ export class InlineCompletionsModel extends Disposable {
11051105
this._editor.setPosition(targetPosition, 'inlineCompletions.jump');
11061106

11071107
// TODO: consider using view information to reveal it
1108-
const isSingleLineChange = targetRange.isSingleLine() && (s.inlineCompletion.displayLocation || !s.inlineCompletion.insertText.includes('\n'));
1108+
const isSingleLineChange = targetRange.isSingleLine() && (s.inlineCompletion.hint || !s.inlineCompletion.insertText.includes('\n'));
11091109
if (isSingleLineChange) {
11101110
this._editor.revealPosition(targetPosition);
11111111
} else {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ export class InlineCompletionsSource extends Disposable {
270270
const result = suggestions.map(c => ({
271271
range: c.editRange.toString(),
272272
text: c.insertText,
273-
displayLocation: c.displayLocation ? { label: c.displayLocation.label, range: c.displayLocation.range.toString(), kind: c.displayLocation.kind, jumpToEdit: c.displayLocation.jumpToEdit } : undefined,
273+
hint: c.hint,
274274
isInlineEdit: c.isInlineEdit,
275275
showInlineEditMenu: c.showInlineEditMenu,
276276
providerId: c.source.provider.providerId?.toString(),

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

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { BugIndicatingError } from '../../../../../base/common/errors.js';
77
import { matchesSubString } from '../../../../../base/common/filters.js';
88
import { IObservable, ITransaction, observableSignal, observableValue } from '../../../../../base/common/observable.js';
99
import { commonPrefixLength, commonSuffixLength, splitLines } from '../../../../../base/common/strings.js';
10+
import { URI } from '../../../../../base/common/uri.js';
1011
import { ICommandService } from '../../../../../platform/commands/common/commands.js';
1112
import { ISingleEditOperation } from '../../../../common/core/editOperation.js';
1213
import { applyEditsToRanges, StringEdit, StringReplacement } from '../../../../common/core/edits/stringEdit.js';
@@ -19,11 +20,11 @@ import { getPositionOffsetTransformerFromTextModel } from '../../../../common/co
1920
import { PositionOffsetTransformerBase } from '../../../../common/core/text/positionToOffset.js';
2021
import { TextLength } from '../../../../common/core/text/textLength.js';
2122
import { linesDiffComputers } from '../../../../common/diff/linesDiffComputers.js';
22-
import { Command, InlineCompletion, InlineCompletionDisplayLocationKind, InlineCompletionEndOfLifeReason, InlineCompletionTriggerKind, InlineCompletionWarning, PartialAcceptInfo } from '../../../../common/languages.js';
23+
import { Command, InlineCompletion, InlineCompletionHintStyle, InlineCompletionEndOfLifeReason, InlineCompletionTriggerKind, InlineCompletionWarning, PartialAcceptInfo, InlineCompletionHint } from '../../../../common/languages.js';
2324
import { EndOfLinePreference, ITextModel } from '../../../../common/model.js';
2425
import { TextModelText } from '../../../../common/model/textModelText.js';
2526
import { InlineCompletionViewData, InlineCompletionViewKind } from '../view/inlineEdits/inlineEditsViewInterface.js';
26-
import { IDisplayLocation, InlineSuggestData, InlineSuggestionList, PartialAcceptance, SnippetInfo } from './provideInlineCompletions.js';
27+
import { InlineSuggestData, InlineSuggestionList, PartialAcceptance, SnippetInfo } from './provideInlineCompletions.js';
2728
import { singleTextRemoveCommonPrefix } from './singleTextEditHelpers.js';
2829

2930
export type InlineSuggestionItem = InlineEditItem | InlineCompletionItem;
@@ -33,7 +34,7 @@ export namespace InlineSuggestionItem {
3334
data: InlineSuggestData,
3435
textModel: ITextModel,
3536
): InlineSuggestionItem {
36-
if (!data.isInlineEdit) {
37+
if (!data.isInlineEdit && !data.uri) {
3738
return InlineCompletionItem.create(data, textModel);
3839
} else {
3940
return InlineEditItem.create(data, textModel);
@@ -45,7 +46,7 @@ abstract class InlineSuggestionItemBase {
4546
constructor(
4647
protected readonly _data: InlineSuggestData,
4748
public readonly identity: InlineSuggestionIdentity,
48-
public readonly displayLocation: InlineSuggestDisplayLocation | undefined
49+
public readonly hint: InlineSuggestHint | undefined
4950
) { }
5051

5152
/**
@@ -57,10 +58,10 @@ abstract class InlineSuggestionItemBase {
5758
public get isFromExplicitRequest(): boolean { return this._data.context.triggerKind === InlineCompletionTriggerKind.Explicit; }
5859
public get forwardStable(): boolean { return this.source.inlineSuggestions.enableForwardStability ?? false; }
5960
public get editRange(): Range { return this.getSingleTextEdit().range; }
60-
public get targetRange(): Range { return this.displayLocation?.range && !this.displayLocation.jumpToEdit ? this.displayLocation?.range : this.editRange; }
61+
public get targetRange(): Range { return this.hint?.range && !this.hint.jumpToEdit ? this.hint?.range : this.editRange; }
6162
public get insertText(): string { return this.getSingleTextEdit().text; }
6263
public get semanticId(): string { return this.hash; }
63-
public get action(): Command | undefined { return this._sourceInlineCompletion.action; }
64+
public get action(): Command | undefined { return this._sourceInlineCompletion.gutterMenuLinkAction; }
6465
public get command(): Command | undefined { return this._sourceInlineCompletion.command; }
6566
public get warning(): InlineCompletionWarning | undefined { return this._sourceInlineCompletion.warning; }
6667
public get showInlineEditMenu(): boolean { return !!this._sourceInlineCompletion.showInlineEditMenu; }
@@ -163,25 +164,25 @@ export class InlineSuggestionIdentity {
163164
}
164165
}
165166

166-
class InlineSuggestDisplayLocation implements IDisplayLocation {
167+
export class InlineSuggestHint {
167168

168-
public static create(displayLocation: IDisplayLocation) {
169-
return new InlineSuggestDisplayLocation(
170-
displayLocation.range,
171-
displayLocation.label,
172-
displayLocation.kind,
169+
public static create(displayLocation: InlineCompletionHint) {
170+
return new InlineSuggestHint(
171+
Range.lift(displayLocation.range),
172+
displayLocation.content,
173+
displayLocation.style,
173174
displayLocation.jumpToEdit
174175
);
175176
}
176177

177178
private constructor(
178179
public readonly range: Range,
179-
public readonly label: string,
180-
public readonly kind: InlineCompletionDisplayLocationKind,
180+
public readonly content: string,
181+
public readonly style: InlineCompletionHintStyle,
181182
public readonly jumpToEdit: boolean,
182183
) { }
183184

184-
public withEdit(edit: StringEdit, positionOffsetTransformer: PositionOffsetTransformerBase): InlineSuggestDisplayLocation | undefined {
185+
public withEdit(edit: StringEdit, positionOffsetTransformer: PositionOffsetTransformerBase): InlineSuggestHint | undefined {
185186
const offsetRange = new OffsetRange(
186187
positionOffsetTransformer.getOffset(this.range.getStartPosition()),
187188
positionOffsetTransformer.getOffset(this.range.getEndPosition())
@@ -194,7 +195,7 @@ class InlineSuggestDisplayLocation implements IDisplayLocation {
194195

195196
const newRange = positionOffsetTransformer.getRange(newOffsetRange);
196197

197-
return new InlineSuggestDisplayLocation(newRange, this.label, this.kind, this.jumpToEdit);
198+
return new InlineSuggestHint(newRange, this.content, this.style, this.jumpToEdit);
198199
}
199200
}
200201

@@ -212,7 +213,7 @@ export class InlineCompletionItem extends InlineSuggestionItemBase {
212213
const trimmedEdit = edit.removeCommonSuffixAndPrefix(textModel.getValue());
213214
const textEdit = transformer.getTextReplacement(edit);
214215

215-
const displayLocation = data.displayLocation ? InlineSuggestDisplayLocation.create(data.displayLocation) : undefined;
216+
const displayLocation = data.hint ? InlineSuggestHint.create(data.hint) : undefined;
216217

217218
return new InlineCompletionItem(edit, trimmedEdit, textEdit, textEdit.range, data.snippetInfo, data.additionalTextEdits, data, identity, displayLocation);
218219
}
@@ -229,7 +230,7 @@ export class InlineCompletionItem extends InlineSuggestionItemBase {
229230

230231
data: InlineSuggestData,
231232
identity: InlineSuggestionIdentity,
232-
displayLocation: InlineSuggestDisplayLocation | undefined,
233+
displayLocation: InlineSuggestHint | undefined,
233234
) {
234235
super(data, identity, displayLocation);
235236
}
@@ -250,7 +251,7 @@ export class InlineCompletionItem extends InlineSuggestionItemBase {
250251
this.additionalTextEdits,
251252
this._data,
252253
identity,
253-
this.displayLocation
254+
this.hint
254255
);
255256
}
256257

@@ -263,7 +264,7 @@ export class InlineCompletionItem extends InlineSuggestionItemBase {
263264
const positionOffsetTransformer = getPositionOffsetTransformerFromTextModel(textModel);
264265
const newTextEdit = positionOffsetTransformer.getTextReplacement(newEdit);
265266

266-
let newDisplayLocation = this.displayLocation;
267+
let newDisplayLocation = this.hint;
267268
if (newDisplayLocation) {
268269
newDisplayLocation = newDisplayLocation.withEdit(textModelEdit, positionOffsetTransformer);
269270
if (!newDisplayLocation) {
@@ -358,8 +359,8 @@ export class InlineEditItem extends InlineSuggestionItemBase {
358359
const replacedText = textModel.getValueInRange(replacedRange);
359360
return SingleUpdatedNextEdit.create(edit, replacedText);
360361
});
361-
const displayLocation = data.displayLocation ? InlineSuggestDisplayLocation.create(data.displayLocation) : undefined;
362-
return new InlineEditItem(offsetEdit, singleTextEdit, data, identity, edits, displayLocation, false, textModel.getVersionId());
362+
const hint = data.hint ? InlineSuggestHint.create(data.hint) : undefined;
363+
return new InlineEditItem(offsetEdit, singleTextEdit, data.uri, data, identity, edits, hint, false, textModel.getVersionId());
363364
}
364365

365366
public readonly snippetInfo: SnippetInfo | undefined = undefined;
@@ -369,16 +370,17 @@ export class InlineEditItem extends InlineSuggestionItemBase {
369370
private constructor(
370371
private readonly _edit: StringEdit,
371372
private readonly _textEdit: TextReplacement,
373+
public readonly uri: URI | undefined,
372374

373375
data: InlineSuggestData,
374376

375377
identity: InlineSuggestionIdentity,
376378
private readonly _edits: readonly SingleUpdatedNextEdit[],
377-
displayLocation: InlineSuggestDisplayLocation | undefined,
379+
hint: InlineSuggestHint | undefined,
378380
private readonly _lastChangePartOfInlineEdit = false,
379381
private readonly _inlineEditModelVersion: number,
380382
) {
381-
super(data, identity, displayLocation);
383+
super(data, identity, hint);
382384
}
383385

384386
public get updatedEditModelVersion(): number { return this._inlineEditModelVersion; }
@@ -392,10 +394,11 @@ export class InlineEditItem extends InlineSuggestionItemBase {
392394
return new InlineEditItem(
393395
this._edit,
394396
this._textEdit,
397+
this.uri,
395398
this._data,
396399
identity,
397400
this._edits,
398-
this.displayLocation,
401+
this.hint,
399402
this._lastChangePartOfInlineEdit,
400403
this._inlineEditModelVersion,
401404
);
@@ -439,7 +442,7 @@ export class InlineEditItem extends InlineSuggestionItemBase {
439442
const positionOffsetTransformer = getPositionOffsetTransformerFromTextModel(textModel);
440443
const newTextEdit = positionOffsetTransformer.getTextEdit(newEdit).toReplacement(new TextModelText(textModel));
441444

442-
let newDisplayLocation = this.displayLocation;
445+
let newDisplayLocation = this.hint;
443446
if (newDisplayLocation) {
444447
newDisplayLocation = newDisplayLocation.withEdit(textModelChanges, positionOffsetTransformer);
445448
if (!newDisplayLocation) {
@@ -450,6 +453,7 @@ export class InlineEditItem extends InlineSuggestionItemBase {
450453
return new InlineEditItem(
451454
newEdit,
452455
newTextEdit,
456+
this.uri,
453457
this._data,
454458
this.identity,
455459
edits,

0 commit comments

Comments
 (0)