Auto merge of #2292 - micbou:diagnostic-highlight-end-of-line, r=Valloric

[READY] Fix diagnostic highlighting at line ending

When highlighting a range of characters for a diagnostic, we make sure that the start and end positions do not go paste the line contents or the range will not be highlighted at all (don't ask, this is a Vim feature). However, we don't account for the end position not being included in the diagnostic range. So, when this position ends at line ending or after it, we move it just before the `EOL` character. Since the end position is not part of the range, this character will not be highlighted, which is not what we want. We fix this behavior by decrementing the end column before clamping it and incrementing it after.

Fixes https://github.com/Valloric/YouCompleteMe/issues/846.

<!-- 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/2292)
<!-- Reviewable:end -->
This commit is contained in:
Homu 2016-08-20 18:43:22 +09:00
commit 358363972a
2 changed files with 43 additions and 14 deletions

View File

@ -1220,6 +1220,32 @@ def _BuildChunk( start_line,
} }
@patch( 'vim.eval', new_callable = ExtendedMock )
def AddDiagnosticSyntaxMatch_ErrorInMiddleOfLine_test( vim_eval ):
current_buffer = MockBuffer( [
'Highlight this error please'
], 'some_file', 1 )
with patch( 'vim.current.buffer', current_buffer ):
vimsupport.AddDiagnosticSyntaxMatch( 1, 16, 1, 21 )
vim_eval.assert_called_once_with(
r"matchadd('YcmErrorSection', '\%1l\%16c\_.\{-}\%1l\%21c')" )
@patch( 'vim.eval', new_callable = ExtendedMock )
def AddDiagnosticSyntaxMatch_WarningAtEndOfLine_test( vim_eval ):
current_buffer = MockBuffer( [
'Highlight this warning'
], 'some_file', 1 )
with patch( 'vim.current.buffer', current_buffer ):
vimsupport.AddDiagnosticSyntaxMatch( 1, 16, 1, 23, is_error = False )
vim_eval.assert_called_once_with(
r"matchadd('YcmWarningSection', '\%1l\%16c\_.\{-}\%1l\%23c')" )
@patch( 'vim.command', new_callable=ExtendedMock ) @patch( 'vim.command', new_callable=ExtendedMock )
@patch( 'vim.current', new_callable=ExtendedMock) @patch( 'vim.current', new_callable=ExtendedMock)
def WriteToPreviewWindow_test( vim_current, vim_command ): def WriteToPreviewWindow_test( vim_current, vim_command ):

View File

@ -208,26 +208,29 @@ def ClearYcmSyntaxMatches():
vim.eval( 'matchdelete({0})'.format( match[ 'id' ] ) ) vim.eval( 'matchdelete({0})'.format( match[ 'id' ] ) )
# Returns the ID of the newly added match
# Both line and column numbers are 1-based
def AddDiagnosticSyntaxMatch( line_num, def AddDiagnosticSyntaxMatch( line_num,
column_num, column_num,
line_end_num = None, line_end_num = None,
column_end_num = None, column_end_num = None,
is_error = True ): is_error = True ):
"""Highlight a range in the current window starting from
(|line_num|, |column_num|) included to (|line_end_num|, |column_end_num|)
excluded. If |line_end_num| or |column_end_num| are not given, highlight the
character at (|line_num|, |column_num|). Both line and column numbers are
1-based. Return the ID of the newly added match."""
group = 'YcmErrorSection' if is_error else 'YcmWarningSection' group = 'YcmErrorSection' if is_error else 'YcmWarningSection'
if not line_end_num:
line_end_num = line_num
line_num, column_num = LineAndColumnNumbersClamped( line_num, column_num ) line_num, column_num = LineAndColumnNumbersClamped( line_num, column_num )
line_end_num, column_end_num = LineAndColumnNumbersClamped( line_end_num,
column_end_num )
if not column_end_num: if not line_end_num or not column_end_num:
return GetIntValue( return GetIntValue(
"matchadd('{0}', '\%{1}l\%{2}c')".format( group, line_num, column_num ) ) "matchadd('{0}', '\%{1}l\%{2}c')".format( group, line_num, column_num ) )
else:
# -1 and then +1 to account for column end not included in the range.
line_end_num, column_end_num = LineAndColumnNumbersClamped(
line_end_num, column_end_num - 1 )
column_end_num += 1
return GetIntValue( return GetIntValue(
"matchadd('{0}', '\%{1}l\%{2}c\_.\\{{-}}\%{3}l\%{4}c')".format( "matchadd('{0}', '\%{1}l\%{2}c\_.\\{{-}}\%{3}l\%{4}c')".format(
group, line_num, column_num, line_end_num, column_end_num ) ) group, line_num, column_num, line_end_num, column_end_num ) )