广告位招租

ScintillaNET 括号匹配

所以你想突出匹配的牙套吗?没问题。但它不是免费的。一种编程语言中的大括号字符可能是另一种编程语言中的运算符。因此,闪烁体为您提供了突出显示匹配括号的工具,但它不能为您做到这一点。

我们的基本方法是:听UpdateUI事件以了解插入符号何时更改位置,确定插入符号是否与大括号字符相邻,使用查找匹配的大括号字符大括号匹配,然后用BraceHighlight. 这听起来像是很多工作,但其实很简单。让我们从设置大括号样式开始:

scintilla.Styles[Style.BraceLight].BackColor = Color.LightGray;
scintilla.Styles[Style.BraceLight].ForeColor = Color.BlueViolet;
scintilla.Styles[Style.BraceBad].ForeColor = Color.Red;

您会注意到,我们还为不匹配的大括号设置了样式。我们会用红色标出。

For the purposes of this recipe we’ll assume the following characters are braces: ‘(‘, ‘)’, ‘[‘, ‘]’, ‘{‘, ‘}’, ‘<‘, and ‘>’. This is convenient because that’s also what theBraceMatch方法支持,稍后您将看到。要确定一个字符是否是我们要处理的大括号字符之一,我们将使用一个简单的helper方法:

private static bool IsBrace(int c)
{
    switch (c)
    {
        case '(':
        case ')':
        case '[':
        case ']':
        case '{':
        case '}':
        case '<':
        case '>':
            return true;
    }

    return false;
}

现在剩下的就是处理UpdateUI活动:

int lastCaretPos = 0;

private void scintilla_UpdateUI(object sender, UpdateUIEventArgs e)
{
    // Has the caret changed position?
    var caretPos = scintilla.CurrentPosition;
    if (lastCaretPos != caretPos)
    {
        lastCaretPos = caretPos;
        var bracePos1 = -1;
        var bracePos2 = -1;

        // Is there a brace to the left or right?
        if (caretPos > 0 && IsBrace(scintilla.GetCharAt(caretPos - 1)))
            bracePos1 = (caretPos - 1);
        else if (IsBrace(scintilla.GetCharAt(caretPos)))
            bracePos1 = caretPos;

        if (bracePos1 >= 0)
        {
            // Find the matching brace
            bracePos2 = scintilla.BraceMatch(bracePos1);
            if (bracePos2 == Scintilla.InvalidPosition)
                scintilla.BraceBadLight(bracePos1);
            else
                scintilla.BraceHighlight(bracePos1, bracePos2);
        }
        else
        {
            // Turn off brace matching
            scintilla.BraceHighlight(Scintilla.InvalidPosition, Scintilla.InvalidPosition);
        }
    }
}

这个UpdateUI事件的调用有很多原因,不仅仅是因为插入符号移动了。所以在处理程序的顶部是一个检查,看看插入符号是否自上次更新事件已激发。接下来我们看一下当前插入符号位置之前的字符当前插入符号的位置,使用我们的简单IsBrace辅助方法。如果是大括号字符,bracePos将设置,然后我们可以查找匹配的大括号字符。Spancilla通过提供BraceMatch方法查找与IsBrace方法执行并知道根据起始字符是向后还是向前扫描。它还足够聪明,可以跳过嵌套的大括号。如果你想找到一个BraceMatch方法不支持您将不得不滚动自己的扫描逻辑。如果找到匹配的大括号,则使用大括号突出显示方法,如果没有,则使用BraceBadLight方法

这是基本的大括号匹配,但我们可以更进一步。闪烁还提供了显示缩进指南的能力,这是在不同的缩进水平的垂直线。这是大括号匹配的一个很好的辅助功能。当我们进行大括号匹配时,我们还可以在BraceLight风格。要启用缩进参考线,我们使用未发酵的财产:

scintilla.IndentationGuides = IndentView.LookBoth;

为了突出显示缩进指南,我们使用HighlightGuide财产。此属性的值是要突出显示的指南的列号。由于缩进参考线是不同缩进水平的垂直线,所以我们必须通过提供缩进的列(读取级别)来告诉闪烁哪个缩进级别应该突出显示。文档位置的列号可以使用GetColumn方法

综上所述,以下是完整的配方:

int lastCaretPos = 0;

private void form_Load(object sender, EventArgs e)
{
    scintilla.IndentationGuides = IndentView.LookBoth;
    scintilla.Styles[Style.BraceLight].BackColor = Color.LightGray;
    scintilla.Styles[Style.BraceLight].ForeColor = Color.BlueViolet;
    scintilla.Styles[Style.BraceBad].ForeColor = Color.Red;
}

private static bool IsBrace(int c)
{
    switch (c)
    {
        case '(':
        case ')':
        case '[':
        case ']':
        case '{':
        case '}':
        case '<':
        case '>':
            return true;
    }

    return false;
}

private void scintilla_UpdateUI(object sender, UpdateUIEventArgs e)
{
    // Has the caret changed position?
    var caretPos = scintilla.CurrentPosition;
    if (lastCaretPos != caretPos)
    {
        lastCaretPos = caretPos;
        var bracePos1 = -1;
        var bracePos2 = -1;

        // Is there a brace to the left or right?
        if (caretPos > 0 && IsBrace(scintilla.GetCharAt(caretPos - 1)))
            bracePos1 = (caretPos - 1);
        else if (IsBrace(scintilla.GetCharAt(caretPos)))
            bracePos1 = caretPos;

        if (bracePos1 >= 0)
        {
            // Find the matching brace
            bracePos2 = scintilla.BraceMatch(bracePos1);
            if (bracePos2 == Scintilla.InvalidPosition)
            {
                scintilla.BraceBadLight(bracePos1);
                scintilla.HighlightGuide = 0;
            }
            else
            {
                scintilla.BraceHighlight(bracePos1, bracePos2);
                scintilla.HighlightGuide = scintilla.GetColumn(bracePos1);
            }
        }
        else
        {
            // Turn off brace matching
            scintilla.BraceHighlight(Scintilla.InvalidPosition, Scintilla.InvalidPosition);
            scintilla.HighlightGuide = 0;
        }
    }
}

原文链接:https://www.exueyuan.top/545.html,转载请注明出处。

0
广告位招租

评论0

请先

广告位招租
易学手机界面分析工具上线!可用于安卓手机界面,模拟器界面分析,加速自动化开发!查看详情
没有账号? 注册  忘记密码?

社交账号快速登录

微信扫一扫关注
如已关注,请回复“登录”二字获取验证码