New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Connect: Entering a # character forces all preprocessor entries to be reindented #2487
Comments
Hello, I'm the original bug reporter. I decided to create a self explaining CS file to ease the bug hunt: http://online.ru-zero.com/files/test.cs Thanks! |
Thanks @KakCAT. Thank you for the feedback. We will be addressing the issue soon. |
The # key is a trigger character for formatting. It automatically formats the region before and after the #. This entails all trivia between the previous token and the next token after the #. All of the directives in the sample are part of the trivia between the # and the next token, so they all get formatted. The sample has text that is not currently at the proper indentation level. All of the text in the format range gets indented to the proper level, this includes the directives, shifting all the way to the left and the method call, getting shifted to the right, but none of the surrounding type or method declarations get adjusted because they are outside of the auto formatted region. AFAICT this is the expected and intended behavior of the formatter. @Pilchie any thoughts? |
Hello, I don't know if this is correct or not, but my opinion is that in case it is correct, there should be a way to disable it, as well as automatical format can be disabled on ; , on } and on paste. Reformatting shouldn't be enforced on any case if the user doesn't want to use it. |
This one doesn't look like its going to be easy to fix, not without a lot of rewrite of the command handlers or the formatter. The formatter only operates between tokens and since the # is part of trivia it doesn't count as a token. All special action keys other than ENTER are handled by the format command handler, which just formats. The ENTER key has its own command handler that possibly uses the smart indenter (but in some circumstances uses the formatter). It looks like this scenario would be better served by the smart indenter and not the formatter, but I'm not certain of all the ramifications of that change. Possibly the formatter needs an overhaul. As for options, there currently only options to control formatting when ; or } are typed. All other keys that trigger formatting have no option, so they default to on. |
Moving out to 1.1 based on Matt's assesement. Note that this only an issue around comments - if there are real tokens inside the preprocessor directives, this isn't as bad. |
Hi, shouldn't there be a switch where all autoformatting is disabled? I mean, this may or not may be important, but I'd really prefer to completely disable autoformatting if typing a '#' in my code is going to mess all my format. Right now my only option is keep using VS2013 and switch to VS2015 to compile when required. |
Note that connect bug http://connect.microsoft.com/VisualStudio/feedback/details/1247309/gets-wrong-indentation-for-region-and-endregion is related to this. Once I wrap some text with |
This comment has been minimized.
This comment has been minimized.
I thought this was not supposed to happen if you had smart-indent off. If you change this: To 'None' or 'Block' do you still see # automatically updating the indentation? |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
@heejaechang see mattwars comment on May 3, 2017 for a summary of a few issues
Workaround is to type ctrl+z (undo) whenever you are typing/pasting preprocessor directives. [edit] actually this was not my bug report, got things mixed up, but great if it helps anyways |
@weltkante ah, thank you for the screencast. now I see exactly what the issue is. this looks like a bug. not sure what is the actual cause. but let me assign the issue to me and see whether I can fix it. |
📝 I'm going to collapse all the comments not related to the original issue so the person interested in working on this has a good starting place. I might get some of the reasons wrong, but there is only a very limited selection to choose from. |
@sharwell thank you! didn't know one can do that. |
Brought over from https://developercommunity.visualstudio.com/content/problem/1094319/region-autoindent-dedents-herestring-lines-startin.html. I've experienced this, plus erroneous formatting of string s = @"
# A PowerShell comment
Get-ChildItem
"; becomes: string s = @"
# A PowerShell command
Get-ChildItem
"; |
@rjmholt I don't repro this at all. Can you supply your full file that demonstrates the issue? Thanks! |
The full file I experienced this with was this one |
Still can't repro the issue. Which line were you on? |
So I was making edits here. Based on the guidance in the original issue I opened, I just experimented with editing and it occurs when new ifdefs are being added. When Here's a gif: |
Ah thanks! that will def help narrow what to investigate. so it's not that editing in the string caused reindentation. Rather, editing of pp-directives outside of hte string affected indentation of code inside of it. Thanks! :) |
Once a section of code is momentarily #if’d out, it is no longer parsed as c# tokens, and is no longer thought of as containing things like keywords or verbatim strings. The one thing it does continue to recognize is other # directives, which is now no longer inside a string.
|
It might be interesting to explore changing the c# parser to keep parsing c# tokens inside of #if'd out blocks. This way we could also colorized them (albeit dimmed). |
I assume the issue here is that PP directives can nest, so it's not until the end of the file that the parser realises it has no production to follow, meaning it can't produce an error early and move on? With that said, I would assume a tokeniser would emit the opening PP directive as a single token ending at the newline, allowing it to resume a normal state for later scanning of things like strings — I wouldn't have expected an opening PP token to affect the way the tokeniser sees strings (or really almost any preceding tokens to affect the tokeniser, especially in a language generally as well behaved as C#). But I'm only making assumptions about how C# is parsed based on my experience elsewhere, especially that the pre-processor isn't really a pre-processor and instead that the tokeniser/parser are responsible for consuming PP directives. |
It def does. Consider something as simple as: #if false
#else The section inside the if is meaningless until we hit the #if false
Console.WriteLine(@"foo
#else
Console.WriteLine("");
#endif We don't interpret the Note: this behavior is mandated by the language and cannot be changed as we have found that there is actually code out there that depends on the behavior between preprocessor directives and strings. i.e. imagine a test file that has it's own ifdefs, and it contains strings that contain pp directives in the strings. changing the lang/behavior here will completely break that. |
Ah yes that makes sense -- an unfortunate consequence of needing to emulate an actual preprocessor, where unhygienic macro semantics are expected. I can feel myself wanting to pull on this thread more, since I'm thinking about how something like C++ handles its preprocessor pragmas, but I'm guessing we'd keep hitting reasons for the behaviour and don't want to waste anyone's time. Thanks for the discussion! |
The primary resolution to the above issue is avoiding re-indentation of the file if preprocessor directives are not complete. |
Ported from TFS WorkItem: 1160552
Repro Steps:
This item was filed by a customer. Please communicate and close the loop with your customer via the customer tab inside TFS.
Problem Description
Hi,
Entering a # character forces all preprocessor entries to be indented again, even when all formatting options have been disabled. It also displaces some "}"s
My setup is: automatical formatting fully disabled , tabs size=4, keep tabs, indenting=none
I'm supplying two images to ease the explanation.
image1: https://dl.dropboxusercontent.com/u/49509038/img/vs2015_ctp6/img1.png
image2: https://dl.dropboxusercontent.com/u/49509038/img/vs2015_ctp6/img2.png
Revisions:
------------------------
Customer Information
------------------------
User ID: 10125130
Handle: KakCAT
---------------------------
Connect Site Information
---------------------------
Site Name: Visual Studio and .NET Framework
Site ID: 210
Feedback ID: 1266613
Feedback Form: 6049
----------------------
Problem Description
-----------------------
Hi,
Entering a # character forces all preprocessor entries to be indented again, even when all formatting options have been disabled. It also displaces some "}"s
My setup is: automatical formatting fully disabled , tabs size=4, keep tabs, indenting=none
I'm supplying two images to ease the explanation.
image1: https://dl.dropboxusercontent.com/u/49509038/img/vs2015_ctp6/img1.png
image2: https://dl.dropboxusercontent.com/u/49509038/img/vs2015_ctp6/img2.png
repro on Win8.1 with VS2015 CTP6
The text was updated successfully, but these errors were encountered: