aboutsummaryrefslogtreecommitdiff
path: root/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'runtime')
-rw-r--r--runtime/autoload/provider/clipboard.vim2
-rw-r--r--runtime/doc/api.txt13
-rw-r--r--runtime/doc/builtin.txt9
-rw-r--r--runtime/doc/deprecated.txt1
-rw-r--r--runtime/doc/dev_arch.txt10
-rw-r--r--runtime/doc/develop.txt8
-rw-r--r--runtime/doc/gui.txt3
-rw-r--r--runtime/doc/intro.txt24
-rw-r--r--runtime/doc/lsp.txt36
-rw-r--r--runtime/doc/lua.txt6
-rw-r--r--runtime/doc/map.txt2
-rw-r--r--runtime/doc/nvim.txt36
-rw-r--r--runtime/doc/ui.txt2
-rw-r--r--runtime/doc/various.txt3
-rw-r--r--runtime/doc/vim_diff.txt5
-rw-r--r--runtime/lua/vim/_defaults.lua3
-rw-r--r--runtime/lua/vim/_meta/api.lua14
-rw-r--r--runtime/lua/vim/_meta/vimfn.lua13
-rw-r--r--runtime/lua/vim/_system.lua126
-rw-r--r--runtime/lua/vim/filetype.lua2
-rw-r--r--runtime/lua/vim/lsp.lua208
-rw-r--r--runtime/lua/vim/lsp/client.lua8
-rw-r--r--runtime/lua/vim/lsp/rpc.lua2
23 files changed, 307 insertions, 229 deletions
diff --git a/runtime/autoload/provider/clipboard.vim b/runtime/autoload/provider/clipboard.vim
index 58d3d4550f..848fa401f1 100644
--- a/runtime/autoload/provider/clipboard.vim
+++ b/runtime/autoload/provider/clipboard.vim
@@ -158,7 +158,7 @@ function! provider#clipboard#Executable() abort
let s:copy['*'] = s:copy['+']
let s:paste['*'] = s:paste['+']
return 'termux-clipboard'
- elseif !empty($TMUX) && executable('tmux')
+ elseif executable('tmux') && (!empty($TMUX) || 0 == jobwait([jobstart(['tmux', 'list-buffers'])], 2000)[0])
let tmux_v = v:lua.vim.version.parse(system(['tmux', '-V']))
if !empty(tmux_v) && !v:lua.vim.version.lt(tmux_v, [3,2,0])
let s:copy['+'] = ['tmux', 'load-buffer', '-w', '-']
diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt
index c5dabeb551..9cb8f72348 100644
--- a/runtime/doc/api.txt
+++ b/runtime/doc/api.txt
@@ -1114,7 +1114,7 @@ nvim_open_term({buffer}, {opts}) *nvim_open_term()*
Open a terminal instance in a buffer
By default (and currently the only option) the terminal will not be
- connected to an external process. Instead, input send on the channel will
+ connected to an external process. Instead, input sent on the channel will
be echoed directly by the terminal. This is useful to display ANSI
terminal sequences returned as part of a rpc message, or similar.
@@ -1125,6 +1125,17 @@ nvim_open_term({buffer}, {opts}) *nvim_open_term()*
|nvim_chan_send()| can be called immediately to process sequences in a
virtual terminal having the intended size.
+ Example: this `TermHl` command can be used to display and highlight raw
+ ANSI termcodes, so you can use Nvim as a "scrollback pager" (for terminals
+ like kitty): *terminal-scrollback-pager* >lua
+ vim.api.nvim_create_user_command('TermHl', function()
+ local b = vim.api.nvim_create_buf(false, true)
+ local chan = vim.api.nvim_open_term(b, {})
+ vim.api.nvim_chan_send(chan, table.concat(vim.api.nvim_buf_get_lines(0, 0, -1, false), '\n'))
+ vim.api.nvim_win_set_buf(0, b)
+ end, { desc = 'Highlights ANSI termcodes in curbuf' })
+<
+
Attributes: ~
not allowed when |textlock| is active
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt
index 585db21a0b..304e63fd95 100644
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -5443,7 +5443,7 @@ jobwait({jobs} [, {timeout}]) *jobwait()*
• {timeout} (`integer?`)
Return: ~
- (`any`)
+ (`integer[]`)
join({list} [, {sep}]) *join()*
Join the items in {list} together into one String.
@@ -7986,7 +7986,7 @@ rpcnotify({channel}, {event} [, {args}...]) *rpcnotify()*
Parameters: ~
• {channel} (`integer`)
• {event} (`string`)
- • {args} (`any?`)
+ • {...} (`any`)
Return: ~
(`any`)
@@ -8001,7 +8001,7 @@ rpcrequest({channel}, {method} [, {args}...]) *rpcrequest()*
Parameters: ~
• {channel} (`integer`)
• {method} (`string`)
- • {args} (`any?`)
+ • {...} (`any`)
Return: ~
(`any`)
@@ -10234,6 +10234,7 @@ str2list({string} [, {utf8}]) *str2list()*
and exists only for backwards-compatibility.
With UTF-8 composing characters are handled properly: >vim
echo str2list("á") " returns [97, 769]
+<
Parameters: ~
• {string} (`string`)
@@ -11991,7 +11992,7 @@ winlayout([{tabnr}]) *winlayout()*
• {tabnr} (`integer?`)
Return: ~
- (`any`)
+ (`any[]`)
winline() *winline()*
The result is a Number, which is the screen line of the cursor
diff --git a/runtime/doc/deprecated.txt b/runtime/doc/deprecated.txt
index c6ca5e5ce9..ab9c0b2ce8 100644
--- a/runtime/doc/deprecated.txt
+++ b/runtime/doc/deprecated.txt
@@ -64,6 +64,7 @@ LSP
• `client.is_stopped()` Use |Client:is_stopped()| instead.
• `client.supports_method()` Use |Client:supports_method()| instead.
• `client.on_attach()` Use |Client:on_attach()| instead.
+• `vim.lsp.start_client()` Use |vim.lsp.start()| instead.
------------------------------------------------------------------------------
DEPRECATED IN 0.10 *deprecated-0.10*
diff --git a/runtime/doc/dev_arch.txt b/runtime/doc/dev_arch.txt
index 1cb3b9ad67..2be6221117 100644
--- a/runtime/doc/dev_arch.txt
+++ b/runtime/doc/dev_arch.txt
@@ -46,11 +46,11 @@ Remember to bump NVIM_API_LEVEL if it wasn't already during this development
cycle.
Other references:
-* |msgpack-rpc|
-* |ui|
-* https://github.com/neovim/neovim/pull/3246
-* https://github.com/neovim/neovim/pull/18375
-* https://github.com/neovim/neovim/pull/21605
+- |msgpack-rpc|
+- |ui|
+- https://github.com/neovim/neovim/pull/3246
+- https://github.com/neovim/neovim/pull/18375
+- https://github.com/neovim/neovim/pull/21605
diff --git a/runtime/doc/develop.txt b/runtime/doc/develop.txt
index a61c569a67..da64475465 100644
--- a/runtime/doc/develop.txt
+++ b/runtime/doc/develop.txt
@@ -300,7 +300,7 @@ vim.paste in runtime/lua/vim/_editor.lua like this: >
--- @returns false if client should cancel the paste.
-LUA STDLIB DESIGN GUIDELINES *dev-lua*
+STDLIB DESIGN GUIDELINES *dev-lua*
See also |dev-naming|.
@@ -337,7 +337,7 @@ preference):
way. Advantage is that propagation happens for free and it's harder to
accidentally swallow errors. (E.g. using
`uv_handle/pipe:write()` without checking return values is common.)
-4. `on_error` parameter
+4. `on_error` callback
- For async and "visitors" traversing a graph, where many errors may be
collected while work continues.
5. `vim.notify` (sometimes with optional `opts.silent` (async, visitors ^))
@@ -434,7 +434,9 @@ Use existing common {verb} names (actions) if possible:
- eval: Evaluates an expression
- exec: Executes code, may return a result
- fmt: Formats
- - get: Gets things (often by a query)
+ - get: Gets things. Two variants (overloads):
+ 1. `get<T>(id: int): T` returns one item.
+ 2. `get<T>(filter: dict): T[]` returns a list.
- inspect: Presents a high-level, often interactive, view
- is_enabled: Checks if functionality is enabled.
- open: Opens something (a buffer, window, …)
diff --git a/runtime/doc/gui.txt b/runtime/doc/gui.txt
index 21f1ba8241..85a0df03f9 100644
--- a/runtime/doc/gui.txt
+++ b/runtime/doc/gui.txt
@@ -20,8 +20,9 @@ features, whereas help tags with the "ui-" prefix refer to the |ui-protocol|.
Nvim provides a default, builtin UI (the |TUI|), but there are many other
(third-party) GUIs that you can use instead:
-- Firenvim (Nvim in your web browser!) https://github.com/glacambre/firenvim
+ *vscode*
- vscode-neovim (Nvim in VSCode!) https://github.com/vscode-neovim/vscode-neovim
+- Firenvim (Nvim in your web browser!) https://github.com/glacambre/firenvim
- Neovide https://neovide.dev/
- Goneovim https://github.com/akiyosi/goneovim
- Nvy https://github.com/RMichelsen/Nvy
diff --git a/runtime/doc/intro.txt b/runtime/doc/intro.txt
index d099c29bdb..85169fcc17 100644
--- a/runtime/doc/intro.txt
+++ b/runtime/doc/intro.txt
@@ -49,17 +49,19 @@ For more information try one of these:
==============================================================================
Nvim on the interwebs *internet*
- *www* *distribution* *download*
-
- Nvim home page: https://neovim.io/
- Downloads: https://github.com/neovim/neovim/releases
- Vim FAQ: https://vimhelp.org/vim_faq.txt.html
-
-
- *bugs* *bug-report*
-Report bugs and request features here:
-https://github.com/neovim/neovim/issues
-
+ *www* *distribution*
+- Nvim home page: https://neovim.io/
+- Vim FAQ: https://vimhelp.org/vim_faq.txt.html
+
+ *download* *upgrade* *ubuntu*
+To install or upgrade Nvim, you can...
+- Download a pre-built archive:
+ https://github.com/neovim/neovim/releases
+- Use your system package manager:
+ https://github.com/neovim/neovim/blob/master/INSTALL.md#install-from-package
+
+ *bugs* *bug-report* *feature-request*
+Report bugs and request features here: https://github.com/neovim/neovim/issues
Be brief, yet complete. Always give a reproducible example and try to find
out which settings or other things trigger the bug.
diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt
index e311831bd3..2654d7f14f 100644
--- a/runtime/doc/lsp.txt
+++ b/runtime/doc/lsp.txt
@@ -841,12 +841,11 @@ start({config}, {opts}) *vim.lsp.start()*
})
<
- See |vim.lsp.start_client()| for all available options. The most important
+ See |vim.lsp.ClientConfig| for all available options. The most important
are:
• `name` arbitrary name for the LSP client. Should be unique per language
server.
- • `cmd` command string[] or function, described at
- |vim.lsp.start_client()|.
+ • `cmd` command string[] or function.
• `root_dir` path to the project root. By default this is used to decide
if an existing client should be re-used. The example above uses
|vim.fs.root()| to detect the root by traversing the file system upwards
@@ -868,7 +867,7 @@ start({config}, {opts}) *vim.lsp.start()*
Parameters: ~
• {config} (`vim.lsp.ClientConfig`) Configuration for the server. See
|vim.lsp.ClientConfig|.
- • {opts} (`table?`) Optional keyword arguments
+ • {opts} (`table?`) Optional keyword arguments.
• {reuse_client}?
(`fun(client: vim.lsp.Client, config: vim.lsp.ClientConfig): boolean`)
Predicate used to decide if a client should be re-used.
@@ -876,25 +875,15 @@ start({config}, {opts}) *vim.lsp.start()*
re-uses a client if name and root_dir matches.
• {bufnr}? (`integer`) Buffer handle to attach to if
starting or re-using a client (0 for current).
+ • {attach}? (`boolean`) Whether to attach the client to a
+ buffer (default true). If set to `false`, `reuse_client`
+ and `bufnr` will be ignored.
• {silent}? (`boolean`) Suppress error reporting if the LSP
server fails to start (default false).
Return: ~
(`integer?`) client_id
-start_client({config}) *vim.lsp.start_client()*
- Starts and initializes a client with the given configuration.
-
- Parameters: ~
- • {config} (`vim.lsp.ClientConfig`) Configuration for the server. See
- |vim.lsp.ClientConfig|.
-
- Return (multiple): ~
- (`integer?`) client_id |vim.lsp.get_client_by_id()| Note: client may
- not be fully initialized. Use `on_init` to do any actions once the
- client has been initialized.
- (`string?`) Error message, if any
-
status() *vim.lsp.status()*
Consumes the latest progress messages from all clients and formats them as
a string. Empty if there are no clients or if no new messages
@@ -968,8 +957,7 @@ Lua module: vim.lsp.client *lsp-client*
server.
• {config} (`vim.lsp.ClientConfig`) copy of the table
that was passed by the user to
- |vim.lsp.start_client()|. See
- |vim.lsp.ClientConfig|.
+ |vim.lsp.start()|. See |vim.lsp.ClientConfig|.
• {server_capabilities} (`lsp.ServerCapabilities?`) Response from the
server sent on `initialize` describing the
server's capabilities.
@@ -1093,7 +1081,7 @@ Lua module: vim.lsp.client *lsp-client*
• {commands}? (`table<string,fun(command: lsp.Command, ctx: table)>`)
Table that maps string of clientside commands to
user-defined functions. Commands passed to
- start_client take precedence over the global
+ `start()` take precedence over the global
command registry. Each key must be a unique
command name, and the value is a function which
is called if any LSP action (code action, code
@@ -1122,9 +1110,9 @@ Lua module: vim.lsp.client *lsp-client*
Callback invoked before the LSP "initialize"
phase, where `params` contains the parameters
being sent to the server and `config` is the
- config that was passed to
- |vim.lsp.start_client()|. You can use this to
- modify parameters before they are sent.
+ config that was passed to |vim.lsp.start()|. You
+ can use this to modify parameters before they
+ are sent.
• {on_init}? (`elem_or_list<fun(client: vim.lsp.Client, initialize_result: lsp.InitializeResult)>`)
Callback invoked after LSP "initialize", where
`result` is a table of `capabilities` and
@@ -2296,7 +2284,7 @@ connect({host_or_path}, {port}) *vim.lsp.rpc.connect()*
• a host and port via TCP
Return a function that can be passed to the `cmd` field for
- |vim.lsp.start_client()| or |vim.lsp.start()|.
+ |vim.lsp.start()|.
Parameters: ~
• {host_or_path} (`string`) host to connect to or path to a pipe/domain
diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt
index 047e263768..48fa595a53 100644
--- a/runtime/doc/lua.txt
+++ b/runtime/doc/lua.txt
@@ -17,9 +17,9 @@ get an idea of what lurks beneath: >vim
:lua vim.print(package.loaded)
Nvim includes a "standard library" |lua-stdlib| for Lua. It complements the
-"editor stdlib" (|builtin-functions| and |Ex-commands|) and the |API|, all of
-which can be used from Lua code (|lua-vimscript| |vim.api|). Together these
-"namespaces" form the Nvim programming interface.
+"editor stdlib" (|vimscript-functions| + |Ex-commands|) and the |API|, all of
+which can be used from Lua code (|lua-vimscript| |vim.api|). These three
+namespaces form the Nvim programming interface.
Lua plugins and user config are automatically discovered and loaded, just like
Vimscript. See |lua-guide| for practical guidance.
diff --git a/runtime/doc/map.txt b/runtime/doc/map.txt
index 11048aee30..34cf309576 100644
--- a/runtime/doc/map.txt
+++ b/runtime/doc/map.txt
@@ -12,7 +12,7 @@ manual.
Type |gO| to see the table of contents.
==============================================================================
-1. Key mapping *key-mapping* *mapping* *macro*
+1. Key mapping *keybind* *key-mapping* *mapping* *macro*
Key mapping is used to change the meaning of typed keys. The most common use
is to define a sequence of commands for a function key. Example: >
diff --git a/runtime/doc/nvim.txt b/runtime/doc/nvim.txt
index 86e344c654..8593511dbc 100644
--- a/runtime/doc/nvim.txt
+++ b/runtime/doc/nvim.txt
@@ -6,21 +6,23 @@
Nvim *nvim* *neovim* *nvim-intro*
-Nvim is based on Vim by Bram Moolenaar.
+Nvim is based on Vim by Bram Moolenaar. Nvim is emphatically a fork of Vim,
+not a clone: compatibility with Vim (especially editor and Vimscript features,
+except |Vim9script|) is maintained where possible. See |vim-differences| for
+the complete reference.
-If you already use Vim see |nvim-from-vim| for a quickstart.
-If you are new to Vim, try the 30-minute tutorial: >vim
+If you already use Vim, see |nvim-from-vim| for a quickstart. If you just
+installed Nvim and have never used it before, watch this 10-minute
+video: https://youtu.be/TQn2hJeHQbM .
- :Tutor<Enter>
-
-Nvim is emphatically a fork of Vim, not a clone: compatibility with Vim
-(especially editor and Vimscript features) is maintained where possible. See
-|vim-differences| for the complete reference of differences from Vim.
+To learn how to use Vim in 30 minutes, try the tutorial: >vim
+ :Tutor<Enter>
+<
Type |gO| to see the table of contents.
==============================================================================
-Transitioning from Vim *nvim-from-vim*
+Transitioning from Vim *nvim-from-vim*
1. To start the transition, create your |init.vim| (user config) file: >vim
@@ -71,4 +73,20 @@ the same Nvim configuration on all of your machines, by creating
source ~/.config/nvim/init.vim
==============================================================================
+What next? *nvim-quickstart*
+
+If you are just trying out Nvim for a few minutes, and want to see the
+extremes of what it can do, try one of these popular "extension packs" or
+"distributions" (Note: Nvim is not affiliated with these projects, and does
+not support them):
+
+- *kickstart* https://github.com/nvim-lua/kickstart.nvim
+- *lazyvim* https://www.lazyvim.org/
+- *nvchad* https://nvchad.com/
+
+However, in general, we recommend (eventually) taking time to learn Nvim from
+its stock configuration, and incrementally setting options and adding plugins
+to your |config| as you find an explicit need to do so.
+
+==============================================================================
vim:tw=78:ts=8:et:ft=help:norl:
diff --git a/runtime/doc/ui.txt b/runtime/doc/ui.txt
index 55eba484bc..77eddfd8e1 100644
--- a/runtime/doc/ui.txt
+++ b/runtime/doc/ui.txt
@@ -788,7 +788,7 @@ must handle.
kind
Name indicating the message kind:
- "" (empty) Unknown (consider a feature-request: |bugs|)
+ "" (empty) Unknown (consider a |feature-request|)
"confirm" |confirm()| or |:confirm| dialog
"confirm_sub" |:substitute| confirm dialog |:s_c|
"emsg" Error (|errors|, internal error, |:throw|, …)
diff --git a/runtime/doc/various.txt b/runtime/doc/various.txt
index d967e7c75b..5049439337 100644
--- a/runtime/doc/various.txt
+++ b/runtime/doc/various.txt
@@ -534,7 +534,8 @@ gO Show a filetype-specific, navigable "outline" of the
current buffer. For example, in a |help| buffer this
shows the table of contents.
- Currently works in |help| and |:Man| buffers.
+ Works in |help| and |:Man| buffers, or any buffer with
+ an active |LSP| client (|lsp-defaults|).
[N]gs *gs* *:sl* *:sleep*
:[N]sl[eep] [N][m] Do nothing for [N] seconds, or [N] milliseconds if [m]
diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt
index 6e1a9adb83..8d2d672ce1 100644
--- a/runtime/doc/vim_diff.txt
+++ b/runtime/doc/vim_diff.txt
@@ -186,6 +186,9 @@ nvim_terminal:
- 'textwidth' set to 0
- 'nowrap'
- 'nolist'
+ - 'nonumber'
+ - 'norelativenumber'
+ - 'signcolumn' set to "no"
- 'winhighlight' uses |hl-StatusLineTerm| and |hl-StatusLineTermNC| in
place of |hl-StatusLine| and |hl-StatusLineNC|
@@ -686,7 +689,7 @@ Cscope:
https://github.com/dhananjaylatkar/cscope_maps.nvim
Eval:
-- Vim9script
+- *Vim9script* (the Vim 9+ flavor of Vimscript) is not supported.
- *cscope_connection()*
- *err_teapot()*
- *js_encode()*
diff --git a/runtime/lua/vim/_defaults.lua b/runtime/lua/vim/_defaults.lua
index 6583cf48b3..ef83a3ccc3 100644
--- a/runtime/lua/vim/_defaults.lua
+++ b/runtime/lua/vim/_defaults.lua
@@ -492,6 +492,9 @@ do
vim.bo.textwidth = 0
vim.wo[0][0].wrap = false
vim.wo[0][0].list = false
+ vim.wo[0][0].number = false
+ vim.wo[0][0].relativenumber = false
+ vim.wo[0][0].signcolumn = 'no'
-- This is gross. Proper list options support when?
local winhl = vim.o.winhighlight
diff --git a/runtime/lua/vim/_meta/api.lua b/runtime/lua/vim/_meta/api.lua
index acd12b353d..d74ee11b46 100644
--- a/runtime/lua/vim/_meta/api.lua
+++ b/runtime/lua/vim/_meta/api.lua
@@ -1654,7 +1654,7 @@ function vim.api.nvim_notify(msg, log_level, opts) end
--- Open a terminal instance in a buffer
---
--- By default (and currently the only option) the terminal will not be
---- connected to an external process. Instead, input send on the channel
+--- connected to an external process. Instead, input sent on the channel
--- will be echoed directly by the terminal. This is useful to display
--- ANSI terminal sequences returned as part of a rpc message, or similar.
---
@@ -1665,6 +1665,18 @@ function vim.api.nvim_notify(msg, log_level, opts) end
--- Then `nvim_chan_send()` can be called immediately to process sequences
--- in a virtual terminal having the intended size.
---
+--- Example: this `TermHl` command can be used to display and highlight raw ANSI termcodes, so you
+--- can use Nvim as a "scrollback pager" (for terminals like kitty): [terminal-scrollback-pager]()
+---
+--- ```lua
+--- vim.api.nvim_create_user_command('TermHl', function()
+--- local b = vim.api.nvim_create_buf(false, true)
+--- local chan = vim.api.nvim_open_term(b, {})
+--- vim.api.nvim_chan_send(chan, table.concat(vim.api.nvim_buf_get_lines(0, 0, -1, false), '\n'))
+--- vim.api.nvim_win_set_buf(0, b)
+--- end, { desc = 'Highlights ANSI termcodes in curbuf' })
+--- ```
+---
--- @param buffer integer the buffer to use (expected to be empty)
--- @param opts vim.api.keyset.open_term Optional parameters.
--- - on_input: Lua callback for input sent, i e keypresses in terminal
diff --git a/runtime/lua/vim/_meta/vimfn.lua b/runtime/lua/vim/_meta/vimfn.lua
index f9b5d93a4b..e207f641de 100644
--- a/runtime/lua/vim/_meta/vimfn.lua
+++ b/runtime/lua/vim/_meta/vimfn.lua
@@ -4928,7 +4928,7 @@ function vim.fn.jobstop(id) end
---
--- @param jobs integer[]
--- @param timeout? integer
---- @return any
+--- @return integer[]
function vim.fn.jobwait(jobs, timeout) end
--- Join the items in {list} together into one String.
@@ -7244,9 +7244,9 @@ function vim.fn.round(expr) end
---
--- @param channel integer
--- @param event string
---- @param args? any
+--- @param ... any
--- @return any
-function vim.fn.rpcnotify(channel, event, args) end
+function vim.fn.rpcnotify(channel, event, ...) end
--- Sends a request to {channel} to invoke {method} via
--- |RPC| and blocks until a response is received.
@@ -7256,9 +7256,9 @@ function vim.fn.rpcnotify(channel, event, args) end
---
--- @param channel integer
--- @param method string
---- @param args? any
+--- @param ... any
--- @return any
-function vim.fn.rpcrequest(channel, method, args) end
+function vim.fn.rpcrequest(channel, method, ...) end
--- @deprecated
--- Deprecated. Replace >vim
@@ -9328,6 +9328,7 @@ function vim.fn.str2float(string, quoted) end
--- and exists only for backwards-compatibility.
--- With UTF-8 composing characters are handled properly: >vim
--- echo str2list("á") " returns [97, 769]
+--- <
---
--- @param string string
--- @param utf8? boolean
@@ -10870,7 +10871,7 @@ function vim.fn.winheight(nr) end
--- <
---
--- @param tabnr? integer
---- @return any
+--- @return any[]
function vim.fn.winlayout(tabnr) end
--- The result is a Number, which is the screen line of the cursor
diff --git a/runtime/lua/vim/_system.lua b/runtime/lua/vim/_system.lua
index ce5dbffeaa..c0a0570e13 100644
--- a/runtime/lua/vim/_system.lua
+++ b/runtime/lua/vim/_system.lua
@@ -47,15 +47,6 @@ local function close_handle(handle)
end
end
----@param state vim.SystemState
-local function close_handles(state)
- close_handle(state.handle)
- close_handle(state.stdin)
- close_handle(state.stdout)
- close_handle(state.stderr)
- close_handle(state.timer)
-end
-
--- @class vim.SystemObj
--- @field cmd string[]
--- @field pid integer
@@ -132,9 +123,7 @@ function SystemObj:write(data)
-- (https://github.com/neovim/neovim/pull/17620#discussion_r820775616)
stdin:write('', function()
stdin:shutdown(function()
- if stdin then
- stdin:close()
- end
+ close_handle(stdin)
end)
end)
end
@@ -146,25 +135,52 @@ function SystemObj:is_closing()
return handle == nil or handle:is_closing() or false
end
----@param output fun(err:string?, data: string?)|false
----@return uv.uv_stream_t?
----@return fun(err:string?, data: string?)? Handler
-local function setup_output(output)
- if output == nil then
- return assert(uv.new_pipe(false)), nil
+--- @param output? uv.read_start.callback|false
+--- @param text? boolean
+--- @return uv.uv_stream_t? pipe
+--- @return uv.read_start.callback? handler
+--- @return string[]? data
+local function setup_output(output, text)
+ if output == false then
+ return
end
+ local bucket --- @type string[]?
+ local handler --- @type uv.read_start.callback
+
if type(output) == 'function' then
- return assert(uv.new_pipe(false)), output
+ handler = output
+ else
+ bucket = {}
+ handler = function(err, data)
+ if err then
+ error(err)
+ end
+ if text and data then
+ bucket[#bucket + 1] = data:gsub('\r\n', '\n')
+ else
+ bucket[#bucket + 1] = data
+ end
+ end
end
- assert(output == false)
- return nil, nil
+ local pipe = assert(uv.new_pipe(false))
+
+ --- @type uv.read_start.callback
+ local function handler_with_close(err, data)
+ handler(err, data)
+ if data == nil then
+ pipe:read_stop()
+ pipe:close()
+ end
+ end
+
+ return pipe, handler_with_close, bucket
end
----@param input string|string[]|true|nil
----@return uv.uv_stream_t?
----@return string|string[]?
+--- @param input? string|string[]|boolean
+--- @return uv.uv_stream_t?
+--- @return string|string[]?
local function setup_input(input)
if not input then
return
@@ -208,28 +224,6 @@ local function setup_env(env, clear_env)
return renv
end
---- @param stream uv.uv_stream_t
---- @param text? boolean
---- @param bucket string[]
---- @return fun(err: string?, data: string?)
-local function default_handler(stream, text, bucket)
- return function(err, data)
- if err then
- error(err)
- end
- if data ~= nil then
- if text then
- bucket[#bucket + 1] = data:gsub('\r\n', '\n')
- else
- bucket[#bucket + 1] = data
- end
- else
- stream:read_stop()
- stream:close()
- end
- end
-end
-
local is_win = vim.fn.has('win32') == 1
local M = {}
@@ -255,9 +249,9 @@ local function spawn(cmd, opts, on_exit, on_error)
return handle, pid_or_err --[[@as integer]]
end
----@param timeout integer
----@param cb fun()
----@return uv.uv_timer_t
+--- @param timeout integer
+--- @param cb fun()
+--- @return uv.uv_timer_t
local function timer_oneshot(timeout, cb)
local timer = assert(uv.new_timer())
timer:start(timeout, 0, function()
@@ -273,7 +267,12 @@ end
--- @param signal integer
--- @param on_exit fun(result: vim.SystemCompleted)?
local function _on_exit(state, code, signal, on_exit)
- close_handles(state)
+ close_handle(state.handle)
+ close_handle(state.stdin)
+ close_handle(state.timer)
+
+ -- #30846: Do not close stdout/stderr here, as they may still have data to
+ -- read. They will be closed in uv.read_start on EOF.
local check = assert(uv.new_check())
check:start(function()
@@ -311,6 +310,15 @@ local function _on_exit(state, code, signal, on_exit)
end)
end
+--- @param state vim.SystemState
+local function _on_error(state)
+ close_handle(state.handle)
+ close_handle(state.stdin)
+ close_handle(state.stdout)
+ close_handle(state.stderr)
+ close_handle(state.timer)
+end
+
--- Run a system command
---
--- @param cmd string[]
@@ -324,8 +332,8 @@ function M.run(cmd, opts, on_exit)
opts = opts or {}
- local stdout, stdout_handler = setup_output(opts.stdout)
- local stderr, stderr_handler = setup_output(opts.stderr)
+ local stdout, stdout_handler, stdout_data = setup_output(opts.stdout, opts.text)
+ local stderr, stderr_handler, stderr_data = setup_output(opts.stderr, opts.text)
local stdin, towrite = setup_input(opts.stdin)
--- @type vim.SystemState
@@ -335,7 +343,9 @@ function M.run(cmd, opts, on_exit)
timeout = opts.timeout,
stdin = stdin,
stdout = stdout,
+ stdout_data = stdout_data,
stderr = stderr,
+ stderr_data = stderr_data,
}
--- @diagnostic disable-next-line:missing-fields
@@ -350,17 +360,15 @@ function M.run(cmd, opts, on_exit)
}, function(code, signal)
_on_exit(state, code, signal, on_exit)
end, function()
- close_handles(state)
+ _on_error(state)
end)
- if stdout then
- state.stdout_data = {}
- stdout:read_start(stdout_handler or default_handler(stdout, opts.text, state.stdout_data))
+ if stdout and stdout_handler then
+ stdout:read_start(stdout_handler)
end
- if stderr then
- state.stderr_data = {}
- stderr:read_start(stderr_handler or default_handler(stderr, opts.text, state.stderr_data))
+ if stderr and stderr_handler then
+ stderr:read_start(stderr_handler)
end
local obj = new_systemobj(state)
diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua
index 5d771c30e9..b4c37dd160 100644
--- a/runtime/lua/vim/filetype.lua
+++ b/runtime/lua/vim/filetype.lua
@@ -1873,6 +1873,8 @@ local filename = {
['.clang-tidy'] = 'yaml',
['yarn.lock'] = 'yaml',
matplotlibrc = 'yaml',
+ ['.condarc'] = 'yaml',
+ condarc = 'yaml',
zathurarc = 'zathurarc',
['/etc/zprofile'] = 'zsh',
['.zlogin'] = 'zsh',
diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua
index b1a3316e3e..4717d7995a 100644
--- a/runtime/lua/vim/lsp.lua
+++ b/runtime/lua/vim/lsp.lua
@@ -211,17 +211,117 @@ local function reuse_client_default(client, config)
return false
end
+--- Reset defaults set by `set_defaults`.
+--- Must only be called if the last client attached to a buffer exits.
+local function reset_defaults(bufnr)
+ if vim.bo[bufnr].tagfunc == 'v:lua.vim.lsp.tagfunc' then
+ vim.bo[bufnr].tagfunc = nil
+ end
+ if vim.bo[bufnr].omnifunc == 'v:lua.vim.lsp.omnifunc' then
+ vim.bo[bufnr].omnifunc = nil
+ end
+ if vim.bo[bufnr].formatexpr == 'v:lua.vim.lsp.formatexpr()' then
+ vim.bo[bufnr].formatexpr = nil
+ end
+ vim._with({ buf = bufnr }, function()
+ local keymap = vim.fn.maparg('K', 'n', false, true)
+ if keymap and keymap.callback == vim.lsp.buf.hover and keymap.buffer == 1 then
+ vim.keymap.del('n', 'K', { buffer = bufnr })
+ end
+ end)
+end
+
+--- @param code integer
+--- @param signal integer
+--- @param client_id integer
+local function on_client_exit(code, signal, client_id)
+ local client = all_clients[client_id]
+
+ vim.schedule(function()
+ for bufnr in pairs(client.attached_buffers) do
+ if client and client.attached_buffers[bufnr] and api.nvim_buf_is_valid(bufnr) then
+ api.nvim_exec_autocmds('LspDetach', {
+ buffer = bufnr,
+ modeline = false,
+ data = { client_id = client_id },
+ })
+ end
+
+ client.attached_buffers[bufnr] = nil
+
+ if #lsp.get_clients({ bufnr = bufnr, _uninitialized = true }) == 0 then
+ reset_defaults(bufnr)
+ end
+ end
+
+ local namespace = vim.lsp.diagnostic.get_namespace(client_id)
+ vim.diagnostic.reset(namespace)
+ end)
+
+ local name = client.name or 'unknown'
+
+ -- Schedule the deletion of the client object so that it exists in the execution of LspDetach
+ -- autocommands
+ vim.schedule(function()
+ all_clients[client_id] = nil
+
+ -- Client can be absent if executable starts, but initialize fails
+ -- init/attach won't have happened
+ if client then
+ changetracking.reset(client)
+ end
+ if code ~= 0 or (signal ~= 0 and signal ~= 15) then
+ local msg = string.format(
+ 'Client %s quit with exit code %s and signal %s. Check log for errors: %s',
+ name,
+ code,
+ signal,
+ lsp.get_log_path()
+ )
+ vim.notify(msg, vim.log.levels.WARN)
+ end
+ end)
+end
+
+--- Creates and initializes a client with the given configuration.
+--- @param config vim.lsp.ClientConfig Configuration for the server.
+--- @return integer? client_id |vim.lsp.get_client_by_id()| Note: client may not be
+--- fully initialized. Use `on_init` to do any actions once
+--- the client has been initialized.
+--- @return string? # Error message, if any
+local function create_and_initialize_client(config)
+ local ok, res = pcall(require('vim.lsp.client').create, config)
+ if not ok then
+ return nil, res --[[@as string]]
+ end
+
+ local client = assert(res)
+
+ --- @diagnostic disable-next-line: invisible
+ table.insert(client._on_exit_cbs, on_client_exit)
+
+ all_clients[client.id] = client
+
+ client:initialize()
+
+ return client.id, nil
+end
+
--- @class vim.lsp.start.Opts
--- @inlinedoc
---
--- Predicate used to decide if a client should be re-used. Used on all
--- running clients. The default implementation re-uses a client if name and
--- root_dir matches.
---- @field reuse_client? fun(client: vim.lsp.Client, config: vim.lsp.ClientConfig): boolean
+--- @field reuse_client? (fun(client: vim.lsp.Client, config: vim.lsp.ClientConfig): boolean)
---
--- Buffer handle to attach to if starting or re-using a client (0 for current).
--- @field bufnr? integer
---
+--- Whether to attach the client to a buffer (default true).
+--- If set to `false`, `reuse_client` and `bufnr` will be ignored.
+--- @field attach? boolean
+---
--- Suppress error reporting if the LSP server fails to start (default false).
--- @field silent? boolean
@@ -239,10 +339,10 @@ end
--- })
--- ```
---
---- See |vim.lsp.start_client()| for all available options. The most important are:
+--- See |vim.lsp.ClientConfig| for all available options. The most important are:
---
--- - `name` arbitrary name for the LSP client. Should be unique per language server.
---- - `cmd` command string[] or function, described at |vim.lsp.start_client()|.
+--- - `cmd` command string[] or function.
--- - `root_dir` path to the project root. By default this is used to decide if an existing client
--- should be re-used. The example above uses |vim.fs.root()| to detect the root by traversing
--- the file system upwards starting from the current directory until either a `pyproject.toml`
@@ -262,7 +362,7 @@ end
--- `ftplugin/<filetype_name>.lua` (See |ftplugin-name|)
---
--- @param config vim.lsp.ClientConfig Configuration for the server.
---- @param opts vim.lsp.start.Opts? Optional keyword arguments
+--- @param opts vim.lsp.start.Opts? Optional keyword arguments.
--- @return integer? client_id
function lsp.start(config, opts)
opts = opts or {}
@@ -271,6 +371,10 @@ function lsp.start(config, opts)
for _, client in pairs(all_clients) do
if reuse_client(client, config) then
+ if opts.attach == false then
+ return client.id
+ end
+
if lsp.buf_attach_client(bufnr, client.id) then
return client.id
else
@@ -279,7 +383,7 @@ function lsp.start(config, opts)
end
end
- local client_id, err = lsp.start_client(config)
+ local client_id, err = create_and_initialize_client(config)
if err then
if not opts.silent then
vim.notify(err, vim.log.levels.WARN)
@@ -287,6 +391,10 @@ function lsp.start(config, opts)
return nil
end
+ if opts.attach == false then
+ return client_id
+ end
+
if client_id and lsp.buf_attach_client(bufnr, client_id) then
return client_id
end
@@ -383,78 +491,7 @@ function lsp._set_defaults(client, bufnr)
end
end
---- Reset defaults set by `set_defaults`.
---- Must only be called if the last client attached to a buffer exits.
-local function reset_defaults(bufnr)
- if vim.bo[bufnr].tagfunc == 'v:lua.vim.lsp.tagfunc' then
- vim.bo[bufnr].tagfunc = nil
- end
- if vim.bo[bufnr].omnifunc == 'v:lua.vim.lsp.omnifunc' then
- vim.bo[bufnr].omnifunc = nil
- end
- if vim.bo[bufnr].formatexpr == 'v:lua.vim.lsp.formatexpr()' then
- vim.bo[bufnr].formatexpr = nil
- end
- vim._with({ buf = bufnr }, function()
- local keymap = vim.fn.maparg('K', 'n', false, true)
- if keymap and keymap.callback == vim.lsp.buf.hover and keymap.buffer == 1 then
- vim.keymap.del('n', 'K', { buffer = bufnr })
- end
- end)
-end
-
---- @param code integer
---- @param signal integer
---- @param client_id integer
-local function on_client_exit(code, signal, client_id)
- local client = all_clients[client_id]
-
- vim.schedule(function()
- for bufnr in pairs(client.attached_buffers) do
- if client and client.attached_buffers[bufnr] and api.nvim_buf_is_valid(bufnr) then
- api.nvim_exec_autocmds('LspDetach', {
- buffer = bufnr,
- modeline = false,
- data = { client_id = client_id },
- })
- end
-
- client.attached_buffers[bufnr] = nil
-
- if #lsp.get_clients({ bufnr = bufnr, _uninitialized = true }) == 0 then
- reset_defaults(bufnr)
- end
- end
-
- local namespace = vim.lsp.diagnostic.get_namespace(client_id)
- vim.diagnostic.reset(namespace)
- end)
-
- local name = client.name or 'unknown'
-
- -- Schedule the deletion of the client object so that it exists in the execution of LspDetach
- -- autocommands
- vim.schedule(function()
- all_clients[client_id] = nil
-
- -- Client can be absent if executable starts, but initialize fails
- -- init/attach won't have happened
- if client then
- changetracking.reset(client)
- end
- if code ~= 0 or (signal ~= 0 and signal ~= 15) then
- local msg = string.format(
- 'Client %s quit with exit code %s and signal %s. Check log for errors: %s',
- name,
- code,
- signal,
- lsp.get_log_path()
- )
- vim.notify(msg, vim.log.levels.WARN)
- end
- end)
-end
-
+--- @deprecated
--- Starts and initializes a client with the given configuration.
--- @param config vim.lsp.ClientConfig Configuration for the server.
--- @return integer? client_id |vim.lsp.get_client_by_id()| Note: client may not be
@@ -462,21 +499,8 @@ end
--- the client has been initialized.
--- @return string? # Error message, if any
function lsp.start_client(config)
- local ok, res = pcall(require('vim.lsp.client').create, config)
- if not ok then
- return nil, res --[[@as string]]
- end
-
- local client = assert(res)
-
- --- @diagnostic disable-next-line: invisible
- table.insert(client._on_exit_cbs, on_client_exit)
-
- all_clients[client.id] = client
-
- client:initialize()
-
- return client.id, nil
+ vim.deprecate('vim.lsp.start_client()', 'vim.lsp.start()', '0.13')
+ return create_and_initialize_client(config)
end
---Buffer lifecycle handler for textDocument/didSave
diff --git a/runtime/lua/vim/lsp/client.lua b/runtime/lua/vim/lsp/client.lua
index a14b6ccda6..a83d75bf75 100644
--- a/runtime/lua/vim/lsp/client.lua
+++ b/runtime/lua/vim/lsp/client.lua
@@ -78,7 +78,7 @@ local validate = vim.validate
--- @field settings? table
---
--- Table that maps string of clientside commands to user-defined functions.
---- Commands passed to start_client take precedence over the global command registry. Each key
+--- Commands passed to `start()` take precedence over the global command registry. Each key
--- must be a unique command name, and the value is a function which is called if any LSP action
--- (code action, code lenses, ...) triggers the command.
--- @field commands? table<string,fun(command: lsp.Command, ctx: table)>
@@ -104,7 +104,7 @@ local validate = vim.validate
--- @field on_error? fun(code: integer, err: string)
---
--- Callback invoked before the LSP "initialize" phase, where `params` contains the parameters
---- being sent to the server and `config` is the config that was passed to |vim.lsp.start_client()|.
+--- being sent to the server and `config` is the config that was passed to |vim.lsp.start()|.
--- You can use this to modify parameters before they are sent.
--- @field before_init? fun(params: lsp.InitializeParams, config: vim.lsp.ClientConfig)
---
@@ -167,7 +167,7 @@ local validate = vim.validate
--- @field requests table<integer,{ type: string, bufnr: integer, method: string}>
---
--- copy of the table that was passed by the user
---- to |vim.lsp.start_client()|.
+--- to |vim.lsp.start()|.
--- @field config vim.lsp.ClientConfig
---
--- Response from the server sent on `initialize` describing the server's
@@ -307,7 +307,7 @@ local function default_get_language_id(_bufnr, filetype)
return filetype
end
---- Validates a client configuration as given to |vim.lsp.start_client()|.
+--- Validates a client configuration as given to |vim.lsp.start()|.
--- @param config vim.lsp.ClientConfig
local function validate_config(config)
validate('config', config, 'table')
diff --git a/runtime/lua/vim/lsp/rpc.lua b/runtime/lua/vim/lsp/rpc.lua
index 6c8564845f..2327a37ab1 100644
--- a/runtime/lua/vim/lsp/rpc.lua
+++ b/runtime/lua/vim/lsp/rpc.lua
@@ -617,7 +617,7 @@ end
--- - a host and port via TCP
---
--- Return a function that can be passed to the `cmd` field for
---- |vim.lsp.start_client()| or |vim.lsp.start()|.
+--- |vim.lsp.start()|.
---
---@param host_or_path string host to connect to or path to a pipe/domain socket
---@param port integer? TCP port to connect to. If absent the first argument must be a pipe