53 "_statement": "?{0}".format(Editor.AttributeProtectedID), |
54 "_statement": "?{0}".format(Editor.AttributeProtectedID), |
54 "__statement": "?{0}".format(Editor.AttributePrivateID), |
55 "__statement": "?{0}".format(Editor.AttributePrivateID), |
55 "import": "", |
56 "import": "", |
56 "None": "", |
57 "None": "", |
57 } |
58 } |
58 |
59 |
59 def __init__(self, viewManager, project, ui): |
60 def __init__(self, viewManager, project, ui): |
60 """ |
61 """ |
61 Constructor |
62 Constructor |
62 |
63 |
63 @param viewManager reference to the viewmanager object |
64 @param viewManager reference to the viewmanager object |
64 @type ViewManager |
65 @type ViewManager |
65 @param project reference to the project object |
66 @param project reference to the project object |
66 @type Project |
67 @type Project |
67 @param ui reference to the user interface |
68 @param ui reference to the user interface |
68 @type UserInterface |
69 @type UserInterface |
69 """ |
70 """ |
70 super().__init__( |
71 super().__init__("JediServer", multiplex=True, parent=ui) |
71 "JediServer", multiplex=True, parent=ui) |
72 |
72 |
|
73 self.__ui = ui |
73 self.__ui = ui |
74 self.__vm = viewManager |
74 self.__vm = viewManager |
75 self.__ericProject = project |
75 self.__ericProject = project |
76 |
76 |
77 self.__editorLanguageMapping = {} |
77 self.__editorLanguageMapping = {} |
78 |
78 |
79 self.__documentationViewer = None |
79 self.__documentationViewer = None |
80 |
80 |
81 # attributes to store the resuls of the client side |
81 # attributes to store the resuls of the client side |
82 self.__completions = None |
82 self.__completions = None |
83 self.__calltips = None |
83 self.__calltips = None |
84 |
84 |
85 self.__methodMapping = { |
85 self.__methodMapping = { |
86 "CompletionsResult": self.__processCompletionsResult, |
86 "CompletionsResult": self.__processCompletionsResult, |
87 "CallTipsResult": self.__processCallTipsResult, |
87 "CallTipsResult": self.__processCallTipsResult, |
88 "DocumentationResult": self.__processDocumentationResult, |
88 "DocumentationResult": self.__processDocumentationResult, |
89 "HoverHelpResult": self.__processHoverHelpResult, |
89 "HoverHelpResult": self.__processHoverHelpResult, |
90 "GotoDefinitionResult": self.__processGotoDefinitionResult, |
90 "GotoDefinitionResult": self.__processGotoDefinitionResult, |
91 "GotoReferencesResult": self.__processGotoReferencesResult, |
91 "GotoReferencesResult": self.__processGotoReferencesResult, |
92 |
|
93 "RefactoringDiff": self.__showRefactoringDiff, |
92 "RefactoringDiff": self.__showRefactoringDiff, |
94 "RefactoringApplyResult": self.__checkRefactoringResult, |
93 "RefactoringApplyResult": self.__checkRefactoringResult, |
95 |
|
96 "ClientException": self.__processClientException, |
94 "ClientException": self.__processClientException, |
97 } |
95 } |
98 |
96 |
99 # temporary store for editor references indexed by Uuid |
97 # temporary store for editor references indexed by Uuid |
100 self.__editors = {} |
98 self.__editors = {} |
101 |
99 |
102 # Python 3 |
100 # Python 3 |
103 self.__ensureActive("Python3") |
101 self.__ensureActive("Python3") |
104 |
102 |
105 def __updateEditorLanguageMapping(self): |
103 def __updateEditorLanguageMapping(self): |
106 """ |
104 """ |
107 Private method to update the editor language to connection mapping. |
105 Private method to update the editor language to connection mapping. |
108 """ |
106 """ |
109 self.__editorLanguageMapping = {} |
107 self.__editorLanguageMapping = {} |
110 for name in self.connectionNames(): |
108 for name in self.connectionNames(): |
111 if name == "Python3": |
109 if name == "Python3": |
112 self.__editorLanguageMapping.update({ |
110 self.__editorLanguageMapping.update( |
113 "Python3": "Python3", |
111 { |
114 "MicroPython": "Python3", |
112 "Python3": "Python3", |
115 "Pygments|Python": "Python3", |
113 "MicroPython": "Python3", |
116 "Pygments|Python 2.x": "Python3", |
114 "Pygments|Python": "Python3", |
117 "Cython": "Python3", |
115 "Pygments|Python 2.x": "Python3", |
118 }) |
116 "Cython": "Python3", |
119 |
117 } |
|
118 ) |
|
119 |
120 def isSupportedLanguage(self, language): |
120 def isSupportedLanguage(self, language): |
121 """ |
121 """ |
122 Public method to check, if the given language is supported. |
122 Public method to check, if the given language is supported. |
123 |
123 |
124 @param language editor programming language to check |
124 @param language editor programming language to check |
125 @type str |
125 @type str |
126 @return flag indicating the support status |
126 @return flag indicating the support status |
127 @rtype bool |
127 @rtype bool |
128 """ |
128 """ |
129 return language in self.__editorLanguageMapping |
129 return language in self.__editorLanguageMapping |
130 |
130 |
131 def __idString(self, editor): |
131 def __idString(self, editor): |
132 """ |
132 """ |
133 Private method to determine the ID string for the back-end. |
133 Private method to determine the ID string for the back-end. |
134 |
134 |
135 @param editor reference to the editor to determine the ID string for |
135 @param editor reference to the editor to determine the ID string for |
136 @type Editor |
136 @type Editor |
137 @return ID string |
137 @return ID string |
138 @rtype str |
138 @rtype str |
139 """ |
139 """ |
140 idString = "" |
140 idString = "" |
141 |
141 |
142 language = editor.getLanguage() |
142 language = editor.getLanguage() |
143 if ( |
143 if ( |
144 self.__ericProject.isOpen() and |
144 self.__ericProject.isOpen() |
145 self.__ericProject.getProjectLanguage() == language |
145 and self.__ericProject.getProjectLanguage() == language |
146 ): |
146 ): |
147 filename = editor.getFileName() |
147 filename = editor.getFileName() |
148 if self.__ericProject.isProjectSource(filename): |
148 if self.__ericProject.isProjectSource(filename): |
149 idString = JediServer.IdProject |
149 idString = JediServer.IdProject |
150 |
150 |
151 if not idString and language in self.__editorLanguageMapping: |
151 if not idString and language in self.__editorLanguageMapping: |
152 idString = self.__editorLanguageMapping[language] |
152 idString = self.__editorLanguageMapping[language] |
153 |
153 |
154 return idString |
154 return idString |
155 |
155 |
156 def __prepareData(self, editor): |
156 def __prepareData(self, editor): |
157 """ |
157 """ |
158 Private method to gather data about current cursor position. |
158 Private method to gather data about current cursor position. |
159 |
159 |
160 @param editor reference to the editor object, that called this method |
160 @param editor reference to the editor object, that called this method |
161 @type Editor |
161 @type Editor |
162 @return tuple of filename, line, index, source |
162 @return tuple of filename, line, index, source |
163 @rtype tuple (str, int, int, str) |
163 @rtype tuple (str, int, int, str) |
164 """ |
164 """ |
165 filename = editor.getFileName() |
165 filename = editor.getFileName() |
166 line, index = editor.getCursorPosition() |
166 line, index = editor.getCursorPosition() |
167 line += 1 # jedi line numbers are 1 based |
167 line += 1 # jedi line numbers are 1 based |
168 source = editor.text() |
168 source = editor.text() |
169 return filename, line, index, source |
169 return filename, line, index, source |
170 |
170 |
171 def requestCompletions(self, editor, context, acText): |
171 def requestCompletions(self, editor, context, acText): |
172 """ |
172 """ |
173 Public method to request a list of possible completions. |
173 Public method to request a list of possible completions. |
174 |
174 |
175 @param editor reference to the editor object, that called this method |
175 @param editor reference to the editor object, that called this method |
176 @type Editor |
176 @type Editor |
177 @param context flag indicating to autocomplete a context |
177 @param context flag indicating to autocomplete a context |
178 @type bool |
178 @type bool |
179 @param acText text to be completed |
179 @param acText text to be completed |
180 @type str |
180 @type str |
181 """ |
181 """ |
182 if not Preferences.getJedi("JediCompletionsEnabled"): |
182 if not Preferences.getJedi("JediCompletionsEnabled"): |
183 return |
183 return |
184 |
184 |
185 idString = self.__idString(editor) |
185 idString = self.__idString(editor) |
186 if not idString: |
186 if not idString: |
187 return |
187 return |
188 |
188 |
189 filename, line, index, source = self.__prepareData(editor) |
189 filename, line, index, source = self.__prepareData(editor) |
190 fuzzy = Preferences.getJedi("JediFuzzyCompletionsEnabled") |
190 fuzzy = Preferences.getJedi("JediFuzzyCompletionsEnabled") |
191 |
191 |
192 self.__ensureActive(idString) |
192 self.__ensureActive(idString) |
193 |
193 |
194 self.sendJson("getCompletions", { |
194 self.sendJson( |
195 "FileName": filename, |
195 "getCompletions", |
196 "Source": source, |
196 { |
197 "Line": line, |
197 "FileName": filename, |
198 "Index": index, |
198 "Source": source, |
199 "Fuzzy": fuzzy, |
199 "Line": line, |
200 "CompletionText": acText, |
200 "Index": index, |
201 }, idString=idString) |
201 "Fuzzy": fuzzy, |
202 |
202 "CompletionText": acText, |
|
203 }, |
|
204 idString=idString, |
|
205 ) |
|
206 |
203 def __processCompletionsResult(self, result): |
207 def __processCompletionsResult(self, result): |
204 """ |
208 """ |
205 Private method to process the completions sent by the client. |
209 Private method to process the completions sent by the client. |
206 |
210 |
207 @param result dictionary containing the result sent by the client |
211 @param result dictionary containing the result sent by the client |
208 @type dict |
212 @type dict |
209 """ |
213 """ |
210 names = [] |
214 names = [] |
211 for completion in result["Completions"]: |
215 for completion in result["Completions"]: |
212 name = completion['Name'] |
216 name = completion["Name"] |
213 context = completion['FullName'] |
217 context = completion["FullName"] |
214 if context: |
218 if context: |
215 if context.endswith(".{0}".format(name)): |
219 if context.endswith(".{0}".format(name)): |
216 context = context.rsplit(".", 1)[0] |
220 context = context.rsplit(".", 1)[0] |
217 name = "{0} ({1})".format(name, context) |
221 name = "{0} ({1})".format(name, context) |
218 |
222 |
219 name += JediServer.PictureIDs.get(completion['CompletionType'], '') |
223 name += JediServer.PictureIDs.get(completion["CompletionType"], "") |
220 names.append(name) |
224 names.append(name) |
221 |
225 |
222 if "Error" not in result: |
226 if "Error" not in result: |
223 editor = self.__vm.getOpenEditor(result["FileName"]) |
227 editor = self.__vm.getOpenEditor(result["FileName"]) |
224 if editor is not None: |
228 if editor is not None: |
225 editor.completionsListReady(names, |
229 editor.completionsListReady(names, result["CompletionText"]) |
226 result["CompletionText"]) |
230 |
227 |
|
228 def getCallTips(self, editor, pos, commas): |
231 def getCallTips(self, editor, pos, commas): |
229 """ |
232 """ |
230 Public method to calculate calltips. |
233 Public method to calculate calltips. |
231 |
234 |
232 @param editor reference to the editor object, that called this method |
235 @param editor reference to the editor object, that called this method |
233 @type Editor |
236 @type Editor |
234 @param pos position in the text for the calltip |
237 @param pos position in the text for the calltip |
235 @type int |
238 @type int |
236 @param commas minimum number of commas contained in the calltip |
239 @param commas minimum number of commas contained in the calltip |
238 @return list of possible calltips |
241 @return list of possible calltips |
239 @rtype list of str |
242 @rtype list of str |
240 """ |
243 """ |
241 if not Preferences.getJedi("JediCalltipsEnabled"): |
244 if not Preferences.getJedi("JediCalltipsEnabled"): |
242 return [] |
245 return [] |
243 |
246 |
244 # reset the calltips buffer |
247 # reset the calltips buffer |
245 self.__calltips = None |
248 self.__calltips = None |
246 |
249 |
247 idString = self.__idString(editor) |
250 idString = self.__idString(editor) |
248 if not idString: |
251 if not idString: |
249 return [] |
252 return [] |
250 |
253 |
251 filename, line, index, source = self.__prepareData(editor) |
254 filename, line, index, source = self.__prepareData(editor) |
252 |
255 |
253 self.__ensureActive(idString) |
256 self.__ensureActive(idString) |
254 self.sendJson("getCallTips", { |
257 self.sendJson( |
255 "FileName": filename, |
258 "getCallTips", |
256 "Source": source, |
259 { |
257 "Line": line, |
260 "FileName": filename, |
258 "Index": index, |
261 "Source": source, |
259 }, idString=idString) |
262 "Line": line, |
260 |
263 "Index": index, |
|
264 }, |
|
265 idString=idString, |
|
266 ) |
|
267 |
261 # emulate the synchronous behaviour |
268 # emulate the synchronous behaviour |
262 timer = QTimer() |
269 timer = QTimer() |
263 timer.setSingleShot(True) |
270 timer.setSingleShot(True) |
264 timer.start(5000) # 5s timeout |
271 timer.start(5000) # 5s timeout |
265 while self.__calltips is None and timer.isActive(): |
272 while self.__calltips is None and timer.isActive(): |
266 QCoreApplication.processEvents() |
273 QCoreApplication.processEvents() |
267 QThread.msleep(100) |
274 QThread.msleep(100) |
268 |
275 |
269 return [] if self.__calltips is None else self.__calltips |
276 return [] if self.__calltips is None else self.__calltips |
270 |
277 |
271 def __processCallTipsResult(self, result): |
278 def __processCallTipsResult(self, result): |
272 """ |
279 """ |
273 Private method to process the calltips sent by the client. |
280 Private method to process the calltips sent by the client. |
274 |
281 |
275 @param result dictionary containing the result sent by the client |
282 @param result dictionary containing the result sent by the client |
276 @type dict |
283 @type dict |
277 """ |
284 """ |
278 if "Error" in result: |
285 if "Error" in result: |
279 self.__calltips = [] |
286 self.__calltips = [] |
280 else: |
287 else: |
281 self.__calltips = result["CallTips"] |
288 self.__calltips = result["CallTips"] |
282 |
289 |
283 def requestCodeDocumentation(self, editor): |
290 def requestCodeDocumentation(self, editor): |
284 """ |
291 """ |
285 Public method to request source code documentation for the given |
292 Public method to request source code documentation for the given |
286 editor. |
293 editor. |
287 |
294 |
288 @param editor reference to the editor to get source code documentation |
295 @param editor reference to the editor to get source code documentation |
289 for |
296 for |
290 @type Editor |
297 @type Editor |
291 """ |
298 """ |
292 if self.__documentationViewer is None: |
299 if self.__documentationViewer is None: |
293 return |
300 return |
294 |
301 |
295 idString = self.__idString(editor) |
302 idString = self.__idString(editor) |
296 |
303 |
297 if not idString: |
304 if not idString: |
298 language = editor.getLanguage() |
305 language = editor.getLanguage() |
299 warning = ( |
306 warning = self.tr("Language <b>{0}</b> is not supported.").format(language) |
300 self.tr("Language <b>{0}</b> is not supported.") |
307 self.__documentationViewer.documentationReady(warning, isWarning=True) |
301 .format(language) |
|
302 ) |
|
303 self.__documentationViewer.documentationReady( |
|
304 warning, isWarning=True) |
|
305 return |
308 return |
306 |
309 |
307 filename, line, index, source = self.__prepareData(editor) |
310 filename, line, index, source = self.__prepareData(editor) |
308 sourceLines = source.splitlines() |
311 sourceLines = source.splitlines() |
309 # Correct index if cursor is standing after an opening bracket |
312 # Correct index if cursor is standing after an opening bracket |
310 if line > 0 and index > 0 and sourceLines[line - 1][index - 1] == '(': |
313 if line > 0 and index > 0 and sourceLines[line - 1][index - 1] == "(": |
311 index -= 1 |
314 index -= 1 |
312 |
315 |
313 self.__ensureActive(idString) |
316 self.__ensureActive(idString) |
314 self.sendJson("getDocumentation", { |
317 self.sendJson( |
315 "FileName": filename, |
318 "getDocumentation", |
316 "Source": source, |
319 { |
317 "Line": line, |
320 "FileName": filename, |
318 "Index": index, |
321 "Source": source, |
319 }, idString=idString) |
322 "Line": line, |
320 |
323 "Index": index, |
|
324 }, |
|
325 idString=idString, |
|
326 ) |
|
327 |
321 def __processDocumentationResult(self, result): |
328 def __processDocumentationResult(self, result): |
322 """ |
329 """ |
323 Private method to process the documentation sent by the client. |
330 Private method to process the documentation sent by the client. |
324 |
331 |
325 @param result dictionary containing the result sent by the client |
332 @param result dictionary containing the result sent by the client |
326 @type dict with keys 'name', 'module', 'argspec', 'docstring' |
333 @type dict with keys 'name', 'module', 'argspec', 'docstring' |
327 """ |
334 """ |
328 if self.__documentationViewer is None: |
335 if self.__documentationViewer is None: |
329 return |
336 return |
330 |
337 |
331 docu = None |
338 docu = None |
332 |
339 |
333 if "Error" not in result: |
340 if "Error" not in result: |
334 docu = result["DocumentationDict"] |
341 docu = result["DocumentationDict"] |
335 docu["note"] = ( |
342 docu["note"] = self.tr("Present in <i>{0}</i> module").format( |
336 self.tr("Present in <i>{0}</i> module") |
343 docu["module"] |
337 .format(docu["module"])) |
344 ) |
338 |
345 |
339 if docu is None: |
346 if docu is None: |
340 msg = self.tr("No documentation available.") |
347 msg = self.tr("No documentation available.") |
341 self.__documentationViewer.documentationReady( |
348 self.__documentationViewer.documentationReady(msg, isDocWarning=True) |
342 msg, isDocWarning=True) |
|
343 else: |
349 else: |
344 self.__documentationViewer.documentationReady(docu) |
350 self.__documentationViewer.documentationReady(docu) |
345 |
351 |
346 def gotoDefinition(self, editor): |
352 def gotoDefinition(self, editor): |
347 """ |
353 """ |
348 Public slot to find the definition for the word at the cursor position |
354 Public slot to find the definition for the word at the cursor position |
349 and go to it. |
355 and go to it. |
350 |
356 |
351 Note: This is executed upon a mouse click sequence. |
357 Note: This is executed upon a mouse click sequence. |
352 |
358 |
353 @param editor reference to the calling editor |
359 @param editor reference to the calling editor |
354 @type Editor |
360 @type Editor |
355 """ |
361 """ |
356 if not Preferences.getJedi("MouseClickEnabled"): |
362 if not Preferences.getJedi("MouseClickEnabled"): |
357 return |
363 return |
358 |
364 |
359 idString = self.__idString(editor) |
365 idString = self.__idString(editor) |
360 if not idString: |
366 if not idString: |
361 return |
367 return |
362 |
368 |
363 filename, line, index, source = self.__prepareData(editor) |
369 filename, line, index, source = self.__prepareData(editor) |
364 |
370 |
365 self.__ensureActive(idString) |
371 self.__ensureActive(idString) |
366 |
372 |
367 euuid = str(uuid.uuid4()) |
373 euuid = str(uuid.uuid4()) |
368 self.__editors[euuid] = editor |
374 self.__editors[euuid] = editor |
369 |
375 |
370 self.sendJson("gotoDefinition", { |
376 self.sendJson( |
371 "FileName": filename, |
377 "gotoDefinition", |
372 "Source": source, |
378 { |
373 "Line": line, |
379 "FileName": filename, |
374 "Index": index, |
380 "Source": source, |
375 "Uuid": euuid, |
381 "Line": line, |
376 }, idString=idString) |
382 "Index": index, |
377 |
383 "Uuid": euuid, |
|
384 }, |
|
385 idString=idString, |
|
386 ) |
|
387 |
378 def __processGotoDefinitionResult(self, result): |
388 def __processGotoDefinitionResult(self, result): |
379 """ |
389 """ |
380 Private method callback for the goto definition result. |
390 Private method callback for the goto definition result. |
381 |
391 |
382 @param result dictionary containing the result data |
392 @param result dictionary containing the result data |
383 @type dict |
393 @type dict |
384 """ |
394 """ |
385 euuid = result["Uuid"] |
395 euuid = result["Uuid"] |
386 if "Error" not in result: |
396 if "Error" not in result: |
387 # ignore errors silently |
397 # ignore errors silently |
388 location = result["GotoDefinitionDict"] |
398 location = result["GotoDefinitionDict"] |
389 if location: |
399 if location: |
390 self.__vm.openSourceFile(location["ModulePath"], |
400 self.__vm.openSourceFile( |
391 location["Line"], |
401 location["ModulePath"], location["Line"], addNext=True |
392 addNext=True) |
402 ) |
393 else: |
403 else: |
394 ericApp().getObject("UserInterface").statusBar().showMessage( |
404 ericApp().getObject("UserInterface").statusBar().showMessage( |
395 self.tr('Jedi: No definition found'), 5000) |
405 self.tr("Jedi: No definition found"), 5000 |
396 |
406 ) |
|
407 |
397 with contextlib.suppress(KeyError): |
408 with contextlib.suppress(KeyError): |
398 del self.__editors[euuid] |
409 del self.__editors[euuid] |
399 |
410 |
400 def __processGotoReferencesResult(self, result): |
411 def __processGotoReferencesResult(self, result): |
401 """ |
412 """ |
402 Private method callback for the goto references result. |
413 Private method callback for the goto references result. |
403 |
414 |
404 @param result dictionary containing the result data |
415 @param result dictionary containing the result data |
405 @type dict |
416 @type dict |
406 """ |
417 """ |
407 euuid = result["Uuid"] |
418 euuid = result["Uuid"] |
408 with contextlib.suppress(ImportError): |
419 with contextlib.suppress(ImportError): |
409 from QScintilla.Editor import ReferenceItem |
420 from QScintilla.Editor import ReferenceItem |
410 |
421 |
411 if "Error" not in result: |
422 if "Error" not in result: |
412 # ignore errors silently |
423 # ignore errors silently |
413 references = result["GotoReferencesList"] |
424 references = result["GotoReferencesList"] |
414 if references: |
425 if references: |
415 try: |
426 try: |
421 ReferenceItem( |
432 ReferenceItem( |
422 modulePath=ref["ModulePath"], |
433 modulePath=ref["ModulePath"], |
423 codeLine=ref["Code"], |
434 codeLine=ref["Code"], |
424 line=ref["Line"], |
435 line=ref["Line"], |
425 column=ref["Column"], |
436 column=ref["Column"], |
426 ) for ref in references |
437 ) |
|
438 for ref in references |
427 ] |
439 ] |
428 editor.gotoReferenceHandler(referenceItemsList) |
440 editor.gotoReferenceHandler(referenceItemsList) |
429 |
441 |
430 with contextlib.suppress(KeyError): |
442 with contextlib.suppress(KeyError): |
431 del self.__editors[euuid] |
443 del self.__editors[euuid] |
432 |
444 |
433 def hoverHelp(self, editor, line, index): |
445 def hoverHelp(self, editor, line, index): |
434 """ |
446 """ |
435 Public method to initiate the display of mouse hover help. |
447 Public method to initiate the display of mouse hover help. |
436 |
448 |
437 @param editor reference to the calling editor |
449 @param editor reference to the calling editor |
438 @type Editor |
450 @type Editor |
439 @param line line number (zero based) |
451 @param line line number (zero based) |
440 @type int |
452 @type int |
441 @param index index within the line (zero based) |
453 @param index index within the line (zero based) |
442 @type int |
454 @type int |
443 """ |
455 """ |
444 idString = self.__idString(editor) |
456 idString = self.__idString(editor) |
445 if not idString: |
457 if not idString: |
446 return |
458 return |
447 |
459 |
448 filename = editor.getFileName() |
460 filename = editor.getFileName() |
449 line += 1 # jedi line numbers are 1 based |
461 line += 1 # jedi line numbers are 1 based |
450 source = editor.text() |
462 source = editor.text() |
451 |
463 |
452 self.__ensureActive(idString) |
464 self.__ensureActive(idString) |
453 |
465 |
454 euuid = str(uuid.uuid4()) |
466 euuid = str(uuid.uuid4()) |
455 self.__editors[euuid] = editor |
467 self.__editors[euuid] = editor |
456 |
468 |
457 self.sendJson("hoverHelp", { |
469 self.sendJson( |
458 "FileName": filename, |
470 "hoverHelp", |
459 "Source": source, |
471 { |
460 "Line": line, |
472 "FileName": filename, |
461 "Index": index, |
473 "Source": source, |
462 "Uuid": euuid, |
474 "Line": line, |
463 }, idString=idString) |
475 "Index": index, |
464 |
476 "Uuid": euuid, |
|
477 }, |
|
478 idString=idString, |
|
479 ) |
|
480 |
465 def __processHoverHelpResult(self, result): |
481 def __processHoverHelpResult(self, result): |
466 """ |
482 """ |
467 Private method callback for the goto definition result. |
483 Private method callback for the goto definition result. |
468 |
484 |
469 @param result dictionary containing the result data |
485 @param result dictionary containing the result data |
470 @type dict |
486 @type dict |
471 """ |
487 """ |
472 euuid = result["Uuid"] |
488 euuid = result["Uuid"] |
473 if "Error" not in result: |
489 if "Error" not in result: |
474 # ignore errors silently |
490 # ignore errors silently |
475 helpText = result["HoverHelp"] |
491 helpText = result["HoverHelp"] |
476 if helpText: |
492 if helpText: |
477 with contextlib.suppress(KeyError): |
493 with contextlib.suppress(KeyError): |
478 self.__editors[euuid].showMouseHoverHelpData( |
494 self.__editors[euuid].showMouseHoverHelpData( |
479 result["Line"] - 1, |
495 result["Line"] - 1, result["Index"], helpText |
480 result["Index"], |
|
481 helpText |
|
482 ) |
496 ) |
483 else: |
497 else: |
484 ericApp().getObject("UserInterface").statusBar().showMessage( |
498 ericApp().getObject("UserInterface").statusBar().showMessage( |
485 self.tr('Jedi: No mouse hover help found'), 5000) |
499 self.tr("Jedi: No mouse hover help found"), 5000 |
486 |
500 ) |
|
501 |
487 with contextlib.suppress(KeyError): |
502 with contextlib.suppress(KeyError): |
488 del self.__editors[euuid] |
503 del self.__editors[euuid] |
489 |
504 |
490 ####################################################################### |
505 ####################################################################### |
491 ## Refactoring methods below |
506 ## Refactoring methods below |
492 ####################################################################### |
507 ####################################################################### |
493 |
508 |
494 @pyqtSlot() |
509 @pyqtSlot() |
495 def refactoringRenameVariable(self): |
510 def refactoringRenameVariable(self): |
496 """ |
511 """ |
497 Public slot to rename the selected variable. |
512 Public slot to rename the selected variable. |
498 """ |
513 """ |
499 editor = self.__vm.activeWindow() |
514 editor = self.__vm.activeWindow() |
500 if editor: |
515 if editor: |
501 idString = self.__idString(editor) |
516 idString = self.__idString(editor) |
502 if not idString: |
517 if not idString: |
503 return |
518 return |
504 |
519 |
505 newName, ok = QInputDialog.getText( |
520 newName, ok = QInputDialog.getText( |
506 None, |
521 None, |
507 self.tr("Rename Variable"), |
522 self.tr("Rename Variable"), |
508 self.tr("Enter the new name for the variable:"), |
523 self.tr("Enter the new name for the variable:"), |
509 QLineEdit.EchoMode.Normal, |
524 QLineEdit.EchoMode.Normal, |
510 editor.selectedText() |
525 editor.selectedText(), |
511 ) |
526 ) |
512 |
527 |
513 if ok and newName and self.__vm.checkAllDirty(): |
528 if ok and newName and self.__vm.checkAllDirty(): |
514 filename = editor.getFileName() |
529 filename = editor.getFileName() |
515 line, index = editor.getCursorPosition() |
530 line, index = editor.getCursorPosition() |
516 source = editor.text() |
531 source = editor.text() |
517 |
532 |
518 self.__ensureActive(idString) |
533 self.__ensureActive(idString) |
519 |
534 |
520 euuid = str(uuid.uuid4()) |
535 euuid = str(uuid.uuid4()) |
521 self.__editors[euuid] = editor |
536 self.__editors[euuid] = editor |
522 |
537 |
523 self.sendJson("renameVariable", { |
538 self.sendJson( |
524 "FileName": filename, |
539 "renameVariable", |
525 "Source": source, |
540 { |
526 "Line": line + 1, |
541 "FileName": filename, |
527 "Index": index, |
542 "Source": source, |
528 "Uuid": euuid, |
543 "Line": line + 1, |
529 "NewName": newName, |
544 "Index": index, |
530 }, idString=idString) |
545 "Uuid": euuid, |
531 |
546 "NewName": newName, |
|
547 }, |
|
548 idString=idString, |
|
549 ) |
|
550 |
532 @pyqtSlot() |
551 @pyqtSlot() |
533 def refactoringExtractNewVariable(self): |
552 def refactoringExtractNewVariable(self): |
534 """ |
553 """ |
535 Public slot to extract a statement to a new variable. |
554 Public slot to extract a statement to a new variable. |
536 """ |
555 """ |
537 editor = self.__vm.activeWindow() |
556 editor = self.__vm.activeWindow() |
538 if editor: |
557 if editor: |
539 idString = self.__idString(editor) |
558 idString = self.__idString(editor) |
540 if not idString: |
559 if not idString: |
541 return |
560 return |
542 |
561 |
543 newName, ok = QInputDialog.getText( |
562 newName, ok = QInputDialog.getText( |
544 None, |
563 None, |
545 self.tr("Extract Variable"), |
564 self.tr("Extract Variable"), |
546 self.tr("Enter the name for the new variable:"), |
565 self.tr("Enter the name for the new variable:"), |
547 QLineEdit.EchoMode.Normal |
566 QLineEdit.EchoMode.Normal, |
548 ) |
567 ) |
549 |
568 |
550 if ok and newName and editor.checkDirty(): |
569 if ok and newName and editor.checkDirty(): |
551 filename = editor.getFileName() |
570 filename = editor.getFileName() |
552 sLine, sIndex, eLine, eIndex = editor.getSelection() |
571 sLine, sIndex, eLine, eIndex = editor.getSelection() |
553 source = editor.text() |
572 source = editor.text() |
554 |
573 |
555 self.__ensureActive(idString) |
574 self.__ensureActive(idString) |
556 |
575 |
557 euuid = str(uuid.uuid4()) |
576 euuid = str(uuid.uuid4()) |
558 self.__editors[euuid] = editor |
577 self.__editors[euuid] = editor |
559 |
578 |
560 self.sendJson("extractVariable", { |
579 self.sendJson( |
561 "FileName": filename, |
580 "extractVariable", |
562 "Source": source, |
581 { |
563 "Line": sLine + 1, |
582 "FileName": filename, |
564 "Index": sIndex, |
583 "Source": source, |
565 "EndLine": eLine + 1, |
584 "Line": sLine + 1, |
566 "EndIndex": eIndex, |
585 "Index": sIndex, |
567 "Uuid": euuid, |
586 "EndLine": eLine + 1, |
568 "NewName": newName, |
587 "EndIndex": eIndex, |
569 }, idString=idString) |
588 "Uuid": euuid, |
570 |
589 "NewName": newName, |
|
590 }, |
|
591 idString=idString, |
|
592 ) |
|
593 |
571 @pyqtSlot() |
594 @pyqtSlot() |
572 def refactoringInlineVariable(self): |
595 def refactoringInlineVariable(self): |
573 """ |
596 """ |
574 Public slot to inline the selected variable. |
597 Public slot to inline the selected variable. |
575 |
598 |
576 Note: This is the opposite to Extract New Variable. |
599 Note: This is the opposite to Extract New Variable. |
577 """ |
600 """ |
578 editor = self.__vm.activeWindow() |
601 editor = self.__vm.activeWindow() |
579 if editor: |
602 if editor: |
580 idString = self.__idString(editor) |
603 idString = self.__idString(editor) |
581 if not idString: |
604 if not idString: |
582 return |
605 return |
583 |
606 |
584 if editor.checkDirty(): |
607 if editor.checkDirty(): |
585 filename = editor.getFileName() |
608 filename = editor.getFileName() |
586 line, index = editor.getCursorPosition() |
609 line, index = editor.getCursorPosition() |
587 source = editor.text() |
610 source = editor.text() |
588 |
611 |
589 self.__ensureActive(idString) |
612 self.__ensureActive(idString) |
590 |
613 |
591 euuid = str(uuid.uuid4()) |
614 euuid = str(uuid.uuid4()) |
592 self.__editors[euuid] = editor |
615 self.__editors[euuid] = editor |
593 |
616 |
594 self.sendJson("inlineVariable", { |
617 self.sendJson( |
595 "FileName": filename, |
618 "inlineVariable", |
596 "Source": source, |
619 { |
597 "Line": line + 1, |
620 "FileName": filename, |
598 "Index": index, |
621 "Source": source, |
599 "Uuid": euuid, |
622 "Line": line + 1, |
600 }, idString=idString) |
623 "Index": index, |
601 |
624 "Uuid": euuid, |
|
625 }, |
|
626 idString=idString, |
|
627 ) |
|
628 |
602 @pyqtSlot() |
629 @pyqtSlot() |
603 def refactoringExtractFunction(self): |
630 def refactoringExtractFunction(self): |
604 """ |
631 """ |
605 Public slot to extract an expression to a function. |
632 Public slot to extract an expression to a function. |
606 """ |
633 """ |
607 editor = self.__vm.activeWindow() |
634 editor = self.__vm.activeWindow() |
608 if editor: |
635 if editor: |
609 idString = self.__idString(editor) |
636 idString = self.__idString(editor) |
610 if not idString: |
637 if not idString: |
611 return |
638 return |
612 |
639 |
613 newName, ok = QInputDialog.getText( |
640 newName, ok = QInputDialog.getText( |
614 None, |
641 None, |
615 self.tr("Extract Function"), |
642 self.tr("Extract Function"), |
616 self.tr("Enter the name for the function:"), |
643 self.tr("Enter the name for the function:"), |
617 QLineEdit.EchoMode.Normal |
644 QLineEdit.EchoMode.Normal, |
618 ) |
645 ) |
619 |
646 |
620 if ok and newName and editor.checkDirty(): |
647 if ok and newName and editor.checkDirty(): |
621 filename = editor.getFileName() |
648 filename = editor.getFileName() |
622 sLine, sIndex, eLine, eIndex = editor.getSelection() |
649 sLine, sIndex, eLine, eIndex = editor.getSelection() |
623 source = editor.text() |
650 source = editor.text() |
624 |
651 |
625 self.__ensureActive(idString) |
652 self.__ensureActive(idString) |
626 |
653 |
627 euuid = str(uuid.uuid4()) |
654 euuid = str(uuid.uuid4()) |
628 self.__editors[euuid] = editor |
655 self.__editors[euuid] = editor |
629 |
656 |
630 self.sendJson("extractFunction", { |
657 self.sendJson( |
631 "FileName": filename, |
658 "extractFunction", |
632 "Source": source, |
659 { |
633 "Line": sLine + 1, |
660 "FileName": filename, |
634 "Index": sIndex, |
661 "Source": source, |
635 "EndLine": eLine + 1, |
662 "Line": sLine + 1, |
636 "EndIndex": eIndex, |
663 "Index": sIndex, |
637 "Uuid": euuid, |
664 "EndLine": eLine + 1, |
638 "NewName": newName, |
665 "EndIndex": eIndex, |
639 }, idString=idString) |
666 "Uuid": euuid, |
640 |
667 "NewName": newName, |
|
668 }, |
|
669 idString=idString, |
|
670 ) |
|
671 |
641 def __showRefactoringDiff(self, result): |
672 def __showRefactoringDiff(self, result): |
642 """ |
673 """ |
643 Private method to show the diff of a refactoring. |
674 Private method to show the diff of a refactoring. |
644 |
675 |
645 @param result dictionary containing the result data |
676 @param result dictionary containing the result data |
646 @type dict |
677 @type dict |
647 """ |
678 """ |
648 if "Error" not in result: |
679 if "Error" not in result: |
649 euuid = result["Uuid"] |
680 euuid = result["Uuid"] |
655 self.__cancelRefactoring(euuid) |
686 self.__cancelRefactoring(euuid) |
656 else: |
687 else: |
657 EricMessageBox.critical( |
688 EricMessageBox.critical( |
658 None, |
689 None, |
659 self.tr("Refactoring"), |
690 self.tr("Refactoring"), |
660 self.tr("<p>The refactoring could not be performed.</p>" |
691 self.tr( |
661 "<p>Reason: {0}</p>").format(result["ErrorString"]) |
692 "<p>The refactoring could not be performed.</p>" |
662 ) |
693 "<p>Reason: {0}</p>" |
663 |
694 ).format(result["ErrorString"]), |
|
695 ) |
|
696 |
664 def __applyRefactoring(self, uid): |
697 def __applyRefactoring(self, uid): |
665 """ |
698 """ |
666 Private method to apply a given refactoring. |
699 Private method to apply a given refactoring. |
667 |
700 |
668 @param uid UID of the calculated refactoring |
701 @param uid UID of the calculated refactoring |
669 @type str |
702 @type str |
670 """ |
703 """ |
671 with contextlib.suppress(KeyError): |
704 with contextlib.suppress(KeyError): |
672 editor = self.__editors[uid] |
705 editor = self.__editors[uid] |
673 idString = self.__idString(editor) |
706 idString = self.__idString(editor) |
674 |
707 |
675 self.sendJson("applyRefactoring", { |
708 self.sendJson( |
676 "Uuid": uid, |
709 "applyRefactoring", |
677 }, idString=idString) |
710 { |
678 |
711 "Uuid": uid, |
|
712 }, |
|
713 idString=idString, |
|
714 ) |
|
715 |
679 del self.__editors[uid] |
716 del self.__editors[uid] |
680 |
717 |
681 def __cancelRefactoring(self, uid): |
718 def __cancelRefactoring(self, uid): |
682 """ |
719 """ |
683 Private method to cancel a given refactoring. |
720 Private method to cancel a given refactoring. |
684 |
721 |
685 @param uid UID of the calculated refactoring |
722 @param uid UID of the calculated refactoring |
686 @type str |
723 @type str |
687 """ |
724 """ |
688 with contextlib.suppress(KeyError): |
725 with contextlib.suppress(KeyError): |
689 editor = self.__editors[uid] |
726 editor = self.__editors[uid] |
690 idString = self.__idString(editor) |
727 idString = self.__idString(editor) |
691 |
728 |
692 self.sendJson("cancelRefactoring", { |
729 self.sendJson( |
693 "Uuid": uid, |
730 "cancelRefactoring", |
694 }, idString=idString) |
731 { |
695 |
732 "Uuid": uid, |
|
733 }, |
|
734 idString=idString, |
|
735 ) |
|
736 |
696 del self.__editors[uid] |
737 del self.__editors[uid] |
697 |
738 |
698 def __checkRefactoringResult(self, result): |
739 def __checkRefactoringResult(self, result): |
699 """ |
740 """ |
700 Private method to check the refactoring result for errors. |
741 Private method to check the refactoring result for errors. |
701 |
742 |
702 @param result dictionary containing the result data |
743 @param result dictionary containing the result data |
703 @type dict |
744 @type dict |
704 """ |
745 """ |
705 if "Error" in result: |
746 if "Error" in result: |
706 EricMessageBox.critical( |
747 EricMessageBox.critical( |
707 None, |
748 None, |
708 self.tr("Apply Refactoring"), |
749 self.tr("Apply Refactoring"), |
709 self.tr("<p>The refactoring could not be applied.</p>" |
750 self.tr( |
710 "<p>Reason: {0}</p>").format(result["ErrorString"]) |
751 "<p>The refactoring could not be applied.</p>" "<p>Reason: {0}</p>" |
711 ) |
752 ).format(result["ErrorString"]), |
712 |
753 ) |
|
754 |
713 ####################################################################### |
755 ####################################################################### |
714 ## Methods below handle the network connection |
756 ## Methods below handle the network connection |
715 ####################################################################### |
757 ####################################################################### |
716 |
758 |
717 def handleCall(self, method, params): |
759 def handleCall(self, method, params): |
718 """ |
760 """ |
719 Public method to handle a method call from the client. |
761 Public method to handle a method call from the client. |
720 |
762 |
721 @param method requested method name |
763 @param method requested method name |
722 @type str |
764 @type str |
723 @param params dictionary with method specific parameters |
765 @param params dictionary with method specific parameters |
724 @type dict |
766 @type dict |
725 """ |
767 """ |
726 self.__methodMapping[method](params) |
768 self.__methodMapping[method](params) |
727 |
769 |
728 def __processClientException(self, params): |
770 def __processClientException(self, params): |
729 """ |
771 """ |
730 Private method to handle exceptions of the refactoring client. |
772 Private method to handle exceptions of the refactoring client. |
731 |
773 |
732 @param params dictionary containing the exception data |
774 @param params dictionary containing the exception data |
733 @type dict |
775 @type dict |
734 """ |
776 """ |
735 if params["ExceptionType"] == "ProtocolError": |
777 if params["ExceptionType"] == "ProtocolError": |
736 self.__ui.appendToStderr( |
778 self.__ui.appendToStderr( |
737 self.tr("The data received from the Jedi server could not be" |
779 self.tr( |
738 " decoded. Please report this issue with the received" |
780 "The data received from the Jedi server could not be" |
739 " data to the eric bugs email address.\n" |
781 " decoded. Please report this issue with the received" |
740 "Error: {0}\n" |
782 " data to the eric bugs email address.\n" |
741 "Data:\n{1}\n").format( |
783 "Error: {0}\n" |
742 params["ExceptionValue"], |
784 "Data:\n{1}\n" |
743 params["ProtocolData"])) |
785 ).format(params["ExceptionValue"], params["ProtocolData"]) |
|
786 ) |
744 else: |
787 else: |
745 self.__ui.appendToStderr( |
788 self.__ui.appendToStderr( |
746 self.tr("An exception happened in the Jedi client. Please" |
789 self.tr( |
747 " report it to the eric bugs email address.\n" |
790 "An exception happened in the Jedi client. Please" |
748 "Exception: {0}\n" |
791 " report it to the eric bugs email address.\n" |
749 "Value: {1}\n" |
792 "Exception: {0}\n" |
750 "Traceback: {2}\n").format( |
793 "Value: {1}\n" |
|
794 "Traceback: {2}\n" |
|
795 ).format( |
751 params["ExceptionType"], |
796 params["ExceptionType"], |
752 params["ExceptionValue"], |
797 params["ExceptionValue"], |
753 params["Traceback"])) |
798 params["Traceback"], |
754 |
799 ) |
|
800 ) |
|
801 |
755 def __startJediClient(self, interpreter, idString, clientEnv): |
802 def __startJediClient(self, interpreter, idString, clientEnv): |
756 """ |
803 """ |
757 Private method to start the Jedi client with the given interpreter. |
804 Private method to start the Jedi client with the given interpreter. |
758 |
805 |
759 @param interpreter interpreter to be used for the Jedi client |
806 @param interpreter interpreter to be used for the Jedi client |
760 @type str |
807 @type str |
761 @param idString id of the client to be started |
808 @param idString id of the client to be started |
762 @type str |
809 @type str |
763 @param clientEnv dictionary with environment variables to run the |
810 @param clientEnv dictionary with environment variables to run the |
820 if idString == "Python3": |
876 if idString == "Python3": |
821 venvName = Preferences.getDebugger("Python3VirtualEnv") |
877 venvName = Preferences.getDebugger("Python3VirtualEnv") |
822 if not venvName: |
878 if not venvName: |
823 venvName, _ = venvManager.getDefaultEnvironment() |
879 venvName, _ = venvManager.getDefaultEnvironment() |
824 if venvName: |
880 if venvName: |
825 interpreter = venvManager.getVirtualenvInterpreter( |
881 interpreter = venvManager.getVirtualenvInterpreter(venvName) |
826 venvName) |
|
827 execPath = venvManager.getVirtualenvExecPath(venvName) |
882 execPath = venvManager.getVirtualenvExecPath(venvName) |
828 |
883 |
829 # build a suitable environment |
884 # build a suitable environment |
830 if execPath: |
885 if execPath: |
831 if "PATH" in clientEnv: |
886 if "PATH" in clientEnv: |
832 clientEnv["PATH"] = os.pathsep.join( |
887 clientEnv["PATH"] = os.pathsep.join( |
833 [execPath, clientEnv["PATH"]]) |
888 [execPath, clientEnv["PATH"]] |
|
889 ) |
834 else: |
890 else: |
835 clientEnv["PATH"] = execPath |
891 clientEnv["PATH"] = execPath |
836 if interpreter: |
892 if interpreter: |
837 ok = self.__startJediClient(interpreter, idString, clientEnv) |
893 ok = self.__startJediClient(interpreter, idString, clientEnv) |
838 else: |
894 else: |
839 ok = False |
895 ok = False |
840 return ok |
896 return ok |
841 |
897 |
842 def __interpreterForProject(self): |
898 def __interpreterForProject(self): |
843 """ |
899 """ |
844 Private method to determine the interpreter for the current project and |
900 Private method to determine the interpreter for the current project and |
845 the environment to run it. |
901 the environment to run it. |
846 |
902 |
847 @return tuple containing the interpreter of the current project and the |
903 @return tuple containing the interpreter of the current project and the |
848 environment variables |
904 environment variables |
849 @rtype tuple of (str, dict) |
905 @rtype tuple of (str, dict) |
850 """ |
906 """ |
851 projectLanguage = self.__ericProject.getProjectLanguage() |
907 projectLanguage = self.__ericProject.getProjectLanguage() |
852 interpreter = "" |
908 interpreter = "" |
853 clientEnv = os.environ.copy() |
909 clientEnv = os.environ.copy() |
854 if "PATH" in clientEnv: |
910 if "PATH" in clientEnv: |
855 clientEnv["PATH"] = self.__ui.getOriginalPathString() |
911 clientEnv["PATH"] = self.__ui.getOriginalPathString() |
856 |
912 |
857 if projectLanguage in ("Python3", "MicroPython", "Cython"): |
913 if projectLanguage in ("Python3", "MicroPython", "Cython"): |
858 interpreter = self.__ericProject.getProjectInterpreter( |
914 interpreter = self.__ericProject.getProjectInterpreter(resolveGlobal=False) |
859 resolveGlobal=False) |
|
860 if interpreter: |
915 if interpreter: |
861 execPath = self.__ericProject.getProjectExecPath() |
916 execPath = self.__ericProject.getProjectExecPath() |
862 |
917 |
863 # build a suitable environment |
918 # build a suitable environment |
864 if execPath: |
919 if execPath: |
865 if "PATH" in clientEnv: |
920 if "PATH" in clientEnv: |
866 clientEnv["PATH"] = os.pathsep.join( |
921 clientEnv["PATH"] = os.pathsep.join( |
867 [execPath, clientEnv["PATH"]]) |
922 [execPath, clientEnv["PATH"]] |
|
923 ) |
868 else: |
924 else: |
869 clientEnv["PATH"] = execPath |
925 clientEnv["PATH"] = execPath |
870 |
926 |
871 return interpreter, clientEnv |
927 return interpreter, clientEnv |
872 |
928 |
873 @pyqtSlot() |
929 @pyqtSlot() |
874 def handleNewConnection(self): |
930 def handleNewConnection(self): |
875 """ |
931 """ |
876 Public slot for new incoming connections from a client. |
932 Public slot for new incoming connections from a client. |
877 """ |
933 """ |
878 super().handleNewConnection() |
934 super().handleNewConnection() |
879 |
935 |
880 self.__updateEditorLanguageMapping() |
936 self.__updateEditorLanguageMapping() |
881 |
937 |
882 def activate(self): |
938 def activate(self): |
883 """ |
939 """ |
884 Public method to activate the Jedi server. |
940 Public method to activate the Jedi server. |
885 """ |
941 """ |
886 self.__documentationViewer = self.__ui.documentationViewer() |
942 self.__documentationViewer = self.__ui.documentationViewer() |
887 if self.__documentationViewer is not None: |
943 if self.__documentationViewer is not None: |
888 self.__documentationViewer.registerProvider( |
944 self.__documentationViewer.registerProvider( |
889 "jedi", self.tr("Jedi"), self.requestCodeDocumentation, |
945 "jedi", |
890 self.isSupportedLanguage) |
946 self.tr("Jedi"), |
891 |
947 self.requestCodeDocumentation, |
|
948 self.isSupportedLanguage, |
|
949 ) |
|
950 |
892 self.__ericProject.projectOpened.connect(self.__projectOpened) |
951 self.__ericProject.projectOpened.connect(self.__projectOpened) |
893 self.__ericProject.projectClosed.connect(self.__projectClosed) |
952 self.__ericProject.projectClosed.connect(self.__projectClosed) |
894 |
953 |
895 def deactivate(self): |
954 def deactivate(self): |
896 """ |
955 """ |
897 Public method to deactivate the code assist server. |
956 Public method to deactivate the code assist server. |
898 """ |
957 """ |
899 """ |
958 """ |
900 Public method to shut down the code assist server. |
959 Public method to shut down the code assist server. |
901 """ |
960 """ |
902 if self.__documentationViewer is not None: |
961 if self.__documentationViewer is not None: |
903 self.__documentationViewer.unregisterProvider("jedi") |
962 self.__documentationViewer.unregisterProvider("jedi") |
904 |
963 |
905 with contextlib.suppress(TypeError): |
964 with contextlib.suppress(TypeError): |
906 self.__ericProject.projectOpened.disconnect(self.__projectOpened) |
965 self.__ericProject.projectOpened.disconnect(self.__projectOpened) |
907 self.__ericProject.projectClosed.disconnect(self.__projectClosed) |
966 self.__ericProject.projectClosed.disconnect(self.__projectClosed) |
908 |
967 |
909 self.stopAllClients() |
968 self.stopAllClients() |
910 |
969 |
911 @pyqtSlot() |
970 @pyqtSlot() |
912 def __projectOpened(self): |
971 def __projectOpened(self): |
913 """ |
972 """ |
914 Private slot to handle the projectOpened signal. |
973 Private slot to handle the projectOpened signal. |
915 """ |
974 """ |
916 self.__ensureActive(JediServer.IdProject) |
975 self.__ensureActive(JediServer.IdProject) |
917 self.sendJson("openProject", { |
976 self.sendJson( |
918 "ProjectPath": self.__ericProject.getProjectPath(), |
977 "openProject", |
919 }, idString=JediServer.IdProject) |
978 { |
920 |
979 "ProjectPath": self.__ericProject.getProjectPath(), |
|
980 }, |
|
981 idString=JediServer.IdProject, |
|
982 ) |
|
983 |
921 @pyqtSlot() |
984 @pyqtSlot() |
922 def __projectClosed(self): |
985 def __projectClosed(self): |
923 """ |
986 """ |
924 Private slot to handle the projectClosed signal. |
987 Private slot to handle the projectClosed signal. |
925 """ |
988 """ |
926 self.__ensureActive(JediServer.IdProject) |
989 self.__ensureActive(JediServer.IdProject) |
927 self.sendJson("closeProject", {}, idString=JediServer.IdProject) |
990 self.sendJson("closeProject", {}, idString=JediServer.IdProject) |
928 |
991 |
929 self.stopClient(idString=JediServer.IdProject) |
992 self.stopClient(idString=JediServer.IdProject) |