From 3a37832265727b6da7c3c0b266a0893f63a2ca4b Mon Sep 17 00:00:00 2001 From: Daniel Mathiot Date: Mon, 13 Jun 2022 08:33:43 +0200 Subject: [PATCH 1/8] fix: deprecate ts_utils get_node_text #88 (#98) --- lua/neogen/configurations/python.lua | 7 +++---- lua/neogen/granulator.lua | 16 +++++++--------- lua/neogen/utilities/extractors.lua | 4 +--- 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/lua/neogen/configurations/python.lua b/lua/neogen/configurations/python.lua index 23deafc..b07c22e 100644 --- a/lua/neogen/configurations/python.lua +++ b/lua/neogen/configurations/python.lua @@ -1,4 +1,3 @@ -local ts_utils = require("nvim-treesitter.ts_utils") local nodes_utils = require("neogen.utilities.nodes") local extractors = require("neogen.utilities.extractors") local locator = require("neogen.locators.default") @@ -110,7 +109,7 @@ return { -- Check if function is a static method. If so, will not remove the first parameter if node:parent():type() == "decorated_definition" then local decorator = nodes_utils:matching_child_nodes(node:parent(), "decorator") - decorator = ts_utils.get_node_text(decorator[1])[1] + decorator = vim.treesitter.query.get_node_text(decorator[1], 0) if decorator == "@staticmethod" then remove_identifier = false end @@ -185,7 +184,7 @@ return { for _, assignment in pairs(nodes["assignment"]) do local left_side = assignment:field("left")[1] local left_attribute = left_side:field("attribute")[1] - left_attribute = ts_utils.get_node_text(left_attribute)[1] + left_attribute = vim.treesitter.query.get_node_text(left_attribute, 0) if left_attribute and not vim.startswith(left_attribute, "_") then table.insert(results[i.ClassAttribute], left_attribute) end @@ -233,7 +232,7 @@ return { if child:type() == "comment" then local start_row = child:start() if start_row == 0 then - if vim.startswith(ts_utils.get_node_text(node, 0)[1], "#!") then + if vim.startswith(vim.treesitter.query.get_node_text(node, 0), "#!") then return 1, 0 end end diff --git a/lua/neogen/granulator.lua b/lua/neogen/granulator.lua index 616ad37..b10e446 100644 --- a/lua/neogen/granulator.lua +++ b/lua/neogen/granulator.lua @@ -1,4 +1,3 @@ -local ts_utils = require("nvim-treesitter.ts_utils") local helpers = require("neogen.utilities.helpers") --- Tries to use the configuration to find all required content nodes from the parent node @@ -27,14 +26,13 @@ return function(parent_node, node_data) end if not data.match or child_node:type() == data.match then - if type(data.extract) == "function" then - -- Extract content from it { [type] = { data } } - for type, extracted_data in pairs(data.extract(child_node)) do - result[type] = extracted_data - end - else - -- if not extract function, get the text from the node (required: data.type) - result[data.type] = ts_utils.get_node_text(child_node) + if not type(data.extract) == "function" then + return + end + + -- Extract content from it { [type] = { data } } + for type, extracted_data in pairs(data.extract(child_node)) do + result[type] = extracted_data end end end diff --git a/lua/neogen/utilities/extractors.lua b/lua/neogen/utilities/extractors.lua index aed0b31..021b09a 100644 --- a/lua/neogen/utilities/extractors.lua +++ b/lua/neogen/utilities/extractors.lua @@ -1,5 +1,3 @@ -local ts_utils = require("nvim-treesitter.ts_utils") - return { --- Extract the content from each node from data --- @param _ any self @@ -14,7 +12,7 @@ return { return node:type() end local get_text = function(node) - return ts_utils.get_node_text(node)[1] + return vim.treesitter.query.get_node_text(node, 0) end if opts.type then result[k] = vim.tbl_map(get_type, v) From f5fbf3130c2b923928b2cb4000522a7635f5b017 Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 13 Jun 2022 06:34:00 +0000 Subject: [PATCH 2/8] [docgen] Update doc/neogen.txt skip-checks: true --- doc/neogen.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/neogen.txt b/doc/neogen.txt index 4805720..08b1f07 100644 --- a/doc/neogen.txt +++ b/doc/neogen.txt @@ -287,7 +287,7 @@ Class~ Fields~ {annotation_convention} `(string)` select which annotation convention to use {use_default_comment} `(boolean)` Prepend default filetype comment before a annotation -{append?} neogen.TemplateConfig.Append custom placement of the annotation +{append} `(optional)` neogen.TemplateConfig.Append custom placement of the annotation {position} `(fun(node: userdata, type: string): number,number)` Provide an absolute position for the annotation If values are `nil`, use default positioning @@ -296,7 +296,7 @@ Class~ {child_name} `(string)` Which child node to use for appending the annotation {fallback} `(string)` Node to fallback if `child_name` is not found {position} "'after'"|"'before'" Place the annotation relative to position with `child_name` or `fallback` -{disabled?} `(table)` Disable custom placement for provided types +{disabled} `(optional)` `(table)` Disable custom placement for provided types For example, to customize the placement for a python annotation, we can use `append`, like so: From 08c88e2a85ec5d99f6bfda9d81652ba1cd00de40 Mon Sep 17 00:00:00 2001 From: Daniel Mathiot Date: Tue, 14 Jun 2022 19:08:46 +0200 Subject: [PATCH 3/8] ref(helpers) Improve get_node_text deprecation --- lua/neogen/configurations/python.lua | 9 +++++---- lua/neogen/utilities/extractors.lua | 4 +++- lua/neogen/utilities/helpers.lua | 9 +++++++++ 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/lua/neogen/configurations/python.lua b/lua/neogen/configurations/python.lua index b07c22e..cb4b4f4 100644 --- a/lua/neogen/configurations/python.lua +++ b/lua/neogen/configurations/python.lua @@ -1,4 +1,5 @@ local nodes_utils = require("neogen.utilities.nodes") +local helpers = require("neogen.utilities.helpers") local extractors = require("neogen.utilities.extractors") local locator = require("neogen.locators.default") local template = require("neogen.template") @@ -109,7 +110,7 @@ return { -- Check if function is a static method. If so, will not remove the first parameter if node:parent():type() == "decorated_definition" then local decorator = nodes_utils:matching_child_nodes(node:parent(), "decorator") - decorator = vim.treesitter.query.get_node_text(decorator[1], 0) + decorator = helpers.get_node_text(decorator[1]) if decorator == "@staticmethod" then remove_identifier = false end @@ -128,7 +129,7 @@ return { results[i.Return] = res.return_statement results[i.ReturnTypeHint] = res[i.ReturnTypeHint] results[i.HasReturn] = (res.return_statement or res.anonymous_return or res[i.ReturnTypeHint]) - and { true } + and { true } or nil results[i.ArbitraryArgs] = res[i.ArbitraryArgs] results[i.Kwargs] = res[i.Kwargs] @@ -184,7 +185,7 @@ return { for _, assignment in pairs(nodes["assignment"]) do local left_side = assignment:field("left")[1] local left_attribute = left_side:field("attribute")[1] - left_attribute = vim.treesitter.query.get_node_text(left_attribute, 0) + left_attribute = helpers.get_node_text(left_attribute) if left_attribute and not vim.startswith(left_attribute, "_") then table.insert(results[i.ClassAttribute], left_attribute) end @@ -232,7 +233,7 @@ return { if child:type() == "comment" then local start_row = child:start() if start_row == 0 then - if vim.startswith(vim.treesitter.query.get_node_text(node, 0), "#!") then + if vim.startswith(helpers.get_node_text(node), "#!") then return 1, 0 end end diff --git a/lua/neogen/utilities/extractors.lua b/lua/neogen/utilities/extractors.lua index 021b09a..4c26767 100644 --- a/lua/neogen/utilities/extractors.lua +++ b/lua/neogen/utilities/extractors.lua @@ -1,3 +1,5 @@ +local helpers = require("neogen.utilities.helpers") + return { --- Extract the content from each node from data --- @param _ any self @@ -12,7 +14,7 @@ return { return node:type() end local get_text = function(node) - return vim.treesitter.query.get_node_text(node, 0) + return helpers.get_node_text(node) end if opts.type then result[k] = vim.tbl_map(get_type, v) diff --git a/lua/neogen/utilities/helpers.lua b/lua/neogen/utilities/helpers.lua index f35f516..7f977eb 100644 --- a/lua/neogen/utilities/helpers.lua +++ b/lua/neogen/utilities/helpers.lua @@ -22,4 +22,13 @@ return { split = function(s, sep, plain) return vim.fn.has("nvim-0.6") == 1 and vim.split(s, sep, { plain = plain }) or vim.split(s, sep, plain) end, + + --- Gets the text from the node + ---@private + ---@param node userdata node to fetch text from + ---@param bufnr? number originated buffer number. Defaults to 0 + ---@return table newline separated list of text + get_node_text = function(node, bufnr) + return vim.split(vim.treesitter.query.get_node_text(node, bufnr or 0), "\n") + end, } From d5326a114a7146b46f8af3579d3865334156c5f7 Mon Sep 17 00:00:00 2001 From: Daniel Mathiot Date: Wed, 15 Jun 2022 10:33:07 +0200 Subject: [PATCH 4/8] fix: Return value instead of table in get_node_text Closes #99 --- lua/neogen/configurations/python.lua | 6 +++--- lua/neogen/utilities/extractors.lua | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lua/neogen/configurations/python.lua b/lua/neogen/configurations/python.lua index cb4b4f4..9469717 100644 --- a/lua/neogen/configurations/python.lua +++ b/lua/neogen/configurations/python.lua @@ -110,7 +110,7 @@ return { -- Check if function is a static method. If so, will not remove the first parameter if node:parent():type() == "decorated_definition" then local decorator = nodes_utils:matching_child_nodes(node:parent(), "decorator") - decorator = helpers.get_node_text(decorator[1]) + decorator = helpers.get_node_text(decorator[1])[1] if decorator == "@staticmethod" then remove_identifier = false end @@ -185,7 +185,7 @@ return { for _, assignment in pairs(nodes["assignment"]) do local left_side = assignment:field("left")[1] local left_attribute = left_side:field("attribute")[1] - left_attribute = helpers.get_node_text(left_attribute) + left_attribute = helpers.get_node_text(left_attribute)[1] if left_attribute and not vim.startswith(left_attribute, "_") then table.insert(results[i.ClassAttribute], left_attribute) end @@ -233,7 +233,7 @@ return { if child:type() == "comment" then local start_row = child:start() if start_row == 0 then - if vim.startswith(helpers.get_node_text(node), "#!") then + if vim.startswith(helpers.get_node_text(node)[1], "#!") then return 1, 0 end end diff --git a/lua/neogen/utilities/extractors.lua b/lua/neogen/utilities/extractors.lua index 4c26767..3b209e1 100644 --- a/lua/neogen/utilities/extractors.lua +++ b/lua/neogen/utilities/extractors.lua @@ -14,7 +14,7 @@ return { return node:type() end local get_text = function(node) - return helpers.get_node_text(node) + return helpers.get_node_text(node)[1] end if opts.type then result[k] = vim.tbl_map(get_type, v) From 17dd80c2364a09b3642d7f884c3c9332fe3bcc2c Mon Sep 17 00:00:00 2001 From: i3Cheese Date: Wed, 15 Jun 2022 11:45:46 +0300 Subject: [PATCH 5/8] feat(snippets): Add snippy support (#93) --- README.md | 2 +- doc/neogen.txt | 5 ++++- lua/neogen/snippet.lua | 17 +++++++++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 342500f..c5dc0ae 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,7 @@ And this is done via the `snippet_engine` option in neogen's setup: - `snippet_engine` option will use provided engine to place the annotations: -Currently supported: `luasnip`. +Currently supported: `luasnip`, `snippy`. ```lua require('neogen').setup({ snippet_engine = "luasnip" }) diff --git a/doc/neogen.txt b/doc/neogen.txt index 08b1f07..c274c75 100644 --- a/doc/neogen.txt +++ b/doc/neogen.txt @@ -180,12 +180,14 @@ Feel free to submit a PR, I will be happy to help you ! We use semantic versioning ! (https://semver.org) Here is the current Neogen version: > - neogen.version = "2.6.0" + neogen.version = "2.7.0" < # Changelog~ Note: We will only document `major` and `minor` versions, not `patch` ones. +## 2.7.0~ + - Add support for `snippy` snippet engine ! (see |neogen-snippet-integration|) ## 2.6.0~ - Add support for placeholders in snippet insertion ! None: placeholders are automatically set when using a bundled snippet engine. @@ -235,6 +237,7 @@ To use a snippet engine, pass the option into neogen setup: < Some snippet engines come out of the box bundled with neogen: - `"luasnip"` (https://github.com/L3MON4D3/LuaSnip) +- `"snippy"` (https://github.com/dcampos/nvim-snippy) If you want to customize the placeholders, you can use `placeholders_text` option: > diff --git a/lua/neogen/snippet.lua b/lua/neogen/snippet.lua index 492213c..2ba6b65 100644 --- a/lua/neogen/snippet.lua +++ b/lua/neogen/snippet.lua @@ -11,6 +11,7 @@ local conf = require("neogen.config").get() --- < --- Some snippet engines come out of the box bundled with neogen: --- - `"luasnip"` (https://github.com/L3MON4D3/LuaSnip) +--- - `"snippy"` (https://github.com/dcampos/nvim-snippy) --- --- If you want to customize the placeholders, you can use `placeholders_text` option: --- > @@ -94,4 +95,20 @@ snippet.engines.luasnip = function(snip, pos) ) end +--- Expand snippet for snippy engine +---@param snip string the snippet to expand +---@param pos table a tuple of row, col +---@private +snippet.engines.snippy = function (snip, pos) + local ok, snippy = pcall(require, "snippy") + if not ok then + notify("Snippy not found, aborting...", vim.log.levels.ERROR) + return + end + local row, _ = unpack(pos) + vim.api.nvim_buf_set_lines(0, row, row, true, {''}) -- snippy will change `row` + vim.api.nvim_win_set_cursor(0, {row + 1, 0}) -- `snip` already has indent so we should ignore `col` + snippy.expand_snippet({body = snip}) +end + return snippet From e58d27999332b7efbe2bcbb81c030f4a64148b5a Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 15 Jun 2022 08:46:07 +0000 Subject: [PATCH 6/8] [docgen] Update doc/neogen.txt skip-checks: true --- doc/neogen.txt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/doc/neogen.txt b/doc/neogen.txt index c274c75..aa7d940 100644 --- a/doc/neogen.txt +++ b/doc/neogen.txt @@ -180,14 +180,12 @@ Feel free to submit a PR, I will be happy to help you ! We use semantic versioning ! (https://semver.org) Here is the current Neogen version: > - neogen.version = "2.7.0" + neogen.version = "2.6.0" < # Changelog~ Note: We will only document `major` and `minor` versions, not `patch` ones. -## 2.7.0~ - - Add support for `snippy` snippet engine ! (see |neogen-snippet-integration|) ## 2.6.0~ - Add support for placeholders in snippet insertion ! None: placeholders are automatically set when using a bundled snippet engine. From 110c307ddff7f376ae1ed071798e5f590901547f Mon Sep 17 00:00:00 2001 From: Dhruv Manilawala Date: Wed, 15 Jun 2022 14:46:09 +0530 Subject: [PATCH 7/8] feat: add option to specify annotation convention (#97) To know more about this new version, please visit `:h neogen-changelog` ! --- lua/neogen/generator.lua | 27 +++++++++++++++++++++++---- lua/neogen/init.lua | 12 ++++++++++-- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/lua/neogen/generator.lua b/lua/neogen/generator.lua index bd25bf1..8930d30 100644 --- a/lua/neogen/generator.lua +++ b/lua/neogen/generator.lua @@ -106,12 +106,14 @@ end ---@param data table the data from the granulator, which is a set of [type] = results ---@param template table a template from the configuration ---@param required_type string +---@param annotation_convention string ---@return table { line, content }, with line being the line to append the content -local function generate_content(parent, data, template, required_type) +local function generate_content(parent, data, template, required_type, annotation_convention) local row, col = get_place_pos(parent, template.position, template.append, required_type) local commentstring = vim.trim(vim.bo.commentstring:format("")) - local generated_template = template[template.annotation_convention] + annotation_convention = annotation_convention or template.annotation_convention + local generated_template = template[annotation_convention] local result = {} local default_text = {} @@ -188,7 +190,7 @@ local function generate_content(parent, data, template, required_type) end return setmetatable({}, { - __call = function(_, filetype, typ, return_snippet) + __call = function(_, filetype, typ, return_snippet, annotation_convention) if filetype == "" then notify("No filetype detected", vim.log.levels.WARN) return @@ -204,6 +206,17 @@ return setmetatable({}, { notify("Type `" .. typ .. "` not supported", vim.log.levels.WARN) return end + annotation_convention = annotation_convention or {} + if annotation_convention[filetype] and not template[annotation_convention[filetype]] then + notify( + ("Annotation convention %s not supported for language %s"):format( + annotation_convention[filetype], + filetype + ), + vim.log.levels.WARN + ) + return + end local parent_node = get_parent_node(filetype, typ, language) if not parent_node then @@ -213,7 +226,13 @@ return setmetatable({}, { local data = granulator(parent_node, language.data[typ]) -- Will try to generate the documentation from a template and the data found from the granulator - local row, template_content, default_text = generate_content(parent_node, data, template, typ) + local row, template_content, default_text = generate_content( + parent_node, + data, + template, + typ, + annotation_convention[filetype] + ) local content = {} local marks_pos = {} diff --git a/lua/neogen/init.lua b/lua/neogen/init.lua index 0a5a295..479bfea 100644 --- a/lua/neogen/init.lua +++ b/lua/neogen/init.lua @@ -150,6 +150,9 @@ neogen.configuration = { ---@param opts table Optional configs to change default behaviour of generation. --- - {opts.type} `(string, default: "func")` Which type we are trying to use for generating annotations. --- Currently supported: `func`, `class`, `type`, `file` +--- - {opts.annotation_convention} `(table)` convention to use for generating annotations. +--- This is language specific. For example, `generate({ annotation_convention = { python = 'numpydoc' } })` +--- If no convention is specified for a specific language, it'll use the default annotation convention for the language. --- - {opts.return_snippet} `boolean` if true, will return 3 values from the function call. --- This option is useful if you want to get the snippet to use with a unsupported snippet engine --- Below are the returned values: @@ -163,7 +166,8 @@ neogen.generate = function(opts) return end - return require("neogen.generator")(vim.bo.filetype, opts and opts.type, opts and opts.return_snippet) + opts = opts or {} + return require("neogen.generator")(vim.bo.filetype, opts.type, opts.return_snippet, opts.annotation_convention) end -- Expose more API ============================================================ @@ -237,6 +241,10 @@ end --- --- Note: We will only document `major` and `minor` versions, not `patch` ones. --- +--- ## 2.8.0~ +--- - Specify annotation convention on `generate()` method (see |neogen.generate()|) +--- ## 2.7.0~ +--- - Add support for `snippy` snippet engine ! (see |neogen-snippet-integration|) --- ## 2.6.0~ --- - Add support for placeholders in snippet insertion ! --- None: placeholders are automatically set when using a bundled snippet engine. @@ -272,7 +280,7 @@ end --- with multiple annotation conventions. ---@tag neogen-changelog ---@toc_entry Changes in neogen plugin -neogen.version = "2.6.0" +neogen.version = "2.8.0" --minidoc_afterlines_end return neogen From 2286d51628ea680b21ab6222ef22bab0b6676d13 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 15 Jun 2022 09:16:28 +0000 Subject: [PATCH 8/8] [docgen] Update doc/neogen.txt skip-checks: true --- doc/neogen.txt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/doc/neogen.txt b/doc/neogen.txt index aa7d940..f8b3b77 100644 --- a/doc/neogen.txt +++ b/doc/neogen.txt @@ -152,6 +152,9 @@ Parameters~ {opts} `(table)` Optional configs to change default behaviour of generation. - {opts.type} `(string, default: "func")` Which type we are trying to use for generating annotations. Currently supported: `func`, `class`, `type`, `file` + - {opts.annotation_convention} `(table)` convention to use for generating annotations. + This is language specific. For example, `generate({ annotation_convention = { python = 'numpydoc' } })` + If no convention is specified for a specific language, it'll use the default annotation convention for the language. - {opts.return_snippet} `boolean` if true, will return 3 values from the function call. This option is useful if you want to get the snippet to use with a unsupported snippet engine Below are the returned values: @@ -180,12 +183,16 @@ Feel free to submit a PR, I will be happy to help you ! We use semantic versioning ! (https://semver.org) Here is the current Neogen version: > - neogen.version = "2.6.0" + neogen.version = "2.8.0" < # Changelog~ Note: We will only document `major` and `minor` versions, not `patch` ones. +## 2.8.0~ + - Specify annotation convention on `generate()` method (see |neogen.generate()|) +## 2.7.0~ + - Add support for `snippy` snippet engine ! (see |neogen-snippet-integration|) ## 2.6.0~ - Add support for placeholders in snippet insertion ! None: placeholders are automatically set when using a bundled snippet engine.