Skip to content
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

[folding] should not fold whitespace after function #3353

Closed
Tyriar opened this issue Feb 23, 2016 · 32 comments
Closed

[folding] should not fold whitespace after function #3353

Tyriar opened this issue Feb 23, 2016 · 32 comments
Assignees
Labels
editor-folding Editor code folding issues feature-request Request for new features or functionality on-testplan

Comments

@Tyriar
Copy link
Member

Tyriar commented Feb 23, 2016

Consider the Python script:

def a:
  pass



def b:
  pass

Currently all whitespace following the pass in a is collapsed with it:

image

This will make it the code harder to read in some cases as there is no space between the functions are the author intended, making a look more like part of b.

@Tyriar Tyriar added the bug Issue identified by VS Code Team member as probable bug label Feb 23, 2016
@aeschli aeschli added the editor-folding Editor code folding issues label Feb 24, 2016
@aeschli aeschli added this to the Feb 2016 milestone Feb 24, 2016
@aeschli aeschli changed the title Python code folding should not fold whitespace after function [folding] should not fold whitespace after function Feb 24, 2016
@aeschli
Copy link
Contributor

aeschli commented Feb 24, 2016

To implement this we need to know more about the underlying language. Does a definition end with the last non-whitespace line, or with a line of the same indent. The current implementation is tuned for the JavaScript case:

function alwaysNull() {
  return 0;

}

@aeschli aeschli added feature-request Request for new features or functionality and removed bug Issue identified by VS Code Team member as probable bug labels Feb 24, 2016
@aeschli aeschli modified the milestones: Backlog, Feb 2016 Feb 24, 2016
@Tyriar
Copy link
Member Author

Tyriar commented Feb 24, 2016

This is something that can wait until language-awareness comes about. The def ends on the last non-whitespace line that is of the same indent level (or lower):

def a:
  something


  something_else # a ends here


def b: # since there was a deintent here
def a:
  something


  def b:
    something_else # a ends here


def b: # since there was a deintent here

For both these cases I would expect:

def a: [...]


def b: # since there was a deintent here

@Tyriar
Copy link
Member Author

Tyriar commented Jun 24, 2016

As @inergy points out on #4968, adding a newline at the end of the folded section will immediately add the new line to the folded block.

@NiklasRosenstein
Copy link

NiklasRosenstein commented Jul 13, 2016

Is there a fix in sight? This *The current folding behaviour is super annoying 😅

@NiklasRosenstein
Copy link

NiklasRosenstein commented Oct 15, 2016

Any update on this? How can people work with this folding behaviour? I switched to Atom not long after my last comment but switched back to VSCode recently because Atom is so slow. The folding behaviour is literally the only thing I was switching to Atom in the first place.

If anyone has a hint on where the behaviour can be changed, I might just look into submitting a patch myself. It's just hard to find your way around without any idea how VSCode is structured etc.

@NiklasRosenstein
Copy link

Bump

@ZombieProtectionAgency
Copy link

Is the post-fold whitespace folding a different issue than the collapsing of trailing whitespace?

@NiklasRosenstein
Copy link

What's the difference of whitespace that follows a folding and trailing whitespace? (except if you mean whitespace trailing in a line not trailing a block like empty newlines?)

@ZombieProtectionAgency
Copy link

When you add new lines after an already folded block the folded block will gobble them up as you add them

@NiklasRosenstein
Copy link

NiklasRosenstein commented Dec 6, 2016

I don't know if that is a separate issue, but it is certainly linked. The block fold shouldn't consume any newlines after the code block anyway, so if that's fixed, it wouldn't gobble them up anymore.

@DollarAkshay
Copy link

IS this bug still not fixed ?

@NiklasRosenstein
Copy link

Nope. And its still super annoying. I'd give it a shot if I had an idea where to start, but no one seems to be interested in that either.

@Satak
Copy link

Satak commented Jan 26, 2017

+1 for fixing this.

@feliperyan
Copy link

If someone can point me in the right direction I will work on this - it's really disrupting my workflow with Python

@NiklasRosenstein
Copy link

NiklasRosenstein 15 Oct 2016 -- If anyone has a hint on where the behaviour can be changed, I might just look into submitting a patch myself. It's just hard to find your way around without any idea how VSCode is structured etc.

NiklasRosenstein 19 Dec 2016 -- I'd give it a shot if I had an idea where to start, but no one seems to be interested in that either.

I don't think that's ever going to happen, @feliperyan

@Tyriar
Copy link
Member Author

Tyriar commented Jan 31, 2017

I believe this is blocked on #3422 which will involve a fair bit of work. Just keep adding 👍's to the issues and they will eventually bubble to the top of the sorted list which is one of the ways we prioritize.

@spitis
Copy link

spitis commented Feb 26, 2017

Ugly, but better than nothing, workaround:

