<feed xmlns='http://www.w3.org/2005/Atom'>
<title>rneovim.git/test/functional/plugin/lsp_spec.lua, branch master</title>
<subtitle>Neovim fork with Rahm's personal hacks.</subtitle>
<link rel='alternate' type='text/html' href='http://git.josher.dev/rneovim.git/'/>
<entry>
<title>perf(lua): share compatible file watchers</title>
<updated>2026-09-24T19:36:55+00:00</updated>
<author>
<name>Lewis Russell</name>
<email>lewis6991@gmail.com</email>
</author>
<published>2026-09-07T15:21:52+00:00</published>
<link rel='alternate' type='text/html' href='http://git.josher.dev/rneovim.git/commit/?id=c4efa259b4aa0bfee0c40a5b67fe5da548f51d85'/>
<id>c4efa259b4aa0bfee0c40a5b67fe5da548f51d85</id>
<content type='text'>
Problem:

LSP servers can register identical file watchers before removing old
registrations. Each registration creates another watcher tree, making
setup and teardown expensive in large workspaces.

Solution:

Move glob compilation into vim._watch and accept rules for multiple
roots alongside existing single-path and LPeg inputs. Share compatible
backends until their last subscription is cancelled.

Ref: #23291

AI-assisted
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Problem:

LSP servers can register identical file watchers before removing old
registrations. Each registration creates another watcher tree, making
setup and teardown expensive in large workspaces.

Solution:

Move glob compilation into vim._watch and accept rules for multiple
roots alongside existing single-path and LPeg inputs. Share compatible
backends until their last subscription is cancelled.

Ref: #23291

AI-assisted
</pre>
</div>
</content>
</entry>
<entry>
<title>fix(lsp): stale client when rpc.connect fails #41792</title>
<updated>2026-09-09T17:31:26+00:00</updated>
<author>
<name>stenja</name>
<email>stenja@users.noreply.github.com</email>
</author>
<published>2026-09-09T17:31:26+00:00</published>
<link rel='alternate' type='text/html' href='http://git.josher.dev/rneovim.git/commit/?id=a55f134ee305ebf3cb75149025c5e75f5e2090e0'/>
<id>a55f134ee305ebf3cb75149025c5e75f5e2090e0</id>
<content type='text'>
Problem:
When vim.lsp.rpc.connect is used for an LSP and the connection fails
(due to ECONNREFUSED, for example), the LSP client is left
uninitialized. Subsequent calls to vim.lsp.start will reuse the
uninitialized client, but no new connection will be attempted.

Solution:
When vim.lsp.rpc.connect encounters a connection error, terminate the
client. This allows the user to do something in response to the failed
connection in the on_exit callback, and also makes it so subsequent
attempts to start the LSP will try to establish a new connection rather
than using the previous uninitialized client.

Co-authored-by: Jason Stenftenagel &lt;jasonstenftenagel@gmail.com&gt;</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Problem:
When vim.lsp.rpc.connect is used for an LSP and the connection fails
(due to ECONNREFUSED, for example), the LSP client is left
uninitialized. Subsequent calls to vim.lsp.start will reuse the
uninitialized client, but no new connection will be attempted.

Solution:
When vim.lsp.rpc.connect encounters a connection error, terminate the
client. This allows the user to do something in response to the failed
connection in the on_exit callback, and also makes it so subsequent
attempts to start the LSP will try to establish a new connection rather
than using the previous uninitialized client.

Co-authored-by: Jason Stenftenagel &lt;jasonstenftenagel@gmail.com&gt;</pre>
</div>
</content>
</entry>
<entry>
<title>feat(watch): add on_error callback</title>
<updated>2026-09-09T10:39:57+00:00</updated>
<author>
<name>Lewis Russell</name>
<email>lewis6991@gmail.com</email>
</author>
<published>2026-09-07T15:21:52+00:00</published>
<link rel='alternate' type='text/html' href='http://git.josher.dev/rneovim.git/commit/?id=efdd73c0962cf46889d2e043efb892cf3ec432b7'/>
<id>efdd73c0962cf46889d2e043efb892cf3ec432b7</id>
<content type='text'>
Problem: Watcher failures are reported inconsistently, and callers
cannot detect when a watcher is no longer usable.

Solution: Route startup and event failures and unexpected inotifywait
exits through an optional on_error callback. Log to nvim-watch.log by
default. Ignore disappearing child directories and exits caused by
cancellation. Let LSP log failures and notify once per message, using
INFO for missing roots and ERROR otherwise, without interrupting
registration.

AI-assisted
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Problem: Watcher failures are reported inconsistently, and callers
cannot detect when a watcher is no longer usable.

