zokugun / vscode-explicit-folding

Customize your Folding for Visual Studio Code
MIT License
99 stars 14 forks source link

Weird behavior with "nested":false, "foldLastLine":false #51

Closed HolyBlackCat closed 3 years ago

HolyBlackCat commented 3 years ago

Found a rather obscure issue.

Describe the issue

The end of a folding range is determined incorrectly.

I have following settings:

    "folding": {
        "cpp": [
            { // R"(...)" (C++ only)
                "beginRegex": "\"\\(",
                "endRegex": "\\)\"",
                "nested": false,
                "foldLastLine": false,
            },
            {
                "begin": "(",
                "end": ")",
                "foldLastLine": false,
            },
        ],
    },

Now, in the following code...

(

"(

)"

)

If I fold the topmost (, the folding stops at )", rather than at ). In other words, I get this:

▶ (   
  )"

  )

While I expected this:

▶ (
  )

This doesn't happen if I do any of the following:

To reproduce

daiyam commented 3 years ago

I can't reproduce the issue. Can you add the configuration "explicitFolding.debug": true, and post the log?

Here what I get:

document] lang: cpp, fileName: test.cpp
[main] regex: /(?<_0_0>"\()|(?<_2_0>\)")|(?<_0_1>\()|(?<_2_1>\))/g
[main] line: 1, offset: 0, type: BEGIN, match: (, regex: 1
[main] line: 3, offset: 0, type: BEGIN, match: "(, regex: 0
[main] line: 5, offset: 0, type: END, match: )", regex: 0
[main] line: 7, offset: 0, type: END, match: ), regex: 1
[document] foldings: [{"start":2,"end":3,"kind":3},{"start":0,"end":5,"kind":3}]
HolyBlackCat commented 3 years ago

@daiyam Ah sorry, I accidentally commented out "nested":false in my first post. Edited it. Here's the log (after uncommenting), just in case:

[document] lang: cpp, fileName: Untitled-1
[main] regex: /(?<_0_0>"\()|(?<_0_1>\()|(?<_2_1>\))/g
[main] line: 1, offset: 0, type: BEGIN, match: (, regex: 1
[main] line: 3, offset: 0, type: BEGIN, match: "(, regex: 0
[loop=0] regex: /(?<_2_0>\)")/g
[loop=0] line: 5, offset: 0, type: END, match: )", regex: 0
[main] line: 5, offset: 0, type: END, match: ), regex: 1
[main] line: 7, offset: 0, type: END, match: ), regex: 1
[document] foldings: [{"start":2,"end":3,"kind":3},{"start":0,"end":3,"kind":3}]
daiyam commented 3 years ago

Yep. It's a bug!

daiyam commented 3 years ago

I've having a conflict with a rule like:

{
    "name": "comment",
    "kind": "comment",
    "beginRegex": "^\\/\\/\\*",
    "endRegex": "^\\/\\/[^*]",
    "foldLastLine": false,
    "nested": false
}

where the last line shouldn't be consumed.

In your case, the last line has to be consumed.

I'm thinking to add the property consumeLast but not sure of the default value...

daiyam commented 3 years ago

I will add consumeEnd astrue by default

daiyam commented 3 years ago

It should be fixed in https://github.com/zokugun/vscode-explicit-folding/commit/c5cdea437c0e64a5cb8e66ea4e2281f6daf168b2.

FALLAI-Denis commented 3 years ago

I think I have a similar problem for handling comment line blocks.

Depending on the rules used, I don't get the same result.

Consider the following source code:

