config/modules/neovim/commands/SmartQuit.lua

97 lines
2.7 KiB
Lua
Raw Normal View History

vim.api.nvim_create_user_command("SmartQuit", function(opts)
-- scan all buffers for unsaved buffers
local unsaved = {}
local saved = {}
for _, buf in ipairs(vim.api.nvim_list_bufs()) do
if vim.api.nvim_buf_is_loaded(buf) and vim.api.nvim_buf_get_option(buf, "buflisted") then
if vim.api.nvim_buf_get_option(buf, "modified") then
table.insert(unsaved, buf)
else
table.insert(saved, buf)
end
end
end
if #unsaved == 0 then
vim.cmd("qa")
return
end
-- gui for resolving unsaved files
local lines = {}
for _, buf in ipairs(unsaved) do
local full_path = vim.api.nvim_buf_get_name(buf)
local name = full_path == "" and ("[No Name] #" .. buf) or vim.fn.fnamemodify(full_path, ":~:.")
table.insert(lines, "" .. name)
end
table.insert(lines, "")
table.insert(lines, " s - Save all and quit")
table.insert(lines, " c - Close saved; leave unsaved open")
table.insert(lines, " d - DISCARD ALL")
local buf = vim.api.nvim_create_buf(false, true)
vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines)
vim.api.nvim_buf_set_option(buf, "readonly", true)
local width = math.max(unpack(vim.tbl_map(function(l) return #l end, lines)))
local height = #lines
local win = vim.api.nvim_open_win(buf, true, {
relative = "editor",
width = width + 1,
height = height,
row = (vim.o.lines - height) / 2 - 1,
col = (vim.o.columns - width) / 2,
style = "minimal",
border = "rounded",
title = {
{ #unsaved .. " Unsaved Buffer" .. (#unsaved != 1 and "s" or "") .. "!", "ErrorMsg" },
},
title_pos = "center",
})
vim.wo[win].winhighlight = "Normal:Normal,FloatBorder:ErrorMsg"
vim.api.nvim_win_set_option(win, "cursorline", false)
local hl = vim.api.nvim_get_hl_by_name('Cursor', true)
hl.blend = 100
vim.api.nvim_set_hl(0, 'Cursor', hl)
vim.opt.guicursor:append('a:Cursor/lCursor')
function close()
local hl = vim.api.nvim_get_hl_by_name('Cursor', true)
hl.blend = 0
vim.api.nvim_set_hl(0, 'Cursor', hl)
vim.opt.guicursor:remove('a:Cursor/lCursor')
vim.api.nvim_win_close(win, true)
end
-- keyboard event handlers
vim.keymap.set("n", "s", function()
for _, buf in ipairs(unsaved) do
vim.api.nvim_buf_call(buf, function()
vim.cmd("write")
end)
end
close()
vim.cmd("qa")
end, { buffer = buf })
vim.keymap.set("n", "c", function()
for _, buf in ipairs(saved) do
vim.api.nvim_buf_delete(buf, {})
end
close()
end, { buffer = buf })
vim.keymap.set("n", "d", function()
vim.cmd("qa!")
end, { buffer = buf })
vim.keymap.set("n", "<esc>", function()
close()
end, { buffer = buf })
vim.api.nvim_create_autocmd({ 'WinLeave' }, {
buffer = buf,
callback = close,
})
end, { nargs = 0 })
vim.api.nvim_set_hl(0, "QuitPopUpBorder", { fg = "red" })