Skip to content

Commit

Permalink
feat: add NoNeckPainResize command (#162)
Browse files Browse the repository at this point in the history
## 📃 Summary

Kind of provides an escape hatch for things like
#155

This PR provides a new `NoNeckPainResize` command, that updates the
width of the main buffer and triggers a resize of the windows. This can
be useful when switching context and the user don't want to update the
`setup` method.
  • Loading branch information
shortcuts committed Jan 31, 2023
1 parent 0dd69f6 commit 3fc9c82
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 18 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,8 @@ NoNeckPain.bufferOptions = {

| Command | Description |
|-------------|----------------------------|
|`:NoNeckPain`| Toggles the plugin state, between enable and disable.|
|`:NoNeckPain`| Toggles the plugin state, between enable and disable. |
|`:NoNeckPainResize INT`| Updates the config `width` with the given `INT` value and resizes the no-neck-pain windows. |

## ⌨ Contributing

Expand Down
7 changes: 7 additions & 0 deletions doc/no-neck-pain.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@
`NoNeckPain.toggle`()
Toggle the plugin by calling the `enable`/`disable` methods respectively.

------------------------------------------------------------------------------
*NoNeckPain.resize()*
`NoNeckPain.resize`({width})
Sets the config `width` to the given `width` value and resizes the NoNeckPain windows.

@param width number: any positive integer superior to 0.

------------------------------------------------------------------------------
*NoNeckPain.enable()*
`NoNeckPain.enable`()
Expand Down
1 change: 1 addition & 0 deletions doc/tags
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ NoNeckPain.bufferOptions no-neck-pain.txt /*NoNeckPain.bufferOptions*
NoNeckPain.disable() no-neck-pain.txt /*NoNeckPain.disable()*
NoNeckPain.enable() no-neck-pain.txt /*NoNeckPain.enable()*
NoNeckPain.options no-neck-pain.txt /*NoNeckPain.options*
NoNeckPain.resize() no-neck-pain.txt /*NoNeckPain.resize()*
NoNeckPain.setup() no-neck-pain.txt /*NoNeckPain.setup()*
NoNeckPain.toggle() no-neck-pain.txt /*NoNeckPain.toggle()*
21 changes: 21 additions & 0 deletions lua/no-neck-pain/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,27 @@ function NoNeckPain.toggle()
_G.NoNeckPain.state = M.toggle("publicAPI_toggle")
end

--- Sets the config `width` to the given `width` value and resizes the NoNeckPain windows.
---
--- @param width number: any positive integer superior to 0.
function NoNeckPain.resize(width)
if not _G.NoNeckPain.state.enabled then
error("no-neck-pain.nvim must be enabled, run `NoNeckPain` first.")
end

width = tonumber(width) or 0

if _G.NoNeckPain.config.width == width then
return
end

if width > 0 then
_G.NoNeckPain.config = vim.tbl_deep_extend("keep", { width = width }, _G.NoNeckPain.config)
end

_G.NoNeckPain.state = M.init("publicAPI_resize", nil, false)
end

--- Initializes the plugin, sets event listeners and internal state.
function NoNeckPain.enable()
if _G.NoNeckPain.config == nil then
Expand Down
24 changes: 17 additions & 7 deletions lua/no-neck-pain/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,15 @@ function N.toggle(scope)
end

-- Creates side buffers and set the tab state, focuses the `curr` window if required.
local function init(scope, tab, goToCurr)
function N.init(scope, tab, goToCurr)
if tab == nil then
tab = Ta.get(S.tabs)

if tab == nil then
error("called the internal `init` method on a `nil` tab.")
end
end

D.log(scope, "init called on tab %d for current window %d", tab.id, tab.wins.main.curr)

-- if we do not have side buffers, we must ensure we only trigger a focus if we re-create them
Expand All @@ -41,6 +49,8 @@ local function init(scope, tab, goToCurr)
then
vim.fn.win_gotoid(tab.wins.main.curr)
end

return S
end

-- Initializes the plugin, sets event listeners and internal state.
Expand All @@ -63,7 +73,7 @@ function N.enable(scope)
tab.wins.main.curr = vim.api.nvim_get_current_win()
tab.wins.splits = Sp.get(tab)

init(scope, tab, true)
N.init(scope, tab, true)

vim.api.nvim_create_autocmd({ "VimResized" }, {
callback = function(p)
Expand All @@ -72,7 +82,7 @@ function N.enable(scope)
return
end

init(p.event, tab)
N.init(p.event, tab)
end)
end,
group = augroupName,
Expand Down Expand Up @@ -130,7 +140,7 @@ function N.enable(scope)
tab.wins.splits = Sp.insert(tab.wins.splits, focusedWin, vsplit)

if vsplit then
init(p.event, tab)
N.init(p.event, tab)
end
end)
end,
Expand Down Expand Up @@ -193,7 +203,7 @@ function N.enable(scope)
end

-- we only restore focus on curr if there's no split left
init(p.event, tab, tab.wins.splits == nil)
N.init(p.event, tab, tab.wins.splits == nil)
end)
end,
group = augroupName,
Expand Down Expand Up @@ -222,14 +232,14 @@ function N.enable(scope)
if tree ~= nil and tree.id ~= nil and not vim.tbl_contains(wins, tree.id) then
D.log(p.event, "%s have been closed, resizing", name)

return init(p.event, tab)
return N.init(p.event, tab)
end

-- we have a new tree registered, we can resize
if trees[name].id ~= tab.wins.external.trees[name].id then
D.log(p.event, "%s have been opened, resizing", name)

return init(p.event, tab)
return N.init(p.event, tab)
end
end
tab.wins.external.trees = trees
Expand Down
7 changes: 6 additions & 1 deletion plugin/no-neck-pain.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,13 @@ _G.NoNeckPainLoaded = true

if vim.fn.has("nvim-0.7") == 0 then
vim.cmd("command NoNeckPain lua require('no-neck-pain').toggle()")
vim.cmd("command -nargs=1 NoNeckPainResize lua require('no-neck-pain').toggle()")
else
vim.api.nvim_create_user_command("NoNeckPain", function()
require("no-neck-pain").toggle()
end, {})
end, { desc = "Toggles the plugin" })

vim.api.nvim_create_user_command("NoNeckPainResize", function(tbl)
require("no-neck-pain").resize(tbl.args)
end, { desc = "Resizes the main centered window", nargs = 1 })
end
12 changes: 3 additions & 9 deletions tests/test_API.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
local Co = require("no-neck-pain.util.constants")
local helpers = dofile("tests/helpers.lua")

local child = helpers.new_child_neovim()
Expand All @@ -23,20 +24,13 @@ local T = MiniTest.new_set({
},
})

local SCOPES = { "left", "right" }
local EXTERNALS = { "NvimTree", "undotree" }

T["install"] = MiniTest.new_set()

T["install"]["sets global loaded variable and provide toggle command"] = function()
T["install"]["sets global loaded variable"] = function()
eq_type_global(child, "_G.NoNeckPainLoaded", "boolean")
eq_global(child, "_G.NoNeckPain", vim.NIL)

child.cmd("NoNeckPain")
eq_state(child, "enabled", true)

child.cmd("NoNeckPain")
eq_state(child, "enabled", false)
end

T["setup"] = MiniTest.new_set()
Expand Down Expand Up @@ -87,7 +81,7 @@ T["setup"]["sets exposed methods and default options value"] = function()
eq_config(child, "buffers.wo.wrap", true)
eq_config(child, "buffers.wo.linebreak", true)

for _, scope in pairs(SCOPES) do
for _, scope in pairs(Co.SIDES) do
eq_type_config(child, "buffers." .. scope, "table")
eq_type_config(child, "buffers." .. scope .. ".bo", "table")
eq_type_config(child, "buffers." .. scope .. ".wo", "table")
Expand Down
67 changes: 67 additions & 0 deletions tests/test_commands.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
local helpers = dofile("tests/helpers.lua")

local child = helpers.new_child_neovim()
local eq_global, eq_state, eq_buf_width =
helpers.expect.global_equality, helpers.expect.state_equality, helpers.expect.buf_width_equality

local T = MiniTest.new_set({
hooks = {
-- This will be executed before every (even nested) case
pre_case = function()
-- Restart child process with custom 'init.lua' script
child.restart({ "-u", "scripts/minimal_init.lua" })
end,
-- This will be executed one after all tests from this set are finished
post_once = child.stop,
},
})

T["commands"] = MiniTest.new_set()

T["commands"]["NoNeckPain toggles the plugin state"] = function()
child.cmd("NoNeckPain")
eq_state(child, "enabled", true)

child.cmd("NoNeckPain")
eq_state(child, "enabled", false)
end

T["commands"]["NoNeckPainResize sets the config width and resizes windows"] = function()
child.cmd("NoNeckPain")

eq_global(child, "_G.NoNeckPain.config.width", 100)

-- need to know why the child isn't precise enough
eq_buf_width(child, "tabs[1].wins.main.curr", 80)

child.cmd("NoNeckPainResize 20")

eq_global(child, "_G.NoNeckPain.config.width", 20)

-- need to know why the child isn't precise enough
eq_buf_width(child, "tabs[1].wins.main.curr", 20)
end

T["commands"]["NoNeckPainResize throws with the plugin disabled"] = function()
helpers.expect.error(function()
child.cmd("NoNeckPainResize 20")
end)
end

T["commands"]["NoNeckPainResize does nothing with the same widht"] = function()
child.cmd("NoNeckPain")

eq_global(child, "_G.NoNeckPain.config.width", 100)

-- need to know why the child isn't precise enough
eq_buf_width(child, "tabs[1].wins.main.curr", 80)

child.cmd("NoNeckPainResize 100")

eq_global(child, "_G.NoNeckPain.config.width", 100)

-- need to know why the child isn't precise enough
eq_buf_width(child, "tabs[1].wins.main.curr", 80)
end

return T

0 comments on commit 3fc9c82

Please sign in to comment.