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": [
"documentPaste",
"diffContentOptions",
"dropMetadata"
"diffContentOptions"
],
"activationEvents": [
"onNotebook:jupyter-notebook",

View File

@ -48,7 +48,7 @@ function getImageMimeType(uri: vscode.Uri): string | undefined {
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(
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);
pasteEdit.yieldTo = [vscode.DocumentPasteEditKind.Empty.append('text')];
pasteEdit.yieldTo = [vscode.DocumentDropOrPasteEditKind.Empty.append('text')];
pasteEdit.additionalEdit = insert.additionalEdit;
return [pasteEdit];
}
@ -85,7 +85,7 @@ class DropOrPasteEditProvider implements vscode.DocumentPasteEditProvider, vscod
}
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.title = vscode.l10n.t('Insert Image as Attachment');
return dropEdit;

View File

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

View File

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

View File

@ -30,7 +30,7 @@ enum CopyFilesSettings {
*/
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 = [
Mime.textUriList,
@ -39,8 +39,8 @@ class ResourcePasteOrDropProvider implements vscode.DocumentPasteEditProvider, v
];
private readonly _yieldTo = [
vscode.DocumentPasteEditKind.Empty.append('text'),
vscode.DocumentPasteEditKind.Empty.append('markdown', 'image', 'attachment'),
vscode.DocumentDropOrPasteEditKind.Empty.append('text'),
vscode.DocumentDropOrPasteEditKind.Empty.append('markdown', 'image', 'attachment'),
];
constructor(
@ -133,7 +133,7 @@ class ResourcePasteOrDropProvider implements vscode.DocumentPasteEditProvider, v
}
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;

View File

@ -17,7 +17,7 @@ import { UriList } from '../../util/uriList';
*/
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];
@ -61,8 +61,8 @@ class PasteUrlEditProvider implements vscode.DocumentPasteEditProvider {
if (!(await shouldInsertMarkdownLinkByDefault(this._parser, document, pasteUrlSetting, ranges, token))) {
pasteEdit.yieldTo = [
vscode.DocumentPasteEditKind.Empty.append('text'),
vscode.DocumentPasteEditKind.Empty.append('uri')
vscode.DocumentDropOrPasteEditKind.Empty.append('text'),
vscode.DocumentDropOrPasteEditKind.Empty.append('uri')
];
}

View File

@ -265,5 +265,5 @@ export interface DropOrPasteEdit {
readonly snippet: vscode.SnippetString;
readonly label: string;
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 {
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';

View File

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

View File

@ -37,7 +37,7 @@ suite.skip('vscode API - Copy Paste', function () {
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');
const newDocContent = getNextDocumentText(testDisposables, doc);
@ -62,7 +62,7 @@ suite.skip('vscode API - Copy Paste', function () {
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');
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(' ')}`));
}
}
}, { providedPasteEditKinds: [vscode.DocumentPasteEditKind.Empty.append('test')], copyMimeTypes: [textPlain] }));
}, { providedPasteEditKinds: [vscode.DocumentDropOrPasteEditKind.Empty.append('test')], copyMimeTypes: [textPlain] }));
await vscode.commands.executeCommand('editor.action.clipboardCopyAction');
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'));
providerAResolve();
}
}, { providedPasteEditKinds: [vscode.DocumentPasteEditKind.Empty.append('test')], copyMimeTypes: [textPlain] }));
}, { providedPasteEditKinds: [vscode.DocumentDropOrPasteEditKind.Empty.append('test')], copyMimeTypes: [textPlain] }));
// Later registered providers will be called first
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'));
}
}, { providedPasteEditKinds: [vscode.DocumentPasteEditKind.Empty.append('test')], copyMimeTypes: [textPlain] }));
}, { providedPasteEditKinds: [vscode.DocumentDropOrPasteEditKind.Empty.append('test')], copyMimeTypes: [textPlain] }));
await vscode.commands.executeCommand('editor.action.clipboardCopyAction');
const newDocContent = getNextDocumentText(testDisposables, doc);
@ -159,7 +159,7 @@ suite.skip('vscode API - Copy Paste', function () {
dataTransfer.set(textPlain, new vscode.DataTransferItem('xyz'));
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 {
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();
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');
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> {
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 {
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');
}
}, { providedPasteEditKinds: [vscode.DocumentPasteEditKind.Empty.append('test')], copyMimeTypes: [textPlain] }));
}, { providedPasteEditKinds: [vscode.DocumentDropOrPasteEditKind.Empty.append('test')], copyMimeTypes: [textPlain] }));
await vscode.commands.executeCommand('editor.action.clipboardCopyAction');
const newDocContent = getNextDocumentText(testDisposables, doc);

View File

@ -2146,7 +2146,7 @@ export type DropYieldTo = { readonly kind: HierarchicalKind } | { readonly mimeT
/**
* @internal
*/
export interface DocumentOnDropEdit {
export interface DocumentDropEdit {
readonly title: string;
readonly kind: HierarchicalKind | undefined;
readonly handledMimeType?: string;
@ -2158,11 +2158,12 @@ export interface DocumentOnDropEdit {
/**
* @internal
*/
export interface DocumentOnDropEditProvider {
export interface DocumentDropEditProvider {
readonly id?: 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 {

View File

@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
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';
export const ILanguageFeaturesService = createDecorator<ILanguageFeaturesService>('ILanguageFeaturesService');
@ -75,7 +75,7 @@ export interface ILanguageFeaturesService {
readonly evaluatableExpressionProvider: LanguageFeatureRegistry<EvaluatableExpressionProvider>;
readonly documentOnDropEditProvider: LanguageFeatureRegistry<DocumentOnDropEditProvider>;
readonly documentDropEditProvider: LanguageFeatureRegistry<DocumentDropEditProvider>;
readonly mappedEditsProvider: LanguageFeatureRegistry<MappedEditsProvider>;

View File

@ -5,7 +5,7 @@
import { URI } from 'vs/base/common/uri';
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 { 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 documentRangeSemanticTokensProvider = new LanguageFeatureRegistry<DocumentRangeSemanticTokensProvider>(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 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 { IPosition } from 'vs/editor/common/core/position';
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 { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures';
import { localize } from 'vs/nls';
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 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);
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();
this._register(languageFeaturesService.documentOnDropEditProvider.register('*', new DefaultTextPasteOrDropEditProvider()));
this._register(languageFeaturesService.documentOnDropEditProvider.register('*', new PathProvider()));
this._register(languageFeaturesService.documentOnDropEditProvider.register('*', new RelativePathProvider(workspaceContextService)));
this._register(languageFeaturesService.documentDropEditProvider.register('*', new DefaultTextPasteOrDropEditProvider()));
this._register(languageFeaturesService.documentDropEditProvider.register('*', new PathProvider()));
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 { Range } from 'vs/editor/common/core/range';
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 { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures';
import { DraggedTreeItemsIdentifier } from 'vs/editor/common/services/treeViewsDnd';
@ -46,7 +46,7 @@ export class DropIntoEditorController extends Disposable implements IEditorContr
private _currentOperation?: CancelablePromise<void>;
private readonly _dropProgressManager: InlineProgressManager;
private readonly _postDropWidgetManager: PostEditWidgetManager<DocumentOnDropEdit>;
private readonly _postDropWidgetManager: PostEditWidgetManager<DocumentDropEdit>;
private readonly treeItemsTransfer = LocalSelectionTransfer.getInstance<DraggedTreeItemsIdentifier>();
@ -97,7 +97,7 @@ export class DropIntoEditorController extends Disposable implements IEditorContr
return;
}
const providers = this._languageFeaturesService.documentOnDropEditProvider
const providers = this._languageFeaturesService.documentDropEditProvider
.ordered(model)
.filter(provider => {
if (!provider.dropMimeTypes) {
@ -130,10 +130,10 @@ export class DropIntoEditorController extends Disposable implements IEditorContr
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 => {
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 }));
} catch (err) {
console.error(err);
@ -145,7 +145,7 @@ export class DropIntoEditorController extends Disposable implements IEditorContr
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 });
for (const [configMime, desiredKindStr] of Object.entries(preferredProviders)) {
const desiredKind = new HierarchicalKind(desiredKindStr);

View File

@ -5,7 +5,7 @@
import { URI } from 'vs/base/common/uri';
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 { SnippetParser } from 'vs/editor/contrib/snippet/browser/snippetParser';
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
* 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 (typeof edit.insertText === 'string' ? edit.insertText === '' : edit.insertText.snippet === '') {
return {

View File

@ -13,7 +13,7 @@ import 'vs/css!./postEditWidget';
import { ContentWidgetPositionPreference, ICodeEditor, IContentWidget, IContentWidgetPosition } from 'vs/editor/browser/editorBrowser';
import { IBulkEditResult, IBulkEditService } from 'vs/editor/browser/services/bulkEditService';
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 { createCombinedWorkspaceEdit } from 'vs/editor/contrib/dropOrPasteInto/browser/edit';
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';
interface EditSet<Edit extends DocumentPasteEdit | DocumentOnDropEdit> {
interface EditSet<Edit extends DocumentPasteEdit | DocumentDropEdit> {
readonly activeEditIndex: number;
readonly allEdits: ReadonlyArray<Edit>;
}
@ -32,7 +32,7 @@ interface ShowCommand {
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';
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>>());

View File

@ -5,11 +5,11 @@
import * as assert from 'assert';
import { HierarchicalKind } from 'vs/base/common/hierarchicalKind';
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';
function createTestEdit(kind: string, args?: Partial<DocumentOnDropEdit>): DocumentOnDropEdit {
function createTestEdit(kind: string, args?: Partial<DocumentDropEdit>): DocumentDropEdit {
return {
title: '',
insertText: '',
@ -21,13 +21,13 @@ function createTestEdit(kind: string, args?: Partial<DocumentOnDropEdit>): Docum
suite('sortEditsByYieldTo', () => {
test('Should noop for empty edits', () => {
const edits: DocumentOnDropEdit[] = [];
const edits: DocumentDropEdit[] = [];
assert.deepStrictEqual(sortEditsByYieldTo(edits), []);
});
test('Yielded to edit should get sorted after target', () => {
const edits: DocumentOnDropEdit[] = [
const edits: DocumentDropEdit[] = [
createTestEdit('a', { yieldTo: [{ kind: new HierarchicalKind('b') }] }),
createTestEdit('b'),
];
@ -36,7 +36,7 @@ suite('sortEditsByYieldTo', () => {
test('Should handle chain of yield to', () => {
{
const edits: DocumentOnDropEdit[] = [
const edits: DocumentDropEdit[] = [
createTestEdit('c', { yieldTo: [{ kind: new HierarchicalKind('a') }] }),
createTestEdit('a', { yieldTo: [{ kind: new HierarchicalKind('b') }] }),
createTestEdit('b'),
@ -45,7 +45,7 @@ suite('sortEditsByYieldTo', () => {
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('c', { yieldTo: [{ kind: new HierarchicalKind('a') }] }),
createTestEdit('b'),
@ -56,7 +56,7 @@ suite('sortEditsByYieldTo', () => {
});
test(`Should not reorder when yield to isn't used`, () => {
const edits: DocumentOnDropEdit[] = [
const edits: DocumentDropEdit[] = [
createTestEdit('c', { yieldTo: [{ kind: new HierarchicalKind('x') }] }),
createTestEdit('a', { yieldTo: [{ kind: new HierarchicalKind('y') }] }),
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 typeh from 'vs/workbench/contrib/typeHierarchy/common/typeHierarchy';
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 { isFalsyOrEmpty } from 'vs/base/common/arrays';
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);
this._documentOnDropEditProviders.set(handle, provider);
this._registrations.set(handle, combinedDisposable(
this._languageFeaturesService.documentOnDropEditProvider.register(selector, provider),
this._languageFeaturesService.documentDropEditProvider.register(selector, provider),
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();
readonly dropMimeTypes?: readonly string[];
readonly resolveDocumentDropEdit?: languages.DocumentDropEditProvider['resolveDocumentDropEdit'];
constructor(
private readonly _handle: number,
private readonly _proxy: ExtHostLanguageFeaturesShape,
@ -1095,9 +1097,19 @@ class MainThreadDocumentOnDropEditProvider implements languages.DocumentOnDropEd
@IUriIdentityService private readonly _uriIdentService: IUriIdentityService
) {
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);
try {
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);
},
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
DocumentPasteTriggerKind: extHostTypes.DocumentPasteTriggerKind,
DocumentDropEdit: extHostTypes.DocumentDropEdit,
DocumentPasteEditKind: extHostTypes.DocumentPasteEditKind,
DocumentDropOrPasteEditKind: extHostTypes.DocumentDropOrPasteEditKind,
DocumentPasteEdit: extHostTypes.DocumentPasteEdit,
InlayHint: extHostTypes.InlayHint,
InlayHintLabelPart: extHostTypes.InlayHintLabelPart,

View File

@ -2082,7 +2082,6 @@ export interface IPasteEditProviderMetadataDto {
export interface IDocumentPasteContextDto {
readonly only: string | undefined;
readonly triggerKind: languages.DocumentPasteTriggerKind;
}
export interface IPasteEditDto {
@ -2095,10 +2094,13 @@ export interface IPasteEditDto {
}
export interface IDocumentDropEditProviderMetadata {
readonly supportsResolve: boolean;
dropMimeTypes: readonly string[];
}
export interface IDocumentOnDropEditDto {
export interface IDocumentDropEditDto {
_cacheId?: ChainedCacheId;
title: string;
kind: string | undefined;
insertText: string | { snippet: string };
@ -2170,7 +2172,7 @@ export interface ExtHostLanguageFeaturesShape {
$provideTypeHierarchySupertypes(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;
$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>;
$provideInlineEdit(handle: number, document: UriComponents, context: languages.IInlineEditContext, token: CancellationToken): Promise<IdentifiableInlineEdit | undefined>;
$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 { ExtHostTelemetry, IExtHostTelemetry } from 'vs/workbench/api/common/extHostTelemetry';
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 type * as vscode from 'vscode';
import { Cache } from './cache';
@ -581,7 +581,7 @@ class DocumentPasteEditProvider {
});
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,
}, token);
if (!edits || token.isCancellationRequested) {
@ -1956,7 +1956,9 @@ class TypeHierarchyAdapter {
}
}
class DocumentOnDropEditAdapter {
class DocumentDropEditAdapter {
private readonly _cache = new Cache<vscode.DocumentDropEdit>('DocumentDropEdit');
constructor(
private readonly _proxy: extHostProtocol.MainThreadLanguageFeaturesShape,
@ -1966,7 +1968,7 @@ class DocumentOnDropEditAdapter {
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 pos = typeConvert.Position.to(position);
const dataTransfer = typeConvert.DataTransfer.toDataTransfer(dataTransferDto, async (id) => {
@ -1978,7 +1980,11 @@ class DocumentOnDropEditAdapter {
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),
kind: edit.kind?.value,
yieldTo: edit.yieldTo?.map(x => x.value),
@ -1986,6 +1992,22 @@ class DocumentOnDropEditAdapter {
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 {
@ -2036,7 +2058,7 @@ type Adapter = DocumentSymbolAdapter | CodeLensAdapter | DefinitionAdapter | Hov
| DocumentSemanticTokensAdapter | DocumentRangeSemanticTokensAdapter
| EvaluatableExpressionAdapter | InlineValuesAdapter
| LinkedEditingRangeAdapter | InlayHintsAdapter | InlineCompletionAdapter
| DocumentOnDropEditAdapter | MappedEditsAdapter | NewSymbolNamesAdapter | InlineEditAdapter;
| DocumentDropEditAdapter | MappedEditsAdapter | NewSymbolNamesAdapter | InlineEditAdapter;
class AdapterData {
constructor(
@ -2704,18 +2726,29 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF
registerDocumentOnDropEditProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.DocumentDropEditProvider, metadata?: vscode.DocumentDropEditProviderMetadata) {
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);
}
$provideDocumentOnDropEdits(handle: number, requestId: number, resource: UriComponents, position: IPosition, dataTransferDto: extHostProtocol.DataTransferDTO, token: CancellationToken): Promise<extHostProtocol.IDocumentOnDropEditDto[] | undefined> {
return this._withAdapter(handle, DocumentOnDropEditAdapter, adapter =>
$provideDocumentOnDropEdits(handle: number, requestId: number, resource: UriComponents, position: IPosition, dataTransferDto: extHostProtocol.DataTransferDTO, token: CancellationToken): Promise<extHostProtocol.IDocumentDropEditDto[] | undefined> {
return this._withAdapter(handle, DocumentDropEditAdapter, adapter =>
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
registerMappedEditsProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.MappedEditsProvider): vscode.Disposable {

View File

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

View File

@ -7,6 +7,41 @@ declare module 'vscode' {
// 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.
*/
@ -30,7 +65,7 @@ declare module 'vscode' {
/**
* Requested kind of paste edits to return.
*/
readonly only: DocumentPasteEditKind | undefined;
readonly only: DocumentDropOrPasteEditKind | undefined;
/**
* The reason why paste edits were requested.
@ -103,11 +138,11 @@ declare module 'vscode' {
title: string;
/**
* {@link DocumentPasteEditKind Kind} of the edit.
* {@link DocumentDropOrPasteEditKind Kind} of the edit.
*
* Used to identify specific types of edits.
*/
kind: DocumentPasteEditKind;
kind: DocumentDropOrPasteEditKind;
/**
* 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.
*/
yieldTo?: readonly DocumentPasteEditKind[];
yieldTo?: readonly DocumentDropOrPasteEditKind[];
/**
* 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.
* @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 {
/**
* 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.
@ -181,6 +201,74 @@ declare module 'vscode' {
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 {
/**
* Registers a new {@linkcode DocumentPasteEditProvider}.
@ -192,5 +280,10 @@ declare module 'vscode' {
* @returns A {@link Disposable} that unregisters this provider when disposed of.
*/
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;
}
}