@@ -337,6 +337,137 @@ describe("neotree", function()
337337 end )
338338 end )
339339
340+ describe (" open_file_close_others" , function ()
341+ local function make_node (id , type_ , path_ )
342+ return {
343+ id = id ,
344+ type = type_ ,
345+ path = path_ ,
346+ }
347+ end
348+
349+ local function make_state (selected_node )
350+ return {
351+ tree = {
352+ get_node = function ()
353+ return selected_node
354+ end ,
355+ },
356+ }
357+ end
358+
359+ it (" opens the file and closes other windows" , function ()
360+ local file = make_node (" f1" , " file" , " /tmp/test.txt" )
361+ local state = make_state (file )
362+
363+ -- Track vim commands and API calls
364+ local cmds = {}
365+ local original_cmd = vim .cmd
366+ vim .cmd = function (c )
367+ table.insert (cmds , c )
368+ end
369+
370+ local set_win_calls = {}
371+ local original_set_win = vim .api .nvim_set_current_win
372+ vim .api .nvim_set_current_win = function (win )
373+ table.insert (set_win_calls , win )
374+ end
375+
376+ local original_get_win = vim .api .nvim_get_current_win
377+ vim .api .nvim_get_current_win = function ()
378+ return 2
379+ end
380+
381+ -- Mock neotree window detection
382+ local original_list_wins = vim .api .nvim_tabpage_list_wins
383+ local original_win_get_buf = vim .api .nvim_win_get_buf
384+ local original_buf_get_name = vim .api .nvim_buf_get_name
385+ local original_win_close = vim .api .nvim_win_close
386+
387+ vim .api .nvim_tabpage_list_wins = function ()
388+ return { 1 , 2 }
389+ end
390+ vim .api .nvim_win_get_buf = function (winid )
391+ return winid
392+ end
393+ vim .api .nvim_buf_get_name = function (bufnr )
394+ if bufnr == 1 then
395+ return " neo-tree filesystem [1]"
396+ end
397+ return " /tmp/test.txt"
398+ end
399+
400+ local closed_wins = {}
401+ vim .api .nvim_win_close = function (winid , force )
402+ table.insert (closed_wins , { winid = winid , force = force })
403+ end
404+
405+ neotree .open_file_close_others (state )
406+
407+ -- Verify vsplit was called
408+ local found_vsplit = false
409+ for _ , c in ipairs (cmds ) do
410+ if c == " rightbelow vsplit" then
411+ found_vsplit = true
412+ break
413+ end
414+ end
415+ assert .is_true (found_vsplit )
416+
417+ -- Verify edit command was called with the file path
418+ local found_edit = false
419+ for _ , c in ipairs (cmds ) do
420+ if c :match (" ^edit.*/tmp/test.txt$" ) then
421+ found_edit = true
422+ break
423+ end
424+ end
425+ assert .is_true (found_edit )
426+
427+ -- Restore original functions
428+ vim .cmd = original_cmd
429+ vim .api .nvim_set_current_win = original_set_win
430+ vim .api .nvim_get_current_win = original_get_win
431+ vim .api .nvim_tabpage_list_wins = original_list_wins
432+ vim .api .nvim_win_get_buf = original_win_get_buf
433+ vim .api .nvim_buf_get_name = original_buf_get_name
434+ vim .api .nvim_win_close = original_win_close
435+ end )
436+
437+ it (" no-ops when selected node is not a file" , function ()
438+ local dir = make_node (" d1" , " directory" , " /tmp/dir" )
439+ local state = make_state (dir )
440+
441+ local cmd_called = false
442+ local original_cmd = vim .cmd
443+ vim .cmd = function ()
444+ cmd_called = true
445+ end
446+
447+ neotree .open_file_close_others (state )
448+
449+ assert .is_false (cmd_called )
450+
451+ vim .cmd = original_cmd
452+ end )
453+
454+ it (" no-ops when node is nil" , function ()
455+ local state = make_state (nil )
456+
457+ local cmd_called = false
458+ local original_cmd = vim .cmd
459+ vim .cmd = function ()
460+ cmd_called = true
461+ end
462+
463+ neotree .open_file_close_others (state )
464+
465+ assert .is_false (cmd_called )
466+
467+ vim .cmd = original_cmd
468+ end )
469+ end )
470+
340471 describe (" show_git_changes_tree" , function ()
341472 it (" invokes Neotree with merge base and updates gitsigns base" , function ()
342473 -- avoid tab/window creation in this test
0 commit comments