Auto merge of #3247 - micbou:diagnostic-matches-current-window, r=puremourning

[READY] Update diagnostic matches only in current window

Unfortunately, switching windows when updating the diagnostic matches causes too many side-effects like issues #3228 and #3242. Revert PRs https://github.com/Valloric/YouCompleteMe/pull/3024 and https://github.com/Valloric/YouCompleteMe/pull/3229 and only update matches in the current window.

Fixes #3242.

<!-- 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/3247)
<!-- Reviewable:end -->
This commit is contained in:
zzbot 2018-11-27 12:11:50 -08:00 committed by GitHub
commit 75bf1738dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 21 additions and 65 deletions

View File

@ -129,28 +129,29 @@ class DiagnosticInterface( object ):
if not self._user_options[ 'enable_diagnostic_highlighting' ]: if not self._user_options[ 'enable_diagnostic_highlighting' ]:
return return
with vimsupport.CurrentWindow(): # Vim doesn't provide a way to update the matches for a different window
for window in vimsupport.GetWindowsForBufferNumber( self._bufnr ): # than the current one (which is a view of the current buffer).
vimsupport.SwitchWindow( window ) if vimsupport.GetCurrentBufferNumber() != self._bufnr:
return
matches_to_remove = vimsupport.GetDiagnosticMatchesInCurrentWindow() matches_to_remove = vimsupport.GetDiagnosticMatchesInCurrentWindow()
for diags in itervalues( self._line_to_diags ): for diags in itervalues( self._line_to_diags ):
# Insert squiggles in reverse order so that errors overlap warnings. # Insert squiggles in reverse order so that errors overlap warnings.
for diag in reversed( diags ): for diag in reversed( diags ):
group = ( 'YcmErrorSection' if _DiagnosticIsError( diag ) else group = ( 'YcmErrorSection' if _DiagnosticIsError( diag ) else
'YcmWarningSection' ) 'YcmWarningSection' )
for pattern in _ConvertDiagnosticToMatchPatterns( diag ): for pattern in _ConvertDiagnosticToMatchPatterns( diag ):
# The id doesn't matter for matches that we may add. # The id doesn't matter for matches that we may add.
match = vimsupport.DiagnosticMatch( 0, group, pattern ) match = vimsupport.DiagnosticMatch( 0, group, pattern )
try: try:
matches_to_remove.remove( match ) matches_to_remove.remove( match )
except ValueError: except ValueError:
vimsupport.AddDiagnosticMatch( match ) vimsupport.AddDiagnosticMatch( match )
for match in matches_to_remove: for match in matches_to_remove:
vimsupport.RemoveDiagnosticMatch( match ) vimsupport.RemoveDiagnosticMatch( match )
def _UpdateSigns( self ): def _UpdateSigns( self ):

View File

@ -1047,14 +1047,13 @@ def YouCompleteMe_AsyncDiagnosticUpdate_PerFile_test( ycm,
] ) ] )
] ) ] )
# FIXME: diagnostic matches in windows other than the current one are not
# updated.
assert_that( assert_that(
test_utils.VIM_MATCHES_FOR_WINDOW, test_utils.VIM_MATCHES_FOR_WINDOW,
has_entries( { has_entries( {
1: contains( 1: contains(
VimMatch( 'YcmErrorSection', '\\%1l\\%1c\\_.\\{-}\\%1l\\%1c' ) VimMatch( 'YcmErrorSection', '\\%1l\\%1c\\_.\\{-}\\%1l\\%1c' )
),
3: contains(
VimMatch( 'YcmErrorSection', '\\%3l\\%3c\\_.\\{-}\\%3l\\%3c' )
) )
} ) } )
) )

View File

@ -23,7 +23,6 @@ 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
@ -1218,49 +1217,6 @@ 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
def GetPreviousWindowNumber():
return GetIntValue( 'winnr("#")' ) - 1
@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."""
previous_window = vim.windows[ GetPreviousWindowNumber() ]
current_window = vim.current.window
with AutocommandEventsIgnored( [ 'WinEnter', 'Winleave' ] ):
try:
yield
finally:
# Ensure <c-w>p still go to the previous window.
vim.current.window = previous_window
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
# Expects version_string in 'MAJOR.MINOR.PATCH' format, e.g. '8.1.278' # Expects version_string in 'MAJOR.MINOR.PATCH' format, e.g. '8.1.278'
def VimVersionAtLeast( version_string ): def VimVersionAtLeast( version_string ):
major, minor, patch = ( int( x ) for x in version_string.split( '.' ) ) major, minor, patch = ( int( x ) for x in version_string.split( '.' ) )