Skip to content

Commit 4f70778

Browse files
committed
fix: vimcmd_entry regressions
1 parent b7aaca9 commit 4f70778

1 file changed

Lines changed: 69 additions & 58 deletions

File tree

lua/fzf-lua/actions.lua

Lines changed: 69 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -140,15 +140,13 @@ M.resume = function(_, _)
140140
end
141141

142142
local edit_entry = function(entry, fullpath, will_replace_curbuf, opts)
143-
-- URI entries only execute new buffers (new|vnew|tabnew)
144-
-- and later use `utils.jump_to_location` to load the buffer
145-
local bufnr = (function()
146-
-- Is the requested buffer is already loaded by the (split) command?
147-
local curbuf = vim.api.nvim_win_get_buf(0)
148-
local curbname = vim.api.nvim_buf_get_name(curbuf)
149-
if entry.bufnr == curbuf or path.equals(curbname, fullpath) then return end
150-
-- Entry already contains bufnr
151-
if entry.bufnr then return entry.bufnr end
143+
local curbuf = vim.api.nvim_win_get_buf(0)
144+
local curbname = vim.api.nvim_buf_get_name(curbuf)
145+
if entry.bufnr == curbuf or path.equals(curbname, fullpath) then
146+
-- requested buffer already loaded in the current window (split?)
147+
return true
148+
end
149+
local bufnr = entry.bufnr or (function()
152150
-- Always open files relative to the current win/tab cwd (#1854)
153151
-- We normalize the path or Windows will fail with directories starting
154152
-- with special characters, for example "C:\app\(web)" will be translated
@@ -158,39 +156,40 @@ local edit_entry = function(entry, fullpath, will_replace_curbuf, opts)
158156
if bufnr == 0 and not opts.silent then
159157
utils.warn("Unable to add buffer %s", relpath)
160158
return
161-
else
162-
vim.bo[bufnr].buflisted = true
163-
return bufnr
164159
end
160+
vim.bo[bufnr].buflisted = true
161+
return bufnr
165162
end)()
166-
if tonumber(bufnr) then
167-
-- If current buffer is an unnamed empty buffer (e.g. "new"), wipe on switch
168-
if will_replace_curbuf
169-
and vim.bo.buftype == ""
170-
and vim.bo.filetype == ""
171-
and vim.api.nvim_buf_line_count(0) == 1
172-
and vim.api.nvim_buf_get_lines(0, 0, -1, false)[1] == ""
173-
and vim.api.nvim_buf_get_name(0) == ""
174-
then
175-
vim.bo.bufhidden = "wipe"
176-
end
177-
-- NOTE: nvim_set_current_buf will load the buffer if needed
178-
-- calling bufload will mess up `BufReadPost` autocmds
179-
-- vim.fn.bufload(bufnr)
180-
local ok, _ = pcall(vim.api.nvim_set_current_buf, bufnr)
181-
-- When `:set nohidden && set confirm`, neovim will invoke the save dialog
182-
-- and confirm with the user when trying to switch from a dirty buffer, if
183-
-- user cancelles the save dialog pcall will fail with:
184-
-- Vim:E37: No write since last change (add ! to override)
185-
if not ok then return end
163+
-- abort if we're unable to load the buffer
164+
if not tonumber(bufnr) then return end
165+
-- wipe unnamed empty buffers (e.g. "new") on switch
166+
if will_replace_curbuf
167+
and vim.bo.buftype == ""
168+
and vim.bo.filetype == ""
169+
and vim.api.nvim_buf_line_count(0) == 1
170+
and vim.api.nvim_buf_get_lines(0, 0, -1, false)[1] == ""
171+
and vim.api.nvim_buf_get_name(0) == ""
172+
then
173+
vim.bo.bufhidden = "wipe"
186174
end
175+
-- NOTE: nvim_set_current_buf will load the buffer if needed
176+
-- calling bufload will mess up `BufReadPost` autocmds
177+
-- vim.fn.bufload(bufnr)
178+
local ok, _ = pcall(vim.api.nvim_set_current_buf, bufnr)
179+
-- When `:set nohidden && set confirm`, neovim will invoke the save dialog
180+
-- and confirm with the user when trying to switch from a dirty buffer, if
181+
-- user cancelles the save dialog pcall will fail with:
182+
-- Vim:E37: No write since last change (add ! to override)
183+
if not ok then return end
184+
return true
187185
end
188186

189187
---@param vimcmd string
190188
---@param selected string[]
191189
---@param opts fzf-lua.Config
190+
---@param bufedit boolean?
192191
---@return string?
193-
M.vimcmd_entry = function(vimcmd, selected, opts)
192+
M.vimcmd_entry = function(vimcmd, selected, opts, bufedit)
194193
for i, sel in ipairs(selected) do
195194
(function()
196195
-- Lua 5.1 goto compatiblity hack (function wrap)
@@ -210,38 +209,54 @@ M.vimcmd_entry = function(vimcmd, selected, opts)
210209
-- technically we should never get to the `uv.cwd()` fallback
211210
fullpath = path.join({ opts.cwd or opts._cwd or uv.cwd(), fullpath })
212211
end
213-
local is_buf_edit = opts._is_buf_edit
214212
-- Can't be called from term window (for example, "reload" actions) due to
215213
-- nvim_exec2(): Vim(normal):Can't re-enter normal mode from terminal mode
216214
-- NOTE: we do not use `opts.__CTX.bufnr` as caller might be the fzf term
217215
if not utils.is_term_buffer(0) then
218216
vim.cmd("normal! m`")
219217
end
220-
if not is_buf_edit then
221-
local relpath = path.normalize(path.relative_to(fullpath, uv.cwd()))
222-
vim.cmd(("%s %s"):format(vimcmd, relpath))
223-
elseif not entry.uri then
224-
-- <auto> (without prefix, formerly `:b|e`) replace the current buffer
225-
local will_replace_curbuf = #vimcmd == 0
226-
if will_replace_curbuf and utils.wo.winfixbuf then
227-
utils.warn("'winfixbuf' is set for current window, will open in a split.")
228-
vimcmd, will_replace_curbuf = "split", false
218+
if bufedit then
219+
local will_replace_curbuf = (function()
220+
if #vimcmd > 0 then return false end
221+
local curbuf = vim.api.nvim_win_get_buf(0)
222+
local curbname = vim.api.nvim_buf_get_name(curbuf)
223+
if entry.bufnr == curbuf or path.equals(curbname, fullpath) then
224+
-- requested buffer already loaded in the current window (split?)
225+
return false
226+
end
227+
return true
228+
end)()
229+
if will_replace_curbuf then
230+
if utils.wo.winfixbuf then
231+
utils.warn("'winfixbuf' is set for current window, will open in a split.")
232+
vimcmd, will_replace_curbuf = "split", false
233+
elseif not vim.o.hidden
234+
and not vim.o.confirm
235+
and utils.buffer_is_dirty(vim.api.nvim_get_current_buf(), true) then
236+
return
237+
end
229238
end
230239
if #vimcmd > 0 then vim.cmd(vimcmd) end
231-
edit_entry(entry, fullpath, will_replace_curbuf, opts)
240+
-- NOTE: URI entries only execute new buffers (new|vnew|tabnew)
241+
-- and later use `utils.jump_to_location` to load the buffer
242+
if not entry.uri and not edit_entry(entry, fullpath, will_replace_curbuf, opts) then
243+
-- error loading buffer or save dialog cancelled
244+
return
245+
end
246+
else
247+
local relpath = path.normalize(path.relative_to(fullpath, uv.cwd()))
248+
vim.cmd(("%s %s"):format(vimcmd, relpath))
232249
end
233250
-- Reload actions from fzf's (buf/arg del, etc) window end here
234251
if utils.is_term_buffer(0) and vim.bo.ft == "fzf" then
235252
return
236253
end
237254
-- Java LSP entries, 'jdt://...' or LSP locations
238255
if entry.uri then
239-
if utils.is_term_bufname(entry.uri) then
240-
-- nvim_exec2(): Vim(normal):Can't re-enter normal mode from terminal mode
241-
pcall(utils.jump_to_location, entry, "utf-16", opts.reuse_win)
242-
else
243-
utils.jump_to_location(entry --[[@as lsp.Location]], "utf-16", opts.reuse_win)
244-
end
256+
-- pcall for two failed cases
257+
-- (1) nvim_exec2(): Vim(normal):Can't re-enter normal mode from terminal mode
258+
-- (2) save dialog cancellation
259+
pcall(utils.jump_to_location, entry, "utf-16", opts.reuse_win)
245260
elseif entry.ctag and entry.line == 0 then
246261
vim.api.nvim_win_set_cursor(0, { 1, 0 })
247262
vim.fn.search(entry.ctag, "W")
@@ -263,27 +278,23 @@ end
263278

264279
-- file actions
265280
M.file_edit = function(selected, opts)
266-
opts._is_buf_edit = true
267-
M.vimcmd_entry("", selected, opts)
281+
M.vimcmd_entry("", selected, opts, true)
268282
end
269283

270284
M.file_split = function(selected, opts)
271-
opts._is_buf_edit = true
272-
M.vimcmd_entry("split", selected, opts)
285+
M.vimcmd_entry("split", selected, opts, true)
273286
end
274287

275288
M.file_vsplit = function(selected, opts)
276-
M.vimcmd_entry("vsplit", selected, opts)
289+
M.vimcmd_entry("vsplit", selected, opts, true)
277290
end
278291

279292
M.file_tabedit = function(selected, opts)
280293
-- local vimcmd = "tab split | <auto>"
281-
opts._is_buf_edit = true
282-
M.vimcmd_entry("tabnew | setlocal bufhidden=wipe", selected, opts)
294+
M.vimcmd_entry("tabnew | setlocal bufhidden=wipe", selected, opts, true)
283295
end
284296

285297
M.file_open_in_background = function(selected, opts)
286-
opts._is_buf_edit = true
287298
M.vimcmd_entry("badd", selected, opts)
288299
end
289300

0 commit comments

Comments
 (0)