Skip to content

Commit

Permalink
Update DropMetada and documentPaste proposed API for 1.88 compatibili…
Browse files Browse the repository at this point in the history
…ty (#13632)

contributed on behalf of STMicroelectronics

Signed-off-by: Remi Schnekenburger <rschnekenburger@eclipsesource.com>
  • Loading branch information
rschnekenbu authored Apr 26, 2024
1 parent de86a44 commit 59d0913
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 59 deletions.
4 changes: 2 additions & 2 deletions packages/plugin-ext/src/common/plugin-api-rpc-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import * as theia from '@theia/plugin';
import type * as monaco from '@theia/monaco-editor-core';
import { MarkdownString as MarkdownStringDTO } from '@theia/core/lib/common/markdown-rendering';
import { UriComponents } from './uri-components';
import { CompletionItemTag, SnippetString } from '../plugin/types-impl';
import { CompletionItemTag, DocumentPasteEditKind, SnippetString } from '../plugin/types-impl';
import { Event as TheiaEvent } from '@theia/core/lib/common/event';
import { URI } from '@theia/core/shared/vscode-uri';
import { SerializedRegExp } from './plugin-api-rpc';
Expand Down Expand Up @@ -330,7 +330,7 @@ export interface DocumentDropEdit {
}

export interface DocumentDropEditProviderMetadata {
readonly id: string;
readonly providedDropEditKinds?: readonly DocumentPasteEditKind[];
readonly dropMimeTypes: readonly string[];
}

Expand Down
4 changes: 4 additions & 0 deletions packages/plugin-ext/src/plugin/plugin-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,8 @@ import {
TextMergeTabInput,
WebviewEditorTabInput,
DocumentPasteEdit,
DocumentPasteEditKind,
DocumentPasteTriggerKind,
ExternalUriOpenerPriority,
EditSessionIdentityMatch,
TerminalOutputAnchor,
Expand Down Expand Up @@ -1403,6 +1405,8 @@ export function createAPIFactory(
TerminalOutputAnchor,
TerminalExitReason,
DocumentPasteEdit,
DocumentPasteEditKind,
DocumentPasteTriggerKind,
ExternalUriOpenerPriority,
TerminalQuickFixTerminalCommand,
TerminalQuickFixOpener,
Expand Down
62 changes: 48 additions & 14 deletions packages/plugin-ext/src/plugin/types-impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1643,15 +1643,11 @@ export class DocumentLink {

@es5ClassCompat
export class DocumentDropEdit {

id?: string;

priority?: number;

label?: string;

title?: string;
kind: DocumentPasteEditKind;
handledMimeType?: string;
yieldTo?: ReadonlyArray<DocumentPasteEditKind>;
insertText: string | SnippetString;

additionalEdit?: WorkspaceEdit;

constructor(insertText: string | SnippetString) {
Expand Down Expand Up @@ -3740,19 +3736,57 @@ export class InteractiveWindowInput {
// #endregion

// #region DocumentPaste
export class DocumentPasteEditKind {
static Empty: DocumentPasteEditKind;

constructor(public readonly value: string) { }

/** @stubbed */
append(...parts: string[]): CodeActionKind {
return CodeActionKind.Empty;
};

/** @stubbed */
intersects(other: CodeActionKind): boolean {
return false;
}

/** @stubbed */
contains(other: CodeActionKind): boolean {
return false;
}
}
DocumentPasteEditKind.Empty = new DocumentPasteEditKind('');

@es5ClassCompat
export class DocumentPasteEdit {
constructor(insertText: string | SnippetString, id: string, label: string) {
constructor(insertText: string | SnippetString, title: string, kind: DocumentPasteEditKind) {
this.insertText = insertText;
this.id = id;
this.label = label;
this.title = title;
this.kind = kind;
}
title: string;
kind: DocumentPasteEditKind;
insertText: string | SnippetString;
additionalEdit?: WorkspaceEdit;
id: string;
label: string;
priority?: number;
yieldTo?: readonly DocumentPasteEditKind[];
}

/**
* The reason why paste edits were requested.
*/
export enum DocumentPasteTriggerKind {
/**
* Pasting was requested as part of a normal paste operation.
*/
Automatic = 0,

/**
* Pasting was requested by the user with the `paste as` command.
*/
PasteAs = 1,
}

// #endregion

// #region DocumentPaste
Expand Down
147 changes: 117 additions & 30 deletions packages/plugin/src/theia.proposed.documentPaste.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,54 +23,107 @@
export module '@theia/plugin' {

/**
* Provider invoked when the user copies and pastes code.
* The reason why paste edits were requested.
*/
export interface DocumentPasteEditProvider {
export enum DocumentPasteTriggerKind {
/**
* Pasting was requested as part of a normal paste operation.
*/
Automatic = 0,

/**
* Pasting was requested by the user with the `paste as` command.
*/
PasteAs = 1,
}

/**
* Additional information about the paste operation.
*/

export interface DocumentPasteEditContext {
/**
* Requested kind of paste edits to return.
*/
readonly only: DocumentPasteEditKind | undefined;

/**
* The reason why paste edits were requested.
*/
readonly triggerKind: DocumentPasteTriggerKind;
}

/**
* Provider invoked when the user copies or pastes in a {@linkcode TextDocument}.
*/
interface DocumentPasteEditProvider<T extends DocumentPasteEdit = DocumentPasteEdit> {

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

/**
* Invoked before the user pastes into a document.
*
* In this method, extensions can return a workspace edit that replaces the standard pasting behavior.
* Returned edits can replace the standard pasting behavior.
*
* @param document Document being pasted into
* @param ranges Currently selected ranges in the document.
* @param dataTransfer The data transfer associated with the paste.
* @param ranges Range in the {@linkcode document} to paste into.
* @param dataTransfer The {@link DataTransfer data transfer} associated with the paste. This object is only valid for the duration of the paste operation.
* @param context Additional context for the paste.
* @param token A cancellation token.
*
* @return Optional workspace edit that applies the paste. Return undefined to use standard pasting.
* @return Set of potential {@link DocumentPasteEdit edits} that apply the paste. Return `undefined` to use standard pasting.
*/
provideDocumentPasteEdits?(document: TextDocument, ranges: readonly Range[], dataTransfer: DataTransfer, token: CancellationToken): ProviderResult<DocumentPasteEdit>;
provideDocumentPasteEdits?(document: TextDocument, ranges: readonly Range[], dataTransfer: DataTransfer, context: DocumentPasteEditContext,
token: CancellationToken): ProviderResult<T[]>;

/**
* Optional method which fills in the {@linkcode DocumentPasteEdit.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 DocumentPasteEdit.additionalEdit}.
*
* @param pasteEdit The {@linkcode DocumentPasteEdit} to resolve.
* @param token A cancellation token.
*
* @returns The resolved paste edit or a thenable that resolves to such. It is OK to return the given
* `pasteEdit`. If no result is returned, the given `pasteEdit` is used.
*/
resolveDocumentPasteEdit?(pasteEdit: T, token: CancellationToken): ProviderResult<T>;
}

/**
* An operation applied on paste
* An edit applied on paste.
*/
class DocumentPasteEdit {

/**
* Human readable label that describes the edit.
*/
label: string;
title: string;

/**
* Controls the ordering or multiple paste edits. If this provider yield to edits, it will be shown lower in the list.
* {@link DocumentPasteEditKind Kind} of the edit.
*
* Used to identify specific types of edits.
*/
yieldTo?: ReadonlyArray<
| { readonly extensionId: string; readonly providerId: string }
| { readonly mimeType: string }
>;
kind: DocumentPasteEditKind;

/**
* The text or snippet to insert at the pasted locations.
Expand All @@ -83,43 +136,77 @@ export module '@theia/plugin' {
additionalEdit?: WorkspaceEdit;

/**
* @param insertText The text or snippet to insert at the pasted locations.
* Controls the ordering of paste edits provided by multiple providers.
*
* TODO: Reverse args, but this will break existing consumers :(
* If this edit yields to another, it will be shown lower in the list of paste edit.
*/
constructor(insertText: string | SnippetString, id: string, label: string);
yieldTo?: readonly DocumentPasteEditKind[];

/**
* Create a new paste edit.
*
* @param insertText The text or snippet to insert at the pasted locations.
* @param title Human readable label that describes the edit.
* @param kind {@link DocumentPasteEditKind Kind} of the edit.
*/
constructor(insertText: string | SnippetString, title: string, kind: DocumentPasteEditKind);
}

/**
* TODO: Share with code action kind?
*/
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 {
/**
* Identifies the provider.
*
* This id is used when users configure the default provider for paste.
* List of {@link DocumentPasteEditKind kinds} that the provider may return in {@linkcode DocumentPasteEditProvider.provideDocumentPasteEdits provideDocumentPasteEdits}.
*
* This id should be unique within the extension but does not need to be unique across extensions.
* The provider will only be invoked when one of these kinds is being requested. For normal pasting, all providers will be invoked.
*/
readonly id: string;
readonly providedPasteEditKinds: readonly DocumentPasteEditKind[];

/**
* Mime types that {@link DocumentPasteEditProvider.prepareDocumentPaste provideDocumentPasteEdits} may add on copy.
* Mime types that {@linkcode DocumentPasteEditProvider.prepareDocumentPaste prepareDocumentPaste} may add on copy.
*/
readonly copyMimeTypes?: readonly string[];

/**
* Mime types that {@link DocumentPasteEditProvider.provideDocumentPasteEdits provideDocumentPasteEdits} should be invoked for.
* Mime types that {@linkcode DocumentPasteEditProvider.provideDocumentPasteEdits provideDocumentPasteEdits} should be invoked for.
*
* 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
* Use `files` to indicate that the provider should be invoked if any {@link DataTransferFile files} are present in the {@linkcode DataTransfer}.
* Note that {@linkcode DataTransferFile} entries are only created when dropping content from outside the editor, such as
* from the operating system.
*/
readonly pasteMimeTypes?: readonly string[];
}

namespace languages {
/**
* Registers a new {@linkcode DocumentPasteEditProvider}.
*
* @param selector A selector that defines the documents this provider applies to.
* @param provider A paste editor provider.
* @param metadata Additional metadata about the provider.
*
* @returns A {@link Disposable} that unregisters this provider when disposed of.
* @stubbed
*/
export function registerDocumentPasteEditProvider(selector: DocumentSelector, provider: DocumentPasteEditProvider, metadata: DocumentPasteProviderMetadata): Disposable;
}
}
25 changes: 12 additions & 13 deletions packages/plugin/src/theia.proposed.dropMetadata.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,16 @@ export module '@theia/plugin' {
/**
* Human readable label that describes the edit.
*/
label?: string;
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.
Expand All @@ -39,21 +48,11 @@ export module '@theia/plugin' {
/**
* Controls the ordering or multiple paste edits. If this provider yield to edits, it will be shown lower in the list.
*/
yieldTo?: ReadonlyArray<
| { readonly extensionId: string; readonly providerId: string }
| { readonly mimeType: string }
>;
yieldTo?: ReadonlyArray<DocumentPasteEditKind>;
}

export interface DocumentDropEditProviderMetadata {
/**
* Identifies the provider.
*
* This id is used when users configure the default provider for drop.
*
* This id should be unique within the extension but does not need to be unique across extensions.
*/
readonly id: string;
readonly providedDropEditKinds?: readonly DocumentPasteEditKind[];

/**
* List of data transfer types that the provider supports.
Expand Down

0 comments on commit 59d0913

Please sign in to comment.