Auto merge of #3024 - micbou:diagnostic-matches-current-buffer, r=micbou

[READY] Update diagnostic matches for all windows

Since the `getmatches` and `setmatches` Vim functions only allow manipulating matches for the current window, we shouldn't update diagnostic matches if the buffer is not the current window.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/valloric/youcompleteme/3024)
<!-- Reviewable:end -->
This commit is contained in:
zzbot 2018-06-20 11:46:15 -07:00 committed by GitHub
commit e1ead995c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 590 additions and 369 deletions

View File

@ -59,7 +59,7 @@ class DiagnosticInterface( object ):
def PopulateLocationList( self ): def PopulateLocationList( self ):
# Do nothing if loc list is already populated by diag_interface # Do nothing if loc list is already populated by diag_interface
if not self._user_options[ 'always_populate_location_list' ]: if not self._user_options[ 'always_populate_location_list' ]:
self._UpdateLocationList() self._UpdateLocationLists()
return bool( self._diagnostics ) return bool( self._diagnostics )
@ -77,7 +77,7 @@ class DiagnosticInterface( object ):
self.UpdateMatches() self.UpdateMatches()
if self._user_options[ 'always_populate_location_list' ]: if self._user_options[ 'always_populate_location_list' ]:
self._UpdateLocationList() self._UpdateLocationLists()
def _ApplyDiagnosticFilter( self, diags ): def _ApplyDiagnosticFilter( self, diags ):
@ -119,8 +119,8 @@ class DiagnosticInterface( object ):
return count return count
def _UpdateLocationList( self ): def _UpdateLocationLists( self ):
vimsupport.SetLocationListForBuffer( vimsupport.SetLocationListsForBuffer(
self._bufnr, self._bufnr,
vimsupport.ConvertDiagnosticsToQfList( self._diagnostics ) ) vimsupport.ConvertDiagnosticsToQfList( self._diagnostics ) )
@ -129,46 +129,28 @@ class DiagnosticInterface( object ):
if not self._user_options[ 'enable_diagnostic_highlighting' ]: if not self._user_options[ 'enable_diagnostic_highlighting' ]:
return return
matches_to_remove = vimsupport.GetDiagnosticMatchesInCurrentWindow() with vimsupport.CurrentWindow():
for window in vimsupport.GetWindowsForBufferNumber( self._bufnr ):
vimsupport.SwitchWindow( window )
for diags in itervalues( self._line_to_diags ): matches_to_remove = vimsupport.GetDiagnosticMatchesInCurrentWindow()
# Insert squiggles in reverse order so that errors overlap warnings.
for diag in reversed( diags ):
patterns = []
group = ( 'YcmErrorSection' if _DiagnosticIsError( diag ) else for diags in itervalues( self._line_to_diags ):
'YcmWarningSection' ) # Insert squiggles in reverse order so that errors overlap warnings.
for diag in reversed( diags ):
group = ( 'YcmErrorSection' if _DiagnosticIsError( diag ) else
'YcmWarningSection' )
location_extent = diag[ 'location_extent' ] for pattern in _ConvertDiagnosticToMatchPatterns( diag ):
if location_extent[ 'start' ][ 'line_num' ] <= 0: # The id doesn't matter for matches that we may add.
location = diag[ 'location' ] match = vimsupport.DiagnosticMatch( 0, group, pattern )
patterns.append( vimsupport.GetDiagnosticMatchPattern( try:
location[ 'line_num' ], matches_to_remove.remove( match )
location[ 'column_num' ] ) ) except ValueError:
else: vimsupport.AddDiagnosticMatch( match )
patterns.append( vimsupport.GetDiagnosticMatchPattern(
location_extent[ 'start' ][ 'line_num' ],
location_extent[ 'start' ][ 'column_num' ],
location_extent[ 'end' ][ 'line_num' ],
location_extent[ 'end' ][ 'column_num' ] ) )
for diag_range in diag[ 'ranges' ]: for match in matches_to_remove:
patterns.append( vimsupport.GetDiagnosticMatchPattern( vimsupport.RemoveDiagnosticMatch( match )
diag_range[ 'start' ][ 'line_num' ],
diag_range[ 'start' ][ 'column_num' ],
diag_range[ 'end' ][ 'line_num' ],
diag_range[ 'end' ][ 'column_num' ] ) )
for pattern in patterns:
# The id doesn't matter for matches that we may add.
match = vimsupport.DiagnosticMatch( 0, group, pattern )
try:
matches_to_remove.remove( match )
except ValueError:
vimsupport.AddDiagnosticMatch( match )
for match in matches_to_remove:
vimsupport.RemoveDiagnosticMatch( match )
def _UpdateSigns( self ): def _UpdateSigns( self ):
@ -221,3 +203,29 @@ def _NormalizeDiagnostic( diag ):
location[ 'column_num' ] = ClampToOne( location[ 'column_num' ] ) location[ 'column_num' ] = ClampToOne( location[ 'column_num' ] )
location[ 'line_num' ] = ClampToOne( location[ 'line_num' ] ) location[ 'line_num' ] = ClampToOne( location[ 'line_num' ] )
return diag return diag
def _ConvertDiagnosticToMatchPatterns( diagnostic ):
patterns = []
location_extent = diagnostic[ 'location_extent' ]
if location_extent[ 'start' ][ 'line_num' ] <= 0:
location = diagnostic[ 'location' ]
patterns.append( vimsupport.GetDiagnosticMatchPattern(
location[ 'line_num' ],
location[ 'column_num' ] ) )
else:
patterns.append( vimsupport.GetDiagnosticMatchPattern(
location_extent[ 'start' ][ 'line_num' ],
location_extent[ 'start' ][ 'column_num' ],
location_extent[ 'end' ][ 'line_num' ],
location_extent[ 'end' ][ 'column_num' ] ) )
for diagnostic_range in diagnostic[ 'ranges' ]:
patterns.append( vimsupport.GetDiagnosticMatchPattern(
diagnostic_range[ 'start' ][ 'line_num' ],
diagnostic_range[ 'start' ][ 'column_num' ],
diagnostic_range[ 'end' ][ 'line_num' ],
diagnostic_range[ 'end' ][ 'column_num' ] ) )
return patterns

View File

@ -34,7 +34,7 @@ from ycm.client.base_request import BuildRequestData
return_value = '/some/dir' ) return_value = '/some/dir' )
def BuildRequestData_AddWorkingDir_test( *args ): def BuildRequestData_AddWorkingDir_test( *args ):
current_buffer = VimBuffer( 'foo' ) current_buffer = VimBuffer( 'foo' )
with MockVimBuffers( [ current_buffer ], current_buffer, ( 1, 1 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
assert_that( BuildRequestData(), has_entry( 'working_dir', '/some/dir' ) ) assert_that( BuildRequestData(), has_entry( 'working_dir', '/some/dir' ) )
@ -42,6 +42,6 @@ def BuildRequestData_AddWorkingDir_test( *args ):
return_value = '/some/dir' ) return_value = '/some/dir' )
def BuildRequestData_AddWorkingDirWithFileName_test( *args ): def BuildRequestData_AddWorkingDirWithFileName_test( *args ):
current_buffer = VimBuffer( 'foo' ) current_buffer = VimBuffer( 'foo' )
with MockVimBuffers( [ current_buffer ], current_buffer, ( 1, 1 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
assert_that( BuildRequestData( current_buffer.number ), assert_that( BuildRequestData( current_buffer.number ),
has_entry( 'working_dir', '/some/dir' ) ) has_entry( 'working_dir', '/some/dir' ) )

View File

@ -34,7 +34,7 @@ from ycm.tests import YouCompleteMeInstance
@YouCompleteMeInstance( { 'g:ycm_extra_conf_vim_data': [ 'tempname()' ] } ) @YouCompleteMeInstance( { 'g:ycm_extra_conf_vim_data': [ 'tempname()' ] } )
def SendCommandRequest_ExtraConfVimData_Works_test( ycm ): def SendCommandRequest_ExtraConfVimData_Works_test( ycm ):
current_buffer = VimBuffer( 'buffer' ) current_buffer = VimBuffer( 'buffer' )
with MockVimBuffers( [ current_buffer ], current_buffer ): with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
with patch( 'ycm.youcompleteme.SendCommandRequest' ) as send_request: with patch( 'ycm.youcompleteme.SendCommandRequest' ) as send_request:
ycm.SendCommandRequest( [ 'GoTo' ], 'python', False, 1, 1 ) ycm.SendCommandRequest( [ 'GoTo' ], 'python', False, 1, 1 )
assert_that( assert_that(
@ -59,7 +59,7 @@ def SendCommandRequest_ExtraConfVimData_Works_test( ycm ):
@YouCompleteMeInstance( { 'g:ycm_extra_conf_vim_data': [ 'undefined_value' ] } ) @YouCompleteMeInstance( { 'g:ycm_extra_conf_vim_data': [ 'undefined_value' ] } )
def SendCommandRequest_ExtraConfData_UndefinedValue_test( ycm ): def SendCommandRequest_ExtraConfData_UndefinedValue_test( ycm ):
current_buffer = VimBuffer( 'buffer' ) current_buffer = VimBuffer( 'buffer' )
with MockVimBuffers( [ current_buffer ], current_buffer ): with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
with patch( 'ycm.youcompleteme.SendCommandRequest' ) as send_request: with patch( 'ycm.youcompleteme.SendCommandRequest' ) as send_request:
ycm.SendCommandRequest( [ 'GoTo' ], 'python', False, 1, 1 ) ycm.SendCommandRequest( [ 'GoTo' ], 'python', False, 1, 1 )
assert_that( assert_that(
@ -82,7 +82,7 @@ def SendCommandRequest_ExtraConfData_UndefinedValue_test( ycm ):
def SendCommandRequest_BuildRange_NoVisualMarks_test( ycm, *args ): def SendCommandRequest_BuildRange_NoVisualMarks_test( ycm, *args ):
current_buffer = VimBuffer( 'buffer', contents = [ 'first line', current_buffer = VimBuffer( 'buffer', contents = [ 'first line',
'second line' ] ) 'second line' ] )
with MockVimBuffers( [ current_buffer ], current_buffer ): with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
with patch( 'ycm.youcompleteme.SendCommandRequest' ) as send_request: with patch( 'ycm.youcompleteme.SendCommandRequest' ) as send_request:
ycm.SendCommandRequest( [ 'GoTo' ], 'python', True, 1, 2 ) ycm.SendCommandRequest( [ 'GoTo' ], 'python', True, 1, 2 )
send_request.assert_called_once_with( send_request.assert_called_once_with(
@ -114,7 +114,7 @@ def SendCommandRequest_BuildRange_VisualMarks_test( ycm, *args ):
'second line' ], 'second line' ],
visual_start = [ 1, 4 ], visual_start = [ 1, 4 ],
visual_end = [ 2, 8 ] ) visual_end = [ 2, 8 ] )
with MockVimBuffers( [ current_buffer ], current_buffer ): with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
with patch( 'ycm.youcompleteme.SendCommandRequest' ) as send_request: with patch( 'ycm.youcompleteme.SendCommandRequest' ) as send_request:
ycm.SendCommandRequest( [ 'GoTo' ], 'python', True, 1, 2 ) ycm.SendCommandRequest( [ 'GoTo' ], 'python', True, 1, 2 )
send_request.assert_called_once_with( send_request.assert_called_once_with(

View File

@ -66,7 +66,7 @@ def SendCompletionRequest_UnicodeWorkingDirectory_test( ycm ):
return { 'completions': [], 'completion_start_column': 1 } return { 'completions': [], 'completion_start_column': 1 }
with CurrentWorkingDirectory( unicode_dir ): with CurrentWorkingDirectory( unicode_dir ):
with MockVimBuffers( [ current_buffer ], current_buffer ): with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
with MockCompletionRequest( ServerResponse ): with MockCompletionRequest( ServerResponse ):
ycm.SendCompletionRequest() ycm.SendCompletionRequest()
ok_( ycm.CompletionRequestReady() ) ok_( ycm.CompletionRequestReady() )
@ -106,7 +106,7 @@ def SendCompletionRequest_ResponseContainingError_test( ycm, post_vim_message ):
} ] } ]
} }
with MockVimBuffers( [ current_buffer ], current_buffer ): with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
with MockCompletionRequest( ServerResponse ): with MockCompletionRequest( ServerResponse ):
ycm.SendCompletionRequest() ycm.SendCompletionRequest()
ok_( ycm.CompletionRequestReady() ) ok_( ycm.CompletionRequestReady() )
@ -138,7 +138,7 @@ def SendCompletionRequest_ErrorFromServer_test( ycm,
post_vim_message, post_vim_message,
logger ): logger ):
current_buffer = VimBuffer( 'buffer' ) current_buffer = VimBuffer( 'buffer' )
with MockVimBuffers( [ current_buffer ], current_buffer ): with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
with MockCompletionRequest( ServerError( 'Server error' ) ): with MockCompletionRequest( ServerError( 'Server error' ) ):
ycm.SendCompletionRequest() ycm.SendCompletionRequest()
ok_( ycm.CompletionRequestReady() ) ok_( ycm.CompletionRequestReady() )

