about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--hm/soispha/conf/nvim/plugins/luasnip/default.nix16
-rw-r--r--hm/soispha/conf/nvim/plugins/luasnip/lua/snippets/all.lua126
2 files changed, 138 insertions, 4 deletions
diff --git a/hm/soispha/conf/nvim/plugins/luasnip/default.nix b/hm/soispha/conf/nvim/plugins/luasnip/default.nix
index 50a0b94c..130fafee 100644
--- a/hm/soispha/conf/nvim/plugins/luasnip/default.nix
+++ b/hm/soispha/conf/nvim/plugins/luasnip/default.nix
@@ -1,12 +1,20 @@
-{lib, ...}: {
+{
+  lib,
+  pkgs,
+  ...
+}: {
   programs.nixvim = {
     plugins.luasnip = {
       enable = true;
     };
     extraConfigLuaPost = ''
-      ${lib.strings.fileContents ./lua/luasnip.lua}
-      require("luasnip.loaders.from_lua").load({paths = "${./lua/snippets}"})
-      require("luasnip.loaders.from_lua").lazy_load({paths = "${./lua/snippets}"})
+      ${lib.strings.fileContents ./lua/luasnip.lua};
+      require("luasnip.loaders.from_lua").load({paths = "${./lua/snippets}"});
+      require("luasnip.loaders.from_lua").lazy_load({paths = "${./lua/snippets}"});
     '';
+    extraPlugins = [
+      # needed for the todo-comments snippets
+      pkgs.vimPlugins.comment-nvim
+    ];
   };
 }
diff --git a/hm/soispha/conf/nvim/plugins/luasnip/lua/snippets/all.lua b/hm/soispha/conf/nvim/plugins/luasnip/lua/snippets/all.lua
index d73ce7ae..ba8816aa 100644
--- a/hm/soispha/conf/nvim/plugins/luasnip/lua/snippets/all.lua
+++ b/hm/soispha/conf/nvim/plugins/luasnip/lua/snippets/all.lua
@@ -56,4 +56,130 @@ local auto_pairs = {
 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")
 
+--- 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
+_G.luasnip = {}
+_G.luasnip.vars = {
+  username = "@Soispha";
+  email = "soispha@vhack.eu";
+}
+
+
+--- 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;
+}
+
+---@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
+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
+---@return table: All possible snippets build from the marks
+local process_marks = function(context, aliases, opts, marks)
+  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;
+  end
+  return output;
+end
+
+local todo_snippet_specs = {
+  { { trig = "todo"; };  { "TODO"; };                                     { ctype = 1; }; };
+  { { trig = "fix"; };   { "FIXME"; "ISSUE"; };                           { ctype = 1; }; };
+  { { trig = "hack"; };  { "HACK"; };                                     { ctype = 1; }; };
+  { { trig = "warn"; };  { "WARNING"; };                                  { ctype = 1; }; };
+  { { trig = "perf"; };  { "PERFORMANCE"; "OPTIMIZE"; };                  { ctype = 1; }; };
+  { { trig = "note"; };  { "NOTE"; "INFO"; };                             { ctype = 1; }; };
+
+  -- NOTE: Block commented todo-comments
+  { { trig = "todob"; }; { "TODO"; };                                     { ctype = 2; }; };
+  { { trig = "fixb"; };  { "FIXME"; "ISSUE"; };                           { ctype = 2; }; };
+  { { trig = "hackb"; }; { "HACK"; };                                     { ctype = 2; }; };
+  { { trig = "warnb"; }; { "WARNING"; };                                  { ctype = 2; }; };
+  { { trig = "perfb"; }; { "PERF"; "PERFORMANCE"; "OPTIM"; "OPTIMIZE"; }; { ctype = 2; }; };
+  { { trig = "noteb"; }; { "NOTE"; "INFO"; };                             { ctype = 2; }; };
+}
+
+local todo_comment_snippets = {}
+for _, v in ipairs(todo_snippet_specs) do
+  local snippets = process_marks(v[1], v[2][1], v[3], marks)
+  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"; })
+
+-- }}}