From 81a771570ef1ba177105c8eb2878e327cf3855bb Mon Sep 17 00:00:00 2001 From: Evgeni Chasnovski Date: Mon, 25 Nov 2024 12:14:48 +0200 Subject: [PATCH] fix(pick): handle error when choosing item(s) Resolve #1363 --- lua/mini/pick.lua | 13 ++++++++++--- tests/test_pick.lua | 13 +++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/lua/mini/pick.lua b/lua/mini/pick.lua index ddb4697e..7dc7131b 100644 --- a/lua/mini/pick.lua +++ b/lua/mini/pick.lua @@ -2536,7 +2536,11 @@ H.actions = { choose_in_split = function(picker, _) return H.picker_choose(picker, 'split') end, choose_in_tabpage = function(picker, _) return H.picker_choose(picker, 'tabnew') end, choose_in_vsplit = function(picker, _) return H.picker_choose(picker, 'vsplit') end, - choose_marked = function(picker, _) return not picker.opts.source.choose_marked(MiniPick.get_picker_matches().marked) end, + choose_marked = function(picker, _) + local ok, res = pcall(picker.opts.source.choose_marked, MiniPick.get_picker_matches().marked) + if not ok then vim.schedule(function() H.error('Error during choose marked:\n' .. res) end) end + return not (ok and res) + end, delete_char = function(picker, _) H.picker_query_delete(picker, 1) end, delete_char_right = function(picker, _) H.picker_query_delete(picker, 0) end, @@ -2631,8 +2635,11 @@ H.picker_choose = function(picker, pre_command) end) end - -- Returning nothing, `nil`, or `false` should lead to picker stop - return not picker.opts.source.choose(cur_item) + local ok, res = pcall(picker.opts.source.choose, cur_item) + -- Delay error to have time to hide picker window + if not ok then vim.schedule(function() H.error('Error during choose:\n' .. res) end) end + -- Error or returning nothing, `nil`, or `false` should lead to picker stop + return not (ok and res) end H.picker_mark_indexes = function(picker, range_type) diff --git a/tests/test_pick.lua b/tests/test_pick.lua index e9ba6ad9..def953d4 100644 --- a/tests/test_pick.lua +++ b/tests/test_pick.lua @@ -5250,6 +5250,19 @@ T['Choose']['uses output as "should continue"'] = function() validate({ '', '' }) end +T['Choose']['handles error in choose function'] = function() + child.lua_notify([[MiniPick.start({ source = { items = { 'a' }, choose = function() error('Oops!') end } })]]) + expect.error(function() type_keys('') end, 'Error during choose:.*Oops!') + eq(is_picker_active(), false) + eq(#child.api.nvim_list_wins(), 1) + + child.lua_notify([[MiniPick.start({ source = { items = { 'a' }, choose_marked = function() error('Oops!') end } })]]) + type_keys('') + expect.error(function() type_keys('') end, 'Error during choose marked:.*Oops!') + eq(is_picker_active(), false) + eq(#child.api.nvim_list_wins(), 1) +end + T['Mark'] = new_set() T['Mark']['works'] = function()