Merge and cleanup drop and paste proposal (#209591)

These two proposals overlap a lot and will be finalized together
This commit is contained in:
Matt Bierner 2024-04-05 13:03:10 -07:00 committed by GitHub
parent 235d4d104b
commit 8c363b460b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
26 changed files with 254 additions and 185 deletions

View file

@ -11,8 +11,7 @@
}, },
"enabledApiProposals": [ "enabledApiProposals": [
"documentPaste", "documentPaste",
"diffContentOptions", "diffContentOptions"
"dropMetadata"
], ],
"activationEvents": [ "activationEvents": [
"onNotebook:jupyter-notebook", "onNotebook:jupyter-notebook",

View file

@ -48,7 +48,7 @@ function getImageMimeType(uri: vscode.Uri): string | undefined {
class DropOrPasteEditProvider implements vscode.DocumentPasteEditProvider, vscode.DocumentDropEditProvider { class DropOrPasteEditProvider implements vscode.DocumentPasteEditProvider, vscode.DocumentDropEditProvider {
public static readonly kind = vscode.DocumentPasteEditKind.Empty.append('markdown', 'image', 'attachment'); public static readonly kind = vscode.DocumentDropOrPasteEditKind.Empty.append('markdown', 'image', 'attachment');
async provideDocumentPasteEdits( async provideDocumentPasteEdits(
document: vscode.TextDocument, document: vscode.TextDocument,
@ -68,7 +68,7 @@ class DropOrPasteEditProvider implements vscode.DocumentPasteEditProvider, vscod
} }
const pasteEdit = new vscode.DocumentPasteEdit(insert.insertText, vscode.l10n.t('Insert Image as Attachment'), DropOrPasteEditProvider.kind); const pasteEdit = new vscode.DocumentPasteEdit(insert.insertText, vscode.l10n.t('Insert Image as Attachment'), DropOrPasteEditProvider.kind);
pasteEdit.yieldTo = [vscode.DocumentPasteEditKind.Empty.append('text')]; pasteEdit.yieldTo = [vscode.DocumentDropOrPasteEditKind.Empty.append('text')];
pasteEdit.additionalEdit = insert.additionalEdit; pasteEdit.additionalEdit = insert.additionalEdit;
return [pasteEdit]; return [pasteEdit];
} }
@ -85,7 +85,7 @@ class DropOrPasteEditProvider implements vscode.DocumentPasteEditProvider, vscod
} }
const dropEdit = new vscode.DocumentDropEdit(insert.insertText); const dropEdit = new vscode.DocumentDropEdit(insert.insertText);
dropEdit.yieldTo = [vscode.DocumentPasteEditKind.Empty.append('text')]; dropEdit.yieldTo = [vscode.DocumentDropOrPasteEditKind.Empty.append('text')];
dropEdit.additionalEdit = insert.additionalEdit; dropEdit.additionalEdit = insert.additionalEdit;
dropEdit.title = vscode.l10n.t('Insert Image as Attachment'); dropEdit.title = vscode.l10n.t('Insert Image as Attachment');
return dropEdit; return dropEdit;

View file

@ -7,8 +7,6 @@
"include": [ "include": [
"src/**/*", "src/**/*",
"../../src/vscode-dts/vscode.d.ts", "../../src/vscode-dts/vscode.d.ts",
"../../src/vscode-dts/vscode.proposed.documentPaste.d.ts", "../../src/vscode-dts/vscode.proposed.documentPaste.d.ts"
"../../src/vscode-dts/vscode.proposed.dropMetadata.d.ts"
] ]
} }

View file

