Skip to content

Commit 3ada59c

Browse files
committed
Adjust the document paste handling provider.
- provideDocumentPasteEdits API was updated in VS Code 1.88.0 Signed-off-by: Roland Grunberg <rgrunber@redhat.com>
1 parent e578b50 commit 3ada59c

2 files changed

Lines changed: 147 additions & 23 deletions

File tree

src/pasteEventHandler.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
import { CancellationToken, commands, DataTransfer, DocumentPasteEdit as VDocumentPasteEdit, DocumentPasteEditProvider, DocumentPasteProviderMetadata, ExtensionContext, languages, Range, TextDocument, window } from "vscode";
1+
import { CancellationToken, commands, DataTransfer, DocumentPasteEdit as VDocumentPasteEdit, DocumentPasteEditProvider, DocumentPasteProviderMetadata, ExtensionContext, languages, Range, TextDocument, window, DocumentPasteEditContext, ProviderResult, DocumentPasteEdit } from "vscode";
22
import { FormattingOptions, Location, WorkspaceEdit as PWorkspaceEdit } from "vscode-languageclient";
33
import { LanguageClient } from "vscode-languageclient/node";
44
import { Commands } from "./commands";
55
import { JAVA_SELECTOR } from "./standardLanguageClient";
66

77
const TEXT_MIMETYPE: string = "text/plain";
88
const MIMETYPES: DocumentPasteProviderMetadata = {
9-
pasteMimeTypes: [TEXT_MIMETYPE]
9+
pasteMimeTypes: [TEXT_MIMETYPE],
10+
providedPasteEditKinds: []
1011
};
1112

