diff options
author | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2024-05-23 13:31:11 +0200 |
---|---|---|
committer | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2024-05-23 13:33:40 +0200 |
commit | fd9b0ecef4142a62b45404700ba1cff488f84a73 (patch) | |
tree | ef6c1f74f05a2220a41ccff4b0890c39229f32f7 /modules/home/conf/nvim/plgs/luasnip | |
parent | refactor(pkgs): Categorize into `by-name` shards (diff) | |
download | nixos-config-fd9b0ecef4142a62b45404700ba1cff488f84a73.tar.gz nixos-config-fd9b0ecef4142a62b45404700ba1cff488f84a73.zip |
refactor(modules/home): Setup as "normal" NixOS module
Diffstat (limited to 'modules/home/conf/nvim/plgs/luasnip')
6 files changed, 388 insertions, 0 deletions
diff --git a/modules/home/conf/nvim/plgs/luasnip/default.nix b/modules/home/conf/nvim/plgs/luasnip/default.nix new file mode 100644 index 00000000..130fafee --- /dev/null +++ b/modules/home/conf/nvim/plgs/luasnip/default.nix @@ -0,0 +1,20 @@ +{ + 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}"}); + ''; + extraPlugins = [ + # needed for the todo-comments snippets + pkgs.vimPlugins.comment-nvim + ]; + }; +} diff --git a/modules/home/conf/nvim/plgs/luasnip/lua/luasnip.lua b/modules/home/conf/nvim/plgs/luasnip/lua/luasnip.lua new file mode 100644 index 00000000..a05fa57f --- /dev/null +++ b/modules/home/conf/nvim/plgs/luasnip/lua/luasnip.lua @@ -0,0 +1,7 @@ +require("luasnip").config.set_config({ + -- Enable auto triggered snippets + enable_autosnippets = true, + + -- Use Tab (or some other key if you prefer) to trigger visual selection + store_selection_keys = "<Tab>", +}) diff --git a/modules/home/conf/nvim/plgs/luasnip/lua/snippets/all.lua b/modules/home/conf/nvim/plgs/luasnip/lua/snippets/all.lua new file mode 100644 index 00000000..c3f75058 --- /dev/null +++ b/modules/home/conf/nvim/plgs/luasnip/lua/snippets/all.lua @@ -0,0 +1,182 @@ +local ls = require("luasnip") +-- auto_pairs {{{ +local get_visual = function(args, parent) + if #parent.snippet.env.SELECT_RAW > 0 then + return sn(nil, i(1, parent.snippet.env.SELECT_RAW)) + else + return sn(nil, i(1, "")) + end +end +local function char_count_same(c1, c2) + local line = vim.api.nvim_get_current_line() + -- '%'-escape chars to force explicit match (gsub accepts patterns). + -- second return value is number of substitutions. + local _, ct1 = string.gsub(line, "%" .. c1, "") + local _, ct2 = string.gsub(line, "%" .. c2, "") + return ct1 == ct2 +end + +local function even_count(c, ...) + local line = vim.api.nvim_get_current_line() + local _, ct = string.gsub(line, c, "") + return ct % 2 == 0 +end + +-- This makes creation of pair-type snippets easier. +local function pair(pair_begin, pair_end, file_types, condition_function) + -- FIXME(@Soispha): This only works if file_types == nil, otherwise the snippet does not expand. + -- It would be nice, if it would support both an empty array (`{}`) and nil <2023-08-27> + -- file_types = file_types or {}; + + return s( + { trig = pair_begin, wordTrig = false, snippetType = "autosnippet" }, + { t({ pair_begin }), d(1, get_visual), t({ pair_end }) }, + { + condition = function() + local filetype_check = true + if file_types ~= nil then + filetype_check = file_types[vim.bo.filetype] or false + end + return (not condition_function(pair_begin, pair_end)) and filetype_check + end, + } + ) +end + +local auto_pairs = { + pair("(", ")", nil, char_count_same), + pair("{", "}", nil, char_count_same), + pair("[", "]", nil, char_count_same), + pair("<", ">", { ["rust"] = true, ["tex"] = true }, char_count_same), + pair("'", "'", nil, even_count), + pair('"', '"', nil, even_count), + pair("`", "`", nil, even_count), +} + +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" }) + +-- }}} diff --git a/modules/home/conf/nvim/plgs/luasnip/lua/snippets/html/html.lua b/modules/home/conf/nvim/plgs/luasnip/lua/snippets/html/html.lua new file mode 100644 index 00000000..17e1e7fb --- /dev/null +++ b/modules/home/conf/nvim/plgs/luasnip/lua/snippets/html/html.lua @@ -0,0 +1,108 @@ +local get_visual = function(args, parent) + if #parent.snippet.env.SELECT_RAW > 0 then + return sn(nil, i(1, parent.snippet.env.SELECT_RAW)) + else + return sn(nil, i(1)) + end +end + +local line_begin = require("luasnip.extras.expand_conditions").line_begin + +return { + -- HEADER + s( + { + trig = "h([123456])", + regTrig = true, + wordTrig = false, + snippetType = "autosnippet", + }, + fmt( + [[ + <h{}>{}</h{}> + ]], + { + f(function(_, snip) + return snip.captures[1] + end), + d(1, get_visual), + f(function(_, snip) + return snip.captures[1] + end), + } + ), + { condition = line_begin } + ), -- PARAGRAPH + s( + { trig = "pp", snippetType = "autosnippet" }, + fmt( + [[ + <p>{}</p> + ]], + { d(1, get_visual) } + ), + { condition = line_begin } + ), -- UNORDERED LIST + s( + { trig = "itt", snippetType = "autosnippet" }, + fmt( + [[ + <ul> + <li>{}</li>{} + </ul> + ]], + { i(1), i(0) } + ), + { condition = line_begin } + ), -- LIST ITEM + s( + { trig = "ii", snippetType = "autosnippet" }, + fmt( + [[ + <li>{}</li> + ]], + { d(1, get_visual) } + ), + { condition = line_begin } + ), + -- DOCUMENT TEMPLATE + s( + { trig = "base" }, + fmt( + [[ + <!doctype HTML> + <html lang="en"> + <head> + <meta charset="UTF-8"> + <title>{}</title> + </head> + <body> + {} + </body> + </html> + ]], + { i(1, "FooBar"), i(0) } + ), + { condition = line_begin } + ), -- ANCHOR TAG + s( + { + trig = "([^%l])aa", + regTrig = true, + wordTrig = false, + snippetType = "autosnippet", + }, + fmt( + [[ + {}<a href="{}">{}</a> + ]], + { + f(function(_, snip) + return snip.captures[1] + end), + i(1), + d(2, get_visual), + } + ) + ), +} diff --git a/modules/home/conf/nvim/plgs/luasnip/lua/snippets/tex/delimiter.lua b/modules/home/conf/nvim/plgs/luasnip/lua/snippets/tex/delimiter.lua new file mode 100644 index 00000000..22434aa3 --- /dev/null +++ b/modules/home/conf/nvim/plgs/luasnip/lua/snippets/tex/delimiter.lua @@ -0,0 +1,34 @@ +local get_visual = function(args, parent) + if #parent.snippet.env.SELECT_RAW > 0 then + return sn(nil, i(1, parent.snippet.env.SELECT_RAW)) + else + return sn(nil, i(1, "")) + end +end + +local translation_table = { ["("] = ")", ["{"] = "}", ["["] = "]" } + +-- Return snippet tables +return { + -- LEFT/RIGHT ALL BRACES + s( + { + trig = "([^%a])l([%(%[%{])", + regTrig = true, + wordTrig = false, + snippetType = "autosnippet", + }, + fmta("<>\\left<><>\\right<>", { + f(function(_, snip) + return snip.captures[1] + end), + f(function(_, snip) + return snip.captures[2] + end), + d(1, get_visual), + f(function(_, snip) + return translation_table[snip.captures[2]] + end), + }) + ), +} diff --git a/modules/home/conf/nvim/plgs/luasnip/lua/snippets/tex/greek.lua b/modules/home/conf/nvim/plgs/luasnip/lua/snippets/tex/greek.lua new file mode 100644 index 00000000..ebf4f9d7 --- /dev/null +++ b/modules/home/conf/nvim/plgs/luasnip/lua/snippets/tex/greek.lua @@ -0,0 +1,37 @@ +-- Return snippet tables +return { + s({ trig = ";a", snippetType = "autosnippet" }, { t("\\alpha") }), + s({ trig = ";b", snippetType = "autosnippet" }, { t("\\beta") }), + s({ trig = ";g", snippetType = "autosnippet" }, { t("\\gamma") }), + s({ trig = ";G", snippetType = "autosnippet" }, { t("\\Gamma") }), + s({ trig = ";d", snippetType = "autosnippet" }, { t("\\delta") }), + s({ trig = ";D", snippetType = "autosnippet" }, { t("\\Delta") }), + s({ trig = ";e", snippetType = "autosnippet" }, { t("\\epsilon") }), + s({ trig = ";ve", snippetType = "autosnippet" }, { t("\\varepsilon") }), + s({ trig = ";z", snippetType = "autosnippet" }, { t("\\zeta") }), + s({ trig = ";h", snippetType = "autosnippet" }, { t("\\eta") }), + s({ trig = ";o", snippetType = "autosnippet" }, { t("\\theta") }), + s({ trig = ";vo", snippetType = "autosnippet" }, { t("\\vartheta") }), + s({ trig = ";O", snippetType = "autosnippet" }, { t("\\Theta") }), + s({ trig = ";k", snippetType = "autosnippet" }, { t("\\kappa") }), + s({ trig = ";l", snippetType = "autosnippet" }, { t("\\lambda") }), + s({ trig = ";L", snippetType = "autosnippet" }, { t("\\Lambda") }), + s({ trig = ";m", snippetType = "autosnippet" }, { t("\\mu") }), + s({ trig = ";n", snippetType = "autosnippet" }, { t("\\nu") }), + s({ trig = ";x", snippetType = "autosnippet" }, { t("\\xi") }), + s({ trig = ";X", snippetType = "autosnippet" }, { t("\\Xi") }), + s({ trig = ";i", snippetType = "autosnippet" }, { t("\\pi") }), + s({ trig = ";I", snippetType = "autosnippet" }, { t("\\Pi") }), + s({ trig = ";r", snippetType = "autosnippet" }, { t("\\rho") }), + s({ trig = ";s", snippetType = "autosnippet" }, { t("\\sigma") }), + s({ trig = ";S", snippetType = "autosnippet" }, { t("\\Sigma") }), + s({ trig = ";t", snippetType = "autosnippet" }, { t("\\tau") }), + s({ trig = ";f", snippetType = "autosnippet" }, { t("\\phi") }), + s({ trig = ";vf", snippetType = "autosnippet" }, { t("\\varphi") }), + s({ trig = ";F", snippetType = "autosnippet" }, { t("\\Phi") }), + s({ trig = ";c", snippetType = "autosnippet" }, { t("\\chi") }), + s({ trig = ";p", snippetType = "autosnippet" }, { t("\\psi") }), + s({ trig = ";P", snippetType = "autosnippet" }, { t("\\Psi") }), + s({ trig = ";w", snippetType = "autosnippet" }, { t("\\omega") }), + s({ trig = ";W", snippetType = "autosnippet" }, { t("\\Omega") }), +} |