Skip to content

Commit 62e46a3

Browse files
committed
Take care of start column in multiline diags for detailed diag popups
Previously, we have always used the diagnostics start column of the *starting* line of a multiline diagnostic. This is wrong, as the starting column for a line in the middle of a multiline diagnostic is always 1. Previous patch just happens to work if the start column of the first line of the diagnostic is also 1.
1 parent 2b33bf3 commit 62e46a3

File tree

2 files changed

+86
-2
lines changed

2 files changed

+86
-2
lines changed

python/ycm/vimsupport.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -288,18 +288,22 @@ def GetTextPropertyForDiag( buffer_number, line_number, diag ):
288288
end_line = end[ 'line_num' ]
289289
if start_line == end_line:
290290
length = end[ 'column_num' ] - start[ 'column_num' ]
291+
column = start[ 'column_num' ]
291292
elif start_line == line_number:
292293
# -1 switches to 0-based indexing.
293294
current_line_len = len( vim.buffers[ buffer_number ][ line_number - 1 ] )
294295
# +2 includes the start columnand accounts for properties at the end of line
295296
# covering \n as well.
296297
length = current_line_len - start[ 'column_num' ] + 2
298+
column = start[ 'column_num' ]
297299
elif end_line == line_number:
298300
length = end[ 'column_num' ] - 1
301+
column = 1
299302
else:
300303
# -1 switches to 0-based indexing.
301304
# +1 accounts for properties at the end of line covering \n as well.
302305
length = len( vim.buffers[ buffer_number ][ line_number - 1 ] ) + 1
306+
column = 1
303307
if diag[ 'kind' ] == 'ERROR':
304308
property_name = 'YcmErrorProperty'
305309
else:
@@ -309,7 +313,7 @@ def GetTextPropertyForDiag( buffer_number, line_number, diag ):
309313
f'{{ "bufnr": { buffer_number }, '
310314
f'"types": [ "{ property_name }" ] }} )' )
311315
return next( filter(
312-
lambda p: start[ 'column_num' ] == int( p[ 'col' ] ) and
316+
lambda p: column == int( p[ 'col' ] ) and
313317
length == int( p[ 'length' ] ),
314318
vim_props ) )
315319
else:

test/diagnostics.test.vim

+81-1
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,87 @@ function! Test_ShowDetailedDiagnostic_Popup_WithCharacters()
348348
%bwipe!
349349
endfunction
350350

351-
function! Test_ShowDetailedDiagnostic_Popup_MultilineDiag()
351+
function! Test_ShowDetailedDiagnostic_Popup_MultilineDiagNotFromStartOfLine()
352+
let f = tempname() . '.cc'
353+
execut 'edit' f
354+
call setline( 1, [
355+
\ 'int main () {',
356+
\ ' int a \',
357+
\ '=\',
358+
\ '=',
359+
\ '3;',
360+
\ '}',
361+
\ ] )
362+
call youcompleteme#test#setup#WaitForInitialParse( {} )
363+
364+
call WaitForAssert( {->
365+
\ assert_true(
366+
\ py3eval(
367+
\ 'len( ycm_state.CurrentBuffer()._diag_interface._diagnostics )'
368+
\ ) ) } )
369+
370+
" Start of multiline diagnostic.
371+
call cursor( [ 2, 9 ] )
372+
YcmShowDetailedDiagnostic popup
373+
374+
"let popup_location = screenpos( bufwinid( '%' ), 3, 13 )
375+
let id = popup_locate( 3, 30 )
376+
call assert_notequal( 0, id, "Couldn't find popup!" )
377+
378+
call youcompleteme#test#popup#CheckPopupPosition( id, {
379+
\ 'visible': 1,
380+
\ 'col': 16,
381+
\ 'line': 3,
382+
\ } )
383+
call assert_match(
384+
\ "^Variable 'rd' declared const here.*",
385+
\ getbufline( winbufnr(id), 1, '$' )[ 0 ] )
386+
387+
" Middle of multiline diagnostic.
388+
call cursor( [ 3, 1 ] )
389+
YcmShowDetailedDiagnostic popup
390+
391+
let popup_location = screenpos( bufwinid( '%' ), 3, 13 )
392+
let id = popup_locate( popup_location[ 'row' ], popup_location[ 'col' ] )
393+
call assert_notequal( 0, id, "Couldn't find popup!" )
394+
395+
" End of multiline diagnostic.
396+
call youcompleteme#test#popup#CheckPopupPosition( id, {
397+
\ 'visible': 1,
398+
\ 'col': 16,
399+
\ 'line': 3,
400+
\ } )
401+
call assert_match(
402+
\ "^Variable 'rd' declared const here.*",
403+
\ getbufline( winbufnr(id), 1, '$' )[ 0 ] )
404+
405+
call cursor( [ 4, 1 ] )
406+
YcmShowDetailedDiagnostic popup
407+
408+
let popup_location = screenpos( bufwinid( '%' ), 3, 13 )
409+
let id = popup_locate( popup_location[ 'row' ], popup_location[ 'col' ] )
410+
call assert_notequal( 0, id, "Couldn't find popup!" )
411+
412+
call youcompleteme#test#popup#CheckPopupPosition( id, {
413+
\ 'visible': 1,
414+
\ 'col': 16,
415+
\ 'line': 3,
416+
\ } )
417+
call assert_match(
418+
\ "^Variable 'rd' declared const here.*",
419+
\ getbufline( winbufnr(id), 1, '$' )[ 0 ] )
420+
421+
" From vim's test_popupwin.vim
422+
" trigger the check for last_cursormoved by going into insert mode
423+
call test_override( 'char_avail', 1 )
424+
call feedkeys( "ji\<Esc>", 'xt' )
425+
call assert_equal( {}, popup_getpos( id ) )
426+
call test_override( 'ALL', 0 )
427+
428+
%bwipe!
429+
endfunction
430+
431+
function! Test_ShowDetailedDiagnostic_Popup_MultilineDiagFromStartOfLine()
352432
let f = tempname() . '.cc'
353433
execut 'edit' f
354434
call setline( 1, [

0 commit comments

Comments
 (0)