1213
/**
@@ -61,7 +62,7 @@ class PasteEditProvider implements DocumentPasteEditProvider {
6162
}
6263
}
6364

64-
async provideDocumentPasteEdits(document: TextDocument, ranges: readonly Range[], dataTransfer: DataTransfer, token: CancellationToken): Promise<VDocumentPasteEdit> {
65+
async provideDocumentPasteEdits?(document: TextDocument, ranges: readonly Range[], dataTransfer: DataTransfer, context: DocumentPasteEditContext, token: CancellationToken): Promise<DocumentPasteEdit[]> {
6566

6667
const insertText: string = await dataTransfer.get(TEXT_MIMETYPE).asString();
6768

@@ -92,10 +93,12 @@ class PasteEditProvider implements DocumentPasteEditProvider {
9293
try {
9394
const pasteResponse: PDocumentPasteEdit = await commands.executeCommand(Commands.EXECUTE_WORKSPACE_COMMAND, Commands.HANDLE_PASTE_EVENT, JSON.stringify(pasteEventParams));
9495
if (pasteResponse) {
95-
return {
96-
insertText: pasteResponse.insertText,
97-
additionalEdit: pasteResponse.additionalEdit ? await this.languageClient.protocol2CodeConverter.asWorkspaceEdit(pasteResponse.additionalEdit) : undefined
98-
} as VDocumentPasteEdit;
96+
return [
97+
{
98+
insertText: pasteResponse.insertText,
99+
additionalEdit: pasteResponse.additionalEdit ? await this.languageClient.protocol2CodeConverter.asWorkspaceEdit(pasteResponse.additionalEdit) : undefined
100+
}
101+
] as DocumentPasteEdit[];
99102
}
100103
} catch (e) {
101104
// Do nothing

vscode.proposed.documentPaste.d.ts

Lines changed: 137 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,42 +8,107 @@ declare module 'vscode' {
88
// https://github.com/microsoft/vscode/issues/30066/
99

1010
/**
11-
* Provider invoked when the user copies and pastes code.
11+
* The reason why paste edits were requested.
1212
*/
13-
interface DocumentPasteEditProvider {
13+
export enum DocumentPasteTriggerKind {
14+
/**
15+
* Pasting was requested as part of a normal paste operation.
16+
*/
17+
Automatic = 0,
18+
19+
/**
20+
* Pasting was requested by the user with the `paste as` command.
21+
*/
22+
PasteAs = 1,
23+
}
24+
25+
/**
26+
* Additional information about the paste operation.
27+
*/
28+
29+
export interface DocumentPasteEditContext {
30+
/**
31+
* Requested kind of paste edits to return.
32+
*/
33+
readonly only: DocumentPasteEditKind | undefined;
34+
35+
/**
36+
* The reason why paste edits were requested.
37+
*/
38+
readonly triggerKind: DocumentPasteTriggerKind;
39+
}
40+
41+
/**
42+
* Provider invoked when the user copies or pastes in a {@linkcode TextDocument}.
43+
*/
44+
interface DocumentPasteEditProvider<T extends DocumentPasteEdit = DocumentPasteEdit> {
1445

1546
/**
1647
* Optional method invoked after the user copies text in a file.
1748
*
18-
* During {@link prepareDocumentPaste}, an extension can compute metadata that is attached to
19-
* a {@link DataTransfer} and is passed back to the provider in {@link provideDocumentPasteEdits}.
49+
* This allows the provider to attach copy metadata to the {@link DataTransfer}
50+
* which is then passed back to providers in {@linkcode provideDocumentPasteEdits}.
51+
*
52+
* Note that currently any changes to the {@linkcode DataTransfer} are isolated to the current editor session.
53+
* This means that added metadata cannot be seen by other applications.
2054
*
2155
* @param document Document where the copy took place.
22-
* @param ranges Ranges being copied in the `document`.
23-
* @param dataTransfer The data transfer associated with the copy. You can store additional values on this for later use in {@link provideDocumentPasteEdits}.
56+
* @param ranges Ranges being copied in {@linkcode document}.
57+
* @param dataTransfer The data transfer associated with the copy. You can store additional values on this for later use in {@linkcode provideDocumentPasteEdits}.
58+
* This object is only valid for the duration of this method.
2459
* @param token A cancellation token.
60+
*
61+
* @return Optional thenable that resolves when all changes to the `dataTransfer` are complete.
2562
*/
2663
prepareDocumentPaste?(document: TextDocument, ranges: readonly Range[], dataTransfer: DataTransfer, token: CancellationToken): void | Thenable<void>;
2764

2865
/**
2966
* Invoked before the user pastes into a document.
3067
*
31-
* In this method, extensions can return a workspace edit that replaces the standard pasting behavior.
68+
* Returned edits can replace the standard pasting behavior.
3269
*
3370
* @param document Document being pasted into
34-
* @param ranges Currently selected ranges in the document.
35-
* @param dataTransfer The data transfer associated with the paste.
71+
* @param ranges Range in the {@linkcode document} to paste into.
72+
* @param dataTransfer The {@link DataTransfer data transfer} associated with the paste. This object is only valid for the duration of the paste operation.
73+
* @param context Additional context for the paste.
74+
* @param token A cancellation token.
75+
*
76+
* @return Set of potential {@link DocumentPasteEdit edits} that apply the paste. Return `undefined` to use standard pasting.
77+
*/
78+
provideDocumentPasteEdits?(document: TextDocument, ranges: readonly Range[], dataTransfer: DataTransfer, context: DocumentPasteEditContext, token: CancellationToken): ProviderResult<T[]>;
79+
80+
/**
81+
* Optional method which fills in the {@linkcode DocumentPasteEdit.additionalEdit} before the edit is applied.
82+
*
83+
* This is called once per edit and should be used if generating the complete edit may take a long time.
84+
* Resolve can only be used to change {@link DocumentPasteEdit.additionalEdit}.
85+
*
86+
* @param pasteEdit The {@linkcode DocumentPasteEdit} to resolve.
3687
* @param token A cancellation token.
3788
*
38-
* @return Optional workspace edit that applies the paste. Return undefined to use standard pasting.
89+
* @returns The resolved paste edit or a thenable that resolves to such. It is OK to return the given
90+
* `pasteEdit`. If no result is returned, the given `pasteEdit` is used.
3991
*/
40-
provideDocumentPasteEdits(document: TextDocument, ranges: readonly Range[], dataTransfer: DataTransfer, token: CancellationToken): ProviderResult<DocumentPasteEdit>;
92+
resolveDocumentPasteEdit?(pasteEdit: T, token: CancellationToken): ProviderResult<T>;
4193
}
4294

4395
/**
44-
* An operation applied on paste
96+
* An edit applied on paste.
4597
*/
4698
class DocumentPasteEdit {
99+
100+
/**
101+
* Human readable label that describes the edit.
102+
*/
103+
title: string;
104+
105+
/**
106+
* {@link DocumentPasteEditKind Kind} of the edit.
107+
*
108+
* Used to identify specific types of edits.
109+
*/
110+
kind: DocumentPasteEditKind;
111+
47112
/**
48113
* The text or snippet to insert at the pasted locations.
49114
*/
@@ -55,21 +120,77 @@ declare module 'vscode' {
55120
additionalEdit?: WorkspaceEdit;
56121

57122
/**
123+
* Controls the ordering of paste edits provided by multiple providers.
124+
*
125+
* If this edit yields to another, it will be shown lower in the list of paste edit.
126+
*/
127+
yieldTo?: readonly DocumentPasteEditKind[];
128+
129+
/**
130+
* Create a new paste edit.
131+
*
58132
* @param insertText The text or snippet to insert at the pasted locations.
133+
* @param title Human readable label that describes the edit.
134+
* @param kind {@link DocumentPasteEditKind Kind} of the edit.
59135
*/
60-
constructor(insertText: string | SnippetString);
136+
constructor(insertText: string | SnippetString, title: string, kind: DocumentPasteEditKind);
137+
}
138+
139+
140+
/**
141+
* TODO: Share with code action kind?
142+
*/
143+
class DocumentPasteEditKind {
144+
static readonly Empty: DocumentPasteEditKind;
145+
146+
// TODO: Add `Text` any others?
147+
148+
private constructor(value: string);
149+
150+
readonly value: string;
151+
152+
append(...parts: string[]): CodeActionKind;
153+
intersects(other: CodeActionKind): boolean;
154+
contains(other: CodeActionKind): boolean;
61155
}
62156

63157
interface DocumentPasteProviderMetadata {
64158
/**
65-
* Mime types that `provideDocumentPasteEdits` should be invoked for.
159+
* List of {@link DocumentPasteEditKind kinds} that the provider may return in {@linkcode DocumentPasteEditProvider.provideDocumentPasteEdits provideDocumentPasteEdits}.
66160
*
67-
* Use the special `files` mimetype to indicate the provider should be invoked if any files are present in the `DataTransfer`.
161+
* The provider will only be invoked when one of these kinds is being requested. For normal pasting, all providers will be invoked.
162+
*/
163+
readonly providedPasteEditKinds: readonly DocumentPasteEditKind[];
164+
165+
/**
166+
* Mime types that {@linkcode DocumentPasteEditProvider.prepareDocumentPaste prepareDocumentPaste} may add on copy.
68167
*/
69-
readonly pasteMimeTypes: readonly string[];
168+
readonly copyMimeTypes?: readonly string[];
169+
170+
/**
171+
* Mime types that {@linkcode DocumentPasteEditProvider.provideDocumentPasteEdits provideDocumentPasteEdits} should be invoked for.
172+
*
173+
* This can either be an exact mime type such as `image/png`, or a wildcard pattern such as `image/*`.
174+
*
175+
* Use `text/uri-list` for resources dropped from the explorer or other tree views in the workbench.
176+
*
177+
* Use `files` to indicate that the provider should be invoked if any {@link DataTransferFile files} are present in the {@linkcode DataTransfer}.
178+
* Note that {@linkcode DataTransferFile} entries are only created when dropping content from outside the editor, such as
179+
* from the operating system.
180+
*/
181+
readonly pasteMimeTypes?: readonly string[];
70182
}
71183

72184
namespace languages {
185+
/**
186+
* Registers a new {@linkcode DocumentPasteEditProvider}.
187+
*
188+
* @param selector A selector that defines the documents this provider applies to.
189+
* @param provider A paste editor provider.
190+
* @param metadata Additional metadata about the provider.
191+
*
192+
* @returns A {@link Disposable} that unregisters this provider when disposed of.
193+
*/
73194
export function registerDocumentPasteEditProvider(selector: DocumentSelector, provider: DocumentPasteEditProvider, metadata: DocumentPasteProviderMetadata): Disposable;
74195
}
75196
}

0 commit comments

Comments
 (0)