wellle / tmux-complete.vim

Vim plugin for insert mode completion of words in adjacent tmux panes
MIT License
515 stars 21 forks source link

Add support for coc.nvim #84

Closed kabouzeid closed 5 years ago

kabouzeid commented 5 years ago

https://github.com/neoclide/coc.nvim

wellle commented 5 years ago

@kabouzeid: Thank you, I'll review this soon 👍

In the meantime, do you want to update the README too to mention the coc.nvim integration? (I'd suggest to do it similar to the ncm2 one just above ncm2)

kabouzeid commented 5 years ago

Done :)

kabouzeid commented 5 years ago

Thanks, I have tested it and it works 😁. By the way, if you haven’t tried coc yet, I can highly recommend it!

wellle commented 5 years ago

Thank you, I probably will 👍

balta2ar commented 5 years ago

@kabouzeid @chemzqm Please pardon my ignorance, but wouldn't a coc extension implemented in Vimscript block the editor? I thought that in order to make it asyncronous you need to implement it in JS/TS as a coc-extension (https://github.com/neoclide/coc.nvim/wiki/Using-coc-extensions). Again, sorry if my question is silly.

chemzqm commented 5 years ago

but wouldn't a coc extension implemented in Vimscript block the editor?

It use callback in complete function, so it can be implemented in async manner, it's ok to be sync when the completion wouldn't take too long.

balta2ar commented 5 years ago

I've been using this for a while and it looks like it's the main contributor to the delays in my configuration:

$ less /tmp/coc-nvim.log | \grep 'tmuxcomplete" takes'
2019-05-04T20:49:26.933 DEBUG (pid:14927) [completion-complete] - Source "tmuxcomplete" takes 337ms
2019-05-04T20:49:27.249 DEBUG (pid:14927) [completion-complete] - Source "tmuxcomplete" takes 271ms
2019-05-04T20:49:27.598 DEBUG (pid:14927) [completion-complete] - Source "tmuxcomplete" takes 323ms
2019-05-04T20:49:27.942 DEBUG (pid:14927) [completion-complete] - Source "tmuxcomplete" takes 294ms
2019-05-04T20:49:28.258 DEBUG (pid:14927) [completion-complete] - Source "tmuxcomplete" takes 267ms
2019-05-04T20:49:29.025 DEBUG (pid:14927) [completion-complete] - Source "tmuxcomplete" takes 660ms
2019-05-04T20:49:29.729 DEBUG (pid:14927) [completion-complete] - Source "tmuxcomplete" takes 348ms
2019-05-04T20:49:30.122 DEBUG (pid:14927) [completion-complete] - Source "tmuxcomplete" takes 289ms
2019-05-04T20:50:43.289 DEBUG (pid:14927) [completion-complete] - Source "tmuxcomplete" takes 368ms
2019-05-04T20:53:38.589 DEBUG (pid:14927) [completion-complete] - Source "tmuxcomplete" takes 347ms
2019-05-04T20:53:39.878 DEBUG (pid:14927) [completion-complete] - Source "tmuxcomplete" takes 286ms
2019-05-04T20:53:41.880 DEBUG (pid:14927) [completion-complete] - Source "tmuxcomplete" takes 300ms
2019-05-04T20:53:45.175 DEBUG (pid:14927) [completion-complete] - Source "tmuxcomplete" takes 304ms
2019-05-04T20:53:47.880 DEBUG (pid:14927) [completion-complete] - Source "tmuxcomplete" takes 303ms
2019-05-04T20:53:48.234 DEBUG (pid:14927) [completion-complete] - Source "tmuxcomplete" takes 305ms
2019-05-04T20:53:50.340 DEBUG (pid:14927) [completion-complete] - Source "tmuxcomplete" takes 295ms
2019-05-04T20:53:53.490 DEBUG (pid:14927) [completion-complete] - Source "tmuxcomplete" takes 304ms
2019-05-04T20:54:06.194 DEBUG (pid:14927) [completion-complete] - Source "tmuxcomplete" takes 298ms
2019-05-04T20:54:08.450 DEBUG (pid:14927) [completion-complete] - Source "tmuxcomplete" takes 306ms
2019-05-04T20:54:09.233 DEBUG (pid:14927) [completion-complete] - Source "tmuxcomplete" takes 294ms
2019-05-04T20:54:10.093 DEBUG (pid:14927) [completion-complete] - Source "tmuxcomplete" takes 316ms
2019-05-04T20:54:10.800 DEBUG (pid:14927) [completion-complete] - Source "tmuxcomplete" takes 364ms
2019-05-04T23:40:42.595 DEBUG (pid:14927) [completion-complete] - Source "tmuxcomplete" takes 351ms
2019-05-04T23:40:42.966 DEBUG (pid:14927) [completion-complete] - Source "tmuxcomplete" takes 310ms
2019-05-04T23:40:43.350 DEBUG (pid:14927) [completion-complete] - Source "tmuxcomplete" takes 292ms
2019-05-04T23:40:43.954 DEBUG (pid:14927) [completion-complete] - Source "tmuxcomplete" takes 351ms
2019-05-04T23:40:44.283 DEBUG (pid:14927) [completion-complete] - Source "tmuxcomplete" takes 295ms

