fix: protect code cell options from formatting#655
fix: protect code cell options from formatting#655mcanouil wants to merge 3 commits intoquarto-dev:mainfrom
Conversation
|
Thanks for the PR. I assume this was done to prevent |
|
Another thought here is that this kind of PR really makes me wish we had a test suite in this repo. |
I was thinking about making it specific at first but then I realised that the expected comments are all hardcoded, so I reconsidered, and made a general protection for the comments symbols (hardcoded in two places).
I'm not yet very familiar on this part, but I can't agree more with this. I did "manual tests" as far as this approach can go. |
|
Let's hold on on this PR as the behaviour is not new at all so it can wait a bit for me to implement a test soon as I get some spare time. |
|
@mcanouil we now have extension tests! If you're interested in merging this PR, want to add some tests? |
|
We are continuing to get more user reports of this such as in posit-dev/positron#9432, so I'd love to see a test written here so we can merge this fix in! |
|
I'll try to make some time to make this happen. |
|
I've setup the test, but I can't get to make the formatting command to work. npx @vscode/test-cli --grep "Code Block Formatting" --install-extensions "ms-python.black-formatter"I don't know how to trigger all the logic of the formatCellCommand The easiest would be to export I've also tried to trigger the whole document formatting, but it does not work for an unknown reason. I have to drop this for now, but if someone has a better understand of the whole formatting logic of the extension (not that trivial) and knows how to trigger the activation, feel free to take over. |
|
Ah, I don't think we can use any other extensions in the tests, because of the way that they use a special build of VS Code that is specially built for running extension tests. Instead, what we'll want to do is mock out a formatter to run in the tests. This is the same thing that #754 needs. We may want to put the formatting mock somewhere that all tests can use it. I also think that exporting a function to use in a test is a very good/reasonable way to go. |
|
Well, I don't think the issue is the presence/absence of the formatter. I can only make the test install the extension to be sure |
|
Ok, now I have some information. The vscode-test instance shows a notification that the selection marker is not within a cell that supports formatting which is clearly wrong, but no clue why from yarn run test --grep "Code Block Formatting" |
|
For reference: In another PR I added a mocked cell formatter in a test here: 873fcab |
|
@vezwork Thanks, I'll try to take a look next week-end and see to finalise this PR. |
|
Even changing to your testFormatter function does not work. See when running extension debug mode: Screen.Recording.2025-10-19.at.19.10.58.movI have to drop this as It costs me way too much time for no good reasons. Feel free to take over as I won't spend more time on this for the next few months at least. |
…code Quarto code cells carry metadata on leading comment lines (`#| label: foo`, `#| echo: false`, `//| label: bar`, ...) that must survive verbatim so Quarto can parse them on the next render. Previously, `formatBlock` handed the entire cell to the language formatter (Black, autopep8, styler, ...), which treats these lines as ordinary comments and may reflow, reorder, or rewrite them. Hide the option lines from the formatter entirely by slicing them off `blockLines` before calling `virtualDocForCode`, and shift the returned edits back into the real code range via `block.range.start.line + 1 + optionLines`. Blocks that are entirely option directives short-circuit to `undefined` (no formatter invocation, no out-of-range toast). This replaces the filter-after approach that dropped any edit whose start line landed in the option region, which quietly swallowed valid multi-line edits and block-wide edits starting at virtual-doc line 0.
Add a `Code Block Formatting` suite that registers a fake Python formatter from a pure `string -> string` function, so each case can prove exactly what did and did not get rewritten. The fake formatters mangle `=` and `+` into spaced forms, rewrite `#| ` to `# PIPE`, and normalise comment spacing. Cover six scenarios: a single directive followed by code, multiple directives preserved in original order, a block with no directives, a directives-only block (no-op), multiline code with badly-formatted standalone and inline comments, and a hostile formatter run against a mixed block to prove the directives never reach the formatter at all.
446a935 to
dfcc6a7
Compare
Implement a mechanism to prevent code cell options from being formatted, ensuring that only relevant code is affected during formatting operations.
Fixes #368, fixes #135