RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

Syntax Highlighting Trouble

WarAngel

Wanderer
Syntax Highlighting Trouble

I'm trying to make a program that I can use which will highlight certains keywords in the script a certain color. This works fine if the file is relatively small, but once the file gets to be around 1 megabyte in size, it takes nearly 5-10 minutes which is not really plausible. I have used other programs, such as EditPlus, which parse a whole file, no matter the size, in a matter of seconds. Does anyone know of a better way to do syntax highlighting stuff? (Note: the text box is simply a RichTextBox control)

Code:
        private void ParseText()
        {
            string text = this.scriptText.Text;
            foreach (string myString in Globals.SyntaxColor.RedKeys)
            {
                Regex matchCheck = new Regex(myString);
                int numMatches = matchCheck.Matches(text).Count;
                foreach (Match match in matchCheck.Matches(text))
                {
                    scriptText.SelectionStart = match.Index;
                    scriptText.SelectionLength = match.Length;
                    scriptText.SelectionColor = Color.Red;
                }
            }
            foreach (string myString in Globals.SyntaxColor.BlueKeys)
            {
                Regex matchCheck = new Regex(myString);
                int numMatches = matchCheck.Matches(text).Count;
                foreach (Match match in matchCheck.Matches(text))
                {
                    scriptText.SelectionStart = match.Index;
                    scriptText.SelectionLength = match.Length;
                    scriptText.SelectionColor = Color.Red;
                }
            }
            foreach (string myString in Globals.SyntaxColor.GreenKeys)
            {
                Regex matchCheck = new Regex(myString);
                int numMatches = matchCheck.Matches(text).Count;
                foreach (Match match in matchCheck.Matches(text))
                {
                    scriptText.SelectionStart = match.Index;
                    scriptText.SelectionLength = match.Length;
                    scriptText.SelectionColor = Color.Red;
                }
            }
            scriptText.SelectionStart = 0;
            scriptText.SelectionLength = 0;
}
 

Courageous

Wanderer
I'll let you in on a secret. A goodly number of these tools that you refer to, that "parse the whole file in a manner of seconds," actually use lazy evaluation to do their job. IOW, they understand what's in the window, what needs to be displayed, and basically only display that.

While I get the idea you are doing this for fun, there are already customizable color hiliting editors out there, like vim.

http://www.vim.org

C//
 

WarAngel

Wanderer
Any ideas where I could find out how to do the so-called "lazy evaluation" technique to accomplish something a bit faster than what I'm using now? You are right that it's just for fun, but I still hope to complete it or at least try to find a solution to the problem, in an attempt to expand my knowledge. :)

Thanks for the editor btw.
 

Courageous

Wanderer
Well, they're generally easy enough. What you have to do is make your application "view fulstrum aware". In otherwords, you need to write some code that knows how much of your edited area is on screen. You then need to hook up a scroll bar to know how much is off screen, so that it is proportional, and lets the users scroll around.

(this can have an additional benefit: once you're this far, you can stream your code in and out of files, without loading the whole file; it's basically the same optimization for hiliting as it is for large-file editing).

It gets a bit tricky, mostly because of comments. Theoretically, the begin tag for a comment can be waaaay to the "north". If the code doesn't know about it, code currently in the view won't be hilited correctly. I think even vim needs to do some kind of "look ahead," and it can fail if the comment gets to be larger than the look ahead quantity.

There are more precise ways, but understand that vim wants to be fast.

C//
 
Not sure if this would would be a noticable optimization, but I noticed in your code, you look for all red colored keywords, and modify your color, then blue words, ect... Wouldn't it be better to simply look for ANY keyword, and when you find one, look up the color? That way you're only iterating over the entire content of the file once, instead of multiple times for each color?
 

WarAngel

Wanderer
@T.O.D.: I'm going to implement that soon. Thanks for the idea. :)

Code:
        private void scriptText_VScroll(object sender, EventArgs e)
        {
            if (scrolling == false)
            {
                scrolling = true;
                MessageBox.Show("Scrolling!");
                if (loaded != false)
                {
                    int d = scriptText.GetPositionFromCharIndex(0).Y % (scriptText.Font.Height + 1);
                    ParseNewVisible(d);
                }
                scrolling = false;
            }
        }
...
        void ParseNewVisible(int d)
        {
            MessageBox.Show("ParseNewVisible");
            //we get index of first visible char and number of first visible line
            Point pos = new Point(0, 0);

            pos.X = 0;
            pos.Y = ClientRectangle.Height + scriptText.Font.Height;
            int beginIndex = scriptText.GetCharIndexFromPosition(pos);

            pos.X = ClientRectangle.Width;
            pos.Y = ClientRectangle.Height + scriptText.Font.Height;
            int lastIndex = scriptText.GetCharIndexFromPosition(pos);

            scriptText.SelectionStart = beginIndex;
            scriptText.SelectionLength = lastIndex - beginIndex;

            string text = scriptText.SelectedText;
            
            //ParseText(text);

            Regex r = new Regex("\\n");
            string[] lines = r.Split(scriptText.SelectedText);

            //linesNums = lines.Length;
            //curLine = 0;

            foreach (string l in lines)
            {
                //curLine += 1;
                ParseLine(l);
            }

            //scriptText.SelectionStart = lastIndex;
            //scriptText.SelectionLength = 0;
            scriptText.SelectionStart = beginIndex;
            scriptText.SelectionLength = lastIndex - beginIndex;
        }
...
        void ParseLine(string line)
        {
            Regex bracketCheck = new Regex(@"\[*\]");
            foreach (Match match in bracketCheck.Matches(line))
            {
                scriptText.SelectionColor = Color.Orchid;
                scriptText.SelectedText = line;
                scriptText.SelectedText = "\n";
                return;
            }
            Regex r = new Regex("([ =.\\t{}():;])");
            String[] tokens = r.Split(line);

            foreach (string token in tokens)
            {
                line.Replace("\n", "");
                // Set the token’s default color and font.
                scriptText.SelectionColor = Color.Black;

                // Check whether the token is a keyword.
                foreach (string myString in Globals.SyntaxColor.BlueKeys)
                {
                    if (myString.ToLower() == token.ToLower())
                    {
                        scriptText.SelectionColor = Color.Blue;
                        break;
                    }
                }

                foreach (string myString in Globals.SyntaxColor.RedKeys)
                {
                    if (myString.ToLower() == token.ToLower())
                    {
                        scriptText.SelectionColor = Color.Red;
                        break;
                    }
                }

                foreach (string myString in Globals.SyntaxColor.GreenKeys)
                {
                    if (myString.ToLower() == token.ToLower())
                    {
                        scriptText.SelectionColor = Color.Green;
                        break;
                    }
                }

                scriptText.SelectedText = token;
            }
            scriptText.SelectedText = "\n";
        }

This is a new problem I've run into. I have the syntax highlighting working fine, but now I have scrolling problems. Whenever I scroll up, the view returns back to where it was before I scrolled. This sounds rather simple, but I've asked a few people for help, and no one is quite sure what it is. I've tried different variations to no avail. Hopefully someone here can help me. Thanks in advance.
 

WarAngel

Wanderer
lol, I just had to point out the fact that I randomly got negative karma for the first post in this topic with the line "English suck."
 
Top