public static SpanData <TData>?GetCurrentSpanReference <TData>(SpanDataCollection <TData> spanReferenceCollection, ITextView textView) { var caretPos = textView.Caret.Position; // There are no refs in virtual space if (caretPos.VirtualSpaces > 0) { return(null); } var pos = caretPos.BufferPosition; // If it's at the end of a word wrapped line, don't mark the reference that's // shown on the next line. if (caretPos.Affinity == PositionAffinity.Predecessor && pos.Position != 0) { pos = pos - 1; var prevSpanData = spanReferenceCollection.Find(pos.Position); if (prevSpanData is null || prevSpanData.Value.Span.End != pos.Position) { return(prevSpanData); } else { return(null); } }
void TextView_Closed(object?sender, EventArgs e) { if (!(documentViewerReferenceEnablers is null)) { foreach (var v in documentViewerReferenceEnablers.Values) { if (v is null) { continue; } v.IsEnabledChanged -= DocumentViewerReferenceEnabler_IsEnabledChanged; v.Dispose(); } } documentViewerReferenceEnablers = null; documentViewerReferenceEnablerProviders = null; currentReference = null; currentSpanReference = null; spanReferenceCollection = SpanDataCollection <ReferenceAndId> .Empty; textView.Closed -= TextView_Closed; textView.Options.OptionChanged -= Options_OptionChanged; textView.Caret.PositionChanged -= Caret_PositionChanged; if (!(documentViewer is null)) { documentViewer.GotNewContent -= DocumentViewer_GotNewContent; } }
public DocumentViewerControl(ITextBufferFactoryService textBufferFactoryService, IDsTextEditorFactoryService dsTextEditorFactoryService, IDocumentViewerHelper textEditorHelper) { if (textBufferFactoryService == null) { throw new ArgumentNullException(nameof(textBufferFactoryService)); } if (dsTextEditorFactoryService == null) { throw new ArgumentNullException(nameof(dsTextEditorFactoryService)); } this.textEditorHelper = textEditorHelper ?? throw new ArgumentNullException(nameof(textEditorHelper)); defaultContentType = textBufferFactoryService.TextContentType; cachedColorsList = new CachedColorsList(); emptyContent = new DocumentViewerContent(string.Empty, CachedTextColorsCollection.Empty, SpanDataCollection <ReferenceInfo> .Empty, new Dictionary <string, object>()); currentContent = new CurrentContent(emptyContent, defaultContentType); spanReferenceCollection = SpanDataCollection <ReferenceAndId> .Empty; var textBuffer = textBufferFactoryService.CreateTextBuffer(textBufferFactoryService.TextContentType); CachedColorsListTaggerProvider.AddColorizer(textBuffer, cachedColorsList); var roles = dsTextEditorFactoryService.CreateTextViewRoleSet(defaultRoles); var options = new TextViewCreatorOptions { EnableUndoHistory = false }; var textView = dsTextEditorFactoryService.CreateTextView(textBuffer, roles, options); var wpfTextViewHost = dsTextEditorFactoryService.CreateTextViewHost(textView, false); this.wpfTextViewHost = wpfTextViewHost; wpfTextViewHost.TextView.Options.SetOptionValue(DefaultWpfViewOptions.AppearanceCategory, AppearanceCategoryConstants.TextEditor); wpfTextViewHost.TextView.Options.SetOptionValue(DefaultTextViewOptions.ViewProhibitUserInputId, true); wpfTextViewHost.TextView.Options.SetOptionValue(DefaultTextViewHostOptions.GlyphMarginId, true); Children.Add(wpfTextViewHost.HostControl); }
/// <summary> /// Constructor /// </summary> /// <param name="text">Text</param> /// <param name="colorCollection">Colors</param> /// <param name="referenceCollection">References</param> /// <param name="customDataDict">Custom data dictionary</param> internal DocumentViewerContent(string text, CachedTextColorsCollection colorCollection, SpanDataCollection <ReferenceInfo> referenceCollection, Dictionary <string, object> customDataDict) { if (text == null) { throw new ArgumentNullException(nameof(text)); } if (colorCollection == null) { throw new ArgumentNullException(nameof(colorCollection)); } if (referenceCollection == null) { throw new ArgumentNullException(nameof(referenceCollection)); } if (customDataDict == null) { throw new ArgumentNullException(nameof(customDataDict)); } colorCollection.Freeze(); Text = text; ColorCollection = colorCollection; ReferenceCollection = referenceCollection; this.customDataDict = customDataDict; MethodDebugInfos = GetCustomData <ReadOnlyCollection <MethodDebugInfo> >(DocumentViewerContentDataIds.DebugInfo) ?? emptyMethodDebugInfos; }
public void Clear() { CurrentWaitAdorner = null; cachedColorsList.Clear(); currentContent = new CurrentContent(emptyContent, defaultContentType); spanReferenceCollection = SpanDataCollection <ReferenceAndId> .Empty; wpfTextViewHost.TextView.TextBuffer.Replace(new Span(0, wpfTextViewHost.TextView.TextBuffer.CurrentSnapshot.Length), string.Empty); }
DocumentViewerHighlightReferencesTagger(ITextView textView) { this.textView = textView ?? throw new ArgumentNullException(nameof(textView)); spanReferenceCollection = SpanDataCollection <ReferenceAndId> .Empty; textView.Closed += TextView_Closed; textView.Options.OptionChanged += Options_OptionChanged; textView.Caret.PositionChanged += Caret_PositionChanged; UpdateReferenceHighlighting(); }
public BlockStructureCollection(CodeBracesRange[] ranges) { if (ranges.Length == 0) { coll = SpanDataCollection <CodeBracesRange[]> .Empty; } else { var builder = new Builder(ranges); coll = new SpanDataCollection <CodeBracesRange[]>(builder.Build()); } }
public BracePairCollection(CodeBracesRange[] ranges) { if (ranges == null) { throw new ArgumentNullException(nameof(ranges)); } if (ranges.Length == 0) { leftSorted = SpanDataCollection <Span> .Empty; rightSorted = SpanDataCollection <Span> .Empty; } else { int prevEnd; var builder = SpanDataCollectionBuilder <Span> .CreateBuilder(ranges.Length); Array.Sort(ranges, LeftSorter.Instance); prevEnd = 0; foreach (var p in ranges) { if (!p.Flags.IsBraces()) { continue; } if (prevEnd <= p.Left.Start) { builder.Add(new Span(p.Left.Start, p.Left.Length), new Span(p.Right.Start, p.Right.Length)); prevEnd = p.Left.End; } } leftSorted = builder.Create(); builder.Clear(); Array.Sort(ranges, RightSorter.Instance); prevEnd = 0; foreach (var p in ranges) { if (!p.Flags.IsBraces()) { continue; } if (prevEnd <= p.Right.Start) { builder.Add(new Span(p.Right.Start, p.Right.Length), new Span(p.Left.Start, p.Left.Length)); prevEnd = p.Right.End; } } rightSorted = builder.Create(); } }
public IEnumerable <ITagSpan <IClassificationTag> > GetTags(NormalizedSnapshotSpanCollection spans) { if (spans.Count == 0) { yield break; } var snapshot = spans[0].Snapshot; if (classifications == null || classificationsVersion != snapshot.Version.VersionNumber) { //TODO: Do this asynchronously classificationsVersion = snapshot.Version.VersionNumber; classifications = CreateClassifications(snapshot); } foreach (var span in spans) { int index = classifications.GetStartIndex(span.Span.Start); if (index < 0) { continue; } for (int i = index; i < classifications.Count; i++) { var spanData = classifications[i]; if (spanData.Span.Start > span.Span.End) { break; } Debug.Assert(spanData.Span.End <= snapshot.Length); if (spanData.Span.End > snapshot.Length) { break; } foreach (var t in GetTags(new SnapshotSpan(snapshot, spanData.Span), spanData.Data)) { yield return(t); } } } }
public bool SetContent(DocumentViewerContent content, IContentType contentType) { if (content == null) { throw new ArgumentNullException(nameof(content)); } if (contentType == null) { contentType = defaultContentType; } HideCancelButton(); var newContent = new CurrentContent(content, contentType); if (currentContent.Equals(newContent)) { return(false); } currentContent = newContent; spanReferenceCollection = newContent.Content.GetCustomData <SpanDataCollection <ReferenceAndId> >(DocumentViewerContentDataIds.SpanReference) ?? SpanDataCollection <ReferenceAndId> .Empty; TextView.TextBuffer.ChangeContentType(contentType, null); cachedColorsList.Clear(); cachedColorsList.Add(0, content.ColorCollection); // If it's the same text, don't update text buffer and caret. It can be the same text if // it's not been cached, eg. it's the resources or some other content with UI content. // This simulates the cached code path above which also doesn't move the caret. And as // an added bonus, it will use less memory and CPU. bool sameText = IsSameTextAsCurrentSnapshot(TextView.TextSnapshot, content.Text); if (!sameText) { TextView.TextBuffer.Replace(new Span(0, TextView.TextBuffer.CurrentSnapshot.Length), content.Text); TextView.Caret.MoveTo(new SnapshotPoint(TextView.TextSnapshot, 0)); TextView.Caret.EnsureVisible(); TextView.Selection.Clear(); } return(true); }
static IEnumerable <SpanData <TData> > GetReferenceInfosFrom <TData>(SpanDataCollection <TData> referenceCollection, int position, bool forward) { if (referenceCollection.Count == 0) { yield break; } int startIndex = referenceCollection.GetStartIndex(position); // If it's between two refs, always prefer the one whose Start == position if (startIndex >= 0 && startIndex + 1 < referenceCollection.Count && referenceCollection[startIndex + 1].Span.Start == position) { startIndex = startIndex + 1; } if (forward) { if (startIndex < 0) { startIndex = referenceCollection.Count - 1; } for (int i = 0; i < referenceCollection.Count; i++) { int index = (startIndex + i + 1) % referenceCollection.Count; yield return(referenceCollection[index]); } } else { if (startIndex < 0) { startIndex = 0; } for (int i = 0; i < referenceCollection.Count; i++) { int index = (referenceCollection.Count + startIndex - (i + 1)) % referenceCollection.Count; yield return(referenceCollection[index]); } } }
void DocumentViewer_GotNewContent(object?sender, DocumentViewerGotNewContentEventArgs e) { spanReferenceCollection = documentViewer?.Content.GetCustomData <SpanDataCollection <ReferenceAndId> >(DocumentViewerContentDataIds.SpanReference) ?? SpanDataCollection <ReferenceAndId> .Empty; currentReference = GetCurrentReference(); currentSpanReference = GetCurrentSpanReference(); }
public DocumentViewerDotNetSpanMap(IModuleIdProvider moduleIdProvider, IReadOnlyList <MethodDebugInfo> methodDebugInfos, SpanDataCollection <ReferenceInfo> references) { this.moduleIdProvider = moduleIdProvider ?? throw new ArgumentNullException(nameof(moduleIdProvider)); this.methodDebugInfos = methodDebugInfos ?? throw new ArgumentNullException(nameof(methodDebugInfos)); this.references = references ?? throw new ArgumentNullException(nameof(references)); }