如何在 Visual Studio 编辑器中的特定 line/column/length 上创建标签?

How to create a tag on a specific line/column/length in Visual Studio editor?

我想在 Visual Studio 编辑器中创建标签,以根据代码中的 line/column/length 个位置插入各种字形、装饰、文本高亮等。

我一直在仔细阅读文档演练页面(https://docs.microsoft.com/en-us/visualstudio/extensibility/walkthrough-creating-a-margin-glyph?view=vs-2017 和相关页面)。尽管有点复杂且难以理解,但 API 似乎非常注重提供分析代码的方法:它能够将您的代码分成跨度、分类等。

但是,我有 "opposite" 需要:我已经通过我的外部分析引擎完成了分析。我已经有一组结果显示在编辑器中,每个结果 line/column/length 。喜欢:

是否可以直接根据 line/column/length 位置在 Visual Studio 编辑器中创建标签?任何提示,任何指向更详细文档或教程的指针都将不胜感激。

Lance 的 link 非常有助于理解另一种创建不同于 MS 文档示例的标签的方法。

确实,我不分析span中包含的文本,分析已经在外面完成了。我得到了一些 "defects" 个位置的列表。

我将它们放入 defectsLocation 字典中(defectsLocation[文件名][行] = 位置数据 (...)

这是我做的:

internal class MyDefectTagger : ITagger<MyDefectTag>
{
    private IClassifier m_classifier;
    private ITextBuffer m_buffer;

    internal MyDefectTagger(IClassifier classifier, ITextBuffer buffer)
    {
        m_classifier = classifier;
        m_buffer = buffer;
    }

    IEnumerable<ITagSpan<MyDefectTag>>
        ITagger<MyDefectTag>.GetTags(NormalizedSnapshotSpanCollection spans)
    {
        if (MyModel.Instance == null || MyModel.Instance.defectsLocation == null)
        {
            yield return null;
        }

        var filename = GetFileName(m_buffer);

        if (!MyModel.Instance.defectsLocation.ContainsKey(filename))
        {
            yield return null;
        }

        foreach (SnapshotSpan span in spans)
        {
            ITextSnapshot textSnapshot = span.Snapshot;

            foreach (ITextSnapshotLine textSnapshotLine in textSnapshot.Lines)
            {
                var line = textSnapshotLine.LineNumber + 1; // Lines start at 1 in VS Editor

                if (MyModel.Instance.defectsLocation[filename].ContainsKey(line) &&
                    !MyModel.Instance.defectsLocation[filename][line].rendered)
                {
                    var rendered = MyModel.Instance.defectsLocation[filename][line].rendered;
                    yield return new TagSpan<MyDefectTag>(
                        new SnapshotSpan(textSnapshotLine.Start, 0),
                        new MyDefectTag()
                    );
                }
            }
        }
    }
}