From 234228971c910c5f2d4e9b559e74f473c43379c6 Mon Sep 17 00:00:00 2001 From: manishb Date: Sun, 22 Jul 2018 17:53:08 -0400 Subject: [PATCH 1/2] Improve foldfix performance and potentially fix some bugs --- src/actions/motion.ts | 59 ++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/src/actions/motion.ts b/src/actions/motion.ts index 61ebc3da38e..c8dadd90385 100644 --- a/src/actions/motion.ts +++ b/src/actions/motion.ts @@ -260,25 +260,33 @@ class MoveDownFoldFix extends MoveByScreenLineMaintainDesiredColumn { value = 1; public async execAction(position: Position, vimState: VimState): Promise { - if (position.line === TextEditor.getLineCount() - 1) { + if (position.line >= TextEditor.getLineCount() - 1) { return position; } - let t: Position; - let count = 0; + let t: Position | IMovement; + let prevLine: number = position.line; + let prevChar: number = position.character; const prevDesiredColumn = vimState.desiredColumn; + const moveDownByScreenLine = new MoveDownByScreenLine(); do { - t = await new MoveDownByScreenLine().execAction(position, vimState); - count += 1; + t = await moveDownByScreenLine.execAction(position, vimState); + t = t instanceof Position ? t : t.stop; + const lineChanged = prevLine !== t.line; + // wrappedLine movement goes to eol character only when at the last line + // thus a column change on wrappedLine movement represents a visual last line + const colChanged = prevChar !== t.character; + if (lineChanged || !colChanged) { + break; + } + prevChar = t.character; + prevLine = t.line; } while (t.line === position.line); - if (t.line > position.line + 1) { - return t; - } - while (count > 0) { - t = await new MoveUpByScreenLine().execAction(position, vimState); - count--; + // fix column change at last line caused by wrappedLine movement + // causes cursor lag and flicker if a large repeat prefix is given to movement + if (t.character !== prevDesiredColumn) { + t = new Position(t.line, prevDesiredColumn); } - vimState.desiredColumn = prevDesiredColumn; - return await position.getDown(vimState.desiredColumn); + return t; } } @@ -339,26 +347,19 @@ class MoveUpFoldFix extends MoveByScreenLineMaintainDesiredColumn { if (position.line === 0) { return position; } - let t: Position; + let t: Position | IMovement; const prevDesiredColumn = vimState.desiredColumn; - let count = 0; - + const moveUpByScreenLine = new MoveUpByScreenLine(); do { - t = ( - await new MoveUpByScreenLineMaintainDesiredColumn().execAction(position, vimState) - ); - count += 1; + t = await moveUpByScreenLine.execAction(position, vimState); + t = t instanceof Position ? t : t.stop; } while (t.line === position.line); - vimState.desiredColumn = prevDesiredColumn; - if (t.line < position.line - 1) { - return t; - } - while (count > 0) { - t = await new MoveDownByScreenLine().execAction(position, vimState); - count--; + // fix column change at last line caused by wrappedLine movement + // causes cursor lag and flicker if a large repeat prefix is given to movement + if (t.character !== prevDesiredColumn) { + t = new Position(t.line, prevDesiredColumn); } - vimState.desiredColumn = prevDesiredColumn; - return await position.getUp(vimState.desiredColumn); + return t; } } From 3e4fa9cac8bb3e1bdf0e07a32b1df811c25e87ab Mon Sep 17 00:00:00 2001 From: manishb Date: Sun, 22 Jul 2018 17:53:08 -0400 Subject: [PATCH 2/2] Improve foldfix performance and potentially fix some bugs(#1855 #2163) --- src/actions/motion.ts | 59 ++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/src/actions/motion.ts b/src/actions/motion.ts index 61ebc3da38e..c8dadd90385 100644 --- a/src/actions/motion.ts +++ b/src/actions/motion.ts @@ -260,25 +260,33 @@ class MoveDownFoldFix extends MoveByScreenLineMaintainDesiredColumn { value = 1; public async execAction(position: Position, vimState: VimState): Promise { - if (position.line === TextEditor.getLineCount() - 1) { + if (position.line >= TextEditor.getLineCount() - 1) { return position; } - let t: Position; - let count = 0; + let t: Position | IMovement; + let prevLine: number = position.line; + let prevChar: number = position.character; const prevDesiredColumn = vimState.desiredColumn; + const moveDownByScreenLine = new MoveDownByScreenLine(); do { - t = await new MoveDownByScreenLine().execAction(position, vimState); - count += 1; + t = await moveDownByScreenLine.execAction(position, vimState); + t = t instanceof Position ? t : t.stop; + const lineChanged = prevLine !== t.line; + // wrappedLine movement goes to eol character only when at the last line + // thus a column change on wrappedLine movement represents a visual last line + const colChanged = prevChar !== t.character; + if (lineChanged || !colChanged) { + break; + } + prevChar = t.character; + prevLine = t.line; } while (t.line === position.line); - if (t.line > position.line + 1) { - return t; - } - while (count > 0) { - t = await new MoveUpByScreenLine().execAction(position, vimState); - count--; + // fix column change at last line caused by wrappedLine movement + // causes cursor lag and flicker if a large repeat prefix is given to movement + if (t.character !== prevDesiredColumn) { + t = new Position(t.line, prevDesiredColumn); } - vimState.desiredColumn = prevDesiredColumn; - return await position.getDown(vimState.desiredColumn); + return t; } } @@ -339,26 +347,19 @@ class MoveUpFoldFix extends MoveByScreenLineMaintainDesiredColumn { if (position.line === 0) { return position; } - let t: Position; + let t: Position | IMovement; const prevDesiredColumn = vimState.desiredColumn; - let count = 0; - + const moveUpByScreenLine = new MoveUpByScreenLine(); do { - t = ( - await new MoveUpByScreenLineMaintainDesiredColumn().execAction(position, vimState) - ); - count += 1; + t = await moveUpByScreenLine.execAction(position, vimState); + t = t instanceof Position ? t : t.stop; } while (t.line === position.line); - vimState.desiredColumn = prevDesiredColumn; - if (t.line < position.line - 1) { - return t; - } - while (count > 0) { - t = await new MoveDownByScreenLine().execAction(position, vimState); - count--; + // fix column change at last line caused by wrappedLine movement + // causes cursor lag and flicker if a large repeat prefix is given to movement + if (t.character !== prevDesiredColumn) { + t = new Position(t.line, prevDesiredColumn); } - vimState.desiredColumn = prevDesiredColumn; - return await position.getUp(vimState.desiredColumn); + return t; } }