mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-22 09:38:38 +01:00
Updates inlineCompletions proposal from inlineCompletionsNew proposal.
Also moves InlineCompletionList.commands to inlineCompletionsAdditions proposal.
This commit is contained in:
@@ -29,7 +29,7 @@ import { IExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocu
|
||||
import { Extension, IExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensionService';
|
||||
import { ExtHostFileSystem } from 'vs/workbench/api/common/extHostFileSystem';
|
||||
import { ExtHostFileSystemEventService } from 'vs/workbench/api/common/extHostFileSystemEventService';
|
||||
import { ExtHostLanguageFeatures, InlineCompletionController } from 'vs/workbench/api/common/extHostLanguageFeatures';
|
||||
import { ExtHostLanguageFeatures } from 'vs/workbench/api/common/extHostLanguageFeatures';
|
||||
import { ExtHostLanguages } from 'vs/workbench/api/common/extHostLanguages';
|
||||
import { ExtHostMessageService } from 'vs/workbench/api/common/extHostMessageService';
|
||||
import { IExtHostOutputService } from 'vs/workbench/api/common/extHostOutput';
|
||||
@@ -526,6 +526,9 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
},
|
||||
registerInlineCompletionItemProvider(selector: vscode.DocumentSelector, provider: vscode.InlineCompletionItemProvider): vscode.Disposable {
|
||||
checkProposedApiEnabled(extension, 'inlineCompletions');
|
||||
if (provider.handleDidShowCompletionItem && !isProposedApiEnabled(extension, 'inlineCompletionsAdditions')) {
|
||||
throw new Error(`When the method "handleDidShowCompletionItem" is implemented on a provider, the usage of the proposed api 'inlineCompletionsAdditions' must be declared!`);
|
||||
}
|
||||
return extHostLanguageFeatures.registerInlineCompletionsProvider(extension, checkSelector(selector), provider);
|
||||
},
|
||||
registerInlineCompletionItemProviderNew(selector: vscode.DocumentSelector, provider: vscode.InlineCompletionItemProviderNew): vscode.Disposable {
|
||||
@@ -792,10 +795,6 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
get tabGroups(): vscode.TabGroups {
|
||||
return extHostEditorTabs.tabGroups;
|
||||
},
|
||||
getInlineCompletionItemController<T extends vscode.InlineCompletionItem>(provider: vscode.InlineCompletionItemProvider<T>): vscode.InlineCompletionController<T> {
|
||||
checkProposedApiEnabled(extension, 'inlineCompletions');
|
||||
return InlineCompletionController.get(provider);
|
||||
},
|
||||
};
|
||||
|
||||
// namespace: workspace
|
||||
@@ -1244,7 +1243,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
FunctionBreakpoint: extHostTypes.FunctionBreakpoint,
|
||||
InlineCompletionItem: extHostTypes.InlineSuggestion,
|
||||
InlineCompletionItemNew: extHostTypes.InlineSuggestionNew,
|
||||
InlineCompletionList: extHostTypes.InlineSuggestions,
|
||||
InlineCompletionList: extHostTypes.InlineSuggestionList,
|
||||
InlineCompletionListNew: extHostTypes.InlineSuggestionsNew,
|
||||
Hover: extHostTypes.Hover,
|
||||
IndentAction: languageConfiguration.IndentAction,
|
||||
|
||||
@@ -7,7 +7,7 @@ import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { mixin } from 'vs/base/common/objects';
|
||||
import type * as vscode from 'vscode';
|
||||
import * as typeConvert from 'vs/workbench/api/common/extHostTypeConverters';
|
||||
import { Range, Disposable, CompletionList, SnippetString, CodeActionKind, SymbolInformation, DocumentSymbol, SemanticTokensEdits, SemanticTokens, SemanticTokensEdit, Location, InlineCompletionTriggerKindNew } from 'vs/workbench/api/common/extHostTypes';
|
||||
import { Range, Disposable, CompletionList, SnippetString, CodeActionKind, SymbolInformation, DocumentSymbol, SemanticTokensEdits, SemanticTokens, SemanticTokensEdit, Location, InlineCompletionTriggerKindNew, InlineCompletionTriggerKind } from 'vs/workbench/api/common/extHostTypes';
|
||||
import { ISingleEditOperation } from 'vs/editor/common/core/editOperation';
|
||||
import * as languages from 'vs/editor/common/languages';
|
||||
import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments';
|
||||
@@ -32,7 +32,6 @@ import { IExtHostApiDeprecationService } from 'vs/workbench/api/common/extHostAp
|
||||
import { Cache } from './cache';
|
||||
import { StopWatch } from 'vs/base/common/stopwatch';
|
||||
import { isCancellationError } from 'vs/base/common/errors';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { raceCancellationError } from 'vs/base/common/async';
|
||||
import { isProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { DataTransferConverter, DataTransferDTO } from 'vs/workbench/api/common/shared/dataTransfer';
|
||||
@@ -1033,10 +1032,15 @@ class InlineCompletionAdapterBase {
|
||||
}
|
||||
|
||||
class InlineCompletionAdapter extends InlineCompletionAdapterBase {
|
||||
private readonly _cache = new Cache<vscode.InlineCompletionItem>('InlineCompletionItem');
|
||||
private readonly _disposables = new Map<number, DisposableStore>();
|
||||
private readonly _references = new ReferenceMap<{
|
||||
dispose(): void;
|
||||
items: readonly vscode.InlineCompletionItem[];
|
||||
}>();
|
||||
|
||||
private readonly isAdditionProposedApiEnabled = isProposedApiEnabled(this.extension, 'inlineCompletionsAdditions');
|
||||
|
||||
constructor(
|
||||
private readonly extension: IExtensionDescription,
|
||||
private readonly _documents: ExtHostDocuments,
|
||||
private readonly _provider: vscode.InlineCompletionItemProvider,
|
||||
private readonly _commands: CommandsConverter,
|
||||
@@ -1044,6 +1048,11 @@ class InlineCompletionAdapter extends InlineCompletionAdapterBase {
|
||||
super();
|
||||
}
|
||||
|
||||
private readonly languageTriggerKindToVSCodeTriggerKind: Record<languages.InlineCompletionTriggerKind, InlineCompletionTriggerKind> = {
|
||||
[languages.InlineCompletionTriggerKind.Automatic]: InlineCompletionTriggerKind.Automatic,
|
||||
[languages.InlineCompletionTriggerKind.Explicit]: InlineCompletionTriggerKind.Invoke,
|
||||
};
|
||||
|
||||
override async provideInlineCompletions(resource: URI, position: IPosition, context: languages.InlineCompletionContext, token: CancellationToken): Promise<extHostProtocol.IdentifiableInlineCompletions | undefined> {
|
||||
const doc = this._documents.getDocument(resource);
|
||||
const pos = typeConvert.Position.to(position);
|
||||
@@ -1053,12 +1062,10 @@ class InlineCompletionAdapter extends InlineCompletionAdapterBase {
|
||||
context.selectedSuggestionInfo
|
||||
? {
|
||||
range: typeConvert.Range.to(context.selectedSuggestionInfo.range),
|
||||
text: context.selectedSuggestionInfo.text,
|
||||
isSnippetText: context.selectedSuggestionInfo.isSnippetText,
|
||||
completionKind: typeConvert.CompletionItemKind.to(context.selectedSuggestionInfo.completionKind),
|
||||
text: context.selectedSuggestionInfo.text
|
||||
}
|
||||
: undefined,
|
||||
triggerKind: context.triggerKind
|
||||
triggerKind: this.languageTriggerKindToVSCodeTriggerKind[context.triggerKind]
|
||||
}, token);
|
||||
|
||||
if (!result) {
|
||||
@@ -1073,9 +1080,17 @@ class InlineCompletionAdapter extends InlineCompletionAdapterBase {
|
||||
}
|
||||
|
||||
const normalizedResult = isArray(result) ? result : result.items;
|
||||
const commands = isArray(result) ? [] : result.commands || [];
|
||||
|
||||
const pid = this._cache.add(normalizedResult);
|
||||
let disposableStore: DisposableStore | undefined = undefined;
|
||||
const pid = this._references.createReferenceId({
|
||||
dispose() {
|
||||
if (disposableStore) {
|
||||
disposableStore.dispose();
|
||||
}
|
||||
},
|
||||
items: normalizedResult
|
||||
});
|
||||
|
||||
return {
|
||||
pid,
|
||||
@@ -1084,41 +1099,40 @@ class InlineCompletionAdapter extends InlineCompletionAdapterBase {
|
||||
if (item.command) {
|
||||
if (!disposableStore) {
|
||||
disposableStore = new DisposableStore();
|
||||
this._disposables.set(pid, disposableStore);
|
||||
}
|
||||
command = this._commands.toInternal(item.command, disposableStore);
|
||||
}
|
||||
|
||||
const insertText = item.insertText ?? item.text;
|
||||
if (insertText === undefined) {
|
||||
throw new Error('text or insertText must be defined');
|
||||
}
|
||||
const insertText = item.insertText;
|
||||
return ({
|
||||
insertText: typeof insertText === 'string' ? insertText : { snippet: insertText.value },
|
||||
filterText: item.filterText,
|
||||
range: item.range ? typeConvert.Range.from(item.range) : undefined,
|
||||
command,
|
||||
idx: idx,
|
||||
completeBracketPairs: item.completeBracketPairs
|
||||
completeBracketPairs: this.isAdditionProposedApiEnabled ? item.completeBracketPairs : false
|
||||
});
|
||||
}),
|
||||
commands: commands.map(c => {
|
||||
if (!disposableStore) {
|
||||
disposableStore = new DisposableStore();
|
||||
}
|
||||
return this._commands.toInternal(c, disposableStore);
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
override disposeCompletions(pid: number) {
|
||||
this._cache.delete(pid);
|
||||
const d = this._disposables.get(pid);
|
||||
if (d) {
|
||||
d.clear();
|
||||
}
|
||||
this._disposables.delete(pid);
|
||||
const data = this._references.disposeReferenceId(pid);
|
||||
data?.dispose();
|
||||
}
|
||||
|
||||
override handleDidShowCompletionItem(pid: number, idx: number): void {
|
||||
const completionItem = this._cache.get(pid, idx);
|
||||
const completionItem = this._references.get(pid)?.items[idx];
|
||||
if (completionItem) {
|
||||
InlineCompletionController.get(this._provider).fireOnDidShowCompletionItem({
|
||||
completionItem
|
||||
});
|
||||
if (this._provider.handleDidShowCompletionItem && this.isAdditionProposedApiEnabled) {
|
||||
this._provider.handleDidShowCompletionItem(completionItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1250,26 +1264,6 @@ class ReferenceMap<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class InlineCompletionController<T extends vscode.InlineCompletionItem> implements vscode.InlineCompletionController<T> {
|
||||
private static readonly map = new WeakMap<vscode.InlineCompletionItemProvider<any>, InlineCompletionController<any>>();
|
||||
|
||||
static get<T extends vscode.InlineCompletionItem>(provider: vscode.InlineCompletionItemProvider<T>): InlineCompletionController<T> {
|
||||
let existing = InlineCompletionController.map.get(provider);
|
||||
if (!existing) {
|
||||
existing = new InlineCompletionController();
|
||||
InlineCompletionController.map.set(provider, existing);
|
||||
}
|
||||
return existing;
|
||||
}
|
||||
|
||||
private readonly _onDidShowCompletionItemEmitter = new Emitter<vscode.InlineCompletionItemDidShowEvent<T>>();
|
||||
readonly onDidShowCompletionItem: vscode.Event<vscode.InlineCompletionItemDidShowEvent<T>> = this._onDidShowCompletionItemEmitter.event;
|
||||
|
||||
fireOnDidShowCompletionItem(event: vscode.InlineCompletionItemDidShowEvent<T>): void {
|
||||
this._onDidShowCompletionItemEmitter.fire(event);
|
||||
}
|
||||
}
|
||||
|
||||
class SignatureHelpAdapter {
|
||||
|
||||
private readonly _cache = new Cache<vscode.SignatureHelp>('SignatureHelp');
|
||||
@@ -2210,7 +2204,7 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF
|
||||
// --- ghost test
|
||||
|
||||
registerInlineCompletionsProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.InlineCompletionItemProvider): vscode.Disposable {
|
||||
const handle = this._addNewAdapter(new InlineCompletionAdapter(this._documents, provider, this._commands.converter), extension);
|
||||
const handle = this._addNewAdapter(new InlineCompletionAdapter(extension, this._documents, provider, this._commands.converter), extension);
|
||||
this._proxy.$registerInlineCompletionsSupport(handle, this._transformDocumentSelector(selector));
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
|
||||
@@ -1595,33 +1595,24 @@ export class CompletionList {
|
||||
@es5ClassCompat
|
||||
export class InlineSuggestion implements vscode.InlineCompletionItem {
|
||||
|
||||
insertText?: string | SnippetString;
|
||||
|
||||
filterText?: string;
|
||||
|
||||
/**
|
||||
* @deprecated Use `insertText` instead. Will be removed eventually.
|
||||
*/
|
||||
text?: string;
|
||||
|
||||
insertText: string;
|
||||
range?: Range;
|
||||
command?: vscode.Command;
|
||||
|
||||
constructor(insertText: string | SnippetString, range?: Range, command?: vscode.Command) {
|
||||
constructor(insertText: string, range?: Range, command?: vscode.Command) {
|
||||
this.insertText = insertText;
|
||||
this.range = range;
|
||||
this.command = command;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Return an array of inline completion items directly. Will be removed eventually.
|
||||
*/
|
||||
@es5ClassCompat
|
||||
export class InlineSuggestions implements vscode.InlineCompletionList {
|
||||
items: vscode.InlineCompletionItem[];
|
||||
export class InlineSuggestionList implements vscode.InlineCompletionList {
|
||||
items: vscode.InlineCompletionItemNew[];
|
||||
|
||||
constructor(items: vscode.InlineCompletionItem[]) {
|
||||
commands: vscode.Command[] | undefined = undefined;
|
||||
|
||||
constructor(items: vscode.InlineCompletionItemNew[]) {
|
||||
this.items = items;
|
||||
}
|
||||
}
|
||||
@@ -2622,8 +2613,8 @@ export class EvaluatableExpression implements vscode.EvaluatableExpression {
|
||||
}
|
||||
|
||||
export enum InlineCompletionTriggerKind {
|
||||
Automatic = 0,
|
||||
Explicit = 1,
|
||||
Invoke = 0,
|
||||
Automatic = 1,
|
||||
}
|
||||
|
||||
export enum InlineCompletionTriggerKindNew {
|
||||
|
||||
Reference in New Issue
Block a user