local ls = require("luasnip") local fmt = require('luasnip.extras.fmt').fmt local ls_namespace = vim.api.nvim_create_namespace('luasnip') local group = vim.api.nvim_create_augroup('LuaSnip', { clear = true }) vim.api.nvim_create_autocmd('ModeChanged', { callback = function(opts) if ls.session.current_nodes[opts.buf] and ((vim.v.event.old_mode == 's' and vim.v.event.new_mode == 'n') or vim.v.event.old_mode == 'i') then ls.unlink_current() ls.cleanup() end end, }) vim.api.nvim_create_autocmd({'CursorHold', 'CursorHoldI'}, { callback = function(opts) vim.api.nvim_buf_clear_namespace(opts.buf, ls_namespace, 0, -1) if ls.session.current_nodes[opts.buf] and ls.choice_active() then vim.notify('current nodes: ' .. #ls.session.current_nodes[opts.buf]) local pos = vim.api.nvim_win_get_cursor(0) vim.api.nvim_buf_set_extmark(opts.buf, ls_namespace, pos[1] - 1, pos[2], { virt_text = {{'<-- choice node', 'Comment'}}, virt_text_pos = 'eol', hl_mode = 'combine', }) end end, group = group }) vim.api.nvim_create_autocmd('User', { pattern = 'LuasnipCleanup', callback = function(opts) vim.api.nvim_buf_clear_namespace(opts.buf, ls_namespace, 0, -1) end, group = group }) local s = ls.s local sn = ls.sn local t = ls.text_node local f = ls.function_node local i = ls.insert_node local c = ls.choice_node local d = ls.dynamic_node local exec = function(command) return f(function(_, _, command_arg) local results, code = require('plenary.job'):new({ command = vim.env.SHELL, args = {'-c', command_arg}, enable_recording = true, }):sync() if not code == 0 or #results == 0 then error(string.format('exec "%s" failed', command_arg)) end return results end, {}, {user_args = {command}}) end local user_email = { exec([[git config --get user.name]]), t(' <'), c(1, { exec([[git config --get user.email]]), t([[robert.gunzler@postman.com]]), t([[robert@gnzler.io]]), }), t('>'), } -- snipmate snippets require('luasnip.loaders.from_snipmate').load({ paths = {'~/.config/nvim/after/snippets'} }) ls.add_snippets('all', { s('me' , user_email), s('today', f(function() return os.date('%Y-%m-%d') end, {})), s('now' , f(function() return os.date('%Y-%m-%dT%H:%M:%SZ') end, {})) }, { type = 'snippets', key = 'generic_helpers'}) local autowrap = function(top, bot, inner) local autoinsert = function(args, _, _, wrap_with) local nodes = {} if vim.trim(table.concat(args[1] or {})) ~= "" then table.insert(nodes, wrap_with) end return sn(nil, nodes) end local argnodes = {} local maxpos = -1 for _, e in ipairs(inner) do if e.pos ~= nil then table.insert(argnodes, e.pos) if e.pos > maxpos then maxpos = e.pos end end end local nodes = {} table.insert(nodes, d(maxpos+1, autoinsert, argnodes, {user_args = {top}})) for _, e in ipairs(inner) do table.insert(nodes, e) end table.insert(nodes, d(maxpos+2, autoinsert, argnodes, {user_args = {bot}})) return nodes end local comment = function(wrapped, blockcomment) local get_cstring = function() local cs = require('Comment.ft').calculate { ctype = blockcomment and 2 or 1, range = require('Comment.utils').get_region() } local tbl = vim.split(cs or '', '%s', {plain = true, trimempty = true}) return (#tbl == 0) and {'', ''} or ((#tbl == 1) and {tbl[1] .. ' ', ''} or {tbl[1], tbl[2]}) end if type(wrapped) ~= "table" then wrapped = {wrapped} end local nodes = {} table.insert(nodes, f(function() return get_cstring()[1] end)) for _, n in ipairs(wrapped) do table.insert(nodes, n) end table.insert(nodes, f(function() return get_cstring()[2] end)) return nodes end local todo_comment = function(key) local nodes = {} if type(key) == 'string' then table.insert(nodes, t(key)) elseif type(key) == 'table' then table.insert(nodes, c(1, vim.tbl_map(function(e) return t(e) end, key))) end local wrapped = autowrap(t('('), t(')'), { c(#nodes, { t(''), -- bare exec([[git config --get user.name]]), -- name f(function() return os.date('%Y-%m-%d') end, {}), -- time }), }) for _, n in ipairs(wrapped) do table.insert(nodes, n) end table.insert(nodes, t(': ')) return comment(nodes) end ls.add_snippets('all', { s('todo', todo_comment('TODO')), s('note', todo_comment('NOTE')), s('hack', todo_comment('HACK')), s('warn', todo_comment({'WARN', 'XXX'})), s('fix' , todo_comment({'FIX', 'FIXME', 'ISSUE', 'BUG'})), }, { type = 'snippets', key = 'todo_comments'}) ls.add_snippets('gitcommit', { s('sign' , fmt('Signed-off-by: {}', {sn(1, user_email)})), s('change', fmt('Change-type: {}', {c(1, {t('patch'), t('minor'), t('major')}) })) }, { type = 'snippets', key = 'signature_helpers'}) ls.add_snippets('go', { s('pack:main', fmt([[ package main func main() {{ {} }} ]], {i(1, 'println("hello world!")')})) }, { type = 'snippets', key = 'golang'})