Skip to content

Commit 246762b

Browse files
authored
Merge pull request #18 from mhiro2/refactor/toggle-api
refactor(toggle): Rename `toggle_visibility` to `toggle` and preserve popup IDs
2 parents b397bef + 64f6321 commit 246762b

6 files changed

Lines changed: 66 additions & 25 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ Using lazy.nvim:
7373
vim.keymap.set("n", "<leader>pm", function() peekstack.peek.marks_buffer() end)
7474

7575
-- Utility: temporarily hide/show all popups in current stack
76-
vim.keymap.set("n", "<leader>ph", "<cmd>PeekstackToggleVisibility<cr>", { desc = "Peekstack: toggle visibility" })
76+
vim.keymap.set("n", "<leader>ph", "<cmd>PeekstackToggle<cr>", { desc = "Peekstack: toggle" })
7777
end,
7878
}
7979
```
@@ -112,7 +112,7 @@ Built-in provider names:
112112
- `:PeekstackRestorePopup` — restore the last closed popup (undo close)
113113
- `:PeekstackRestoreAllPopups` — restore all closed popups
114114
- `:PeekstackCloseAll` — close all popups in the current stack
115-
- `:PeekstackToggleVisibility` — temporarily hide/show all popups in the current stack
115+
- `:PeekstackToggle` — temporarily hide/show all popups in the current stack
116116
- `:PeekstackHistory` — show popup history and select to restore
117117
- `:PeekstackQuickPeek [provider]` — quick peek without stacking (default: `lsp.definition`, accepts any registered provider)
118118

doc/peekstack.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ Commands are registered after `setup()` is called.
291291
:PeekstackCloseAll *:PeekstackCloseAll*
292292
Close all popups in the current stack.
293293

294-
:PeekstackToggleVisibility *:PeekstackToggleVisibility*
294+
:PeekstackToggle *:PeekstackToggle*
295295
Temporarily hide or show all popups in the current stack. When hidden,
296296
popup windows are closed but the stack state is preserved. Toggling
297297
again recreates the windows in their original layout. Pushing a new

lua/peekstack/commands.lua

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ local COMMAND_NAMES = {
1313
"PeekstackHistory",
1414
"PeekstackCloseAll",
1515
"PeekstackQuickPeek",
16-
"PeekstackToggleVisibility",
16+
"PeekstackToggle",
1717
}
1818

1919
---@param session PeekstackSession|table
@@ -174,8 +174,8 @@ function M.setup()
174174
require("peekstack.core.stack").close_all()
175175
end, {})
176176

177-
vim.api.nvim_create_user_command("PeekstackToggleVisibility", function()
178-
local toggled = require("peekstack.core.stack").toggle_visibility()
177+
vim.api.nvim_create_user_command("PeekstackToggle", function()
178+
local toggled = require("peekstack.core.stack").toggle()
179179
if not toggled then
180180
notify.info("No popups in the current stack")
181181
end

lua/peekstack/core/popup.lua

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,10 @@ function M.create(location, opts)
199199
end
200200
set_cursor(winid, location, line_offset)
201201

202-
local id = next_id
203-
next_id = next_id + 1
202+
local id = opts.id or next_id
203+
if not opts.id then
204+
next_id = next_id + 1
205+
end
204206

205207
local popup = {
206208
id = id,

lua/peekstack/core/stack.lua

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ function M.push(location, opts)
281281
local stack = ensure_stack()
282282
-- Auto-show hidden stack before pushing a new popup
283283
if stack.hidden then
284-
M.toggle_visibility(stack.root_winid)
284+
M.toggle(stack.root_winid)
285285
end
286286
local model = popup.create(location, create_opts)
287287
if not model then
@@ -543,6 +543,7 @@ end
543543
---@return PeekstackPopupModel?
544544
local function reopen_popup(item, stack)
545545
local reopen_opts = {
546+
id = item.id,
546547
buffer_mode = item.buffer_mode or "copy",
547548
origin_winid = stack.root_winid,
548549
parent_popup_id = item.parent_popup_id,
@@ -554,10 +555,7 @@ local function reopen_popup(item, stack)
554555
if not model then
555556
return nil
556557
end
557-
model.id = item.id
558558
model.pinned = item.pinned or false
559-
vim.b[model.bufnr].peekstack_popup_id = model.id
560-
vim.w[model.winid].peekstack_popup_id = model.id
561559
return model
562560
end
563561

@@ -849,7 +847,7 @@ end
849847
---When shown, popup windows are recreated from the stored models.
850848
---@param winid? integer
851849
---@return boolean
852-
function M.toggle_visibility(winid)
850+
function M.toggle(winid)
853851
deps()
854852
local stack = ensure_stack(winid)
855853
if #stack.popups == 0 then
Lines changed: 53 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ local config = require("peekstack.config")
33
local events = require("peekstack.core.events")
44
local helpers = require("tests.helpers")
55

6-
describe("stack.toggle_visibility", function()
6+
describe("stack.toggle", function()
77
before_each(function()
88
stack._reset()
99
config.setup({})
@@ -14,7 +14,7 @@ describe("stack.toggle_visibility", function()
1414
local s = stack.current_stack()
1515
-- Restore visibility so windows can be closed normally
1616
if s.hidden then
17-
stack.toggle_visibility()
17+
stack.toggle()
1818
end
1919
for i = #s.popups, 1, -1 do
2020
stack.close(s.popups[i].id)
@@ -23,7 +23,7 @@ describe("stack.toggle_visibility", function()
2323
end)
2424

2525
it("returns false on empty stack", function()
26-
assert.is_false(stack.toggle_visibility())
26+
assert.is_false(stack.toggle())
2727
assert.is_false(stack.is_hidden())
2828
end)
2929

@@ -34,7 +34,7 @@ describe("stack.toggle_visibility", function()
3434
assert.is_not_nil(m1)
3535
assert.is_not_nil(m2)
3636

37-
assert.is_true(stack.toggle_visibility())
37+
assert.is_true(stack.toggle())
3838
assert.is_true(stack.is_hidden())
3939

4040
-- Windows should be gone but popups remain in the stack
@@ -53,11 +53,11 @@ describe("stack.toggle_visibility", function()
5353
assert.is_not_nil(m2)
5454

5555
-- Hide
56-
stack.toggle_visibility()
56+
stack.toggle()
5757
assert.is_true(stack.is_hidden())
5858

5959
-- Show
60-
assert.is_true(stack.toggle_visibility())
60+
assert.is_true(stack.toggle())
6161
assert.is_false(stack.is_hidden())
6262

6363
local s = stack.current_stack()
@@ -76,8 +76,8 @@ describe("stack.toggle_visibility", function()
7676
local id1 = m1.id
7777
local id2 = m2.id
7878

79-
stack.toggle_visibility()
80-
stack.toggle_visibility()
79+
stack.toggle()
80+
stack.toggle()
8181

8282
local s = stack.current_stack()
8383
assert.equals(id1, s.popups[1].id)
@@ -88,7 +88,7 @@ describe("stack.toggle_visibility", function()
8888
local loc = helpers.make_location()
8989
stack.push(loc)
9090

91-
stack.toggle_visibility()
91+
stack.toggle()
9292
assert.is_true(stack.is_hidden())
9393

9494
-- Pushing should auto-show
@@ -109,7 +109,7 @@ describe("stack.toggle_visibility", function()
109109
stack.push(loc)
110110
stack.push(loc)
111111

112-
stack.toggle_visibility()
112+
stack.toggle()
113113
assert.is_true(stack.is_hidden())
114114

115115
stack.close_all()
@@ -124,7 +124,7 @@ describe("stack.toggle_visibility", function()
124124
stack.push(loc)
125125
stack.push(loc)
126126

127-
stack.toggle_visibility()
127+
stack.toggle()
128128
assert.is_true(stack.is_hidden())
129129

130130
-- reflow_all should skip hidden popups (winid=nil) safely
@@ -140,13 +140,54 @@ describe("stack.toggle_visibility", function()
140140
end
141141
end)
142142

143+
it("close by id works after hide/show cycle", function()
144+
local loc = helpers.make_location()
145+
local m1 = stack.push(loc)
146+
local m2 = stack.push(loc)
147+
148+
-- Hide then show
149+
stack.toggle()
150+
stack.toggle()
151+
152+
-- close should find the popup by its original id
153+
assert.is_true(stack.close(m2.id))
154+
assert.is_true(stack.close(m1.id))
155+
156+
local s = stack.current_stack()
157+
assert.equals(0, #s.popups)
158+
end)
159+
160+
it("keymaps reference correct popup id after hide/show cycle", function()
161+
local loc = helpers.make_location()
162+
local m1 = stack.push(loc)
163+
164+
local original_id = m1.id
165+
166+
-- Hide then show (recreates buffer + keymaps)
167+
stack.toggle()
168+
stack.toggle()
169+
170+
local s = stack.current_stack()
171+
local restored = s.popups[1]
172+
assert.equals(original_id, restored.id)
173+
174+
-- The close keymap should work via the buffer variable
175+
assert.equals(original_id, vim.b[restored.bufnr].peekstack_popup_id)
176+
177+
-- Simulate what the close keymap does: resolve + close by popup_id
178+
local found = stack.find_by_id(original_id)
179+
assert.is_not_nil(found)
180+
assert.equals(restored.bufnr, found.bufnr)
181+
assert.is_true(stack.close(original_id))
182+
end)
183+
143184
it("does not leak popups to history when hiding", function()
144185
local loc = helpers.make_location()
145186
stack.push(loc)
146187
stack.push(loc)
147188

148189
local history_before = #stack.history_list()
149-
stack.toggle_visibility()
190+
stack.toggle()
150191
local history_after = #stack.history_list()
151192

152193
assert.equals(history_before, history_after)

0 commit comments

Comments
 (0)