diff --git a/src/FSharp.Compiler.LanguageServer/Common/CapabilitiesManager.fs b/src/FSharp.Compiler.LanguageServer/Common/CapabilitiesManager.fs index b8b50e95f33..23d81ff7403 100644 --- a/src/FSharp.Compiler.LanguageServer/Common/CapabilitiesManager.fs +++ b/src/FSharp.Compiler.LanguageServer/Common/CapabilitiesManager.fs @@ -2,43 +2,62 @@ open Microsoft.VisualStudio.LanguageServer.Protocol open Microsoft.CommonLanguageServerProtocol.Framework +open FSharp.Compiler.LanguageServer type IServerCapabilitiesOverride = - abstract member OverrideServerCapabilities: ServerCapabilities -> ServerCapabilities + abstract member OverrideServerCapabilities: FSharpLanguageServerConfig * ServerCapabilities * ClientCapabilities -> ServerCapabilities -type CapabilitiesManager(scOverrides: IServerCapabilitiesOverride seq) = +type CapabilitiesManager(config: FSharpLanguageServerConfig, scOverrides: IServerCapabilitiesOverride seq) = let mutable initializeParams = None - let defaultCapabilities = + let getInitializeParams () = + match initializeParams with + | Some params' -> params' + | None -> failwith "InitializeParams is null" + + let addIf (enabled: bool) (capability: 'a) = + if enabled then capability |> withNull else null + + let defaultCapabilities (clientCapabilities: ClientCapabilities) = + // TODO: don't register if dynamic registraion is supported ServerCapabilities( TextDocumentSync = TextDocumentSyncOptions(OpenClose = true, Change = TextDocumentSyncKind.Full), DiagnosticOptions = - DiagnosticOptions(WorkDoneProgress = true, InterFileDependencies = true, Identifier = "potato", WorkspaceDiagnostics = true), + addIf + config.EnabledFeatures.Diagnostics + (DiagnosticOptions( + WorkDoneProgress = true, + InterFileDependencies = true, + Identifier = "potato", + WorkspaceDiagnostics = true + )), //CompletionProvider = CompletionOptions(TriggerCharacters = [| "."; " " |], ResolveProvider = true, WorkDoneProgress = true), //HoverProvider = SumType(HoverOptions(WorkDoneProgress = true)) SemanticTokensOptions = - SemanticTokensOptions( - Legend = - SemanticTokensLegend( - TokenTypes = (SemanticTokenTypes.AllTypes |> Seq.toArray), // XXX should be extended - TokenModifiers = (SemanticTokenModifiers.AllModifiers |> Seq.toArray) - ), - Range = false - ) + addIf + config.EnabledFeatures.SemanticHighlighting + + (SemanticTokensOptions( + Legend = + SemanticTokensLegend( + TokenTypes = (SemanticTokenTypes.AllTypes |> Seq.toArray), // XXX should be extended + TokenModifiers = (SemanticTokenModifiers.AllModifiers |> Seq.toArray) + ), + Range = false + )) ) interface IInitializeManager with member this.SetInitializeParams(request) = initializeParams <- Some request + member this.GetInitializeParams() = getInitializeParams () + member this.GetInitializeResult() = + let clientCapabilities = getInitializeParams().Capabilities + let serverCapabilities = - (defaultCapabilities, scOverrides) - ||> Seq.fold (fun acc (x: IServerCapabilitiesOverride) -> x.OverrideServerCapabilities acc) + (defaultCapabilities clientCapabilities, scOverrides) + ||> Seq.fold (fun acc (x: IServerCapabilitiesOverride) -> x.OverrideServerCapabilities(config, acc, clientCapabilities)) InitializeResult(Capabilities = serverCapabilities) - - member this.GetInitializeParams() = - match initializeParams with - | Some params' -> params' - | None -> failwith "InitializeParams is null" diff --git a/src/FSharp.Compiler.LanguageServer/FSharp.Compiler.LanguageServer.fsproj b/src/FSharp.Compiler.LanguageServer/FSharp.Compiler.LanguageServer.fsproj index 1b5f7c99122..d6ebfc1c6f6 100644 --- a/src/FSharp.Compiler.LanguageServer/FSharp.Compiler.LanguageServer.fsproj +++ b/src/FSharp.Compiler.LanguageServer/FSharp.Compiler.LanguageServer.fsproj @@ -34,6 +34,7 @@ + diff --git a/src/FSharp.Compiler.LanguageServer/FSharpLanguageServer.fs b/src/FSharp.Compiler.LanguageServer/FSharpLanguageServer.fs index 9d0d3ec4412..c5329d3cdbb 100644 --- a/src/FSharp.Compiler.LanguageServer/FSharpLanguageServer.fs +++ b/src/FSharp.Compiler.LanguageServer/FSharpLanguageServer.fs @@ -30,11 +30,18 @@ type Extensions = Async.StartAsTask(this, cancellationToken = ct) type FSharpLanguageServer - (jsonRpc: JsonRpc, logger: ILspLogger, ?initialWorkspace: FSharpWorkspace, ?addExtraHandlers: Action) = + ( + jsonRpc: JsonRpc, + logger: ILspLogger, + ?initialWorkspace: FSharpWorkspace, + ?addExtraHandlers: Action, + ?config: FSharpLanguageServerConfig + ) = // TODO: Switch to SystemTextJsonLanguageServer inherit NewtonsoftLanguageServer(jsonRpc, Newtonsoft.Json.JsonSerializer.CreateDefault(), logger) + let config = defaultArg config FSharpLanguageServerConfig.Default let initialWorkspace = defaultArg initialWorkspace (FSharpWorkspace()) do @@ -50,6 +57,7 @@ type FSharpLanguageServer serviceCollection .AddSingleton(initialWorkspace) .AddSingleton() + .AddSingleton(config) .AddSingleton>() .AddSingleton>() .AddSingleton() @@ -77,7 +85,16 @@ type FSharpLanguageServer static member Create(initialWorkspace, addExtraHandlers: Action) = FSharpLanguageServer.Create(LspLogger System.Diagnostics.Trace.TraceInformation, initialWorkspace, addExtraHandlers) - static member Create(logger: ILspLogger, initialWorkspace, ?addExtraHandlers: Action) = + static member Create(initialWorkspace, config: FSharpLanguageServerConfig, addExtraHandlers: Action) = + FSharpLanguageServer.Create(LspLogger System.Diagnostics.Trace.TraceInformation, initialWorkspace, addExtraHandlers, config) + + static member Create + ( + logger: ILspLogger, + initialWorkspace, + ?addExtraHandlers: Action, + ?config: FSharpLanguageServerConfig + ) = let struct (clientStream, serverStream) = FullDuplexStream.CreatePair() @@ -96,7 +113,7 @@ type FSharpLanguageServer jsonRpc.TraceSource.Switch.Level <- SourceLevels.All let server = - new FSharpLanguageServer(jsonRpc, logger, initialWorkspace, ?addExtraHandlers = addExtraHandlers) + new FSharpLanguageServer(jsonRpc, logger, initialWorkspace, ?addExtraHandlers = addExtraHandlers, ?config = config) jsonRpc.StartListening() diff --git a/src/FSharp.Compiler.LanguageServer/FSharpLanguageServerConfig.fs b/src/FSharp.Compiler.LanguageServer/FSharpLanguageServerConfig.fs new file mode 100644 index 00000000000..a1acd2b88da --- /dev/null +++ b/src/FSharp.Compiler.LanguageServer/FSharpLanguageServerConfig.fs @@ -0,0 +1,23 @@ +namespace FSharp.Compiler.LanguageServer + +type FSharpLanguageServerFeatures = + { + Diagnostics: bool + SemanticHighlighting: bool + } + + static member Default = + { + Diagnostics = true + SemanticHighlighting = true + } + +type FSharpLanguageServerConfig = + { + EnabledFeatures: FSharpLanguageServerFeatures + } + + static member Default = + { + EnabledFeatures = FSharpLanguageServerFeatures.Default + } diff --git a/src/FSharp.VisualStudio.Extension/ExtensionEntrypoint.cs b/src/FSharp.VisualStudio.Extension/ExtensionEntrypoint.cs index 8fbaf39dc70..ba47320b925 100644 --- a/src/FSharp.VisualStudio.Extension/ExtensionEntrypoint.cs +++ b/src/FSharp.VisualStudio.Extension/ExtensionEntrypoint.cs @@ -2,6 +2,8 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.VisualStudio.Extensibility; +using System.Threading; +using System; using Extension = Microsoft.VisualStudio.Extensibility.Extension; /// diff --git a/src/FSharp.VisualStudio.Extension/FSharp.VisualStudio.Extension.csproj b/src/FSharp.VisualStudio.Extension/FSharp.VisualStudio.Extension.csproj index db3a0a846f3..fae776deb73 100644 --- a/src/FSharp.VisualStudio.Extension/FSharp.VisualStudio.Extension.csproj +++ b/src/FSharp.VisualStudio.Extension/FSharp.VisualStudio.Extension.csproj @@ -9,10 +9,10 @@ - - - - + + + +