@@ -140,15 +140,13 @@ M.resume = function(_, _)
140140end
141141
142142local 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
187185end
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
265280M .file_edit = function (selected , opts )
266- opts ._is_buf_edit = true
267- M .vimcmd_entry (" " , selected , opts )
281+ M .vimcmd_entry (" " , selected , opts , true )
268282end
269283
270284M .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 )
273286end
274287
275288M .file_vsplit = function (selected , opts )
276- M .vimcmd_entry (" vsplit" , selected , opts )
289+ M .vimcmd_entry (" vsplit" , selected , opts , true )
277290end
278291
279292M .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 )
283295end
284296
285297M .file_open_in_background = function (selected , opts )
286- opts ._is_buf_edit = true
287298 M .vimcmd_entry (" badd" , selected , opts )
288299end
289300
0 commit comments