2017-04-17 63 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。

相關問題