-
Notifications
You must be signed in to change notification settings - Fork 44
Fix cell formatting issues #754
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
8c9747e
to
0902ef2
Compare
edits.forEach((edit) => { | ||
editBuilder.replace(edit.range, edit.newText); | ||
}); | ||
// Sort edits by descending start position to avoid range shifting issues |
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.
Unrelated but I thought we should make this robust to providers returning unsorted edits.
|
||
// Bail if any edit is out of range. We used to filter these edits out but | ||
// this could bork the cell. | ||
if (edits.some(edit => !blockRange.contains(edit.range))) { |
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.
Unrelated but I'm pretty sure applying edits partially can bork our cells 😬
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.
I pulled down this PR, rebased on main, and followed the reproduction steps in #745 (which this PR should address). I ran into a new error that prevented any formatting from occuring:

I reverted this code change locally (bailing if edits are out of range) and formatting works again and the problem described in #745 is addressed.
Thanks for the PR! Something for us to consider: Every time I see a PR here I get a feeling of dread: we have no test coverage and so I have very little visibility or intuition of the impact that these changes make. What kind of infrastructure would we have to add for us to have unit test coverage for these kinds of changes? |
Part of the reason this is still a draft is that I'd like to add some tests here. They'll be limited in scope though. Here are the levels of tests we have in our R stack, by ascending level of scope:
We spend most of our time and energy on internal LSP tests. |
@lionel- we now have extension tests! The tests are focused on roundtripping right now, but they do already involve executing commands. Do you think an extension test (a snapshot test?) that opens our test qmd files, executes the format command, and checks the contents of the file would provide enough coverage for this PR? I'd like to get this PR in, so I'm happy to write the tests. Please advise! |
I pulled down this PR, rebased on main, and followed the reproduction steps in #745 (which this PR should address). I ran into a new error that prevented any formatting from occuring: ![]() I was able to reproduce #745 in Positron on the |
I have some local changes where I'm able to load the minimal repro qmd specified in #745, set the editor's cursor to inside a code cell, and do
...but the cursor is definitely within a cell. I suspect that the Quarto extension is toasting this because there is no R formatter available. The test VSCode instance has 0 extensions installed: I know from looking under the extensions tab while the tests are running. That means there's no R extension. That means there's no R formatter available! It is confusing to me that there are 0 extensions installed because the vscode testing guide says:
but that does not seem to be the case for our extension tests. For one other thing, the test instance of VSCode always has an |
Another thought I had is that we might want to mock out a formatter to use in the tests, or maybe two (one that adds a final newline and one that does not). |
@juliasilge and I discussed a couple possible ways to test this PR:
|
I made a copy of this PR: #818, it is
Excuse me for copying the branch&PR to a new branch&PR, but I didn't feel comfortable force pushing (because of the rebase on main) to this one. I don't currently know how to interpret the test results I am getting in #818: The test does what I expect until I ran the test after reverting the main fix by @lionel- (the change in |
Sounds reasonable!
I like (1) as it reliably targets the behaviour we want to test. The second solution would make the snapshots dependent on external behaviour (formatters like ruff change behaviour over time). This might be reasonable for monitoring a file as a sanity check, but probably not as a basis for comprehensive testing. |
Do you mean that we should keep applying partial edits? I don't think we should do that ever because this runs the risk of corrupting the cell contents. To see this, imagine a formatter returning two edits, one that removes lines 4-6 with 6 being out of range, and another edit that changes line 4. If you discard the first edit, the second will change the wrong line. Relevant bit from the LSP protocol:
Note that this requires the sorting that I added in this PR to be stable, so that the order of edits starting at the same position is preserved, which is guaranteed by ES2019. (We should add a comment about that.) To be robust, which I think we should because of the potential of corrupting the user's work without them being aware, we should either:
I think the reason edits may be OOR is that So it should be safe to adjust OOR edits by substracting 1 to the high bound. If the edit is still OOR after that, then we probably should error out as the edit is not consistent with our assumptions about the document. @DavisVaughan Does this reasoning make sense to you? |
Thanks for the thorough comment @lionel-! Very clarifying.
I mostly did that just because I didn't understand your fix or what is going on in this area in general and was trying things to get it working. I understand now that the right thing to do should be to modify the out of range edits like you described. |
Maybe a better way to go about this is to:
This way we don't need to adjust out of range text edits. This approach feels cleaner to me. |
@lionel- for this particular Note that for something like this
it will leave the trailing newlines due to your last bullet, which I don't love? Is it simpler to do this?
That way we don't need any fancy tracking, and we always clean up extraneous blank lines in a code chunk |
Hmm then maybe we should go all the way and trim all trailing newlines at the end of a chunk? Leading and trailing newlines in chunks might be considered part of quarto formatting rules, and I think we don't expect any surrounding whitespace in chunks? |
I think we are in agreement already. By "exactly 1 trailing newline", I just mean that you need a
formats to
So yea the code content itself becomes just |
oh gotcha, yep I'm all for that |
@vezwork Sounds good! |
0902ef2
to
186ac61
Compare
rebased on main and force pushed. For some reason I'm a co-author on the commits now. |
Added a test that currently fails on this branch because of "out of range edits" from the mock formatter. It will also fail if the |
Addresses #745
But needs to be tested more widely and deal with formatters that don't ensure a trailing newline as discussed in #745 (comment).