0

im working on a code editor and i came up with this set of codes:

public class Test2 : Form {

  RichTextBox m_rtb = null;

  public static void Main() {
    Application.Run(new Test2());
  }

  public Test2() {
    Text = "Test2";
    ClientSize = new Size(400, 400);
    m_rtb = new RichTextBox();
    m_rtb.Multiline = true;
    m_rtb.WordWrap = false;
    m_rtb.AcceptsTab = true;
        m_rtb.ScrollBars = RichTextBoxScrollBars.ForcedBoth;
    m_rtb.Dock = DockStyle.Fill;
    m_rtb.SelectionFont = new Font("Courier New", 10, FontStyle.Regular);
    m_rtb.SelectionColor = Color.Black;
    Controls.Add(m_rtb);
    Parse();
    m_rtb.TextChanged += new EventHandler(this.TextChangedEvent);
  }

  void Parse() {
    String inputLanguage = 
      "// Comment.\n" +
      "using System;\n" + "\n" +
      "public class Stuff : Form { \n" +
      "  public static void Main(String args) {\n" +
      "  }\n" +   
      "}\n" ; 

    // Foreach line in input,
    // identify key words and format them when adding to the rich text box.
    Regex r = new Regex("\\n");
    String [] lines = r.Split(inputLanguage);
    foreach (string l in lines) {
      ParseLine(l);
    }    
  }

  void ParseLine(string line) {
    Regex r = new Regex("([ \\t{}();])");
    String [] tokens = r.Split(line);

    foreach (string token in tokens) {
      // Set the token's default color and font.
      m_rtb.SelectionColor = Color.Black;
      m_rtb.SelectionFont = new Font("Courier New", 10, FontStyle.Regular);

      // Check for a comment.
      if (token == "//" || token.StartsWith("//")) {
        // Find the start of the comment and then extract the whole comment.
        int index = line.IndexOf("//");
        string comment = line.Substring(index, line.Length - index);
        m_rtb.SelectionColor = Color.LightGreen;
        m_rtb.SelectionFont = new Font("Courier New", 10, FontStyle.Regular);
        m_rtb.SelectedText = comment;
        break;
      }

      // Check whether the token is a keyword. 
      String [] keywords = { "public", "void", "using", "static", "class" }; 
      for (int i = 0; i < keywords.Length; i++) {
        if (keywords[i] == token) {
          // Apply alternative color and font to highlight keyword.
          m_rtb.SelectionColor = Color.Blue;
          m_rtb.SelectionFont = new Font("Courier New", 10, FontStyle.Bold);
          break;
        }
      }
      m_rtb.SelectedText = token;
    }    
    m_rtb.SelectedText = "\n";
  } 

  private void TextChangedEvent(object sender, EventArgs e) {
    // Calculate the starting position of the current line.
    int start = 0, end = 0;
    for (start = m_rtb.SelectionStart - 1; start > 0; start--) {
      if (m_rtb.Text[start] == '\n')  { start++; break; }
    }

    // Calculate the end position of the current line.
    for (end = m_rtb.SelectionStart; end < m_rtb.Text.Length; end++) {
      if (m_rtb.Text[end] == '\n') break;
    }

    // Extract the current line that is being edited.
    String line = m_rtb.Text.Substring(start, end - start);

    // Backup the users current selection point.
    int selectionStart = m_rtb.SelectionStart;
    int selectionLength = m_rtb.SelectionLength;

    // Split the line into tokens.
    Regex r = new Regex("([ \\t{}();])");
    string [] tokens = r.Split(line);
    int index = start;
    foreach (string token in tokens) {

      // Set the token's default color and font.
      m_rtb.SelectionStart = index;
      m_rtb.SelectionLength = token.Length;
      m_rtb.SelectionColor = Color.Black;
      m_rtb.SelectionFont = new Font("Courier New", 10, FontStyle.Regular);

      // Check for a comment.
      if (token == "//" || token.StartsWith("//")) {
        // Find the start of the comment and then extract the whole comment.
        int length = line.Length - (index - start);
        string commentText = m_rtb.Text.Substring(index, length);
        m_rtb.SelectionStart = index;
        m_rtb.SelectionLength = length;
        m_rtb.SelectionColor = Color.LightGreen;
        m_rtb.SelectionFont = new Font("Courier New", 10, FontStyle.Regular);
        break;
      }

      // Check whether the token is a keyword. 
      String [] keywords = { "public", "void", "using", "static", "class" }; 
      for (int i = 0; i < keywords.Length; i++) {
        if (keywords[i] == token) {
          // Apply alternative color and font to highlight keyword.        
          m_rtb.SelectionColor = Color.Blue;
          m_rtb.SelectionFont = new Font("Courier New", 10, FontStyle.Bold);
          break;
        }
      }
      index += token.Length;
    }
    // Restore the users current selection point.    
    m_rtb.SelectionStart = selectionStart;
    m_rtb.SelectionLength = selectionLength;  
  } 
}

problem was everytime i press space keys or type the entire code editor keeps on scanning like searching on what to highlight and i find it a bit annoying ...

so i just want to ask for possible solution about this ... to avoid highlighting of whole richtextbox like scanning what to highlight next .

thanks a lot in advance for the help! more power!

Maverik
  • 5,619
  • 35
  • 48
Elegiac
  • 129
  • 1
  • 17

1 Answers1

0

I answered this in your most recent question, but in case someone else is reading this and doesn't find it, I'll post it here (Since this is specifically about performance):

You can use a couple of things to improve performance:

1) You can get the line that the user is editing by getting the text range from the current selection. I would recommend using WPF's richtextbox as it contains much more features and has the useful TextPointer class which you can utilise to get the current line. It seems like you are using WinForms however, so this can be done with these few lines of code (with the addition of some trivial code):

int start_index = RTB.GetFirstCharIndexOfCurrentLine();
int line = RTB.GetLineFromCharIndex(index);
int last_index = RTB.GetFirstCharIndexFromLine(line+1);
RTB.Select(start_index, last_index);

You can then work with the current selection.

2) If you don't want it to update so frequently, you can create a timer which measures the delay since the last edit, and reset the timer if another edit is made before the timer elapses.

JessMcintosh
  • 460
  • 2
  • 6
  • 21