Skip to content
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

Multicursor reformatting #2741

Merged
merged 9 commits into from
Mar 8, 2025

Conversation

pbwolf
Copy link
Contributor

@pbwolf pbwolf commented Mar 2, 2025

What has changed?

  • After a multicursor command, all cursors are preserved and all affected places are reformatted.
  • Consequently, Calva's user may issue one multicursor command after another, incrementally affecting the same bunch of cursors.

All commands that manipulate the document via DocumentModel are potentially affected, even commands that are not multicursor-capable. The single-cursor reformatting code path is just the base case of the multi-cursor code path, so it should be regarded as all-new despite the same underlying clj-format.

Extending auto-reformatting to multiple cursors changed the calculation of the region(s) to reformat. It may be that the region that gets reformatted after some commands will be benignly different from before, e.g., more extensive.

I did not add reformatting to the multicursor section of the paredit documentation, since it is not controlled by a setting.

Details:

  • Formatting preserves multiple cursors by inserting and removing individual runs of whitespace, instead of replacing a monolithic Clojure code block with a formatted version of the same. VS Code automatically adjusts each cursor as spaces are inserted or removed above it or to its left.
  • The user's cursors no longer relate directly to reformatting.
    1. One structural edit might be indicated by multiple cursors, perhaps arrayed at various points in the same list.
    2. Structural edits' blast radius ("formatDepth") may depend on the surroundings and one structural edit may differ from another in the same simultaneous bunch.
  • Regions to reformat are computed from the array of ModelEdits instead of from one cursor position and a formatDepth option. Specifically: DocumentModel.edit finds the bounds of the list enclosing each ModelEdit and translates those bounds to offsets in the expected post-edit document. (The heuristics are those used by Calva's unit test suite, which also tries to predict the net result of a bunch of ModelEdits.) After the edit transaction, DocumentModel.edit formats whatever forms are at those positions. "formatDepth" did not scale to multiple cursors and has been removed.
  • Reformatting is skipped if the document version number is greater than expected, a clue that VS Code interleaved two async commands.

Fixes #2738, #2737

My Calva PR Checklist

I have:

  • Read How to Contribute.
  • Directed this pull request at the dev branch. (Or have specific reasons to target some other branch.)
  • Made sure I have changed the PR base branch, so that it is not published. (Sorry for the nagging.)
  • Made sure there is an issue registered with a clear problem statement that this PR addresses, (created the issue if it was not present).
    • Updated the [Unreleased] entry in CHANGELOG.md, linking the issue(s) that the PR is addressing.
  • Figured if anything about the fix warrants tests on Mac/Linux/Windows/Remote/Whatever, and either tested it there if so, or mentioned it in the PR.
  • Added to or updated docs in this branch, if appropriate
  • Tests
    • Tested the particular change
    • Figured if the change might have some side effects and tested those as well.
  • Formatted all JavaScript and TypeScript code that was changed. (use the prettier extension or run npm run prettier-format)
  • Confirmed that there are no linter warnings or errors (use the eslint extension, run npm run eslint before creating your PR, or run npm run eslint-watch to eslint as you go).

Ping @PEZ, @bpringe, @corasaurus-hex, @Cyrik

Copy link

netlify bot commented Mar 2, 2025

Deploy Preview for calva-docs ready!

Name Link
🔨 Latest commit 6fab18a
🔍 Latest deploy log https://app.netlify.com/sites/calva-docs/deploys/67cb9f2a5464410008d8527b
😎 Deploy Preview https://deploy-preview-2741--calva-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Comment on lines 249 to 253
/** whitespace and substance. Pre-format and re-formatted text can be expressed
* as a series of SpacedUnit. The substance parts can be aligned and then
* changes in size can be translated to TextEdits.
*/
type SpacedUnit = [spaces: string, stuff: string];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is pretty awesome stuff! Looks lik some of it could be extracted into a module that doesn't need vscode and thus we could unit have unit tests?

@pbwolf pbwolf mentioned this pull request Mar 2, 2025
12 tasks
@PEZ
Copy link
Collaborator

PEZ commented Mar 4, 2025

Not sure if there's something else but the conflicts to fix here? I have been running with this branch for a few days and it is awesome. Don't think I've noticed anything that doesn't work.

@pbwolf
Copy link
Contributor Author

pbwolf commented Mar 4, 2025

This is pretty awesome stuff! Looks like some of it could be extracted into a module that doesn't need vscode and thus we could unit have unit tests?

Not sure if there's something else but the conflicts to fix here? I have been running with this branch for a few days and it is awesome. Don't think I've noticed anything that doesn't work.

Thank you for the notes. I aim to merge dev's recent advances and extract some unit-testable parts

@pbwolf
Copy link
Contributor Author

pbwolf commented Mar 8, 2025

Procedures that calculate whitespace adjustments are extracted to a new module and demonstrated with tests that check the text and cursor positions in the results. The cursor-position tests motivated some changes to the model of VS Code's implicit cursor adjustment after edits above or to the left of the cursor. The implicit behavior is described in passing on the VS Code Extension API reference page (https://code.visualstudio.com/api/references/vscode-api#TextEditorEdit) as "Although the equivalent text [insertion] can be made with replace, insert will produce a different resulting selection (it will get moved)."

@pbwolf pbwolf marked this pull request as draft March 8, 2025 03:30
@pbwolf pbwolf marked this pull request as ready for review March 8, 2025 04:10
@PEZ PEZ merged commit cf2efde into BetterThanTomorrow:dev Mar 8, 2025
5 checks passed
@PEZ
Copy link
Collaborator

PEZ commented Mar 8, 2025

Thanks, @pbwolf! This is such a QOL change for me. You don't mention it in the PR, but also the format-current-form command is now multi-cursor.

PEZ added a commit that referenced this pull request Mar 8, 2025
…t-C"

This reverts commit cf2efde, reversing
changes made to 4c49053.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants