stevearc / dressing.nvim

Neovim plugin to improve the default vim.ui interfaces
MIT License
1.7k stars 32 forks source link

vim.ui.input should block to wait user input when more than one vim.ui.xxx #80

Closed 3Xpl0it3r closed 1 year ago

3Xpl0it3r commented 1 year ago

Describe the bug Is there any way to block vim.ui.input to wait user complete input, then there more than one vim.ui.xxxx in lua. In this case first vim.ui.input will skip user input directory step into vim.wait code and finally step into vim.ui.select

System information

    local done = false
    vim.ui.input({ prompt = "hehe" }, function(input)
        -- do some thing
        done = true
    end)
    local i = 0
    -- Waits 1000ms, then repeats every 750ms until timer:close().
    vim.wait(10000, function()
        return done == true
    end)

    vim.ui.select(crate_fuz_list, { prompt = "select one" }, function(crate_choice)
        if not crate_choice then
            return
        end
    end)
stevearc commented 1 year ago

Sorry, that's just not how this code works. vim.fn.input is synchronous and blocking, so you are guaranteed that all code following that call will run after the user has completed the input. vim.ui.input, on the other hand, is asynchronous. Calling it kicks off the input request to the user (by opening a floating window), but the code following that function call will run more or less immediately. If you want to know when the user has completed the input, that's what the callback is for.

The benefits of async are that you can perform operations without completely freezing vim's UI. The downside is that once you have one async function, everything above it in the stack also has to be async.

The way to structure your code above to run one after another is like this:

vim.ui.input({ prompt = "hehe" }, function(input)
  -- Do something here
  vim.ui.select(crate_fuz_list, { prompt = "select one" }, function(crate_choice)
    -- Do something else
  end)
end)