|
152 | 152 | ---@param template table a template from the configuration |
153 | 153 | ---@param required_type string |
154 | 154 | ---@param annotation_convention string |
| 155 | +---@param sections string[] | string the parts of a docstring to create |
155 | 156 | ---@return table { line, content }, with line being the line to append the content |
156 | | -local function generate_content(parent, data, template, required_type, annotation_convention) |
| 157 | +local function generate_content(parent, data, template, required_type, annotation_convention, partial) |
| 158 | + if partial == nil then |
| 159 | + partial = false |
| 160 | + end |
| 161 | + |
157 | 162 | local row, col = get_place_pos(parent, template.position, template.append, required_type) |
158 | 163 |
|
159 | 164 | local commentstring = vim.trim(vim.bo.commentstring:format("")) |
@@ -188,7 +193,7 @@ local function generate_content(parent, data, template, required_type, annotatio |
188 | 193 | end |
189 | 194 |
|
190 | 195 | local ins_type = type(inserted_type) |
191 | | - if ins_type == "nil" then |
| 196 | + if not partial and ins_type == "nil" then |
192 | 197 | local no_data = vim.tbl_isempty(data) |
193 | 198 | if opts.no_results then |
194 | 199 | if no_data then |
@@ -231,11 +236,110 @@ local function generate_content(parent, data, template, required_type, annotatio |
231 | 236 | end |
232 | 237 | end |
233 | 238 |
|
| 239 | + if partial then |
| 240 | + local index = 1 |
| 241 | + |
| 242 | + while result[index] == "" do |
| 243 | + table.remove(result, index) |
| 244 | + end |
| 245 | + end |
| 246 | + |
234 | 247 | return row, result, default_text |
235 | 248 | end |
236 | 249 |
|
| 250 | +--- Interpret all `sections` into Neogen-compatible section names. |
| 251 | +--- Each section name is a partial match. e.g. "parameter" will match |
| 252 | +--- "has_parameter" and "parameters". |
| 253 | +---@param sections string[] | string A user's desired parts of a docstring to create. |
| 254 | +---@return string[] # The resolved section names. |
| 255 | +--- |
| 256 | +local function expand_sections(sections) |
| 257 | + local function has_match(expression, options) |
| 258 | + for _, option in ipairs(options) do |
| 259 | + if option:match(expression) then |
| 260 | + return true |
| 261 | + end |
| 262 | + end |
| 263 | + |
| 264 | + return false |
| 265 | + end |
| 266 | + |
| 267 | + local i = require("neogen.types.template").item |
| 268 | + |
| 269 | + if type(sections) == "string" then |
| 270 | + sections = {sections} |
| 271 | + end |
| 272 | + |
| 273 | + local has_parameter = false |
| 274 | + local parameters = { |
| 275 | + i.ArbitraryArgs, |
| 276 | + i.HasParameter, |
| 277 | + i.Kwargs, |
| 278 | + i.Parameter, |
| 279 | + i.Tparam, |
| 280 | + i.Vararg, |
| 281 | + } |
| 282 | + |
| 283 | + local has_return = false |
| 284 | + local returns = { |
| 285 | + i.HasReturn, |
| 286 | + i.Return, |
| 287 | + i.ReturnAnonym, |
| 288 | + i.ReturnTypeHint, |
| 289 | + } |
| 290 | + |
| 291 | + local has_throw = false |
| 292 | + local throws = { i.HasThrow, i.Throw } |
| 293 | + |
| 294 | + local has_yield = false |
| 295 | + local yields = { i.HasYield, i.Yield } |
| 296 | + |
| 297 | + local output = {} |
| 298 | + |
| 299 | + for _, section in ipairs(sections) do |
| 300 | + if not has_parameter and has_match(section, parameters) then |
| 301 | + vim.list_extend(output, parameters) |
| 302 | + has_parameter = true |
| 303 | + end |
| 304 | + |
| 305 | + if not has_return and has_match(section, returns) then |
| 306 | + vim.list_extend(output, returns) |
| 307 | + has_return = true |
| 308 | + end |
| 309 | + |
| 310 | + if not has_throw and has_match(section, throws) then |
| 311 | + vim.list_extend(output, throws) |
| 312 | + has_throw = true |
| 313 | + end |
| 314 | + |
| 315 | + if not has_yield and has_match(section, yields) then |
| 316 | + vim.list_extend(output, yields) |
| 317 | + has_yield = true |
| 318 | + end |
| 319 | + end |
| 320 | + |
| 321 | + return output |
| 322 | +end |
| 323 | + |
| 324 | +--- Remove `data` that is not present in `sections`. |
| 325 | +---@param data table the data from configurations[lang].data |
| 326 | +---@param sections string[] Any part of `data` not found in `sections` will be omitted. |
| 327 | +---@return table # The filtered output of `data`. |
| 328 | +local function filter_by_sections(data, sections) |
| 329 | + local output = {} |
| 330 | + |
| 331 | + for key, value in pairs(data) do |
| 332 | + if vim.tbl_contains(sections, key) then |
| 333 | + output[key] = value |
| 334 | + end |
| 335 | + end |
| 336 | + |
| 337 | + return output |
| 338 | +end |
| 339 | + |
| 340 | + |
237 | 341 | return setmetatable({}, { |
238 | | - __call = function(_, filetype, node_type, return_snippet, annotation_convention) |
| 342 | + __call = function(_, filetype, node_type, return_snippet, annotation_convention, sections) |
239 | 343 | if filetype == "" then |
240 | 344 | notify("No filetype detected", vim.log.levels.WARN) |
241 | 345 | return |
@@ -279,9 +383,21 @@ return setmetatable({}, { |
279 | 383 |
|
280 | 384 | local data = granulator(parent_node, language.data[node_type]) |
281 | 385 |
|
| 386 | + local partial = false |
| 387 | + |
| 388 | + if sections ~= nil then |
| 389 | + partial = true |
| 390 | + sections = expand_sections(sections) |
| 391 | + data = filter_by_sections(data, sections) |
| 392 | + end |
| 393 | + |
282 | 394 | -- Will try to generate the documentation from a template and the data found from the granulator |
283 | 395 | local row, template_content, default_text = |
284 | | - generate_content(parent_node, data, template, node_type, annotation_convention[filetype]) |
| 396 | + generate_content(parent_node, data, template, node_type, annotation_convention[filetype], partial) |
| 397 | + |
| 398 | + if partial then |
| 399 | + row = vim.api.nvim_win_get_cursor(0)[1] |
| 400 | + end |
285 | 401 |
|
286 | 402 | local content = {} |
287 | 403 | local marks_pos = {} |
|
0 commit comments