41
41
)
42
42
from pygls .workspace import TextDocument
43
43
44
+ from .constants import MAX_CONCURRENT_DEBOUNCE_CALLS
44
45
from .initialization_options import HoverDisableOptions , InitializationOptions
45
46
from .type_map import get_lsp_completion_type , get_lsp_symbol_type
46
47
53
54
P = ParamSpec ("P" )
54
55
55
56
57
+ _debounce_semaphore = threading .Semaphore (MAX_CONCURRENT_DEBOUNCE_CALLS )
58
+
59
+
56
60
def debounce (
57
- interval_s : int , keyed_by : Optional [str ] = None
61
+ interval_s : float , keyed_by : Optional [str ] = None
58
62
) -> Callable [[Callable [P , None ]], Callable [P , None ]]:
59
63
"""Debounce calls to this function until interval_s seconds have passed.
60
64
61
- Decorator copied from https://github.com/python-lsp/python-lsp-
62
- server
65
+ Decorator adapted from https://github.com/python-lsp/python-lsp-server
63
66
"""
64
67
65
68
def wrapper (func : Callable [P , None ]) -> Callable [P , None ]:
@@ -68,20 +71,25 @@ def wrapper(func: Callable[P, None]) -> Callable[P, None]:
68
71
69
72
@functools .wraps (func )
70
73
def debounced (* args : P .args , ** kwargs : P .kwargs ) -> None :
74
+ _debounce_semaphore .acquire ()
75
+
71
76
sig = inspect .signature (func )
72
77
call_args = sig .bind (* args , ** kwargs )
73
78
key = call_args .arguments [keyed_by ] if keyed_by else None
74
79
75
80
def run () -> None :
76
- with lock :
77
- del timers [key ]
78
- return func (* args , ** kwargs )
81
+ try :
82
+ with lock :
83
+ del timers [key ]
84
+ func (* args , ** kwargs )
85
+ finally :
86
+ _debounce_semaphore .release ()
79
87
80
88
with lock :
81
89
old_timer = timers .get (key )
82
90
if old_timer :
83
91
old_timer .cancel ()
84
-
92
+ _debounce_semaphore . release ()
85
93
timer = threading .Timer (interval_s , run )
86
94
timers [key ] = timer
87
95
timer .start ()
@@ -148,22 +156,26 @@ def lsp_range(name: Name) -> Optional[Range]:
148
156
)
149
157
150
158
151
- def lsp_location (name : Name ) -> Optional [Location ]:
159
+ def lsp_location (name : Name , uri : Optional [ str ] = None ) -> Optional [Location ]:
152
160
"""Get LSP location from Jedi definition."""
153
- module_path = name .module_path
154
- if module_path is None :
155
- return None
161
+ if uri is None :
162
+ module_path = name .module_path
163
+ if module_path is None :
164
+ return None
165
+ uri = module_path .as_uri ()
156
166
157
167
lsp = lsp_range (name )
158
168
if lsp is None :
159
169
return None
160
170
161
- return Location (uri = module_path . as_uri () , range = lsp )
171
+ return Location (uri = uri , range = lsp )
162
172
163
173
164
- def lsp_symbol_information (name : Name ) -> Optional [SymbolInformation ]:
174
+ def lsp_symbol_information (
175
+ name : Name , uri : Optional [str ] = None
176
+ ) -> Optional [SymbolInformation ]:
165
177
"""Get LSP SymbolInformation from Jedi definition."""
166
- location = lsp_location (name )
178
+ location = lsp_location (name , uri )
167
179
if location is None :
168
180
return None
169
181
0 commit comments