Skip to content

Commit

Permalink
chore(doc): automatic vimdoc update (#3)
Browse files Browse the repository at this point in the history
Co-authored-by: s1n7ax <s1n7ax@users.noreply.github.com>
  • Loading branch information
github-actions[bot] and s1n7ax authored Mar 31, 2024
1 parent c268e8f commit c8d9dd1
Showing 1 changed file with 66 additions and 84 deletions.
150 changes: 66 additions & 84 deletions doc/lua-async-await.txt
Original file line number Diff line number Diff line change
@@ -1,133 +1,115 @@
*lua-async-await.txt* For Neovim >= 0.9.4 Last change: 2023 December 10
*lua-async-await.txt* For Neovim >= 0.9.4 Last change: 2024 March 31

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

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

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

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

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

WHAT *lua-async-await-what*

WHY? *lua-async-await-why?*
Take a look at before and after

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

Ex:-
**Before:**

>lua
self.client.request('workspace/executeCommand', cmd_info, function(err, res)
request('workspace/executeCommand', cmd_info, function(err, res)
if err then
log.error(command .. ' failed! arguments: ', arguments, ' error: ', err)
log.error(err)
else
log.debug(command .. ' success! response: ', res)
log.debug(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.
**After:**

>lua
-- on error, statement will fail throwing an error just like any synchronous API
local result = request('workspace/executeCommand', cmd_info, buffer)
log.debug(result)
<


So I wanted Promise like error handling but without Promises.
WHY *lua-async-await-why*

Well, callback creates callback hell.

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

Assume following is the asynchronous API
HOW TO USE *lua-async-await-how-to-use*

>lua
local function lsp_request(callback)
local runner = require("async.runner")
local wrap = require("async.wrap")
local wait = require("async.waits.wait_with_error_handler")

local function success_async(callback)
local timer = vim.loop.new_timer()

assert(timer)

timer:start(2000, 0, function()
-- First parameter is the error
callback('something went wrong', nil)
callback(nil, "hello world")
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 function fail_async(callback)
local timer = vim.loop.new_timer()

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

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

Result:

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


WHEN NESTED ~

>lua
local M = require('sync')
end

local nested = M.sync(function()
local response = M.wait_handle_error(M.wrap(lsp_request)())
end)
local function log(message)
vim.print(os.date("%H:%M:%S") .. " " .. message)
end

vim.cmd.messages("clear")

M.sync(function()
M.wait_handle_error(nested.run)
local nested = runner(function()
local success_sync = wrap(success_async)
local fail_sync = wrap(fail_async)

local success_result = wait(success_sync())
-- here we get the result because there is no error
log("success_result is: " .. success_result)

-- following is going to fail and error will get caught by
-- the parent runner function's 'catch'
wait(fail_sync())
end)

runner(function()
log("starting the execution")
-- just wait for nested runner to complete the execution
wait(nested.run)
end)
.catch(function(err)
print('parent error handler ' .. err)
log("parent error handler " .. err)
end)
.run()
<

Result:

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

>txt
18:44:46 starting the execution
18:44:48 success_result is: hello world
18:44:50 parent error handler ...-async-await/lua/async/waits/wait_with_error_handler.lua:14: ...-async-await/lua/async/waits/wait_with_error_handler.lua:14: something went wrong
<

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

0 comments on commit c8d9dd1

Please sign in to comment.