diff --git a/extensions/typescript-language-features/src/languageFeatures/dropOrPasteResource.ts b/extensions/typescript-language-features/src/languageFeatures/dropOrPasteResource.ts new file mode 100644 index 0000000000000..9f4e13dd64564 --- /dev/null +++ b/extensions/typescript-language-features/src/languageFeatures/dropOrPasteResource.ts @@ -0,0 +1,52 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as vscode from 'vscode'; +import { ITypeScriptServiceClient } from '../typescriptService'; +import { UriList } from '../utils/uriList'; + +const mimes = Object.freeze({ + uriList: 'text/uri-list', +}); + + +class MyDocumentDropEditProvider implements vscode.DocumentDropEditProvider { + + constructor( + private readonly client: ITypeScriptServiceClient, + ) { } + + async provideDocumentDropEdits( + document: vscode.TextDocument, + position: vscode.Position, + dataTransfer: vscode.DataTransfer, + token: vscode.CancellationToken + ): Promise<vscode.DocumentDropEdit | undefined> { + const text = dataTransfer.get(mimes.uriList)?.value; + if (!text) { + return; + } + + const uriList = UriList.from(text); + if (!uriList.entries.length) { + return; + } + + const response = await this.client.execute('getDropOrPasteEdit', {}, token); + if (!response || response.type !== 'response' || !response.body) { + + } + const edit = new vscode.DocumentDropEdit(uriList.entries[0].str); + + return edit; + } +} + +export function register( + selector: vscode.DocumentSelector, + client: ITypeScriptServiceClient, +): vscode.Disposable { + return vscode.languages.registerDocumentDropEditProvider(selector, new MyDocumentDropEditProvider(client)); +} diff --git a/extensions/typescript-language-features/src/languageProvider.ts b/extensions/typescript-language-features/src/languageProvider.ts index 7b95591604bd0..aed858673b7ba 100644 --- a/extensions/typescript-language-features/src/languageProvider.ts +++ b/extensions/typescript-language-features/src/languageProvider.ts @@ -70,6 +70,7 @@ export default class LanguageProvider extends Disposable { import('./languageFeatures/directiveCommentCompletions').then(provider => this._register(provider.register(selector, this.client))), import('./languageFeatures/documentHighlight').then(provider => this._register(provider.register(selector, this.client))), import('./languageFeatures/documentSymbol').then(provider => this._register(provider.register(selector, this.client, cachedNavTreeResponse))), + import('./languageFeatures/dropOrPasteResource').then(provider => this._register(provider.register(selector, this.client))), import('./languageFeatures/fileReferences').then(provider => this._register(provider.register(this.client, this.commandManager))), import('./languageFeatures/fixAll').then(provider => this._register(provider.register(selector, this.client, this.fileConfigurationManager, this.client.diagnosticsManager))), import('./languageFeatures/folding').then(provider => this._register(provider.register(selector, this.client))), diff --git a/extensions/typescript-language-features/src/typescriptService.ts b/extensions/typescript-language-features/src/typescriptService.ts index 931b287df03e1..38c13850b35f0 100644 --- a/extensions/typescript-language-features/src/typescriptService.ts +++ b/extensions/typescript-language-features/src/typescriptService.ts @@ -78,6 +78,12 @@ interface StandardTsServerRequests { 'linkedEditingRange': [Proto.FileLocationRequestArgs, Proto.LinkedEditingRangeResponse]; 'mapCode': [Proto.MapCodeRequestArgs, Proto.MapCodeResponse]; 'getPasteEdits': [Proto.GetPasteEditsRequestArgs, Proto.GetPasteEditsResponse]; + + // Experimental + + // FIll in right types here + // You can define the types in `extensions/typescript-language-features/src/tsServer/protocol/protocol.d.ts` before they are officially published + 'getDropOrPasteEdit': [Proto.FileLocationRequestArgs, Proto.DefinitionResponse]; } interface NoResponseTsServerRequests { diff --git a/extensions/typescript-language-features/src/utils/uriList.ts b/extensions/typescript-language-features/src/utils/uriList.ts new file mode 100644 index 0000000000000..8b7f52e568f07 --- /dev/null +++ b/extensions/typescript-language-features/src/utils/uriList.ts @@ -0,0 +1,35 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { coalesce } from './arrays'; +import * as vscode from 'vscode'; + +function splitUriList(str: string): string[] { + return str.split('\r\n'); +} + +function parseUriList(str: string): string[] { + return splitUriList(str) + .filter(value => !value.startsWith('#')) // Remove comments + .map(value => value.trim()); +} + +export class UriList { + + static from(str: string): UriList { + return new UriList(coalesce(parseUriList(str).map(line => { + try { + return { uri: vscode.Uri.parse(line), str: line }; + } catch { + // Uri parse failure + return undefined; + } + }))); + } + + private constructor( + public readonly entries: ReadonlyArray<{ readonly uri: vscode.Uri; readonly str: string }> + ) { } +}