我想在Visual Studio(2010)擴展中開始使用,而且我很難找到合適的材料。我有SDK,但包含的示例似乎是裝飾,窗口和圖標等。Visual Studio文本編輯器擴展
我試圖做一個擴展,將直接與文本編輯器工作(以alphabetize我的所有方法名稱在類中,或使所有常量名稱大寫例如),但我無法找到演示這種類型的功能,甚至是一個教程。
有誰知道我在哪裏可以找到這種東西?
我想在Visual Studio(2010)擴展中開始使用,而且我很難找到合適的材料。我有SDK,但包含的示例似乎是裝飾,窗口和圖標等。Visual Studio文本編輯器擴展
我試圖做一個擴展,將直接與文本編輯器工作(以alphabetize我的所有方法名稱在類中,或使所有常量名稱大寫例如),但我無法找到演示這種類型的功能,甚至是一個教程。
有誰知道我在哪裏可以找到這種東西?
我有相同問題的「入門編輯器擴展」的網站,現在已經瀏覽過的網頁幾個小時,直到我能瞭解並解釋如何從這樣的擴展開始。
在我的下面的例子中,我們將創建一個小而愚蠢的擴展,當編輯完成後,它總會將「Hello」添加到代碼文件的開頭。這是非常基本的,但應該給你一個想法如何繼續開發這件事。
請注意:您必須自行解析代碼文件 - Visual Studio不會提供有關類,方法或其他內容的信息。 [*]
對於那些跳過此答案的用戶,請確保您先下載並安裝了Visual Studio SDK,或者您已經安裝了Visual Studio SDK將無法找到第一步中提到的項目類型。
創建項目
啓動的(如果你選擇了.NET Framework 4中作爲目標框架纔可見)創造型 「的Visual C#>擴展> VSIX項目」 的新項目。 請注意,您可能不得不選擇「編輯器分類器」項目類型而不是「VSIX項目」類型才能使其工作。下面評論。
項目創建完成後,將打開「source.extension.vsixmanifest」文件,使您可以設置產品名稱,作者,版本,說明,圖標等。我認爲這一步很自我解釋,現在可以關閉該選項卡並稍後通過打開vsixmanifest文件進行恢復。
創建一個監聽器類,以收到通知的文本編輯器實例的創作
接下來,我們需要傾聽每當一個文本編輯器已經在Visual Studio中創建和綁定我們的代碼格式化工具吧。 VS2010中的文本編輯器是IWpfTextView
的一個實例。
添加一個新的類,我們的項目並將其命名爲TextViewCreationListener
。這個類必須實現Microsoft.VisualStudio.Text.Editor.IWpfTextViewCreationListener
接口。您需要添加一個對Microsoft.VisualStudio.Text.UI的參考文件。Wpf到您的項目。程序集DLL位於Visual Studio SDK目錄下的VisualStudioIntegration \ Common \ Assemblies \ v4.0中。
您必須實現接口的TextViewCreated
方法。此方法有一個參數,指定已創建的文本編輯器的實例。我們將創建一個新的代碼格式化類,這個實例將在稍後傳遞給它。
我們需要通過指定屬性[Export(typeof(IWpfTextViewCreationListener))]
來使TextViewCreationListener
類對Visual Studio可見。將對System.ComponentModel.Composition的引用添加到您的項目中,以獲取Export
屬性。
此外,我們需要指定代碼格式化程序應與文本編輯器綁定的文件類型。我們只想格式化代碼文件而不是純文本文件,因此我們將屬性[ContentType("code")]
添加到偵聽器類。你必須添加一個參考Microsoft.VisualStudio.CoreUtility到你的項目爲此。此外,我們只想更改可編輯的代碼,而不是周圍的顏色或裝飾(如示例項目中所示),因此我們將該屬性[TextViewRole(PredefinedTextViewRoles.Editable)]
添加到類中。再次,您需要一個新的參考,這次到Microsoft.VisualStudio.Text.UI。
將該類標記爲內部密封。至少這是我的建議。現在你的類應該類似於此:
[ContentType("code")]
[Export(typeof(IWpfTextViewCreationListener))]
[TextViewRole(PredefinedTextViewRoles.Editable)]
internal sealed class TextViewCreationListener : IWpfTextViewCreationListener
{
public void TextViewCreated(IWpfTextView textView)
{
}
}
創建代碼格式化
接下來的一類,我們需要一個類處理代碼格式化邏輯,排序方式等。再次,在這個例子中,只要編輯完成,它就會簡單地在文件的開頭添加「Hello」。
在您的項目中添加一個名爲Formatter
的新類。
添加一個構造函數,其中需要一個IWpfTextView
參數。請記住,我們希望將創建的編輯器實例傳遞給我們監聽器類的TextViewCreated
方法中的此格式化類(只需將new Formatter(textView);
添加到那裏的方法中)。
將傳遞的實例保存在成員變量中。稍後格式化代碼時(例如,檢索插入位置)它會變得很方便。也綁上編輯器實例的TextBuffer
財產Changed
和PostChanged
事件:
public Formatter(IWpfTextView view)
{
_view = view;
_view.TextBuffer.Changed += new EventHandler<TextContentChangedEventArgs>(TextBuffer_Changed);
_view.TextBuffer.PostChanged += new EventHandler(TextBuffer_PostChanged);
}
的Changed
事件被稱爲每次編輯已經做出的時間(例如輸入一個字符,粘貼代碼或的程序化的變化)。因爲它也會對程序變化做出反應,所以我使用bool來確定我們的擴展或用戶/其他任何內容是否正在更改代碼,並且僅當我們的擴展尚未編輯時才調用我的自定義FormatCode()
方法。否則,你會遞歸調用此方法將導致程序崩潰的Visual Studio:
private void TextBuffer_Changed(object sender, TextContentChangedEventArgs e)
{
if (!_isChangingText)
{
_isChangingText = true;
FormatCode(e);
}
}
我們有這個布爾成員變量在PostChanged
事件處理程序再次重置爲false
。
讓我們將Changed
事件的事件參數傳遞給我們自定義的FormatCode
方法,因爲它們包含在上次編輯和現在之間已更改的內容。這些編輯存儲在INormalizedTextChangeCollection
類型的e.Changes
數組中(有關此類型的更多信息,請參閱我的帖子末尾的鏈接)。我們循環所有這些編輯,並使用此編輯生成的新文本調用我們的自定義HandleChange
方法。
private void FormatCode(TextContentChangedEventArgs e)
{
if (e.Changes != null)
{
for (int i = 0; i < e.Changes.Count; i++)
{
HandleChange(e.Changes[0].NewText);
}
}
}
在HandleChange
方法,我們實際上可以掃描關鍵字來處理這些以特定的方式(請記住,你必須分析你自己的任何代碼!) - 但在這裏,我們只是默默地加上「你好」向爲測試目的開始文件。例如。我們必須更改編輯器實例的TextBuffer
。爲此,我們需要創建一個ITextEdit
對象,我們可以使用該對象處理文本並在之後應用它的更改。該代碼是相當自我解釋:
private void HandleChange(string newText)
{
ITextEdit edit = _view.TextBuffer.CreateEdit();
edit.Insert(0, "Hello");
edit.Apply();
}
編譯時,此插件,Visual Studio中的實驗蜂巢只有我們的擴展加載啓動。創建一個新的C#文件並開始輸入查看結果。
我希望這給你一些想法如何繼續在這個話題。我現在必須自己去探索它。
我強烈建議在MSDN上編輯文本模型的文檔,以獲得有關如何做到這一點的提示。 http://msdn.microsoft.com/en-us/library/dd885240.aspx#textmodel
腳註
[*]需要注意的是Visual Studio的2015年或更新版本來與Rosyln編譯器平臺,這的確已經分析了C#和VB.NET文件你(和其他可能的預並且展示了它們的層次語法結構,但我不是這個主題的專家,但還沒有給出如何使用這些新服務的答案。無論如何,啓動編輯器擴展的基本進程與此答案中描述的相同。請注意 - 如果您使用這些服務 - 您將變得依賴於Visual Studio 2015+,並且該擴展將無法在早期版本中使用。
我建立了你的規格的程序。它不工作。我插入了一些日誌記錄,並沒有調用任何方法。有任何想法嗎? –
我通過使用「編輯器分類器」項目類型而不是VISX項目類型來獲得此工作。您的演示和我的擴展程序完美運行。 –
@Mike Christian:好的,我無法檢查爲什麼VISX項目類型無法正常工作,但我在答案中爲項目類型添加了備註。 –
只是看看在MSDN http://msdn.microsoft.com/en-us/library/dd885122.aspx
托爾斯滕
@吃豆人:可惜我不得不把它放在後面(由於缺乏資源),所以我從來沒有完全理解它。如果我真的搞清楚了,我會讓你知道的。對於小型操作,我發現寫宏可以很好地工作。 –
@吃豆人:這確實是最棒的。我感覺你對MSDN的東西感到痛苦(有時候)。令人遺憾的是,我認爲這個延伸的東西只是那些'黑色藝術'之一 –
我希望我發佈的答案中的鏈接可以幫助你。這些教程幾乎解釋了我需要知道的關於VS插件的所有內容,即使屏幕截圖缺失。 –