Fix functions broken by rebase, extract some functions into own module.

This commit is contained in:
L3MON4D3 2022-03-22 11:46:16 +01:00
parent b5a14df406
commit 56d5f999f2
6 changed files with 293 additions and 195 deletions

View file

@ -1,6 +1,7 @@
local snip_mod = require("luasnip.nodes.snippet")
local util = require("luasnip.util.util")
local session = require("luasnip.session")
local snippet_collection = require("luasnip.session.snippet_collection")
local next_expand = nil
local next_expand_params = nil
@ -21,23 +22,12 @@ end
-- returns matching snippet (needs to be copied before usage!) and its expand-
-- parameters(trigger and captures). params are returned here because there's
-- no need to recalculate them.
local function match_snippet(line, snippet_table)
local expand_params
local fts = util.get_snippet_filetypes()
for _, prio in ipairs(snippet_table.order) do
local snippets = snippet_table[prio]
for _, ft in ipairs(fts) do
for _, snip in ipairs(snippets[ft] or {}) do
expand_params = snip:matches(line)
if expand_params then
-- return matching snippet and table with expand-parameters.
return snip, expand_params
end
end
end
end
return nil
local function match_snippet(line, type)
return snippet_collection.match_snippet(
line,
util.get_snippet_filetypes(),
type
)
end
-- ft:
@ -55,9 +45,9 @@ local function get_snippets(ft, opts)
opts = opts or {}
local snippet_type = opts.type or "snippets"
if not ft then
return ls[snippet_type] or {}
return snippet_collection.by_ft[snippet_type][ft] or {}
end
return ls[snippet_type][ft] or {}
return snippet_collection.by_ft[snippet_type][ft] or {}
end
local function get_context(snip)
@ -140,7 +130,7 @@ end
local function expandable()
next_expand, next_expand_params = match_snippet(
util.get_current_line_to_cursor(),
session.by_prio.snippets
"snippets"
)
return next_expand ~= nil
end
@ -246,7 +236,7 @@ local function expand()
else
snip, expand_params = match_snippet(
util.get_current_line_to_cursor(),
session.by_prio.snippets
"snippets"
)
end
if snip then
@ -271,7 +261,7 @@ end
local function expand_auto()
local snip, expand_params = match_snippet(
util.get_current_line_to_cursor(),
session.by_prio.autosnippets
"autosnippets"
)
if snip then
local cursor = util.get_cursor_0ind()
@ -538,7 +528,7 @@ local function cleanup()
-- Use this to reload luasnip
vim.cmd([[doautocmd User LuasnipCleanup]])
-- clear all snippets.
session.clear_snippets()
snippet_collection.clear_snippets()
end
local function refresh_notify(ft)
@ -588,57 +578,13 @@ local function clean_invalidated(opts)
end
end
local function invalidate_snippets(snippets)
for _, snip in ipairs(snippets) do
snip:invalidate()
end
if clean_invalidated({ inv_limit = 100 }) then
ls.refresh_notify()
end
end
local function setup_snip_env()
setfenv(2, vim.tbl_extend("force", _G, session.config.snip_env))
end
local function _add_snippets(ft, snippets, opts)
local prio_snip_table = session.by_prio[opts.type]
-- TODO: not the nicest loop, can it be improved? Do table-checks outside
-- it, preferably.
for _, snip in ipairs(snippets) do
snip.priority = opts.override_prio
or (snip.priority ~= -1 and snip.priority)
or opts.default_prio
or 1000
if not prio_snip_table[snip.priority] then
prio_snip_table[snip.priority] = {}
end
local ft_table
if not prio_snip_table[snip.priority][ft] then
ft_table = {}
prio_snip_table[snip.priority][ft] = ft_table
else
ft_table = prio_snip_table[snip.priority][ft]
end
ft_table[#ft_table + 1] = snip
end
-- append here, table was created/emptied in add_snippets.
if opts.key then
vim.list_extend(session.by_key[opts.key], snippets)
end
if opts.refresh_notify then
refresh_notify(ft)
end
end
local function add_snippets(ft, snippets, opts)
vim.validate({
filetype = { ft, {"string", "nil"} },
filetype = { ft, { "string", "nil" } },
snippets = { snippets, "table" },
opts = { opts, { "table", "nil" } },
})
@ -648,19 +594,19 @@ local function add_snippets(ft, snippets, opts)
-- alternatively, "autosnippets"
opts.type = opts.type or "snippets"
if opts.key then
if session.by_key[opts.key] then
invalidate_snippets(session.by_key[opts.key])
end
session.by_key[opts.key] = {}
-- if ft is nil, snippets already has this format.
if ft then
snippets = {
[ft] = snippets,
}
end
if not ft then
for ft_, ft_snippets in pairs(snippets) do
_add_snippets(ft_, ft_snippets, opts)
snippet_collection.add_snippets(snippets, opts)
if opts.refresh_notify then
for ft_, _ in pairs(snippets) do
refresh_notify(ft_)
end
else
_add_snippets(ft, snippets, opts)
end
end

View file

@ -11,6 +11,7 @@ local Environ = require("luasnip.util.environ")
local session = require("luasnip.session")
local pattern_tokenizer = require("luasnip.util.pattern_tokenizer")
local dict = require("luasnip.util.dict")
local snippet_collection = require("luasnip.session.snippet_collection")
local true_func = function()
return true
@ -1130,7 +1131,8 @@ function Snippet:invalidate()
-- override matching-function.
self.matches = no_match
self.invalidated = true
session.invalidated_count = session.invalidated_count + 1
snippet_collection.invalidated_count = snippet_collection.invalidated_count
+ 1
end
return {

View file

@ -1,116 +0,0 @@
-- used to store values like current nodes or the active node for autocommands.
local M = {}
M.ft_redirect = {}
setmetatable(M.ft_redirect, {
__index = function(table, key)
-- no entry for this ft(key), set it to avoid calls on each expand for
-- this filetype.
local val = { key }
rawset(table, key, val)
return val
end,
})
M.current_nodes = {}
M.ns_id = vim.api.nvim_create_namespace("Luasnip")
-- only here for overview.
M.active_choice_node = nil
M.latest_load_ft = nil
M.last_expand_snip = nil
M.last_expand_opts = nil
-- jump_active is set while luasnip moves the cursor, prevents
-- (for example) updating dependents or deleting a snippet via
-- exit_out_of_region while jumping.
-- init with false, it will be set by (eg.) ls.jump().
M.jump_active = false
M.config = nil
M.invalidated_count = 0
-- store snippets by some key.
M.by_key = {}
-- stores snippets/autosnippets by priority.
M.by_prio = {
snippets = {
-- stores sorted keys, eg 1=1000, 2=1010, 3=1020,..., used for
-- quick iterating.
order = {
1000,
},
[1000] = {
all = {},
},
},
autosnippets = {
order = {
1000,
},
[1000] = {
all = {},
},
},
}
-- this isn't in util/util.lua due to circular dependencies. Would be cleaner
-- to include it there, but it's alright to keep here for now.
--
-- this is linear, binary search would certainly be nicer, but for our
-- applications this should easily be enough.
local function insert_sorted_unique(t, k)
local tbl_len = #t
local i = 1
-- k does not yet exist in table, find first i so t[i] > k.
for _ = 1, tbl_len do
if t[i] > k then
break
end
i = i + 1
end
-- shift all t[j] with j > i back by one.
for j = tbl_len, i, -1 do
t[j + 1] = t[j]
end
t[i] = k
end
local sort_mt = {
__newindex = function(t, k, v)
-- update priority-order as well.
insert_sorted_unique(t.order, k)
rawset(t, k, v)
end,
}
setmetatable(M.by_prio.snippets, sort_mt)
setmetatable(M.by_prio.autosnippets, sort_mt)
-- ft: any filetype, optional.
function M.clear_snippets(ft)
if ft then
-- remove all ft-(auto)snippets for all priorities.
for _, prio in ipairs(M.by_prio.snippets.order) do
M.by_prio.snippets[prio][ft] = {}
end
for _, prio in ipairs(M.by_prio.autosnippets.order) do
M.by_prio.autosnippets[prio][ft] = {}
end
else
-- remove all (auto)snippets for all priorities.
for _, prio in ipairs(M.by_prio.snippets.order) do
M.by_prio.snippets[prio] = {}
end
for _, prio in ipairs(M.by_prio.autosnippets.order) do
M.by_prio.autosnippets[prio] = {}
end
end
end
return M

View file

@ -0,0 +1,34 @@
-- used to store values like current nodes or the active node for autocommands.
local M = {}
M.ft_redirect = {}
setmetatable(M.ft_redirect, {
__index = function(table, key)
-- no entry for this ft(key), set it to avoid calls on each expand for
-- this filetype.
local val = { key }
rawset(table, key, val)
return val
end,
})
M.current_nodes = {}
M.ns_id = vim.api.nvim_create_namespace("Luasnip")
-- only here for overview.
M.active_choice_node = nil
M.latest_load_ft = nil
M.last_expand_snip = nil
M.last_expand_opts = nil
-- jump_active is set while luasnip moves the cursor, prevents
-- (for example) updating dependents or deleting a snippet via
-- exit_out_of_region while jumping.
-- init with false, it will be set by (eg.) ls.jump().
M.jump_active = false
M.config = nil
M.invalidated_count = 0
return M

View file

@ -0,0 +1,232 @@
-- store snippets by some key.
-- also ordered by filetype, eg.
-- {
-- key = {
-- ft1 = {...},
-- ft2 = {...}
-- }
-- }
local by_key = {}
-- stores snippets/autosnippets by priority.
local by_prio = {
snippets = {
-- stores sorted keys, eg 1=1000, 2=1010, 3=1020,..., used for
-- quick iterating.
order = {
1000,
},
[1000] = {
all = {},
},
},
autosnippets = {
order = {
1000,
},
[1000] = {
all = {},
},
},
}
-- this isn't in util/util.lua due to circular dependencies. Would be cleaner
-- to include it there, but it's alright to keep here for now.
--
-- this is linear, binary search would certainly be nicer, but for our
-- applications this should easily be enough.
local function insert_sorted_unique(t, k)
local tbl_len = #t
local i = 1
-- k does not yet exist in table, find first i so t[i] > k.
for _ = 1, tbl_len do
if t[i] > k then
break
end
i = i + 1
end
-- shift all t[j] with j > i back by one.
for j = tbl_len, i, -1 do
t[j + 1] = t[j]
end
t[i] = k
end
local sort_mt = {
__newindex = function(t, k, v)
-- update priority-order as well.
insert_sorted_unique(t.order, k)
rawset(t, k, v)
end,
}
setmetatable(by_prio.snippets, sort_mt)
setmetatable(by_prio.autosnippets, sort_mt)
local by_ft = {
snippets = {},
autosnippets = {},
}
M = {
by_key = by_key,
by_prio = by_prio,
by_ft = by_ft,
}
-- ft: any filetype, optional.
function M.clear_snippets(ft)
if ft then
-- remove all ft-(auto)snippets for all priorities.
-- set to empty table so we won't need to rebuild/clear the order-table.
for _, prio in ipairs(M.by_prio.snippets.order) do
M.by_prio.snippets[prio][ft] = {}
end
for _, prio in ipairs(M.by_prio.autosnippets.order) do
M.by_prio.autosnippets[prio][ft] = {}
end
M.by_ft.snippets[ft] = nil
M.by_ft.autosnippets[ft] = nil
for key, _ in pairs(by_key) do
by_key[key][ft] = nil
end
else
-- remove all (auto)snippets for all priorities.
for _, prio in ipairs(M.by_prio.snippets.order) do
M.by_prio.snippets[prio] = {}
end
for _, prio in ipairs(M.by_prio.autosnippets.order) do
M.by_prio.autosnippets[prio] = {}
end
M.by_ft.snippets = {}
M.by_ft.autosnippets = {}
by_key = {}
M.by_key = by_key
end
end
function M.add_snippets() end
function M.match_snippet(line, fts, type)
local expand_params
for _, prio in ipairs(by_prio[type].order) do
local snippets = by_prio[type][prio]
for _, ft in ipairs(fts) do
for _, snip in ipairs(snippets[ft] or {}) do
expand_params = snip:matches(line)
if expand_params then
-- return matching snippet and table with expand-parameters.
return snip, expand_params
end
end
end
end
return nil
end
local function without_invalidated(snippets_by_ft)
local new_snippets = {}
for ft, ft_snippets in pairs(snippets_by_ft) do
new_snippets[ft] = {}
for _, snippet in ipairs(ft_snippets) do
if not snippet.invalidated then
table.insert(new_snippets[ft], snippet)
end
end
end
return new_snippets
end
M.invalidated_count = 0
local function clean_invalidated(opts)
opts = opts or {}
if opts.inv_limit then
if M.invalidated_count <= opts.inv_limit then
return
end
end
-- remove invalidated snippets from all tables.
for _, type_snippets in pairs(by_prio) do
for _, prio_snippets in pairs(type_snippets) do
prio_snippets = without_invalidated(prio_snippets)
end
end
for type, type_snippets in pairs(by_ft) do
by_ft[type] = without_invalidated(type_snippets)
end
for key, key_snippets in pairs(by_key) do
by_key[key] = without_invalidated(key_snippets)
end
M.invalidated_count = 0
end
local function invalidate_snippets(snippets_by_ft)
for _, ft_snippets in pairs(snippets_by_ft) do
for _, snip in ipairs(ft_snippets) do
snip:invalidate()
end
end
clean_invalidated({ inv_limit = 100 })
end
function M.add_snippets(snippets, opts)
local prio_snip_table = by_prio[opts.type]
for ft, ft_snippets in pairs(snippets) do
local ft_table = by_ft[opts.type][ft]
if not ft_table then
ft_table = {}
by_ft[opts.type][ft] = ft_table
end
-- TODO: not the nicest loop, can it be improved? Do table-checks outside
-- it, preferably.
for _, snip in ipairs(ft_snippets) do
snip.priority = opts.override_prio
or (snip.priority ~= -1 and snip.priority)
or opts.default_prio
or 1000
if not prio_snip_table[snip.priority] then
prio_snip_table[snip.priority] = {}
end
local prio_ft_table
if not prio_snip_table[snip.priority][ft] then
prio_ft_table = {}
prio_snip_table[snip.priority][ft] = prio_ft_table
else
prio_ft_table = prio_snip_table[snip.priority][ft]
end
prio_ft_table[#prio_ft_table + 1] = snip
ft_table[#ft_table + 1] = snip
end
end
if opts.key then
if by_key[opts.key] then
invalidate_snippets(by_key[opts.key])
end
by_key[opts.key] = snippets
end
end
return M

0
lua/luasnip/snippets.lua Normal file
View file