6

विजुअल स्टूडियो में #region निर्देश के टेक्स्ट रंग को बदलने के एक सरल तरीके के लिए लंबे समय तक खोज करने के बाद, मैंने निष्कर्ष निकाला है कि ऐसा करने का कोई आसान तरीका नहीं है।विजुअल स्टूडियो संपादक में टेक्स्ट रंग बदलने के लिए ऐड-इन कैसे लिखें?

मुझे पता है कि #region कथन रंग कैसे बदलें, और ध्वस्त क्षेत्र रंग को कैसे बदला जाए, लेकिन मैं क्षेत्र के विवरण के साथ पाठ का रंग बदलना चाहता हूं। तो: - How to change the color of expanded regions' titles in VS2008? देख

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

public void Test() 
{ 
} 

#endregion   <--- this too 

यह बहुत से लोगों को कुछ इस तरह की तलाश कर रहे है।

तो मैं रंग बदलने के लिए एक साधारण विजुअल स्टूडियो एड-इन लिखने पर विचार कर रहा हूं। हालांकि, यह तुलना में मैं Snapshot, Tagger, Classifier, WpfTextViewCreationListener की तरह सोचा था कि यह हो सकता है, वर्गों के साथ, AdornmentLayer आदि

सीधे शब्दों में कहें, मैं कहाँ शुरू करने के लिए पता नहीं है और अधिक जटिल है! मैंने एमएसडीएन साइट पर tutorials के कुछ जोड़े का पालन किया, लेकिन जो कुछ मैं करने की कोशिश कर रहा हूं उसके लिए वे बहुत जटिल लगते हैं।

क्या कोई मुझे ऐसा करने का सबसे आसान तरीका बता सकता है? अर्थात। वीएस एसडीके के भीतर कौन से वर्ग/विधियों/घटनाओं का उपयोग करना चाहिए। मुझे कोई फर्क नहीं पड़ता कि रंग यूआई आदि के माध्यम से अनुकूलन योग्य नहीं है। मैं वीएस -2010 का उपयोग कर रहा हूँ।

संपादित करें: बस मुझे mztools वेबसाइट की सिफारिश की गई थी; मैं वहां भी एक नज़र डालूंगा। यह भी ध्यान दिया गया है कि region एस की स्टैक ओवरफ्लो का सिंटैक्स हाइलाइटिंग बिल्कुल वैसा ही है जो मैं चाहता हूं!

+0

[studiostyl.es] के अनुसार (http://studiostyl.es/schemes/create) सादा पाठ होंगे। – Default

उत्तर

11

अंत में मैं कम से कम वीएस -2010 के लिए एक समाधान के साथ आया था। जबकि मैंने इसे '#region' और '#endregion' टैग रंग देने के लिए उपयोग किया है, तो एक समान समाधान विजुअल स्टूडियो विंडो में किसी भी टेक्स्ट सामग्री के लिए लागू होना चाहिए।

ऐसा लगता है कि इस प्रकार की समस्या को IViewTaggerProvider बनाकर हल किया जा सकता है जो 'वर्गीकरण' के साथ स्रोत कोड के हिस्सों को 'टैग' करेगा। विजुअल स्टूडियो उस वर्गीकरण के साथ टैग किए गए पाठ के लिए एक शैली प्रदान करेगा जिसे उपयोगकर्ता द्वारा वांछित शैली में उपकरण> विकल्प ...> पर्यावरण> फ़ॉन्ट्स और रंग के माध्यम से वांछित शैली में बदला जा सकता है।

[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>; 
    } 
} 

यह एक ITagger वस्तु है, जो, एक दृश्य स्टूडियो पाठ दृश्य को देखते हुए दिया वर्गीकरण प्रकार के साथ पाठ के कुछ हिस्सों को टैग कर लेगा बनाता है:


टैगर प्रदाता की तरह लग रहा है। ध्यान दें कि यह सभी टेक्स्ट दृश्यों के लिए काम करेगा (यानी स्रोत कोड संपादक, 'परिणाम खोजें' विंडो इत्यादि)। ContentType विशेषता (केवल C# पर) संपादित करके इसे बदलना संभव हो सकता है?


वर्गीकरण प्रकार (इस मामले "क्षेत्र अग्रभूमि" में) के रूप में परिभाषित किया गया है:

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; 
    } 
} 

Order विशेषता निर्धारित करता है जब वर्गीकरण अन्य वर्गीकरण जो भी लागू हो सकता है की तुलना में लागू किया जाएगा पाठ की एक अवधि। DisplayNameउपकरण> विकल्प ... संवाद में उपयोग किया जाएगा।


