Bläddra i källkod

Merge pull request #3679 from puremourning/hover-cursorhold

[READY] Maximise displayed text for hover popup
mergify[bot] 4 år sedan
förälder
incheckning
170bae7975
3 ändrade filer med 103 tillägg och 5 borttagningar
  1. 25 2
      autoload/youcompleteme.vim
  2. 54 3
      test/hover.test.vim
  3. 24 0
      test/testdata/python/doc.py

+ 25 - 2
autoload/youcompleteme.vim

@@ -1338,13 +1338,36 @@ if exists( '*popup_atcursor' )
     endif
 
     call popup_hide( s:cursorhold_popup )
+
+    " Try to position the popup at the cursor, but avoid wrapping. If the
+    " longest line is > screen width (&columns), then we just have to wrap, and
+    " place the popup at the leftmost column.
+    "
+    " Find the longest line (FIXME: probably doesn't work well for multi-byte)
+    let lines = split( response, "\n" )
+    let len = max( map( copy( lines ), "len( v:val )" ) )
+
+    let wrap = 0
+    let col = 'cursor'
+
+    " max width is screen columns minus x padding (2)
+    if len >= (&columns - 2)
+      " There's at least one line > our max - enable word wrap and draw the
+      " popup at the leftmost column
+      let col = 1
+      let wrap = 1
+    endif
+
     let s:cursorhold_popup = popup_atcursor(
-          \   split( response, "\n" ),
+          \   lines,
           \   {
+          \     'col': col,
+          \     'wrap': wrap,
           \     'padding': [ 0, 1, 0, 1 ],
-          \     'maxwidth': &columns,
           \     'moved': 'word',
+          \     'maxwidth': &columns,
           \     'close': 'click',
+          \     'fixed': 0,
           \   }
           \ )
     call setbufvar( winbufnr( s:cursorhold_popup ),

+ 54 - 3
test/hover.test.vim

@@ -14,13 +14,15 @@ function! s:CheckPopupVisibleScreenPos( loc, text, syntax )
   let popup = popup_locate( a:loc.row, a:loc.col )
   call assert_notequal( 0,
                       \ popup,
-                      \ 'Locate popup at '
+                      \ 'Locate popup at ('
                       \ . a:loc.row
                       \ . ','
                       \ . a:loc.col
                       \ . ')' )
-  call assert_equal( a:text,
-                   \ getbufline( winbufnr( popup ), 1, '$' ) )
+  if a:text isnot v:none
+    call assert_equal( a:text,
+                     \ getbufline( winbufnr( popup ), 1, '$' ) )
+  endif
   call assert_equal( a:syntax, getbufvar( winbufnr( popup ), '&syntax' ) )
 endfunction
 
@@ -373,3 +375,52 @@ endfunction
 function! TearDown_Test_Hover_Custom_Command()
   au! MyYCMCustom
 endfunction
+
+function! Test_Long_Single_Line()
+  call youcompleteme#test#setup#OpenFile( '/test/testdata/python/doc.py', {} )
+  call cursor( [ 37, 3 ] )
+  normal \D
+
+  " The popup should cover at least the whole of the line above, and not the
+  " current line
+  call s:CheckPopupVisible( 36, 1, v:none, '' )
+  call s:CheckPopupVisible( 36, &columns, v:none, '' )
+
+  call s:CheckPopupNotVisible( 37, 1 )
+  call s:CheckPopupNotVisible( 37, &columns )
+
+  " Also wrap is ON so it should cover at least 2 lines + 2 for the header/empty
+  " line
+  call s:CheckPopupVisible( 35, 1, v:none, '' )
+  call s:CheckPopupVisible( 35, &columns, v:none, '' )
+  call s:CheckPopupVisible( 33, 1, v:none, '' )
+  call s:CheckPopupVisible( 33, &columns, v:none, '' )
+
+  call popup_clear()
+  %bwipe!
+endfunction
+
+function! Test_Long_Wrapped()
+  call youcompleteme#test#setup#OpenFile( '/test/testdata/python/doc.py', {} )
+  call cursor( [ 38, 22 ] )
+  normal \D
+
+  " The popup should cover at least the whole of the line above, and not the
+  " current line. In this case, it's because the popup was shifted.
+  call s:CheckPopupVisible( 37, 1, v:none, '' )
+  call s:CheckPopupVisible( 37, &columns, v:none, '' )
+
+  call s:CheckPopupNotVisible( 38, 1 )
+  call s:CheckPopupNotVisible( 38, &columns )
+
+  " Also, wrap is off, so it should be _exactly_ 9 lines + 2 for the signature
+  " and the empty line
+  call s:CheckPopupVisible( 27, 1, v:none, '' )
+  call s:CheckPopupVisible( 27, &columns, v:none, '' )
+
+  call s:CheckPopupNotVisible( 26, 1 )
+  call s:CheckPopupNotVisible( 26, &columns )
+
+  call popup_clear()
+  %bwipe!
+endfunction

+ 24 - 0
test/testdata/python/doc.py

@@ -12,3 +12,27 @@ def Main():
   Test_OneLine()
   Test_MultiLine()
 
+
+def Really_Long_Method( which, has, some, param, that, take, the, whole, line ):
+  """Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum egestas libero urna, vel sagittis felis condimentum in. Nulla arcu eros, aliquet vel mollis vitae, semper eu ex. Donec posuere quam et ornare sagittis. Curabitur nunc ex, fringilla quis lorem sed, dignissim congue felis. Integer vestibulum ac elit vel blandit. Nam non dui urna. Integer eu semper massa. Nullam ac elit interdum, aliquet elit nec, porttitor orci. Duis tempus justo lorem, ac fringilla ante viverra egestas. Etiam eleifend enim ac libero dapibus, quis condimentum lectus tristique. Fusce feugiat, lorem et faucibus eleifend, ipsum nisi maximus justo, at consectetur ligula leo vitae justo."""
+  # Really long one-line
+  pass
+
+
+def Really_Long_Method_2():
+  """Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum egestas
+  libero urna, vel sagittis felis condimentum in. Nulla arcu eros, aliquet vel
+  mollis vitae, semper eu ex. Donec posuere quam et ornare sagittis. Curabitur
+  nunc ex, fringilla quis lorem sed, dignissim congue felis. Integer vestibulum
+  ac elit vel blandit. Nam non dui urna. Integer eu semper massa. Nullam ac elit
+  interdum, aliquet elit nec, porttitor orci. Duis tempus justo lorem, ac
+  fringilla ante viverra egestas. Etiam eleifend enim ac libero dapibus, quis
+  condimentum lectus tristique. Fusce feugiat, lorem et faucibus eleifend, ipsum
+  nisi maximus justo, at consectetur ligula leo vitae justo."""
+  # Really long one para
+  pass
+
+
+def Moan():
+  Really_Long_Method()
+  Really_Long_Method_2()