From fe3aa649456472f21921727a99d31761ca333594 Mon Sep 17 00:00:00 2001 From: Mike J McGuirk <62523234+mikejmcguirk@users.noreply.github.com> Date: Fri, 7 Aug 2026 11:27:19 -0400 Subject: [PATCH] feat(lsp): pass target buffer to `reuse_client` predicate #41163 Problem: The reuse_client predicate does not pass the target buffer, preventing decisions from being truly made per buffer. Solution: Pass the target buffer. --- runtime/doc/lsp.txt | 4 ++-- runtime/doc/news.txt | 2 ++ runtime/lua/vim/lsp.lua | 6 +++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt index 5deb9edba2..400d4a7bfc 100644 --- a/runtime/doc/lsp.txt +++ b/runtime/doc/lsp.txt @@ -932,7 +932,7 @@ Lua module: vim.lsp *lsp-core* filetypes = { 'my_filetype1', 'my_filetype2' }, }) < - • {reuse_client}? (`fun(client: vim.lsp.Client, config: vim.lsp.ClientConfig): boolean`) + • {reuse_client}? (`fun(client: vim.lsp.Client, config: vim.lsp.ClientConfig, bufnr: integer): boolean`) Predicate which decides if a client should be re-used. Used on all running clients. The default implementation re-uses a client if name and root_dir @@ -1407,7 +1407,7 @@ start({config}, {opts}) *vim.lsp.start()* • {bufnr}? (`integer`) Buffer handle to attach to if starting or re-using a client (0 for current). • {reuse_client}? - (`fun(client: vim.lsp.Client, config: vim.lsp.ClientConfig): boolean`) + (`fun(client: vim.lsp.Client, config: vim.lsp.ClientConfig, bufnr: integer): boolean`) Predicate used to decide if a client should be re-used. Used on all running clients. The default implementation re-uses a client if it has the same name and if the given diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 49110b9c28..e9952afd98 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -330,6 +330,8 @@ LSP while a completion item is selected accepts the item as with |complete_CTRL-Y|, then inserts the character. Previously `commitCharacters` had no effect. +• The `reuse_client` predicate now passes the target buffer. See |vim.lsp.Config| and + |vim.lsp.start()| LUA diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index cd4a983c08..20d02b4aa8 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -191,7 +191,7 @@ end --- --- Predicate which decides 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, bufnr: integer): boolean # --- --- [lsp-root_dir()]() --- Decides the workspace root: the directory where the LSP server will base its workspaceFolders, @@ -680,7 +680,7 @@ end --- running clients. The default implementation re-uses a client if it has the --- same name and if the given workspace folders (or root_dir) are all included --- in the client's workspace folders. ---- @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, bufnr: integer): boolean --- --- Buffer handle to attach to if starting or re-using a client (0 for current). --- @field bufnr? integer @@ -759,7 +759,7 @@ function lsp.start(config, opts) end for _, client in pairs(lsp.client._all) do - if reuse_client(client, config) then + if reuse_client(client, config, bufnr) then if opts.attach == false then return client.id end