Exemplo n.º 1
0
        public SnapshotSpan GetSpanOfEnclosing(SnapshotSpan activeSpan)
        {
            if (!XmlBackgroundParser.TryGetParser(activeSpan.Snapshot.TextBuffer, out var parser))
            {
                return(codeNavigator.GetSpanOfEnclosing(activeSpan));
            }

            // use last parse if it's up to date, which is most likely will be
            // else use a spine from the end of the selection and update as needed
            var            lastParse = parser.LastOutput;
            List <XObject> nodePath;
            XmlSpineParser spine = null;

            if (lastParse != null && lastParse.TextSnapshot.Version.VersionNumber == activeSpan.Snapshot.Version.VersionNumber)
            {
                var n = lastParse.XDocument.FindAtOrBeforeOffset(activeSpan.Start.Position);
                nodePath = n.GetPath();
            }
            else
            {
                spine    = parser.GetSpineParser(activeSpan.Start);
                nodePath = spine.AdvanceToNodeEndAndGetNodePath(activeSpan.Snapshot);
            }

            // this is a little odd because it was ported from MonoDevelop, where it has to maintain its own stack of state
            // for contract selection. it describes the current semantic selection as a node path, the index of the node in that path
            // that's selected, and the kind of selection that node has.
            int            selectedNodeIndex = nodePath.Count;
            SelectionLevel selectionLevel    = default;

            // keep on expanding the selection until we find one that contains the current selection but is a little bigger
            while (ExpandSelection(nodePath, spine, activeSpan, ref selectedNodeIndex, ref selectionLevel))
            {
                var selectionSpan = GetSelectionSpan(activeSpan.Snapshot, nodePath, ref selectedNodeIndex, ref selectionLevel);
                if (selectionSpan is TextSpan s && s.Start <= activeSpan.Start && s.End >= activeSpan.End && s.Length > activeSpan.Length)
                {
                    var selectionSnapshotSpan = new SnapshotSpan(activeSpan.Snapshot, s.Start, s.Length);

                    // if we're in content, the code navigator may be able to make a useful smaller expansion
                    if (selectionLevel == SelectionLevel.Content)
                    {
                        var codeNavigatorSpan = codeNavigator.GetSpanOfEnclosing(activeSpan);
                        if (selectionSnapshotSpan.Contains(codeNavigatorSpan))
                        {
                            return(codeNavigatorSpan);
                        }
                    }
                    return(selectionSnapshotSpan);
                }
            }

            return(codeNavigator.GetSpanOfEnclosing(activeSpan));
        }
Exemplo n.º 2
0
        public bool TryGetUE4Macro(SnapshotPoint triggerPoint, out UE4MacroStatement ue4MacroStatement)
        {
            ue4MacroStatement = null;

            var currentPoint = triggerPoint - 1;
            var extent       = _navigator.GetExtentOfWord(currentPoint);

            var statement     = _navigator.GetSpanOfEnclosing(extent.Span);
            var statementText = statement.GetText();

            var match = Regex.Match(statementText, $@"({UE4Statics.MacroNamesRegExPatern})\((.*)\)",
                                    RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(100));

            if (!match.Success)
            {
                return(false);
            }
            if (!match.Groups[1].Success || !match.Groups[2].Success)
            {
                return(false);
            }

            var contentPosition = statement.Start + match.Groups[2].Index;
            var contentEnd      = contentPosition + match.Groups[2].Length;

            var specifiersSpan = new SnapshotSpan(contentPosition, contentEnd);


            var macro = (UE4Macros)Enum.Parse(typeof(UE4Macros), match.Groups[1].Value.ToUpper());

            ue4MacroStatement = new UE4MacroStatement(specifiersSpan, macro);
            return(true);
        }
