From 50ce07238be84b577edd9cc5fca694dfbf810883 Mon Sep 17 00:00:00 2001 From: Boris Staletic Date: Tue, 2 Jan 2024 13:06:25 +0100 Subject: [PATCH] Handle scrolling when hover popup is open There are two kinds of scrolling that need to be handled: 1. Scrolling the buffer in a window shifts the buffer, but popups stay in place. Instead, we close the popup whenever we receive a WinScrolled event. 2. Scrolling the popup contents themselves resets the `updatetime` timer and can trigger a second CursorHold event, which leads to YCM resetting the hover popup. Instead, only re-display the hover popup if it is not already visible. --- autoload/youcompleteme.vim | 9 ++++++--- test/hover.test.vim | 27 +++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/autoload/youcompleteme.vim b/autoload/youcompleteme.vim index b43df82a39..a0e33510a3 100644 --- a/autoload/youcompleteme.vim +++ b/autoload/youcompleteme.vim @@ -717,6 +717,7 @@ function! s:EnableAutoHover() augroup YcmBufHover autocmd! * autocmd CursorHold call s:Hover() + autocmd WinScrolled call popup_close( s:cursorhold_popup ) augroup END endif endfunction @@ -1621,9 +1622,11 @@ if exists( '*popup_atcursor' ) return endif - call youcompleteme#GetCommandResponseAsync( - \ function( 's:ShowHoverResult' ), - \ b:ycm_hover.command ) + if empty( popup_getpos( s:cursorhold_popup ) ) + call youcompleteme#GetCommandResponseAsync( + \ function( 's:ShowHoverResult' ), + \ b:ycm_hover.command ) + endif endfunction diff --git a/test/hover.test.vim b/test/hover.test.vim index f19df03db3..79a911dac6 100644 --- a/test/hover.test.vim +++ b/test/hover.test.vim @@ -482,3 +482,30 @@ function! Test_Long_Wrapped() call popup_clear() endfunction + +function! Test_Long_Scrolling() + let f = tempname() . '.cc' + execut 'edit' f + let current_win_id = bufwinid( '%' ) + let lines = repeat( [ ' * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' ], 50 ) + call insert( lines, '/**', 0 ) + call extend( lines, [ ' */', 'void f();' ] ) + call setline( 1, lines ) + call cursor( [ 54, 6 ] ) + doautocmd CursorHold + call WaitForAssert( { -> assert_equal( 1, len( popup_list() ) ) } ) + let popup_id = popup_list()[ 0 ] + call test_setmouse( 15, 15 ) + call feedkeys( "\", "xt" ) + let win_info = getwininfo( popup_id )[ 0 ] + call assert_notequal( 1, win_info[ 'topline' ] ) + doautocmd CursorHold + sleep 1 + let win_info = getwininfo( popup_id )[ 0 ] + call assert_notequal( 1, win_info[ 'topline' ] ) + let new_mouse_line = getwininfo( current_win_id )[ 0 ][ 'height' ] + call test_setmouse( new_mouse_line, 15 ) + call feedkeys( "\", "xt" ) + doautocmd WinScrolled + call assert_equal( 0, len( popup_list() ) ) +endfunction