Files
nvim-config/lua/plugins/oil.lua
Wesley van Tilburg bb91392a21 initial config push
2026-03-09 16:07:08 +00:00

151 lines
5.7 KiB
Lua

-- 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 = {
["<CR>"] = false, -- disable default, we override below
["<C-t>"] = false, -- don't override global <C-t> (popup terminal)
},
})
-- Override <CR> 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", "<BS>", 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", "<leader>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", "<CR>", 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 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)
-- Remember blank buffer to clean up after opening
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
vim.api.nvim_buf_delete(old_buf, { force = true })
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 <leader>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", "<leader>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,
})