[.net] Problem with syntax highlighting

Started by
1 comment, last by Zyndrof 17 years, 5 months ago
Hi there! I'm making a syntax highlighter and I've come a long way, everything works perfectly... as long as you write on the first line. When moving to the next lines and writing the words that are supposed to be highlighted only the first line is colored, with the color that's set for the most recent match, why does this occur and how can I solve it?
'searches teh text and colors it...
    Private Sub ExtendedRichTextBox_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ExtendedRichTextBox.TextChanged

        Dim selectionAt As Integer = ExtendedRichTextBox.SelectionStart

        'find out the linenumber...
        lineNumber = ExtendedRichTextBox.GetLineFromCharIndex(ExtendedRichTextBox.SelectionStart()) + 1

        If ExtendedRichTextBox.GetFirstCharIndexFromLine(lineNumber) = -1 Then
            line = ExtendedRichTextBox.Text.Substring(ExtendedRichTextBox.GetFirstCharIndexOfCurrentLine())
            startCharIndex = 0
        Else
            line = ExtendedRichTextBox.Text.Substring(startCharIndex, ExtendedRichTextBox.GetFirstCharIndexFromLine(lineNumber) - ExtendedRichTextBox.GetFirstCharIndexOfCurrentLine)
        End If

        'regular expression...
        Dim reg_exp As Regex

        'give reg_exp some values...
        For i As Integer = 0 To 4

            'give reg_exp a value from the array...
            reg_exp = New Regex(syntaxText(i))

            'search for matches...
            Dim match As Match
            match = reg_exp.Match(line)

            'give the match the right color...
            If reg_exp.IsMatch(line) Then

                With ExtendedRichTextBox
                    .Select(match.Index, match.Length)
                    .SelectionColor = syntaxColor(i)
                    .SelectionStart = selectionAt
                    .SelectionColor = textColor
                End With

            End If
        Next

    End Sub

Thank you in advance! [Edited by - Zyndrof on November 16, 2006 11:53:34 AM]
Advertisement
I think the following line is the cause of the headache:
.Select(match.Index, match.Length)

It returns the index into the string that you matched against, not the character index in the text box; you would always select the index into the RichTextBox text instead of going to the line and then indexing into it. Here is some code that does it for you (and it gets rid of the annoying flickering [smile])

Hope this helps.

Imports System.TextImports System.Text.RegularExpressionsPublic Class Form1    Dim textColor As Color = Color.Black    Dim syntaxColor As Color = Color.Blue    Dim keywords() As String = {"apple", "orange", "grape", "pear", "banana"}    ' this is used to prevent the flickering from all the selecting and deselecting    Declare Function LockWindowUpdate Lib "user32" (ByVal hwndLock As Integer) As Integer    Private Sub RichTextBox1_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles RichTextBox1.TextChanged        LockWindowUpdate(RichTextBox1.Handle)        Dim selectionStart As Integer = RichTextBox1.SelectionStart ' stores the caret position        Dim firstCharIndex = RichTextBox1.GetFirstCharIndexOfCurrentLine()        Dim lineNumber As Integer = RichTextBox1.GetLineFromCharIndex(firstCharIndex)        Dim currentLine As String = RichTextBox1.Lines(lineNumber)        ' first, make sure that the entire line is set to the text color        RichTextBox1.Select(firstCharIndex, currentLine.Length)        RichTextBox1.SelectionColor = textColor        ' build a regular expression string that contains all the keywords        Dim builder As StringBuilder = New StringBuilder()        For i As Integer = 0 To keywords.Length - 1            If i > 0 Then                builder.Append("|")            End If            builder.Append("\b" + keywords(i) + "\b")        Next        ' get each of the matches and set the text color to the syntaxColor value        Dim matches As MatchCollection = Regex.Matches(currentLine, builder.ToString(), RegexOptions.IgnoreCase)        For i As Integer = 0 To matches.Count - 1            With RichTextBox1                .Select(firstCharIndex + matches(i).Index, matches(i).Length)                .SelectionColor = syntaxColor                .SelectionStart = firstCharIndex + matches(i).Index + matches(i).Length                .SelectionColor = textColor            End With        Next        ' set the caret back to its starting position        RichTextBox1.SelectionStart = selectionStart        LockWindowUpdate(0)    End SubEnd Class


If you have any questions, feel free to drop me a line.
~del
Thank you! It works perfectly, now I will try to change the code to let the syntaxColor change for each word... :)

This topic is closed to new replies.

Advertisement