Add an empty comment (#) in between functions you want to fold, and they will act as whitespace upon folding.

@NiklasRosenstein
Copy link

NiklasRosenstein commented Feb 26, 2017 via email

@acls
Copy link

acls commented May 8, 2017

The fix seems rather simple: don't fold newlines. Newlines at the end of a js function. eg:

function alwaysNull() {
  return 0;

}

is a formatting issue that shouldn't be hidden by the editor.

@Tyriar
Copy link
Member Author

Tyriar commented May 8, 2017

@acls it's not simple though as maybe people, including myself, sometimes break up chunks of code within functions. To give a real example: https://github.com/sourcelair/xterm.js/blob/2221f70ff05ba2af42ee0d26bed2f75dafe2d116/src/Linkifier.ts#L136

  private _addLinkMatcherToList(matcher: LinkMatcher): void {
    if (this._linkMatchers.length === 0) {
      this._linkMatchers.push(matcher);
      return;
    }

    for (let i = this._linkMatchers.length - 1; i >= 0; i--) {
      if (matcher.priority <= this._linkMatchers[i].priority) {
        this._linkMatchers.splice(i + 1, 0, matcher);
        return;
      }
    }

    this._linkMatchers.splice(0, 0, matcher);
  }

This is perfectly valid code but would fold like this:

  private _addLinkMatcherToList(matcher: LinkMatcher): void { ...

    for (let i = this._linkMatchers.length - 1; i >= 0; i--) {
      if (matcher.priority <= this._linkMatchers[i].priority) {
        this._linkMatchers.splice(i + 1, 0, matcher);
        return;
      }
    }

    this._linkMatchers.splice(0, 0, matcher);
  }

Going forward with that solution would be a big regression. We need language-aware folding support to be implemented #3422.

@acls
Copy link

acls commented May 9, 2017

Oops, I meant, don't fold trailing newlines. So you would find the end of the fold and then remove any empty lines.

@Tyriar
Copy link
Member Author

Tyriar commented May 9, 2017

@aeschli could we do this by ignoring empty or whitespace-only lines when considering where where the fold should end? For example:

  private _addLinkMatcherToList(matcher: LinkMatcher): void { 
    if (this._linkMatchers.length === 0) {
      this._linkMatchers.push(matcher);
      return;
    }

    // ^ Skip above line as it's empty
    for (let i = this._linkMatchers.length - 1; i >= 0; i--) {
      if (matcher.priority <= this._linkMatchers[i].priority) {
        this._linkMatchers.splice(i + 1, 0, matcher);
        return;
      }
    }

    // ^ Skip above line as it's empty
    this._linkMatchers.splice(0, 0, matcher);
  } // ^ Fold found

For python you could do this as well, for the following block:

def foo:
  a = 1

  pass



def bar:
  pass

We can determine the right folding level by simply ignoring the empty lines so we're essentially checking this:

def foo:
  a = 1
  pass
def bar: # ^ Fold found
  pass

@acls
Copy link

acls commented May 9, 2017

I made PR #26258 last night, shortly after my last comment, that I think fixes this issue.

@aeschli
Copy link
Contributor

aeschli commented May 10, 2017

I don't think there's a strategy that pleases both the C-style and the Python style language camps.

I doubt the C-style users will accept the argument that the remaining new line is a formatting issue.
I think we need to specify the language style in the language configuration. Also, see #25365 (comment)

@acls
Copy link

acls commented May 10, 2017

I'm in the C-style camp and if the rest of my campers don't like it, then wrap the one line change in a config setting. The vscode source is in the C-style camp and it has a meager 6 instances where there is an empty line before the closing bracket.

I think language specific folding is needed for some things, but the default handling of trailing whitespace isn't one of them.

Since vscode is similar to Sublime and Atom, I'll add that both of them handle folding the same as in #26258.

@acls
Copy link

acls commented May 10, 2017

Don't get me wrong, I think language aware folding is needed and should be able to collapse this:

function alwaysNull() {
  return 0;

}

to this:

function alwaysNull() { ...
}

or even this:

function alwaysNull() { ... }

But the default indention based should collapse it to:

function alwaysNull() { ...

}

The reason being is that Python and other indention based languages are just that, indention based. And it's obviously a problem in those languages to be collapsing the whitespace.

@rkeithhill
Copy link

+1 for collapsing to a single line - when the opening { is on the first line:

function alwaysNull() { ... }

@flamders
Copy link

flamders commented Jun 1, 2017

Hi guys, as I understand a patch exist that fixes the worst problem #26258

I run on Ubuntu 16.04 (snap install). Can you perhaps give me a pointer for applying that patch? Thx

@acls
Copy link

acls commented Jun 21, 2017

I don't know about the snap install, but I do know the easiest way to apply the patch is to push the Merge pull request button. Can someone please just push it.

All sarcasm aside can someone merge #26258 or give a good reason as to why it hasn't been merge. The only reason I've heard so far is that c-style camp wouldn't accept it as a formatting issue. I recently found clang-format, a tool for formatting c-style languages.

It formats this c code:

int main(int argc, char **argv) {
  printf("hello ");
  printf("world\n");


}

into this:

int main(int argc, char **argv) {
  printf("hello ");
  printf("world\n");
}

And if formats this javascript:

function foo() {
  var result = 0;
  return result;


}

into this

function foo() {
  var result = 0;
  return result;
}

clang-format doesn't have a configuration option to keep empty lines before a closing brace. So my initial assertion is true it is a formatting issue.

@regexus
Copy link

regexus commented Jul 30, 2017

I also would like to know why this issue considered as belonging to language-aware folding. Not ignore empty lines at the end of the block is just a bug that current folding behavior has and it should be fixed before the big language-aware folding thing is done.
The patch from acls works as expected, without any problems. Please merge it. It will make python programmers happy and will probably not affect well formatted c-like code at all. Please look at the comparison images in my comment on the pull request page #26258 for more info.

@Shamtam
Copy link

Shamtam commented Aug 24, 2017

+1 to merging the fix in #26258 into the master branch... I've resorted to building from repository and using the OSS version, but would much prefer to be back on the Insider's edition build to get the regular updates without having to re-build. This is pretty much the only thing keeping me from reverting back to a regular release channel.

@aeschli
Copy link
Contributor

aeschli commented Sep 20, 2017

I pushed a new language configuration setting to distinguish C-style block language from offSide style languages:

	"folding": {
		"offSide": true
	}

I added the section to corresponding languages and adapted the indentation based folding to use the new setting.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
editor-folding Editor code folding issues feature-request Request for new features or functionality on-testplan
Projects
None yet
Development

Successfully merging a pull request may close this issue.