aboutsummaryrefslogtreecommitdiffstats
path: root/lua/dep.lua
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--lua/dep.lua369
1 files changed, 237 insertions, 132 deletions
diff --git a/lua/dep.lua b/lua/dep.lua
index 6454d19..cb86e4d 100644
--- a/lua/dep.lua
+++ b/lua/dep.lua
@@ -3,9 +3,15 @@ local proc = require("dep/proc")
logger:open()
-local initialized, config_path, base_dir
+local initialized, perf, config_path, base_dir
local packages, root
+local function bench(name, code, ...)
+ local start = os.clock()
+ code(...)
+ perf[name] = os.clock() - start
+end
+
local function get_name(id)
local name = id:match("^[%w-_.]+/([%w-_.]+)$")
if name then
@@ -52,6 +58,7 @@ local function register(spec, overrides)
on_load = {},
dependencies = {}, -- inward edges
dependents = {}, -- outward edges
+ perf = {},
}
packages[id] = package
@@ -120,6 +127,10 @@ local function register_recursive(list, overrides)
local name, module = "<unnamed module>", list.modules[i]
if type(module) == "string" then
+ if list.modules.prefix then
+ module = list.modules.prefix .. module
+ end
+
name, module = module, require(module)
end
@@ -224,6 +235,11 @@ end
local function run_hooks(package, type)
local hooks = package[type]
+ if #hooks == 0 then
+ return true
+ end
+
+ local start = os.clock()
for i = 1, #hooks do
local ok, err = pcall(hooks[i])
@@ -233,26 +249,36 @@ local function run_hooks(package, type)
end
end
- if #hooks ~= 0 then
- logger:log(
- "hook",
- string.format("triggered %d %s %s for %s", #hooks, type, #hooks == 1 and "hook" or "hooks", package.id)
- )
- end
+ package.perf[type] = os.clock() - start
+
+ logger:log(
+ "hook",
+ string.format("triggered %d %s %s for %s", #hooks, type, #hooks == 1 and "hook" or "hooks", package.id)
+ )
return true
end
local function ensure_added(package)
if not package.added then
- local ok, err = pcall(vim.cmd, "packadd " .. package.name)
- if ok then
- package.added = true
- logger:log("vim", string.format("packadd completed for %s", package.id))
- else
+ local ok, err = run_hooks(package, "on_setup")
+ if not ok then
package.error = true
return false, err
end
+
+ local start = os.clock()
+
+ ok, err = pcall(vim.cmd, "packadd " .. package.name)
+ if not ok then
+ package.error = true
+ return false, err
+ end
+
+ package.added = true
+ package.perf.pack = os.clock() - start
+
+ logger:log("vim", string.format("packadd completed for %s", package.id))
end
return true
@@ -270,13 +296,7 @@ local function configure_recursive(package)
end
if not package.configured then
- local ok, err = run_hooks(package, "on_setup")
- if not ok then
- logger:log("error", string.format("failed to set up %s; reason: %s", package.id, err))
- return
- end
-
- ok, err = ensure_added(package)
+ local ok, err = ensure_added(package)
if not ok then
logger:log("error", string.format("failed to configure %s; reason: %s", package.id, err))
return
@@ -339,19 +359,21 @@ local function load_recursive(package)
end
local function reload_meta()
- local ok, err = pcall(
- vim.cmd,
- [[
- silent! helptags ALL
- silent! UpdateRemotePlugins
- ]]
- )
+ bench("meta", function()
+ local ok, err = pcall(
+ vim.cmd,
+ [[
+ silent! helptags ALL
+ silent! UpdateRemotePlugins
+ ]]
+ )
- if ok then
- logger:log("vim", "reloaded helptags and remote plugins")
- else
- logger:log("error", string.format("failed to reload helptags and remote plugins; reason: %s", err))
- end
+ if ok then
+ logger:log("vim", "reloaded helptags and remote plugins")
+ else
+ logger:log("error", string.format("failed to reload helptags and remote plugins; reason: %s", err))
+ end
+ end)
end
local function reload()
@@ -526,146 +548,225 @@ local function sync_list(list)
end
end
-local function print_list()
- local buffer = vim.api.nvim_create_buf(true, true)
- local line = 0
- local indent = 0
+local function get_commits(cb)
+ local results = {}
+ local done = 0
+ for i = 1, #packages do
+ local package = packages[i]
- local function print(chunks)
- local concat = {}
- local column = 0
+ if package.exists then
+ proc.git_rev_parse(package.dir, "HEAD", function(err, commit)
+ if not err then
+ results[package.id] = commit
+ end
- for i = 1, indent do
- concat[#concat + 1] = " "
- column = column + 2
+ done = done + 1
+ if done == #packages then
+ cb(results)
+ end
+ end)
+ else
+ done = done + 1
end
+ end
+end
- if not chunks then
- chunks = {}
- elseif type(chunks) == "string" then
- chunks = { { chunks } }
- end
+local function print_list(cb)
+ get_commits(function(commits)
+ local buffer = vim.api.nvim_create_buf(true, true)
+ local line, indent = 0, 0
- for i = 1, #chunks do
- local chunk = chunks[i]
- concat[#concat + 1] = chunk[1]
- chunk.offset, column = column, column + #chunk[1]
- end
+ local function print(chunks)
+ local concat = {}
+ local column = 0
- vim.api.nvim_buf_set_lines(buffer, line, -1, false, { table.concat(concat) })
+ for i = 1, indent do
+ concat[#concat + 1] = " "
+ column = column + 2
+ end
- for i = 1, #chunks do
- local chunk = chunks[i]
- if chunk[2] then
- vim.api.nvim_buf_add_highlight(buffer, -1, chunk[2], line, chunk.offset, chunk.offset + #chunk[1])
+ if not chunks then
+ chunks = {}
+ elseif type(chunks) == "string" then
+ chunks = { { chunks } }
end
- end
- line = line + 1
- end
+ for i = 1, #chunks do
+ local chunk = chunks[i]
+ concat[#concat + 1] = chunk[1]
+ chunk.offset, column = column, column + #chunk[1]
+ end
- print({
- { "Installed packages:" },
- { string.format(" (%s)", #packages), "Comment" },
- })
+ vim.api.nvim_buf_set_lines(buffer, line, -1, false, { table.concat(concat) })
- indent = 1
- local loaded = {}
+ for i = 1, #chunks do
+ local chunk = chunks[i]
+ if chunk[2] then
+ vim.api.nvim_buf_add_highlight(buffer, -1, chunk[2], line, chunk.offset, chunk.offset + #chunk[1])
+ end
+ end
- local function dry_load(package)
- if loaded[package.id] then
- return
+ line = line + 1
end
- for i = 1, #package.dependencies do
- if not loaded[package.dependencies[i].id] then
+ print(string.format("Installed packages (%s):", #packages))
+ indent = 1
+
+ local loaded = {}
+
+ local function dry_load(package)
+ if loaded[package.id] then
return
end
- end
- loaded[package.id], loaded[#loaded + 1] = true, package
+ for i = 1, #package.dependencies do
+ if not loaded[package.dependencies[i].id] then
+ return
+ end
+ end
- local line = {
- { "- ", "Comment" },
- { package.id, "Underlined" },
- }
+ loaded[package.id], loaded[#loaded + 1] = true, package
- if not package.exists then
- line[#line + 1] = { " *not installed", "Comment" }
- end
+ local line = {
+ { string.format("[%s] ", commits[package.id] or " "), "Comment" },
+ { package.id, "Underlined" },
+ }
- if not package.loaded then
- line[#line + 1] = { " *not loaded", "Comment" }
- end
+ if not package.exists then
+ line[#line + 1] = { " *not installed", "Comment" }
+ end
- if not package.enabled then
- line[#line + 1] = { " *disabled", "Comment" }
- end
+ if not package.loaded then
+ line[#line + 1] = { " *not loaded", "Comment" }
+ end
- if package.pin then
- line[#line + 1] = { " *pinned", "Comment" }
+ if not package.enabled then
+ line[#line + 1] = { " *disabled", "Comment" }
+ end
+
+ if package.pin then
+ line[#line + 1] = { " *pinned", "Comment" }
+ end
+
+ print(line)
+
+ for i = 1, #package.dependents do
+ dry_load(package.dependents[i])
+ end
end
- print(line)
+ dry_load(root)
+ indent = 0
+
+ print()
+ print("Load time (μs):")
+ indent = 1
+ local profiles = {}
+
+ for i = 1, #packages do
+ local package = packages[i]
+ local profile = {
+ package = package,
+ total = 0,
+ setup = package.perf.on_setup or 0,
+ load = package.perf.on_load or 0,
+ pack = package.perf.pack or 0,
+
+ "total",
+ "setup",
+ "pack",
+ "load",
+ }
+
+ if package == root then
+ for k, v in pairs(perf) do
+ if profile[k] then
+ profile[k] = profile[k] + v
+ end
+ end
+ end
- for i = 1, #package.dependents do
- dry_load(package.dependents[i])
+ for i = 1, #profile do
+ profile.total = profile.total + profile[profile[i]]
+ end
+
+ profiles[#profiles + 1] = profile
end
- end
- dry_load(root)
- indent = 0
+ table.sort(profiles, function(a, b)
+ return a.total > b.total
+ end)
- print()
- print("Dependency graph:")
+ for i = 1, #profiles do
+ local profile = profiles[i]
+ local line = {
+ { "- ", "Comment" },
+ { profile.package.id, "Underlined" },
+ { string.rep(" ", 40 - #profile.package.id) },
+ }
+
+ for i = 1, #profile do
+ local key, value = profile[i], profile[profile[i]]
+ line[#line + 1] = { string.format(" %5s ", key), "Comment" }
+ line[#line + 1] = { string.format("%4d", value * 1000000) }
+ end
- local function walk_graph(package)
- indent = indent + 1
+ print(line)
+ end
- local line = {
- { "| ", "Comment" },
- { package.id, "Underlined" },
- }
+ indent = 0
+ print()
+ print("Dependency graph:")
- local function add_edges(package)
- for i = 1, #package.dependencies do
- local dependency = package.dependencies[i]
+ local function walk_graph(package)
+ local line = {
+ { "| ", "Comment" },
+ { package.id, "Underlined" },
+ }
+
+ local function add_edges(package)
+ for i = 1, #package.dependencies do
+ local dependency = package.dependencies[i]
- if dependency ~= root then -- don't convolute the list
- line[#line + 1] = { " " .. dependency.id, "Comment" }
- add_edges(dependency)
+ if dependency ~= root then -- don't convolute the list
+ line[#line + 1] = { " " .. dependency.id, "Comment" }
+ add_edges(dependency)
+ end
end
end
- end
- add_edges(package)
- print(line)
+ add_edges(package)
+ print(line)
- for i = 1, #package.dependents do
- walk_graph(package.dependents[i])
+ for i = 1, #package.dependents do
+ indent = indent + 1
+ walk_graph(package.dependents[i])
+ indent = indent - 1
+ end
end
- indent = indent - 1
- end
+ walk_graph(root)
- walk_graph(root)
- indent = 0
+ print()
+ print("Debug information:")
- print()
- print("Debug information:")
+ local debug = {}
+ for l in vim.inspect(packages):gmatch("[^\n]+") do
+ debug[#debug + 1] = l
+ end
- local lines = {}
- for l in vim.inspect(packages):gmatch("[^\n]+") do
- lines[#lines + 1] = l
- end
- vim.api.nvim_buf_set_lines(buffer, line, -1, false, lines)
+ vim.api.nvim_buf_set_lines(buffer, line, -1, false, debug)
+ vim.api.nvim_buf_set_name(buffer, "packages.dep")
+ vim.api.nvim_buf_set_option(buffer, "bufhidden", "wipe")
+ vim.api.nvim_buf_set_option(buffer, "modifiable", false)
- vim.api.nvim_buf_set_name(buffer, "packages.dep")
- vim.api.nvim_buf_set_option(buffer, "bufhidden", "wipe")
- vim.api.nvim_buf_set_option(buffer, "modifiable", false)
+ vim.cmd("sp")
+ vim.api.nvim_win_set_buf(0, buffer)
- vim.cmd("sp")
- vim.api.nvim_win_set_buf(0, buffer)
+ if cb then
+ cb()
+ end
+ end)
end
vim.cmd([[
@@ -709,15 +810,19 @@ return setmetatable({
end),
}, {
__call = function(self, config)
+ perf = {}
config_path = debug.getinfo(2, "S").source:sub(2)
initialized, err = pcall(function()
base_dir = config.base_dir or (vim.fn.stdpath("data") .. "/site/pack/deps/opt/")
packages = {}
- root = register("chiyadev/dep")
- register_recursive(config)
- sort_dependencies()
- ensure_acyclic()
+ bench("load", function()
+ root = register("chiyadev/dep")
+ register_recursive(config)
+ sort_dependencies()
+ ensure_acyclic()
+ end)
+
reload()
local should_sync = function(package)