Skip to content

Commit

Permalink
feat(disable): warns with better ux when trying to leave (#364)
Browse files Browse the repository at this point in the history
## 📃 Summary

closes #363
closes #358
  • Loading branch information
shortcuts committed May 26, 2024
1 parent 37ce637 commit 0c19c54
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 15 deletions.
49 changes: 37 additions & 12 deletions lua/no-neck-pain/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ function N.enable(scope)
then
D.log(s, "one of the NNP side has been closed")

return N.disable(p.event)
return N.disable(s)
end

if S.isSideWinValid(S, "curr") then
Expand All @@ -269,7 +269,7 @@ function N.enable(scope)
if p.event == "QuitPre" then
D.log(s, "curr has been closed")

return N.disable(p.event)
return N.disable(s)
end

D.log(s, "`curr` has been deleted, resetting state")
Expand Down Expand Up @@ -425,11 +425,45 @@ end
function N.disable(scope)
D.log(scope, "calling disable for tab %d", S.activeTab)

local activeTab = S.activeTab

local wins = vim.tbl_filter(function(win)
return win ~= S.getSideID(S, "left")
and win ~= S.getSideID(S, "right")
and not A.isRelativeWindow(win)
end, vim.api.nvim_tabpage_list_wins(activeTab))

if #wins == 0 then
for name, modified in pairs(A.getOpenedBuffers()) do
if modified then
local bufname = name
if vim.startswith(name, "NoNamePain") then
bufname = string.sub(name, 11)
end

vim.schedule(function()
vim.notify(
"[no-neck-pain.nvim] unable to quit nvim because one or more buffer has modified files, please save or discard changes",
vim.log.levels.ERROR
)
vim.cmd("rightbelow vertical split")
vim.cmd("buffer " .. bufname)
N.init(scope)
end)
return
end
end

pcall(vim.api.nvim_del_augroup_by_name, A.getAugroupName(S.activeTab))
pcall(vim.api.nvim_del_augroup_by_name, "NoNeckPainVimEnterAutocmd")

return vim.cmd("quitall!")
end

pcall(vim.api.nvim_del_augroup_by_name, A.getAugroupName(S.activeTab))

local sides = { left = S.getSideID(S, "left"), right = S.getSideID(S, "right") }
local currID = S.getSideID(S, "curr")
local activeTab = S.activeTab

if S.refreshTabs(S) == 0 then
pcall(vim.api.nvim_del_augroup_by_name, "NoNeckPainVimEnterAutocmd")
Expand All @@ -441,15 +475,6 @@ function N.disable(scope)

for side, id in pairs(sides) do
if vim.api.nvim_win_is_valid(id) then
local wins = vim.tbl_filter(function(win)
return win ~= id and not A.isRelativeWindow(win)
-- return win ~= id
end, vim.api.nvim_tabpage_list_wins(activeTab))

if #wins == 0 then
return vim.cmd("quit")
end

S.removeNamespace(S, vim.api.nvim_win_get_buf(id), side)
W.close(scope, id, side)
end
Expand Down
22 changes: 22 additions & 0 deletions lua/no-neck-pain/util/api.lua
Original file line number Diff line number Diff line change
Expand Up @@ -151,4 +151,26 @@ function A.debounce(context, callback, timeout)
end)
end

---Returns a map of opened buffer name with a boolean indicating if they are modified or not.
---
---@return table
---@private
function A.getOpenedBuffers()
local opened = {}

for _, buf in ipairs(vim.api.nvim_list_bufs()) do
if vim.fn.buflisted(buf) ~= 0 then
local name = vim.api.nvim_buf_get_name(buf)

if name == nil or name == "" then
name = string.format("NoNamePain%s", buf)
end

opened[name] = vim.api.nvim_buf_get_option(buf, "modified")
end
end

return opened
end

return A
32 changes: 29 additions & 3 deletions tests/test_API.lua
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ T["disable"]["(multiple tab) resets state"] = function()
Helpers.expect.state(child, "tabs", vim.NIL)
end

T["disable"]["does not close the window if unsaved buffer"] = function()
T["disable"]["(no file) does not close the window if unsaved buffer"] = function()
child.set_size(500, 500)
child.lua([[ require('no-neck-pain').setup({width=50}) ]])
Helpers.toggle(child)
Expand All @@ -376,13 +376,39 @@ T["disable"]["does not close the window if unsaved buffer"] = function()
Helpers.expect.equality(Helpers.listBuffers(child), { 1, 2, 3 })

child.api.nvim_buf_set_lines(1, 0, 1, false, { "foo" })
Helpers.expect.equality(child.lua_get("vim.api.nvim_buf_get_option(1, 'modified')"), true)

Helpers.expect.equality(Helpers.winsInTab(child), { 1001, 1000, 1002 })
Helpers.expect.equality(child.lua_get("vim.api.nvim_get_current_win()"), 1000)

child.cmd("quit")

Helpers.expect.equality(child.is_running(), true)
end

T["disable"]["(on file) does not close the window if unsaved buffer"] = function()
child.set_size(500, 500)
child.restart({ "-u", "scripts/minimal_init.lua", "lua/no-neck-pain/main.lua" })
child.lua([[ require('no-neck-pain').setup({width=50}) ]])
Helpers.toggle(child)

Helpers.expect.state(child, "enabled", true)
Helpers.expect.state(child, "tabs[1].wins.main", {
curr = 1000,
left = 1001,
right = 1002,
})
Helpers.expect.equality(Helpers.listBuffers(child), { 1, 2, 3 })

child.api.nvim_buf_set_lines(1, 0, 1, false, { "foo" })
Helpers.expect.equality(child.lua_get("vim.api.nvim_buf_get_option(1, 'modified')"), true)

Helpers.expect.equality(Helpers.winsInTab(child), { 1001, 1000, 1002 })
Helpers.expect.equality(child.lua_get("vim.api.nvim_get_current_win()"), 1000)

child.cmd("quit")

-- error because e37 requires confirmation
Helpers.expect.equality(child.is_blocked(), true)
Helpers.expect.equality(child.is_running(), true)
end

T["disable"]["relative window doesn't prevent quitting nvim"] = function()
Expand Down

0 comments on commit 0c19c54

Please sign in to comment.