mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-15 21:01:05 +01:00
Switch to provider based model for on drop
This simplifies implementing the provider and also give potentially gives us more control over how the drop happens
This commit is contained in:
@@ -3,14 +3,15 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { distinct } from 'vs/base/common/arrays';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
import { ISingleEditOperation } from 'vs/editor/common/core/editOperation';
|
||||
import * as languages from 'vs/editor/common/languages';
|
||||
import * as search from 'vs/workbench/contrib/search/common/search';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { Position as EditorPosition } from 'vs/editor/common/core/position';
|
||||
import { IPosition, Position as EditorPosition } from 'vs/editor/common/core/position';
|
||||
import { Range as EditorRange, IRange } from 'vs/editor/common/core/range';
|
||||
import { ExtHostContext, MainThreadLanguageFeaturesShape, ExtHostLanguageFeaturesShape, MainContext, ILanguageConfigurationDto, IRegExpDto, IIndentationRuleDto, IOnEnterRuleDto, ILocationDto, IWorkspaceSymbolDto, reviveWorkspaceEditDto, IDocumentFilterDto, ILocationLinkDto, ISignatureHelpProviderMetadataDto, ILinkDto, ICallHierarchyItemDto, ISuggestDataDto, ICodeActionDto, ISuggestDataDtoField, ISuggestResultDtoField, ICodeActionProviderMetadataDto, ILanguageWordDefinitionDto, IdentifiableInlineCompletions, IdentifiableInlineCompletion, ITypeHierarchyItemDto, IInlayHintDto } from '../common/extHost.protocol';
|
||||
import { ILanguageConfigurationService } from 'vs/editor/common/languages/languageConfigurationRegistry';
|
||||
@@ -27,19 +28,33 @@ import { decodeSemanticTokensDto } from 'vs/editor/common/services/semanticToken
|
||||
import { revive } from 'vs/base/common/marshalling';
|
||||
import { CancellationError } from 'vs/base/common/errors';
|
||||
import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures';
|
||||
import { Mimes } from 'vs/base/common/mime';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { performSnippetEdit } from 'vs/editor/contrib/snippet/browser/snippetController2';
|
||||
import { DataTransferConverter } from 'vs/workbench/api/common/shared/dataTransfer';
|
||||
import { extractEditorsDropData } from 'vs/workbench/browser/dnd';
|
||||
import { IDataTransfer, IDataTransferItem } from 'vs/workbench/common/dnd';
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
||||
@extHostNamedCustomer(MainContext.MainThreadLanguageFeatures)
|
||||
export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesShape {
|
||||
export class MainThreadLanguageFeatures extends Disposable implements MainThreadLanguageFeaturesShape {
|
||||
|
||||
private readonly _proxy: ExtHostLanguageFeaturesShape;
|
||||
private readonly _registrations = new Map<number, IDisposable>();
|
||||
|
||||
private readonly _dropIntoEditorListeners = new Map<ICodeEditor, IDisposable>();
|
||||
|
||||
constructor(
|
||||
extHostContext: IExtHostContext,
|
||||
@ILanguageService private readonly _languageService: ILanguageService,
|
||||
@ILanguageConfigurationService private readonly _languageConfigurationService: ILanguageConfigurationService,
|
||||
@ILanguageFeaturesService private readonly _languageFeaturesService: ILanguageFeaturesService,
|
||||
@ICodeEditorService private readonly _codeEditorService: ICodeEditorService,
|
||||
@IInstantiationService private readonly _instantiationService: IInstantiationService,
|
||||
) {
|
||||
super();
|
||||
|
||||
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostLanguageFeatures);
|
||||
|
||||
if (this._languageService) {
|
||||
@@ -69,13 +84,34 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha
|
||||
});
|
||||
updateAllWordDefinitions();
|
||||
}
|
||||
|
||||
const registerDropListenerOnEditor = (editor: ICodeEditor) => {
|
||||
this._dropIntoEditorListeners.get(editor)?.dispose();
|
||||
this._dropIntoEditorListeners.set(editor, editor.onDropIntoEditor(e => this.onDropIntoEditor(editor, e.position, e.event)));
|
||||
};
|
||||
|
||||
this._register(_codeEditorService.onCodeEditorAdd(registerDropListenerOnEditor));
|
||||
|
||||
this._register(_codeEditorService.onCodeEditorRemove(editor => {
|
||||
this._dropIntoEditorListeners.get(editor)?.dispose();
|
||||
this._dropIntoEditorListeners.delete(editor);
|
||||
}));
|
||||
|
||||
for (const editor of this._codeEditorService.listCodeEditors()) {
|
||||
registerDropListenerOnEditor(editor);
|
||||
}
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
override dispose(): void {
|
||||
for (const registration of this._registrations.values()) {
|
||||
registration.dispose();
|
||||
}
|
||||
this._registrations.clear();
|
||||
|
||||
dispose(this._dropIntoEditorListeners.values());
|
||||
this._dropIntoEditorListeners.clear();
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
$unregister(handle: number): void {
|
||||
@@ -850,6 +886,69 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
// --- document drop Edits
|
||||
|
||||
$registerDocumentOnDropProvider(handle: number, selector: IDocumentFilterDto[]): void {
|
||||
this._registrations.set(handle, this._languageFeaturesService.documentOnDropEditProvider.register(selector, {
|
||||
provideDocumentOnDropEdits: async (model, position, dataTransfer, token) => {
|
||||
const dataTransferDto = await DataTransferConverter.toDataTransferDTO(dataTransfer);
|
||||
return this._proxy.$provideDocumentOnDropEdits(handle, model.uri, position, dataTransferDto, token);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private async onDropIntoEditor(editor: ICodeEditor, position: IPosition, dragEvent: DragEvent) {
|
||||
if (!dragEvent.dataTransfer || !editor.hasModel()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const model = editor.getModel();
|
||||
const modelVersionNow = model.getVersionId();
|
||||
|
||||
const textEditorDataTransfer: IDataTransfer = new Map<string, IDataTransferItem>();
|
||||
for (const item of dragEvent.dataTransfer.items) {
|
||||
if (item.kind === 'string') {
|
||||
const type = item.type;
|
||||
const asStringValue = new Promise<string>(resolve => item.getAsString(resolve));
|
||||
textEditorDataTransfer.set(type, {
|
||||
asString: () => asStringValue,
|
||||
value: undefined
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (!textEditorDataTransfer.has(Mimes.uriList.toLowerCase())) {
|
||||
const editorData = (await this._instantiationService.invokeFunction(extractEditorsDropData, dragEvent))
|
||||
.filter(input => input.resource)
|
||||
.map(input => input.resource!.toString());
|
||||
|
||||
if (editorData.length) {
|
||||
const str = distinct(editorData).join('\n');
|
||||
textEditorDataTransfer.set(Mimes.uriList.toLowerCase(), {
|
||||
asString: () => Promise.resolve(str),
|
||||
value: undefined
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (textEditorDataTransfer.size === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const ordered = this._languageFeaturesService.documentOnDropEditProvider.ordered(model);
|
||||
for (const provider of ordered) {
|
||||
const edit = await provider.provideDocumentOnDropEdits(model, position, textEditorDataTransfer, CancellationToken.None);
|
||||
if (editor.getModel().getVersionId() !== modelVersionNow) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (edit) {
|
||||
performSnippetEdit(editor, edit);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class MainThreadDocumentSemanticTokensProvider implements languages.DocumentSemanticTokensProvider {
|
||||
|
||||
Reference in New Issue
Block a user