Skip to content

Commit e219594

Browse files
authored
Lazily construct rope projects and resources (#298)
1 parent 738730a commit e219594

File tree

5 files changed

+40
-25
lines changed

5 files changed

+40
-25
lines changed

pyls/plugins/rope_completion.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def pyls_settings():
1515

1616

1717
@hookimpl
18-
def pyls_completions(document, position):
18+
def pyls_completions(config, workspace, document, position):
1919
# Rope is a bit rubbish at completing module imports, so we'll return None
2020
word = document.word_at_position({
2121
# The -1 should really be trying to look at the previous word, but that might be quite expensive
@@ -26,9 +26,11 @@ def pyls_completions(document, position):
2626
return None
2727

2828
offset = document.offset_at_position(position)
29-
definitions = code_assist(
30-
document._rope_project, document.source,
31-
offset, document._rope, maxfixes=3)
29+
rope_config = config.settings(document_path=document.path).get('rope', {})
30+
rope_project = workspace._rope_project_builder(rope_config)
31+
document_rope = document._rope_resource(rope_config)
32+
33+
definitions = code_assist(rope_project, document.source, offset, document_rope, maxfixes=3)
3234

3335
definitions = sorted_proposals(definitions)
3436
new_definitions = []
@@ -42,7 +44,8 @@ def pyls_completions(document, position):
4244
'kind': _kind(d),
4345
'detail': '{0} {1}'.format(d.scope or "", d.name),
4446
'documentation': doc or "",
45-
'sortText': _sort_text(d)})
47+
'sortText': _sort_text(d)
48+
})
4649
definitions = new_definitions
4750

4851
return definitions or None

pyls/plugins/rope_rename.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,13 @@
1212

1313

1414
@hookimpl
15-
def pyls_rename(workspace, document, position, new_name):
15+
def pyls_rename(config, workspace, document, position, new_name):
16+
rope_config = config.settings(document_path=document.path).get('rope', {})
17+
rope_project = workspace._rope_project_builder(rope_config)
18+
1619
rename = Rename(
17-
workspace._rope,
18-
libutils.path_to_resource(workspace._rope, document.path),
20+
rope_project,
21+
libutils.path_to_resource(rope_project, document.path),
1922
document.offset_at_position(position)
2023
)
2124

pyls/workspace.py

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,16 @@ def __init__(self, root_uri, rpc_manager):
8181
self._root_path = uris.to_fs_path(self._root_uri)
8282
self._docs = {}
8383

84-
# Whilst incubating, keep private
85-
self.__rope = Project(self._root_path)
86-
self.__rope.prefs.set('extension_modules', self.PRELOADED_MODULES)
84+
# Whilst incubating, keep rope private
85+
self.__rope = None
86+
self.__rope_config = None
8787

88-
@property
89-
def _rope(self):
88+
def _rope_project_builder(self, rope_config):
9089
# TODO: we could keep track of dirty files and validate only those
90+
if self.__rope is None or self.__rope_config != rope_config:
91+
rope_folder = rope_config.get('ropeFolder')
92+
self.__rope = Project(self._root_path, ropefolder=rope_folder)
93+
self.__rope.prefs.set('extension_modules', self.PRELOADED_MODULES)
9194
self.__rope.validate()
9295
return self.__rope
9396

@@ -143,14 +146,15 @@ def source_roots(self, document_path):
143146
def _create_document(self, doc_uri, source=None, version=None):
144147
path = uris.to_fs_path(doc_uri)
145148
return Document(
146-
doc_uri, source=source,
147-
extra_sys_path=self.source_roots(path), rope=self._rope, version=version
149+
doc_uri, source=source, version=version,
150+
extra_sys_path=self.source_roots(path),
151+
rope_project_builder=self._rope_project_builder,
148152
)
149153

150154

151155
class Document(object):
152156

153-
def __init__(self, uri, source=None, version=None, local=True, extra_sys_path=None, rope=None):
157+
def __init__(self, uri, source=None, version=None, local=True, extra_sys_path=None, rope_project_builder=None):
154158
self.uri = uri
155159
self.version = version
156160
self.path = uris.to_fs_path(uri)
@@ -159,14 +163,13 @@ def __init__(self, uri, source=None, version=None, local=True, extra_sys_path=No
159163
self._local = local
160164
self._source = source
161165
self._extra_sys_path = extra_sys_path or []
162-
self._rope_project = rope
166+
self._rope_project_builder = rope_project_builder
163167

164168
def __str__(self):
165169
return str(self.uri)
166170

167-
@property
168-
def _rope(self):
169-
return libutils.path_to_resource(self._rope_project, self.path)
171+
def _rope_resource(self, rope_config):
172+
return libutils.path_to_resource(self._rope_project_builder(rope_config), self.path)
170173

171174
@property
172175
def lines(self):

test/plugins/test_completion.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ def _a_hello():
2424
"""
2525

2626

27-
def test_rope_import_completion():
27+
def test_rope_import_completion(config, workspace):
2828
com_position = {'line': 0, 'character': 7}
2929
doc = Document(DOC_URI, DOC)
30-
items = pyls_rope_completions(doc, com_position)
30+
items = pyls_rope_completions(config, workspace, doc, com_position)
3131
assert items is None
3232

3333

@@ -44,13 +44,14 @@ def test_jedi_completion():
4444
pyls_jedi_completions(doc, {'line': 1, 'character': 1000})
4545

4646

47-
def test_rope_completion():
47+
def test_rope_completion(config, workspace):
4848
# Over 'i' in os.path.isabs(...)
4949
com_position = {'line': 1, 'character': 15}
5050
rope = Project(LOCATION)
5151
rope.prefs.set('extension_modules', get_preferred_submodules())
52-
doc = Document(DOC_URI, DOC, rope=rope)
53-
items = pyls_rope_completions(doc, com_position)
52+
workspace.put_document(DOC_URI, source=DOC)
53+
doc = workspace.get_document(DOC_URI)
54+
items = pyls_rope_completions(config, workspace, doc, com_position)
5455

5556
assert items
5657
assert items[0]['label'] == 'isabs'

vscode-client/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,11 @@
145145
"type": "boolean",
146146
"default": true,
147147
"description": "Enable or disable the plugin."
148+
},
149+
"pyls.rope.ropeFolder": {
150+
"type": "string",
151+
"default": ".ropeproject",
152+
"description": "The name of the folder in which rope stores project configurations and data. Pass `null` for not using such a folder at all."
148153
}
149154
}
150155
}

0 commit comments

Comments
 (0)