[英]Syntax highlighting richtextbox in C# on a single line only
我正在使用Richtextbox开发自己的语法荧光笔。 它已经在工作,但是我注意到,当有许多行代码时,键入速度会大大降低。 这是因为我的语法高亮功能是对每次Richtextbox中的所有更改进行着色。 下面是该函数的最小示例,以了解其工作原理:
private void colorCode()
{
// getting keywords/functions
string keywords = @"\b(class|function)\b";
MatchCollection keywordMatches = Regex.Matches(codeBox.Text, keywords);
// saving the original caret position + forecolor
int originalIndex = codeBox.SelectionStart;
int originalLength = codeBox.SelectionLength;
Color originalColor = Color.Black
// focuses a label before highlighting (avoids blinking)
titleLabel.Focus();;
// removes any previous highlighting (so modified words won't remain highlighted)
codeBox.SelectionStart = 0;
codeBox.SelectionLength = codeBox.Text.Length;
codeBox.SelectionColor = originalColor;
foreach (Match m in keywordMatches)
{
codeBox.SelectionStart = m.Index;
codeBox.SelectionLength = m.Length;
codeBox.SelectionColor = Color.Blue;
}
// restoring the original colors, for further writing
codeBox.SelectionStart = originalIndex;
codeBox.SelectionLength = originalLength;
codeBox.SelectionColor = originalColor;
// giving back the focus
codeBox.Focus();
}
为了解决该问题,我想编写一个不会更改整个Richtextbox的函数,而只是更改光标位置的行。 我意识到这仍然会在最小化代码上引起相同的问题,但这对我来说不是问题。 问题是,我似乎无法正常工作。 到目前为止,这是我得到的:
void changeLine(RichTextBox RTB, int line, Color clr, int curPos){
string testWords = @"\b(test1|test2)\b";
MatchCollection testwordMatches = Regex.Matches(RTB.Lines[line], testWords);
foreach (Match m in testwordMatches)
{
//RTB.SelectionStart = m.Index;
//RTB.SelectionLength = m.Length;
RTB.SelectionColor = Color.Blue;
}
RTB.SelectionStart = curPos;
RTB.SelectionColor = Color.Black;
}
问题是,当在testWords中找到一个单词时,它会进行着色,但是会为整个行着色,而不仅仅是单词。 这是因为我无法找出正确选择的方法。 所以我希望你们可以帮助我。
编辑:
我想补充一点,我确实考虑过其他解决方案,例如将行放入列表中或使用Stringbuilder。 但是这些会将行变成字符串,并且不允许我像Richtextbox那样进行颜色格式化。
好吧,您显然需要语言词法分析器和解析器。 使用正则表达式无法解决此任务。 由于某些基本的语法规则(或语法的“功率等级”)(只是了解Thomsky语法层次结构),它无法完成此任务。
您需要使用一些语法工具包。 例如,ANTLR4提供语法词法分析器/解析器生成器和一组预定义的语法。
例如,您可以在此处找到很多用户编写的语法(包括最新的C#语法): https : //github.com/antlr/grammars-v4
然后仅通过它生成解析器/词法分析器,并将其作为字符串输入。 它将输出具有每个令牌的索引和长度的完整层次结构,您可以为它们着色而无需跳过整个丰富框。
另外,请考虑在用户输入之间使用一些超时,这样就不会为每个符号着色输出(只需保存先前标记的颜色,并使用一段时间,直到重新着色输出然后刷新即可)。 这样,它将像在Visual Studio中一样顺利进行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.