summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
authorYi Ming <ofseed@foxmail.com>2026-04-15 22:12:18 +0800
committerYi Ming <ofseed@foxmail.com>2026-04-16 16:50:36 +0800
commit37aa66c1a29dca17a0e2c962d64694ddfe7cf945 (patch)
tree11769053d13f5504537f9cda87ec5f4776237c02 /src
parent481e70550cae117131db186743e152167cb465fd (diff)
feat(docs): render class dot members as module functions
AI-assisted: Codex
Diffstat (limited to 'src')
-rwxr-xr-xsrc/gen/gen_vimdoc.lua53
-rw-r--r--src/gen/luacats_parser.lua3
2 files changed, 47 insertions, 9 deletions
diff --git a/src/gen/gen_vimdoc.lua b/src/gen/gen_vimdoc.lua
index 257a7d1f62..6609381042 100755
--- a/src/gen/gen_vimdoc.lua
+++ b/src/gen/gen_vimdoc.lua
@@ -67,6 +67,17 @@ local function contains(t, xs)
return vim.tbl_contains(xs, t)
end
+--- True if the `.` class member should render like a module function.
+--- @param fun nvim.gen_vimdoc.HelptagTarget
+--- @return boolean
+local function is_module_fun(fun)
+ return fun.classvar ~= nil
+ and fun.member_sep == '.'
+ and fun.modvar ~= nil
+ and fun.module ~= nil
+ and fun.classvar == fun.modvar
+end
+
--- @type {level:integer, prerelease:boolean}?
local nvim_api_info_
@@ -99,6 +110,9 @@ end
--- @return string
local function fn_helptag_fmt_common(fun)
local fn_sfx = fun.table and '' or '()'
+ if is_module_fun(fun) then
+ return fmt('%s.%s%s', fun.module, fun.name, fn_sfx)
+ end
if fun.classvar then
return fmt('%s:%s%s', fun.classvar, fun.name, fn_sfx)
end
@@ -663,8 +677,9 @@ end
--- @param class nvim.luacats.parser.class
--- @param classes table<string,nvim.luacats.parser.class>
+--- @param hidden_fields? table<string,table<string,true>>
--- @param cfg nvim.gen_vimdoc.Config
-local function render_class(class, classes, cfg)
+local function render_class(class, classes, hidden_fields, cfg)
if class.access or class.nodoc or class.inlinedoc then
return
end
@@ -683,7 +698,15 @@ local function render_class(class, classes, cfg)
table.insert(ret, md_to_vimdoc(class.desc, INDENTATION, INDENTATION, TEXT_WIDTH))
end
- local fields_txt = render_fields_or_params(class.fields, nil, classes, cfg)
+ local class_hidden = hidden_fields and hidden_fields[class.name]
+ local fields = class.fields
+ if class_hidden then
+ fields = vim.tbl_filter(function(field)
+ return not class_hidden[field.name]
+ end, fields)
+ end
+
+ local fields_txt = render_fields_or_params(fields, nil, classes, cfg)
if not fields_txt:match('^%s*$') then
table.insert(ret, '\n Fields: ~\n')
table.insert(ret, fields_txt)
@@ -694,12 +717,22 @@ local function render_class(class, classes, cfg)
end
--- @param classes table<string,nvim.luacats.parser.class>
+--- @param funs nvim.luacats.parser.fun[]
--- @param cfg nvim.gen_vimdoc.Config
-local function render_classes(classes, cfg)
+local function render_classes(classes, funs, cfg)
local ret = {} --- @type string[]
+ -- Hide `.` members of returned class-modules from class Fields;
+ -- they render as module functions.
+ local hidden_fields = {} --- @type table<string,table<string,true>>
+ for _, fun in ipairs(funs) do
+ if is_module_fun(fun) and fun.class then
+ hidden_fields[fun.class] = hidden_fields[fun.class] or {}
+ hidden_fields[fun.class][fun.name] = true
+ end
+ end
for _, class in vim.spairs(classes) do
- ret[#ret + 1] = render_class(class, classes, cfg)
+ ret[#ret + 1] = render_class(class, classes, hidden_fields, cfg)
end
return table.concat(ret)
@@ -718,7 +751,7 @@ local function render_fun_header(fun, cfg)
end
local nm = fun.name
- if fun.classvar then
+ if fun.classvar and not is_module_fun(fun) then
nm = fmt('%s:%s', fun.classvar, nm)
end
if nm == 'vim.bo' then
@@ -735,8 +768,12 @@ local function render_fun_header(fun, cfg)
if #proto + #tag > TEXT_WIDTH - 8 then
table.insert(ret, fmt('%78s\n', tag))
local name, pargs = proto:match('([^(]+%()(.*)')
- table.insert(ret, name)
- table.insert(ret, wrap(pargs, 0, #name, TEXT_WIDTH))
+ if name then
+ table.insert(ret, name)
+ table.insert(ret, wrap(pargs, 0, #name, TEXT_WIDTH))
+ else
+ table.insert(ret, proto)
+ end
else
local pad = TEXT_WIDTH - #proto - #tag
table.insert(ret, proto .. string.rep(' ', pad) .. tag)
@@ -1115,7 +1152,7 @@ local function gen_target(cfg)
cfg,
briefs,
render_funs(funs, all_classes, cfg),
- render_classes(classes, cfg)
+ render_classes(classes, funs, cfg)
)
end
diff --git a/src/gen/luacats_parser.lua b/src/gen/luacats_parser.lua
index 98185d7498..796dcd0b93 100644
--- a/src/gen/luacats_parser.lua
+++ b/src/gen/luacats_parser.lua
@@ -30,6 +30,7 @@ local luacats_grammar = require('gen.luacats_grammar')
--- @field module? string
--- @field modvar? string
--- @field classvar? string
+--- @field member_sep? '.'|':'
--- @field deprecated? true
--- @field async? true
--- @field since? string
@@ -324,6 +325,7 @@ local function process_lua_line(line, state, classes, classvars, has_indent)
cur_obj.name = fun_or_meth_nm
cur_obj.class = class
cur_obj.classvar = parent_tbl
+ cur_obj.member_sep = sep
-- Add self param to methods
if sep == ':' then
cur_obj.params = cur_obj.params or {}
@@ -333,7 +335,6 @@ local function process_lua_line(line, state, classes, classvars, has_indent)
})
end
- -- Add method as the field to the class
table.insert(classes[class].fields, fun2field(cur_obj))
return
end