From 079aaaf1e68da34e26ea21e55e919aaf4003e14e Mon Sep 17 00:00:00 2001 From: "N. Taylor Mullen" Date: Tue, 14 Jan 2020 14:04:10 -0800 Subject: [PATCH] Start Razor Language Server when new Razor LSP editor opens. (#1487) - Included the LanguageServer core dlls as part of the VSIX install. To do this I had to expose the language server's output path via a target and then dynamically include its outputs in the VSIX output. - Given how VSIX's are built I could not privately reference our language server to ensure that it's built when the VSIX is built. To work around this limitation I added a `_BuildLanguageServer` target that calls MSBuild directly on the language server as part of build. - For now I'm dynamically booting the currently built language server that's deployed with the extension. I haven't given a lot of thought to what flavor of OS (x64 vs. x86) the server can run on; or if we need to ensure dotnet.exe is available. - Found that the VS LSP client and the O# language server library that we use don't inter-operate as we'd expect. The server ends up telling the client that it doesn't care about text document change events (we do). I've created a separate PR in O# to fix this: https://github.com/OmniSharp/csharp-language-server-protocol/pull/199 - Add OmniSharp 3rd party library to signing information for VSIX insertions. aspnet/AspNetCore#17789 --- eng/Signing.props | 7 +- ...oft.AspNetCore.Razor.LanguageServer.csproj | 7 ++ .../RazorLanguageServerClient.cs | 75 +++++++++++++++++++ ...crosoft.VisualStudio.RazorExtension.csproj | 25 ++++++- 4 files changed, 112 insertions(+), 2 deletions(-) create mode 100644 src/Razor/src/Microsoft.VisualStudio.LanguageServerClient.Razor/RazorLanguageServerClient.cs diff --git a/eng/Signing.props b/eng/Signing.props index 7759137c18d..a3710643cd4 100644 --- a/eng/Signing.props +++ b/eng/Signing.props @@ -3,7 +3,7 @@ @@ -14,6 +14,11 @@ --> + + + + + diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Microsoft.AspNetCore.Razor.LanguageServer.csproj b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Microsoft.AspNetCore.Razor.LanguageServer.csproj index 96d2acedac5..62ee16c97bd 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Microsoft.AspNetCore.Razor.LanguageServer.csproj +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Microsoft.AspNetCore.Razor.LanguageServer.csproj @@ -17,6 +17,13 @@ + + + <_ServerOutputPath Include="$(OutputPath)"> + + + + $(PublishDir)\OmniSharpPlugin diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServerClient.Razor/RazorLanguageServerClient.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServerClient.Razor/RazorLanguageServerClient.cs new file mode 100644 index 00000000000..d79d05fa0d5 --- /dev/null +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServerClient.Razor/RazorLanguageServerClient.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Diagnostics; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.VisualStudio.LanguageServer.Client; +using Microsoft.VisualStudio.Threading; +using Microsoft.VisualStudio.Utilities; + +namespace Microsoft.VisualStudio.LanguageServerClient.Razor +{ + [Export(typeof(ILanguageClient))] + [ContentType(RazorLSPContentTypeDefinition.Name)] + internal class RazorLanguageServerClient : ILanguageClient + { + public string Name => "Razor Language Server Client"; + + public IEnumerable ConfigurationSections => null; + + public object InitializationOptions => null; + + public IEnumerable FilesToWatch => null; + + public event AsyncEventHandler StartAsync; + public event AsyncEventHandler StopAsync + { + add { } + remove { } + } + + public async Task ActivateAsync(CancellationToken token) + { + await Task.Yield(); + + var currentAssembly = typeof(RazorLanguageServerClient).Assembly; + var currentAssemblyLocation = currentAssembly.Location; + var extensionDirectory = Path.GetDirectoryName(currentAssemblyLocation); + var languageServerPath = Path.Combine(extensionDirectory, "LanguageServer", "rzls.exe"); + var info = new ProcessStartInfo(); + info.FileName = languageServerPath; + info.Arguments = "-lsp --logLevel Trace"; + info.RedirectStandardInput = true; + info.RedirectStandardOutput = true; + info.UseShellExecute = false; + info.CreateNoWindow = true; + + Process process = new Process(); + process.StartInfo = info; + + if (process.Start()) + { + return new Connection(process.StandardOutput.BaseStream, process.StandardInput.BaseStream); + } + + return null; + } + + public async Task OnLoadedAsync() + { + await StartAsync.InvokeAsync(this, EventArgs.Empty); + } + + public Task OnServerInitializeFailedAsync(Exception e) + { + return Task.CompletedTask; + } + + public Task OnServerInitializedAsync() + { + return Task.CompletedTask; + } + } +} diff --git a/src/Razor/src/Microsoft.VisualStudio.RazorExtension/Microsoft.VisualStudio.RazorExtension.csproj b/src/Razor/src/Microsoft.VisualStudio.RazorExtension/Microsoft.VisualStudio.RazorExtension.csproj index 098b2616bd7..bd71544b79a 100644 --- a/src/Razor/src/Microsoft.VisualStudio.RazorExtension/Microsoft.VisualStudio.RazorExtension.csproj +++ b/src/Razor/src/Microsoft.VisualStudio.RazorExtension/Microsoft.VisualStudio.RazorExtension.csproj @@ -23,7 +23,7 @@ false - + true @@ -113,6 +113,29 @@ <_GeneratedVSIXBindingRedirectFile>$(IntermediateOutputPath)$(MSBuildProjectName).BindingRedirects.cs + + + + + + + + + + + <_ResolvedPackageVersionInfoProperty>@(_ResolvedPackageVersionInfo) + + + + + true + LanguageServer\ + + + +