fix(picker): vim.ui.select callback is called when canceling selection (#1115)

## Description

From the docs on `:help vim.ui.select`
```
      • {on_choice}  (`fun(item: any?, idx: integer?)`) Called once the user
                     made a choice. `idx` is the 1-based index of `item`
                     within `items`. `nil` if the user aborted the dialog.
```

Right now the behavior will call `on_choice` if the user confirmed a
selection, but will not be called at all if the user explicitly or
implicitly closes the picker. As a plugin author, I rely on the
guarantee that if I call `vim.ui.select`, the callback _will_ be called
either with a value or with a nil.

I just added the simplest, dumbest possible fix for this that prevents
double-calling the callback.

## Related Issue(s)

N/A

## Screenshots

N/A
This commit is contained in:
Steven Arcangeli 2025-02-13 08:52:20 -08:00 committed by GitHub
parent e5960d8e32
commit 4c3bfa29f3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -24,6 +24,7 @@ function M.select(items, opts, on_choice)
local title = opts.prompt or "Select"
title = title:gsub("^%s*", ""):gsub("[%s:]*$", "")
local completed = false
---@type snacks.picker.finder.Item[]
return Snacks.picker.pick({
@ -39,12 +40,23 @@ function M.select(items, opts, on_choice)
},
actions = {
confirm = function(picker, item)
if completed then
return
end
completed = true
picker:close()
vim.schedule(function()
on_choice(item and item.item, item and item.idx)
end)
end,
},
on_close = function()
if completed then
return
end
completed = true
vim.schedule(on_choice)
end,
})
end