11121 Commits

Author SHA1 Message Date
tao
4a08596314 fix(path): normalize separators (slashes) #39155
Problem:
Continue separators normalization, and try to keep it at the
nvim <-> external boundary, e.g., `fn.xxx`, `api.xxx`, `:xxx`

Solution:
some key changes
- normalize `$HOME-windows`
- normalize entry points of changing directory
  - `nvim_set_current_dir()`, `chdir()`
- normalize the named pipe
  - `--listen` arg, `--server` arg, `:restart`
  - `serverstart()`, `sockconnect()`, `serverstop()`
- make `expand()` respect 'shellslash' again
- clean up `did_set_shellslash`
- replace `forward_slash` with `TO_SLASH`
- remove obsolete `TMP_PATHSEPSTR`
- remove `slash_adjust` in `do_autocmd_dirchanged`?
- make `fnamemodify()` always return `/` (except when substituting
  separators via `:s`, `:gs` ?)

Note:
- these funcs still apply `slash_adjust` on return, as before:
  `:pwd`, `chdir()`, `exepath()`, `getcwd()`
- these funcs alwarys return `/`, unlike before the normalization PRs
  - `getcompletion()`, `finddir()`, `findfile()`

Also
- clean up code, comments, formatting and tests
- move `TO_SLASH` from `f_chdir` to `changedir_func`
- move `TO_SLASH` from `f_bufadd` to `buflist_new`

Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
2026-07-12 13:23:44 -04:00
Kim A. Brandt
543a96e491 fix(lsp): unclear error on malformed server responses #40422
Problem:
Malformed server responses with `null` (vim.NIL) values, do not show
clear error messages.


Solution:
Assert two known, specific cases, to avoid user confusion.
2026-07-12 12:52:10 -04:00
Justin M. Keyes
81c4c295ac refactor(insert): rename edit.c => insert.c #40705
Problem:
- `edit.c` is an unnecessarily misleading and less-discoverable name
  than `insert.c`.
- Numerous insert-mode related things are named with a `ins_` prefix.
- There is already a `insexpand.c` module...

Solution:
Rename `edit.c` => `insert.c`.
2026-07-12 11:57:17 -04:00
Barrett Ruth
41294e4253 docs(dir): remove augroup deletion note #40696 2026-07-11 18:20:27 -04:00
Barrett Ruth
67af4141c8 fix(filetype): false positive when matching directory buffer #40695
Problem:
URI buffer names can end with a slash, but slash-ended directory
matching should not preempt URI filetype patterns.

Solution:
Do not use the slash shortcut for names with URI schemes, so those
continue through normal filetype matching.

Co-authored-by: Adam Karafyllidis <akisarou90@gmail.com>
2026-07-11 18:19:44 -04:00
Justin M. Keyes
8d51e07fa1 feat(eval): writefile() treats RPC string as "blob"
related: fb6aeaba2d
2026-07-11 13:49:52 +02:00
glepnir
59dbca9b0c fix(api): nvim_cmd() "args" type too narrow #40670
Problem: nvim_cmd() accepts number/boolean in args and converts them
to strings, but the keyset declares ArrayOf(String).

Solution: use ArrayOf(Union(Integer, String, Boolean)) and wrap union
types in parens when generating array annotations.
2026-07-10 20:34:08 -04:00
Barrett Ruth
3b88a8a65d fix(filetype): ensure directory bufname ends w/ slash sep #40552
Problem:
`vim.filetype.match()` needs a cheap way to recognize directory buffers
without doing filesystem stat work.

Solution:
Ensure full buffer names for directories end in a trailing slash. Now
directory buffers can proceed through the normal 'filetype' path.

Note side-effects: session and ShaDa buffer-list restore behavior must
be compatible, so those + corresponding tests must be updated.
2026-07-10 12:40:13 -04:00
Barrett Ruth
20a4b1bc5e fix(dir): user/plugin can override default "-" mapping #40676 2026-07-10 11:52:24 -04:00
Barrett Ruth
7dccbfed10 fix(dir): select origin on parent navigation #40658 2026-07-09 17:47:56 -04:00
Barrett Ruth
a54a7f6a78 fix(dir): preserve alternate buffer #40659 2026-07-09 15:41:09 -04:00
Nathan Zeng
c0a16a5977 feat(restart)!: ZR restores session #40498 2026-07-09 07:09:12 -04:00
Evgeni Chasnovski
fce6d9a549 feat(lua): add cwd context to vim._with() #40653
Problem: No concise way to execute a callback with temporarily set
  working directory. This might be useful when sourcing nested files to
  allow them to assume that current working directory is their root
  directory.

