private void CleanUpEndLocation(ITrackingSpan?endTrackingSpan) { if (endTrackingSpan != null) { // Find the empty comment and remove it... var endSnapshotSpan = endTrackingSpan.GetSpan(SubjectBuffer.CurrentSnapshot); SubjectBuffer.Delete(endSnapshotSpan.Span); // Remove the whitespace before the comment if necessary. If whitespace is removed, // then remember the indentation depth so we can appropriately position the caret // in virtual space when the session is ended. var line = SubjectBuffer.CurrentSnapshot.GetLineFromPosition(endSnapshotSpan.Start.Position); var lineText = line.GetText(); if (lineText.Trim() == string.Empty) { _indentCaretOnCommit = true; var document = this.SubjectBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges(); if (document != null) { var lineFormattingOptions = SubjectBuffer.GetLineFormattingOptions(EditorOptionsService, explicitFormat: false); _indentDepth = lineText.GetColumnFromLineOffset(lineText.Length, lineFormattingOptions.TabSize); } else { // If we don't have a document, then just guess the typical default TabSize value. _indentDepth = lineText.GetColumnFromLineOffset(lineText.Length, tabSize: 4); } SubjectBuffer.Delete(new Span(line.Start.Position, line.Length)); _ = SubjectBuffer.CurrentSnapshot.GetSpan(new Span(line.Start.Position, 0)); } } }
private void SetNewEndPosition(ITrackingSpan?endTrackingSpan) { Contract.ThrowIfNull(ExpansionSession); if (SetEndPositionIfNoneSpecified(ExpansionSession)) { return; } if (endTrackingSpan != null) { if ( !TryGetSpanOnHigherBuffer( endTrackingSpan.GetSpan(SubjectBuffer.CurrentSnapshot), TextView.TextBuffer, out var endSpanInSurfaceBuffer ) ) { return; } ExpansionSession.EndSpan = new SnapshotSpan(endSpanInSurfaceBuffer.Start, 0); } }
protected override void AugmentQuickInfoSessionCore( IQuickInfoSession session, IList <object?> quickInfoContent, IDocumentMarkup documentMarkup, TooltipFormattingProvider tooltipFormattingProvider, out ITrackingSpan?applicableToSpan) { applicableToSpan = null; session.StoreVsSquiggleContents(quickInfoContent.ToArray()); }
public NavigationBarItem( string text, Glyph glyph, ImmutableArray <ITrackingSpan> trackingSpans, ITrackingSpan?navigationTrackingSpan, ImmutableArray <NavigationBarItem> childItems = default, int indent = 0, bool bolded = false, bool grayed = false) { this.Text = text; this.Glyph = glyph; this.TrackingSpans = trackingSpans; this.NavigationTrackingSpan = navigationTrackingSpan; this.ChildItems = childItems.NullToEmpty(); this.Indent = indent; this.Bolded = bolded; this.Grayed = grayed; }
public static bool IsSameTrackingSpan(ITrackingSpan?a, ITrackingSpan?b) { if (a == b) { return(true); } if (a is null || b is null) { return(false); } if (a.TextBuffer != b.TextBuffer) { return(false); } var sa = a.GetSpan(a.TextBuffer.CurrentSnapshot); var sb = b.GetSpan(b.TextBuffer.CurrentSnapshot); return(sa == sb); }
public NavigationBarPresentedItem( string text, Glyph glyph, ImmutableArray <ITrackingSpan> trackingSpans, ITrackingSpan?navigationTrackingSpan, ImmutableArray <NavigationBarItem> childItems, bool bolded, bool grayed) : base( text, glyph, trackingSpans, navigationTrackingSpan, childItems, indent: 0, bolded: bolded, grayed: grayed) { }
public void AugmentQuickInfoSession(IQuickInfoSession?session, IList <object?>?quickInfoContent, out ITrackingSpan?applicableToSpan) { if (session is not(null or { IsDismissed: true }) &&
public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> quickInfoContent, out ITrackingSpan?applicableToSpan) { applicableToSpan = null; var qiSession = QuickInfoSession.TryGetSession(session); if (qiSession is null) { // Mouse hovered over something and the default quick info controller created // a quick info session. if (session.Properties.ContainsProperty(hasTriggeredQuickInfoKey)) { return; } session.Properties.AddProperty(hasTriggeredQuickInfoKey, null); var point = session.GetTriggerPoint(session.TextView.TextSnapshot); if (!(point is null)) { quickInfoTriggerServiceProvider.Create(session.TextView).TryTrigger(point.Value, session.TrackMouse); } return; } // The item has been fetched async, now show it to the user // It's possible for another quick info session to already be active, eg. when // hovering over a url in a string, so close it. quickInfoTriggerServiceProvider.CloseOtherSessions(session); var item = qiSession.Item; Debug2.Assert(!(item is null)); if (item is null) { return; } var info = qiSession.State; Debug.Assert(item.TextSpan.End <= info.Snapshot.Length); if (item.TextSpan.End > info.Snapshot.Length) { return; } applicableToSpan = info.Snapshot.CreateTrackingSpan(item.TextSpan.ToSpan(), SpanTrackingMode.EdgeInclusive); foreach (var o in quickInfoContentCreatorProvider.Create(session.TextView).Create(item)) { quickInfoContent.Add(o); } }
protected override void AugmentQuickInfoSessionCore( IQuickInfoSession session, IList <object?> quickInfoContent, IDocumentMarkup documentMarkup, TooltipFormattingProvider tooltipFormattingProvider, out ITrackingSpan?applicableToSpan) { applicableToSpan = null; ITextSnapshot textSnapshot = TextBuffer.CurrentSnapshot; TextRange textRange = GetCurrentTextRange(session, textSnapshot); IShellLocks shellLocks = Shell.Instance.GetComponent <IShellLocks>(); Span? finalSpan = null; void GetEnhancedTooltips() { using (shellLocks.UsingReadLock()) { IDocument document = documentMarkup.Document; var presenter = new MultipleTooltipContentPresenter(tooltipFormattingProvider.GetTooltipFormatting(), document); IContextBoundSettingsStore settings = document.GetSettings(); ISolution?solution = MainQuickInfoSource.TryGetCurrentSolution(); bool hasIdentifierTooltipContent = false; var resolveContext = solution is null ? UniversalModuleReferenceContext.Instance : document.GetContext(solution); using (CompilationContextCookie.GetOrCreate(resolveContext)) { if (solution is not null && MainQuickInfoSource.GetIdentifierContentGroup(textRange.CreateDocumentRange(document), solution, settings) is { } contentGroup) { foreach (IdentifierTooltipContent content in contentGroup.Identifiers) { presenter.AddIdentifierTooltipContent(content); finalSpan = content.TrackingRange.ToSpan().Union(finalSpan); hasIdentifierTooltipContent = true; } if (contentGroup.ArgumentRole is not null) { presenter.AddArgumentRoleTooltipContent(contentGroup.ArgumentRole); // Only track the argument role if we have nothing else displayed. // See https://github.com/MrJul/ReSharper.EnhancedTooltip/issues/70 finalSpan ??= contentGroup.ArgumentRole.TrackingRange.ToSpan(); } } var highlighters = documentMarkup.GetHighlightersOver(textRange).ToList(); foreach (var highlighter in highlighters) { IEnumerable <IReSharperTooltipContent> contents = MainQuickInfoSource.GetTooltipContents(highlighter, highlighter.Range, documentMarkup, solution, hasIdentifierTooltipContent); foreach (IReSharperTooltipContent content in contents) { if (presenter.TryAddReSharperContent(content)) { finalSpan = content.TrackingRange.ToSpan().Union(finalSpan); } } } } var vsSquiggleContents = session.RetrieveVsSquiggleContents() .OfType <string>() .ToSet(); bool ignoredFirstVsElement = false; foreach (object?content in quickInfoContent) { if (content is null) { continue; } // ignore existing R# elements if (content is IQuickInfoContent) { continue; } var contentFullName = content.GetType().FullName; if (content.ToString().Contains("quickinfo:")) { continue; } // ignore the first VS element, as it's the identifier tooltip and we already have one if (hasIdentifierTooltipContent && !ignoredFirstVsElement) { if (contentFullName == VsFullTypeNames.ContainerElement || /* VS 2017 >= 15.8 */ contentFullName == VsFullTypeNames.QuickInfoDisplayPanel || /* VS 2015 and VS 2017 < 15.8 */ content is ITextBuffer /* VS2012 and VS2013 */) { ignoredFirstVsElement = true; continue; } } // ignore Roslyn's bulb info placeholder (interactive tooltip "press ctrl+.") if (contentFullName == VsFullTypeNames.LightBulbQuickInfoPlaceHolder) { continue; } if (contentFullName == VsFullTypeNames.QuickInfoDisplayPanel) { presenter.AddVsIdentifierContent(new VsIdentifierContent(content)); } else if (content is string stringContent && vsSquiggleContents.Contains(stringContent)) { presenter.AddVsSquiggleContent(new VsSquiggleContent(stringContent)); }