pynvim icon indicating copy to clipboard operation
pynvim copied to clipboard

`<abuf>` is wrong for `BufUnload` with hidden buffer

Open laomaiweng opened this issue 2 years ago • 2 comments

    @pynvim.command('Scratch')
    def cmd_scratch(self):
        buffer = self.nvim.api.create_buf(False, True)
        win = self.nvim.api.open_win(buffer, True, {'width':60,'height':5,'style':'minimal','relative':'editor','row':0,'col':0})
        self.nvim.out_write(f'Scratch {buffer=} {win=}\n')

    @pynvim.autocmd('BufUnload', eval='+expand("<abuf>")', sync=True)
    def on_bufunload(self, buffer):
        self.nvim.out_write(f'BufUnload {buffer=} {self.nvim.current.buffer.number=}\n')

When I :bdelete the scratch buffer, the BufUnload event fires and the callback receives the number of the newly focused buffer (i.e. the same as nvim.current.buffer, not the scratch buffer) in its buffer argument, from the <abuf> expansion. IIUC, the BufUnload docs says <abuf> should hold the unloading buffer number (here, the scratch buffer). Am I doing something wrong or is that a bug?

(This looks a lot like neovim/node-client#58.)

laomaiweng avatar Oct 19 '23 17:10 laomaiweng

Looks like a bug. So in the first invocation a wrong buf number is passed, but in the consequent invocations it works correctly.

So the autocmd defined by the rplugin is:

BufUnload * call remote#define#request(4, "/path/to/rplugin/python3/myplugin:autocmd:BufUnload:*", eval("+expand(\
"<abuf>\")"))

Here a rpcrequest call should block until a response is received, and note that the evaluation of expand("<abuf>") is done on the neovim client side (in the vimscript that calls the autocmd).

But in the first invocation when it is yet to be bootstrapped:

BufUnload *         call remote#define#AutocmdBootstrap("python3", "/path/to/rplugin/python3/myplugin:autocmd:BufUnload:*"
, v:true, "BufUnload", {'group': 'RPC_DEFINE_AUTOCMD_GROUP_2', 'pattern': '*', 'eval': '+expand("<abuf>")'}, "\"doau RPC_DEFINE_AUTOCMD_GROUP_2 BufUnload \".fnameesc
ape(expand(\"<amatch>\"))")

It looks like by the time the actual RPC request is made, the buffer is already gone and hence wrong buffer number is passed. I think this is a bug of neovim core (rplugin provider) rather than pynvim --- probably why node-client also suffers the same error.

wookayin avatar Oct 28 '23 06:10 wookayin

https://github.com/neovim/neovim/blob/master/runtime/autoload/remote/define.vim#L114

eval(a:forward)

this executes doau RPC_DEFINE_AUTOCMD_GROUP_2 BufUnload (i.e. no <amatch>, <abuf>) -- <amatch>, <abuf> cannot be expanded correctly due to a different (autocmd) execution context (i.e. during doautocmd BufUnload).

wookayin avatar Oct 28 '23 06:10 wookayin