/// <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); }
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)); }
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()))); }