switching from handling plugin downloading on our own to use vim.pack
This commit is contained in:
parent
70853bd01e
commit
9b19b61372
14 changed files with 26 additions and 802 deletions
2
LICENSE
2
LICENSE
|
|
@ -1,6 +1,6 @@
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2023-2025 squibid
|
Copyright (c) 2023-2026 squibid
|
||||||
Copyright (c) 2021-2023 chiya.dev
|
Copyright (c) 2021-2023 chiya.dev
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
|
|
||||||
55
lua/dep.lua
55
lua/dep.lua
|
|
@ -1,19 +1,12 @@
|
||||||
local logger = require("dep.log")
|
local logger = require("dep.log")
|
||||||
local git = require("dep.git")
|
|
||||||
local fs = require("dep.fs")
|
|
||||||
local packager = require("dep.package")
|
local packager = require("dep.package")
|
||||||
local modules = require("dep.modules")
|
local modules = require("dep.modules")
|
||||||
local bench = require("dep.bench")
|
local bench = require("dep.bench")
|
||||||
local lazy = require("dep.lazy")
|
local lazy = require("dep.lazy")
|
||||||
local ui = require("dep.ui")
|
|
||||||
|
|
||||||
-- all functions for convenience
|
-- all functions for convenience
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
-- TODO: maybe add the ability to get a lockfile? it's useful to make a config
|
|
||||||
-- rebuildable, but idk if it's actually useful for a neovim config
|
|
||||||
-- (look into how ofter people who use lazy.nvim us it)
|
|
||||||
|
|
||||||
--- 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
|
||||||
|
|
@ -32,9 +25,8 @@ local function synctree(tree, cb)
|
||||||
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
|
||||||
|
|
||||||
fs:clean(packager)
|
for _, p in pairs(tree) do
|
||||||
for _, package in pairs(tree) do
|
p:reload()
|
||||||
package:reload()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if cb then
|
if cb then
|
||||||
|
|
@ -43,18 +35,20 @@ local function synctree(tree, cb)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, package in pairs(tree) do
|
-- convert our spec to vim.pack.Spec
|
||||||
local co = coroutine.create(function()
|
local vimspecs = {}
|
||||||
-- if the package provided prefers a local source then use the local
|
for _, p in ipairs(tree) do
|
||||||
-- source instead of the git repository
|
table.insert(vimspecs, {
|
||||||
if package.path then
|
name = p.name,
|
||||||
fs:sync(package, done)
|
src = p.path or p.url,
|
||||||
else
|
version = p.commit or p.branch
|
||||||
git.sync(package, done)
|
})
|
||||||
end
|
|
||||||
end)
|
|
||||||
coroutine.resume(co)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
vim.pack.add(vimspecs, {
|
||||||
|
load = done,
|
||||||
|
confirm = false,
|
||||||
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
--- check if a package should be synced
|
--- check if a package should be synced
|
||||||
|
|
@ -100,7 +94,7 @@ return function(opts)
|
||||||
local root = packager:new({
|
local root = packager:new({
|
||||||
"squibid/dep",
|
"squibid/dep",
|
||||||
url = "https://git.squi.bid/squibid/dep.git",
|
url = "https://git.squi.bid/squibid/dep.git",
|
||||||
branch = "lazy"
|
branch = "pack"
|
||||||
})
|
})
|
||||||
if not root then
|
if not root then
|
||||||
logger:log("error", "couldn't register root package")
|
logger:log("error", "couldn't register root package")
|
||||||
|
|
@ -157,21 +151,4 @@ return function(opts)
|
||||||
package:reload()
|
package:reload()
|
||||||
end
|
end
|
||||||
end, {})
|
end, {})
|
||||||
|
|
||||||
vim.api.nvim_create_user_command("DepClean", function()
|
|
||||||
-- clean AND reload to make sure that all old packages are gone
|
|
||||||
fs:clean(packager)
|
|
||||||
end, {})
|
|
||||||
|
|
||||||
vim.api.nvim_create_user_command("DepUi", function()
|
|
||||||
ui.open(packager)
|
|
||||||
ui.set_page("P")
|
|
||||||
end, {})
|
|
||||||
|
|
||||||
vim.api.nvim_create_user_command("DepLog", function()
|
|
||||||
ui.open(packager)
|
|
||||||
ui.set_page("L")
|
|
||||||
end, {})
|
|
||||||
|
|
||||||
logger:cleanup()
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,78 +0,0 @@
|
||||||
local h = require('dep.helpers')
|
|
||||||
local logger = require('dep.log')
|
|
||||||
|
|
||||||
local fs = {}
|
|
||||||
|
|
||||||
--- abstract away fs:link to make calling more intuitive
|
|
||||||
---@param package package package to update
|
|
||||||
---@param cb function callback on success
|
|
||||||
function fs:sync(package, cb)
|
|
||||||
if not package.exists then
|
|
||||||
fs:link(package, cb)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--- create a symlink to a local package
|
|
||||||
---@param package package package to link
|
|
||||||
---@param cb function callback on success
|
|
||||||
function fs:link(package, cb)
|
|
||||||
h.uv.fs_symlink(package.path, package.dir, nil, function(err, _)
|
|
||||||
if err then
|
|
||||||
logger:log("error", "failed to symlink %s; reason: %s", package.id, err)
|
|
||||||
else
|
|
||||||
cb(err)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
--- clean out old packages
|
|
||||||
---@param package package any package
|
|
||||||
function fs:clean(package)
|
|
||||||
h.uv.fs_scandir(
|
|
||||||
package.get_base_dir(),
|
|
||||||
vim.schedule_wrap(function(err, handle)
|
|
||||||
if err then
|
|
||||||
logger:log("error", "failed to clean; reason: %s", err)
|
|
||||||
else
|
|
||||||
local queue = {}
|
|
||||||
|
|
||||||
while handle do
|
|
||||||
local name = h.uv.fs_scandir_next(handle)
|
|
||||||
if name and name ~= package.get_root().name then
|
|
||||||
queue[name] = package.get_base_dir().."/"..name
|
|
||||||
elseif name == package.get_root().name then
|
|
||||||
-- we need to ensure that there is no chance of nuking dep
|
|
||||||
goto continue
|
|
||||||
elseif name == nil then
|
|
||||||
break
|
|
||||||
else
|
|
||||||
-- if there's a single error bail out
|
|
||||||
logger:log("error", "failed to run clean uv.fs_scandir_next failed")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
::continue::
|
|
||||||
end
|
|
||||||
|
|
||||||
-- keep packages that still exist
|
|
||||||
for _, pkg in pairs(package.get_packages()) do
|
|
||||||
queue[pkg.name] = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
-- start deleting all of the packages which are chosen for deletion
|
|
||||||
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", "deleted %s", name)
|
|
||||||
else
|
|
||||||
logger:log("error", "failed to delete %s", name)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
coroutine.resume(co)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
return fs
|
|
||||||
161
lua/dep/git.lua
161
lua/dep/git.lua
|
|
@ -1,161 +0,0 @@
|
||||||
-- 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 proc = require('dep.proc')
|
|
||||||
|
|
||||||
local git = {}
|
|
||||||
|
|
||||||
--- install or update a given package
|
|
||||||
---@param package package package to update/install
|
|
||||||
---@param cb function callback
|
|
||||||
function git.sync(package, cb)
|
|
||||||
local function sync()
|
|
||||||
-- update or install
|
|
||||||
if package.exists then
|
|
||||||
git.update(package, cb)
|
|
||||||
else
|
|
||||||
git.install(package, cb)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- handle arbitrary branches here
|
|
||||||
if package.branch then
|
|
||||||
proc.git_resolve_branch(package.url, package.branch, function(err, message)
|
|
||||||
if not err then
|
|
||||||
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")
|
|
||||||
|
|
||||||
logger:log("config", "package: %s configured", package.id)
|
|
||||||
package.configured = true
|
|
||||||
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
|
|
||||||
cb()
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
proc.git_clone(package.dir, package.url, package.branch, function(err, message)
|
|
||||||
if err then
|
|
||||||
logger:log("error", "failed to install %s; reason: %s",
|
|
||||||
package.id, message)
|
|
||||||
else
|
|
||||||
if package.commit then
|
|
||||||
proc.git_checkout(package.dir, package.branch, package.commit, function(err, message)
|
|
||||||
if err then
|
|
||||||
logger:log("error", "failed to checkout %s; reason: %s", package.id, message)
|
|
||||||
else
|
|
||||||
package.exists = true
|
|
||||||
package:unconfiguretree()
|
|
||||||
logger:log("install", "installed %s", package.id)
|
|
||||||
configurepkg(package)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
else
|
|
||||||
package.exists = true
|
|
||||||
package:unconfiguretree()
|
|
||||||
logger:log("install", "installed %s", package.id)
|
|
||||||
configurepkg(package)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
cb(err)
|
|
||||||
end)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
--- update a package
|
|
||||||
---@param package package package to update
|
|
||||||
---@param cb function callback
|
|
||||||
function git.update(package, cb)
|
|
||||||
if not package.enabled then
|
|
||||||
cb()
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local function log_err(err)
|
|
||||||
logger:log("error", "failed to update %s; reason: %s", package.id, err)
|
|
||||||
end
|
|
||||||
|
|
||||||
if package.pin then
|
|
||||||
cb()
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
proc.git_rev_parse(package.dir, "HEAD", function(err, before)
|
|
||||||
if err then
|
|
||||||
log_err(before)
|
|
||||||
cb(err)
|
|
||||||
else
|
|
||||||
if package.commit then
|
|
||||||
proc.git_checkout(package.dir, package.branch, package.commit, function(err, message)
|
|
||||||
if err then
|
|
||||||
log_err(message)
|
|
||||||
cb(err)
|
|
||||||
else
|
|
||||||
proc.git_rev_parse(package.dir, package.commit, function(err, after)
|
|
||||||
if err then
|
|
||||||
log_err(after)
|
|
||||||
cb(err)
|
|
||||||
elseif before == after then
|
|
||||||
logger:log("skip", "skipped %s", package.id)
|
|
||||||
cb(err)
|
|
||||||
else
|
|
||||||
package:unconfiguretree()
|
|
||||||
logger:log("update", "updated %s; %s -> %s", package.id, before, after)
|
|
||||||
configurepkg(package)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
else
|
|
||||||
proc.git_fetch(package.dir, "origin", package.branch or "HEAD", function(err, message)
|
|
||||||
if err then
|
|
||||||
log_err(message)
|
|
||||||
cb(err)
|
|
||||||
else
|
|
||||||
proc.git_rev_parse(package.dir, "FETCH_HEAD^{commit}", function(err, after)
|
|
||||||
if err then
|
|
||||||
log_err(after)
|
|
||||||
cb(err)
|
|
||||||
elseif before == after then
|
|
||||||
logger:log("skip", "skipped %s", package.id)
|
|
||||||
cb(err)
|
|
||||||
else
|
|
||||||
proc.git_reset(package.dir, after, function(err, message)
|
|
||||||
if err then
|
|
||||||
log_err(message)
|
|
||||||
else
|
|
||||||
package:unconfiguretree()
|
|
||||||
logger:log("update", "updated %s; %s -> %s", package.id, before, after)
|
|
||||||
configurepkg(package)
|
|
||||||
end
|
|
||||||
|
|
||||||
cb(err)
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
return git
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
return {
|
|
||||||
-- vim.loop was depricated in nvim 0.10
|
|
||||||
uv = vim.uv or vim.loop
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
local h = require("dep.helpers")
|
|
||||||
local packager = require("dep.package")
|
local packager = require("dep.package")
|
||||||
|
|
||||||
---@class lazy
|
---@class lazy
|
||||||
|
|
@ -16,7 +15,7 @@ local function colorscheme()
|
||||||
if not p.loaded then
|
if not p.loaded then
|
||||||
for _, ext in ipairs({ ".lua", ".vim" }) do
|
for _, ext in ipairs({ ".lua", ".vim" }) do
|
||||||
local path = p.dir.."/colors/"..e.match..ext
|
local path = p.dir.."/colors/"..e.match..ext
|
||||||
if h.uv.fs_stat(path) then
|
if vim.uv.fs_stat(path) then
|
||||||
p:ensureadded(true)
|
p:ensureadded(true)
|
||||||
-- break out of here, we've loaded the colorscheme
|
-- break out of here, we've loaded the colorscheme
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
local h = require('dep.helpers')
|
|
||||||
|
|
||||||
local logger = {}
|
local logger = {}
|
||||||
|
|
||||||
logger.stage_colors = {
|
logger.stage_colors = {
|
||||||
|
|
@ -16,8 +14,8 @@ logger.stage_colors = {
|
||||||
local function default_log_path()
|
local function default_log_path()
|
||||||
-- create cache directory and chmod it if it doesn't already exist
|
-- create cache directory and chmod it if it doesn't already exist
|
||||||
local path = vim.fn.stdpath("cache")
|
local path = vim.fn.stdpath("cache")
|
||||||
if not h.uv.fs_stat(path) then
|
if not vim.uv.fs_stat(path) then
|
||||||
h.uv.fs_mkdir(path, 0x1ff) -- 0777
|
vim.uv.fs_mkdir(path, 0x1ff) -- 0777
|
||||||
end
|
end
|
||||||
|
|
||||||
return vim.fs.normalize(path).."/dep.log"
|
return vim.fs.normalize(path).."/dep.log"
|
||||||
|
|
@ -39,8 +37,8 @@ function logger:setup(path)
|
||||||
logger.path = path or default_log_path()
|
logger.path = path or default_log_path()
|
||||||
local pipe
|
local pipe
|
||||||
|
|
||||||
logger.handle = assert(h.uv.fs_open(logger.path, "w", 0x1a4)) -- 0644
|
logger.handle = assert(vim.uv.fs_open(logger.path, "w", 0x1a4)) -- 0644
|
||||||
pipe = h.uv.new_pipe()
|
pipe = vim.uv.new_pipe() --[[@as uv.uv_pipe_t]]
|
||||||
pipe:open(logger.handle)
|
pipe:open(logger.handle)
|
||||||
|
|
||||||
return pipe
|
return pipe
|
||||||
|
|
@ -94,7 +92,7 @@ function logger:cleanup(pipe, handle)
|
||||||
pipe = nil
|
pipe = nil
|
||||||
end
|
end
|
||||||
if handle then
|
if handle then
|
||||||
h.uv.fs_close(logger.handle)
|
vim.uv.fs_close(logger.handle)
|
||||||
handle = nil
|
handle = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
local h = require('dep.helpers')
|
|
||||||
local logger = require('dep.log')
|
local logger = require('dep.log')
|
||||||
local module = require("dep.modules.module")
|
local module = require("dep.modules.module")
|
||||||
|
|
||||||
|
|
@ -30,9 +29,9 @@ function modules:setup(speclist, overrides, config_path)
|
||||||
"lua", (speclist.modules.prefix:gsub("%.", "/"))
|
"lua", (speclist.modules.prefix:gsub("%.", "/"))
|
||||||
)
|
)
|
||||||
|
|
||||||
local handle = h.uv.fs_scandir(path)
|
local handle = vim.uv.fs_scandir(path)
|
||||||
while handle do
|
while handle do
|
||||||
local name = h.uv.fs_scandir_next(handle)
|
local name = vim.uv.fs_scandir_next(handle)
|
||||||
if name then
|
if name then
|
||||||
-- skip non-lua files
|
-- skip non-lua files
|
||||||
if name:sub(#name - 3) ~= ".lua" then
|
if name:sub(#name - 3) ~= ".lua" then
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@ function package:new(spec, overrides)
|
||||||
|
|
||||||
o.name = spec.as or o.name or spec_man.get_name(spec)
|
o.name = spec.as or o.name or spec_man.get_name(spec)
|
||||||
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.path = spec.path and vim.fs.normalize(spec.path) or spec.path
|
o.path = spec.path and "file://"..vim.fs.normalize(spec.path) or spec.path
|
||||||
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
|
||||||
o.commit = spec.commit
|
o.commit = spec.commit
|
||||||
|
|
|
||||||
129
lua/dep/proc.lua
129
lua/dep/proc.lua
|
|
@ -1,129 +0,0 @@
|
||||||
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)
|
|
||||||
local buffer = {}
|
|
||||||
|
|
||||||
local function cb_output(_, data, _)
|
|
||||||
table.insert(buffer, table.concat(data))
|
|
||||||
end
|
|
||||||
local function cb_exit(_, exit_code, _)
|
|
||||||
local output = table.concat(buffer)
|
|
||||||
cb(exit_code ~= 0, output)
|
|
||||||
end
|
|
||||||
table.insert(args, 1, process)
|
|
||||||
vim.fn.jobstart(args, {
|
|
||||||
cwd = cwd,
|
|
||||||
env = env,
|
|
||||||
stdin = nil,
|
|
||||||
on_exit = cb_exit,
|
|
||||||
on_stdout = cb_output,
|
|
||||||
on_stderr = cb_output,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
local git_env = { GIT_TERMINAL_PROMPT = 0 }
|
|
||||||
|
|
||||||
function proc.git_rev_parse(dir, arg, cb)
|
|
||||||
local args = { "rev-parse", "--short", arg }
|
|
||||||
|
|
||||||
proc.exec("git", args, dir, git_env, cb)
|
|
||||||
end
|
|
||||||
|
|
||||||
function proc.git_clone(dir, url, branch, cb)
|
|
||||||
local args = { "clone", "--depth=1", "--recurse-submodules", "--shallow-submodules", url, dir }
|
|
||||||
|
|
||||||
if branch then
|
|
||||||
args[#args + 1] = "--branch="..branch
|
|
||||||
end
|
|
||||||
|
|
||||||
proc.exec("git", args, nil, git_env, cb)
|
|
||||||
end
|
|
||||||
|
|
||||||
function proc.git_fetch(dir, remote, refspec, cb)
|
|
||||||
local args = { "fetch", "--depth=1", "--recurse-submodules", remote, refspec }
|
|
||||||
|
|
||||||
proc.exec("git", args, dir, git_env, cb)
|
|
||||||
end
|
|
||||||
|
|
||||||
function proc.git_reset(dir, treeish, cb)
|
|
||||||
local args = { "reset", "--hard", "--recurse-submodules", treeish, "--" }
|
|
||||||
|
|
||||||
proc.exec("git", args, dir, git_env, cb)
|
|
||||||
end
|
|
||||||
|
|
||||||
function proc.git_checkout(dir, branch, commit, cb)
|
|
||||||
local args = { "fetch", "--depth=2147483647", "origin", branch }
|
|
||||||
proc.exec("git", args, dir, git_env, function(err, message)
|
|
||||||
cb(err, message)
|
|
||||||
|
|
||||||
args = { "checkout", commit }
|
|
||||||
proc.exec("git", args, dir, git_env, cb)
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
function proc.git_resolve_branch(url, branch, cb)
|
|
||||||
-- if the branch doesn't contain a * then return the branch
|
|
||||||
if not string.match(branch, "*") then
|
|
||||||
cb(false, branch)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local buffer = {}
|
|
||||||
local function cb_output(_, data, _)
|
|
||||||
if data[1] ~= "" then
|
|
||||||
buffer = data
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
vim.fn.jobstart({ "git", "ls-remote", "--tags", "--sort", "v:refname", url },
|
|
||||||
{
|
|
||||||
cwd = nil,
|
|
||||||
env = git_env,
|
|
||||||
stdin = nil,
|
|
||||||
on_stdout = cb_output,
|
|
||||||
on_stderr = cb_output,
|
|
||||||
on_exit = function(_, exit_code, _)
|
|
||||||
if exit_code ~= 0 then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
-- get a list of all versions
|
|
||||||
local versions = {}
|
|
||||||
for _, v in pairs(buffer) do
|
|
||||||
local s, e = string.find(v, "refs/tags/.+")
|
|
||||||
if not s or not e then
|
|
||||||
goto continue
|
|
||||||
end
|
|
||||||
|
|
||||||
local tag = string.sub(v, s, e)
|
|
||||||
tag = tag:gsub("refs/tags/", ""):gsub("%^{}", "")
|
|
||||||
|
|
||||||
table.insert(versions, tag)
|
|
||||||
::continue::
|
|
||||||
end
|
|
||||||
|
|
||||||
-- match the chosen version against all versions
|
|
||||||
for i = #versions, 1, -1 do
|
|
||||||
if branch == "*" then
|
|
||||||
cb(false, versions[i])
|
|
||||||
return
|
|
||||||
else
|
|
||||||
local r = string.match(versions[i], branch)
|
|
||||||
if r then
|
|
||||||
cb(false, r)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
}
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
return proc
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
||||||
local logger = require("dep.log")
|
|
||||||
|
|
||||||
local format = {}
|
|
||||||
|
|
||||||
--- format a boolean to a chunk with highlights
|
|
||||||
---@param b boolean
|
|
||||||
---@return chunk chunk
|
|
||||||
function format.bool(b)
|
|
||||||
return { vim.inspect(b), b and "DiffAdd" or "DiffDelete" }
|
|
||||||
end
|
|
||||||
|
|
||||||
--- format a number to a chunk with highlights
|
|
||||||
---@param n number
|
|
||||||
---@return chunk chunk
|
|
||||||
function format.number(n)
|
|
||||||
return { vim.inspect(n), "Number" }
|
|
||||||
end
|
|
||||||
|
|
||||||
--- format a log line with highlights
|
|
||||||
---@param log_line string log line
|
|
||||||
---@return chunk[] chunks
|
|
||||||
function format.log_line(log_line)
|
|
||||||
-- make sure we don't do operations on nil values
|
|
||||||
if not log_line or log_line == "" then
|
|
||||||
return {}
|
|
||||||
end
|
|
||||||
|
|
||||||
-- error on any nil values, this should prevent us from parsing an incorrectly
|
|
||||||
-- formatted log line
|
|
||||||
local log_time, colon, log_path, log_path_ln, level, rest
|
|
||||||
local ok = pcall(function()
|
|
||||||
log_time = string.sub(log_line, string.find(log_line, "%[") + 1,
|
|
||||||
string.find(log_line, "%]") - 1)
|
|
||||||
colon = string.find(log_line, ":", 11)
|
|
||||||
log_path = string.sub(log_line, string.find(log_line, "%]") + 2,
|
|
||||||
colon - 1)
|
|
||||||
log_path_ln = string.sub(log_line, colon + 1,
|
|
||||||
string.find(log_line, ":", colon + 1) - 1)
|
|
||||||
level = string.sub(log_line, string.find(log_line, "%(") + 1,
|
|
||||||
string.find(log_line, "%)") - 1)
|
|
||||||
rest = string.sub(log_line, string.find(log_line, "%)") + 2)
|
|
||||||
end)
|
|
||||||
if not ok then
|
|
||||||
return {}
|
|
||||||
end
|
|
||||||
|
|
||||||
return {
|
|
||||||
{ "[", "" },
|
|
||||||
{ log_time, "Boolean" },
|
|
||||||
{ "] ", "" },
|
|
||||||
{ log_path, "String" },
|
|
||||||
{ ":", "" },
|
|
||||||
{ log_path_ln, "Number" },
|
|
||||||
{ ": ", "" },
|
|
||||||
{ rest, logger.stage_colors[level] or "" }
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
return format
|
|
||||||
|
|
@ -1,207 +0,0 @@
|
||||||
local h = require("dep.helpers")
|
|
||||||
local page = require("dep.ui.page")
|
|
||||||
local logger = require("dep.log")
|
|
||||||
local format = require("dep.ui.format")
|
|
||||||
|
|
||||||
---@class ui
|
|
||||||
---@field bufnr number
|
|
||||||
---@field winnr number
|
|
||||||
---@field header_bufnr number
|
|
||||||
---@field header_winnr number
|
|
||||||
---@field pages page[]
|
|
||||||
local ui = {}
|
|
||||||
|
|
||||||
-- the active page being displayed
|
|
||||||
local active_page
|
|
||||||
|
|
||||||
-- all the pages
|
|
||||||
local pages = {}
|
|
||||||
|
|
||||||
-- the header ext mark
|
|
||||||
local header_ext_id
|
|
||||||
|
|
||||||
local function page_packages(packager)
|
|
||||||
local p = page:new("Packages", "P")
|
|
||||||
for _, pkg in pairs(packager.get_packages()) do
|
|
||||||
p:new_line({
|
|
||||||
{ pkg.id, "@conditional" },
|
|
||||||
{ " loaded: ", "" },
|
|
||||||
format.bool(pkg.loaded),
|
|
||||||
{ " lazy: ", "" },
|
|
||||||
format.bool(pkg.lazy)
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
return p
|
|
||||||
end
|
|
||||||
|
|
||||||
local function page_log()
|
|
||||||
local p = page:new("Log", "L")
|
|
||||||
local f = io.open(logger.path, "r")
|
|
||||||
if not f then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
-- put the cursor at the bottom of the page after drawing
|
|
||||||
p.post_draw = function()
|
|
||||||
if ui.winnr then
|
|
||||||
vim.api.nvim_win_set_cursor(ui.winnr, { #p.content, 0 })
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- read in the contents of the file, and keep watching for updates
|
|
||||||
local function update_contents()
|
|
||||||
repeat
|
|
||||||
local line = f:read("*l")
|
|
||||||
|
|
||||||
-- if the line isn't empty we shouldn't draw it
|
|
||||||
if line then
|
|
||||||
p:new_line(format.log_line(line))
|
|
||||||
end
|
|
||||||
until not line
|
|
||||||
end
|
|
||||||
|
|
||||||
update_contents()
|
|
||||||
|
|
||||||
local fullpath = vim.api.nvim_call_function(
|
|
||||||
"fnamemodify", { logger.path, ":p" })
|
|
||||||
h.uv.new_fs_event():start(fullpath, {}, vim.schedule_wrap(function()
|
|
||||||
update_contents()
|
|
||||||
|
|
||||||
-- if the log is currently being displayed then make sure to draw it when
|
|
||||||
-- it updates
|
|
||||||
if active_page == p then
|
|
||||||
p:draw(ui.bufnr)
|
|
||||||
end
|
|
||||||
end))
|
|
||||||
|
|
||||||
return p
|
|
||||||
end
|
|
||||||
|
|
||||||
--- set the current page
|
|
||||||
---@param p string|page page to set
|
|
||||||
function ui.set_page(p)
|
|
||||||
if type(p) == "string" then
|
|
||||||
for _, v in ipairs(pages) do
|
|
||||||
if p == v.kb then
|
|
||||||
v:draw(ui.bufnr)
|
|
||||||
active_page = v
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
elseif type(p) == "table" then
|
|
||||||
p:draw(ui.bufnr)
|
|
||||||
active_page = p
|
|
||||||
end
|
|
||||||
|
|
||||||
-- color the header text
|
|
||||||
local txt = vim.api.nvim_buf_get_text(ui.header_bufnr, 0, 0, -1, -1, {})[1]
|
|
||||||
local start_range = (string.find(txt, active_page.name)) - 2
|
|
||||||
local end_range = #active_page.name + start_range + 2
|
|
||||||
|
|
||||||
if header_ext_id then
|
|
||||||
vim.api.nvim_buf_del_extmark(ui.header_bufnr, active_page.hlns, header_ext_id)
|
|
||||||
end
|
|
||||||
header_ext_id = vim.api.nvim_buf_set_extmark(ui.header_bufnr,
|
|
||||||
active_page.hlns, 0, start_range, {
|
|
||||||
hl_mode = "replace",
|
|
||||||
hl_group = "CurSearch",
|
|
||||||
end_col = end_range,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
local setup
|
|
||||||
--- setup all the pages
|
|
||||||
---@param packager package the packager
|
|
||||||
local function setup_pages(packager)
|
|
||||||
if setup then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local header_text = ""
|
|
||||||
|
|
||||||
table.insert(pages, page_packages(packager))
|
|
||||||
table.insert(pages, page_log())
|
|
||||||
|
|
||||||
for _, v in ipairs(pages) do
|
|
||||||
header_text = header_text.." "..v.name.." "
|
|
||||||
|
|
||||||
vim.keymap.set("n", v.kb, function()
|
|
||||||
ui.set_page(v)
|
|
||||||
end, { buffer = ui.bufnr })
|
|
||||||
end
|
|
||||||
|
|
||||||
-- set the header text
|
|
||||||
vim.api.nvim_buf_set_lines(ui.header_bufnr, 0, -1, false, { header_text })
|
|
||||||
|
|
||||||
-- add keymaps
|
|
||||||
vim.keymap.set("n", "q", function()
|
|
||||||
vim.api.nvim_win_close(ui.winnr, false)
|
|
||||||
ui.winnr = nil
|
|
||||||
end, { buffer = ui.bufnr })
|
|
||||||
|
|
||||||
setup = true
|
|
||||||
end
|
|
||||||
|
|
||||||
--- setup the ui
|
|
||||||
---@param packager package
|
|
||||||
function ui.open(packager)
|
|
||||||
if not ui.bufnr then
|
|
||||||
ui.bufnr = vim.api.nvim_create_buf(false, true)
|
|
||||||
end
|
|
||||||
if not ui.header_bufnr then
|
|
||||||
ui.header_bufnr = vim.api.nvim_create_buf(false, true)
|
|
||||||
end
|
|
||||||
|
|
||||||
local header_height = 1
|
|
||||||
local width = math.floor(vim.o.columns * 0.8)
|
|
||||||
local height = math.floor(vim.o.lines * 0.8) - header_height
|
|
||||||
|
|
||||||
if not ui.winnr then
|
|
||||||
ui.winnr = vim.api.nvim_open_win(ui.bufnr, true, {
|
|
||||||
relative = "editor",
|
|
||||||
row = (vim.o.lines - height) / 2,
|
|
||||||
col = (vim.o.columns - width) / 2,
|
|
||||||
width = width,
|
|
||||||
height = height,
|
|
||||||
border = "solid",
|
|
||||||
zindex = 998,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
if not ui.header_winnr then
|
|
||||||
ui.header_winnr = vim.api.nvim_open_win(ui.header_bufnr, false, {
|
|
||||||
relative = "editor",
|
|
||||||
row = ((vim.o.lines - height) / 2) - (header_height * 2),
|
|
||||||
col = (vim.o.columns - width) / 2,
|
|
||||||
width = width,
|
|
||||||
height = header_height,
|
|
||||||
border = "solid",
|
|
||||||
zindex = 999,
|
|
||||||
focusable = false
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
vim.api.nvim_win_set_buf(ui.winnr, ui.bufnr)
|
|
||||||
vim.api.nvim_win_set_buf(ui.header_winnr, ui.header_bufnr)
|
|
||||||
|
|
||||||
-- make sure the header closes when the body does and vice versa
|
|
||||||
local function cb()
|
|
||||||
vim.api.nvim_win_close(ui.header_winnr, false)
|
|
||||||
ui.header_winnr = nil
|
|
||||||
vim.api.nvim_win_close(ui.winnr, false)
|
|
||||||
ui.winnr = nil
|
|
||||||
end
|
|
||||||
vim.api.nvim_create_autocmd("WinClosed", {
|
|
||||||
pattern = ui.winnr.."",
|
|
||||||
callback = cb
|
|
||||||
})
|
|
||||||
vim.api.nvim_create_autocmd("WinClosed", {
|
|
||||||
pattern = ui.header_winnr.."",
|
|
||||||
callback = cb
|
|
||||||
})
|
|
||||||
|
|
||||||
setup_pages(packager)
|
|
||||||
end
|
|
||||||
|
|
||||||
return ui
|
|
||||||
|
|
@ -1,84 +0,0 @@
|
||||||
---@class chunk: table
|
|
||||||
---@field [1] string text to be displayed
|
|
||||||
---@field [2] string neovim highlight group to use
|
|
||||||
|
|
||||||
---@class page
|
|
||||||
---@field name string name of the ui page
|
|
||||||
---@field kb string keybind of the page
|
|
||||||
---@field content chunk[]|chunk[][] all the chunks
|
|
||||||
---@field hlns number highlight namespace
|
|
||||||
---@field pre_draw function things to do prior to drawing to the buffer
|
|
||||||
---@field post_draw function things to do post drawing to the buffer
|
|
||||||
local page = {}
|
|
||||||
|
|
||||||
--- create a new page
|
|
||||||
---@param name string the name of the page
|
|
||||||
---@param kb string keybind to change to the page
|
|
||||||
---@return page page
|
|
||||||
function page:new(name, kb)
|
|
||||||
local o = {}
|
|
||||||
self.__index = self
|
|
||||||
setmetatable(o, self)
|
|
||||||
|
|
||||||
o.hlns = vim.api.nvim_create_namespace("DepUi")
|
|
||||||
o.name = name
|
|
||||||
o.kb = kb
|
|
||||||
o.content = {}
|
|
||||||
|
|
||||||
return o
|
|
||||||
end
|
|
||||||
|
|
||||||
--- add a new line to the page
|
|
||||||
---@param line chunk|chunk[] new line
|
|
||||||
function page:new_line(line)
|
|
||||||
table.insert(self.content, line)
|
|
||||||
end
|
|
||||||
|
|
||||||
--- draw the page to the given buffer
|
|
||||||
---@param bufnr number buffer number
|
|
||||||
function page:draw(bufnr)
|
|
||||||
-- try to run pre_draw steps
|
|
||||||
if self.pre_draw then
|
|
||||||
self.pre_draw()
|
|
||||||
end
|
|
||||||
|
|
||||||
-- ready all information for rendering
|
|
||||||
for i, chunk in ipairs(self.content) do
|
|
||||||
local linenr = i - 1
|
|
||||||
local text = ""
|
|
||||||
local hls = {}
|
|
||||||
|
|
||||||
if type(chunk[1]) == "table" then
|
|
||||||
local j = 0
|
|
||||||
for _, ch in ipairs(chunk) do
|
|
||||||
text = text..ch[1]
|
|
||||||
table.insert(hls, { ch[2], j, j + #ch[1] })
|
|
||||||
j = j + #ch[1]
|
|
||||||
end
|
|
||||||
elseif type(chunk[1]) == "string" then
|
|
||||||
text = chunk[1]
|
|
||||||
table.insert(hls, { chunk[2], 0, #text })
|
|
||||||
end
|
|
||||||
|
|
||||||
-- draw the text to the buffer
|
|
||||||
vim.api.nvim_buf_set_lines(bufnr, linenr, -1, false, { text })
|
|
||||||
|
|
||||||
-- highlight the buffer
|
|
||||||
for _, hl in ipairs(hls) do
|
|
||||||
vim.api.nvim_buf_set_extmark(bufnr, self.hlns, linenr, hl[2], {
|
|
||||||
hl_mode = "replace",
|
|
||||||
hl_group = hl[1],
|
|
||||||
end_col = hl[3],
|
|
||||||
end_row = linenr
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
-- try to run post_draw steps
|
|
||||||
if self.post_draw then
|
|
||||||
self.post_draw()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return page
|
|
||||||
|
|
@ -1,33 +1,6 @@
|
||||||
---@diagnostic disable: undefined-global, undefined-field
|
---@diagnostic disable: undefined-global, undefined-field
|
||||||
local dep_ui_format = require("dep.ui.format")
|
|
||||||
local dep_spec_man = require("dep.spec")
|
local dep_spec_man = require("dep.spec")
|
||||||
|
|
||||||
describe("ui log formatting", function()
|
|
||||||
it("returns the proper chunks to print a formatted line", function()
|
|
||||||
assert.same(
|
|
||||||
{
|
|
||||||
{ "[", "" },
|
|
||||||
{ "11:22:33", "Boolean" },
|
|
||||||
{ "] ", "" },
|
|
||||||
{ "file.lua", "String" },
|
|
||||||
{ ":", "" },
|
|
||||||
{ "1", "Number" },
|
|
||||||
{ ": ", "" },
|
|
||||||
{ "some fancy message", "" }
|
|
||||||
},
|
|
||||||
dep_ui_format.log_line("[11:22:33] file.lua:1:(vim) some fancy message")
|
|
||||||
)
|
|
||||||
|
|
||||||
-- malformed log line
|
|
||||||
assert.same({},
|
|
||||||
dep_ui_format.log_line("11:22:33] file.lua:1:(vim) some fancy message"))
|
|
||||||
|
|
||||||
-- test nil values
|
|
||||||
assert.same({}, dep_ui_format.log_line(""))
|
|
||||||
assert.same({}, dep_ui_format.log_line(nil))
|
|
||||||
end)
|
|
||||||
end)
|
|
||||||
|
|
||||||
describe("package specification", function()
|
describe("package specification", function()
|
||||||
it("gets the package's name", function()
|
it("gets the package's name", function()
|
||||||
assert.equal(dep_spec_man.get_name({ "user/package" }), "package")
|
assert.equal(dep_spec_man.get_name({ "user/package" }), "package")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue