From 5cb086348faf9a17b99e005f0a71710d77727736 Mon Sep 17 00:00:00 2001 From: Elliot Roberts Date: Thu, 10 Aug 2023 07:30:06 -0700 Subject: [PATCH 1/2] add tests for VSCode auto-surround handling --- test/mode/modeInsert.test.ts | 44 ++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/test/mode/modeInsert.test.ts b/test/mode/modeInsert.test.ts index cb385351768..397734bbe65 100644 --- a/test/mode/modeInsert.test.ts +++ b/test/mode/modeInsert.test.ts @@ -625,4 +625,48 @@ suite('Mode Insert', () => { endMode: Mode.Insert, }); }); + + suite('VSCode auto-surround', () => { + test('preserves selection', async () => { + await modeHandler.handleMultipleKeyEvents(['i', 's', 'e', 'l', 'e', 'c', 't']); + await vscode.commands.executeCommand('editor.action.selectAll'); + await modeHandler.handleKeyEvent('"'); + assertEqualLines(['"select"']); + assert.strictEqual(modeHandler.currentMode, Mode.Insert); + assert.strictEqual(vscode.window.activeTextEditor!.selection.start.character, 1); + assert.strictEqual(vscode.window.activeTextEditor!.selection.end.character, 7); + }); + + test('replaces selection', async () => { + await modeHandler.handleMultipleKeyEvents(['i', 't', 'e', 'm', 'p']); + await vscode.commands.executeCommand('editor.action.selectAll'); + await modeHandler.handleMultipleKeyEvents(['"', 'f', 'i', 'n', 'a', 'l']); + assertEqualLines(['"final"']); + assert.strictEqual(modeHandler.currentMode, Mode.Insert); + assert.strictEqual(vscode.window.activeTextEditor!.selection.start.character, 6); + assert.strictEqual(vscode.window.activeTextEditor!.selection.end.character, 6); + }); + + test('stacks', async () => { + await modeHandler.handleMultipleKeyEvents(['i', 't', 'e', 'x', 't']); + await vscode.commands.executeCommand('editor.action.selectAll'); + + await modeHandler.handleMultipleKeyEvents(['"', "'", '(', '[', '{', '<', '`']); + assertEqualLines(['"\'([{<`text`>}])\'"']); + }); + + test('handles snippet', async () => { + await modeHandler.handleKeyEvent('i'); + await vscode.commands.executeCommand('editor.action.insertSnippet', { + snippet: '${3:foo} ${1:bar} ${2:baz}', + }); + await modeHandler.handleMultipleKeyEvents(['(', 'o', 'n', 'e']); + await vscode.commands.executeCommand('jumpToNextSnippetPlaceholder'); + await modeHandler.handleMultipleKeyEvents(['<', 't', 'w', 'o']); + await vscode.commands.executeCommand('jumpToNextSnippetPlaceholder'); + await modeHandler.handleKeyEvent('`'); + assertEqualLines(['`foo` (one) ']); + assert.strictEqual(modeHandler.currentMode, Mode.Insert); + }); + }); }); From ccd9c86ec8a0a1b915ad6bd330ef7da45d8885ca Mon Sep 17 00:00:00 2001 From: Elliot Roberts Date: Thu, 10 Aug 2023 09:04:42 -0700 Subject: [PATCH 2/2] fix handling VSCode auto-surrounding selections --- src/mode/modeHandler.ts | 4 ++++ src/transformations/execute.ts | 20 +++++++++++++------- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/mode/modeHandler.ts b/src/mode/modeHandler.ts index 81a9447798b..0748c24b767 100644 --- a/src/mode/modeHandler.ts +++ b/src/mode/modeHandler.ts @@ -1272,6 +1272,10 @@ export class ModeHandler implements vscode.Disposable, IModeHandler { } break; + case Mode.Insert: + // Don't collapse existing selections in insert mode + selections.push(new vscode.Selection(start, stop)); + break; default: // Note that this collapses the selection onto one position selections.push(new vscode.Selection(stop, stop)); diff --git a/src/transformations/execute.ts b/src/transformations/execute.ts index 6585c37540b..5c6fe9eb4e5 100644 --- a/src/transformations/execute.ts +++ b/src/transformations/execute.ts @@ -241,13 +241,19 @@ export async function executeTransformations( } } - const selections = vimState.editor.selections.map((sel) => { - let range = Cursor.FromVSCodeSelection(sel); - if (range.start.isBefore(range.stop)) { - range = range.withNewStop(range.stop.getLeftThroughLineBreaks(true)); - } - return new vscode.Selection(range.start, range.stop); - }); + let selections; + if (vimState.currentMode === Mode.Insert) { + // Insert mode selections do not need to be modified + selections = vimState.editor.selections; + } else { + selections = vimState.editor.selections.map((sel) => { + let range = Cursor.FromVSCodeSelection(sel); + if (range.start.isBefore(range.stop)) { + range = range.withNewStop(range.stop.getLeftThroughLineBreaks(true)); + } + return new vscode.Selection(range.start, range.stop); + }); + } const firstTransformation = transformations[0]; const manuallySetCursorPositions = (firstTransformation.type === 'deleteRange' ||