-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Provide an async api to work with other plugin like asyncomplete.vim #76
Comments
Hey, thanks for the interest. I'll see what I can do 👍 |
Here is my take on this. (this is me writing without actually trying it and by glancing at tmux-complete.vim source, so there could be bugs here) Here is what the asyncomplete source would look like. You might want to have another parameter to detect if there is an error or not. function s:completor(opt, ctx)
call tmuxcomplete#get_async_completions({ candidates, startcol -> asyncomplete#complete(a:opt['name'], a:ctx, startcol, candidates) })
endfunction
call asyncomplete#register_source({
\ 'name': 'tmuxcomplete',
\ 'whitelist': [*],
\ 'completor': function('s:completor'),
\ }) Here is what the async completions for tmux complete would look like. I'm using async.vim to normalize jobs between vim8 and neovim. If you want to avoid external plugin dependency you can also embed async.vim in your plugin https://github.com/prabirshrestha/async.vim#embedding function! tmuxcomplete#get_async_completions(cb) abort
let l:cmd = tmuxcomplete#getcommand('', 'words')
let l:opt = {
\ 'callback': a:cb,
\ 'buffer': '',
\ 'startcol': tmuxcomplete#complete(1, '')
\ }
let l:jobid = async#jobs#start({
\ 'cmd': l:cmd,
\ 'on_stdout': function('s:on_stdout', [l:opt]),
\ 'on_exit': function('s:on_exit', [l:opt]),
\ })
" if l:jobid is <= 0 failed to start job
endfunction
function! s:on_stdout(opt, id, data, event) abort
let l:opt['buffer'] = l:opt['buffer'] . join(a:data, "\n")
endfunction
function! s:on_exit(opt, id, exitCode, event) abort
" handle bad exit code
call a:opt['callback'](split(a:buffer, "\n"), l:opt['startcol'])
endfunction There are other optimizations you could do. If you know your command always splits candidates based on |
@prabirshrestha: Wow, thanks for stepping in! I did look at some of your plugins and documentation on Tuesday to see how this would be done. I have to say they all looked really good and I think I found the pieces I would have needed. I will try to look into this over the weekend, thank you very much 👍 |
@prabirshrestha: Thanks again! I took your suggestion and made some changes and got it working. Please have a look at #77. 🙏 Btw, one thing I noticed in its current stage. In a buffer, when I insert a single I suspect that asyncomplete triggers autocompletion on the first character I enter. If I enter the next one before the first completion suggestions come in, that job gets aborted, but it seems like no new job for the new prefix is triggered. I tried similar things with the gocode completion and couldn't manage to reproduce the issue there. Maybe they are just quick enough with their suggestions, or is there any sort of option I might be missing? Let me know if you'd want me to open an issue about this in your asyncomplete.vim repo. I just want to check here quickly in case I'm missing something simple. |
@wellle What you experienced is actually the current feature of asyncomplete.vim and not purely a bug. It is a known issue that I would like to solve in the near future.
Yes.
Partially correct.
when you call If you really do want to call your completor function on every prefix change it is possible too. If you are interested in reading more about the algorithm you can read more of it at roxma/nvim-completion-manager#30 (comment) |
@prabirshrestha: Thanks for all that information, that's very helpful! I tried the suggested When I tested I did actually have
I did however find a hack that seems to make it work: If in my completor I add this line before actually starting the async job (04d2aa7): call asyncomplete#complete(a:opt['name'], a:ctx, l:startcol, [''], 1) Then, even in the case where I type very quickly, the results show up in the end. So I guess by sending a first completion (empty, doesn't match anything) I open the door to send more completions later, even if the context changed in between. Seeing that this works, I wonder if asyncomplete couldn't take care of this itself? I mean it could add this first empty completion on its own (as incomplete set) to make this case work. But I imagine there must be a cleaner way to set up the internal structure than this hack. |
You guys are so nice. Thanks a lot. : ) |
@wellle Seems like could be a bug in asyncomplete. The source code is quite small so feel free to have a look at it there. All async vim autocomplete plugins are currently based of timer hacks, so it could also be an issue with timing. What if you set the
Assume function! asyncomplete#context_changed(ctx) abort
" return (b:changedtick!=a:ctx['changedtick']) || (getcurpos()!=a:ctx['curpos'])
" Note: changedtick is triggered when `<c-x><c-u>` is pressed due to vim's
" bug, use curpos as workaround
return getcurpos() != a:ctx['curpos']
endfunction |
@prabirshrestha: Thanks! I just tried |
I want to make tmux-complete.vim work with asyncomplete.vim, but there is no document about it. Thanks to @prabirshrestha, he mentioned that it would be better for tmux-complete.vim to have an an async api so that tmux-complete.vim could work asynchronously. So I am wondering wether you could offer an async api in tmux-complete.vim as mentioned here. Thanks a lot.
The text was updated successfully, but these errors were encountered: