dotnet / roslyn

The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.
https://docs.microsoft.com/dotnet/csharp/roslyn-sdk/
MIT License
19.11k stars 4.04k forks source link

Add an option to apply code formatting to collection initializers #8269

Open HellBrick opened 8 years ago

HellBrick commented 8 years ago

At this moment VS code formatter never touches the collection initializers. I would guess this is done to preserve a hypothetical manual item alignment, but as someone who never does that, I find it very annoying that I have to format the code inside the collection initializers manually. So I'd like to suggest adding an option to specify whether the formatter should format the collection initializers (just like there is Ignore spaces in declaration statements to allow/disallow manual declaration alignment).

DustinCampbell commented 8 years ago

Yes, I agree. I'd like an option too.

i00lii commented 8 years ago

Hi, I'm adding my voice to the voting for this feature.

jamesqo commented 7 years ago

I think this would be a good idea, too.

Pilchie commented 7 years ago

:link: Also requested in https://developercommunity.visualstudio.com/content/problem/94365/dictionary-or-array-inline-initialization-code-sty.html

momvart commented 7 years ago

And it is a problem of multi-line initializer.

jinujoseph commented 7 years ago

also requested in https://developercommunity.visualstudio.com/content/problem/124958/code-formatting-does-not-take-effects-on-codes-in.html

Jabronironi commented 6 years ago

+1 Would love this feature!

Kirill-Maurin commented 6 years ago

+1, I don't like manual formatting

davkean commented 6 years ago

Also another two reports here: https://twitter.com/ShawnWildermuth/status/999815299410079746.

sharwell commented 5 years ago

This went to an initial design review, but we believe it needs a more specific proposal before it can move forward. Two areas of particular interest are the following:

/cc @heejaechang to help form a more concrete proposal including a specific option or options that can be specified in .editorconfig.

MisinformedDNA commented 5 years ago

@sharwell @heejaechang

Even if formatting of collection initializers is disabled, users likely want the indentation of these lines to be updated to match project settings regarding tabs/spaces.

If the concept of "disabling collection initializers" existed and the user still wanted to respect the other settings, what does "disabling collection initializers" even mean?

Also, if using manual alignment is the real issue here, then I think the real question would be, "Why are people manually aligning? And what settings need to be introduced to undo that need?"

I would propose an experimental setting csharp_preserve_collection_initializers, defaulted to true, which would represent no change in current behavior. Opting in (setting to false) would apply all rules to the collection initializers. Then we can collect data and see what kinds of issues arise for users.

sharwell commented 5 years ago

This issue will eventually offer a specific resolution to #779

v-kydela commented 4 years ago

It makes sense that some (very few) users would want to do their own manual formatting in object initializers and that they wouldn't want the formatter to interfere, but I'd argue that the same could be said of all code. If you don't want your code to be formatted, just turn off auto-formatting.

Also, even in those cases when people don't want Visual Studio to interfere with their whitespace, they probably still want their indentation to line up correctly. The problem I'm having is that my initializers aren't getting indented when I paste.

jez9999 commented 4 years ago

+1 from me too

GearTheWorld commented 4 years ago

Please count me in. It's ugly to see the formatting not applied as well as frustrating to have to do it manually

This looks so wrong ;)

image

webczat commented 3 years ago

+1. Actually it is partially an accessibility issue, as for a blind person like me it's non obvious whether something is misindented. Most people can look it up easily, I have to turn on indentation announcements in a screenreader and actually walk through the whole thing. And it is easy to misindent by accident.

SetTrend commented 3 years ago

Me, too.

I painstakingly set formatting options in Tools > Options > Text Editor > C# > Formatting/Spacing.

Now, when I manually create an array of objects by utilizing C# initializers, the Edit > Advanced > Format Document menu command doesn't format initializers honoring my settings:

Initializers not formatted

This is very inconvenient as I have to manually edit quite a number of futile code just to be able to easily survey it later on.

GearTheWorld commented 3 years ago

What's the status of this issue? It is of a very importance specially when we have a lot of initializers in the condition that when closing the brace on this condition all initializer braces stay at the same place. Have to manually go up and fix all of them. We need a fix ASAP.

v-kydela commented 3 years ago

@heejaechang - Do you have a more specific proposal yet?

heejaechang commented 3 years ago

