lazy.nvim/lua/lazy/util.lua

249 lines
5.6 KiB
Lua
Raw Permalink Normal View History

---@class LazyUtil: LazyUtilCore
2022-11-24 21:03:00 +00:00
local M = setmetatable({}, { __index = require("lazy.core.util") })
function M.file_exists(file)
return vim.loop.fs_stat(file) ~= nil
end
---@param opts? LazyFloatOptions
2022-12-24 10:26:29 +00:00
function M.float(opts)
return require("lazy.view.float")(opts)
2022-12-24 10:26:29 +00:00
end
function M.wo(win, k, v)
if vim.api.nvim_set_option_value then
vim.api.nvim_set_option_value(k, v, { scope = "local", win = win })
else
vim.wo[win][k] = v
end
end
2022-11-24 21:03:00 +00:00
function M.open(uri)
if M.file_exists(uri) then
return M.float({ style = "", file = uri })
2022-11-24 21:03:00 +00:00
end
local Config = require("lazy.core.config")
2022-11-24 21:03:00 +00:00
local cmd
if Config.options.ui.browser then
cmd = { Config.options.ui.browser, uri }
elseif vim.fn.has("win32") == 1 then
cmd = { "explorer", uri }
2022-11-24 21:03:00 +00:00
elseif vim.fn.has("macunix") == 1 then
cmd = { "open", uri }
else
if vim.fn.executable("xdg-open") == 1 then
cmd = { "xdg-open", uri }
elseif vim.fn.executable("wslview") == 1 then
cmd = { "wslview", uri }
else
cmd = { "open", uri }
end
2022-11-24 21:03:00 +00:00
end
local ret = vim.fn.jobstart(cmd, { detach = true })
if ret <= 0 then
2022-11-24 21:03:00 +00:00
local msg = {
"Failed to open uri",
ret,
vim.inspect(cmd),
}
vim.notify(table.concat(msg, "\n"), vim.log.levels.ERROR)
end
end
function M.read_file(file)
local fd = assert(io.open(file, "r"))
---@type string
local data = fd:read("*a")
fd:close()
return data
end
function M.write_file(file, contents)
local fd = assert(io.open(file, "w+"))
fd:write(contents)
fd:close()
end
2022-12-23 09:18:19 +00:00
---@generic F: fun()
2022-11-24 21:03:00 +00:00
---@param ms number
2022-12-23 09:18:19 +00:00
---@param fn F
---@return F
2022-11-24 21:03:00 +00:00
function M.throttle(ms, fn)
local timer = vim.loop.new_timer()
local running = false
local first = true
2022-12-23 09:18:19 +00:00
return function(...)
local args = { ... }
local wrapped = function()
fn(unpack(args))
end
2022-11-24 21:03:00 +00:00
if not running then
if first then
2022-12-23 09:18:19 +00:00
wrapped()
2022-11-24 21:03:00 +00:00
first = false
end
timer:start(ms, 0, function()
running = false
2022-12-23 09:18:19 +00:00
vim.schedule(wrapped)
2022-11-24 21:03:00 +00:00
end)
running = true
end
end
end
---@class LazyCmdOptions: LazyFloatOptions
---@field cwd? string
---@field env? table<string,string>
---@field float? LazyFloatOptions
-- Opens a floating terminal (interactive by default)
---@param cmd? string[]|string
---@param opts? LazyCmdOptions|{interactive?:boolean}
function M.float_term(cmd, opts)
cmd = cmd or {}
if type(cmd) == "string" then
cmd = { cmd }
end
if #cmd == 0 then
2023-04-23 14:59:31 +01:00
cmd = { vim.o.shell }
end
opts = opts or {}
local float = M.float(opts)
vim.fn.termopen(cmd, vim.tbl_isempty(opts) and vim.empty_dict() or opts)
if opts.interactive ~= false then
vim.cmd.startinsert()
vim.api.nvim_create_autocmd("TermClose", {
once = true,
buffer = float.buf,
callback = function()
float:close({ wipe = true })
vim.cmd.checktime()
end,
})
end
return float
end
--- Runs the command and shows it in a floating window
---@param cmd string[]
---@param opts? LazyCmdOptions|{filetype?:string}
function M.float_cmd(cmd, opts)
opts = opts or {}
local float = M.float(opts)
if opts.filetype then
vim.bo[float.buf].filetype = opts.filetype
end
local Process = require("lazy.manage.process")
local lines = Process.exec(cmd, { cwd = opts.cwd })
vim.api.nvim_buf_set_lines(float.buf, 0, -1, false, lines)
vim.bo[float.buf].modifiable = false
return float
end
---@deprecated use float_term or float_cmd instead
function M.open_cmd()
M.warn([[`require("lazy.util").open_cmd()` is deprecated. Please use `float_term` instead. Check the docs]])
end
2022-11-24 21:03:00 +00:00
---@return string?
function M.head(file)
local f = io.open(file)
if f then
local ret = f:read()
f:close()
return ret
end
end
---@return {branch: string, hash:string}?
function M.git_info(dir)
local line = M.head(dir .. "/.git/HEAD")
if line then
---@type string, string
local ref, branch = line:match("ref: (refs/heads/(.*))")
if ref then
return {
branch = branch,
hash = M.head(dir .. "/.git/" .. ref),
}
end
end
end
---@param msg string|string[]
---@param opts? table
function M.markdown(msg, opts)
if type(msg) == "table" then
msg = table.concat(msg, "\n") or msg
end
vim.notify(
msg,
vim.log.levels.INFO,
vim.tbl_deep_extend("force", {
title = "lazy.nvim",
on_open = function(win)
M.wo(win, "conceallevel", 3)
M.wo(win, "concealcursor", "n")
M.wo(win, "spell", false)
2022-11-24 21:03:00 +00:00
vim.treesitter.start(vim.api.nvim_win_get_buf(win), "markdown")
end,
}, opts or {})
)
end
function M._dump(value, result)
local t = type(value)
if t == "number" or t == "boolean" then
table.insert(result, tostring(value))
elseif t == "string" then
table.insert(result, ("%q"):format(value))
elseif t == "table" then
table.insert(result, "{")
local i = 1
---@diagnostic disable-next-line: no-unknown
for k, v in pairs(value) do
if k == i then
elseif type(k) == "string" then
table.insert(result, ("[%q]="):format(k))
else
table.insert(result, k .. "=")
end
M._dump(v, result)
table.insert(result, ",")
i = i + 1
end
table.insert(result, "}")
else
error("Unsupported type " .. t)
end
end
function M.dump(value)
local result = {}
M._dump(value, result)
return table.concat(result, "")
end
2022-12-05 13:46:11 +00:00
---@generic V
---@param t table<string, V>
---@param fn fun(key:string, value:V)
function M.foreach(t, fn)
---@type string[]
local keys = vim.tbl_keys(t)
pcall(table.sort, keys, function(a, b)
return a:lower() < b:lower()
end)
2022-12-05 13:46:11 +00:00
for _, key in ipairs(keys) do
fn(key, t[key])
end
end
2022-11-24 21:03:00 +00:00
return M