@@ -14,6 +14,12 @@ class PopupManager():
14
14
15
15
It uses the WorkScheduler class to handle sending requests to the server to
16
16
ensure good performance.
17
+
18
+ The main challenge is that certain activities, such as cursor movement, can
19
+ automatically dismiss the popup - even though the cursor may still be in the
20
+ argument list. Therefore the class listens to the on_hidden event, and will
21
+ redisplay if necessary (i.e. if the cursor is still in the argument list).
22
+ If the popup is explicitly dismissed, on_close_popup is called.
17
23
"""
18
24
19
25
html_template = ''
@@ -30,6 +36,9 @@ def __init__(self, proxy):
30
36
self .signature_index = 0
31
37
self .current_parameter = 0
32
38
39
+ # Track current popup location to see if we only need to update the text
40
+ self .current_location = None
41
+
33
42
def queue_signature_popup (self , view ):
34
43
cursor = view .rowcol (view .sel ()[0 ].begin ())
35
44
point = Location (cursor [0 ] + 1 , cursor [1 ] + 1 )
@@ -58,14 +67,15 @@ def on_response(self, responseJson, view):
58
67
self .current_parameter = responseJson ["body" ]["argumentIndex" ]
59
68
60
69
# Add a region to track the arg list as the user types
61
- # Needs to be ajusted to 0-based indexing
70
+ # Needs to be adjusted to 0-based indexing
62
71
arg_span = self .signature_help ["applicableSpan" ]
63
72
span_start = view .text_point (
64
73
arg_span ["start" ]["line" ] - 1 ,
65
74
arg_span ["start" ]["offset" ] - 2 )
66
75
span_end = view .text_point (
67
76
arg_span ["end" ]["line" ] - 1 ,
68
- arg_span ["end" ]["offset" ] - 1 )
77
+ arg_span ["end" ]["offset" ])
78
+
69
79
arg_region = sublime .Region (span_start , span_end )
70
80
view .add_regions ('argSpan' , [arg_region ],
71
81
flags = sublime .HIDDEN )
@@ -78,15 +88,36 @@ def display(self):
78
88
popup_text = PopupManager .html_template .substitute (popup_parts )
79
89
80
90
log .debug ('Displaying signature popup' )
81
- if not self .current_view .is_popup_visible ():
91
+
92
+ arg_region = self .current_view .get_regions ('argSpan' )[0 ]
93
+ location = arg_region .begin () # Default to start of arg list
94
+
95
+ # If the cursor is not in the first line of the arg list, set the popup
96
+ # location to first non-whitespace, or EOL, of the current line
97
+ cursor_point = self .current_view .sel ()[0 ].begin ()
98
+ opening_line = self .current_view .line (arg_region .begin ())
99
+ if (not opening_line .contains (cursor_point )):
100
+ cursor_line_start = self .current_view .line (cursor_point ).begin ()
101
+ location = self .current_view .find (
102
+ r'\s*?(?=[\S\n\r]|$)' ,
103
+ cursor_line_start
104
+ ).end ()
105
+
106
+ # If the popup is currently visible and at the right location, then
107
+ # call 'update' instead of 'show', else this can get in a loop when show
108
+ # causes the old popup to be hidden (and on_hidden is called), as well
109
+ # as causing some unnecessary UI flickering.
110
+ if self .current_view .is_popup_visible () and self .current_location == location :
111
+ self .current_view .update_popup (popup_text )
112
+ else :
113
+ self .current_location = location
82
114
self .current_view .show_popup (
83
115
popup_text ,
84
116
sublime .COOPERATE_WITH_AUTO_COMPLETE ,
85
117
on_navigate = self .on_navigate ,
86
118
on_hide = self .on_hidden ,
119
+ location = location ,
87
120
max_width = 800 )
88
- else :
89
- self .current_view .update_popup (popup_text )
90
121
91
122
def move_next (self ):
92
123
if not self .signature_help :
@@ -113,15 +144,17 @@ def on_navigate(self, loc):
113
144
def on_hidden (self ):
114
145
log .debug ('In popup on_hidden handler' )
115
146
if not self .current_view :
147
+ log .debug ('No current view for popup session. Hiding popup' )
116
148
return
117
149
150
+ # If we're still in the arg list, then redisplay
118
151
cursor_region = self .current_view .sel ()[0 ]
119
152
arg_regions = self .current_view .get_regions ('argSpan' )
120
153
if len (arg_regions ):
121
154
argSpan = self .current_view .get_regions ('argSpan' )[0 ]
122
155
if argSpan .contains (cursor_region ):
123
156
log .debug ('Was hidden while in region. Redisplaying' )
124
- # Occurs on left/right movement. Rerun to redisplay popup.
157
+ # Occurs on cursor movement. Rerun to redisplay popup.
125
158
self .display ()
126
159
else :
127
160
# Cleanup
@@ -202,7 +235,8 @@ def get_current_signature_parts(self):
202
235
param = item ["parameters" ][self .current_parameter ]
203
236
activeParam = '<span class="param">{0}:</span> <i>{1}</i>' .format (
204
237
param ["name" ],
205
- param ["documentation" ][0 ]["text" ] if param ["documentation" ] else "" )
238
+ param ["documentation" ][0 ]["text" ]
239
+ if param ["documentation" ] else "" )
206
240
else :
207
241
activeParam = ''
208
242
0 commit comments