async Task <InitializeResult> IRequestHandler <InitializeParams, InitializeResult> .Handle(InitializeParams request, CancellationToken token) { ClientSettings = request; if (request.Trace == InitializeTrace.Verbose && MinimumLogLevel >= LogLevel.Information) { MinimumLogLevel = LogLevel.Trace; } await Task.WhenAll(_initializeDelegates.Select(c => c(request))); _clientVersion = request.Capabilities.GetClientVersion(); _serializer.SetClientCapabilities(_clientVersion.Value, request.Capabilities); var supportedCapabilites = new List <ISupports>(); if (_clientVersion == ClientVersion.Lsp3) { if (request.Capabilities.TextDocument != null) { supportedCapabilites.AddRange( LspHandlerDescriptorHelpers.GetSupportedCapabilities(request.Capabilities.TextDocument) ); } if (request.Capabilities.Workspace != null) { supportedCapabilites.AddRange( LspHandlerDescriptorHelpers.GetSupportedCapabilities(request.Capabilities.Workspace) ); } } _supportedCapabilities.Add(supportedCapabilites); AddHandlers(_serviceProvider.GetServices <IJsonRpcHandler>().ToArray()); var textDocumentCapabilities = ClientSettings.Capabilities.TextDocument; var workspaceCapabilities = ClientSettings.Capabilities.Workspace; var ccp = new ClientCapabilityProvider(_collection); var serverCapabilities = new ServerCapabilities() { CodeActionProvider = ccp.GetStaticOptions(textDocumentCapabilities.CodeAction).Get <ICodeActionOptions, CodeActionOptions>(CodeActionOptions.Of), CodeLensProvider = ccp.GetStaticOptions(textDocumentCapabilities.CodeLens).Get <ICodeLensOptions, CodeLensOptions>(CodeLensOptions.Of), CompletionProvider = ccp.GetStaticOptions(textDocumentCapabilities.Completion).Get <ICompletionOptions, CompletionOptions>(CompletionOptions.Of), DefinitionProvider = ccp.HasStaticHandler(textDocumentCapabilities.Definition), DocumentFormattingProvider = ccp.HasStaticHandler(textDocumentCapabilities.Formatting), DocumentHighlightProvider = ccp.HasStaticHandler(textDocumentCapabilities.DocumentHighlight), DocumentLinkProvider = ccp.GetStaticOptions(textDocumentCapabilities.DocumentLink).Get <IDocumentLinkOptions, DocumentLinkOptions>(DocumentLinkOptions.Of), DocumentOnTypeFormattingProvider = ccp.GetStaticOptions(textDocumentCapabilities.OnTypeFormatting).Get <IDocumentOnTypeFormattingOptions, DocumentOnTypeFormattingOptions>(DocumentOnTypeFormattingOptions.Of), DocumentRangeFormattingProvider = ccp.HasStaticHandler(textDocumentCapabilities.RangeFormatting), DocumentSymbolProvider = ccp.HasStaticHandler(textDocumentCapabilities.DocumentSymbol), ExecuteCommandProvider = ccp.GetStaticOptions(workspaceCapabilities.ExecuteCommand).Reduce <IExecuteCommandOptions, ExecuteCommandOptions>(ExecuteCommandOptions.Of), HoverProvider = ccp.HasStaticHandler(textDocumentCapabilities.Hover), ReferencesProvider = ccp.HasStaticHandler(textDocumentCapabilities.References), RenameProvider = ccp.GetStaticOptions(textDocumentCapabilities.Rename).Get <IRenameOptions, RenameOptions>(RenameOptions.Of), SignatureHelpProvider = ccp.GetStaticOptions(textDocumentCapabilities.SignatureHelp).Get <ISignatureHelpOptions, SignatureHelpOptions>(SignatureHelpOptions.Of), WorkspaceSymbolProvider = ccp.HasStaticHandler(workspaceCapabilities.Symbol), ImplementationProvider = ccp.GetStaticOptions(textDocumentCapabilities.Implementation).Get <IImplementationOptions, ImplementationOptions>(ImplementationOptions.Of), TypeDefinitionProvider = ccp.GetStaticOptions(textDocumentCapabilities.TypeDefinition).Get <ITypeDefinitionOptions, TypeDefinitionOptions>(TypeDefinitionOptions.Of), ColorProvider = ccp.GetStaticOptions(textDocumentCapabilities.ColorProvider).Get <IColorOptions, ColorOptions>(ColorOptions.Of), FoldingRangeProvider = ccp.GetStaticOptions(textDocumentCapabilities.FoldingRangeProvider).Get <IFoldingRangeOptions, FoldingRangeOptions>(FoldingRangeOptions.Of), }; if (_collection.ContainsHandler(typeof(IDidChangeWorkspaceFoldersHandler))) { serverCapabilities.Workspace = new WorkspaceServerCapabilities() { WorkspaceFolders = new WorkspaceFolderOptions() { Supported = true, ChangeNotifications = Guid.NewGuid().ToString() } }; } var textDocumentSyncKind = _collection.ContainsHandler(typeof(IDidChangeTextDocumentHandler)) ? _collection .Select(x => x.Handler) .OfType <IDidChangeTextDocumentHandler>() .Where(x => x.Change != TextDocumentSyncKind.None) .Min(z => z.Change) : TextDocumentSyncKind.None; if (_clientVersion == ClientVersion.Lsp2) { serverCapabilities.TextDocumentSync = textDocumentSyncKind; } else { serverCapabilities.TextDocumentSync = new TextDocumentSyncOptions() { Change = textDocumentSyncKind, OpenClose = _collection.ContainsHandler(typeof(IDidOpenTextDocumentHandler)) || _collection.ContainsHandler(typeof(IDidCloseTextDocumentHandler)), Save = _collection.ContainsHandler(typeof(IDidSaveTextDocumentHandler)) ? new SaveOptions() { IncludeText = true /* TODO: Make configurable */ } : null, WillSave = _collection.ContainsHandler(typeof(IWillSaveTextDocumentHandler)), WillSaveWaitUntil = _collection.ContainsHandler(typeof(IWillSaveWaitUntilTextDocumentHandler)) }; } // TODO: Need a call back here // serverCapabilities.Experimental; _reciever.Initialized(); var result = ServerSettings = new InitializeResult() { Capabilities = serverCapabilities }; await Task.WhenAll(_initializedDelegates.Select(c => c(request, result))); // TODO: if (_clientVersion == ClientVersion.Lsp2) { // Small delay to let client respond await Task.Delay(100, token); _initializeComplete.OnNext(result); _initializeComplete.OnCompleted(); } return(result); }
async Task <InitializeResult> IRequestHandler <InitializeParams, InitializeResult> .Handle( InitializeParams request, CancellationToken token) { ClientSettings = request; if (request.Trace == InitializeTrace.Verbose) { var loggerSettings = _serviceProvider.GetService <LanguageServerLoggerSettings>(); if (loggerSettings?.MinimumLogLevel <= LogLevel.Information) { loggerSettings.MinimumLogLevel = LogLevel.Trace; } var optionsMonitor = _serviceProvider.GetService <IOptionsMonitor <LoggerFilterOptions> >() as LanguageServerLoggerFilterOptions; if (optionsMonitor?.CurrentValue.MinLevel <= LogLevel.Information) { optionsMonitor.CurrentValue.MinLevel = LogLevel.Trace; optionsMonitor.Set(optionsMonitor.CurrentValue); } } _clientVersion = request.Capabilities?.GetClientVersion() ?? ClientVersion.Lsp2; _serializer.SetClientCapabilities(_clientVersion.Value, request.Capabilities); var supportedCapabilities = new List <ISupports>(); if (_clientVersion == ClientVersion.Lsp3) { if (request.Capabilities.TextDocument != null) { supportedCapabilities.AddRange( LspHandlerDescriptorHelpers.GetSupportedCapabilities(request.Capabilities.TextDocument) ); } if (request.Capabilities.Workspace != null) { supportedCapabilities.AddRange( LspHandlerDescriptorHelpers.GetSupportedCapabilities(request.Capabilities.Workspace) ); } } _supportedCapabilities.Add(supportedCapabilities); ClientSettings.Capabilities ??= new ClientCapabilities(); var textDocumentCapabilities = ClientSettings.Capabilities.TextDocument ??= new TextDocumentClientCapabilities(); var workspaceCapabilities = ClientSettings.Capabilities.Workspace ??= new WorkspaceClientCapabilities(); var windowCapabilities = ClientSettings.Capabilities.Window ??= new WindowClientCapabilities(); _serverWorkDoneManager.Initialized(windowCapabilities); { RegisterHandlers(_collection); } await Task.WhenAll(_initializeDelegates.Select(c => c(this, request, token))); var ccp = new ClientCapabilityProvider(_collection, windowCapabilities.WorkDoneProgress); var serverCapabilities = new ServerCapabilities() { CodeActionProvider = ccp.GetStaticOptions(textDocumentCapabilities.CodeAction) .Get <ICodeActionOptions, CodeActionOptions>(CodeActionOptions.Of), CodeLensProvider = ccp.GetStaticOptions(textDocumentCapabilities.CodeLens) .Get <ICodeLensOptions, CodeLensOptions>(CodeLensOptions.Of), CompletionProvider = ccp.GetStaticOptions(textDocumentCapabilities.Completion) .Get <ICompletionOptions, CompletionOptions>(CompletionOptions.Of), DefinitionProvider = ccp.GetStaticOptions(textDocumentCapabilities.Definition) .Get <IDefinitionOptions, DefinitionOptions>(DefinitionOptions.Of), DocumentFormattingProvider = ccp.GetStaticOptions(textDocumentCapabilities.Formatting) .Get <IDocumentFormattingOptions, DocumentFormattingOptions>(DocumentFormattingOptions.Of), DocumentHighlightProvider = ccp.GetStaticOptions(textDocumentCapabilities.DocumentHighlight) .Get <IDocumentHighlightOptions, DocumentHighlightOptions>(DocumentHighlightOptions.Of), DocumentLinkProvider = ccp.GetStaticOptions(textDocumentCapabilities.DocumentLink) .Get <IDocumentLinkOptions, DocumentLinkOptions>(DocumentLinkOptions.Of), DocumentOnTypeFormattingProvider = ccp.GetStaticOptions(textDocumentCapabilities.OnTypeFormatting) .Get <IDocumentOnTypeFormattingOptions, DocumentOnTypeFormattingOptions>( DocumentOnTypeFormattingOptions.Of), DocumentRangeFormattingProvider = ccp.GetStaticOptions(textDocumentCapabilities.RangeFormatting) .Get <IDocumentRangeFormattingOptions, DocumentRangeFormattingOptions>(DocumentRangeFormattingOptions .Of), DocumentSymbolProvider = ccp.GetStaticOptions(textDocumentCapabilities.DocumentSymbol) .Get <IDocumentSymbolOptions, DocumentSymbolOptions>(DocumentSymbolOptions.Of), ExecuteCommandProvider = ccp.GetStaticOptions(workspaceCapabilities.ExecuteCommand) .Reduce <IExecuteCommandOptions, ExecuteCommandOptions>(ExecuteCommandOptions.Of), TextDocumentSync = ccp.GetStaticOptions(textDocumentCapabilities.Synchronization) .Reduce <ITextDocumentSyncOptions, TextDocumentSyncOptions>(TextDocumentSyncOptions.Of), HoverProvider = ccp.GetStaticOptions(textDocumentCapabilities.Hover) .Get <IHoverOptions, HoverOptions>(HoverOptions.Of), ReferencesProvider = ccp.GetStaticOptions(textDocumentCapabilities.References) .Get <IReferencesOptions, ReferencesOptions>(ReferencesOptions.Of), RenameProvider = ccp.GetStaticOptions(textDocumentCapabilities.Rename) .Get <IRenameOptions, RenameOptions>(RenameOptions.Of), SignatureHelpProvider = ccp.GetStaticOptions(textDocumentCapabilities.SignatureHelp) .Get <ISignatureHelpOptions, SignatureHelpOptions>(SignatureHelpOptions.Of), WorkspaceSymbolProvider = ccp.GetStaticOptions(workspaceCapabilities.Symbol) .Get <IWorkspaceSymbolOptions, WorkspaceSymbolOptions>(WorkspaceSymbolOptions.Of), ImplementationProvider = ccp.GetStaticOptions(textDocumentCapabilities.Implementation) .Get <IImplementationOptions, ImplementationOptions>(ImplementationOptions.Of), TypeDefinitionProvider = ccp.GetStaticOptions(textDocumentCapabilities.TypeDefinition) .Get <ITypeDefinitionOptions, TypeDefinitionOptions>(TypeDefinitionOptions.Of), ColorProvider = ccp.GetStaticOptions(textDocumentCapabilities.ColorProvider) .Get <IDocumentColorOptions, DocumentColorOptions>(DocumentColorOptions.Of), FoldingRangeProvider = ccp.GetStaticOptions(textDocumentCapabilities.FoldingRange) .Get <IFoldingRangeOptions, FoldingRangeOptions>(FoldingRangeOptions.Of), SelectionRangeProvider = ccp.GetStaticOptions(textDocumentCapabilities.FoldingRange) .Get <ISelectionRangeOptions, SelectionRangeOptions>(SelectionRangeOptions.Of), DeclarationProvider = ccp.GetStaticOptions(textDocumentCapabilities.Declaration) .Get <IDeclarationOptions, DeclarationOptions>(DeclarationOptions.Of), #pragma warning disable 618 CallHierarchyProvider = ccp.GetStaticOptions(textDocumentCapabilities.CallHierarchy) .Get <ICallHierarchyOptions, CallHierarchyOptions>(CallHierarchyOptions.Of), SemanticTokensProvider = ccp.GetStaticOptions(textDocumentCapabilities.SemanticTokens) .Get <ISemanticTokensOptions, SemanticTokensOptions>(SemanticTokensOptions.Of), #pragma warning restore 618 }; if (_collection.ContainsHandler(typeof(IDidChangeWorkspaceFoldersHandler))) { serverCapabilities.Workspace = new WorkspaceServerCapabilities() { WorkspaceFolders = new WorkspaceFolderOptions() { Supported = true, ChangeNotifications = Guid.NewGuid().ToString() } }; } if (ccp.HasStaticHandler(textDocumentCapabilities.Synchronization)) { var textDocumentSyncKind = TextDocumentSyncKind.None; if (_collection.ContainsHandler(typeof(IDidChangeTextDocumentHandler))) { var kinds = _collection .Select(x => x.Handler) .OfType <IDidChangeTextDocumentHandler>() .Select(x => x.GetRegistrationOptions()?.SyncKind ?? TextDocumentSyncKind.None) .Where(x => x != TextDocumentSyncKind.None) .ToArray(); if (kinds.Any()) { textDocumentSyncKind = kinds.Min(z => z); } } if (_clientVersion == ClientVersion.Lsp2) { serverCapabilities.TextDocumentSync = textDocumentSyncKind; } else { serverCapabilities.TextDocumentSync = new TextDocumentSyncOptions() { Change = textDocumentSyncKind, OpenClose = _collection.ContainsHandler(typeof(IDidOpenTextDocumentHandler)) || _collection.ContainsHandler(typeof(IDidCloseTextDocumentHandler)), Save = _collection.ContainsHandler(typeof(IDidSaveTextDocumentHandler)) ? new SaveOptions() { IncludeText = true /* TODO: Make configurable */ } : null, WillSave = _collection.ContainsHandler(typeof(IWillSaveTextDocumentHandler)), WillSaveWaitUntil = _collection.ContainsHandler(typeof(IWillSaveWaitUntilTextDocumentHandler)) }; } } // TODO: Need a call back here // serverCapabilities.Experimental; _serverReceiver.Initialized(); var result = ServerSettings = new InitializeResult() { Capabilities = serverCapabilities, ServerInfo = _serverInfo ?? new ServerInfo() { Name = Assembly.GetEntryAssembly()?.GetName().Name, Version = Assembly.GetEntryAssembly()?.GetCustomAttribute <AssemblyInformationalVersionAttribute>() ?.InformationalVersion ?? Assembly.GetEntryAssembly()?.GetCustomAttribute <AssemblyVersionAttribute>()?.Version } }; await Task.WhenAll(_initializedDelegates.Select(c => c(this, request, result, token))); foreach (var item in _collection) { LspHandlerDescriptorHelpers.InitializeHandler(item, _supportedCapabilities, item.Handler); } // TODO: if (_clientVersion == ClientVersion.Lsp2) { _initializeComplete.OnNext(result); _initializeComplete.OnCompleted(); } return(result); }