diff --git a/lua/config/autocmds.lua b/lua/config/autocmds.lua index 32e3dd4..98bca85 100644 --- a/lua/config/autocmds.lua +++ b/lua/config/autocmds.lua @@ -154,15 +154,6 @@ create_autocmd("BufRead", function(ev) end, { desc = "Make read-only files non-modifiable", group = augroup }) create_autocmd("VimEnter", function() - vim.system({ "curl", "-SsfL", "https://vtip.43z.one" }, nil, function(obj) - local res = obj.stdout - if obj.code ~= 0 then res = "Error fetching tip: " .. table.concat({ obj.stderr, obj.stdout }, "\n") end - vim.schedule(function() - vim.notify(res, vim.log.levels.INFO, { title = "In Case You Didn't Know!", timeout = 5000 }) - -- Add the tip to the cache file - local cache = vim.fn.stdpath("cache") --[[@as string]] - vim.fn.writefile({ res }, vim.fs.joinpath(cache, "vtip.log"), "a") - end) - end) + require("utils.vtip").fetch() return true end, { desc = "Fetch tips from vtip.43z.one", group = augroup }) diff --git a/lua/config/commands.lua b/lua/config/commands.lua index 47945e0..1b81c5a 100644 --- a/lua/config/commands.lua +++ b/lua/config/commands.lua @@ -58,3 +58,15 @@ vim.api.nvim_create_user_command("LspCapabilities", function() end, {}) vim.api.nvim_create_user_command("OrganizeImports", require("utils.organize_imports"), {}) + +vim.api.nvim_create_user_command("VTip", function() -- Show new vtip + return require("utils.vtip").fetch() +end, { desc = "Show VTip" }) + +vim.api.nvim_create_user_command("VTipClear", function() -- Clear vtip + return require("utils.vtip").clear() +end, { desc = "Clear VTip" }) + +vim.api.nvim_create_user_command("VTipHistory", function() -- Show vtip history + return require("utils.vtip").history() +end, { desc = "Show VTip history" }) diff --git a/lua/utils/vtip.lua b/lua/utils/vtip.lua new file mode 100644 index 0000000..bb54b36 --- /dev/null +++ b/lua/utils/vtip.lua @@ -0,0 +1,87 @@ +local cache = vim.fn.stdpath("cache") --[[@as string]] +local notifications = require("utils.notifications") +local M = { + file = vim.fs.joinpath(cache, "vtip.log"), + ---@param res string + notify = function(res) + return notifications.info(res, { + title = "In Case You Didn't Know!", + timeout = 5000, + }) + end, + ---@param err string + error = function(err) + return notifications.error(err, { + title = "Error fetching VTip", + timeout = 5000, + }) + end, + url = "https://vtip.43z.one", +} + +---Fetch a new VTip +---If callback is not provided, the VTip will be shown via vim.notify +---@param on_success? fun(res: string): any? +---@param on_error? fun(err: string): any? +function M.fetch(on_success, on_error) + on_success, on_error = on_success or M.notify, on_error or M.error + local ok = pcall(vim.system, { "curl", "-SsfL", M.url }, nil, function(obj) + if obj.code ~= 0 or obj.signal ~= 0 then + local err = table.concat({ obj.stderr, obj.stdout }, "\n") + return on_error(err) + end + local res = assert(obj.stdout, "No stdout from curl") -- this isn't possible + vim.schedule(function() -- Writefile has to be scheduled + local write_res = vim.split(res, "\n", { plain = true, trimempty = true }) -- writefile expects a list of lines + vim.fn.writefile(write_res, M.file, "a") -- Append the tip to the cache file + end) + return on_success(res) + end) + if ok then return end + return on_error("Could not spawn curl") +end + +--- Open a popup with the VTip history +function M.history() + --- Replace newlines with null bytes + local lines = vim.tbl_map(function(line) return line:gsub("\n", "\0") end, vim.fn.readfile(M.file)) + if #lines == 0 then return notifications.info("VTip history is empty") end + + local buf = vim.api.nvim_create_buf(false, true) + vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines) + vim.bo[buf].filetype = "vtip" + vim.bo[buf].modifiable = false + vim.bo[buf].bufhidden = "wipe" + vim.bo[buf].buftype = "nofile" + + local width = math.floor(vim.o.columns * 0.5) + local height = math.floor(vim.o.lines * 0.5) + local win = vim.api.nvim_open_win(buf, true, { + relative = "editor", + width = width, + height = height, + row = math.floor((vim.o.lines - height) / 2), + col = math.floor((vim.o.columns - width) / 2), + style = "minimal", + zindex = 50, + border = "single", + title = "VTip History", + title_pos = "center", + }) + vim.keymap.set("n", "q", function() -- Close the window when the user presses q + return vim.api.nvim_win_close(win, true) + end, { buffer = buf, nowait = true }) + + vim.api.nvim_win_set_buf(win, buf) +end + +--- Clear the VTip history +function M.clear() + local ok, err = vim.uv.fs_unlink(M.file) + if not ok and err then + local msg = "Could not delete VTip cache file: " .. err + return notifications.error(msg) + end +end + +return M