Exemplo n.º 3
0
        public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> qiContent, out ITrackingSpan applicableToSpan)
        {
            // Map the trigger point down to our buffer.
            SnapshotPoint?subjectTriggerPoint = session.GetTriggerPoint(_mSubjectBuffer.CurrentSnapshot);

            if (!subjectTriggerPoint.HasValue)
            {
                applicableToSpan = null;
                return;
            }

            ITextSnapshot currentSnapshot = subjectTriggerPoint.Value.Snapshot;

            //look for occurrences of our QuickInfo words in the span
            ITextStructureNavigator navigator = _mProvider.NavigatorService.GetTextStructureNavigator(_mSubjectBuffer);



            TextExtent extent = navigator.GetExtentOfWord(subjectTriggerPoint.Value);

            if (extent.IsSignificant)
            {
                var tt1 = navigator.GetSpanOfNextSibling(extent.Span);
                var tt2 = navigator.GetSpanOfFirstChild(extent.Span);
                var tt3 = navigator.GetSpanOfPreviousSibling(extent.Span);
                var tt4 = navigator.GetSpanOfEnclosing(extent.Span);
                var t1  = tt1.GetText();
                var t2  = tt2.GetText();
                var t3  = tt3.GetText();
            }

            string searchText = extent.Span.GetText();

            foreach (string key in _mDictionary.Keys)
            {
                int foundIndex = searchText.IndexOf(key, StringComparison.CurrentCultureIgnoreCase);
                if (foundIndex > -1)
                {
                    applicableToSpan = currentSnapshot.CreateTrackingSpan
                                       (
                        //querySpan.Start.Add(foundIndex).Position, 9, SpanTrackingMode.EdgeInclusive
                        extent.Span.Start + foundIndex, key.Length, SpanTrackingMode.EdgeInclusive
                                       );

                    string value;
                    _mDictionary.TryGetValue(key, out value);
                    qiContent.Add(value ?? "");

                    return;
                }
            }

            applicableToSpan = null;
        }
Exemplo n.º 4
0
        private UE4Statement TrackUE4MacroSpecifier(SnapshotPoint triggerPoint, out bool inMeta)
        {
            SnapshotPoint           currentPoint = triggerPoint - 1;
            ITextStructureNavigator navigator    = m_sourceProvider.NavigatorService.GetTextStructureNavigator(m_textBuffer);
            TextExtent extent = navigator.GetExtentOfWord(currentPoint);

            SnapshotSpan statement     = navigator.GetSpanOfEnclosing(extent.Span);
            var          statementText = statement.GetText();

            inMeta = false;

            var macros = typeof(UE4Macros).GetEnumNames().Aggregate("", (a, e) => a += "|" + e);

            var match = Regex.Match(statementText, $@"({macros})\((.*)\)", RegexOptions.IgnoreCase);

            if (!match.Success)
            {
                return(null);
            }
            if (!match.Groups[1].Success || !match.Groups[2].Success)
            {
                return(null);
            }

            var contentPosition = statement.Start + match.Groups[2].Index;
            var contentEnd      = contentPosition + match.Groups[2].Length;

            if (extent.Span.Start < contentPosition || extent.Span.End > contentEnd)
            {
                return(null);
            }

            var macroConst = (UE4Macros)Enum.Parse(typeof(UE4Macros), match.Groups[1].Value.ToUpper());

            List <string> specifiersList;
            List <string> metaList;

            ParseSpecifiers(match.Groups[2].Value, extent, contentPosition, out inMeta, out specifiersList, out metaList);

            return(new UE4Statement {
                MacroConst = macroConst, Specifiers = specifiersList.ToArray(), MetaSpecifiers = metaList.ToArray()
            });
        }
        public static int?GetSubwordBoundary(this ITextStructureNavigator navigator, SnapshotPoint point, bool forward)
        {
            var wordSpan = navigator.GetExtentOfWord(point).Span;

            wordSpan = new SnapshotSpan(navigator.GetSpanOfPreviousSibling(wordSpan).Start,
                                        navigator.GetSpanOfNextSibling(wordSpan).End);
            if (wordSpan.Length == 0)
            {
                return(null);
            }

            int          step = forward ? 1 : -1;
            SnapshotSpan wordSpanPrev;

            do
            {
                var word = wordSpan.GetText();
                int i    = point.Position - wordSpan.Start;

                while (0 < i && i < word.Length)
                {
                    if (IsSubwordBoundary(word, i, forward))
                    {
                        return(wordSpan.Start + i);
                    }
                    i += step;
                }

                point = wordSpan.Start + i;

                wordSpanPrev = wordSpan;
                wordSpan     = navigator.GetSpanOfEnclosing(wordSpan);
            } while (wordSpan != wordSpanPrev);

            return(null);
        }
 public SnapshotSpan GetSpanOfEnclosing(SnapshotSpan activeSpan)
 {
     return(_delegateNavigator.GetSpanOfEnclosing(activeSpan));
 }
