summary refs log tree commit diff
path: root/.vim/lua/snips.lua
diff options
context:
space:
mode:
Diffstat (limited to '.vim/lua/snips.lua')
-rw-r--r--.vim/lua/snips.lua191
1 files changed, 141 insertions, 50 deletions
diff --git a/.vim/lua/snips.lua b/.vim/lua/snips.lua
index 32e97d1..581b782 100644
--- a/.vim/lua/snips.lua
+++ b/.vim/lua/snips.lua
@@ -2,75 +2,166 @@
 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(_, _, arg)
-    local p = io.popen(arg, 'r')
-    local res = {}
-    for line in p:lines() do
-      table.insert(res, line)
+  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 res
-  end, {}, { user_args = { command }})
+    return results
+  end, {}, {user_args = {command}})
 end
 
-local calculate_commentstring = require('Comment.ft').calculate
-local get_region = require('Comment.utils').get_region
+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('>'),
+}
 
----@param ctype number|(ex.: 1 (line), 2 (block))
-local comment = function(ctype, inner)
+-- 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 = calculate_commentstring({ ctype = ctype, range = get_region() }) or ''
-    local tbl = vim.split(cs, '%s', {plain = true, trimempty = true})
+    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) and {tbl[1] .. ' ', ''}
         or {tbl[1], tbl[2]})
   end
-  return sn(nil, {
-    f(function() return get_cstring()[1] end),
-    t(' '),
-    inner,
-    f(function() return get_cstring()[2] end),
-  })
-end
 
--- snipmate snippets
--- require('luasnip.loaders.from_snipmate').load({ paths = {'~/.config/nvim/after/snippets'} })
+  if type(wrapped) ~= "table" then
+    wrapped = {wrapped}
+  end
 
-ls.add_snippets('all', {
-  s('sign', t('Robert Günzler <r@gnzler.io>')),
-  s('me',
-    fmt(
-      [[{} <{}>]], {
-        exec('git config --get user.name'),
-        exec('git config --get user.email'),
-      }
-    )
-  ),
-}, { type = 'snippets', key = 'signature_helpers'})
+  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
 
-ls.add_snippets('all', {
-  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 = 'date_helpers'})
+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({ trig = 'todo', docstring = 'TODO:' }, comment(1, fmt([[{}: ]], { t('TODO') }))),
-  -- s({ trig = 'todo', docstring = '{1:TODO}: {2}' }, comment(1, fmt([[{}: {}]], { c(1, {t('TODO')}), i(2) }))),
-  -- s('note', comment(1, fmt([[NOTE: {}]], { i(0) }))),
-  -- s('hack', comment(1, fmt([[HACK: {}]], { i(0) }))),
-  -- s('warn', comment(1, fmt([[{}: {}]], {
-  --   c(1, {t('WARN'), t('WARNING'), t('XXX')}),
-  --   i(0),
-  -- }))),
-  -- s('fix', comment(1, fmt([[{}: {}]], {
-  --   c(1, {t('FIX'), t('FIXME'), t('ISSUE'), t('BUG')}),
-  --   i(0),
-  -- }))),
+  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'})
+