@ -16,8 +16,7 @@
"Programming Languages" "Programming Languages"
], ],
"enabledApiProposals": [ "enabledApiProposals": [
"documentPaste", "documentPaste"
"dropMetadata"
], ],
"activationEvents": [ "activationEvents": [
"onLanguage:markdown", "onLanguage:markdown",

View file

@ -30,7 +30,7 @@ enum CopyFilesSettings {
*/ */
class ResourcePasteOrDropProvider implements vscode.DocumentPasteEditProvider, vscode.DocumentDropEditProvider { class ResourcePasteOrDropProvider implements vscode.DocumentPasteEditProvider, vscode.DocumentDropEditProvider {
public static readonly kind = vscode.DocumentPasteEditKind.Empty.append('markdown', 'link'); public static readonly kind = vscode.DocumentDropOrPasteEditKind.Empty.append('markdown', 'link');
public static readonly mimeTypes = [ public static readonly mimeTypes = [
Mime.textUriList, Mime.textUriList,
@ -39,8 +39,8 @@ class ResourcePasteOrDropProvider implements vscode.DocumentPasteEditProvider, v
]; ];
private readonly _yieldTo = [ private readonly _yieldTo = [
vscode.DocumentPasteEditKind.Empty.append('text'), vscode.DocumentDropOrPasteEditKind.Empty.append('text'),
vscode.DocumentPasteEditKind.Empty.append('markdown', 'image', 'attachment'), vscode.DocumentDropOrPasteEditKind.Empty.append('markdown', 'image', 'attachment'),
]; ];
constructor( constructor(
@ -133,7 +133,7 @@ class ResourcePasteOrDropProvider implements vscode.DocumentPasteEditProvider, v
} }
if (!(await shouldInsertMarkdownLinkByDefault(this._parser, document, settings.insert, ranges, token))) { if (!(await shouldInsertMarkdownLinkByDefault(this._parser, document, settings.insert, ranges, token))) {
edit.yieldTo.push(vscode.DocumentPasteEditKind.Empty.append('uri')); edit.yieldTo.push(vscode.DocumentDropOrPasteEditKind.Empty.append('uri'));
} }
return edit; return edit;

View file

@ -17,7 +17,7 @@ import { UriList } from '../../util/uriList';
*/ */
class PasteUrlEditProvider implements vscode.DocumentPasteEditProvider { class PasteUrlEditProvider implements vscode.DocumentPasteEditProvider {
public static readonly kind = vscode.DocumentPasteEditKind.Empty.append('markdown', 'link'); public static readonly kind = vscode.DocumentDropOrPasteEditKind.Empty.append('markdown', 'link');
public static readonly pasteMimeTypes = [Mime.textPlain]; public static readonly pasteMimeTypes = [Mime.textPlain];
@ -61,8 +61,8 @@ class PasteUrlEditProvider implements vscode.DocumentPasteEditProvider {
if (!(await shouldInsertMarkdownLinkByDefault(this._parser, document, pasteUrlSetting, ranges, token))) { if (!(await shouldInsertMarkdownLinkByDefault(this._parser, document, pasteUrlSetting, ranges, token))) {
pasteEdit.yieldTo = [ pasteEdit.yieldTo = [
vscode.DocumentPasteEditKind.Empty.append('text'), vscode.DocumentDropOrPasteEditKind.Empty.append('text'),
vscode.DocumentPasteEditKind.Empty.append('uri') vscode.DocumentDropOrPasteEditKind.Empty.append('uri')
]; ];
} }

View file

@ -265,5 +265,5 @@ export interface DropOrPasteEdit {
readonly snippet: vscode.SnippetString; readonly snippet: vscode.SnippetString;
readonly label: string; readonly label: string;
readonly additionalEdits: vscode.WorkspaceEdit; readonly additionalEdits: vscode.WorkspaceEdit;
readonly yieldTo: vscode.DocumentPasteEditKind[]; readonly yieldTo: vscode.DocumentDropOrPasteEditKind[];
} }

View file

@ -9,7 +9,7 @@ import { Mime } from '../util/mimes';
class UpdatePastedLinksEditProvider implements vscode.DocumentPasteEditProvider { class UpdatePastedLinksEditProvider implements vscode.DocumentPasteEditProvider {
public static readonly kind = vscode.DocumentPasteEditKind.Empty.append('text', 'markdown', 'updateLinks'); public static readonly kind = vscode.DocumentDropOrPasteEditKind.Empty.append('text', 'markdown', 'updateLinks');
public static readonly metadataMime = 'vnd.vscode.markdown.updateLinksMetadata'; public static readonly metadataMime = 'vnd.vscode.markdown.updateLinksMetadata';

View file

@ -6,7 +6,6 @@
"include": [ "include": [
"src/**/*", "src/**/*",
"../../src/vscode-dts/vscode.d.ts", "../../src/vscode-dts/vscode.d.ts",
"../../src/vscode-dts/vscode.proposed.documentPaste.d.ts", "../../src/vscode-dts/vscode.proposed.documentPaste.d.ts"
"../../src/vscode-dts/vscode.proposed.dropMetadata.d.ts"
] ]
} }

View file

@ -37,7 +37,7 @@ suite.skip('vscode API - Copy Paste', function () {
dataTransfer.set(textPlain, new vscode.DataTransferItem(reversed)); dataTransfer.set(textPlain, new vscode.DataTransferItem(reversed));
} }
} }
}, { providedPasteEditKinds: [vscode.DocumentPasteEditKind.Empty.append('test')], copyMimeTypes: [textPlain] })); }, { providedPasteEditKinds: [vscode.DocumentDropOrPasteEditKind.Empty.append('test')], copyMimeTypes: [textPlain] }));
await vscode.commands.executeCommand('editor.action.clipboardCopyAction'); await vscode.commands.executeCommand('editor.action.clipboardCopyAction');
const newDocContent = getNextDocumentText(testDisposables, doc); const newDocContent = getNextDocumentText(testDisposables, doc);
@ -62,7 +62,7 @@ suite.skip('vscode API - Copy Paste', function () {
dataTransfer.set(textPlain, new vscode.DataTransferItem(reversed + '\n')); dataTransfer.set(textPlain, new vscode.DataTransferItem(reversed + '\n'));
} }
} }
}, { providedPasteEditKinds: [vscode.DocumentPasteEditKind.Empty.append('test')], copyMimeTypes: [textPlain] })); }, { providedPasteEditKinds: [vscode.DocumentDropOrPasteEditKind.Empty.append('test')], copyMimeTypes: [textPlain] }));
await vscode.commands.executeCommand('editor.action.clipboardCopyAction'); await vscode.commands.executeCommand('editor.action.clipboardCopyAction');
const newDocContent = getNextDocumentText(testDisposables, doc); const newDocContent = getNextDocumentText(testDisposables, doc);
@ -88,7 +88,7 @@ suite.skip('vscode API - Copy Paste', function () {
dataTransfer.set(textPlain, new vscode.DataTransferItem(`(${ranges.length})${selections.join(' ')}`)); dataTransfer.set(textPlain, new vscode.DataTransferItem(`(${ranges.length})${selections.join(' ')}`));
} }
} }
}, { providedPasteEditKinds: [vscode.DocumentPasteEditKind.Empty.append('test')], copyMimeTypes: [textPlain] })); }, { providedPasteEditKinds: [vscode.DocumentDropOrPasteEditKind.Empty.append('test')], copyMimeTypes: [textPlain] }));
await vscode.commands.executeCommand('editor.action.clipboardCopyAction'); await vscode.commands.executeCommand('editor.action.clipboardCopyAction');
editor.selections = [new vscode.Selection(0, 0, 0, 0)]; editor.selections = [new vscode.Selection(0, 0, 0, 0)];
@ -118,7 +118,7 @@ suite.skip('vscode API - Copy Paste', function () {
dataTransfer.set(textPlain, new vscode.DataTransferItem('a')); dataTransfer.set(textPlain, new vscode.DataTransferItem('a'));
providerAResolve(); providerAResolve();
} }
}, { providedPasteEditKinds: [vscode.DocumentPasteEditKind.Empty.append('test')], copyMimeTypes: [textPlain] })); }, { providedPasteEditKinds: [vscode.DocumentDropOrPasteEditKind.Empty.append('test')], copyMimeTypes: [textPlain] }));
// Later registered providers will be called first // Later registered providers will be called first
testDisposables.push(vscode.languages.registerDocumentPasteEditProvider({ language: 'plaintext' }, new class implements vscode.DocumentPasteEditProvider { testDisposables.push(vscode.languages.registerDocumentPasteEditProvider({ language: 'plaintext' }, new class implements vscode.DocumentPasteEditProvider {
@ -132,7 +132,7 @@ suite.skip('vscode API - Copy Paste', function () {
dataTransfer.set(textPlain, new vscode.DataTransferItem('b')); dataTransfer.set(textPlain, new vscode.DataTransferItem('b'));
} }
}, { providedPasteEditKinds: [vscode.DocumentPasteEditKind.Empty.append('test')], copyMimeTypes: [textPlain] })); }, { providedPasteEditKinds: [vscode.DocumentDropOrPasteEditKind.Empty.append('test')], copyMimeTypes: [textPlain] }));
await vscode.commands.executeCommand('editor.action.clipboardCopyAction'); await vscode.commands.executeCommand('editor.action.clipboardCopyAction');
const newDocContent = getNextDocumentText(testDisposables, doc); const newDocContent = getNextDocumentText(testDisposables, doc);
@ -159,7 +159,7 @@ suite.skip('vscode API - Copy Paste', function () {
dataTransfer.set(textPlain, new vscode.DataTransferItem('xyz')); dataTransfer.set(textPlain, new vscode.DataTransferItem('xyz'));
providerAResolve(); providerAResolve();
} }
}, { providedPasteEditKinds: [vscode.DocumentPasteEditKind.Empty.append('test')], copyMimeTypes: [textPlain] })); }, { providedPasteEditKinds: [vscode.DocumentDropOrPasteEditKind.Empty.append('test')], copyMimeTypes: [textPlain] }));
testDisposables.push(vscode.languages.registerDocumentPasteEditProvider({ language: 'plaintext' }, new class implements vscode.DocumentPasteEditProvider { testDisposables.push(vscode.languages.registerDocumentPasteEditProvider({ language: 'plaintext' }, new class implements vscode.DocumentPasteEditProvider {
async prepareDocumentPaste(_document: vscode.TextDocument, _ranges: readonly vscode.Range[], dataTransfer: vscode.DataTransfer, _token: vscode.CancellationToken): Promise<void> { async prepareDocumentPaste(_document: vscode.TextDocument, _ranges: readonly vscode.Range[], dataTransfer: vscode.DataTransfer, _token: vscode.CancellationToken): Promise<void> {
@ -172,7 +172,7 @@ suite.skip('vscode API - Copy Paste', function () {
const str = await entry!.asString(); const str = await entry!.asString();
dataTransfer.set(textPlain, new vscode.DataTransferItem(reverseString(str))); dataTransfer.set(textPlain, new vscode.DataTransferItem(reverseString(str)));
} }
}, { providedPasteEditKinds: [vscode.DocumentPasteEditKind.Empty.append('test')], copyMimeTypes: [textPlain] })); }, { providedPasteEditKinds: [vscode.DocumentDropOrPasteEditKind.Empty.append('test')], copyMimeTypes: [textPlain] }));
await vscode.commands.executeCommand('editor.action.clipboardCopyAction'); await vscode.commands.executeCommand('editor.action.clipboardCopyAction');
const newDocContent = getNextDocumentText(testDisposables, doc); const newDocContent = getNextDocumentText(testDisposables, doc);
@ -192,13 +192,13 @@ suite.skip('vscode API - Copy Paste', function () {
async prepareDocumentPaste(_document: vscode.TextDocument, _ranges: readonly vscode.Range[], dataTransfer: vscode.DataTransfer, _token: vscode.CancellationToken): Promise<void> { async prepareDocumentPaste(_document: vscode.TextDocument, _ranges: readonly vscode.Range[], dataTransfer: vscode.DataTransfer, _token: vscode.CancellationToken): Promise<void> {
dataTransfer.set(textPlain, new vscode.DataTransferItem('xyz')); dataTransfer.set(textPlain, new vscode.DataTransferItem('xyz'));
} }
}, { providedPasteEditKinds: [vscode.DocumentPasteEditKind.Empty.append('test')], copyMimeTypes: [textPlain] })); }, { providedPasteEditKinds: [vscode.DocumentDropOrPasteEditKind.Empty.append('test')], copyMimeTypes: [textPlain] }));
testDisposables.push(vscode.languages.registerDocumentPasteEditProvider({ language: 'plaintext' }, new class implements vscode.DocumentPasteEditProvider { testDisposables.push(vscode.languages.registerDocumentPasteEditProvider({ language: 'plaintext' }, new class implements vscode.DocumentPasteEditProvider {
async prepareDocumentPaste(_document: vscode.TextDocument, _ranges: readonly vscode.Range[], _dataTransfer: vscode.DataTransfer, _token: vscode.CancellationToken): Promise<void> { async prepareDocumentPaste(_document: vscode.TextDocument, _ranges: readonly vscode.Range[], _dataTransfer: vscode.DataTransfer, _token: vscode.CancellationToken): Promise<void> {
throw new Error('Expected testing error from bad provider'); throw new Error('Expected testing error from bad provider');
} }
}, { providedPasteEditKinds: [vscode.DocumentPasteEditKind.Empty.append('test')], copyMimeTypes: [textPlain] })); }, { providedPasteEditKinds: [vscode.DocumentDropOrPasteEditKind.Empty.append('test')], copyMimeTypes: [textPlain] }));
await vscode.commands.executeCommand('editor.action.clipboardCopyAction'); await vscode.commands.executeCommand('editor.action.clipboardCopyAction');
const newDocContent = getNextDocumentText(testDisposables, doc); const newDocContent = getNextDocumentText(testDisposables, doc);

View file

