refactor(pack,ts): switch specs to src field and decentralize update hooks
This commit is contained in:
@@ -37,13 +37,16 @@ require("pack").setup({
|
|||||||
"https://github.com/hedyhli/outline.nvim",
|
"https://github.com/hedyhli/outline.nvim",
|
||||||
"nvim.undotree",
|
"nvim.undotree",
|
||||||
{
|
{
|
||||||
"https://github.com/saghen/blink.cmp",
|
src = "https://github.com/saghen/blink.cmp",
|
||||||
version = vim.version.range("^1"),
|
version = vim.version.range("^1"),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
require("ts").setup({
|
require("ts").setup({
|
||||||
"https://github.com/tree-sitter/tree-sitter-bash",
|
{
|
||||||
|
src = "https://github.com/tree-sitter/tree-sitter-bash",
|
||||||
|
filetypes = { "sh" },
|
||||||
|
},
|
||||||
-- required by cpp
|
-- required by cpp
|
||||||
"https://github.com/tree-sitter/tree-sitter-c",
|
"https://github.com/tree-sitter/tree-sitter-c",
|
||||||
"https://github.com/uyha/tree-sitter-cmake",
|
"https://github.com/uyha/tree-sitter-cmake",
|
||||||
@@ -54,14 +57,14 @@ require("ts").setup({
|
|||||||
"https://github.com/gbprod/tree-sitter-gitcommit",
|
"https://github.com/gbprod/tree-sitter-gitcommit",
|
||||||
"https://github.com/tree-sitter/tree-sitter-go",
|
"https://github.com/tree-sitter/tree-sitter-go",
|
||||||
{
|
{
|
||||||
"https://github.com/ngalaiko/tree-sitter-go-template",
|
src = "https://github.com/ngalaiko/tree-sitter-go-template",
|
||||||
lang = "gotmpl",
|
lang = "gotmpl",
|
||||||
},
|
},
|
||||||
"https://github.com/tree-sitter/tree-sitter-html",
|
"https://github.com/tree-sitter/tree-sitter-html",
|
||||||
"https://github.com/tree-sitter/tree-sitter-json",
|
"https://github.com/tree-sitter/tree-sitter-json",
|
||||||
"https://github.com/tree-sitter-grammars/tree-sitter-luadoc",
|
"https://github.com/tree-sitter-grammars/tree-sitter-luadoc",
|
||||||
{
|
{
|
||||||
"https://github.com/tree-sitter/tree-sitter-php",
|
src = "https://github.com/tree-sitter/tree-sitter-php",
|
||||||
parsers = {
|
parsers = {
|
||||||
{ lang = "php", location = "php" },
|
{ lang = "php", location = "php" },
|
||||||
{ lang = "php_only", location = "php_only" },
|
{ lang = "php_only", location = "php_only" },
|
||||||
@@ -71,19 +74,19 @@ require("ts").setup({
|
|||||||
"https://github.com/tree-sitter/tree-sitter-rust",
|
"https://github.com/tree-sitter/tree-sitter-rust",
|
||||||
"https://github.com/serenadeai/tree-sitter-scss",
|
"https://github.com/serenadeai/tree-sitter-scss",
|
||||||
{
|
{
|
||||||
"https://github.com/derekstride/tree-sitter-sql",
|
src = "https://github.com/derekstride/tree-sitter-sql",
|
||||||
version = "gh-pages",
|
version = "gh-pages",
|
||||||
},
|
},
|
||||||
"https://github.com/tree-sitter-grammars/tree-sitter-svelte",
|
"https://github.com/tree-sitter-grammars/tree-sitter-svelte",
|
||||||
{
|
{
|
||||||
"https://github.com/tree-sitter/tree-sitter-typescript",
|
src = "https://github.com/tree-sitter/tree-sitter-typescript",
|
||||||
parsers = {
|
parsers = {
|
||||||
{ lang = "typescript", location = "typescript" },
|
{ lang = "typescript", location = "typescript" },
|
||||||
{ lang = "tsx", location = "tsx" },
|
{ lang = "tsx", location = "tsx" },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"https://github.com/tree-sitter-grammars/tree-sitter-xml",
|
src = "https://github.com/tree-sitter-grammars/tree-sitter-xml",
|
||||||
parsers = {
|
parsers = {
|
||||||
{ lang = "xml", location = "xml" },
|
{ lang = "xml", location = "xml" },
|
||||||
{ lang = "dtd", location = "dtd" },
|
{ lang = "dtd", location = "dtd" },
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ local plugin_cmds = {
|
|||||||
max_args = 1,
|
max_args = 1,
|
||||||
complete = complete_plugin_names,
|
complete = complete_plugin_names,
|
||||||
run = function(args)
|
run = function(args)
|
||||||
require("pack").reload_plugin(args[1] --[[@as -nil]])
|
require("pack").reload_plugin(args[1] --[[@as -nil]], true)
|
||||||
end,
|
end,
|
||||||
},
|
},
|
||||||
update = {
|
update = {
|
||||||
|
|||||||
+69
-70
@@ -24,13 +24,11 @@ local function exec(path)
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
---@class ow.Pack.PluginSpec
|
---@class ow.Pack.Spec : vim.pack.Spec
|
||||||
---@field [1] string
|
---@field src string
|
||||||
---@field name? string
|
|
||||||
---@field version? string | vim.VersionRange
|
|
||||||
---@field build? string[] | fun(self: ow.Pack.Plugin)
|
---@field build? string[] | fun(self: ow.Pack.Plugin)
|
||||||
|
|
||||||
---@class ow.Pack.Plugin : ow.Pack.PluginSpec
|
---@class ow.Pack.Plugin : ow.Pack.Spec
|
||||||
---@field name string
|
---@field name string
|
||||||
---@field path string
|
---@field path string
|
||||||
|
|
||||||
@@ -81,7 +79,7 @@ local function is_url(src)
|
|||||||
return src:find("://") ~= nil
|
return src:find("://") ~= nil
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param spec string | ow.Pack.PluginSpec
|
---@param spec string | ow.Pack.Spec
|
||||||
---@return vim.pack.Spec
|
---@return vim.pack.Spec
|
||||||
local function to_pack_spec(spec)
|
local function to_pack_spec(spec)
|
||||||
if type(spec) == "string" then
|
if type(spec) == "string" then
|
||||||
@@ -89,7 +87,7 @@ local function to_pack_spec(spec)
|
|||||||
end
|
end
|
||||||
|
|
||||||
return {
|
return {
|
||||||
src = spec[1],
|
src = spec.src,
|
||||||
name = spec.name,
|
name = spec.name,
|
||||||
version = spec.version,
|
version = spec.version,
|
||||||
data = {
|
data = {
|
||||||
@@ -130,62 +128,49 @@ local watcher = nil
|
|||||||
---@type ow.Util.KeyedDebounceHandle<string>?
|
---@type ow.Util.KeyedDebounceHandle<string>?
|
||||||
local on_change_handle = nil
|
local on_change_handle = nil
|
||||||
|
|
||||||
---@alias ow.Pack.Hook fun(ev: ow.Pack.Event.Data)
|
---@alias ow.Pack.Hook fun(data: ow.Pack.Event.Data)
|
||||||
|
|
||||||
---@type table<string, ow.Pack.Hook>
|
|
||||||
local hooks = {}
|
|
||||||
|
|
||||||
---@class ow.Pack
|
---@class ow.Pack
|
||||||
---@field plugins ow.Pack.Plugin[]
|
---@field plugins table<string, ow.Pack.Plugin> keyed by src
|
||||||
local M = {
|
local M = {
|
||||||
plugins = {},
|
plugins = {},
|
||||||
}
|
}
|
||||||
|
|
||||||
---@param name string
|
|
||||||
---@param fn ow.Pack.Hook
|
|
||||||
function M.register_hook(name, fn)
|
|
||||||
hooks[name] = fn
|
|
||||||
end
|
|
||||||
|
|
||||||
local function setup_event_listener()
|
|
||||||
local group =
|
|
||||||
vim.api.nvim_create_augroup("ow.Pack.events", { clear = true })
|
|
||||||
vim.api.nvim_create_autocmd("PackChanged", {
|
|
||||||
group = group,
|
|
||||||
---@param ev ow.Pack.Event
|
|
||||||
callback = function(ev)
|
|
||||||
local name = ev.data.spec.name
|
|
||||||
if not name then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if ev.data.kind ~= "install" and ev.data.kind ~= "update" then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local hook = hooks[name]
|
|
||||||
if hook then
|
|
||||||
hook(ev.data)
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
---@return string[]
|
---@return string[]
|
||||||
function M.get_names()
|
function M.get_names()
|
||||||
return vim.tbl_map(function(p)
|
return vim.tbl_values(vim.tbl_map(function(p)
|
||||||
return p.name
|
return p.name
|
||||||
end, M.plugins)
|
end, M.plugins))
|
||||||
end
|
end
|
||||||
|
|
||||||
---@return string[]
|
---@return string[]
|
||||||
function M.get_paths()
|
function M.get_paths()
|
||||||
return vim.tbl_map(function(p)
|
return vim.tbl_values(vim.tbl_map(function(p)
|
||||||
return p.path
|
return p.path
|
||||||
end, M.plugins)
|
end, M.plugins))
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param plugin_path string
|
||||||
|
function M.unload(plugin_path)
|
||||||
|
local lua_dir = vim.fs.joinpath(plugin_path, "lua")
|
||||||
|
local search = lua_dir .. "/?.lua;" .. lua_dir .. "/?/init.lua"
|
||||||
|
for name in pairs(package.loaded) do
|
||||||
|
if package.searchpath(name, search) then
|
||||||
|
package.loaded[name] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param name string
|
---@param name string
|
||||||
function M.reload_plugin(name)
|
---@param required boolean
|
||||||
load(name, true)
|
function M.reload_plugin(name, required)
|
||||||
|
for _, plugin in pairs(M.plugins) do
|
||||||
|
if plugin.name == name then
|
||||||
|
M.unload(plugin.path)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
load(name, required)
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.watch()
|
function M.watch()
|
||||||
@@ -195,7 +180,7 @@ function M.watch()
|
|||||||
|
|
||||||
local w, err = vim.uv.new_fs_event()
|
local w, err = vim.uv.new_fs_event()
|
||||||
if not w then
|
if not w then
|
||||||
util.error("pack: failed to create fs_event: %s", err)
|
log.error("pack: failed to create fs_event: %s", err)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local on_change, handle = util.keyed_debounce(
|
local on_change, handle = util.keyed_debounce(
|
||||||
@@ -232,7 +217,7 @@ function M.watch()
|
|||||||
end
|
end
|
||||||
)
|
)
|
||||||
if not ok then
|
if not ok then
|
||||||
util.error("pack: failed to watch %s: %s", plugins_dir, err)
|
log.error("pack: failed to watch %s: %s", plugins_dir, err)
|
||||||
w:close()
|
w:close()
|
||||||
handle:close()
|
handle:close()
|
||||||
return
|
return
|
||||||
@@ -256,10 +241,10 @@ function M.unwatch()
|
|||||||
end
|
end
|
||||||
|
|
||||||
---@param specs vim.pack.Spec[]
|
---@param specs vim.pack.Spec[]
|
||||||
---@param on_load fun(data: { spec: vim.pack.Spec, path: string })
|
---@param on_load boolean|fun(plug_data: {spec: vim.pack.Spec, path: string})
|
||||||
---@return table<string, true> changed names installed or updated during this call
|
---@return table<string, ow.Pack.Event.Data>
|
||||||
function M.install(specs, on_load)
|
function M.install(specs, on_load)
|
||||||
---@type table<string, true>
|
---@type table<string, ow.Pack.Event.Data>
|
||||||
local changed = {}
|
local changed = {}
|
||||||
local group =
|
local group =
|
||||||
vim.api.nvim_create_augroup("ow.Pack.install", { clear = true })
|
vim.api.nvim_create_augroup("ow.Pack.install", { clear = true })
|
||||||
@@ -267,12 +252,9 @@ function M.install(specs, on_load)
|
|||||||
group = group,
|
group = group,
|
||||||
---@param ev ow.Pack.Event
|
---@param ev ow.Pack.Event
|
||||||
callback = function(ev)
|
callback = function(ev)
|
||||||
local name = ev.data.spec.name
|
local src = ev.data.spec.src
|
||||||
if
|
if ev.data.kind == "install" or ev.data.kind == "update" then
|
||||||
name
|
changed[src] = ev.data
|
||||||
and (ev.data.kind == "install" or ev.data.kind == "update")
|
|
||||||
then
|
|
||||||
changed[name] = true
|
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
@@ -281,11 +263,11 @@ function M.install(specs, on_load)
|
|||||||
return changed
|
return changed
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param specs (string | ow.Pack.PluginSpec)[]
|
---@param specs (string | ow.Pack.Spec)[]
|
||||||
function M.setup(specs)
|
function M.setup(specs)
|
||||||
local pack_specs = {}
|
local pack_specs = {}
|
||||||
for _, spec in ipairs(specs) do
|
for _, spec in ipairs(specs) do
|
||||||
local src = type(spec) == "string" and spec or spec[1]
|
local src = type(spec) == "string" and spec or spec.src
|
||||||
if is_url(src) then
|
if is_url(src) then
|
||||||
table.insert(pack_specs, to_pack_spec(spec))
|
table.insert(pack_specs, to_pack_spec(spec))
|
||||||
else
|
else
|
||||||
@@ -294,11 +276,11 @@ function M.setup(specs)
|
|||||||
vim.api.nvim_get_runtime_file("pack/*/opt/" .. src, false)
|
vim.api.nvim_get_runtime_file("pack/*/opt/" .. src, false)
|
||||||
---@type ow.Pack.Plugin
|
---@type ow.Pack.Plugin
|
||||||
local plugin = {
|
local plugin = {
|
||||||
[1] = src,
|
src = src,
|
||||||
name = src,
|
name = src,
|
||||||
path = runtime[1] or "",
|
path = runtime[1] or "",
|
||||||
}
|
}
|
||||||
table.insert(M.plugins, plugin)
|
M.plugins[plugin.src] = plugin
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -310,30 +292,47 @@ function M.setup(specs)
|
|||||||
local d = data.spec.data or {}
|
local d = data.spec.data or {}
|
||||||
---@type ow.Pack.Plugin
|
---@type ow.Pack.Plugin
|
||||||
local plugin = {
|
local plugin = {
|
||||||
[1] = data.spec.src,
|
src = data.spec.src,
|
||||||
name = data.spec.name,
|
name = data.spec.name,
|
||||||
version = data.spec.version,
|
version = data.spec.version,
|
||||||
build = d.build,
|
build = d.build,
|
||||||
path = data.path,
|
path = data.path,
|
||||||
}
|
}
|
||||||
table.insert(M.plugins, plugin)
|
M.plugins[plugin.src] = plugin
|
||||||
vim.cmd.packadd(plugin.name)
|
vim.cmd.packadd(plugin.name)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
for _, plugin in ipairs(M.plugins) do
|
for _, plugin in pairs(M.plugins) do
|
||||||
if plugin.build then
|
if plugin.build then
|
||||||
if changed[plugin.name] then
|
local data = changed[plugin.src]
|
||||||
|
if data then
|
||||||
|
plugin.path = data.path
|
||||||
run_build(plugin)
|
run_build(plugin)
|
||||||
end
|
end
|
||||||
M.register_hook(plugin.name, function(ev)
|
|
||||||
plugin.path = ev.path
|
|
||||||
run_build(plugin)
|
|
||||||
end)
|
|
||||||
end
|
end
|
||||||
load(plugin.name, false)
|
load(plugin.name, false)
|
||||||
end
|
end
|
||||||
|
|
||||||
setup_event_listener()
|
vim.api.nvim_create_autocmd("PackChanged", {
|
||||||
|
group = vim.api.nvim_create_augroup(
|
||||||
|
"ow.Pack.updates",
|
||||||
|
{ clear = true }
|
||||||
|
),
|
||||||
|
callback = function(ev)
|
||||||
|
if ev.data.kind ~= "update" then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local plugin = M.plugins[ev.data.spec.src]
|
||||||
|
if not plugin then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
plugin.path = ev.data.path
|
||||||
|
if plugin.build then
|
||||||
|
run_build(plugin)
|
||||||
|
end
|
||||||
|
M.reload_plugin(plugin.name, false)
|
||||||
|
end,
|
||||||
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param names? string[]
|
---@param names? string[]
|
||||||
|
|||||||
+94
-76
@@ -7,31 +7,30 @@ local M = {}
|
|||||||
---@field location? string
|
---@field location? string
|
||||||
---@field generate? boolean
|
---@field generate? boolean
|
||||||
---@field from_json? boolean
|
---@field from_json? boolean
|
||||||
|
---@field filetypes? string[]
|
||||||
|
|
||||||
---@class ow.TS.RepoBase
|
---@class ow.TS.RepoBase
|
||||||
---@field [1] string
|
---@field src string
|
||||||
---@field version? string | vim.VersionRange
|
---@field version? string | vim.VersionRange
|
||||||
|
|
||||||
---@class ow.TS.Repo : ow.TS.RepoBase
|
---@class ow.TS.Repo : ow.TS.RepoBase
|
||||||
---@field name string
|
---@field name string
|
||||||
---@field parsers ow.TS.Parser[]
|
---@field parsers ow.TS.Parser[]
|
||||||
|
|
||||||
---@class RepoState
|
|
||||||
---@field repo ow.TS.Repo
|
|
||||||
---@field path? string
|
---@field path? string
|
||||||
|
|
||||||
---@class ow.TS.SingleRepoOpts : ow.TS.RepoBase
|
---@class ow.TS.SingleSpec : ow.TS.RepoBase
|
||||||
---@field lang? string
|
---@field lang? string
|
||||||
---@field location? string
|
---@field location? string
|
||||||
---@field generate? boolean
|
---@field generate? boolean
|
||||||
---@field from_json? boolean
|
---@field from_json? boolean
|
||||||
|
---@field filetypes? string[]
|
||||||
|
|
||||||
---@class ow.TS.MultiRepoOpts : ow.TS.RepoBase
|
---@class ow.TS.MultiSpec : ow.TS.RepoBase
|
||||||
---@field parsers ow.TS.Parser[]
|
---@field parsers ow.TS.Parser[]
|
||||||
---@field generate? boolean
|
---@field generate? boolean
|
||||||
---@field from_json? boolean
|
---@field from_json? boolean
|
||||||
|
|
||||||
---@alias ow.TS.RepoOpts ow.TS.SingleRepoOpts | ow.TS.MultiRepoOpts
|
---@alias ow.TS.Spec ow.TS.SingleSpec | ow.TS.MultiSpec
|
||||||
|
|
||||||
---@param path string
|
---@param path string
|
||||||
---@param lang string
|
---@param lang string
|
||||||
@@ -53,6 +52,28 @@ local function start_treesitter(buf)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@param parser ow.TS.Parser
|
||||||
|
---@param so string
|
||||||
|
local function register(parser, so)
|
||||||
|
vim.treesitter.language.add(parser.lang, { path = so })
|
||||||
|
local filetypes = { parser.lang }
|
||||||
|
if parser.filetypes then
|
||||||
|
vim.treesitter.language.register(parser.lang, parser.filetypes)
|
||||||
|
vim.list_extend(filetypes, parser.filetypes)
|
||||||
|
end
|
||||||
|
|
||||||
|
vim.api.nvim_create_autocmd("FileType", {
|
||||||
|
group = vim.api.nvim_create_augroup(
|
||||||
|
"ow.ts.parser." .. parser.lang,
|
||||||
|
{ clear = true }
|
||||||
|
),
|
||||||
|
pattern = filetypes,
|
||||||
|
callback = function(ev)
|
||||||
|
start_treesitter(ev.buf)
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
---@param lang string
|
---@param lang string
|
||||||
local function activate_open_buffers(lang)
|
local function activate_open_buffers(lang)
|
||||||
local fts = vim.treesitter.language.get_filetypes(lang)
|
local fts = vim.treesitter.language.get_filetypes(lang)
|
||||||
@@ -66,10 +87,10 @@ local function activate_open_buffers(lang)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param state RepoState
|
---@param repo ow.TS.Repo
|
||||||
---@param parser ow.TS.Parser
|
---@param parser ow.TS.Parser
|
||||||
local function build(state, parser)
|
local function build(repo, parser)
|
||||||
local path = assert(state.path, "repo not installed: " .. state.repo.name)
|
local path = assert(repo.path, "repo not installed: " .. repo.name)
|
||||||
local cwd = parser.location and vim.fs.joinpath(path, parser.location)
|
local cwd = parser.location and vim.fs.joinpath(path, parser.location)
|
||||||
or path
|
or path
|
||||||
local out = parser_so(path, parser.lang)
|
local out = parser_so(path, parser.lang)
|
||||||
@@ -88,7 +109,7 @@ local function build(state, parser)
|
|||||||
)
|
)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
vim.treesitter.language.add(parser.lang, { path = out })
|
register(parser, out)
|
||||||
activate_open_buffers(parser.lang)
|
activate_open_buffers(parser.lang)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -137,13 +158,13 @@ local function build(state, parser)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param pack_name string
|
---@param name string
|
||||||
---@return string? lang
|
---@return string? lang
|
||||||
---@return string? err
|
---@return string? err
|
||||||
local function lang_from_name(pack_name)
|
local function lang_from_name(name)
|
||||||
local lang = pack_name:match("^tree%-sitter%-(.+)$")
|
local lang = name:match("^tree%-sitter%-(.+)$")
|
||||||
if not lang then
|
if not lang then
|
||||||
return nil, "cannot derive lang from pack name: " .. pack_name
|
return nil, "cannot derive lang from pack name: " .. name
|
||||||
end
|
end
|
||||||
return lang
|
return lang
|
||||||
end
|
end
|
||||||
@@ -166,34 +187,30 @@ local function pick(child, parent)
|
|||||||
return parent
|
return parent
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param entry string | ow.TS.RepoOpts
|
---@param spec string | ow.TS.Spec
|
||||||
---@return ow.TS.Repo?
|
---@return ow.TS.Repo?
|
||||||
local function normalize(entry)
|
local function spec_to_repo(spec)
|
||||||
---@type ow.TS.RepoOpts
|
if type(spec) == "string" then
|
||||||
local opts
|
spec = { src = spec } --[[@as ow.TS.SingleSpec]]
|
||||||
if type(entry) == "string" then
|
|
||||||
opts = { entry } --[[@as ow.TS.SingleRepoOpts]]
|
|
||||||
else
|
|
||||||
opts = entry
|
|
||||||
end
|
end
|
||||||
local name = name_from_url(opts[1])
|
local name = name_from_url(spec.src)
|
||||||
|
|
||||||
---@type ow.TS.Parser[]
|
---@type ow.TS.Parser[]
|
||||||
local parsers = {}
|
local parsers = {}
|
||||||
local input_parsers = (opts --[[@as ow.TS.MultiRepoOpts]]).parsers
|
if spec.parsers then
|
||||||
if input_parsers then
|
---@cast spec ow.TS.MultiSpec
|
||||||
---@cast opts ow.TS.MultiRepoOpts
|
for _, s in ipairs(spec.parsers) do
|
||||||
for _, s in ipairs(opts.parsers) do
|
|
||||||
table.insert(parsers, {
|
table.insert(parsers, {
|
||||||
lang = s.lang,
|
lang = s.lang,
|
||||||
location = s.location,
|
location = s.location,
|
||||||
generate = pick(s.generate, opts.generate),
|
generate = pick(s.generate, spec.generate),
|
||||||
from_json = pick(s.from_json, opts.from_json),
|
from_json = pick(s.from_json, spec.from_json),
|
||||||
|
filetypes = s.filetypes,
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
---@cast opts ow.TS.SingleRepoOpts
|
---@cast spec ow.TS.SingleSpec
|
||||||
local lang = opts.lang
|
local lang = spec.lang
|
||||||
if not lang then
|
if not lang then
|
||||||
local derived, err = lang_from_name(name)
|
local derived, err = lang_from_name(name)
|
||||||
if not derived then
|
if not derived then
|
||||||
@@ -204,79 +221,80 @@ local function normalize(entry)
|
|||||||
end
|
end
|
||||||
table.insert(parsers, {
|
table.insert(parsers, {
|
||||||
lang = lang,
|
lang = lang,
|
||||||
location = opts.location,
|
location = spec.location,
|
||||||
generate = opts.generate,
|
generate = spec.generate,
|
||||||
from_json = opts.from_json,
|
from_json = spec.from_json,
|
||||||
|
filetypes = spec.filetypes,
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
return {
|
return {
|
||||||
[1] = opts[1],
|
src = spec.src,
|
||||||
name = name,
|
name = name,
|
||||||
version = opts.version,
|
version = spec.version,
|
||||||
parsers = parsers,
|
parsers = parsers,
|
||||||
|
path = nil,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param opts (string | ow.TS.RepoOpts)[]
|
---@param specs (string | ow.TS.Spec)[]
|
||||||
function M.setup(opts)
|
function M.setup(specs)
|
||||||
---@type ow.TS.Repo[]
|
---@type table<string, ow.TS.Repo>
|
||||||
local repos = {}
|
local repos = {}
|
||||||
for _, entry in ipairs(opts) do
|
local pack = require("pack")
|
||||||
local repo = normalize(entry)
|
for _, spec in ipairs(specs) do
|
||||||
|
local repo = spec_to_repo(spec)
|
||||||
if repo then
|
if repo then
|
||||||
table.insert(repos, repo)
|
repos[repo.src] = repo
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
---@type vim.pack.Spec[]
|
---@type vim.pack.Spec[]
|
||||||
local pack_specs = vim.tbl_map(function(p)
|
local vim_specs = {}
|
||||||
return { src = p[1], name = p.name, version = p.version }
|
for _, repo in pairs(repos) do
|
||||||
end, repos)
|
table.insert(
|
||||||
|
vim_specs,
|
||||||
---@type RepoState[]
|
{ src = repo.src, name = repo.name, version = repo.version }
|
||||||
local states = {}
|
)
|
||||||
---@type table<string, RepoState>
|
|
||||||
local by_src = {}
|
|
||||||
for _, repo in ipairs(repos) do
|
|
||||||
local state = { repo = repo }
|
|
||||||
table.insert(states, state)
|
|
||||||
by_src[repo[1]] = state
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local pack = require("pack")
|
local changed = pack.install(vim_specs, function(data)
|
||||||
local changed = pack.install(pack_specs, function(data)
|
local repo = repos[data.spec.src]
|
||||||
local state = by_src[data.spec.src]
|
if repo then
|
||||||
if state then
|
repo.path = data.path
|
||||||
state.path = data.path
|
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
for _, state in ipairs(states) do
|
for _, repo in pairs(repos) do
|
||||||
pack.register_hook(state.repo.name, function(ev)
|
if not repo.path then
|
||||||
state.path = ev.path
|
log.error("Repo not installed: %s", repo.name)
|
||||||
for _, parser in ipairs(state.repo.parsers) do
|
|
||||||
build(state, parser)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
if not state.path then
|
|
||||||
log.error("Repo not installed: %s", state.repo.name)
|
|
||||||
goto continue
|
goto continue
|
||||||
end
|
end
|
||||||
for _, parser in ipairs(state.repo.parsers) do
|
for _, parser in ipairs(repo.parsers) do
|
||||||
local so = parser_so(state.path, parser.lang)
|
local so = parser_so(repo.path, parser.lang)
|
||||||
if changed[state.repo.name] or not vim.uv.fs_stat(so) then
|
if changed[repo.src] or not vim.uv.fs_stat(so) then
|
||||||
build(state, parser)
|
build(repo, parser)
|
||||||
else
|
else
|
||||||
vim.treesitter.language.add(parser.lang, { path = so })
|
register(parser, so)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
::continue::
|
::continue::
|
||||||
end
|
end
|
||||||
|
|
||||||
vim.api.nvim_create_autocmd("FileType", {
|
vim.api.nvim_create_autocmd("PackChanged", {
|
||||||
|
group = vim.api.nvim_create_augroup("ow.ts.updates", { clear = true }),
|
||||||
callback = function(ev)
|
callback = function(ev)
|
||||||
start_treesitter(ev.buf)
|
if ev.data.kind ~= "update" then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local repo = repos[ev.data.spec.src]
|
||||||
|
if not repo then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
repo.path = ev.data.path
|
||||||
|
for _, parser in ipairs(repo.parsers) do
|
||||||
|
build(repo, parser)
|
||||||
|
end
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user