prettier-plugin-svelte
prettier-plugin-svelte copied to clipboard
Script & style contents lost when invoked with range option
Hello 👋
There are some cases when users would like to reformat only parts of file, unfortunately it's not working right now.
Reproduction: Use following file
<script>
console.
log('hello')
</script>
<article>
<section>
</section>
</article>
{#if
true}
<div></div>
{/if}
<style>
.css.is.best{ align-content:
baseline}
</style>
and run
prettier index.svelte --range-start 0 --range-end 10
Output:
<script ✂prettier:content✂="CiAgY29uc29sZS4KICBsb2coJ2hlbGxvJykK">{}</script>
<article>
<section>
</section>
</article>
{#if
true}
<div></div>
{/if}
<style ✂prettier:content✂="CiAgICAuY3NzLmlzLmJlc3R7IGFsaWduLWNvbnRlbnQ6CiAgICAgICAgICAgIGJhc2VsaW5lfQo="></style>
Apart from nothing being really formatted (different issue, I've noticed it also does not work in official html), we get those base64 encoded placeholders.
During my investigation I've noticed that parser.preprocess
encodes content, and printer.embed
decodes it, but printer.embed
is not called with custom range used.
I'd like to ask, what is the technical reasoning behind those placeholders? This package uses svelte
parser under the hood, and it returns deep AST with embedded JS already parsed (and TS types stripped, right?). Would it be possible to get rid of parse.preprocess
if svelte parser had shallow option that would leave text of Script
and Style
nodes as text? I believe it could be then passed to textToDoc
in embed
Unfortunately getting rid of some kind of snipping is not possible given the way the Svelte compiler is written. From what I understand, the compiler expects vanilla JS/CSS in the script/style tags, and is greedy, meaning the moment it encounters a script or style tag it switches to a JS/CSS parser and parses until it finds a closing tag. If those JS/CSS parsers find anything that's not valid JS/CSS syntax, they throw. So we have to find another way to handle embeds, by somehow unsnipping everything even when ranges are given.
Hmm you're right it would be really complex. Shallow parser would open Pandora box of brace nesting and quoting issues...
Snipping unfortunately also messes up offset inside file, length of base64 encode is different than that of original.
I'm not that familar with how formatting a specific range works in prettier. Possible solutions without knowing more:
- Check if we can do snipping differently, preserving the offsets
- Check if we can recalculate the offsets after snipping to adjust for the new lengths
I dug into this today and found out that right now it's impossible to support range formatting, because we can't hook into Prettier at the required position: https://github.com/prettier/prettier/issues/11404
any update on this? it still doesen't work.
+1
This is not solved these days , and it was reported first time 3 years ago. :( :(