Format with stylua

This commit is contained in:
L3MON4D3 2023-12-02 15:17:21 +00:00 committed by github-actions[bot]
parent e13d6dd410
commit e4ad5fee01
18 changed files with 741 additions and 384 deletions

View file

@ -29,8 +29,10 @@ local autotable = require("luasnip.util.auto_table").autotable
local tree_watcher = require("luasnip.loaders.fs_watchers").tree
local path_watcher = require("luasnip.loaders.fs_watchers").path
local digraph = require("luasnip.util.directed_graph")
local refresh_notify = require("luasnip.session.enqueueable_operations").refresh_notify
local clean_invalidated = require("luasnip.session.enqueueable_operations").clean_invalidated
local refresh_notify =
require("luasnip.session.enqueueable_operations").refresh_notify
local clean_invalidated =
require("luasnip.session.enqueueable_operations").clean_invalidated
local Data = require("luasnip.loaders.data")
@ -74,17 +76,18 @@ local function search_lua_rtp(modulename)
-- essentially stolen from vim.loader.
local rtp_lua_path = package.path
for _, path in ipairs(vim.api.nvim_get_runtime_file("", true)) do
rtp_lua_path = rtp_lua_path .. (";%s/lua/?.lua;%s/lua/?/init.lua"):format(path, path)
rtp_lua_path = rtp_lua_path
.. (";%s/lua/?.lua;%s/lua/?/init.lua"):format(path, path)
end
return package.searchpath(modulename, rtp_lua_path)
end
local function _luasnip_load_file(file)
-- vim.loader.enabled does not seem to be official api, so always reset
-- if the loader is available.
-- To be sure, even pcall it, in case there are conditions under which
-- it might error.
-- vim.loader.enabled does not seem to be official api, so always reset
-- if the loader is available.
-- To be sure, even pcall it, in case there are conditions under which
-- it might error.
if vim.loader then
-- pcall, not sure if this can fail in some way..
-- Does not seem like it though
@ -133,10 +136,14 @@ local function _luasnip_load_file(file)
ls_tracked_dopackage = function(package_name)
local package_file = search_lua_rtp(package_name)
if not package_file then
error(("Could not find package %s in rtp and package.path"):format(package_name))
error(
("Could not find package %s in rtp and package.path"):format(
package_name
)
)
end
return ls_tracked_dofile(package_file)
end
end,
}
)
-- defaults snip-env requires metatable for resolving
@ -180,16 +187,28 @@ end
--- some root, and registers new files.
local Collection = {}
local Collection_mt = {
__index = Collection
__index = Collection,
}
function Collection.new(root, lazy, include_ft, exclude_ft, add_opts, lazy_watcher, fs_event_providers)
function Collection.new(
root,
lazy,
include_ft,
exclude_ft,
add_opts,
lazy_watcher,
fs_event_providers
)
local ft_filter = loader_util.ft_filter(include_ft, exclude_ft)
local o = setmetatable({
root = root,
file_filter = function(path)
if not path:sub(1, #root) == root then
log.warn("Tried to filter file `%s`, which is not inside the root `%s`.", path, root)
log.warn(
"Tried to filter file `%s`, which is not inside the root `%s`.",
path,
root
)
return false
end
return lua_package_file_filter(path) and ft_filter(path)
@ -197,7 +216,7 @@ function Collection.new(root, lazy, include_ft, exclude_ft, add_opts, lazy_watch
add_opts = add_opts,
lazy = lazy,
-- store ft -> set of files that should be lazy-loaded.
lazy_files = autotable(2, {warn = false}),
lazy_files = autotable(2, { warn = false }),
-- store, for all files in this collection, their filetype.
-- No need to always recompute it, and we can use this to store which
-- files belong to the collection.
@ -205,7 +224,7 @@ function Collection.new(root, lazy, include_ft, exclude_ft, add_opts, lazy_watch
file_dependencies = digraph.new_labeled(),
-- store fs_watchers for files the snippets-files depend on.
dependency_watchers = {},
fs_event_providers = fs_event_providers
fs_event_providers = fs_event_providers,
}, Collection_mt)
-- only register files up to a depth of 2.
@ -219,8 +238,8 @@ function Collection.new(root, lazy, include_ft, exclude_ft, add_opts, lazy_watch
end,
change_file = function(path)
o:reload(path)
end
}, {lazy = lazy_watcher, fs_event_providers = fs_event_providers})
end,
}, { lazy = lazy_watcher, fs_event_providers = fs_event_providers })
if not ok then
error(("Could not create watcher: %s"):format(err_or_watcher))
@ -239,7 +258,11 @@ function Collection:add_file(path, ft)
if self.lazy then
if not session.loaded_fts[ft] then
log.info("Registering lazy-load-snippets for ft `%s` from file `%s`", ft, path)
log.info(
"Registering lazy-load-snippets for ft `%s` from file `%s`",
ft,
path
)
-- only register to load later.
self.lazy_files[ft][path] = true
@ -255,11 +278,7 @@ function Collection:add_file(path, ft)
self:load_file(path, ft)
end
function Collection:load_file(path, ft)
log.info(
"Adding snippets for filetype `%s` from file `%s`",
ft,
path
)
log.info("Adding snippets for filetype `%s` from file `%s`", ft, path)
self.loaded_path_ft[path] = ft
local snippets, autosnippets, dependent_files = _luasnip_load_file(path)
@ -277,26 +296,40 @@ function Collection:load_file(path, ft)
self.file_dependencies:set_edge(file_dependency, path, path)
if not self.dependency_watchers[file_dependency] then
self.dependency_watchers[file_dependency] = path_watcher(file_dependency, {
change = function(_)
local depending_files = self.file_dependencies:connected_component(file_dependency, "Forward")
for _, file in ipairs(depending_files) do
-- Prevent loading one of the utility-files as a snippet-file.
-- This will not reject any snippet-file in
-- depending_files. This is because since they are in
-- depending_files, we have their dependency-information,
-- which can only be obtained by loading them, and so there
-- can't be any unloaded files in there.
if self.loaded_path_ft[file] then
self:load_file(file, self.loaded_path_ft[file])
self.dependency_watchers[file_dependency] = path_watcher(
file_dependency,
{
change = function(_)
local depending_files =
self.file_dependencies:connected_component(
file_dependency,
"Forward"
)
for _, file in ipairs(depending_files) do
-- Prevent loading one of the utility-files as a snippet-file.
-- This will not reject any snippet-file in
-- depending_files. This is because since they are in
-- depending_files, we have their dependency-information,
-- which can only be obtained by loading them, and so there
-- can't be any unloaded files in there.
if self.loaded_path_ft[file] then
self:load_file(file, self.loaded_path_ft[file])
end
end
end
end
}, {lazy = false, fs_event_providers = self.fs_event_providers})
end,
},
{ lazy = false, fs_event_providers = self.fs_event_providers }
)
end
end
loader_util.add_file_snippets(ft, path, snippets, autosnippets, self.add_opts)
loader_util.add_file_snippets(
ft,
path,
snippets,
autosnippets,
self.add_opts
)
refresh_notify(ft)
end
@ -341,25 +374,58 @@ end
local function _load(lazy, opts)
local o = loader_util.normalize_opts(opts)
local collection_roots = loader_util.resolve_root_paths(o.paths, "luasnippets")
local collection_roots =
loader_util.resolve_root_paths(o.paths, "luasnippets")
local lazy_roots = loader_util.resolve_lazy_root_paths(o.lazy_paths)
log.info("Found roots `%s` for paths `%s`.", vim.inspect(collection_roots), vim.inspect(o.paths))
log.info(
"Found roots `%s` for paths `%s`.",
vim.inspect(collection_roots),
vim.inspect(o.paths)
)
if o.paths and #o.paths ~= #collection_roots then
log.warn("Could not resolve all collection-roots for paths `%s`: only found `%s`", vim.inspect(o.paths), vim.inspect(collection_roots))
log.warn(
"Could not resolve all collection-roots for paths `%s`: only found `%s`",
vim.inspect(o.paths),
vim.inspect(collection_roots)
)
end
log.info("Determined roots `%s` for lazy_paths `%s`.", vim.inspect(lazy_roots), vim.inspect(o.lazy_paths))
log.info(
"Determined roots `%s` for lazy_paths `%s`.",
vim.inspect(lazy_roots),
vim.inspect(o.lazy_paths)
)
if o.lazy_paths and #o.lazy_paths ~= #lazy_roots then
log.warn("Could not resolve all collection-roots for lazy_paths `%s`: only found `%s`", vim.inspect(o.lazy_paths), vim.inspect(lazy_roots))
log.warn(
"Could not resolve all collection-roots for lazy_paths `%s`: only found `%s`",
vim.inspect(o.lazy_paths),
vim.inspect(lazy_roots)
)
end
for paths_lazy, roots in pairs({[true] = lazy_roots, [false] = collection_roots}) do
for paths_lazy, roots in pairs({
[true] = lazy_roots,
[false] = collection_roots,
}) do
for _, collection_root in ipairs(roots) do
local ok, coll_or_err = pcall(Collection.new, collection_root, lazy, o.include, o.exclude, o.add_opts, paths_lazy, o.fs_event_providers)
local ok, coll_or_err = pcall(
Collection.new,
collection_root,
lazy,
o.include,
o.exclude,
o.add_opts,
paths_lazy,
o.fs_event_providers
)
if not ok then
log.error("Could not create collection at %s: %s", collection_root, coll_or_err)
log.error(
"Could not create collection at %s: %s",
collection_root,
coll_or_err
)
else
table.insert(Data.lua_collections, coll_or_err)
end
@ -379,7 +445,9 @@ function M.lazy_load(opts)
_load(true, opts)
-- load for current buffer on startup.
for _, ft in ipairs(loader_util.get_load_fts(vim.api.nvim_get_current_buf())) do
for _, ft in
ipairs(loader_util.get_load_fts(vim.api.nvim_get_current_buf()))
do
M._load_lazy_loaded_ft(ft)
end
end

