diff --git a/src/actions/motion.ts b/src/actions/motion.ts index 2eacb33aa34..c3cb9c38f7f 100755 --- a/src/actions/motion.ts +++ b/src/actions/motion.ts @@ -1968,6 +1968,21 @@ export abstract class MoveInsideCharacter extends ExpandingSelection { vimState.recordedState.operatorPositionDiff = openPos.subtract(selStart); } + // Adjust for VisualLine mode: exclude the line containing the closing brace + // moves the cursor back to just within the brackets, accurately mirroring what + // Vim does for Vi{ Vi( Vi[ etc. + if ( + !this.includeSurrounding && + vimState.currentMode === Mode.VisualLine && + closePos.line > openPos.line + ) { + const adjustedLine = closePos.line - 1; + if (adjustedLine >= 0) { + const lineText = vimState.document.lineAt(adjustedLine).text; + closePos = new Position(adjustedLine, lineText.length); + } + } + // TODO: setting the cursor manually like this shouldn't be necessary (probably a Cursor, not Position, should be passed to `exec`) vimState.cursorStartPosition = openPos; return { diff --git a/test/mode/modeVisualLine.test.ts b/test/mode/modeVisualLine.test.ts index 767783acf4f..afb2268aac9 100644 --- a/test/mode/modeVisualLine.test.ts +++ b/test/mode/modeVisualLine.test.ts @@ -3,7 +3,7 @@ import * as assert from 'assert'; import { getAndUpdateModeHandler } from '../../extension'; import { Mode } from '../../src/mode/mode'; import { ModeHandler } from '../../src/mode/modeHandler'; -import { newTest } from '../testSimplifier'; +import { newTest, newTestOnly } from '../testSimplifier'; import { assertEqualLines, setupWorkspace } from './../testUtils'; suite('Mode Visual Line', () => { @@ -585,4 +585,26 @@ suite('Mode Visual Line', () => { }); } }); + + suite('Vi{ should not select the ending brace, if it is on a new line.', () => { + test('Vi{ selection content test', async () => { + // Insert the full block using insert mode simulation + await modeHandler.handleMultipleKeyEvents('i{\nsome text on new line\n}'.split('')); + + // Back to normal mode + await modeHandler.handleKeyEvent(''); + + // Move cursor to start of "some text..." + await modeHandler.handleMultipleKeyEvents(['g', 'g', 'j', 'l', 'l', 'l', 'l']); + + // Simulate Vi{ + await modeHandler.handleMultipleKeyEvents(['V', 'i', '{']); + + const doc = modeHandler.vimState.editor.document; + const sel = modeHandler.vimState.editor.selection; + const selectedText = doc.getText(sel); + + assert.strictEqual(selectedText, ' some text on new line'); + }); + }); });