preservim / tagbar

Vim plugin that displays tags in a window, ordered by scope
https://preservim.github.io/tagbar
Other
6.1k stars 485 forks source link

Close pane with tagbar would also close the nerdtree pane #821

Closed WeissZucker closed 1 year ago

WeissZucker commented 2 years ago

When I open a file from nerdtree in split view,(press i), and toggle tagbar for the file, then close the file, the nerdtree pane would also be closed. How can I disable this behaviour?

alerque commented 2 years ago

This is probably a bug. The plugin should not be closing panes it did not open / does not own. I doubt this is something you can disable with a setting, somebody probably needs to comb through and figure out why it is happening and fix it.

raven42 commented 2 years ago

I can confirm this behavior. And I've also verified it only occurs when the tagbar window is open. I've been playing around with the code to see if there is a fix that can be applied easily enough. I've been able to add a little bit of code that will prevent vim from closing, or from closing the nerdtree window. However when doing this, it is leaving the tagbar window open and populated with info from the file that was just closed even though the file window is closed.

Incase you are interested, here is the current patch I have. It is not working fully... but it is something. I'll continue to play around with it when I have some time. [edit: removed in favor of patch below]

raven42 commented 2 years ago

Ok... here is an updated patch that should have the desired behavior I believe.

However this does have a change in behavior. Previously if the netrw (or nerdtree) window was the only remaining window other than tagbar, then vim would quit. I'm not sure if this was the desired behavior when tagbar was first written, but we just might want to take care that that this will possible change the workflow some people are used to. I know that I for one am used to this behavior, so even just for me it would be a change in behavior and would change my normal workflow. I have a layout with both nerdtree and tagbar windows open at the same time for most files, and I'm used to just doing a single :q to close out of vim. However with this patch, that would change. Because of this, I'm thinking we may want to have this behind a configuration somewhere, either a config that will close the netrw window when it is the last window, or a config that will leave the netrw window open if that is the last window.

@alerque, what are your thoughts?

diff --git a/autoload/tagbar.vim b/autoload/tagbar.vim
index 12ddd6a..5fe228b 100644
--- a/autoload/tagbar.vim
+++ b/autoload/tagbar.vim
@@ -3515,12 +3515,19 @@ function! s:HandleOnlyWindow() abort
     let vim_quitting = s:vim_quitting
     let s:vim_quitting = 0

-    if vim_quitting && !s:HasOpenFileWindows()
+    let file_open = s:HasOpenFileWindows()
+
+    if vim_quitting && !file_open
         call tagbar#debug#log('Closing Tagbar window due to QuitPre event')
         if winnr('$') >= 1
             call s:goto_win(tagbarwinnr, 1)
         endif

+        if file_open == 2
+            call s:CloseWindow()
+            return
+        endif
+
         " Before quitting Vim, delete the tagbar buffer so that the '0 mark is
         " correctly set to the previous buffer.
         if tabpagenr('$') == 1
@@ -3633,27 +3640,40 @@ endfunction

 " s:HasOpenFileWindows() {{{2
 function! s:HasOpenFileWindows() abort
+    let netrw = 0
     for i in range(1, winnr('$'))
         let buf = winbufnr(i)

+        let bft = getbufvar(buf, '&filetype')
+        if bft ==# 'netrw' || bft == 'nerdtree'
+            let netrw = 1
+        endif
+
+        call tagbar#debug#log('checking for open file - filetype:' . getbufvar(buf, '&filetype'))
         " skip unlisted buffers, except for netrw
-        if !buflisted(buf) && getbufvar(buf, '&filetype') !=# 'netrw'
+        if !buflisted(buf)
+            call tagbar#debug#log('skipping due to unlisted')
             continue
         endif

         " skip temporary buffers with buftype set
         if getbufvar(buf, '&buftype') !=# ''
+            call tagbar#debug#log('skipping due to temp buffer')
             continue
         endif

         " skip the preview window
         if getwinvar(i, '&previewwindow')
+            call tagbar#debug#log('skipping due to preview window')
             continue
         endif

         return 1
     endfor

+    if netrw
+        return 2
+    endif
     return 0
 endfunction
alerque commented 2 years ago

I'm out of pocket for at least a week or so.