@@ -12,6 +12,12 @@ class PopupManager():
12
12
13
13
It uses the WorkScheduler class to handle sending requests to the server to
14
14
ensure good performance.
15
+
16
+ The main challenge is that certain activities, such as cursor movement, can
17
+ automatically dismiss the popup - even though the cursor may still be in the
18
+ argument list. Therefore the class listens to the on_hidden event, and will
19
+ redisplay if necessary (i.e. if the cursor is still in the argument list).
20
+ If the popup is explicitly dismissed, on_close_popup is called.
15
21
"""
16
22
17
23
html_template = ''
@@ -28,8 +34,8 @@ def __init__(self, proxy):
28
34
self .signature_index = 0
29
35
self .current_parameter = 0
30
36
31
- # Used to avoid looping
32
- self .suppress_onhidden = 0
37
+ # Track current popup location to see if we only need to update the text
38
+ self .current_location = None
33
39
34
40
def queue_signature_popup (self , view ):
35
41
cursor = view .rowcol (view .sel ()[0 ].begin ())
@@ -59,14 +65,14 @@ def on_response(self, responseJson, view):
59
65
self .current_parameter = responseJson ["body" ]["argumentIndex" ]
60
66
61
67
# Add a region to track the arg list as the user types
62
- # Needs to be ajusted to 0-based indexing
68
+ # Needs to be adjusted to 0-based indexing
63
69
arg_span = self .signature_help ["applicableSpan" ]
64
70
span_start = view .text_point (
65
71
arg_span ["start" ]["line" ] - 1 ,
66
72
arg_span ["start" ]["offset" ] - 2 )
67
73
span_end = view .text_point (
68
74
arg_span ["end" ]["line" ] - 1 ,
69
- arg_span ["end" ]["offset" ] - 1 )
75
+ arg_span ["end" ]["offset" ])
70
76
71
77
arg_region = sublime .Region (span_start , span_end )
72
78
view .add_regions ('argSpan' , [arg_region ],
@@ -95,22 +101,21 @@ def display(self):
95
101
cursor_line_start
96
102
).end ()
97
103
98
- # Need to hide/redisplay in case location moved, but this triggers an
99
- # on_hidden loop if we don't ignore the event (which occurs later)
100
- # from the hide message
101
- if self .current_view .is_popup_visible ():
102
- self .suppress_onhidden += 1
103
- log .debug ('+suppress_onhidden: {0}' .format (self .suppress_onhidden ))
104
- self .current_view .hide_popup ()
105
-
106
- self .current_view .show_popup (
107
- popup_text ,
108
- sublime .COOPERATE_WITH_AUTO_COMPLETE ,
109
- on_navigate = self .on_navigate ,
110
- on_hide = self .on_hidden ,
111
- location = location ,
112
- max_width = 800 )
113
-
104
+ # If the popup is currently visible and at the right location, then
105
+ # call 'update' instead of 'show', else this can get in a loop when show
106
+ # causes the old popup to be hidden (and on_hidden is called), as well
107
+ # as causing some unnecessary UI flickering.
108
+ if self .current_view .is_popup_visible () and self .current_location == location :
109
+ self .current_view .update_popup (popup_text )
110
+ else :
111
+ self .current_location = location
112
+ self .current_view .show_popup (
113
+ popup_text ,
114
+ sublime .COOPERATE_WITH_AUTO_COMPLETE ,
115
+ on_navigate = self .on_navigate ,
116
+ on_hide = self .on_hidden ,
117
+ location = location ,
118
+ max_width = 800 )
114
119
115
120
def move_next (self ):
116
121
if not self .signature_help :
@@ -140,12 +145,7 @@ def on_hidden(self):
140
145
log .debug ('No current view for popup session. Hiding popup' )
141
146
return
142
147
143
- # Did we hide the popup ourselves in order to redisplay it?
144
- if self .suppress_onhidden > 0 :
145
- self .suppress_onhidden -= 1
146
- log .debug ('-suppress_onhidden: {0}' .format (self .suppress_onhidden ))
147
- return
148
-
148
+ # If we're still in the arg list, then redisplay
149
149
cursor_region = self .current_view .sel ()[0 ]
150
150
arg_regions = self .current_view .get_regions ('argSpan' )
151
151
if len (arg_regions ):
0 commit comments