Stillat / vscode-antlers-language-server

Provides rich language features for Statamic's Antlers templating language, including code completions, syntax highlighting, and more.
https://antlers.dev
MIT License
36 stars 3 forks source link

Additional new lines are being removed when formatted. #75

Open johncarter- opened 1 year ago

johncarter- commented 1 year ago

Describe the bug Additional new lines are being removed when formatted.

Impacted Products

Versions and Other Plugins/Extensions Antlers Toolbox for VS Code v2.6.7

To Reproduce

<section class="pb-36">
    <div class="container mt-24">

        {{ partial:_components/select_link }}

        <div>
            <div class="max-w-[40rem]">
                {{ partial:_components/listing_card }}
            </div>
        </div>

    </div>
</section>

Format leads to:

<section class="pb-36">
    <div class="container mt-24">

        {{ partial:_components/select_link }}
        <!-- MISSING LINE BREAK HERE -->
        <div>
            <div class="max-w-[40rem]">
                {{ partial:_components/listing_card }}
            </div>
        </div>

    </div>
</section>

Expected behavior I would want the original line preserved.

Additional context I understand that Antlers uses the HTML formatting (https://antlers.dev/docs/formatting#settings) but despite these settings it still removes the extra line:

{
    // ...
    "html.format.wrapAttributesIndentSize": 120,
    "html.format.wrapLineLength": 999999999,
    "html.format.preserveNewLines": true,
    "html.format.maxPreserveNewLines": 3,
    // ...
}
JohnathonKoster commented 10 months ago

This is currently expected behavior.

Swennet commented 9 months ago

+1! I hate that it doesn't preserve newlines after Antlers tags and it makes our HTML look messy. An option to turn this off would be great.

JohnathonKoster commented 9 months ago

+1! I hate that it doesn't preserve newlines after Antlers tags and it makes our HTML look messy. An option to turn this off would be great.

An option to disable this entirely would make things much worse. I'll take a look at supporting this in some situations, but won't be able to get rid of it entirely due to how things are implemented (no guarantees/promises on timelines, as this will be a tough one) 👍

Swennet commented 9 months ago

Great to hear @JohnathonKoster! Just out of curiosity, how would that make things much worse?

JohnathonKoster commented 9 months ago

The implementation will convert Antlers tags and tag pairs into a temporary format that is compatible with existing HTML formatters. So something like this:

<div>{{ collection:pages }} <p>some content</p> {{ /collection:pages }}</div>

might get sent to the formatter as

<div><antlers001> <p>some content</p> </antlers001></div>

the process is then reversed after other formatters have done their job, and an Antlers-specific formatter handles the internal Antlers parts. In this example, there would be no weird side effects. However, anything like this:

{{ if something }}
one
{{ elseif something_else }}
two
{{ else }}
three
{{ /if }}

might need temporary "supporting" elements to help get the indentation better for one, two, and three (since there is no structural information inside the conditions).

In addition to those temporary supporting elements, each of the condition's branches becomes their own set of HTML tag-pairs that is tracked by the parser and document transformation steps. The closing tag for each of these needs to be removed (except for the very last {{ /if }} - in this case, we need to remove the temporary opening tag), and both the opening/closing tag of all supporting elements also needs to be removed - it is because of these that the formatter currently aggressively removes newlines, otherwise we'd have an ocean of whitespace around all of these.

andjsch commented 6 months ago

I do have the same problem. Sometimes it works though, when it's not all antlers tags - don't have an example ready for when it's working as expected.

{{#
    @name Layout
    @desc The default layout file.
#}}

<!-- /layout.antlers.html -->
<!doctype html>
<html lang="{{ site:short_locale }}" class="antialiased scroll-smooth scroll-pt-4">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
        <style>
            @font-face {
                font-family: "Croissant One";
                font-weight: 400;
                font-display: swap;
                src: url('/resources/fonts/CroissantOne-Regular.ttf') format('truetype');
            }
        </style>
        {{ vite src="resources/css/site.css|resources/js/site.js" }}
        {{ partial:statamic-peak-seo::snippets/seo }}
        {{ partial:statamic-peak-browser-appearance::snippets/browser_appearance }}
        {{ partial:statamic-peak-tools::snippets/live_preview }}
    </head>
    <body class="flex flex-col min-h-screen bg-oeeins-beige selection:bg-primary selection:text-white">
        {{ stack:seo_body }}
        {{ partial:statamic-peak-tools::snippets/noscript }}
        {{ partial:statamic-peak-tools::navigation/skip_to_content }}
        {{ partial:statamic-peak-tools::components/toolbar }}

        {{ partial:layout/header }}
        {{ template_content }}
        {{ partial:layout/footer }}
    </body>
</html>
<!-- End: /layout.antlers.html -->

will become

{{#
    @name Layout
    @desc The default layout file.
#}}

<!-- /layout.antlers.html -->
<!doctype html>
<html lang="{{ site:short_locale }}" class="antialiased scroll-smooth scroll-pt-4">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
        <style>
            @font-face {
                font-family: "Croissant One";
                font-weight: 400;
                font-display: swap;
                src: url('/resources/fonts/CroissantOne-Regular.ttf') format('truetype');
            }
        </style>
        {{ vite src="resources/css/site.css|resources/js/site.js" }}
        {{ partial:statamic-peak-seo::snippets/seo }}
        {{ partial:statamic-peak-browser-appearance::snippets/browser_appearance }}
        {{ partial:statamic-peak-tools::snippets/live_preview }}
    </head>
    <body class="flex flex-col min-h-screen bg-oeeins-beige selection:bg-primary selection:text-white">
        {{ stack:seo_body }}
        {{ partial:statamic-peak-tools::snippets/noscript }}
        {{ partial:statamic-peak-tools::navigation/skip_to_content }}
        {{ partial:statamic-peak-tools::components/toolbar }}
        {{ partial:layout/header }}
        {{ template_content }}
        {{ partial:layout/footer }}
    </body>
</html>
<!-- End: /layout.antlers.html -->

It would be cool if we could mark lines that should be kept by adding a space or two if it keeps my empty formatting lines as I intended.