Exemplo n.º 7
0
 public SnapshotSpan GetSpanOfEnclosing(SnapshotSpan activeSpan)
 {
     return(_plainTextNavigator.GetSpanOfEnclosing(activeSpan));
 }
Exemplo n.º 8
0
        private ReadOnlyCollection <ITagSpan <IntraTextAdornmentTag> > GetTagsCore(SnapshotSpan span)
        {
            var list     = new List <ITagSpan <IntraTextAdornmentTag> >();
            var offset   = span.Start.Position;
            var snapshot = span.Snapshot;

            // vars used in loop
            SnapshotSpan                    cbSpan;
            CBAdornmentData                 cbAdornmentData;
            CBETagControl                   tagElement;
            int                             cbStartPosition;
            int                             cbEndPosition;
            int                             cbHeaderPosition;
            string                          cbHeader;
            IntraTextAdornmentTag           cbTag;
            SnapshotSpan                    cbSnapshotSpan;
            TagSpan <IntraTextAdornmentTag> cbTagSpan;
            bool                            isSingleLineComment = false;
            bool                            isMultiLineComment  = false;

#if DEBUG
            // Stop time
            if (watch == null)
            {
                watch = new System.Diagnostics.Stopwatch();
            }
            watch.Restart();
#endif

            try
            {
                // Find all closing bracets
                for (int i = 0; i < span.Length; i++)
                {
                    var position = i + offset;
                    var chr      = snapshot[position];

                    // Skip comments
                    switch (chr)
                    {
                    case '/':
                        if (position > 0)
                        {
                            if (snapshot[position - 1] == '/')
                            {
                                isSingleLineComment = true;
                            }
                            if (snapshot[position - 1] == '*')
                            {
                                if (!isMultiLineComment)
                                {
                                    // Multiline comment was not started in this span
                                    // Every tag until now was inside a comment
                                    foreach (var tag in list)
                                    {
                                        RemoveFromCache((tag.Tag.Adornment as CBETagControl).AdornmentData);
                                    }
                                    list.Clear();
                                }
                                isMultiLineComment = false;
                            }
                        }
                        break;

                    case '*':
                        if (position > 0 && snapshot[position - 1] == '/')
                        {
                            isMultiLineComment = true;
                        }
                        break;

                    case (char)10:
                        isSingleLineComment = false;
                        break;

                    case (char)13:
                        isSingleLineComment = false;
                        break;
                    }

                    if (chr != '}' || isSingleLineComment || isMultiLineComment)
                    {
                        continue;
                    }

                    // getting start and end position of code block
                    cbEndPosition = position;
                    if (position >= 0 && snapshot[position - 1] == '{')
                    {
                        // empty code block {}
                        cbStartPosition = position - 1;
                        cbSpan          = new SnapshotSpan(snapshot, cbStartPosition, cbEndPosition - cbStartPosition);
                    }
                    else
                    {
                        // create inner span to navigate to get code block start
                        cbSpan          = _TextStructureNavigator.GetSpanOfEnclosing(new SnapshotSpan(snapshot, position - 1, 1));
                        cbStartPosition = cbSpan.Start;
                    }

                    // Don't display tag for code blocks on same line
                    if (!snapshot.GetText(cbSpan).Contains('\n'))
                    {
                        continue;
                    }

                    // getting the code blocks header
                    cbHeaderPosition = -1;
                    if (snapshot[cbStartPosition] == '{')
                    {
                        // cbSpan does not contain the header
                        cbHeader = GetCodeBlockHeader(cbSpan, out cbHeaderPosition);
                    }
                    else
                    {
                        // cbSpan does contain the header
                        cbHeader = GetCodeBlockHeader(cbSpan, out cbHeaderPosition, position);
                    }

                    // Trim header
                    if (cbHeader != null && cbHeader.Length > 0)
                    {
                        cbHeader = cbHeader.Trim()
                                   .Replace(Environment.NewLine, "")
                                   .Replace('\t', ' ');
                        // Strip unnecessary spaces
                        while (cbHeader.Contains("  "))
                        {
                            cbHeader = cbHeader.Replace("  ", " ");
                        }
                    }

                    // Skip tag if option "only when header not visible"
                    if (_VisibleSpan != null && !IsTagVisible(cbHeaderPosition, cbEndPosition, _VisibleSpan, snapshot))
                    {
                        continue;
                    }

                    var iconMoniker = Microsoft.VisualStudio.Imaging.KnownMonikers.QuestionMark;
                    if (CBETagPackage.CBEDisplayMode != (int)CBEOptionPage.DisplayModes.Text &&
                        !string.IsNullOrWhiteSpace(cbHeader) && !cbHeader.Contains("{"))
                    {
                        iconMoniker = IconMonikerSelector.SelectMoniker(cbHeader);
                    }

                    // use cache or create new tag
                    cbAdornmentData = _adornmentCache
                                      .Where(o =>
                                             o.StartPosition == cbStartPosition &&
                                             o.EndPosition == cbEndPosition)
                                      .FirstOrDefault();

                    if (cbAdornmentData?.Adornment != null)
                    {
                        tagElement = cbAdornmentData.Adornment as CBETagControl;
                    }
                    else
                    {
                        // create new adornment
                        tagElement = new CBETagControl()
                        {
                            Text        = cbHeader,
                            IconMoniker = iconMoniker,
                            DisplayMode = CBETagPackage.CBEDisplayMode
                        };

                        tagElement.TagClicked += Adornment_TagClicked;

                        cbAdornmentData          = new CBAdornmentData(cbStartPosition, cbEndPosition, cbHeaderPosition, tagElement);
                        tagElement.AdornmentData = cbAdornmentData;
                        _adornmentCache.Add(cbAdornmentData);
                    }

                    tagElement.LineHeight = _FontSize * CBETagPackage.CBETagScale;

                    // Add new tag to list
                    cbTag          = new IntraTextAdornmentTag(tagElement, null);
                    cbSnapshotSpan = new SnapshotSpan(snapshot, position + 1, 0);
                    cbTagSpan      = new TagSpan <IntraTextAdornmentTag>(cbSnapshotSpan, cbTag);
                    list.Add(cbTagSpan);
                }
            }
            catch (NullReferenceException)
            {
                // May happen, when closing a text editor
            }

#if DEBUG
            watch.Stop();
            if (watch.Elapsed.Milliseconds > 100)
            {
                System.Diagnostics.Debug.WriteLine("Time elapsed: " + watch.Elapsed +
                                                   " on Thread: " + System.Threading.Thread.CurrentThread.ManagedThreadId +
                                                   " in Span: " + span.Start.Position + ":" + span.End.Position + " length: " + span.Length);
            }
#endif

            return(new ReadOnlyCollection <ITagSpan <IntraTextAdornmentTag> >(list));
        }