View File

@ -57,10 +57,9 @@ def MockArbitraryBuffer( filetype ):
# Arbitrary, but valid, single buffer open. # Arbitrary, but valid, single buffer open.
current_buffer = VimBuffer( os.path.realpath( 'TEST_BUFFER' ), current_buffer = VimBuffer( os.path.realpath( 'TEST_BUFFER' ),
window = 1,
filetype = filetype ) filetype = filetype )
with MockVimBuffers( [ current_buffer ], current_buffer ): with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
yield yield
@ -402,7 +401,7 @@ def EventNotification_FileReadyToParse_TagFiles_UnicodeWorkingDirectory_test(
with patch( 'ycm.client.event_notification.EventNotification.' with patch( 'ycm.client.event_notification.EventNotification.'
'PostDataToHandlerAsync' ) as post_data_to_handler_async: 'PostDataToHandlerAsync' ) as post_data_to_handler_async:
with CurrentWorkingDirectory( unicode_dir ): with CurrentWorkingDirectory( unicode_dir ):
with MockVimBuffers( [ current_buffer ], current_buffer, ( 1, 5 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 5 ) ):
ycm.OnFileReadyToParse() ycm.OnFileReadyToParse()
assert_that( assert_that(
@ -455,7 +454,7 @@ def EventNotification_BufferVisit_BuildRequestForCurrentAndUnsavedBuffers_test(
with patch( 'ycm.client.event_notification.EventNotification.' with patch( 'ycm.client.event_notification.EventNotification.'
'PostDataToHandlerAsync' ) as post_data_to_handler_async: 'PostDataToHandlerAsync' ) as post_data_to_handler_async:
with MockVimBuffers( [ current_buffer, modified_buffer, unmodified_buffer ], with MockVimBuffers( [ current_buffer, modified_buffer, unmodified_buffer ],
current_buffer, [ current_buffer ],
( 1, 5 ) ): ( 1, 5 ) ):
ycm.OnBufferVisit() ycm.OnBufferVisit()
@ -503,7 +502,8 @@ def EventNotification_BufferUnload_BuildRequestForDeletedAndUnsavedBuffers_test(
with patch( 'ycm.client.event_notification.EventNotification.' with patch( 'ycm.client.event_notification.EventNotification.'
'PostDataToHandlerAsync' ) as post_data_to_handler_async: 'PostDataToHandlerAsync' ) as post_data_to_handler_async:
with MockVimBuffers( [ current_buffer, deleted_buffer ], current_buffer ): with MockVimBuffers( [ current_buffer, deleted_buffer ],
[ current_buffer ] ):
ycm.OnBufferUnload( deleted_buffer.number ) ycm.OnBufferUnload( deleted_buffer.number )
assert_that( assert_that(
@ -543,7 +543,7 @@ def EventNotification_FileReadyToParse_SyntaxKeywords_SeedWithCache_test(
with patch( 'ycm.client.event_notification.EventNotification.' with patch( 'ycm.client.event_notification.EventNotification.'
'PostDataToHandlerAsync' ) as post_data_to_handler_async: 'PostDataToHandlerAsync' ) as post_data_to_handler_async:
with MockVimBuffers( [ current_buffer ], current_buffer ): with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
ycm.OnFileReadyToParse() ycm.OnFileReadyToParse()
assert_that( assert_that(
# Positional arguments passed to PostDataToHandlerAsync. # Positional arguments passed to PostDataToHandlerAsync.
@ -578,7 +578,7 @@ def EventNotification_FileReadyToParse_SyntaxKeywords_ClearCacheIfRestart_test(
with patch( 'ycm.client.event_notification.EventNotification.' with patch( 'ycm.client.event_notification.EventNotification.'
'PostDataToHandlerAsync' ) as post_data_to_handler_async: 'PostDataToHandlerAsync' ) as post_data_to_handler_async:
with MockVimBuffers( [ current_buffer ], current_buffer ): with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
ycm.OnFileReadyToParse() ycm.OnFileReadyToParse()
assert_that( assert_that(
# Positional arguments passed to PostDataToHandlerAsync. # Positional arguments passed to PostDataToHandlerAsync.

View File

@ -52,7 +52,7 @@ def OmniCompleter_GetCompletions_Cache_List_test( ycm ):
filetype = FILETYPE, filetype = FILETYPE,
omnifunc = Omnifunc ) omnifunc = Omnifunc )
with MockVimBuffers( [ current_buffer ], current_buffer, ( 1, 5 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 5 ) ):
ycm.SendCompletionRequest() ycm.SendCompletionRequest()
assert_that( assert_that(
ycm.GetCompletionResponse(), ycm.GetCompletionResponse(),
@ -76,7 +76,7 @@ def OmniCompleter_GetCompletions_Cache_ListFilter_test( ycm ):
filetype = FILETYPE, filetype = FILETYPE,
omnifunc = Omnifunc ) omnifunc = Omnifunc )
with MockVimBuffers( [ current_buffer ], current_buffer, ( 1, 6 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 6 ) ):
ycm.SendCompletionRequest() ycm.SendCompletionRequest()
assert_that( assert_that(
ycm.GetCompletionResponse(), ycm.GetCompletionResponse(),
@ -100,7 +100,7 @@ def OmniCompleter_GetCompletions_NoCache_List_test( ycm ):
filetype = FILETYPE, filetype = FILETYPE,
omnifunc = Omnifunc ) omnifunc = Omnifunc )
with MockVimBuffers( [ current_buffer ], current_buffer, ( 1, 5 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 5 ) ):
ycm.SendCompletionRequest() ycm.SendCompletionRequest()
assert_that( assert_that(
ycm.GetCompletionResponse(), ycm.GetCompletionResponse(),
@ -124,7 +124,7 @@ def OmniCompleter_GetCompletions_NoCache_ListFilter_test( ycm ):
filetype = FILETYPE, filetype = FILETYPE,
omnifunc = Omnifunc ) omnifunc = Omnifunc )
with MockVimBuffers( [ current_buffer ], current_buffer, ( 1, 6 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 6 ) ):
ycm.SendCompletionRequest() ycm.SendCompletionRequest()
# Actual result is that the results are not filtered, as we expect the # Actual result is that the results are not filtered, as we expect the
# omnifunc or vim itself to do this filtering. # omnifunc or vim itself to do this filtering.
@ -150,7 +150,7 @@ def OmniCompleter_GetCompletions_NoCache_UseFindStart_test( ycm ):
filetype = FILETYPE, filetype = FILETYPE,
omnifunc = Omnifunc ) omnifunc = Omnifunc )
with MockVimBuffers( [ current_buffer ], current_buffer, ( 1, 6 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 6 ) ):
ycm.SendCompletionRequest() ycm.SendCompletionRequest()
# Actual result is that the results are not filtered, as we expect the # Actual result is that the results are not filtered, as we expect the
# omnifunc or vim itself to do this filtering. # omnifunc or vim itself to do this filtering.
@ -176,7 +176,7 @@ def OmniCompleter_GetCompletions_Cache_UseFindStart_test( ycm ):
filetype = FILETYPE, filetype = FILETYPE,
omnifunc = Omnifunc ) omnifunc = Omnifunc )
with MockVimBuffers( [ current_buffer ], current_buffer, ( 1, 6 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 6 ) ):
ycm.SendCompletionRequest() ycm.SendCompletionRequest()
# There are no results because the query 'test.t' doesn't match any # There are no results because the query 'test.t' doesn't match any
# candidate (and cache_omnifunc=1, so we FilterAndSortCandidates). # candidate (and cache_omnifunc=1, so we FilterAndSortCandidates).
@ -202,7 +202,7 @@ def OmniCompleter_GetCompletions_Cache_Object_test( ycm ):
filetype = FILETYPE, filetype = FILETYPE,
omnifunc = Omnifunc ) omnifunc = Omnifunc )
with MockVimBuffers( [ current_buffer ], current_buffer, ( 1, 6 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 6 ) ):
ycm.SendCompletionRequest() ycm.SendCompletionRequest()
assert_that( assert_that(
ycm.GetCompletionResponse(), ycm.GetCompletionResponse(),
@ -241,7 +241,7 @@ def OmniCompleter_GetCompletions_Cache_ObjectList_test( ycm ):
filetype = FILETYPE, filetype = FILETYPE,
omnifunc = Omnifunc ) omnifunc = Omnifunc )
with MockVimBuffers( [ current_buffer ], current_buffer, ( 1, 7 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 7 ) ):
ycm.SendCompletionRequest() ycm.SendCompletionRequest()
assert_that( assert_that(
ycm.GetCompletionResponse(), ycm.GetCompletionResponse(),
@ -286,7 +286,7 @@ def OmniCompleter_GetCompletions_NoCache_ObjectList_test( ycm ):
filetype = FILETYPE, filetype = FILETYPE,
omnifunc = Omnifunc ) omnifunc = Omnifunc )
with MockVimBuffers( [ current_buffer ], current_buffer, ( 1, 7 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 7 ) ):
ycm.SendCompletionRequest() ycm.SendCompletionRequest()
# We don't filter the result - we expect the omnifunc to do that # We don't filter the result - we expect the omnifunc to do that
# based on the query we supplied (Note: that means no fuzzy matching!). # based on the query we supplied (Note: that means no fuzzy matching!).
@ -339,7 +339,7 @@ def OmniCompleter_GetCompletions_Cache_ObjectListObject_test( ycm ):
filetype = FILETYPE, filetype = FILETYPE,
omnifunc = Omnifunc ) omnifunc = Omnifunc )
with MockVimBuffers( [ current_buffer ], current_buffer, ( 1, 7 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 7 ) ):
ycm.SendCompletionRequest() ycm.SendCompletionRequest()
assert_that( assert_that(
ycm.GetCompletionResponse(), ycm.GetCompletionResponse(),
@ -384,7 +384,7 @@ def OmniCompleter_GetCompletions_NoCache_ObjectListObject_test( ycm ):
filetype = FILETYPE, filetype = FILETYPE,
omnifunc = Omnifunc ) omnifunc = Omnifunc )
with MockVimBuffers( [ current_buffer ], current_buffer, ( 1, 7 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 7 ) ):
ycm.SendCompletionRequest() ycm.SendCompletionRequest()
# No FilterAndSortCandidates for cache_omnifunc=0 (we expect the omnifunc # No FilterAndSortCandidates for cache_omnifunc=0 (we expect the omnifunc
# to do the filtering?) # to do the filtering?)
@ -422,7 +422,7 @@ def OmniCompleter_GetCompletions_Cache_List_Unicode_test( ycm ):
filetype = FILETYPE, filetype = FILETYPE,
omnifunc = Omnifunc ) omnifunc = Omnifunc )
with MockVimBuffers( [ current_buffer ], current_buffer, ( 1, 12 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 12 ) ):
ycm.SendCompletionRequest() ycm.SendCompletionRequest()
assert_that( assert_that(
ycm.GetCompletionResponse(), ycm.GetCompletionResponse(),
@ -448,7 +448,7 @@ def OmniCompleter_GetCompletions_NoCache_List_Unicode_test( ycm ):
filetype = FILETYPE, filetype = FILETYPE,
omnifunc = Omnifunc ) omnifunc = Omnifunc )
with MockVimBuffers( [ current_buffer ], current_buffer, ( 1, 12 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 12 ) ):
ycm.SendCompletionRequest() ycm.SendCompletionRequest()
assert_that( assert_that(
ycm.GetCompletionResponse(), ycm.GetCompletionResponse(),
@ -474,7 +474,7 @@ def OmniCompleter_GetCompletions_Cache_List_Filter_Unicode_test( ycm ):
filetype = FILETYPE, filetype = FILETYPE,
omnifunc = Omnifunc ) omnifunc = Omnifunc )
with MockVimBuffers( [ current_buffer ], current_buffer, ( 1, 17 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 17 ) ):
ycm.SendCompletionRequest() ycm.SendCompletionRequest()
assert_that( assert_that(
ycm.GetCompletionResponse(), ycm.GetCompletionResponse(),
@ -498,7 +498,7 @@ def OmniCompleter_GetCompletions_NoCache_List_Filter_Unicode_test( ycm ):
filetype = FILETYPE, filetype = FILETYPE,
omnifunc = Omnifunc ) omnifunc = Omnifunc )
with MockVimBuffers( [ current_buffer ], current_buffer, ( 1, 17 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 17 ) ):
ycm.SendCompletionRequest() ycm.SendCompletionRequest()
assert_that( assert_that(
ycm.GetCompletionResponse(), ycm.GetCompletionResponse(),
@ -537,7 +537,7 @@ def OmniCompleter_GetCompletions_Cache_ObjectList_Unicode_test( ycm ):
filetype = FILETYPE, filetype = FILETYPE,
omnifunc = Omnifunc ) omnifunc = Omnifunc )
with MockVimBuffers( [ current_buffer ], current_buffer, ( 1, 17 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 17 ) ):
ycm.SendCompletionRequest() ycm.SendCompletionRequest()
assert_that( assert_that(
ycm.GetCompletionResponse(), ycm.GetCompletionResponse(),
@ -591,7 +591,7 @@ def OmniCompleter_GetCompletions_Cache_ObjectListObject_Unicode_test( ycm ):
filetype = FILETYPE, filetype = FILETYPE,
omnifunc = Omnifunc ) omnifunc = Omnifunc )
with MockVimBuffers( [ current_buffer ], current_buffer, ( 1, 13 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 13 ) ):
ycm.SendCompletionRequest() ycm.SendCompletionRequest()
assert_that( assert_that(
ycm.GetCompletionResponse(), ycm.GetCompletionResponse(),
@ -634,7 +634,7 @@ def OmniCompleter_GetCompletions_RestoreCursorPositionAfterOmnifuncCall_test(
filetype = FILETYPE, filetype = FILETYPE,
omnifunc = Omnifunc ) omnifunc = Omnifunc )
with MockVimBuffers( [ current_buffer ], current_buffer, ( 3, 5 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 3, 5 ) ):
ycm.SendCompletionRequest() ycm.SendCompletionRequest()
assert_that( assert_that(
vimsupport.CurrentLineAndColumn(), vimsupport.CurrentLineAndColumn(),
@ -662,7 +662,7 @@ def OmniCompleter_GetCompletions_NoCache_NoSemanticTrigger_test( ycm ):
filetype = FILETYPE, filetype = FILETYPE,
omnifunc = Omnifunc ) omnifunc = Omnifunc )
with MockVimBuffers( [ current_buffer ], current_buffer, ( 1, 3 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 3 ) ):
ycm.SendCompletionRequest() ycm.SendCompletionRequest()
assert_that( assert_that(
ycm.GetCompletionResponse(), ycm.GetCompletionResponse(),
@ -686,7 +686,7 @@ def OmniCompleter_GetCompletions_NoCache_ForceSemantic_test( ycm ):
filetype = FILETYPE, filetype = FILETYPE,
omnifunc = Omnifunc ) omnifunc = Omnifunc )
with MockVimBuffers( [ current_buffer ], current_buffer, ( 1, 3 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 3 ) ):
ycm.SendCompletionRequest( force_semantic = True ) ycm.SendCompletionRequest( force_semantic = True )
assert_that( assert_that(
ycm.GetCompletionResponse(), ycm.GetCompletionResponse(),
@ -712,7 +712,7 @@ def OmniCompleter_GetCompletions_FiletypeDisabled_SemanticTrigger_test( ycm ):
filetype = FILETYPE, filetype = FILETYPE,
omnifunc = Omnifunc ) omnifunc = Omnifunc )
with MockVimBuffers( [ current_buffer ], current_buffer, ( 1, 6 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 6 ) ):
ycm.SendCompletionRequest() ycm.SendCompletionRequest()
assert_that( assert_that(
ycm.GetCompletionResponse(), ycm.GetCompletionResponse(),
@ -740,7 +740,7 @@ def OmniCompleter_GetCompletions_AllFiletypesDisabled_SemanticTrigger_test(
filetype = FILETYPE, filetype = FILETYPE,
omnifunc = Omnifunc ) omnifunc = Omnifunc )
with MockVimBuffers( [ current_buffer ], current_buffer, ( 1, 6 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 6 ) ):
ycm.SendCompletionRequest() ycm.SendCompletionRequest()
assert_that( assert_that(
ycm.GetCompletionResponse(), ycm.GetCompletionResponse(),
@ -766,7 +766,7 @@ def OmniCompleter_GetCompletions_FiletypeDisabled_ForceSemantic_test( ycm ):
filetype = FILETYPE, filetype = FILETYPE,
omnifunc = Omnifunc ) omnifunc = Omnifunc )
with MockVimBuffers( [ current_buffer ], current_buffer, ( 1, 6 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 6 ) ):
ycm.SendCompletionRequest( force_semantic = True ) ycm.SendCompletionRequest( force_semantic = True )
assert_that( assert_that(
ycm.GetCompletionResponse(), ycm.GetCompletionResponse(),
@ -792,7 +792,7 @@ def OmniCompleter_GetCompletions_AllFiletypesDisabled_ForceSemantic_test( ycm ):
filetype = FILETYPE, filetype = FILETYPE,
omnifunc = Omnifunc ) omnifunc = Omnifunc )
with MockVimBuffers( [ current_buffer ], current_buffer, ( 1, 6 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 6 ) ):
ycm.SendCompletionRequest( force_semantic = True ) ycm.SendCompletionRequest( force_semantic = True )
assert_that( assert_that(
ycm.GetCompletionResponse(), ycm.GetCompletionResponse(),

View File

@ -22,6 +22,7 @@ from __future__ import absolute_import
# Not installing aliases from python-future; it's unreliable and slow. # Not installing aliases from python-future; it's unreliable and slow.
from builtins import * # noqa from builtins import * # noqa
from collections import defaultdict
from future.utils import iteritems, PY2 from future.utils import iteritems, PY2
from mock import DEFAULT, MagicMock, patch from mock import DEFAULT, MagicMock, patch
from hamcrest import assert_that, equal_to from hamcrest import assert_that, equal_to
@ -70,7 +71,7 @@ LET_REGEX = re.compile( '^let (?P<option>[\w:]+) = (?P<value>.*)$' )
# https://github.com/Valloric/YouCompleteMe/pull/1694 # https://github.com/Valloric/YouCompleteMe/pull/1694
VIM_MOCK = MagicMock() VIM_MOCK = MagicMock()
VIM_MATCHES = [] VIM_MATCHES_FOR_WINDOW = defaultdict( list )
VIM_SIGNS = [] VIM_SIGNS = []
VIM_OPTIONS = { VIM_OPTIONS = {
@ -107,9 +108,9 @@ def _MockGetBufferNumber( buffer_filename ):
def _MockGetBufferWindowNumber( buffer_number ): def _MockGetBufferWindowNumber( buffer_number ):
for vim_buffer in VIM_MOCK.buffers: for window in VIM_MOCK.windows:
if vim_buffer.number == buffer_number and vim_buffer.window: if window.buffer.number == buffer_number:
return vim_buffer.window return window.number
return -1 return -1
@ -198,25 +199,26 @@ def _MockVimFunctionsEval( value ):
def _MockVimMatchEval( value ): def _MockVimMatchEval( value ):
current_window = VIM_MOCK.current.window.number
if value == 'getmatches()': if value == 'getmatches()':
# Returning a copy, because ClearYcmSyntaxMatches() gets the result of return VIM_MATCHES_FOR_WINDOW[ current_window ]
# getmatches(), iterates over it and removes elements from VIM_MATCHES.
return list( VIM_MATCHES )
match = MATCHADD_REGEX.search( value ) match = MATCHADD_REGEX.search( value )
if match: if match:
group = match.group( 'group' ) group = match.group( 'group' )
option = match.group( 'pattern' ) option = match.group( 'pattern' )
vim_match = VimMatch( group, option ) vim_match = VimMatch( group, option )
VIM_MATCHES.append( vim_match ) VIM_MATCHES_FOR_WINDOW[ current_window ].append( vim_match )
return vim_match.id return vim_match.id
match = MATCHDELETE_REGEX.search( value ) match = MATCHDELETE_REGEX.search( value )
if match: if match:
match_id = int( match.group( 'id' ) ) match_id = int( match.group( 'id' ) )
for index, vim_match in enumerate( VIM_MATCHES ): vim_matches = VIM_MATCHES_FOR_WINDOW[ current_window ]
for index, vim_match in enumerate( vim_matches ):
if vim_match.id == match_id: if vim_match.id == match_id:
VIM_MATCHES.pop( index ) vim_matches.pop( index )
return -1 return -1
return 0 return 0
@ -334,7 +336,6 @@ class VimBuffer( object ):
- |filetype| : buffer filetype. Empty string if no filetype is set; - |filetype| : buffer filetype. Empty string if no filetype is set;
- |modified| : True if the buffer has unsaved changes, False otherwise; - |modified| : True if the buffer has unsaved changes, False otherwise;
- |bufhidden|: value of the 'bufhidden' option (see :h bufhidden); - |bufhidden|: value of the 'bufhidden' option (see :h bufhidden);
- |window| : number of the buffer window. None if the buffer is hidden;
- |omnifunc| : omni completion function used by the buffer. Must be a Python - |omnifunc| : omni completion function used by the buffer. Must be a Python
function that takes the same arguments and returns the same function that takes the same arguments and returns the same
values as a Vim completion function (:h complete-functions). values as a Vim completion function (:h complete-functions).
@ -351,7 +352,6 @@ class VimBuffer( object ):
filetype = '', filetype = '',
modified = False, modified = False,
bufhidden = '', bufhidden = '',
window = None,
omnifunc = None, omnifunc = None,
visual_start = None, visual_start = None,
visual_end = None ): visual_end = None ):
@ -361,7 +361,6 @@ class VimBuffer( object ):
self.filetype = filetype self.filetype = filetype
self.modified = modified self.modified = modified
self.bufhidden = bufhidden self.bufhidden = bufhidden
self.window = window
self.omnifunc = omnifunc self.omnifunc = omnifunc
self.omnifunc_name = omnifunc.__name__ if omnifunc else '' self.omnifunc_name = omnifunc.__name__ if omnifunc else ''
self.changedtick = 1 self.changedtick = 1
@ -402,9 +401,9 @@ class VimBuffer( object ):
class VimBuffers( object ): class VimBuffers( object ):
"""An object that looks like a vim.buffers object.""" """An object that looks like a vim.buffers object."""
def __init__( self, *buffers ): def __init__( self, buffers ):
"""Arguments are VimBuffer objects.""" """|buffers| is a list of VimBuffer objects."""
self._buffers = list( buffers ) self._buffers = buffers
def __getitem__( self, number ): def __getitem__( self, number ):
@ -424,10 +423,61 @@ class VimBuffers( object ):
return self._buffers.pop( index ) return self._buffers.pop( index )
class VimWindow( object ):
"""An object that looks like a vim.window object:
- |number|: number of the window;
- |buffer_object|: a VimBuffer object representing the buffer inside the
window;
- |cursor|: a tuple corresponding to the cursor position."""
def __init__( self, number, buffer_object, cursor = None ):
self.number = number
self.buffer = buffer_object
self.cursor = cursor
class VimWindows( object ):
"""An object that looks like a vim.windows object."""
def __init__( self, buffers, cursor ):
"""|buffers| is a list of VimBuffer objects corresponding to the window
layout. The first element of that list is assumed to be the current window.
|cursor| is the cursor position of that window."""
windows = []
windows.append( VimWindow( 1, buffers[ 0 ], cursor ) )
for window_number in range( 1, len( buffers ) ):
windows.append( VimWindow( window_number + 1, buffers[ window_number ] ) )
self._windows = windows
def __getitem__( self, number ):
"""Emulates vim.windows[ number ]"""
for window in self._windows:
if number == window.number:
return window
raise KeyError( number )
def __iter__( self ):
"""Emulates for loop on vim.windows"""
return iter( self._windows )
class VimCurrent( object ):
"""An object that looks like a vim.current object. |current_window| must be a
VimWindow object."""
def __init__( self, current_window ):
self.buffer = current_window.buffer
self.window = current_window
self.line = self.buffer.contents[ current_window.cursor[ 0 ] - 1 ]
class VimMatch( object ): class VimMatch( object ):
def __init__( self, group, pattern ): def __init__( self, group, pattern ):
self.id = len( VIM_MATCHES ) + 1 current_window = VIM_MOCK.current.window.number
self.id = len( VIM_MATCHES_FOR_WINDOW[ current_window ] ) + 1
self.group = group self.group = group
self.pattern = pattern self.pattern = pattern
@ -480,20 +530,26 @@ class VimSign( object ):
@contextlib.contextmanager @contextlib.contextmanager
def MockVimBuffers( buffers, current_buffer, cursor_position = ( 1, 1 ) ): def MockVimBuffers( buffers, window_buffers, cursor_position = ( 1, 1 ) ):
"""Simulates the Vim buffers list |buffers| where |current_buffer| is the """Simulates the Vim buffers list |buffers| where |current_buffer| is the
buffer displayed in the current window and |cursor_position| is the current buffer displayed in the current window and |cursor_position| is the current
cursor position. All buffers are represented by a VimBuffer object.""" cursor position. All buffers are represented by a VimBuffer object."""
if current_buffer not in buffers: if ( not isinstance( buffers, list ) or
raise RuntimeError( 'Current buffer must be part of the buffers list.' ) not all( isinstance( buf, VimBuffer ) for buf in buffers ) ):
raise RuntimeError( 'First parameter must be a list of VimBuffer objects.' )
if ( not isinstance( window_buffers, list ) or
not all( isinstance( buf, VimBuffer ) for buf in window_buffers ) ):
raise RuntimeError( 'Second parameter must be a list of VimBuffer objects '
'representing the window layout.' )
if len( window_buffers ) < 1:
raise RuntimeError( 'Second parameter must contain at least one element '
'which corresponds to the current window.' )
line = current_buffer.contents[ cursor_position[ 0 ] - 1 ] with patch( 'vim.buffers', VimBuffers( buffers ) ):
with patch( 'vim.windows', VimWindows( window_buffers,
with patch( 'vim.buffers', VimBuffers( *buffers ) ): cursor_position ) ) as windows:
with patch( 'vim.current.buffer', current_buffer ): with patch( 'vim.current', VimCurrent( windows[ 1 ] ) ):
with patch( 'vim.current.window.cursor', cursor_position ): yield VIM_MOCK
with patch( 'vim.current.line', line ):
yield VIM_MOCK
def MockVimModule(): def MockVimModule():
@ -518,7 +574,6 @@ def MockVimModule():
Failure to use this approach may lead to unexpected failures in other Failure to use this approach may lead to unexpected failures in other
tests.""" tests."""
VIM_MOCK.buffers = {}
VIM_MOCK.command = MagicMock( side_effect = _MockVimCommand ) VIM_MOCK.command = MagicMock( side_effect = _MockVimCommand )
VIM_MOCK.eval = MagicMock( side_effect = _MockVimEval ) VIM_MOCK.eval = MagicMock( side_effect = _MockVimEval )
VIM_MOCK.error = VimError VIM_MOCK.error = VimError

View File

@ -41,7 +41,7 @@ import json
@patch( 'vim.eval', new_callable = ExtendedMock ) @patch( 'vim.eval', new_callable = ExtendedMock )
def SetLocationListForBuffer_Current_test( vim_eval ): def SetLocationListsForBuffer_Current_test( vim_eval ):
diagnostics = [ { diagnostics = [ {
'bufnr': 3, 'bufnr': 3,
'filename': 'some_filename', 'filename': 'some_filename',
@ -50,18 +50,17 @@ def SetLocationListForBuffer_Current_test( vim_eval ):
'type': 'E', 'type': 'E',
'valid': 1 'valid': 1
} ] } ]
current_buffer = VimBuffer( '/test', number = 3, window = 7 ) current_buffer = VimBuffer( '/test', number = 3 )
with MockVimBuffers( [ current_buffer ], current_buffer, ( 1, 1 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
vimsupport.SetLocationListForBuffer( 3, diagnostics ) vimsupport.SetLocationListsForBuffer( 3, diagnostics )
# We asked for the buffer which is current, so we use winnr 0
vim_eval.assert_has_exact_calls( [ vim_eval.assert_has_exact_calls( [
call( 'setloclist( 0, {0} )'.format( json.dumps( diagnostics ) ) ) call( 'setloclist( 1, {0} )'.format( json.dumps( diagnostics ) ) )
] ) ] )
@patch( 'vim.eval', new_callable = ExtendedMock, side_effect = [ 8, 1 ] ) @patch( 'vim.eval', new_callable = ExtendedMock )
def SetLocationListForBuffer_NotCurrent_test( vim_eval ): def SetLocationListsForBuffer_NotCurrent_test( vim_eval ):
diagnostics = [ { diagnostics = [ {
'bufnr': 3, 'bufnr': 3,
'filename': 'some_filename', 'filename': 'some_filename',
@ -70,22 +69,16 @@ def SetLocationListForBuffer_NotCurrent_test( vim_eval ):
'type': 'E', 'type': 'E',
'valid': 1 'valid': 1
} ] } ]
current_buffer = VimBuffer( '/test', number = 3, window = 7 ) current_buffer = VimBuffer( '/test', number = 3 )
other_buffer = VimBuffer( '/notcurrent', number = 1, window = 8 ) other_buffer = VimBuffer( '/notcurrent', number = 1 )
with MockVimBuffers( [ current_buffer, other_buffer ], with MockVimBuffers( [ current_buffer, other_buffer ], [ current_buffer ] ):
current_buffer, vimsupport.SetLocationListsForBuffer( 1, diagnostics )
( 1, 1 ) ):
vimsupport.SetLocationListForBuffer( 1, diagnostics )
# We asked for a buffer which is not current, so we find the window vim_eval.assert_not_called()
vim_eval.assert_has_exact_calls( [
call( 'bufwinnr(1)' ), # returns 8 due to side_effect
call( 'setloclist( 8, {0} )'.format( json.dumps( diagnostics ) ) )
] )
@patch( 'vim.eval', new_callable = ExtendedMock, side_effect = [ -1, 1 ] ) @patch( 'vim.eval', new_callable = ExtendedMock, side_effect = [ -1, 1 ] )
def SetLocationListForBuffer_NotVisible_test( vim_eval ): def SetLocationListsForBuffer_NotVisible_test( vim_eval ):
diagnostics = [ { diagnostics = [ {
'bufnr': 3, 'bufnr': 3,
'filename': 'some_filename', 'filename': 'some_filename',
@ -94,17 +87,32 @@ def SetLocationListForBuffer_NotVisible_test( vim_eval ):
'type': 'E', 'type': 'E',
'valid': 1 'valid': 1
} ] } ]
current_buffer = VimBuffer( '/test', number = 3, window = 7 ) current_buffer = VimBuffer( '/test', number = 3 )
other_buffer = VimBuffer( '/notcurrent', number = 1, window = 8 ) other_buffer = VimBuffer( '/notcurrent', number = 1 )
with MockVimBuffers( [ current_buffer, other_buffer ], with MockVimBuffers( [ current_buffer, other_buffer ], [ current_buffer ] ):
current_buffer, vimsupport.SetLocationListsForBuffer( 1, diagnostics )
( 1, 1 ) ):
vimsupport.SetLocationListForBuffer( 1, diagnostics ) vim_eval.assert_not_called()
@patch( 'vim.eval', new_callable = ExtendedMock, side_effect = [ -1, 1 ] )
def SetLocationListsForBuffer_MultipleWindows_test( vim_eval ):
diagnostics = [ {
'bufnr': 3,
'filename': 'some_filename',
'lnum': 5,
'col': 22,
'type': 'E',
'valid': 1
} ]
current_buffer = VimBuffer( '/test', number = 3 )
other_buffer = VimBuffer( '/notcurrent', number = 1 )
with MockVimBuffers( [ current_buffer, other_buffer ],
[ current_buffer, other_buffer ] ):
vimsupport.SetLocationListsForBuffer( 1, diagnostics )
# We asked for a buffer which is not current, so we find the window
vim_eval.assert_has_exact_calls( [ vim_eval.assert_has_exact_calls( [
call( 'bufwinnr(1)' ), # returns -1 due to side_effect call( 'setloclist( 2, {0} )'.format( json.dumps( diagnostics ) ) )
call( 'setloclist( 0, {0} )'.format( json.dumps( diagnostics ) ) )
] ) ] )
@ -118,8 +126,8 @@ def SetLocationList_test( vim_eval ):
'type': 'E', 'type': 'E',
'valid': 1 'valid': 1
} ] } ]
current_buffer = VimBuffer( '/test', number = 3, window = 7 ) current_buffer = VimBuffer( '/test', number = 3 )
with MockVimBuffers( [ current_buffer ], current_buffer, ( 1, 1 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 1 ) ):
vimsupport.SetLocationList( diagnostics ) vimsupport.SetLocationList( diagnostics )
vim_eval.assert_has_calls( [ vim_eval.assert_has_calls( [
@ -137,10 +145,10 @@ def SetLocationList_NotCurrent_test( vim_eval ):
'type': 'E', 'type': 'E',
'valid': 1 'valid': 1
} ] } ]
current_buffer = VimBuffer( '/test', number = 3, window = 7 ) current_buffer = VimBuffer( '/test', number = 3 )
other_buffer = VimBuffer( '/notcurrent', number = 1, window = 8 ) other_buffer = VimBuffer( '/notcurrent', number = 1 )
with MockVimBuffers( [ current_buffer, other_buffer ], with MockVimBuffers( [ current_buffer, other_buffer ],
current_buffer, [ current_buffer, other_buffer ],
( 1, 1 ) ): ( 1, 1 ) ):
vimsupport.SetLocationList( diagnostics ) vimsupport.SetLocationList( diagnostics )
@ -171,7 +179,7 @@ def SetFittingHeightForCurrentWindow_test( vim_command, *args ):
# Create a buffer with one line that is longer than the window width. # Create a buffer with one line that is longer than the window width.
current_buffer = VimBuffer( 'buffer', current_buffer = VimBuffer( 'buffer',
contents = [ 'a' * 140 ] ) contents = [ 'a' * 140 ] )
with MockVimBuffers( [ current_buffer ], current_buffer ): with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
vimsupport.SetFittingHeightForCurrentWindow() vimsupport.SetFittingHeightForCurrentWindow()
vim_command.assert_called_once_with( '2wincmd _' ) vim_command.assert_called_once_with( '2wincmd _' )
@ -1373,24 +1381,21 @@ def WriteToPreviewWindow_JumpFail_MultiLine_test( vim_current, vim_command ):
def BufferIsVisibleForFilename_test(): def BufferIsVisibleForFilename_test():
vim_buffers = [ visible_buffer = VimBuffer( 'visible_filename', number = 1 )
VimBuffer( 'visible_filename', number = 1, window = 1 ), hidden_buffer = VimBuffer( 'hidden_filename', number = 2 )
VimBuffer( 'hidden_filename', number = 2, window = None )
]
with patch( 'vim.buffers', vim_buffers ): with MockVimBuffers( [ visible_buffer, hidden_buffer ], [ visible_buffer ] ):
eq_( vimsupport.BufferIsVisibleForFilename( 'visible_filename' ), True ) eq_( vimsupport.BufferIsVisibleForFilename( 'visible_filename' ), True )
eq_( vimsupport.BufferIsVisibleForFilename( 'hidden_filename' ), False ) eq_( vimsupport.BufferIsVisibleForFilename( 'hidden_filename' ), False )
eq_( vimsupport.BufferIsVisibleForFilename( 'another_filename' ), False ) eq_( vimsupport.BufferIsVisibleForFilename( 'another_filename' ), False )
def CloseBuffersForFilename_test(): def CloseBuffersForFilename_test():
vim_buffers = [ current_buffer = VimBuffer( 'some_filename', number = 2 )
VimBuffer( 'some_filename', number = 2 ), other_buffer = VimBuffer( 'some_filename', number = 5 )
VimBuffer( 'some_filename', number = 5 )
]
with MockVimBuffers( vim_buffers, vim_buffers[ 0 ] ) as vim: with MockVimBuffers( [ current_buffer, other_buffer ],
[ current_buffer ] ) as vim:
vimsupport.CloseBuffersForFilename( 'some_filename' ) vimsupport.CloseBuffersForFilename( 'some_filename' )
assert_that( vim.buffers, empty() ) assert_that( vim.buffers, empty() )
@ -1555,7 +1560,7 @@ def SelectFromList_Negative_test( vim_eval ):
def Filetypes_IntegerFiletype_test(): def Filetypes_IntegerFiletype_test():
current_buffer = VimBuffer( 'buffer', number = 1, filetype = '42' ) current_buffer = VimBuffer( 'buffer', number = 1, filetype = '42' )
with MockVimBuffers( [ current_buffer ], current_buffer ): with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
assert_that( vimsupport.CurrentFiletypes(), contains( '42' ) ) assert_that( vimsupport.CurrentFiletypes(), contains( '42' ) )
assert_that( vimsupport.GetBufferFiletypes( 1 ), contains( '42' ) ) assert_that( vimsupport.GetBufferFiletypes( 1 ), contains( '42' ) )
assert_that( vimsupport.FiletypesForBuffer( current_buffer ), assert_that( vimsupport.FiletypesForBuffer( current_buffer ),
@ -1613,7 +1618,7 @@ def JumpToLocation_SameFile_SameBuffer_NoSwapFile_test( vim_command ):
# No 'u' prefix for the current buffer name string to simulate Vim returning # No 'u' prefix for the current buffer name string to simulate Vim returning
# bytes on Python 2 but unicode on Python 3. # bytes on Python 2 but unicode on Python 3.
current_buffer = VimBuffer( 'uni¢𐍈d€' ) current_buffer = VimBuffer( 'uni¢𐍈d€' )
with MockVimBuffers( [ current_buffer ], current_buffer ) as vim: with MockVimBuffers( [ current_buffer ], [ current_buffer ] ) as vim:
vimsupport.JumpToLocation( os.path.realpath( u'uni¢𐍈d€' ), 2, 5 ) vimsupport.JumpToLocation( os.path.realpath( u'uni¢𐍈d€' ), 2, 5 )
assert_that( vim.current.window.cursor, equal_to( ( 2, 4 ) ) ) assert_that( vim.current.window.cursor, equal_to( ( 2, 4 ) ) )
@ -1628,7 +1633,7 @@ def JumpToLocation_SameFile_SameBuffer_NoSwapFile_test( vim_command ):
@patch( 'vim.command', new_callable = ExtendedMock ) @patch( 'vim.command', new_callable = ExtendedMock )
def JumpToLocation_DifferentFile_SameBuffer_Unmodified_test( vim_command ): def JumpToLocation_DifferentFile_SameBuffer_Unmodified_test( vim_command ):
current_buffer = VimBuffer( 'uni¢𐍈d€' ) current_buffer = VimBuffer( 'uni¢𐍈d€' )
with MockVimBuffers( [ current_buffer ], current_buffer ) as vim: with MockVimBuffers( [ current_buffer ], [ current_buffer ] ) as vim:
target_name = os.path.realpath( u'different_uni¢𐍈d€' ) target_name = os.path.realpath( u'different_uni¢𐍈d€' )
vimsupport.JumpToLocation( target_name, 2, 5 ) vimsupport.JumpToLocation( target_name, 2, 5 )
@ -1648,7 +1653,7 @@ def JumpToLocation_DifferentFile_SameBuffer_Modified_CannotHide_test(
vim_command ): vim_command ):
current_buffer = VimBuffer( 'uni¢𐍈d€', modified = True ) current_buffer = VimBuffer( 'uni¢𐍈d€', modified = True )
with MockVimBuffers( [ current_buffer ], current_buffer ) as vim: with MockVimBuffers( [ current_buffer ], [ current_buffer ] ) as vim:
target_name = os.path.realpath( u'different_uni¢𐍈d€' ) target_name = os.path.realpath( u'different_uni¢𐍈d€' )
vimsupport.JumpToLocation( target_name, 2, 5 ) vimsupport.JumpToLocation( target_name, 2, 5 )
@ -1668,7 +1673,7 @@ def JumpToLocation_DifferentFile_SameBuffer_Modified_CanHide_test(
vim_command ): vim_command ):
current_buffer = VimBuffer( 'uni¢𐍈d€', modified = True, bufhidden = "hide" ) current_buffer = VimBuffer( 'uni¢𐍈d€', modified = True, bufhidden = "hide" )
with MockVimBuffers( [ current_buffer ], current_buffer ) as vim: with MockVimBuffers( [ current_buffer ], [ current_buffer ] ) as vim:
target_name = os.path.realpath( u'different_uni¢𐍈d€' ) target_name = os.path.realpath( u'different_uni¢𐍈d€' )
vimsupport.JumpToLocation( target_name, 2, 5 ) vimsupport.JumpToLocation( target_name, 2, 5 )
@ -1689,7 +1694,7 @@ def JumpToLocation_DifferentFile_SameBuffer_SwapFile_Unexpected_test(
vim_command ): vim_command ):
current_buffer = VimBuffer( 'uni¢𐍈d€' ) current_buffer = VimBuffer( 'uni¢𐍈d€' )
with MockVimBuffers( [ current_buffer ], current_buffer ): with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
assert_that( assert_that(
calling( vimsupport.JumpToLocation ).with_args( calling( vimsupport.JumpToLocation ).with_args(
os.path.realpath( u'different_uni¢𐍈d€' ), 2, 5 ), os.path.realpath( u'different_uni¢𐍈d€' ), 2, 5 ),
@ -1704,7 +1709,7 @@ def JumpToLocation_DifferentFile_SameBuffer_SwapFile_Unexpected_test(
side_effect = [ None, VimError( 'E325' ), None ] ) side_effect = [ None, VimError( 'E325' ), None ] )
def JumpToLocation_DifferentFile_SameBuffer_SwapFile_Quit_test( vim_command ): def JumpToLocation_DifferentFile_SameBuffer_SwapFile_Quit_test( vim_command ):
current_buffer = VimBuffer( 'uni¢𐍈d€' ) current_buffer = VimBuffer( 'uni¢𐍈d€' )
with MockVimBuffers( [ current_buffer ], current_buffer ): with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
target_name = os.path.realpath( u'different_uni¢𐍈d€' ) target_name = os.path.realpath( u'different_uni¢𐍈d€' )
vimsupport.JumpToLocation( target_name, 2, 5 ) vimsupport.JumpToLocation( target_name, 2, 5 )
@ -1722,7 +1727,7 @@ def JumpToLocation_DifferentFile_SameBuffer_SwapFile_Quit_test( vim_command ):
side_effect = [ None, KeyboardInterrupt, None ] ) side_effect = [ None, KeyboardInterrupt, None ] )
def JumpToLocation_DifferentFile_SameBuffer_SwapFile_Abort_test( vim_command ): def JumpToLocation_DifferentFile_SameBuffer_SwapFile_Abort_test( vim_command ):
current_buffer = VimBuffer( 'uni¢𐍈d€' ) current_buffer = VimBuffer( 'uni¢𐍈d€' )
with MockVimBuffers( [ current_buffer ], current_buffer ): with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
target_name = os.path.realpath( u'different_uni¢𐍈d€' ) target_name = os.path.realpath( u'different_uni¢𐍈d€' )
vimsupport.JumpToLocation( target_name, 2, 5 ) vimsupport.JumpToLocation( target_name, 2, 5 )
@ -1740,7 +1745,7 @@ def JumpToLocation_DifferentFile_NewOrExistingTab_NotAlreadyOpened_test(
vim_command ): vim_command ):
current_buffer = VimBuffer( 'uni¢𐍈d€' ) current_buffer = VimBuffer( 'uni¢𐍈d€' )
with MockVimBuffers( [ current_buffer ], current_buffer ): with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
target_name = os.path.realpath( u'different_uni¢𐍈d€' ) target_name = os.path.realpath( u'different_uni¢𐍈d€' )
vimsupport.JumpToLocation( target_name, 2, 5 ) vimsupport.JumpToLocation( target_name, 2, 5 )
@ -1765,7 +1770,7 @@ def JumpToLocation_DifferentFile_NewOrExistingTab_AlreadyOpened_test(
current_tab = MagicMock( windows = [ current_window, different_window ] ) current_tab = MagicMock( windows = [ current_window, different_window ] )
with patch( 'vim.tabpages', [ current_tab ] ): with patch( 'vim.tabpages', [ current_tab ] ):
with MockVimBuffers( [ current_buffer, different_buffer ], with MockVimBuffers( [ current_buffer, different_buffer ],
current_buffer ) as vim: [ current_buffer ] ) as vim:
vimsupport.JumpToLocation( os.path.realpath( u'different_uni¢𐍈d€' ), vimsupport.JumpToLocation( os.path.realpath( u'different_uni¢𐍈d€' ),
2, 5 ) 2, 5 )

View File

@ -28,8 +28,8 @@ MockVimModule()
import os import os
import sys import sys
from hamcrest import ( assert_that, contains, empty, equal_to, is_in, is_not, from hamcrest import ( assert_that, contains, empty, equal_to, has_entries,
matches_regexp ) is_in, is_not, matches_regexp )
from mock import call, MagicMock, patch from mock import call, MagicMock, patch
from ycm.paths import _PathToPythonUsedDuringBuild from ycm.paths import _PathToPythonUsedDuringBuild
@ -194,8 +194,8 @@ def YouCompleteMe_DebugInfo_ServerRunning_test( ycm ):
extra_conf = os.path.join( dir_of_script, 'testdata', '.ycm_extra_conf.py' ) extra_conf = os.path.join( dir_of_script, 'testdata', '.ycm_extra_conf.py' )
_LoadExtraConfFile( extra_conf ) _LoadExtraConfFile( extra_conf )
current_buffer = VimBuffer( buf_name, filetype='cpp' ) current_buffer = VimBuffer( buf_name, filetype = 'cpp' )
with MockVimBuffers( [ current_buffer ], current_buffer ): with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
assert_that( assert_that(
ycm.DebugInfo(), ycm.DebugInfo(),
matches_regexp( matches_regexp(
@ -224,7 +224,7 @@ def YouCompleteMe_DebugInfo_ServerNotRunning_test( ycm ):
StopServer( ycm ) StopServer( ycm )
current_buffer = VimBuffer( 'current_buffer' ) current_buffer = VimBuffer( 'current_buffer' )
with MockVimBuffers( [ current_buffer ], current_buffer ): with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
assert_that( assert_that(
ycm.DebugInfo(), ycm.DebugInfo(),
matches_regexp( matches_regexp(
@ -264,8 +264,8 @@ def YouCompleteMe_OnVimLeave_KeepClientLogfile_test( ycm ):
def YouCompleteMe_ToggleLogs_WithParameters_test( ycm, def YouCompleteMe_ToggleLogs_WithParameters_test( ycm,
open_filename, open_filename,
close_buffers_for_filename ): close_buffers_for_filename ):
logfile_buffer = VimBuffer( ycm._client_logfile, window = 1 ) logfile_buffer = VimBuffer( ycm._client_logfile )
with MockVimBuffers( [ logfile_buffer ], logfile_buffer ): with MockVimBuffers( [ logfile_buffer ], [ logfile_buffer ] ):
ycm.ToggleLogs( os.path.basename( ycm._client_logfile ), ycm.ToggleLogs( os.path.basename( ycm._client_logfile ),
'nonexisting_logfile', 'nonexisting_logfile',
os.path.basename( ycm._server_stdout ) ) os.path.basename( ycm._server_stdout ) )
@ -290,7 +290,7 @@ def YouCompleteMe_ToggleLogs_WithoutParameters_SelectLogfileNotAlreadyOpen_test(
ycm, open_filename, *args ): ycm, open_filename, *args ):
current_buffer = VimBuffer( 'current_buffer' ) current_buffer = VimBuffer( 'current_buffer' )
with MockVimBuffers( [ current_buffer ], current_buffer ): with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
ycm.ToggleLogs() ycm.ToggleLogs()
open_filename.assert_has_exact_calls( [ open_filename.assert_has_exact_calls( [
@ -309,8 +309,8 @@ def YouCompleteMe_ToggleLogs_WithoutParameters_SelectLogfileNotAlreadyOpen_test(
def YouCompleteMe_ToggleLogs_WithoutParameters_SelectLogfileAlreadyOpen_test( def YouCompleteMe_ToggleLogs_WithoutParameters_SelectLogfileAlreadyOpen_test(
ycm, close_buffers_for_filename, *args ): ycm, close_buffers_for_filename, *args ):
logfile_buffer = VimBuffer( ycm._server_stdout, window = 1 ) logfile_buffer = VimBuffer( ycm._server_stdout )
with MockVimBuffers( [ logfile_buffer ], logfile_buffer ): with MockVimBuffers( [ logfile_buffer ], [ logfile_buffer ] ):
ycm.ToggleLogs() ycm.ToggleLogs()
close_buffers_for_filename.assert_has_exact_calls( [ close_buffers_for_filename.assert_has_exact_calls( [
@ -326,7 +326,7 @@ def YouCompleteMe_ToggleLogs_WithoutParameters_NoSelection_test(
ycm, post_vim_message, *args ): ycm, post_vim_message, *args ):
current_buffer = VimBuffer( 'current_buffer' ) current_buffer = VimBuffer( 'current_buffer' )
with MockVimBuffers( [ current_buffer ], current_buffer ): with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
ycm.ToggleLogs() ycm.ToggleLogs()
assert_that( assert_that(
@ -339,7 +339,7 @@ def YouCompleteMe_ToggleLogs_WithoutParameters_NoSelection_test(
@YouCompleteMeInstance() @YouCompleteMeInstance()
def YouCompleteMe_GetDefinedSubcommands_ListFromServer_test( ycm ): def YouCompleteMe_GetDefinedSubcommands_ListFromServer_test( ycm ):
current_buffer = VimBuffer( 'buffer' ) current_buffer = VimBuffer( 'buffer' )
with MockVimBuffers( [ current_buffer ], current_buffer ): with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
with patch( 'ycm.client.base_request._JsonFromFuture', with patch( 'ycm.client.base_request._JsonFromFuture',
return_value = [ 'SomeCommand', 'AnotherCommand' ] ): return_value = [ 'SomeCommand', 'AnotherCommand' ] ):
assert_that( assert_that(
@ -358,7 +358,7 @@ def YouCompleteMe_GetDefinedSubcommands_ErrorFromServer_test( ycm,
post_vim_message, post_vim_message,
logger ): logger ):
current_buffer = VimBuffer( 'buffer' ) current_buffer = VimBuffer( 'buffer' )
with MockVimBuffers( [ current_buffer ], current_buffer ): with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
with patch( 'ycm.client.base_request._JsonFromFuture', with patch( 'ycm.client.base_request._JsonFromFuture',
side_effect = ServerError( 'Server error' ) ): side_effect = ServerError( 'Server error' ) ):
result = ycm.GetDefinedSubcommands() result = ycm.GetDefinedSubcommands()
@ -376,7 +376,7 @@ def YouCompleteMe_ShowDetailedDiagnostic_MessageFromServer_test(
ycm, post_vim_message ): ycm, post_vim_message ):
current_buffer = VimBuffer( 'buffer' ) current_buffer = VimBuffer( 'buffer' )
with MockVimBuffers( [ current_buffer ], current_buffer ): with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
with patch( 'ycm.client.base_request._JsonFromFuture', with patch( 'ycm.client.base_request._JsonFromFuture',
return_value = { 'message': 'some_detailed_diagnostic' } ): return_value = { 'message': 'some_detailed_diagnostic' } ):
ycm.ShowDetailedDiagnostic(), ycm.ShowDetailedDiagnostic(),
@ -392,7 +392,7 @@ def YouCompleteMe_ShowDetailedDiagnostic_Exception_test(
ycm, post_vim_message ): ycm, post_vim_message ):
current_buffer = VimBuffer( 'buffer' ) current_buffer = VimBuffer( 'buffer' )
with MockVimBuffers( [ current_buffer ], current_buffer ): with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
with patch( 'ycm.client.base_request._JsonFromFuture', with patch( 'ycm.client.base_request._JsonFromFuture',
side_effect = RuntimeError( 'Some exception' ) ): side_effect = RuntimeError( 'Some exception' ) ):
ycm.ShowDetailedDiagnostic(), ycm.ShowDetailedDiagnostic(),
@ -408,7 +408,7 @@ def YouCompleteMe_ShowDiagnostics_FiletypeNotSupported_test( ycm,
post_vim_message ): post_vim_message ):
current_buffer = VimBuffer( 'buffer', filetype = 'not_supported' ) current_buffer = VimBuffer( 'buffer', filetype = 'not_supported' )
with MockVimBuffers( [ current_buffer ], current_buffer ): with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
ycm.ShowDiagnostics() ycm.ShowDiagnostics()
post_vim_message.assert_called_once_with( post_vim_message.assert_called_once_with(
@ -424,8 +424,8 @@ def YouCompleteMe_ShowDiagnostics_FiletypeNotSupported_test( ycm,
def YouCompleteMe_ShowDiagnostics_NoDiagnosticsDetected_test( def YouCompleteMe_ShowDiagnostics_NoDiagnosticsDetected_test(
ycm, set_location_list_for_window, post_vim_message, *args ): ycm, set_location_list_for_window, post_vim_message, *args ):
current_buffer = VimBuffer( 'buffer', filetype = 'cpp', window = 99 ) current_buffer = VimBuffer( 'buffer', filetype = 'cpp' )
with MockVimBuffers( [ current_buffer ], current_buffer ): with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
with patch( 'ycm.client.event_notification.EventNotification.Response', with patch( 'ycm.client.event_notification.EventNotification.Response',
return_value = {} ): return_value = {} ):
ycm.ShowDiagnostics() ycm.ShowDiagnostics()
@ -436,7 +436,7 @@ def YouCompleteMe_ShowDiagnostics_NoDiagnosticsDetected_test(
call( 'Diagnostics refreshed', warning = False ), call( 'Diagnostics refreshed', warning = False ),
call( 'No warnings or errors detected.', warning = False ) call( 'No warnings or errors detected.', warning = False )
] ) ] )
set_location_list_for_window.assert_called_once_with( 0, [] ) set_location_list_for_window.assert_called_once_with( 1, [] )
@YouCompleteMeInstance( { 'g:ycm_log_level': 'debug', @YouCompleteMeInstance( { 'g:ycm_log_level': 'debug',
@ -461,9 +461,8 @@ def YouCompleteMe_ShowDiagnostics_DiagnosticsFound_DoNotOpenLocationList_test(
current_buffer = VimBuffer( 'buffer', current_buffer = VimBuffer( 'buffer',
filetype = 'cpp', filetype = 'cpp',
number = 3, number = 3 )
window = 99 ) with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
with MockVimBuffers( [ current_buffer ], current_buffer ):
with patch( 'ycm.client.event_notification.EventNotification.Response', with patch( 'ycm.client.event_notification.EventNotification.Response',
return_value = [ diagnostic ] ): return_value = [ diagnostic ] ):
ycm.ShowDiagnostics() ycm.ShowDiagnostics()
@ -473,7 +472,7 @@ def YouCompleteMe_ShowDiagnostics_DiagnosticsFound_DoNotOpenLocationList_test(
warning = False ), warning = False ),
call( 'Diagnostics refreshed', warning = False ) call( 'Diagnostics refreshed', warning = False )
] ) ] )
set_location_list_for_window.assert_called_once_with( 0, [ { set_location_list_for_window.assert_called_once_with( 1, [ {
'bufnr': 3, 'bufnr': 3,
'lnum': 19, 'lnum': 19,
'col': 2, 'col': 2,
@ -508,9 +507,8 @@ def YouCompleteMe_ShowDiagnostics_DiagnosticsFound_OpenLocationList_test(
current_buffer = VimBuffer( 'buffer', current_buffer = VimBuffer( 'buffer',
filetype = 'cpp', filetype = 'cpp',
number = 3, number = 3 )
window = 99 ) with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
with MockVimBuffers( [ current_buffer ], current_buffer ):
with patch( 'ycm.client.event_notification.EventNotification.Response', with patch( 'ycm.client.event_notification.EventNotification.Response',
return_value = [ diagnostic ] ): return_value = [ diagnostic ] ):
ycm.ShowDiagnostics() ycm.ShowDiagnostics()
@ -520,7 +518,7 @@ def YouCompleteMe_ShowDiagnostics_DiagnosticsFound_OpenLocationList_test(
warning = False ), warning = False ),
call( 'Diagnostics refreshed', warning = False ) call( 'Diagnostics refreshed', warning = False )
] ) ] )
set_location_list_for_window.assert_called_once_with( 0, [ { set_location_list_for_window.assert_called_once_with( 1, [ {
'bufnr': 3, 'bufnr': 3,
'lnum': 19, 'lnum': 19,
'col': 2, 'col': 2,
@ -607,13 +605,12 @@ def YouCompleteMe_UpdateDiagnosticInterface_PrioritizeErrorsOverWarnings_test(
current_buffer = VimBuffer( 'buffer', current_buffer = VimBuffer( 'buffer',
filetype = 'c', filetype = 'c',
contents = contents.splitlines(), contents = contents.splitlines(),
number = 5, number = 5 )
window = 2 )
test_utils.VIM_MATCHES = [] test_utils.VIM_MATCHES_FOR_WINDOW.clear()
test_utils.VIM_SIGNS = [] test_utils.VIM_SIGNS = []
with MockVimBuffers( [ current_buffer ], current_buffer, ( 3, 1 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 3, 1 ) ):
with patch( 'ycm.client.event_notification.EventNotification.Response', with patch( 'ycm.client.event_notification.EventNotification.Response',
return_value = diagnostics ): return_value = diagnostics ):
ycm.OnFileReadyToParse() ycm.OnFileReadyToParse()
@ -626,12 +623,14 @@ def YouCompleteMe_UpdateDiagnosticInterface_PrioritizeErrorsOverWarnings_test(
# Error match is added after warning matches. # Error match is added after warning matches.
assert_that( assert_that(
test_utils.VIM_MATCHES, test_utils.VIM_MATCHES_FOR_WINDOW,
contains( has_entries( {
VimMatch( 'YcmWarningSection', '\%3l\%5c\_.\{-}\%3l\%7c' ), 1: contains(
VimMatch( 'YcmWarningSection', '\%3l\%3c\_.\{-}\%3l\%9c' ), VimMatch( 'YcmWarningSection', '\%3l\%5c\_.\{-}\%3l\%7c' ),
VimMatch( 'YcmErrorSection', '\%3l\%8c' ) VimMatch( 'YcmWarningSection', '\%3l\%3c\_.\{-}\%3l\%9c' ),
) VimMatch( 'YcmErrorSection', '\%3l\%8c' )
)
} )
) )
# Only the error sign is placed. # Only the error sign is placed.
@ -643,19 +642,19 @@ def YouCompleteMe_UpdateDiagnosticInterface_PrioritizeErrorsOverWarnings_test(
) )
# The error is not echoed again when moving the cursor along the line. # The error is not echoed again when moving the cursor along the line.
with MockVimBuffers( [ current_buffer ], current_buffer, ( 3, 2 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 3, 2 ) ):
post_vim_message.reset_mock() post_vim_message.reset_mock()
ycm.OnCursorMoved() ycm.OnCursorMoved()
post_vim_message.assert_not_called() post_vim_message.assert_not_called()
# The error is cleared when moving the cursor to another line. # The error is cleared when moving the cursor to another line.
with MockVimBuffers( [ current_buffer ], current_buffer, ( 2, 2 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 2, 2 ) ):
post_vim_message.reset_mock() post_vim_message.reset_mock()
ycm.OnCursorMoved() ycm.OnCursorMoved()
post_vim_message.assert_called_once_with( "", warning = False ) post_vim_message.assert_called_once_with( "", warning = False )
# The error is echoed when moving the cursor back. # The error is echoed when moving the cursor back.
with MockVimBuffers( [ current_buffer ], current_buffer, ( 3, 2 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 3, 2 ) ):
post_vim_message.reset_mock() post_vim_message.reset_mock()
ycm.OnCursorMoved() ycm.OnCursorMoved()
post_vim_message.assert_called_once_with( post_vim_message.assert_called_once_with(
@ -668,11 +667,13 @@ def YouCompleteMe_UpdateDiagnosticInterface_PrioritizeErrorsOverWarnings_test(
ycm.HandleFileParseRequest( block = True ) ycm.HandleFileParseRequest( block = True )
assert_that( assert_that(
test_utils.VIM_MATCHES, test_utils.VIM_MATCHES_FOR_WINDOW,
contains( has_entries( {
VimMatch( 'YcmWarningSection', '\%3l\%5c\_.\{-}\%3l\%7c' ), 1: contains(
VimMatch( 'YcmWarningSection', '\%3l\%3c\_.\{-}\%3l\%9c' ) VimMatch( 'YcmWarningSection', '\%3l\%5c\_.\{-}\%3l\%7c' ),
) VimMatch( 'YcmWarningSection', '\%3l\%3c\_.\{-}\%3l\%9c' )
)
} )
) )
assert_that( assert_that(
@ -687,23 +688,25 @@ def YouCompleteMe_UpdateDiagnosticInterface_PrioritizeErrorsOverWarnings_test(
def YouCompleteMe_UpdateMatches_ClearDiagnosticMatchesInNewBuffer_test( ycm ): def YouCompleteMe_UpdateMatches_ClearDiagnosticMatchesInNewBuffer_test( ycm ):
current_buffer = VimBuffer( 'buffer', current_buffer = VimBuffer( 'buffer',
filetype = 'c', filetype = 'c',
number = 5, number = 5 )
window = 2 )
test_utils.VIM_MATCHES = [ test_utils.VIM_MATCHES_FOR_WINDOW.clear()
test_utils.VIM_MATCHES_FOR_WINDOW[ 1 ] = [
VimMatch( 'YcmWarningSection', '\%3l\%5c\_.\{-}\%3l\%7c' ), VimMatch( 'YcmWarningSection', '\%3l\%5c\_.\{-}\%3l\%7c' ),
VimMatch( 'YcmWarningSection', '\%3l\%3c\_.\{-}\%3l\%9c' ), VimMatch( 'YcmWarningSection', '\%3l\%3c\_.\{-}\%3l\%9c' ),
VimMatch( 'YcmErrorSection', '\%3l\%8c' ) VimMatch( 'YcmErrorSection', '\%3l\%8c' )
] ]
with MockVimBuffers( [ current_buffer ], current_buffer ): with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
ycm.UpdateMatches() ycm.UpdateMatches()
assert_that( test_utils.VIM_MATCHES, empty() ) assert_that( test_utils.VIM_MATCHES_FOR_WINDOW,
has_entries( { 1: empty() } ) )
@YouCompleteMeInstance( { 'g:ycm_echo_current_diagnostic': 1, @YouCompleteMeInstance( { 'g:ycm_echo_current_diagnostic': 1,
'g:ycm_always_populate_location_list': 1 } ) 'g:ycm_always_populate_location_list': 1,
'g:ycm_enable_diagnostic_highlighting': 1 } )
@patch.object( ycm_buffer_module, @patch.object( ycm_buffer_module,
'DIAGNOSTIC_UI_ASYNC_FILETYPES', 'DIAGNOSTIC_UI_ASYNC_FILETYPES',
[ 'ycmtest' ] ) [ 'ycmtest' ] )
@ -731,6 +734,19 @@ def YouCompleteMe_AsyncDiagnosticUpdate_SingleFile_test( ycm,
'line_num': 1, 'line_num': 1,
'column_num': 1 'column_num': 1
}, },
'location_extent': {
'start': {
'filepath': '/current',
'line_num': 1,
'column_num': 1,
},
'end': {
'filepath': '/current',
'line_num': 1,
'column_num': 1,
}
},
'ranges': []
}, },
{ {
'kind': 'ERROR', 'kind': 'ERROR',
@ -740,6 +756,19 @@ def YouCompleteMe_AsyncDiagnosticUpdate_SingleFile_test( ycm,
'line_num': 4, 'line_num': 4,
'column_num': 2 'column_num': 2
}, },
'location_extent': {
'start': {
'filepath': '/has_diags',
'line_num': 4,
'column_num': 2,
},
'end': {
'filepath': '/has_diags',
'line_num': 4,
'column_num': 2,
}
},
'ranges': []
}, },
{ {
'kind': 'ERROR', 'kind': 'ERROR',
@ -749,76 +778,99 @@ def YouCompleteMe_AsyncDiagnosticUpdate_SingleFile_test( ycm,
'line_num': 8, 'line_num': 8,
'column_num': 4 'column_num': 4
}, },
}, 'location_extent': {
'start': {
'filepath': '/not_open',
'line_num': 8,
'column_num': 4,
},
'end': {
'filepath': '/not_open',
'line_num': 8,
'column_num': 4,
}
},
'ranges': []
}
] ]
current_buffer = VimBuffer( '/current', current_buffer = VimBuffer( '/current',
filetype = 'ycmtest', filetype = 'ycmtest',
number = 1, contents = [ 'current' ] * 10,
window = 10 ) number = 1 )
buffers = [ no_diags_buffer = VimBuffer( '/no_diags',
current_buffer, filetype = 'ycmtest',
VimBuffer( '/no_diags', contents = [ 'nodiags' ] * 10,
filetype = 'ycmtest', number = 2 )
number = 2, hidden_buffer = VimBuffer( '/has_diags',
window = 9 ), filetype = 'ycmtest',
VimBuffer( '/has_diags', contents = [ 'hasdiags' ] * 10,
filetype = 'ycmtest', number = 3 )
number = 3,
window = 8 ), buffers = [ current_buffer, no_diags_buffer, hidden_buffer ]
] windows = [ current_buffer, no_diags_buffer ]
# Register each buffer internally with YCM # Register each buffer internally with YCM
for current in buffers: for current in buffers:
with MockVimBuffers( buffers, current, ( 1, 1 ) ): with MockVimBuffers( buffers, [ current ] ):
ycm.OnFileReadyToParse() ycm.OnFileReadyToParse()
with patch( 'ycm.vimsupport.SetLocationListForWindow', with patch( 'ycm.vimsupport.SetLocationListForWindow',
new_callable = ExtendedMock ) as set_location_list_for_window: new_callable = ExtendedMock ) as set_location_list_for_window:
with MockVimBuffers( buffers, current_buffer, ( 1, 1 ) ): with MockVimBuffers( buffers, windows ):
ycm.UpdateWithNewDiagnosticsForFile( '/current', diagnostics ) ycm.UpdateWithNewDiagnosticsForFile( '/current', diagnostics )
# We update the diagnostic on the current cursor position # We update the diagnostic on the current cursor position
post_vim_message.assert_has_exact_calls( [ post_vim_message.assert_has_exact_calls( [
call( "error text in current buffer", truncate = True, warning = False ), call( "error text in current buffer", truncate = True, warning = False ),
] ) ] )
# Ensure we included all the diags though # Ensure we included all the diags though
set_location_list_for_window.assert_has_exact_calls( [ set_location_list_for_window.assert_has_exact_calls( [
call( 0, [ call( 1, [
{ {
'lnum': 1, 'lnum': 1,
'col': 1, 'col': 1,
'bufnr': 1, 'bufnr': 1,
'valid': 1, 'valid': 1,
'type': 'E', 'type': 'E',
'text': 'error text in current buffer', 'text': 'error text in current buffer',
}, },
{ {
'lnum': 4, 'lnum': 4,
'col': 2, 'col': 2,
'bufnr': 3, 'bufnr': 3,
'valid': 1, 'valid': 1,
'type': 'E', 'type': 'E',
'text': 'error text in hidden buffer', 'text': 'error text in hidden buffer',
}, },
{ {
'lnum': 8, 'lnum': 8,
'col': 4, 'col': 4,
'bufnr': -1, # sic: Our mocked bufnr function actually returns -1, 'bufnr': -1, # sic: Our mocked bufnr function actually returns -1,
# even though YCM is passing "create if needed". # even though YCM is passing "create if needed".
# FIXME? we shouldn't do that, and we should pass # FIXME? we shouldn't do that, and we should pass
# filename instead # filename instead
'valid': 1, 'valid': 1,
'type': 'E', 'type': 'E',
'text': 'error text in buffer not open in Vim' 'text': 'error text in buffer not open in Vim'
} }
] )
] ) ] )
] )
assert_that(
test_utils.VIM_MATCHES_FOR_WINDOW,
has_entries( {
1: contains(
VimMatch( 'YcmErrorSection', '\%1l\%1c\_.\{-}\%1l\%1c' )
)
} )
)
@YouCompleteMeInstance( { 'g:ycm_echo_current_diagnostic': 1, @YouCompleteMeInstance( { 'g:ycm_echo_current_diagnostic': 1,
'g:ycm_always_populate_location_list': 1 } ) 'g:ycm_always_populate_location_list': 1,
'g:ycm_enable_diagnostic_highlighting': 1 } )
@patch.object( ycm_buffer_module, @patch.object( ycm_buffer_module,
'DIAGNOSTIC_UI_ASYNC_FILETYPES', 'DIAGNOSTIC_UI_ASYNC_FILETYPES',
[ 'ycmtest' ] ) [ 'ycmtest' ] )
@ -835,87 +887,175 @@ def YouCompleteMe_AsyncDiagnosticUpdate_PerFile_test( ycm,
# Ordered to ensure that the calls to update are deterministic # Ordered to ensure that the calls to update are deterministic
diagnostics_per_file = [ diagnostics_per_file = [
( '/current', [ { ( '/current', [ {
'kind': 'ERROR', 'kind': 'ERROR',
'text': 'error text in current buffer', 'text': 'error text in current buffer',
'location': { 'location': {
'filepath': '/current', 'filepath': '/current',
'line_num': 1, 'line_num': 1,
'column_num': 1 'column_num': 1
}, }, ] ), },
( '/has_diags', [ { 'location_extent': {
'kind': 'ERROR', 'start': {
'text': 'error text in hidden buffer', 'filepath': '/current',
'location': { 'line_num': 1,
'filepath': '/has_diags', 'column_num': 1,
'line_num': 4, },
'column_num': 2 'end': {
}, }, ] ), 'filepath': '/current',
'line_num': 1,
'column_num': 1,
}
},
'ranges': [],
} ] ),
( '/separate_window', [ {
'kind': 'ERROR',
'text': 'error text in a buffer open in a separate window',
'location': {
'filepath': '/separate_window',
'line_num': 3,
'column_num': 3
},
'location_extent': {
'start': {
'filepath': '/separate_window',
'line_num': 3,
'column_num': 3,
},
'end': {
'filepath': '/separate_window',
'line_num': 3,
'column_num': 3,
}
},
'ranges': []
} ] ),
( '/hidden', [ {
'kind': 'ERROR',
'text': 'error text in hidden buffer',
'location': {
'filepath': '/hidden',
'line_num': 4,
'column_num': 2
},
'location_extent': {
'start': {
'filepath': '/hidden',
'line_num': 4,
'column_num': 2,
},
'end': {
'filepath': '/hidden',
'line_num': 4,
'column_num': 2,
}
},
'ranges': []
} ] ),
( '/not_open', [ { ( '/not_open', [ {
'kind': 'ERROR', 'kind': 'ERROR',
'text': 'error text in buffer not open in Vim', 'text': 'error text in buffer not open in Vim',
'location': { 'location': {
'filepath': '/not_open', 'filepath': '/not_open',
'line_num': 8, 'line_num': 8,
'column_num': 4 'column_num': 4
}, }, ] ) },
'location_extent': {
'start': {
'filepath': '/not_open',
'line_num': 8,
'column_num': 4,
},
'end': {
'filepath': '/not_open',
'line_num': 8,
'column_num': 4,
}
},
'ranges': []
} ] )
] ]
current_buffer = VimBuffer( '/current', current_buffer = VimBuffer( '/current',
filetype = 'ycmtest', filetype = 'ycmtest',
number = 1, contents = [ 'current' ] * 10,
window = 10 ) number = 1 )
no_diags_buffer = VimBuffer( '/no_diags',
filetype = 'ycmtest',
contents = [ 'no_diags' ] * 10,
number = 2 )
separate_window = VimBuffer( '/separate_window',
filetype = 'ycmtest',
contents = [ 'separate_window' ] * 10,
number = 3 )
hidden_buffer = VimBuffer( '/hidden',
filetype = 'ycmtest',
contents = [ 'hidden' ] * 10,
number = 4 )
buffers = [ buffers = [
current_buffer, current_buffer,
VimBuffer( '/no_diags', no_diags_buffer,
filetype = 'ycmtest', separate_window,
number = 2, hidden_buffer
window = 9 ), ]
VimBuffer( '/has_diags', windows = [
filetype = 'ycmtest', current_buffer,
number = 3, no_diags_buffer,
window = 8 ), separate_window
] ]
# Register each buffer internally with YCM # Register each buffer internally with YCM
for current in buffers: for current in buffers:
with MockVimBuffers( buffers, current, ( 1, 1 ) ): with MockVimBuffers( buffers, [ current ] ):
ycm.OnFileReadyToParse() ycm.OnFileReadyToParse()
with patch( 'ycm.vimsupport.SetLocationListForWindow', with patch( 'ycm.vimsupport.SetLocationListForWindow',
new_callable = ExtendedMock ) as set_location_list_for_window: new_callable = ExtendedMock ) as set_location_list_for_window:
with MockVimBuffers( buffers, current_buffer, ( 1, 1 ) ): with MockVimBuffers( buffers, windows ):
for filename, diagnostics in diagnostics_per_file: for filename, diagnostics in diagnostics_per_file:
ycm.UpdateWithNewDiagnosticsForFile( filename, diagnostics ) ycm.UpdateWithNewDiagnosticsForFile( filename, diagnostics )
# We update the diagnostic on the current cursor position # We update the diagnostic on the current cursor position
post_vim_message.assert_has_exact_calls( [ post_vim_message.assert_has_exact_calls( [
call( "error text in current buffer", truncate = True, warning = False ), call( "error text in current buffer", truncate = True, warning = False ),
] ) ] )
# Ensure we included all the diags though # Ensure we included all the diags though
set_location_list_for_window.assert_has_exact_calls( [ set_location_list_for_window.assert_has_exact_calls( [
call( 0, [ call( 1, [
{ {
'lnum': 1, 'lnum': 1,
'col': 1, 'col': 1,
'bufnr': 1, 'bufnr': 1,
'valid': 1, 'valid': 1,
'type': 'E', 'type': 'E',
'text': 'error text in current buffer', 'text': 'error text in current buffer',
}, },
] ), ] ),
call( 8, [ call( 3, [
{ {
'lnum': 4, 'lnum': 3,
'col': 2, 'col': 3,
'bufnr': 3, 'bufnr': 3,
'valid': 1, 'valid': 1,
'type': 'E', 'type': 'E',
'text': 'error text in hidden buffer', 'text': 'error text in a buffer open in a separate window',
}, },
] )
] ) ] )
] )
assert_that(
test_utils.VIM_MATCHES_FOR_WINDOW,
has_entries( {
1: contains(
VimMatch( 'YcmErrorSection', '\%1l\%1c\_.\{-}\%1l\%1c' )
),
3: contains(
VimMatch( 'YcmErrorSection', '\%3l\%3c\_.\{-}\%3l\%3c' )
)
} )
)
@YouCompleteMeInstance() @YouCompleteMeInstance()
@ -945,12 +1085,10 @@ def YouCompleteMe_OnPeriodicTick_DontRetry_test( ycm,
current_buffer = VimBuffer( '/current', current_buffer = VimBuffer( '/current',
filetype = 'ycmtest', filetype = 'ycmtest',
number = 1, number = 1 )
window = 10 )
buffers = [ current_buffer ]
# Create the request and make the first poll; we expect no response # Create the request and make the first poll; we expect no response
with MockVimBuffers( buffers, current_buffer, ( 1, 1 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 1 ) ):
assert_that( ycm.OnPeriodicTick(), equal_to( True ) ) assert_that( ycm.OnPeriodicTick(), equal_to( True ) )
post_data_to_handler_async.assert_called() post_data_to_handler_async.assert_called()
@ -996,12 +1134,10 @@ def YouCompleteMe_OnPeriodicTick_Exception_test( ycm,
current_buffer = VimBuffer( '/current', current_buffer = VimBuffer( '/current',
filetype = 'ycmtest', filetype = 'ycmtest',
number = 1, number = 1 )
window = 10 )
buffers = [ current_buffer ]
# Create the request and make the first poll; we expect no response # Create the request and make the first poll; we expect no response
with MockVimBuffers( buffers, current_buffer, ( 1, 1 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 1 ) ):
assert_that( ycm.OnPeriodicTick(), equal_to( True ) ) assert_that( ycm.OnPeriodicTick(), equal_to( True ) )
post_data_to_handler_async.assert_called() post_data_to_handler_async.assert_called()
@ -1036,12 +1172,10 @@ def YouCompleteMe_OnPeriodicTick_ValidResponse_test( ycm,
current_buffer = VimBuffer( '/current', current_buffer = VimBuffer( '/current',
filetype = 'ycmtest', filetype = 'ycmtest',
number = 1, number = 1 )
window = 10 )
buffers = [ current_buffer ]
# Create the request and make the first poll; we expect no response # Create the request and make the first poll; we expect no response
with MockVimBuffers( buffers, current_buffer, ( 1, 1 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 1 ) ):
assert_that( ycm.OnPeriodicTick(), equal_to( True ) ) assert_that( ycm.OnPeriodicTick(), equal_to( True ) )
post_data_to_handler_async.assert_called() post_data_to_handler_async.assert_called()
@ -1065,7 +1199,7 @@ def YouCompleteMe_OnPeriodicTick_ValidResponse_test( ycm,
def YouCompleteMe_OnCompleteDone_CompletionRequest_test( ycm, def YouCompleteMe_OnCompleteDone_CompletionRequest_test( ycm,
on_complete_done ): on_complete_done ):
current_buffer = VimBuffer( 'current_buffer' ) current_buffer = VimBuffer( 'current_buffer' )
with MockVimBuffers( [ current_buffer ], current_buffer, ( 1, 1 ) ): with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 1 ) ):
ycm.SendCompletionRequest() ycm.SendCompletionRequest()
ycm.OnCompleteDone() ycm.OnCompleteDone()
on_complete_done.assert_called() on_complete_done.assert_called()
@ -1082,5 +1216,5 @@ def YouCompleteMe_OnCompleteDone_NoCompletionRequest_test( ycm,
@YouCompleteMeInstance() @YouCompleteMeInstance()
def YouCompleteMe_ShouldResendFileParseRequest_NoParseRequest_test( ycm ): def YouCompleteMe_ShouldResendFileParseRequest_NoParseRequest_test( ycm ):
current_buffer = VimBuffer( 'current_buffer' ) current_buffer = VimBuffer( 'current_buffer' )
with MockVimBuffers( [ current_buffer ], current_buffer ): with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
assert_that( ycm.ShouldResendFileParseRequest(), equal_to( False ) ) assert_that( ycm.ShouldResendFileParseRequest(), equal_to( False ) )

View File

@ -23,6 +23,7 @@ from __future__ import absolute_import
from builtins import * # noqa from builtins import * # noqa
from future.utils import iterkeys from future.utils import iterkeys
import contextlib
import vim import vim
import os import os
import json import json
@ -289,36 +290,18 @@ def SetLocationList( diagnostics ):
SetLocationListForWindow( 0, diagnostics ) SetLocationListForWindow( 0, diagnostics )
def GetWindowNumberForBufferDiagnostics( buffer_number ): def GetWindowsForBufferNumber( buffer_number ):
"""Return an appropriate window number to use for displaying diagnostics """Return the list of windows containing the buffer with number
associated with the buffer number supplied. Always returns a valid window |buffer_number| for the current tab page."""
number or 0 meaning the current window.""" return [ window for window in vim.windows
if window.buffer.number == buffer_number ]
# Location lists are associated with _windows_ not _buffers_. This makes a lot
# of sense, but YCM associates diagnostics with _buffers_, because it is the
# buffer that actually gets parsed.
#
# The heuristic we use is to determine any open window for a specified buffer,
# and set that. If there is no such window on the current tab page, we use the
# current window (by passing 0 as the window number)
if buffer_number == vim.current.buffer.number:
return 0
window_number = GetIntValue( "bufwinnr({0})".format( buffer_number ) )
if window_number < 0:
return 0
return window_number
def SetLocationListForBuffer( buffer_number, diagnostics ): def SetLocationListsForBuffer( buffer_number, diagnostics ):
"""Populate the location list of an apppropriate window for the supplied """Populate location lists for all windows containing the buffer with number
buffer number. See SetLocationListForWindow for format of diagnostics.""" |buffer_number|. See SetLocationListForWindow for format of diagnostics."""
return SetLocationListForWindow( for window in GetWindowsForBufferNumber( buffer_number ):
GetWindowNumberForBufferDiagnostics( buffer_number ), SetLocationListForWindow( window.number, diagnostics )
diagnostics )
def SetLocationListForWindow( window_number, diagnostics ): def SetLocationListForWindow( window_number, diagnostics ):
@ -1181,3 +1164,39 @@ def BuildRange( start_line, end_line ):
} }
} }
} }
@contextlib.contextmanager
def AutocommandEventsIgnored( events = [ 'all' ] ):
"""Context manager to perform operations without triggering autocommand
events. |events| is a list of events to ignore. By default, all events are
ignored."""
old_eventignore = vim.options[ 'eventignore' ]
ignored_events = {
event for event in ToUnicode( old_eventignore ).split( ',' ) if event }
ignored_events.update( events )
vim.options[ 'eventignore' ] = ','.join( ignored_events )
try:
yield
finally:
vim.options[ 'eventignore' ] = old_eventignore
@contextlib.contextmanager
def CurrentWindow():
"""Context manager to perform operations on other windows than the current one
without triggering autocommands related to window movement. Use the
SwitchWindow function to move to other windows while under the context."""
current_window = vim.current.window
with AutocommandEventsIgnored( [ 'WinEnter', 'Winleave' ] ):
try:
yield
finally:
vim.current.window = current_window
def SwitchWindow( window ):
"""Move to the window object |window|. This function should be called under
the CurrentWindow context if you are going to switch back to the original
window."""
vim.current.window = window

View File

@ -385,7 +385,7 @@ class YouCompleteMe( object ):
bufnr = vimsupport.GetBufferNumberForFilename( filepath ) bufnr = vimsupport.GetBufferNumberForFilename( filepath )
if bufnr in self._buffers and vimsupport.BufferIsVisible( bufnr ): if bufnr in self._buffers and vimsupport.BufferIsVisible( bufnr ):
# Note: We only update location lists, etc. for visible buffers, because # Note: We only update location lists, etc. for visible buffers, because
# otherwise we defualt to using the curren location list and the results # otherwise we default to using the current location list and the results
# are that non-visible buffer errors clobber visible ones. # are that non-visible buffer errors clobber visible ones.
self._buffers[ bufnr ].UpdateWithNewDiagnostics( diagnostics ) self._buffers[ bufnr ].UpdateWithNewDiagnostics( diagnostics )
else: else: