microsoft / vscode

Visual Studio Code
https://code.visualstudio.com
MIT License
164.37k stars 29.32k forks source link

[folding] language-aware folding #3422

Closed aeschli closed 6 years ago

aeschli commented 8 years ago

The current implementation of folding uses an indentation based folding strategy that is unaware of the language it works on. Knowledge on the underlying language allows us to solve the following requests:

rkeithhill commented 8 years ago

Another issue I don't see in that list is user-configured folding like this example from C#:

#region Public methods
...
#endregion

In the PowerShell extension we would like to provide this same sort of feature the same syntax as what C# uses which, in PowerShell, looks like a "special" comment.

fromthewoods commented 8 years ago

PowerShell block comment folding is weird in the Insider build 0.10.10. <# Comments here and here

>

Broken: http://i.imgur.com/M6Ay1vl.gif It should fold around the <# + #> Like this: http://i.imgur.com/HFRHJJL.gif https://blogs.msdn.microsoft.com/powershell/2008/06/14/block-comments-in-v2/

fromthewoods commented 8 years ago

Now I understand. It's the indentation level. Language-aware folding ftw!

bgelens commented 8 years ago

PowerShell here-string breaks folding logic. Here-string end marker must be placed on first column of new line. untitled As you can see, the function isn't folded correctly anymore although folding was done on the function keyword. Code after the here-string stays visible as well.

rkeithhill commented 8 years ago

Yeah, I think for VSCode to give the best experience for code-folding they're definitely going to need help from the various language extensions/services.

daviwil commented 8 years ago

Either that or we're going to have to tweak the PowerShell syntax definition to jive with their folding model a little better. May need some pointers from Martin about what we can do to improve folding if the tmLanguage definition is a factor.

aeschli commented 8 years ago

@rkeithhill For the moment there's nothing you can tweek on your side until we allow languages to control code folding.

jgeorgeson commented 8 years ago

As another example, Ant build.xml files can have large text blocks where the content doesn't adhere to indentation of the XML. Such as

    <echo file="myfle.txt">
totally unindented
text
       goes here
 and breaks VS Code folding
    </echo>
felixfbecker commented 8 years ago

PowerShell here-string breaks folding logic. Here-string end marker must be placed on first column of new line.

the same thing happens with PHP heredoc.

Also, sections in INI files cannot get folded by indentation

nfloersch commented 8 years ago

I'm probably way out of my depth here...

User-controlled folding - with "regions" - seems fairly straight-forward to define. The editor needs to only be language aware enough to know how each language shows comments. Then if a comment starts with "region" or "endregion" such as...

region ... #endregion

//region ... //endregion /region/ ... /endregion/ 'region ... 'endregion ---region ... ---endregion

...

You treat the content in-between as a region. It seems like creating a list of all supported language comment syntaxes is the only thing necessary.

pcgeek86 commented 8 years ago

Definitely need this resolved for PowerShell

Seairth commented 8 years ago

The language syntax files already have foldingStartMarker/foldingStopMarker. It seems that one way forward would be to use these, if available, then fall back to the current/default behavior of indentation-based folding.

adbertram commented 7 years ago

Any update on this? I really need regions and here strings collapsable in PowerShell.

DollarAkshay commented 7 years ago

Any update ? Python code folding is really annoying me

Sevin777 commented 7 years ago

Is fixing this currently on the roadmap? When can we expect this to be implemented? This is the only major blocker keeping me from using VS Code.

DustinCampbell commented 7 years ago

Adding myself here as I'd like to get proper #region..#endregion folding working for C#.

madumlao commented 7 years ago

Just a suggestion - if ever you use language-aware folding, please leave indentation-based folding available as an option.

Too many editors have burned me with their intepretation of what counts as a block or not (try a mixed-language source file) and in some cases indentation is really the only way to hint source file structure.

hlink commented 7 years ago

For C#, #region and #endregion support, along with support for the recommended documentation tags, is a must before my team can use VSCode. https://msdn.microsoft.com/en-us/library/5ast78ax.aspx

Huachao commented 7 years ago

@aeschli any updates on this, it's almost one year since the issue is opened?

aeschli commented 7 years ago

There is currently nothing in the works, but the issue is discussed on every planning meeting and weighted against other open issues.

mattmcnabb commented 7 years ago

This is so needed for PowerShell, and I assume for other languages as well. Right now it's one of the biggest pain points when transitioning from the PowerShell ISE to Code. This seems to be a huge want for the entire community, so I hope that the popularity of this issue gets it added to the roadmap soon.

simonua commented 7 years ago

Same is true for TypeScript. We are placing #region and #endregion in all our source files to get ahead of any addition of this feature. Bit of a gamble and overhead, but here's to hoping.

adbertram commented 7 years ago

Let's add this to the roadmap at the next planning meeting. That'd be awesome.

gerane commented 7 years ago

@aeschli This is a blocker for adoption for many in the PowerShell community. It would require far too much modification to their code to make VSCode usable (or modification to get it working isn't even possible). This is a topic I see referenced on an almost daily basis when people are discussing VSCode adoption for PowerShell projects.

simonua commented 7 years ago

@aeschli Is UserVoice still in use for VS Code anywhere? Would be good for us to just add or upvote there. This link is dead: https://visualstudio.uservoice.com/forums/293070-visual-studio-code

And thanks for all the work on VS Code. It shows.

krissmilne commented 7 years ago

I make use of correct indenting as well as using #region #endregion comment blocks throughout my code.

The default indent folding is ok, however it also creates several problems:

Providing the ability to override the default indent folding with a user defined foldingStartMarker/foldingStopMarker would provide the most flexible work around to the issue without having to cater for default across languages.

pr-yemibedu commented 7 years ago

Hello, A setting of

mpearon commented 7 years ago

I'm seeing the same behavior that has been documented on this string, but I though I would add to the noise a bit! :) brokenfolding

crysyn commented 7 years ago

I use #region/#endregion all the time in C#... but it is behaving rather oddly in the latest VSCode Insiders build.

region will not offer a folding option at all if it is not at the start of the line

endregion will offer a folding option if it is at the start of the line

region with out a matching #endregion will fold until the end of the document or a new #region is encountered. This includes skipping over intended child #region and #endregion tags

When the folding does work it does not consume the matching #endregion tag... Most folding does not consume the opening/closing tags in all honesty so that may just be a style it does that I do not like.

Not sure if this is the place to report oddness with #region and folding.

aeschli commented 7 years ago

@crysyn What's currently available is indentation-based folding only. We don't have support for markers (#region/#endregion) or language aware (here string, tags, if-else...blocks) folding. This issue is to collect the inputs and votes for that.

daniel-keen commented 7 years ago

I would really appreciate having adequate folding the regions. In a way that they would work regardless of the indentation. Additionally, I would love to be able to fold parts including brackets. This was quite annoying when I first saw how it works here. Since that time I am simply not using this feature. Therefore it seems to be useless in my case. That is just my opinion. Hope it will help you somehow.

D3MaxT commented 7 years ago

This is so badly needed. Please bump it up from the backlog to a near-future release milestone! :) Thank you!

crysyn commented 7 years ago

To that end then in general code folding is a huge help for code organization. I would move that in general the concept of the folding should be changed from indentation to scopes or code blocks but I am not sure if that is a general enough concept for a universal editor to implement. It would however unify the folding concept between languages where whitespace is used to define blocks (like python) and where other delimiters like { and } signify it (like C#).. #region/#endregion would simply just be another set of delimiters that provide their block tag After the open instead of previous to it like the whitespace and { } versions.

The folding also should really display the line before the block and then [...] at its end to signify that the block of code that follows was folded... Right now following good coding practices with { and } delimiters make if statements with one line of logic go from 4 lines to 3 lines in an arguably less useful fashion.

madumlao commented 7 years ago

Just a further suggestion, even after syntax-aware folding is implemented, indentation can be respected as an option on top of syntax as an additional (optional) block marker. That is, not only can you fold your if ($foo) { ... }, but if you custom-indent the inner parts of a block you can still sub-fold the contents based on indentation. i.e., indentation is an optionally-enabled block marker for all languages.

This is especially useful for anyone writing mixed languages, for example, code snippets inside MarkDown, generated XML / HTML inside PHP, markers for the start/end of a domain-specific language or API (e.g. curl_open ... curl_close snippets not part of a block)..., indented multi-line string continuations... I think the benefits are so numerous and obvious that indentation changes should even be considered block markers for all languages by default.

pr-yemibedu commented 7 years ago

Hello, If the path of language blocks gets explored, more people would be happier to have each of their languages get fair share of proper folding. Nested languages would want scoped folding if at all. Having multiple styles are helpful as first class fold patterns. So folding should have user defined cut points to allow you to make this a practical reality and include help from extension writers. Settings?

Having a fallback fold style is an alternative and not a compliment. Only because it is so basic and people will constantly want to add to that form rather than have a something catered to their needs. I speak for example the ident style is nice for both python and f#(fsharp) but it lacks a little in things like folding comments for example. Thank you. Good day.

acls commented 7 years ago

I think #3353 should be removed from the list since the behavior requested there should be the default indention-based folding. And a new issue could be added to handle folding C-style functions from open to close brackets.

DollarAkshay commented 7 years ago

@acls What about python ?

acls commented 7 years ago

@DollarAkshay That issue is specifically for Python. The default should be changed to cater to indentation-based languages like Python. So Python shouldn't need language-aware folding, except for maybe multiline docstrings or other things not based on indentation.

DollarAkshay commented 7 years ago

@acls No it does, because the default indentation based folding does not work as expected. It collapses the whitespaces underneath too.

acls commented 7 years ago

@DollarAkshay I already made a PR for that issue that fixes the folding issues for Python.

acls commented 7 years ago

@DollarAkshay That PR, #26258, should become the default. And anything specific to C-style languages(not indention-based) should be part of this issue.

handrades commented 7 years ago

Please also fix the powershell region folding. I know you guys are busy doing other important things but this is one of those little things that keep some users away from VSCode

cadayton commented 7 years ago

Knowing that VSCode is folding based on indentation works for me when working with PowerShell. I really like the fact that I don't have to specify '#Region & #End' to get that desired folding functionality. My first step after opening a PowerShell project is to enter 'Ctrl +K +0' to collapse all of the code. Hope this doesn't change. Checkout a few of my GitHub scripts for a working example.

pcgeek86 commented 7 years ago

Thanks for the pointer @cadayton. I was looking for a way to fold / unfold code from the keyboard, but I was searching for the wrong term (eg. "collapse" and "expand"). Now I have a solution. 😄

delve commented 7 years ago

The trouble with indention based folding for me in Powershell is that it imposes requirements on things like comment docs that I would then have to impose upon the rest of my team. That's a political argument I'd rather not waste time and capital on; it would be better if VSCode simply recognized what a block comment is in PS and folded accordingly.

madumlao commented 7 years ago

The trouble with indention based folding for me in Powershell is that it imposes requirements on things like comment docs that I would then have to impose upon the rest of my team. That's a political argument I'd rather not waste time and capital on; it would be better if VSCode simply recognized what a block comment is in PS and folded accordingly.

I recognize this is an issue on a lot of languages and yes we need syntax-aware folding as an answer. But all the same I would rather not people talk about indentation / syntax-aware folding as if they were mutually-exclusive methods. You could implement language-aware folding that also recognizes indentation changes as blocks. e.g.

string generation example

# this part should be code folded as a parent block
function echoUser($user) {
    debug("Echoing User {$user->id}");
    # this part should be cold folded as a sub block
    echo '<tr class="user">';
        echo "<td>{$user->id}</td>";
        echo "<td><a href='{$user->getHref()}'>{$user->name}</a></td>" ;
        # this is another sub-block that gets folded
        echo "<td class='actions''>";
            echo "<a class='btn details' href='{$user->getHref()}' />";
            echo "<button class='delete' data='{$user->getHref()}' />";
        echo "</td>";
    echo '</tr>';
}

api example

$url = "my/api/url";
# this should be cold-foded as a block
$ch = curl_init($url);
    curl_setopt($ch, CURLOPT_DATA, $data);
    curl_setopt($ch, CURLOPT_FOLLOW, true);
    # other commands against the curl API
$response = curl_exec($ch);
curl_close($ch);

In both cases, the programmer's indentation signals a logical block even though the compiler does not actually create one. And here the indentation-specified block does not conflict with the language-aware blocks. These aren't just special cases - any structure of code or data that is not enforced by the main syntax flow can lead to cases like this where indentation is the best way to make sense of the structure. We're talking inline JSON, XML, function literals, object literals, API calls, embedded languages, shell pipelines, subprocesses, string concatentations etc.

You could write a million and one special rules for each case, but that's flaky at best since people will never tire of making new APIs and structures. Recognizing indentation as a "block" supports all those cases for all languages. The main problem is that right now, indentation is the only "block" supported.

TLDR: it's not either-or. At worst case there should be a switch that you can use to enable indentation folding (regardless of language-aware folding), and heck, it should probably be on by default.

MLefebvreICO commented 7 years ago

Still waiting for code regions here !!

cossio commented 7 years ago

+1 to this feature. Could it be handled by extensions?

pbaksa commented 7 years ago

language-configuration.json - autoClosingPairs could be also used for this...

SSCtech commented 7 years ago

+1