mbbill / undotree

The undo history visualizer for VIM
http://www.vim.org/scripts/script.php?script_id=4177
BSD 3-Clause "New" or "Revised" License
3.96k stars 101 forks source link

[bug] When using ":q" to quit buffer, E1312 occur #156

Open ACOTSAE opened 1 year ago

ACOTSAE commented 1 year ago

At present, I am certain that the t:undotree.Hide() function is causing this error. vim version

2023-05-21 132734

vimrc: filetype plugin on call plug#begin() Plug 'mbbill/undotree' nnoremap \<silent> \<F5> :UndotreeToggle\<cr> call plug#end()

Process: Using Gvim or vim in terminal open any files. Using ":UndotreeToggle" or ":UndotreeShow" to open undotree. Using ":q" to buffer. E1312

2023-05-21 130830 2023-05-21 132333
ACOTSAE commented 1 year ago

I found a similar error in gogy.vm I used different versions of VIM to reproduce this error and found the error will occur version after 9.0.0907 It seems that the error probably comes out of this patch vim/vim@d63a855

To address this issue, I have modified the code in function! s:exitIfLast() section to

function! s:exitIfLast() abort
    let num = 0
    if exists('t:undotree') && t:undotree.IsVisible()
        let num = num + 1
    endif
    if exists('t:diffpanel') && t:diffpanel.IsVisible()
        let num = num + 1
    endif
    if winnr('$') <= num
        echo winnr('$')
        if tabpagenr('$') == 1
            quitall
        else
            echo 'tabclose'
            "E1312
            tabclose
        endif
        "if exists('t:undotree')
        "echo winnr('$')'undertree'
            "error E1312
        "call t:undotree.Hide()
        "endif
        "if exists('t:diffpanel')
        "call t:diffpanel.Hide()
        "endif
    endif
endfunction

When there is only one tab, it works will, when having multiple tabs, however, like code annotations, E1312 still happen. But when I execute 'tabclose' on the command line, the error does not occur.

tuurep commented 1 year ago

Related: https://github.com/mbbill/undotree/issues/129#issuecomment-1024498777

Ocraw commented 6 months ago

Seems to be stale, altho I think the problem is straight forward the solution might not be. In case the former is not as obvious, here's my 2c to hopefully unstuck this:

In a recent vim update the closing/resizing of windows was forbidden in auto commands, cause it seems you would get problems saving their state or something if layout was changed. Is there a different approach to automatically close the last window/buffer outside of au? Or tell vim that the window layout is unlocked [window_layout_locked()]?

also:

function! s:exitIfLast() abort
    let num = 0
    if exists('t:undotree') && t:undotree.IsVisible()
        let num = num + 1
    endif
    if exists('t:diffpanel') && t:diffpanel.IsVisible()
        let num = num + 1
    endif
    if winnr('$') <= num
          quitall
    endif
endfunction

seems to do the trick, the solution posted by ACOTSAE raises the same error (cannot resize window in this autocommand) if you try to q! and have multiple tabs with modified buffers, at least for me, leading to many "q/q!" to clear the window. But this might "just" be the fact that the plugin gets interrupted by vim refusing to close, in the case of my approach you still get a plugin error but unrelated to resizing, and can quit as you normally would, after vim complains about tabs having modified buffers, not sure if behind the scenes something else goes horribly wrong, but didn't notice any anomaly so far.

Hope this helps a little.

mbbill commented 2 months ago

I spent some time investigating the issue caused by patch 9.0.0907, and honestly, I can't find a good workaround for it. It seems that Vim discourages plugins from altering window layouts in autocommands or even timers. I'm considering removing the auto-close feature to suppress the error message. Users might need to use :qa like they do with other plugins when they're the last ones open. What do you all think?

b0ae989c commented 2 months ago

... Vim discourages plugins from altering window layouts in autocommands or even timers. ... removing the auto-close feature to suppress the error message

Sounds good. Changing window layout in autocmds can be messy, and I did encounter strange bugs with it in a different context.