darkrc/vim/lua/snip.lua

116 lines
2.3 KiB
Lua

local snip = {
snippets = {};
ft = {};
}
function snip:new(name, filetype, snippet)
if snippet==nil then
return self:new(name, nil, filetype)
end
if type(snippet) ~= "table" then
snippet = { snippet }
end
if filetype then
if not self.ft[filetype] then
self.ft[filetype] = {snippets = {}}
end
self.ft[filetype].snippets[name] = snippet
else
self.snippets[name] = snippet
end
end
function snip:each(filetype)
return coroutine.wrap(function()
for name, snippet in pairs(snip.snippets) do
coroutine.yield(name, snippet)
end
if filetype and snip.ft[filetype] then
for name, snippet in pairs(snip.ft[filetype].snippets) do
coroutine.yield(name, snippet)
end
end
end)
end
function snip:get(name, filetype)
local snippet = snip.snippets[name]
if filetype and snip.ft[filetype] then
snippet = snip.ft[filetype].snippets[name] or snippet
end
if snippet then
return snippet
end
end
local function complete(lead)
local names = {}
local known = {}
for name, snippet in snip:each(vim.o.filetype) do
if (name:find("^"..lead)) then
if type(snippet)=="string"
or snippet.condition == nil
or snippet.condition() then
if not known[name] then
table.insert(names, name)
end
known[name] = true
end
end
end
table.sort(names)
return names
end
local function process_item(item, lines)
if type(item) == "string" then
for _, line in ipairs(vim.fn.split(item, "\n")) do
table.insert(lines, line)
end
elseif type(item) == "function" then
process_item(item(), lines)
else
error("Unable to handle snippet item of type "..type(item))
end
end
function snip:insert(name)
local snippet = self:get(name, vim.o.filetype)
if not snippet then
print "No snippet with that name"
return
end
local mode = snippet.mode or "l"
local lines = {}
for _, item in ipairs(snippet) do
process_item(item, lines)
end
vim.api.nvim_put(lines, mode, true, true)
end
vim.api.nvim_create_user_command("Snip", function(params)
snip:insert(params.args)
end, {nargs=1, complete=complete})
vim.api.nvim_create_user_command("Snips", function()
local list = {}
for name in snip:each(vim.o.filetype) do
table.insert(list, name)
end
table.sort(list)
print(table.concat(list, ", "))
end, {})
vim.api.nvim_create_user_command("SnipReload", function()
package.loaded.snip = nil
require "snip"
end, {})
return snip