6

Visual Studioで#regionディレクティブのテキストの色を変更する簡単な方法を探してから、簡単な方法はないと結論づけました。Visual Studioエディタでテキストの色を変更するアドインを作成する方法?

#regionステートメントの色を変更する方法と、折りたたまれた領域の色を変更する方法は分かっていますが、領域の説明でテキストの色を変更したいと思います。だから、:

#region Some text <--- all this text should be in a different color 

public void Test() 
{ 
} 

#endregion   <--- this too 

多くの人がこのような何かを探しているようだ - How to change the color of expanded regions' titles in VS2008?を参照してください。

私は、単純なVisual Studioアドインを使って色を変更する方法を検討してきました。 はしかし、それはSnapshotTaggerClassifierWpfTextViewCreationListenerAdornmentLayerなど

のようなクラスは、簡単に言えばと、私はどこから始めればわからないが、私はそれが可能だろうと思ったよりも複雑です!私はMSDNのサイトでtutorialsの2つに従っていましたが、私がしようとしているものはあまりにも複雑です。

誰かがこれを行う最も簡単な方法を教えてもらえますか?つまりどのクラス/メソッド/イベントを使用する必要がありますVS SDK内の。 UIなどで色をカスタマイズできないのではないかと心配しています。私はVS2010を使用しています。

編集:ちょうど私にはmztoolsウェブサイトがおすすめです。私はそこにも見ていきます。また、StackOverflowの構文強調表示regionは、私が望むものとほぼ同じです!

+0

