diff options
| author | Yi Ming <ofseed@foxmail.com> | 2026-04-15 22:12:18 +0800 |
|---|---|---|
| committer | Yi Ming <ofseed@foxmail.com> | 2026-04-16 16:50:36 +0800 |
| commit | 37aa66c1a29dca17a0e2c962d64694ddfe7cf945 (patch) | |
| tree | 11769053d13f5504537f9cda87ec5f4776237c02 /src | |
| parent | 481e70550cae117131db186743e152167cb465fd (diff) | |
feat(docs): render class dot members as module functions
AI-assisted: Codex
Diffstat (limited to 'src')
| -rwxr-xr-x | src/gen/gen_vimdoc.lua | 53 | ||||
| -rw-r--r-- | src/gen/luacats_parser.lua | 3 |
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 |
