2017-04-17 61 views
0

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

例如,我可以得到一个IWpfTextView,但是一旦我得到它,我不知道该如何处理它。是否有实际从中获取所有格式的示例?我只对文本前景/背景颜色非常感兴趣,就是这样。

注:我需要每个编辑格式的文本,所以很遗憾做使用剪贴板剪切和粘贴是不是一种选择。

+0

你能给出关于你想要用文本做什么的更多具体细节吗?有可能是其他的东西比颜色效果更好... – Jimmy

+0

@Jimmy我需要简单地存储文本。与格式。在每个键入的键或每个改变(例如,重构)上进行。如果可能的话,我也可以使用* diff *数据。 –

+0

@DmitryNesteruk换句话说,是*颜色*重要的,还是另一种格式化边界的指示适合你? – Jimmy

回答

1

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

+0

不幸的是,这在计算上是不可行的,因为我需要每次编辑时的格式化。我会澄清答案。 –

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到你选择的颜色的映射。或者,我们可以通过IClassificationFormatMap询问VS会做什么。同样,请记住,这是受用户设置,光与暗的主题等

无论哪种方式,它可能是这个样子:

// 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。

相关问题