[スタジオスチル.es](http://studiostyl.es/schemes/create)によると、これはプレーンテキストになります。 – Default

答えて

11

私は最終的に少なくともVS2010のための解決策を思いついた。 私はこれを '#region'と '#endregion'タグに色付けしていますが、Visual Studioウィンドウのテキストコンテンツにも同様のソリューションを適用する必要があります。

この種の問題は、ソースコードの一部に「分類」を「付ける」IViewTaggerProviderを作成することで解決できるようです。 Visual Studioは、その分類でタグ付けされたテキストのスタイルを提供します。ツール>オプション...>環境>フォントと色を使用して、ユーザーが目的のスタイルに変更できます。


タガープロバイダは、次のようになります。

[Export(typeof(IViewTaggerProvider))] 
[ContentType("any")] 
[TagType(typeof(ClassificationTag))] 
public sealed class RegionTaggerProvider : IViewTaggerProvider 
{ 
    [Import] 
    public IClassificationTypeRegistryService Registry; 

    [Import] 
    internal ITextSearchService TextSearchService { get; set; } 

    public ITagger<T> CreateTagger<T>(ITextView textView, ITextBuffer buffer) where T : ITag 
    { 
     if (buffer != textView.TextBuffer) 
      return null; 

     var classType = Registry.GetClassificationType("region-foreground"); 
     return new RegionTagger(textView, TextSearchService, classType) as ITagger<T>; 
    } 
} 

これは、Visual Studioのテキストビューを与え、ITaggerオブジェクトを作成し、指定された分類タイプを使用してテキストの一部をタグ付けします。これはすべてのテキストビュー(つまり、ソースコードエディタ、[結果の検索]ウィンドウなど)で機能します。これを変更するには、ContentType属性(C#?)を編集します。


分類タイプ(この場合は「地域前景」)は次のように定義される。分類も適用することができる他の分類に比べて適用される場合Order属性が決定

public static class TypeExports 
{ 
    [Export(typeof(ClassificationTypeDefinition))] 
    [Name("region-foreground")] 
    public static ClassificationTypeDefinition OrdinaryClassificationType; 
} 

[Export(typeof(EditorFormatDefinition))] 
[ClassificationType(ClassificationTypeNames = "region-foreground")] 
[Name("region-foreground")] 
[UserVisible(true)] 
[Order(After = Priority.High)] 
public sealed class RegionForeground : ClassificationFormatDefinition 
{ 
    public RegionForeground() 
    { 
     DisplayName = "Region Foreground"; 
     ForegroundColor = Colors.Gray; 
    } 
} 

テキストの範囲。 DisplayNameは、ツール>オプション...ダイアログで使用されます。


分類が定義されると、ITaggerクラスは、ビューのテキストを検索し、見つかったテキストの該当するセクションのための分類を提供することができます。

簡単に言えば、テキストビューのViewLayoutChangedイベントをリッスンすることです。テキストビューのコンテンツが変更されたとき(ユーザーが何かを入力したなど)に発生します。

それはそれは(「スパン」と呼ばれる)に興味を持っているテキストエリアのテキストを検索する必要があります。ここでは、#regionまたは#endregionのいずれかを含む行のスパンを返します。これを単純にしておきましたが、一致するものを見つけるのに使われるTextSearchServiceは、正規表現を使って検索することもできます。

最後に、この方法は、それが発見したテキストのタグを取得するには、Visual Studioのために提供され、GetTags()と呼ばれます。所与のスパンコレクションについて、これは、分類タグ、すなわち特定の方法で分類されるべきスパンの領域を有するテキストスパンを返す。

そのコードは次のとおりです。私は名前空間と形Microsoft.VisualStudio.Text.*を典型的に使用して文を省略した簡略化のため

public sealed class RegionTagger : ITagger<ClassificationTag> 
{ 
    private readonly ITextView m_View; 
    private readonly ITextSearchService m_SearchService; 
    private readonly IClassificationType m_Type; 
    private NormalizedSnapshotSpanCollection m_CurrentSpans; 

    public event EventHandler<SnapshotSpanEventArgs> TagsChanged = delegate { }; 

    public RegionTagger(ITextView view, ITextSearchService searchService, IClassificationType type) 
    { 
     m_View = view; 
     m_SearchService = searchService; 
     m_Type = type; 

     m_CurrentSpans = GetWordSpans(m_View.TextSnapshot); 

     m_View.GotAggregateFocus += SetupSelectionChangedListener; 
    } 

    private void SetupSelectionChangedListener(object sender, EventArgs e) 
    { 
     if (m_View != null) 
     { 
      m_View.LayoutChanged += ViewLayoutChanged; 
      m_View.GotAggregateFocus -= SetupSelectionChangedListener; 
     } 
    } 

    private void ViewLayoutChanged(object sender, TextViewLayoutChangedEventArgs e) 
    { 
     if (e.OldSnapshot != e.NewSnapshot) 
     { 
      m_CurrentSpans = GetWordSpans(e.NewSnapshot); 
      TagsChanged(this, new SnapshotSpanEventArgs(new SnapshotSpan(e.NewSnapshot, 0, e.NewSnapshot.Length))); 
     } 
    } 

    private NormalizedSnapshotSpanCollection GetWordSpans(ITextSnapshot snapshot) 
    { 
     var wordSpans = new List<SnapshotSpan>(); 
     wordSpans.AddRange(FindAll(@"#region", snapshot).Select(regionLine => regionLine.Start.GetContainingLine().Extent)); 
     wordSpans.AddRange(FindAll(@"#endregion", snapshot).Select(regionLine => regionLine.Start.GetContainingLine().Extent)); 
     return new NormalizedSnapshotSpanCollection(wordSpans); 
    } 

    private IEnumerable<SnapshotSpan> FindAll(String searchPattern, ITextSnapshot textSnapshot) 
    { 
     if (textSnapshot == null) 
      return null; 

     return m_SearchService.FindAll(
      new FindData(searchPattern, textSnapshot) { 
        FindOptions = FindOptions.WholeWord | FindOptions.MatchCase 
       }); 
    } 

    public IEnumerable<ITagSpan<ClassificationTag>> GetTags(NormalizedSnapshotSpanCollection spans) 
    { 
     if (spans == null || spans.Count == 0 || m_CurrentSpans.Count == 0) 
      yield break; 

     ITextSnapshot snapshot = m_CurrentSpans[0].Snapshot; 
     spans = new NormalizedSnapshotSpanCollection(spans.Select(s => s.TranslateTo(snapshot, SpanTrackingMode.EdgeExclusive))); 

     foreach (var span in NormalizedSnapshotSpanCollection.Intersection(m_CurrentSpans, spans)) 
     { 
      yield return new TagSpan<ClassificationTag>(span, new ClassificationTag(m_Type)); 
     } 
    } 
} 

。これらを利用できるようにするには、まずVisual Studio 2010 SDKをダウンロードする必要があります。


私は過去数ヶ月間この問題を解決しています。

色がブレンドされていないことがわかりましたので、不透明度が100%未満の色は、スパン内の既存の色を「フェードアウト」しません。これは構文強調を維持するのに便利です。

それは繰り返し、各キー操作上のドキュメントを検索しますようにそれが見えるように私はまた、その効率の小さなアイデアを持っています。 Visual Studioがこれを何とか最適化しているかどうかを調べるための調査は行っていません。私は大きなファイル(>〜1000行)でVisual Studioの速度が低下することに気づきますが、私はResharperも使用していますので、このプラグインだけではないと思います。これは主に当て推量を使用してコード化されたとして

は、私は、任意のコメントや明確化や、物事を単純化したり、コードのパフォーマンスを改善でき、コードの変更を歓迎します。

+0

万が一の完全なプロジェクトがどこかに投稿されたオープンソースですか? – Maslow

+0

いいえ - まだありません。良いアイデアだろう、どんな提案を投稿するか? –

+0

codeplex.comまたはgithub?私はちょうど私の投稿をbreusable.codeplex.comに投稿しました – Maslow

0

私はあなたがVisual Studioのアドインプロジェクトを開始することができ、それは、Visual StudioオブジェクトモデルとしたEnvDTEを、使用、およびMSDNのドキュメントをここで見つけてくださいうと思います。 http://msdn.microsoft.com/en-us/vstudio/bb968855 あなたのVisual Studioの動作を制御することができ、同様にデバッガ、コードエディタなどがEnvDTEによって実装されています。

関連する問題