2
votes

I'm coding a simple code editor for a very simple scripting language we use at work. My syntax highlighting code works fine if I do it on the entire RichTextBox (rtbMain) but when I try to get it to work on just that line, so I can run the function with rtbMain changes, it gets weird. I can't seem to figure out why. Am I even going about this the right way?

rtbMain is the main text box. frmColors.lbRegExps is a listbox of words to highlight (later it will have slightly more powerful regular expressions.) frmColor.lbHexColors is another listbox with the corresponding hex colors for the words.

Private Sub HighLight(ByVal All As Boolean)
    Dim RegExp As System.Text.RegularExpressions.MatchCollection
    Dim RegExpMatch As System.Text.RegularExpressions.Match
    Dim FirstCharIndex As Integer = rtbMain.GetFirstCharIndexOfCurrentLine
    Dim CurrentLine As Integer = rtbMain.GetLineFromCharIndex(FirstCharIndex)
    Dim CurrentLineText As String = rtbMain.Lines(CurrentLine)
    Dim CharsToCurrentLine As Integer = rtbMain.SelectionStart
    Dim PassNumber As Integer = 0

    LockWindowUpdate(Me.Handle.ToInt32) 'Let's lock the window so it doesn't scroll all crazy.
    If All = True Then 'Highlight everything.
        For Each pass In frmColors.lbRegExps.Items
            RegExp = System.Text.RegularExpressions.Regex.Matches(LCase(rtbMain.Text), LCase(pass))
            For Each RegExpMatch In RegExp
                rtbMain.Select(RegExpMatch.Index, RegExpMatch.Length)
                rtbMain.SelectionColor = ColorTranslator.FromHtml(frmColors.lbHexColors.Items(PassNumber))
            Next
            PassNumber += 1
        Next
    Else 'Highlight just that row.
        For Each pass In FrmColors.lbRegExps.Items
            RegExp = System.Text.RegularExpressions.Regex.Matches(LCase(CurrentLineText), LCase(pass))
            For Each RegExpMatch In RegExp
                rtbMain.Select(RegExpMatch.Index + (CharsToCurrentLine - RegExpMatch.Length), RegExpMatch.Length)
                rtbMain.SelectionColor = Color.Blue
            Next
        Next
    End If

    rtbMain.Select(CharsToCurrentLine, 0) 'Reset colors and positon and then unlock drawing.
    rtbMain.SelectionColor = Color.Black
    LockWindowUpdate(0)
End Sub
3
What do you mean by "it gets weird"?EndangeredMassa
Have you ever used Notepad++? It's really easy to create syntax highlighting for a user defined language and so you wouldn't even need to write this. Of course you might have other reasons but if you're just creating a standalone editor it's something to consider.Bryan Anderson
Any code can get weird if it is preceded by "On Error Resume Next ".... =P. But seriously exactly what is it doing when it's trying just to parse a single line?Quintin Robinson
by getting weird i mean it highlights seemingly random stuff. I removed that On error bit lol :P and right now we use notepad++ and textpad, both are very nice but im looking to add more power than they have.The Digital Ninja

3 Answers

11
votes

Ok I figured it out. I was calling the even on rtbMain.TextChange thinking that this would only trigger if the text actually changed. Nay Nay, it will also trigger if formatting is changed. so each time it changed something while it was doing its first pass and highlighting everything, it would then trigger to highlight the line. It would do this until there was nothing left to change.

I set a boolean variable for weather or not it was currently highlighting and added an if condition inside the TextChange sub

P.S. I don't have the self-learner badge so any up ratings would be welcome :P

2
votes

This doesn't really answer your question, but if you're writing your own editor you may be better off using some existing open source work that's been done for .NET. I'd recommend:

Roger Alsing's SyntaxBox

0
votes
Private Sub HighLight(ByVal All As Boolean)
    Dim RegExp As System.Text.RegularExpressions.MatchCollection
    Dim RegExpMatch As System.Text.RegularExpressions.Match
    Dim FirstCharIndex As Integer = rtbMain.GetFirstCharIndexOfCurrentLine
    Dim CurrentLine As Integer = rtbMain.GetLineFromCharIndex(FirstCharIndex)
    Dim CurrentLineText As String = rtbMain.Lines(CurrentLine)
    Dim CharsToCurrentLine As Integer = rtbMain.SelectionStart
    Dim PassNumber As Integer = 0

    LockWindowUpdate(Me.Handle.ToInt32) ''lets lock the window so it doesnt scroll all crazy 
    If All = True Then ''highlight everything
        For Each pass In frmColors.lbRegExps.Items
            RegExp = System.Text.RegularExpressions.Regex.Matches(LCase(rtbMain.Text), LCase(pass))
            For Each RegExpMatch In RegExp
                rtbMain.Select(RegExpMatch.Index, RegExpMatch.Length)
                rtbMain.SelectionColor = ColorTranslator.FromHtml(frmColors.lbHexColors.Items(PassNumber))
            Next
            PassNumber += 1
        Next
    Else ''higlight just that row 
        For Each pass In FrmColors.lbRegExps.Items
            RegExp = System.Text.RegularExpressions.Regex.Matches(LCase(CurrentLineText), LCase(pass))
            For Each RegExpMatch In RegExp
                rtbMain.Select(RegExpMatch.Index + (CharsToCurrentLine - RegExpMatch.Length), RegExpMatch.Length)
                rtbMain.SelectionColor = Color.Blue
            Next
        Next
    End If

    rtbMain.Select(CharsToCurrentLine, 0) ''reset colors and positon and then unlock drawing
    rtbMain.SelectionColor = Color.Black
    LockWindowUpdate(0)
End Sub