View file

@ -8,8 +8,10 @@ local tree_watcher = require("luasnip.loaders.fs_watchers").tree
local Data = require("luasnip.loaders.data")
local session = require("luasnip.session")
local snippetcache = require("luasnip.loaders.snippet_cache")
local refresh_notify = require("luasnip.session.enqueueable_operations").refresh_notify
local clean_invalidated = require("luasnip.session.enqueueable_operations").clean_invalidated
local refresh_notify =
require("luasnip.session.enqueueable_operations").refresh_notify
local clean_invalidated =
require("luasnip.session.enqueueable_operations").clean_invalidated
local log = require("luasnip.util.log").new("snipmate-loader")
@ -24,7 +26,7 @@ local function load_snipmate(filename)
return {
snippets = {},
autosnippets = {},
misc = {}
misc = {},
}
end
@ -123,7 +125,7 @@ local function load_snipmate(filename)
return {
snippets = snippets.snippet,
autosnippets = snippets.autosnippet,
misc = extends
misc = extends,
}
end
@ -134,14 +136,22 @@ Data.snipmate_cache = snippetcache.new(load_snipmate)
--- some root, and registers new files.
local Collection = {}
local Collection_mt = {
__index = Collection
__index = Collection,
}
local function snipmate_package_file_filter(fname)
return fname:match("%.snippets$")
end
function Collection.new(root, lazy, include_ft, exclude_ft, add_opts, lazy_watcher, fs_event_providers)
function Collection.new(
root,
lazy,
include_ft,
exclude_ft,
add_opts,
lazy_watcher,
fs_event_providers
)
local ft_filter = loader_util.ft_filter(include_ft, exclude_ft)
local o = setmetatable({
root = root,
@ -159,7 +169,11 @@ function Collection.new(root, lazy, include_ft, exclude_ft, add_opts, lazy_watch
---@return LuaSnip.Loaders.Snipmate.FileCategory?
categorize_file = function(path)
if not path:sub(1, #root) == root then
log.warn("Tried to filter file `%s`, which is not inside the root `%s`.", path, root)
log.warn(
"Tried to filter file `%s`, which is not inside the root `%s`.",
path,
root
)
return nil
end
if snipmate_package_file_filter(path) then
@ -174,9 +188,9 @@ function Collection.new(root, lazy, include_ft, exclude_ft, add_opts, lazy_watch
add_opts = add_opts,
lazy = lazy,
-- store ft -> set of files that should be lazy-loaded.
lazy_files = autotable(2, {warn = false}),
lazy_files = autotable(2, { warn = false }),
-- store for each path the set of filetypes it has been loaded with.
loaded_path_fts = autotable(2, {warn = false}),
loaded_path_fts = autotable(2, { warn = false }),
-- model filetype-extensions (`extends <someft>` in `ft.snippets`).
-- Better than a flat table with t[ft] = {someft=true, somotherft=true}
-- since transitive dependencies are easier to understand/query.
@ -189,7 +203,7 @@ function Collection.new(root, lazy, include_ft, exclude_ft, add_opts, lazy_watch
-- store all files in the collection, by their filetype.
-- This information is necessary to handle `extends` even for files
-- that are not actually loaded (due to in/exclude).
collection_files_by_ft = autotable(2, {warn = false}),
collection_files_by_ft = autotable(2, { warn = false }),
-- set if creation successful.
watcher = nil,
}, Collection_mt)
@ -215,8 +229,8 @@ function Collection.new(root, lazy, include_ft, exclude_ft, add_opts, lazy_watch
vim.schedule_wrap(function()
o:reload(path)
end)()
end
}, {lazy = lazy_watcher, fs_event_providers = fs_event_providers})
end,
}, { lazy = lazy_watcher, fs_event_providers = fs_event_providers })
if not ok then
error(("Could not create watcher: %s"):format(err_or_watcher))
@ -250,7 +264,11 @@ function Collection:add_file(path, add_ft)
if self.lazy then
if not session.loaded_fts[add_ft] then
log.info("Registering lazy-load-snippets for ft `%s` from file `%s`", add_ft, path)
log.info(
"Registering lazy-load-snippets for ft `%s` from file `%s`",
add_ft,
path
)
-- only register to load later.
self.lazy_files[add_ft][path] = true
@ -282,11 +300,7 @@ function Collection:load_file(path, ft, skip_load_mode)
return
end
log.info(
"Adding snippets for filetype `%s` from file `%s`",
ft,
path
)
log.info("Adding snippets for filetype `%s` from file `%s`", ft, path)
-- Set here to skip loads triggered for the same path-file-combination in
-- subsequent code, which would trigger and endless loop.
@ -319,14 +333,27 @@ function Collection:load_file(path, ft, skip_load_mode)
self.ft_extensions:set_edge(extended_ft, ft, path)
end
loader_util.add_file_snippets(ft, path, snippets, autosnippets, self.add_opts)
loader_util.add_file_snippets(
ft,
path,
snippets,
autosnippets,
self.add_opts
)
-- get all filetypes this one extends (directly or transitively), and load
-- their files.
local load_fts = self.ft_extensions:connected_component(ft, "Backward")
for _, extended_ft in ipairs(load_fts) do
for file, _ in pairs(self.collection_files_by_ft[extended_ft]) do
for _, file_ft in ipairs(self.ft_extensions:connected_component(extended_ft, "Forward")) do
for _, file_ft in
ipairs(
self.ft_extensions:connected_component(
extended_ft,
"Forward"
)
)
do
-- skips load if the file is already loaded for the given filetype.
-- One bad side-effect of this current implementation is that
-- the edges in the graph will be reset/set multiple times,
@ -342,7 +369,9 @@ end
function Collection:do_lazy_load(lazy_ft)
for file, _ in pairs(self.lazy_files[lazy_ft]) do
for _, ft in ipairs(self.ft_extensions:connected_component(lazy_ft, "Forward")) do
for _, ft in
ipairs(self.ft_extensions:connected_component(lazy_ft, "Forward"))
do
-- skips load if the file is already loaded for the given filetype.
self:load_file(file, ft, "SkipIfLoaded")
end
@ -383,22 +412,54 @@ local function _load(lazy, opts)
local collection_roots = loader_util.resolve_root_paths(o.paths, "snippets")
local lazy_roots = loader_util.resolve_lazy_root_paths(o.lazy_paths)
log.info("Found roots `%s` for paths `%s`.", vim.inspect(collection_roots), vim.inspect(o.paths))
log.info(
"Found roots `%s` for paths `%s`.",
vim.inspect(collection_roots),
vim.inspect(o.paths)
)
if o.paths and #o.paths ~= #collection_roots then
log.warn("Could not resolve all collection-roots for paths `%s`: only found `%s`", vim.inspect(o.paths), vim.inspect(collection_roots))
log.warn(
"Could not resolve all collection-roots for paths `%s`: only found `%s`",
vim.inspect(o.paths),
vim.inspect(collection_roots)
)
end
log.info("Determined roots `%s` for lazy_paths `%s`.", vim.inspect(lazy_roots), vim.inspect(o.lazy_paths))
log.info(
"Determined roots `%s` for lazy_paths `%s`.",
vim.inspect(lazy_roots),
vim.inspect(o.lazy_paths)
)
if o.lazy_paths and #o.lazy_paths ~= #lazy_roots then
log.warn("Could not resolve all collection-roots for lazy_paths `%s`: only found `%s`", vim.inspect(o.lazy_paths), vim.inspect(lazy_roots))
log.warn(
"Could not resolve all collection-roots for lazy_paths `%s`: only found `%s`",
vim.inspect(o.lazy_paths),
vim.inspect(lazy_roots)
)
end
for paths_lazy, roots in pairs({[true] = lazy_roots, [false] = collection_roots}) do
for paths_lazy, roots in pairs({
[true] = lazy_roots,
[false] = collection_roots,
}) do
for _, collection_root in ipairs(roots) do
local ok, coll_or_err = pcall(Collection.new, collection_root, lazy, o.include, o.exclude, o.add_opts, paths_lazy, o.fs_event_providers)
local ok, coll_or_err = pcall(
Collection.new,
collection_root,
lazy,
o.include,
o.exclude,
o.add_opts,
paths_lazy,
o.fs_event_providers
)
if not ok then
log.error("Could not create collection at %s: %s", collection_root, coll_or_err)
log.error(
"Could not create collection at %s: %s",
collection_root,
coll_or_err
)
else
table.insert(Data.snipmate_collections, coll_or_err)
end
@ -417,7 +478,9 @@ end
function M.lazy_load(opts)
_load(true, opts)
-- load for current buffer on startup.
for _, ft in ipairs(loader_util.get_load_fts(vim.api.nvim_get_current_buf())) do
for _, ft in
ipairs(loader_util.get_load_fts(vim.api.nvim_get_current_buf()))
do
M._load_lazy_loaded_ft(ft)
end
end

View file

@ -6,8 +6,10 @@ local autotable = require("luasnip.util.auto_table").autotable
local path_watcher = require("luasnip.loaders.fs_watchers").path
local Data = require("luasnip.loaders.data")
local session = require("luasnip.session")
local refresh_notify = require("luasnip.session.enqueueable_operations").refresh_notify
local clean_invalidated = require("luasnip.session.enqueueable_operations").clean_invalidated
local refresh_notify =
require("luasnip.session.enqueueable_operations").refresh_notify
local clean_invalidated =
require("luasnip.session.enqueueable_operations").clean_invalidated
local json_decoders = {
json = util.json_decode,
@ -60,7 +62,7 @@ local function get_file_snippets(file)
return {
snippets = {},
autosnippets = {},
misc = {}
misc = {},
}
end
@ -124,26 +126,24 @@ local function get_file_snippets(file)
return {
snippets = snippets,
autosnippets = {},
misc = {}
misc = {},
}
end
-- has to be set in separate module to allow different module-path-separators
-- in `require`.
Data.vscode_cache = require("luasnip.loaders.snippet_cache").new(get_file_snippets)
Data.vscode_cache =
require("luasnip.loaders.snippet_cache").new(get_file_snippets)
--- Parse package.json(c), determine all files that contribute snippets, and
--- which filetype is associated with them.
--- @param manifest string
--- @return table<string, table<string, true|nil>>
--- @return table<string, table<string, true|nil>>
local function get_snippet_files(manifest)
-- if root doesn't contain a package.json, or it contributes no snippets,
-- return no snippets.
if not Path.exists(manifest) then
log.warn(
"Manifest %s does not exist",
manifest
)
log.warn("Manifest %s does not exist", manifest)
return {}
end
@ -157,16 +157,13 @@ local function get_snippet_files(manifest)
if
not package_data.contributes or not package_data.contributes.snippets
then
log.warn(
"Manifest %s does not contribute any snippets.",
manifest
)
log.warn("Manifest %s does not contribute any snippets.", manifest)
return {}
end
-- stores ft -> files -> true|nil, allow iterating files and their
-- filetypes while preventing duplicates.
local ft_file_set = autotable(2, {warn = false})
local ft_file_set = autotable(2, { warn = false })
-- parent-directory of package.json(c), all files in the package.json(c)
-- are relative to it.
@ -175,8 +172,7 @@ local function get_snippet_files(manifest)
for _, snippet_entry in pairs(package_data.contributes.snippets) do
local absolute_path = Path.join(package_parent, snippet_entry.path)
local normalized_snippet_file =
Path.normalize(absolute_path)
local normalized_snippet_file = Path.normalize(absolute_path)
if not normalized_snippet_file then
-- path does not exist (yet), try and guess the correct path anyway.
@ -203,15 +199,21 @@ end
-- Responsible for watching a single json-snippet-file.
local SnippetfileWatcher = {}
local SnippetfileWatcher_mt = {__index = SnippetfileWatcher}
local SnippetfileWatcher_mt = { __index = SnippetfileWatcher }
function SnippetfileWatcher.new(path, initial_ft, fs_event_providers, lazy, load_cb)
function SnippetfileWatcher.new(
path,
initial_ft,
fs_event_providers,
lazy,
load_cb
)
local o = setmetatable({
path = path,
load_cb = load_cb,
-- track which filetypes this file has been loaded for, so we can
-- reload for all of them.
loaded_fts = {[initial_ft] = true}
loaded_fts = { [initial_ft] = true },
}, SnippetfileWatcher_mt)
local load_all_fts = function()
@ -220,21 +222,25 @@ function SnippetfileWatcher.new(path, initial_ft, fs_event_providers, lazy, load
refresh_notify(ft)
end
end
local ok, err_or_watcher = pcall(path_watcher, path, {
local ok, err_or_watcher = pcall(path_watcher, path, {
add = load_all_fts,
change = function()
load_all_fts()
-- clean snippets if enough were removed.
clean_invalidated()
end
},
{ lazy = lazy, fs_event_providers = fs_event_providers})
end,
}, { lazy = lazy, fs_event_providers = fs_event_providers })
if not ok then
-- has to be handled by caller, we can't really proceed if the creation
-- failed.
error(("Could not create path_watcher for path %s: %s"):format(path, err_or_watcher))
error(
("Could not create path_watcher for path %s: %s"):format(
path,
err_or_watcher
)
)
end
o.watcher = err_or_watcher
@ -260,15 +266,23 @@ end
--- some root, and registers new files.
local Collection = {}
local Collection_mt = {
__index = Collection
__index = Collection,
}
function Collection.new(manifest_path, lazy, include_ft, exclude_ft, add_opts, lazy_watcher, fs_event_providers)
function Collection.new(
manifest_path,
lazy,
include_ft,
exclude_ft,
add_opts,
lazy_watcher,
fs_event_providers
)
local ft_filter = loader_util.ft_filter(include_ft, exclude_ft)
local o = setmetatable({
lazy = lazy,
-- store ft -> set of files that should be lazy-loaded.
lazy_files = autotable(2, {warn = false}),
lazy_files = autotable(2, { warn = false }),
fs_event_providers = fs_event_providers,
-- store path-watchers (so we don't register more than one for one
@ -284,7 +298,7 @@ function Collection.new(manifest_path, lazy, include_ft, exclude_ft, add_opts, l
loader_util.add_file_snippets(ft, path, snippets, {}, add_opts)
end,
-- initialized in a bit, we have to store+reset a watcher for the manifest-file.
manifest_watcher = nil
manifest_watcher = nil,
}, Collection_mt)
-- callback for updating the file-filetype-associations from the manifest.
@ -302,8 +316,8 @@ function Collection.new(manifest_path, lazy, include_ft, exclude_ft, add_opts, l
local watcher_ok, err = pcall(path_watcher, manifest_path, {
-- don't handle removals for now.
add = update_manifest,
change = update_manifest
}, {lazy = lazy_watcher, fs_event_providers = fs_event_providers})
change = update_manifest,
}, { lazy = lazy_watcher, fs_event_providers = fs_event_providers })
if not watcher_ok then
error(("Could not create watcher: %s"):format(err))
@ -321,7 +335,11 @@ function Collection:add_file(path, ft)
if self.lazy then
if not session.loaded_fts[ft] then
log.info("Registering lazy-load-snippets for ft `%s` from file `%s`", ft, path)
log.info(
"Registering lazy-load-snippets for ft `%s` from file `%s`",
ft,
path
)
-- only register to load later.
self.lazy_files[ft][path] = true
@ -338,18 +356,25 @@ function Collection:add_file(path, ft)
end
function Collection:load_file(path, ft)
log.info(
"Registering file %s with filetype %s for loading.",
path,
ft
)
log.info("Registering file %s with filetype %s for loading.", path, ft)
if not self.path_watchers[path] then
-- always register these lazily, that way an upate to the package.json
-- without the snippet-file existing will work!
-- Also make sure we use the same fs_event_providers.
local ok, watcher_or_err = pcall(SnippetfileWatcher.new, path, ft, self.fs_event_providers, true, self.load_callback)
local ok, watcher_or_err = pcall(
SnippetfileWatcher.new,
path,
ft,
self.fs_event_providers,
true,
self.load_callback
)
if not ok then
log.error("Could not create SnippetFileWatcher for path %s: %s", path, watcher_or_err)
log.error(
"Could not create SnippetFileWatcher for path %s: %s",
path,
watcher_or_err
)
return
end
self.path_watchers[path] = watcher_or_err
@ -380,7 +405,8 @@ local function get_rtp_paths()
return vim.list_extend(
-- would be very surprised if this yields duplicates :D
vim.api.nvim_get_runtime_file("package.json", true),
vim.api.nvim_get_runtime_file("package.jsonc", true) )
vim.api.nvim_get_runtime_file("package.jsonc", true)
)
end
--- Generate list of manifest-paths from list of directory-paths.
@ -395,16 +421,22 @@ local function get_manifests(paths)
if paths then
-- Get path to package.json/package.jsonc, or continue if it does not exist.
for _, dir in ipairs(paths) do
local tentative_manifest_path = Path.expand(Path.join(dir, "package.json"))
local tentative_manifest_path =
Path.expand(Path.join(dir, "package.json"))
-- expand returns nil for paths that don't exist.
if tentative_manifest_path then
table.insert(manifest_paths, tentative_manifest_path)
else
tentative_manifest_path = Path.expand(Path.join(dir, "package.jsonc"))
tentative_manifest_path =
Path.expand(Path.join(dir, "package.jsonc"))
if tentative_manifest_path then
table.insert(manifest_paths, tentative_manifest_path)
else
log.warn("Could not find package.json(c) in path %s (expanded to %s).", dir, Path.expand(dir))
log.warn(
"Could not find package.json(c) in path %s (expanded to %s).",
dir,
Path.expand(dir)
)
end
end
end
@ -434,8 +466,14 @@ local function get_lazy_manifests(paths)
for _, dir in ipairs(paths) do
local absolute_dir = Path.expand_maybe_nonexisting(dir)
table.insert(lazy_manifest_paths, Path.join(absolute_dir, "package.json"))
table.insert(lazy_manifest_paths, Path.join(absolute_dir, "package.jsonc"))
table.insert(
lazy_manifest_paths,
Path.join(absolute_dir, "package.json")
)
table.insert(
lazy_manifest_paths,
Path.join(absolute_dir, "package.jsonc")
)
end
end
@ -448,23 +486,55 @@ local function _load(lazy, opts)
local manifests = get_manifests(o.paths)
local lazy_manifests = get_lazy_manifests(o.lazy_paths)
log.info("Found manifests `%s` for paths `%s`.", vim.inspect(manifests), vim.inspect(o.paths))
log.info(
"Found manifests `%s` for paths `%s`.",
vim.inspect(manifests),
vim.inspect(o.paths)
)
if o.paths and #o.paths ~= #manifests then
log.warn("Could not resolve all manifests for paths `%s`: only found `%s`", vim.inspect(o.paths), vim.inspect(manifests))
log.warn(
"Could not resolve all manifests for paths `%s`: only found `%s`",
vim.inspect(o.paths),
vim.inspect(manifests)
)
end
log.info("Determined roots `%s` for lazy_paths `%s`.", vim.inspect(lazy_manifests), vim.inspect(o.lazy_paths))
log.info(
"Determined roots `%s` for lazy_paths `%s`.",
vim.inspect(lazy_manifests),
vim.inspect(o.lazy_paths)
)
-- two lazy manifests from each lazy directory.
if o.lazy_paths and #o.lazy_paths ~= 2*#lazy_manifests then
log.warn("Could not resolve all manifests for lazy_paths `%s`: only found `%s`", vim.inspect(o.lazy_paths), vim.inspect(lazy_manifests))
if o.lazy_paths and #o.lazy_paths ~= 2 * #lazy_manifests then
log.warn(
"Could not resolve all manifests for lazy_paths `%s`: only found `%s`",
vim.inspect(o.lazy_paths),
vim.inspect(lazy_manifests)
)
end
for is_lazy, manifest_paths in pairs({[true] = lazy_manifests, [false] = manifests}) do
for is_lazy, manifest_paths in pairs({
[true] = lazy_manifests,
[false] = manifests,
}) do
for _, manifest_path in ipairs(manifest_paths) do
local ok, coll_or_err = pcall(Collection.new, manifest_path, lazy, o.include, o.exclude, o.add_opts, is_lazy, o.fs_event_providers)
local ok, coll_or_err = pcall(
Collection.new,
manifest_path,
lazy,
o.include,
o.exclude,
o.add_opts,
is_lazy,
o.fs_event_providers
)
if not ok then
log.error("Could not create collection for manifest %s: %s", manifest_path, coll_or_err)
log.error(
"Could not create collection for manifest %s: %s",
manifest_path,
coll_or_err
)
else
table.insert(Data.vscode_package_collections, coll_or_err)
end
@ -489,7 +559,9 @@ function M.lazy_load(opts)
_load(true, opts)
-- load for current buffer on startup.
for _, ft in ipairs(loader_util.get_load_fts(vim.api.nvim_get_current_buf())) do
for _, ft in
ipairs(loader_util.get_load_fts(vim.api.nvim_get_current_buf()))
do
M._load_lazy_loaded_ft(ft)
end
end
@ -499,13 +571,17 @@ function M.load_standalone(opts)
local lazy = vim.F.if_nil(opts.lazy, false)
local add_opts = loader_util.make_add_opts(opts)
local fs_event_providers = vim.F.if_nil(opts.fs_event_providers, {autocmd = true, libuv = false})
local fs_event_providers =
vim.F.if_nil(opts.fs_event_providers, { autocmd = true, libuv = false })
local path
if not lazy then
path = Path.expand(opts.path)
if not path then
log.error("Expanding path %s does not produce an existing path.", opts.path)
log.error(
"Expanding path %s does not produce an existing path.",
opts.path
)
return
end
else
@ -514,15 +590,26 @@ function M.load_standalone(opts)
Data.vscode_ft_paths["all"][path] = true
local ok, watcher_or_err = pcall(SnippetfileWatcher.new, path, "all", fs_event_providers, lazy, function()
local data = Data.vscode_cache:fetch(path)
-- autosnippets are included in snippets for this loader.
local snippets = data.snippets
loader_util.add_file_snippets("all", path, snippets, {}, add_opts)
end)
local ok, watcher_or_err = pcall(
SnippetfileWatcher.new,
path,
"all",
fs_event_providers,
lazy,
function()
local data = Data.vscode_cache:fetch(path)
-- autosnippets are included in snippets for this loader.
local snippets = data.snippets
loader_util.add_file_snippets("all", path, snippets, {}, add_opts)
end
)
if not ok then
log.error("Could not create SnippetFileWatcher for path %s: %s", path, watcher_or_err)
log.error(
"Could not create SnippetFileWatcher for path %s: %s",
path,
watcher_or_err
)
return
end

View file

@ -9,7 +9,9 @@ local M = {}
-- used by both watchers.
local callback_mt = {
__index = function() return util.nop end
__index = function()
return util.nop
end,
}
--- @alias LuaSnip.FSWatcher.FSEventProviders
@ -48,7 +50,8 @@ local callback_mt = {
local function get_opts(opts)
opts = opts or {}
local lazy = vim.F.if_nil(opts.lazy, false)
local fs_event_providers = vim.F.if_nil(opts.fs_event_providers, {autocmd = true, libuv = false})
local fs_event_providers =
vim.F.if_nil(opts.fs_event_providers, { autocmd = true, libuv = false })
return lazy, fs_event_providers
end
@ -65,10 +68,17 @@ vim.api.nvim_create_autocmd({ "BufWritePost" }, {
local realpath = Path.normalize(args.file)
if not realpath then
-- if nil, the path does not exist for some reason.
log.info("Registered BufWritePost with <afile> %s, but realpath does not exist. Aborting fs-watcher-notification.", args.file)
log.info(
"Registered BufWritePost with <afile> %s, but realpath does not exist. Aborting fs-watcher-notification.",
args.file
)
return
end
log.debug("Received update for file %s, using realpath %s.", args.file, realpath)
log.debug(
"Received update for file %s, using realpath %s.",
args.file,
realpath
)
-- remove stopped watchers.
-- Does not really matter whether we do this before or after the
@ -103,7 +113,7 @@ vim.api.nvim_create_autocmd({ "BufWritePost" }, {
--- @field root_realpath string? Set as soon as the watcher is started.
local TreeWatcher = {}
local TreeWatcher_mt = {
__index = TreeWatcher
__index = TreeWatcher,
}
function TreeWatcher:stop()
@ -129,39 +139,46 @@ function TreeWatcher:fs_event_callback(err, relpath, events)
return
end
vim.schedule_wrap(function()
log_tree.debug("raw: self.root: %s; err: %s; relpath: %s; change: %s; rename: %s", self.root, err, relpath, events.change, events.rename)
local full_path = Path.join(self.root, relpath)
local path_stat = uv.fs_stat(full_path)
log_tree.debug(
"raw: self.root: %s; err: %s; relpath: %s; change: %s; rename: %s",
self.root,
err,
relpath,
events.change,
events.rename
)
local full_path = Path.join(self.root, relpath)
local path_stat = uv.fs_stat(full_path)
-- try to figure out what happened in the directory.
if events.rename then
if not uv.fs_stat(self.root) then
self:remove_root()
return
end
if not path_stat then
self:remove_child(relpath, full_path)
return
end
-- try to figure out what happened in the directory.
if events.rename then
if not uv.fs_stat(self.root) then
self:remove_root()
return
end
if not path_stat then
self:remove_child(relpath, full_path)
return
end
local f_type
-- if there is a link to a directory, we are notified on changes!!
if path_stat.type == "link" then
f_type = uv.fs_stat(uv.fs_realpath(full_path))
else
f_type = path_stat.type
end
local f_type
-- if there is a link to a directory, we are notified on changes!!
if path_stat.type == "link" then
f_type = uv.fs_stat(uv.fs_realpath(full_path))
else
f_type = path_stat.type
end
if f_type == "file" then
self:new_file(relpath, full_path)
return
elseif f_type == "directory" then
self:new_dir(relpath, full_path)
return
if f_type == "file" then
self:new_file(relpath, full_path)
return
elseif f_type == "directory" then
self:new_dir(relpath, full_path)
return
end
elseif events.change then
self:change_child(relpath, full_path)
end
elseif events.change then
self:change_child(relpath, full_path)
end
end)()
end
@ -180,7 +197,8 @@ function TreeWatcher:BufWritePost_callback(realpath)
end
-- `#self.realpath_root+2`: remove root and path-separator.
local root_relative_components = Path.components(realpath:sub(#self.realpath_root+2))
local root_relative_components =
Path.components(realpath:sub(#self.realpath_root + 2))
local rel = root_relative_components[1]
if #root_relative_components == 1 then
-- wrote file.
@ -223,14 +241,25 @@ function TreeWatcher:start()
if self.fs_event_providers.libuv then
-- does not work on nfs-drive, at least if it's edited from another
-- machine.
local success, err = self.fs_event:start(self.root, {}, function(err, relpath, events)
self:fs_event_callback(err, relpath, events)
end)
local success, err = self.fs_event:start(
self.root,
{},
function(err, relpath, events)
self:fs_event_callback(err, relpath, events)
end
)
if not success then
log_tree.error("Could not start libuv-monitor for path %s due to error %s", self.path, err)
log_tree.error(
"Could not start libuv-monitor for path %s due to error %s",
self.path,
err
)
else
log_tree.info("Monitoring root-directory %s with libuv-monitor.", self.root)
log_tree.info(
"Monitoring root-directory %s with libuv-monitor.",
self.root
)
end
end
@ -241,9 +270,15 @@ function TreeWatcher:start()
if self.realpath_root then
-- receive notifications on BufWritePost.
table.insert(M.active_watchers, self)
log_tree.info("Monitoring root-directory %s with autocmd-monitor.", self.root)
log_tree.info(
"Monitoring root-directory %s with autocmd-monitor.",
self.root
)
else
log_tree.error("Could not resolve realpath for root %s, not enabling autocmd-monitor", self.root)
log_tree.error(
"Could not resolve realpath for root %s, not enabling autocmd-monitor",
self.root
)
end
end
@ -266,11 +301,11 @@ function TreeWatcher:start()
-- the watch-event, but that seems okay for our purposes)
local files, dirs = Path.scandir(self.root)
for _, file in ipairs(files) do
local relpath = file:sub(#self.root+2)
local relpath = file:sub(#self.root + 2)
self:new_file(relpath, file)
end
for _, dir in ipairs(dirs) do
local relpath = dir:sub(#self.root+2)
local relpath = dir:sub(#self.root + 2)
self:new_dir(relpath, dir)
end
end
@ -299,7 +334,12 @@ function TreeWatcher:new_dir(rel, full)
self.callbacks.new_dir(full)
-- directory exists => don't need to set lazy.
-- inherit fs_event_providers.
self.dir_watchers[rel] = M.tree(full, self.depth-1, self.callbacks, {lazy = false, fs_event_providers = self.fs_event_providers})
self.dir_watchers[rel] = M.tree(
full,
self.depth - 1,
self.callbacks,
{ lazy = false, fs_event_providers = self.fs_event_providers }
)
end
function TreeWatcher:change_file(rel, full)
@ -392,7 +432,7 @@ function M.tree(root, depth, callbacks, opts)
callbacks = callbacks,
depth = depth,
fs_event_providers = fs_event_providers
fs_event_providers = fs_event_providers,
}, TreeWatcher_mt)
-- if the path does not yet exist, set watcher up s.t. it will start
@ -405,7 +445,11 @@ function M.tree(root, depth, callbacks, opts)
error(("Could not find parent-path for %s"):format(root))
end
log_tree.info("Path %s does not exist yet, watching %s for creation.", root, parent_path)
log_tree.info(
"Path %s does not exist yet, watching %s for creation.",
root,
parent_path
)
local parent_watcher
parent_watcher = M.tree(parent_path, 1, {
@ -416,8 +460,8 @@ function M.tree(root, depth, callbacks, opts)
parent_watcher:stop_self()
end
end,
-- use same providers.
}, { lazy = true, fs_event_providers = fs_event_providers} )
-- use same providers.
}, { lazy = true, fs_event_providers = fs_event_providers })
else
o:start()
end
@ -437,14 +481,17 @@ end
local PathWatcher = {}
local PathWatcher_mt = {
__index = PathWatcher
__index = PathWatcher,
}
function PathWatcher:change(full)
log_path.info("detected change at path %s", full)
if self.removed then
-- this is certainly unexpected.
log_path.warn("PathWatcher at %s detected change, but path does not exist logically. Not triggering callback.", full)
log_path.warn(
"PathWatcher at %s detected change, but path does not exist logically. Not triggering callback.",
full
)
else
self.callbacks.change(self.path)
end
@ -482,7 +529,14 @@ function PathWatcher:fs_event_callback(err, relpath, events)
end
vim.schedule_wrap(function()
log_path.debug("raw: path: %s; err: %s; relpath: %s; change: %s; rename: %s", self.path, err, relpath, events.change, events.rename)
log_path.debug(
"raw: path: %s; err: %s; relpath: %s; change: %s; rename: %s",
self.path,
err,
relpath,
events.change,
events.rename
)
if events.rename then
if not uv.fs_stat(self.path) then
@ -517,12 +571,20 @@ function PathWatcher:start()
if self.fs_event_providers.libuv then
-- does not work on nfs-drive, at least if it's edited from another
-- machine.
local success, err = self.fs_event:start(self.path, {}, function(err, relpath, events)
self:fs_event_callback(err, relpath, events)
end)
local success, err = self.fs_event:start(
self.path,
{},
function(err, relpath, events)
self:fs_event_callback(err, relpath, events)
end
)
if not success then
log_path.error("Could not start libuv-monitor for file %s due to error %s", self.path, err)
log_path.error(
"Could not start libuv-monitor for file %s due to error %s",
self.path,
err
)
else
log_path.info("Monitoring file %s with libuv-monitor.", self.path)
end
@ -538,7 +600,10 @@ function PathWatcher:start()
table.insert(M.active_watchers, self)
log_path.info("Monitoring file %s with autocmd-monitor.", self.path)
else
log_path.error("Could not resolve realpath for file %s, not enabling BufWritePost-monitor", self.path)
log_path.error(
"Could not resolve realpath for file %s, not enabling BufWritePost-monitor",
self.path
)
end
end
@ -582,7 +647,7 @@ function M.path(path, callbacks, opts)
-- wait for `start()` to send notifications.
send_notifications = false,
callbacks = callbacks,
fs_event_providers = fs_event_providers
fs_event_providers = fs_event_providers,
}, PathWatcher_mt)
-- if the path does not yet exist, set watcher up s.t. it will start
@ -595,7 +660,11 @@ function M.path(path, callbacks, opts)
error(("Could not find parent-path for %s"):format(path))
end
log_path.info("Path %s does not exist yet, watching %s for creation.", path, parent_path)
log_path.info(
"Path %s does not exist yet, watching %s for creation.",
path,
parent_path
)
local parent_watcher
parent_watcher = M.tree(parent_path, 1, {
@ -608,7 +677,7 @@ function M.path(path, callbacks, opts)
parent_watcher:stop_self()
end
end,
}, {lazy = true, fs_event_providers = fs_event_providers} )
}, { lazy = true, fs_event_providers = fs_event_providers })
else
o:start()
end

View file

@ -12,7 +12,6 @@ local duplicate = require("luasnip.nodes.duplicate")
--- mtime is nil if the file does not currently exist. Since `get_fn` may still
--- return data, there's no need to treat this differently.
--- @class LuaSnip.Loaders.SnippetCache
--- SnippetCache stores snippets and other data loaded by files.
--- @field private get_fn fun(file: string): LuaSnip.Loaders.SnippetFileData
@ -33,7 +32,7 @@ local M = {}
function M.new(get_fn)
return setmetatable({
get_fn = get_fn,
cache = {}
cache = {},
}, SnippetCache)
end
@ -44,8 +43,11 @@ local function copy_filedata(data)
--- @as LuaSnip.Loaders.SnippetFileData
return {
snippets = vim.tbl_map(duplicate.duplicate_addable, data.snippets),
autosnippets = vim.tbl_map(duplicate.duplicate_addable, data.autosnippets),
misc = vim.deepcopy(data.misc)
autosnippets = vim.tbl_map(
duplicate.duplicate_addable,
data.autosnippets
),
misc = vim.deepcopy(data.misc),
}
end
@ -62,7 +64,12 @@ function SnippetCache:fetch(fname)
--- @as LuaSnip.Loaders.SnippetCache.Mtime
local mtime = current_stat and current_stat.mtime
if cached and mtime and mtime.sec == cached.mtime.sec and mtime.nsec == cached.mtime.nsec then
if
cached
and mtime
and mtime.sec == cached.mtime.sec
and mtime.nsec == cached.mtime.nsec
then
-- happy path: data is cached, and valid => just return cached data.
return copy_filedata(cached.data)
end
@ -75,7 +82,7 @@ function SnippetCache:fetch(fname)
-- store it.
self.cache[fname] = {
data = res,
mtime = mtime
mtime = mtime,
}
-- return it.

View file

@ -124,7 +124,9 @@ local function collection_file_ft(collection_root, fname)
if #fname_components == #collection_components + 1 then
-- if the file is a direct child of the collection-root, get the text
-- before the last dot.
return fname_components[#collection_components + 1]:match("(.*)%.[^%.]*")
return fname_components[#collection_components + 1]:match(
"(.*)%.[^%.]*"
)
else
-- if the file is nested deeper, the name of the directory immediately
-- below the root is the filetype.
@ -227,13 +229,15 @@ local function get_load_fts(bufnr)
end
local function add_file_snippets(ft, filename, snippets, autosnippets, add_opts)
snippet_collection.add_snippets({ [ft] = snippets },
snippet_collection.add_snippets(
{ [ft] = snippets },
vim.tbl_extend("keep", {
type = "snippets",
key = "__snippets__" .. ft .. "__" .. filename,
}, add_opts)
)
snippet_collection.add_snippets({ [ft] = autosnippets },
snippet_collection.add_snippets(
{ [ft] = autosnippets },
vim.tbl_extend("keep", {
type = "autosnippets",
key = "__autosnippets__" .. ft .. "__" .. filename,
@ -264,7 +268,8 @@ local function normalize_opts(opts)
lazy_paths = vim.split(lazy_paths, ",")
end
local fs_event_providers = vim.F.if_nil(opts.fs_event_providers, {autocmd = true, libuv = false})
local fs_event_providers =
vim.F.if_nil(opts.fs_event_providers, { autocmd = true, libuv = false })
return {
paths = paths,

View file

@ -66,7 +66,7 @@ local DupAddable_mt = {
function M.duplicate_addable(addable)
return setmetatable({
addable = addable,
_all = vim.tbl_map(M.duplicate_expandable, addable:retrieve_all())
_all = vim.tbl_map(M.duplicate_expandable, addable:retrieve_all()),
}, DupAddable_mt)
end

View file

@ -26,7 +26,7 @@ local clean_enqueued = false
function M.clean_invalidated()
if not clean_enqueued then
vim.schedule(function()
snippet_collection.clean_invalidated({inv_limit = 100})
snippet_collection.clean_invalidated({ inv_limit = 100 })
end)
end
clean_enqueued = true

View file

@ -1,6 +1,7 @@
local source = require("luasnip.session.snippet_collection.source")
local u_table = require("luasnip.util.table")
local auto_creating_tables = require("luasnip.util.auto_table").warn_depth_autotable
local auto_creating_tables =
require("luasnip.util.auto_table").warn_depth_autotable
local session = require("luasnip.session")
-- store snippets by some key.
@ -238,7 +239,8 @@ function M.add_snippets(snippets, opts)
or opts.type
assert(
snip_type == "autosnippets" or snip_type == "snippets",
"snippetType must be either 'autosnippets' or 'snippets', was " .. vim.inspect(snip_type)
"snippetType must be either 'autosnippets' or 'snippets', was "
.. vim.inspect(snip_type)
)
local snip_ft = snip.filetype or ft
@ -312,7 +314,7 @@ end
-- modules that want to call refresh_notify probably also want to notify others
-- of adding those snippets => put those functions into the same module.
function M.refresh_notify(ft_or_nil)
local fts = ft_or_nil and {ft_or_nil} or get_all_snippet_fts()
local fts = ft_or_nil and { ft_or_nil } or get_all_snippet_fts()
for _, ft in ipairs(fts) do
session.latest_load_ft = ft

View file

@ -25,8 +25,8 @@ local function auto_creating_tables(self, key, depth)
if depth ~= 1 then
setmetatable(t, {
__index = function(s, k)
return auto_creating_tables(s, k, depth-1)
end
return auto_creating_tables(s, k, depth - 1)
end,
})
end
self[key] = t
@ -39,12 +39,13 @@ function M.autotable(max_depth, opts)
opts = opts or {}
local warn = vim.F.if_nil(opts.warn, false)
local auto_table_func = warn and auto_creating_tables_warn_depth or auto_creating_tables
local auto_table_func = warn and auto_creating_tables_warn_depth
or auto_creating_tables
return setmetatable({}, {
__index = function(s, k)
return auto_table_func(s, k, max_depth-1)
end
return auto_table_func(s, k, max_depth - 1)
end,
})
end

View file

@ -150,13 +150,12 @@ end
-- return all vertices reachable from this one.
function DirectedGraph:connected_component(vert, edge_direction)
local outgoing_vertices_field =
edge_direction == "Backward"
local outgoing_vertices_field = edge_direction == "Backward"
and "incoming_edge_verts"
or "outgoing_edge_verts"
or "outgoing_edge_verts"
local visited = {}
local to_visit = {[vert] = true}
local to_visit = { [vert] = true }
-- get any value in table.
local next_vert, _ = next(to_visit, nil)
@ -188,9 +187,9 @@ local function new_labeled_graph()
label_to_vert = {},
vert_to_label = {},
-- map label -> origin-vert -> dest-vert
label_to_verts = autotable(3, {warn = false}),
label_to_verts = autotable(3, { warn = false }),
-- map edge (origin,dest) to set of labels.
verts_to_label = autotable(3, {warn = false})
verts_to_label = autotable(3, { warn = false }),
}, LabeledDigraph)
end
@ -218,7 +217,7 @@ function LabeledDigraph:set_edge(lv1, lv2, edge_label)
-- determine before setting the lv1-lv2-edge.
local other_edge_exists = next(self.verts_to_label[lv1][lv2], nil) ~= nil
-- store both associations;
-- store both associations;
self.verts_to_label[lv1][lv2][edge_label] = true
self.label_to_verts[edge_label][lv1][lv2] = true
@ -260,5 +259,5 @@ end
return {
new = new_graph,
new_labeled = new_labeled_graph
new_labeled = new_labeled_graph,
}

View file

@ -95,7 +95,10 @@ function Path.expand_nonexisting(filepath, cwd)
-- replace ~ with home-directory.
:gsub("^~", vim.env.HOME)
-- replace ./ or .\ with config-directory (likely ~/.config/nvim)
:gsub("^[.][/\\]", MYCONFIG_ROOT .. sep)
:gsub(
"^[.][/\\]",
MYCONFIG_ROOT .. sep
)
return Path.normalize_nonexisting(filepath, cwd)
end
@ -182,11 +185,11 @@ function Path.extension(fname)
end
function Path.components(path)
return vim.split(path, sep, {plain=true, trimempty=true})
return vim.split(path, sep, { plain = true, trimempty = true })
end
function Path.parent(path)
local last_component = path:match("%" .. sep .."[^" .. sep .. "]+$")
local last_component = path:match("%" .. sep .. "[^" .. sep .. "]+$")
if not last_component then
return nil
end

View file

@ -12,7 +12,6 @@ local function set_to_list(tbl)
return ls
end
---Convert value or list of values to a table of booleans for fast lookup.
---@generic T
---@param values T|T[]|table<T, boolean>

View file

@ -84,9 +84,7 @@ require("luasnip.config")._setup()
vim.api.nvim_create_augroup("_luasnip_lazy_load", {})
vim.api.nvim_create_autocmd({ "BufWinEnter", "FileType" }, {
callback = function(event)
require("luasnip.loaders").load_lazy_loaded(
tonumber(event.buf)
)
require("luasnip.loaders").load_lazy_loaded(tonumber(event.buf))
end,
group = "_luasnip_lazy_load",
})

View file

@ -312,8 +312,8 @@ M.scratchdir_path = scratchdir_path
function M.scratch_prepare()
-- clean (maybe a test was not able to clean up after itself) and re-create
-- scratch-directory.
os.execute(("rm -rf \"%s\""):format(scratchdir_path))
os.execute(("mkdir \"%s\""):format(scratchdir_path))
os.execute(('rm -rf "%s"'):format(scratchdir_path))
os.execute(('mkdir "%s"'):format(scratchdir_path))
exec_lua(([[
local function translate_callbacks(cbs)
@ -341,14 +341,14 @@ function M.scratch_prepare()
end
function M.scratch_mkdir(scratch_rel)
os.execute(("mkdir -p \"%s/%s\""):format(scratchdir_path, scratch_rel))
os.execute(('mkdir -p "%s/%s"'):format(scratchdir_path, scratch_rel))
end
function M.scratch_touch(scratch_rel)
os.execute(("touch \"%s/%s\""):format(scratchdir_path, scratch_rel))
os.execute(('touch "%s/%s"'):format(scratchdir_path, scratch_rel))
end
function M.scratch_clear()
os.execute(("rm -rf \"%s\""):format(scratchdir_path))
os.execute(('rm -rf "%s"'):format(scratchdir_path))
end
function M.scratch_edit(scratch_rel)

View file

@ -338,27 +338,31 @@ describe("add_snippets", function()
-- maybe a bit out of place here, but this issue would mainly manifest when invalidating snippets for some key.
it("replacing snippets via key works for duplicated snippets.", function()
exec_lua[[
exec_lua([[
ls.add_snippets("all", {
require("luasnip.nodes.duplicate").duplicate_addable(s("asdf", {t"fasd"}))
}, {key = "asdf"})
]]
]])
feed("iasdf")
exec_lua("ls.expand()")
screen:expect{grid=[[
screen:expect({
grid = [[
fasd^ |
{0:~ }|
{2:-- INSERT --} |]]}
exec_lua[[
{2:-- INSERT --} |]],
})
exec_lua([[
ls.add_snippets("all", {
require("luasnip.nodes.duplicate").duplicate_addable(s("asdf", {t"asdf"}))
}, {key = "asdf"})
]]
]])
feed("<esc>ccasdf")
exec_lua("ls.expand()")
screen:expect{grid=[[
screen:expect({
grid = [[
asdf^ |
{0:~ }|
{2:-- INSERT --} |]]}
{2:-- INSERT --} |]],
})
end)
end)

View file

@ -425,35 +425,25 @@ describe("loaders:", function()
"<Esc>2jwcereplaces"
)
reload_test(
"vscode-reload: load symlinked and edit real",
function()
exec_lua(
string.format(
[[require("luasnip.loaders.from_vscode").lazy_load({paths="%s"})]],
os.getenv("LUASNIP_SOURCE")
.. "/tests/symlinked_data/vscode-snippets"
)
reload_test("vscode-reload: load symlinked and edit real", function()
exec_lua(
string.format(
[[require("luasnip.loaders.from_vscode").lazy_load({paths="%s"})]],
os.getenv("LUASNIP_SOURCE")
.. "/tests/symlinked_data/vscode-snippets"
)
end,
"/tests/data/vscode-snippets/snippets/all.json",
"<Esc>4jwlcereplaces"
)
)
end, "/tests/data/vscode-snippets/snippets/all.json", "<Esc>4jwlcereplaces")
reload_test(
"lua-reload: load symlinked and edit real",
function()
exec_lua(
string.format(
[[require("luasnip.loaders.from_lua").lazy_load({paths="%s"})]],
os.getenv("LUASNIP_SOURCE")
.. "/tests/symlinked_data/lua-snippets/luasnippets"
)
reload_test("lua-reload: load symlinked and edit real", function()
exec_lua(
string.format(
[[require("luasnip.loaders.from_lua").lazy_load({paths="%s"})]],
os.getenv("LUASNIP_SOURCE")
.. "/tests/symlinked_data/lua-snippets/luasnippets"
)
end,
"/tests/data/lua-snippets/luasnippets/all.lua",
"<Esc>jfecereplaces"
)
)
end, "/tests/data/lua-snippets/luasnippets/all.lua", "<Esc>jfecereplaces")
reload_test(
"snipmate-reload: load real and edit symlinked",
@ -507,7 +497,7 @@ describe("loaders:", function()
--- Multiple writes are sometimes necessary because after the first write,
--- for some reason, a function called in BufWritePost does not read the
--- new file contents.
---
---
--- I've never encountered either of these issues in normal usage, so I'm
--- guessing that they are somehow caused by the testing-framework.
---
@ -579,95 +569,111 @@ describe("loaders:", function()
end)
it("lazy registration works for lua.", function()
exec_lua( ([[
exec_lua(([[
require("luasnip.loaders.from_lua").load({lazy_paths="%s"})
]]):format(ls_helpers.scratchdir_path .. "/snippets") )
]]):format(ls_helpers.scratchdir_path .. "/snippets"))
ls_helpers.scratch_edit("snippets/all.lua")
feed([[ireturn { ls.parser.parse_snippet("asdf", "qwer") }]])
screen:expect{grid=[[
screen:expect({
grid = [[
return { ls.parser.parse_snippet("asdf", "qwer") }|
{0:^~ }|
{0:~ }|
{0:~ }|
{2:-- INSERT --} |]]}
{2:-- INSERT --} |]],
})
feed("<Esc>:w<Cr>")
feed("oasdf")
screen:expect{grid=[[
screen:expect({
grid = [[
return { ls.parser.parse_snippet("asdf", "qwer") }|
asdf^ |
{0:~ }|
{0:~ }|
{2:-- INSERT --} |]]}
{2:-- INSERT --} |]],
})
exec_lua("ls.expand()")
screen:expect{grid=[[
screen:expect({
grid = [[
return { ls.parser.parse_snippet("asdf", "qwer") }|
qwer^ |
{0:~ }|
{0:~ }|
{2:-- INSERT --} |]]}
{2:-- INSERT --} |]],
})
end)
it("lazy registration works for snipmate.", function()
exec_lua( ([[
exec_lua(([[
require("luasnip.loaders.from_snipmate").load({lazy_paths="%s"})
]]):format(ls_helpers.scratchdir_path .. "/snippets") )
]]):format(ls_helpers.scratchdir_path .. "/snippets"))
ls_helpers.scratch_edit("snippets/all.snippets")
feed([[isnippet asdf<Cr> qwer]])
screen:expect{grid=[[
screen:expect({
grid = [[
snippet asdf |
qwer^ |
{0:~ }|
{0:~ }|
{2:-- INSERT --} |]]}
{2:-- INSERT --} |]],
})
feed("<Esc>:w<Cr>")
feed("oasdf")
screen:expect{grid=[[
screen:expect({
grid = [[
snippet asdf |
qwer |
asdf^ |
{0:~ }|
{2:-- INSERT --} |]]}
{2:-- INSERT --} |]],
})
exec_lua("ls.expand()")
screen:expect{grid=[[
screen:expect({
grid = [[
snippet asdf |
qwer |
qwer^ |
{0:~ }|
{2:-- INSERT --} |]]}
{2:-- INSERT --} |]],
})
end)
it("lazy registration works for vscode (packages).", function()
exec_lua( ([[
exec_lua(([[
require("luasnip.loaders.from_vscode").load({lazy_paths="%s"})
]]):format(ls_helpers.scratchdir_path .. "/snippets") )
]]):format(ls_helpers.scratchdir_path .. "/snippets"))
-- double as quick test for package.jsonc
ls_helpers.scratch_edit("snippets/package.jsonc")
feed([[i{ "name": "snippets", "contributes": { "snippets": [{"language": ["all"], "path": "./all.json"}] } }]])
feed(
[[i{ "name": "snippets", "contributes": { "snippets": [{"language": ["all"], "path": "./all.json"}] } }]]
)
feed("<Esc>:w<Cr>")
feed("<Esc>:w<Cr>")
feed("<Esc>:w<Cr>")
exec_lua("vim.wait(100, function() end)")
screen:expect{grid=[[
screen:expect({
grid = [[
{ "name": "snippets", "contributes": { "snippets":|
[{"language": ["all"], "path": "./all.json"}] } ^}|
{0:~ }|
{0:~ }|
<scratch/snippets/package.jsonc" 1L, 101B written |]]}
<scratch/snippets/package.jsonc" 1L, 101B written |]],
})
ls_helpers.scratch_edit("snippets/all.json")
@ -677,60 +683,75 @@ describe("loaders:", function()
feed("<Esc>:w<Cr>")
exec_lua("vim.wait(100, function() end)")
screen:expect{grid=[[
screen:expect({
grid = [[
{"snip": {"prefix": "asdf", "body": ["qwer"]}^} |
{0:~ }|
{0:~ }|
{0:~ }|
<tests/scratch/snippets/all.json" 1L, 47B written |]]}
<tests/scratch/snippets/all.json" 1L, 47B written |]],
})
feed("oasdf")
exec_lua("ls.expand()")
screen:expect{grid=[[
screen:expect({
grid = [[
{"snip": {"prefix": "asdf", "body": ["qwer"]}} |
qwer^ |
{0:~ }|
{0:~ }|
{2:-- INSERT --} |]]}
{2:-- INSERT --} |]],
})
end)
it("lazy registration works for vscode (standalone .code-snippets).", function()
exec_lua( ([[
it(
"lazy registration works for vscode (standalone .code-snippets).",
function()
exec_lua(
([[
require("luasnip.loaders.from_vscode").load_standalone({path = "%s", lazy = true})
]]):format(ls_helpers.scratchdir_path .. "/vs/snips.code-snippets") )
]]):format(
ls_helpers.scratchdir_path .. "/vs/snips.code-snippets"
)
)
ls_helpers.scratch_edit("vs/snips.code-snippets")
ls_helpers.scratch_edit("vs/snips.code-snippets")
feed([[i{"snip": {"prefix": "asdf", "body": ["qwer"]}}]])
feed("<Esc>:w<Cr>")
feed("<Esc>:w<Cr>")
exec_lua("vim.wait(100, function() end)")
feed([[i{"snip": {"prefix": "asdf", "body": ["qwer"]}}]])
feed("<Esc>:w<Cr>")
feed("<Esc>:w<Cr>")
exec_lua("vim.wait(100, function() end)")
screen:expect{grid=[[
screen:expect({
grid = [[
{"snip": {"prefix": "asdf", "body": ["qwer"]}^} |
{0:~ }|
{0:~ }|
{0:~ }|
</scratch/vs/snips.code-snippets" 1L, 47B written |]]}
</scratch/vs/snips.code-snippets" 1L, 47B written |]],
})
feed("oasdf")
exec_lua("ls.expand()")
feed("oasdf")
exec_lua("ls.expand()")
screen:expect{grid=[[
screen:expect({
grid = [[
{"snip": {"prefix": "asdf", "body": ["qwer"]}} |
qwer^ |
{0:~ }|
{0:~ }|
{2:-- INSERT --} |]]}
end)
{2:-- INSERT --} |]],
})
end
)
it("lua-loader refreshes snippets when dependency is written.", function()
ls_helpers.scratch_mkdir("snippets")
exec_lua( ([[
exec_lua(([[
require("luasnip.loaders.from_lua").lazy_load({paths="%s"})
]]):format(ls_helpers.scratchdir_path .. "/snippets") )
]]):format(ls_helpers.scratchdir_path .. "/snippets"))
-- this file will provide the body of the snippet.
ls_helpers.scratch_edit("util/a_string.lua")
@ -740,20 +761,28 @@ describe("loaders:", function()
ls_helpers.scratch_edit("snippets/all.lua")
-- extract into variable, so the path does no show up in screen-tests.
exec_lua(([[dependency_file = "%s"]]):format(ls_helpers.scratchdir_path .. "/util/a_string.lua"))
feed([[ireturn { ls.parser.parse_snippet("asdf", ls_tracked_dofile(dependency_file)) }]])
exec_lua(
([[dependency_file = "%s"]]):format(
ls_helpers.scratchdir_path .. "/util/a_string.lua"
)
)
feed(
[[ireturn { ls.parser.parse_snippet("asdf", ls_tracked_dofile(dependency_file)) }]]
)
feed("<Esc>:w<Cr>")
exec_lua("vim.wait(100, function() end)")
feed("oasdf")
exec_lua("ls.expand()")
screen:expect{grid=[[
screen:expect({
grid = [[
return { ls.parser.parse_snippet("asdf", ls_tracke|
d_dofile(dependency_file)) } |
qwer^ |
{0:~ }|
{2:-- INSERT --} |]]}
{2:-- INSERT --} |]],
})
ls_helpers.scratch_edit("util/a_string.lua")
feed([[<Esc>$bcezxcv]])
@ -761,75 +790,92 @@ describe("loaders:", function()
feed("oasdf")
exec_lua("ls.expand()")
screen:expect{grid=[[
screen:expect({
grid = [[
return "zxcv" |
zxcv^ |
{0:~ }|
{0:~ }|
{2:-- INSERT --} |]]}
{2:-- INSERT --} |]],
})
end)
it("snipmate-loader handles transitive extends, and updates it when changed.", function()
-- setup filetypes A B C D, where A extends B, and C extends D, but B (initially) does not extend C.
-- If we add this extends, snippets from D should be available in A.
-- I think if this works, all the "simpler" cases should also work fine. Add more tests if they don't.
it(
"snipmate-loader handles transitive extends, and updates it when changed.",
function()
-- setup filetypes A B C D, where A extends B, and C extends D, but B (initially) does not extend C.
-- If we add this extends, snippets from D should be available in A.
-- I think if this works, all the "simpler" cases should also work fine. Add more tests if they don't.
ls_helpers.scratch_mkdir("snippets")
exec_lua( ([[
ls_helpers.scratch_mkdir("snippets")
exec_lua(([[
require("luasnip.loaders.from_snipmate").lazy_load({paths="%s"})
]]):format(ls_helpers.scratchdir_path .. "/snippets") )
]]):format(ls_helpers.scratchdir_path .. "/snippets"))
ls_helpers.scratch_edit("snippets/A.snippets")
feed([[iextends B<Esc>:w<Cr>]])
ls_helpers.scratch_edit("snippets/C.snippets")
feed([[iextends D<Esc>:w<Cr>]])
ls_helpers.scratch_edit("snippets/D.snippets")
feed([[isnippet DDDD<Cr> dddd<Esc>:w<Cr>]])
ls_helpers.scratch_edit("snippets/A.snippets")
feed([[iextends B<Esc>:w<Cr>]])
ls_helpers.scratch_edit("snippets/C.snippets")
feed([[iextends D<Esc>:w<Cr>]])
ls_helpers.scratch_edit("snippets/D.snippets")
feed([[isnippet DDDD<Cr> dddd<Esc>:w<Cr>]])
ls_helpers.scratch_edit("snippets/B.snippets")
feed([[iextends C<Esc>:w<Cr>]])
ls_helpers.scratch_edit("snippets/B.snippets")
feed([[iextends C<Esc>:w<Cr>]])
exec_lua("vim.wait(100, function() end)")
exec_lua("vim.wait(100, function() end)")
exec("set ft=A")
feed("oDDDD")
exec_lua("ls.expand()")
screen:expect{grid=[[
exec("set ft=A")
feed("oDDDD")
exec_lua("ls.expand()")
screen:expect({
grid = [[
extends C |
dddd^ |
{0:~ }|
{0:~ }|
{2:-- INSERT --} |]]}
{2:-- INSERT --} |]],
})
-- make sure we know that A receives snippets from 4 files,
-- A/B/C/D.snippets.
-- This data is used in the edit_snippet_files-dialog, and this check is
-- to somewhat ensure it behaves consistently (can't test it directly,
-- unfortunately, I guess since the test-instance waits for input before
-- proceeding, but as soon as we give it, we can't check the options :( )
-- Anyway, this works too, for now.
assert.are.same(4, exec_lua([[return #require("luasnip.util.table").set_to_list(require("luasnip.loaders.data").snipmate_ft_paths["A"]) ]]))
end)
-- make sure we know that A receives snippets from 4 files,
-- A/B/C/D.snippets.
-- This data is used in the edit_snippet_files-dialog, and this check is
-- to somewhat ensure it behaves consistently (can't test it directly,
-- unfortunately, I guess since the test-instance waits for input before
-- proceeding, but as soon as we give it, we can't check the options :( )
-- Anyway, this works too, for now.
assert.are.same(
4,
exec_lua(
[[return #require("luasnip.util.table").set_to_list(require("luasnip.loaders.data").snipmate_ft_paths["A"]) ]]
)
)
end
)
it("Clearing before a lazy collection is loaded will prevent it from loading.", function()
exec_lua( ([[
it(
"Clearing before a lazy collection is loaded will prevent it from loading.",
function()
exec_lua(([[
require("luasnip.loaders.from_snipmate").load({lazy_paths="%s"})
]]):format(ls_helpers.scratchdir_path .. "/snippets") )
exec_lua("ls.cleanup()")
]]):format(ls_helpers.scratchdir_path .. "/snippets"))
exec_lua("ls.cleanup()")
ls_helpers.scratch_edit("snippets/all.snippets")
feed([[isnippet DDDD<Cr> dddd<Esc>:w<Cr>]])
-- make sure snippets are not loaded because of cleanup, and not
-- because we don't give the test-instance time to load them :D
exec_lua("vim.wait(100, function() end)")
ls_helpers.scratch_edit("snippets/all.snippets")
feed([[isnippet DDDD<Cr> dddd<Esc>:w<Cr>]])
-- make sure snippets are not loaded because of cleanup, and not
-- because we don't give the test-instance time to load them :D
exec_lua("vim.wait(100, function() end)")
feed("oDDDD")
exec_lua("ls.expand()")
screen:expect{grid=[[
feed("oDDDD")
exec_lua("ls.expand()")
screen:expect({
grid = [[
snippet DDDD |
dddd |
DDDD^ |
{0:~ }|
{2:-- INSERT --} |]]}
end)
{2:-- INSERT --} |]],
})
end
)
end)

View file

@ -91,8 +91,9 @@ describe("fs_events", function()
["a/1/b"] = 1,
["a/3/b/d"] = 1,
["a/4/a/a"] = 1,
["a/4/a/b/a"] = 0
}, {
["a/4/a/b/a"] = 0,
},
{
-- directories
["a/1"] = 1,
["a/2"] = 1,
@ -101,16 +102,17 @@ describe("fs_events", function()
["a/3/b/c"] = 1,
["a/4"] = 1,
["a/4/a"] = 1,
["a/4/a/b"] = 1
}, {
["a/4/a/b"] = 1,
},
{
-- changed files
-- this is reported twice, once on create, once on the actual change.
-- Maybe a small peculiarity to watch out for, but does not seem bad.
["a/1/a"] = 2,
["a/1/b"] = 1
}},
exec_lua([[return {seen_files, seen_dirs, changed}]]) )
["a/1/b"] = 1,
},
}, exec_lua([[return {seen_files, seen_dirs, changed}]]))
end)
it("works with autocmd-event-provider.", function()
@ -185,21 +187,23 @@ describe("fs_events", function()
["a/3/b/d"] = 1,
["a/4/a/a"] = 1,
["a/4/a/b/a"] = 0,
}, {
},
{
["a/1"] = 1,
["a/3"] = 1,
["a/3/b"] = 1,
["a/4"] = 1,
["a/4/a"] = 1,
["a/4/a/b"] = 1,
}, {
},
{
["a/1/b"] = 1,
["a/1/a"] = 1,
["a/4/a/a"] = 1,
-- to deep.
["a/4/a/b/a"] = 0
} },
exec_lua([[return {seen_files, seen_dirs, changed}]]) )
["a/4/a/b/a"] = 0,
},
}, exec_lua([[return {seen_files, seen_dirs, changed}]]))
end)
it("lazy registration works with libuv.", function()
@ -233,10 +237,11 @@ describe("fs_events", function()
assert.are.same({
{
["a/a/a"] = 1,
}, {
},
{
["a/a/a"] = 1,
} },
exec_lua([[return {seen_files, changed}]]) )
},
}, exec_lua([[return {seen_files, changed}]]))
end)
it("lazy registration works with autocmd.", function()
@ -269,9 +274,10 @@ describe("fs_events", function()
assert.are.same({
{
["a/a/a"] = 1,
}, {
},
{
["a/a/a"] = 1,
} },
exec_lua([[return {seen_files, changed}]]) )
},
}, exec_lua([[return {seen_files, changed}]]))
end)
end)