Exemplo n.º 9
0
        public SnapshotSpan GetSpanOfEnclosing(SnapshotSpan activeSpan)
        {
            if (!XmlBackgroundParser.TryGetParser(activeSpan.Snapshot.TextBuffer, out var parser))
            {
                return(xmlNavigator.GetSpanOfEnclosing(activeSpan));
            }

            // use last parse if it's up to date, which is most likely will be
            // else use a spine from the end of the selection and update as needed
            var            lastParse = parser.LastOutput;
            List <XObject> nodePath;
            XmlSpineParser spine = null;

            if (lastParse != null && lastParse.TextSnapshot.Version.VersionNumber == activeSpan.Snapshot.Version.VersionNumber)
            {
                var n = lastParse.XDocument.FindAtOrBeforeOffset(activeSpan.Start.Position);
                nodePath = n.GetPath();
            }
            else
            {
                spine    = parser.GetSpineParser(activeSpan.Start);
                nodePath = spine.AdvanceToNodeEndAndGetNodePath(activeSpan.Snapshot);
            }

            if (nodePath.Count > 0)
            {
                var leaf = nodePath[nodePath.Count - 1];
                if (leaf is XAttribute || leaf is XText)
                {
                    var syntax = MSBuildElementSyntax.Get(nodePath);
                    if (syntax != null)
                    {
                        int    offset;
                        string text;
                        bool   isCondition = false;
                        if (leaf is XText t)
                        {
                            offset = t.Span.Start;
                            text   = t.Text;
                        }
                        else
                        {
                            var att = (XAttribute)leaf;
                            offset      = att.ValueOffset;
                            text        = att.Value;
                            isCondition = true;
                        }

                        var expr = isCondition
                                                        ? ExpressionParser.ParseCondition(text, offset)
                                                        : ExpressionParser.Parse(text, ExpressionOptions.ItemsMetadataAndLists, offset);

                        var expansion = Expand(activeSpan, expr, out var isText);

                        if (expansion is SnapshotSpan expandedSpan)
                        {
                            if (isText)
                            {
                                var xmlNavigatorSpan = xmlNavigator.GetSpanOfEnclosing(activeSpan);
                                if (expandedSpan.Contains(xmlNavigatorSpan))
                                {
                                    return(xmlNavigatorSpan);
                                }
                            }
                            return(expandedSpan);
                        }
                    }
                }
            }

            return(xmlNavigator.GetSpanOfEnclosing(activeSpan));
        }
