- nvim requires rpc responses in reverse order. https://github.com/neovim/neovim/issues/19932
- NVIM_APPNAME: UIs normally should NOT set this.

ref #23520
fix #24050
fix #23660
fix #23353
fix #23337
fix #22213
fix #19161
fix #18088
fix #20693
This commit is contained in:
Justin M. Keyes 2023-06-19 08:40:33 -07:00 committed by GitHub
parent 91f57723ad
commit 72a6643b13
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 104 additions and 98 deletions

View File

@ -17,8 +17,15 @@ Applications can also embed libnvim to work with the C API directly.
API Usage *api-rpc* *RPC* *rpc* API Usage *api-rpc* *RPC* *rpc*
*msgpack-rpc* *msgpack-rpc*
RPC is the typical way to control Nvim programmatically. Nvim implements the RPC is the main way to control Nvim programmatically. Nvim implements the
MessagePack-RPC protocol: MessagePack-RPC protocol with these extra (out-of-spec) constraints:
1. Responses must be given in reverse order of requests (like "unwinding
a stack").
2. Nvim processes all messages (requests and notifications) in the order they
are received.
MessagePack-RPC specification:
https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md
https://github.com/msgpack/msgpack/blob/0b8f5ac/spec.md https://github.com/msgpack/msgpack/blob/0b8f5ac/spec.md

View File

@ -8842,10 +8842,13 @@ termopen({cmd} [, {opts}]) *termopen()*
to the current (unmodified) buffer. Parameters and behavior to the current (unmodified) buffer. Parameters and behavior
are the same as |jobstart()| except "pty", "width", "height", are the same as |jobstart()| except "pty", "width", "height",
and "TERM" are ignored: "height" and "width" are taken from and "TERM" are ignored: "height" and "width" are taken from
the current window. the current window. Note that termopen() implies a "pty" arg
Returns the same values as |jobstart()|. to jobstart(), and thus has the implications documented at
|jobstart()|.
Terminal environment is initialized as in ||jobstart-env|, Returns the same values as jobstart().
Terminal environment is initialized as in |jobstart-env|,
except $TERM is set to "xterm-256color". Full behavior is except $TERM is set to "xterm-256color". Full behavior is
described in |terminal|. described in |terminal|.

View File

@ -151,7 +151,7 @@ from the host TTY, or if Nvim is |--headless| it uses default values: >vim
When channels are opened with the `rpc` option set to true, the channel can be When channels are opened with the `rpc` option set to true, the channel can be
used for remote method calls in both directions, see |msgpack-rpc|. Note that used for remote method calls in both directions, see |msgpack-rpc|. Note that
rpc channels are implicitly trusted and the process at the other end can rpc channels are implicitly trusted and the process at the other end can
invoke any |api| function! invoke any |API| function!
============================================================================== ==============================================================================
4. Standard IO channel *channel-stdio* 4. Standard IO channel *channel-stdio*

View File

@ -117,6 +117,13 @@ internally and are no longer exposed as part of the API. Instead, use
- *vim.lsp.diagnostic.set_virtual_text()* - *vim.lsp.diagnostic.set_virtual_text()*
LSP FUNCTIONS LSP FUNCTIONS
- *vim.lsp.buf.server_ready()*
Use |LspAttach| instead, depending on your use-case. "Server ready" is not
part of the LSP spec, so the Nvim LSP client cannot meaningfully implement
it. "Ready" is ambiguous because:
- Language servers may finish analyzing the workspace, but edits can always
re-trigger analysis/builds.
- Language servers can serve some requests even while processing changes.
- *vim.lsp.buf.range_code_action()* Use |vim.lsp.buf.code_action()| with - *vim.lsp.buf.range_code_action()* Use |vim.lsp.buf.code_action()| with
the `range` parameter. the `range` parameter.
- *vim.lsp.util.diagnostics_to_items()* Use |vim.diagnostic.toqflist()| instead. - *vim.lsp.util.diagnostics_to_items()* Use |vim.diagnostic.toqflist()| instead.

View File

@ -478,6 +478,8 @@ External UIs are expected to implement these common features:
- Consider the "option_set" |ui-global| event as a hint for other GUI - Consider the "option_set" |ui-global| event as a hint for other GUI
behaviors. Various UI-related options ('guifont', 'ambiwidth', …) are behaviors. Various UI-related options ('guifont', 'ambiwidth', …) are
published in this event. See also "mouse_on", "mouse_off". published in this event. See also "mouse_on", "mouse_off".
- UIs generally should NOT set |$NVIM_APPNAME| (unless explicitly requested by
the user).
vim:tw=78:ts=8:sw=4:et:ft=help:norl: vim:tw=78:ts=8:sw=4:et:ft=help:norl:

View File

@ -207,10 +207,10 @@ specification. These LSP requests/notifications are defined by default:
*lsp-handler* *lsp-handler*
lsp-handlers are functions with special signatures that are designed to handle LSP handlers are functions with signatures designed to handle LSP responses
responses and notifications from LSP servers. and notifications.
For |lsp-request|, each |lsp-handler| has this signature: > For |lsp-response|, each |lsp-handler| has this signature: >
function(err, result, ctx, config) function(err, result, ctx, config)
< <
@ -363,42 +363,37 @@ To configure the behavior of a builtin |lsp-handler|, the convenient method
Handlers can be set by: Handlers can be set by:
- Setting a field in vim.lsp.handlers. *vim.lsp.handlers* - Setting a field in vim.lsp.handlers. *vim.lsp.handlers*
vim.lsp.handlers is a global table that contains the default mapping of vim.lsp.handlers is a global table that contains the default mapping of
|lsp-method| names to |lsp-handlers|. |lsp-method| names to |lsp-handlers|. To override the handler for the
`"textDocument/definition"` method: >lua
To override the handler for the `"textDocument/definition"` method: >lua
vim.lsp.handlers["textDocument/definition"] = my_custom_default_definition vim.lsp.handlers["textDocument/definition"] = my_custom_default_definition
< <
- The {handlers} parameter for |vim.lsp.start_client()|. - The {handlers} parameter of |vim.lsp.start()|. This sets the default
This will set the |lsp-handler| as the default handler for this server. |lsp-handler| for the server being started. Example: >lua
For example: >lua vim.lsp.start {
vim.lsp.start_client {
..., -- Other configuration omitted. ..., -- Other configuration omitted.
handlers = { handlers = {
["textDocument/definition"] = my_custom_server_definition ["textDocument/definition"] = my_custom_server_definition
}, },
} }
- The {handler} parameter for |vim.lsp.buf_request()|. - The {handler} parameter of |vim.lsp.buf_request_all()|. This sets
This will set the |lsp-handler| ONLY for the current request. the |lsp-handler| ONLY for the given request(s). Example: >lua
For example: >lua vim.lsp.buf_request_all(
vim.lsp.buf_request(
0, 0,
"textDocument/definition", "textDocument/definition",
definition_params, my_request_params,
my_request_custom_definition my_handler
) )
< <
In summary, the |lsp-handler| will be chosen based on the current |lsp-method| In summary, the |lsp-handler| will be chosen based on the current |lsp-method|
in the following order: in the following order:
1. Handler passed to |vim.lsp.buf_request()|, if any. 1. Handler passed to |vim.lsp.buf_request_all()|, if any.
2. Handler defined in |vim.lsp.start_client()|, if any. 2. Handler defined in |vim.lsp.start()|, if any.
3. Handler defined in |vim.lsp.handlers|, if any. 3. Handler defined in |vim.lsp.handlers|, if any.
*vim.lsp.log_levels* *vim.lsp.log_levels*
@ -709,31 +704,27 @@ buf_notify({bufnr}, {method}, {params}) *vim.lsp.buf_notify()*
(boolean) success true if any client returns true; false otherwise (boolean) success true if any client returns true; false otherwise
*vim.lsp.buf_request_all()* *vim.lsp.buf_request_all()*
buf_request_all({bufnr}, {method}, {params}, {callback}) buf_request_all({bufnr}, {method}, {params}, {handler})
Sends an async request for all active clients attached to the buffer. Sends an async request for all active clients attached to the buffer and
Executes the callback on the combined result. Parameters are the same as executes the `handler` callback with the combined result.
|vim.lsp.buf_request()| but the return result and callback are different.
Parameters: ~ Parameters: ~
• {bufnr} (integer) Buffer handle, or 0 for current. • {bufnr} (integer) Buffer handle, or 0 for current.
• {method} (string) LSP method name • {method} (string) LSP method name
• {params} (table|nil) Parameters to send to the server • {params} (table|nil) Parameters to send to the server
• {callback} (function) The callback to call when all requests are • {handler} (function) Handler called after all requests are completed.
finished. Unlike `buf_request`, this will collect all the Server results are passed as a `client_id:result` map.
responses from each server instead of handling them. A map
of client_id:request_result will be provided to the
callback.
Return: ~ Return: ~
fun() cancel A function that will cancel all requests fun() cancel Function that cancels all requests.
*vim.lsp.buf_request_sync()* *vim.lsp.buf_request_sync()*
buf_request_sync({bufnr}, {method}, {params}, {timeout_ms}) buf_request_sync({bufnr}, {method}, {params}, {timeout_ms})
Sends a request to all server and waits for the response of all of them. Sends a request to all server and waits for the response of all of them.
Calls |vim.lsp.buf_request_all()| but blocks Nvim while awaiting the Calls |vim.lsp.buf_request_all()| but blocks Nvim while awaiting the
result. Parameters are the same as |vim.lsp.buf_request()| but the return result. Parameters are the same as |vim.lsp.buf_request_all()| but the
result is different. Wait maximum of {timeout_ms} (default 1000) ms. result is different. Waits a maximum of {timeout_ms} (default 1000) ms.
Parameters: ~ Parameters: ~
• {bufnr} (integer) Buffer handle, or 0 for current. • {bufnr} (integer) Buffer handle, or 0 for current.

View File

@ -1002,10 +1002,18 @@ Log levels are one of the values defined in `vim.log.levels`:
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
LUA-VIMSCRIPT BRIDGE *lua-vimscript* LUA-VIMSCRIPT BRIDGE *lua-vimscript*
Nvim Lua provides an interface to Vimscript variables and functions, and Nvim Lua provides an interface or "bridge" to Vimscript variables and
editor commands and options. functions, and editor commands and options.
Objects passed over this bridge are COPIED (marshalled): there are no
"references". |lua-guide-variables| For example, using `vim.fn.remove()` on
a Lua list copies the list object to Vimscript and does NOT modify the Lua
list: >lua
local list = { 1, 2, 3 }
vim.fn.remove(list, 0)
vim.print(list) --> "{ 1, 2, 3 }"
See also https://github.com/nanotee/nvim-lua-guide.
vim.call({func}, {...}) *vim.call()* vim.call({func}, {...}) *vim.call()*
Invokes |vim-function| or |user-function| {func} with arguments {...}. Invokes |vim-function| or |user-function| {func} with arguments {...}.

View File

@ -1546,6 +1546,7 @@ supports incremental command preview:
-- If invoked as a preview callback, performs 'inccommand' preview by -- If invoked as a preview callback, performs 'inccommand' preview by
-- highlighting trailing whitespace in the current buffer. -- highlighting trailing whitespace in the current buffer.
local function trim_space_preview(opts, preview_ns, preview_buf) local function trim_space_preview(opts, preview_ns, preview_buf)
vim.cmd('hi clear Whitespace')
local line1 = opts.line1 local line1 = opts.line1
local line2 = opts.line2 local line2 = opts.line2
local buf = vim.api.nvim_get_current_buf() local buf = vim.api.nvim_get_current_buf()

View File

@ -2088,17 +2088,13 @@ A jump table for the options with a short description can be found at |Q_op|.
:set dir=c:\\tmp,\ dir\\,with\\,commas,\\\ dir\ with\ spaces :set dir=c:\\tmp,\ dir\\,with\\,commas,\\\ dir\ with\ spaces
< - For backwards compatibility with Vim version 3.0 a '>' at the start < - For backwards compatibility with Vim version 3.0 a '>' at the start
of the option is removed. of the option is removed.
Using "." first in the list is recommended. This means that editing
the same file twice will result in a warning. Using "/tmp" on Unix is Editing the same file twice will result in a warning. Using "/tmp" on
discouraged: When the system crashes you lose the swap file. is discouraged: if the system crashes you lose the swap file. And
"/var/tmp" is often not cleared when rebooting, thus is a better others on the computer may be able to see the files.
choice than "/tmp". But others on the computer may be able to see the Use |:set+=| and |:set-=| when adding or removing directories from the
files, and it can contain a lot of files, your swap files get lost in list, this avoids problems if the Nvim default is changed.
the crowd. That is why a "tmp" directory in your home directory is
tried first.
The use of |:set+=| and |:set-=| is preferred when adding or removing
directories from the list. This avoids problems when a future version
uses another default.
This option cannot be set from a |modeline| or in the |sandbox|, for This option cannot be set from a |modeline| or in the |sandbox|, for
security reasons. security reasons.

View File

@ -1298,7 +1298,6 @@ will probably never match.
When "\Z" appears anywhere in the pattern, all composing characters are When "\Z" appears anywhere in the pattern, all composing characters are
ignored. Thus only the base characters need to match, the composing ignored. Thus only the base characters need to match, the composing
characters may be different and the number of composing characters may differ. characters may be different and the number of composing characters may differ.
Only relevant when 'encoding' is "utf-8".
Exception: If the pattern starts with one or more composing characters, these Exception: If the pattern starts with one or more composing characters, these
must match. must match.
*/\%C* */\%C*

View File

@ -34,7 +34,6 @@ enter Normal mode command, you can also set 'langmap' option:
:set langmap=ФИСВУАПРШОЛДЬТЩЗЙКЫЕГМЦЧНЯ;ABCDEFGHIJKLMNOPQRSTUVWXYZ, :set langmap=ФИСВУАПРШОЛДЬТЩЗЙКЫЕГМЦЧНЯ;ABCDEFGHIJKLMNOPQRSTUVWXYZ,
фисвуапршолдьтщзйкыегмцчня;abcdefghijklmnopqrstuvwxyz фисвуапршолдьтщзйкыегмцчня;abcdefghijklmnopqrstuvwxyz
This is in utf-8, you cannot read this if your 'encoding' is not utf-8.
You have to type this command in one line, it is wrapped for the sake of You have to type this command in one line, it is wrapped for the sake of
readability. readability.

View File

@ -1384,20 +1384,23 @@ STATE DIRECTORY (DEFAULT) ~
Unix: ~/.local/state ~/.local/state/nvim Unix: ~/.local/state ~/.local/state/nvim
Windows: ~/AppData/Local ~/AppData/Local/nvim-data Windows: ~/AppData/Local ~/AppData/Local/nvim-data
Note: Throughout the user manual these defaults are used as placeholders, e.g. Note: Throughout the help pages these defaults are used as placeholders, e.g.
"~/.config" is understood to mean "$XDG_CONFIG_HOME or ~/.config". "~/.config" is understood to mean "$XDG_CONFIG_HOME or ~/.config".
NVIM_APPNAME *$NVIM_APPNAME* NVIM_APPNAME *$NVIM_APPNAME*
The XDG directories used by Nvim can be further configured by setting the The standard directories can be further configured by the `$NVIM_APPNAME`
`$NVIM_APPNAME` environment variable. This variable controls the directory environment variable. This variable controls the sub-directory that Nvim will
Neovim will look for (and auto-create) in the various XDG parent directories. read from (and auto-create) in each of the base directories. For example,
For example, setting `$NVIM_APPNAME` to "neovim" before running Neovim will setting `$NVIM_APPNAME` to "foo" before starting will cause Nvim to look for
result in Neovim looking for configuration files in `$XDG_CONFIG_HOME/neovim` configuration files in `$XDG_CONFIG_HOME/foo` instead of
instead of `$XDG_CONFIG_HOME/nvim`. `$XDG_CONFIG_HOME/nvim`.
Note: Similarly to the $XDG environment variables, when One use-case for $NVIM_APPNAME is to "isolate" Nvim applications.
`$XDG_CONFIG_HOME/nvim` is mentioned, it should be understood as Alternatively, for true isolation, on Linux you can use cgroups namespaces: >
`$XDG_CONFIG_HOME/$NVIM_APPNAME`. systemd-run --user -qt -p PrivateUsers=yes -p BindPaths=/home/user/profile_xy:/home/user/.config/nvim nvim
Note: Throughout the help pages, wherever `$XDG_CONFIG_…/nvim` is mentioned it
is understood to mean `$XDG_CONFIG_…/$NVIM_APPNAME`.
LOG FILE *log* *$NVIM_LOG_FILE* *E5430* LOG FILE *log* *$NVIM_LOG_FILE* *E5430*
Besides 'debug' and 'verbose', Nvim keeps a general log file for internal Besides 'debug' and 'verbose', Nvim keeps a general log file for internal

View File

@ -82,9 +82,8 @@ You must be in the right directory, otherwise Vim can't find the swap file.
============================================================================== ==============================================================================
*11.2* Where is the swap file? *11.2* Where is the swap file?
Vim can store the swap file in several places. Normally it is in the same Vim can store the swap file in several places. To find it, change to the
directory as the original file. To find it, change to the directory of the directory of the file, and use: >
file, and use: >
vim -r vim -r

View File

@ -190,8 +190,7 @@ font. Example: >
xterm -u8 -fn -misc-fixed-medium-r-normal--18-120-100-100-c-90-iso10646-1 xterm -u8 -fn -misc-fixed-medium-r-normal--18-120-100-100-c-90-iso10646-1
Now you can run Vim inside this terminal. Set 'encoding' to "utf-8" as Now you can run Vim inside this terminal.
before. That's all.
USING UNICODE IN AN ORDINARY TERMINAL USING UNICODE IN AN ORDINARY TERMINAL

View File

@ -88,13 +88,10 @@ g8 Print the hex values of the bytes used in the
*8g8* *8g8*
8g8 Find an illegal UTF-8 byte sequence at or after the 8g8 Find an illegal UTF-8 byte sequence at or after the
cursor. This works in two situations: cursor.
1. when 'encoding' is any 8-bit encoding Can be used when editing a file that was supposed to
2. when 'encoding' is "utf-8" and 'fileencoding' is be UTF-8 but was read as if it is an 8-bit encoding
any 8-bit encoding because it contains illegal bytes.
Thus it can be used when editing a file that was
supposed to be UTF-8 but was read as if it is an 8-bit
encoding because it contains illegal bytes.
Does not wrap around the end of the file. Does not wrap around the end of the file.
Note that when the cursor is on an illegal byte or the Note that when the cursor is on an illegal byte or the
cursor is halfway through a multibyte character the cursor is halfway through a multibyte character the

View File

@ -1491,7 +1491,7 @@ function lsp.start_client(config)
---successful, then it will return {request_id} as the ---successful, then it will return {request_id} as the
---second result. You can use this with `client.cancel_request(request_id)` ---second result. You can use this with `client.cancel_request(request_id)`
---to cancel the-request. ---to cancel the-request.
---@see |vim.lsp.buf_request()| ---@see |vim.lsp.buf_request_all()|
function client.request(method, params, handler, bufnr) function client.request(method, params, handler, bufnr)
if not handler then if not handler then
handler = assert( handler = assert(
@ -2119,22 +2119,19 @@ function lsp.buf_request(bufnr, method, params, handler)
return client_request_ids, _cancel_all_requests return client_request_ids, _cancel_all_requests
end end
---Sends an async request for all active clients attached to the buffer. --- Sends an async request for all active clients attached to the buffer and executes the `handler`
---Executes the callback on the combined result. --- callback with the combined result.
---Parameters are the same as |vim.lsp.buf_request()| but the return result and callback are
---different.
--- ---
---@param bufnr (integer) Buffer handle, or 0 for current. ---@param bufnr (integer) Buffer handle, or 0 for current.
---@param method (string) LSP method name ---@param method (string) LSP method name
---@param params (table|nil) Parameters to send to the server ---@param params (table|nil) Parameters to send to the server
---@param callback fun(request_results: table<integer, {error: lsp.ResponseError, result: any}>) (function) ---@param handler fun(results: table<integer, {error: lsp.ResponseError, result: any}>) (function)
--- The callback to call when all requests are finished. --- Handler called after all requests are completed. Server results are passed as
--- Unlike `buf_request`, this will collect all the responses from each server instead of handling them. --- a `client_id:result` map.
--- A map of client_id:request_result will be provided to the callback.
--- ---
---@return fun() cancel A function that will cancel all requests ---@return fun() cancel Function that cancels all requests.
function lsp.buf_request_all(bufnr, method, params, callback) function lsp.buf_request_all(bufnr, method, params, handler)
local request_results = {} local results = {}
local result_count = 0 local result_count = 0
local expected_result_count = 0 local expected_result_count = 0
@ -2147,12 +2144,12 @@ function lsp.buf_request_all(bufnr, method, params, callback)
end) end)
local function _sync_handler(err, result, ctx) local function _sync_handler(err, result, ctx)
request_results[ctx.client_id] = { error = err, result = result } results[ctx.client_id] = { error = err, result = result }
result_count = result_count + 1 result_count = result_count + 1
set_expected_result_count() set_expected_result_count()
if result_count >= expected_result_count then if result_count >= expected_result_count then
callback(request_results) handler(results)
end end
end end
@ -2164,8 +2161,8 @@ end
--- Sends a request to all server and waits for the response of all of them. --- Sends a request to all server and waits for the response of all of them.
--- ---
--- Calls |vim.lsp.buf_request_all()| but blocks Nvim while awaiting the result. --- Calls |vim.lsp.buf_request_all()| but blocks Nvim while awaiting the result.
--- Parameters are the same as |vim.lsp.buf_request()| but the return result is --- Parameters are the same as |vim.lsp.buf_request_all()| but the result is
--- different. Wait maximum of {timeout_ms} (default 1000) ms. --- different. Waits a maximum of {timeout_ms} (default 1000) ms.
--- ---
---@param bufnr (integer) Buffer handle, or 0 for current. ---@param bufnr (integer) Buffer handle, or 0 for current.
---@param method (string) LSP method name ---@param method (string) LSP method name

View File

@ -62,7 +62,6 @@ local exclude_invalid = {
["'string'"] = "eval.txt", ["'string'"] = "eval.txt",
Query = 'treesitter.txt', Query = 'treesitter.txt',
['eq?'] = 'treesitter.txt', ['eq?'] = 'treesitter.txt',
['lsp-request'] = 'lsp.txt',
matchit = 'vim_diff.txt', matchit = 'vim_diff.txt',
['matchit.txt'] = 'help.txt', ['matchit.txt'] = 'help.txt',
["set!"] = "treesitter.txt", ["set!"] = "treesitter.txt",
@ -70,7 +69,6 @@ local exclude_invalid = {
['v:_null_dict'] = 'builtin.txt', ['v:_null_dict'] = 'builtin.txt',
['v:_null_list'] = 'builtin.txt', ['v:_null_list'] = 'builtin.txt',
['v:_null_string'] = 'builtin.txt', ['v:_null_string'] = 'builtin.txt',
['vim.lsp.buf_request()'] = 'lsp.txt',
['vim.lsp.util.get_progress_messages()'] = 'lsp.txt', ['vim.lsp.util.get_progress_messages()'] = 'lsp.txt',
} }