Unfortunately, such long delays and synchronous updates ruin the experience of using coc and I had to turn this integration off.

It use callback in complete function, so it can be implemented in async manner

I wasn't sure how to do that, so I've knocked up a simple integration as a source implemented in JavaScript:

source code

```js const { sources } = require('coc.nvim') const { spawn } = require('child_process') function onStdoutAvailable(command, args, token, onSuccess) { const child = spawn(command, args) return new Promise((resolve, reject) => { let output = '' let exited = false token.onCancellationRequested(() => { child.kill('SIGHUP') resolve(null) }) child.stdout.on('data', data => { output = output + data.toString() }) child.on('exit', () => { exited = true if (!output) return resolve(null) try { return resolve(onSuccess(output)) } catch (e) { reject(new Error('invalid output from tmuxcomplete ' + e)) } }) setTimeout(() => { if (!exited) { child.kill('SIGHUP') reject(new Error('tmuxcomplete timeout')) } }, 2000) }) } exports.activate = context => { let source = { name: 'tmux', triggerCharacters: [], doComplete: function (opt, token) { if (!opt.input) return Promise.resolve(null) const script = 'sh' const args = ['/home/bz/rc.arch/bz/.vim/plugged/tmux-complete.vim/sh/tmuxcomplete', '-l', '-a'] return onStdoutAvailable(script, args, token, (output) => { let list = output.split('\n') return { items: list.map(item => { return { word: item, menu: this.menu } }) } }) } } context.subscriptions.push(sources.createSource(source)) } ```

It uses hard-coded absolute paths, setTimeout (instead of cancellation token) and I'm not sure about the best location inside of tmuxcomplete folder structure, so I haven't prepared a proper PR, but if anyone feels like taking it from here, feel free to do that.

wellle commented 5 years ago

Thank you @balta2ar!

@kabouzeid: Is this something you’d be interested in working on?

kabouzeid commented 5 years ago

I don’t have the required know how unfortunately. Also on my end I don’t experience any noticeable delays in vim.

Maybe @chemzqm can help.

chemzqm commented 5 years ago

As you can see https://github.com/wellle/tmux-complete.vim/blob/master/autoload/coc/source/tmuxcomplete.vim#L10 coc.nvim use callback function to notify completion result, so you can use vim/neovim's job API to get the results from shell command.

I can provide a simple function for the job, it's better implemented with tmux-complete.vim since other plugin could benefit.

kabouzeid commented 5 years ago

So you mean execute tmuxcomplete#gather_candidates() async and then call the callback, right? I don’t have much experience with vim script, is this complicated?

wellle commented 5 years ago

@balta2ar: Thank you, I tested it locally (by making the shell script sleep a bit) and could reproduce the blocking behaviour.

I had a look at how to do asynchronous jobs in Vim/Neovim and added asynchronous support for coc.nvim in https://github.com/wellle/tmux-complete.vim/pull/86.

Please try again 👍

/cc @kabouzeid

balta2ar commented 5 years ago

@wellle Amazing! The difference is dramatic, thank you very much!

kabouzeid commented 5 years ago

Just tried it, works perfectly on my end (Neovim 0.4.0).

Where can I send you a few euros for a cup of coffee or a beer to thank you?

wellle commented 5 years ago

@kabouzeid: Haha thank you! And thanks again for your initial work on the integration! 💪

Was fun playing around with the new async execution models in Vim/Neovim 👍 (I wish there was a single way to do it though)