@ -2146,7 +2146,7 @@ export type DropYieldTo = { readonly kind: HierarchicalKind } | { readonly mimeT
/** /**
* @internal * @internal
*/ */
export interface DocumentOnDropEdit { export interface DocumentDropEdit {
readonly title: string; readonly title: string;
readonly kind: HierarchicalKind | undefined; readonly kind: HierarchicalKind | undefined;
readonly handledMimeType?: string; readonly handledMimeType?: string;
@ -2158,11 +2158,12 @@ export interface DocumentOnDropEdit {
/** /**
* @internal * @internal
*/ */
export interface DocumentOnDropEditProvider { export interface DocumentDropEditProvider {
readonly id?: string; readonly id?: string;
readonly dropMimeTypes?: readonly string[]; readonly dropMimeTypes?: readonly string[];
provideDocumentOnDropEdits(model: model.ITextModel, position: IPosition, dataTransfer: IReadonlyVSDataTransfer, token: CancellationToken): ProviderResult<DocumentOnDropEdit[]>; provideDocumentDropEdits(model: model.ITextModel, position: IPosition, dataTransfer: IReadonlyVSDataTransfer, token: CancellationToken): ProviderResult<DocumentDropEdit[]>;
resolveDocumentDropEdit?(edit: DocumentDropEdit, token: CancellationToken): Promise<DocumentDropEdit>;
} }
export interface DocumentContextItem { export interface DocumentContextItem {

View file

@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { LanguageFeatureRegistry, NotebookInfoResolver } from 'vs/editor/common/languageFeatureRegistry'; import { LanguageFeatureRegistry, NotebookInfoResolver } from 'vs/editor/common/languageFeatureRegistry';
import { CodeActionProvider, CodeLensProvider, CompletionItemProvider, DeclarationProvider, DefinitionProvider, DocumentColorProvider, DocumentFormattingEditProvider, DocumentHighlightProvider, DocumentOnDropEditProvider, DocumentPasteEditProvider, DocumentRangeFormattingEditProvider, DocumentRangeSemanticTokensProvider, DocumentSemanticTokensProvider, DocumentSymbolProvider, EvaluatableExpressionProvider, FoldingRangeProvider, HoverProvider, ImplementationProvider, InlayHintsProvider, InlineCompletionsProvider, InlineValuesProvider, LinkedEditingRangeProvider, LinkProvider, MappedEditsProvider, MultiDocumentHighlightProvider, NewSymbolNamesProvider, OnTypeFormattingEditProvider, ReferenceProvider, RenameProvider, SelectionRangeProvider, SignatureHelpProvider, TypeDefinitionProvider, InlineEditProvider } from 'vs/editor/common/languages'; import { CodeActionProvider, CodeLensProvider, CompletionItemProvider, DeclarationProvider, DefinitionProvider, DocumentColorProvider, DocumentFormattingEditProvider, DocumentHighlightProvider, DocumentDropEditProvider, DocumentPasteEditProvider, DocumentRangeFormattingEditProvider, DocumentRangeSemanticTokensProvider, DocumentSemanticTokensProvider, DocumentSymbolProvider, EvaluatableExpressionProvider, FoldingRangeProvider, HoverProvider, ImplementationProvider, InlayHintsProvider, InlineCompletionsProvider, InlineValuesProvider, LinkedEditingRangeProvider, LinkProvider, MappedEditsProvider, MultiDocumentHighlightProvider, NewSymbolNamesProvider, OnTypeFormattingEditProvider, ReferenceProvider, RenameProvider, SelectionRangeProvider, SignatureHelpProvider, TypeDefinitionProvider, InlineEditProvider } from 'vs/editor/common/languages';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
export const ILanguageFeaturesService = createDecorator<ILanguageFeaturesService>('ILanguageFeaturesService'); export const ILanguageFeaturesService = createDecorator<ILanguageFeaturesService>('ILanguageFeaturesService');
@ -75,7 +75,7 @@ export interface ILanguageFeaturesService {
readonly evaluatableExpressionProvider: LanguageFeatureRegistry<EvaluatableExpressionProvider>; readonly evaluatableExpressionProvider: LanguageFeatureRegistry<EvaluatableExpressionProvider>;
readonly documentOnDropEditProvider: LanguageFeatureRegistry<DocumentOnDropEditProvider>; readonly documentDropEditProvider: LanguageFeatureRegistry<DocumentDropEditProvider>;
readonly mappedEditsProvider: LanguageFeatureRegistry<MappedEditsProvider>; readonly mappedEditsProvider: LanguageFeatureRegistry<MappedEditsProvider>;

View file

@ -5,7 +5,7 @@
import { URI } from 'vs/base/common/uri'; import { URI } from 'vs/base/common/uri';
import { LanguageFeatureRegistry, NotebookInfo, NotebookInfoResolver } from 'vs/editor/common/languageFeatureRegistry'; import { LanguageFeatureRegistry, NotebookInfo, NotebookInfoResolver } from 'vs/editor/common/languageFeatureRegistry';
import { CodeActionProvider, CodeLensProvider, CompletionItemProvider, DocumentPasteEditProvider, DeclarationProvider, DefinitionProvider, DocumentColorProvider, DocumentFormattingEditProvider, MultiDocumentHighlightProvider, DocumentHighlightProvider, DocumentOnDropEditProvider, DocumentRangeFormattingEditProvider, DocumentRangeSemanticTokensProvider, DocumentSemanticTokensProvider, DocumentSymbolProvider, EvaluatableExpressionProvider, FoldingRangeProvider, HoverProvider, ImplementationProvider, InlayHintsProvider, InlineCompletionsProvider, InlineValuesProvider, LinkedEditingRangeProvider, LinkProvider, OnTypeFormattingEditProvider, ReferenceProvider, RenameProvider, SelectionRangeProvider, SignatureHelpProvider, TypeDefinitionProvider, MappedEditsProvider, NewSymbolNamesProvider, InlineEditProvider } from 'vs/editor/common/languages'; import { CodeActionProvider, CodeLensProvider, CompletionItemProvider, DocumentPasteEditProvider, DeclarationProvider, DefinitionProvider, DocumentColorProvider, DocumentFormattingEditProvider, MultiDocumentHighlightProvider, DocumentHighlightProvider, DocumentDropEditProvider, DocumentRangeFormattingEditProvider, DocumentRangeSemanticTokensProvider, DocumentSemanticTokensProvider, DocumentSymbolProvider, EvaluatableExpressionProvider, FoldingRangeProvider, HoverProvider, ImplementationProvider, InlayHintsProvider, InlineCompletionsProvider, InlineValuesProvider, LinkedEditingRangeProvider, LinkProvider, OnTypeFormattingEditProvider, ReferenceProvider, RenameProvider, SelectionRangeProvider, SignatureHelpProvider, TypeDefinitionProvider, MappedEditsProvider, NewSymbolNamesProvider, InlineEditProvider } from 'vs/editor/common/languages';
import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures';
import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions';
@ -43,7 +43,7 @@ export class LanguageFeaturesService implements ILanguageFeaturesService {
readonly evaluatableExpressionProvider = new LanguageFeatureRegistry<EvaluatableExpressionProvider>(this._score.bind(this)); readonly evaluatableExpressionProvider = new LanguageFeatureRegistry<EvaluatableExpressionProvider>(this._score.bind(this));
readonly documentRangeSemanticTokensProvider = new LanguageFeatureRegistry<DocumentRangeSemanticTokensProvider>(this._score.bind(this)); readonly documentRangeSemanticTokensProvider = new LanguageFeatureRegistry<DocumentRangeSemanticTokensProvider>(this._score.bind(this));
readonly documentSemanticTokensProvider = new LanguageFeatureRegistry<DocumentSemanticTokensProvider>(this._score.bind(this)); readonly documentSemanticTokensProvider = new LanguageFeatureRegistry<DocumentSemanticTokensProvider>(this._score.bind(this));
readonly documentOnDropEditProvider = new LanguageFeatureRegistry<DocumentOnDropEditProvider>(this._score.bind(this)); readonly documentDropEditProvider = new LanguageFeatureRegistry<DocumentDropEditProvider>(this._score.bind(this));
readonly documentPasteEditProvider = new LanguageFeatureRegistry<DocumentPasteEditProvider>(this._score.bind(this)); readonly documentPasteEditProvider = new LanguageFeatureRegistry<DocumentPasteEditProvider>(this._score.bind(this));
readonly mappedEditsProvider: LanguageFeatureRegistry<MappedEditsProvider> = new LanguageFeatureRegistry<MappedEditsProvider>(this._score.bind(this)); readonly mappedEditsProvider: LanguageFeatureRegistry<MappedEditsProvider> = new LanguageFeatureRegistry<MappedEditsProvider>(this._score.bind(this));

View file

@ -14,14 +14,14 @@ import { relativePath } from 'vs/base/common/resources';
import { URI } from 'vs/base/common/uri'; import { URI } from 'vs/base/common/uri';
import { IPosition } from 'vs/editor/common/core/position'; import { IPosition } from 'vs/editor/common/core/position';
import { IRange } from 'vs/editor/common/core/range'; import { IRange } from 'vs/editor/common/core/range';
import { DocumentOnDropEdit, DocumentOnDropEditProvider, DocumentPasteContext, DocumentPasteEdit, DocumentPasteEditProvider, DocumentPasteEditsSession, DocumentPasteTriggerKind } from 'vs/editor/common/languages'; import { DocumentDropEdit, DocumentDropEditProvider, DocumentPasteContext, DocumentPasteEdit, DocumentPasteEditProvider, DocumentPasteEditsSession, DocumentPasteTriggerKind } from 'vs/editor/common/languages';
import { ITextModel } from 'vs/editor/common/model'; import { ITextModel } from 'vs/editor/common/model';
import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures';
import { localize } from 'vs/nls'; import { localize } from 'vs/nls';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
abstract class SimplePasteAndDropProvider implements DocumentOnDropEditProvider, DocumentPasteEditProvider { abstract class SimplePasteAndDropProvider implements DocumentDropEditProvider, DocumentPasteEditProvider {
abstract readonly kind: HierarchicalKind; abstract readonly kind: HierarchicalKind;
abstract readonly dropMimeTypes: readonly string[] | undefined; abstract readonly dropMimeTypes: readonly string[] | undefined;
@ -39,7 +39,7 @@ abstract class SimplePasteAndDropProvider implements DocumentOnDropEditProvider,
}; };
} }
async provideDocumentOnDropEdits(_model: ITextModel, _position: IPosition, dataTransfer: IReadonlyVSDataTransfer, token: CancellationToken): Promise<DocumentOnDropEdit[] | undefined> { async provideDocumentDropEdits(_model: ITextModel, _position: IPosition, dataTransfer: IReadonlyVSDataTransfer, token: CancellationToken): Promise<DocumentDropEdit[] | undefined> {
const edit = await this.getEdit(dataTransfer, token); const edit = await this.getEdit(dataTransfer, token);
return edit ? [{ insertText: edit.insertText, title: edit.title, kind: edit.kind, handledMimeType: edit.handledMimeType, yieldTo: edit.yieldTo }] : undefined; return edit ? [{ insertText: edit.insertText, title: edit.title, kind: edit.kind, handledMimeType: edit.handledMimeType, yieldTo: edit.yieldTo }] : undefined;
} }
@ -219,9 +219,9 @@ export class DefaultDropProvidersFeature extends Disposable {
) { ) {
super(); super();
this._register(languageFeaturesService.documentOnDropEditProvider.register('*', new DefaultTextPasteOrDropEditProvider())); this._register(languageFeaturesService.documentDropEditProvider.register('*', new DefaultTextPasteOrDropEditProvider()));
this._register(languageFeaturesService.documentOnDropEditProvider.register('*', new PathProvider())); this._register(languageFeaturesService.documentDropEditProvider.register('*', new PathProvider()));
this._register(languageFeaturesService.documentOnDropEditProvider.register('*', new RelativePathProvider(workspaceContextService))); this._register(languageFeaturesService.documentDropEditProvider.register('*', new RelativePathProvider(workspaceContextService)));
} }
} }

View file

@ -14,7 +14,7 @@ import { EditorOption } from 'vs/editor/common/config/editorOptions';
import { IPosition } from 'vs/editor/common/core/position'; import { IPosition } from 'vs/editor/common/core/position';
import { Range } from 'vs/editor/common/core/range'; import { Range } from 'vs/editor/common/core/range';
import { IEditorContribution } from 'vs/editor/common/editorCommon'; import { IEditorContribution } from 'vs/editor/common/editorCommon';
import { DocumentOnDropEdit, DocumentOnDropEditProvider } from 'vs/editor/common/languages'; import { DocumentDropEdit, DocumentDropEditProvider } from 'vs/editor/common/languages';
import { ITextModel } from 'vs/editor/common/model'; import { ITextModel } from 'vs/editor/common/model';
import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures';
import { DraggedTreeItemsIdentifier } from 'vs/editor/common/services/treeViewsDnd'; import { DraggedTreeItemsIdentifier } from 'vs/editor/common/services/treeViewsDnd';
@ -46,7 +46,7 @@ export class DropIntoEditorController extends Disposable implements IEditorContr
private _currentOperation?: CancelablePromise<void>; private _currentOperation?: CancelablePromise<void>;
private readonly _dropProgressManager: InlineProgressManager; private readonly _dropProgressManager: InlineProgressManager;
private readonly _postDropWidgetManager: PostEditWidgetManager<DocumentOnDropEdit>; private readonly _postDropWidgetManager: PostEditWidgetManager<DocumentDropEdit>;
private readonly treeItemsTransfer = LocalSelectionTransfer.getInstance<DraggedTreeItemsIdentifier>(); private readonly treeItemsTransfer = LocalSelectionTransfer.getInstance<DraggedTreeItemsIdentifier>();
@ -97,7 +97,7 @@ export class DropIntoEditorController extends Disposable implements IEditorContr
return; return;
} }
const providers = this._languageFeaturesService.documentOnDropEditProvider const providers = this._languageFeaturesService.documentDropEditProvider
.ordered(model) .ordered(model)
.filter(provider => { .filter(provider => {
if (!provider.dropMimeTypes) { if (!provider.dropMimeTypes) {
@ -130,10 +130,10 @@ export class DropIntoEditorController extends Disposable implements IEditorContr
this._currentOperation = p; this._currentOperation = p;
} }
private async getDropEdits(providers: readonly DocumentOnDropEditProvider[], model: ITextModel, position: IPosition, dataTransfer: VSDataTransfer, tokenSource: EditorStateCancellationTokenSource) { private async getDropEdits(providers: readonly DocumentDropEditProvider[], model: ITextModel, position: IPosition, dataTransfer: VSDataTransfer, tokenSource: EditorStateCancellationTokenSource) {
const results = await raceCancellation(Promise.all(providers.map(async provider => { const results = await raceCancellation(Promise.all(providers.map(async provider => {
try { try {
const edits = await provider.provideDocumentOnDropEdits(model, position, dataTransfer, tokenSource.token); const edits = await provider.provideDocumentDropEdits(model, position, dataTransfer, tokenSource.token);
return edits?.map(edit => ({ ...edit, providerId: provider.id })); return edits?.map(edit => ({ ...edit, providerId: provider.id }));
} catch (err) { } catch (err) {
console.error(err); console.error(err);
@ -145,7 +145,7 @@ export class DropIntoEditorController extends Disposable implements IEditorContr
return sortEditsByYieldTo(edits); return sortEditsByYieldTo(edits);
} }
private getInitialActiveEditIndex(model: ITextModel, edits: ReadonlyArray<DocumentOnDropEdit & { readonly providerId?: string }>) { private getInitialActiveEditIndex(model: ITextModel, edits: ReadonlyArray<DocumentDropEdit & { readonly providerId?: string }>) {
const preferredProviders = this._configService.getValue<Record<string, string>>(defaultProviderConfig, { resource: model.uri }); const preferredProviders = this._configService.getValue<Record<string, string>>(defaultProviderConfig, { resource: model.uri });
for (const [configMime, desiredKindStr] of Object.entries(preferredProviders)) { for (const [configMime, desiredKindStr] of Object.entries(preferredProviders)) {
const desiredKind = new HierarchicalKind(desiredKindStr); const desiredKind = new HierarchicalKind(desiredKindStr);

View file

@ -5,7 +5,7 @@
import { URI } from 'vs/base/common/uri'; import { URI } from 'vs/base/common/uri';
import { ResourceTextEdit } from 'vs/editor/browser/services/bulkEditService'; import { ResourceTextEdit } from 'vs/editor/browser/services/bulkEditService';
import { DocumentOnDropEdit, DocumentPasteEdit, DropYieldTo, WorkspaceEdit } from 'vs/editor/common/languages'; import { DocumentDropEdit, DocumentPasteEdit, DropYieldTo, WorkspaceEdit } from 'vs/editor/common/languages';
import { Range } from 'vs/editor/common/core/range'; import { Range } from 'vs/editor/common/core/range';
import { SnippetParser } from 'vs/editor/contrib/snippet/browser/snippetParser'; import { SnippetParser } from 'vs/editor/contrib/snippet/browser/snippetParser';
import { HierarchicalKind } from 'vs/base/common/hierarchicalKind'; import { HierarchicalKind } from 'vs/base/common/hierarchicalKind';
@ -14,7 +14,7 @@ import { HierarchicalKind } from 'vs/base/common/hierarchicalKind';
* Given a {@link DropOrPasteEdit} and set of ranges, creates a {@link WorkspaceEdit} that applies the insert text from * Given a {@link DropOrPasteEdit} and set of ranges, creates a {@link WorkspaceEdit} that applies the insert text from
* the {@link DropOrPasteEdit} at each range plus any additional edits. * the {@link DropOrPasteEdit} at each range plus any additional edits.
*/ */
export function createCombinedWorkspaceEdit(uri: URI, ranges: readonly Range[], edit: DocumentPasteEdit | DocumentOnDropEdit): WorkspaceEdit { export function createCombinedWorkspaceEdit(uri: URI, ranges: readonly Range[], edit: DocumentPasteEdit | DocumentDropEdit): WorkspaceEdit {
// If the edit insert text is empty, skip applying at each range // If the edit insert text is empty, skip applying at each range
if (typeof edit.insertText === 'string' ? edit.insertText === '' : edit.insertText.snippet === '') { if (typeof edit.insertText === 'string' ? edit.insertText === '' : edit.insertText.snippet === '') {
return { return {

View file

@ -13,7 +13,7 @@ import 'vs/css!./postEditWidget';
import { ContentWidgetPositionPreference, ICodeEditor, IContentWidget, IContentWidgetPosition } from 'vs/editor/browser/editorBrowser'; import { ContentWidgetPositionPreference, ICodeEditor, IContentWidget, IContentWidgetPosition } from 'vs/editor/browser/editorBrowser';
import { IBulkEditResult, IBulkEditService } from 'vs/editor/browser/services/bulkEditService'; import { IBulkEditResult, IBulkEditService } from 'vs/editor/browser/services/bulkEditService';
import { Range } from 'vs/editor/common/core/range'; import { Range } from 'vs/editor/common/core/range';
import { DocumentOnDropEdit, DocumentPasteEdit } from 'vs/editor/common/languages'; import { DocumentDropEdit, DocumentPasteEdit } from 'vs/editor/common/languages';
import { TrackedRangeStickiness } from 'vs/editor/common/model'; import { TrackedRangeStickiness } from 'vs/editor/common/model';
import { createCombinedWorkspaceEdit } from 'vs/editor/contrib/dropOrPasteInto/browser/edit'; import { createCombinedWorkspaceEdit } from 'vs/editor/contrib/dropOrPasteInto/browser/edit';
import { IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
@ -22,7 +22,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
interface EditSet<Edit extends DocumentPasteEdit | DocumentOnDropEdit> { interface EditSet<Edit extends DocumentPasteEdit | DocumentDropEdit> {
readonly activeEditIndex: number; readonly activeEditIndex: number;
readonly allEdits: ReadonlyArray<Edit>; readonly allEdits: ReadonlyArray<Edit>;
} }
@ -32,7 +32,7 @@ interface ShowCommand {
readonly label: string; readonly label: string;
} }
class PostEditWidget<T extends DocumentPasteEdit | DocumentOnDropEdit> extends Disposable implements IContentWidget { class PostEditWidget<T extends DocumentPasteEdit | DocumentDropEdit> extends Disposable implements IContentWidget {
private static readonly baseId = 'editor.widget.postEditWidget'; private static readonly baseId = 'editor.widget.postEditWidget';
readonly allowEditorOverflow = true; readonly allowEditorOverflow = true;
@ -132,7 +132,7 @@ class PostEditWidget<T extends DocumentPasteEdit | DocumentOnDropEdit> extends D
} }
} }
export class PostEditWidgetManager<T extends DocumentPasteEdit | DocumentOnDropEdit> extends Disposable { export class PostEditWidgetManager<T extends DocumentPasteEdit | DocumentDropEdit> extends Disposable {
private readonly _currentWidget = this._register(new MutableDisposable<PostEditWidget<T>>()); private readonly _currentWidget = this._register(new MutableDisposable<PostEditWidget<T>>());

View file

@ -5,11 +5,11 @@
import * as assert from 'assert'; import * as assert from 'assert';
import { HierarchicalKind } from 'vs/base/common/hierarchicalKind'; import { HierarchicalKind } from 'vs/base/common/hierarchicalKind';
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
import { DocumentOnDropEdit } from 'vs/editor/common/languages'; import { DocumentDropEdit } from 'vs/editor/common/languages';
import { sortEditsByYieldTo } from 'vs/editor/contrib/dropOrPasteInto/browser/edit'; import { sortEditsByYieldTo } from 'vs/editor/contrib/dropOrPasteInto/browser/edit';
function createTestEdit(kind: string, args?: Partial<DocumentOnDropEdit>): DocumentOnDropEdit { function createTestEdit(kind: string, args?: Partial<DocumentDropEdit>): DocumentDropEdit {
return { return {
title: '', title: '',
insertText: '', insertText: '',
@ -21,13 +21,13 @@ function createTestEdit(kind: string, args?: Partial<DocumentOnDropEdit>): Docum
suite('sortEditsByYieldTo', () => { suite('sortEditsByYieldTo', () => {
test('Should noop for empty edits', () => { test('Should noop for empty edits', () => {
const edits: DocumentOnDropEdit[] = []; const edits: DocumentDropEdit[] = [];
assert.deepStrictEqual(sortEditsByYieldTo(edits), []); assert.deepStrictEqual(sortEditsByYieldTo(edits), []);
}); });
test('Yielded to edit should get sorted after target', () => { test('Yielded to edit should get sorted after target', () => {
const edits: DocumentOnDropEdit[] = [ const edits: DocumentDropEdit[] = [
createTestEdit('a', { yieldTo: [{ kind: new HierarchicalKind('b') }] }), createTestEdit('a', { yieldTo: [{ kind: new HierarchicalKind('b') }] }),
createTestEdit('b'), createTestEdit('b'),
]; ];
@ -36,7 +36,7 @@ suite('sortEditsByYieldTo', () => {
test('Should handle chain of yield to', () => { test('Should handle chain of yield to', () => {
{ {
const edits: DocumentOnDropEdit[] = [ const edits: DocumentDropEdit[] = [
createTestEdit('c', { yieldTo: [{ kind: new HierarchicalKind('a') }] }), createTestEdit('c', { yieldTo: [{ kind: new HierarchicalKind('a') }] }),
createTestEdit('a', { yieldTo: [{ kind: new HierarchicalKind('b') }] }), createTestEdit('a', { yieldTo: [{ kind: new HierarchicalKind('b') }] }),
createTestEdit('b'), createTestEdit('b'),
@ -45,7 +45,7 @@ suite('sortEditsByYieldTo', () => {
assert.deepStrictEqual(sortEditsByYieldTo(edits).map(x => x.kind?.value), ['b', 'a', 'c']); assert.deepStrictEqual(sortEditsByYieldTo(edits).map(x => x.kind?.value), ['b', 'a', 'c']);
} }
{ {
const edits: DocumentOnDropEdit[] = [ const edits: DocumentDropEdit[] = [
createTestEdit('a', { yieldTo: [{ kind: new HierarchicalKind('b') }] }), createTestEdit('a', { yieldTo: [{ kind: new HierarchicalKind('b') }] }),
createTestEdit('c', { yieldTo: [{ kind: new HierarchicalKind('a') }] }), createTestEdit('c', { yieldTo: [{ kind: new HierarchicalKind('a') }] }),
createTestEdit('b'), createTestEdit('b'),
@ -56,7 +56,7 @@ suite('sortEditsByYieldTo', () => {
}); });
test(`Should not reorder when yield to isn't used`, () => { test(`Should not reorder when yield to isn't used`, () => {
const edits: DocumentOnDropEdit[] = [ const edits: DocumentDropEdit[] = [
createTestEdit('c', { yieldTo: [{ kind: new HierarchicalKind('x') }] }), createTestEdit('c', { yieldTo: [{ kind: new HierarchicalKind('x') }] }),
createTestEdit('a', { yieldTo: [{ kind: new HierarchicalKind('y') }] }), createTestEdit('a', { yieldTo: [{ kind: new HierarchicalKind('y') }] }),
createTestEdit('b'), createTestEdit('b'),

View file

@ -32,7 +32,7 @@ import * as callh from 'vs/workbench/contrib/callHierarchy/common/callHierarchy'
import * as search from 'vs/workbench/contrib/search/common/search'; import * as search from 'vs/workbench/contrib/search/common/search';
import * as typeh from 'vs/workbench/contrib/typeHierarchy/common/typeHierarchy'; import * as typeh from 'vs/workbench/contrib/typeHierarchy/common/typeHierarchy';
import { extHostNamedCustomer, IExtHostContext } from 'vs/workbench/services/extensions/common/extHostCustomers'; import { extHostNamedCustomer, IExtHostContext } from 'vs/workbench/services/extensions/common/extHostCustomers';
import { ExtHostContext, ExtHostLanguageFeaturesShape, ICallHierarchyItemDto, ICodeActionDto, ICodeActionProviderMetadataDto, IdentifiableInlineCompletion, IdentifiableInlineCompletions, IdentifiableInlineEdit, IDocumentDropEditProviderMetadata, IDocumentFilterDto, IIndentationRuleDto, IInlayHintDto, ILanguageConfigurationDto, ILanguageWordDefinitionDto, ILinkDto, ILocationDto, ILocationLinkDto, IOnEnterRuleDto, IPasteEditDto, IPasteEditProviderMetadataDto, IRegExpDto, ISignatureHelpProviderMetadataDto, ISuggestDataDto, ISuggestDataDtoField, ISuggestResultDtoField, ITypeHierarchyItemDto, IWorkspaceSymbolDto, MainContext, MainThreadLanguageFeaturesShape } from '../common/extHost.protocol'; import { ExtHostContext, ExtHostLanguageFeaturesShape, ICallHierarchyItemDto, ICodeActionDto, ICodeActionProviderMetadataDto, IdentifiableInlineCompletion, IdentifiableInlineCompletions, IdentifiableInlineEdit, IDocumentDropEditDto, IDocumentDropEditProviderMetadata, IDocumentFilterDto, IIndentationRuleDto, IInlayHintDto, ILanguageConfigurationDto, ILanguageWordDefinitionDto, ILinkDto, ILocationDto, ILocationLinkDto, IOnEnterRuleDto, IPasteEditDto, IPasteEditProviderMetadataDto, IRegExpDto, ISignatureHelpProviderMetadataDto, ISuggestDataDto, ISuggestDataDtoField, ISuggestResultDtoField, ITypeHierarchyItemDto, IWorkspaceSymbolDto, MainContext, MainThreadLanguageFeaturesShape } from '../common/extHost.protocol';
import { ResourceMap } from 'vs/base/common/map'; import { ResourceMap } from 'vs/base/common/map';
import { isFalsyOrEmpty } from 'vs/base/common/arrays'; import { isFalsyOrEmpty } from 'vs/base/common/arrays';
import { HierarchicalKind } from 'vs/base/common/hierarchicalKind'; import { HierarchicalKind } from 'vs/base/common/hierarchicalKind';
@ -968,7 +968,7 @@ export class MainThreadLanguageFeatures extends Disposable implements MainThread
const provider = new MainThreadDocumentOnDropEditProvider(handle, this._proxy, metadata, this._uriIdentService); const provider = new MainThreadDocumentOnDropEditProvider(handle, this._proxy, metadata, this._uriIdentService);
this._documentOnDropEditProviders.set(handle, provider); this._documentOnDropEditProviders.set(handle, provider);
this._registrations.set(handle, combinedDisposable( this._registrations.set(handle, combinedDisposable(
this._languageFeaturesService.documentOnDropEditProvider.register(selector, provider), this._languageFeaturesService.documentDropEditProvider.register(selector, provider),
toDisposable(() => this._documentOnDropEditProviders.delete(handle)), toDisposable(() => this._documentOnDropEditProviders.delete(handle)),
)); ));
} }
@ -1082,12 +1082,14 @@ class MainThreadPasteEditProvider implements languages.DocumentPasteEditProvider
} }
} }
class MainThreadDocumentOnDropEditProvider implements languages.DocumentOnDropEditProvider { class MainThreadDocumentOnDropEditProvider implements languages.DocumentDropEditProvider {
private readonly dataTransfers = new DataTransferFileCache(); private readonly dataTransfers = new DataTransferFileCache();
readonly dropMimeTypes?: readonly string[]; readonly dropMimeTypes?: readonly string[];
readonly resolveDocumentDropEdit?: languages.DocumentDropEditProvider['resolveDocumentDropEdit'];
constructor( constructor(
private readonly _handle: number, private readonly _handle: number,
private readonly _proxy: ExtHostLanguageFeaturesShape, private readonly _proxy: ExtHostLanguageFeaturesShape,
@ -1095,9 +1097,19 @@ class MainThreadDocumentOnDropEditProvider implements languages.DocumentOnDropEd
@IUriIdentityService private readonly _uriIdentService: IUriIdentityService @IUriIdentityService private readonly _uriIdentService: IUriIdentityService
) { ) {
this.dropMimeTypes = metadata?.dropMimeTypes ?? ['*/*']; this.dropMimeTypes = metadata?.dropMimeTypes ?? ['*/*'];
if (metadata?.supportsResolve) {
this.resolveDocumentDropEdit = async (edit, token) => {
const resolved = await this._proxy.$resolvePasteEdit(this._handle, (<IDocumentDropEditDto>edit)._cacheId!, token);
if (resolved.additionalEdit) {
edit.additionalEdit = reviveWorkspaceEditDto(resolved.additionalEdit, this._uriIdentService);
}
return edit;
};
}
} }
async provideDocumentOnDropEdits(model: ITextModel, position: IPosition, dataTransfer: IReadonlyVSDataTransfer, token: CancellationToken): Promise<languages.DocumentOnDropEdit[] | undefined> { async provideDocumentDropEdits(model: ITextModel, position: IPosition, dataTransfer: IReadonlyVSDataTransfer, token: CancellationToken): Promise<languages.DocumentDropEdit[] | undefined> {
const request = this.dataTransfers.add(dataTransfer); const request = this.dataTransfers.add(dataTransfer);
try { try {
const dataTransferDto = await typeConvert.DataTransfer.from(dataTransfer); const dataTransferDto = await typeConvert.DataTransfer.from(dataTransfer);

View file

@ -665,7 +665,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
return extHostLanguages.createLanguageStatusItem(extension, id, selector); return extHostLanguages.createLanguageStatusItem(extension, id, selector);
}, },
registerDocumentDropEditProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentDropEditProvider, metadata?: vscode.DocumentDropEditProviderMetadata): vscode.Disposable { registerDocumentDropEditProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentDropEditProvider, metadata?: vscode.DocumentDropEditProviderMetadata): vscode.Disposable {
return extHostLanguageFeatures.registerDocumentOnDropEditProvider(extension, selector, provider, isProposedApiEnabled(extension, 'dropMetadata') ? metadata : undefined); return extHostLanguageFeatures.registerDocumentOnDropEditProvider(extension, selector, provider, isProposedApiEnabled(extension, 'documentPaste') ? metadata : undefined);
} }
}; };
@ -1624,7 +1624,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
// proposed api types // proposed api types
DocumentPasteTriggerKind: extHostTypes.DocumentPasteTriggerKind, DocumentPasteTriggerKind: extHostTypes.DocumentPasteTriggerKind,
DocumentDropEdit: extHostTypes.DocumentDropEdit, DocumentDropEdit: extHostTypes.DocumentDropEdit,
DocumentPasteEditKind: extHostTypes.DocumentPasteEditKind, DocumentDropOrPasteEditKind: extHostTypes.DocumentDropOrPasteEditKind,
DocumentPasteEdit: extHostTypes.DocumentPasteEdit, DocumentPasteEdit: extHostTypes.DocumentPasteEdit,
InlayHint: extHostTypes.InlayHint, InlayHint: extHostTypes.InlayHint,
InlayHintLabelPart: extHostTypes.InlayHintLabelPart, InlayHintLabelPart: extHostTypes.InlayHintLabelPart,

View file

@ -2082,7 +2082,6 @@ export interface IPasteEditProviderMetadataDto {
export interface IDocumentPasteContextDto { export interface IDocumentPasteContextDto {
readonly only: string | undefined; readonly only: string | undefined;
readonly triggerKind: languages.DocumentPasteTriggerKind; readonly triggerKind: languages.DocumentPasteTriggerKind;
} }
export interface IPasteEditDto { export interface IPasteEditDto {
@ -2095,10 +2094,13 @@ export interface IPasteEditDto {
} }
export interface IDocumentDropEditProviderMetadata { export interface IDocumentDropEditProviderMetadata {
readonly supportsResolve: boolean;
dropMimeTypes: readonly string[]; dropMimeTypes: readonly string[];
} }
export interface IDocumentOnDropEditDto { export interface IDocumentDropEditDto {
_cacheId?: ChainedCacheId;
title: string; title: string;
kind: string | undefined; kind: string | undefined;
insertText: string | { snippet: string }; insertText: string | { snippet: string };
@ -2170,7 +2172,7 @@ export interface ExtHostLanguageFeaturesShape {
$provideTypeHierarchySupertypes(handle: number, sessionId: string, itemId: string, token: CancellationToken): Promise<ITypeHierarchyItemDto[] | undefined>; $provideTypeHierarchySupertypes(handle: number, sessionId: string, itemId: string, token: CancellationToken): Promise<ITypeHierarchyItemDto[] | undefined>;
$provideTypeHierarchySubtypes(handle: number, sessionId: string, itemId: string, token: CancellationToken): Promise<ITypeHierarchyItemDto[] | undefined>; $provideTypeHierarchySubtypes(handle: number, sessionId: string, itemId: string, token: CancellationToken): Promise<ITypeHierarchyItemDto[] | undefined>;
$releaseTypeHierarchy(handle: number, sessionId: string): void; $releaseTypeHierarchy(handle: number, sessionId: string): void;
$provideDocumentOnDropEdits(handle: number, requestId: number, resource: UriComponents, position: IPosition, dataTransferDto: DataTransferDTO, token: CancellationToken): Promise<IDocumentOnDropEditDto[] | undefined>; $provideDocumentOnDropEdits(handle: number, requestId: number, resource: UriComponents, position: IPosition, dataTransferDto: DataTransferDTO, token: CancellationToken): Promise<IDocumentDropEditDto[] | undefined>;
$provideMappedEdits(handle: number, document: UriComponents, codeBlocks: string[], context: IMappedEditsContextDto, token: CancellationToken): Promise<IWorkspaceEditDto | null>; $provideMappedEdits(handle: number, document: UriComponents, codeBlocks: string[], context: IMappedEditsContextDto, token: CancellationToken): Promise<IWorkspaceEditDto | null>;
$provideInlineEdit(handle: number, document: UriComponents, context: languages.IInlineEditContext, token: CancellationToken): Promise<IdentifiableInlineEdit | undefined>; $provideInlineEdit(handle: number, document: UriComponents, context: languages.IInlineEditContext, token: CancellationToken): Promise<IdentifiableInlineEdit | undefined>;
$freeInlineEdit(handle: number, pid: number): void; $freeInlineEdit(handle: number, pid: number): void;

View file

@ -32,7 +32,7 @@ import { ExtHostDiagnostics } from 'vs/workbench/api/common/extHostDiagnostics';
import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments'; import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments';
import { ExtHostTelemetry, IExtHostTelemetry } from 'vs/workbench/api/common/extHostTelemetry'; import { ExtHostTelemetry, IExtHostTelemetry } from 'vs/workbench/api/common/extHostTelemetry';
import * as typeConvert from 'vs/workbench/api/common/extHostTypeConverters'; import * as typeConvert from 'vs/workbench/api/common/extHostTypeConverters';
import { CodeActionKind, CompletionList, Disposable, DocumentPasteEditKind, DocumentSymbol, InlineCompletionTriggerKind, InlineEditTriggerKind, InternalDataTransferItem, Location, Range, SemanticTokens, SemanticTokensEdit, SemanticTokensEdits, SnippetString, SymbolInformation, SyntaxTokenType } from 'vs/workbench/api/common/extHostTypes'; import { CodeActionKind, CompletionList, Disposable, DocumentDropOrPasteEditKind, DocumentSymbol, InlineCompletionTriggerKind, InlineEditTriggerKind, InternalDataTransferItem, Location, Range, SemanticTokens, SemanticTokensEdit, SemanticTokensEdits, SnippetString, SymbolInformation, SyntaxTokenType } from 'vs/workbench/api/common/extHostTypes';
import { isProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions'; import { isProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
import type * as vscode from 'vscode'; import type * as vscode from 'vscode';
import { Cache } from './cache'; import { Cache } from './cache';
@ -581,7 +581,7 @@ class DocumentPasteEditProvider {
}); });
const edits = await this._provider.provideDocumentPasteEdits(doc, vscodeRanges, dataTransfer, { const edits = await this._provider.provideDocumentPasteEdits(doc, vscodeRanges, dataTransfer, {
only: context.only ? new DocumentPasteEditKind(context.only) : undefined, only: context.only ? new DocumentDropOrPasteEditKind(context.only) : undefined,
triggerKind: context.triggerKind, triggerKind: context.triggerKind,
}, token); }, token);
if (!edits || token.isCancellationRequested) { if (!edits || token.isCancellationRequested) {
@ -1956,7 +1956,9 @@ class TypeHierarchyAdapter {
} }
} }
class DocumentOnDropEditAdapter { class DocumentDropEditAdapter {
private readonly _cache = new Cache<vscode.DocumentDropEdit>('DocumentDropEdit');
constructor( constructor(
private readonly _proxy: extHostProtocol.MainThreadLanguageFeaturesShape, private readonly _proxy: extHostProtocol.MainThreadLanguageFeaturesShape,
@ -1966,7 +1968,7 @@ class DocumentOnDropEditAdapter {
private readonly _extension: IExtensionDescription, private readonly _extension: IExtensionDescription,
) { } ) { }
async provideDocumentOnDropEdits(requestId: number, uri: URI, position: IPosition, dataTransferDto: extHostProtocol.DataTransferDTO, token: CancellationToken): Promise<extHostProtocol.IDocumentOnDropEditDto[] | undefined> { async provideDocumentOnDropEdits(requestId: number, uri: URI, position: IPosition, dataTransferDto: extHostProtocol.DataTransferDTO, token: CancellationToken): Promise<extHostProtocol.IDocumentDropEditDto[] | undefined> {
const doc = this._documents.getDocument(uri); const doc = this._documents.getDocument(uri);
const pos = typeConvert.Position.to(position); const pos = typeConvert.Position.to(position);
const dataTransfer = typeConvert.DataTransfer.toDataTransfer(dataTransferDto, async (id) => { const dataTransfer = typeConvert.DataTransfer.toDataTransfer(dataTransferDto, async (id) => {
@ -1978,7 +1980,11 @@ class DocumentOnDropEditAdapter {
return undefined; return undefined;
} }
return asArray(edits).map((edit): extHostProtocol.IDocumentOnDropEditDto => ({ const editsArray = asArray(edits);
const cacheId = this._cache.add(editsArray);
return editsArray.map((edit, i): extHostProtocol.IDocumentDropEditDto => ({
_cacheId: [cacheId, i],
title: edit.title ?? localize('defaultDropLabel', "Drop using '{0}' extension", this._extension.displayName || this._extension.name), title: edit.title ?? localize('defaultDropLabel', "Drop using '{0}' extension", this._extension.displayName || this._extension.name),
kind: edit.kind?.value, kind: edit.kind?.value,
yieldTo: edit.yieldTo?.map(x => x.value), yieldTo: edit.yieldTo?.map(x => x.value),
@ -1986,6 +1992,22 @@ class DocumentOnDropEditAdapter {
additionalEdit: edit.additionalEdit ? typeConvert.WorkspaceEdit.from(edit.additionalEdit, undefined) : undefined, additionalEdit: edit.additionalEdit ? typeConvert.WorkspaceEdit.from(edit.additionalEdit, undefined) : undefined,
})); }));
} }
async resolveDropEdit(id: extHostProtocol.ChainedCacheId, token: CancellationToken): Promise<{ additionalEdit?: extHostProtocol.IWorkspaceEditDto }> {
const [sessionId, itemId] = id;
const item = this._cache.get(sessionId, itemId);
if (!item || !this._provider.resolveDocumentDropEdit) {
return {}; // this should not happen...
}
const resolvedItem = (await this._provider.resolveDocumentDropEdit(item, token)) ?? item;
const additionalEdit = resolvedItem.additionalEdit ? typeConvert.WorkspaceEdit.from(resolvedItem.additionalEdit, undefined) : undefined;
return { additionalEdit };
}
releaseDropEdits(id: number): any {
this._cache.delete(id);
}
} }
class MappedEditsAdapter { class MappedEditsAdapter {
@ -2036,7 +2058,7 @@ type Adapter = DocumentSymbolAdapter | CodeLensAdapter | DefinitionAdapter | Hov
| DocumentSemanticTokensAdapter | DocumentRangeSemanticTokensAdapter | DocumentSemanticTokensAdapter | DocumentRangeSemanticTokensAdapter
| EvaluatableExpressionAdapter | InlineValuesAdapter | EvaluatableExpressionAdapter | InlineValuesAdapter
| LinkedEditingRangeAdapter | InlayHintsAdapter | InlineCompletionAdapter | LinkedEditingRangeAdapter | InlayHintsAdapter | InlineCompletionAdapter
| DocumentOnDropEditAdapter | MappedEditsAdapter | NewSymbolNamesAdapter | InlineEditAdapter; | DocumentDropEditAdapter | MappedEditsAdapter | NewSymbolNamesAdapter | InlineEditAdapter;
class AdapterData { class AdapterData {
constructor( constructor(
@ -2704,18 +2726,29 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF
registerDocumentOnDropEditProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.DocumentDropEditProvider, metadata?: vscode.DocumentDropEditProviderMetadata) { registerDocumentOnDropEditProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.DocumentDropEditProvider, metadata?: vscode.DocumentDropEditProviderMetadata) {
const handle = this._nextHandle(); const handle = this._nextHandle();
this._adapter.set(handle, new AdapterData(new DocumentOnDropEditAdapter(this._proxy, this._documents, provider, handle, extension), extension)); this._adapter.set(handle, new AdapterData(new DocumentDropEditAdapter(this._proxy, this._documents, provider, handle, extension), extension));
this._proxy.$registerDocumentOnDropEditProvider(handle, this._transformDocumentSelector(selector, extension), isProposedApiEnabled(extension, 'dropMetadata') ? metadata : undefined); this._proxy.$registerDocumentOnDropEditProvider(handle, this._transformDocumentSelector(selector, extension), isProposedApiEnabled(extension, 'documentPaste') && metadata ? {
supportsResolve: !!provider.resolveDocumentDropEdit,
dropMimeTypes: metadata.dropMimeTypes,
} : undefined);
return this._createDisposable(handle); return this._createDisposable(handle);
} }
$provideDocumentOnDropEdits(handle: number, requestId: number, resource: UriComponents, position: IPosition, dataTransferDto: extHostProtocol.DataTransferDTO, token: CancellationToken): Promise<extHostProtocol.IDocumentOnDropEditDto[] | undefined> { $provideDocumentOnDropEdits(handle: number, requestId: number, resource: UriComponents, position: IPosition, dataTransferDto: extHostProtocol.DataTransferDTO, token: CancellationToken): Promise<extHostProtocol.IDocumentDropEditDto[] | undefined> {
return this._withAdapter(handle, DocumentOnDropEditAdapter, adapter => return this._withAdapter(handle, DocumentDropEditAdapter, adapter =>
Promise.resolve(adapter.provideDocumentOnDropEdits(requestId, URI.revive(resource), position, dataTransferDto, token)), undefined, undefined); Promise.resolve(adapter.provideDocumentOnDropEdits(requestId, URI.revive(resource), position, dataTransferDto, token)), undefined, undefined);
} }
$resolveDropEdit(handle: number, id: extHostProtocol.ChainedCacheId, token: CancellationToken): Promise<{ additionalEdit?: extHostProtocol.IWorkspaceEditDto }> {
return this._withAdapter(handle, DocumentDropEditAdapter, adapter => adapter.resolveDropEdit(id, token), {}, undefined);
}
$releaseDropEdits(handle: number, cacheId: number): void {
this._withAdapter(handle, DocumentDropEditAdapter, adapter => Promise.resolve(adapter.releaseDropEdits(cacheId)), undefined, undefined);
}
// --- mapped edits // --- mapped edits
registerMappedEditsProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.MappedEditsProvider): vscode.Disposable { registerMappedEditsProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.MappedEditsProvider): vscode.Disposable {

View file

@ -2794,9 +2794,9 @@ export class DocumentDropEdit {
additionalEdit?: WorkspaceEdit; additionalEdit?: WorkspaceEdit;
kind?: DocumentPasteEditKind; kind?: DocumentDropOrPasteEditKind;
constructor(insertText: string | SnippetString, title?: string, kind?: DocumentPasteEditKind) { constructor(insertText: string | SnippetString, title?: string, kind?: DocumentDropOrPasteEditKind) {
this.insertText = insertText; this.insertText = insertText;
this.title = title; this.title = title;
this.kind = kind; this.kind = kind;
@ -2808,8 +2808,8 @@ export enum DocumentPasteTriggerKind {
PasteAs = 1, PasteAs = 1,
} }
export class DocumentPasteEditKind { export class DocumentDropOrPasteEditKind {
static Empty: DocumentPasteEditKind; static Empty: DocumentDropOrPasteEditKind;
private static sep = '.'; private static sep = '.';
@ -2817,29 +2817,28 @@ export class DocumentPasteEditKind {
public readonly value: string public readonly value: string
) { } ) { }
public append(...parts: string[]): DocumentPasteEditKind { public append(...parts: string[]): DocumentDropOrPasteEditKind {
return new DocumentPasteEditKind((this.value ? [this.value, ...parts] : parts).join(DocumentPasteEditKind.sep)); return new DocumentDropOrPasteEditKind((this.value ? [this.value, ...parts] : parts).join(DocumentDropOrPasteEditKind.sep));
} }
public intersects(other: DocumentPasteEditKind): boolean { public intersects(other: DocumentDropOrPasteEditKind): boolean {
return this.contains(other) || other.contains(this); return this.contains(other) || other.contains(this);
} }
public contains(other: DocumentPasteEditKind): boolean { public contains(other: DocumentDropOrPasteEditKind): boolean {
return this.value === other.value || other.value.startsWith(this.value + DocumentPasteEditKind.sep); return this.value === other.value || other.value.startsWith(this.value + DocumentDropOrPasteEditKind.sep);
} }
} }
DocumentPasteEditKind.Empty = new DocumentPasteEditKind(''); DocumentDropOrPasteEditKind.Empty = new DocumentDropOrPasteEditKind('');
@es5ClassCompat
export class DocumentPasteEdit { export class DocumentPasteEdit {
title: string; title: string;
insertText: string | SnippetString; insertText: string | SnippetString;
additionalEdit?: WorkspaceEdit; additionalEdit?: WorkspaceEdit;
kind: DocumentPasteEditKind; kind: DocumentDropOrPasteEditKind;
constructor(insertText: string | SnippetString, title: string, kind: DocumentPasteEditKind) { constructor(insertText: string | SnippetString, title: string, kind: DocumentDropOrPasteEditKind) {
this.title = title; this.title = title;
this.insertText = insertText; this.insertText = insertText;
this.kind = kind; this.kind = kind;

View file

@ -56,7 +56,6 @@ export const allApiProposals = Object.freeze({
diffContentOptions: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.diffContentOptions.d.ts', diffContentOptions: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.diffContentOptions.d.ts',
documentFiltersExclusive: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.documentFiltersExclusive.d.ts', documentFiltersExclusive: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.documentFiltersExclusive.d.ts',
documentPaste: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.documentPaste.d.ts', documentPaste: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.documentPaste.d.ts',
dropMetadata: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.dropMetadata.d.ts',
editSessionIdentityProvider: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.editSessionIdentityProvider.d.ts', editSessionIdentityProvider: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.editSessionIdentityProvider.d.ts',
editorInsets: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.editorInsets.d.ts', editorInsets: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.editorInsets.d.ts',
extensionRuntime: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.extensionRuntime.d.ts', extensionRuntime: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.extensionRuntime.d.ts',

View file

@ -7,6 +7,41 @@ declare module 'vscode' {
// https://github.com/microsoft/vscode/issues/30066/ // https://github.com/microsoft/vscode/issues/30066/
/**
* Identifies a {@linkcode DocumentDropEdit} or {@linkcode DocumentPasteEdit}
*/
class DocumentDropOrPasteEditKind {
static readonly Empty: DocumentDropOrPasteEditKind;
private constructor(value: string);
/**
* The raw of the kind.
*/
readonly value: string;
/**
* Create a new kind by appending a more specific selector to the current kind.
*
* Does not modify the current kind.
*/
append(...parts: string[]): DocumentDropOrPasteEditKind;
/**
* Checks if this code action kind intersects `other`.
*
* @param other Kind to check.
*/
intersects(other: DocumentDropOrPasteEditKind): boolean;
/**
* Checks if `other` is a sub-kind of this `DocumentDropOrPasteEditKind`.
*
* @param other Kind to check.
*/
contains(other: DocumentDropOrPasteEditKind): boolean;
}
/** /**
* The reason why paste edits were requested. * The reason why paste edits were requested.
*/ */
@ -30,7 +65,7 @@ declare module 'vscode' {
/** /**
* Requested kind of paste edits to return. * Requested kind of paste edits to return.
*/ */
readonly only: DocumentPasteEditKind | undefined; readonly only: DocumentDropOrPasteEditKind | undefined;
/** /**
* The reason why paste edits were requested. * The reason why paste edits were requested.
@ -103,11 +138,11 @@ declare module 'vscode' {
title: string; title: string;
/** /**
* {@link DocumentPasteEditKind Kind} of the edit. * {@link DocumentDropOrPasteEditKind Kind} of the edit.
* *
* Used to identify specific types of edits. * Used to identify specific types of edits.
*/ */
kind: DocumentPasteEditKind; kind: DocumentDropOrPasteEditKind;
/** /**
* The text or snippet to insert at the pasted locations. * The text or snippet to insert at the pasted locations.
@ -124,43 +159,28 @@ declare module 'vscode' {
* *
* If this edit yields to another, it will be shown lower in the list of paste edit. * If this edit yields to another, it will be shown lower in the list of paste edit.
*/ */
yieldTo?: readonly DocumentPasteEditKind[]; yieldTo?: readonly DocumentDropOrPasteEditKind[];
/** /**
* Create a new paste edit. * Create a new paste edit.
* *
* @param insertText The text or snippet to insert at the pasted locations. * @param insertText The text or snippet to insert at the pasted locations.
* @param title Human readable label that describes the edit. * @param title Human readable label that describes the edit.
* @param kind {@link DocumentPasteEditKind Kind} of the edit. * @param kind {@link DocumentDropOrPasteEditKind Kind} of the edit.
*/ */
constructor(insertText: string | SnippetString, title: string, kind: DocumentPasteEditKind); constructor(insertText: string | SnippetString, title: string, kind: DocumentDropOrPasteEditKind);
} }
/** /**
* TODO: Share with code action kind? * Provides additional metadata about how a {@linkcode DocumentPasteEditProvider} works.
*/ */
class DocumentPasteEditKind {
static readonly Empty: DocumentPasteEditKind;
// TODO: Add `Text` any others?
private constructor(value: string);
readonly value: string;
append(...parts: string[]): CodeActionKind;
intersects(other: CodeActionKind): boolean;
contains(other: CodeActionKind): boolean;
}
interface DocumentPasteProviderMetadata { interface DocumentPasteProviderMetadata {
/** /**
* List of {@link DocumentPasteEditKind kinds} that the provider may return in {@linkcode DocumentPasteEditProvider.provideDocumentPasteEdits provideDocumentPasteEdits}. * List of {@link DocumentDropOrPasteEditKind kinds} that the provider may return in {@linkcode DocumentPasteEditProvider.provideDocumentPasteEdits provideDocumentPasteEdits}.
* *
* The provider will only be invoked when one of these kinds is being requested. For normal pasting, all providers will be invoked. * This is used to filter out providers when a specific kind of edit is requested.
*/ */
readonly providedPasteEditKinds: readonly DocumentPasteEditKind[]; readonly providedPasteEditKinds: readonly DocumentDropOrPasteEditKind[];
/** /**
* Mime types that {@linkcode DocumentPasteEditProvider.prepareDocumentPaste prepareDocumentPaste} may add on copy. * Mime types that {@linkcode DocumentPasteEditProvider.prepareDocumentPaste prepareDocumentPaste} may add on copy.
@ -181,6 +201,74 @@ declare module 'vscode' {
readonly pasteMimeTypes?: readonly string[]; readonly pasteMimeTypes?: readonly string[];
} }
/**
* TODO on finalization:
* - Add ctor(insertText: string | SnippetString, title?: string, kind?: DocumentDropOrPasteEditKind); Can't be done as this is an extension to an existing class
*/
export interface DocumentDropEdit {
/**
* Human readable label that describes the edit.
*/
title?: string;
/**
* {@link DocumentDropOrPasteEditKind Kind} of the edit.
*
* Used to identify specific types of edits.
*/
kind: DocumentDropOrPasteEditKind;
/**
* Controls the ordering or multiple edits. If this provider yield to edits, it will be shown lower in the list.
*/
yieldTo?: readonly DocumentDropOrPasteEditKind[];
}
export interface DocumentDropEditProvider<T extends DocumentDropEdit = DocumentDropEdit> {
// Overload that allows returning multiple edits
provideDocumentDropEdits(document: TextDocument, position: Position, dataTransfer: DataTransfer, token: CancellationToken): ProviderResult<DocumentDropEdit | DocumentDropEdit[]>;
/**
* Optional method which fills in the {@linkcode DocumentDropEdit.additionalEdit} before the edit is applied.
*
* This is called once per edit and should be used if generating the complete edit may take a long time.
* Resolve can only be used to change {@link DocumentDropEdit.additionalEdit}.
*
* @param pasteEdit The {@linkcode DocumentDropEdit} to resolve.
* @param token A cancellation token.
*
* @returns The resolved edit or a thenable that resolves to such. It is OK to return the given
* `edit`. If no result is returned, the given `edit` is used.
*/
resolveDocumentDropEdit?(edit: T, token: CancellationToken): ProviderResult<T>;
}
/**
* Provides additional metadata about how a {@linkcode DocumentDropEditProvider} works.
*/
export interface DocumentDropEditProviderMetadata {
/**
* List of {@link DocumentDropOrPasteEditKind kinds} that the provider may return in {@linkcode DocumentDropEditProvider.provideDocumentDropEdits provideDocumentDropEdits}.
*
* This is used to filter out providers when a specific kind of edit is requested.
*/
readonly providedDropEditKinds?: readonly DocumentDropOrPasteEditKind[];
/**
* List of {@link DataTransfer} mime types that the provider can handle.
*
* This can either be an exact mime type such as `image/png`, or a wildcard pattern such as `image/*`.
*
* Use `text/uri-list` for resources dropped from the explorer or other tree views in the workbench.
*
* Use `files` to indicate that the provider should be invoked if any {@link DataTransferFile files} are present in the {@link DataTransfer}.
* Note that {@link DataTransferFile} entries are only created when dropping content from outside the editor, such as
* from the operating system.
*/
readonly dropMimeTypes: readonly string[];
}
namespace languages { namespace languages {
/** /**
* Registers a new {@linkcode DocumentPasteEditProvider}. * Registers a new {@linkcode DocumentPasteEditProvider}.
@ -192,5 +280,10 @@ declare module 'vscode' {
* @returns A {@link Disposable} that unregisters this provider when disposed of. * @returns A {@link Disposable} that unregisters this provider when disposed of.
*/ */
export function registerDocumentPasteEditProvider(selector: DocumentSelector, provider: DocumentPasteEditProvider, metadata: DocumentPasteProviderMetadata): Disposable; export function registerDocumentPasteEditProvider(selector: DocumentSelector, provider: DocumentPasteEditProvider, metadata: DocumentPasteProviderMetadata): Disposable;
/**
* Overload which adds extra metadata
*/
export function registerDocumentDropEditProvider(selector: DocumentSelector, provider: DocumentDropEditProvider, metadata?: DocumentDropEditProviderMetadata): Disposable;
} }
} }

View file

@ -1,65 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
declare module 'vscode' {
// https://github.com/microsoft/vscode/issues/179430
/**
* TODO:
* - Add ctor(insertText: string | SnippetString, title?: string, kind?: DocumentPasteEditKind); Can't be done as this is an extension to an existing class
* - Update provider to return multiple edits
*/
export interface DocumentDropEdit {
/**
* Human readable label that describes the edit.
*/
title?: string;
/**
* {@link DocumentPasteEditKind Kind} of the edit.
*
* Used to identify specific types of edits.
*
* TODO: use own type?
*/
kind: DocumentPasteEditKind;
/**
* The mime type from the {@link DataTransfer} that this edit applies.
*
* TODO: Should this be taken from `dropMimeTypes` instead?
*/
handledMimeType?: string;
/**
* Controls the ordering or multiple paste edits. If this provider yield to edits, it will be shown lower in the list.
*/
yieldTo?: ReadonlyArray<DocumentPasteEditKind>;
}
export interface DocumentDropEditProviderMetadata {
readonly providedDropEditKinds?: readonly DocumentPasteEditKind[];
/**
* List of {@link DataTransfer} mime types that the provider can handle.
*
* This can either be an exact mime type such as `image/png`, or a wildcard pattern such as `image/*`.
*
* Use `text/uri-list` for resources dropped from the explorer or other tree views in the workbench.
*
* Use `files` to indicate that the provider should be invoked if any {@link DataTransferFile files} are present in the {@link DataTransfer}.
* Note that {@link DataTransferFile} entries are only created when dropping content from outside the editor, such as
* from the operating system.
*/
readonly dropMimeTypes: readonly string[];
}
export namespace languages {
export function registerDocumentDropEditProvider(selector: DocumentSelector, provider: DocumentDropEditProvider, metadata?: DocumentDropEditProviderMetadata): Disposable;
}
}