|
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