Skip to content

Commit f451807

Browse files
committed
Fix traceback in neovim when changin tabs; use WindowID rather than window number for getting the location lists
1 parent 0d387ad commit f451807

File tree

4 files changed

+159
-121
lines changed

4 files changed

+159
-121
lines changed

python/ycm/tests/test_utils.py

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -489,14 +489,35 @@ def pop( self, index ):
489489
return self._buffers.pop( index )
490490

491491

492+
class VimTabpages:
493+
def __init__( self, *args ):
494+
"""|buffers| is a list of VimBuffer objects."""
495+
self._tabpages = []
496+
self._tabpages.extend( args )
497+
498+
499+
def __getitem__( self, number ):
500+
"""Emulates vim.buffers[ number ]"""
501+
for tabpage in self._tabpages:
502+
if number == tabpage.number:
503+
return tabpage
504+
raise KeyError( number )
505+
506+
507+
def __iter__( self ):
508+
"""Emulates for loop on vim.buffers"""
509+
return iter( self._tabpages )
510+
511+
492512
class VimWindow:
493513
"""An object that looks like a vim.window object:
494514
- |number|: number of the window;
495515
- |buffer_object|: a VimBuffer object representing the buffer inside the
496516
window;
497517
- |cursor|: a tuple corresponding to the cursor position."""
498518

499-
def __init__( self, number, buffer_object, cursor = None ):
519+
def __init__( self, tabpage, number, buffer_object, cursor = None ):
520+
self.tabpage = tabpage
500521
self.number = number
501522
self.buffer = buffer_object
502523
self.cursor = cursor
@@ -510,31 +531,33 @@ def __repr__( self ):
510531
f'cursor = { self.cursor } )' )
511532

512533

513-
class VimWindows:
534+
class VimTabpage:
514535
"""An object that looks like a vim.windows object."""
515536

516-
def __init__( self, buffers, cursor ):
537+
def __init__( self, number, buffers, cursor ):
517538
"""|buffers| is a list of VimBuffer objects corresponding to the window
518539
layout. The first element of that list is assumed to be the current window.
519540
|cursor| is the cursor position of that window."""
520-
windows = []
521-
windows.append( VimWindow( 1, buffers[ 0 ], cursor ) )
541+
self.number = number
542+
self.windows = []
543+
self.windows.append( VimWindow( self, 1, buffers[ 0 ], cursor ) )
522544
for window_number in range( 1, len( buffers ) ):
523-
windows.append( VimWindow( window_number + 1, buffers[ window_number ] ) )
524-
self._windows = windows
545+
self.windows.append( VimWindow( self,
546+
window_number + 1,
547+
buffers[ window_number ] ) )
525548

526549

527550
def __getitem__( self, number ):
528551
"""Emulates vim.windows[ number ]"""
529552
try:
530-
return self._windows[ number ]
553+
return self.windows[ number ]
531554
except IndexError:
532555
raise IndexError( 'no such window' )
533556

534557

535558
def __iter__( self ):
536559
"""Emulates for loop on vim.windows"""
537-
return iter( self._windows )
560+
return iter( self.windows )
538561

539562

540563
class VimCurrent:
@@ -544,6 +567,7 @@ class VimCurrent:
544567
def __init__( self, current_window ):
545568
self.buffer = current_window.buffer
546569
self.window = current_window
570+
self.tabpage = current_window.tabpage
547571
self.line = self.buffer.contents[ current_window.cursor[ 0 ] - 1 ]
548572

549573

@@ -639,10 +663,11 @@ def MockVimBuffers( buffers, window_buffers, cursor_position = ( 1, 1 ) ):
639663
'which corresponds to the current window.' )
640664

