4141)
4242from pygls .workspace import TextDocument
4343
44+ from .constants import MAX_CONCURRENT_DEBOUNCE_CALLS
4445from .initialization_options import HoverDisableOptions , InitializationOptions
4546from .type_map import get_lsp_completion_type , get_lsp_symbol_type
4647
5354P = ParamSpec ("P" )
5455
5556
57+ _debounce_semaphore = threading .Semaphore (MAX_CONCURRENT_DEBOUNCE_CALLS )
58+
59+
5660def debounce (
57- interval_s : int , keyed_by : Optional [str ] = None
61+ interval_s : float , keyed_by : Optional [str ] = None
5862) -> Callable [[Callable [P , None ]], Callable [P , None ]]:
5963 """Debounce calls to this function until interval_s seconds have passed.
6064
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
6366 """
6467
6568 def wrapper (func : Callable [P , None ]) -> Callable [P , None ]:
@@ -68,20 +71,25 @@ def wrapper(func: Callable[P, None]) -> Callable[P, None]:
6871
6972 @functools .wraps (func )
7073 def debounced (* args : P .args , ** kwargs : P .kwargs ) -> None :
74+ _debounce_semaphore .acquire ()
75+
7176 sig = inspect .signature (func )
7277 call_args = sig .bind (* args , ** kwargs )
7378 key = call_args .arguments [keyed_by ] if keyed_by else None
7479
7580 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 ()
7987
8088 with lock :
8189 old_timer = timers .get (key )
8290 if old_timer :
8391 old_timer .cancel ()
84-
92+ _debounce_semaphore . release ()
8593 timer = threading .Timer (interval_s , run )
8694 timers [key ] = timer
8795 timer .start ()
@@ -148,22 +156,26 @@ def lsp_range(name: Name) -> Optional[Range]:
148156 )
149157
150158
151- def lsp_location (name : Name ) -> Optional [Location ]:
159+ def lsp_location (name : Name , uri : Optional [ str ] = None ) -> Optional [Location ]:
152160 """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 ()
156166
157167 lsp = lsp_range (name )
158168 if lsp is None :
159169 return None
160170
161- return Location (uri = module_path . as_uri () , range = lsp )
171+ return Location (uri = uri , range = lsp )
162172
163173
164- def lsp_symbol_information (name : Name ) -> Optional [SymbolInformation ]:
174+ def lsp_symbol_information (
175+ name : Name , uri : Optional [str ] = None
176+ ) -> Optional [SymbolInformation ]:
165177 """Get LSP SymbolInformation from Jedi definition."""
166- location = lsp_location (name )
178+ location = lsp_location (name , uri )
167179 if location is None :
168180 return None
169181
0 commit comments