Skip to content

Commit

Permalink
feat: keeps side buffers for current tab (#150)
Browse files Browse the repository at this point in the history
## 📃 Summary

closes #89

This PR is a first step of the tabs support, it allows restoring the
state correctly when executing `tabprevious`, so the side buffers are
not closed.

State-per-tab will be followed in
#152
  • Loading branch information
shortcuts committed Jan 26, 2023
1 parent 230b034 commit e513dc3
Show file tree
Hide file tree
Showing 12 changed files with 257 additions and 58 deletions.
28 changes: 18 additions & 10 deletions lua/no-neck-pain/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ local E = require("no-neck-pain.util.event")
local M = require("no-neck-pain.util.map")
local W = require("no-neck-pain.util.win")
local T = require("no-neck-pain.util.trees")
local Ta = require("no-neck-pain.util.tabs")
local Sp = require("no-neck-pain.util.split")
local St = require("no-neck-pain.util.state")

Expand Down Expand Up @@ -33,11 +34,12 @@ local function init(scope, goToCurr)
hadSideBuffers = false
end

S.tabs = Ta.refresh(S.tabs)
-- before creating side buffers, we determine if we should consider externals
S.wins.external.trees = T.refresh()
S.wins.external.trees = T.refresh(S)
S.wins.main.left, S.wins.main.right = W.createSideBuffers(S.wins)
-- we might have closed trees during the buffer creation process, we re-fetch the latest IDs to prevent inconsistencies
S.wins.external.trees = T.refresh()
S.wins.external.trees = T.refresh(S)

if
goToCurr or (not hadSideBuffers and (S.wins.main.left ~= nil or S.wins.main.right ~= nil))
Expand All @@ -61,7 +63,7 @@ function N.enable()
vim.api.nvim_create_autocmd({ "VimResized" }, {
callback = function(p)
vim.schedule(function()
if E.skip(S, false) then
if E.skip(S, false, false) then
return
end

Expand All @@ -75,7 +77,7 @@ function N.enable()
vim.api.nvim_create_autocmd({ "WinEnter" }, {
callback = function(p)
vim.schedule(function()
if E.skip(S, false) then
if E.skip(S, false, true) then
return
end

Expand Down Expand Up @@ -118,7 +120,7 @@ function N.enable()
vim.api.nvim_create_autocmd({ "QuitPre", "BufDelete" }, {
callback = function(p)
vim.schedule(function()
if E.skip(nil, false) then
if E.skip(nil, false, true) then
return
end

Expand Down Expand Up @@ -146,13 +148,17 @@ function N.enable()
end)
end,
group = "NoNeckPain",
desc = "Handles the closure of main NNP windows and restoring the state correctly",
desc = "Handles the closure of main NNP windows",
})

vim.api.nvim_create_autocmd({ "WinClosed", "BufDelete" }, {
callback = function(p)
vim.schedule(function()
if E.skip(nil, false) or S.wins.splits == nil or W.stateWinsActive(S, true) then
if
E.skip(nil, false, true)
or S.wins.splits == nil
or W.stateWinsActive(S, true)
then
return
end

Expand Down Expand Up @@ -180,7 +186,7 @@ function N.enable()
vim.api.nvim_create_autocmd({ "WinEnter", "WinClosed" }, {
callback = function(p)
vim.schedule(function()
if E.skip(S, true) then
if E.skip(S, true, false) then
return
end

Expand All @@ -191,7 +197,7 @@ function N.enable()
return
end

local trees = T.refresh()
local trees = T.refresh(S)

-- we cycle over supported integrations to see which got closed or opened
for name, tree in pairs(S.wins.external.trees) do
Expand Down Expand Up @@ -247,11 +253,13 @@ function N.disable(scope)
end
end

-- determine if we should quit vim or just close the window
for _, side in pairs(W.SIDES) do
if S.wins.main[side] ~= nil then
local activeWins = vim.api.nvim_list_wins()
local activeWins = vim.api.nvim_tabpage_list_wins(S.tabs)
local haveOtherWins = false

-- if we have other wins active and usable, we won't quit vim
for _, activeWin in pairs(activeWins) do
if S.wins.main[side] ~= activeWin and not W.isRelativeWindow(activeWin) then
haveOtherWins = true
Expand Down
9 changes: 8 additions & 1 deletion lua/no-neck-pain/util/event.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
local W = require("no-neck-pain.util.win")
local Ta = require("no-neck-pain.util.tabs")

local E = {}

Expand All @@ -25,11 +26,17 @@ end
-- - we have splits open (when `skipSplit` is `true`)
-- - we are focusing a floating window
-- - we are focusing one of the side buffer
function E.skip(state, skipSplit)
function E.skip(state, skipSplit, skipTab)
if not _G.NoNeckPain.state.enabled then
return true
end

if state ~= nil and skipTab then
if vim.api.nvim_win_get_tabpage(0) ~= state.tabs then
return true
end
end

if skipSplit or W.isRelativeWindow() then
return true
end
Expand Down
2 changes: 1 addition & 1 deletion lua/no-neck-pain/util/split.lua
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ end

-- tries to get all of the active splits
function Sp.get(state)
local wins = vim.api.nvim_list_wins()
local wins = vim.api.nvim_tabpage_list_wins(state.tabs)
local screenWidth = vim.api.nvim_list_uis()[1].width

local splits = {}
Expand Down
18 changes: 18 additions & 0 deletions lua/no-neck-pain/util/tabs.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
local D = require("no-neck-pain.util.debug")

local Ta = {}

-- returns the current tabpage.
function Ta.refresh(curr)
local new = vim.api.nvim_win_get_tabpage(0)

if curr == new then
return curr
end

D.log("Ta.refresh", "new tab page registered: was %d, now %d", curr, new)

return new
end

return Ta
4 changes: 2 additions & 2 deletions lua/no-neck-pain/util/trees.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ function T.isSideTree(fileType)
end

-- returns all of the side trees wins and their width.
function T.refresh()
local wins = vim.api.nvim_list_wins()
function T.refresh(state)
local wins = vim.api.nvim_tabpage_list_wins(state.tabs)
local trees = {
NvimTree = {
id = nil,
Expand Down
4 changes: 2 additions & 2 deletions lua/no-neck-pain/util/win.lua
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ end

-- returns the available wins and their total number, without the `list` ones.
function W.winsExceptState(state, withTrees)
local wins = vim.api.nvim_list_wins()
local wins = vim.api.nvim_tabpage_list_wins(state.tabs)
local mergedWins = W.mergeState(
state.wins.main,
state.wins.splits,
Expand Down Expand Up @@ -282,7 +282,7 @@ end
--
-- @param checkSplits bool: checks for splits wins too when `true`.
function W.stateWinsActive(state, checkSplits)
local wins = vim.api.nvim_list_wins()
local wins = vim.api.nvim_tabpage_list_wins(state.tabs)
local swins = state.wins.main

if checkSplits and state.wins.splits ~= nil then
Expand Down
14 changes: 10 additions & 4 deletions tests/test_API.lua
Original file line number Diff line number Diff line change
Expand Up @@ -140,24 +140,30 @@ T["setup"]["enables the plugin with mapping"] = function()
require('no-neck-pain').setup({width=50,toggleMapping="nn"})
]])

eq(child.lua_get("vim.api.nvim_list_wins()"), { 1000 })
eq(child.lua_get("vim.api.nvim_tabpage_list_wins(1)"), { 1000 })
eq_type_global(child, "_G.NoNeckPainLoaded", "boolean")

child.lua("vim.api.nvim_input('nn')")

eq(child.lua_get("vim.api.nvim_list_wins()"), { 1001, 1000, 1002 })
eq(
child.lua_get("vim.api.nvim_tabpage_list_wins(_G.NoNeckPain.state.tabs)"),
{ 1001, 1000, 1002 }
)
eq_state(child, "enabled", true)

child.lua("vim.api.nvim_input('nn')")

eq(child.lua_get("vim.api.nvim_list_wins()"), { 1000 })
eq(child.lua_get("vim.api.nvim_tabpage_list_wins(_G.NoNeckPain.state.tabs)"), { 1000 })
eq_state(child, "enabled", false)
end

T["setup"]["starts the plugin on VimEnter"] = function()
child.restart({ "-u", "scripts/test_auto_open.lua" })

eq(child.lua_get("vim.api.nvim_list_wins()"), { 1001, 1000, 1002 })
eq(
child.lua_get("vim.api.nvim_tabpage_list_wins(_G.NoNeckPain.state.tabs)"),
{ 1001, 1000, 1002 }
)
eq_state(child, "enabled", true)

child.stop()
Expand Down
17 changes: 13 additions & 4 deletions tests/test_autocmd.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ T["auto command"]["does not create side buffers window's width < options.width"]
require('no-neck-pain').enable()
]])

eq(child.lua_get("vim.api.nvim_list_wins()"), { 1000 })
eq(child.lua_get("vim.api.nvim_tabpage_list_wins(_G.NoNeckPain.state.tabs)"), { 1000 })
eq_state(child, "wins.main.curr", 1000)
eq_state(child, "wins.main.left", vim.NIL)
eq_state(child, "wins.main.right", vim.NIL)
Expand All @@ -39,7 +39,10 @@ T["auto command"]["does not shift using when opening/closing float window"] = fu
require('no-neck-pain').enable()
]])

eq(child.lua_get("vim.api.nvim_list_wins()"), { 1001, 1000, 1002 })
eq(
child.lua_get("vim.api.nvim_tabpage_list_wins(_G.NoNeckPain.state.tabs)"),
{ 1001, 1000, 1002 }
)
eq_state(child, "wins.main.left", 1001)
eq_state(child, "wins.main.right", 1002)

Expand All @@ -48,7 +51,10 @@ T["auto command"]["does not shift using when opening/closing float window"] = fu

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

eq(child.lua_get("vim.api.nvim_list_wins()"), { 1001, 1000, 1002, 1003 })
eq(
child.lua_get("vim.api.nvim_tabpage_list_wins(_G.NoNeckPain.state.tabs)"),
{ 1001, 1000, 1002, 1003 }
)
eq_state(child, "wins.main.left", 1001)
eq_state(child, "wins.main.right", 1002)

Expand All @@ -59,7 +65,10 @@ T["auto command"]["does not shift using when opening/closing float window"] = fu
child.lua("vim.fn.win_gotoid(1003)")
child.cmd("q")

eq(child.lua_get("vim.api.nvim_list_wins()"), { 1001, 1000, 1002 })
eq(
child.lua_get("vim.api.nvim_tabpage_list_wins(_G.NoNeckPain.state.tabs)"),
{ 1001, 1000, 1002 }
)
eq_state(child, "wins.main.left", 1001)
eq_state(child, "wins.main.right", 1002)

Expand Down
21 changes: 15 additions & 6 deletions tests/test_buffers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -213,14 +213,17 @@ T["curr"]["closing `curr` window without any other window quits Neovim"] = funct
require('no-neck-pain').enable()
]])

eq(child.lua_get("vim.api.nvim_list_wins()"), { 1001, 1000, 1002 })
eq(
child.lua_get("vim.api.nvim_tabpage_list_wins(_G.NoNeckPain.state.tabs)"),
{ 1001, 1000, 1002 }
)
eq_state(child, "wins.main.curr", 1000)

child.cmd("q")

-- neovim is closed, so it errors
helpers.expect.error(function()
child.lua_get("vim.api.nvim_list_wins()")
child.lua_get("vim.api.nvim_tabpage_list_wins(_G.NoNeckPain.state.tabs)")
end)
end

Expand Down Expand Up @@ -266,14 +269,17 @@ T["left/right"]["closing the `left` buffer disables NNP"] = function()
require('no-neck-pain').enable()
]])

eq(child.lua_get("vim.api.nvim_list_wins()"), { 1001, 1000, 1002 })
eq(
child.lua_get("vim.api.nvim_tabpage_list_wins(_G.NoNeckPain.state.tabs)"),
{ 1001, 1000, 1002 }
)
eq_state(child, "wins.main.left", 1001)
eq_state(child, "wins.main.right", 1002)

child.lua("vim.fn.win_gotoid(_G.NoNeckPain.state.wins.main.left)")
child.cmd("q")

eq(child.lua_get("vim.api.nvim_list_wins()"), { 1000 })
eq(child.lua_get("vim.api.nvim_tabpage_list_wins(_G.NoNeckPain.state.tabs)"), { 1000 })

eq_state(child, "enabled", false)
end
Expand All @@ -284,14 +290,17 @@ T["left/right"]["closing the `right` buffer disables NNP"] = function()
require('no-neck-pain').enable()
]])