एक बार वर्गीकरण परिभाषित किया गया है, एक ITagger वर्ग के लिए एक दृश्य के पाठ खोज और पाठ यह पाता है के लागू वर्गों के लिए वर्गीकरण प्रदान कर सकते हैं।

बस शब्दों में कहें, इसका काम टेक्स्ट दृश्य के ViewLayoutChanged ईवेंट को सुनना है, जिसे प्रदान किया गया पाठ दृश्य की सामग्री में परिवर्तन होने पर निकाल दिया जाता है (उदा। क्योंकि उपयोगकर्ता ने कुछ टाइप किया है)।

इसके बाद इसे उस पाठ के क्षेत्र के लिए टेक्स्ट खोजना चाहिए जिसमें उसे रुचि है (जिसे 'अवधि' कहा जाता है)। यहां, यह #region या #endregion युक्त लाइनों के स्पैन देता है। मैंने यह सरल रखा है, लेकिन TextSearchService मिलान खोजने के लिए उपयोग किया जाता है नियमित अभिव्यक्तियों का उपयोग करके भी खोज सकता है।

अंत में, एक विधि पाठ यह पाया गया है की टैग पुनः प्राप्त करने के दृश्य स्टूडियो के लिए प्रदान की जाती है, GetTags() कहा जाता है। किसी दिए गए अवधि संग्रह के लिए, यह वर्गीकरण टैग के साथ टेक्स्ट स्पैन लौटाएगा, यानी उन स्पैन के क्षेत्र जिन्हें एक निश्चित तरीके से वर्गीकृत किया जाना चाहिए।

इसका कोड है:

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)); 
     } 
    } 
} 

संक्षिप्तता के लिए मैं नामस्थान और का उपयोग कर बयान है, जो प्रपत्र Microsoft.VisualStudio.Text.* की आम तौर पर कर रहे हैं नहीं दिखाए हैं। इनके लिए उपलब्ध होने के लिए, Visual Studio 2010 SDK को पहले डाउनलोड किया जाना चाहिए।


मैं बिना किसी मुद्दे के पिछले कुछ महीनों के लिए इस समाधान का उपयोग कर रहा हूं।

एक सीमा मैंने देखा है कि रंग 'मिश्रित' नहीं हैं, इसलिए 100% से कम अस्पष्टता वाला रंग एक रंग में मौजूदा रंगों को 'फीका' नहीं करेगा - जो सिंटैक्स हाइलाइटिंग को संरक्षित करने के लिए उपयोगी हो सकता है।

मुझे इसकी दक्षता का भी थोड़ा सा विचार नहीं है, क्योंकि ऐसा लगता है कि यह प्रत्येक कुंजीपटल पर बार-बार एक दस्तावेज़ खोजेगा। मैंने यह देखने के लिए शोध नहीं किया है कि विजुअल स्टूडियो इसे किसी भी तरह अनुकूलित करता है या नहीं। मुझे बड़ी फ़ाइलों (> ~ 1000 लाइनों) पर विजुअल स्टूडियो की मंदी दिखाई देती है, लेकिन मैं Resharper का भी उपयोग करता हूं, इसलिए मैं इसे अकेले इस प्लगइन में विशेषता नहीं दे सकता।

यह ज्यादातर अटकलबाजी का उपयोग कर कोडित किया गया था के रूप में, मैं कोई टिप्पणी या कोड में परिवर्तन जो स्पष्ट या चीजों को आसान बनाने या कोड के प्रदर्शन पर सुधार सकता स्वागत करते हैं।

+0

कोई मौका पूर्ण परियोजना खुला स्रोत कहीं पोस्ट किया जाता है? – Maslow

+0

नहीं - अभी तक नहीं। हालांकि, यह एक अच्छा विचार होगा, कोई सुझाव यह कहां पोस्ट करना है? –

+0

codeplex.com या github? मैंने बस breusable.codeplex.com – Maslow

0

मुझे लगता है कि आप दृश्य स्टूडियो ऐड-इन परियोजना के साथ शुरू कर सकता है, यह EnvDTE है, जो दृश्य स्टूडियो ऑब्जेक्ट मॉडल के रूप में माना जाता था, के लिए इस्तेमाल किया जाएगा और कृपया MSDN दस्तावेज़ यहाँ मिल: http://msdn.microsoft.com/en-us/vstudio/bb968855 आप अपने दृश्य स्टूडियो व्यवहार को नियंत्रित कर सकता है, जैसे EnvDTE द्वारा डीबगर, कोड संपादक और इतने पर।

संबंधित मुद्दे