コード例 #1
0
        private static CustomCompletionSet MergeCompletionSets(IList <CompletionSet> completionSets, CustomCompletionSet newCompletions)
        {
            var htmlCompletionsSet = completionSets.First();

            // if we are in an element with tagPrefix, VS adds all HTML elements with the same prefix in the completion - we don't want it
            var originalCompletions = htmlCompletionsSet.Completions.Where(c => !c.DisplayText.Contains(":"));

            // merge
            var mergedCompletionSet = new CustomCompletionSet(
                htmlCompletionsSet.Moniker,
                htmlCompletionsSet.DisplayName,
                htmlCompletionsSet.ApplicableTo,
                newCompletions.Completions.Concat(originalCompletions).OrderBy(n => n.DisplayText).Distinct(CompletionEqualityComparer.Instance),
                htmlCompletionsSet.CompletionBuilders);

            completionSets.Remove(htmlCompletionsSet);
            return(mergedCompletionSet);
        }
コード例 #2
0
        public void AugmentCompletionSession(ICompletionSession session, IList <CompletionSet> completionSets)
        {
            var completionSetsCount = completionSets.Count;
            var tokens = classifier.Tokens;

            if (tokens != null)
            {
                // find current token
                var cursorPosition = session.TextView.Caret.Position.BufferPosition;

                var currentTokenIndex = FindCurrentTokenIndex(tokens, cursorPosition.Position);
                if (currentTokenIndex >= 0)
                {
                    // prepare the context
                    var currentToken = classifier.Tokens[currentTokenIndex];
                    var items        = Enumerable.Empty <SimpleDothtmlCompletion>();
                    var context      = GetCompletionContext(session);
                    context.CompletionSession = session;
                    context.CurrentTokenIndex = currentTokenIndex;
                    context.CurrentNode       = parser.Root.FindNodeByPosition(cursorPosition.Position - 1);
                    var combineWithHtmlCompletions = false;
                    int?applicableToStartPosition  = null;

                    TriggerPoint triggerPoint = TriggerPoint.None;
                    if (currentToken.Type == DothtmlTokenType.DirectiveStart)
                    {
                        // directive name completion
                        triggerPoint = TriggerPoint.DirectiveName;
                        items        = sourceProvider.CompletionProviders.Where(p => p.TriggerPoint == triggerPoint).SelectMany(p => p.GetItems(context));
                    }
                    else if (currentToken.Type == DothtmlTokenType.DirectiveValue)
                    {
                        // directive value
                        triggerPoint = TriggerPoint.DirectiveValue;

                        // prepare applicable start position to include value text tag in the intellisense selection to replace
                        applicableToStartPosition = tokens[currentTokenIndex].StartPosition;
                        items = sourceProvider.CompletionProviders.Where(p => p.TriggerPoint == triggerPoint).SelectMany(p => p.GetItems(context));
                    }
                    else if (currentToken.Type == DothtmlTokenType.OpenTag || IsTagName(currentTokenIndex, tokens))
                    {
                        // element name
                        triggerPoint = TriggerPoint.TagName;
                        items        = sourceProvider.CompletionProviders.Where(p => p.TriggerPoint == triggerPoint).SelectMany(p => p.GetItems(context));
                        if (currentToken.Type != DothtmlTokenType.OpenTag)
                        {
                            applicableToStartPosition = tokens[GetTagNameStartTokenIndex(currentTokenIndex, tokens)].StartPosition;
                        }
                        combineWithHtmlCompletions = true;
                    }
                    else if (currentToken.Type == DothtmlTokenType.WhiteSpace || currentToken.Type == DothtmlTokenType.Text)
                    {
                        var previousToken = GetPreviousToken(currentTokenIndex, tokens, new[] { DothtmlTokenType.WhiteSpace });

                        if (context.CurrentNode?.Tokens.All(all => all.Type == DothtmlTokenType.WhiteSpace || (all.Type == DothtmlTokenType.Text && string.IsNullOrWhiteSpace(all.Text))) == true)
                        {
                            session.Dismiss();
                            return;
                        }

                        // prepare applicable start position to include current text tag in the intellisense selection to replace
                        if (currentToken.Type == DothtmlTokenType.Text)
                        {
                            applicableToStartPosition = tokens[currentTokenIndex].StartPosition;
                        }

                        if (context.CurrentNode is DothtmlDirectiveNode && previousToken?.Type == DothtmlTokenType.DirectiveName)
                        {
                            // directive value
                            triggerPoint = TriggerPoint.DirectiveValue;
                            items        = sourceProvider.CompletionProviders.Where(p => p.TriggerPoint == triggerPoint).SelectMany(p => p.GetItems(context));
                        }
                        else if (previousToken?.Type == DothtmlTokenType.OpenBinding)
                        {
                            // binding name
                            triggerPoint = TriggerPoint.BindingName;
                            items        = sourceProvider.CompletionProviders.Where(p => p.TriggerPoint == triggerPoint).SelectMany(p => p.GetItems(context));
                        }
                        else if (context.CurrentNode is DothtmlElementNode || context.CurrentNode is DothtmlAttributeNode)
                        {
                            // attribute name
                            triggerPoint = TriggerPoint.TagAttributeName;
                            items        = sourceProvider.CompletionProviders.Where(p => p.TriggerPoint == triggerPoint).SelectMany(p => p.GetItems(context));
                            combineWithHtmlCompletions = sourceProvider.CompletionProviders.OfType <MainTagAttributeNameCompletionProvider>().Single().CombineWithHtmlCompletions;
                        }
                        else if (previousToken?.Type == DothtmlTokenType.SingleQuote || previousToken?.Type == DothtmlTokenType.DoubleQuote || previousToken?.Type == DothtmlTokenType.Equals)
                        {
                            // attribute value
                            triggerPoint = TriggerPoint.TagAttributeValue;
                            items        = sourceProvider.CompletionProviders.Where(p => p.TriggerPoint == triggerPoint).SelectMany(p => p.GetItems(context));
                            combineWithHtmlCompletions = true;
                        }
                    }
                    else if (currentToken.Type == DothtmlTokenType.SingleQuote || currentToken.Type == DothtmlTokenType.DoubleQuote || currentToken.Type == DothtmlTokenType.Equals)
                    {
                        // attribute value
                        triggerPoint = TriggerPoint.TagAttributeValue;
                        items        = sourceProvider.CompletionProviders.Where(p => p.TriggerPoint == triggerPoint).SelectMany(p => p.GetItems(context));
                        combineWithHtmlCompletions = true;
                    }
                    else if (currentToken.Type == DothtmlTokenType.OpenBinding)
                    {
                        // binding name
                        triggerPoint = TriggerPoint.BindingName;
                        items        = sourceProvider.CompletionProviders.Where(p => p.TriggerPoint == triggerPoint).SelectMany(p => p.GetItems(context));
                    }
                    else if (currentToken.Type == DothtmlTokenType.Colon)
                    {
                        if (context.CurrentNode is DothtmlBindingNode)
                        {
                            // binding value
                            triggerPoint = TriggerPoint.BindingValue;
                            items        = sourceProvider.CompletionProviders.Where(p => p.TriggerPoint == triggerPoint).SelectMany(p => p.GetItems(context));
                        }
                        else
                        {
                            // element name
                            triggerPoint = TriggerPoint.TagName;
                            items        = sourceProvider.CompletionProviders.Where(p => p.TriggerPoint == triggerPoint).SelectMany(p => p.GetItems(context));
                            combineWithHtmlCompletions = true;
                        }
                    }
                    var results = items.OrderBy(v => v.DisplayText).Distinct(CompletionEqualityComparer.Instance).ToList();

                    // handle duplicate sessions (sometimes this method is called twice (e.g. when space key is pressed) so we need to make sure that we'll display only one session
                    lock (activeSessions)
                    {
                        if (activeSessions.Count > 0)
                        {
                            activeSessions.ToList().ForEach(fe => fe.Dismiss());
                        }
                        activeSessions.Add(session);

                        session.Dismissed += (s, a) =>
                        {
                            lock (activeSessions)
                            {
                                activeSessions.Remove((ICompletionSession)s);
                            }
                        };
                        session.Committed += (s, a) =>
                        {
                            lock (activeSessions)
                            {
                                activeSessions.Remove((ICompletionSession)s);
                            }
                        };
                    }

                    if (results.Any())
                    {
                        // show the session
                        var newCompletionSet = new CustomCompletionSet("dotVVM", "dotVVM", FindTokenSpanAtPosition(session, applicableToStartPosition ?? -1), results, null);
                        if (combineWithHtmlCompletions && completionSets.Any())
                        {
                            newCompletionSet = MergeCompletionSets(completionSets, newCompletionSet);
                        }
                        else
                        {
                            completionSets.Clear();
                        }
                        completionSets.Add(newCompletionSet);
                    }
                }
            }
        }