diff --git a/runtime/lua/vim/_core/server.lua b/runtime/lua/vim/_core/server.lua index 45fc262376..514a73f620 100644 --- a/runtime/lua/vim/_core/server.lua +++ b/runtime/lua/vim/_core/server.lua @@ -21,17 +21,30 @@ function M.serverlist(opts, addrs) return addrs end - local peer = opts.peer == true local want_info = opts.info == true - local discover = peer or want_info - - if not discover then + if opts.peer ~= true and not want_info then return addrs end - local own_set = {} ---@type table + local seen = {} ---@type table for _, a in ipairs(addrs) do - own_set[a] = true + seen[a] = true + end + + local peers ---@type string[]|vim.ServerInfo[] + if want_info then + local self_pid = vim.fn.getpid() + local self_active = vim.v.useractive + peers = vim.tbl_map(function(addr) ---@param addr vim.ServerInfo + return { + addr = addr, + pid = self_pid, + own = true, + active = self_active, + } + end, addrs) + else + peers = addrs end -- Discover peer servers in stdpath("run"). @@ -42,27 +55,32 @@ function M.serverlist(opts, addrs) return name:match('nvim.*') end, { path = root, type = 'socket', limit = math.huge }) - local peer_pids = {} ---@type table - local peer_active = {} ---@type table - for _, socket in ipairs(socket_paths) do - if not own_set[socket] and not vim.list_contains(addrs, socket) then + if not seen[socket] then local ok, chan = pcall(vim.fn.sockconnect, 'pipe', socket, { rpc = true }) if ok and chan and chan > 0 then -- Check that the server is responding -- TODO: do we need a timeout or error handling here? - local ok_chan, chan_info = pcall(vim.fn.rpcrequest, chan, 'nvim_get_chan_info', 0) - if ok_chan and type(chan_info) == 'table' and chan_info.id then - table.insert(addrs, socket) + local ok_rpc, peer_info = pcall( + vim.fn.rpcrequest, + chan, + 'nvim_exec_lua', + [[return { pid = vim.fn.getpid(), active = vim.v.useractive, }]], + {} + ) + + if ok_rpc and type(peer_info) == 'table' then + ---@cast peer_info vim.ServerInfo + seen[socket] = true if want_info then - local ok_pid, pid = pcall(vim.fn.rpcrequest, chan, 'nvim_eval', 'getpid()') - if ok_pid and type(pid) == 'number' then - peer_pids[socket] = pid - end - local ok_la, la = pcall(vim.fn.rpcrequest, chan, 'nvim_get_vvar', 'useractive') - if ok_la and type(la) == 'number' then - peer_active[socket] = la - end + table.insert(peers, { + addr = socket, + pid = peer_info.pid, + own = false, + active = peer_info.active, + }) + else + table.insert(peers, socket) end end pcall(vim.fn.chanclose, chan) @@ -70,23 +88,7 @@ function M.serverlist(opts, addrs) end end - if not want_info then - return addrs - end - - local self_pid = vim.fn.getpid() - local self_active = vim.v.useractive - local result = {} ---@type vim.ServerInfo[] - for _, addr in ipairs(addrs) do - local own = own_set[addr] == true - table.insert(result, { - addr = addr, - pid = own and self_pid or peer_pids[addr], - own = own, - active = own and self_active or peer_active[addr], - }) - end - return result + return peers end -- (Windows only) Canonical --listen address persisted across restarts.