From 10cc21c935abae208ae82584040b0143bd213ad7 Mon Sep 17 00:00:00 2001 From: Barrett Ruth Date: Mon, 16 Mar 2026 20:08:19 -0400 Subject: [PATCH] fix(float): support `close = false` for floating oil windows Problem: `select` with `close = false` was broken for floating oil windows. The float auto-close autocmd would always close the window when focus left, and there was no mechanism to preserve it. Solution: Add `oil_keep_open` window flag set when `close = false` is used on a float. The auto-close autocmd checks this flag before closing. On file select, focus returns to the original window behind the float so the file opens there, then focus restores to the float. Co-Authored-By: Claude Opus 4.6 --- lua/oil/init.lua | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/lua/oil/init.lua b/lua/oil/init.lua index 9adc5f5..4b52a7f 100644 --- a/lua/oil/init.lua +++ b/lua/oil/init.lua @@ -292,9 +292,17 @@ M.open_float = function(dir, opts, cb) if util.is_floating_win() or vim.fn.win_gettype() == 'command' then return end - if vim.api.nvim_win_is_valid(winid) then - vim.api.nvim_win_close(winid, true) + if not vim.api.nvim_win_is_valid(winid) then + for _, id in ipairs(autocmds) do + vim.api.nvim_del_autocmd(id) + end + autocmds = {} + return end + if vim.w[winid].oil_keep_open then + return + end + vim.api.nvim_win_close(winid, true) for _, id in ipairs(autocmds) do vim.api.nvim_del_autocmd(id) end @@ -851,6 +859,8 @@ M.select = function(opts, callback) local prev_win = vim.api.nvim_get_current_win() local oil_bufnr = vim.api.nvim_get_current_buf() + local keep_float_open = util.is_floating_win() and opts.close == false + local float_win = keep_float_open and prev_win or nil -- Async iter over entries so we can normalize the url before opening local i = 1 @@ -868,8 +878,10 @@ M.select = function(opts, callback) return cb('Please save changes before entering new directory') end else - -- Close floating window before opening a file - if vim.w.is_oil_win then + local is_float = util.is_floating_win() + if is_float and opts.close == false then + vim.w.oil_keep_open = true + elseif vim.w.is_oil_win then M.close() end end @@ -892,10 +904,16 @@ M.select = function(opts, callback) vim.bo[filebufnr].buflisted = true end + if keep_float_open and not opts.tab then + local original_win = vim.w[float_win].oil_original_win + if original_win and vim.api.nvim_win_is_valid(original_win) then + vim.api.nvim_set_current_win(original_win) + end + end + local cmd = 'buffer' if opts.tab then vim.cmd.tabnew({ mods = mods }) - -- Make sure the new buffer from tabnew gets cleaned up vim.bo.bufhidden = 'wipe' elseif opts.split then cmd = 'sbuffer' @@ -934,6 +952,13 @@ M.select = function(opts, callback) end) end + if float_win and vim.api.nvim_win_is_valid(float_win) then + if opts.tab then + vim.api.nvim_set_current_tabpage(vim.api.nvim_win_get_tabpage(float_win)) + end + vim.api.nvim_set_current_win(float_win) + end + update_preview_window() finish()