Solution: Add `cwd` context to `vim._with().`
2026-07-09 07:07:14 -04:00
Justin M. Keyes
d55252a3ec refactor(logging)!: rename current_level #40642 2026-07-08 20:15:42 +00:00
Evgeni Chasnovski
0653e7a338 feat(pack): 'packlockfile' option #40562
Problem: No way to configure the lockfile location.

Solution: Add 'packlockfile' option.
2026-07-08 12:23:28 -04:00
Oleh Volynets
ef130902cf fix(lsp): clear push diagnostics on detach #40634
Problem: when an LS client detaches from the buffer, only pull diagnostics
are cleared via capability framework. Push diagnostics remain stuck even
when client stops/restarts.

Solution: clear push diagnostics on client detach.

ref #33864
2026-07-08 12:00:21 -04:00
Caleb White
653f2092ce fix(lsp): refresh document-pull buffers on workspace/diagnostic/refresh #40623
When a server supports both document and workspace pull diagnostics,
`on_refresh` only dispatched a `workspace/diagnostic` request.  The
workspace response handler skips buffers with `pull_kind == "document"`
(i.e. all buffers opened by the user), so their diagnostics went stale
until the next `didChange` or `didOpen` event.

Change `on_refresh` to always refresh document-pull buffers via
`textDocument/diagnostic`, regardless of whether the server also
supports workspace diagnostics.  This ensures that opened buffers
see updated diagnostics (e.g. after a save triggers an external
tool like PHPStan) without requiring the user to re-enter insert
mode.
2026-07-08 07:26:22 -04:00
Barrett Ruth
cfd7f29d52 feat(vim.fs): vim.fs.mkdir() #40599
Problem:
`vim.fs` does not provide a directory creation helper matching its
filesystem API shape.

Solution:
Add `vim.fs.mkdir()` as a thin wrapper around `vim.fn.mkdir()`, with
`parents` and `mode` options.
2026-07-08 07:16:29 -04:00
jdrouhard
6a6431cb99 refactor(lsp): use LspNotify for codelens #40604
Problem: The codelens LSP module was using its own raw buffer events and
its own debounce mechanism for refreshing code lens in attached buffers.

Solution: Switch the module to using the LspNotify autocmd events.
LspNotify fires just after document versions are synced with the server
and provides a built in debounce mechanism for changes.

Additionally, this fixes some bugs with the previous implementation:

1. The workspace/codeLens/refresh handler  re-requested codelens for all
   buffers but when the response came back, it forced an extra redraw
   after clearing the work the handler had just done.
2. Document synchronization was reworked to be more resilient to
   multiple clients providing codelens for a single buffer. The latest
   document version is now separately tracked per client (and per
   client's lenses per row) instead of for the buffer as a whole. This
   allows the on_win() function to properly redraw all codelens even
   when different clients' responses for a particular document version
   come back at different times.
2026-07-07 12:23:59 -04:00
Justin M. Keyes
a6d7193f07 refactor(lua): rename nlua_call_typval 2026-07-06 22:17:25 +02:00
Barrett Ruth
a6827be98f fix(man.lua): cache pages until width changes #40607
Problem: :Man unloads hidden buffers, so reopening large pages reruns rendering
even when the width is unchanged.

Solution: keep regular man buffers loaded and refresh them only when the
effective width changes.
2026-07-06 06:45:10 -04:00
Nathan Zeng
47958bb4db fix(:restart): remove -S [file] from v:argv #40521
Problem:
Session files specified at startup `-S [file]`, logically conflict
with `:restart`.

Solution:
Remove `-S [file]` from `v:argv` when doing :restart.
Also for the "bang" variant `:restart!`, just because it's
simpler (if anyone reports a use-case later, we can revisit).
2026-07-05 17:53:45 -04:00
Justin M. Keyes
8dfe4d6629 fix(api): nvim_win_resize tweaks #40596 2026-07-05 13:22:16 -04:00
jdrouhard
1f18ea1cf7 feat(lsp): convert inlay_hint to capability framework #40569
Problem:
Inlay hints used separate global and per-buffer bufstates tables and
bespoke global autocmds for managing the inlay hint state across buffers
and clients, duplicating the lifecycle logic already provided by the
Capability framework. This caused inconsistencies in how client state
was handled and inlay hint state lifecycle was managed compared to other
LSP features.

Solution:
Replace the ad-hoc bufstate tracking and global autocmds in
vim.lsp.inlay_hint with a proper InlayHint subclass of Capability.

This also refactors the way inlay hint state is managed and fixes bugs I
found while doing this:

1. For each line with inlay hints, the list of the hints along with
   whether they have been applied is stored in a current result on the
   client state. This allows the on_win decorator to clear all inlay
   hints for an old document version once, and then re-add the new
   version's hints line-by-line as they are drawn to the screen,
   modeling the semantic tokens module.
2. It fixes problems with mixing results from multiple clients attached
   to the buffer by fully moving each client's state to its own table.
   Previously, only the most recent document version used to populate a
   line's inlay hints was stored, but there was no distinction for which
   client the hints may have come from. (Fixes #36318)
3. It fixes the workspace/inlayHint/refresh server->client notification
   behavior. Previously it would only re-request inlay hints for buffers
   currently displayed in a window but would not invalidate them in
   non-displayed buffers (or provide any mechanism for those buffers to
   re-request at a later time). Model semantic token module here again
   by invalidating all buffers, and adding a BufWinEnter autocmd to
   refresh hints.
4. Add a mechanism to cancel in-flight requests if a new request for a
   newer document version is made before the last one returned
5. Handle stale results by simply dropping them.
2026-07-05 12:47:30 -04:00
Justin M. Keyes
a0fd59352a Merge #40520 nvim_win_resize 2026-07-05 12:06:13 -04:00
XiaowenHu96
ce718e31f4 feat(api): add nvim_win_resize()
Ref #6645

Problem:
When a window is resized it takes space from the window right/below first,
and only falls back to the window left/above when there is no more room.
Sometimes a user wants the space to come from a specific direction.

Solution:
Add nvim_win_resize(win, width, height, {anchor}) which resizes a window
with a choosable anchor edge, letting a window grow leftwards or upwards
by taking space from the window to the left or above first. The default
anchor reproduces nvim_win_set_width()/nvim_win_set_height().
2026-07-05 21:47:34 +08:00
Barrett Ruth
81e01a80b9 fix(lsp): support -1 column in format range #40570
Problem:
`vim.lsp.buf.format()` accepts ranges using nvim indexing, where an
end column of -1 means end of line. LSP ranges cannot use that,
which is confusing for things like range formatting.

Solution:
Resolve -1 end columns to the line length before converting the range to
LSP positions.
2026-07-05 06:14:55 -04:00
dqnne
0f86ea5ed8 fix(health): always set 'modifiable' #40584
Problem:
When buffers are by default `nomodifiable`, such as when Nvim starts with
`-M`, the health buffer cannot be updated.

Solution:
Always set `modifiable` before modifying the buffer.
2026-07-05 06:09:27 -04:00
Nathan Zeng
656b4d9c34 docs(restart): use 'sessionoptions' to adjust :restart behavior #40583 2026-07-05 05:52:49 -04:00
Barrett Ruth
1aced004ce fix(health): don't check node package via yarn #40572 2026-07-04 16:10:55 -04:00
Barrett Ruth
d0a262db88 feat(channel): add ChanClose event #40568
Problem:
Plugins using RPC sockets cannot detect when the peer closes a
`sockconnect()` channel, so reconnect logic has no reliable trigger.

Solution:
Add a `ChanClose` event with channel info before the channel is removed,
matching the existing `ChanOpen`/`ChanInfo` event model.
2026-07-04 15:21:25 -04:00
jdrouhard
f0559997dd fix(lsp): semantic tokens reset_timer() usage #40554
Problem: reset_timer() was being called without checking for whether the
client state for the client_id still existed. debounce_request() starts
a timer that defers a call to send_request() which then calls
reset_timer(). If the timer fires after the client_state is erased, then
the deferred function attempts to dereference the timer on a nil client
state.

Solution: Change reset_timer to take a state directly so it can't be nil
and move the reset_timer() call inside a guard that ensures state
exists. Additionally, reset a client's timer when the client detaches so
it doesn't become dangling.
2026-07-04 11:22:34 -04:00
jdrouhard
29db6ce84c fix(lsp): use LspNotify for document_color #40571
Problem: The document_color lsp module was already using the capability
framework but was still using raw buffer events to handle requests and
reloading. This means that every keystroke was sending a document_color
request to the server since there was no debounce in the raw handlers.

Solution: Switch to using LspNotify autocmd events. LspNotify fires just
after new document versions are synced with the server and provides a
built in debounce mechanism for changes. It also provides the signal for
when the current state should be cleared (didClose). The detach part is
already handled by the capability framework.

Fixes #39785
2026-07-04 09:29:05 -04:00
Barrett Ruth
6cbc5ea13d docs(lsp): document rpc Client request/notify as fields #40573
Problem:
`request()` and `notify()` are methods of the object returned by
`vim.lsp.rpc.start()`/`connect()`, but were rendered with module-level
helptags (`vim.lsp.rpc.request()`, `vim.lsp.rpc.notify()`) (erroneously
implying module functions that do not exist).

Solution:
Mark the wrappers `@private` and describe them on `vim.lsp.rpc.Client` instead.
2026-07-04 09:24:25 -04:00
STG
abedbfc175 fix(cmdwin): set 'noscrollbind' #40556
Problem:
Opening cmdwin from a 'scrollbind' window makes cmdwin scrollbinded.
Legacy cmdwin set 'noscrollbind'.

Solution:
Set 'noscrollbind'.
2026-07-04 07:29:26 -04:00
Barrett Ruth
7325e3b55a fix(dir): define "-" (up/parent) mapping earlier #40531
Problem:
The dir.lua "-" mapping cannot be easily overridden (because of autocmd
ordering).

Solution:
- Move it to defaults.lua.
- Also to be extra polite: fall back to builtin `-` motion if the user
  disabled the `dir.lua` plugin.
2026-07-02 15:55:48 -04:00
nikolightsaber
3f8be434e1 docs: pos argument in vim.lsp.ListOpts should be optional #40550
Problem: the pos argument in ListOps for lsp is an optional parameter,
but the lua_ls typing system doesn't reflect that

Solution: let pos be optional

Co-authored-by: nikolightsaber <nikolightsaber@gmail.com>
2026-07-02 15:25:44 -04:00
Evgeni Chasnovski
25d33dd12b fix(pack): do not assert non-nil stderr #40544
Problem: On some systems `stderr` can be disabled. This results in not
  usable `vim.pack` since it asserted `stderr` to be non-nil.

Solution: Stop asserting non-nil `stderr`. The downside is that
  potential errors are not shown, but this is intentional since `stderr`
  is disabled on system level.

  Still assert non-nil `stdout` as its output is important for
  `vim.pack` to actually do its job. Disabled `stdout` is not something
  that can work with `vim.pack`.
2026-07-02 12:12:35 -04:00
zeertzjq
0d0772c937 vim-patch:d859e12: runtime(xml): Update xml syntax file
Improve performance

related: chrisbra/vim-xml-runtime#36

d859e128a8

Co-authored-by: Christian Brabandt <cb@256bit.org>
Co-Authored-by: Dmytro Meleshko <dmytro.meleshko@gmail.com>
2026-07-02 08:14:48 +08:00
zeertzjq
6f4ebdad80 vim-patch:a65741c: runtime(screen): Bring the syntax up to version 5
* Match command names introduced in v.5.0.0 (August 2024):
  "auth", "multiinput", "status", "truecolor".
* Match command names introduced in v.4.5.0 (January 2017):
  "defdynamictitle" and "dynamictitle".
* Deprecate command names that have been retired thus far:
  "debug", "maxwin", "nethack", "password", "time".
* Remove a spurious "defzombie" command name (this name is
  just lamented over in the documentation entry for the
  "zombie" command as being more fitting than "zombie"
  because its effects are not local to a window; no such
  name is entered in "comm.c").
* Separately group the Braille navigation commands, "bd_*",
  that may belong to another, superset program Dotscreen:
  (see doc/README.DOTSCREEN and commit 848af83f5 elsewhere).
* Revise string escape characters:
    - Recognise more characters, "%[`<>=eEfFHOPSxX]".
    - Recognise undocumented characters, "%[gNpT]", and list
      relevant Screen commits in the comments.
    - Match optional qualifiers, "%\%([-+L]\|\d\+\).".
* Match more items in double-quoted command arguments.
* Match unquoted environment variable references.
* Match octal numbers, e.g. "defmode 0622".
* Match escaped octal numbers, e.g. "bind \077 help".

Unless a Dotscreen program (c. 1995) or an older than
v.4.3.1 (c. 2015) Screen program, that was compiled with
"HAVE_BRAILLE" defined, is installed and needs configuring,
add to ".vim/after/syntax/screen.vim":
-----------------------------------------------------------
if hlexists('dotscreenCommands')
    syn clear dotscreenCommands
endif
-----------------------------------------------------------

To BACKPORT the updated syntax file to version 4 of Screen,
add to ".vim/after/syntax/screen.vim":
-----------------------------------------------------------
if hlexists('screenDeprecatedCommands')
    syn clear screenDeprecatedCommands
endif

if hlexists('screenVersion5Commands')
    syn clear screenVersion5Commands
endif
-----------------------------------------------------------

References:
https://lists.gnu.org/archive/html/info-gnu/2024-08/msg00004.html
https://lists.gnu.org/archive/html/info-gnu/2017-01/msg00007.html
https://git.savannah.gnu.org/git/screen.git

closes: vim/vim#20550

a65741c8b3

Co-authored-by: Aliaksei Budavei <0x000c70@gmail.com>
Co-authored-by: Dmitri Vereshchagin <dmitri.vereshchagin@gmail.com>
2026-07-02 08:14:48 +08:00
zeertzjq
567053bb3c vim-patch:dd89754: runtime(typst): Improve ftplugin, and syntax file
- Move whitespace formatting settings from the indent to the filetype
  plugin behind a "typst_recommended_style" config option.
- Set browsefilter
- Improve syntax file

Thanks to Maxim Kim for taking on maintainership of the typst runtime
files.

related: vim/vim#20036
closes:  vim/vim#20077

dd8975428b

Co-authored-by: Doug Kearns <dougkearns@gmail.com>
Co-authored-by: Maxim Kim <habamax@gmail.com>
2026-07-02 08:14:48 +08:00
zeertzjq
6003545f38 vim-patch:9.2.0761: runtime(netrw): Unix: unable to open '\' file (#40533)
Problem:  runtime(netrw): Unix: unable to open '\' file
Solution: Adjust directory pattern (Manoj Panda)

closes: vim/vim#20685

86d8af37ba

Co-authored-by: Manoj Panda <manojpandawork@gmail.com>
2026-07-01 23:45:14 +00:00
Barrett Ruth
daa229bfde fix(dir): restore loaded plugin guard #40528 2026-07-01 14:45:55 -04:00
Justin M. Keyes
12ea9735f7 refactor(path): path_skip_sep() #40524
Problem:
Redundant code.

Solution:
Add path_skip_sep() and use it.

Dropping MB_PTR_ADV is safe: the loops only advance while `*p` is
a one-byte separator (`/`, `\`, `:`). MB_PTR_ADV was needed in legacy
Vim because it supported non-UTF-8 (DBCS) *internal* encodings.
2026-07-01 09:48:54 -04:00
tao
fa9b3381bc feat(path): fnamemodify(':h') preserves logical root #40447
Problem:
On Windows, `fnamemodify('//foo/C$', ':h')` incorrectly removes `C$`
as a regular file name and returns `//foo`. However, this is a valid
UNC path, `foo` is a server name and `C$` is a share name.
The correct result should be `//foo/C$`.

Solution:
Extend `os_fileinfo2` and `FileInfo` with `prefix_off`, `rest_off` to
identify path types and logical root boundaries. ':h' can use this info
to prevent traversing past the logical root.

Examples:
  /foo               => /
  //foo              => // (POSIX)
  //foo/bar          => //foo (POSIX)
  //server/share/foo => //server/share/ (Windows)
  C:/foo             => C:/
  //?/C:/foo         => //?/C:/

Co-authored-by: Barrett Ruth <br@barrettruth.com>
2026-07-01 08:25:21 -04:00
Justin M. Keyes
ed9a1c0b15 fix(health): handle failed dir listing 2026-07-01 13:27:07 +02:00
Justin M. Keyes
34efdadb4e feat(health): report ulimit info
Problem:
Nvim shows `(libuv) kqueue(): Too many open files` on macos.
ref https://github.com/neovim/neovim/issues/40238

Solution:
Add a healthcheck for this situation.
2026-07-01 13:26:21 +02:00
Justin M. Keyes
1035a9fb5d refactor(dir): use vim.fs.dir() 2026-07-01 13:01:02 +02:00
Justin M. Keyes
971a0a0fe0 feat(vim.fs): dir() ergonomics 2026-07-01 13:00:06 +02:00
Justin M. Keyes
f141916e3d fix(vim.fs): dir(), find() error-reporting 2026-07-01 12:05:41 +02:00