@v-kydela Hi. probably @sharwell can answer your question better! I believe adding an option is not that hard. all needed to be done in code is removing this rule (http://sourceroslyn.io/#Microsoft.CodeAnalysis.CSharp.Workspaces/SuppressFormattingRule.cs,372), but not sure whether PM is okay with adding a new option.

v-kydela commented 3 years ago

@heejaechang @sharwell

It doesn't look like anyone is assigned to this. Can someone be assigned to move this forward?

sharwell commented 3 years ago

@v-kydela This is still pending a complete design per https://github.com/dotnet/roslyn/issues/8269#issuecomment-471117261. It will be a substantial amount of work to design, implement, and ship this feature. At this time, we are not ready to assign it to a specific individual, but would take a look if someone wanted to create a complete proposal (including edge case behavior details and a migration story for existing users).

meeple142 commented 3 years ago

Is there a template that I should use for an "official proposal" addressing the https://github.com/dotnet/roslyn/issues/8269#issuecomment-471117261 ? Or just wing it?

v-kydela commented 3 years ago

I'm pretty confused because these comments seem to contradict each other.

I believe adding an option is not that hard. all needed to be done in code is removing this rule (http://sourceroslyn.io/#Microsoft.CodeAnalysis.CSharp.Workspaces/SuppressFormattingRule.cs,372)

It will be a substantial amount of work to design, implement, and ship this feature.

Which is true?

tobiasschulz commented 3 years ago

It's obvious they just dont want to do it for some reason...

CyrusNajmabadi commented 3 years ago

It's obvious they just dont want to do it for some reason...

It is a non trivial thing to work on. Especially wrt to testing and potential unintended consequences. We can't just remove a line of code and ship thigns in that state. For all we know this may regress things or have other issues. It may crash for all we know. Or it may end up causing problems with other constructs.

This is the single most complex component we have in the IDE, and virtually all changes we have made have regressed things for some users. We are extremely cautious here as this can be extremely destabilizing to teams.

CyrusNajmabadi commented 3 years ago

It will be a substantial amount of work to design, implement, and ship this feature.

Which is true?

Taht part is true. We would ahve to design this out, implement it, and test the entire matrix of cases that this could impact. I would estimate just the testing portion at several weeks on someone's plate (and i'd likely still not feel confident that we weren't introducing an issue).

SetTrend commented 3 years ago

Well, if it'd be optional (as suggested by OP), wouldn't that automatically solve those concerns? It'd be sort of an A/B test scenario.

CyrusNajmabadi commented 3 years ago

Optional doesn't help as once we ship this we now have to support this and make sure it doesn't regress in the future. That means fully testing its interactions with all other options and language constructs.

GearTheWorld commented 3 years ago

I tend to agree for the regress. Since a few VS updates I see formatting all wrong in many places and many different types of file. Maybe you should consider rethinking the whole process?

Right now, if I paste, and this is the way I reproduce so easily, I see many pages of code with all my initializers damaged. Have to redo all the work again each time I paste some code in an initializer and sadly I need format on paste for other reasons.

CyrusNajmabadi commented 3 years ago

I tend to agree for the regress. Since a few VS updates I see formatting all wrong in many places and many different types of file

Please file issues for any regressions you have experienced.

Maybe you should consider rethinking the whole process?

I'm not sure what this means. Can you clarify? Thanks!

MisinformedDNA commented 3 years ago

@CyrusNajmabadi Are there a list of use/test cases that detail the various issues? Maybe having that would allow people to better understand the complexity and offer (potentially) better solutions?

CyrusNajmabadi commented 3 years ago

With formatting, the challenge is that these constructs can effectively appear in many locations, and they can effectively contain almost anything within them. Initializers are very difficult for this as they can be contained in arbitrary expressions and also contain any and all expressions.

So the test matrix is effectively: all combinations of parent/child expressions here :-/

CyrusNajmabadi commented 3 years ago

Another compounding issue here is that, thanks to anonymous methods, the language allows arbitrary nesting of statements and expressions. And with local functions involved we basically have almost the entirety of the language accessible within an initializer. Indeed, the only things we don't have (namespaces and types), are generally the easier things to format. :-/

MisinformedDNA commented 3 years ago

It occurs to me that there are two related requests people have.

  1. Formatting the initializer
  2. Formatting the code inside the initializer

Focusing only on request 2:

Before:

var a = new KeyValuePair <string,string>( "Hello","World" ) ;
var b = new[] { new KeyValuePair <string,string>( "Hello","World" )

After:

ACTUAL:

var a = new KeyValuePair<string, string>("Hello", "World");    // Formatted
var b = new[] { new KeyValuePair <string,string>( "Hello","World" )    // Not formatted
};

EXPECTED (Applying only the second issue):

var a = new KeyValuePair<string, string>("Hello", "World");    // Formatted
var b = new[] { new KeyValuePair<string, string>("Hello", "World")    // Partly formatted
};

So maybe it's hard to know where the curly braces should go and if it should be one line or four, but it seems obvious that an expression that was formatted correctly outside an initializer, should also be formatted correctly inside an initializer.

That's an easy case, but what would be a case where this wouldn't work or would become tricky?

CyrusNajmabadi commented 3 years ago

that was formatted correctly outside an initializer, should also be formatted correctly inside an initializer.

The challenge here is that our formatter didn't y have a concept of 'correctly formatted'. It's effectively a constraint solver that attempts to set up many interrelated constraints and then just attempts to translate those to whitespace operations between tokens.

CyrusNajmabadi commented 3 years ago

also, the formatting engine didn't have a good concept of whitespace between tokens and trivia (i.e. comments), so those throw another large wrench into things :-/

MisinformedDNA commented 3 years ago

I see you are using the past tense in "the formatting engine didn't have a good concept...". But the present day Roslyn does have a good concept of whitespace, tokens and trivia, right?

CyrusNajmabadi commented 3 years ago

Sorry. I should say: the formatting engine doesn't have a good concept here.

ccornici commented 3 years ago

Sooo, is there any plan to implement formatting for this? I think Resharper has this since 5 years ago or so right?...

gmorris007 commented 3 years ago

I am using VS2019. Code was typed more-or-less like the following. It would be nice if would simply add the normal spacing around the initializer names, curly braces, equal signs, etc. I can take care of the new-lines and indenting.

`

    protected SetraTranslationMatrix[] points =
    {
        // why is code formatting ignoring this part???
        new SetraTranslationMatrix { sourceName= "tot_a", destName="TOTAL_AMPS" },
        new SetraTranslationMatrix { sourceName ="tot_p", destName ="TOTAL_Kw", useKilos = true },
        new SetraTranslationMatrix { sourceName ="tot_s", destName ="TOTAL_kVA", useKilos = true },
        new SetraTranslationMatrix{ sourceName= "tot_wh", destName = "TOTAL_kWh", useKilos=true },
        new SetraTranslationMatrix{sourceName="tot_vah", destName="TOTAL_VAh" },
        new SetraTranslationMatrix{ sourceName= "tot_apf", destName="TOTAL_PF" }
    };

`

raffaeler commented 3 years ago

When code generating the issue is even worse because the initialization members never gets a linefeed. And even if I specify the linefeed as a code token, NormalizeWhitespace remove them all, making impossible a decent formatting. Unfortunately I did not find any way to use NormalizeWhitespace so that it leave my manual (aka forced) crlf.

CyrusNajmabadi commented 3 years ago

Unfortunately I did not find any way to use NormalizeWhitespace so that it leave my manual (aka forced) crlf.

You cannot use Normalize with forced whiskers whitespace. The point of Normalize is to completely overwrite the formatting of all the code to a consistent form that will always parse properly.

raffaeler commented 3 years ago

You cannot use Normalize with forced whiskers whitespace. The point of Normalize is to completely overwrite the formatting of all the code to a consistent form that will always parse properly.

I understand that but this means that when code-generating it is impossible to use initializers (given I want to present the result to the user and not just compile it).

CyrusNajmabadi commented 3 years ago

Yes. If you want to present to users and control how it looks, then you cannot use Normalize. You'll have to specify the newlines and indentation yourself.

Note that this is an entirely orthogonal conversation to the formatting engine discussed here. Currently the formatting engine (unrelated to NormalizeWhitespace) can't be used in source generators at all.

raffaeler commented 3 years ago

I hoped it was a common feature. Writing C# code generators with a stringbuilder give me a sense of discomfort :)

th3W3n commented 3 years ago

+1 I definitely need it!

aarondandy commented 3 years ago

I started using the new file scoped namespaces which effectively causes an unindent on each file. I'm really feeling this now with C# 10 and am sure others will be as well.

GearTheWorld commented 3 years ago

@aarondandy We are all sorry. This an ongoing issue and it plagues everybody. The entire formatting process needs a revamp to my opinion

Microsoft: Please at least don't touch the formatting already in place which we painfully crafted before all our formatting becomes ugly after setting an instance initializer

Believe it or not I'm today with the current version of VS 2022 17.0.0 and still have this huge formatting problem

CyrusNajmabadi commented 3 years ago

Believe it or not I'm today with the current version of VS 2022 17.0.0 and still have this huge formatting problem

We haven't made any changes here (due to many of hte substantial issues listed above). So the formatting situation should be close to the same as with VS2019.