more fixes

This commit is contained in:
2025-04-23 00:15:13 -05:00
parent 254436c24d
commit c29395004d
6 changed files with 282 additions and 183 deletions

View File

@ -2,15 +2,10 @@ local logger = require('dep.log')
local git = require('dep.git') local git = require('dep.git')
local packager = require('dep.package') local packager = require('dep.package')
---all functions for convenience -- all functions for convenience
---@type table
local M = {} local M = {}
---@type boolean -- performance logging
local initialized
---performance logging
---@type table
local perf = {} local perf = {}
--- get execution time of a function --- get execution time of a function
@ -30,13 +25,13 @@ function M.registertree(speclist, overrides)
overrides = overrides or {} overrides = overrides or {}
-- recurse the packages -- recurse the packages
local over = overrides
for _, spec in pairs(speclist) do for _, spec in pairs(speclist) do
-- make sure the overrides override and take into account the packages spec -- make sure the overrides override and take into account the packages spec
---@diagnostic disable-next-line: missing-fields ---@diagnostic disable-next-line: missing-fields
overrides = { over = {
pin = overrides.pin or spec.pin, pin = over.pin or spec.pin,
disable = overrides.disable or spec.disable disable = over.disable or spec.disable
} }
local ok = packager:new(spec, overrides) local ok = packager:new(spec, overrides)
@ -48,8 +43,48 @@ function M.registertree(speclist, overrides)
end end
end end
--- clean out old packages
function M.clean()
vim.loop.fs_scandir(
packager.get_base_dir(),
vim.schedule_wrap(function(err, handle)
if err then
logger:log("error", string.format("failed to clean; reason: %s", err))
else
local queue = {}
while handle do
local name = vim.loop.fs_scandir_next(handle)
if name then
queue[name] = packager.get_base_dir()..name
else
break
end
end
-- keep packages that still exist
for _, package in pairs(packager.get_packages()) do
queue[package.name] = nil
end
for name, dir in pairs(queue) do
local co = coroutine.create(function()
local ok = vim.fn.delete(dir, "rf")
if ok then
logger:log("clean", string.format("deleted %s", name))
else
logger:log("error", string.format("failed to delete %s", name))
end
end)
coroutine.resume(co)
end
end
end)
)
end
--- reload all packages in package table spec --- reload all packages in package table spec
---@param force boolean|nil force all packages to load ---@param force boolean? force all packages to load
function M.reload(force) function M.reload(force)
local reloaded = packager.get_root():loadtree(force) local reloaded = packager.get_root():loadtree(force)
@ -72,63 +107,6 @@ function M.reload(force)
end end
end end
--- check if there's a circular dependency in the package tree
function M.findcycle()
local index = 0
local indexes = {}
local lowlink = {}
local stack = {}
-- use tarjan algorithm to find circular dependencies (strongly connected
-- components)
local function connect(package)
indexes[package.id], lowlink[package.id] = index, index
stack[#stack + 1], stack[package.id] = package, true
index = index + 1
for i = 1, #package.dependents do
local dependent = package.dependents[i]
if not indexes[dependent.id] then
local cycle = connect(dependent)
if cycle then
return cycle
else
lowlink[package.id] = math.min(lowlink[package.id], lowlink[dependent.id])
end
elseif stack[dependent.id] then
lowlink[package.id] = math.min(lowlink[package.id], indexes[dependent.id])
end
end
if lowlink[package.id] == indexes[package.id] then
local cycle = { package }
local node
repeat
node = stack[#stack]
stack[#stack], stack[node.id] = nil, nil
cycle[#cycle + 1] = node
until node == package
-- a node is by definition strongly connected to itself ignore single-node
-- components unless it explicitly specified itself as a dependency
if #cycle > 2 or package.dependents[package.id] then
return cycle
end
end
end
for _, package in pairs(packager.get_packages()) do
if not indexes[package.id] then
local cycle = connect(package)
if cycle then
return cycle
end
end
end
end
--- sync a tree of plugins --- sync a tree of plugins
---@param tree package[] tree of plugins ---@param tree package[] tree of plugins
---@param cb function? callback ---@param cb function? callback
@ -141,16 +119,15 @@ function M.synctree(tree, cb)
has_errors = has_errors or err has_errors = has_errors or err
if progress == #tree then if progress == #tree then
-- TODO: implement clean
-- clean()
M.reload()
if has_errors then if has_errors then
logger:log("error", "there were errors during sync; see :messages or :DepLog for more information") logger:log("error", "there were errors during sync; see :messages or :DepLog for more information")
else else
logger:log("update", "synchronized %s %s", #tree, #tree == 1 and "package" or "packages") logger:log("update", "synchronized %s %s", #tree, #tree == 1 and "package" or "packages")
end end
M.clean()
M.reload()
if cb then if cb then
cb() cb()
end end
@ -158,7 +135,10 @@ function M.synctree(tree, cb)
end end
for _, package in pairs(tree) do for _, package in pairs(tree) do
local co = coroutine.create(function()
git.sync(package, done) git.sync(package, done)
end)
coroutine.resume(co)
end end
end end
@ -167,8 +147,8 @@ return function(opts)
logger.pipe = logger:setup() logger.pipe = logger:setup()
--- make comparison for table.sort --- make comparison for table.sort
---@param a table package spec a ---@param a package package spec a
---@param b table package spec b ---@param b package package spec b
---@return boolean ---@return boolean
local function comp(a, b) local function comp(a, b)
-- NOTE: this doesn't have to be in any real order, it just has to be -- NOTE: this doesn't have to be in any real order, it just has to be
@ -177,7 +157,7 @@ return function(opts)
return a.id < b.id return a.id < b.id
end end
initialized, err = pcall(function() local initialized, err = pcall(function()
packager.set_base_dir(opts.base_dir or vim.fn.stdpath("data").."/site/pack/deps/opt/") packager.set_base_dir(opts.base_dir or vim.fn.stdpath("data").."/site/pack/deps/opt/")
M.benchmark("load", function() M.benchmark("load", function()
-- register all packages -- register all packages
@ -199,7 +179,10 @@ return function(opts)
end end
-- make sure there arent any circular dependencies -- make sure there arent any circular dependencies
M.findcycle() local ok = packager.findcycle(packager.get_packages())
if type(ok) == "table" then
logger:log("error", "found a cycle in the package spec here: %s", vim.inspect(ok))
end
end) end)
-- load packages -- load packages
@ -218,12 +201,13 @@ return function(opts)
-- get all package that need syncing -- get all package that need syncing
local targets = {} local targets = {}
for i, package in pairs(packager.get_packages()) do for _, package in pairs(packager.get_packages()) do
if shouldsync(package) then if shouldsync(package) then
targets[i] = package table.insert(targets, package)
end end
end end
-- install all targets
M.synctree(targets) M.synctree(targets)
end) end)
@ -231,17 +215,18 @@ return function(opts)
logger:log("error", err) logger:log("error", err)
end end
-- add some user commands
vim.api.nvim_create_user_command("DepLog", function() vim.api.nvim_create_user_command("DepLog", function()
vim.cmd('vsp '..logger.path) vim.cmd('vsp '..logger.path)
vim.opt_local.readonly = true vim.opt_local.readonly = true
-- make the log auto update while it's open
local w = vim.uv.new_fs_event() local w = vim.uv.new_fs_event()
local function watch_file(fname) local function watch_file(fname)
local fullpath = vim.api.nvim_call_function( local fullpath = vim.api.nvim_call_function(
'fnamemodify', { fname, ':p' }) 'fnamemodify', { fname, ':p' })
w:start(fullpath, {}, vim.schedule_wrap(function(...) w:start(fullpath, {}, vim.schedule_wrap(function(...)
vim.api.nvim_command('checktime') vim.api.nvim_command('checktime')
-- Debounce: stop/start.
w:stop() w:stop()
watch_file(fname) watch_file(fname)
end)) end))
@ -258,5 +243,11 @@ return function(opts)
M.reload() M.reload()
end, {}) end, {})
vim.api.nvim_create_user_command("DepClean", function()
-- clean AND reload to make sure that all old packages are gone
M.clean()
M.reload()
end, {})
logger:cleanup() logger:cleanup()
end end

View File

@ -1,3 +1,7 @@
-- TODO: clean this up, it's a mess
-- the nesting of all the proc calls is really annoying, and I need to find a
-- cleaner way to do it
local logger = require('dep.log') local logger = require('dep.log')
local proc = require('dep.proc') local proc = require('dep.proc')
@ -7,6 +11,8 @@ local git = {}
---@param package package package to update/install ---@param package package package to update/install
---@param cb function callback ---@param cb function callback
function git.sync(package, cb) function git.sync(package, cb)
local function sync()
-- update or install
if package.exists then if package.exists then
git.update(package, cb) git.update(package, cb)
else else
@ -14,24 +20,38 @@ function git.sync(package, cb)
end end
end end
--- install a given package -- handle arbitrary branches here
---@param package package package to install if package.branch then
---@param cb function callback proc.git_resolve_branch(package.url, package.branch, function(err, message)
function git.install(package, cb) if not err then
local function configurepkg() package.branch = message
sync()
end
end)
else
sync()
end
end
--- configure a package
---@param package table package spec
local function configurepkg(package)
package:runhooks("on_config") package:runhooks("on_config")
logger:log("config", "package: %s configured", package.id) logger:log("config", "package: %s configured", package.id)
package.configured = true package.configured = true
end end
--- install a given package
---@param package package package to install
---@param cb function callback
function git.install(package, cb)
if not package.enabled then if not package.enabled then
cb() cb()
return return
end end
logger:log("error", "%s: doesn't exist", package.id)
proc.git_clone(package.dir, package.url, package.branch, function(err, message) proc.git_clone(package.dir, package.url, package.branch, function(err, message)
if err then if err then
logger:log("error", "failed to install %s; reason: %s", logger:log("error", "failed to install %s; reason: %s",
@ -44,15 +64,15 @@ function git.install(package, cb)
else else
package.exists = true package.exists = true
package:unconfiguretree() package:unconfiguretree()
configurepkg()
logger:log("install", "installed %s", package.id) logger:log("install", "installed %s", package.id)
configurepkg(package)
end end
end) end)
else else
package.exists = true package.exists = true
package:unconfiguretree() package:unconfiguretree()
configurepkg()
logger:log("install", "installed %s", package.id) logger:log("install", "installed %s", package.id)
configurepkg(package)
end end
end end
@ -74,15 +94,6 @@ function git.update(package, cb)
logger:log("error", "failed to update %s; reason: %s", package.id, err) logger:log("error", "failed to update %s; reason: %s", package.id, err)
end end
--- configure a package
---@param pkg table package spec
local function configurepkg(pkg)
package:runhooks("on_config")
logger:log("config", "package: %s configured", pkg.id)
package.configured = true
end
if package.pin then if package.pin then
cb() cb()
return return
@ -112,8 +123,8 @@ function git.update(package, cb)
cb(err) cb(err)
else else
package:unconfiguretree() package:unconfiguretree()
configurepkg(package)
logger:log("update", "updated %s; %s -> %s", package.id, before, after) logger:log("update", "updated %s; %s -> %s", package.id, before, after)
configurepkg(package)
end end
end) end)
end end
@ -124,7 +135,7 @@ function git.update(package, cb)
log_err(message) log_err(message)
cb(err) cb(err)
else else
proc.git_rev_parse(package.dir, "FETCH_HEAD", function(err, after) proc.git_rev_parse(package.dir, "FETCH_HEAD^{commit}", function(err, after)
if err then if err then
log_err(after) log_err(after)
cb(err) cb(err)
@ -137,8 +148,8 @@ function git.update(package, cb)
log_err(message) log_err(message)
else else
package:unconfiguretree() package:unconfiguretree()
configurepkg(package)
logger:log("update", "updated %s; %s -> %s", package.id, before, after) logger:log("update", "updated %s; %s -> %s", package.id, before, after)
configurepkg(package)
end end
cb(err) cb(err)

View File

@ -76,7 +76,7 @@ function logger:log(level, message, ...)
-- write to the pipe if it's open -- write to the pipe if it's open
if logger.pipe then if logger.pipe then
logger.pipe:write(string.format("[%s] %s:%s: %s\n", os.date("%Y/%m/%d"), source.short_src:gsub('.*%/', ''), source.currentline, message)) logger.pipe:write(string.format("[%s] %s:%s: %s\n", os.date("%T"), source.short_src:gsub('.*%/', ''), source.currentline, message))
end end
end) end)
end end

View File

@ -23,13 +23,13 @@ local logger = require('dep.log')
---@field lazy boolean if the package is lazy loaded in any way ---@field lazy boolean if the package is lazy loaded in any way
---@field added boolean if the package has been added in vim ---@field added boolean if the package has been added in vim
---@field configured boolean if the package has been configured ---@field configured boolean if the package has been configured
---@field lazied boolean if the packages lazy loading has been set
---@field loaded boolean if a package has been loaded ---@field loaded boolean if a package has been loaded
---@field subtree_loaded boolean is the subtree has been loaded ---@field subtree_loaded boolean is the subtree has been loaded
---@field on_config function[] table of functions to run on config ---@field on_config function[] table of functions to run on config
---@field on_setup function[] table of function to run on setup ---@field on_setup function[] table of function to run on setup
---@field on_load function[] table of functions to run on load ---@field on_load function[] table of functions to run on load
---@field lazy_load function[] table of functions to run which will tell the ---@field lazy_load function[] table of functions to run which will tell the package when to load
--- package when to load
---@field requirements package[] this package's requirements ---@field requirements package[] this package's requirements
---@field dependents package[] packages that require this package ---@field dependents package[] packages that require this package
---@field perf table performance metrics for the package ---@field perf table performance metrics for the package
@ -153,6 +153,7 @@ local function check_spec(spec)
return false return false
end end
-- turn an id into a spec
if (is == "string") then if (is == "string") then
spec.reqs = { spec.reqs } spec.reqs = { spec.reqs }
end end
@ -165,6 +166,7 @@ local function check_spec(spec)
return false return false
end end
-- turn an id into a spec
if (is == "string") then if (is == "string") then
spec.deps = { spec.deps } spec.deps = { spec.deps }
end end
@ -212,31 +214,33 @@ function package:new(spec, overrides)
local id = spec[1] local id = spec[1]
local o = packages[id] or {} local o = packages[id] or {}
self.__index = self
setmetatable(o, self) setmetatable(o, self)
-- if package hasn't been registered already, get the inital spec regisitered -- if package hasn't been registered already, get the inital spec regisitered
if not o.id then if not o.id then
o.id = id -- id of the package o.id = id
o.enabled = true -- whether it's going to be used o.enabled = true
o.exists = false -- if the package exists on the filesystem o.exists = false
o.lazy = false -- if the package is lazy loaded in any way o.lazy = false
o.added = false -- if the package has been added in vim o.added = false
o.configured = false -- if the package has been configured o.lazied = false
o.loaded = false -- if a package has been loaded o.configured = false
o.loaded = false
o.subtree_loaded = false o.subtree_loaded = false
o.on_config = {} -- table of functions to run on config o.on_config = {}
o.on_setup = {} -- table of function to run on setup o.on_setup = {}
o.on_load = {} -- table of functions to run on load o.on_load = {}
o.lazy_load = {} -- table of functions to run which will tell the package o.lazy_load = {}
-- when to load
o.requirements = {} -- this package's requirements o.requirements = {}
o.dependents = {} -- packages that require this package o.dependents = {}
o.perf = {} o.perf = {}
packages[id] = o packages[id] = o
end end
o.name = spec.as or o.name or id o.name = spec.as or o.name or id:match("^[%w-_.]+/([%w-_.]+)$")
o.url = spec.url or o.url or ("https://github.com/"..id..".git") o.url = spec.url or o.url or ("https://github.com/"..id..".git")
o.branch = spec.branch or o.branch o.branch = spec.branch or o.branch
o.dir = base_dir..o.name o.dir = base_dir..o.name
@ -287,26 +291,32 @@ function package:new(spec, overrides)
if spec.deps then if spec.deps then
---it is the correct type as asserted in check_spec() ---it is the correct type as asserted in check_spec()
---@diagnostic disable-next-line: param-type-mismatch ---@diagnostic disable-next-line: param-type-mismatch
for _, v in pairs(spec.deps) do for _, dep in pairs(spec.deps) do
local pkg = package:new(v) local pkg = package:new(dep)
if type(pkg) ~= "table" then if not pkg then
return false return false
end end
o:link_dependency(nil, pkg) o:link_dependency(o, pkg)
-- if the child package is lazy loaded make sure the child package -- if the child package is lazy loaded make sure the child package
-- is only loaded when the parent package has finished loading -- is only loaded when the parent package has finished loading
if package.lazy then if o.lazy then
table.insert(package.on_load, function() table.insert(o.on_load, function()
o:loadtree(true) local ok = o:loadtree(true)
if not ok then
logger:log("lazy",
"failed to run loadtree for %s, some packages may not be loaded",
o.id)
end
end) end)
-- tell the dep that it's gonna be lazy
pkg.lazy = true
table.insert(pkg.lazy_load, function(_) end) table.insert(pkg.lazy_load, function(_) end)
end end
end end
end end
self.__index = self
return o return o
end end
@ -316,14 +326,23 @@ function package.set_base_dir(_base_dir)
base_dir = _base_dir base_dir = _base_dir
end end
--- get the base directory for packages
---@return string base_dir
---@nodiscard
function package.get_base_dir()
return base_dir
end
--- get the root directory --- get the root directory
---@return package root ---@return package root
---@nodiscard
function package.get_root() function package.get_root()
return root return root
end end
--- get the packages in dep --- get the packages in dep
---@return package root ---@return package root
---@nodiscard
function package.get_packages() function package.get_packages()
return packages return packages
end end
@ -376,12 +395,12 @@ function package:ensureadded(force)
end end
end end
-- run setup hooks
pkg:runhooks("on_setup")
-- now start loading our plugin -- now start loading our plugin
local start = os.clock() local start = os.clock()
-- run setup hooks
self:runhooks("on_setup")
-- trigger the packadd for the plugin -- trigger the packadd for the plugin
---@diagnostic disable-next-line: param-type-mismatch ---@diagnostic disable-next-line: param-type-mismatch
local ok, err = pcall(vim.cmd, "packadd "..pkg.name) local ok, err = pcall(vim.cmd, "packadd "..pkg.name)
@ -394,23 +413,24 @@ function package:ensureadded(force)
logger:log("vim", "packadd completed for %s", pkg.id) logger:log("vim", "packadd completed for %s", pkg.id)
-- set the package to loaded -- set the package to loaded
self.loaded = true pkg.loaded = true
logger:log("load", "loaded %s", self.id) logger:log("load", "loaded %s", pkg.id)
-- trigger the on_load hooks -- trigger the on_load hooks
ok, err = self:runhooks("on_load") ok, err = pkg:runhooks("on_load")
if not ok then if not ok then
logger:log("error", "failed to load %s; reason: %s", self.id, err) logger:log("error", "failed to load %s; reason: %s", pkg.id, err)
return return
end end
end end
-- make sure the package is lazy loaded if need be -- make sure the package is lazy loaded if need be
if not self.added and not self.lazy or force then if not self.added and not self.loaded and not self.lazy or force then
loadpkg(self) loadpkg(self)
elseif not self.added and self.lazy then elseif not self.added and self.lazy then
logger:log("lazy", "registering %d lazy hooks for %s", #self.lazy_load, logger:log("lazy", "registering %d lazy hooks for %s", #self.lazy_load,
self.id) self.id)
self.lazied = true
for _, load_cond in pairs(self.lazy_load) do for _, load_cond in pairs(self.lazy_load) do
-- configure the lazy loader for the user -- configure the lazy loader for the user
local l = require('lazy.utils'):new() local l = require('lazy.utils'):new()
@ -436,26 +456,31 @@ end
--- load all packages in package tree --- load all packages in package tree
---@param force boolean? force lazy packages to load ---@param force boolean? force lazy packages to load
---@return boolean boolean if tree was successfully loaded ---@return boolean boolean if tree was successfully loaded
---@nodiscard
function package:loadtree(force) function package:loadtree(force)
-- if the package doesn't exist or isn't enabled then don't load it
if not self.exists or not self.enabled then if not self.exists or not self.enabled then
logger:log("load", "package %s doesn't exist or is not enabled", self.id)
return false return false
end end
if self.subtree_loaded then -- if the subtree is loaded then it's already loaded unless it needs forcing
logger:log("load", "package %s's subtree is already loaded", self.id) if not force and self.subtree_loaded then
return true return true
end end
-- if the package isn't lazy check that it's requirements are loaded
if not self.lazy then if not self.lazy then
for _, requirement in pairs(self.requirements) do for _, requirement in pairs(self.requirements) do
if not requirement.loaded then if not requirement.loaded and not requirement.lazy then
logger:log("load", "package %s requires %s to be loaded first", self.id, requirement.id) logger:log("error", "failed to load %s; requirement: %s isn't loaded",
self.id, requirement.id)
return false return false
end end
end end
end end
-- if the package isn't loaded and isn't lazy then it should probably be
-- loaded
if not self.loaded then if not self.loaded then
local ok, err = self:ensureadded(force) local ok, err = self:ensureadded(force)
if not ok then if not ok then
@ -464,8 +489,9 @@ function package:loadtree(force)
end end
end end
package.subtree_loaded = true self.subtree_loaded = true
-- make sure the dependants are loaded
for _, dependant in pairs(self.dependents) do for _, dependant in pairs(self.dependents) do
self.subtree_loaded = dependant:loadtree(force) and self.subtree_loaded self.subtree_loaded = dependant:loadtree(force) and self.subtree_loaded
end end
@ -490,4 +516,68 @@ function package:unconfiguretree()
end end
end end
--- check a list of packages for any cycles
---@param pkgs package[] list of packages
---@return package[]|false cycle the cycle that was found or false if not found
---@nodisacard
function package.findcycle(pkgs)
local index = 0
local indexes = {}
local lowlink = {}
local stack = {}
--- use tarjan algorithm to find circular dependencies (strongly connected
--- components)
---@param pkg package
local function connect(pkg)
indexes[pkg.id], lowlink[pkg.id] = index, index
stack[#stack + 1], stack[pkg.id] = pkg, true
index = index + 1
for i = 1, #pkg.dependents do
local dependent = pkg.dependents[i]
if not indexes[dependent.id] then
local cycle = connect(dependent)
if cycle then
return cycle
else
lowlink[pkg.id] = math.min(lowlink[pkg.id], lowlink[dependent.id])
end
elseif stack[dependent.id] then
lowlink[pkg.id] = math.min(lowlink[pkg.id], indexes[dependent.id])
end
end
if lowlink[pkg.id] == indexes[pkg.id] then
local cycle = { pkg }
local node
repeat
node = stack[#stack]
stack[#stack], stack[node.id] = nil, nil
cycle[#cycle + 1] = node
until node == pkg
-- a node is by definition strongly connected to itself ignore single-node
-- components unless it explicitly specified itself as a dependency
if #cycle > 2 or pkg.dependents[pkg.id] then
return cycle
end
end
end
-- actually check the cycle
for _, pkg in pairs(pkgs) do
if not indexes[package.id] then
local cycle = connect(pkg)
if cycle then
return cycle
end
end
end
return false
end
return package return package

View File

@ -1,12 +1,18 @@
local proc = {} local proc = {}
--- execute a process
---@param process string the program
---@param args string[] the args
---@param cwd string? the pwd
---@param env table env
---@param cb function callback
function proc.exec(process, args, cwd, env, cb) function proc.exec(process, args, cwd, env, cb)
local buffer = {} local buffer = {}
local function cb_output(_, data, _) local function cb_output(_, data, _)
table.insert(buffer, table.concat(data)) table.insert(buffer, table.concat(data))
end end
local function cb_exit(job_id, exit_code, _) local function cb_exit(_, exit_code, _)
local output = table.concat(buffer) local output = table.concat(buffer)
cb(exit_code ~= 0, output) cb(exit_code ~= 0, output)
end end
@ -62,27 +68,31 @@ function proc.git_checkout(dir, branch, commit, cb)
end end
function proc.git_resolve_branch(url, branch, cb) function proc.git_resolve_branch(url, branch, cb)
if string.match(branch or "", "*") ~= "*" then -- if the branch doesn't contain a * then return the branch
if not string.match(branch, "*") then
cb(false, branch) cb(false, branch)
return return
end end
local buffer = {}
local buffer = {}
local function cb_output(_, data, _) local function cb_output(_, data, _)
if data[1] ~= "" then if data[1] ~= "" then
buffer = data buffer = data
end end
end end
vim.fn.jobstart({ "git", "ls-remote", "--tags", "--sort", "v:refname", url, }, vim.fn.jobstart({ "git", "ls-remote", "--tags", "--sort", "v:refname", url },
{ {
cwd = nil, cwd = nil,
env = { GIT_TERMINAL_PROMPT = 0 }, env = git_env,
stdin = nil, stdin = nil,
on_stdout = cb_output, on_stdout = cb_output,
on_stderr = cb_output, on_stderr = cb_output,
on_exit = function(_, exit_code, _) on_exit = function(_, exit_code, _)
if exit_code == 0 then if exit_code ~= 0 then
return
end
-- get a list of all versions -- get a list of all versions
local versions = {} local versions = {}
for _, v in pairs(buffer) do for _, v in pairs(buffer) do
@ -92,8 +102,7 @@ function proc.git_resolve_branch(url, branch, cb)
end end
local tag = string.sub(v, s, e) local tag = string.sub(v, s, e)
tag = string.gsub(tag, "refs/tags/", "") tag = tag:gsub("refs/tags/", ""):gsub("%^{}", "")
tag = string.gsub(tag, "%^{}", "")
table.insert(versions, tag) table.insert(versions, tag)
::continue:: ::continue::
@ -113,7 +122,6 @@ function proc.git_resolve_branch(url, branch, cb)
end end
end end
end end
end
}) })
end end

View File

@ -37,7 +37,7 @@ end
---@param opts vim.api.keyset.user_command? options ---@param opts vim.api.keyset.user_command? options
function lazy:cmd(name, opts) function lazy:cmd(name, opts)
opts = opts or {} opts = opts or {}
vim.api.nvim_create_user_command(name, function(o) vim.api.nvim_create_user_command(name, opts['callback'] or function()
self:cleanup() self:cleanup()
end, opts) end, opts)
@ -49,9 +49,8 @@ end
---@param opts vim.api.keyset.create_autocmd? options ---@param opts vim.api.keyset.create_autocmd? options
function lazy:auto(event, opts) function lazy:auto(event, opts)
opts = opts or {} opts = opts or {}
opts['once'] = true opts['once'] = opts['once'] or true
opts['callback'] = opts['callback'] or function()
opts['callback'] = function()
self:cleanup() self:cleanup()
end end
@ -64,7 +63,7 @@ end
---@param opts vim.keymap.set.Opts? options ---@param opts vim.keymap.set.Opts? options
function lazy:keymap(mode, bind, opts) function lazy:keymap(mode, bind, opts)
opts = opts or {} opts = opts or {}
vim.keymap.set(mode, bind, function() vim.keymap.set(mode, bind, opts['callback'] or function()
self:cleanup() self:cleanup()
-- register keymap unload -- register keymap unload