如何使用格式化获取整个Visual Studio活动文档

时间:2017-04-17 21:03:11

标签: visual-studio vs-extensibility visual-studio-sdk vssdk

我知道如何使用VS Extensibility来获取整个活动文档的文本。不幸的是,这只能得到我的文字,并没有给我格式化,我也想要。

例如,我可以得到一个df.item_name.str.replace("[^\w\s-]", "") #0 stback #1 yhhxx #2 adfgs #3 ghytt23 #4 ghh_h #Name: item_name, dtype: object 但是一旦得到它,我不知道该如何处理它。是否有实际从中获取所有格式的示例?我只对文本前景/背景颜色感兴趣,就是这样。

注意:我需要每次编辑上的格式化文字,所以不幸的是,使用剪贴板进行剪切和粘贴不是一种选择。

2 个答案:

答案 0 :(得分:1)

可能最简单的方法是选择所有文本并将其复制到剪贴板。 VS将富文本放入剪贴板,因此当您在其他地方粘贴时,您将获得颜色(假设您在目的地处理了富文本)。

答案 1 :(得分:1)

这是我不是最简单的解决方案。 TL; DR:您可以跳转到https://github.com/jimmylewis/GetVSTextViewFormattedTextSample处的代码。

VS编辑器使用“分类”来显示具有特殊含义的文本片段。然后,可以根据语言和用户设置对这些分类进行不同的格式化。

有一个用于在文档中获取分类的API,但它对我不起作用。或者显然是other people。但是我们仍然可以通过ITagAggregator<IClassificationTag>获得分类,如前面的链接所述,或者就在这里:

[Import]
IViewTagAggregatorFactoryService tagAggregatorFactory = null;

// in some method...
var classificationAggregator = tagAggregatorFactory.CreateTagAggregator<IClassificationTag>(textView);
var wholeBufferSpan = new SnapshotSpan(textBuffer.CurrentSnapshot, 0, textBuffer.CurrentSnapshot.Length);
var tags = classificationAggregator.GetTags(wholeBufferSpan);

有了这些,我们可以重建文件。重要的是要注意某些文本分类,因此您必须将所有内容拼凑在一起。

另外值得注意的是,此时我们还不知道这些标签是如何格式化的 - 即渲染过程中使用的颜色。如果您愿意,可以将自己的映射从IClassificationType定义为您选择的颜色。或者,我们可以询问VS使用IClassificationFormatMap做什么。再次,请记住,这受用户设置,Light vs. Dark主题等的影响

无论哪种方式,它看起来都像这样:

// Magic sauce pt1: See the example repo for an RTFStringBuilder I threw together.
RTFStringBuilder sb = new RTFStringBuilder();
var wholeBufferSpan = new SnapshotSpan(textBuffer.CurrentSnapshot, 0, textBuffer.CurrentSnapshot.Length);
// Magic sauce pt2: see the example repo, but it's basically just 
// mapping the spans from the snippet above with the formatting settings 
// from the IClassificationFormatMap.
var textSpans = GetTextSpansWithFormatting(textBuffer);

int currentPos = 0;
var formattedSpanEnumerator = textSpans.GetEnumerator();
while (currentPos < wholeBufferSpan.Length && formattedSpanEnumerator.MoveNext())
{
    var spanToFormat = formattedSpanEnumerator.Current;
    if (currentPos < spanToFormat.Span.Start)
    {
        int unformattedLength = spanToFormat.Span.Start - currentPos;
        SnapshotSpan unformattedSpan = new SnapshotSpan(textBuffer.CurrentSnapshot, currentPos, unformattedLength);
        sb.AppendText(unformattedSpan.GetText(), System.Drawing.Color.Black);
    }

    System.Drawing.Color textColor = GetTextColor(spanToFormat.Formatting.ForegroundBrush);
    sb.AppendText(spanToFormat.Span.GetText(), textColor);

    currentPos = spanToFormat.Span.End;
}

if (currentPos < wholeBufferSpan.Length)
{
    // append any remaining unformatted text
    SnapshotSpan unformattedSpan = new SnapshotSpan(textBuffer.CurrentSnapshot, currentPos, wholeBufferSpan.Length - currentPos);
    sb.AppendText(unformattedSpan.GetText(), System.Drawing.Color.Black);
}

return sb.ToString();

希望这对你正在做的事情有所帮助。示例repo将在每次编辑后询问您是否希望剪贴板中的格式化文本,但这只是一种我可以测试并看到它工作的脏方法。这很烦人,但它只是一个PoC。