added: smart_split_open function for split windows; so Neovim asks if the user wants to re-open the already open buffer in the current tab as split window or just jump to the existing one

This commit is contained in:
psychhim
2025-10-05 22:12:30 +05:30
parent bb887551fe
commit 8ffc8d8ab6

View File

@@ -2,143 +2,182 @@
vim.cmd [[ let g:neo_tree_remove_legacy_commands = 1 ]] vim.cmd [[ let g:neo_tree_remove_legacy_commands = 1 ]]
return { return {
'nvim-neo-tree/neo-tree.nvim', 'nvim-neo-tree/neo-tree.nvim',
version = '*', version = '*',
dependencies = { dependencies = {
'nvim-lua/plenary.nvim', 'nvim-lua/plenary.nvim',
'nvim-tree/nvim-web-devicons', 'nvim-tree/nvim-web-devicons',
'MunifTanjim/nui.nvim', 'MunifTanjim/nui.nvim',
}, },
config = function() config = function()
local function smart_open(state) local function smart_open(state)
local node = state.tree:get_node() local node = state.tree:get_node()
if not node then if not node then
return return
end end
local path = node:get_id() local path = node:get_id()
-- If the node is a directory, just toggle expand/collapse -- If the node is a directory, just toggle expand/collapse
if node.type == 'directory' then if node.type == 'directory' then
state.commands.toggle_node(state, node) state.commands.toggle_node(state, node)
return return
end end
-- --- File handling starts here --- -- --- File handling starts here ---
-- Reuse already open buffer in any tab safely -- Reuse already open buffer in any tab safely
for _, tab in ipairs(vim.api.nvim_list_tabpages()) do for _, tab in ipairs(vim.api.nvim_list_tabpages()) do
if vim.api.nvim_tabpage_is_valid(tab) then if vim.api.nvim_tabpage_is_valid(tab) then
for _, win in ipairs(vim.api.nvim_tabpage_list_wins(tab)) do for _, win in ipairs(vim.api.nvim_tabpage_list_wins(tab)) do
if vim.api.nvim_win_is_valid(win) then if vim.api.nvim_win_is_valid(win) then
local buf = vim.api.nvim_win_get_buf(win) local buf = vim.api.nvim_win_get_buf(win)
if vim.api.nvim_buf_is_valid(buf) and vim.api.nvim_buf_get_name(buf) == path then if vim.api.nvim_buf_is_valid(buf) and vim.api.nvim_buf_get_name(buf) == path then
vim.api.nvim_set_current_tabpage(tab) vim.api.nvim_set_current_tabpage(tab)
vim.api.nvim_set_current_win(win) vim.api.nvim_set_current_win(win)
-- close Neo-tree if open -- close Neo-tree if open
for _, w in ipairs(vim.api.nvim_list_wins()) do for _, w in ipairs(vim.api.nvim_list_wins()) do
if vim.api.nvim_win_is_valid(w) then if vim.api.nvim_win_is_valid(w) then
local b = vim.api.nvim_win_get_buf(w) local b = vim.api.nvim_win_get_buf(w)
if vim.api.nvim_buf_is_valid(b) and vim.api.nvim_buf_get_option(b, 'filetype') == 'neo-tree' then if vim.api.nvim_buf_is_valid(b) and vim.api.nvim_buf_get_option(b, 'filetype') == 'neo-tree' then
vim.api.nvim_win_close(w, true) vim.api.nvim_win_close(w, true)
end end
end end
end end
return return
end end
end end
end end
end end
end end
-- Reuse empty buffer in current tab -- Reuse empty buffer in current tab
local wins = vim.api.nvim_tabpage_list_wins(0) local wins = vim.api.nvim_tabpage_list_wins(0)
local empty_buf = nil local empty_buf = nil
for _, win in ipairs(wins) do for _, win in ipairs(wins) do
if vim.api.nvim_win_is_valid(win) then if vim.api.nvim_win_is_valid(win) then
local buf = vim.api.nvim_win_get_buf(win) local buf = vim.api.nvim_win_get_buf(win)
if vim.api.nvim_buf_is_valid(buf) then if vim.api.nvim_buf_is_valid(buf) then
local bufname = vim.api.nvim_buf_get_name(buf) local bufname = vim.api.nvim_buf_get_name(buf)
local buftype = vim.api.nvim_buf_get_option(buf, 'buftype') local buftype = vim.api.nvim_buf_get_option(buf, 'buftype')
local modified = vim.api.nvim_buf_get_option(buf, 'modified') local modified = vim.api.nvim_buf_get_option(buf, 'modified')
if bufname == '' and buftype == '' and not modified then if bufname == '' and buftype == '' and not modified then
empty_buf = buf empty_buf = buf
vim.api.nvim_set_current_win(win) vim.api.nvim_set_current_win(win)
break break
end end
end end
end end
end end
if empty_buf then if empty_buf then
vim.cmd('edit ' .. vim.fn.fnameescape(path)) vim.cmd('edit ' .. vim.fn.fnameescape(path))
else else
vim.cmd('tabnew ' .. vim.fn.fnameescape(path)) vim.cmd('tabnew ' .. vim.fn.fnameescape(path))
end end
-- Always close Neo-tree window if open -- Always close Neo-tree window if open
for _, win in ipairs(vim.api.nvim_list_wins()) do for _, win in ipairs(vim.api.nvim_list_wins()) do
if vim.api.nvim_win_is_valid(win) then if vim.api.nvim_win_is_valid(win) then
local buf = vim.api.nvim_win_get_buf(win) local buf = vim.api.nvim_win_get_buf(win)
if vim.api.nvim_buf_is_valid(buf) and vim.api.nvim_buf_get_option(buf, 'filetype') == 'neo-tree' then if vim.api.nvim_buf_is_valid(buf) and vim.api.nvim_buf_get_option(buf, 'filetype') == 'neo-tree' then
vim.api.nvim_win_close(win, true) vim.api.nvim_win_close(win, true)
end end
end end
end end
end end
require('neo-tree').setup { -- Smart_open_split for split windows
close_if_last_window = true, local function smart_open_split(state, direction)
popup_border_style = 'rounded', local node = state.tree:get_node()
enable_git_status = true, if not node then
enable_diagnostics = true, return
default_component_configs = { end
indent = { padding = 1, indent_size = 2 }, local path = node:get_id()
icon = { folder_closed = '', folder_open = '', folder_empty = '' },
}, if node.type == 'directory' then
window = { state.commands.toggle_node(state, node)
position = 'float', return
width = 40, end
mapping_options = { noremap = true, nowait = true },
mappings = { -- Check if file is open in another tab
['<cr>'] = smart_open, local open_tab, open_win
['v'] = function(state) for _, tab in ipairs(vim.api.nvim_list_tabpages()) do
local node = state.tree:get_node() for _, win in ipairs(vim.api.nvim_tabpage_list_wins(tab)) do
if node.type == 'directory' then local buf = vim.api.nvim_win_get_buf(win)
state.commands.toggle_node(state, node) if vim.api.nvim_buf_is_valid(buf) and vim.api.nvim_buf_get_name(buf) == path then
return open_tab = tab
end open_win = win
local path = node:get_id() break
state.commands.open_split(state) -- opens horizontal split (top) end
vim.schedule(function() end
vim.cmd 'wincmd J' -- move the new split to bottom if open_tab then
end) break
end, end
['h'] = function(state) end
local node = state.tree:get_node()
if node.type == 'directory' then if open_tab then
state.commands.toggle_node(state, node) local choice = vim.fn.confirm('File is already open in another tab. Open split here anyway?', '&Yes\n&No',
return 2)
end if choice ~= 1 then
local path = node:get_id() -- User chose No → jump to the tab where file is open
state.commands.open_vsplit(state) -- opens vertical split (left) vim.api.nvim_set_current_tabpage(open_tab)
vim.schedule(function() vim.api.nvim_set_current_win(open_win)
vim.cmd 'wincmd L' -- move the new split to right return
end) end
end, -- Else user chose Yes → continue to open split in current tab
['t'] = 'noop', end
},
}, -- Open split in current tab
filesystem = { if direction == 'v' then
follow_current_file = { state.commands.open_vsplit(state)
enabled = true, -- updated to table format vim.schedule(function()
}, vim.cmd 'wincmd L'
use_libuv_file_watcher = true, end)
hijack_netrw_behavior = 'open_default', else
filtered_items = { state.commands.open_split(state)
visible = true, vim.schedule(function()
hide_dotfiles = false, vim.cmd 'wincmd J'
hide_gitignored = true, end)
}, end
},
} vim.cmd('edit ' .. vim.fn.fnameescape(path))
end, end
require('neo-tree').setup {
close_if_last_window = true,
popup_border_style = 'rounded',
enable_git_status = true,
enable_diagnostics = true,
default_component_configs = {
indent = { padding = 1, indent_size = 2 },
icon = { folder_closed = '', folder_open = '', folder_empty = '' },
},
window = {
position = 'float',
width = 40,
mapping_options = { noremap = true, nowait = true },
mappings = {
['<cr>'] = smart_open,
['v'] = function(state)
smart_open_split(state, 'h')
end,
['h'] = function(state)
smart_open_split(state, 'v')
end,
['t'] = 'noop',
},
},
filesystem = {
follow_current_file = {
enabled = true, -- updated to table format
},
use_libuv_file_watcher = true,
hijack_netrw_behavior = 'open_default',
filtered_items = {
visible = true,
hide_dotfiles = false,
hide_gitignored = true,
},
},
}
end,
} }