Skip to content

Commit

Permalink
Move drop/paste ids onto providers
Browse files Browse the repository at this point in the history
For microsoft#179430, microsoft#30066

This lets us call just the provider we are interested in
  • Loading branch information
mjbvz committed Aug 8, 2023
1 parent 2d89af3 commit 2570eb4
Show file tree
Hide file tree
Showing 16 changed files with 113 additions and 105 deletions.
7 changes: 4 additions & 3 deletions extensions/ipynb/src/notebookImagePaste.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ function getImageMimeType(uri: vscode.Uri): string | undefined {

class DropOrPasteEditProvider implements vscode.DocumentPasteEditProvider, vscode.DocumentDropEditProvider {

private readonly id = 'insertAttachment';
public readonly id = 'insertAttachment';

async provideDocumentPasteEdits(
document: vscode.TextDocument,
Expand All @@ -66,7 +66,7 @@ class DropOrPasteEditProvider implements vscode.DocumentPasteEditProvider, vscod
return;
}

const pasteEdit = new vscode.DocumentPasteEdit(insert.insertText, this.id, vscode.l10n.t('Insert Image as Attachment'));
const pasteEdit = new vscode.DocumentPasteEdit(insert.insertText, vscode.l10n.t('Insert Image as Attachment'));
pasteEdit.yieldTo = [{ mimeType: MimeType.plain }];
pasteEdit.additionalEdit = insert.additionalEdit;
return pasteEdit;
Expand All @@ -84,7 +84,6 @@ class DropOrPasteEditProvider implements vscode.DocumentPasteEditProvider, vscod
}

const dropEdit = new vscode.DocumentDropEdit(insert.insertText);
dropEdit.id = this.id;
dropEdit.yieldTo = [{ mimeType: MimeType.plain }];
dropEdit.additionalEdit = insert.additionalEdit;
dropEdit.label = vscode.l10n.t('Insert Image as Attachment');
Expand Down Expand Up @@ -300,12 +299,14 @@ export function notebookImagePasteSetup(): vscode.Disposable {
const provider = new DropOrPasteEditProvider();
return vscode.Disposable.from(
vscode.languages.registerDocumentPasteEditProvider(JUPYTER_NOTEBOOK_MARKDOWN_SELECTOR, provider, {
id: provider.id,
pasteMimeTypes: [
MimeType.png,
MimeType.uriList,
],
}),
vscode.languages.registerDocumentDropEditProvider(JUPYTER_NOTEBOOK_MARKDOWN_SELECTOR, provider, {
id: provider.id,
dropMimeTypes: [
...Object.values(imageExtToMime),
MimeType.uriList,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import { createEditForMediaFiles, createEditAddingLinksForUriList, mediaMimes, g

class PasteEditProvider implements vscode.DocumentPasteEditProvider {

private readonly _id = 'insertLink';
public static readonly id = 'insertLink';

private readonly _yieldTo = [
{ mimeType: 'text/plain' },
{ extensionId: 'vscode.ipynb', editId: 'insertAttachment' },
{ extensionId: 'vscode.ipynb', providerId: 'insertAttachment' },
];

async provideDocumentPasteEdits(
Expand All @@ -32,7 +32,7 @@ class PasteEditProvider implements vscode.DocumentPasteEditProvider {
return createEdit;
}

const uriEdit = new vscode.DocumentPasteEdit('', this._id, '');
const uriEdit = new vscode.DocumentPasteEdit('', '');
const urlList = await dataTransfer.get('text/uri-list')?.asString();
if (!urlList) {
return;
Expand Down Expand Up @@ -65,7 +65,7 @@ class PasteEditProvider implements vscode.DocumentPasteEditProvider {
return;
}

const pasteEdit = new vscode.DocumentPasteEdit(edit.snippet, this._id, edit.label);
const pasteEdit = new vscode.DocumentPasteEdit(edit.snippet, edit.label);
pasteEdit.additionalEdit = edit.additionalEdits;
pasteEdit.yieldTo = this._yieldTo;
return pasteEdit;
Expand All @@ -74,6 +74,7 @@ class PasteEditProvider implements vscode.DocumentPasteEditProvider {

export function registerPasteSupport(selector: vscode.DocumentSelector,) {
return vscode.languages.registerDocumentPasteEditProvider(selector, new PasteEditProvider(), {
id: PasteEditProvider.id,
pasteMimeTypes: [
'text/uri-list',
...mediaMimes,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const textPlainMime = 'text/plain';

class PasteLinkEditProvider implements vscode.DocumentPasteEditProvider {

readonly id = 'insertMarkdownLink';
public static readonly id = 'insertMarkdownLink';

async provideDocumentPasteEdits(
document: vscode.TextDocument,
Expand All @@ -34,7 +34,7 @@ class PasteLinkEditProvider implements vscode.DocumentPasteEditProvider {
return;
}

const edit = new vscode.DocumentPasteEdit('', this.id, pasteEdit.label);
const edit = new vscode.DocumentPasteEdit('', pasteEdit.label);
edit.additionalEdit = pasteEdit.additionalEdits;
edit.yieldTo = pasteEdit.markdownLink ? undefined : [{ mimeType: textPlainMime }];
return edit;
Expand All @@ -43,6 +43,7 @@ class PasteLinkEditProvider implements vscode.DocumentPasteEditProvider {

export function registerLinkPasteSupport(selector: vscode.DocumentSelector,) {
return vscode.languages.registerDocumentPasteEditProvider(selector, new PasteLinkEditProvider(), {
id: PasteLinkEditProvider.id,
pasteMimeTypes: [textPlainMime]
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import { Schemes } from '../../util/schemes';

class MarkdownImageDropProvider implements vscode.DocumentDropEditProvider {

private readonly _id = 'insertLink';
public static readonly id = 'insertLink';

private readonly _yieldTo = [
{ mimeType: 'text/plain' },
{ extensionId: 'vscode.ipynb', editId: 'insertAttachment' },
{ extensionId: 'vscode.ipynb', providerId: 'insertAttachment' },
];

async provideDocumentDropEdits(document: vscode.TextDocument, _position: vscode.Position, dataTransfer: vscode.DataTransfer, token: vscode.CancellationToken): Promise<vscode.DocumentDropEdit | undefined> {
Expand Down Expand Up @@ -46,7 +46,6 @@ class MarkdownImageDropProvider implements vscode.DocumentDropEditProvider {
}

const edit = new vscode.DocumentDropEdit(snippet.snippet);
edit.id = this._id;
edit.label = snippet.label;
edit.yieldTo = this._yieldTo;
return edit;
Expand All @@ -68,7 +67,6 @@ class MarkdownImageDropProvider implements vscode.DocumentDropEditProvider {
}

const edit = new vscode.DocumentDropEdit(filesEdit.snippet);
edit.id = this._id;
edit.label = filesEdit.label;
edit.additionalEdit = filesEdit.additionalEdits;
edit.yieldTo = this._yieldTo;
Expand All @@ -78,6 +76,7 @@ class MarkdownImageDropProvider implements vscode.DocumentDropEditProvider {

export function registerDropIntoEditorSupport(selector: vscode.DocumentSelector) {
return vscode.languages.registerDocumentDropEditProvider(selector, new MarkdownImageDropProvider(), {
id: MarkdownImageDropProvider.id,
dropMimeTypes: [
'text/uri-list',
...mediaMimes,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ suite.skip('vscode API - Copy Paste', function () {
dataTransfer.set(textPlain, new vscode.DataTransferItem(reversed));
}
}
}, { copyMimeTypes: [textPlain] }));
}, { id: 'test', copyMimeTypes: [textPlain] }));

await vscode.commands.executeCommand('editor.action.clipboardCopyAction');
const newDocContent = getNextDocumentText(testDisposables, doc);
Expand All @@ -62,7 +62,7 @@ suite.skip('vscode API - Copy Paste', function () {
dataTransfer.set(textPlain, new vscode.DataTransferItem(reversed + '\n'));
}
}
}, { copyMimeTypes: [textPlain] }));
}, { id: 'test', copyMimeTypes: [textPlain] }));

await vscode.commands.executeCommand('editor.action.clipboardCopyAction');
const newDocContent = getNextDocumentText(testDisposables, doc);
Expand All @@ -88,7 +88,7 @@ suite.skip('vscode API - Copy Paste', function () {
dataTransfer.set(textPlain, new vscode.DataTransferItem(`(${ranges.length})${selections.join(' ')}`));
}
}
}, { copyMimeTypes: [textPlain] }));
}, { id: 'test', copyMimeTypes: [textPlain] }));

await vscode.commands.executeCommand('editor.action.clipboardCopyAction');
editor.selections = [new vscode.Selection(0, 0, 0, 0)];
Expand Down Expand Up @@ -118,7 +118,7 @@ suite.skip('vscode API - Copy Paste', function () {
dataTransfer.set(textPlain, new vscode.DataTransferItem('a'));
providerAResolve();
}
}, { copyMimeTypes: [textPlain] }));
}, { id: 'test', copyMimeTypes: [textPlain] }));

// Later registered providers will be called first
testDisposables.push(vscode.languages.registerDocumentPasteEditProvider({ language: 'plaintext' }, new class implements vscode.DocumentPasteEditProvider {
Expand All @@ -132,7 +132,7 @@ suite.skip('vscode API - Copy Paste', function () {

dataTransfer.set(textPlain, new vscode.DataTransferItem('b'));
}
}, { copyMimeTypes: [textPlain] }));
}, { id: 'test', copyMimeTypes: [textPlain] }));

await vscode.commands.executeCommand('editor.action.clipboardCopyAction');
const newDocContent = getNextDocumentText(testDisposables, doc);
Expand All @@ -159,7 +159,7 @@ suite.skip('vscode API - Copy Paste', function () {
dataTransfer.set(textPlain, new vscode.DataTransferItem('xyz'));
providerAResolve();
}
}, { copyMimeTypes: [textPlain] }));
}, { id: 'test', copyMimeTypes: [textPlain] }));

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> {
Expand All @@ -172,7 +172,7 @@ suite.skip('vscode API - Copy Paste', function () {
const str = await entry!.asString();
dataTransfer.set(textPlain, new vscode.DataTransferItem(reverseString(str)));
}
}, { copyMimeTypes: [textPlain] }));
}, { id: 'test', copyMimeTypes: [textPlain] }));

