To get possible code completions at a specific caret index in Roslyn, you can use the DocumentService
and Workspace
from the Microsoft.CodeAnalysis
library. Here's an example of how you can modify your existing code to get Intellisense (code completion) suggestions at the specified caretIndex
:
using System;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;
static void Main(string[] args)
{
var code = @"
using System;
public class Test
{
public void TestMethod()
{
var now = DateTime.Now;
now.
}
}";
Console.WriteLine(code);
WorkspaceFactory workspaceFactory = new AdhocWorkspaceFactory();
using (Workspace ws = workspaceFactory.CreateUniqueWorkspace())
{
DocumentId documentId = new DocumentId(Guid.NewGuid().ToString(), SourceKind.CSharp);
TextDocument textDocument = TextDocument.Create("test.cs", FileMode.Open, new DefaultTextDocumentLanguage(sourceFileType: "cs"));
textDocument = textDocument.WithTextContent(code).WithTextChanges(new TextChangeList(new TextChange(TextChangeKind.Insert, caretIndex, Environment.NewLine))).WithTextChanges(textDocument.GetText().ToSnapshot().CreateEdit("initialize caret").Apply()));
Document document = ws.Documents.AddDocument(documentId, textDocument);
SyntaxRoot syntaxRoot = document.GetSyntaxRootAsync().Result;
DocumentId codeDocumentsId = new DocumentId(Guid.NewGuid().ToString(), SourceKind.CSharpScript);
TextDocument codeDocument = TextDocument.Create("codeDocuments.csx", FileMode.Open, new DefaultTextDocumentLanguage());
var textChangeList = new TextChangeList();
textChangeList.Add(new TextChange(TextChangeKind.Insert, 0, Environment.NewLine));
textChangeList.Add(new TextChange(TextChangeKind.Insert, caretIndex, @"<caret> "));
var codeDocumentText = textDocument.WithTextContent("");
codeDocument = codeDocument.WithTextChanges(textChangeList).Result;
Document codeDocumentInstance = ws.Documents.AddDocument(codeDocumentsId, codeDocument);
SemanticModel semanticModel = document.GetSemanticModelAsync().Result;
SyntaxNode rootNodeOfCodeDocument = await codeDocumentInstance.GetSyntaxRootAsync();
using (var enumberator = RosterPool.GlobalInstance.GetRosterPool().GetRoslynSession(ws).DocumentSemanticAnalyzerPool.GetDocuments SemanticAnalyzerPool)
{
SyntaxNode semanticAnalyzeNode = await semanticAnalyzerPool.GetNextAsync();
var documentInfo = new DocumentInfo(document, codeDocumentInstance, semanticModel, semanticAnalyzeNode);
var completionContext = new CompletionContext(documentInfo);
using (var provider = new DefaultCompletionProvider())
provider.TryCompleteAt(caretIndex - caretIndex % 2, document.GetText().ToSnapshot(), documentId, DocumentCreateFlags.Default, new CancellationToken(), out IEnumerable<CompletionList> completionItems);
Console.WriteLine($"Possible completions at the caret index: {string.Join("\n", completionItems?.Select(c => c.ToString())).TrimEnd('\n')}");
}
}
}
This example uses Roslyn's WorkspaceFactory
, creates a new workspace and adds a document with the given code snippet. It also creates another empty document for getting Intellisense suggestions using the specified caret index in your original code snippet. The example then uses the SemanticAnalyzerPool
to obtain the semantic analyzer, creates a completion context, and uses Roslyn's DefaultCompletionProvider
to get Intellisense suggestions at the caret position. Finally, it prints out the possible completions as a list of strings.
Make sure you have the following NuGet packages installed for your project: Microsoft.CodeAnalysis
, Microsoft.CodeAnalysis.CSharp.Workspaces
and Microsoft.CodeAnalysis.CSharpScript
.