Skip to content

Conversation

stask
Copy link

@stask stask commented Oct 17, 2025

Problem: When opening multiple Ruby buffers, a second LSP client is spawned instead of reusing the first client, even though they share the same root directory.

Root cause: The reuse_client function sets cmd_cwd as a side effect during reuse checks. This means the first client is created without cmd_cwd set, causing the reuse check to fail for the second buffer.

Solution: Use before_init to ensure cmd_cwd is set for every client before initialization. Remove the custom reuse_client function to use Neovim's default reuse logic (compare name + root_dir).

Testing: Tested with Neovim 0.11.4 by opening 3 Ruby files. All buffers now correctly reuse the first client.

Note: lsp/ast_grep.lua has the identical pattern and likely has the same issue.

lsp/ruby_lsp.lua Outdated
return client.config.cmd_cwd == config.cmd_cwd
local client_cwd = client.config.cmd_cwd or client.root_dir
local config_cwd = config.cmd_cwd or config.root_dir
return client_cwd == config_cwd
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this thing forcing root_dir to always be equal to CWD?

i would think this whole reuse_client can be dropped, assuming the other comment is addressed.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The custom reuse_client was added in commit 903045b for monorepo support, but I don't fully understand why cmd_cwd comparison is necessary.
I don't have any monorepos that use ruby. This worked for me and i think it doesn't break the original monorepo support.

@stask stask force-pushed the fix/ruby-lsp-duplicate-clients branch from 324d022 to dc8e56d Compare October 18, 2025 07:04
@stask
Copy link
Author

stask commented Oct 18, 2025

Updated the fix based on feedback:

  1. on_new_config doesn't exist in vim.lsp.config - switched to using before_init to set cmd_cwd instead
  2. Removed the custom reuse_client function entirely - once cmd_cwd is properly set via before_init, the default Neovim reuse logic (compare name + root_dir) works correctly

This approach:

  • Fixes the duplicate client bug (tested by opening 3 Ruby files)
  • Preserves monorepo support (cmd_cwd is set to root_dir for every client)
  • Simplifies the code by using default behavior

The commit has been squashed and the message updated.

Problem: When opening multiple Ruby buffers, a second LSP client is
spawned instead of reusing the first client, even though they share
the same root directory.

Root cause: The reuse_client function sets cmd_cwd as a side effect
during reuse checks. This means the first client is created without
cmd_cwd set, causing the reuse check to fail for the second buffer.

Solution: Use before_init to ensure cmd_cwd is set for every client.
Remove the custom reuse_client function to use Neovim's default
reuse logic (compare name + root_dir).

Testing: Tested with Neovim 0.11.4 by opening 3 Ruby files. All
buffers now correctly reuse the first client.
@stask stask force-pushed the fix/ruby-lsp-duplicate-clients branch from dc8e56d to 52b3eea Compare October 18, 2025 07:09
@stask stask requested a review from justinmk October 18, 2025 07:10
},
reuse_client = function(client, config)
before_init = function(_, config)
config.cmd_cwd = config.root_dir
Copy link
Member

@justinmk justinmk Oct 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sadly, before_init happens after the cmd is invoked, which means setting the cmd_cwd won't have the effect that was intended here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants