2025-08-21 01:57:32 -07:00
|
|
|
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 = {
|
2025-08-21 02:43:32 -07:00
|
|
|
{ #unsaved .. " Unsaved Buffer" .. (#unsaved ~= 1 and "s" or "") .. "!", "ErrorMsg" },
|
2025-08-21 01:57:32 -07:00
|
|
|
},
|
|
|
|
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" })
|