public async Task Works_With_IWorkspaceSymbolsHandler() { var process = new NamedPipeServerProcess(Guid.NewGuid().ToString("N"), LoggerFactory); await process.Start(); var client = new LanguageClient(LoggerFactory, process); var handler = Substitute.For <IWorkspaceSymbolsHandler>(); var cts = new CancellationTokenSource(); cts.CancelAfter(1000 * 60 * 5); var serverStart = LanguageServer.From(x => x //.WithHandler(handler) .WithInput(process.ClientOutputStream) .WithOutput(process.ClientInputStream) .WithLoggerFactory(LoggerFactory) .AddDefaultLoggingProvider() .WithMinimumLogLevel(LogLevel.Trace), cts.Token ); await Task.WhenAll( client.Initialize( Directory.GetCurrentDirectory(), new object(), cts.Token), serverStart ); var server = await serverStart; server.AddHandlers(handler); }
public async Task Works_With_IWorkspaceSymbolsHandler() { var process = new NamedPipeServerProcess(Guid.NewGuid().ToString("N"), LoggerFactory); await process.Start(); var client = new LanguageClient(LoggerFactory, process); var handler = Substitute.For <IWorkspaceSymbolsHandler>(); var cts = new CancellationTokenSource(); cts.CancelAfter(1000 * 60 * 5); var serverStart = LanguageServer.From(x => x .WithInput(process.ClientOutputStream) .WithOutput(process.ClientInputStream) .ConfigureLogging(z => z.Services.AddSingleton(LoggerFactory)), cts.Token ); await Task.WhenAll( client.Initialize( Directory.GetCurrentDirectory(), new object(), cts.Token), serverStart ); using var server = await serverStart; server.AddHandlers(handler); }
public async override Task CustomInitializeAsync( ILoggerFactory factory, StdioServerProcess process) { LanguageClient = new LanguageClient(factory, process); DirectoryInfo testdir = Directory.CreateDirectory(Path.Combine(s_binDir, Path.GetRandomFileName())); await LanguageClient.Initialize(testdir.FullName); // Make sure Script Analysis is enabled because we'll need it in the tests. LanguageClient.Workspace.DidChangeConfiguration(JObject.Parse(@" { ""PowerShell"": { ""ScriptAnalysis"": { ""Enable"": true } } } ")); Diagnostics = new List <Diagnostic>(); LanguageClient.TextDocument.OnPublishDiagnostics((uri, diagnostics) => { Diagnostics.AddRange(diagnostics.Where(d => d != null)); }); }
public async Task TriggersStartedTask() { var startedDelegate = Substitute.For <StartedDelegate>(); startedDelegate(Arg.Any <InitializeResult>()).Returns(Task.CompletedTask); var process = new NamedPipeServerProcess(Guid.NewGuid().ToString("N"), LoggerFactory); await process.Start(); var client = new LanguageClient(LoggerFactory, process); var cts = new CancellationTokenSource(); cts.CancelAfter(TimeSpan.FromSeconds(15)); var serverStart = LanguageServer.From(x => x .OnStarted(startedDelegate) .OnStarted(startedDelegate) .OnStarted(startedDelegate) .OnStarted(startedDelegate) .WithInput(process.ClientOutputStream) .WithOutput(process.ClientInputStream) .ConfigureLogging(z => z.Services.AddSingleton(LoggerFactory)) .AddHandlers(TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cs"), "csharp")) , cts.Token); await Task.WhenAll( client.Initialize( Directory.GetCurrentDirectory(), new object(), cts.Token), serverStart ); using var server = await serverStart; _ = startedDelegate.Received(4)(Arg.Any <InitializeResult>()); }
/// <summary> /// Create a <see cref="LanguageClient"/> connected to the test's <see cref="PipeServerProcess"/>. /// </summary> /// <param name="initialize"> /// Automatically initialise the client? /// /// Default is <c>true</c>. /// </param> /// <returns> /// The <see cref="LanguageClient"/>. /// </returns> protected async Task <LanguageClient> CreateClient(bool initialize = true) { if (!_serverProcess.IsRunning) { await StartServer(); } await _serverProcess.HasStarted; LanguageClient client = new LanguageClient(LoggerFactory, _serverProcess); Disposal.Add(client); if (initialize) { await client.Initialize(WorkspaceRoot); } return(client); }
public static LanguageClient MakeClient(Action <ClientCapabilities> configureClientCaps) { Directory.CreateDirectory(DefaultSrcFolder); var loggerFactory = new LoggerFactory(new[] { new InMemoryLoggerProvider() }); var client = new LanguageClient(loggerFactory, new DummyServerProcess(loggerFactory)); client.ClientCapabilities.Window = new WindowClientCapabilities { WorkDoneProgress = new Supports <bool>(true, true) }; client.ClientCapabilities.Workspace.WorkspaceEdit = Supports.OfBoolean <WorkspaceEditCapability>(true); client.ClientCapabilities.Workspace.WorkspaceFolders = Supports.OfBoolean <bool>(true); client.ClientCapabilities.TextDocument.Completion = Supports.OfBoolean <CompletionCapability>(true); configureClientCaps(client.ClientCapabilities); bool hasInitialized = client.Initialize(DefaultWorkspaceRoot).Wait(3000); Assert.IsTrue(hasInitialized); return(client); }
public async Task Test1() { var logFactory = LoggerFactory.Create(a => a.AddNLog().SetMinimumLevel(LogLevel.Trace)); var serverProcess = new NamedPipeServerProcess("test", logFactory); var languageClient = new LanguageClient(logFactory, serverProcess); var clientInit = languageClient.Initialize("/"); var serverInit = RhetosLanguageServer.BuildLanguageServer(serverProcess.ClientOutputStream, serverProcess.ClientInputStream, builder => builder.AddNLog().AddLanguageServer().AddConsole()); Task.WaitAll(clientInit, serverInit); Console.WriteLine(languageClient.IsConnected.ToString()); var textDocument = new TextDocumentItem() { Text = @"// <rhetosRootPath="""" />\nble ble ble\nblelle", Uri = new Uri("file://ble.rhe") }; var opened = await languageClient.SendRequest <object>(DocumentNames.DidOpen, new DidOpenTextDocumentParams() { TextDocument = textDocument }); Task.Delay(2500).Wait(); var result = await languageClient.SendRequest <CompletionList>(DocumentNames.Completion, new CompletionParams() { TextDocument = new TextDocumentIdentifier(textDocument.Uri), Position = new Position() }); Console.WriteLine(JsonConvert.SerializeObject(result.Items, Formatting.Indented)); Task.Delay(3000).Wait(); languageClient.Dispose(); }
/// <summary> /// The main asynchronous program entry-point. /// </summary> /// <returns> /// A <see cref="Task"/> representing program operation. /// </returns> static async Task AsyncMain() { ProcessStartInfo serverStartInfo = new ProcessStartInfo("dotnet") { Arguments = $"\"{ServerAssembly}\"" }; Log.Information("Starting server..."); LanguageClient client = new LanguageClient(Log.Logger, serverStartInfo) { ClientCapabilities = { Workspace = { DidChangeConfiguration = new DidChangeConfigurationCapability { DynamicRegistration = false } } } }; using (client) { // Listen for log messages from the language server. client.Window.OnLogMessage((message, messageType) => { Log.Information("Language server says: [{MessageType:l}] {Message}", messageType, message); }); // Listen for our custom notification from the language server. client.HandleNotification <DummyParams>("dummy/notify", notification => { Log.Information("Received dummy notification from language server: {Message}", notification.Message ); }); await client.Initialize(workspaceRoot : @"C:\Foo"); Log.Information("Client started."); // Update server configuration. client.Workspace.DidChangeConfiguration( new JObject( new JProperty("setting1", true), new JProperty("setting2", "Hello") ) ); // Invoke our custom handler. await client.SendRequest("dummy", new DummyParams { Message = "Hello, world!" }); Log.Information("Stopping language server..."); await client.Shutdown(); Log.Information("Server stopped."); } }
static async Task Main(string[] args) { ProcessStartInfo serverStartInfo = new ProcessStartInfo("c:\\Program Files\\LLVM\\bin\\clangd.exe") { Arguments = "-compile-commands-dir=c:\\dev\\repos\\ILMD" }; var factory = new LoggerFactory(); await Task.Factory.StartNew(async() => { using (var client = new LanguageClient(factory, serverStartInfo)) { var doc = client.ClientCapabilities.TextDocument = new TextDocumentClientCapabilities { CodeAction = new CodeActionCapability { DynamicRegistration = true }, CodeLens = new CodeLensCapability { DynamicRegistration = true }, ColorProvider = new ColorProviderCapability { DynamicRegistration = true }, Completion = new CompletionCapability { CompletionItem = new CompletionItemCapability { CommitCharactersSupport = true, DocumentationFormat = new Container <MarkupKind>(MarkupKind.Markdown, MarkupKind.Plaintext), SnippetSupport = true }, CompletionItemKind = new CompletionItemKindCapability { ValueSet = new Container <CompletionItemKind>((CompletionItemKind[])Enum.GetValues(typeof(CompletionItemKind))) }, ContextSupport = true, DynamicRegistration = true }, Definition = new DefinitionCapability { DynamicRegistration = true, }, DocumentHighlight = new DocumentHighlightCapability { DynamicRegistration = true, }, DocumentLink = new DocumentLinkCapability { DynamicRegistration = true, }, DocumentSymbol = new DocumentSymbolCapability { DynamicRegistration = true, SymbolKind = new SymbolKindCapability { ValueSet = new Container <SymbolKind>((SymbolKind[])Enum.GetValues(typeof(SymbolKind))) } }, Formatting = new DocumentFormattingCapability { DynamicRegistration = true }, Hover = new HoverCapability { DynamicRegistration = true, ContentFormat = new Container <MarkupKind>((MarkupKind[])Enum.GetValues(typeof(MarkupKind))) }, Implementation = new ImplementationCapability { DynamicRegistration = true }, OnTypeFormatting = new DocumentOnTypeFormattingCapability { DynamicRegistration = true }, PublishDiagnostics = new PublishDiagnosticsCapability { RelatedInformation = true }, RangeFormatting = new DocumentRangeFormattingCapability { DynamicRegistration = true }, References = new ReferencesCapability { DynamicRegistration = true }, Rename = new RenameCapability { DynamicRegistration = true }, SignatureHelp = new SignatureHelpCapability { DynamicRegistration = true, SignatureInformation = new SignatureInformationCapability { ContentFormat = new Container <MarkupKind>((MarkupKind[])Enum.GetValues(typeof(MarkupKind))) } }, Synchronization = new SynchronizationCapability { DidSave = true, DynamicRegistration = true, WillSave = true, WillSaveWaitUntil = true }, TypeDefinition = new TypeDefinitionCapability { DynamicRegistration = true }, }; var workspace = client.ClientCapabilities.Workspace = new WorkspaceClientCapabilities { ApplyEdit = true, Configuration = true, DidChangeConfiguration = new DidChangeConfigurationCapability { DynamicRegistration = true }, DidChangeWatchedFiles = new DidChangeWatchedFilesCapability { DynamicRegistration = true }, ExecuteCommand = new ExecuteCommandCapability { DynamicRegistration = true }, Symbol = new WorkspaceSymbolCapability { DynamicRegistration = true, SymbolKind = new SymbolKindCapability { ValueSet = new Container <SymbolKind>((SymbolKind[])Enum.GetValues(typeof(SymbolKind))) } }, WorkspaceEdit = new WorkspaceEditCapability { DocumentChanges = true }, WorkspaceFolders = true }; client.ClientCapabilities.TextDocument.PublishDiagnostics = new PublishDiagnosticsCapability { RelatedInformation = true }; client.HandleNotification("dummy/notify", () => { Log.Information("Received dummy notification from language server."); }); await client.Initialize("c:\\dev\\repos\\ILMD", new InitializedParams { }); var caps = client.ServerCapabilities; var ccaps = client.ClientCapabilities; client.TextDocument.OnPublishDiagnostics((uri, diags) => { }); string filePath = "c:\\dev\\repos\\ILMD\\PeripheralBoard\\PeripheralBoard.DiscoveryBoard\\main.cpp"; client.TextDocument.DidOpen(filePath, "cpp", File.ReadAllText(filePath)); } }); while (true) { Thread.Sleep(10); } }
/// <summary> /// Called when the package is initialising. /// </summary> /// <param name="cancellationToken"> /// A <see cref="CancellationToken"/> that can be used to cancel the operation. /// </param> /// <param name="progress"> /// The initialisation progress-reporting facility. /// </param> /// <returns> /// A <see cref="Task"/> representing package initialisation. /// </returns> protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress <ServiceProgressData> progress) { Trace.WriteLine("Enter ExtensionPackage.InitializeAsync."); cancellationToken.Register( () => InitCompletion.TrySetCanceled(cancellationToken) ); await base.InitializeAsync(cancellationToken, progress); OutputPane = GetOutputPane(PackageOutputPaneGuid, "LSP Demo"); OutputPane.Activate(); await TaskScheduler.Default; try { Trace.WriteLine("Creating language service..."); LanguageClient = new LanguageClient(Log.Logger, new ProcessStartInfo("dotnet") { Arguments = @"""D:\Development\github\tintoy\msbuild-project-tools\out\language-server\MSBuildProjectTools.LanguageServer.Host.dll""", //Arguments = @"""D:\Development\github\tintoy\dotnet-language-client\samples\Server\bin\Debug\netcoreapp2.0\Server.dll""", Environment = { ["MSBUILD_PROJECT_TOOLS_DIR"] = @"D:\Development\github\tintoy\msbuild-project-tools", ["MSBUILD_PROJECT_TOOLS_SEQ_URL"] = "http://localhost:5341/", ["MSBUILD_PROJECT_TOOLS_SEQ_API_KEY"] = "wxEURGakoVuXpIRXyMnt", ["MSBUILD_PROJECT_TOOLS_VERBOSE_LOGGING"] = "1", ["LSP_SEQ_URL"] = "http://localhost:5341/", ["LSP_SEQ_API_KEY"] = "wxEURGakoVuXpIRXyMnt", ["LSP_VERBOSE_LOGGING"] = "1" } }); LanguageClient.Window.OnLogMessage(LanguageClient_LogMessage); await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); Trace.WriteLine("Retrieving solution directory..."); IVsSolution solution = (IVsSolution)GetService(typeof(SVsSolution)); int hr = solution.GetSolutionInfo(out string solutionDir, out _, out _); ErrorHandler.ThrowOnFailure(hr); Trace.WriteLine("Initialising language client..."); await TaskScheduler.Default; await LanguageClient.Initialize(solutionDir); await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); Trace.WriteLine("Language client initialised."); InitCompletion.TrySetResult(null); } catch (Exception languageClientError) { Trace.WriteLine(languageClientError); InitCompletion.TrySetException(languageClientError); } finally { Trace.WriteLine("Exit ExtensionPackage.InitializeAsync."); } }