microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
100.75k stars 12.46k forks source link

Incorrect Indenting Behavior in VS #38830

Open DanielRosenwasser opened 4 years ago

DanielRosenwasser commented 4 years ago

Ported from https://github.com/dotnet/roslyn/issues/44607 by @DanielRosenwasser

This issue has been moved from a ticket on Developer Community.


Found this problem was reported before, appears to have been reported as fixed. But it is happening again… The title info for the original report is:

TITLE: Wrong indenting
DATE: Olaf van der Spek reported 12/7/2018, 12:54:20 PM

Problems is effectively the same. Running VS 2019 v16.6.0. When you select the editor’s setting for “Indenting” which can be one of [NONE|BLOCK|SMART], selecting ‘BLOCK’ the cursor, most of the time, upon present ENTER goes to column 1 on the next line. Appears “INDENTING is behaving as “NONE” is selected.
Not sure when started, bouncing between VS 2017 and 2019, never have seen the problem in 2017, can’t say it ever worked in 2019 for that matter.


Original Comments

Visual Studio Feedback System on 5/27/2020, 03:16 AM:

We have directed your feedback to the appropriate engineering team for further evaluation. The team will review the feedback and notify you about the next steps.


Original Solutions

(no solutions)

CyrusNajmabadi commented 4 years ago

Tagging @ZooDoo4U

DanielRosenwasser commented 4 years ago

@ZooDoo4U wrote


Hope i didn't add confusion, Adding the comment i left on the "Developer Community"...

I'm working in a few languages and file types. C#, javascript, html, jsx, css. Normally i turn off all auto formatting and will normally fix up the code as desired. First thing i'll do is go in to Tool::Options then Languages and set "Indenting to" "BLOCK". I'm thinking what might be happening, and makes the most sense to me, most everyone leaves all the "Auto Formatting" on and they have "On Enter" reformat, just find it too distracting.

In C# files the intending can be really inconsistent, i've seen it happen a lot, but right now, can't get a good repro, but guarantee i've seen it happen a lot, i'm wondering fiddling with some of the setting investigating I got it working right for a little while in C#. Actually when it happened earlier today in C# that is what prompted me to open this issue. Normally I work 70% in C#, then the other languages.

Javascript/JSX files, this i can repro 100%. Start off with, hope i don't confuse it but will try showing where press enter/tab, for example {ENTER} is where the enter key was pressed.

(New Empty file) Then start typing:

