summary refs log tree commit diff
path: root/.vim/lua/snips.lua
blob: 581b7821af1b227c4029946aab318cb224591b51 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
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'})