eq(child.lua_get("vim.api.nvim_list_wins()"), { 1001, 1000, 1002 })
eq(
child.lua_get("vim.api.nvim_tabpage_list_wins(_G.NoNeckPain.state.tabs)"),
{ 1001, 1000, 1002 }
)
eq_state(child, "wins.main.left", 1001)
eq_state(child, "wins.main.right", 1002)

child.lua("vim.fn.win_gotoid(_G.NoNeckPain.state.wins.main.right)")
child.cmd("q")

eq(child.lua_get("vim.api.nvim_list_wins()"), { 1000 })
eq(child.lua_get("vim.api.nvim_tabpage_list_wins(_G.NoNeckPain.state.tabs)"), { 1000 })

eq_state(child, "enabled", false)
end
Expand Down
10 changes: 8 additions & 2 deletions tests/test_scratchpad.lua
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ T["scratchPad"]["default to `norg` fileType"] = function()
})]])
child.lua([[require('no-neck-pain').enable()]])

eq(child.lua_get("vim.api.nvim_list_wins()"), { 1001, 1000, 1002 })
eq(
child.lua_get("vim.api.nvim_tabpage_list_wins(_G.NoNeckPain.state.tabs)"),
{ 1001, 1000, 1002 }
)

local cwd = child.lua_get("vim.fn.getcwd()")
local left = cwd .. "/no-neck-pain-left.norg"
Expand Down Expand Up @@ -92,7 +95,10 @@ T["scratchPad"]["override to md is reflected to the buffer"] = function()
})]])
child.lua([[require('no-neck-pain').enable()]])

eq(child.lua_get("vim.api.nvim_list_wins()"), { 1001, 1000, 1002 })
eq(
child.lua_get("vim.api.nvim_tabpage_list_wins(_G.NoNeckPain.state.tabs)"),
{ 1001, 1000, 1002 }
)

local cwd = child.lua_get("vim.fn.getcwd()")
local left = cwd .. "/no-neck-pain-left.md"
Expand Down
Loading

0 comments on commit e513dc3

Please sign in to comment.