razor icon indicating copy to clipboard operation
razor copied to clipboard

Blazor: Formatting has indention issue

Open tthiery opened this issue 2 years ago • 20 comments

The formatting of razor files is not working reliable for indention. Original Issue: https://github.com/dotnet/vscode-csharp/issues/4997

Actual Behavior

When formatting a Blazor razor page with mixed HTML and @code fragment, the indent formatting is not working reliable. Most lines work somehow, but many do not.

https://github.com/dotnet/razor/assets/442577/77e2a965-20c4-4692-93a8-9c49c697973e

The video shows the code, the manual indent (so it looks like the normal C# formatting) and the form-on-save of vs code reverting it back.

Enumerating out of my head I see issues with expression bodies, method calls in new lines (LINQ Methods) and collection/dictionary initializers.

Expected Behavior

C# code formatting in the @code format works like in any other .cs file.

tthiery avatar Dec 04 '23 20:12 tthiery

@tthiery thanks for logging the issue. There are issues logged for collection/dictionary initializers being problematic/different to a plain .cs file formatting, but the others mentioned are new. Could you expand the view of the code a little, or just include "Before", "After" and "Expected" code snippets for these formatting issues? Each one will likely need a different, and quite specific, fix so extra info is extremely useful. eg, in the video above, is the formatting operation moving the => line back one indent? or forward? And is that property just defined in a @code block? or is there more nesting happening?

davidwengier avatar Dec 04 '23 21:12 davidwengier

Before

image

After (format via vscode save .. moving the indent back; no code behind)

image

tthiery avatar Dec 04 '23 21:12 tthiery

LINQ and Collection Initalizer here

Before image

After image

tthiery avatar Dec 05 '23 19:12 tthiery

I'm not sure if it is the correct issue ticket to post. But I'm also experiencing format issues with indentations of HTML markups.

I am using Visual Studio Enterprise 2022. Version 17.8.3. The project is NET 8. Blazor WASM.

Before auto formatting: image

After the famous Ctrl K - F to auto format: image

I migrate the projects from NET 6. Did not see these issues on 6... Now it's very painful to... manually format everything in these blazor files.

nguyenlamlll avatar Jan 09 '24 18:01 nguyenlamlll

image

Zebra Coloring ... not sure if this best belongs here.

tthiery avatar Jan 23 '24 21:01 tthiery

@tthiery We actually call this "Disco colors" 😁

Definitely not formatting related though, so would be best as a new issue.

davidwengier avatar Jan 23 '24 21:01 davidwengier

@davidwengier May I ask if the issue ticket is good enough for the dotnet team to start working on? I mean, I see it is put under 17.9 planning milestone, but would it be fixed and included in 17.9 soon? Thanks. It becomes quite annoying to us (in my team)...

nguyenlamlll avatar Jan 24 '24 03:01 nguyenlamlll

At this stage a fix in 17.9 is unlikely I'm afraid.

davidwengier avatar Jan 24 '24 03:01 davidwengier

This should have more thumbs up. The indention of the markup and the code is random often. For the code it can be fixed by re-typing the closing } - easy, but the markup indention must be corrected manually for each line each time it was randomized - and this happens almost every time when editing something (especially when breaking long parameter lists to multiple lines). I really hope this is going to get a higher priority, even it doesn't affect the functionality. I append to the previous poster: It's annoying, if you want your code to look clean and stick to even common formatting rules.

nd1012 avatar Mar 25 '24 18:03 nd1012

I'm experiencing several indentation issues as well, some probably related.

The first one is that multi-line render fragments are not indented. This could be related to the property expression not being indented in the video:

private RenderFragment fragment =>
@<div>
    <div>
        ...
    </div>
</div>;

When I put a control structure inside the fragment, it gets really messed up. The whole block from opening to closing braces gets one indentation level too less:

private RenderFragment fragment =>
@<div>
    @if (true)
{
    <div>
        ...
    </div>
}
    <div>
        ...
    </div>
</div>;

Then there's another issue with control structures when they are at the top nesting level in a razor component:

@if (true)
{
    <div>
    ...
</div>
}
@if (true)
{
    <div>
    <p>
        ...
    <p>
</div>

    <div>
    ...
</div>
}

Everything following the first element in the block gets one indentation level too less until the closing tag of that element. Then we are back at the correct indentation level, but opening another element after that will bring back the same incorrect behavior.

However, this applies only to the top level. Wrapping the whole structure inside another element gives the expected behavior:

<div>
    @if (true)
    {
        <div>
        </div>
    }
</div>

NormanM123 avatar May 23 '24 09:05 NormanM123

@NormanM123 the render fragment issue is known, and tracked by a different issue. Could you log a separate issue for the other indentation issue you mentioned. Breaking things into separate issues helps us deliver more fixes, because some are simple bug fixes, and some require lots of work coordination.

davidwengier avatar May 23 '24 09:05 davidwengier

@davidwengier Thank you for the fast reply! I'll open another issue for the @if at the top level of a document.

Are both issues about the render fragment (fragment not indented, control structure inside fragment not indented) known? Because I already did a search but wasn't able to find it. I found #6632, which probably covers my first example, but does it cover the second one with the @if inside the fragment as well?