Exemplo n.º 10
0
        private ReadOnlyCollection <ITagSpan <IntraTextAdornmentTag> > GetTagsCore(SnapshotSpan span)
        {
            var list     = new List <ITagSpan <IntraTextAdornmentTag> >();
            var offset   = span.Start.Position;
            var snapshot = span.Snapshot;

            // vars used in loop

            var isSingleLineComment = false;
            var isMultiLineComment  = false;

            // Find all closing bracets
            for (int i = 0; i < span.Length; i++)
            {
                var position = i + offset;

                // Skip comments
                switch (snapshot[position])
                {
                case '/':
                    if (position > 0)
                    {
                        if (snapshot[position - 1] == '/')
                        {
                            isSingleLineComment = true;
                        }
                        if (snapshot[position - 1] == '*')
                        {
                            if (!isMultiLineComment)
                            {
                                // Multiline comment was not started in this span
                                // Every tag until now was inside a comment
                                foreach (var tag in list)
                                {
                                    RemoveFromCache((tag.Tag.Adornment as CBETagControl).AdornmentData);
                                }
                                list.Clear();
                            }
                            isMultiLineComment = false;
                        }
                    }
                    break;

                case '*':
                    if (position > 0 && snapshot[position - 1] == '/')
                    {
                        isMultiLineComment = true;
                    }
                    break;

                case '\n':
                case '\r':
                    isSingleLineComment = false;
                    break;
                }

                if (snapshot[position] != '}' || isSingleLineComment || isMultiLineComment)
                {
                    continue;
                }


                SnapshotSpan cbSpan;
                int          cbStartPosition;
                // getting start and end position of code block
                var cbEndPosition = position;
                if (position >= 0 && snapshot[position - 1] == '{')
                {
                    // empty code block {}
                    cbStartPosition = position - 1;
                    cbSpan          = new SnapshotSpan(snapshot, position - 1, 1);
                }
                else
                {
                    // create inner span to navigate to get code block start
                    cbSpan          = _TextStructureNavigator.GetSpanOfEnclosing(new SnapshotSpan(snapshot, position - 1, 1));
                    cbStartPosition = cbSpan.Start;
                }

                // Don't display tag for code blocks on same line
                if (!snapshot.GetText(cbSpan).Contains('\n'))
                {
                    continue;
                }

                // getting the code blocks header
                var    cbHeaderPosition = -1;
                string cbHeader;

                if (snapshot[cbStartPosition] == '{')
                {
                    // cbSpan does not contain the header
                    cbHeader = GetCodeBlockHeader(cbSpan, out cbHeaderPosition);
                }
                else
                {
                    // cbSpan does contain the header
                    cbHeader = GetCodeBlockHeader(cbSpan, out cbHeaderPosition, position);
                }

                // Trim header
                if (cbHeader != null && cbHeader.Length > 0)
                {
                    cbHeader = cbHeader.Trim()
                               .Replace(Environment.NewLine, "")
                               .Replace('\t', ' ');
                    // Strip unnecessary spaces
                    while (cbHeader.Contains("  "))
                    {
                        cbHeader = cbHeader.Replace("  ", " ");
                    }
                }

                // Skip tag if option "only when header not visible"
                if (_VisibleSpan != null && !IsTagVisible(cbHeaderPosition, cbEndPosition, _VisibleSpan, snapshot))
                {
                    continue;
                }

                var iconMoniker = Microsoft.VisualStudio.Imaging.KnownMonikers.QuestionMark;
                if (CBETagPackage.CBEDisplayMode != (int)CBEOptionPage.DisplayModes.Text &&
                    !string.IsNullOrWhiteSpace(cbHeader) && !cbHeader.Contains("{"))
                {
                    iconMoniker = IconMonikerSelector.SelectMoniker(cbHeader);
                }

                // use cache or create new tag
                var cbAdornmentData = _adornmentCache
                                      .Find(x =>
                                            x.StartPosition == cbStartPosition &&
                                            x.EndPosition == cbEndPosition);

                CBETagControl tagElement;
                if (cbAdornmentData?.Adornment != null)
                {
                    tagElement = cbAdornmentData.Adornment as CBETagControl;
                }
                else
                {
                    // create new adornment
                    tagElement = new CBETagControl()
                    {
                        Text        = cbHeader,
                        IconMoniker = iconMoniker,
                        DisplayMode = CBETagPackage.CBEDisplayMode
                    };

                    tagElement.TagClicked += Adornment_TagClicked;

                    cbAdornmentData          = new CBAdornmentData(cbStartPosition, cbEndPosition, cbHeaderPosition, tagElement);
                    tagElement.AdornmentData = cbAdornmentData;
                    _adornmentCache.Add(cbAdornmentData);
                }

                tagElement.LineHeight = _FontSize * CBETagPackage.CBETagScale;

                // Add new tag to list
                var cbTag          = new IntraTextAdornmentTag(tagElement, null);
                var cbSnapshotSpan = new SnapshotSpan(snapshot, position + 1, 0);
                var cbTagSpan      = new TagSpan <IntraTextAdornmentTag>(cbSnapshotSpan, cbTag);
                list.Add(cbTagSpan);
            }

            return(new ReadOnlyCollection <ITagSpan <IntraTextAdornmentTag> >(list));
        }
        public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> qiContent, out ITrackingSpan applicableToSpan)
        {
            // Map the trigger point down to our buffer.
            SnapshotPoint?subjectTriggerPoint = session.GetTriggerPoint(this.subjectBuffer.CurrentSnapshot);

            if (!subjectTriggerPoint.HasValue)
            {
                applicableToSpan = null;
                return;
            }

            ITextSnapshot currentSnapshot = subjectTriggerPoint.Value.Snapshot;
            SnapshotSpan  querySpan       = new SnapshotSpan(subjectTriggerPoint.Value, 0);

            //look for occurrences of our QuickInfo words in the span
            ITextStructureNavigator navigator = this.provider.NavigatorService.GetTextStructureNavigator(this.subjectBuffer);
            var    extent     = navigator.GetSpanOfEnclosing(new SnapshotSpan(this.subjectBuffer.CurrentSnapshot, querySpan));
            string searchText = extent.GetText()?.Trim('"');

            Guid parsedId;
            var  allFiles = Rainbow.Repository.rainbowFiles.Values.ToList();

            if (Guid.TryParse(searchText, out parsedId))
            {
                var file = allFiles.FirstOrDefault(f => f != null && parsedId.Equals(f.Id));
                if (file != null)
                {
                    applicableToSpan = currentSnapshot.CreateTrackingSpan
                                       (
                        extent.Span.Start, file.Id.ToString().Length, SpanTrackingMode.EdgeInclusive
                                       );

                    try
                    {
                        qiContent.Add($"Sitecore path: {file.Path}");
                    }
                    catch (InvalidOperationException ex)
                    {
                        // The collection may be modified, so we can't add anything here right now
                        Debug.Write($"Exception occurred when trying to add path {file.Path} (skipping as it is not essential): {ex.Message}");
                    }

                    return;
                }
            }
            else
            {
                foreach (var file in allFiles.Where(f => f != null && f.Id != Guid.Empty && f.Path != null).OrderByDescending(f => f.Path))
                {
                    int foundIndex = searchText.IndexOf(file.Path, StringComparison.CurrentCultureIgnoreCase);
                    if (foundIndex > -1)
                    {
                        applicableToSpan = currentSnapshot.CreateTrackingSpan
                                           (
                            extent.Span.Start + foundIndex, file.Id.ToString().Length, SpanTrackingMode.EdgeInclusive
                                           );

                        try
                        {
                            qiContent.Add($"Sitecore ID: {{{file.Id}}}");
                        }
                        catch (InvalidOperationException ex)
                        {
                            // The collection may be modified, so we can't add anything here right now
                            Debug.Write($"Exception occurred when trying to add ID {file.Id} (skipping as it is not essential): {ex.Message}");
                        }

                        return;
                    }
                }
            }

            applicableToSpan = null;
        }
