Code folding for Microsoft Visual Basic 2008

Syntax highlighting, code folding, brace matching, code indenting, and function list

Code folding for Microsoft Visual Basic 2008

Postby Ventolin » Wed Feb 17, 2010 1:52 pm

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).
Ventolin
Newbie
 
Posts: 4
Joined: Wed Feb 17, 2010 1:34 pm

Re: Code folding for Microsoft Visual Basic 2008

Postby Ventolin » Wed Feb 17, 2010 3:48 pm

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
Ventolin
Newbie
 
Posts: 4
Joined: Wed Feb 17, 2010 1:34 pm

Re: Code folding for Microsoft Visual Basic 2008

Postby Mofi » Thu Feb 18, 2010 2:16 am

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"
User avatar
Mofi
Grand Master
Grand Master
 
Posts: 4066
Joined: Thu Jul 29, 2004 11:00 pm
Location: Vienna

Re: Code folding for Microsoft Visual Basic 2008

Postby Ventolin » Fri Feb 19, 2010 10:32 am

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)?
Ventolin
Newbie
 
Posts: 4
Joined: Wed Feb 17, 2010 1:34 pm

Re: Code folding for Microsoft Visual Basic 2008

Postby Mofi » Fri Feb 19, 2010 11:08 am

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 Extra Downloads page.
User avatar
Mofi
Grand Master
Grand Master
 
Posts: 4066
Joined: Thu Jul 29, 2004 11:00 pm
Location: Vienna

Re: Code folding for Microsoft Visual Basic 2008

Postby Mofi » Sun Feb 21, 2010 9:38 am

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.
User avatar
Mofi
Grand Master
Grand Master
 
Posts: 4066
Joined: Thu Jul 29, 2004 11:00 pm
Location: Vienna

Re: Code folding for Microsoft Visual Basic 2008

Postby Ventolin » Mon Feb 22, 2010 1:38 pm

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
Ventolin
Newbie
 
Posts: 4
Joined: Wed Feb 17, 2010 1:34 pm


Return to Syntax Highlighting