Skip to content

Commit 92a5099

Browse files
committed
Use screenpos() for better popup placement
1 parent cfb117d commit 92a5099

File tree

2 files changed

+41
-13
lines changed

2 files changed

+41
-13
lines changed

python/ycm/signature_help.py

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -108,21 +108,36 @@ def UpdateSignatureHelp( state, signature_info ):
108108

109109
# Generate the buffer as a list of lines
110110
buf_lines = _MakeSignatureHelpBuffer( signature_info )
111+
screen_pos = vimsupport.ScreenPositionForLineColumnInWindow(
112+
vim.current.window,
113+
state.anchor[ 0 ] + 1, # 0-based
114+
state.anchor[ 1 ] + 1 ) # 0-based
115+
116+
# Simulate 'flip' at the screen boundaries by using screenpos.
117+
#
118+
# TODO: revert to cursor-relative positioning and the 'flip' option when that
119+
# is implemented.
120+
if int( screen_pos[ 'row' ] ) <= 1:
121+
line = 2
122+
pos = "topleft"
123+
else:
124+
line = int( screen_pos[ 'row' ] ) - 1 # -1 to display above the cur line
125+
pos = "botleft"
111126

112-
# Find the buffer position of the anchor and calculate it as an offset from
113-
# the cursor position.
114-
cur_pos = vimsupport.CurrentLineAndColumn()
115-
116-
cursor_relative_pos = [ state.anchor[ 0 ] - cur_pos[ 0 ] - 1 ,
117-
state.anchor[ 1 ] - cur_pos[ 1 ] ]
127+
if int( screen_pos[ 'curscol' ] ) <= 1:
128+
col = 1
129+
else:
130+
# -1 for padding,
131+
# -1 for the trigger character inserted (the anchor is set _after_ the
132+
# character is inserted, so we remove it).
133+
# FIXME: multi-byte characters would be wrong. Need to set anchor before
134+
# inserting the char ?
135+
col = int( screen_pos[ 'curscol' ] ) - 2
118136

119-
# Use the cursor offset to find the actual screen position. It's surprisingly
120-
# difficult to calculate the real screen position of a mark, or other buffer
121-
# position.
122137
options = {
123-
"line": 'cursor{:+d}'.format( cursor_relative_pos[ 0 ] ),
124-
"col": 'cursor{:+d}'.format( cursor_relative_pos[ 1 ] - 1 ), # 1 for border
125-
"pos": "botleft",
138+
"line": line,
139+
"col": col,
140+
"pos": pos,
126141
"wrap": 0,
127142
"flip": 1,
128143
"padding": [ 0, 1, 0, 1 ], # Pad 1 char in X axis to match completion menu

python/ycm/vimsupport.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1265,8 +1265,21 @@ def VimSupportsPopupWindows():
12651265
'popup_show',
12661266
'popup_close',
12671267
'prop_add',
1268-
'prop_type_add' ]:
1268+
'prop_type_add',
1269+
'screenpos' ]:
12691270
if not GetIntValue( vim.eval( 'exists( "*{}" )'.format(
12701271
required_method ) ) ):
12711272
return False
12721273
return True
1274+
1275+
1276+
def WinIDForWindow( window ):
1277+
return GetIntValue( 'win_getid( {}, {} )'.format( window.number,
1278+
window.tabpage.number ) )
1279+
1280+
1281+
def ScreenPositionForLineColumnInWindow( window, line, column ):
1282+
return vim.eval( 'screenpos( {}, {}, {} )'.format(
1283+
WinIDForWindow( vim.current.window ),
1284+
line,
1285+
column ) )

0 commit comments

Comments
 (0)