c# - 在 ITextViewLine 上运行正则表达式(Visual Studio 扩展)

标签 c# regex visual-studio visual-studio-extensions

我希望运行正则表达式搜索来查找编辑器窗口中某些关键字的所有出现,然后绘制一些装饰并向其添加一些标签。

有没有办法在 ITextViewLine 上运行正则表达式。

这就是我的调用函数的样子:

private void OnLayoutChanged(object sender, TextViewLayoutChangedEventArgs e)
{
    foreach (ITextViewLine line in e.NewOrReformattedLines)
    {
        this.CreateVisuals(line);
    }
}

private void CreateVisuals(ITextViewLine line)
{
    IWpfTextViewLineCollection textViewLines = _wpfTextView.TextViewLines;
    // Run RegEx match here and do some stuff for all matches
}

根据@stribizhev的建议我尝试使用 FormattedSpan 如下:

private void CreateVisuals(ITextViewLine line)
{
    var textViewLines = _wpfTextView.TextViewLines;
    var snapshot = textViewLines.FormattedSpan;
    var text = snapshot.ToString();
    var todoRegex = new Regex(@"\/\/\s*TODO\b");
    var match = todoRegex.Match(text);
    if (match.Success)
    {
        int matchStart = line.Start.Position + match.Index;
        var span = new SnapshotSpan(_wpfTextView.TextSnapshot, Span.FromBounds(matchStart, matchStart + match.Length));
        DrawAdornment(textViewLines, span);
    }
}

但这会导致在调用 DrawAdornment 时出现 NullReference ,告诉我 span 未设置。 此外,通过在 CreateVisuals 函数中的所有行上放置断点,我发现仅当包含 TODO 的行滚动到 View 之外或成为该行中的第一行时,才会开始突出显示。视口(viewport)。

我尝试的输入是:

using System;
public class Class1
{
    public Class1()
    {
        // TODO: It's a good thing to have todos
    }
}

代码有时能够放置装饰,但它们会稍微向右移动并出现在三个不同的行上。

最佳答案

我终于让它工作了。有两种方法可以做到这一点。

我的方式(更简单):

private void CreateVisuals()
    {
        var textViewLines = _wpfTextView.TextViewLines;
        var text = textViewLines.FormattedSpan.Snapshot.GetText();
        var todoRegex = new Regex(@"\/\/\s*TODO\b");
        var match = todoRegex.Match(text);
        while (match.Success)
        {
            var matchStart = match.Index;
            var span = new SnapshotSpan(_wpfTextView.TextSnapshot, Span.FromBounds(matchStart, matchStart + match.Length));
            DrawAdornment(textViewLines, span);
            match = match.NextMatch();
        }

艰难的方式:(来自 this article )

/// <summary>
/// This will get the text of the ITextView line as it appears in the actual user editable 
/// document. 
/// jared parson: https://gist.github.com/4320643
/// </summary>
public static bool TryGetText(IWpfTextView textView, ITextViewLine textViewLine, out string text)
{
    var extent = textViewLine.Extent;
    var bufferGraph = textView.BufferGraph;
    try
    {
        var collection = bufferGraph.MapDownToSnapshot(extent, SpanTrackingMode.EdgeInclusive, textView.TextSnapshot);
        var span = new SnapshotSpan(collection[0].Start, collection[collection.Count - 1].End);
        //text = span.ToString();
        text = span.GetText();
        return true;
    }
    catch
    {
        text = null;
        return false;
    }
}

Regex todoLineRegex = new Regex(@"\/\/\s*TODO\b");

private void CreateVisuals(ITextViewLine line)
{
    IWpfTextViewLineCollection textViewLines = _view.TextViewLines;
    string text = null;
    if (TryGetText(_view, line, out text))
    {
        var match = todoLineRegex.Match(text);
        if (match.Success)
        {
            int matchStart = line.Start.Position + span.Index;
            var span = new SnapshotSpan(_view.TextSnapshot, Span.FromBounds(matchStart, matchStart + match.Length));
            DrawAdornment(textViewLines, span);
        }
    }
}

关于c# - 在 ITextViewLine 上运行正则表达式(Visual Studio 扩展),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34692917/

相关文章:

c++ - 如何在没有CMake的情况下用visual studio编译opencv

c# - StringBuilder,在值之间添加制表符

regex - Bash 脚本中的正则表达式

php - mySQL 字符串匹配

visual-studio - 是否可以在 Windows Phone 8 应用程序中创建自定义路由事件?

c# - 将引用和 com 目录添加到 visual studio?

c# - 从 EntityFramework ObjectContext 获取类型集合

variables - 如何使用来自资源另一个 .cs 文件的变量与 "using"

c# - ASP.NET MVC 3 中的依赖注入(inject)说明和 DependencyResolver?

python - 用表中的单个 unicode 替换字母数字子字符串