AssistantEric/Assistant.py

changeset 30
8f4d794d8ee0
parent 25
6a68405feb84
child 32
68ef15fe34c3
equal deleted inserted replaced
29:402d146da2f1 30:8f4d794d8ee0
8 calltips system. 8 calltips system.
9 """ 9 """
10 10
11 import re 11 import re
12 12
13 from PyQt4.QtCore import * 13 from PyQt4.QtCore import QRegExp, QObject
14 14
15 from E5Gui.E5Application import e5App 15 from E5Gui.E5Application import e5App
16 16
17 from .APIsManager import APIsManager, ApisNameProject 17 from .APIsManager import APIsManager, ApisNameProject
18 18
19 from QScintilla.Editor import Editor 19 from QScintilla.Editor import Editor
20 20
21 import Preferences 21 import Preferences
22 22
23 AcsAPIs = 0x0001 23 AcsAPIs = 0x0001
24 AcsDocument = 0x0002 24 AcsDocument = 0x0002
25 AcsProject = 0x0004 25 AcsProject = 0x0004
26 AcsOther = 0x1000 26 AcsOther = 0x1000
27
27 28
28 class Assistant(QObject): 29 class Assistant(QObject):
29 """ 30 """
30 Class implementing the autocompletion and calltips system. 31 Class implementing the autocompletion and calltips system.
31 """ 32 """
32 def __init__(self, plugin, newStyle, parent = None): 33 def __init__(self, plugin, parent=None):
33 """ 34 """
34 Constructor 35 Constructor
35 36
36 @param plugin reference to the plugin object 37 @param plugin reference to the plugin object
37 @param newStyle flag indicating usage of new style signals (bool)
38 @param parent parent (QObject) 38 @param parent parent (QObject)
39 """ 39 """
40 QObject.__init__(self, parent) 40 QObject.__init__(self, parent)
41 41
42 self.__plugin = plugin 42 self.__plugin = plugin
43 self.__newStyle = newStyle
44 self.__ui = parent 43 self.__ui = parent
45 self.__project = e5App().getObject("Project") 44 self.__project = e5App().getObject("Project")
46 self.__viewmanager = e5App().getObject("ViewManager") 45 self.__viewmanager = e5App().getObject("ViewManager")
47 self.__pluginManager = e5App().getObject("PluginManager") 46 self.__pluginManager = e5App().getObject("PluginManager")
48 47
49 self.__apisManager = APIsManager(self.__newStyle, self) 48 self.__apisManager = APIsManager(self)
50 49
51 self.__editors = [] 50 self.__editors = []
52 self.__completingContext = False 51 self.__completingContext = False
53 self.__lastContext = None 52 self.__lastContext = None
54 self.__lastFullContext = None 53 self.__lastFullContext = None
57 56
58 def activate(self): 57 def activate(self):
59 """ 58 """
60 Public method to perform actions upon activation. 59 Public method to perform actions upon activation.
61 """ 60 """
62 if self.__newStyle: 61 self.__pluginManager.shutdown.connect(self.__shutdown)
63 self.__pluginManager.shutdown.connect(self.__shutdown) 62
64 63 self.__ui.preferencesChanged.connect(self.__preferencesChanged)
65 self.__ui.preferencesChanged.connect(self.__preferencesChanged) 64
66 65 self.__viewmanager.editorOpenedEd.connect(self.__editorOpened)
67 self.__viewmanager.editorOpenedEd.connect(self.__editorOpened) 66 self.__viewmanager.editorClosedEd.connect(self.__editorClosed)
68 self.__viewmanager.editorClosedEd.connect(self.__editorClosed)
69 else:
70 self.connect(self.__pluginManager, SIGNAL("shutdown()"),
71 self.__shutdown)
72
73 self.connect(self.__ui, SIGNAL('preferencesChanged'),
74 self.__preferencesChanged)
75
76 self.connect(self.__viewmanager, SIGNAL("editorOpenedEd"),
77 self.__editorOpened)
78 self.connect(self.__viewmanager, SIGNAL("editorClosedEd"),
79 self.__editorClosed)
80 67
81 # preload the project APIs object 68 # preload the project APIs object
82 self.__apisManager.getAPIs(ApisNameProject) 69 self.__apisManager.getAPIs(ApisNameProject)
83 70
84 for editor in self.__viewmanager.getOpenEditors(): 71 for editor in self.__viewmanager.getOpenEditors():
86 73
87 def deactivate(self): 74 def deactivate(self):
88 """ 75 """
89 Public method to perform actions upon deactivation. 76 Public method to perform actions upon deactivation.
90 """ 77 """
91 if self.__newStyle: 78 self.__pluginManager.shutdown.disconnect(self.__shutdown)
92 self.__pluginManager.shutdown.disconnect(self.__shutdown) 79
93 80 self.__ui.preferencesChanged.disconnect(self.__preferencesChanged)
94 self.__ui.preferencesChanged.disconnect(self.__preferencesChanged) 81
95 82 self.__viewmanager.editorOpenedEd.disconnect(self.__editorOpened)
96 self.__viewmanager.editorOpenedEd.disconnect(self.__editorOpened) 83 self.__viewmanager.editorClosedEd.disconnect(self.__editorClosed)
97 self.__viewmanager.editorClosedEd.disconnect(self.__editorClosed)
98 else:
99 self.disconnect(self.__pluginManager, SIGNAL("shutdown()"),
100 self.__shutdown)
101
102 self.disconnect(self.__ui, SIGNAL('preferencesChanged'),
103 self.__preferencesChanged)
104
105 self.disconnect(self.__viewmanager, SIGNAL("editorOpenedEd"),
106 self.__editorOpened)
107 self.disconnect(self.__viewmanager, SIGNAL("editorClosedEd"),
108 self.__editorClosed)
109 84
110 self.__shutdown() 85 self.__shutdown()
111 86
112 def __shutdown(self): 87 def __shutdown(self):
113 """ 88 """
139 """ 114 """
140 if self.__plugin.getPreferences("AutoCompletionEnabled"): 115 if self.__plugin.getPreferences("AutoCompletionEnabled"):
141 self.__setAutoCompletionHook(editor) 116 self.__setAutoCompletionHook(editor)
142 if self.__plugin.getPreferences("CalltipsEnabled"): 117 if self.__plugin.getPreferences("CalltipsEnabled"):
143 self.__setCalltipsHook(editor) 118 self.__setCalltipsHook(editor)
144 if self.__newStyle: 119 editor.editorSaved.connect(
145 editor.editorSaved.connect( 120 self.__apisManager.getAPIs(ApisNameProject).editorSaved)
146 self.__apisManager.getAPIs(ApisNameProject).editorSaved)
147 else:
148 self.connect(editor, SIGNAL("editorSaved"),
149 self.__apisManager.getAPIs(ApisNameProject).editorSaved)
150 self.__editors.append(editor) 121 self.__editors.append(editor)
151 122
152 # preload the api to give the manager a chance to prepare the database 123 # preload the api to give the manager a chance to prepare the database
153 language = editor.getLanguage() 124 language = editor.getLanguage()
154 if language == "": 125 if language == "":
160 Private slot called, when an editor was closed. 131 Private slot called, when an editor was closed.
161 132
162 @param editor reference to the editor (QScintilla.Editor) 133 @param editor reference to the editor (QScintilla.Editor)
163 """ 134 """
164 if editor in self.__editors: 135 if editor in self.__editors:
165 if self.__newStyle: 136 editor.editorSaved.disconnect(
166 editor.editorSaved.disconnect( 137 self.__apisManager.getAPIs(ApisNameProject).editorSaved)
167 self.__apisManager.getAPIs(ApisNameProject).editorSaved)
168 else:
169 self.disconnect(editor, SIGNAL("editorSaved"),
170 self.__apisManager.getAPIs(ApisNameProject).editorSaved)
171 self.__editors.remove(editor) 138 self.__editors.remove(editor)
172 if editor.autoCompletionHook() == self.autocomplete: 139 if editor.autoCompletionHook() == self.autocomplete:
173 self.__unsetAutoCompletionHook(editor) 140 self.__unsetAutoCompletionHook(editor)
174 if editor.callTipHook() == self.calltips: 141 if editor.callTipHook() == self.calltips:
175 self.__unsetCalltipsHook(editor) 142 self.__unsetCalltipsHook(editor)
201 return "", pos 168 return "", pos
202 169
203 return ch, pos 170 return ch, pos
204 171
205 ################################# 172 #################################
206 ## autocompletion methods below 173 ## autocompletion methods below
207 ################################# 174 #################################
208 175
209 def __completionListSelected(self, id, txt): 176 def __completionListSelected(self, id, txt):
210 """ 177 """
211 Private slot to handle the selection from the completion list. 178 Private slot to handle the selection from the completion list.
244 """ 211 """
245 Private method to set the autocompletion hook. 212 Private method to set the autocompletion hook.
246 213
247 @param editor reference to the editor (QScintilla.Editor) 214 @param editor reference to the editor (QScintilla.Editor)
248 """ 215 """
249 if self.__newStyle: 216 editor.userListActivated.connect(self.__completionListSelected)
250 editor.userListActivated.connect(self.__completionListSelected)
251 else:
252 self.connect(editor, SIGNAL('userListActivated(int, const QString)'),
253 self.__completionListSelected)
254 editor.setAutoCompletionHook(self.autocomplete) 217 editor.setAutoCompletionHook(self.autocomplete)
255 218
256 def __unsetAutoCompletionHook(self, editor): 219 def __unsetAutoCompletionHook(self, editor):
257 """ 220 """
258 Private method to unset the autocompletion hook. 221 Private method to unset the autocompletion hook.
259 222
260 @param editor reference to the editor (QScintilla.Editor) 223 @param editor reference to the editor (QScintilla.Editor)
261 """ 224 """
262 editor.unsetAutoCompletionHook() 225 editor.unsetAutoCompletionHook()
263 if self.__newStyle: 226 editor.userListActivated.disconnect(self.__completionListSelected)
264 editor.userListActivated.disconnect(self.__completionListSelected)
265 else:
266 self.disconnect(editor, SIGNAL('userListActivated(int, const QString)'),
267 self.__completionListSelected)
268 227
269 def autocomplete(self, editor, context): 228 def autocomplete(self, editor, context):
270 """ 229 """
271 Public method to determine the autocompletion proposals. 230 Public method to determine the autocompletion proposals.
272 231
305 (wc and text[col - 1] not in wc)): 264 (wc and text[col - 1] not in wc)):
306 ch = text[col - 1] 265 ch = text[col - 1]
307 if ch == ')': 266 if ch == ')':
308 depth = 1 267 depth = 1
309 268
310 # ignore everything back to the start of the 269 # ignore everything back to the start of the
311 # corresponding parenthesis 270 # corresponding parenthesis
312 col -= 1 271 col -= 1
313 while col > 0: 272 while col > 0:
314 ch = text[col - 1] 273 ch = text[col - 1]
315 if ch == ')': 274 if ch == ')':
362 @return list of possible completions (list of strings) 321 @return list of possible completions (list of strings)
363 """ 322 """
364 completionsList = [] 323 completionsList = []
365 if api is not None: 324 if api is not None:
366 if context: 325 if context:
367 completions = api.getCompletions(context = word) 326 completions = api.getCompletions(context=word)
368 for completion in completions: 327 for completion in completions:
369 entry = completion["completion"] 328 entry = completion["completion"]
370 if completion["pictureId"]: 329 if completion["pictureId"]:
371 entry += "?{0}".format(completion["pictureId"]) 330 entry += "?{0}".format(completion["pictureId"])
372 if entry not in completionsList: 331 if entry not in completionsList:
373 completionsList.append(entry) 332 completionsList.append(entry)
374 else: 333 else:
375 completions = api.getCompletions(start = word) 334 completions = api.getCompletions(start=word)
376 for completion in completions: 335 for completion in completions:
377 if not completion["context"]: 336 if not completion["context"]:
378 entry = completion["completion"] 337 entry = completion["completion"]
379 else: 338 else:
380 entry = "{0} ({1})".format( 339 entry = "{0} ({1})".format(
381 completion["completion"], 340 completion["completion"],
382 completion["context"] 341 completion["context"]
383 ) 342 )
384 if entry in completionsList: 343 if entry in completionsList:
385 completionsList.remove(entry) 344 completionsList.remove(entry)
386 if completion["pictureId"]: 345 if completion["pictureId"]:
415 374
416 if editor.isUtf8(): 375 if editor.isUtf8():
417 sword = word.encode("utf-8") 376 sword = word.encode("utf-8")
418 else: 377 else:
419 sword = word 378 sword = word
420 res = editor.findFirstTarget(sword, False, 379 res = editor.findFirstTarget(sword, False,
421 editor.autoCompletionCaseSensitivity(), 380 editor.autoCompletionCaseSensitivity(),
422 False, begline = 0, begindex = 0, ws_ = True) 381 False, begline=0, begindex=0, ws_=True)
423 while res: 382 while res:
424 start, length = editor.getFoundTarget() 383 start, length = editor.getFoundTarget()
425 pos = start + length 384 pos = start + length
426 if pos != currentPos: 385 if pos != currentPos:
427 if context: 386 if context:
428 completion = "" 387 completion = ""
429 else: 388 else:
430 completion = word 389 completion = word
431 line, index = editor.lineIndexFromPosition(pos) 390 line, index = editor.lineIndexFromPosition(pos)
432 curWord = editor.getWord(line, index, useWordChars = False) 391 curWord = editor.getWord(line, index, useWordChars=False)
433 completion += curWord[len(completion):] 392 completion += curWord[len(completion):]
434 if completion and completion not in completionsList: 393 if completion and completion not in completionsList:
435 completionsList.append( 394 completionsList.append(
436 "{0}?{1}".format(completion, self.__fromDocumentID)) 395 "{0}?{1}".format(completion, self.__fromDocumentID))
437 396
439 398
440 completionsList.sort() 399 completionsList.sort()
441 return completionsList 400 return completionsList
442 401
443 ########################### 402 ###########################
444 ## calltips methods below 403 ## calltips methods below
445 ########################### 404 ###########################
446 405
447 def __setCalltipsHook(self, editor): 406 def __setCalltipsHook(self, editor):
448 """ 407 """
449 Private method to set the calltip hook. 408 Private method to set the calltip hook.
486 projectCalltips = [] 445 projectCalltips = []
487 446
488 if self.__plugin.getPreferences("AutoCompletionSource") & AcsAPIs: 447 if self.__plugin.getPreferences("AutoCompletionSource") & AcsAPIs:
489 api = self.__apisManager.getAPIs(language) 448 api = self.__apisManager.getAPIs(language)
490 if api is not None: 449 if api is not None:
491 apiCalltips = api.getCalltips(word, commas, self.__lastContext, 450 apiCalltips = api.getCalltips(word, commas, self.__lastContext,
492 self.__lastFullContext, 451 self.__lastFullContext,
493 self.__plugin.getPreferences("CallTipsContextShown")) 452 self.__plugin.getPreferences("CallTipsContextShown"))
494 453
495 if self.__plugin.getPreferences("AutoCompletionSource") & AcsProject: 454 if self.__plugin.getPreferences("AutoCompletionSource") & AcsProject:
496 api = self.__apisManager.getAPIs(ApisNameProject) 455 api = self.__apisManager.getAPIs(ApisNameProject)
497 projectCalltips = api.getCalltips(word, commas, self.__lastContext, 456 projectCalltips = api.getCalltips(word, commas, self.__lastContext,
498 self.__lastFullContext, 457 self.__lastFullContext,
499 self.__plugin.getPreferences("CallTipsContextShown")) 458 self.__plugin.getPreferences("CallTipsContextShown"))
500 459
501 return sorted(set(apiCalltips).union(set(projectCalltips))) 460 return sorted(set(apiCalltips).union(set(projectCalltips)))

eric ide

mercurial