Exemplo n.º 12
0
        void IQuickInfoSource.AugmentQuickInfoSession(IQuickInfoSession session, IList <object> quickInfoContent, out ITrackingSpan applicableToSpan)
        {
            // Map the trigger point down to our buffer.
            SnapshotPoint?subjectTriggerPoint = session.GetTriggerPoint(m_subjectBuffer.CurrentSnapshot);

            if (!subjectTriggerPoint.HasValue)
            {
                applicableToSpan = null;
                return;
            }
            ITextSnapshot currentSnapshot = subjectTriggerPoint.Value.Snapshot;
            SnapshotSpan  querySpan       = new SnapshotSpan(subjectTriggerPoint.Value, 0);
            //look for occurrences of our QuickInfo words in the span
            ITextStructureNavigator navigator = m_provider.NavigatorService.GetTextStructureNavigator(m_subjectBuffer);
            TextExtent extent     = navigator.GetExtentOfWord(subjectTriggerPoint.Value);
            string     searchText = extent.Span.GetText();

            if (searchText.Length < 2)//一般都是一个符号
            {
                applicableToSpan = null;
                return;
            }
            SnapshotSpan ssPrevious  = navigator.GetSpanOfPreviousSibling(extent.Span);
            SnapshotSpan ssEnclosing = navigator.GetSpanOfEnclosing(extent.Span);

            string strPreText = ssPrevious.GetText();
            string strEnclosing = ssEnclosing.GetText();
            string desText, strCtrlName;

            if (strPreText == "<" || strPreText == "</" || strEnclosing.StartsWith("</"))//控件名
            {
                SouiData.GetInstance().GetKeyInf(searchText, out desText, currentSnapshot, out applicableToSpan, querySpan);
                if (desText != null)
                {
                    quickInfoContent.Add(desText);
                }
                else
                {
                    applicableToSpan = null;
                }
                return;
            }
            else if (strPreText == "=\"")//属性值
            {
                applicableToSpan = null;
                return;
            }
            //属性名

            else if (strEnclosing.StartsWith("<"))
            {
                strCtrlName = navigator.GetExtentOfWord(ssEnclosing.Start + 1).Span.GetText();

                if (strCtrlName == null || strCtrlName.Length == 0)
                {
                    applicableToSpan = null;
                    return;
                }
                SouiData.GetInstance().GetProInf(strCtrlName, searchText, out desText, currentSnapshot, out applicableToSpan, querySpan);
                if (desText != null)
                {
                    quickInfoContent.Add(desText);
                    return;
                }
            }
            else if (strPreText.StartsWith("<"))
            {
                strCtrlName = navigator.GetExtentOfWord(ssPrevious.Start + 1).Span.GetText();

                if (strCtrlName == null || strCtrlName.Length == 0)
                {
                    applicableToSpan = null;
                    return;
                }
                SouiData.GetInstance().GetProInf(strCtrlName, searchText, out desText, currentSnapshot, out applicableToSpan, querySpan);
                if (desText != null)
                {
                    quickInfoContent.Add(desText);
                    return;
                }
            }
            strCtrlName = strPreText;
            while (ssPrevious.Start > 0)
            {
                if (strPreText == "<")
                {
                    SouiData.GetInstance().GetProInf(strCtrlName, searchText, out desText, currentSnapshot, out applicableToSpan, querySpan);
                    if (desText != null)
                    {
                        quickInfoContent.Add(desText);
                        return;
                    }
                    break;
                }
                strCtrlName = strPreText;
                ssPrevious  = navigator.GetExtentOfWord(ssPrevious.Start - 1).Span;
                strPreText  = ssPrevious.GetText();
            }
            applicableToSpan = null;
        }