Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 135 additions & 0 deletions doc/lua-async-await.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
*lua-async-await.txt* For Neovim >= 0.9.4 Last change: 2023 December 10

==============================================================================
Table of Contents *lua-async-await-table-of-contents*

1. Lua Async Await |lua-async-await-lua-async-await|
- Why? |lua-async-await-why?|
- How to use |lua-async-await-how-to-use|

==============================================================================
1. Lua Async Await *lua-async-await-lua-async-await*

This is basically ms-jpq/lua-async-await
<https://github.com/ms-jpq/lua-async-await> but with Promise like error
handling

Refer the original repository for more comprehensive documentation on how all
this works


WHY? *lua-async-await-why?*

A Language Server command response contains two parameters. `error` &
`response`. If the error is present then the error should be handled.

Ex:-

>lua
self.client.request('workspace/executeCommand', cmd_info, function(err, res)
if err then
log.error(command .. ' failed! arguments: ', arguments, ' error: ', err)
else
log.debug(command .. ' success! response: ', res)
end
end, buffer)
<

Promises are fine but chaining is annoying specially when you don’t have
arrow function like syntactic sugar. Moreover, at the time of this is writing,
Lua language server generics typing is so primitive and cannot handle
`Promise<Something>` like types.

So I wanted Promise like error handling but without Promises.


HOW TO USE *lua-async-await-how-to-use*

Assume following is the asynchronous API

>lua
local function lsp_request(callback)
local timer = vim.loop.new_timer()

assert(timer)

timer:start(2000, 0, function()
-- First parameter is the error
callback('something went wrong', nil)
end)
end
<


WHEN NO ERROR HANDLER DEFINED ~

This is how you can call this asynchronous API without a callback

>lua
local M = require('sync')

M.sync(function()
local response = M.wait_handle_error(M.wrap(lsp_request)())
end).run()
<

Result:

>
Error executing luv callback:
test6.lua:43: unhandled error test6.lua:105: something went wrong
stack traceback:
[C]: in function 'error'
test6.lua:43: in function 'callback'
test6.lua:130: in function <test6.lua:129>
<


WHEN ERROR HANDLER IS DEFINED ~

>lua
local M = require('sync')

local main = M.sync(function()
local response = M.wait_handle_error(M.wrap(lsp_request)())
end)
.catch(function(err)
print('error occurred ', err)
end)
.run()
<

Result:

>
error occurred test6.lua:105: something went wrong
<


WHEN NESTED ~

>lua
local M = require('sync')

local nested = M.sync(function()
local response = M.wait_handle_error(M.wrap(lsp_request)())
end)

M.sync(function()
M.wait_handle_error(nested.run)
end)
.catch(function(err)
print('parent error handler ' .. err)
end)
.run()
<

Result:

>
parent error handler test6.lua:105: test6.lua:105: something went wrong
<

Generated by panvimdoc <https://github.com/kdheepak/panvimdoc>

vim:tw=78:ts=8:noet:ft=help:norl: