//Source: http://www.codeproject.com/KB/edit/SyntaxRichTextBox/SyntaxRichTextBox_src.zip using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Windows.Forms; using System.ComponentModel; using System.Text.RegularExpressions; using System.Drawing; namespace ShiftOS { public class SyntaxRichTextBox : System.Windows.Forms.RichTextBox { private SyntaxSettings m_settings = new SyntaxSettings(); private static bool m_bPaint = true; private string m_strLine = ""; private int m_nContentLength = 0; private int m_nLineLength = 0; private int m_nLineStart = 0; private int m_nLineEnd = 0; private string m_strKeywords = ""; private int m_nCurSelection = 0; /// /// The settings. /// public SyntaxSettings Settings { get { return m_settings; } } /// /// WndProc /// /// protected override void WndProc(ref System.Windows.Forms.Message m) { if (m.Msg == 0x00f) { if (m_bPaint) base.WndProc(ref m); else m.Result = IntPtr.Zero; } else base.WndProc(ref m); } public void SetLanguage(SyntaxSettings.Language lang) { Color white = Color.Black; Color keyword = Color.Red; Color integer = Color.LightGreen; Color comment = Color.DarkGray; Color str = Color.Orange; Settings.EnableComments = true; Settings.EnableIntegers = true; Settings.EnableStrings = true; if (API.Upgrades["limitlesscustomshades"]) { Settings.CommentColor = comment; Settings.KeywordColor = keyword; Settings.StringColor = str; Settings.IntegerColor = integer; } else { Settings.CommentColor = white; Settings.KeywordColor = white; Settings.StringColor = white; Settings.IntegerColor = white; } switch (lang) { case SyntaxSettings.Language.Lua: var kw = new List() { "function", "local", "return", "if", "else", "elseif", "while", "true", "do", "next", "end", "for", "pairs", "in", "{", "}", "false", "=", "+", "-", "/", "*", "..", "," }; Settings.Keywords.Clear(); foreach (var k in kw) { Settings.Keywords.Add(k); } Settings.Comment = "--"; break; case SyntaxSettings.Language.CSharp: var cskw = new List() { "public", "private", "internal", "static", "dynamic", "namespace", "typeof", "(", ")", "[", "]", "{", "}", "sizeof", "int", "using", "<", ">", ";", "this", "base", ":", "class", "interface", "string", "double", "single", "char", "new", "if", "else", "while", "for", "foreach", "in", "var", "as", "is", "object", "~" }; Settings.Keywords.Clear(); foreach (var k in cskw) { Settings.Keywords.Add(k); } Settings.Comment = "//"; break; } CompileKeywords(); ProcessAllLines(); } /// /// OnTextChanged /// /// protected override void OnTextChanged(EventArgs e) { // Calculate shit here. (NO. I didn't write this. This was there in codeproject... - Michael) m_nContentLength = this.TextLength; int nCurrentSelectionStart = SelectionStart; int nCurrentSelectionLength = SelectionLength; m_bPaint = false; // Find the start of the current line. m_nLineStart = nCurrentSelectionStart; while ((m_nLineStart > 0) && (Text[m_nLineStart - 1] != '\n')) m_nLineStart--; // Find the end of the current line. m_nLineEnd = nCurrentSelectionStart; while ((m_nLineEnd < Text.Length) && (Text[m_nLineEnd] != '\n')) m_nLineEnd++; // Calculate the length of the line. m_nLineLength = m_nLineEnd - m_nLineStart; // Get the current line. m_strLine = Text.Substring(m_nLineStart, m_nLineLength); // Process this line. ProcessLine(); m_bPaint = true; } /// /// Process a line. /// private void ProcessLine() { // Save the position and make the whole line black int nPosition = SelectionStart; SelectionStart = m_nLineStart; SelectionLength = m_nLineLength; SelectionColor = ForeColor; // Process the keywords ProcessRegex(m_strKeywords, Settings.KeywordColor); // Process numbers if (Settings.EnableIntegers) ProcessRegex("\\b(?:[0-9]*\\.)?[0-9]+\\b", Settings.IntegerColor); // Process strings if (Settings.EnableStrings) ProcessRegex("\"[^\"\\\\\\r\\n]*(?:\\\\.[^\"\\\\\\r\\n]*)*\"", Settings.StringColor); // Process comments if (Settings.EnableComments && !string.IsNullOrEmpty(Settings.Comment)) ProcessRegex(Settings.Comment + ".*$", Settings.CommentColor); SelectionStart = nPosition; SelectionLength = 0; SelectionColor = Color.Black; m_nCurSelection = nPosition; } /// /// Process a regular expression. /// /// The regular expression. /// The color. private void ProcessRegex(string strRegex, Color color) { Regex regKeywords = new Regex(strRegex, RegexOptions.IgnoreCase | RegexOptions.Compiled); Match regMatch; for (regMatch = regKeywords.Match(m_strLine); regMatch.Success; regMatch = regMatch.NextMatch()) { // Process the words int nStart = m_nLineStart + regMatch.Index; int nLenght = regMatch.Length; SelectionStart = nStart; SelectionLength = nLenght; SelectionColor = color; } } /// /// Compiles the keywords as a regular expression. /// public void CompileKeywords() { for (int i = 0; i < Settings.Keywords.Count; i++) { string strKeyword = Settings.Keywords[i]; if (i == Settings.Keywords.Count - 1) m_strKeywords += "\\b" + strKeyword + "\\b"; else m_strKeywords += "\\b" + strKeyword + "\\b|"; } } public void ProcessAllLines() { m_bPaint = false; int nStartPos = 0; int i = 0; int nOriginalPos = SelectionStart; while (i < Lines.Length) { m_strLine = Lines[i]; m_nLineStart = nStartPos; m_nLineEnd = m_nLineStart + m_strLine.Length; ProcessLine(); i++; nStartPos += m_strLine.Length + 1; } m_bPaint = true; } } /// /// Class to store syntax objects in. /// public class SyntaxList { public List m_rgList = new List(); public Color m_color = new Color(); } /// /// Settings for the keywords and colors. /// public class SyntaxSettings { SyntaxList m_rgKeywords = new SyntaxList(); string m_strComment = ""; Color m_colorComment = Color.Green; Color m_colorString = Color.Gray; Color m_colorInteger = Color.Red; bool m_bEnableComments = true; bool m_bEnableIntegers = true; bool m_bEnableStrings = true; #region Properties /// /// A list containing all keywords. /// public List Keywords { get { return m_rgKeywords.m_rgList; } } /// /// The color of keywords. /// public Color KeywordColor { get { return m_rgKeywords.m_color; } set { m_rgKeywords.m_color = value; } } /// /// A string containing the comment identifier. /// public string Comment { get { return m_strComment; } set { m_strComment = value; } } /// /// The color of comments. /// public Color CommentColor { get { return m_colorComment; } set { m_colorComment = value; } } /// /// Enables processing of comments if set to true. /// public bool EnableComments { get { return m_bEnableComments; } set { m_bEnableComments = value; } } /// /// Enables processing of integers if set to true. /// public bool EnableIntegers { get { return m_bEnableIntegers; } set { m_bEnableIntegers = value; } } /// /// Enables processing of strings if set to true. /// public bool EnableStrings { get { return m_bEnableStrings; } set { m_bEnableStrings = value; } } /// /// The color of strings. /// public Color StringColor { get { return m_colorString; } set { m_colorString = value; } } /// /// The color of integers. /// public Color IntegerColor { get { return m_colorInteger; } set { m_colorInteger = value; } } #endregion public enum Language { Lua, CSharp, } } }