diff --git a/src/vs/editor/contrib/dropOrPasteInto/browser/copyPasteController.ts b/src/vs/editor/contrib/dropOrPasteInto/browser/copyPasteController.ts index acffc02602d..4a5da94b99f 100644 --- a/src/vs/editor/contrib/dropOrPasteInto/browser/copyPasteController.ts +++ b/src/vs/editor/contrib/dropOrPasteInto/browser/copyPasteController.ts @@ -378,7 +378,6 @@ export class CopyPasteController extends Disposable implements IEditorContributi }, () => p); } - private setCopyMetadata(dataTransfer: DataTransfer, metadata: CopyMetadata) { dataTransfer.setData(vscodeClipboardMime, JSON.stringify(metadata)); } diff --git a/src/vs/editor/contrib/dropOrPasteInto/browser/edit.ts b/src/vs/editor/contrib/dropOrPasteInto/browser/edit.ts index e7b42fe7843..55d8dff9e7b 100644 --- a/src/vs/editor/contrib/dropOrPasteInto/browser/edit.ts +++ b/src/vs/editor/contrib/dropOrPasteInto/browser/edit.ts @@ -7,6 +7,7 @@ import { URI } from 'vs/base/common/uri'; import { ResourceTextEdit } from 'vs/editor/browser/services/bulkEditService'; import { DropYieldTo, WorkspaceEdit } from 'vs/editor/common/languages'; import { Range } from 'vs/editor/common/core/range'; +import { SnippetParser } from 'vs/editor/contrib/snippet/browser/snippetParser'; export interface DropOrPasteEdit { readonly label: string; @@ -14,14 +15,23 @@ export interface DropOrPasteEdit { readonly additionalEdit?: WorkspaceEdit; } +/** + * 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: DropOrPasteEdit): WorkspaceEdit { + // If the edit insert text is empty, skip applying at each range + if (typeof edit.insertText === 'string' ? edit.insertText === '' : edit.insertText.snippet === '') { + return { + edits: edit.additionalEdit?.edits ?? [] + }; + } + return { edits: [ ...ranges.map(range => new ResourceTextEdit(uri, - typeof edit.insertText === 'string' - ? { range, text: edit.insertText, insertAsSnippet: false } - : { range, text: edit.insertText.snippet, insertAsSnippet: true } + { range, text: typeof edit.insertText === 'string' ? SnippetParser.escape(edit.insertText) + '$0' : edit.insertText.snippet, insertAsSnippet: true } )), ...(edit.additionalEdit?.edits ?? []) ] diff --git a/src/vs/editor/contrib/dropOrPasteInto/browser/postEditWidget.ts b/src/vs/editor/contrib/dropOrPasteInto/browser/postEditWidget.ts index af54bdbf846..97287e46c5f 100644 --- a/src/vs/editor/contrib/dropOrPasteInto/browser/postEditWidget.ts +++ b/src/vs/editor/contrib/dropOrPasteInto/browser/postEditWidget.ts @@ -11,10 +11,11 @@ import { Event } from 'vs/base/common/event'; import { Disposable, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle'; import 'vs/css!./postEditWidget'; import { ContentWidgetPositionPreference, ICodeEditor, IContentWidget, IContentWidgetPosition } from 'vs/editor/browser/editorBrowser'; -import { IBulkEditResult, IBulkEditService, ResourceTextEdit } from 'vs/editor/browser/services/bulkEditService'; +import { IBulkEditResult, IBulkEditService } from 'vs/editor/browser/services/bulkEditService'; import { Range } from 'vs/editor/common/core/range'; import { WorkspaceEdit } 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'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -166,25 +167,7 @@ export class PostEditWidgetManager extends Disposable { return; } - let insertTextEdit: ResourceTextEdit[] = []; - if (typeof edit.insertText === 'string' ? edit.insertText === '' : edit.insertText.snippet === '') { - insertTextEdit = []; - } else { - insertTextEdit = ranges.map(range => new ResourceTextEdit(model.uri, - typeof edit.insertText === 'string' - ? { range, text: edit.insertText, insertAsSnippet: false } - : { range, text: edit.insertText.snippet, insertAsSnippet: true } - )); - } - - const allEdits = [ - ...insertTextEdit, - ...(edit.additionalEdit?.edits ?? []) - ]; - - const combinedWorkspaceEdit: WorkspaceEdit = { - edits: allEdits - }; + const combinedWorkspaceEdit = createCombinedWorkspaceEdit(model.uri, ranges, edit); // Use a decoration to track edits around the trigger range const primaryRange = ranges[0];