While experimenting with it, I now experienced more strange behaviors. Given the following code:

@code {
    private RenderFragment Frag1 =>
    @<div>
        <p>...</p>
    </div>;

    private RenderFragment Frag2 =>
    @<div>
        <p>...</p>
    </div>;    //<- When I type this semicolon the formatting changes as shown in the following code block.
}

@code {
    private RenderFragment Frag1 =>
    @<div>
        <p>...</p>
    </div>
    ;

    private RenderFragment Frag2 =>
@<div>
        <p>...</p>
    </div>;
}

The semicolon after the first fragment moves to the next line and the @<div> in the second fragment gets the wrong indentation level. Manually triggering a format after that restores the second fragment, but leaves the semicolon in the first fragment in the wrong line and increases its indentation:

private RenderFragment Frag1 =>
@<div>
    <p>...</p>
</div>
    ;

This behavior with the semicolon being moved to the next line only applies to the render fragment directly preceding the one where I type the semicolon. When I put three render fragments in a code block and type the semicolon of the last one, only the semicolon of the second fragment is affected, the first fragment is left unchanged. Could this be somehow related to #6191, which should be fixed?

When I declare the fragment inside a method, manually triggering a format increases the indentation level of the semicolon by two levels:

//This is how it looks like after typing the semicolon of the second fragment:
@code {
    private RenderFragment Frag1 =>
    @<div>
        <p>...</p>
    </div>
    ;

    private void M()
    {
        RenderFragment frag2 =
@<div>
        <p>...</p>
    </div>;
    }
}

//This is how it looks like after manually triggering a format:
@code {
    private RenderFragment Frag1 =>
    @<div>
        <p>...</p>
    </div>
            ;

    private void M()
    {
        RenderFragment frag2 =
    @<div>
        <p>...</p>
    </div>;
    }
}

And finally, when I declare the fragment inside a local method of the method (two nesting levels), manually triggering a format leaves the indentation level of the semicolon unchanged (same as the closing </div>), but still at the next line.

NormanM123 avatar May 24 '24 00:05 NormanM123

@NormanM123 Thanks for the detailed info! I wish GitHub allowed me to move comment, as https://github.com/dotnet/razor/issues/6632 is the issue I was thinking of, and is the best one to track render fragment issues for now. I don't know if the subsequent issues you mentioned would necessarily be fixed by that, but I would expect that at least has to be the first one done. Essentially, we would need to get render fragments formatting working before we know what rough edges are left after that.

davidwengier avatar May 24 '24 04:05 davidwengier

I'm not sure if it is the correct issue ticket to post. But I'm also experiencing format issues with indentations of HTML markups.

I am using Visual Studio Enterprise 2022. Version 17.8.3. The project is NET 8. Blazor WASM.

Before auto formatting: image

After the famous Ctrl K - F to auto format: image

I migrate the projects from NET 6. Did not see these issues on 6... Now it's very painful to... manually format everything in these blazor files.

I am seeing the same behaviour in vscode:

afbeelding

NathanVG avatar Aug 01 '24 09:08 NathanVG

Blazor formatting when it comes to indentation has been awful for years, it seems like it's only gotten much worse with VS 2022 and .NET 8.... Usually it likes to inexplicably mess up where a block is supposed to be indented towards the end of the HTML portion of the razor file, but not always, and once it messes up one spot it's screwed for the rest of the file including the code block. I've attached 3 screenshots where all I did was 'Format Document' from the Edit->Advanced menu. 3 times in a row and it just completely botches everything repeatedly. I REALLY wish this worked better, I'm at the point of just turning off formatting in VS 2022 entirely for razor files if possible since at least I can then manually fix it and it'll stay. As it sits if I manually fix these and do anything within a method for example, it will re-screw everything within that method for blocks. Insanely frustrating.

One: indent 1

Two: indent 2

Three: indent 3

SoulSeekkor avatar Aug 14 '24 14:08 SoulSeekkor

Just to add, you can see this for yourself with my project: https://github.com/SoulSeekkor/NginxPanel

SoulSeekkor avatar Aug 14 '24 15:08 SoulSeekkor

Forgot to mention, compiler conditionals within the code block indent incorrectly as well (too far to the left).

SoulSeekkor avatar Aug 14 '24 16:08 SoulSeekkor

@SoulSeekkor I've copied your comment to a https://github.com/dotnet/razor/issues/10738 so it can be tracked separately. Each specific example of a formatting issue is a different fix, so separating things out makes sure we don't miss anything (eg, if we fix the bug in this issue, and close it, it wouldn't necessarily fix your scenario)

Forgot to mention, compiler conditionals within the code block

Could you log a new issue with this problem, and provide more details? I suspect this is likely partly a compiler issue as compiler preprocessor directives are not strictly supported right now, and compiler behaviour around them can be surprising.

davidwengier avatar Aug 14 '24 21:08 davidwengier

@davidwengier Sounds good, and sure I'll create a new one for that issue later today!

SoulSeekkor avatar Aug 15 '24 14:08 SoulSeekkor