@@ -134,6 +134,68 @@ describe("popup source mode", function()
134134 vim .fn .delete (temp )
135135 end )
136136
137+ it (" installs <C-w>hjkl navigation keymaps on copy-mode popups" , function ()
138+ local loc = make_location ()
139+ local model = popup .create (loc , { buffer_mode = " copy" })
140+ assert .is_not_nil (model )
141+ assert .is_true (has_buffer_map (model .bufnr , " <C-W>h" ))
142+ assert .is_true (has_buffer_map (model .bufnr , " <C-W>j" ))
143+ assert .is_true (has_buffer_map (model .bufnr , " <C-W>k" ))
144+ assert .is_true (has_buffer_map (model .bufnr , " <C-W>l" ))
145+ popup .close (model )
146+ end )
147+
148+ it (" <C-w>l navigates from popup to adjacent split" , function ()
149+ -- Create a vertical split so there are two windows.
150+ vim .api .nvim_cmd ({ cmd = " vsplit" }, {})
151+ local left_win = vim .api .nvim_get_current_win ()
152+ -- Move to the right split.
153+ vim .api .nvim_cmd ({ cmd = " wincmd" , args = { " l" } }, {})
154+ local right_win = vim .api .nvim_get_current_win ()
155+ assert .is_not .equals (left_win , right_win )
156+
157+ -- Open a popup anchored to the right split.
158+ local loc = make_location ()
159+ local model = stack .push (loc )
160+ assert .is_not_nil (model )
161+ -- Focus the popup (simulates user entering the floating window).
162+ vim .api .nvim_set_current_win (model .winid )
163+ assert .equals (model .winid , vim .api .nvim_get_current_win ())
164+
165+ -- Execute the <C-w>h keymap callback: should land on the left split.
166+ vim .api .nvim_feedkeys (vim .api .nvim_replace_termcodes (" <C-w>h" , true , false , true ), " x" , false )
167+ assert .equals (left_win , vim .api .nvim_get_current_win ())
168+
169+ -- Cleanup
170+ stack .close (model .id )
171+ vim .api .nvim_set_current_win (right_win )
172+ vim .api .nvim_cmd ({ cmd = " close" }, {})
173+ end )
174+
175+ it (" does not install <C-w>hjkl navigation keymaps on source-mode popups" , function ()
176+ local temp = vim .fn .tempname () .. " .lua"
177+ vim .fn .writefile ({ " print('peekstack')" }, temp )
178+ vim .api .nvim_cmd ({ cmd = " edit" , args = { temp } }, {})
179+ local source_bufnr = vim .api .nvim_get_current_buf ()
180+
181+ local model = popup .create ({
182+ uri = vim .uri_from_fname (temp ),
183+ range = { start = { line = 0 , character = 0 }, [" end" ] = { line = 0 , character = 0 } },
184+ provider = " test" ,
185+ }, {
186+ buffer_mode = " source" ,
187+ })
188+
189+ assert .is_not_nil (model )
190+ assert .is_false (has_buffer_map (source_bufnr , " <C-W>h" ))
191+ assert .is_false (has_buffer_map (source_bufnr , " <C-W>j" ))
192+ assert .is_false (has_buffer_map (source_bufnr , " <C-W>k" ))
193+ assert .is_false (has_buffer_map (source_bufnr , " <C-W>l" ))
194+
195+ popup .close (model )
196+ vim .fn .delete (temp )
197+ end )
198+
137199 it (" deletes copy-mode scratch buffer when render.open fails" , function ()
138200 local render = require (" peekstack.ui.render" )
139201 local loc = make_location ()
0 commit comments