mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-23 10:08:49 +01:00
Add PasteEditProvider (#107283)
For #30066 This adds a new `documentPaste` api proposal that lets extensions hook into copy and paste. This can be used to do things such as: - Create link when pasting an image - Bring along imports when copy and pasting code
This commit is contained in:
@@ -457,6 +457,10 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
registerCodeActionsProvider(selector: vscode.DocumentSelector, provider: vscode.CodeActionProvider, metadata?: vscode.CodeActionProviderMetadata): vscode.Disposable {
|
||||
return extHostLanguageFeatures.registerCodeActionProvider(extension, checkSelector(selector), provider, metadata);
|
||||
},
|
||||
registerDocumentPasteEditProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentPasteEditProvider): vscode.Disposable {
|
||||
checkProposedApiEnabled(extension, 'documentPaste');
|
||||
return extHostLanguageFeatures.registerDocumentPasteEditProvider(extension, checkSelector(selector), provider);
|
||||
},
|
||||
registerCodeLensProvider(selector: vscode.DocumentSelector, provider: vscode.CodeLensProvider): vscode.Disposable {
|
||||
return extHostLanguageFeatures.registerCodeLensProvider(extension, checkSelector(selector), provider);
|
||||
},
|
||||
|
||||
@@ -372,6 +372,7 @@ export interface MainThreadLanguageFeaturesShape extends IDisposable {
|
||||
$registerLinkedEditingRangeProvider(handle: number, selector: IDocumentFilterDto[]): void;
|
||||
$registerReferenceSupport(handle: number, selector: IDocumentFilterDto[]): void;
|
||||
$registerQuickFixSupport(handle: number, selector: IDocumentFilterDto[], metadata: ICodeActionProviderMetadataDto, displayName: string, supportsResolve: boolean): void;
|
||||
$registerPasteEditProvider(handle: number, selector: IDocumentFilterDto[], supportsCopy: boolean): void;
|
||||
$registerDocumentFormattingSupport(handle: number, selector: IDocumentFilterDto[], extensionId: ExtensionIdentifier, displayName: string): void;
|
||||
$registerRangeFormattingSupport(handle: number, selector: IDocumentFilterDto[], extensionId: ExtensionIdentifier, displayName: string): void;
|
||||
$registerOnTypeFormattingSupport(handle: number, selector: IDocumentFilterDto[], autoFormatTriggerCharacters: string[], extensionId: ExtensionIdentifier): void;
|
||||
@@ -1730,6 +1731,8 @@ export interface ExtHostLanguageFeaturesShape {
|
||||
$provideCodeActions(handle: number, resource: UriComponents, rangeOrSelection: IRange | ISelection, context: languages.CodeActionContext, token: CancellationToken): Promise<ICodeActionListDto | undefined>;
|
||||
$resolveCodeAction(handle: number, id: ChainedCacheId, token: CancellationToken): Promise<IWorkspaceEditDto | undefined>;
|
||||
$releaseCodeActions(handle: number, cacheId: number): void;
|
||||
$prepareDocumentPaste(handle: number, uri: UriComponents, range: IRange, dataTransfer: DataTransferDTO, token: CancellationToken): Promise<DataTransferDTO | undefined>;
|
||||
$providePasteEdits(handle: number, uri: UriComponents, range: IRange, dataTransfer: DataTransferDTO, token: CancellationToken): Promise<IWorkspaceEditDto | Dto<languages.SnippetTextEdit> | undefined>;
|
||||
$provideDocumentFormattingEdits(handle: number, resource: UriComponents, options: languages.FormattingOptions, token: CancellationToken): Promise<ISingleEditOperation[] | undefined>;
|
||||
$provideDocumentRangeFormattingEdits(handle: number, resource: UriComponents, range: IRange, options: languages.FormattingOptions, token: CancellationToken): Promise<ISingleEditOperation[] | undefined>;
|
||||
$provideOnTypeFormattingEdits(handle: number, resource: UriComponents, position: IPosition, ch: string, options: languages.FormattingOptions, token: CancellationToken): Promise<ISingleEditOperation[] | undefined>;
|
||||
|
||||
@@ -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, InlineCompletionTriggerKind } from 'vs/workbench/api/common/extHostTypes';
|
||||
import { Range, Disposable, CompletionList, SnippetString, CodeActionKind, SymbolInformation, DocumentSymbol, SemanticTokensEdits, SemanticTokens, SemanticTokensEdit, Location, InlineCompletionTriggerKindNew, InlineCompletionTriggerKind, WorkspaceEdit } 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';
|
||||
@@ -31,7 +31,7 @@ import { IdGenerator } from 'vs/base/common/idGenerator';
|
||||
import { IExtHostApiDeprecationService } from 'vs/workbench/api/common/extHostApiDeprecationService';
|
||||
import { Cache } from './cache';
|
||||
import { StopWatch } from 'vs/base/common/stopwatch';
|
||||
import { isCancellationError } from 'vs/base/common/errors';
|
||||
import { isCancellationError, NotImplementedError } from 'vs/base/common/errors';
|
||||
import { raceCancellationError } from 'vs/base/common/async';
|
||||
import { isProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { Dto } from 'vs/workbench/services/extensions/common/proxyIdentifier';
|
||||
@@ -485,6 +485,52 @@ class CodeActionAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
class DocumentPasteEditProvider {
|
||||
|
||||
constructor(
|
||||
private readonly _proxy: extHostProtocol.MainThreadLanguageFeaturesShape,
|
||||
private readonly _documents: ExtHostDocuments,
|
||||
private readonly _provider: vscode.DocumentPasteEditProvider,
|
||||
private readonly _handle: number,
|
||||
) { }
|
||||
|
||||
async prepareDocumentPaste(resource: URI, range: IRange, dataTransferDto: extHostProtocol.DataTransferDTO, token: CancellationToken): Promise<extHostProtocol.DataTransferDTO | undefined> {
|
||||
if (!this._provider.prepareDocumentPaste) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const doc = this._documents.getDocument(resource);
|
||||
const vscodeRange = typeConvert.Range.to(range);
|
||||
|
||||
const dataTransfer = typeConvert.DataTransfer.toDataTransfer(dataTransferDto, () => {
|
||||
throw new NotImplementedError();
|
||||
});
|
||||
await this._provider.prepareDocumentPaste(doc, vscodeRange, dataTransfer, token);
|
||||
|
||||
return typeConvert.DataTransfer.toDataTransferDTO(dataTransfer);
|
||||
}
|
||||
|
||||
async providePasteEdits(requestId: number, resource: URI, range: IRange, dataTransferDto: extHostProtocol.DataTransferDTO, token: CancellationToken): Promise<undefined | extHostProtocol.IWorkspaceEditDto | Dto<languages.SnippetTextEdit>> {
|
||||
const doc = this._documents.getDocument(resource);
|
||||
const vscodeRange = typeConvert.Range.to(range);
|
||||
|
||||
const dataTransfer = typeConvert.DataTransfer.toDataTransfer(dataTransferDto, async (index) => {
|
||||
return (await this._proxy.$resolveDocumentOnDropFileData(this._handle, requestId, index)).buffer;
|
||||
});
|
||||
|
||||
const edit = await this._provider.provideDocumentPasteEdits(doc, vscodeRange, dataTransfer, token);
|
||||
if (!edit) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (edit instanceof WorkspaceEdit) {
|
||||
return typeConvert.WorkspaceEdit.from(edit);
|
||||
} else {
|
||||
return typeConvert.SnippetTextEdit.from(edit as vscode.SnippetTextEdit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class DocumentFormattingAdapter {
|
||||
|
||||
constructor(
|
||||
@@ -1769,7 +1815,7 @@ class DocumentOnDropEditAdapter {
|
||||
}
|
||||
|
||||
type Adapter = DocumentSymbolAdapter | CodeLensAdapter | DefinitionAdapter | HoverAdapter
|
||||
| DocumentHighlightAdapter | ReferenceAdapter | CodeActionAdapter | DocumentFormattingAdapter
|
||||
| DocumentHighlightAdapter | ReferenceAdapter | CodeActionAdapter | DocumentPasteEditProvider | DocumentFormattingAdapter
|
||||
| RangeFormattingAdapter | OnTypeFormattingAdapter | NavigateTypeAdapter | RenameAdapter
|
||||
| CompletionsAdapter | SignatureHelpAdapter | LinkProviderAdapter | ImplementationAdapter
|
||||
| TypeDefinitionAdapter | ColorProviderAdapter | FoldingProviderAdapter | DeclarationAdapter
|
||||
@@ -2413,6 +2459,23 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF
|
||||
Promise.resolve(adapter.provideDocumentOnDropEdits(requestId, URI.revive(resource), position, dataTransferDto, token)), undefined, undefined);
|
||||
}
|
||||
|
||||
// --- copy/paste actions
|
||||
|
||||
registerDocumentPasteEditProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.DocumentPasteEditProvider): vscode.Disposable {
|
||||
const handle = this._nextHandle();
|
||||
this._adapter.set(handle, new AdapterData(new DocumentPasteEditProvider(this._proxy, this._documents, provider, handle), extension));
|
||||
this._proxy.$registerPasteEditProvider(handle, this._transformDocumentSelector(selector), !!provider.prepareDocumentPaste);
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
|
||||
$prepareDocumentPaste(handle: number, resource: UriComponents, range: IRange, dataTransfer: extHostProtocol.DataTransferDTO, token: CancellationToken): Promise<extHostProtocol.DataTransferDTO | undefined> {
|
||||
return this._withAdapter(handle, DocumentPasteEditProvider, adapter => adapter.prepareDocumentPaste(URI.revive(resource), range, dataTransfer, token), undefined, token);
|
||||
}
|
||||
|
||||
$providePasteEdits(handle: number, resource: UriComponents, range: IRange, dataTransferDto: extHostProtocol.DataTransferDTO, token: CancellationToken): Promise<extHostProtocol.IWorkspaceEditDto | Dto<languages.SnippetTextEdit> | undefined> {
|
||||
return this._withAdapter(handle, DocumentPasteEditProvider, adapter => adapter.providePasteEdits(0, URI.revive(resource), range, dataTransferDto, token), undefined, token);
|
||||
}
|
||||
|
||||
// --- configuration
|
||||
|
||||
private static _serializeRegExp(regExp: RegExp): extHostProtocol.IRegExpDto {
|
||||
|
||||
Reference in New Issue
Block a user