diff --git a/python/ycm/vimsupport.py b/python/ycm/vimsupport.py index 1479814598..9c7875c5ed 100644 --- a/python/ycm/vimsupport.py +++ b/python/ycm/vimsupport.py @@ -284,7 +284,17 @@ def GetTextPropertyForDiag( buffer_number, line_number, diag ): range = diag[ 'location_extent' ] start = range[ 'start' ] end = range[ 'end' ] - length = end[ 'column_num' ] - start[ 'column_num' ] + start_line = start[ 'line_num' ] + end_line = end[ 'line_num' ] + if start_line == end_line: + length = end[ 'column_num' ] - start[ 'column_num' ] + elif start_line == line_number: + current_line_len = len( vim.buffers[ buffer_number ][ line_number - 1 ] ) + length = current_line_len - start[ 'column_num' ] + 2 + elif end_line == line_number: + length = end[ 'column_num' ] - 1 + else: + length = len( vim.buffers[ buffer_number ][ line_number - 1 ] ) if diag[ 'kind' ] == 'ERROR': property_name = 'YcmErrorProperty' else: diff --git a/test/diagnostics.test.vim b/test/diagnostics.test.vim index b8a60f9ed5..9a97096c5c 100644 --- a/test/diagnostics.test.vim +++ b/test/diagnostics.test.vim @@ -341,3 +341,83 @@ function! Test_ShowDetailedDiagnostic_Popup_WithCharacters() %bwipe! endfunction + +function! Test_ShowDetailedDiagnostic_Popup_MultilineDiag() + let f = tempname() . '.cc' + execut 'edit' f + call setline( 1, [ + \ 'int main () {', + \ 'const int &&', + \ ' /* */', + \ ' rd = 1;', + \ 'rd = 4;', + \ '}', + \ ] ) + call youcompleteme#test#setup#WaitForInitialParse( {} ) + + call WaitForAssert( {-> + \ assert_true( + \ py3eval( + \ 'len( ycm_state.CurrentBuffer()._diag_interface._diagnostics )' + \ ) ) } ) + + " Start of multiline diagnostic. + call cursor( [ 2, 1 ] ) + YcmShowDetailedDiagnostic popup + + let expected_popup_location = screenpos( bufwinid( '%' ), 3, 13 ) + let id = popup_locate( expected_popup_location[ 'row' ], expected_popup_location[ 'col' ] ) + call assert_notequal( 0, id, "Couldn't find popup!" ) + + call youcompleteme#test#popup#CheckPopupPosition( id, { + \ 'visible': 1, + \ 'col': 13, + \ 'line': 3, + \ } ) + call assert_match( + \ "^Variable 'rd' declared const here.*", + \ getbufline( winbufnr(id), 1, '$' )[ 0 ] ) + + " Middle of multiline diagnostic. + call cursor( [ 3, 9 ] ) + YcmShowDetailedDiagnostic popup + + let expected_popup_location = screenpos( bufwinid( '%' ), 4, 9 ) + let id = popup_locate( expected_popup_location[ 'row' ], expected_popup_location[ 'col' ] ) + call assert_notequal( 0, id, "Couldn't find popup!" ) + + " End of multiline diagnostic. + call youcompleteme#test#popup#CheckPopupPosition( id, { + \ 'visible': 1, + \ 'col': 7, + \ 'line': 4, + \ } ) + call assert_match( + \ "^Variable 'rd' declared const here.*", + \ getbufline( winbufnr(id), 1, '$' )[ 0 ] ) + + call cursor( [ 4, 5 ] ) + YcmShowDetailedDiagnostic popup + + let expected_popup_location = screenpos( bufwinid( '%' ), 5, 5 ) + let id = popup_locate( expected_popup_location[ 'row' ], expected_popup_location[ 'col' ] ) + call assert_notequal( 0, id, "Couldn't find popup!" ) + + call youcompleteme#test#popup#CheckPopupPosition( id, { + \ 'visible': 1, + \ 'col': 7, + \ 'line': 4, + \ } ) + call assert_match( + \ "^Variable 'rd' declared const here.*", + \ getbufline( winbufnr(id), 1, '$' )[ 0 ] ) + + " From vim's test_popupwin.vim + " trigger the check for last_cursormoved by going into insert mode + call test_override( 'char_avail', 1 ) + call feedkeys( "ji\", 'xt' ) + call assert_equal( {}, popup_getpos( id ) ) + call test_override( 'ALL', 0 ) + + %bwipe! +endfunction