diff options
author | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2025-05-04 21:52:51 +0200 |
---|---|---|
committer | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2025-05-04 21:52:51 +0200 |
commit | 70285172bb673141899d378fb7ecc42a1449f1e2 (patch) | |
tree | dc4db819ea4a6b4cce7b4bd1cc4832a96d4d2864 /modules/by-name/nv/nvim | |
parent | modules/nvim/plgs/nvim-cmp: Remove commented out partial enable (diff) | |
download | nixos-config-70285172bb673141899d378fb7ecc42a1449f1e2.zip |
modules/nvim/plgs/luasnip/snippets: Simplify and add spdx-snippets
This simplifies the todo comment snippets and adds spdx-snippet snippets.
Diffstat (limited to 'modules/by-name/nv/nvim')
-rw-r--r-- | modules/by-name/nv/nvim/plgs/luasnip/lua/snippets/all.lua | 258 |
1 files changed, 178 insertions, 80 deletions
diff --git a/modules/by-name/nv/nvim/plgs/luasnip/lua/snippets/all.lua b/modules/by-name/nv/nvim/plgs/luasnip/lua/snippets/all.lua index 7909014e..371f5539 100644 --- a/modules/by-name/nv/nvim/plgs/luasnip/lua/snippets/all.lua +++ b/modules/by-name/nv/nvim/plgs/luasnip/lua/snippets/all.lua @@ -9,6 +9,58 @@ -- If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. local ls = require("luasnip") +local fmt = require("luasnip.extras.fmt").fmt + +--- Get the comment string {begin,end} table +--- +---@param comment_type integer 1 for `line`-comment and 2 for `block`-comment +---@return table comment_strings {["begin"]=begin_comment_string, ["end"]=end_comment_string} +local get_comment_string = function(comment_type) + local calculate_comment_string = require("Comment.ft").calculate + local utils = require("Comment.utils") + + -- use the `Comments.nvim` API to fetch the comment string for the region (eq. '--%s' or '--[[%s]]' for `lua`) + local cstring = + calculate_comment_string({ ctype = comment_type; range = utils.get_region(); }) + + if cstring == nil then + -- TODO: Use `vim.bo.commentstring` <2025-05-02> + + -- Use some useful default values. + return { ["begin"] = "#"; ["end"] = ""; } + end + + -- as we want only the strings themselves and not strings ready for using `format` we want to split the left and right side + local left, right = utils.unwrap_cstr(cstring) + + -- create a `{left, right}` table for it + return { ["begin"] = left; ["end"] = right; } +end + +--- Wraps a table of snippet nodes in two comment function nodes. +--- +---@param comment_type integer 1 for `line`-comment and 2 for `block`-comment +---@param nodes table The nodes that should be wrapped +---@return table wrapped_nodes The now wrapped `nodes` table. +local wrap_snippet_in_comments = function(comment_type, nodes) + local output = {} + + table.insert(output, ls.function_node(function() + return get_comment_string(comment_type)["begin"] + end)) + + + for _, v in ipairs(nodes) do + table.insert(output, v) + end + + table.insert(output, ls.function_node(function() + return get_comment_string(comment_type)["end"] + end)) + + return output +end + -- auto_pairs {{{ local get_visual = function(_, parent) if #parent.snippet.env.SELECT_RAW > 0 then @@ -78,9 +130,6 @@ ls.add_snippets("all", auto_pairs, { type = "snippets"; key = "auto_pairs"; }) -- }}} -- todo_comments {{{ -local calculate_comment_string = require("Comment.ft").calculate -local utils = require("Comment.utils") - local read_git_config = function(config_value) local command = string.format("git config \"%s\"", config_value) @@ -96,7 +145,11 @@ local read_git_config = function(config_value) return string.gsub(result, "\n", "") end -local name_to_handle = function(name) +--- Create a @handle from a full name. +--- +--- Example: +--- “Benedikt Peetz” -> “@bpeetz” +local handle_from_name = function(name) -- from: https://stackoverflow.com/a/7615129 local split = function(inputstr, sep) local t = {} @@ -106,10 +159,16 @@ local name_to_handle = function(name) return t end + -- Split on spaces local parts = split(name, "%s") local output_name = "" + if #parts > 2 then + -- Only use the first chars. + -- + -- Example: + -- “Richard Matthew Stallman” -> “rms” for _, val in ipairs(parts) do output_name = string.format("%s%s", output_name, val:sub(1, 1)) end @@ -117,94 +176,71 @@ local name_to_handle = function(name) output_name = string.format("%s%s", parts[1]:sub(1, 1), parts[2]) elseif #parts == 1 then output_name = parts[1] - else - -- parts is 0 + elseif #parts == 0 then output_name = "<NoName>" end + return string.format("@%s", output_name:lower()) end -_G.luasnip = {} -_G.luasnip.vars = { - username = function() return name_to_handle(read_git_config("user.name")) end, - email = function() return read_git_config("user.email") end, -} - ---- Get the comment string {beg,end} table ----@param ctype integer 1 for `line`-comment and 2 for `block`-comment ----@return table comment_strings {begcstring, endcstring} -local get_cstring = function(ctype) - -- use the `Comments.nvim` API to fetch the comment string for the region (eq. '--%s' or '--[[%s]]' for `lua`) - local cstring = calculate_comment_string({ ctype = ctype, range = utils.get_region() }) or vim.bo.commentstring - -- as we want only the strings themselves and not strings ready for using `format` we want to split the left and right side - local left, right = utils.unwrap_cstr(cstring) - -- create a `{left, right}` table for it - return { left, right } -end +--- Generate a comment snippet +--- +---@param trig string The trigger +---@param name string name for the comment (ex.: {FIX, ISSUE, FIXIT, BUG}) +---@param comment_type integer The comment type. +---@param mark_function function: The function used to get the marks +local todo_snippet = function(trig, name, comment_type, mark_function) + assert(trig, "context doesn't include a `trig` key which is mandatory") + assert(comment_type == 1 or comment_type == 2) ---- Options for marks to be used in a TODO comment ----@return table,table: The first table contains a node for the date, the second for the signature -local marks = { - signature = function() return t("(" .. _G.luasnip.vars:username() .. ")"), t("") end, - date_signature = function() return t("<" .. os.date("%Y-%m-%d") .. ">"), t("(" .. _G.luasnip.vars:username() .. ")") end, - date = function() return t("<" .. os.date("%Y-%m-%d") .. ">"), t("") end, - empty = function() return t(""), t("") end, -} + local context = {} + context.name = name .. " comment" + context.trig = trig ----@param alias string ----@param opts table ----@param mark_function function: This function should return two nodes ----@return table: Returns the comment node -local todo_snippet_nodes = function(alias, opts, mark_function) local date_node, signature_node = mark_function() - -- format them into the actual snippet - local comment_node = fmta("<> <><>: <> <> <>", { - f(function() - return get_cstring(opts.ctype)[1] -- get <comment-string[1]> - end), - t(alias), -- [name-of-comment] - signature_node, - i(0), -- {comment-text} - date_node, - f(function() - return get_cstring(opts.ctype)[2] -- get <comment-string[2]> - end), - }) - return comment_node -end ---- Generate a TODO comment snippet with an automatic description and docstring ----@param context table merged with the generated context table `trig` must be specified ----@param alias string of aliases for the todo comment (ex.: {FIX, ISSUE, FIXIT, BUG}) ----@param opts table merged with the snippet opts table ----@param mark_function function: The function used to get the marks -local todo_snippet = function(context, alias, opts, mark_function) - opts = opts or {} - context = context or {} - if not context.trig then - return error("context doesn't include a `trig` key which is mandatory", 2) -- all we need from the context is the trigger - end - opts.ctype = opts.ctype or 1 -- comment type can be passed in the `opts` table, but if it is not, we have to ensure, it is defined - local alias_string = alias -- `choice_node` documentation - context.name = context.name or (alias_string .. " comment") -- generate the `name` of the snippet if not defined - context.dscr = context.dscr or (alias_string .. " comment with a signature-mark") -- generate the `dscr` if not defined - context.docstring = context.docstring or (" {1:" .. alias_string .. "}: {3} <{2:mark}>{0} ") -- generate the `docstring` if not defined - local comment_node = todo_snippet_nodes(alias, opts, mark_function) - return s(context, comment_node, opts) -- the final todo-snippet constructed from our parameters + local nodes = fmt("{} {}{}: {} {} {}", wrap_snippet_in_comments(comment_type, { + ls.text_node(name); + signature_node; + ls.insert_node(1, "content"); + date_node; + })) + + return ls.snippet(context, nodes, { ctype = comment_type; }) end ----@param context table: The luasnip context ----@param opts table: The luasnip opts table, needs to have a ctype set ----@param aliases string: All aliases for a name ----@param marks table: Possible marks to account in snipped generation +---@param trigger string: The luasnip trigger +---@param comment_type integer: The luasnip comment type +---@param name string: All aliases for a name ---@return table: All possible snippets build from the marks -local process_marks = function(context, aliases, opts, marks) +local process_marks = function(trigger, name, comment_type) + local username = function() + return handle_from_name(read_git_config("user.name")) + end + + local marks = { + signature = function() + return ls.text_node("(" .. username() .. ")"), ls.text_node("") + end; + + date_signature = function() + return ls.text_node("<" .. os.date("%Y-%m-%d") .. ">"), ls.text_node("(" .. username() .. ")") + end; + + date = function() + return ls.text_node("<" .. os.date("%Y-%m-%d") .. ">"), ls.text_node("") + end; + + empty = function() + return ls.text_node(""), ls.text_node("") + end; + } + local output = {} for mark_name, mark_function in pairs(marks) do - local contex_trig_local = context.trig - context.trig = context.trig .. "-" .. mark_name - output[#output + 1] = todo_snippet(context, aliases, opts, mark_function) - context.trig = contex_trig_local + local trig = trigger .. "-" .. mark_name + + output[#output + 1] = todo_snippet(trig, name, comment_type, mark_function) end return output @@ -229,12 +265,74 @@ local todo_snippet_specs = { local todo_comment_snippets = {} for _, v in ipairs(todo_snippet_specs) do - local snippets = process_marks(v[1], v[2][1], v[3], marks) + local snippets = process_marks(v[1].trig, v[2][1], v[3].ctype) for _, value in pairs(snippets) do table.insert(todo_comment_snippets, value) end end -ls.add_snippets("all", todo_comment_snippets, { type = "snippets", key = "todo_comments" }) +ls.add_snippets("all", todo_comment_snippets, { type = "snippets"; key = "todo_comments"; }) +-- }}} + +-- spdx snippets {{{ +local generate_spdx_snippet = function(comment_type, spdx_license_expr, trigger) + assert(trigger, "context doesn't include a `trig` key which is mandatory") + assert(comment_type == 1 or comment_type == 2) + + local context = {} + context.name = trigger .. " spdx snippet expr" + context.trig = trigger + + + local nodes = { + fmt("{} SPDX-SnippetBegin {}", wrap_snippet_in_comments(comment_type, {})); + + fmt("{} SPDX-SnippetCopyrightText: {} {} <{}> {}", + wrap_snippet_in_comments(comment_type, { + ls.insert_node(1, "year"); + ls.insert_node(2, "author"); + ls.insert_node(3, "email"); + }) + ); + + fmt("{} SPDX-License-Identifier: {} {}", wrap_snippet_in_comments(comment_type, { + ls.text_node(spdx_license_expr); + })); + + { ls.insert_node(4, "content"); }; + + fmt("{} SPDX-SnippetEnd {}", wrap_snippet_in_comments(comment_type, {})); + + { ls.insert_node(0); }; + } + + local newline_nodes = {} + for _, sub_nodes in ipairs(nodes) do + for _, node in ipairs(sub_nodes) do + table.insert(newline_nodes, node) + end + + -- luasnip requires newlines to be encoded like this: + table.insert(newline_nodes, ls.text_node({ ""; ""; })) + end + + return ls.snippet(context, newline_nodes, { ctype = comment_type; }) +end + +local spdx = { + { trigger = "spdx-AGPL3+"; license = "AGPL-3.0-or-later"; }; + { trigger = "spdx-GPL3+"; license = "GPL-3.0-or-later"; }; + { trigger = "spdx-MIT"; license = "MIT"; }; +} + +local spdx_snippets = {} +for _, value in ipairs(spdx) do + local snippet = generate_spdx_snippet(1, value.license, value.trigger) + table.insert(spdx_snippets, snippet) + + snippet = generate_spdx_snippet(2, value.license, value.trigger .. "-block") + table.insert(spdx_snippets, snippet) +end +ls.add_snippets("all", spdx_snippets, { type = "snippets"; key = "spdx_snippets"; }) -- }}} |