Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 21 additions & 17 deletions src/vs/editor/common/languages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -788,30 +788,34 @@ export interface InlineCompletion {
* The text can also be a snippet. In that case, a preview with default parameters is shown.
* When accepting the suggestion, the full snippet is inserted.
*/
readonly insertText: string | { snippet: string };
readonly insertText: string | { snippet: string } | undefined;

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

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

/**
* The range to replace.
* Must begin and end on the same line.
* The file for which the edit applies to.
*/
readonly range?: IRange;
readonly uri?: UriComponents;

/**
* A command that is run upon acceptance of this item.
*/
readonly command?: Command;

readonly action?: Command;
readonly gutterMenuLinkAction?: Command;

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

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

readonly warning?: InlineCompletionWarning;

readonly displayLocation?: InlineCompletionDisplayLocation;
readonly hint?: InlineCompletionHint;

/**
* Used for telemetry.
Expand All @@ -845,21 +850,20 @@ export interface InlineCompletionWarning {
icon?: IconPath;
}

export enum InlineCompletionDisplayLocationKind {
export enum InlineCompletionHintStyle {
Code = 1,
Label = 2
}

export interface InlineCompletionDisplayLocation {
export interface InlineCompletionHint {
/** Refers to the current document. */
range: IRange;
kind: InlineCompletionDisplayLocationKind;
label: string;
style: InlineCompletionHintStyle;
content: string;
jumpToEdit: boolean;
}

/**
* TODO: add `| URI | { light: URI; dark: URI }`.
*/
// TODO: add `| URI | { light: URI; dark: URI }`.
export type IconPath = ThemeIcon;

