From 59ff4691f67fc1ddd3d1b7240a2f2eb095e58281 Mon Sep 17 00:00:00 2001 From: Jongwook Choi Date: Mon, 7 Nov 2022 19:15:15 -0500 Subject: fix(vim.ui.input): return empty string when inputs nothing (#20883) fix(vim.ui.input): return empty string when inputs nothing The previous behavior of `vim.ui.input()` when typing with no text input (with an intention of having the empty string as input) was to execute `on_confirm(nil)`, conflicting with its documentation. Inputting an empty string should now correctly execute `on_confirm('')`. This should be clearly distinguished from cancelling or aborting the input UI, in which case `on_confirm(nil)` is executed as before. --- test/functional/lua/ui_spec.lua | 46 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'test/functional/lua/ui_spec.lua') diff --git a/test/functional/lua/ui_spec.lua b/test/functional/lua/ui_spec.lua index 3fcb2dec8d..8f9d8e0f72 100644 --- a/test/functional/lua/ui_spec.lua +++ b/test/functional/lua/ui_spec.lua @@ -83,5 +83,51 @@ describe('vim.ui', function() feed('abcdefg') eq('abcdefg', exec_lua('return result')) end) + + it('can input empty text #18144', function() + feed(':lua vim.ui.input({}, function(input) result = input end)') + feed('') + eq('', exec_lua('return result')) + end) + + it('can input empty text with cancelreturn opt #18144', function() + feed(':lua vim.ui.input({ cancelreturn = "CANCEL" }, function(input) result = input end)') + feed('') + eq('', exec_lua('return result')) + end) + + it('can return nil when aborted with ESC #18144', function() + feed(':lua result = "on_confirm not called"') + feed(':lua vim.ui.input({}, function(input) result = input end)') + feed('Inputted Text') + -- Note: When `result == nil`, exec_lua('returns result') returns vim.NIL + eq(true, exec_lua('return (nil == result)')) + end) + + it('can return opts.cacelreturn when aborted with ESC with cancelreturn opt #18144', function() + feed(':lua result = "on_confirm not called"') + feed(':lua vim.ui.input({ cancelreturn = "CANCEL" }, function(input) result = input end)') + feed('Inputted Text') + eq('CANCEL', exec_lua('return result')) + end) + + it('does not call on_confirm when interrupted with Ctrl-C #18144', function() + feed(':lua result = "on_confirm not called"') + eq('on_confirm not called', exec_lua('return result')) + feed(':lua vim.ui.input({}, function(input) result = input end)') + feed('Inputted Text') + -- Ctrl-C would make vim.ui.input() throw, so `result = input` won't be executed + eq('on_confirm not called', exec_lua('return result')) + end) + + it('can return the identical object when an arbitrary opts.cancelreturn object is given', function() + feed(':lua fn = function() return 42 end') + eq(42, exec_lua('return fn()')) + feed(':lua vim.ui.input({ cancelreturn = fn }, function(input) result = input end)') + feed('cancel') + eq(true, exec_lua('return (result == fn)')) + eq(42, exec_lua('return result()')) + end) + end) end) -- cgit From b3f781ba912b0d24896d85fc8434faaedfddfeb2 Mon Sep 17 00:00:00 2001 From: Steven Arcangeli <506791+stevearc@users.noreply.github.com> Date: Sat, 12 Nov 2022 06:57:35 -0800 Subject: fix: vim.ui.input always calls callback #21006 Followup to #20883 Related: #18144 This patch changes the behavior of the default `vim.ui.input` when the user aborts with ``. Currently, it produces an error message + stack and causes `on_confirm` to not be called. With this patch, `` will cause `on_confirm` to be called with `nil`, the same behavior as when the user aborts with ``. I can think of three good reasons why the behavior should be this way: 1. Easier for the user to understand** It's not intuitive for there to be two ways to abort an input dialog that have _different_ outcomes. As a user, I would expect any action that cancels the input to leave me in the same state. As a plugin author, I see no value in having two possible outcomes for aborting the input. I have to handle both cases, but I can't think of a situation where I would want to treat one differently than the other. 2. Provides an API that can be overridden by other implementations** The current contract of "throw an error upon ``" cannot be replicated by async implementations of `vim.ui.input`. If the callsite wants to handle the case of the user hitting `` they need to use `pcall(vim.ui.input, ...)`, however an async implementation will instantly return and so there will be no way for it to produce the same error-throwing behavior when the user inputs ``. This makes it impossible to be fully API-compatible with the built-in `vim.ui.input`. 3. Provides a useful guarantee to the callsite** As a plugin author, I want the guarantee that `on_confirm` will _always_ be called (only catastrophic errors should prevent this). If I am in the middle of some async thread of logic, I need some way to resume that logic after handing off control to `vim.ui.input`. The only way to handle the `` case is with `pcall`, which as already mentioned, breaks down if you're using an alternative implementation. --- test/functional/lua/ui_spec.lua | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'test/functional/lua/ui_spec.lua') diff --git a/test/functional/lua/ui_spec.lua b/test/functional/lua/ui_spec.lua index 8f9d8e0f72..c34d947b8b 100644 --- a/test/functional/lua/ui_spec.lua +++ b/test/functional/lua/ui_spec.lua @@ -111,13 +111,11 @@ describe('vim.ui', function() eq('CANCEL', exec_lua('return result')) end) - it('does not call on_confirm when interrupted with Ctrl-C #18144', function() + it('can return nil when interrupted with Ctrl-C #18144', function() feed(':lua result = "on_confirm not called"') - eq('on_confirm not called', exec_lua('return result')) feed(':lua vim.ui.input({}, function(input) result = input end)') feed('Inputted Text') - -- Ctrl-C would make vim.ui.input() throw, so `result = input` won't be executed - eq('on_confirm not called', exec_lua('return result')) + eq(true, exec_lua('return (nil == result)')) end) it('can return the identical object when an arbitrary opts.cancelreturn object is given', function() -- cgit From e7ba5ba3cd8e426d07a8359a3d85a62b095faf61 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 13 Nov 2022 08:16:06 +0800 Subject: test(lua/ui_spec): fix Ctrl-C test flakiness (#21039) Prevent Ctrl-C from flushing the command that starts the prompt. --- test/functional/lua/ui_spec.lua | 2 ++ 1 file changed, 2 insertions(+) (limited to 'test/functional/lua/ui_spec.lua') diff --git a/test/functional/lua/ui_spec.lua b/test/functional/lua/ui_spec.lua index c34d947b8b..9ee99b4905 100644 --- a/test/functional/lua/ui_spec.lua +++ b/test/functional/lua/ui_spec.lua @@ -4,6 +4,7 @@ local exec_lua = helpers.exec_lua local clear = helpers.clear local feed = helpers.feed local eval = helpers.eval +local poke_eventloop = helpers.poke_eventloop describe('vim.ui', function() before_each(function() @@ -114,6 +115,7 @@ describe('vim.ui', function() it('can return nil when interrupted with Ctrl-C #18144', function() feed(':lua result = "on_confirm not called"') feed(':lua vim.ui.input({}, function(input) result = input end)') + poke_eventloop() -- This is needed because Ctrl-C flushes input feed('Inputted Text') eq(true, exec_lua('return (nil == result)')) end) -- cgit