mirror of
https://github.com/taigrr/glaze.nvim.git
synced 2026-04-02 03:09:10 -07:00
- auto_install (default: true) — install missing binaries on register - auto_check (default: true) — check for available updates periodically - auto_update (default: false) — auto-update when newer versions found - Disabling auto_check also disables auto_update - Updated README and help docs
267 lines
6.9 KiB
Lua
267 lines
6.9 KiB
Lua
---@brief [[
|
|
--- glaze.nvim - Centralized Go binary management for Neovim plugins
|
|
---
|
|
--- A Mason/Lazy-style interface for managing Go binaries across multiple plugins.
|
|
--- Register your plugin's binaries once, update them all with a single command.
|
|
---
|
|
--- Usage:
|
|
--- require("glaze").setup({})
|
|
--- require("glaze").register("freeze", "github.com/charmbracelet/freeze")
|
|
--- require("glaze").register("glow", "github.com/charmbracelet/glow")
|
|
---@brief ]]
|
|
|
|
local M = {}
|
|
|
|
---@class GlazeBinary
|
|
---@field name string Binary name (executable name)
|
|
---@field url string Go module URL (without @version)
|
|
---@field plugin? string Plugin that registered this binary
|
|
---@field callback? fun(success: boolean) Optional callback after install/update
|
|
|
|
---@class GlazeAutoCheckConfig
|
|
---@field enabled boolean Whether to auto-check for updates
|
|
---@field frequency string|number Frequency: "daily", "weekly", or hours as number
|
|
|
|
---@class GlazeAutoInstallConfig
|
|
---@field enabled boolean Whether to auto-install missing binaries on register
|
|
---@field silent boolean Suppress notifications during auto-install
|
|
|
|
---@class GlazeAutoUpdateConfig
|
|
---@field enabled boolean Whether to auto-update binaries when newer versions are found (requires auto_check)
|
|
|
|
---@class GlazeConfig
|
|
---@field ui GlazeUIConfig
|
|
---@field concurrency number Max parallel installations
|
|
---@field go_cmd string[] Go command (supports goenv)
|
|
---@field auto_install GlazeAutoInstallConfig
|
|
---@field auto_check GlazeAutoCheckConfig
|
|
---@field auto_update GlazeAutoUpdateConfig
|
|
|
|
---@class GlazeUIConfig
|
|
---@field border string Border style
|
|
---@field size { width: number, height: number }
|
|
---@field icons GlazeIcons
|
|
|
|
---@class GlazeIcons
|
|
---@field pending string
|
|
---@field running string
|
|
---@field done string
|
|
---@field error string
|
|
---@field binary string
|
|
|
|
---@type GlazeConfig
|
|
M.config = {
|
|
ui = {
|
|
border = "rounded",
|
|
size = { width = 0.7, height = 0.8 },
|
|
icons = {
|
|
pending = "○",
|
|
running = "◐",
|
|
done = "●",
|
|
error = "✗",
|
|
binary = "",
|
|
},
|
|
},
|
|
concurrency = 4,
|
|
go_cmd = { "go" },
|
|
auto_install = {
|
|
enabled = true,
|
|
silent = false,
|
|
},
|
|
auto_check = {
|
|
enabled = true,
|
|
frequency = "daily",
|
|
},
|
|
auto_update = {
|
|
enabled = false,
|
|
},
|
|
}
|
|
|
|
---@type table<string, GlazeBinary>
|
|
M._binaries = {}
|
|
|
|
---@type number?
|
|
M._ns = nil
|
|
|
|
---@param opts? GlazeConfig
|
|
function M.setup(opts)
|
|
M.config = vim.tbl_deep_extend("force", M.config, opts or {})
|
|
M._ns = vim.api.nvim_create_namespace("glaze")
|
|
|
|
-- Auto-detect goenv
|
|
if vim.fn.executable("goenv") == 1 then
|
|
M.config.go_cmd = { "goenv", "exec", "go" }
|
|
end
|
|
|
|
-- Create commands
|
|
vim.api.nvim_create_user_command("Glaze", function()
|
|
require("glaze.view").open()
|
|
end, { desc = "Open Glaze UI" })
|
|
|
|
vim.api.nvim_create_user_command("GlazeUpdate", function(cmd)
|
|
if cmd.args and cmd.args ~= "" then
|
|
require("glaze.runner").update({ cmd.args })
|
|
else
|
|
require("glaze.runner").update_all()
|
|
end
|
|
end, {
|
|
desc = "Update Go binaries",
|
|
nargs = "?",
|
|
complete = function()
|
|
return vim.tbl_keys(M._binaries)
|
|
end,
|
|
})
|
|
|
|
vim.api.nvim_create_user_command("GlazeInstall", function(cmd)
|
|
if cmd.args and cmd.args ~= "" then
|
|
require("glaze.runner").install({ cmd.args })
|
|
else
|
|
require("glaze.runner").install_missing()
|
|
end
|
|
end, {
|
|
desc = "Install Go binaries",
|
|
nargs = "?",
|
|
complete = function()
|
|
return vim.tbl_keys(M._binaries)
|
|
end,
|
|
})
|
|
|
|
vim.api.nvim_create_user_command("GlazeCheck", function()
|
|
require("glaze.checker").check()
|
|
end, { desc = "Check for binary updates" })
|
|
|
|
-- Auto-check for updates
|
|
if M.config.auto_check.enabled then
|
|
vim.defer_fn(function()
|
|
require("glaze.checker").auto_check()
|
|
end, 3000)
|
|
end
|
|
end
|
|
|
|
---Register a binary for management.
|
|
---If auto_install is enabled and the binary is missing, it will be installed automatically.
|
|
---@param name string Binary/executable name
|
|
---@param url string Go module URL (e.g., "github.com/charmbracelet/freeze")
|
|
---@param opts? { plugin?: string, callback?: fun(success: boolean) }
|
|
function M.register(name, url, opts)
|
|
opts = opts or {}
|
|
M._binaries[name] = {
|
|
name = name,
|
|
url = url,
|
|
plugin = opts.plugin,
|
|
callback = opts.callback,
|
|
}
|
|
|
|
-- Auto-install if enabled and binary is missing
|
|
if M.config.auto_install.enabled and not M.is_installed(name) then
|
|
vim.defer_fn(function()
|
|
if not M.is_installed(name) then
|
|
if not M.config.auto_install.silent then
|
|
vim.notify("[glaze] Auto-installing " .. name .. "…", vim.log.levels.INFO)
|
|
end
|
|
require("glaze.runner").install({ name })
|
|
end
|
|
end, 100)
|
|
end
|
|
end
|
|
|
|
---Unregister a binary.
|
|
---@param name string Binary name to unregister
|
|
function M.unregister(name)
|
|
M._binaries[name] = nil
|
|
end
|
|
|
|
---Get all registered binaries.
|
|
---@return table<string, GlazeBinary>
|
|
function M.binaries()
|
|
return M._binaries
|
|
end
|
|
|
|
---Check if a binary is installed.
|
|
---Checks PATH, $GOBIN, $GOPATH/bin, and $(go env GOBIN).
|
|
---@param name string Binary name
|
|
---@return boolean
|
|
function M.is_installed(name)
|
|
-- Check PATH first
|
|
if vim.fn.executable(name) == 1 then
|
|
return true
|
|
end
|
|
|
|
-- Check $GOBIN
|
|
local gobin = os.getenv("GOBIN")
|
|
if gobin and gobin ~= "" then
|
|
local path = gobin .. "/" .. name
|
|
if vim.uv.fs_stat(path) then
|
|
return true
|
|
end
|
|
end
|
|
|
|
-- Check $GOPATH/bin
|
|
local gopath = os.getenv("GOPATH")
|
|
if gopath and gopath ~= "" then
|
|
local path = gopath .. "/bin/" .. name
|
|
if vim.uv.fs_stat(path) then
|
|
return true
|
|
end
|
|
end
|
|
|
|
-- Check default ~/go/bin
|
|
local home = os.getenv("HOME") or os.getenv("USERPROFILE") or ""
|
|
local default_path = home .. "/go/bin/" .. name
|
|
if vim.uv.fs_stat(default_path) then
|
|
return true
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
---Get the install path for a binary if found.
|
|
---@param name string Binary name
|
|
---@return string? path Full path to the binary, or nil
|
|
function M.bin_path(name)
|
|
-- Check PATH
|
|
local which = vim.fn.exepath(name)
|
|
if which ~= "" then
|
|
return which
|
|
end
|
|
|
|
-- Check $GOBIN
|
|
local gobin = os.getenv("GOBIN")
|
|
if gobin and gobin ~= "" then
|
|
local path = gobin .. "/" .. name
|
|
if vim.uv.fs_stat(path) then
|
|
return path
|
|
end
|
|
end
|
|
|
|
-- Check $GOPATH/bin
|
|
local gopath = os.getenv("GOPATH")
|
|
if gopath and gopath ~= "" then
|
|
local path = gopath .. "/bin/" .. name
|
|
if vim.uv.fs_stat(path) then
|
|
return path
|
|
end
|
|
end
|
|
|
|
-- Check default ~/go/bin
|
|
local home = os.getenv("HOME") or os.getenv("USERPROFILE") or ""
|
|
local default_path = home .. "/go/bin/" .. name
|
|
if vim.uv.fs_stat(default_path) then
|
|
return default_path
|
|
end
|
|
|
|
return nil
|
|
end
|
|
|
|
---Get binary installation status.
|
|
---@param name string Binary name
|
|
---@return "installed"|"missing"|"unknown"
|
|
function M.status(name)
|
|
if not M._binaries[name] then
|
|
return "unknown"
|
|
end
|
|
return M.is_installed(name) and "installed" or "missing"
|
|
end
|
|
|
|
return M
|