diff --git a/src/actions/commands/actions.ts b/src/actions/commands/actions.ts index d42b26133..e004efb18 100644 --- a/src/actions/commands/actions.ts +++ b/src/actions/commands/actions.ts @@ -1411,14 +1411,18 @@ export class PutCommand extends BaseCommand { .join('\n'); } - if (after) { + if (register.registerMode === RegisterMode.LineWise) { // P insert before current line - textToAdd = text + '\n'; - whereToAddText = dest.getLineBegin(); + if (after) { + textToAdd = text + '\n'; + whereToAddText = dest.getLineBegin(); + } else { + textToAdd = '\n' + text; + whereToAddText = dest.getLineEnd(); + } } else { - // p paste after current line - textToAdd = '\n' + text; - whereToAddText = dest.getLineEnd(); + textToAdd = text; + whereToAddText = after ? position : position.getRight(); } } @@ -1470,10 +1474,20 @@ export class PutCommand extends BaseCommand { } else { if (text.indexOf('\n') === -1) { if (!position.isLineEnd()) { - if (after) { - diff = new PositionDiff(0, -1); + if ( + register.registerMode === RegisterMode.BlockWise + ) { + if (after) { + diff = new PositionDiff(0, -1 * text.length); + } else { + diff = new PositionDiff(0, 1); + } } else { - diff = new PositionDiff(0, textToAdd.length); + if (after) { + diff = new PositionDiff(0, -1); + } else { + diff = new PositionDiff(0, textToAdd.length); + } } } } else { @@ -3604,7 +3618,10 @@ class ActionXVisualBlock extends BaseCommand { } public async exec(position: Position, vimState: VimState): Promise { - for (const { start, end } of Position.IterateLine(vimState)) { + const lines: string[] = []; + + for (const { line, start, end } of Position.IterateLine(vimState)) { + lines.push(line); vimState.recordedState.transformations.push({ type: 'deleteRange', range: new Range(start, end), @@ -3612,6 +3629,10 @@ class ActionXVisualBlock extends BaseCommand { }); } + const text = lines.length === 1 ? lines[0] : lines.join('\n'); + vimState.currentRegisterMode = RegisterMode.BlockWise; + Register.put(text, vimState, this.multicursorIndex); + const topLeft = VisualBlockMode.getTopLeftPosition( vimState.cursorPosition, vimState.cursorStartPosition diff --git a/src/actions/operator.ts b/src/actions/operator.ts index c6e106386..155f89715 100644 --- a/src/actions/operator.ts +++ b/src/actions/operator.ts @@ -648,10 +648,18 @@ export class YankVisualBlockMode extends BaseOperator { public async run(vimState: VimState, start: Position, end: Position): Promise { let toCopy: string = ''; + const isMultiline = start.line !== end.line; + for (const { line } of Position.IterateLine(vimState)) { - toCopy += line + '\n'; + if (isMultiline) { + toCopy += line + '\n'; + } else { + toCopy = line; + } } + vimState.currentRegisterMode = RegisterMode.BlockWise; + Register.put(toCopy, vimState, this.multicursorIndex); const numLinesYanked = toCopy.split('\n').length; diff --git a/test/operator/put.test.ts b/test/operator/put.test.ts index 169a2971a..8b4305b4c 100644 --- a/test/operator/put.test.ts +++ b/test/operator/put.test.ts @@ -44,4 +44,32 @@ suite('put operator', () => { keysPressed: '2yyjjpk', end: ['one', 'two', '|three', 'one', 'two', 'four'], }); + + newTest({ + title: 'test visual block single line yank p', + start: ['12|345'], + keysPressed: 'llyhp', + end: ['12|345345'], + }); + + newTest({ + title: 'test visual block single line yank P', + start: ['12|345'], + keysPressed: 'llyhP', + end: ['1|3452345'], + }); + + newTest({ + title: 'test visual block single line delete p', + start: ['12|345'], + keysPressed: 'lldhp', + end: ['1|3452'], + }); + + newTest({ + title: 'test visual block single line delete P', + start: ['12|345'], + keysPressed: 'lldhP', + end: ['|34512'], + }); });