lambdalisue/vim-fern

nvim: "Window was closed immediately" when opening floating window while opening fern in split window

Closed this issue · 7 comments

In nvim, when I quickly open a fern buffer with -opener=split and immediately run a fzf.vim command that opens a floating window, I get the following error.

Error detected while processing function fzf#vim#buffers[6]..<SNR>114_fzf[21]..fzf#run[81]..function fzf#vim#buffers[6]..<SNR>114_fzf[21]..fzf#run[64]..<SNR>71_execute_term[3]..<SNR>71_split[14]..<SNR>71_popup[21]..<SNR>71_create_popup:
line    3:
E5555: API call: Window was closed immediately

This does not happen in vim.

Here is a minimal reproducer (tested in nvim 0.6, ..., 0.9):

nvim --clean \
    --cmd 'set rtp^=~/.vim/plugged/fern.vim' \
    -c 'Fern . -opener=split' \
    -c 'call nvim_open_win(0, v:true, {"relative": "win", "style": "minimal", "row": 2, "col": 4, "width": 8, "height": 4})'

Relevant line in nvim source:
https://github.com/neovim/neovim/blob/ebb10d624825468c1f75bd14725cce500974b673/src/nvim/api/win_config.c#L179

I'm not sure, but it seems to me that there is a problem with fzf.vim. Is it really a problem on the fern side?

As you can see from the minimal reproducer that only involves nvim_open_win(), this bug is only related to fern and nvim's implementation of floating window. I wanted to further minimize the issue so that I can file a bug report in nvim issue tracker with a truly minimal reproducer that doesn't involve fern, but I don't have enough bandwidth to study fern's implementation.

Oops sorry. I only saw the first example. I'll check it out.

Prob -wait solves the issue I guess. It doesn't
https://github.com/lambdalisue/fern.vim/blob/f7f41b5edd12f8fe3f358a2ada02d4662919684e/doc/fern.txt#L580-L581

Disabling auto viewer duplication feature solves the issue as a current workaround for now

nvim --clean \
    --cmd 'set rtp^=.' \
    --cmd 'let g:fern#disable_viewer_auto_duplication=1' \
    -c 'Fern . -opener=split' \
    -c 'call nvim_open_win(0, v:true, {"relative": "win", "style": "minimal", "row": 2, "col": 4, "width": 8, "height": 4})'

So s:duplicate runs in the new floating window.

This line (bwipeout-ing the new buffer with empty authority) makes the new floating window invalid. https://github.com/lambdalisue/fern.vim/blob/f7f41b5edd12f8fe3f358a2ada02d4662919684e/autoload/fern/internal/viewer.vim#L73

So the root cause is that, in a floating window, bwipeout-ing the current buffer destroys the window. I'm not sure if this is feature or bug.

So the root cause is that, in a floating window, bwipeout-ing the current buffer destroys the window. I'm not sure if this is feature or bug.

I guess this is expected behavior. Usual split windows do that too.

I think the real problem is that this line fails. https://github.com/lambdalisue/fern.vim/blob/f7f41b5edd12f8fe3f358a2ada02d4662919684e/autoload/fern/internal/viewer.vim#LL72C1-L72C1 Relevant lines from verbose=16 log:

line 31:     execute printf('silent! keepalt file %s', fnameescape(bufname))
line 31: silent! keepalt file fern://237781dd/file:///home/user/.vim/plugged/fern.vim\$
Error detected while processing command line..WinEnter Autocommands for "<buffer=2>"..function <SNR>40_duplicate[10]..BufReadCmd Autocommands for "fern://*"..function <SNR>6_BufReadCmd[4]..fern#internal#viewer#init[3]..<SNR>37_init:
line   31:
E95: Buffer with this name already exists
line 32:     unsilent echom '1.1' win_getid()
1.1 1002
line 33:     execute printf('silent! bwipeout %s', previous)
line 33: silent! bwipeout fern:///file:///home/user/.vim/plugged/fern.vim$
Executing BufLeave Autocommands for "<buffer=5>"
autocommand let b:fern_cursor = getcurpos()[1:2]

Executing: let b:fern_cursor = getcurpos()[1:2]
Executing WinEnter Autocommands for "<buffer=2>"
autocommand call s:duplicate()

Executing: call s:duplicate()
calling <SNR>40_duplicate()

line 1:   if len(win_findbuf(bufnr('%'))) < 2
line 2:     return
<SNR>40_duplicate returning #0

continuing in WinEnter Autocommands for "<buffer=2>"

Executing CursorMoved Autocommands for "<buffer=2>"
autocommand let b:fern_cursor = getcurpos()[1:2]

Executing: let b:fern_cursor = getcurpos()[1:2]
Executing BufEnter Autocommands for "<buffer=2>"
autocommand setlocal nobuflisted

Executing: setlocal nobuflisted
auto-removing autocommand: BufEnter <buffer=5>
auto-removing autocommand: BufLeave <buffer=5>
auto-removing autocommand: BufReadCmd <buffer=5>
auto-removing autocommand: CursorMoved <buffer=5>
auto-removing autocommand: CursorMovedI <buffer=5>
auto-removing autocommand: WinEnter <buffer=5>
line 34:     unsilent echom '1.2' win_getid()
1.2 1001

This is a bug because we don't need to count the number of popup windows to determine if we should invoke auto duplication feature. I fix that on #475 so please try it. @tomtomjhj