2
2
import logging
3
3
import re
4
4
import sys
5
+ from concurrent .futures import ThreadPoolExecutor
5
6
import importmagic
6
7
from pyls import hookimpl , lsp , _utils
7
8
15
16
UNRES_RE = re .compile (r"Unresolved import '(?P<unresolved>[\w.]+)'" )
16
17
UNREF_RE = re .compile (r"Unreferenced import '(?P<unreferenced>[\w.]+)'" )
17
18
18
- _index_cache = {}
19
+ _index_cache = None
19
20
20
21
21
- def _get_index ( sys_path ):
22
+ def _build_index ( paths ):
22
23
"""Build index of symbols from python modules.
23
- Cache the index so we don't build it multiple times unnecessarily.
24
24
"""
25
- key = tuple (sys_path )
26
- if key not in _index_cache :
27
- log .info ("Started building importmagic index" )
28
- index = importmagic .SymbolIndex ()
29
- # The build tend to be noisy
30
- index .build_index (paths = sys_path )
31
- _index_cache [key ] = index
32
- log .info ("Finished building importmagic index" )
33
- return _index_cache [key ]
25
+ log .info ("Started building importmagic index" )
26
+ index = importmagic .SymbolIndex ()
27
+ index .build_index (paths = paths )
28
+ log .info ("Finished building importmagic index" )
29
+ return index
30
+
31
+
32
+ def _cache_index_callback (future ):
33
+ global _index_cache
34
+ # Cache the index
35
+ _index_cache = future .result ()
36
+
37
+
38
+ def _get_index ():
39
+ """Get the cached index if built and index project files on each call.
40
+ Return an empty index if not built yet.
41
+ """
42
+ # Index haven't been built yet
43
+ if _index_cache is None :
44
+ return importmagic .SymbolIndex ()
45
+
46
+ # Index project files
47
+ # TODO(youben) index project files
48
+ #index.build_index(paths=[])
49
+ return _index_cache
34
50
35
51
36
52
def _get_imports_list (source , index = None ):
@@ -46,6 +62,13 @@ def _get_imports_list(source, index=None):
46
62
return imported
47
63
48
64
65
+ @hookimpl
66
+ def pyls_initialize ():
67
+ pool = ThreadPoolExecutor ()
68
+ builder = pool .submit (_build_index , (sys .path ))
69
+ builder .add_done_callback (_cache_index_callback )
70
+
71
+
49
72
@hookimpl
50
73
def pyls_commands ():
51
74
return [ADD_IMPORT_COMMAND , REMOVE_IMPORT_COMMAND ]
@@ -125,7 +148,7 @@ def pyls_lint(document):
125
148
126
149
127
150
@hookimpl
128
- def pyls_code_actions (config , document ):
151
+ def pyls_code_actions (config , document , context ):
129
152
"""Build a list of actions to be suggested to the user. Each action follow this format:
130
153
{
131
154
'title': 'importmagic',
@@ -146,9 +169,8 @@ def pyls_code_actions(config, document):
146
169
log .debug ("Got importmagic settings: %s" , conf )
147
170
importmagic .Imports .set_style (** {_utils .camel_to_underscore (k ): v for k , v in conf .items ()})
148
171
149
- # Might be slow but is cached once built
150
- # TODO (youben): add project path for indexing
151
- index = _get_index (sys .path )
172
+ # Get empty index while it's building so we don't block here
173
+ index = _get_index ()
152
174
actions = []
153
175
154
176
diagnostics = pyls_lint (document )
0 commit comments