From ec9acc5ccdf46762c3dcee0847e9bd93bdd67009 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Tue, 10 Sep 2019 10:38:58 +0200 Subject: [PATCH] Introduce editor.multiCursorPaste (fixes #80624) --- src/vs/editor/common/config/editorOptions.ts | 19 ++++++++++++++++- .../editor/common/controller/cursorCommon.ts | 3 +++ .../common/controller/cursorTypeOperations.ts | 21 +++++++++++-------- src/vs/monaco.d.ts | 5 +++++ 4 files changed, 38 insertions(+), 10 deletions(-) diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 0317d84ba71..981597a1e91 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -258,7 +258,6 @@ export interface IEditorOptions { * Defaults to '.'. */ wordWrapBreakObtrusiveCharacters?: string; - /** * Performance guard: Stop rendering a line after x characters. * Defaults to 10000. @@ -303,6 +302,11 @@ export interface IEditorOptions { * Defaults to true */ multiCursorMergeOverlapping?: boolean; + /** + * Configure the behaviour when pasting a text with the line count equal to the cursor count. + * Defaults to 'spread'. + */ + multiCursorPaste?: 'spread' | 'full'; /** * Configure the editor's accessibility support. * Defaults to 'auto'. It is best to leave this to 'auto'. @@ -2671,6 +2675,7 @@ export const enum EditorOption { mouseWheelZoom, multiCursorMergeOverlapping, multiCursorModifier, + multiCursorPaste, occurrencesHighlight, overviewRulerBorder, overviewRulerLanes, @@ -2985,6 +2990,18 @@ export const EditorOptions = { }, "The modifier to be used to add multiple cursors with the mouse. The Go To Definition and Open Link mouse gestures will adapt such that they do not conflict with the multicursor modifier. [Read more](https://code.visualstudio.com/docs/editor/codebasics#_multicursor-modifier).") } )), + multiCursorPaste: register(new EditorStringEnumOption( + EditorOption.multiCursorPaste, 'multiCursorPaste', + 'spread' as 'spread' | 'full', + ['spread', 'full'] as const, + { + markdownEnumDescriptions: [ + nls.localize('multiCursorPaste.spread', "Each cursor pastes a single line of the text."), + nls.localize('multiCursorPaste.full', "Each cursor pastes the full text.") + ], + markdownDescription: nls.localize('multiCursorPaste', "Controls pasting when the line count of the pasted text matches the cursor count.") + } + )), occurrencesHighlight: register(new EditorBooleanOption( EditorOption.occurrencesHighlight, 'occurrencesHighlight', true, { description: nls.localize('occurrencesHighlight', "Controls whether the editor should highlight semantic symbol occurrences.") } diff --git a/src/vs/editor/common/controller/cursorCommon.ts b/src/vs/editor/common/controller/cursorCommon.ts index 168234965e9..5b074c3c4f7 100644 --- a/src/vs/editor/common/controller/cursorCommon.ts +++ b/src/vs/editor/common/controller/cursorCommon.ts @@ -97,6 +97,7 @@ export class CursorConfiguration { public readonly emptySelectionClipboard: boolean; public readonly copyWithSyntaxHighlighting: boolean; public readonly multiCursorMergeOverlapping: boolean; + public readonly multiCursorPaste: 'spread' | 'full'; public readonly autoClosingBrackets: EditorAutoClosingStrategy; public readonly autoClosingQuotes: EditorAutoClosingStrategy; public readonly autoClosingOvertype: EditorAutoClosingOvertypeStrategy; @@ -116,6 +117,7 @@ export class CursorConfiguration { || e.hasChanged(EditorOption.wordSeparators) || e.hasChanged(EditorOption.emptySelectionClipboard) || e.hasChanged(EditorOption.multiCursorMergeOverlapping) + || e.hasChanged(EditorOption.multiCursorPaste) || e.hasChanged(EditorOption.autoClosingBrackets) || e.hasChanged(EditorOption.autoClosingQuotes) || e.hasChanged(EditorOption.autoClosingOvertype) @@ -147,6 +149,7 @@ export class CursorConfiguration { this.emptySelectionClipboard = options.get(EditorOption.emptySelectionClipboard); this.copyWithSyntaxHighlighting = options.get(EditorOption.copyWithSyntaxHighlighting); this.multiCursorMergeOverlapping = options.get(EditorOption.multiCursorMergeOverlapping); + this.multiCursorPaste = options.get(EditorOption.multiCursorPaste); this.autoClosingBrackets = options.get(EditorOption.autoClosingBrackets); this.autoClosingQuotes = options.get(EditorOption.autoClosingQuotes); this.autoClosingOvertype = options.get(EditorOption.autoClosingOvertype); diff --git a/src/vs/editor/common/controller/cursorTypeOperations.ts b/src/vs/editor/common/controller/cursorTypeOperations.ts index bcf4d3ef83a..87be27f9a67 100644 --- a/src/vs/editor/common/controller/cursorTypeOperations.ts +++ b/src/vs/editor/common/controller/cursorTypeOperations.ts @@ -105,7 +105,7 @@ export class TypeOperations { }); } - private static _distributePasteToCursors(selections: Selection[], text: string, pasteOnNewLine: boolean, multicursorText: string[]): string[] | null { + private static _distributePasteToCursors(config: CursorConfiguration, selections: Selection[], text: string, pasteOnNewLine: boolean, multicursorText: string[]): string[] | null { if (pasteOnNewLine) { return null; } @@ -118,20 +118,23 @@ export class TypeOperations { return multicursorText; } - // Remove trailing \n if present - if (text.charCodeAt(text.length - 1) === CharCode.LineFeed) { - text = text.substr(0, text.length - 1); - } - let lines = text.split(/\r\n|\r|\n/); - if (lines.length === selections.length) { - return lines; + if (config.multiCursorPaste === 'spread') { + // Try to spread the pasted text in case the line count matches the cursor count + // Remove trailing \n if present + if (text.charCodeAt(text.length - 1) === CharCode.LineFeed) { + text = text.substr(0, text.length - 1); + } + let lines = text.split(/\r\n|\r|\n/); + if (lines.length === selections.length) { + return lines; + } } return null; } public static paste(config: CursorConfiguration, model: ICursorSimpleModel, selections: Selection[], text: string, pasteOnNewLine: boolean, multicursorText: string[]): EditOperationResult { - const distributedPaste = this._distributePasteToCursors(selections, text, pasteOnNewLine, multicursorText); + const distributedPaste = this._distributePasteToCursors(config, selections, text, pasteOnNewLine, multicursorText); if (distributedPaste) { selections = selections.sort(Range.compareRangesUsingStarts); diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index a89afc2c83e..52c82fe6d55 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -2704,6 +2704,11 @@ declare namespace monaco.editor { * Defaults to true */ multiCursorMergeOverlapping?: boolean; + /** + * Configure the behaviour when pasting a text with the line count equal to the cursor count. + * Defaults to 'spread'. + */ + multiCursorPaste?: 'spread' | 'full'; /** * Configure the editor's accessibility support. * Defaults to 'auto'. It is best to leave this to 'auto'.