अंत में मैं कम से कम वीएस -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 का भी उपयोग करता हूं, इसलिए मैं इसे अकेले इस प्लगइन में विशेषता नहीं दे सकता।
यह ज्यादातर अटकलबाजी का उपयोग कर कोडित किया गया था के रूप में, मैं कोई टिप्पणी या कोड में परिवर्तन जो स्पष्ट या चीजों को आसान बनाने या कोड के प्रदर्शन पर सुधार सकता स्वागत करते हैं।
[studiostyl.es] के अनुसार (http://studiostyl.es/schemes/create) सादा पाठ होंगे। – Default