Merge branch 'main' into joh/swc

This commit is contained in:
Johannes
2022-05-25 12:29:28 +02:00
159 changed files with 1894 additions and 930 deletions
+28
View File
@@ -0,0 +1,28 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { VSDataTransfer } from 'vs/base/common/dataTransfer';
import { URI } from 'vs/base/common/uri';
export function toVSDataTransfer(dataTransfer: DataTransfer) {
const vsDataTransfer = new VSDataTransfer();
for (const item of dataTransfer.items) {
const type = item.type;
if (item.kind === 'string') {
const asStringValue = new Promise<string>(resolve => item.getAsString(resolve));
vsDataTransfer.setString(type, asStringValue);
} else if (item.kind === 'file') {
const file = item.getAsFile() as null | (File & { path?: string });
if (file) {
const uri = file.path ? URI.parse(file.path) : undefined;
vsDataTransfer.setFile(type, file.name, uri, async () => {
return new Uint8Array(await file.arrayBuffer());
});
}
}
}
return vsDataTransfer;
}
@@ -338,6 +338,7 @@ export abstract class EditorAction extends EditorCommand {
protected reportTelemetry(accessor: ServicesAccessor, editor: ICodeEditor) {
type EditorActionInvokedClassification = {
owner: 'alexdima';
name: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
id: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
};
+9
View File
@@ -721,6 +721,15 @@ export interface CodeActionProvider {
_getAdditionalMenuItems?(context: CodeActionContext, actions: readonly CodeAction[]): Command[];
}
/**
* @internal
*/
export interface DocumentPasteEditProvider {
prepareDocumentPaste?(model: model.ITextModel, selection: Selection, dataTransfer: VSDataTransfer, token: CancellationToken): Promise<undefined | VSDataTransfer>;
provideDocumentPasteEdits(model: model.ITextModel, selection: Selection, dataTransfer: VSDataTransfer, token: CancellationToken): Promise<WorkspaceEdit | SnippetTextEdit | undefined>;
}
/**
* Represents a parameter of a callable-signature. A parameter can
* have a label and a doc-comment.
@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { LanguageFeatureRegistry, NotebookInfoResolver } from 'vs/editor/common/languageFeatureRegistry';
import { CodeActionProvider, CodeLensProvider, CompletionItemProvider, DeclarationProvider, DefinitionProvider, DocumentColorProvider, DocumentFormattingEditProvider, DocumentHighlightProvider, DocumentOnDropEditProvider, DocumentRangeFormattingEditProvider, DocumentRangeSemanticTokensProvider, DocumentSemanticTokensProvider, DocumentSymbolProvider, EvaluatableExpressionProvider, FoldingRangeProvider, HoverProvider, ImplementationProvider, InlayHintsProvider, InlineCompletionsProvider, InlineValuesProvider, LinkedEditingRangeProvider, LinkProvider, OnTypeFormattingEditProvider, ReferenceProvider, RenameProvider, SelectionRangeProvider, SignatureHelpProvider, TypeDefinitionProvider } from 'vs/editor/common/languages';
import { CodeActionProvider, CodeLensProvider, CompletionItemProvider, DeclarationProvider, DefinitionProvider, DocumentColorProvider, DocumentFormattingEditProvider, DocumentHighlightProvider, DocumentOnDropEditProvider, DocumentPasteEditProvider, DocumentRangeFormattingEditProvider, DocumentRangeSemanticTokensProvider, DocumentSemanticTokensProvider, DocumentSymbolProvider, EvaluatableExpressionProvider, FoldingRangeProvider, HoverProvider, ImplementationProvider, InlayHintsProvider, InlineCompletionsProvider, InlineValuesProvider, LinkedEditingRangeProvider, LinkProvider, OnTypeFormattingEditProvider, ReferenceProvider, RenameProvider, SelectionRangeProvider, SignatureHelpProvider, TypeDefinitionProvider } from 'vs/editor/common/languages';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
export const ILanguageFeaturesService = createDecorator<ILanguageFeaturesService>('ILanguageFeaturesService');
@@ -25,6 +25,8 @@ export interface ILanguageFeaturesService {
readonly codeActionProvider: LanguageFeatureRegistry<CodeActionProvider>;
readonly documentPasteEditProvider: LanguageFeatureRegistry<DocumentPasteEditProvider>;
readonly renameProvider: LanguageFeatureRegistry<RenameProvider>;
readonly documentFormattingEditProvider: LanguageFeatureRegistry<DocumentFormattingEditProvider>;
@@ -5,7 +5,7 @@
import { URI } from 'vs/base/common/uri';
import { LanguageFeatureRegistry, NotebookInfo, NotebookInfoResolver } from 'vs/editor/common/languageFeatureRegistry';
import { CodeActionProvider, CodeLensProvider, CompletionItemProvider, DeclarationProvider, DefinitionProvider, DocumentColorProvider, DocumentFormattingEditProvider, DocumentHighlightProvider, DocumentOnDropEditProvider, DocumentRangeFormattingEditProvider, DocumentRangeSemanticTokensProvider, DocumentSemanticTokensProvider, DocumentSymbolProvider, EvaluatableExpressionProvider, FoldingRangeProvider, HoverProvider, ImplementationProvider, InlayHintsProvider, InlineCompletionsProvider, InlineValuesProvider, LinkedEditingRangeProvider, LinkProvider, OnTypeFormattingEditProvider, ReferenceProvider, RenameProvider, SelectionRangeProvider, SignatureHelpProvider, TypeDefinitionProvider } from 'vs/editor/common/languages';
import { CodeActionProvider, CodeLensProvider, CompletionItemProvider, DocumentPasteEditProvider, DeclarationProvider, DefinitionProvider, DocumentColorProvider, DocumentFormattingEditProvider, DocumentHighlightProvider, DocumentOnDropEditProvider, DocumentRangeFormattingEditProvider, DocumentRangeSemanticTokensProvider, DocumentSemanticTokensProvider, DocumentSymbolProvider, EvaluatableExpressionProvider, FoldingRangeProvider, HoverProvider, ImplementationProvider, InlayHintsProvider, InlineCompletionsProvider, InlineValuesProvider, LinkedEditingRangeProvider, LinkProvider, OnTypeFormattingEditProvider, ReferenceProvider, RenameProvider, SelectionRangeProvider, SignatureHelpProvider, TypeDefinitionProvider } from 'vs/editor/common/languages';
import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
@@ -41,6 +41,7 @@ export class LanguageFeaturesService implements ILanguageFeaturesService {
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 documentPasteEditProvider = new LanguageFeatureRegistry<DocumentPasteEditProvider>(this._score.bind(this));
private _notebookTypeResolver?: NotebookInfoResolver;
@@ -0,0 +1,25 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { registerEditorContribution } from 'vs/editor/browser/editorExtensions';
import { editorConfigurationBaseNode } from 'vs/editor/common/config/editorConfigurationSchema';
import { CopyPasteController } from 'vs/editor/contrib/copyPaste/browser/copyPasteController';
import * as nls from 'vs/nls';
import { ConfigurationScope, Extensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry';
import { Registry } from 'vs/platform/registry/common/platform';
registerEditorContribution(CopyPasteController.ID, CopyPasteController);
Registry.as<IConfigurationRegistry>(Extensions.Configuration).registerConfiguration({
...editorConfigurationBaseNode,
properties: {
'editor.experimental.pasteActions.enabled': {
type: 'boolean',
scope: ConfigurationScope.LANGUAGE_OVERRIDABLE,
description: nls.localize('pasteActions', "Enable/disable running edits from extensions on paste."),
default: false,
},
}
});
@@ -0,0 +1,195 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { addDisposableListener } from 'vs/base/browser/dom';
import { CancelablePromise, createCancelablePromise } from 'vs/base/common/async';
import { CancellationToken } from 'vs/base/common/cancellation';
import { VSDataTransfer } from 'vs/base/common/dataTransfer';
import { Disposable } from 'vs/base/common/lifecycle';
import { Mimes } from 'vs/base/common/mime';
import { generateUuid } from 'vs/base/common/uuid';
import { toVSDataTransfer } from 'vs/editor/browser/dnd';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { IBulkEditService, ResourceEdit, ResourceTextEdit } from 'vs/editor/browser/services/bulkEditService';
import { Selection } from 'vs/editor/common/core/selection';
import { IEditorContribution } from 'vs/editor/common/editorCommon';
import { DocumentPasteEditProvider, SnippetTextEdit, WorkspaceEdit } from 'vs/editor/common/languages';
import { ITextModel } from 'vs/editor/common/model';
import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures';
import { CodeEditorStateFlag, EditorStateCancellationTokenSource } from 'vs/editor/contrib/editorState/browser/editorState';
import { performSnippetEdit } from 'vs/editor/contrib/snippet/browser/snippetController2';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
const vscodeClipboardMime = 'application/vnd.code.copyId';
class DefaultPasteEditProvider implements DocumentPasteEditProvider {
async provideDocumentPasteEdits(model: ITextModel, selection: Selection, dataTransfer: VSDataTransfer, _token: CancellationToken): Promise<WorkspaceEdit | undefined> {
const textDataTransfer = dataTransfer.get(Mimes.text) ?? dataTransfer.get('text');
if (textDataTransfer) {
const text = await textDataTransfer.asString();
return {
edits: [new ResourceTextEdit(model.uri, { range: selection, text })]
};
}
return undefined;
}
}
export class CopyPasteController extends Disposable implements IEditorContribution {
public static readonly ID = 'editor.contrib.copyPasteActionController';
public static get(editor: ICodeEditor): CopyPasteController {
return editor.getContribution<CopyPasteController>(CopyPasteController.ID)!;
}
private readonly _editor: ICodeEditor;
private _currentClipboardItem: undefined | {
readonly handle: string;
readonly dataTransferPromise: CancelablePromise<VSDataTransfer>;
};
constructor(
editor: ICodeEditor,
@IBulkEditService private readonly _bulkEditService: IBulkEditService,
@IClipboardService private readonly _clipboardService: IClipboardService,
@IConfigurationService private readonly _configurationService: IConfigurationService,
@ILanguageFeaturesService private readonly _languageFeaturesService: ILanguageFeaturesService,
) {
super();
this._editor = editor;
this._languageFeaturesService.documentPasteEditProvider.register('*', new DefaultPasteEditProvider());
const container = editor.getContainerDomNode();
this._register(addDisposableListener(container, 'copy', (e: ClipboardEvent) => {
if (!e.clipboardData) {
return;
}
const model = editor.getModel();
const selection = this._editor.getSelection();
if (!model || !selection) {
return;
}
if (!this.arePasteActionsEnabled(model)) {
return;
}
const providers = this._languageFeaturesService.documentPasteEditProvider.ordered(model).filter(x => !!x.prepareDocumentPaste);
if (!providers.length) {
return;
}
const dataTransfer = toVSDataTransfer(e.clipboardData);
// Save off a handle pointing to data that VS Code maintains.
const handle = generateUuid();
e.clipboardData.setData(vscodeClipboardMime, handle);
const promise = createCancelablePromise(async token => {
const results = await Promise.all(providers.map(provider => {
return provider.prepareDocumentPaste!(model, selection, dataTransfer, token);
}));
for (const result of results) {
result?.forEach((value, key) => {
dataTransfer.set(key, value);
});
}
return dataTransfer;
});
this._currentClipboardItem?.dataTransferPromise.cancel();
this._currentClipboardItem = { handle: handle, dataTransferPromise: promise };
}));
this._register(addDisposableListener(container, 'paste', async (e: ClipboardEvent) => {
const selection = this._editor.getSelection();
if (!e.clipboardData || !selection || !editor.hasModel()) {
return;
}
const model = editor.getModel();
if (!this.arePasteActionsEnabled(model)) {
return;
}
const originalDocVersion = model.getVersionId();
const providers = this._languageFeaturesService.documentPasteEditProvider.ordered(model);
if (!providers.length) {
return;
}
const handle = e.clipboardData?.getData(vscodeClipboardMime);
if (typeof handle !== 'string') {
return;
}
e.preventDefault();
e.stopImmediatePropagation();
const tokenSource = new EditorStateCancellationTokenSource(editor, CodeEditorStateFlag.Value | CodeEditorStateFlag.Selection);
try {
const dataTransfer = toVSDataTransfer(e.clipboardData);
if (handle && this._currentClipboardItem?.handle === handle) {
const toMergeDataTransfer = await this._currentClipboardItem.dataTransferPromise;
toMergeDataTransfer.forEach((value, key) => {
dataTransfer.set(key, value);
});
}
if (!dataTransfer.has(Mimes.uriList)) {
const resources = await this._clipboardService.readResources();
if (resources.length) {
const value = resources.join('\n');
dataTransfer.set(Mimes.uriList, {
value,
asString: async () => value,
asFile: () => undefined,
});
}
}
dataTransfer.delete(vscodeClipboardMime);
for (const provider of providers) {
const edit = await provider.provideDocumentPasteEdits(model, selection, dataTransfer, tokenSource.token);
if (originalDocVersion !== model.getVersionId()) {
return;
}
if (edit) {
if ((edit as WorkspaceEdit).edits) {
await this._bulkEditService.apply(ResourceEdit.convert(edit as WorkspaceEdit), { editor });
} else {
performSnippetEdit(editor, edit as SnippetTextEdit);
}
return;
}
}
} finally {
tokenSource.dispose();
}
}, true));
}
public arePasteActionsEnabled(model: ITextModel): boolean {
return this._configurationService.getValue('editor.experimental.pasteActions.enabled', {
resource: model.uri
});
}
}
@@ -121,10 +121,8 @@ export class DropIntoEditorController extends Disposable implements IEditorContr
.map(input => input.resource!.toString());
if (editorData.length) {
const added = new VSDataTransfer();
const str = distinct(editorData).join('\n');
added.setString(Mimes.uriList.toLowerCase(), str);
return added;
textEditorDataTransfer.setString(Mimes.uriList.toLowerCase(), str);
}
}
@@ -188,3 +186,4 @@ class DefaultOnDropProvider implements DocumentOnDropEditProvider {
registerEditorContribution(DropIntoEditorController.ID, DropIntoEditorController);
@@ -451,11 +451,11 @@ export class SuggestController implements IEditorContribution {
type AcceptedSuggestionClassification = {
owner: 'jrieken';
comment: 'Information accepting completion items';
providerId: { classification: 'PublicNonPersonalData'; purpose: 'FeatureInsight'; comments: 'Provider of the completions item' };
basenameHash: { classification: 'PublicNonPersonalData'; purpose: 'FeatureInsight'; comments: 'Hash of the basename of the file into which the completion was inserted' };
fileExtension: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comments: 'File extension of the file into which the completion was inserted' };
languageId: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comments: 'Language type of the file into which the completion was inserted' };
kind: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comments: 'The completion item kind' };
providerId: { classification: 'PublicNonPersonalData'; purpose: 'FeatureInsight'; comment: 'Provider of the completions item' };
basenameHash: { classification: 'PublicNonPersonalData'; purpose: 'FeatureInsight'; comment: 'Hash of the basename of the file into which the completion was inserted' };
fileExtension: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'File extension of the file into which the completion was inserted' };
languageId: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'Language type of the file into which the completion was inserted' };
kind: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The completion item kind' };
};
// _debugDisplayName looks like `vscode.css-language-features(/-:)`, where the last bit is the trigger chars
// normalize it to just the extension ID and lowercase
+1
View File
@@ -15,6 +15,7 @@ import 'vs/editor/contrib/clipboard/browser/clipboard';
import 'vs/editor/contrib/codeAction/browser/codeActionContributions';
import 'vs/editor/contrib/codelens/browser/codelensController';
import 'vs/editor/contrib/colorPicker/browser/colorContributions';
import 'vs/editor/contrib/copyPaste/browser/copyPasteContribution';
import 'vs/editor/contrib/comment/browser/comment';
import 'vs/editor/contrib/contextmenu/browser/contextmenu';
import 'vs/editor/contrib/cursorUndo/browser/cursorUndo';