about summary refs log tree commit diff stats
path: root/modules/by-name
diff options
context:
space:
mode:
authorBenedikt Peetz <benedikt.peetz@b-peetz.de>2025-05-04 21:52:51 +0200
committerBenedikt Peetz <benedikt.peetz@b-peetz.de>2025-05-04 21:52:51 +0200
commit70285172bb673141899d378fb7ecc42a1449f1e2 (patch)
treedc4db819ea4a6b4cce7b4bd1cc4832a96d4d2864 /modules/by-name
parentmodules/nvim/plgs/nvim-cmp: Remove commented out partial enable (diff)
downloadnixos-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')
-rw-r--r--modules/by-name/nv/nvim/plgs/luasnip/lua/snippets/all.lua258
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"; })
 -- }}}