-
-
Notifications
You must be signed in to change notification settings - Fork 505
Use formatWithCursor() to preserve cursor position #3945
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: main
Are you sure you want to change the base?
Conversation
6dc6c19 to
16a3a3f
Compare
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.
Pull request overview
This PR implements cursor position preservation during document formatting by utilizing Prettier's formatWithCursor() API instead of the regular format() method. This addresses issue #3939 where the cursor would jump to an arbitrary position after formatting.
Changes:
- Added
formatWithCursormethod to Prettier type interfaces and implementations - Updated the formatting service to capture cursor position before formatting and restore it afterward
- Properly handles edge cases like range formatting where cursor preservation doesn't apply
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/types.ts | Added PrettierCursorOptions and PrettierCursorResult type exports; added formatWithCursor method to PrettierInstance and PrettierModule interfaces |
| src/PrettierDynamicInstance.ts | Implemented formatWithCursor method that delegates to the underlying Prettier module |
| src/ModuleResolverWeb.ts | Added formatWithCursor support for browser/web extension |
| src/PrettierEditService.ts | Updated formatting logic to use formatWithCursor() when cursor offset is available; added cursor repositioning logic using setImmediate |
| !isRangeFormatting && | ||
| result.cursorOffset >= 0 | ||
| ) { | ||
| setImmediate(() => { |
Copilot
AI
Jan 21, 2026
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.
The setImmediate function is not available in browser environments, but this extension supports both Node.js and browser contexts (as indicated by the "browser" field in package.json). This will cause a runtime error when the extension runs in vscode.dev or other browser-based VS Code instances.
Consider using setTimeout(() => {...}, 0) instead, which works in both Node.js and browser environments and provides similar behavior of deferring execution to the next event loop tick.
| // Schedule cursor repositioning after VS Code applies the edit | ||
| // We use setImmediate to run after the current event loop completes | ||
| if ( | ||
| editor && | ||
| editor.document === document && | ||
| !isRangeFormatting && | ||
| result.cursorOffset >= 0 | ||
| ) { | ||
| setImmediate(() => { | ||
| // Verify the editor is still active and document hasn't changed | ||
| if ( | ||
| window.activeTextEditor === editor && | ||
| editor.document === document | ||
| ) { | ||
| const newPosition = document.positionAt(result.cursorOffset); | ||
| editor.selection = new Selection(newPosition, newPosition); | ||
| } | ||
| }); | ||
| } |
Copilot
AI
Jan 21, 2026
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.
The new cursor position preservation feature lacks test coverage. Consider adding a test that:
- Opens a document with unformatted code
- Places the cursor at a specific position
- Triggers formatting
- Verifies the cursor is at the expected position in the formatted output
This is especially important since this feature involves timing-sensitive operations with setImmediate and the interaction between VS Code's edit application and cursor repositioning.
Previously, the extension used Prettier's format() API which caused the cursor to jump to an arbitrary position after formatting. This change uses Prettier's formatWithCursor() API to preserve the cursor position. Changes: - Add formatWithCursor to PrettierInstance and PrettierModule interfaces - Implement formatWithCursor in PrettierDynamicInstance - Add formatWithCursor to ModuleResolverWeb for browser support - Update PrettierEditService to use formatWithCursor when cursor position is available, and schedule cursor repositioning after VS Code applies the edit Fixes #3939 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
16a3a3f to
15e68cf
Compare
Summary
formatWithCursor()API instead offormat()to preserve cursor position after formattingChanges
PrettierCursorOptionsandPrettierCursorResulttype exports, and addedformatWithCursormethod toPrettierInstanceandPrettierModuleinterfacesformatWithCursormethod that delegates to the underlying Prettier moduleformatWithCursorsupport for the browser/web extensionformat()to optionally useformatWithCursor()when a cursor offset is availableprovideEdits()to capture cursor position before formatting and schedule cursor repositioning after VS Code applies the editTest plan
Fixes #3939
Generated with Claude Code