unify async/sync interface when wrapping functions
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 25/100
Research direction
Start with the plenary.async entry point and the luv file-system operations documentation linked in the issue. Compare the return conventions used by vim.loop and plenary.async. Done means a wrapped file-reading function can be called from both coroutine and non-coroutine contexts with consistent error handling.
Written by the indexing model from the issue text.
Description
Suppose I'm writing a function that reads the contents of a file. If called from an asynchronous context (in a coroutine), I want the code to be asynchronous, and likewise if called in a synchronous context (not in a coroutine).
-- This version only works in async mode (coroutine.running() ~= nil)
local function readfile(path)
local uv = coroutine.running() and require("plenary.async").uv or vim.loop
-- Functions return err, retval.
local err, fd = uv.fs_open(path, "r", 438)
assert(not err, err)
local err, stat = uv.fs_fstat(fd)
assert(not err, err)
local err, data = uv.fs_read(fd, stat.size, 0)
assert(not err, err)
local err = uv.fs_close(fd)
assert(not err, err)
return data
end
Right now, the readfile function only works when calling in an async context. E.g.:
local a = require("plenary/async")
a.run(function()
local data = readfile("myfile.txt")
parse_my_data(data)
end)
It does not work in a synchronous context because vim.loop.fs_open and friends return a single return value (fd or error). I have a preference for the vanilla version because error-checking can be put on the same line:
-- This version only works in sync mode (coroutine.running() == nil)
local function readfile(path)
local uv = coroutine.running() and require("plenary.async").uv or vim.loop
-- Functions return "retval or err"
local fd = assert(uv.fs_open(path, "r", 438))
local stat = assert(uv.fs_fstat(fd))
local data = assert(uv.fs_read(fd, stat.size, 0))
assert(uv.fs_close(fd))
return data
end
I'm sure there's a reasoning behind the current approach and why it's hard, but I'd like to ask whether it's possible to do so. Perhaps this won't be an issue anymore if https://github.com/luvit/luv/pull/618 ever becomes a thing and Neovim starts running things in a coroutine by default.
On closer inspection the dichotomy is likely due to how the callback/async version of the luv calls themselves pass err, args: https://github.com/luvit/luv/blob/master/docs.md#file-system-operations.
- Dominant language
- Lua
- Stars
- 3.5k
- Forks
- 340
- PR merge metrics
- No merged PRs in 30d
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from nvim-lua/plenary.nvim
-
Difficulty 1/5 Under an hour Newbie friendliness 88/100
nvim-lua/plenary.nvim#682 ·
-
Difficulty 1/5 Under an hour Newbie friendliness 72/100
nvim-lua/plenary.nvim#680 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 45/100
nvim-lua/plenary.nvim#675 ·
-
Difficulty 4/5 3-5 days Newbie friendliness 28/100
nvim-lua/plenary.nvim#672 · 1 comment ·
-
Difficulty 4/5 3-5 days Newbie friendliness 25/100
nvim-lua/plenary.nvim#671 · 1 comment ·
All issues in nvim-lua/plenary.nvim
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
Difficulty 1/5 Under an hour Newbie friendliness 94/100
codymikol/multiverse.nvim#320 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
-
Good First Issue
Difficulty 1/5 1-3 hours Newbie friendliness 78/100
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 84/100