Skip to content

Commit

Permalink
fix(autocmds): buffer rerouting and with scratchPads (#322)
Browse files Browse the repository at this point in the history
## 📃 Summary

contributes to #306

- as per
#306 (comment)
listen to `WinLeave` instead of `WinEnter` in order to execute the
re-routing a bit earlier
- determine if we don't re-route to an other side buffer so that we
don't end up triggering the command twice
- do not register the autocmds if scratchPads are enabled
  • Loading branch information
shortcuts committed Mar 24, 2024
1 parent 4a07be6 commit c053da4
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 28 deletions.
56 changes: 31 additions & 25 deletions lua/no-neck-pain/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ function N.enable(scope)
local wins = S.getUnregisteredWins(S)

if #wins ~= 1 then
return D.log( p.event, "no new or too many unregistered windows")
return D.log(p.event, "no new or too many unregistered windows")
end

local focusedWin = wins[1]
Expand All @@ -230,12 +230,13 @@ function N.enable(scope)
vim.api.nvim_create_autocmd({ "QuitPre", "BufDelete" }, {
callback = function(p)
vim.schedule(function()
local s = string.format("%s:quit", p.event)
if E.skip(nil) or not S.isActiveTabRegistered(S) then
return
end

if S.hasSplits(S) then
return D.log(p.event, "skip quit logic: splits still active")
return D.log(s, "splits still active")
end

if
Expand All @@ -248,29 +249,29 @@ function N.enable(scope)
and not S.isSideWinValid(S, "curr")
)
then
D.log(p.event, "one of the NNP side has been closed, disabling...")
D.log(s, "one of the NNP side has been closed, disabling...")

return N.disable(p.event)
end

if S.isSideWinValid(S, "curr") then
D.log(p.event, "curr is still valid, skipping")
D.log(s, "curr is still valid, skipping")

return
end

-- if we still have a side valid but curr has been deleted (mostly because of a :bd),
-- we will fallback to the first valid side
if p.event == "QuitPre" then
D.log(p.event, "one of the NNP side has been closed, disabling...")
D.log(s, "one of the NNP side has been closed, disabling...")

return N.disable(p.event)
end

D.log(p.event, "`curr` has been deleted, resetting state")
D.log(s, "`curr` has been deleted, resetting state")

N.disable(string.format("%s:reset", p.event))
N.enable(string.format("%s:reset", p.event))
N.disable(string.format("%s:reset", s))
N.enable(string.format("%s:reset", s))
end)
end,
group = augroupName,
Expand Down Expand Up @@ -353,38 +354,43 @@ function N.enable(scope)
desc = "Resize to apply on WinEnter/Closed of an integration",
})

