Closed w-cantin closed 3 years ago
You should be able to do something like:
neovim.subscribe('some_notification_name')
neovim.on('notification', (method, args) => {
switch (method) {
case 'some_notification_name':
console.log('got this notification!', args)
break
// Other notification handling . . .
}
})
// Or this, although not 100% sure this works
neovim.subscribe('nvim_buf_detach_event')
neovim.on('nvim_buf_detach_event', (args) => /* do stuff */)
I do this in uivonim (a neovim GUI), see https://github.com/smolck/uivonim/blob/03cc2edb229c495a5180f7778dd026fbafe922e8/src/main/workers/neovim-api.ts#L253
The first method you proposed works fine and is actually quite similar to what the vscode neovim extension does too. The only issue with it is that I would prefer not having to play with autocommands and rpcnotify from the neovim process itself.
The second solution
neovim.subscribe('nvim_buf_detach_event')
neovim.on('nvim_buf_detach_event', (args) => /* do stuff */)
is exactly what I have been trying to do (only for a different event) and unfortunately I can't make it work. Here is what a condensed version of the code I wrote looks like:
const cp = require('child_process');
const attach = require('neovim').attach;
const nvim_proc = cp.spawn('nvim',
['-u', '~/.config/nvim/vscode-init.vim', '-n', '--embed', '-R',
'--headless'
], {});
(async function() {
const nvim = await attach({ proc: nvim_proc });
await nvim.subscribe("nvim_text_changed_event")
await nvim.on("nvim_text_changed_event", () => console.log(`event`))
await nvim.command('edit test.py');
await nvim.input("iline1<CR><Esc>")
const currBuf = await nvim.buffer
let lines = await (currBuf.lines)
console.log(lines)
await nvim.input("iline2 <CR><Esc>")
lines = await (currBuf.lines)
console.log(lines)
nvim.quit();
})();
The output console looks like
['line1', '']
['line1', 'line2 ', '']
which means the file is getting modified in neovim properly. I also tried every combination of camelCase/snakecase/with nvim prefix/with _event suffix for event names. I tried for multiple events not just TextChanged but also bufEnter, bufAttach, buf_changedtick_event.
Thank you for your help. By the way your work on uivonim looks really interesting and I'll definitely keep an eye on it.
Okay so yeah, I wasn't convinced the second solution worked. But unless I'm wrong, I don't think this is a problem with node-client's API, but more to do with how the msgpack-rpc API and events work. Meaning that the only way to get an event for, say, when a buffer's text changes is to call an rpcnotify on BufWrite
or similar and handle that. You have to do that setup yourself.
I could be wrong though; I'll ask about it on Matrix and see what the response is.
Whoa ok I just found another related issue this time for pynvim (I wished I found it earlier...) and I believe one of the core contributor to neovim said that the subscribe functions were useless. Here is his quote:
unfortunately subscribe/unsubscribe are mostly useless and unrelated to the vim "events" (autocommands). Instead see :help autocmd. work to improve this is neovim/neovim#11613 for example
That means using rpcnotify inside autocommands is definitely the way to go. Thank you very much for your help.
Hello,
How can a node client listen to events that were subscribed using the
Neovim.subscribe(event)
function from the main API? For example if one wanted to listen toBufEnter
events it seems easy to write something likebut since there are no callbacks or anything it is not clear what to do after. I have a seen a workaround using
rpcnotify
andnvimClient.on("notification", callbackFunction);
shenanigans like in this vscode extension but the subscribe function seems to already solve the problem.I also found this issue in the go client and it is quite similar to mine. Unfortunately the proposed solution did not really help.
Thank you