diff --git a/src/actions/commands/actions.ts b/src/actions/commands/actions.ts index f61e50ce4a2..ee59e552add 100644 --- a/src/actions/commands/actions.ts +++ b/src/actions/commands/actions.ts @@ -213,7 +213,7 @@ export abstract class BaseCommand extends BaseAction { // begin actions @RegisterAction -class CommandNumber extends BaseCommand { +export class CommandNumber extends BaseCommand { modes = [ModeName.Normal, ModeName.Visual, ModeName.VisualLine, ModeName.VisualBlock]; keys = [""]; isCompleteAction = false; diff --git a/src/actions/operator.ts b/src/actions/operator.ts index c82d7567d50..4d213b36a37 100644 --- a/src/actions/operator.ts +++ b/src/actions/operator.ts @@ -9,6 +9,7 @@ import { Configuration } from './../configuration/configuration'; import { BaseAction, RegisterAction, compareKeypressSequence } from './base'; +import { CommandNumber } from "./commands/actions"; export class BaseOperator extends BaseAction { constructor(multicursorIndex?: number) { @@ -48,8 +49,9 @@ export class BaseOperator extends BaseAction { } public doesRepeatedOperatorApply(vimState: VimState, keysPressed: string[]) { - const prevAction = vimState.recordedState.actionsRun[vimState.recordedState.actionsRun.length - 1]; - return this.isOperator && keysPressed.length === 1 && prevAction + const nonCountActions = vimState.recordedState.actionsRun.filter(x => !(x instanceof CommandNumber)); + const prevAction = nonCountActions[nonCountActions.length - 1]; + return this.isOperator && keysPressed.length === 1 && prevAction && this.modes.indexOf(vimState.currentMode) !== -1 // The previous action is the same as the one we're testing && prevAction.constructor === this.constructor @@ -741,14 +743,18 @@ class ActionVisualReflowParagraph extends BaseOperator { lines = [``, ``]; } + // This tracks if we're pushing the first line of a chunk. If so, then we + // don't want to add an extra space. In addition, when there's a blank + // line, this needs to be reset. + let curIndex = 0; for (const line of content.trim().split("\n")) { - // Preserve newlines. if (line.trim() === "") { for (let i = 0; i < 2; i++) { lines.push(``); } + curIndex = 0; continue; } @@ -760,15 +766,16 @@ class ActionVisualReflowParagraph extends BaseOperator { if (word === "") { continue; } if (lines[lines.length - 1].length + word.length + 1 < maximumLineLength) { - if (i) { - lines[lines.length - 1] += ` ${ word }`; + if (curIndex === 0 && i === 0) { + lines[lines.length - 1] += `${word}`; } else { - lines[lines.length - 1] += `${ word }`; + lines[lines.length - 1] += ` ${ word }`; } } else { lines.push(`${ word }`); } } + curIndex++; } if (!commentType.singleLine) { diff --git a/test/mode/modeNormal.test.ts b/test/mode/modeNormal.test.ts index 785a15cb55e..50ddce4c6ad 100644 --- a/test/mode/modeNormal.test.ts +++ b/test/mode/modeNormal.test.ts @@ -128,6 +128,13 @@ suite("Mode Normal", () => { end: ["one", "two", "|three"], }); + newTest({ + title: "Can handle d2d", + start: ['one', 'two', '|three', 'four', 'five'], + keysPressed: 'd2d', + end: ["one", "two", "|five"], + }); + newTest({ title: "Can handle dd empty line", start: ['one', '|', 'two'],