-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
perf: optimize movement commands with count to execute instantly #9805
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
perf: optimize movement commands with count to execute instantly #9805
Conversation
Previously, movement commands with counts (e.g., 20j, 50k) would loop through each individual movement, causing visible lag and poor performance. This commit optimizes the four basic movement commands (j, k, h, l) by overriding execActionWithCount to calculate the target position directly instead of looping: - MoveDown (j): Calculates target line as current + count - MoveUp (k): Calculates target line as current - count - MoveLeft (h): Calculates target character with surrogate pair handling - MoveRight (l): Calculates target character with surrogate pair handling All special cases are preserved: - Interactive window history navigation - Foldfix mode compatibility - Operator context (d20j, y10k work correctly) - Visual mode selections - Column preservation for vertical movements - Boundary checks (don't exceed document limits) Additionally fixed build issues: - Updated test/index.ts to use new glob API (async/await) - Added skipLibCheck to tsconfig.json for node_modules compatibility - Added ignoreDeprecations: "6.0" to silence baseUrl warning Fixes VSCodeVim#8557
test/index.ts
Outdated
| } catch (err) { | ||
| throw err; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any point to catching an error just to throw it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch! You're absolutely right. The outer try-catch was just re-throwing the error without adding any value. I've removed it - the inner try-catch around mocha.run() is sufficient to handle errors and propagate them to the Promise.
| return position.getDown(); | ||
| } | ||
|
|
||
| public override async execActionWithCount( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For each of these, can't we make the implementation of execAction simply execActionWithCount(..., 1)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Excellent suggestion! I've refactored execAction to simply delegate to execActionWithCount(position, vimState, 1). This eliminates code duplication and centralizes the logic in one place. The method now returns Promise<Position> (with a cast) since execActionWithCount with count=1 always returns a Position in practice, never an IMovement.
| "strict": true, | ||
| "useUnknownInCatchVariables": false, | ||
| "experimentalDecorators": true, | ||
| "ignoreDeprecations": "6.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's this for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was added to suppress a TypeScript compilation error. The baseUrl option (line 16) is deprecated in TypeScript 6.0+ and will be removed in TypeScript 7.0. Without ignoreDeprecations, we get a build error.
The baseUrl is currently needed for the paths mapping ("platform/*": ["src/platform/node/*"]). Ideally, we should migrate away from baseUrl/paths to the new recommended approach, but that would be a larger refactoring outside the scope of this performance optimization.
Should I remove this and open a separate issue to track the TypeScript 7.0 migration, or is it OK to keep it for now?
- Remove unnecessary outer try-catch in test/index.ts - Simplify MoveDown.execAction by delegating to execActionWithCount - Keep ignoreDeprecations in tsconfig.json (required for baseUrl deprecation warning)"
What this PR does / why we need it:
Previously, movement commands with counts (e.g., 20j, 50k) would loop through each individual movement, causing visible lag and poor performance. This made the extension feel sluggish compared to native Vim, especially with large count values.
This PR optimizes the four basic movement commands (j, k, h, l) by overriding
execActionWithCountto calculate the target position directly instead of looping:All special cases are preserved:
Which issue(s) this PR fixes
Fixes #8557
Special notes for your reviewer:
Additionally fixed build issues encountered during development:
test/index.tsto use new glob API (async/await pattern)skipLibChecktotsconfig.jsonfor node_modules compatibilityignoreDeprecations: "6.0"to silence baseUrl warningThe optimization provides instant cursor movement for any count value, matching native Vim's performance. Tested on Windows 10 and Ubuntu 22.04 with various count values (1-200) in Normal, Visual, and Operator-pending modes.
Note:
Those changes were made by GitHub Copilot, using Claude Sonnet 4.5 agent