-- Track the last focused code window (not oil, not terminal) _G.last_code_win = nil vim.api.nvim_create_autocmd("WinEnter", { group = vim.api.nvim_create_augroup("track_code_win", { clear = true }), callback = function() local buf = vim.api.nvim_get_current_buf() local ft = vim.bo[buf].filetype local bt = vim.bo[buf].buftype if ft ~= "oil" and bt ~= "terminal" then _G.last_code_win = vim.api.nvim_get_current_win() end end, }) require("oil").setup({ watch_for_changes = true, keymaps = { [""] = false, -- disable default, we override below [""] = false, -- don't override global (popup terminal) }, }) -- Override in oil buffers to open in last code window vim.api.nvim_create_autocmd("FileType", { group = vim.api.nvim_create_augroup("oil_open_in_code", { clear = true }), pattern = "oil", callback = function(ev) -- Go up a directory with backspace or - vim.keymap.set("n", "", function() require("oil").open(require("oil").get_current_dir() .. "..") end, { buffer = ev.buf, desc = "Go up directory" }) vim.keymap.set("n", "-", function() require("oil").open(require("oil").get_current_dir() .. "..") end, { buffer = ev.buf, desc = "Go up directory" }) -- Delete file under cursor vim.keymap.set("n", "d", function() local oil = require("oil") local entry = oil.get_cursor_entry() if not entry then return end local dir = oil.get_current_dir() if not dir then return end local path = dir .. entry.name vim.ui.input({ prompt = "Delete " .. entry.name .. "? (y/n): " }, function(input) if input == "y" then vim.fn.delete(path, entry.type == "directory" and "rf" or "") oil.discard_all_changes() end end) end, { buffer = ev.buf, desc = "Delete file/dir" }) -- Open file in code window, then auto-focus back to code vim.keymap.set("n", "", function() local oil = require("oil") local entry = oil.get_cursor_entry() if not entry then return end -- Directories: navigate normally in oil if entry.type == "directory" then oil.select() return end local dir = oil.get_current_dir() if not dir then return end local filepath = dir .. entry.name local abs_path = vim.fn.fnamemodify(filepath, ":p") -- Check if file is already tracked in any window's tab list for win, bufs in pairs(_G.win_bufs or {}) do if vim.api.nvim_win_is_valid(win) then for _, buf in ipairs(bufs) do if vim.api.nvim_buf_is_valid(buf) and vim.fn.fnamemodify(vim.api.nvim_buf_get_name(buf), ":p") == abs_path then vim.api.nvim_set_current_win(win) vim.api.nvim_set_current_buf(buf) return end end end end local target_win = nil -- Try last focused code window if _G.last_code_win and vim.api.nvim_win_is_valid(_G.last_code_win) then local buf = vim.api.nvim_win_get_buf(_G.last_code_win) if vim.bo[buf].filetype ~= "oil" and vim.bo[buf].buftype ~= "terminal" then target_win = _G.last_code_win end end -- Fallback: find any non-oil, non-terminal window if not target_win then local cur_win = vim.api.nvim_get_current_win() for _, win in ipairs(vim.api.nvim_tabpage_list_wins(0)) do if win ~= cur_win and vim.api.nvim_win_get_config(win).relative == "" then local buf = vim.api.nvim_win_get_buf(win) if vim.bo[buf].filetype ~= "oil" and vim.bo[buf].buftype ~= "terminal" then target_win = win break end end end end if target_win then vim.api.nvim_set_current_win(target_win) local old_buf = vim.api.nvim_get_current_buf() local is_blank = vim.api.nvim_buf_get_name(old_buf) == "" and not vim.bo[old_buf].modified and vim.api.nvim_buf_line_count(old_buf) <= 1 and vim.api.nvim_buf_get_lines(old_buf, 0, 1, false)[1] == "" vim.cmd.edit(vim.fn.fnameescape(filepath)) if is_blank and old_buf ~= vim.api.nvim_get_current_buf() then local in_use = false for _, win in ipairs(vim.api.nvim_tabpage_list_wins(0)) do if vim.api.nvim_win_get_buf(win) == old_buf then in_use = true break end end if not in_use then vim.api.nvim_buf_delete(old_buf, { force = true }) end end else -- No code window exists: create a split to the right vim.cmd("rightbelow vsplit " .. vim.fn.fnameescape(filepath)) end end, { buffer = ev.buf, desc = "Open file in code window" }) end, }) -- Toggle file tree on the left with e _G.oil_tree_win = nil local function open_tree() vim.cmd("topleft vsplit | vertical resize 30") _G.oil_tree_win = vim.api.nvim_get_current_win() require("oil").open() end vim.keymap.set("n", "e", function() if _G.oil_tree_win and vim.api.nvim_win_is_valid(_G.oil_tree_win) then vim.api.nvim_win_close(_G.oil_tree_win, true) _G.oil_tree_win = nil else open_tree() end end, { desc = "Toggle file tree" }) -- Open file tree on startup (deferred so oil is fully loaded) vim.api.nvim_create_autocmd("VimEnter", { group = vim.api.nvim_create_augroup("oil_startup", { clear = true }), callback = function() vim.schedule(function() open_tree() vim.cmd("wincmd l") end) end, }) -- Keep oil tree pinned at 30 columns after layout changes vim.api.nvim_create_autocmd("WinResized", { group = vim.api.nvim_create_augroup("oil_pin_width", { clear = true }), callback = function() if _G.oil_tree_win and vim.api.nvim_win_is_valid(_G.oil_tree_win) then vim.api.nvim_win_set_width(_G.oil_tree_win, 30) end end, })