diff options
author | Mathias Fußenegger <mfussenegger@users.noreply.github.com> | 2022-11-19 10:48:49 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-19 10:48:49 +0100 |
commit | af204dd0f193c3cd3154156c9f9fd40199b840c6 (patch) | |
tree | 9edb14530ecad40c0d60b114ceeb0424af902ba8 /runtime/lua/vim/lsp/handlers.lua | |
parent | 0958dccc6ddeca2e4ab36c1a0f444d2d5995ae99 (diff) | |
download | rneovim-af204dd0f193c3cd3154156c9f9fd40199b840c6.tar.gz rneovim-af204dd0f193c3cd3154156c9f9fd40199b840c6.tar.bz2 rneovim-af204dd0f193c3cd3154156c9f9fd40199b840c6.zip |
feat(lsp): run handler in coroutine to support async response (#21026)
To illustrate a use-case this also changes `window/showMessageRequest`
to use `vim.ui.select`
Diffstat (limited to 'runtime/lua/vim/lsp/handlers.lua')
-rw-r--r-- | runtime/lua/vim/lsp/handlers.lua | 44 |
1 files changed, 30 insertions, 14 deletions
diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index c648a53555..c80adc6a87 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -81,22 +81,38 @@ M['window/workDoneProgress/create'] = function(_, result, ctx) end --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#window_showMessageRequest +---@param result lsp.ShowMessageRequestParams M['window/showMessageRequest'] = function(_, result) - local actions = result.actions - print(result.message) - local option_strings = { result.message, '\nRequest Actions:' } - for i, action in ipairs(actions) do - local title = action.title:gsub('\r\n', '\\r\\n') - title = title:gsub('\n', '\\n') - table.insert(option_strings, string.format('%d. %s', i, title)) - end - - -- window/showMessageRequest can return either MessageActionItem[] or null. - local choice = vim.fn.inputlist(option_strings) - if choice < 1 or choice > #actions then - return vim.NIL + local actions = result.actions or {} + local co, is_main = coroutine.running() + if co and not is_main then + local opts = { + prompt = result.message .. ': ', + format_item = function(action) + return (action.title:gsub('\r\n', '\\r\\n')):gsub('\n', '\\n') + end, + } + vim.ui.select(actions, opts, function(choice) + -- schedule to ensure resume doesn't happen _before_ yield with + -- default synchronous vim.ui.select + vim.schedule(function() + coroutine.resume(co, choice or vim.NIL) + end) + end) + return coroutine.yield() else - return actions[choice] + local option_strings = { result.message, '\nRequest Actions:' } + for i, action in ipairs(actions) do + local title = action.title:gsub('\r\n', '\\r\\n') + title = title:gsub('\n', '\\n') + table.insert(option_strings, string.format('%d. %s', i, title)) + end + local choice = vim.fn.inputlist(option_strings) + if choice < 1 or choice > #actions then + return vim.NIL + else + return actions[choice] + end end end |