1

I have some application that parses source code of a programming language. I'm using System.Windows.Forms.RichTextBox as a code editor. I highlight language's keywords with the following alogrithm:

  • Whenever text is changed, back to the beginning of the last word, call this substring word.
  • If the keywords contains word then set color of word to blue
    Otherwise set color of word to black

I am using RichTextBox.SelectionStarts, RichTextBox.Select(int, int) and RichTextBox.SelectionColor. That is working just fine.

However, when I press Enter key, the cursor backs to most begin of the line. As a source-code editor, I want it to follow the last line begging. I put the padding white space characters from the previous line in a string str, and then richTextBox.Text = richTextBox.Text.Insert(richTextBox.SelectionStarts, str). When I do so, all text highlighting is corrupted, that all text is in blue color.

Can anyone give a suggestion how to append line padding spaces without corrupting the highlighting?

  • Assign the SelectionText property to insert text without destroying the formatting of existing text. Opposite of http://stackoverflow.com/questions/7271550/removing-richtextbox-lines-while-keeping-the-colour-of-remaining-lines-in-c-shar/7273057#7273057 – Hans Passant Jul 19 '12 at 17:08
  • @HansPassant Can you put your comment as an answer? I would accept it. Or prefer to close question as an exact duplicate ? :P :P –  Jul 19 '12 at 17:14
  • @HansPassant Besides, it is `SelectedText`, not `SelectionText` :P :P –  Jul 19 '12 at 17:22

2 Answers2

2

No clue what is the exact problem of your code. Maybe you should look at the established solutions. E.g., Scintilla.NET is a .NET wrapper for the well-known Scintilla control. It is extensible with custom lexers so it might suit your needs.

Viktor Latypov
  • 14,289
  • 3
  • 40
  • 55
0

Ah, I see. Here is a good start:

Put this at the very top of your form:

using System.Text.RegularExpressions;

Then put this into the RichTextBox TextChanged:

            // getting keywords/functions
            string keywords = @"\b(abstract|as|base|break|case|catch|checked|continue|default|delegate|do|else|event|explicit|extern|false|finally|fixed|for|foreach|goto|if|implicit|in|interface|internal|is|lock|namespace|new|null|object|operator|out|override|params|private|protected|public|readonly|ref|return|sealed|sizeof|stackalloc|switch|this|throw|true|try|typeof|unchecked|unsafe|using|virtual|volatile|while)\b";
            MatchCollection keywordMatches = Regex.Matches(codeRichTextBox.Text, keywords);

            // getting types/classes from the text 
            string types = @"\b(Console)\b";
            MatchCollection typeMatches = Regex.Matches(codeRichTextBox.Text, types);

            // getting comments (inline or multiline)
            string comments = @"(\/\/.+?$|\/\*.+?\*\/)";
            MatchCollection commentMatches = Regex.Matches(codeRichTextBox.Text, comments, RegexOptions.Multiline);

            // getting strings
            string strings = "\".+?\"";
            MatchCollection stringMatches = Regex.Matches(codeRichTextBox.Text, strings);

            string stringz = "bool|byte|char|class|const|decimal|double|enum|float|int|long|sbyte|short|static|string|struct|uint|ulong|ushort|void";
            MatchCollection stringzMatchez = Regex.Matches(codeRichTextBox.Text, stringz);

            // saving the original caret position + forecolor
            int originalIndex = codeRichTextBox.SelectionStart;
            int originalLength = codeRichTextBox.SelectionLength;
            Color originalColor = Color.Black;

            // MANDATORY - focuses a label before highlighting (avoids blinking)
            label1.Focus();

            // removes any previous highlighting (so modified words won't remain highlighted)
            codeRichTextBox.SelectionStart = 0;
            codeRichTextBox.SelectionLength = codeRichTextBox.Text.Length;
            codeRichTextBox.SelectionColor = originalColor;

            // scanning...
            foreach (Match m in keywordMatches)
            {
                codeRichTextBox.SelectionStart = m.Index;
                codeRichTextBox.SelectionLength = m.Length;
                codeRichTextBox.SelectionColor = Color.Blue;
            }

            foreach (Match m in typeMatches)
            {
                codeRichTextBox.SelectionStart = m.Index;
                codeRichTextBox.SelectionLength = m.Length;
                codeRichTextBox.SelectionColor = Color.DarkCyan;
            }

            foreach (Match m in commentMatches)
            {
                codeRichTextBox.SelectionStart = m.Index;
                codeRichTextBox.SelectionLength = m.Length;
                codeRichTextBox.SelectionColor = Color.Green;
            }

            foreach (Match m in stringMatches)
            {
                codeRichTextBox.SelectionStart = m.Index;
                codeRichTextBox.SelectionLength = m.Length;
                codeRichTextBox.SelectionColor = Color.Brown;
            }

            foreach (Match m in stringzMatchez)
            {
                codeRichTextBox.SelectionStart = m.Index;
                codeRichTextBox.SelectionLength = m.Length;
                codeRichTextBox.SelectionColor = Color.Purple;
            }

            // restoring the original colors, for further writing
            codeRichTextBox.SelectionStart = originalIndex;
            codeRichTextBox.SelectionLength = originalLength;
            codeRichTextBox.SelectionColor = originalColor;

            // giving back the focus
            codeRichTextBox.Focus();

That will provide RichTextBox coding syntax for C#

If you want coding syntax for another language, replace the contents of the keywords string, and the contents of the stringz string, with the language of your choice.

To change the Color of the keywords, or stringz, then look at the foreach (Match m in keywordMatches), or foreach (Match m in stringzMatchez)

If you are doing any other language than C#, then remove types, and edit the strings and comments

I hope this helps you :)

Momoro
  • 599
  • 4
  • 23