Skip to content

Commit b56f6ed

Browse files
committed
fix(ui): close picker when last item is deleted
1 parent f185518 commit b56f6ed

1 file changed

Lines changed: 69 additions & 9 deletions

File tree

lua/opencode/ui/base_picker.lua

Lines changed: 69 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ local Promise = require('opencode.promise')
1919
---@field multi_selection? table<string, boolean> Actions that support multi-selection
2020
---@field preview? "file"|"none"|false Preview mode: "file" for file preview, "none" or false to disable
2121
---@field layout_opts? OpencodeUIPickerConfig
22+
---@field close? fun() Close the picker programmatically (set by the backend)
2223

2324
---@class TelescopeEntry
2425
---@field value any
@@ -147,6 +148,11 @@ local function telescope_ui(opts)
147148
width = opts.width + 7, -- extra space for telescope UI
148149
} or nil,
149150
attach_mappings = function(prompt_bufnr, map)
151+
opts.close = function()
152+
selection_made = true
153+
actions.close(prompt_bufnr)
154+
end
155+
150156
actions.select_default:replace(function()
151157
selection_made = true
152158
local selection = action_state.get_selected_entry()
@@ -197,8 +203,12 @@ local function telescope_ui(opts)
197203
local new_items = action.fn(items_to_process, opts)
198204
Promise.wrap(new_items):and_then(function(resolved_items)
199205
if action.reload and resolved_items then
200-
opts.items = resolved_items
201-
refresh_picker()
206+
if #resolved_items == 0 and opts.close then
207+
opts.close()
208+
else
209+
opts.items = resolved_items
210+
refresh_picker()
211+
end
202212
end
203213
end)
204214
end
@@ -295,9 +305,33 @@ local function fzf_ui(opts)
295305
end)
296306
end
297307

308+
local closed = false
309+
310+
opts.close = function()
311+
if closed then
312+
return
313+
end
314+
closed = true
315+
vim.schedule(function()
316+
local ok, fzf_win = pcall(require, 'fzf-lua.win')
317+
if ok and fzf_win.__SELF then
318+
local win = fzf_win.__SELF()
319+
if win then
320+
win:close()
321+
end
322+
end
323+
if opts.callback then
324+
opts.callback(nil)
325+
end
326+
end)
327+
end
328+
298329
---@type FzfLuaActions
299330
local actions_config = {
300331
['default'] = function(selected, fzf_opts)
332+
if closed then
333+
return
334+
end
301335
if not selected or #selected == 0 then
302336
if opts.callback then
303337
opts.callback(nil)
@@ -310,6 +344,9 @@ local function fzf_ui(opts)
310344
end
311345
end,
312346
['esc'] = function()
347+
if closed then
348+
return
349+
end
313350
if opts.callback then
314351
opts.callback(nil)
315352
end
@@ -346,8 +383,12 @@ local function fzf_ui(opts)
346383
Promise.wrap(new_items):and_then(function(resolved_items)
347384
if action.reload and resolved_items then
348385
---@cast resolved_items any[]
349-
opts.items = resolved_items
350-
refresh_fzf()
386+
if #resolved_items == 0 and opts.close then
387+
opts.close()
388+
else
389+
opts.items = resolved_items
390+
refresh_fzf()
391+
end
351392
end
352393
end)
353394
end
@@ -376,6 +417,10 @@ local function mini_pick_ui(opts)
376417

377418
local mappings = {}
378419

420+
opts.close = function()
421+
mini_pick.stop()
422+
end
423+
379424
for action_name, action in pairs(opts.actions) do
380425
if action.key and action.key[1] then
381426
mappings[action_name] = {
@@ -387,8 +432,12 @@ local function mini_pick_ui(opts)
387432
local new_items = action.fn(current.item, opts)
388433
Promise.wrap(new_items):and_then(function(resolved_items)
389434
if action.reload and resolved_items then
390-
opts.items = resolved_items
391-
mini_pick_ui(opts)
435+
if #resolved_items == 0 and opts.close then
436+
opts.close()
437+
else
438+
opts.items = resolved_items
439+
mini_pick_ui(opts)
440+
end
392441
end
393442
end)
394443
end
@@ -522,6 +571,13 @@ local function snacks_picker_ui(opts)
522571
snack_opts.win.input.keys[action.key[1]] = { action_name, mode = action.key.mode or 'i' }
523572

524573
snack_opts.actions[action_name] = function(_picker, item)
574+
if not opts.close then
575+
opts.close = function()
576+
selection_made = true
577+
_picker:close()
578+
end
579+
end
580+
525581
if item then
526582
local items_to_process
527583
if action.multi_selection then
@@ -540,9 +596,13 @@ local function snacks_picker_ui(opts)
540596
local new_items = action.fn(items_to_process, opts)
541597
Promise.wrap(new_items):and_then(function(resolved_items)
542598
if action.reload and resolved_items then
543-
opts.items = resolved_items
544-
_picker:refresh()
545-
_picker:find()
599+
if #resolved_items == 0 and opts.close then
600+
opts.close()
601+
else
602+
opts.items = resolved_items
603+
_picker:refresh()
604+
_picker:find()
605+
end
546606
end
547607
end)
548608
end)

0 commit comments

Comments
 (0)