33

Visual Studio(2010)拡張を開始しようとしており、適切な資料を見つけるのに苦労しています。私はSDKを持っていますが、付属のサンプルは装飾者、ウィンドウ、アイコンのようです。Visual Studioテキストエディタ拡張子

私はテキストエディタ(クラス内のすべてのメソッド名をアルファベット順に並べたり、すべての定数名を大文字にするなど)に直接的に対応する拡張機能を作成しようとしていますが、デモは見つかりませんこのタイプの機能、またはチュートリアルでもあります。

誰も私がこの種のものを見つけることができるか知っていますか?

+0

@ Pac-Man:悲しいことに、私はそれをバックバーナーに置く必要があったので(リソースが不足しているため)、決してそれに慣れることはできませんでした。私がそれを理解するなら、私はあなたに知らせるでしょう。小規模な操作では、マクロを書くことはかなりうまくいくことが分かりました。 –

+0

@ Pac-Man:それは確かに最も優れているだろう。私はMSDNのもの(時には)に関するあなたの苦痛を感じる。悲しいことに、私はこの拡張物はそれらの「黒い芸術」の一つに過ぎないと思う。 –

+0

私が投稿した答えの私のリンクがあなたを助けることを願っています。これらのチュートリアルでは、スクリーンショットが見つからなくても、VSアドインについて知っておく必要があるすべてについて私に説明しています。 –

答えて

54

の「エディタの拡張入門」サイトを見ていると、今ウェブに私ができることまで数時間を閲覧していますそのような拡張からどのように始める必要があるかを理解し、説明することができます。

次の例では、編集が行われたときにコードファイルの先頭に常に「Hello」を追加する小さなダム拡張を作成します。非常に基本的ですが、このことをどのように開発し続けるかというアイデアを伝えるべきです。

警告:Visual Studioでは、コードファイルを完全に解析する必要があります。クラス、メソッドなどの情報は含まれていません。これは、コードの書式設定ツールを実行するときに取るべき最大のハードルであり、この回答でカバーされません。[*]

この回答をスキップした人は、まずVisual Studio SDKをダウンロードしてインストールしてください手順1で述べたプロジェクトの種類が見つかりません。タイプ "ビジュアルC#>拡張> VSIXプロジェクト"(あなたがターゲットフレームワークとしての.NET Framework 4を選択した場合のみ表示)の新しいプロジェクトを作成することによって、プロジェクト

  1. スタートを作成

    「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))]属性を指定して、Visual StudioにTextViewCreationListenerクラスを表示させる必要があります。 Export属性のSystem.ComponentModel.Compositionへの参照をプロジェクトに追加します。

  4. さらに、コードフォーマッタをテキストエディタにバインドするファイルの種類を指定する必要があります。テキストファイルではなくコードファイルの書式を整えるのが好きなので、属性[ContentType("code")]をリスナークラスに追加します。このために、Microsoft.VisualStudio.CoreUtilityへの参照をプロジェクトに追加する必要があります。

  5. また、編集可能なコードだけを変更し、周囲の色や装飾は変更しないでください(この例のプロジェクトのように)。[TextViewRole(PredefinedTextViewRoles.Editable)]という属性をクラスに追加します。再度、新しい参照が必要です。今度はMicrosoft.VisualStudio.Text.UIです。

  6. クラスを内部シールとしてマークします。少なくとも私のお勧めです。今、あなたのクラスは次のようになります。

[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イベント(例えばコードまたはprogrammatical変更を貼り付け、文字を入力して)、編集が行われたたびに呼び出されます。私はプログラムの変更にも反応するので、拡張機能やユーザ/その他のものが現時点でコードを変更しているのかどうかを判断し、拡張機能がまだ編集されていない場合にのみ私のカスタムFormatCode()メソッドを呼び出します。そうしないと、再帰的にVisual Studioのをクラッシュしていました。このメソッドを呼び出します:

    private void TextBuffer_Changed(object sender, TextContentChangedEventArgs e) 
    { 
        if (!_isChangingText) 
        { 
         _isChangingText = true; 
         FormatCode(e); 
        } 
    } 
    
  5. 我々はfalseに再びPostChangedイベントハンドラで、このブールメンバ変数をリセットする必要があります。

  6. Changedイベントのイベント引数は、最後の編集と現在の変更の間に変更された内容が含まれているので、FormatCodeのカスタムメソッドに渡しましょう。これらの編集内容は、INormalizedTextChangeCollectionの配列e.Changes(このタイプの詳細については、投稿の最後のリンク)に格納されています。これらのすべての編集をループし、カスタム編集HandleChangeメソッドをこの編集で生成された新しいテキストで呼び出します。キーワードは、特定の方法でそれらを処理するために、我々は実際にスキャンでき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. (あなたが自分で任意のコードを解析する必要があり、忘れないでください!) - しかし、ここで私達はちょうどdumblyに「こんにちは」を追加テストの目的でファイルの開始。例えば。エディタインスタンスの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:OK、VISXプロジェクトのタイプが正しく機能しなかった理由を確認することはできませんが、回答のプロジェクトタイプにメモを追加しました。 –

関連する問題