93 lines
2.7 KiB
Lua
93 lines
2.7 KiB
Lua
local wezterm = require("wezterm")
|
|
local State = require("state")
|
|
|
|
local M = {}
|
|
|
|
--- Retry a shell command up to `retries` times with delay between attempts.
|
|
-- @param cmd table: command and arguments
|
|
-- @param retries number: number of attempts
|
|
-- @param delay_ms number: delay in milliseconds between attempts
|
|
-- @return boolean, string|nil: success status and output
|
|
function M.retry_command(cmd, retries, delay_ms)
|
|
for a = 1, retries do
|
|
local ok, out = wezterm.run_child_process(cmd)
|
|
if ok then
|
|
return true, out
|
|
end
|
|
if a < retries then
|
|
wezterm.log_error(("Retrying: %s (Attempt %d/%d)"):format(table.concat(cmd, " "), a, retries))
|
|
wezterm.sleep_ms(delay_ms)
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
--- Calculate a basic checksum from a list of items (based on `id` string).
|
|
-- Used for detecting changes in project listings.
|
|
-- @param list table: list of tables with `id` field
|
|
-- @return string: 8-digit hex checksum
|
|
function M.checksum(list)
|
|
local h = 0
|
|
for _, v in ipairs(list) do
|
|
for i = 1, #v.id do
|
|
h = (h * 31 + v.id:byte(i)) & 0xFFFFFFFF
|
|
end
|
|
end
|
|
return ("%08x"):format(h)
|
|
end
|
|
|
|
--- Return platform-specific exclude flags for `fd` or PowerShell.
|
|
-- Memoized to avoid rebuilding each call.
|
|
-- @return table: list of flags for file search
|
|
function M.get_exclude_flags()
|
|
if State._exclude_flags then
|
|
return State._exclude_flags
|
|
end
|
|
local flags = {}
|
|
for _, d in ipairs(State.exclude_dirs) do
|
|
table.insert(flags, State.is_windows and "-Exclude" or "--exclude")
|
|
table.insert(flags, d)
|
|
end
|
|
State._exclude_flags = flags
|
|
return flags
|
|
end
|
|
|
|
--- Return max-depth flags for `fd` and `find`.
|
|
-- @param req number|nil: requested depth, or fallback to default
|
|
-- @return table, table: fd-style flags, find-style flags
|
|
function M.depth_flags(req)
|
|
if req == -1 then
|
|
-- Unlimited depth
|
|
return {}, {}
|
|
end
|
|
local d = req or State.DEFAULT_DEPTH
|
|
return { "--max-depth", tostring(d) }, { "-maxdepth", tostring(d) }
|
|
end
|
|
|
|
--- Return the final component (basename) of a path.
|
|
-- Works on both `/` and `\` for cross-platform support.
|
|
-- @param path string: full path
|
|
-- @return string: base directory or file name
|
|
function M.basename(path)
|
|
return path:match("([^/\\]+)[/\\]*$") or path
|
|
end
|
|
|
|
--- Build a list of prune flags for use in a `find` command.
|
|
-- These exclude specific subdirectories during traversal.
|
|
-- @param base string: base path
|
|
-- @param dirs table: list of directory names to exclude
|
|
-- @return table: list of flags for `find`
|
|
function M.build_prune_flags(base, dirs)
|
|
local flags = {}
|
|
for _, d in ipairs(dirs or {}) do
|
|
table.insert(flags, "(")
|
|
table.insert(flags, "-path")
|
|
table.insert(flags, base .. "/" .. d)
|
|
table.insert(flags, "-prune")
|
|
table.insert(flags, ")")
|
|
table.insert(flags, "-o")
|
|
end
|
|
return flags
|
|
end
|
|
|
|
return M
|