641665
with patch( 'vim.buffers', VimBuffers( buffers ) ):
642-
with patch( 'vim.windows', VimWindows( window_buffers,
643-
cursor_position ) ) as windows:
644-
with patch( 'vim.current', VimCurrent( windows[ 0 ] ) ):
645-
yield VIM_MOCK
666+
with patch( 'vim.tabpages', VimTabpages(
667+
VimTabpage( 1, window_buffers, cursor_position ) ) ) as tabpages:
668+
with patch( 'vim.windows', tabpages[ 1 ] ) as windows:
669+
with patch( 'vim.current', VimCurrent( windows[ 0 ] ) ):
670+
yield VIM_MOCK
646671

647672

648673
def MockVimModule():

python/ycm/tests/vimsupport_test.py

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,9 @@ def _BuildLocations( start_line, start_column, end_line, end_column ):
6969

7070

7171
class VimsupportTest( TestCase ):
72+
@patch( 'ycm.vimsupport.WinIDForWindow', side_effect = range( 1001, 1010 ) )
7273
@patch( 'vim.eval', new_callable = ExtendedMock )
73-
def test_SetLocationListsForBuffer_Current( self, vim_eval ):
74+
def test_SetLocationListsForBuffer_Current( self, vim_eval, *args ):
7475
diagnostics = [ {
7576
'bufnr': 3,
7677
'filename': 'some_filename',
@@ -84,10 +85,10 @@ def test_SetLocationListsForBuffer_Current( self, vim_eval ):
8485
vimsupport.SetLocationListsForBuffer( 3, diagnostics )
8586

8687
vim_eval.assert_has_exact_calls( [
87-
call( 'setloclist( 1, [], " ", { "title": "ycm_loc", '
88+
call( 'setloclist( 1001, [], " ", { "title": "ycm_loc", '
8889
'"items": [{"bufnr": 3, "filename": "some_filename", "lnum": 5, '
8990
'"col": 22, "type": "E", "valid": 1}] } )' ),
90-
call( 'getloclist( 1, { "nr": "$", "id": 0 } ).id' ),
91+
call( 'getloclist( 1001, { "nr": "$", "id": 0 } ).id' ),
9192
] )
9293

9394

@@ -127,8 +128,9 @@ def test_SetLocationListsForBuffer_NotVisible( self, vim_eval ):
127128
vim_eval.assert_not_called()
128129

129130

131+
@patch( 'ycm.vimsupport.WinIDForWindow', side_effect = range( 1001, 1010 ) )
130132
@patch( 'vim.eval', new_callable = ExtendedMock, side_effect = [ -1, 1 ] )
131-
def test_SetLocationListsForBuffer_MultipleWindows( self, vim_eval ):
133+
def test_SetLocationListsForBuffer_MultipleWindows( self, vim_eval, *args ):
132134
diagnostics = [ {
133135
'bufnr': 3,
134136
'filename': 'some_filename',
@@ -144,14 +146,15 @@ def test_SetLocationListsForBuffer_MultipleWindows( self, vim_eval ):
144146
vimsupport.SetLocationListsForBuffer( 1, diagnostics )
145147

146148
vim_eval.assert_has_exact_calls( [
147-
call( 'setloclist( 2, [], " ", { "title": "ycm_loc", "items": '
149+
call( 'setloclist( 1001, [], " ", { "title": "ycm_loc", "items": '
148150
f'{ json.dumps( diagnostics ) } }} )' ),
149-
call( 'getloclist( 2, { "nr": "$", "id": 0 } ).id' ),
151+
call( 'getloclist( 1001, { "nr": "$", "id": 0 } ).id' ),
150152
] )
151153

152154

155+
@patch( 'ycm.vimsupport.WinIDForWindow', side_effect = range( 1001, 1010 ) )
153156
@patch( 'vim.eval', new_callable = ExtendedMock )
154-
def test_SetLocationList( self, vim_eval ):
157+
def test_SetLocationList( self, vim_eval, *args ):
155158
diagnostics = [ {
156159
'bufnr': 3,
157160
'filename': 'some_filename',
@@ -165,15 +168,16 @@ def test_SetLocationList( self, vim_eval ):
165168
vimsupport.SetLocationList( diagnostics )
166169

167170
vim_eval.assert_has_exact_calls( [
168-
call( 'setloclist( 0, [], " ", { "title": "ycm_loc", "items": [{"bufnr": '
169-
'3, "filename": "some_filename", "lnum": '
171+
call( 'setloclist( 1001, [], " ", { "title": "ycm_loc", "items": '
172+
'[{"bufnr": 3, "filename": "some_filename", "lnum": '
170173
'5, "col": 22, "type": "E", "valid": 1}] } )' ),
171-
call( 'getloclist( 0, { "nr": "$", "id": 0 } ).id' ),
174+
call( 'getloclist( 1001, { "nr": "$", "id": 0 } ).id' ),
172175
] )
173176

174177

178+
@patch( 'ycm.vimsupport.WinIDForWindow', side_effect = range( 1001, 1010 ) )
175179
@patch( 'vim.eval', new_callable = ExtendedMock )
176-
def test_SetLocationList_NotCurrent( self, vim_eval ):
180+
def test_SetLocationList_NotCurrent( self, vim_eval, *args ):
177181
diagnostics = [ {
178182
'bufnr': 3,
179183
'filename': 'some_filename',
@@ -192,10 +196,10 @@ def test_SetLocationList_NotCurrent( self, vim_eval ):
192196
# This version does not check the current
193197
# buffer and just sets the current win
194198
vim_eval.assert_has_exact_calls( [
195-
call( 'setloclist( 0, [], " ", { "title": "ycm_loc", "items": [{"bufnr": '
196-
'3, "filename": "some_filename", "lnum": 5, "col": 22, '
199+
call( 'setloclist( 1001, [], " ", { "title": "ycm_loc", "items": '
200+
'[{"bufnr": 3, "filename": "some_filename", "lnum": 5, "col": 22, '
197201
'"type": "E", "valid": 1}] } )' ),
198-
call( 'getloclist( 0, { "nr": "$", "id": 0 } ).id' ),
202+
call( 'getloclist( 1001, { "nr": "$", "id": 0 } ).id' ),
199203
] )
200204

201205

@@ -2052,9 +2056,9 @@ def test_JumpToLocation_DifferentFile_Split_AllTabs_AlreadyOpened(
20522056
current_window = MagicMock( buffer = current_buffer )
20532057
different_window = MagicMock( buffer = different_buffer )
20542058
current_tab = MagicMock( windows = [ current_window, different_window ] )
2055-
with patch( 'vim.tabpages', [ current_tab ] ):
2056-
with MockVimBuffers( [ current_buffer, different_buffer ],
2057-
[ current_buffer ] ) as vim:
2059+
with MockVimBuffers( [ current_buffer, different_buffer ],
2060+
[ current_buffer ] ) as vim:
2061+
with patch( 'vim.tabpages', [ current_tab ] ):
20582062
vimsupport.JumpToLocation( os.path.realpath( 'different_uni¢𐍈d€' ),
20592063
2,
20602064
5,
@@ -2102,9 +2106,9 @@ def test_JumpToLocation_DifferentFile_NewOrExistingTab_AlreadyOpened(
21022106
current_window = MagicMock( buffer = current_buffer )
21032107
different_window = MagicMock( buffer = different_buffer )
21042108
current_tab = MagicMock( windows = [ current_window, different_window ] )
2105-
with patch( 'vim.tabpages', [ current_tab ] ):
2106-
with MockVimBuffers( [ current_buffer, different_buffer ],
2107-
[ current_buffer ] ) as vim:
2109+
with MockVimBuffers( [ current_buffer, different_buffer ],
2110+
[ current_buffer ] ) as vim:
2111+
with patch( 'vim.tabpages', [ current_tab ] ):
21082112
vimsupport.JumpToLocation( os.path.realpath( 'different_uni¢𐍈d€' ),
21092113
2,
21102114
5,

0 commit comments

Comments
 (0)