Skip to content

Commit 37bda06

Browse files
authored
fix(picker_ui): handle 'winfixbuf' when opening selected file (#426)
When the current window has 'winfixbuf' enabled (Neovim 0.10+), :edit fails with E1513. Detect this case in M.select's 'edit' branch and either retarget a suitable non-fixed window or fall back to :split. Also extend find_suitable_window to skip windows with 'winfixbuf'. Fixes the following error when invoking the picker from a winfixbuf-locked window: E1513: Cannot switch buffer. 'winfixbuf' is enabled
1 parent 287d7b7 commit 37bda06

1 file changed

Lines changed: 26 additions & 5 deletions

File tree

lua/fff/picker_ui.lua

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2228,6 +2228,15 @@ function M.recall_query_from_history()
22282228
end)
22292229
end
22302230

2231+
--- Check whether the given window has 'winfixbuf' enabled.
2232+
--- pcall-guarded so this stays safe on Neovim versions that predate the option.
2233+
--- @param win number Window ID
2234+
--- @return boolean
2235+
local function window_has_winfixbuf(win)
2236+
local ok, val = pcall(vim.api.nvim_get_option_value, 'winfixbuf', { win = win })
2237+
return ok and val == true
2238+
end
2239+
22312240
--- Find the first visible window with a normal file buffer
22322241
--- @return number|nil Window ID of the first suitable window, or nil if none found
22332242
local function find_suitable_window()
@@ -2254,6 +2263,7 @@ local function find_suitable_window()
22542263
and modifiable
22552264
and not is_picker_window
22562265
and filetype ~= 'undotree'
2266+
and not window_has_winfixbuf(win)
22572267
then
22582268
return win
22592269
end
@@ -2465,17 +2475,28 @@ function M.select(action)
24652475
M.close()
24662476

24672477
if action == 'edit' then
2478+
local current_win = vim.api.nvim_get_current_win()
24682479
local current_buf = vim.api.nvim_get_current_buf()
24692480
local current_buftype = vim.api.nvim_get_option_value('buftype', { buf = current_buf })
24702481
local current_buf_modifiable = vim.api.nvim_get_option_value('modifiable', { buf = current_buf })
2471-
2472-
-- If current active buffer is not a normal buffer we find a suitable window with a tab otherwise opening a new split
2473-
if current_buftype ~= '' or not current_buf_modifiable then
2482+
local current_winfixbuf = window_has_winfixbuf(current_win)
2483+
2484+
-- If the current window can't host a new buffer (special buftype, non-modifiable,
2485+
-- or 'winfixbuf' locking it), retarget a suitable window or fall back to a split.
2486+
-- Without this, :edit raises E1513 ("Cannot switch buffer. 'winfixbuf' is enabled")
2487+
-- whenever the picker is invoked from a window pinned via :h winfixbuf.
2488+
local opened_via_split = false
2489+
if current_buftype ~= '' or not current_buf_modifiable or current_winfixbuf then
24742490
local suitable_win = find_suitable_window()
2475-
if suitable_win then vim.api.nvim_set_current_win(suitable_win) end
2491+
if suitable_win then
2492+
vim.api.nvim_set_current_win(suitable_win)
2493+
elseif current_winfixbuf then
2494+
vim.cmd('split ' .. vim.fn.fnameescape(relative_path))
2495+
opened_via_split = true
2496+
end
24762497
end
24772498

2478-
vim.cmd('edit ' .. vim.fn.fnameescape(relative_path))
2499+
if not opened_via_split then vim.cmd('edit ' .. vim.fn.fnameescape(relative_path)) end
24792500
elseif action == 'split' then
24802501
vim.cmd('split ' .. vim.fn.fnameescape(relative_path))
24812502
elseif action == 'vsplit' then

0 commit comments

Comments
 (0)