export interface InlineCompletions<TItem extends InlineCompletion = InlineCompletion> {
Expand Down
10 changes: 5 additions & 5 deletions src/vs/editor/common/standalone/standaloneEnums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -437,17 +437,17 @@ export enum InlayHintKind {
Parameter = 2
}

export enum InlineCompletionDisplayLocationKind {
Code = 1,
Label = 2
}

export enum InlineCompletionEndOfLifeReasonKind {
Accepted = 0,
Rejected = 1,
Ignored = 2
}

export enum InlineCompletionHintStyle {
Code = 1,
Label = 2
}

/**
* How an {@link InlineCompletionsProvider inline completion provider} was triggered.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -753,7 +753,7 @@ export class InlineCompletionsModel extends Disposable {
return false;
}

if (state.inlineCompletion.displayLocation) {
if (state.inlineCompletion.hint) {
return false;
}

Expand Down Expand Up @@ -803,7 +803,7 @@ export class InlineCompletionsModel extends Disposable {
return true;
}

if (this._inAcceptFlow.read(reader) && this._appearedInsideViewport.read(reader) && !s.inlineCompletion.displayLocation?.jumpToEdit) {
if (this._inAcceptFlow.read(reader) && this._appearedInsideViewport.read(reader) && !s.inlineCompletion.hint?.jumpToEdit) {
return false;
}

Expand All @@ -821,7 +821,7 @@ export class InlineCompletionsModel extends Disposable {
if (this._tabShouldIndent.read(reader)) {
return false;
}
if (this._inAcceptFlow.read(reader) && this._appearedInsideViewport.read(reader) && !s.inlineCompletion.displayLocation?.jumpToEdit) {
if (this._inAcceptFlow.read(reader) && this._appearedInsideViewport.read(reader) && !s.inlineCompletion.hint?.jumpToEdit) {
return true;
}
if (s.inlineCompletion.targetRange.startLineNumber === this._editorObs.cursorLineNumber.read(reader)) {
Expand Down Expand Up @@ -925,7 +925,7 @@ export class InlineCompletionsModel extends Disposable {

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

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

// TODO: consider using view information to reveal it
const isSingleLineChange = targetRange.isSingleLine() && (s.inlineCompletion.displayLocation || !s.inlineCompletion.insertText.includes('\n'));
const isSingleLineChange = targetRange.isSingleLine() && (s.inlineCompletion.hint || !s.inlineCompletion.insertText.includes('\n'));
if (isSingleLineChange) {
this._editor.revealPosition(targetPosition);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ export class InlineCompletionsSource extends Disposable {
const result = suggestions.map(c => ({
range: c.editRange.toString(),
text: c.insertText,
displayLocation: c.displayLocation ? { label: c.displayLocation.label, range: c.displayLocation.range.toString(), kind: c.displayLocation.kind, jumpToEdit: c.displayLocation.jumpToEdit } : undefined,
hint: c.hint,
isInlineEdit: c.isInlineEdit,
showInlineEditMenu: c.showInlineEditMenu,
providerId: c.source.provider.providerId?.toString(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { BugIndicatingError } from '../../../../../base/common/errors.js';
import { matchesSubString } from '../../../../../base/common/filters.js';
import { IObservable, ITransaction, observableSignal, observableValue } from '../../../../../base/common/observable.js';
import { commonPrefixLength, commonSuffixLength, splitLines } from '../../../../../base/common/strings.js';
import { URI } from '../../../../../base/common/uri.js';
import { ICommandService } from '../../../../../platform/commands/common/commands.js';
import { ISingleEditOperation } from '../../../../common/core/editOperation.js';
import { applyEditsToRanges, StringEdit, StringReplacement } from '../../../../common/core/edits/stringEdit.js';
Expand All @@ -19,11 +20,11 @@ import { getPositionOffsetTransformerFromTextModel } from '../../../../common/co
import { PositionOffsetTransformerBase } from '../../../../common/core/text/positionToOffset.js';
import { TextLength } from '../../../../common/core/text/textLength.js';
import { linesDiffComputers } from '../../../../common/diff/linesDiffComputers.js';
import { Command, InlineCompletion, InlineCompletionDisplayLocationKind, InlineCompletionEndOfLifeReason, InlineCompletionTriggerKind, InlineCompletionWarning, PartialAcceptInfo } from '../../../../common/languages.js';
import { Command, InlineCompletion, InlineCompletionHintStyle, InlineCompletionEndOfLifeReason, InlineCompletionTriggerKind, InlineCompletionWarning, PartialAcceptInfo, InlineCompletionHint } from '../../../../common/languages.js';
import { EndOfLinePreference, ITextModel } from '../../../../common/model.js';
import { TextModelText } from '../../../../common/model/textModelText.js';
import { InlineCompletionViewData, InlineCompletionViewKind } from '../view/inlineEdits/inlineEditsViewInterface.js';
import { IDisplayLocation, InlineSuggestData, InlineSuggestionList, PartialAcceptance, SnippetInfo } from './provideInlineCompletions.js';
import { InlineSuggestData, InlineSuggestionList, PartialAcceptance, SnippetInfo } from './provideInlineCompletions.js';
import { singleTextRemoveCommonPrefix } from './singleTextEditHelpers.js';

export type InlineSuggestionItem = InlineEditItem | InlineCompletionItem;
Expand All @@ -33,7 +34,7 @@ export namespace InlineSuggestionItem {
data: InlineSuggestData,
textModel: ITextModel,
): InlineSuggestionItem {
if (!data.isInlineEdit) {
if (!data.isInlineEdit && !data.uri) {
return InlineCompletionItem.create(data, textModel);
} else {
return InlineEditItem.create(data, textModel);
Expand All @@ -45,7 +46,7 @@ abstract class InlineSuggestionItemBase {
constructor(
protected readonly _data: InlineSuggestData,
public readonly identity: InlineSuggestionIdentity,
public readonly displayLocation: InlineSuggestDisplayLocation | undefined
public readonly hint: InlineSuggestHint | undefined
) { }

/**
Expand All @@ -57,10 +58,10 @@ abstract class InlineSuggestionItemBase {
public get isFromExplicitRequest(): boolean { return this._data.context.triggerKind === InlineCompletionTriggerKind.Explicit; }
public get forwardStable(): boolean { return this.source.inlineSuggestions.enableForwardStability ?? false; }
public get editRange(): Range { return this.getSingleTextEdit().range; }
public get targetRange(): Range { return this.displayLocation?.range && !this.displayLocation.jumpToEdit ? this.displayLocation?.range : this.editRange; }
public get targetRange(): Range { return this.hint?.range && !this.hint.jumpToEdit ? this.hint?.range : this.editRange; }
public get insertText(): string { return this.getSingleTextEdit().text; }
public get semanticId(): string { return this.hash; }
public get action(): Command | undefined { return this._sourceInlineCompletion.action; }
public get action(): Command | undefined { return this._sourceInlineCompletion.gutterMenuLinkAction; }
public get command(): Command | undefined { return this._sourceInlineCompletion.command; }
public get warning(): InlineCompletionWarning | undefined { return this._sourceInlineCompletion.warning; }
public get showInlineEditMenu(): boolean { return !!this._sourceInlineCompletion.showInlineEditMenu; }
Expand Down Expand Up @@ -163,25 +164,25 @@ export class InlineSuggestionIdentity {
}
}

class InlineSuggestDisplayLocation implements IDisplayLocation {
export class InlineSuggestHint {

public static create(displayLocation: IDisplayLocation) {
return new InlineSuggestDisplayLocation(
displayLocation.range,
displayLocation.label,
displayLocation.kind,
public static create(displayLocation: InlineCompletionHint) {
return new InlineSuggestHint(
Range.lift(displayLocation.range),
displayLocation.content,
displayLocation.style,
displayLocation.jumpToEdit
);
}

private constructor(
public readonly range: Range,
public readonly label: string,
public readonly kind: InlineCompletionDisplayLocationKind,
public readonly content: string,
public readonly style: InlineCompletionHintStyle,
public readonly jumpToEdit: boolean,
) { }

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

const newRange = positionOffsetTransformer.getRange(newOffsetRange);

return new InlineSuggestDisplayLocation(newRange, this.label, this.kind, this.jumpToEdit);
return new InlineSuggestHint(newRange, this.content, this.style, this.jumpToEdit);
}
}

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

const displayLocation = data.displayLocation ? InlineSuggestDisplayLocation.create(data.displayLocation) : undefined;
const displayLocation = data.hint ? InlineSuggestHint.create(data.hint) : undefined;

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

data: InlineSuggestData,
identity: InlineSuggestionIdentity,
displayLocation: InlineSuggestDisplayLocation | undefined,
displayLocation: InlineSuggestHint | undefined,
) {
super(data, identity, displayLocation);
}
Expand All @@ -250,7 +251,7 @@ export class InlineCompletionItem extends InlineSuggestionItemBase {
this.additionalTextEdits,
this._data,
identity,
this.displayLocation
this.hint
);
}

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

let newDisplayLocation = this.displayLocation;
let newDisplayLocation = this.hint;
if (newDisplayLocation) {
newDisplayLocation = newDisplayLocation.withEdit(textModelEdit, positionOffsetTransformer);
if (!newDisplayLocation) {
Expand Down Expand Up @@ -358,8 +359,8 @@ export class InlineEditItem extends InlineSuggestionItemBase {
const replacedText = textModel.getValueInRange(replacedRange);
return SingleUpdatedNextEdit.create(edit, replacedText);
});
const displayLocation = data.displayLocation ? InlineSuggestDisplayLocation.create(data.displayLocation) : undefined;
return new InlineEditItem(offsetEdit, singleTextEdit, data, identity, edits, displayLocation, false, textModel.getVersionId());
const hint = data.hint ? InlineSuggestHint.create(data.hint) : undefined;
return new InlineEditItem(offsetEdit, singleTextEdit, data.uri, data, identity, edits, hint, false, textModel.getVersionId());
}

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

data: InlineSuggestData,

identity: InlineSuggestionIdentity,
private readonly _edits: readonly SingleUpdatedNextEdit[],
displayLocation: InlineSuggestDisplayLocation | undefined,
hint: InlineSuggestHint | undefined,
private readonly _lastChangePartOfInlineEdit = false,
private readonly _inlineEditModelVersion: number,
) {
super(data, identity, displayLocation);
super(data, identity, hint);
}

public get updatedEditModelVersion(): number { return this._inlineEditModelVersion; }
Expand All @@ -392,10 +394,11 @@ export class InlineEditItem extends InlineSuggestionItemBase {
return new InlineEditItem(
this._edit,
this._textEdit,
this.uri,
this._data,
identity,
this._edits,
this.displayLocation,
this.hint,
this._lastChangePartOfInlineEdit,
this._inlineEditModelVersion,
);
Expand Down Expand Up @@ -439,7 +442,7 @@ export class InlineEditItem extends InlineSuggestionItemBase {
const positionOffsetTransformer = getPositionOffsetTransformerFromTextModel(textModel);
const newTextEdit = positionOffsetTransformer.getTextEdit(newEdit).toReplacement(new TextModelText(textModel));

let newDisplayLocation = this.displayLocation;
let newDisplayLocation = this.hint;
if (newDisplayLocation) {
newDisplayLocation = newDisplayLocation.withEdit(textModelChanges, positionOffsetTransformer);
if (!newDisplayLocation) {
Expand All @@ -450,6 +453,7 @@ export class InlineEditItem extends InlineSuggestionItemBase {
return new InlineEditItem(
newEdit,
newTextEdit,
this.uri,
this._data,
this.identity,
edits,
Expand Down
Loading
Loading