Code folding for Microsoft Visual Basic 2008

Code folding for Microsoft Visual Basic 2008

4
NewbieNewbie
4

    Feb 17, 2010#1

    Hi,

    I have been trying to get code folding working properly with MS Visual Basic 2008 .net and update the existing VB templates for this version. I am running UE Studio 09.30.0.1002 and have also tried UE 15.20.0.1022 with the same results (same language file).

    However, I have been unable to get If... Then... with a comment folding correctly.

    For example:

    Code: Select all

    If a = b Then
        'This comment here allows the If... Then statement to fold correctly
        a = 1
    End If
    
    If a = b Then 'This If statement with a comment does not fold
        b = 1
    End If
    (The indentation for the above two examples works as expected).

    The current workaround would be to simply move the comment after the "Then" statement to the next line to get the If... Then... statement to fold correctly.

    Is there any way to get comments on the same line as the If.. Then.. and have folding working?

    TIA

    Vent

    Here's my current VB.NET language file, updated with XML block comments and some compiler directives (replaced by newer wordfile, see below).

      Feb 17, 2010#2

      Hi,

      I also have discovered another issue with Do While loops...

      Code: Select all

              Do While a<=2
                  'This Does Not Fold correctly
                  a += 1
              Loop
      
              Do
                  'This Folds correctly
                  a += 1
              Loop
              
              Do
                  'This Does Not Fold correctly
                  a += 1
              Loop While a <= 2
              
               While a <= 2
                  'This Folds correctly
                  a += 1
              End While
      Do While... and ...Loop While don't fold correctly.

      Here's the modified language file snippet:

      Code: Select all

      /Open Fold Strings = "Partial Class" "Class" "Function" "Sub" "Structure" "#Region" "#If" "#Else" "Try" "Catch" "For" "With" "If" "ElseIf" "Else" "Select Case" "Do While" "Do" "While"
      /Close Fold Strings = "End Class" "End Function" "End Sub" "End Structure" "#End Region" "#End If" "#Else" "End Try" "Catch" "Next" "End With" "ElseIf" "Else" "End If" "End Select" "Loop" "End While" "Loop While"
      /Ignore Fold Strings = "Exit Function" "Exit Sub" "Exit For" "Declare Function" "Continue For" "Case Else" "Exit Do" "Exit While"
      I also found another oddity:

      If I have a variable with the word "Then" inside it, the folding also fails!

      Code: Select all

              If AThenB Then
                  a=b
              End If
      Any ideas on how to fix this situation also?

      Thanks for your help!

      Regards,

      Vent

      6,681583
      Grand MasterGrand Master
      6,681583

        Feb 18, 2010#3

        Okay, first I remembered that a customized code folding for Visual Basic files is a problem because of the internal code folding defaults, for details see Code folding issue with my BASIC files. So first you have to replace keyword VB_LANG by also known language marker keyword PUREBASIC_LANG in the first line of your wordfile. That disables all internal code folding defaults as a test without any open/close fold strings in the wordfile showed me. If there is VB_LANG in the wordfile, code folding finds blocks to fold even when the wordfile does not contain any open/close fold strings.

        Next I experimented with the fold strings by adding one after the other and evaluate the result on a *.vb file with all your examples. As I found out it is necessary to close UltraEdit and restart it after modifying the open/close fold strings in the wordfile and saving the wordfile to force the code folding engine to use the new fold strings. However, finally I found the fold strings which results in correct code folding for all your examples (hopefully because I don't know the syntax of Visual Basic files).

        /Open Fold Strings = "Function" "Sub" "Structure" "#Region" "#If" "#Else" "Try" "Catch" "For" "With" "Select Case" "Class" "If" "ElseIf" "Else" "Do" "While"
        /Close Fold Strings = "End Function" "End Sub" "End Structure" "#End Region" "#End If" "#Else" "End Try" "End Catch" "Next" "End With" "End Select" "End Class" "End If" "ElseIf" "Else" "Loop" "End While"
        Best regards from an UC/UE/UES for Windows user from Austria

        4
        NewbieNewbie
        4

          Feb 19, 2010#4

          Hi Mofi,

          Thank you very much for your help!

          Your language file does indeed fix the examples that I have given, but unfortunately doesn't work if the commands are wrapped inside a sub or a class definition. For example:

          This example works correctly:

          Code: Select all

          Class TestClass
          
          Sub Test()
          
                  If AThenB Then
                      a=b
                  End If
          
                   While a <= 2
                      'This Folds correctly
                      a += 1
                  End While
                  
                  Do
                      'This Folds correctly
                      a += 1
                  Loop
          
          End Sub
          
          End Class
          However, if I put either the "Do While or "Loop While" loops in the sub it fails:

          Code: Select all

          Class TestClass
          
          Sub Test()
          
                  If AThenB Then
                      a=b
                  End If
          
                   While a <= 2
                      'This Folds correctly
                      a += 1
                  End While
                  
                  Do
                      'This Folds correctly
                      a += 1
                  Loop
                                   
                  Do While a<=2
                      'This Does Not Fold correctly
                      a += 1
                  Loop
          
                  Do
                      'This Does Not Fold correctly
                      a += 1
                  Loop While a <= 2
          
          End Sub
          
          End Class
          I have tried playing with the language file again but can not get the folding to work.

          Here is the language file modified with the duplicates removed as you suggested.

          Code: Select all

          /L21"VB_NET" PUREBASIC_LANG DisableMLS Nocase Line Comment = ' File Extensions = BAS FRM CLS VBS ASP INC VB
          /Colors = 0,32768,8421376,1381796,255,
          /Colors Back = 16777215,16777215,16777215,16777215,16777215,
          /Colors Auto Back = 1,1,1,1,1,
          /Font Style = 0,0,0,0,0,
          /Delimiters = ~!@%^&*()-+=|\/{}[]:;"'<> ,	.?
          /Function String = "%*^{Sub ^}^{Function ^}*("
          /Open Brace Strings = "{" "(" "[" "<"
          /Close Brace Strings = "}" ")" "]" ">"
          /Indent Strings = "Then" "Select Case" "Do While" "Do Until" "Else" "Do" "<td>" "<tr>"
          /Unindent Strings = "End" "Next" "End If" "End Select" "Loop" "End Select" "Loop While" "Else" "</TD>" "</tr>"
          /Ignore Fold Strings = "Exit Function" "Exit Sub" "Exit For" "Declare Function" "Continue For" "Case Else" "Exit Do" "Exit While"
          /Open Fold Strings = "Function" "Sub" "Structure" "#Region" "#If" "#Else" "Try" "Catch" "For" "With" "Select Case" "Class" "If" "ElseIf" "Else" "Do" "While"
          /Close Fold Strings = "End Function" "End Sub" "End Structure" "#End Region" "#End If" "#Else" "End Try" "End Catch" "Next" "End With" "End Select" "End Class" "End If" "ElseIf" "Else" "Loop" "End While"
          /Open Comment Fold Strings = "<summary>"
          /Close Comment Fold Strings = "</remarks>"
          /C1"CONSTANTS" Colors = 16711680 Colors Back = 16777215 Colors Auto Back = 1 Font Style = 0
          3DDKSHADOW 3DHIGHLIGHT 3DLIGHT
          ABORT ABORTRETRYIGNORE ACTIVEBORDER ACTIVETITLEBAR ALIAS APPLICATIONMODAL APPLICATIONWORKSPACE ARCHIVE
          BACK BINARYCOMPARE BLACK BLUE BUTTONFACE BUTTONSHADOW BUTTONTEXT
          CANCEL CDROM CR CRITICAL CRLF CYAN
          DEFAULT DEFAULTBUTTON1 DEFAULTBUTTON2 DEFAULTBUTTON3 DESKTOP DIRECTORY
          EXCLAMATION
          FALSE FIXED FORAPPENDING FORMFEED FORREADING FORWRITING FROMUNICODE
          GRAYTEXT GREEN
          HIDDEN HIDE HIGHLIGHT HIGHLIGHTTEXT HIRAGANA
          IGNORE INACTIVEBORDER INACTIVECAPTIONTEXT INACTIVETITLEBAR INFOBACKGROUND INFORMATION INFOTEXT
          KATAKANA
          LF LOWERCASE
          MAGENTA MAXIMIZEDFOCUS MENUBAR MENUTEXT METHOD MINIMIZEDFOCUS MINIMIZEDNOFOCUS MSGBOXRIGHT
          MSGBOXRTLREADING MSGBOXSETFOREGROUND
          NARROW NEWLINE NO NORMAL NORMALFOCUS NORMALNOFOCUS NULLSTRING
          OBJECTERROR OK OKCANCEL OKONLY
          PROPERCASE
          QUESTION
          RAMDISK READONLY RED REMOTE REMOVABLE RETRY RETRYCANCEL
          SCROLLBARS SYSTEMFOLDER SYSTEMMODAL
          TEMPORARYFOLDER TEXTCOMPARE TITLEBARTEXT TRUE
          UNICODE UNKNOWN UPPERCASE
          VERTICALTAB VOLUME
          WHITE WIDE WIN16 WIN32 WINDOWBACKGROUND WINDOWFRAME WINDOWSFOLDER WINDOWTEXT
          YELLOW YES YESNO YESNOCANCEL
          /C2"DATATYPES" Colors = 16711680 Colors Back = 16777215 Colors Auto Back = 1 Font Style = 0
          BOOLEAN BYTE
          DATE DECIMIAL DOUBLE
          INTEGER
          LONG
          OBJECT
          SINGLE STRING
          /C3"KEYWORDS" Colors = 16711680 Colors Back = 16777215 Colors Auto Back = 1 Font Style = 0
          ADDHANDLER As ASSEMBLY AUTO
          BEGINEPILOGUE Binary ByRef ByVal
          Else ElseIf Empty ENDPROLOGUE ENVIRON Error EXTERNALSOURCE
          For Friend
          GET
          HANDLES
          Input Is
          Len Lock
          Me Mid MUSTINHERIT MYBASE MYCLASS
          New Next Nothing NOTINHERITABLE NOTOVERRIDABLE Null
          OFF On Option Optional OVERRIDABLE
          ParamArray Partial Print Private Property Public
          Resume
          Seek SENDKEYS SET SHELL Static Step
          Then THROW Time To
          WithEvents
          /C4"OBJECTS" Colors = 0 Colors Back = 16777215 Colors Auto Back = 1 Font Style = 0
          COLLECTION
          DEBUG DICTIONARY DRIVE DRIVES
          ERR
          FILE FILES FILESYSTEMOBJECT FOLDER FOLDERS
          TEXTSTREAM
          /C5"OPERATORS" Colors = 0 Colors Back = 16777215 Colors Auto Back = 1 Font Style = 0
          &
          *
          +
          -
          // /
          =
          \
          ^
          ADDRESSOF
          BITAND BITNOT BITOR BITXOR
          GETTYPE
          LIKE
          MOD
          XOR
          /C6"STATEMENTS" Colors = 16711680 Colors Back = 16777215 Colors Auto Back = 1 Font Style = 0
          #Const #End #If #Region
          AND ANDALSO APPACTIVATE
          BEEP
          CALL CASE CATCH CHDIR CHDRIVE CLASS CONST
          DECLARE DELEGATE DELETESETTING DIM DO DOEVENTS
          EACH END ENUM EVENT EXIT
          FINALLY FUNCTION
          IF IMPLEMENTS IMPORTS INHERITS INTERFACE
          KILL
          LOOP
          NAMESPACE NOT
          OPEN OR ORELSE
          PUT
          RAISEEVENT RANDOMIZE REDIM REM RESET
          SAVESETTING SELECT SETATTR SHADOWS STOP STRUCTURE SUB SWITCH SYNCLOCK
          TRY
          WHILE WIDTH WITH WRITE
          /C7"FUNCTIONS" Colors = 16711680 Colors Back = 16777215 Colors Auto Back = 1 Font Style = 0
          ABS ARRAY ASC ASCB ASCW
          CALLBYNAME CBOOL CBYTE CCHAR CCHR CDATE CDBL CDEC CHOOSE CHR CHR$ CHRB CHRB$ CHRW CINT CLNG CLNG8 CLOSE
          COBJ COMMAND COMMAND$ CONVERSION COS CREATEOBJECT CSHORT CSTR CTYPE CURDIR CVDATE
          DATEADD DATEDIFF DATEPART DATESERIAL DATEVALUE DAY DDB DIR DIR$
          EOF ERROR$ EXP
          FILEATTR FILECOPY FILEDATATIME FILELEN FILTER FIX FORMAT FORMAT$ FORMATCURRENCY FORMATDATETIME
          FORMATNUMBER FORMATPERCENT FREEFILE FV
          GETALLSETTINGS GETATTRGETOBJECT GETSETTING
          HEX HEX$ HOUR
          IIF IMESTATUS INPUT$ INPUTB INPUTB$ INPUTBOX INSTR INSTRB INSTRREV INT IPMT IRR ISARRAY ISDATE ISEMPTY
          ISERROR ISNULL ISNUMERIC ISOBJECT
          JOIN
          LBOUND LCASE LCASE$ LEFT LEFT$ LEFTB LEFTB$ LENB LINEINPUT LOC LOF LOG LTRIM LTRIM$
          MID$ MIDB MIDB$ MINUTE MIRR MKDIR MONTH MONTHNAME MSGBOX
          NOW NPER NPV
          OCT OCT$
          PARTITION PMT PPMT PV
          RATE REPLACE RIGHT RIGHT$ RIGHTB RIGHTB$ RMDIR RND RTRIM RTRIM$
          SECOND SIN SLN SPACE SPACE$ SPC SPLIT STR STR$ STRCOMP STRCONV STRING$ STRREVERSE SYD
          TAB TAN TIMEOFDAY TIMER TIMESERIAL TIMEVALUE TODAY TRIM TRIM$ TYPENAME
          UBOUND UCASE UCASE$
          VAL
          WEEKDAY WEEKDAYNAME
          YEAR
          /C8"DEPRECATED" Colors = 16711680 Colors Back = 16777215 Colors Auto Back = 1 Font Style = 0
          ANY ATN
          CALENDAR CIRCLE CURRENCY
          DEFBOOL DEFBYTE DEFCUR DEFDATE DEFDBL DEFDEC DEFINT DEFLNG DEFOBJ DEFSNG DEFSTR DEFVAR
          EQV
          GOSUB
          IMP INITIALIZE ISMISSING
          LET LINE LSET
          RSET
          SGN SQR
          TERMINATE
          VARIANT VARTYPE
          WEND
          In another issue I also have issues with the following:

          Code: Select all

                  Select Case a
                      Case 1
                          b=1
                      Case 2
                          b=2
                      Case Else
                          b=0
                  End Select
          I have not been able to get the "Select Case" to fold at all correctly, though just having "Select Case" as an open fold statement and "End Select" as a close fold statement does fold the entire Select Case segment.

          BTW, are you sure you need to restart UE/US for the updated language file to be recognised? It seems to work if you just reselect the language under Menu View - View As...

          Thank you again for your help!

          Regards,

          Vent

          PS. Is there a language file for the language file (.uew files)?

          6,681583
          Grand MasterGrand Master
          6,681583

            Feb 19, 2010#5

            I answer here what I can quickly answer. On weekend I will look into the remaining code folding problems.
            Ventolin wrote:I have not been able to get the "Select Case" to fold at all correctly, though just having "Select Case" as an open fold statement and "End Select" as a close fold statement does fold the entire Select Case segment.
            I have long time ago given up to get case sections in C/C++ to indent/unindent and fold/unfold correctly because it simply does not work. The main reason why I have given up is that in general it is a bad design (for C/C++) when case sections have so many lines that individual folds are really needed. I have looked into my C/C++ files and have found nowhere a case where I would really need folding of individual case sections and therefore have never looked deeper into it.
            Ventolin wrote:BTW, are you sure you need to restart UE/US for the updated language file to be recognised? It seems to work if you just reselect the language under Menu View - View As...
            Good idea! I did not try that. Normally I have a highlighted sample file and the wordfile opened side-by-side, and after saving the wordfile and setting the focus to the sample file the changes are applied immediately. That works for the words in the color groups and the function list, but as I found out during my experiments not reliable for the code folding. Thanks for this hint.
            Ventolin wrote:Is there a language file for the language file (.uew files)?
            Yes, the wordfile you can download with a click on Wordfile Editing on the user-submitted wordfiles page.

              Feb 21, 2010#6

              I played with the fold strings and can nothing other say than you better remove "While" and "End While" from the Open respectively Close Fold Strings and contact IDM support by email.

              I found out that with language marker VB_LANG or VBSCRIPT_LANG internally the following Open/Close Fold Strings are set:

              "If" "For" "Select Case" "Else" "ElseIf" "Do While"
              "End If" "Next" "Else" "ElseIf" "End Select" "Loop"


              But according to your examples this is not enough. Better would be:

              /Open Fold Strings = "Class" "Function" "Sub" "Structure" "#Region" "#If" "#Else" "Try" "Catch" "For" "With" "Select Case" "If" "ElseIf" "Else" "Do" "While"
              /Close Fold Strings = "End Class" "End Function" "End Sub" "End Structure" "#End Region" "#End If" "#Else" "End Try" "End Catch" "Next" "End With" "End Select" "End If" "ElseIf" "Else" "Loop" "End While"


              But with "While" as open fold string Do While and Loop While are a problem. In other languages like in HTML it is possible that more than one open/close fold string can be on the same line, for example <div class="body"><div class="header">. Therefore the code folding engine interprets Do While as start of 2 blocks for folding and Loop While as close for 1 block and open for 1 other block with the result that everything below is interpreted wrong. Also normally the order of open/close fold strings defined in the wordfile (or internally) is not important and therefore it is not possible to define open/close fold strings which are parts of other, longer open/close fold strings.

              That's the reason why every try to get your examples fold correct must fail. A solution would be that VB_LANG is used and with this keyword the code folding engine uses additionally 2 rules:
              1. The code folding engine searches in a line for open/close fold string in the order as defined in the wordfile (or internally).
              2. Scanning a line for open/fold is stopped after first open or close fold string is found.
              With these 2 special code folding rules enabled by language marker keyword VB_LANG or VBSCRIPT_LANG and perhaps also with PUREBASIC_LANG the open/close fold strings as written above would work.

              Alternatively second special rule would not be needed when first rule is implemented and following is defined in the wordfile:

              /Open Fold Strings = "Class" "Function" "Sub" "Structure" "#Region" "#If" "#Else" "Try" "Catch" "For" "With" "Select Case" "If" "ElseIf" "Else" "Do While" "Do" "While"
              /Close Fold Strings = "End Class" "End Function" "End Sub" "End Structure" "#End Region" "#End If" "#Else" "End Try" "End Catch" "Next" "End With" "End Select" "End If" "ElseIf" "Else" "Loop While" "Loop" "End While"


              The order of the open/close fold strings is very important here because "Do" is just a part of "Do While" and "Loop" and "While" are parts of "Loop While".


              While playing with the code folding engine I get a better understanding how it probably works internally and now I understand why it must fail for case sections.

              "Case" is start of a block and at the same time also the end of the block above, EXCEPT when block above starts with "Select Case" - 1st special rule. Additionally "Case Else" is the close fold string for the case block above - 2nd special rule. And the block starting with "Select Case" or last block with just "Case" ends with "End Select" - 3rd special rule. And last "End Select" is at the same time also the end of the block starting with "Select Case" - 4th special rule. So to get case conditions correct folding completely these 4 special rules must be implemented for syntax highlighting of files using a wordfile with VB_LANG or VBSCRIPT_LANG.

              The same problem for case conditions exists for C/C++. A switch block starts with { and ends with }. Inside this block there are the case and default keywords. The same 4 rules would be necessary for C/C++ to get the entire switch block with its subblocks correct folded. Just the strings are different in comparison to BASIC languages.

              Conclusion: Send an email with this text as enhancement request to IDM support. Add for the developers a sample file containing as much foldable blocks nested (using all open/fold strings) as possible with comments what should fold.

              PS: I have sent an email to IDM about the problem that function list and highlighting of a file is updated automatically when the wordfile used is updated and saved in the same instance of UltraEdit and the highlighted file gets back the focus, but the code folding engine is not executed in this case. I found out that simply using File - Revert to Saved of the not modified sample file works also for forcing the code folding engine to rescan the file with the updated open/fold strings. I have assigned key F4 to command Revert to Saved, but non for the highlighting languages and therefore pressing F4 was the best method for me to force the code folding engine to rescan the current sample file with the updated open/close fold strings.
              Best regards from an UC/UE/UES for Windows user from Austria

              4
              NewbieNewbie
              4

                Feb 22, 2010#7

                Hi Mofi,

                Thank you very much for your very detailed explanation!

                I would have to agree with you that it is not possible to get the folding right with just the language file alone.

                I have also come up with a language file workaround that can be used instead of trying the get the folding working correctly and may also help to write better code:

                Code: Select all

                /Open Comment Fold Strings = "<summary>" "<Region>"
                /Close Comment Fold Strings = "</remarks>" "</Region>"
                (The above code includes standard XML comments syntax for Visual Studio & Visual Basic, <Summary> and </Remarks> which is accepted by visual studio before function, subroutine, class and structure statements).

                Here I have defined a custom comment fold string "<Region>" and "</Region>" which would force a fold in any block of code. Furthermore as these are comment fold blocks a comment can be added after the <Region> tag which is displayed when the code is folded. In this way I can remove the problem fold statement from the language file and also use the comments to highlight what the code does inside the fold.

                For example:

                Code: Select all

                    '<Region> While Folding Test
                    While a <= 2            'This Folds correctly
                        a += 1
                    End While
                    '</Region>
                So I think until the developers add support for what I consider to be major languages (Visual Studio languages) the <region> comment tag will work quite satisfactorily for now. I think also this tag could be used in other languages with similar folding issues. You could also use <Div> and </Div> instead of <Region> or anything else for that matter!

                Thank you for the hint about Revert to Saved forcing the folding engine to refresh as this will certainly help save time debugging language files. I think this also works if you just save a modified file.

                Best Regards and thanks again,

                Vent