if _G.NoNeckPain.config.autocmds.skipEnteringNoNeckPainBuffer then
vim.api.nvim_create_autocmd({ "WinEnter" }, {
if
_G.NoNeckPain.config.autocmds.skipEnteringNoNeckPainBuffer and not S.hasScratchPadEnabled(S)
then
vim.api.nvim_create_autocmd({ "WinLeave" }, {
callback = function(p)
vim.schedule(function()
p.event = string.format("%s:skipEnteringNoNeckPainBuffer", p.event)
if
not S.hasTabs(S)
or not S.isActiveTabRegistered(S)
or E.skip()
then
if not S.hasTabs(S) or not S.isActiveTabRegistered(S) or E.skip() then
return D.log(p.event, "skip")
end

local currentWin = vim.api.nvim_get_current_win()
local leftID = S.getSideID(S, "left")
local rightID = S.getSideID(S, "right")

if
currentWin ~= S.getSideID(S, "left")
and currentWin ~= S.getSideID(S, "right")
then
if currentWin ~= leftID and currentWin ~= rightID then
return
end

local wins = vim.api.nvim_list_wins()

for i = 1, #wins do
if wins[i] ~= currentWin then
goto continue
local id = i == #wins and 1 or i + 1
if
wins[id] ~= currentWin
and wins[id] ~= leftID
and wins[id] ~= rightID
then
vim.fn.win_gotoid(wins[id])

return D.log(
p.event,
"rerouted focus of %d to %d",
currentWin,
wins[id]
)
end

vim.fn.win_gotoid(wins[i == #wins and 1 or i + 1])

::continue::
end
end)
end,
Expand Down
11 changes: 11 additions & 0 deletions lua/no-neck-pain/state.lua
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,17 @@ function State:getScratchpad()
return self.tabs[self.activeTab].scratchPadEnabled
end

---Whether the scratchPad feature is enabled or not.
---
---@return boolean: the config value of the scratchPad
---@private
function State:hasScratchPadEnabled()
return _G.NoNeckPain.config.buffers.scratchPad.enabled
or _G.NoNeckPain.config.buffers.left.scratchPad.enabled
or _G.NoNeckPain.config.buffers.right.scratchPad.enabled
or self.getScratchpad(self)
end

---Register a new `tab` with the given `id` in the state.
---
---@param id number: the id of the tab.
Expand Down
69 changes: 66 additions & 3 deletions tests/test_autocmds.lua
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,11 @@ T["auto command"]["does not shift when opening/closing float window"] = function
Helpers.expect.buf_width(child, "tabs[1].wins.main.left", 15)
Helpers.expect.buf_width(child, "tabs[1].wins.main.right", 15)

child.lua("vim.api.nvim_open_win(0,true, {width=100,height=100,relative='cursor',row=0,col=0})")
child.api.nvim_open_win(
0,
true,
{ width = 100, height = 100, relative = "cursor", row = 0, col = 0 }
)

Helpers.expect.equality(Helpers.winsInTab(child), { 1001, 1000, 1002, 1003 })
Helpers.expect.state(child, "tabs[1].wins.main", {
Expand All @@ -54,7 +58,7 @@ T["auto command"]["does not shift when opening/closing float window"] = function
Helpers.expect.buf_width(child, "tabs[1].wins.main.right", 15)

-- Close float window keeps the buffer here with the same width
child.lua("vim.fn.win_gotoid(1003)")
child.fn.win_gotoid(1003)
child.cmd("q")

Helpers.expect.equality(Helpers.winsInTab(child), { 1001, 1000, 1002 })
Expand All @@ -72,7 +76,9 @@ T["skipEnteringNoNeckPainBuffer"] = MiniTest.new_set()

T["skipEnteringNoNeckPainBuffer"]["goes to new valid buffer when entering side"] = function()
child.set_size(5, 200)
child.lua([[ require('no-neck-pain').setup({width=50, autocmds = { skipEnteringNoNeckPainBuffer = true }}) ]])
child.lua(
[[ require('no-neck-pain').setup({width=50, autocmds = { skipEnteringNoNeckPainBuffer = true }}) ]]
)
Helpers.toggle(child)

Helpers.expect.config(child, "autocmds.skipEnteringNoNeckPainBuffer", true)
Expand Down Expand Up @@ -110,4 +116,61 @@ T["skipEnteringNoNeckPainBuffer"]["goes to new valid buffer when entering side"]
Helpers.expect.equality(child.api.nvim_get_current_win(), 1003)
end

T["skipEnteringNoNeckPainBuffer"]["does not register if scratchPad feature is enabled (global)"] = function()
child.set_size(5, 200)
child.lua(
[[ require('no-neck-pain').setup({width=50, buffers = { scratchPad = { enabled = true } }, autocmds = { skipEnteringNoNeckPainBuffer = true }}) ]]
)
Helpers.toggle(child)

Helpers.expect.config(child, "buffers.scratchPad.enabled", true)
Helpers.expect.config(child, "autocmds.skipEnteringNoNeckPainBuffer", true)

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

child.fn.win_gotoid(1001)
Helpers.wait(child)
Helpers.expect.equality(child.api.nvim_get_current_win(), 1001)
end

T["skipEnteringNoNeckPainBuffer"]["does not register if scratchPad feature is enabled (left)"] = function()
child.set_size(5, 200)
child.lua(
[[ require('no-neck-pain').setup({width=50, buffers = { left = { scratchPad = { enabled = true } } }, autocmds = { skipEnteringNoNeckPainBuffer = true }}) ]]
)
Helpers.toggle(child)

Helpers.expect.config(child, "buffers.scratchPad.enabled", false)
Helpers.expect.config(child, "buffers.left.scratchPad.enabled", true)
Helpers.expect.config(child, "autocmds.skipEnteringNoNeckPainBuffer", true)

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

child.fn.win_gotoid(1001)
Helpers.wait(child)
Helpers.expect.equality(child.api.nvim_get_current_win(), 1001)
end

T["skipEnteringNoNeckPainBuffer"]["does not register if scratchPad feature is enabled (right)"] = function()
child.set_size(5, 200)
child.lua(
[[ require('no-neck-pain').setup({width=50, buffers = { right = { scratchPad = { enabled = true } } }, autocmds = { skipEnteringNoNeckPainBuffer = true }}) ]]
)
Helpers.toggle(child)

Helpers.expect.config(child, "buffers.scratchPad.enabled", false)
Helpers.expect.config(child, "buffers.left.scratchPad.enabled", false)
Helpers.expect.config(child, "buffers.right.scratchPad.enabled", true)
Helpers.expect.config(child, "autocmds.skipEnteringNoNeckPainBuffer", true)

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

child.fn.win_gotoid(1001)
Helpers.wait(child)
Helpers.expect.equality(child.api.nvim_get_current_win(), 1001)
end

return T

0 comments on commit c053da4

Please sign in to comment.