diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index a885606999e..2a09a8b1f41 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -1439,6 +1439,10 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I checkProposedApiEnabled(extension, 'mappedEditsProvider'); return extHostLanguageFeatures.registerMappedEditsProvider(extension, selector, provider); }, + registerMappedEditsProvider2(provider: vscode.MappedEditsProvider2) { + checkProposedApiEnabled(extension, 'mappedEditsProvider'); + return extHostLanguageFeatures.registerMappedEditsProvider2(extension, provider); + }, createChatParticipant(id: string, handler: vscode.ChatExtendedRequestHandler) { return extHostChatAgents2.createChatAgent(extension, id, handler); }, diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 526e9666065..417748e7fd9 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -392,6 +392,16 @@ export interface IMappedEditsContextDto { conversation?: IConversationItemDto[]; } +export interface IMappedEditsRequestDto { + readonly resource: UriComponents; + readonly codeBlock: string; + readonly conversation?: IConversationItemDto[]; +} + +export interface IMappedEditsResultDto { + readonly errorMessage?: string; +} + export interface ISignatureHelpProviderMetadataDto { readonly triggerCharacters: readonly string[]; readonly retriggerCharacters: readonly string[]; @@ -455,6 +465,7 @@ export interface MainThreadLanguageFeaturesShape extends IDisposable { $resolveDocumentOnDropFileData(handle: number, requestId: number, dataId: string): Promise; $setLanguageConfiguration(handle: number, languageId: string, configuration: ILanguageConfigurationDto): void; $registerMappedEditsProvider(handle: number, selector: IDocumentFilterDto[], displayName: string): void; + $registerMappedEditsProvider2(handle: number, displayName: string): void; } export interface MainThreadLanguagesShape extends IDisposable { diff --git a/src/vs/workbench/api/common/extHostLanguageFeatures.ts b/src/vs/workbench/api/common/extHostLanguageFeatures.ts index 9459f74eb4f..cb294bec4be 100644 --- a/src/vs/workbench/api/common/extHostLanguageFeatures.ts +++ b/src/vs/workbench/api/common/extHostLanguageFeatures.ts @@ -2133,6 +2133,12 @@ class DocumentDropEditAdapter { } } +const reviveContextItem = (item: extHostProtocol.IDocumentContextItemDto) => ({ + uri: URI.revive(item.uri), + version: item.version, + ranges: item.ranges.map(r => typeConvert.Range.to(r)), +} satisfies vscode.DocumentContextItem); + class MappedEditsAdapter { constructor( @@ -2149,14 +2155,6 @@ class MappedEditsAdapter { const uri = URI.revive(resource); const doc = this._documents.getDocument(uri); - - const reviveContextItem = (item: extHostProtocol.IDocumentContextItemDto) => ({ - uri: URI.revive(item.uri), - version: item.version, - ranges: item.ranges.map(r => typeConvert.Range.to(r)), - } satisfies vscode.DocumentContextItem); - - const usedContext = context.documents.map(docSubArray => docSubArray.map(reviveContextItem)); const ctx = { @@ -2184,6 +2182,41 @@ class MappedEditsAdapter { } } +class MappedEditsAdapter2 { + + constructor( + private readonly _provider: vscode.MappedEditsProvider2, + ) { } + + async provideMappedEdits( + request: extHostProtocol.IMappedEditsRequestDto, + response: extHostProtocol.IMappedEditsResponseDto, + token: CancellationToken + ): Promise { + + const revivedRequest = { + resource: URI.revive(request.resource), + codeBlock: request.codeBlock, + conversation: request.conversation?.map(c => { + if (c.type === 'response') { + return { + type: 'response', + message: c.message, + references: c.references?.map(reviveContextItem) + } satisfies vscode.ConversationResponse; + } else { + return { + type: 'request', + message: c.message, + } satisfies vscode.ConversationRequest; + } + }) + } satisfies vscode.MappedEditsRequest; + + return this._provider.provideMappedEdits(revivedRequest, response, token); + } +} + type Adapter = DocumentSymbolAdapter | CodeLensAdapter | DefinitionAdapter | HoverAdapter | DocumentHighlightAdapter | MultiDocumentHighlightAdapter | ReferenceAdapter | CodeActionAdapter | DocumentPasteEditProvider | DocumentFormattingAdapter | RangeFormattingAdapter @@ -2194,7 +2227,7 @@ type Adapter = DocumentSymbolAdapter | CodeLensAdapter | DefinitionAdapter | Hov | DocumentSemanticTokensAdapter | DocumentRangeSemanticTokensAdapter | EvaluatableExpressionAdapter | InlineValuesAdapter | LinkedEditingRangeAdapter | InlayHintsAdapter | InlineCompletionAdapter - | DocumentDropEditAdapter | MappedEditsAdapter | NewSymbolNamesAdapter | InlineEditAdapter; + | DocumentDropEditAdapter | MappedEditsAdapter | MappedEditsAdapter2 | NewSymbolNamesAdapter | InlineEditAdapter; class AdapterData { constructor( @@ -2920,6 +2953,12 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF Promise.resolve(adapter.provideMappedEdits(document, codeBlocks, context, token)), null, token); } + registerMappedEditsProvider2(extension: IExtensionDescription, provider: vscode.MappedEditsProvider2): vscode.Disposable { + const handle = this._addNewAdapter(new MappedEditsAdapter2(provider), extension); + this._proxy.$registerMappedEditsProvider2(handle, extension.displayName ?? extension.name); + return this._createDisposable(handle); + } + // --- copy/paste actions registerDocumentPasteEditProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.DocumentPasteEditProvider, metadata: vscode.DocumentPasteProviderMetadata): vscode.Disposable { diff --git a/src/vscode-dts/vscode.proposed.mappedEditsProvider.d.ts b/src/vscode-dts/vscode.proposed.mappedEditsProvider.d.ts index 9b7ba15c596..2692669ffb4 100644 --- a/src/vscode-dts/vscode.proposed.mappedEditsProvider.d.ts +++ b/src/vscode-dts/vscode.proposed.mappedEditsProvider.d.ts @@ -52,7 +52,34 @@ declare module 'vscode' { ): ProviderResult; } + export interface MappedEditsRequest { + readonly resource: Uri; + readonly codeBlock: string; + readonly conversation?: (ConversationRequest | ConversationResponse)[]; + } + + export interface MappedEditsResposeStream { + edit(value: TextEdit, resource: Uri): void; + } + + export interface MappedEditsResult { + readonly errorMessage?: string; + } + + /** + * Interface for providing mapped edits for a given document. + */ + export interface MappedEditsProvider2 { + provideMappedEdits( + request: MappedEditsRequest, + result: MappedEditsResposeStream, + token: CancellationToken + ): ProviderResult; + } + namespace chat { export function registerMappedEditsProvider(documentSelector: DocumentSelector, provider: MappedEditsProvider): Disposable; + + export function registerMappedEditsProvider2(provider: MappedEditsProvider2): Disposable; } }