News
Nvim :help pages, generated
from source
using the tree-sitter-vimdoc parser.
Notable changes since Nvim 0.12
For changes in the previous release, see
news-0.12.
====== Remove this section before release. ======
The following changes to UNRELEASED features were made during the development
cycle (Nvim HEAD, the "master" branch).
EVENTS
EXPERIMENTS
LSP
LUA
vim.pos, vim.range always require the buf parameter.
range.cursor() and range.to_cursor() are removed.
Use range.mark() and range.to_mark() instead.
pos.to_cursor() returns a (row, col) tuple
instead of returning them as separate values.
Renamed current_level param of vim.log.new().
vim.opt.{option}:get() has improved structure for dict-like options.
Some shapes changed:
"key:value" list options (e.g.
'diffopt',
'mousescroll') return a map
{ key = value } instead of an array of
"key:value" strings.
The
,, literal-comma convention (e.g.
'isfname') is not reconstructed in
the structured view; the raw string value is unchanged.
DIAGNOSTICS
OPTIONS
When
ui2 is enabled, since the ruler is no longer a left-aligned box of
fixed width, there is no longer an inconsistent special handling of item
groups in
'rulerformat' to configure that fixed width. An old-style left-
aligned fixed-width ruler can now be achieved by using item groups exactly
as they are documented, e.g.
%-20.20(...%).
TREESITTER
UI
Healthchecks for
vim.ui.img were moved to
:checkhealth vim.health.
VIMSCRIPT
These changes may require adaptations in your config or plugins.
API
API results containing a Lua function reference (e.g. a "callback" reported
by
nvim_get_keymap() or
nvim_get_autocmds(), or a "callback" option
value) are serialized over RPC as a human-readable
"<Lua …>" hint string,
instead of nil.
DIAGNOSTICS
vim.diagnostic.Opts.Status.format no longer accepts the table mapping
from severity to text. Use vim.diagnostic.Opts.Signs.text instead.
EDITOR
Interactive
Ex-mode (
:exmode,
nvim -e) is a persistent
cmdwin. This is much
more flexible and makes "Ex mode" more useful as a kind of "cmdline REPL",
with the tradeoff of dropping some POSIX Ex-mode quirks.
mode() returns "n" or "i"; "cv" indicates
-es (script mode) only.
Ex mode is entered with "1q:" or
:exmode, not "gQ".
":global/pat/visual" no longer switches to Normal mode per matching line.
Non-interactive Ex-mode (
-es, "script mode") executes stdin as Ex commands
directly. It is a "script host", not "POSIX Ex mode".
Output ends with a final newline.
:visual is
:edit: it does not switch to reading stdin as Normal-mode
commands, and ":global/pat/visual" does not enter Normal mode per
matching line.
Commands that wait for typed input (
input(),
getchar(), …) stop Nvim
at end-of-input instead of consuming the next stdin line.
An empty line is a no-op instead of advancing the cursor (or failing
with
E501 at end-of-file).
On Windows, the
trust db now stores paths with "/" slashes. This means the
trust store will be reset (one time).
stdpath("log") moved to stdpath("state")/logs.
Only supports one "cmdline level", not "infinite recursion".
ZR now performs
:restart. Add a count to change the behavior.
EVENTS
ui-messages msg_show.bufwrite and
msg_show.completion messages are now
msg_show.progress events.
LSP
vim.lsp.ClientConfig.cmd given as a string array now uses
vim.lsp.ClientConfig.root_dir as its default process working directory.
client.attached_buffers[buf] now stores languageId string (was boolean).
LUA
"standalone" Lua interpreter mode
nvim -ll was removed. Use
-l script
mode instead.
vim.opt no longer supports chaining multiple infix operators (e.g.
vim.opt.wildignore + '*.o' + '*.obj'). Instead, use tables:
vim.opt.wildignore + {'*.o', '*.obj'}
OPTIONS
The
'statusline' %= item is no longer ignored in item groups. It applies
to the containing item group and its
minwid.
An
%< item inside an item group now only applies to the containing group
and its
maxwid. Therefore, multiple
%< can now be effective.
The default truncation of item groups is now at the first contained item.
To restore the previous truncation from the left, add a
%< to the start.
The same applies to
'rulerformat',
'statuscolumn',
'tabline',
'winbar',
'titlestring', and
'iconstring'.
'rulerformat' can no longer be set empty, the new default expression will be
restored instead.
PLUGINS
TREESITTER
UI
The bottom right cell of the screen is no longer left empty when the ruler
is shown. This was originally intended to prevent unwanted scrolling on
quirky terminals.
VIMSCRIPT
The following new features were added.
API
api-contract treats
opts and any parameters thereafter, as optional
(equivalent to passing an empty dict). Clients may omit such optional
parameters.
The Lua
vim.api bridge is also a "client" and thus may omit
opts and
any following parameters:
-- Before:
vim.print(vim.api.nvim_get_mark('A', {}))
-- After:
vim.print(vim.api.nvim_get_mark('A'))
nvim_open_win() zindex controls whether the UI will use a dimmed cursor
shape when an unfocused float is on top of the cursor.
nvim_echo() distinguishes zero percent from omitted percent for Progress
events.
nvim_buf_set_extmark() virt_lines_overflow accepts "wrap" to enable
wrapping onto extra rows and "auto" which enables horizontal scrolling when
'nowrap' is set and wrapping when
'wrap' is set.
BUILD
Building using "zig build" requires zig 0.16.x.
zig build: "-Dcross" option was removed. Often cross-compilation is now
detected, so e.g. from a linux host:
zig build -Dtarget=aarch64-macos
will automatically compile a host Lua for use during build.
zig build: The new "-Dhost={target_string}" option can be used to override
the used host. Use "-Dhost=native" to force cross-compiling or "-Dhost="
(empty string) to assume that target binaries can run on the host during the
build process (e.g. if target is x86 on a x86_64 system, or if emulation set
up with binfmt or similar).
zig build: Nvim can now be built to produce a WebAssembly binary via
"-Dtarget=wasm32-emscripten", which can run inside a web browser. A basic
browser-based demo for running it is also included. Still very
experimental.
DEFAULTS
'rulerformat' default is exposed as a statusline expression (previously it
was implemented as an internal C routine).
DIAGNOSTICS
EDITOR
cmdwin (
q:,
q/,
q?,
c_CTRL-F) is implemented as a "normal"
buffer+window instead of a nested-state modal loop:
You can create/navigate windows/tabpages while cmdwin is active. Chaos!
API calls (e.g.
nvim_buf_delete()) that previously failed with
"E11: Invalid in command-line window" while cmdwin was open, now work
normally. Async plugins no longer need special
CmdwinLeave workarounds.
:restart saves/restores the current session (window layout, buffers, …).
:restart! (with a bang "!") does not save/restore the session.
:detach with range "%" detaches all UIs except the current one.
:detach! (with bang "!") marks the current UI as detachable: Nvim will
continue running if the UI disconnects unexpectedly (e.g. if you
accidentally close your terminal, ssh connection lost, etc.).
Use
:connect to reattach.
v_al and
v_il text objects select the whole buffer and the current line
without leading or trailing white space.
During
complete()-triggered completion,
CTRL-N and
CTRL-P are now subject
to insert-mode mappings.
Multibyte characters, translated by
'langmap', now invoke correct
mappings.
Example:
set langmap=õ]
Typing õõ in
Normal-mode now invokes a mapping bound to ]].
New
complete-items field "commit_chars": characters that accept the
selected completion item when typed.
EVENTS
ChanClose is triggered after a channel is closed, before it is removed.
TabMoved is triggered when tabs are reordered.
HIGHLIGHTS
Dimmed for text that should be de-emphasized.
LSP
LSP capabilities:
:checkhealth vim.lsp highlights the "current buffer".
Support for nested snippets.
lsp-completion supports
commitCharacters: typing a commit character
while a completion item is selected accepts the item as with
complete_CTRL-Y, then inserts the character. Previously
commitCharacters had no effect.
LUA
vim.ui.img can display images. Use
:checkhealth vim.health to confirm
your terminal supports it.
writefile() treats Lua and RPC strings as
Blob, so it can be used to
write binary data.
vim.fs.dir() with
opts.err=true, reports errors. An inaccessible root
dir yields a single (name, nil, err) item.
vim.fs.find() returns a list of errors as its second return value.
vim.fs.mkdir() creates directories, including parent directories with
opts.parents=true.
vim.fs.slug() generates a filesystem-safe file name from an arbitrary
identity string, with an optional length bound.
Added
__eq metamethod to
vim.VersionRange. 2 distinct but representing
the same range instances now compare equal.
Documentation for
vim.fn now points to preferred Lua alternatives when
available.
vim.pos can now convert between positions and buffer offsets.
vim.pos.cursor() without arguments returns the cursor position of the
current window.
vim.log provides a logging interface.
vim.o now accepts table style values for assignment.
OPTIONS
Lua functions/closures can be assigned to "func" and "expr" options:
option-value-function (e.g.
vim.o.operatorfunc),
expr-option-function
(e.g.
vim.wo.foldexpr,
vim.bo.indentexpr). Reading such an option:
...from Lua, gets the function itself.
...from Vimscript/RPC, gets a human-readable "<Lua …>" hint string.
'winpinned' prevents window from closing unless specifically targeted.
treesitter-highlight performance on large injection-heavy files improves
by 50% to 100% by reusing edited child-tree ranges.
Nvim architecture allows pure-Lua implementations of some vim.fn
functions, which skips the Vimscript <=> Lua "bridge" (no data
conversion/marshalling) entirely, if the vim.fn function is called from
Lua.
Internal LSP data is cleared using table.clear, which reduces GC and
memory reallocation during each data reset.
RPC client avoids string allocations when parsing Content-Length messages.
LSP: "overscan" semantic_token range requests to avoid flicker.
PLUGINS
The zip plugin is now
zip, a read-only archive browser built on
dir.
To use the legacy plugin instead:
:packadd old-zip
provider: add bun support for Node.js plugins
STARTUP
TERMINAL
TREESITTER
v_]N v_[N expand selection to sibling treesitter node.
The diff treesitter parser is bundled.
TUI
The TUI will re-query the terminal's background color when resuming from
a suspended state, and Nvim will update
'background' accordingly.
User can override the builtin "terminfo" via
$NVIM_TERMDEFS. This is
similar to Vim's
t_xx options.
UI
:checkhealth shows filewatcher info in the Performance section.
:browse oldfiles
VIMSCRIPT
fnamemodify(':h') preserves logical roots for more path formats.
v:starttime is the process start time (nanoseconds since UNIX epoch).
serverlist() with
info=true returns details for each server (own + peers).
These Vimscript functions may be called from
api-fast context (e.g.
vim.uv timer/handle callbacks):
keytrans(),
char2nr(),
nr2char(),
str2list(),
strpart(),
strcharpart(),
strgetchar(),
strchars(),
strcharlen(),
strlen(),
strdisplaywidth(),
byteidx(),
charidx(),
utf16idx(),
tr(),
trim().
These existing features changed their behavior.
nvim_exec_autocmds({buf=…}) runs in the context of the target buffer.
Editing a local directory now shows its contents in a
filetype=directory
buffer. See
dir.
:Open with no arguments uses the current file.
The "buffer" key was renamed to "buf" in these functions (but the old name
"buffer" is still accepted, for backwards compatibility):
Markdown inline highlighting now conceals the backslash in backslash escapes.
Markdown inline backslash escapes and hard line breaks no longer use the
@string.escape capture.
vim.fs.normalize() opts.expand_env=false key was renamed to
opts.plain=true and now does not expand leading tildes ("~") in addition
to environment variables ("expand_env" is still accepted, for backwards
compatibility).
These deprecated features were removed.