Files
cave.nvim/lua/cave/util.lua
2024-10-02 14:58:20 +02:00

85 lines
2.4 KiB
Lua

local Path = require "cave.path"
local Meta = require "cave.meta"
local buffers = require "astrocore.buffer"
local Table = Meta.Table
local validate = Meta.validate
local List = Meta.List
local Str = Meta.String
local Util = {}
---@param old table
---@param new table
---@return table
function Util.tbl_diff(old, new)
validate { old = { old, Table }, new = { new, Table } }
local diff = {
added = {},
removed = {},
modified = {},
}
for old_name, old_value in pairs(old) do
local new_value = new[old_name]
if new_value == nil then
diff.removed[old_name] = old_value
elseif type(old_value) ~= type(new_value) or old_value ~= new_value then
diff.modified[old_name] = { old = old_value, new = new_value }
end
end
for new_name, new_value in pairs(new) do
local old_value = old[new_name]
if old_value == nil then
diff.added[new_name] = new_value
elseif type(old_value) ~= type(new_value) or old_value ~= new_value then
assert(diff.modified[new_name].old == old_value and diff.modified[new_name].new == new_value)
end
end
return diff
end
function Util.save_all_buffers()
for _, buf in ipairs(vim.t.bufs) do
local buf_valid = buffers.is_valid(buf)
local buf_modified = vim.api.nvim_buf_get_option(buf, "modified")
if not buf_valid or not buf_modified then goto continue end
local buf_name = vim.fn.fnamemodify(vim.api.nvim_buf_get_name(buf), "%")
if buf_name == "" then goto continue end
local confirm = vim.fn.confirm(('Save changes to "%s"?'):format(buf_name), "&Yes\n&No", 1, "Question")
if confirm == 1 then vim.api.nvim_buf_call(buf, vim.cmd.write) end
::continue::
end
end
function Util.close_all_buffers() buffers.close_all() end
---@return string
function Util.generate_uuid()
local uuidgen_path = Path.new "uuidgen"
assert(uuidgen_path:is_executable())
local cmd = { tostring(uuidgen_path), "-t" }
local output = vim.fn.systemlist(cmd)
validate { output = { output, List(Str) } }
assert(#output == 1)
return output[1]
end
---@param t any
---@return any
function Util.plain(t)
if type(t) ~= "table" then return t end
local mt = getmetatable(t)
if mt ~= nil and (rawget(mt, "__tostring") ~= nil or rawget(mt, "__name") ~= nil) then
return tostring(t)
end
setmetatable(t, nil)
for key, value in pairs(t) do
t[key] = Util.plain(value)
end
return t
end
return Util