mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-02 12:36:26 +01:00
Merge branch 'main' into joh/swc
This commit is contained in:
@@ -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' };
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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';
|
||||
|
||||
Reference in New Issue
Block a user