Hey guys, does anyone has an idea how hard is it to make competition source for https://github.com/nvim-lua/completion-nvim from conjure?
Should be pretty easy! Here's the deoplete implementation https://github.com/Olical/conjure/blob/master/rplugin/python3/deoplete/sources/conjure.py CoC https://github.com/jlesquembre/coc-conjure/blob/master/index.js asyncomplete https://github.com/thecontinium/asyncomplete-conjure.vim/blob/master/autoload/asyncomplete/sources/conjure.vim
There's essentially a sort of promise implementation in Conjure to make the async work a little easier, you can use a sync complete function that blocks or the true async promise based one (highly recommended!). I would imagine asyncomplete is similar to completion-nvim?
I think yes they are similar, will figure it out and see if I can make minimal working solution
really want to have it with nvim-completition
Sweet! If you do get it working (feel free to ask me some questions if you're really stuck but I think those examples should be enough) let me know and I'll add it to the lists of completion tools.
function M.get_completions(prefix)
local p = eval["completions-promise"](prefix)
while not promise["done?"](p)
do
print("i am waiting") -- **what is the equivalent of time.sleep?**
end
result = promise["close"](p)
local complete_items = {}
for _, item in ipairs(result) do
if item ~= "^" .. prefix then
table.insert(complete_items, {
word = item,
kind = 'conjure',
icase = 1,
dup = 0,
empty = 0,
})
end
end
print(vim.inspect(complete_items))
return complete_items
end
what is the equivalent of time sleep?
for lua code, or what is the proper way of handling async code?
I think you'll have to do something like this but from lua https://github.com/thecontinium/asyncomplete-conjure.vim/blob/master/autoload/asyncomplete/sources/conjure.vim
so you set up a timer then periodically check if the completions are done
Any other method (like sleeping) will block the editor
The reason the deoplete and coc implementations can sleep is because they're run in a separate process so they don't block nvim's ui.
You could actually use the conjure.timer
module or maybe just copy parts of it that you need
(module conjure.timer
{require {a conjure.aniseed.core
nvim conjure.aniseed.nvim}})
(defn defer [f ms]
(let [t (vim.loop.new_timer)]
(t:start ms 0 (vim.schedule_wrap f))
t))
(defn destroy [t]
(when t
(t:stop)
(t:close))
nil)
This uses the vim.loop.*
functions which don't seem to be documented but actually map to libuv functions, so I just googled for "lib uv api" then guessed my way through to using new_timer, start, stop and close.
libuv is great for anything like this
So a combination of using / taking and modifying Conjure's timer module + the lib uv docs should be enough to get a repeating timer running where you can check if the promise is done.
Oh you have to return the results :thinking_face: that's not great, it's not really async in that way then, it's a sync function that they somehow run in an async way? You could try calling eval.completions-sync
or using promise.await
like that function does. I just think this will block neovim's ui which isn't great https://github.com/Olical/conjure/blob/566915cc545edd68bab2ad76eb59dfa43648a8b3/fnl/conjure/eval.fnl#L200-L203
Or maybe there's a way to sleep the process from libuv that I don't really know about.
well yes looks like probably I can use sync api for my code, it is used later using timer, could that be the case
:thinking_face: maybe? I don't really understand the completion-nvim plugin right now, but it's worth checking what sort of APIs they give you. If you can write a callback based async completer (so you call a function when you're done) it'll be easier to check the promise every 5ms or something then call the callback with the results when it's done.
?
https://github.com/nvim-lua/completion-nvim/blob/master/lua/completion/complete.lua