/// <summary>
        /// Provide CompletionContext items for the current auto-completion session.
        /// </summary>
        /// <param name="session">The current auto-completion session.</param>
        /// <param name="trigger">The action that triggered the auto-completion session.</param>
        /// <param name="triggerLocation">The location in the text where auto-completion was triggered.</param>
        /// <param name="applicableToSpan">The text area that may be affected by the auto-completion.</param>
        /// <param name="cancellationToken">A cancellation token.</param>
        /// <returns>A task returning a CompletionContext, filled with CompletionItems, if applicable.</returns>
        public Task <CompletionContext> GetCompletionContextAsync(InitialTrigger trigger, SnapshotPoint triggerLocation, SnapshotSpan applicableToSpan, CancellationToken token) => Task.Run(() =>
        {
            IAsyncCompletionSession session = null;             // TODO: where to get from?
            bool addPrefix = false;
            if (trigger.Character == '\0' && !_navigator.GetExtentOfWord(triggerLocation.Subtract(1)).Span.GetText().EndsWith("<", System.StringComparison.OrdinalIgnoreCase))
            {
                // Meaning: autocomplete was not triggered by typing '<', but by using a shortcut, e.g. Ctrl+Space.
                // If the previous character is not '<', then we need to add one to the completion item text.
                addPrefix = true;
            }

            SnapshotSpan ats = applicableToSpan;
            SnapshotPoint t  = triggerLocation;
            // TODO: Find a way to determine where in the comment section the completion was triggered, to filter out CompletionItems that are not applicable in the current context

            List <CompletionItem> completions = new List <CompletionItem>()
            {
                CreateCompletionItem(addPrefix, "conceptualLink", "conceptualLink target=\"\"/>", "This element is used to create a link to a MAML topic within the See Also section of a topic or an inline link to a MAML topic within one of the other XML comments elements.", false, 3),
                CreateCompletionItem(addPrefix, "inheritdoc", "inheritdoc/>", "This element can help minimize the effort required to document complex APIs by allowing common documentation to be inherited from base types/members."),
                CreateCompletionItem(addPrefix, "inheritdocCref", "inheritdoc cref=\"\"/>", "Inherit documentation from a specific member.", false, 3),
                CreateCompletionItem(addPrefix, "inheritdocCrefSelect", "inheritdoc cref=\"\" select=\"summary|remarks\"/>", "Inherit documentation from a specific member and comments.", false, 28),
                CreateCompletionItem(addPrefix, "token", "token", "This element represents a replaceable tag within a topic."),
                // exception
                CreateCompletionItem(addPrefix, "AttachedEventComments", "AttachedEventComments", "This element is used to define the content that should appear on the auto-generated attached event member topic for a given WPF routed event member."),
                CreateCompletionItem(addPrefix, "AttachedPropertyComments", "AttachedPropertyComments", "This element is used to define the content that should appear on the auto-generated attached property member topic for a given WPF dependency property member."),
                CreateCompletionItem(addPrefix, "event", "event cref=\"\"", "This element is used to list events that can be raised by a type's member.", false, 1),
                CreateCompletionItem(addPrefix, "overloads", "overloads", "This element is used to define the content that should appear on the auto-generated overloads topic for a given set of member overloads."),
                CreateCompletionItem(addPrefix, "preliminary", "preliminary/>", "This element is used to indicate that a particular type or member is preliminary and is subject to change."),
                CreateCompletionItem(addPrefix, "threadsafety", "threadsafety static=\"true\" instance=\"false\"/>", "This element is used to indicate whether or not a class or structure's static and instance members are safe for use in multi-threaded scenarios."),
                // list
                CreateCompletionItem(addPrefix, "note", "note type=\"note\"", "This element is used to create a note-like section within a topic to draw attention to some important information."),
                // language
                CreateCompletionItem(addPrefix, "null", "see langword=\"null\"/>", "Inserts the language-specific keyword 'null'.", true),
                CreateCompletionItem(addPrefix, "static", "see langword=\"static\"/>", "Inserts the language-specific keyword 'static'.", true),
                CreateCompletionItem(addPrefix, "virtual", "see langword=\"virtual\"/>", "Inserts the language-specific keyword 'virtual'.", true),
                CreateCompletionItem(addPrefix, "true", "see langword=\"true\"/>", "Inserts the language-specific keyword 'true'.", true),
                CreateCompletionItem(addPrefix, "false", "see langword=\"false\"/>", "Inserts the language-specific keyword 'false'.", true),
                CreateCompletionItem(addPrefix, "abstract", "see langword=\"abstract\"/>", "Inserts the language-specific keyword 'abstract'.", true),
                CreateCompletionItem(addPrefix, "sealed", "see langword=\"sealed\"/>", "Inserts the language-specific keyword 'sealed'.", true),
                CreateCompletionItem(addPrefix, "async", "see langword=\"async\"/>", "Inserts the language-specific keyword 'async'.", true),
                CreateCompletionItem(addPrefix, "await", "see langword=\"await\"/>", "Inserts the language-specific keyword 'await'.", true),
                CreateCompletionItem(addPrefix, "asyncAwait", "see langword=\"async/await\"/>", "Inserts the language-specific keyword 'async/await'.", true),
                // code
                CreateCompletionItem(addPrefix, "codeImport", "code language=\"\" title=\" \" source=\"..\\Path\\SourceFile.cs\" region=\"Region Name\"/>", "This element is used to indicate that a multi-line section of text should be imported from the named region of the named file and formatted as a code block.", false, 65),
                CreateCompletionItem(addPrefix, "codeLanguage", "code language=\"\" title=\" \"></code>", "This element is used to indicate that a multi-line section of text should be formatted as a code block.", false, 19),
            };

            // Add handler for the completion of the session, so we can move the cursor to a position in the inserted text, if necessary.
            if (session != null)
            {
                session.ItemCommitted += Session_ItemCommitted;
            }

            return(new CompletionContext(completions.OrderBy(ci => ci.SortText).ToImmutableArray()));            // Why doesn't VS sort?
        });
        private CompletionContext CompletionOnChar(InitialTrigger trigger, SnapshotPoint triggerLocation, SnapshotSpan applicableToSpan, CancellationToken token)
        {
            switch (trigger.Character)
            {
            case ':':
            case '.':
                //StartCompletionSession(nCmdID, ch);
                break;

            default:
                //completeCurrentToken(nCmdID, ch);
                break;
            }
            return(null);
        }
        public async Task <CompletionContext> GetCompletionContextAsync(InitialTrigger trigger, SnapshotPoint triggerLocation, SnapshotSpan applicableToSpan, CancellationToken token)
        {
            var document = applicableToSpan.Snapshot.GetOpenDocumentInCurrentContextWithChanges();

            Microsoft.CodeAnalysis.Completion.CompletionTrigger CreateTrigger()
            {
                switch (trigger.Reason)
                {
                case InitialTriggerReason.Invoke:
                case InitialTriggerReason.InvokeAndCommitIfUnique:
                    return(Microsoft.CodeAnalysis.Completion.CompletionTrigger.Invoke);

                case InitialTriggerReason.Insertion:
                    return(Microsoft.CodeAnalysis.Completion.CompletionTrigger.CreateInsertionTrigger(trigger.Character));

                case InitialTriggerReason.Deletion:
                    return(Microsoft.CodeAnalysis.Completion.CompletionTrigger.CreateDeletionTrigger(trigger.Character));

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            var completions = await _completionService.GetCompletionsAsync(
                document,
                triggerLocation.Position,
                CreateTrigger(),
                document.Workspace.Options,
                cancellationToken : token);

            if (completions == null)
            {
                return(CompletionContext.Empty);
            }

            var items = completions.Items
                        .Select(x =>
            {
                var item = new CompletionItem(x.DisplayText, this, new ImageElement(x.Glyph.GetImageId()));
                item.Properties.AddProperty("Document", document);
                item.Properties.AddProperty("CompletionItem", x);
                return(item);
            })
                        .ToImmutableArray();

            return(new CompletionContext(items));
        }
        public async Task <CompletionContext> GetCompletionContextAsync(InitialTrigger trigger, SnapshotPoint triggerLocation, SnapshotSpan applicableToSpan, CancellationToken token)
        {
            switch (trigger.Reason)
            {
            case InitialTriggerReason.Invoke:
                break;

            case InitialTriggerReason.InvokeAndCommitIfUnique:
                break;

            case InitialTriggerReason.Insertion:
                return(CompletionOnChar(trigger, triggerLocation, applicableToSpan, token));

            case InitialTriggerReason.Deletion:
                return(CompletionOnChar(trigger, triggerLocation, applicableToSpan, token));

            case InitialTriggerReason.Snippets:
                break;
            }
            return(null);
        }
Example #5
0
        public Task <CompletionContext> GetCompletionContextAsync(
            InitialTrigger trigger,
            SnapshotPoint triggerLocation,
            SnapshotSpan applicableSpan,
            CancellationToken token)
        {
            _foregroundDispatcher.AssertBackgroundThread();

            var syntaxTree           = _parser.CodeDocument?.GetSyntaxTree();
            var location             = new SourceSpan(applicableSpan.Start.Position, applicableSpan.Length);
            var razorCompletionItems = _completionFactsService.GetCompletionItems(syntaxTree, location);

            var completionItems = new List <CompletionItem>();

            foreach (var razorCompletionItem in razorCompletionItems)
            {
                if (razorCompletionItem.Kind != RazorCompletionItemKind.Directive)
                {
                    // Don't support any other types of completion kinds other than directives.
                    continue;
                }

                var completionItem = new CompletionItem(
                    displayText: razorCompletionItem.DisplayText,
                    filterText: razorCompletionItem.DisplayText,
                    insertText: razorCompletionItem.InsertText,
                    source: this,
                    icon: DirectiveImageGlyph,
                    filters: DirectiveCompletionFilters,
                    suffix: string.Empty,
                    sortText: razorCompletionItem.DisplayText,
                    attributeIcons: ImmutableArray <ImageElement> .Empty);
                completionItem.Properties.AddProperty(DescriptionKey, razorCompletionItem.Description);
                completionItems.Add(completionItem);
            }
            var context = new CompletionContext(completionItems.ToImmutableArray());

            return(Task.FromResult(context));
        }
Example #6
0
        public Task <CompletionContext> GetCompletionContextAsync(InitialTrigger trigger, SnapshotPoint triggerPt,
                                                                  SnapshotSpan applicableToSpan, CancellationToken token)
        {
            _items.Clear();

            switch (_mode)
            {
            case CompletionMode.AfterAssignOrCompare:
                HandleAfterAssignOrCompare(applicableToSpan, _params.str, _params.pt, _fileName);
                break;

            case CompletionMode.AfterIfDef:
                HandleAfterIfDef(_fileName);
                break;

            case CompletionMode.AfterComma:
                HandleAfterComma(applicableToSpan, _fileName);
                break;

            case CompletionMode.AfterCase:
                HandleAfterCase(applicableToSpan, _fileName);
                break;

            case CompletionMode.AfterExtract:
                HandleAfterExtract(applicableToSpan, _params.str, _fileName);
                break;

            case CompletionMode.AfterReturn:
                HandleAfterReturn(applicableToSpan, _fileName);
                break;

            case CompletionMode.AfterTag:
                HandleAfterTag();
                break;

            case CompletionMode.AfterWord:
                HandleAfterWord(_params.str, triggerPt, _params.snapshot, _fileName);
                break;

            case CompletionMode.AfterSymbol:
                HandleAfterSymbol(triggerPt, _fileName);
                break;

            case CompletionMode.AfterNumber:
                HandleAfterSymbol(triggerPt, _fileName);
                break;

            case CompletionMode.AfterStringLiteral:
                HandleAfterStringLiteral(triggerPt, _fileName);
                break;

            case CompletionMode.AfterOrderBy:
                HandleAfterOrderBy();
                break;

            case CompletionMode.DotSeparatedWords:
                HandleDotSeparatedWords(applicableToSpan, _params.str, _params.str2, _fileName);
                break;

            case CompletionMode.Word:
                GetWordCompletions(triggerPt, _params.pt, _fileName);
                break;

            case CompletionMode.ClassFunction:
                HandleAfterMethodArgsStart(triggerPt, _params.str, _params.str2, _fileName);
                break;

            case CompletionMode.Function:
                HandleAfterFunctionArgsStart(triggerPt, _params.str, _fileName);
                break;

            case CompletionMode.Include:
                HandleAfterInclude(_params.str, _fileName);
                break;
            }

            return(Task <CompletionContext> .FromResult(new CompletionContext(_items.Keys.OrderBy(i => i.SortText.ToLower()).ToImmutableArray())));
        }