From 2202a08d6f609015f236476d39b7b868f072968c Mon Sep 17 00:00:00 2001 From: Andreas Louv Date: Sun, 5 Mar 2023 23:55:31 +0100 Subject: [PATCH] Add support for "customNotificationHandlers" --- README.md | 7 +++++++ autoload/lsp/handlers.vim | 24 +++++++++++++----------- autoload/lsp/lsp.vim | 8 +++++++- autoload/lsp/lspserver.vim | 3 ++- doc/lsp.txt | 6 ++++++ 5 files changed, 35 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index b7cc6c9..c9113fd 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,9 @@ To use the plugin features with a particular file type(s), you need to first reg To register a LSP server, add the following lines to your .vimrc file (use only the LSP servers that you need from the below list). If you used [vim-plug](https://github.com/junegunn/vim-plug) to install the LSP plugin, the steps are described later in this section. ``` + function! TypeScriptCustomNotificationHandler(lspserver, reply) abort + echom printf("TypeScript Version = %s", reply.params.version) + endfunction let lspServers = [ \ #{ \ filetype: ['c', 'cpp'], @@ -59,6 +62,9 @@ To register a LSP server, add the following lines to your .vimrc file (use only \ filetype: ['javascript', 'typescript'], \ path: '/usr/local/bin/typescript-language-server', \ args: ['--stdio'] + \ customNotificationHandlers: { + \ '$/typescriptVersion': function('TypeScriptCustomNotificationHandler') + \ } \ }, \ #{ \ filetype: 'sh', @@ -115,6 +121,7 @@ filetype|One or more file types supported by the LSP server. This can be a Stri path|complete path to the LSP server executable (without any arguments). args|a list of command-line arguments passed to the LSP server. Each argument is a separate List item. initializationOptions|User provided initialization options. May be of any type. For example the *intelephense* PHP language server accept several options here with the License Key among others. +customNotificationHandlers|A dictionary of notifications and functions that can be specified to add support for custom language server notifications. The LSP servers are added using the LspAddServer() function. This function accepts a list of LSP servers with the above information. diff --git a/autoload/lsp/handlers.vim b/autoload/lsp/handlers.vim index ce761f2..70d56c8 100644 --- a/autoload/lsp/handlers.vim +++ b/autoload/lsp/handlers.vim @@ -73,10 +73,6 @@ def ProcessUnsupportedNotifOnce(lspserver: dict, reply: dict) endif enddef -# silently ignore an unsupported notification message -def IgnoreNotif(lspserver: dict, reply: dict) -enddef - # process notification messages from the LSP server export def ProcessNotif(lspserver: dict, reply: dict): void var lsp_notif_handlers: dict = @@ -84,22 +80,28 @@ export def ProcessNotif(lspserver: dict, reply: dict): void 'window/showMessage': ProcessShowMsgNotif, 'window/logMessage': ProcessLogMsgNotif, 'textDocument/publishDiagnostics': ProcessDiagNotif, - '$/progress': IgnoreNotif, '$/logTrace': ProcessLogTraceNotif, - '$/status/report': IgnoreNotif, - '$/status/show': IgnoreNotif, 'telemetry/event': ProcessUnsupportedNotifOnce, + } + + var lsp_ignored_notif_handlers: list = + [ + '$/progress', + '$/status/report', + '$/status/show', # Java language server sends the 'language/status' notification which is # not in the LSP specification - 'language/status': IgnoreNotif, + 'language/status', # Typescript language server sends the '$/typescriptVersion' notification # which is not in the LSP specification - '$/typescriptVersion': IgnoreNotif - } + '$/typescriptVersion' + ] if lsp_notif_handlers->has_key(reply.method) lsp_notif_handlers[reply.method](lspserver, reply) - else + elseif lspserver.customNotificationHandlers->has_key(reply.method) + lspserver.customNotificationHandlers[reply.method](lspserver, reply) + elseif lsp_ignored_notif_handlers->index(reply.method) == -1 util.ErrMsg($'Error: Unsupported notification received from LSP server {reply->string()}') endif enddef diff --git a/autoload/lsp/lsp.vim b/autoload/lsp/lsp.vim index 616e7ba..e42b12a 100644 --- a/autoload/lsp/lsp.vim +++ b/autoload/lsp/lsp.vim @@ -429,6 +429,11 @@ export def AddServer(serverList: list>) initializationOptions = server.initializationOptions endif + var customNotificationHandlers: dict = {} + if server->has_key('customNotificationHandlers') + customNotificationHandlers = server.customNotificationHandlers + endif + if server.omnicompl->type() != v:t_bool util.ErrMsg($'Error: Setting of omnicompl {server.omnicompl} is not a Boolean') return @@ -441,7 +446,8 @@ export def AddServer(serverList: list>) var lspserver: dict = lserver.NewLspServer(server.path, args, server.syncInit, - initializationOptions) + initializationOptions, + customNotificationHandlers) var ftypes = server.filetype if ftypes->type() == v:t_string diff --git a/autoload/lsp/lspserver.vim b/autoload/lsp/lspserver.vim index e366b8f..fd78974 100644 --- a/autoload/lsp/lspserver.vim +++ b/autoload/lsp/lspserver.vim @@ -1589,12 +1589,13 @@ def TagFunc(lspserver: dict, pat: string, flags: string, info: dict): return symbol.TagFunc(lspserver, taglocations, pat) enddef -export def NewLspServer(path: string, args: list, isSync: bool, initializationOptions: any): dict +export def NewLspServer(path: string, args: list, isSync: bool, initializationOptions: any, customNotificationHandlers: dict): dict var lspserver: dict = { path: path, args: args, syncInit: isSync, initializationOptions: initializationOptions, + customNotificationHandlers: customNotificationHandlers, running: false, ready: false, job: v:none, diff --git a/doc/lsp.txt b/doc/lsp.txt index 9449483..f25181d 100644 --- a/doc/lsp.txt +++ b/doc/lsp.txt @@ -220,6 +220,12 @@ To add a language server, the following information is needed: or useful for initialization. Those can be provided in this dictionary and if present will be transmitted to the lsp server. + customNotificationHandlers + (Optional) some lsp servers (e.g. + typescript-language-server) will send additional + notifications which you might want to silence or handle. + The provided notification handlers will be called with a + reference to the 'lspserver' and the 'reply'. omnicompl (Optional) a boolean value that enables (true) or disables (false) omni-completion for this file types. By default this is set to 'v:true'. -- 2.48.1