aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/_editor.lua
diff options
context:
space:
mode:
authorphanium <91544758+phanen@users.noreply.github.com>2025-03-24 20:14:22 +0800
committerGitHub <noreply@github.com>2025-03-24 05:14:22 -0700
commitaf4231d4070c8d664b919f5466a827905881ef32 (patch)
tree8f511f1750b2982af055450a4e8ae7b4b61f7aa0 /runtime/lua/vim/_editor.lua
parentc98260822699bf622b14caffc908a47039deca51 (diff)
downloadrneovim-af4231d4070c8d664b919f5466a827905881ef32.tar.gz
rneovim-af4231d4070c8d664b919f5466a827905881ef32.tar.bz2
rneovim-af4231d4070c8d664b919f5466a827905881ef32.zip
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 24cea4c7f7417c7fe99a98a0487f51dd68c4f409. 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`.
Diffstat (limited to 'runtime/lua/vim/_editor.lua')
-rw-r--r--runtime/lua/vim/_editor.lua57
1 files changed, 42 insertions, 15 deletions
diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua
index 6a8b23ba40..f0b8587476 100644
--- a/runtime/lua/vim/_editor.lua
+++ b/runtime/lua/vim/_editor.lua
@@ -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(