//MYJOB    JOB ,'MY JOB',CLASS=A,NOTIFY=&SYSUID
//****
//* FIRST COMMENT BLOCK
//****
//MYPROC   PROC P1='P1',                                               
//         P2='P2'
//*
//* SECOND COMMENT BLOCK
//* 
//MYSTEP   EXEC PGM=MYPROG
//STEPLIB  DD DISP=SHR,DSN=MY.LOADLIB
//IN       DD DISP=SHR,DSN=&P1
//OUT      DD DSN=&P2,
//            DISP=(NEW,CATLG),
//            SPACE=(CYL,(5,5),RLSE)
//*
//A         DD  dfjdlfj,
//            ldfjdflkj,
//            fkmfkdfpk
/*
//MYPROC   PEND
//*
//STEP     EXEC PROC=MYPROC,
//              P1='MY.FIC.ALPHA',
//              P2='MY.FIC.BETA'
//* That's all

The following rule works for all comment blocks, even those included in separator hierarchies ("First" and "Second" comment block):

             "name": "comment"
            ,"beginRegex": "^\\/\\/\\*"
            ,"endRegex": "^\\/\\/[^*]"
            ,"nested": false
            ,"foldLastLine": false
            ,"kind": "comment"

While the following rule only works for the 1st level of separator (only "First" comment block):

            "name": "comment",
            "beginRegex": "^\\/\\/\\*",
            "whileRegex": "^\\/\\/\\*",
            "foldLastLine": true,
            "nested": false,
            "kind": "comment"

Set of rules used:

    "[jcl]": {
        "files.autoGuessEncoding": true,
        "editor.rulers": [0,{"column":11,"color":"#603020"},{"column":15,"color":"#603020"},{"column":71,"color": "#603020"},{"column":72,"color": "#603020"},{"column":80,"color": "#ff0000"}],
        /* Requirement for Explicit Folding */
        "editor.folding": true,
        "editor.showFoldingControls": "always",
        "editor.foldingStrategy": "auto",
        "editor.foldingHighlight": true,
        /* Explicit Folding */
        "explicitFolding.debug": true,
        "explicitFolding.rules": [
           {// Bloc commentaires
            //"name": "comment",
            //"beginRegex": "^\\/\\/\\*",
            //"whileRegex": "^\\/\\/\\*",
            //"foldLastLine": true,
            //"nested": false,
            //"kind": "comment"

             "name": "comment"
            ,"beginRegex": "^\\/\\/\\*"
            ,"endRegex": "^\\/\\/[^*]"
            ,"nested": false
            ,"foldLastLine": false
            ,"kind": "comment"

           },
           {// DD
            "name": "dd",
            //"separatorRegex": "^\\/\\/[^*]\\S* +DD "
            "beginRegex": "^\\/\\/[^*]\\S* +DD ",
            "continuationRegex": "^\\/\\/(\\*|\\S* +DD \\S+,(?: |$)| +\\S+,(?: |$))",
            "nested": true
           },

           {// JOB
            "name": "job",
            "separatorRegex": "^\\/\\/[^*]\\S* +JOB(?: |$)",
            "strict": "never",
            "nested": [
               {// PROC - PEND
                "name": "proc",
                "beginRegex": "^\\/\\/[^*]\\S* +PROC(?: |$)",
                "endRegex": "^\\/\\/[^*]\\S* +PEND(?: |$)",
                "foldLastLine": true,
                "strict": "never",
                "nested": [
                    {// EXEC
                     "name": "exec",
                     "separatorRegex": "^\\/\\/[^*]\\S* +EXEC ",
                     "strict": "never",
                     "nested": true
                     //"nested": [
                     //   {// DD
                     //    "name": "dd",
                     //    //"separatorRegex": "^\\/\\/[^*]\\S* +DD "
                     //    "beginRegex": "^\\/\\/[^*]\\S* +DD ",
                     //    "continuationRegex": "^\\/\\/(\\*|\\S* +DD \\S+,(?: |$)| +\\S+,(?: |$))"
                     //   }
                     // ]
                    }
                  ]
                }
              ]
            }
          ]
      },

Same kind of problem with the rule concerning the row sequence "DD": works with the first occurrence ("OUT DD"), but does not work on the second occurrence ("A DD").

Note : full regex stop at "PROC"... do'nt understand wy...

[main] regex: /(?<_0_0>^\/\/\*)|(?<_4_1>^\/\/[^*]\S* +JOB(?: |$))|(?<_0_2>^\/\/[^*]\S* +PROC(?: |$))/g

Using version 0.14.4.

daiyam commented 3 years ago

@FALLAI-Denis For DD, can you reply in https://github.com/zokugun/vscode-explicit-folding/issues/48#issuecomment-866712662?

With the exception of DD, here the rule I have:

{ // JOB
    "name": "job",
    "separatorRegex": "^\\/\\/[^*]\\S* +JOB(?: |$)",
    "strict": "never",
    "nested": [
        { // PROC - PEND
            "name": "proc",
            "beginRegex": "^\\/\\/[^*]\\S* +PROC(?: |$)",
            "endRegex": "^\\/\\/[^*]\\S* +PEND(?: |$)",
            "nested": [
                { // EXEC
                    "name": "exec",
                    "separatorRegex": "^\\/\\/[^*]\\S* +EXEC ",
                    "nested": [
                        { // Bloc commentaires
                            "whileRegex": "^\\/\\/\\*",
                            "kind": "comment"
                        },
                    ]
                }
            ]
        }
    ]
}

Note : full regex stop at "PROC"... do'nt understand wy...

Yep, there is an issue with the repeated "strict": "never"...

FALLAI-Denis commented 3 years ago

So I understand that the declaration "strict": "never" must be declared at the first level of a hierarchy of separators and each lower level inherits this declaration.

In my implementation, foldLastine is present in the rules to assess its impact depending on whether it takes the value true or false.

daiyam commented 3 years ago

Yep, there is an issue with the repeated "strict": "never"...

@FALLAI-Denis The issue has been fixed in v0.14.5

daiyam commented 3 years ago

@HolyBlackCat Can you tell me if you are still having issues?

HolyBlackCat commented 3 years ago

Yep, everything works now, thanks! I didn't realize you rolled out a new version, sorry for the delay.