mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +00:00 
			
		
		
		
	fix(lsp): fix incorrect typing and doc for vim.lsp.rpc
				
					
				
			Typings introduced in #26032 and #26552 have a few conflicts, so we merge and clean them up. We also fix some incorrect type annotation in the `vim.lsp.rpc` package. See the associated PR for more details. Summary: - vim.rpc.Dispatchers -> vim.lsp.rpc.Dispatchers - vim.lsp.rpc.Error -> lsp.ResponseError - Revise docs
This commit is contained in:
		 Jongwook Choi
					Jongwook Choi
				
			
				
					committed by
					
						 Mathias Fußenegger
						Mathias Fußenegger
					
				
			
			
				
	
			
			
			 Mathias Fußenegger
						Mathias Fußenegger
					
				
			
						parent
						
							92c59c39c3
						
					
				
				
					commit
					ce4ea638c7
				
			| @@ -2089,7 +2089,10 @@ Lua module: vim.lsp.rpc                                              *lsp-rpc* | |||||||
|  |  | ||||||
| connect({host}, {port})                                *vim.lsp.rpc.connect()* | connect({host}, {port})                                *vim.lsp.rpc.connect()* | ||||||
|     Create a LSP RPC client factory that connects via TCP to the given host |     Create a LSP RPC client factory that connects via TCP to the given host | ||||||
|     and port |     and port. | ||||||
|  |  | ||||||
|  |     Return a function that can be passed to the `cmd` field for | ||||||
|  |     |vim.lsp.start_client()| or |vim.lsp.start()|. | ||||||
|  |  | ||||||
|     Parameters: ~ |     Parameters: ~ | ||||||
|       • {host}  (`string`) host to connect to |       • {host}  (`string`) host to connect to | ||||||
| @@ -2097,14 +2100,15 @@ connect({host}, {port})                                *vim.lsp.rpc.connect()* | |||||||
|  |  | ||||||
|     Return: ~ |     Return: ~ | ||||||
|         (`fun(dispatchers: vim.lsp.rpc.Dispatchers): vim.lsp.rpc.PublicClient`) |         (`fun(dispatchers: vim.lsp.rpc.Dispatchers): vim.lsp.rpc.PublicClient`) | ||||||
|         function intended to be passed to |vim.lsp.start_client()| or |  | ||||||
|         |vim.lsp.start()| on the field cmd |  | ||||||
|  |  | ||||||
|                                          *vim.lsp.rpc.domain_socket_connect()* |                                          *vim.lsp.rpc.domain_socket_connect()* | ||||||
| domain_socket_connect({pipe_path}) | domain_socket_connect({pipe_path}) | ||||||
|     Create a LSP RPC client factory that connects via named pipes (Windows) or |     Create a LSP RPC client factory that connects via named pipes (Windows) or | ||||||
|     unix domain sockets (Unix) to the given pipe_path (file path on Unix and |     unix domain sockets (Unix) to the given pipe_path (file path on Unix and | ||||||
|     name on Windows) |     name on Windows). | ||||||
|  |  | ||||||
|  |     Return a function that can be passed to the `cmd` field for | ||||||
|  |     |vim.lsp.start_client()| or |vim.lsp.start()|. | ||||||
|  |  | ||||||
|     Parameters: ~ |     Parameters: ~ | ||||||
|       • {pipe_path}  (`string`) file path of the domain socket (Unix) or name |       • {pipe_path}  (`string`) file path of the domain socket (Unix) or name | ||||||
| @@ -2112,8 +2116,6 @@ domain_socket_connect({pipe_path}) | |||||||
|  |  | ||||||
|     Return: ~ |     Return: ~ | ||||||
|         (`fun(dispatchers: vim.lsp.rpc.Dispatchers): vim.lsp.rpc.PublicClient`) |         (`fun(dispatchers: vim.lsp.rpc.Dispatchers): vim.lsp.rpc.PublicClient`) | ||||||
|         function intended to be passed to |vim.lsp.start_client()| or |  | ||||||
|         |vim.lsp.start()| on the field cmd |  | ||||||
|  |  | ||||||
| format_rpc_error({err})                       *vim.lsp.rpc.format_rpc_error()* | format_rpc_error({err})                       *vim.lsp.rpc.format_rpc_error()* | ||||||
|     Constructs an error message from an LSP error object. |     Constructs an error message from an LSP error object. | ||||||
| @@ -2122,7 +2124,7 @@ format_rpc_error({err})                       *vim.lsp.rpc.format_rpc_error()* | |||||||
|       • {err}  (`table`) The error object |       • {err}  (`table`) The error object | ||||||
|  |  | ||||||
|     Return: ~ |     Return: ~ | ||||||
|         (`string`) The formatted error message |         (`string`) error_message The formatted error message | ||||||
|  |  | ||||||
| notify({method}, {params})                              *vim.lsp.rpc.notify()* | notify({method}, {params})                              *vim.lsp.rpc.notify()* | ||||||
|     Sends a notification to the LSP server. |     Sends a notification to the LSP server. | ||||||
| @@ -2144,24 +2146,29 @@ request({method}, {params}, {callback}, {notify_reply_callback}) | |||||||
|                                  method |                                  method | ||||||
|       • {callback}               (`fun(err: lsp.ResponseError?, result: any)`) |       • {callback}               (`fun(err: lsp.ResponseError?, result: any)`) | ||||||
|                                  Callback to invoke |                                  Callback to invoke | ||||||
|       • {notify_reply_callback}  (`function?`) Callback to invoke as soon as a |       • {notify_reply_callback}  (`fun(message_id: integer)?`) Callback to | ||||||
|                                  request is no longer pending |                                  invoke as soon as a request is no longer | ||||||
|  |                                  pending | ||||||
|  |  | ||||||
|     Return: ~ |     Return (multiple): ~ | ||||||
|         (`boolean success, integer? request_id`) true, message_id if request |         (`boolean`) success `true` if request could be sent, `false` if not | ||||||
|         could be sent, `false` if not |         (`integer?`) message_id if request could be sent, `nil` if not | ||||||
|  |  | ||||||
|                                             *vim.lsp.rpc.rpc_response_error()* |                                             *vim.lsp.rpc.rpc_response_error()* | ||||||
| rpc_response_error({code}, {message}, {data}) | rpc_response_error({code}, {message}, {data}) | ||||||
|     Creates an RPC response object/table. |     Creates an RPC response table `error` to be sent to the LSP response. | ||||||
|  |  | ||||||
|     Parameters: ~ |     Parameters: ~ | ||||||
|       • {code}     (`integer`) RPC error code defined by JSON RPC |       • {code}     (`integer`) RPC error code defined, see | ||||||
|  |                    `vim.lsp.protocol.ErrorCodes` | ||||||
|       • {message}  (`string?`) arbitrary message to send to server |       • {message}  (`string?`) arbitrary message to send to server | ||||||
|       • {data}     (`any?`) arbitrary data to send to server |       • {data}     (`any?`) arbitrary data to send to server | ||||||
|  |  | ||||||
|     Return: ~ |     Return: ~ | ||||||
|         (`vim.lsp.rpc.Error`) |         (`lsp.ResponseError`) | ||||||
|  |  | ||||||
|  |     See also: ~ | ||||||
|  |       • lsp.ErrorCodes See `vim.lsp.protocol.ErrorCodes` | ||||||
|  |  | ||||||
|                                                          *vim.lsp.rpc.start()* |                                                          *vim.lsp.rpc.start()* | ||||||
| start({cmd}, {cmd_args}, {dispatchers}, {extra_spawn_params}) | start({cmd}, {cmd_args}, {dispatchers}, {extra_spawn_params}) | ||||||
| @@ -2174,14 +2181,14 @@ start({cmd}, {cmd_args}, {dispatchers}, {extra_spawn_params}) | |||||||
|       • {cmd}                 (`string`) Command to start the LSP server. |       • {cmd}                 (`string`) Command to start the LSP server. | ||||||
|       • {cmd_args}            (`string[]`) List of additional string arguments |       • {cmd_args}            (`string[]`) List of additional string arguments | ||||||
|                               to pass to {cmd}. |                               to pass to {cmd}. | ||||||
|       • {dispatchers}         (`table?`) Dispatchers for LSP message types. |       • {dispatchers}         (`vim.lsp.rpc.Dispatchers?`) Dispatchers for LSP | ||||||
|                               Valid dispatcher names are: |                               message types. Valid dispatcher names are: | ||||||
|                               • `"notification"` |                               • `"notification"` | ||||||
|                               • `"server_request"` |                               • `"server_request"` | ||||||
|                               • `"on_error"` |                               • `"on_error"` | ||||||
|                               • `"on_exit"` |                               • `"on_exit"` | ||||||
|       • {extra_spawn_params}  (`table?`) Additional context for the LSP server |       • {extra_spawn_params}  (`vim.lsp.rpc.ExtraSpawnParams?`) Additional | ||||||
|                               process. May contain: |                               context for the LSP server process. May contain: | ||||||
|                               • {cwd} (string) Working directory for the LSP |                               • {cwd} (string) Working directory for the LSP | ||||||
|                                 server process |                                 server process | ||||||
|                               • {detached?} (boolean) Detach the LSP server |                               • {detached?} (boolean) Detach the LSP server | ||||||
| @@ -2191,7 +2198,7 @@ start({cmd}, {cmd_args}, {dispatchers}, {extra_spawn_params}) | |||||||
|                                 variables for LSP server process |                                 variables for LSP server process | ||||||
|  |  | ||||||
|     Return: ~ |     Return: ~ | ||||||
|         (`table?`) client RPC object, with these methods: |         (`vim.lsp.rpc.PublicClient?`) Client RPC object, with these methods: | ||||||
|         • `notify()` |vim.lsp.rpc.notify()| |         • `notify()` |vim.lsp.rpc.notify()| | ||||||
|         • `request()` |vim.lsp.rpc.request()| |         • `request()` |vim.lsp.rpc.request()| | ||||||
|         • `is_closing()` returns a boolean indicating if the RPC is closing. |         • `is_closing()` returns a boolean indicating if the RPC is closing. | ||||||
|   | |||||||
| @@ -61,7 +61,7 @@ end | |||||||
| --- @field wait fun(self: vim.SystemObj, timeout?: integer): vim.SystemCompleted | --- @field wait fun(self: vim.SystemObj, timeout?: integer): vim.SystemCompleted | ||||||
| --- @field kill fun(self: vim.SystemObj, signal: integer|string) | --- @field kill fun(self: vim.SystemObj, signal: integer|string) | ||||||
| --- @field write fun(self: vim.SystemObj, data?: string|string[]) | --- @field write fun(self: vim.SystemObj, data?: string|string[]) | ||||||
| --- @field is_closing fun(self: vim.SystemObj): boolean? | --- @field is_closing fun(self: vim.SystemObj): boolean | ||||||
| local SystemObj = {} | local SystemObj = {} | ||||||
|  |  | ||||||
| --- @param state vim.SystemState | --- @param state vim.SystemState | ||||||
| @@ -140,7 +140,7 @@ end | |||||||
| --- @return boolean | --- @return boolean | ||||||
| function SystemObj:is_closing() | function SystemObj:is_closing() | ||||||
|   local handle = self._state.handle |   local handle = self._state.handle | ||||||
|   return handle == nil or handle:is_closing() |   return handle == nil or handle:is_closing() or false | ||||||
| end | end | ||||||
|  |  | ||||||
| ---@param output fun(err:string?, data: string?)|false | ---@param output fun(err:string?, data: string?)|false | ||||||
|   | |||||||
| @@ -258,7 +258,7 @@ end | |||||||
| --- Validates a client configuration as given to |vim.lsp.start_client()|. | --- Validates a client configuration as given to |vim.lsp.start_client()|. | ||||||
| --- | --- | ||||||
| ---@param config (lsp.ClientConfig) | ---@param config (lsp.ClientConfig) | ||||||
| ---@return (string|fun(dispatchers:vim.rpc.Dispatchers):RpcClientPublic?) Command | ---@return (string|fun(dispatchers:vim.rpc.Dispatchers):vim.lsp.rpc.PublicClient?) Command | ||||||
| ---@return string[] Arguments | ---@return string[] Arguments | ||||||
| ---@return string Encoding. | ---@return string Encoding. | ||||||
| local function validate_client_config(config) | local function validate_client_config(config) | ||||||
| @@ -291,7 +291,7 @@ local function validate_client_config(config) | |||||||
|     'flags.debounce_text_changes must be a number with the debounce time in milliseconds' |     'flags.debounce_text_changes must be a number with the debounce time in milliseconds' | ||||||
|   ) |   ) | ||||||
|  |  | ||||||
|   local cmd, cmd_args --- @type (string|fun(dispatchers:vim.rpc.Dispatchers):RpcClientPublic), string[] |   local cmd, cmd_args --- @type (string|fun(dispatchers:vim.rpc.Dispatchers):vim.lsp.rpc.PublicClient), string[] | ||||||
|   local config_cmd = config.cmd |   local config_cmd = config.cmd | ||||||
|   if type(config_cmd) == 'function' then |   if type(config_cmd) == 'function' then | ||||||
|     cmd = config_cmd |     cmd = config_cmd | ||||||
| @@ -826,6 +826,8 @@ function lsp.start_client(config) | |||||||
|   --- |   --- | ||||||
|   ---@param method (string) LSP method name |   ---@param method (string) LSP method name | ||||||
|   ---@param params (table) The parameters for that method |   ---@param params (table) The parameters for that method | ||||||
|  |   ---@return any result | ||||||
|  |   ---@return lsp.ResponseError error code and message set in case an exception happens during the request. | ||||||
|   function dispatch.server_request(method, params) |   function dispatch.server_request(method, params) | ||||||
|     if log.trace() then |     if log.trace() then | ||||||
|       log.trace('server_request', method, params) |       log.trace('server_request', method, params) | ||||||
| @@ -953,7 +955,7 @@ function lsp.start_client(config) | |||||||
|   end |   end | ||||||
|  |  | ||||||
|   -- Start the RPC client. |   -- Start the RPC client. | ||||||
|   local rpc --- @type RpcClientPublic? |   local rpc --- @type vim.lsp.rpc.PublicClient? | ||||||
|   if type(cmd) == 'function' then |   if type(cmd) == 'function' then | ||||||
|     rpc = cmd(dispatch) |     rpc = cmd(dispatch) | ||||||
|   else |   else | ||||||
|   | |||||||
| @@ -5,29 +5,6 @@ local validate, schedule, schedule_wrap = vim.validate, vim.schedule, vim.schedu | |||||||
|  |  | ||||||
| local is_win = uv.os_uname().version:find('Windows') | local is_win = uv.os_uname().version:find('Windows') | ||||||
|  |  | ||||||
| ---@alias vim.lsp.rpc.Dispatcher fun(method: string, params: table<string, any>):nil, vim.lsp.rpc.Error? |  | ||||||
| ---@alias vim.lsp.rpc.on_error fun(code: integer, ...: any) |  | ||||||
| ---@alias vim.lsp.rpc.on_exit fun(code: integer, signal: integer) |  | ||||||
|  |  | ||||||
| ---@class vim.lsp.rpc.Dispatchers |  | ||||||
| ---@field notification vim.lsp.rpc.Dispatcher |  | ||||||
| ---@field server_request vim.lsp.rpc.Dispatcher |  | ||||||
| ---@field on_exit vim.lsp.rpc.on_error |  | ||||||
| ---@field on_error vim.lsp.rpc.on_exit |  | ||||||
|  |  | ||||||
| ---@class vim.lsp.rpc.PublicClient |  | ||||||
| ---@field request fun(method: string, params?: table, callback: fun(err: lsp.ResponseError | nil, result: any), notify_reply_callback:function?) |  | ||||||
| ---@field notify fun(method: string, params: any) |  | ||||||
| ---@field is_closing fun(): boolean |  | ||||||
| ---@field terminate fun(): nil |  | ||||||
|  |  | ||||||
| ---@class vim.lsp.rpc.Client |  | ||||||
| ---@field message_index integer |  | ||||||
| ---@field message_callbacks table<integer, function> dict of message_id to callback |  | ||||||
| ---@field notify_reply_callbacks table<integer, function> dict of message_id to callback |  | ||||||
| ---@field transport vim.lsp.rpc.Transport |  | ||||||
| ---@field dispatchers vim.lsp.rpc.Dispatchers |  | ||||||
|  |  | ||||||
| --- Checks whether a given path exists and is a directory. | --- Checks whether a given path exists and is a directory. | ||||||
| ---@param filename string path to check | ---@param filename string path to check | ||||||
| ---@return boolean | ---@return boolean | ||||||
| @@ -186,7 +163,7 @@ M.client_errors = vim.tbl_add_reverse_lookup(M.client_errors) | |||||||
| --- Constructs an error message from an LSP error object. | --- Constructs an error message from an LSP error object. | ||||||
| --- | --- | ||||||
| ---@param err table The error object | ---@param err table The error object | ||||||
| ---@return string#The formatted error message | ---@return string error_message The formatted error message | ||||||
| function M.format_rpc_error(err) | function M.format_rpc_error(err) | ||||||
|   validate({ |   validate({ | ||||||
|     err = { err, 't' }, |     err = { err, 't' }, | ||||||
| @@ -213,17 +190,14 @@ function M.format_rpc_error(err) | |||||||
|   return table.concat(message_parts, ' ') |   return table.concat(message_parts, ' ') | ||||||
| end | end | ||||||
|  |  | ||||||
| ---@class vim.lsp.rpc.Error | --- Creates an RPC response table `error` to be sent to the LSP response. | ||||||
| ---@field code integer RPC error code defined by JSON RPC, see `vim.lsp.protocol.ErrorCodes` |  | ||||||
| ---@field message? string arbitrary message to send to server |  | ||||||
| ---@field data? any arbitrary data to send to server |  | ||||||
|  |  | ||||||
| --- Creates an RPC response object/table. |  | ||||||
| --- | --- | ||||||
| ---@param code integer RPC error code defined by JSON RPC | ---@param code integer RPC error code defined, see `vim.lsp.protocol.ErrorCodes` | ||||||
| ---@param message? string arbitrary message to send to server | ---@param message? string arbitrary message to send to server | ||||||
| ---@param data? any arbitrary data to send to server | ---@param data? any arbitrary data to send to server | ||||||
| ---@return vim.lsp.rpc.Error | --- | ||||||
|  | ---@see lsp.ErrorCodes See `vim.lsp.protocol.ErrorCodes` | ||||||
|  | ---@return lsp.ResponseError | ||||||
| function M.rpc_response_error(code, message, data) | function M.rpc_response_error(code, message, data) | ||||||
|   -- TODO should this error or just pick a sane error (like InternalError)? |   -- TODO should this error or just pick a sane error (like InternalError)? | ||||||
|   ---@type string |   ---@type string | ||||||
| @@ -237,28 +211,28 @@ function M.rpc_response_error(code, message, data) | |||||||
|   }) |   }) | ||||||
| end | end | ||||||
|  |  | ||||||
| --- @class vim.rpc.Dispatchers | --- @class vim.lsp.rpc.Dispatchers | ||||||
| --- @field notification fun(method: string, params: table) | --- @field notification fun(method: string, params: table) | ||||||
| --- @field server_request fun(method: string, params: table): any?, string? | --- @field server_request fun(method: string, params: table): any?, lsp.ResponseError? | ||||||
| --- @field on_exit fun(code: integer, signal: integer) | --- @field on_exit fun(code: integer, signal: integer) | ||||||
| --- @field on_error fun(code: integer, err: any) | --- @field on_error fun(code: integer, err: any) | ||||||
|  |  | ||||||
| --- @type vim.rpc.Dispatchers | --- @type vim.lsp.rpc.Dispatchers | ||||||
| local default_dispatchers = { | local default_dispatchers = { | ||||||
|   --- Default dispatcher for notifications sent to an LSP server. |   --- Default dispatcher for notifications sent to an LSP server. | ||||||
|   --- |   --- | ||||||
|   ---@param method (string) The invoked LSP method |   ---@param method string The invoked LSP method | ||||||
|   ---@param params (table) Parameters for the invoked LSP method |   ---@param params table Parameters for the invoked LSP method | ||||||
|   notification = function(method, params) |   notification = function(method, params) | ||||||
|     log_debug('notification', method, params) |     log_debug('notification', method, params) | ||||||
|   end, |   end, | ||||||
|  |  | ||||||
|   --- Default dispatcher for requests sent to an LSP server. |   --- Default dispatcher for requests sent to an LSP server. | ||||||
|   --- |   --- | ||||||
|   ---@param method (string) The invoked LSP method |   ---@param method string The invoked LSP method | ||||||
|   ---@param params (table) Parameters for the invoked LSP method |   ---@param params table Parameters for the invoked LSP method | ||||||
|   ---@return nil |   ---@return any result (always nil for the default dispatchers) | ||||||
|   ---@return vim.lsp.rpc.Error#`vim.lsp.protocol.ErrorCodes.MethodNotFound` |   ---@return lsp.ResponseError error `vim.lsp.protocol.ErrorCodes.MethodNotFound` | ||||||
|   server_request = function(method, params) |   server_request = function(method, params) | ||||||
|     log_debug('server_request', method, params) |     log_debug('server_request', method, params) | ||||||
|     return nil, M.rpc_response_error(protocol.ErrorCodes.MethodNotFound) |     return nil, M.rpc_response_error(protocol.ErrorCodes.MethodNotFound) | ||||||
| @@ -266,25 +240,21 @@ local default_dispatchers = { | |||||||
|  |  | ||||||
|   --- Default dispatcher for when a client exits. |   --- Default dispatcher for when a client exits. | ||||||
|   --- |   --- | ||||||
|   ---@param code (integer) Exit code |   ---@param code integer Exit code | ||||||
|   ---@param signal (integer) Number describing the signal used to terminate (if |   ---@param signal integer Number describing the signal used to terminate (if any) | ||||||
|   ---any) |  | ||||||
|   on_exit = function(code, signal) |   on_exit = function(code, signal) | ||||||
|     log_info('client_exit', { code = code, signal = signal }) |     log_info('client_exit', { code = code, signal = signal }) | ||||||
|   end, |   end, | ||||||
|  |  | ||||||
|   --- Default dispatcher for client errors. |   --- Default dispatcher for client errors. | ||||||
|   --- |   --- | ||||||
|   ---@param code (integer) Error code |   ---@param code integer Error code | ||||||
|   ---@param err (any) Details about the error |   ---@param err any Details about the error | ||||||
|   ---any) |  | ||||||
|   on_error = function(code, err) |   on_error = function(code, err) | ||||||
|     log_error('client_error:', M.client_errors[code], err) |     log_error('client_error:', M.client_errors[code], err) | ||||||
|   end, |   end, | ||||||
| } | } | ||||||
|  |  | ||||||
| ---@cast default_dispatchers vim.lsp.rpc.Dispatchers |  | ||||||
|  |  | ||||||
| ---@private | ---@private | ||||||
| function M.create_read_loop(handle_body, on_no_chunk, on_error) | function M.create_read_loop(handle_body, on_no_chunk, on_error) | ||||||
|   local parse_chunk = coroutine.wrap(request_parser_loop) --[[@as fun(chunk: string?): vim.lsp.rpc.Headers?, string?]] |   local parse_chunk = coroutine.wrap(request_parser_loop) --[[@as fun(chunk: string?): vim.lsp.rpc.Headers?, string?]] | ||||||
| @@ -314,6 +284,14 @@ function M.create_read_loop(handle_body, on_no_chunk, on_error) | |||||||
|   end |   end | ||||||
| end | end | ||||||
|  |  | ||||||
|  | ---@private | ||||||
|  | ---@class vim.lsp.rpc.Client | ||||||
|  | ---@field message_index integer | ||||||
|  | ---@field message_callbacks table<integer, function> dict of message_id to callback | ||||||
|  | ---@field notify_reply_callbacks table<integer, function> dict of message_id to callback | ||||||
|  | ---@field transport vim.lsp.rpc.Transport | ||||||
|  | ---@field dispatchers vim.lsp.rpc.Dispatchers | ||||||
|  |  | ||||||
| ---@class vim.lsp.rpc.Client | ---@class vim.lsp.rpc.Client | ||||||
| local Client = {} | local Client = {} | ||||||
|  |  | ||||||
| @@ -356,13 +334,14 @@ function Client:send_response(request_id, err, result) | |||||||
| end | end | ||||||
|  |  | ||||||
| ---@package | ---@package | ||||||
| --- Sends a request to the LSP server and runs {callback} upon response. | --- Sends a request to the LSP server and runs {callback} upon response. |vim.lsp.rpc.request()| | ||||||
| --- | --- | ||||||
| ---@param method string The invoked LSP method | ---@param method string The invoked LSP method | ||||||
| ---@param params? table Parameters for the invoked LSP method | ---@param params table? Parameters for the invoked LSP method | ||||||
| ---@param callback fun(err?: lsp.ResponseError, result: any) Callback to invoke | ---@param callback fun(err?: lsp.ResponseError, result: any) Callback to invoke | ||||||
| ---@param notify_reply_callback? function Callback to invoke as soon as a request is no longer pending | ---@param notify_reply_callback fun(message_id: integer)|nil Callback to invoke as soon as a request is no longer pending | ||||||
| ---@return boolean success, integer|nil request_id true, request_id if request could be sent, `false` if not | ---@return boolean success `true` if request could be sent, `false` if not | ||||||
|  | ---@return integer? message_id if request could be sent, `nil` if not | ||||||
| function Client:request(method, params, callback, notify_reply_callback) | function Client:request(method, params, callback, notify_reply_callback) | ||||||
|   validate({ |   validate({ | ||||||
|     callback = { callback, 'f' }, |     callback = { callback, 'f' }, | ||||||
| @@ -382,14 +361,14 @@ function Client:request(method, params, callback, notify_reply_callback) | |||||||
|     if message_callbacks then |     if message_callbacks then | ||||||
|       message_callbacks[message_id] = schedule_wrap(callback) |       message_callbacks[message_id] = schedule_wrap(callback) | ||||||
|     else |     else | ||||||
|       return false |       return false, nil | ||||||
|     end |     end | ||||||
|     if notify_reply_callback and notify_reply_callbacks then |     if notify_reply_callback and notify_reply_callbacks then | ||||||
|       notify_reply_callbacks[message_id] = schedule_wrap(notify_reply_callback) |       notify_reply_callbacks[message_id] = schedule_wrap(notify_reply_callback) | ||||||
|     end |     end | ||||||
|     return result, message_id |     return result, message_id | ||||||
|   else |   else | ||||||
|     return false |     return false, nil | ||||||
|   end |   end | ||||||
| end | end | ||||||
|  |  | ||||||
| @@ -443,7 +422,7 @@ function Client:handle_body(body) | |||||||
|   log_debug('rpc.receive', decoded) |   log_debug('rpc.receive', decoded) | ||||||
|  |  | ||||||
|   if type(decoded.method) == 'string' and decoded.id then |   if type(decoded.method) == 'string' and decoded.id then | ||||||
|     local err --- @type vim.lsp.rpc.Error? |     local err --- @type lsp.ResponseError|nil | ||||||
|     -- Schedule here so that the users functions don't trigger an error and |     -- Schedule here so that the users functions don't trigger an error and | ||||||
|     -- we can still use the result. |     -- we can still use the result. | ||||||
|     schedule(function() |     schedule(function() | ||||||
| @@ -469,7 +448,7 @@ function Client:handle_body(body) | |||||||
|             ) |             ) | ||||||
|           end |           end | ||||||
|           if err then |           if err then | ||||||
|             ---@cast err vim.lsp.rpc.Error |             ---@cast err lsp.ResponseError | ||||||
|             assert( |             assert( | ||||||
|               type(err) == 'table', |               type(err) == 'table', | ||||||
|               'err must be a table. Use rpc_response_error to help format errors.' |               'err must be a table. Use rpc_response_error to help format errors.' | ||||||
| @@ -564,9 +543,9 @@ function Client:handle_body(body) | |||||||
| end | end | ||||||
|  |  | ||||||
| ---@class vim.lsp.rpc.Transport | ---@class vim.lsp.rpc.Transport | ||||||
| ---@field write fun(msg: string): nil | ---@field write fun(msg: string) | ||||||
| ---@field is_closing fun(): boolean|nil | ---@field is_closing fun(): boolean | ||||||
| ---@field terminate fun(): nil | ---@field terminate fun() | ||||||
|  |  | ||||||
| ---@param dispatchers vim.lsp.rpc.Dispatchers | ---@param dispatchers vim.lsp.rpc.Dispatchers | ||||||
| ---@param transport vim.lsp.rpc.Transport | ---@param transport vim.lsp.rpc.Transport | ||||||
| @@ -582,9 +561,17 @@ local function new_client(dispatchers, transport) | |||||||
|   return setmetatable(state, { __index = Client }) |   return setmetatable(state, { __index = Client }) | ||||||
| end | end | ||||||
|  |  | ||||||
|  | ---@class vim.lsp.rpc.PublicClient | ||||||
|  | ---@field request fun(method: string, params: table?, callback: fun(err: lsp.ResponseError|nil, result: any), notify_reply_callback: fun(integer)|nil):boolean,integer? see |vim.lsp.rpc.request()| | ||||||
|  | ---@field notify fun(method: string, params: any):boolean see |vim.lsp.rpc.notify()| | ||||||
|  | ---@field is_closing fun(): boolean | ||||||
|  | ---@field terminate fun() | ||||||
|  |  | ||||||
| ---@param client vim.lsp.rpc.Client | ---@param client vim.lsp.rpc.Client | ||||||
| ---@return vim.lsp.rpc.PublicClient | ---@return vim.lsp.rpc.PublicClient | ||||||
| local function public_client(client) | local function public_client(client) | ||||||
|  |   ---@type vim.lsp.rpc.PublicClient | ||||||
|  |   ---@diagnostic disable-next-line: missing-fields | ||||||
|   local result = {} |   local result = {} | ||||||
|  |  | ||||||
|   ---@private |   ---@private | ||||||
| @@ -601,9 +588,10 @@ local function public_client(client) | |||||||
|   --- |   --- | ||||||
|   ---@param method (string) The invoked LSP method |   ---@param method (string) The invoked LSP method | ||||||
|   ---@param params (table?) Parameters for the invoked LSP method |   ---@param params (table?) Parameters for the invoked LSP method | ||||||
|   ---@param callback fun(err: lsp.ResponseError | nil, result: any) Callback to invoke |   ---@param callback fun(err: lsp.ResponseError|nil, result: any) Callback to invoke | ||||||
|   ---@param notify_reply_callback (function?) Callback to invoke as soon as a request is no longer pending |   ---@param notify_reply_callback fun(message_id: integer)|nil Callback to invoke as soon as a request is no longer pending | ||||||
|   ---@return boolean success, integer|nil request_id true, message_id if request could be sent, `false` if not |   ---@return boolean success `true` if request could be sent, `false` if not | ||||||
|  |   ---@return integer? message_id if request could be sent, `nil` if not | ||||||
|   function result.request(method, params, callback, notify_reply_callback) |   function result.request(method, params, callback, notify_reply_callback) | ||||||
|     return client:request(method, params, callback, notify_reply_callback) |     return client:request(method, params, callback, notify_reply_callback) | ||||||
|   end |   end | ||||||
| @@ -619,7 +607,7 @@ local function public_client(client) | |||||||
|   return result |   return result | ||||||
| end | end | ||||||
|  |  | ||||||
| ---@param dispatchers? vim.lsp.rpc.Dispatchers | ---@param dispatchers vim.lsp.rpc.Dispatchers? | ||||||
| ---@return vim.lsp.rpc.Dispatchers | ---@return vim.lsp.rpc.Dispatchers | ||||||
| local function merge_dispatchers(dispatchers) | local function merge_dispatchers(dispatchers) | ||||||
|   if not dispatchers then |   if not dispatchers then | ||||||
| @@ -631,23 +619,30 @@ local function merge_dispatchers(dispatchers) | |||||||
|       error(string.format('dispatcher.%s must be a function', name)) |       error(string.format('dispatcher.%s must be a function', name)) | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
|   return { |   ---@type vim.lsp.rpc.Dispatchers | ||||||
|     notification = dispatchers.notification and vim.schedule_wrap(dispatchers.notification) |   local merged = { | ||||||
|       or default_dispatchers.notification, |     notification = ( | ||||||
|     on_error = dispatchers.on_error and vim.schedule_wrap(dispatchers.on_error) |       dispatchers.notification and vim.schedule_wrap(dispatchers.notification) | ||||||
|       or default_dispatchers.on_error, |       or default_dispatchers.notification | ||||||
|  |     ), | ||||||
|  |     on_error = ( | ||||||
|  |       dispatchers.on_error and vim.schedule_wrap(dispatchers.on_error) | ||||||
|  |       or default_dispatchers.on_error | ||||||
|  |     ), | ||||||
|     on_exit = dispatchers.on_exit or default_dispatchers.on_exit, |     on_exit = dispatchers.on_exit or default_dispatchers.on_exit, | ||||||
|     server_request = dispatchers.server_request or default_dispatchers.server_request, |     server_request = dispatchers.server_request or default_dispatchers.server_request, | ||||||
|   } |   } | ||||||
|  |   return merged | ||||||
| end | end | ||||||
|  |  | ||||||
| --- Create a LSP RPC client factory that connects via TCP to the given host | --- Create a LSP RPC client factory that connects via TCP to the given host and port. | ||||||
| --- and port | --- | ||||||
|  | --- Return a function that can be passed to the `cmd` field for | ||||||
|  | --- |vim.lsp.start_client()| or |vim.lsp.start()|. | ||||||
| --- | --- | ||||||
| ---@param host string host to connect to | ---@param host string host to connect to | ||||||
| ---@param port integer port to connect to | ---@param port integer port to connect to | ||||||
| ---@return fun(dispatchers: vim.lsp.rpc.Dispatchers): vim.lsp.rpc.PublicClient # function intended to be passed to |vim.lsp.start_client()| or |vim.lsp.start()| on the field cmd | ---@return fun(dispatchers: vim.lsp.rpc.Dispatchers): vim.lsp.rpc.PublicClient | ||||||
| function M.connect(host, port) | function M.connect(host, port) | ||||||
|   return function(dispatchers) |   return function(dispatchers) | ||||||
|     dispatchers = merge_dispatchers(dispatchers) |     dispatchers = merge_dispatchers(dispatchers) | ||||||
| @@ -694,10 +689,13 @@ end | |||||||
|  |  | ||||||
| --- Create a LSP RPC client factory that connects via named pipes (Windows) | --- Create a LSP RPC client factory that connects via named pipes (Windows) | ||||||
| --- or unix domain sockets (Unix) to the given pipe_path (file path on | --- or unix domain sockets (Unix) to the given pipe_path (file path on | ||||||
| --- Unix and name on Windows) | --- Unix and name on Windows). | ||||||
|  | --- | ||||||
|  | --- Return a function that can be passed to the `cmd` field for | ||||||
|  | --- |vim.lsp.start_client()| or |vim.lsp.start()|. | ||||||
| --- | --- | ||||||
| ---@param pipe_path string file path of the domain socket (Unix) or name of the named pipe (Windows) to connect to | ---@param pipe_path string file path of the domain socket (Unix) or name of the named pipe (Windows) to connect to | ||||||
| ---@return fun(dispatchers: vim.lsp.rpc.Dispatchers): vim.lsp.rpc.PublicClient#function intended to be passed to |vim.lsp.start_client()| or |vim.lsp.start()| on the field cmd | ---@return fun(dispatchers: vim.lsp.rpc.Dispatchers): vim.lsp.rpc.PublicClient | ||||||
| function M.domain_socket_connect(pipe_path) | function M.domain_socket_connect(pipe_path) | ||||||
|   return function(dispatchers) |   return function(dispatchers) | ||||||
|     dispatchers = merge_dispatchers(dispatchers) |     dispatchers = merge_dispatchers(dispatchers) | ||||||
| @@ -755,19 +753,21 @@ end | |||||||
| ---@param cmd string Command to start the LSP server. | ---@param cmd string Command to start the LSP server. | ||||||
| ---@param cmd_args string[] List of additional string arguments to pass to {cmd}. | ---@param cmd_args string[] List of additional string arguments to pass to {cmd}. | ||||||
| --- | --- | ||||||
| ---@param dispatchers? vim.lsp.rpc.Dispatchers (table|nil) Dispatchers for LSP message types. | ---@param dispatchers? vim.lsp.rpc.Dispatchers Dispatchers for LSP message types. | ||||||
| --- Valid dispatcher names are: | --- Valid dispatcher names are: | ||||||
| ---  - `"notification"` | ---  - `"notification"` | ||||||
| ---  - `"server_request"` | ---  - `"server_request"` | ||||||
| ---  - `"on_error"` | ---  - `"on_error"` | ||||||
| ---  - `"on_exit"` | ---  - `"on_exit"` | ||||||
| --- | --- | ||||||
| ---@param extra_spawn_params? vim.lsp.rpc.ExtraSpawnParams (table|nil) Additional context for the LSP | ---@param extra_spawn_params? vim.lsp.rpc.ExtraSpawnParams Additional context for the LSP | ||||||
| --- server process. May contain: | --- server process. May contain: | ||||||
| ---   - {cwd} (string) Working directory for the LSP server process | ---   - {cwd} (string) Working directory for the LSP server process | ||||||
| --- - {detached?} (boolean) Detach the LSP server process from the current process. Defaults to false on Windows and true otherwise. | ---   - {detached?} (boolean) Detach the LSP server process from the current process. | ||||||
|  | ---                  Defaults to false on Windows and true otherwise. | ||||||
| ---   - {env?} (table) Additional environment variables for LSP server process | ---   - {env?} (table) Additional environment variables for LSP server process | ||||||
| ---@return vim.lsp.rpc.PublicClient? (table|nil) client RPC object, with these methods: | --- | ||||||
|  | ---@return vim.lsp.rpc.PublicClient? Client RPC object, with these methods: | ||||||
| ---   - `notify()` |vim.lsp.rpc.notify()| | ---   - `notify()` |vim.lsp.rpc.notify()| | ||||||
| ---   - `request()` |vim.lsp.rpc.request()| | ---   - `request()` |vim.lsp.rpc.request()| | ||||||
| ---   - `is_closing()` returns a boolean indicating if the RPC is closing. | ---   - `is_closing()` returns a boolean indicating if the RPC is closing. | ||||||
| @@ -846,7 +846,7 @@ function M.start(cmd, cmd_args, dispatchers, extra_spawn_params) | |||||||
|     end |     end | ||||||
|     local msg = string.format('Spawning language server with cmd: `%s` failed%s', cmd, sfx) |     local msg = string.format('Spawning language server with cmd: `%s` failed%s', cmd, sfx) | ||||||
|     vim.notify(msg, vim.log.levels.WARN) |     vim.notify(msg, vim.log.levels.WARN) | ||||||
|     return |     return nil | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   sysobj = sysobj_or_err --[[@as vim.SystemObj]] |   sysobj = sysobj_or_err --[[@as vim.SystemObj]] | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user