Skip to content

(GH-1428) Make region folding case insensitive and strict whitespace #1430

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

Merged
merged 1 commit into from
Jul 16, 2018

Conversation

glennsarti
Copy link
Contributor

@glennsarti glennsarti commented Jul 12, 2018

PR Summary

Previously the code folding feature would fail to find region blocks starting
with Region or ending with EndRegion. This was due to the regex only
looking for lower case. This commit updates the start and end region
detection to be case insensitive, similar to that defined in
microsoft/vscode@64186b0

This commit adds has strict whitespace rules for the region/endregion keyword
which means only #region will match whereas # region will not.

Previously the code folding had trouble detecting the beginning of comment
blocks and regions which were not indented. This was due to the empty line
regex expecting at least one whitespace character to be considered "an empty
line". This commit modifies the empty line regex to also allow an empty string
which is indeed, an empty line.

Fixes #1428

PR Checklist

Note: Tick the boxes below that apply to this pull request by putting an x between the square brackets.
Please mark anything not applicable to this PR NA.

  • PR has a meaningful title
  • Summarized changes
  • This PR is ready to merge and is not work in progress
    • If the PR is work in progress, please add the prefix WIP: to the beginning of the title and remove the prefix when the PR is ready

@glennsarti glennsarti force-pushed the gh-1428-folding-casing branch from ae7065b to e91298b Compare July 12, 2018 12:00
@glennsarti glennsarti changed the title (GH-1428) Make region code folding non-case sensitive parse whitespace (GH-1428) Make region folding case insensitive and parse whitespace correctly Jul 12, 2018
@@ -354,7 +354,7 @@ export class FoldingProvider implements vscode.FoldingRangeProvider {
): ILineNumberRangeList {
const result = [];

const emptyLine = /^[\s]+$/;
const emptyLine = /^[\s]*$/;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does JS really require the [] here? Wouldn't /^\s*$/ be sufficient?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh....Good point. Will test

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

const emptyLine = /^[\s]+$/;
const startRegionText = /^#\s*region\b/;
const endRegionText = /^#\s*endregion\b/;
const emptyLine = /^[\s]*$/;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as above.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

const startRegionText = /^#\s*region\b/;
const endRegionText = /^#\s*endregion\b/;
const emptyLine = /^[\s]*$/;
const startRegionText = /^#\s*[rR]egion\b/;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does JS support (?i) to set the regex to ignore case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Depends. This commit brings it into line with the VSCode "default" behaviour, but, we could add this. I'm not fussed either way on this issue.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good enough for me. FWIW, ISE only supports lower-case #region / #endregion.

Copy link
Contributor

@rkeithhill rkeithhill Jul 12, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OTOH leading folks down a path that doesn't work in ISE … is that a bad thing and do we care? Also, ISE doesn't like a space between the # and region|endregion. It's pretty picky.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My inclination would be:

  • No space between # and region (similar to other pragmas, e.g. #requires, #if)
  • Support total case insensitivity (/^#region\b/i), since PowerShell is generally case insensitive

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True....

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting the tests for that, don't include spaces between #
microsoft/vscode@9e05d4b#diff-e10026493ca8c706f842f8b49b1ccdfa

Copy link
Contributor

@rkeithhill rkeithhill Jul 13, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also find it odd that they allow any number of spaces after the # e.g.

#                Region

would be a valid region start.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So given all this, plus the powershell region snippet has no space (

"Region Block": {
"prefix": "#region",
"body": [
"#region ${1}",
"$0",
"#endregion"
],
"description": "Region Block for organizing and folding of your code"
}
) I'll change the regex to not allow whitespace.

Can always add it back in :-)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

Copy link
Contributor

@rkeithhill rkeithhill left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM other than minor suggestions on the regex's - depending on the funky JS support for regex. :-)

@glennsarti glennsarti force-pushed the gh-1428-folding-casing branch from e91298b to c5d3b59 Compare July 13, 2018 01:17
@glennsarti
Copy link
Contributor Author

Ready for review/merge again.

@glennsarti glennsarti force-pushed the gh-1428-folding-casing branch from c5d3b59 to e5f16ce Compare July 13, 2018 01:27
const startRegionText = /^#\s*region\b/;
const endRegionText = /^#\s*endregion\b/;
const emptyLine = /^\s*$/;
const startRegionText = /^#\s*region\b/i;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still think we shouldn't match # region for this; I can imagine ordinary comments matching this, and I don't think I've ever seen any usage of a pragma that permitted whitespace like this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May want to hit up the VSCode team on that, as they're ALL like that

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can only find examples where the whitespace comes before the #, like:

Having an indented #region like:

if ($x)
{
    #region

       DoStuff

    #endregion
}

seems pretty reasonable to me.

But I feel like setting folds for

#   Region
if ($x)
{
    ... Blah
}

# EndRegion

could cause problems. Any line comment beginning with the word "region" would become a fold, meaning we would then look for # endregion, and may not find one.

Copy link
Contributor Author

@glennsarti glennsarti Jul 13, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I am so sorry...I need glasses 👎

-100 points to me.

^\\s*# is not ^#\\s*

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haha, no I thought that's what was going on, just wanted to be sure 😄

Thanks so much for this @glennsarti!

…hitespace

Previously the code folding feature would fail to find region blocks starting
with `Region` or ending with `EndRegion`.  This was due to the regex only
looking for lower case.  This commit updates the start and end region
detection to be case insensitive, similar to that defined in
microsoft/vscode@64186b0

This commit adds has strict whitespace rules for the region/endregion keyword
which means only `#region` will match whereas `# region` will not.

Previously the code folding had trouble detecting the beginning of comment
blocks and regions which were not indented.  This was due to the empty line
regex expecting at least one whitespace character to be considered "an empty
line".  This commit modifies the empty line regex to also allow an empty string
which is indeed, an empty line.
@glennsarti glennsarti force-pushed the gh-1428-folding-casing branch from e5f16ce to c61ca6d Compare July 13, 2018 02:11
@glennsarti
Copy link
Contributor Author

glennsarti commented Jul 13, 2018

Pending Green CI, this is ready for review again.

Tests are green

@rkeithhill
Copy link
Contributor

LGTM!

@glennsarti glennsarti changed the title (GH-1428) Make region folding case insensitive and parse whitespace correctly (GH-1428) Make region folding case insensitive and strict whitespace Jul 13, 2018
const startRegionText = /^#\s*region\b/;
const endRegionText = /^#\s*endregion\b/;
const emptyLine = /^\s*$/;
const startRegionText = /^#region\b/i;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait, I think you were right about the whitespace here -- no? That the regex should look like /^\s*#region/i?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As in, like the other VSCode folding regexes

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope....the regex I use is slightly different, because it's checking the grammar token (it's within the line) not the whole line. That's why I do an Empty Line check.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the code below it, it looks like subsequentText() gets the whole comment line and then tests it against the regex, which starts with ^. Which I read as not matching an indented #region. Does that sound right?

Copy link
Contributor Author

@glennsarti glennsarti Jul 13, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the logic I'm using is;

    Find the `#` character (This is the `punctuation.definition.comment.powershell` scope)
        If there is only whitespace before the `#` then
            if the text after, and including the `#` matches the starting regex then
                #Do Something
            end
            if the text after, and including the `#` matches the ending regex then
                #Do Something
          end
       end
     end

What this means is the start/endregion regexes will never have the whitespace in the front.

That said, it could be optimized by grabbing the whole line and regex-ing on that...but that's for another PR.

Copy link
Contributor Author

@glennsarti glennsarti Jul 13, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, looks like the method subsequentText() is named wrong. Should be textFrom() or something like that.

Copy link
Contributor

@rjmholt rjmholt Jul 13, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, so it does this:

    #   Some text is here
    ^-------------------^
    [offset]            [end of line]

subsequentText() seems as good a name as any - but maybe the comment should be something like:

Get the text from a given offset to the end of the line it's on

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anyway, I'm satisfied!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rjmholt PR #1438 refactors the detection to be easier to understand.

Copy link
Member

@TylerLeonhardt TylerLeonhardt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 🎉

@TylerLeonhardt TylerLeonhardt merged commit b4a66c3 into PowerShell:master Jul 16, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

PowerShell Extension 1.8.1 breaks editor folding on region tags
4 participants