await vscode.commands.executeCommand('editor.action.clipboardCopyAction');
const newDocContent = getNextDocumentText(testDisposables, doc);
Expand All @@ -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> {
dataTransfer.set(textPlain, new vscode.DataTransferItem('xyz'));
}
}, { copyMimeTypes: [textPlain] }));
}, { id: 'test', copyMimeTypes: [textPlain] }));

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> {
throw new Error('Expected testing error from bad provider');
}
}, { copyMimeTypes: [textPlain] }));
}, { id: 'test', copyMimeTypes: [textPlain] }));

await vscode.commands.executeCommand('editor.action.clipboardCopyAction');
const newDocContent = getNextDocumentText(testDisposables, doc);
Expand Down
7 changes: 3 additions & 4 deletions src/vs/editor/common/languages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,6 @@ export interface CodeActionProvider {
* @internal
*/
export interface DocumentPasteEdit {
readonly id: string;
readonly label: string;
readonly detail: string;
readonly handledMimeType?: string;
Expand All @@ -816,7 +815,7 @@ export interface DocumentPasteEdit {
*/
export interface DocumentPasteEditProvider {

readonly id?: string;
readonly id: string;

readonly copyMimeTypes?: readonly string[];
readonly pasteMimeTypes?: readonly string[];
Expand Down Expand Up @@ -2012,13 +2011,12 @@ export enum ExternalUriOpenerPriority {
/**
* @internal
*/
export type DropYieldTo = { readonly editId: string } | { readonly mimeType: string };
export type DropYieldTo = { readonly providerId: string } | { readonly mimeType: string };

/**
* @internal
*/
export interface DocumentOnDropEdit {
readonly id: string;
readonly label: string;
readonly handledMimeType?: string;
readonly yieldTo?: readonly DropYieldTo[];
Expand All @@ -2030,6 +2028,7 @@ export interface DocumentOnDropEdit {
* @internal
*/
export interface DocumentOnDropEditProvider {
readonly id?: string;
readonly dropMimeTypes?: readonly string[];

provideDocumentOnDropEdits(model: model.ITextModel, position: IPosition, dataTransfer: IReadonlyVSDataTransfer, token: CancellationToken): ProviderResult<DocumentOnDropEdit>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,12 +284,6 @@ export class CopyPasteController extends Disposable implements IEditorContributi
return;
}

// If the only edit returned is a text edit, use the default paste handler
if (providerEdits.length === 1 && providerEdits[0].id === 'text') {
await this.applyDefaultPasteHandler(dataTransfer, metadata, tokenSource.token);
return;
}

if (providerEdits.length) {
const canShowWidget = editor.getOption(EditorOption.pasteAs).showPasteSelector === 'afterPaste';
return this._postPasteWidgetManager.applyEditAndShowIfNeeded(selections, { activeEditIndex: 0, allEdits: providerEdits }, canShowWidget, tokenSource.token);
Expand Down Expand Up @@ -324,7 +318,11 @@ export class CopyPasteController extends Disposable implements IEditorContributi
}

// Filter out any providers the don't match the full data transfer we will send them.
const supportedProviders = allProviders.filter(provider => isSupportedPasteProvider(provider, dataTransfer));
let supportedProviders = allProviders.filter(provider => isSupportedPasteProvider(provider, dataTransfer));
if (preferredId) {
// We are looking for a specific edit
supportedProviders = supportedProviders.filter(edit => edit.id === preferredId);
}

const providerEdits = await this.getPasteEdits(supportedProviders, dataTransfer, model, selections, tokenSource.token);
if (tokenSource.token.isCancellationRequested) {
Expand All @@ -336,14 +334,13 @@ export class CopyPasteController extends Disposable implements IEditorContributi
}

let pickedEdit: DocumentPasteEdit | undefined;
if (typeof preferredId === 'string') {
// We are looking for a specific edit
pickedEdit = providerEdits.find(edit => edit.id === preferredId);
if (preferredId) {
pickedEdit = providerEdits.at(0);
} else {
const selected = await this._quickInputService.pick(
providerEdits.map((edit): IQuickPickItem & { edit: DocumentPasteEdit } => ({
label: edit.label,
description: edit.id,
description: edit.providerId,
detail: edit.detail,
edit,
})), {
Expand Down Expand Up @@ -431,15 +428,18 @@ export class CopyPasteController extends Disposable implements IEditorContributi
}
}

private async getPasteEdits(providers: readonly DocumentPasteEditProvider[], dataTransfer: VSDataTransfer, model: ITextModel, selections: readonly Selection[], token: CancellationToken): Promise<DocumentPasteEdit[]> {
private async getPasteEdits(providers: readonly DocumentPasteEditProvider[], dataTransfer: VSDataTransfer, model: ITextModel, selections: readonly Selection[], token: CancellationToken): Promise<Array<DocumentPasteEdit & { providerId: string }>> {
const results = await raceCancellation(
Promise.all(providers.map(provider => {
Promise.all(providers.map(async provider => {
try {
return provider.provideDocumentPasteEdits?.(model, selections, dataTransfer, token);
const edit = await provider.provideDocumentPasteEdits?.(model, selections, dataTransfer, token);
if (edit) {
return { ...edit, providerId: provider.id };
}
} catch (err) {
console.error(err);
return undefined;
}
return undefined;
})),
token);
const edits = coalesce(results ?? []);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ abstract class SimplePasteAndDropProvider implements DocumentOnDropEditProvider,

async provideDocumentPasteEdits(_model: ITextModel, _ranges: readonly IRange[], dataTransfer: IReadonlyVSDataTransfer, token: CancellationToken): Promise<DocumentPasteEdit | undefined> {
const edit = await this.getEdit(dataTransfer, token);
return edit ? { id: this.id, insertText: edit.insertText, label: edit.label, detail: edit.detail, handledMimeType: edit.handledMimeType, yieldTo: edit.yieldTo } : undefined;
return edit ? { insertText: edit.insertText, label: edit.label, detail: edit.detail, handledMimeType: edit.handledMimeType, yieldTo: edit.yieldTo } : undefined;
}

async provideDocumentOnDropEdits(_model: ITextModel, _position: IPosition, dataTransfer: IReadonlyVSDataTransfer, token: CancellationToken): Promise<DocumentOnDropEdit | undefined> {
const edit = await this.getEdit(dataTransfer, token);
return edit ? { id: this.id, insertText: edit.insertText, label: edit.label, handledMimeType: edit.handledMimeType, yieldTo: edit.yieldTo } : undefined;
return edit ? { insertText: edit.insertText, label: edit.label, handledMimeType: edit.handledMimeType, yieldTo: edit.yieldTo } : undefined;
}

protected abstract getEdit(dataTransfer: IReadonlyVSDataTransfer, token: CancellationToken): Promise<DocumentPasteEdit | undefined>;
Expand All @@ -60,7 +60,6 @@ class DefaultTextProvider extends SimplePasteAndDropProvider {

const insertText = await textEntry.asString();
return {
id: this.id,
handledMimeType: Mimes.text,
label: localize('text.label', "Insert Plain Text"),
detail: builtInLabel,
Expand Down Expand Up @@ -107,7 +106,6 @@ class PathProvider extends SimplePasteAndDropProvider {
}

return {
id: this.id,
handledMimeType: Mimes.uriList,
insertText,
label,
Expand Down Expand Up @@ -144,7 +142,6 @@ class RelativePathProvider extends SimplePasteAndDropProvider {
}

return {
id: this.id,
handledMimeType: Mimes.uriList,
insertText: relativeUris.join(' '),
label: entries.length > 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,16 @@ export class DropIntoEditorController extends Disposable implements IEditorContr
}

private async getDropEdits(providers: DocumentOnDropEditProvider[], model: ITextModel, position: IPosition, dataTransfer: VSDataTransfer, tokenSource: EditorStateCancellationTokenSource) {
const results = await raceCancellation(Promise.all(providers.map(provider => {
return provider.provideDocumentOnDropEdits(model, position, dataTransfer, tokenSource.token);
const results = await raceCancellation(Promise.all(providers.map(async provider => {
try {
const edit = await provider.provideDocumentOnDropEdits(model, position, dataTransfer, tokenSource.token);
if (edit) {
return { ...edit, providerId: provider.id };
}
} catch (err) {
console.error(err);
}
return undefined;
})), tokenSource.token);
const edits = coalesce(results ?? []);
sortEditsByYieldTo(edits);
Expand Down
Loading

0 comments on commit 2570eb4

Please sign in to comment.