From f538102d33d81614636558ba8179fb75cf54e8d0 Mon Sep 17 00:00:00 2001 From: Ben Jackson Date: Tue, 1 Sep 2020 15:01:24 +0100 Subject: [PATCH] Don't leak buffers when creating output view --- python3/vimspector/output.py | 21 ++++++++ tests/tabpage.test.vim | 100 +++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+) diff --git a/python3/vimspector/output.py b/python3/vimspector/output.py index 43dd240..90df09d 100644 --- a/python3/vimspector/output.py +++ b/python3/vimspector/output.py @@ -17,6 +17,7 @@ from vimspector import utils, install import vim import json +import typing class TabBuffer( object ): @@ -55,6 +56,8 @@ def ShowOutputInWindow( win_id, category ): class OutputView( object ): """Container for a 'tabbed' window of buffers that can be used to display files or the output of commands.""" + _buffers: typing.Dict[ str, TabBuffer ] + def __init__( self, window, api_prefix ): self._window = window self._buffers = {} @@ -146,6 +149,17 @@ class OutputView( object ): cmd = None, completion_handler = None, syntax = None ): + + buf_to_delete = None + if ( not self._buffers + and self._window is not None + and self._window.valid + and not self._window.buffer.name ): + # If there's an empty buffer in the current window that we're not using, + # delete it. We could try and use it, but that complicates the call to + # SetUpCommandBuffer + buf_to_delete = self._window.buffer + if file_name is not None: assert cmd is None if install.GetOS() == "windows": @@ -160,6 +174,7 @@ class OutputView( object ): category, self._api_prefix, completion_handler = completion_handler ) + self._buffers[ category ] = TabBuffer( out, len( self._buffers ) ) self._buffers[ category ].is_job = True self._RenderWinBar( category ) @@ -170,6 +185,7 @@ class OutputView( object ): name = 'vimspector.Output:{0}'.format( category ) tab_buffer = TabBuffer( utils.NewEmptyBuffer(), len( self._buffers ) ) + self._buffers[ category ] = tab_buffer if category == 'Console': @@ -187,6 +203,11 @@ class OutputView( object ): syntax, self._buffers[ category ].buf ) + if buf_to_delete: + with utils.RestoreCurrentWindow(): + self._ShowOutput( category ) + utils.CleanUpHiddenBuffer( buf_to_delete ) + def _RenderWinBar( self, category ): if not self._window.valid: return diff --git a/tests/tabpage.test.vim b/tests/tabpage.test.vim index e08a8c0..6338d9c 100644 --- a/tests/tabpage.test.vim +++ b/tests/tabpage.test.vim @@ -49,3 +49,103 @@ function! Test_Step_With_Different_Tabpage() %bwipeout! endfunction +function! Test_All_Buffers_Deleted_NoHidden() + set nohidden + lcd testdata/cpp/simple + edit simple.cpp + + let opts = #{ buflisted: v:true } + + let buffers_before = getbufinfo( opts ) + + call setpos( '.', [ 0, 15, 1 ] ) + call vimspector#ToggleBreakpoint() + call vimspector#Launch() + call vimspector#test#signs#AssertCursorIsAtLineInBuffer( 'simple.cpp', 15, 1 ) + call vimspector#test#signs#AssertPCIsAtLineInBuffer( + \ 'simple.cpp', + \ 15 ) + + call vimspector#Reset() + call vimspector#test#setup#WaitForReset() + + let buffers_after = getbufinfo( opts ) + + call assert_equal( len( buffers_before ), len( buffers_after ) ) + + set hidden& + lcd - + call vimspector#test#setup#Reset() + %bwipe! +endfunction + +function! Test_All_Buffers_Deleted_Hidden() + set hidden + lcd testdata/cpp/simple + edit simple.cpp + + let opts = #{ buflisted: v:true } + + let buffers_before = getbufinfo( opts ) + + call setpos( '.', [ 0, 15, 1 ] ) + call vimspector#ToggleBreakpoint() + call vimspector#Launch() + call vimspector#test#signs#AssertCursorIsAtLineInBuffer( 'simple.cpp', 15, 1 ) + call vimspector#test#signs#AssertPCIsAtLineInBuffer( + \ 'simple.cpp', + \ 15 ) + + call vimspector#Reset() + call vimspector#test#setup#WaitForReset() + + let buffers_after = getbufinfo( opts ) + + call assert_equal( len( buffers_before ), len( buffers_after ) ) + + set hidden& + lcd - + call vimspector#test#setup#Reset() + %bwipe! +endfunction + +function! Test_All_Buffers_Deleted_ToggleLog() + set hidden + let buffers_before = getbufinfo( #{ buflisted: 1 } ) + VimspectorToggleLog + VimspectorToggleLog + let buffers_after = getbufinfo( #{ buflisted: 1 } ) + call assert_equal( len( buffers_before ), len( buffers_after ) ) + + call vimspector#test#setup#Reset() + set hidden& + %bwipe! +endfunction + +let g:vimspector_test_install_done = 0 + +function! Test_All_Buffers_Deleted_Installer() + set hidden + let buffers_before = getbufinfo( #{ buflisted: 1 } ) + + augroup Test_All_Buffers_Deleted_Installer + au! + au User VimspectorInstallSuccess let g:vimspector_test_install_done = 1 + au User VimspectorInstallFailed let g:vimspector_test_install_done = 1 + augroup END + + VimspectorUpdate + + " The test timeout will take care of this taking too long + call WaitForAssert( + \ { -> assert_equal( 1, g:vimspector_test_install_done ) }, + \ 120000 ) + + let buffers_after = getbufinfo( #{ buflisted: 1 } ) + call assert_equal( len( buffers_before ), len( buffers_after ) ) + + call vimspector#test#setup#Reset() + set hidden& + au! Test_All_Buffers_Deleted_Installer + %bwipe! +endfunction