mirror of
https://github.com/neovim/neovim.git
synced 2025-10-21 17:21:49 +00:00
fix(cmdline): cmdline completion of _defer_require() modules #33007
Problem:
`:lua vim.lsp.c<tab>` does not list vim.lsp.completion in the completion
list after 24cea4c7f7
.
Solution:
- Always include `vim.lsp._submodule` keys in candidates.
- Fixes `vim.lsp.c<tab>` -> `vim.lsp.completion`.
- Eager-load `vim.lsp.completion` to get its completion.
- Fixes `vim.lsp.completion.g<tab>` -> `vim.lsp.completion.get`.
This commit is contained in:
@@ -923,6 +923,39 @@ function vim._expand_pat(pat, env)
|
||||
|
||||
local final_env = env
|
||||
|
||||
--- @private
|
||||
---
|
||||
--- Allows submodules to be defined on a `vim.<module>` table without eager-loading the module.
|
||||
---
|
||||
--- Cmdline completion (`:lua vim.lsp.c<tab>`) accesses `vim.lsp._submodules` when no other candidates.
|
||||
--- Cmdline completion (`:lua vim.lsp.completion.g<tab>`) will eager-load the module anyway. #33007
|
||||
---
|
||||
--- @param m table
|
||||
--- @param k string
|
||||
--- @return any
|
||||
local function safe_tbl_get(m, k)
|
||||
local val = rawget(m, k)
|
||||
if val ~= nil then
|
||||
return val
|
||||
end
|
||||
|
||||
local mt = getmetatable(m)
|
||||
if not mt then
|
||||
return m == vim and vim._extra[k] or nil
|
||||
end
|
||||
|
||||
-- use mt.__index, _submodules as fallback
|
||||
if type(mt.__index) == 'table' then
|
||||
return rawget(mt.__index, k)
|
||||
end
|
||||
|
||||
local sub = rawget(m, '_submodules')
|
||||
if sub and type(sub) == 'table' and rawget(sub, k) then
|
||||
-- Access the module to force _defer_require() to load the module.
|
||||
return m[k]
|
||||
end
|
||||
end
|
||||
|
||||
for _, part in ipairs(parts) do
|
||||
if type(final_env) ~= 'table' then
|
||||
return {}, 0
|
||||
@@ -953,16 +986,7 @@ function vim._expand_pat(pat, env)
|
||||
|
||||
key = result
|
||||
end
|
||||
local field = rawget(final_env, key)
|
||||
if field == nil then
|
||||
local mt = getmetatable(final_env)
|
||||
if mt and type(mt.__index) == 'table' then
|
||||
field = rawget(mt.__index, key)
|
||||
elseif final_env == vim and (vim._submodules[key] or vim._extra[key]) then
|
||||
field = vim[key] --- @type any
|
||||
end
|
||||
end
|
||||
final_env = field
|
||||
final_env = safe_tbl_get(final_env, key)
|
||||
|
||||
if not final_env then
|
||||
return {}, 0
|
||||
@@ -992,17 +1016,20 @@ function vim._expand_pat(pat, env)
|
||||
|
||||
if type(final_env) == 'table' then
|
||||
insert_keys(final_env)
|
||||
local sub = rawget(final_env, '_submodules')
|
||||
if type(sub) == 'table' then
|
||||
insert_keys(sub)
|
||||
end
|
||||
if final_env == vim then
|
||||
insert_keys(vim._extra)
|
||||
end
|
||||
end
|
||||
|
||||
local mt = getmetatable(final_env)
|
||||
if mt and type(mt.__index) == 'table' then
|
||||
insert_keys(mt.__index)
|
||||
end
|
||||
|
||||
if final_env == vim then
|
||||
insert_keys(vim._submodules)
|
||||
insert_keys(vim._extra)
|
||||
end
|
||||
|
||||
-- Completion for dict accessors (special vim variables and vim.fn)
|
||||
if mt and vim.tbl_contains({ vim.g, vim.t, vim.w, vim.b, vim.v, vim.fn }, final_env) then
|
||||
local prefix, type = unpack(
|
||||
|
Reference in New Issue
Block a user