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());
        }
Exemple #4
0
 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;
 }
Exemple #5
0
        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)
 {
 }
Exemple #7
0
 public void AugmentQuickInfoSession(IQuickInfoSession?session, IList <object?>?quickInfoContent, out ITrackingSpan?applicableToSpan)
 {
     if (session is not(null or {
         IsDismissed: true
     }) &&
Exemple #8
0
        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));
                        }