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