33

我想在Visual Studio(2010)擴展中開始使用,而且我很難找到合適的材料。我有SDK,但包含的示例似乎是裝飾,窗口和圖標等。Visual Studio文本編輯器擴展

我試圖做一個擴展,將直接與文本編輯器工作(以alphabetize我的所有方法名稱在類中,或使所有常量名稱大寫例如),但我無法找到演示這種類型的功能,甚至是一個教程。

有誰知道我在哪裏可以找到這種東西?

+0

@吃豆人:可惜我不得不把它放在後面(由於缺乏資源),所以我從來沒有完全理解它。如果我真的搞清楚了,我會讓你知道的。對於小型操作,我發現寫宏可以很好地工作。 –

+0

@吃豆人:這確實是最棒的。我感覺你對MSDN的東西感到痛苦(有時候)。令人遺憾的是,我認爲這個延伸的東西只是那些'黑色藝術'之一 –

+0

我希望我發佈的答案中的鏈接可以幫助你。這些教程幾乎解釋了我需要知道的關於VS插件的所有內容,即使屏幕截圖缺失。 –

回答

54

我有相同問題的「入門編輯器擴展」的網站,現在已經瀏覽過的網頁幾個小時,直到我能瞭解並解釋如何從這樣的擴展開始。

在我的下面的例子中,我們將創建一個小而愚蠢的擴展,當編輯完成後,它總會將「Hello」添加到代碼文件的開頭。這是非常基本的,但應該給你一個想法如何繼續開發這件事。

請注意:您必須自行解析代碼文件 - Visual Studio不會提供有關類,方法或其他內容的信息。 [*]

對於那些跳過此答案的用戶,請確保您先下載並安裝了Visual Studio SDK,或者您已經安裝了Visual Studio SDK將無法找到第一步中提到的項目類型。

創建項目

  1. 啓動的(如果你選擇了.NET Framework 4中作爲目標框架纔可見)創造型 「的Visual C#>擴展> VSIX項目」 的新項目。 請注意,您可能不得不選擇「編輯器分類器」項目類型而不是「VSIX項目」類型才能使其工作。下面評論。

  2. 項目創建完成後,將打開「source.extension.vsixmanifest」文件,使您可以設置產品名稱,作者,版本,說明,圖標等。我認爲這一步很自我解釋,現在可以關閉該選項卡並稍後通過打開vsixmanifest文件進行恢復。

創建一個監聽器類,以收到通知的文本編輯器實例的創作

接下來,我們需要傾聽每當一個文本編輯器已經在Visual Studio中創建和綁定我們的代碼格式化工具吧。 VS2010中的文本編輯器是IWpfTextView的一個實例。

  1. 添加一個新的類,我們的項目並將其命名爲TextViewCreationListener。這個類必須實現Microsoft.VisualStudio.Text.Editor.IWpfTextViewCreationListener接口。您需要添加一個對Microsoft.VisualStudio.Text.UI的參考文件。Wpf到您的項目。程序集DLL位於Visual Studio SDK目錄下的VisualStudioIntegration \ Common \ Assemblies \ v4.0中。

  2. 您必須實現接口的TextViewCreated方法。此方法有一個參數,指定已創建的文本編輯器的實例。我們將創建一個新的代碼格式化類,這個實例將在稍後傳遞給它。

  3. 我們需要通過指定屬性[Export(typeof(IWpfTextViewCreationListener))]來使TextViewCreationListener類對Visual Studio可見。將對System.ComponentModel.Composition的引用添加到您的項目中,以獲取Export屬性。

  4. 此外,我們需要指定代碼格式化程序應與文本編輯器綁定的文件類型。我們只想格式化代碼文件而不是純文本文件,因此我們將屬性[ContentType("code")]添加到偵聽器類。你必須添加一個參考Microsoft.VisualStudio.CoreUtility到你的項目爲此。此外,我們只想更改可編輯的代碼,而不是周圍的顏色或裝飾(如示例項目中所示),因此我們將該屬性[TextViewRole(PredefinedTextViewRoles.Editable)]添加到類中。再次,您需要一個新的參考,這次到Microsoft.VisualStudio.Text.UI

  5. 將該類標記爲內部密封。至少這是我的建議。現在你的類應該類似於此:

    [ContentType("code")] 
    [Export(typeof(IWpfTextViewCreationListener))] 
    [TextViewRole(PredefinedTextViewRoles.Editable)] 
    internal sealed class TextViewCreationListener : IWpfTextViewCreationListener 
    { 
        public void TextViewCreated(IWpfTextView textView) 
        { 
        } 
    } 
    

創建代碼格式化

接下來的一類,我們需要一個類處理代碼格式化邏輯,排序方式等。再次,在這個例子中,只要編輯完成,它就會簡單地在文件的開頭添加「Hello」。

  1. 在您的項目中添加一個名爲Formatter的新類。

  2. 添加一個構造函數,其中需要一個IWpfTextView參數。請記住,我們希望將創建的編輯器實例傳遞給我們監聽器類的TextViewCreated方法中的此格式化類(只需將new Formatter(textView);添加到那裏的方法中)。

  3. 將傳遞的實例保存在成員變量中。稍後格式化代碼時(例如,檢索插入位置)它會變得很方便。也綁上編輯器實例的TextBuffer財產ChangedPostChanged事件:

    public Formatter(IWpfTextView view) 
    { 
        _view = view; 
        _view.TextBuffer.Changed += new EventHandler<TextContentChangedEventArgs>(TextBuffer_Changed); 
        _view.TextBuffer.PostChanged += new EventHandler(TextBuffer_PostChanged); 
    } 
    
  4. Changed事件被稱爲每次編輯已經做出的時間(例如輸入一個字符,粘貼代碼或的程序化的變化)。因爲它也會對程序變化做出反應,所以我使用bool來確定我們的擴展或用戶/其他任何內容是否正在更改代碼,並且僅當我們的擴展尚未編輯時才調用我的自定義FormatCode()方法。否則,你會遞歸調用此方法將導致程序崩潰的Visual Studio:

    private void TextBuffer_Changed(object sender, TextContentChangedEventArgs e) 
    { 
        if (!_isChangingText) 
        { 
         _isChangingText = true; 
         FormatCode(e); 
        } 
    } 
    
  5. 我們有這個布爾成員變量在PostChanged事件處理程序再次重置爲false

  6. 讓我們將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); 
         } 
        } 
    } 
    
  7. 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+,並且該擴展將無法在早期版本中使用。

+0

我建立了你的規格的程序。它不工作。我插入了一些日誌記錄,並沒有調用任何方法。有任何想法嗎? –

+3

我通過使用「編輯器分類器」項目類型而不是VISX項目類型來獲得此工作。您的演示和我的擴展程序完美運行。 –

+0

@Mike Christian:好的,我無法檢查爲什麼VISX項目類型無法正常工作,但我在答案中爲項目類型添加了備註。 –

相關問題