Auto merge of #2797 - micbou:echo-diagnostic-async, r=Valloric

[READY] Echo diagnostic asynchronously

If there is a diagnostic on the current line while updating diagnostics, echo it on the command line. Here's a demo:

![echo-diagnostic-async](https://user-images.githubusercontent.com/10026824/31182114-4e784200-a923-11e7-831b-e613d126fd8b.gif)

Without this change, users have to move the cursor up and down to see the message on the command line.

<!-- 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/2797)
<!-- Reviewable:end -->
This commit is contained in:
zzbot 2017-10-04 11:30:50 -07:00 committed by GitHub
commit b5c8e57962
3 changed files with 43 additions and 13 deletions

View File

@ -38,17 +38,15 @@ class DiagnosticInterface( object ):
self._line_to_diags = defaultdict( list )
self._placed_signs = []
self._next_sign_id = 1
self._previous_line_number = -1
self._previous_diag_line_number = -1
self._diag_message_needs_clearing = False
def OnCursorMoved( self ):
if self._user_options[ 'echo_current_diagnostic' ]:
line, _ = vimsupport.CurrentLineAndColumn()
line += 1 # Convert to 1-based
if line != self._previous_line_number:
self._previous_line_number = line
if self._user_options[ 'echo_current_diagnostic' ]:
if line != self._previous_diag_line_number:
self._EchoDiagnosticForLine( line )
@ -72,6 +70,9 @@ class DiagnosticInterface( object ):
self._ApplyDiagnosticFilter( diags ) ]
self._ConvertDiagListToDict()
if self._user_options[ 'echo_current_diagnostic' ]:
self._EchoDiagnostic()
if self._user_options[ 'enable_diagnostic_signs' ]:
self._UpdateSigns()
@ -88,7 +89,15 @@ class DiagnosticInterface( object ):
return filter( diag_filter.IsAllowed, diags )
def _EchoDiagnostic( self ):
line, _ = vimsupport.CurrentLineAndColumn()
line += 1 # Convert to 1-based
self._EchoDiagnosticForLine( line )
def _EchoDiagnosticForLine( self, line_num ):
self._previous_diag_line_number = line_num
diags = self._line_to_diags[ line_num ]
if not diags:
if self._diag_message_needs_clearing:
@ -163,6 +172,9 @@ class DiagnosticInterface( object ):
new_signs = []
obsolete_signs = list( self._placed_signs )
for line, diags in iteritems( self._line_to_diags ):
if not diags:
continue
# We always go for the first diagnostic on line,
# because it is sorted giving priority to the Errors.
diag = diags[ 0 ]

View File

@ -44,6 +44,7 @@ DEFAULT_CLIENT_OPTIONS = {
'keep_logfiles': 0,
'extra_conf_vim_data': [],
'show_diagnostics_ui': 1,
'echo_current_diagnostic': 1,
'enable_diagnostic_signs': 1,
'enable_diagnostic_highlighting': 0,
'always_populate_location_list': 0,

View File

@ -551,6 +551,11 @@ def YouCompleteMe_UpdateDiagnosticInterface_PrioritizeErrorsOverWarnings_test(
ycm.OnFileReadyToParse()
ycm.HandleFileParseRequest( block = True )
# The error on the current line is echoed, not the warning.
post_vim_message.assert_called_once_with(
"expected ';' after expression (FixIt)",
truncate = True, warning = False )
# Error match is added after warning matches.
assert_that(
test_utils.VIM_MATCHES,
@ -566,13 +571,25 @@ def YouCompleteMe_UpdateDiagnosticInterface_PrioritizeErrorsOverWarnings_test(
call( 'sign place 1 name=YcmError line=3 buffer=5' ),
] )
# When moving the cursor on the diagnostics, the error is displayed to the
# user, not the warning.
# The error is not echoed again when moving the cursor along the line.
with MockVimBuffers( [ current_buffer ], current_buffer, ( 3, 2 ) ):
post_vim_message.reset_mock()
ycm.OnCursorMoved()
post_vim_message.assert_has_exact_calls( [
call( "expected ';' after expression (FixIt)",
post_vim_message.assert_not_called()
# The error is cleared when moving the cursor to another line.
with MockVimBuffers( [ current_buffer ], current_buffer, ( 2, 2 ) ):
post_vim_message.reset_mock()
ycm.OnCursorMoved()
post_vim_message.assert_called_once_with( "", warning = False )
# The error is echoed when moving the cursor back.
with MockVimBuffers( [ current_buffer ], current_buffer, ( 3, 2 ) ):
post_vim_message.reset_mock()
ycm.OnCursorMoved()
post_vim_message.assert_called_once_with(
"expected ';' after expression (FixIt)",
truncate = True, warning = False )
] )
vim_command.reset_mock()
with patch( 'ycm.client.event_notification.EventNotification.Response',