Solution: Route startup and event failures and unexpected inotifywait
exits through an optional on_error callback. Log to nvim-watch.log by
default. Ignore disappearing child directories and exits caused by
cancellation. Let LSP log failures and notify once per message, using
INFO for missing roots and ERROR otherwise, without interrupting
registration.

AI-assisted
</pre>
</div>
</content>
</entry>
<entry>
<title>fix(lsp): completion dynamicRegistration breaks capability readers #41771</title>
<updated>2026-09-08T09:48:38+00:00</updated>
<author>
<name>glepnir</name>
<email>glephunter@gmail.com</email>
</author>
<published>2026-09-08T09:48:38+00:00</published>
<link rel='alternate' type='text/html' href='http://git.josher.dev/rneovim.git/commit/?id=b3bd442c5c3cb5f4392c7a15bff12cd412c23872'/>
<id>b3bd442c5c3cb5f4392c7a15bff12cd412c23872</id>
<content type='text'>
Problem:
A server that supports dynamic registration must not also declare
completionProvider at initialize, so server_capabilities.completionProvider
is nil for anything reading it directly.

Solution:
Do not advertise it by default. A client that follows a registration can
declare it itself.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Problem:
A server that supports dynamic registration must not also declare
completionProvider at initialize, so server_capabilities.completionProvider
is nil for anything reading it directly.

Solution:
Do not advertise it by default. A client that follows a registration can
declare it itself.</pre>
</div>
</content>
</entry>
<entry>
<title>feat(lsp): support dynamic registration of completionProvider #41748</title>
<updated>2026-09-07T13:53:35+00:00</updated>
<author>
<name>glepnir</name>
<email>glephunter@gmail.com</email>
</author>
<published>2026-09-07T13:53:35+00:00</published>
<link rel='alternate' type='text/html' href='http://git.josher.dev/rneovim.git/commit/?id=937f835a3e4338f7dbdb9117b74e477e1e5748f5'/>
<id>937f835a3e4338f7dbdb9117b74e477e1e5748f5</id>
<content type='text'>
Problem:
dynamicRegistration is declared false, and completionProvider is read
from server_capabilities only.

Solution:
Declare it, and prefer registerOptions per field.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Problem:
dynamicRegistration is declared false, and completionProvider is read
from server_capabilities only.

Solution:
Declare it, and prefer registerOptions per field.</pre>
</div>
</content>
</entry>
<entry>
<title>fix(lsp): blank line before Content-Length breaks header parsing #41524</title>
<updated>2026-08-29T13:13:04+00:00</updated>
<author>
<name>Yanze Li</name>
<email>liyzunique@gmail.com</email>
</author>
<published>2026-08-29T13:13:04+00:00</published>
<link rel='alternate' type='text/html' href='http://git.josher.dev/rneovim.git/commit/?id=ab707262b1ca4d5b9891f43ca18a59b0dd4154fe'/>
<id>ab707262b1ca4d5b9891f43ca18a59b0dd4154fe</id>
<content type='text'>
Problem:
A blank line before the Content-Length header makes header parsing
fail with "Content-Length not found in header". An LF in the 'name'
state falls through to the 'invalid' state, which only return to
'name' at the *next* LF. That LF terminates the next line, so the
line with Content-Length is swallowed.
The same issue happens when a junk line is a partial match of the
header name (e.g. "Cont\nContent-Length: ...").

Solution:
When seeing an LF in the 'name' state, reset the cursor and stay in
'name' rather than entering 'invalid'.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Problem:
A blank line before the Content-Length header makes header parsing
fail with "Content-Length not found in header". An LF in the 'name'
state falls through to the 'invalid' state, which only return to
'name' at the *next* LF. That LF terminates the next line, so the
line with Content-Length is swallowed.
The same issue happens when a junk line is a partial match of the
header name (e.g. "Cont\nContent-Length: ...").

Solution:
When seeing an LF in the 'name' state, reset the cursor and stay in
'name' rather than entering 'invalid'.</pre>
</div>
</content>
</entry>
<entry>
<title>revert: "fix(lsp): do not expand $VAR in tagfunc filenames" #41489</title>
<updated>2026-08-25T18:09:02+00:00</updated>
<author>
<name>Justin M. Keyes</name>
<email>justinkz@gmail.com</email>
</author>
<published>2026-08-25T18:09:02+00:00</published>
<link rel='alternate' type='text/html' href='http://git.josher.dev/rneovim.git/commit/?id=aae43789d7d857bfdd6462520d0c3a6cc6129d07'/>
<id>aae43789d7d857bfdd6462520d0c3a6cc6129d07</id>
<content type='text'>
revert c5cb0350a6dc578e6ca73eefdd58159e1e039cbf</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
revert c5cb0350a6dc578e6ca73eefdd58159e1e039cbf</pre>
</div>
</content>
</entry>
<entry>
<title>fix(lsp): do not expand $VAR in tagfunc filenames #41398</title>
<updated>2026-08-23T15:30:17+00:00</updated>
<author>
<name>Shubh</name>
<email>shubh@shubhxho.com</email>
</author>
<published>2026-08-23T15:30:17+00:00</published>
<link rel='alternate' type='text/html' href='http://git.josher.dev/rneovim.git/commit/?id=c5cb0350a6dc578e6ca73eefdd58159e1e039cbf'/>
<id>c5cb0350a6dc578e6ca73eefdd58159e1e039cbf</id>
<content type='text'>
Problem:
CTRL-] via lsp tagfunc passes URI paths through :tag, which expands
\$VAR, so files like people_.\$personId.tsx fail with E429.

Solution:
fnameescape() the filename in tag items so \$ is treated as literal.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Problem:
CTRL-] via lsp tagfunc passes URI paths through :tag, which expands
\$VAR, so files like people_.\$personId.tsx fail with E429.

Solution:
fnameescape() the filename in tag items so \$ is treated as literal.</pre>
</div>
</content>
</entry>
<entry>
<title>feat(lsp): fallback to textDocument/formatting from vim.lsp.formatexpr #40079</title>
<updated>2026-08-18T09:16:16+00:00</updated>
<author>
<name>Marcus Caisey</name>
<email>marcus@teckna.com</email>
</author>
<published>2026-08-18T09:16:16+00:00</published>
<link rel='alternate' type='text/html' href='http://git.josher.dev/rneovim.git/commit/?id=d9b4fb1273fd4649593926451121d416154738b1'/>
<id>d9b4fb1273fd4649593926451121d416154738b1</id>
<content type='text'>
Problem:
With the addition of the `:help al` text object, you can now easily
format the whole buffer with `gqal`. However, `vim.lsp.formatexpr` only
uses `textDocument/rangeFormatting` which some language servers (like
gopls) don't support.

Solution:
- Fall back to `textDocument/formatting` if the whole buffer is being formatted
  and the server doesn't support `textDocument/rangeFormatting`.
  - In theory, these two methods should return the same response if the whole
    buffer is being formatted, but I preserved the existing behaviour of
    prioritising `textDocument/rangeFormatting` in case that does not hold (i.e.
    LS bug).
- Also: `vim.lsp.formatexpr` had no tests at all, so actually add tests for it.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Problem:
With the addition of the `:help al` text object, you can now easily
format the whole buffer with `gqal`. However, `vim.lsp.formatexpr` only
uses `textDocument/rangeFormatting` which some language servers (like
gopls) don't support.

Solution:
- Fall back to `textDocument/formatting` if the whole buffer is being formatted
  and the server doesn't support `textDocument/rangeFormatting`.
  - In theory, these two methods should return the same response if the whole
    buffer is being formatted, but I preserved the existing behaviour of
    prioritising `textDocument/rangeFormatting` in case that does not hold (i.e.
    LS bug).
- Also: `vim.lsp.formatexpr` had no tests at all, so actually add tests for it.</pre>
</div>
</content>
</entry>
<entry>
<title>fix(lsp): ignore (and log once) invalid documentSelector globs #41055</title>
<updated>2026-08-04T09:14:15+00:00</updated>
<author>
<name>Rocco Vaccone</name>
<email>25404382+rvaccone@users.noreply.github.com</email>
</author>
<published>2026-08-04T09:14:15+00:00</published>
<link rel='alternate' type='text/html' href='http://git.josher.dev/rneovim.git/commit/?id=d0644230f12b1ade01f5cad35531019ac974e225'/>
<id>d0644230f12b1ade01f5cad35531019ac974e225</id>
<content type='text'>
Problem:
Client:_get_registrations() errors if a documentSelector pattern is not
a valid glob (e.g. "**/**.dart" from dartls). The error discards
already-matched registrations and propagates to supports_method() and
the client/registerCapability handler, disabling capabilities unrelated
to the offending pattern.

Solution:
Skip invalid globs. Treat them as non-matching, and log once per client.

(Similar approach was taken for filewatcher globs: 4d9e5acfb5ee081b5b0761205c8a8c36ed7e49e5)</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Problem:
Client:_get_registrations() errors if a documentSelector pattern is not
a valid glob (e.g. "**/**.dart" from dartls). The error discards
already-matched registrations and propagates to supports_method() and
the client/registerCapability handler, disabling capabilities unrelated
to the offending pattern.

Solution:
Skip invalid globs. Treat them as non-matching, and log once per client.

(Similar approach was taken for filewatcher globs: 4d9e5acfb5ee081b5b0761205c8a8c36ed7e49e5)</pre>
</div>
</content>
</entry>
</feed>