function testMe() {{ENTER} // Here the cursor will be in column 1. Fair enough one might argue it follows block formatting rules here technically

Now continuing on i'll tab in: function testMe() { {TAB}const x = 5;{ENTER}

// Ah now the cursor again is in column 1, expected column 4, or the appropriate tab indent in case you might have started in column 20...

Interesting if using a code snippet for a function in javascript, not sure why but it acts different but the wandering cursor back to column 1 will appear again but not as easy.

funct{TAB} //will get: function snippetPlaceHolder () { // Cursor will be in column 1 }

Continuing on...

function snippetPlaceHolder () { {TAB}if(x===3){ENTER} }

Then here the cursor seeks to the right location under the 'if' but then, adding both the open/closing '{}' then {ENTER}...

function snippetPlaceHolder () { if(x===3) // these two lines should be one tab width in. {{enter}} // appears the formatter here is normalizing lines... }

The code will end up as: function snippetPlaceHolder () { if(x===3) // again should be the right tab with in... { } // the cursor and the closing brace are both back at column 1... }

Hope this is clear. Sorry couldn't get the C# repro but i've seen it happen a fair amount :(

jessetrinity commented 4 years ago

@ZooDoo4U I tried disabling all automatic formatting for TS/JS and set my indentation behavior to BLOCK but I was not able to reproduce the issue of the cursor jumping to the beginning of the line. I tried this in VS 16.6.

Would you be able to provide us with TSServer logs so we can dig into what's happening? You can find the instruction below. You would need to enable logging before performing the behavior that reproduces the issue.

https://github.com/microsoft/JSTSdocs/blob/master/articles/troubleshooting/index.md

ZooDoo4U commented 4 years ago

Would you be open to getting a copy of the ".vssettings" file. Some reason if/when i update each update i'll usually need to import my old settings. Might be easier for both of us? I attached a copy. Let me know if this works :)

Thanks. dan

VS_2019_May_24_2020.zip

jessetrinity commented 4 years ago

That helps. I can get it to happen now but only when typing at the end of the file.

That is, I can reproduce the issue by pressing enter here:

image

But including the final newline on line 4 prevents the issue. image

Turning on automatic brace completion also avoids the issue. Is that the behavior you see?

ZooDoo4U commented 4 years ago

Thanks,

Seems setting the auto close tag "ON" helps some but going through more scenarios even with it on brings in other issues. Notice the lovely formatting with the setting i have set, i get some really "creative" formatting. While if you look at the blah.js file, if you have my setting still loaded try a document reformat, lovely eh? Now ot the indenting issues...

(call this check point #1 -- will reference to show the difference later) With auto-close tag "ON" go to line 20 between the "<>" and ) now type (in column 20 -- think when posted the spacing will be removed so doesn't look like it here but the editor was in column 20....): if( x===15) {{ENTER}} // -- closing tag auto inserted and cursor will be between the {}

Pressing enter to get the closing brace onto the next line, the entire section gets reformatted. Did have auto reformat on EVERYTHING disabled...? Would expect the reformat, and for me it did a rather poor job even at that.

Undo to get back to where i mentioned check point 1, so the cursor will be back between the "<>" and ) on line 20. This time set auto-complete "OFF" start typing in column 20 // -- in the lines following i'm using | to indicate were the cursor is, and {ENTER} showing what was pressed :) if(x===15) {|{ENTER}}

So looks like in general as you mentioned, it will normally only seek to column 1 if at the end of the file. While this last scenario it should have matching correspond braces/parens trailing the cursor again goes to column 1.

Thanks for you attention. The sample/example file i was using is attached in the blah.zip, sorry not too creative with the name.

blah.zip

jessetrinity commented 4 years ago

I'm not sure I am able to follow your steps 100% correctly but I was unable to get an auto format to trigger by typing at the location you indicated. Before and after code snippets or a .gif are more helpful in these cases.

I did notice the closing brace jumping back to the beginning of the line after the return statement (Once I cleaned up the tags to get rid of the parsing errors). Interestingly including a space between the braces before hitting enter changes the behavior. I'll continue looking into it.

ZooDoo4U commented 4 years ago

It did seem to make a difference between being having a trailing space on the line to the right of the cursor or not. I thought as i was typing the file it was syntactically correct, sorry guess something got messed up by me accidentally undoing something one too many times. But does show when the editor decides to reformat stuff in such a weird way, just add confusion, one reason i'm not a big fan of auto formatting stuff....

CyrusNajmabadi commented 4 years ago

@ZooDoo4U here's a useful way to write repros to make them easier to understand. First, use ```ts to indicate a code block, like so:

function foo() {
}

Then, in order to indicate where the caret should be, just use $$. We can remove that sigil and understand where to put the caret. i.e.:

function foo() {
   if (x == 15) {$$

"press enter. that results in: ..."

CyrusNajmabadi commented 4 years ago

Also, feel free to include the text in such a ```ts codeblock and optionally include an image to help make sure that we're seeing what you're seeing. animated gifs work well too, but are more of a last-resort if all else is failing.

ZooDoo4U commented 4 years ago

Thanks.

      if(  meEntering ) 
      {       
           willDo === true; 
      }
ZooDoo4U commented 4 years ago

One more case for this. Also what is interesting, starting up VS from a cold boot and getting into VS, w ith the same text, i get two behaviors with the cursor at $$1 or $$2. Most often starting up VS my font and colors settings are messed up in some way.

If I now press {ENTER} at $$1, the cursor heads to column 1...

But now to get the color theme fixed up going into Tools::Options::Environment->General changing the Color Theme to a stock color theme, now pressing {ENTER} at $$1, the indenting seeks to the correct location. But also my fonts and colors are messed up... Ignoring the font/colors or a second, if now i move to the $$2 spot and press {CTRL+ENTER} to delete the first blank lines, the cursor seeks to column 1.

Now try fixing the font/color issues selecting the Color Theme used most of the colors, most, but not all colors go back to what is expected but fonts are all messed up, below 12 point sorry i can't read and many fonts go down to 8pt. If now i import only the "Font And Colors" from "Import Export Settings" most often stuff is restored (sometimes) about 20% of the time i'll get errors on the import. If the setting import, seems something will be messed up. Like the attached bitmap shows, worse part can't find where that font color can be changed. Don't want this to creep in to how into how to solve world peace, i'll assume opening another issue for the color/import issues would be something else. Just interesting selecting a different color theme and importing only the font & colors has side effect effecting this, as they should be unrelated...?


import React from 'react';
import TodoItem from './TodoItem';
import ContactCard from './ContactCard';

function MainContent()
{
    return (
        <div className="todo-List">
            <ContactCard { name="PlaceHolderName",
                imageUrl="http://placeKitten.com/300/200",$$1
                $$2

                phone="888-425-1212", email="a@bozo.com"}/>

        </div>
    );
}

![vs_bad_text](https://user-images.githubusercontent.com/11509268/83336702-6e5c5780-a26a-11ea-9e5c-90de2265dcdd.png)