eric6/QScintilla/TypingCompleters/CompleterPython.py

changeset 7775
4a1db75550bd
parent 7360
9190402e4505
child 7811
31d56b9bc7bd
equal deleted inserted replaced
7774:9eed155411f0 7775:4a1db75550bd
5 5
6 """ 6 """
7 Module implementing a typing completer for Python. 7 Module implementing a typing completer for Python.
8 """ 8 """
9 9
10
11 import re 10 import re
12 11
13 from PyQt5.QtCore import QRegExp
14 from PyQt5.Qsci import QsciLexerPython, QsciScintilla 12 from PyQt5.Qsci import QsciLexerPython, QsciScintilla
15 13
16 from .CompleterBase import CompleterBase 14 from .CompleterBase import CompleterBase
17 15
18 import Preferences 16 import Preferences
17 from Utilities import rxIndex
19 18
20 19
21 class CompleterPython(CompleterBase): 20 class CompleterPython(CompleterBase):
22 """ 21 """
23 Class implementing typing completer for Python. 22 Class implementing typing completer for Python.
29 @param editor reference to the editor object (QScintilla.Editor) 28 @param editor reference to the editor object (QScintilla.Editor)
30 @param parent reference to the parent object (QObject) 29 @param parent reference to the parent object (QObject)
31 """ 30 """
32 super(CompleterPython, self).__init__(editor, parent) 31 super(CompleterPython, self).__init__(editor, parent)
33 32
34 self.__defRX = QRegExp(r"""^[ \t]*def \w+\(""") 33 self.__defRX = re.compile(r"^[ \t]*def \w+\(")
35 self.__defSelfRX = QRegExp(r"""^[ \t]*def \w+\([ \t]*self[ \t]*[,)]""") 34 self.__defSelfRX = re.compile(r"^[ \t]*def \w+\([ \t]*self[ \t]*[,)]")
36 self.__defClsRX = QRegExp(r"""^[ \t]*def \w+\([ \t]*cls[ \t]*[,)]""") 35 self.__defClsRX = re.compile(r"^[ \t]*def \w+\([ \t]*cls[ \t]*[,)]")
37 self.__classRX = QRegExp(r"""^[ \t]*class \w+\(""") 36 self.__classRX = re.compile(r"^[ \t]*class \w+\(")
38 self.__importRX = QRegExp(r"""^[ \t]*from [\w.]+ """) 37 self.__importRX = re.compile(r"^[ \t]*from [\w.]+ ")
39 self.__classmethodRX = QRegExp(r"""^[ \t]*@classmethod""") 38 self.__classmethodRX = re.compile(r"^[ \t]*@classmethod")
40 self.__staticmethodRX = QRegExp(r"""^[ \t]*@staticmethod""") 39 self.__staticmethodRX = re.compile(r"^[ \t]*@staticmethod")
41 40
42 self.__defOnlyRX = QRegExp(r"""^[ \t]*def """) 41 self.__defOnlyRX = re.compile(r"^[ \t]*def ")
43 42
44 self.__ifRX = QRegExp(r"""^[ \t]*if """) 43 self.__ifRX = re.compile(r"^[ \t]*if ")
45 self.__elifRX = QRegExp(r"""^[ \t]*elif """) 44 self.__elifRX = re.compile(r"^[ \t]*elif ")
46 self.__elseRX = QRegExp(r"""^[ \t]*else:""") 45 self.__elseRX = re.compile(r"^[ \t]*else:")
47 46
48 self.__tryRX = QRegExp(r"""^[ \t]*try:""") 47 self.__tryRX = re.compile(r"^[ \t]*try:")
49 self.__finallyRX = QRegExp(r"""^[ \t]*finally:""") 48 self.__finallyRX = re.compile(r"^[ \t]*finally:")
50 self.__exceptRX = QRegExp(r"""^[ \t]*except """) 49 self.__exceptRX = re.compile(r"^[ \t]*except ")
51 self.__exceptcRX = QRegExp(r"""^[ \t]*except:""") 50 self.__exceptcRX = re.compile(r"^[ \t]*except:")
52 51
53 self.__whileRX = QRegExp(r"""^[ \t]*while """) 52 self.__whileRX = re.compile(r"^[ \t]*while ")
54 self.__forRX = QRegExp(r"""^[ \t]*for """) 53 self.__forRX = re.compile(r"^[ \t]*for ")
55 54
56 self.readSettings() 55 self.readSettings()
57 56
58 def readSettings(self): 57 def readSettings(self):
59 """ 58 """
112 # insert closing parenthesis and self 111 # insert closing parenthesis and self
113 if char == '(': 112 if char == '(':
114 txt = self.editor.text(line)[:col] 113 txt = self.editor.text(line)[:col]
115 if ( 114 if (
116 self.__insertSelf and 115 self.__insertSelf and
117 self.__defRX.exactMatch(txt) 116 self.__defRX.fullmatch(txt) is not None
118 ): 117 ):
119 if self.__isClassMethodDef(): 118 if self.__isClassMethodDef():
120 self.editor.insert('cls') 119 self.editor.insert('cls')
121 self.editor.setCursorPosition(line, col + 3) 120 self.editor.setCursorPosition(line, col + 3)
122 elif self.__isStaticMethodDef(): 121 elif self.__isStaticMethodDef():
125 elif self.__isClassMethod(): 124 elif self.__isClassMethod():
126 self.editor.insert('self') 125 self.editor.insert('self')
127 self.editor.setCursorPosition(line, col + 4) 126 self.editor.setCursorPosition(line, col + 4)
128 if self.__insertClosingBrace: 127 if self.__insertClosingBrace:
129 if ( 128 if (
130 self.__defRX.exactMatch(txt) or 129 self.__defRX.fullmatch(txt) is not None or
131 self.__classRX.exactMatch(txt) 130 self.__classRX.fullmatch(txt) is not None
132 ): 131 ):
133 self.editor.insert('):') 132 self.editor.insert('):')
134 else: 133 else:
135 self.editor.insert(')') 134 self.editor.insert(')')
136 135
146 # space 145 # space
147 # insert import, dedent to if for elif, dedent to try for except, 146 # insert import, dedent to if for elif, dedent to try for except,
148 # dedent def 147 # dedent def
149 elif char == ' ': 148 elif char == ' ':
150 txt = self.editor.text(line)[:col] 149 txt = self.editor.text(line)[:col]
151 if self.__insertImport and self.__importRX.exactMatch(txt): 150 if self.__insertImport and self.__importRX.fullmatch(txt):
152 if self.__importBraceType: 151 if self.__importBraceType:
153 self.editor.insert('import ()') 152 self.editor.insert('import ()')
154 self.editor.setCursorPosition(line, col + 8) 153 self.editor.setCursorPosition(line, col + 8)
155 else: 154 else:
156 self.editor.insert('import ') 155 self.editor.insert('import ')
157 self.editor.setCursorPosition(line, col + 7) 156 self.editor.setCursorPosition(line, col + 7)
158 elif self.__dedentElse and self.__elifRX.exactMatch(txt): 157 elif self.__dedentElse and self.__elifRX.fullmatch(txt):
159 self.__dedentToIf() 158 self.__dedentToIf()
160 elif self.__dedentExcept and self.__exceptRX.exactMatch(txt): 159 elif self.__dedentExcept and self.__exceptRX.fullmatch(txt):
161 self.__dedentExceptToTry(False) 160 self.__dedentExceptToTry(False)
162 elif self.__dedentDef and self.__defOnlyRX.exactMatch(txt): 161 elif self.__dedentDef and self.__defOnlyRX.fullmatch(txt):
163 self.__dedentDefStatement() 162 self.__dedentDefStatement()
164 163
165 # comma 164 # comma
166 # insert blank 165 # insert blank
167 elif char == ',': 166 elif char == ',':
201 if self.__colonDetection: 200 if self.__colonDetection:
202 self.editor.setSelection(line, col, line, col + 1) 201 self.editor.setSelection(line, col, line, col + 1)
203 self.editor.removeSelectedText() 202 self.editor.removeSelectedText()
204 else: 203 else:
205 txt = text[:col] 204 txt = text[:col]
206 if self.__dedentElse and self.__elseRX.exactMatch(txt): 205 if self.__dedentElse and self.__elseRX.fullmatch(txt):
207 self.__dedentElseToIfWhileForTry() 206 self.__dedentElseToIfWhileForTry()
208 elif self.__dedentExcept and self.__exceptcRX.exactMatch(txt): 207 elif self.__dedentExcept and self.__exceptcRX.fullmatch(txt):
209 self.__dedentExceptToTry(True) 208 self.__dedentExceptToTry(True)
210 elif self.__dedentExcept and self.__finallyRX.exactMatch(txt): 209 elif self.__dedentExcept and self.__finallyRX.fullmatch(txt):
211 self.__dedentFinallyToTry() 210 self.__dedentFinallyToTry()
212 211
213 # new line 212 # new line
214 # indent to opening brace 213 # indent to opening brace
215 elif char == '\n': 214 elif char == '\n':
251 indentation = self.editor.indentation(line) 250 indentation = self.editor.indentation(line)
252 ifLine = line - 1 251 ifLine = line - 1
253 while ifLine >= 0: 252 while ifLine >= 0:
254 txt = self.editor.text(ifLine) 253 txt = self.editor.text(ifLine)
255 edInd = self.editor.indentation(ifLine) 254 edInd = self.editor.indentation(ifLine)
256 if self.__elseRX.indexIn(txt) == 0 and edInd <= indentation: 255 if rxIndex(self.__elseRX, txt) == 0 and edInd <= indentation:
257 indentation = edInd - 1 256 indentation = edInd - 1
258 elif (self.__ifRX.indexIn(txt) == 0 or 257 elif (rxIndex(self.__ifRX, txt) == 0 or
259 self.__elifRX.indexIn(txt) == 0) and edInd <= indentation: 258 rxIndex(self.__elifRX, txt) == 0) and edInd <= indentation:
260 self.editor.cancelList() 259 self.editor.cancelList()
261 self.editor.setIndentation(line, edInd) 260 self.editor.setIndentation(line, edInd)
262 break 261 break
263 ifLine -= 1 262 ifLine -= 1
264 263
273 prevInd = self.editor.indentation(line - 1) 272 prevInd = self.editor.indentation(line - 1)
274 ifLine = line - 1 273 ifLine = line - 1
275 while ifLine >= 0: 274 while ifLine >= 0:
276 txt = self.editor.text(ifLine) 275 txt = self.editor.text(ifLine)
277 edInd = self.editor.indentation(ifLine) 276 edInd = self.editor.indentation(ifLine)
278 if self.__elseRX.indexIn(txt) == 0 and edInd <= indentation: 277 if rxIndex(self.__elseRX, txt) == 0 and edInd <= indentation:
279 indentation = edInd - 1 278 indentation = edInd - 1
280 elif ( 279 elif (
281 self.__elifRX.indexIn(txt) == 0 and 280 rxIndex(self.__elifRX, txt) == 0 and
282 edInd == indentation and 281 edInd == indentation and
283 edInd == prevInd 282 edInd == prevInd
284 ): 283 ):
285 indentation = edInd - 1 284 indentation = edInd - 1
286 elif ( 285 elif (
287 (self.__ifRX.indexIn(txt) == 0 or 286 (rxIndex(self.__ifRX, txt) == 0 or
288 self.__whileRX.indexIn(txt) == 0 or 287 rxIndex(self.__whileRX, txt) == 0 or
289 self.__forRX.indexIn(txt) == 0 or 288 rxIndex(self.__forRX, txt) == 0 or
290 self.__tryRX.indexIn(txt) == 0) and 289 rxIndex(self.__tryRX, txt) == 0) and
291 edInd <= indentation 290 edInd <= indentation
292 ): 291 ):
293 self.editor.cancelList() 292 self.editor.cancelList()
294 self.editor.setIndentation(line, edInd) 293 self.editor.setIndentation(line, edInd)
295 break 294 break
307 tryLine = line - 1 306 tryLine = line - 1
308 while tryLine >= 0: 307 while tryLine >= 0:
309 txt = self.editor.text(tryLine) 308 txt = self.editor.text(tryLine)
310 edInd = self.editor.indentation(tryLine) 309 edInd = self.editor.indentation(tryLine)
311 if ( 310 if (
312 (self.__exceptcRX.indexIn(txt) == 0 or 311 (rxIndex(self.__exceptcRX, txt) == 0 or
313 self.__finallyRX.indexIn(txt) == 0) and 312 rxIndex(self.__finallyRX, txt) == 0) and
314 edInd <= indentation 313 edInd <= indentation
315 ): 314 ):
316 indentation = edInd - 1 315 indentation = edInd - 1
317 elif (self.__exceptRX.indexIn(txt) == 0 or 316 elif (rxIndex(self.__exceptRX, txt) == 0 or
318 self.__tryRX.indexIn(txt) == 0) and edInd <= indentation: 317 rxIndex(self.__tryRX, txt) == 0) and edInd <= indentation:
319 self.editor.cancelList() 318 self.editor.cancelList()
320 self.editor.setIndentation(line, edInd) 319 self.editor.setIndentation(line, edInd)
321 break 320 break
322 tryLine -= 1 321 tryLine -= 1
323 322
330 indentation = self.editor.indentation(line) 329 indentation = self.editor.indentation(line)
331 tryLine = line - 1 330 tryLine = line - 1
332 while tryLine >= 0: 331 while tryLine >= 0:
333 txt = self.editor.text(tryLine) 332 txt = self.editor.text(tryLine)
334 edInd = self.editor.indentation(tryLine) 333 edInd = self.editor.indentation(tryLine)
335 if self.__finallyRX.indexIn(txt) == 0 and edInd <= indentation: 334 if rxIndex(self.__finallyRX, txt) == 0 and edInd <= indentation:
336 indentation = edInd - 1 335 indentation = edInd - 1
337 elif ( 336 elif (
338 (self.__tryRX.indexIn(txt) == 0 or 337 (rxIndex(self.__tryRX, txt) == 0 or
339 self.__exceptcRX.indexIn(txt) == 0 or 338 rxIndex(self.__exceptcRX, txt) == 0 or
340 self.__exceptRX.indexIn(txt) == 0) and 339 rxIndex(self.__exceptRX, txt) == 0) and
341 edInd <= indentation 340 edInd <= indentation
342 ): 341 ):
343 self.editor.cancelList() 342 self.editor.cancelList()
344 self.editor.setIndentation(line, edInd) 343 self.editor.setIndentation(line, edInd)
345 break 344 break
355 tryLine = line - 1 354 tryLine = line - 1
356 while tryLine >= 0: 355 while tryLine >= 0:
357 txt = self.editor.text(tryLine) 356 txt = self.editor.text(tryLine)
358 edInd = self.editor.indentation(tryLine) 357 edInd = self.editor.indentation(tryLine)
359 newInd = -1 358 newInd = -1
360 if self.__defRX.indexIn(txt) == 0 and edInd < indentation: 359 if rxIndex(self.__defRX, txt) == 0 and edInd < indentation:
361 newInd = edInd 360 newInd = edInd
362 elif self.__classRX.indexIn(txt) == 0 and edInd < indentation: 361 elif rxIndex(self.__classRX, txt) == 0 and edInd < indentation:
363 newInd = edInd + ( 362 newInd = edInd + (
364 self.editor.indentationWidth() or self.editor.tabWidth() 363 self.editor.indentationWidth() or self.editor.tabWidth()
365 ) 364 )
366 if newInd >= 0: 365 if newInd >= 0:
367 self.editor.cancelList() 366 self.editor.cancelList()
379 indentation = self.editor.indentation(line) 378 indentation = self.editor.indentation(line)
380 curLine = line - 1 379 curLine = line - 1
381 while curLine >= 0: 380 while curLine >= 0:
382 txt = self.editor.text(curLine) 381 txt = self.editor.text(curLine)
383 if ( 382 if (
384 (self.__defSelfRX.indexIn(txt) == 0 or 383 (rxIndex(self.__defSelfRX, txt) == 0 or
385 self.__defClsRX.indexIn(txt) == 0) and 384 rxIndex(self.__defClsRX, txt) == 0) and
386 self.editor.indentation(curLine) == indentation 385 self.editor.indentation(curLine) == indentation
387 ): 386 ):
388 return True 387 return True
389 elif ( 388 elif (
390 self.__classRX.indexIn(txt) == 0 and 389 rxIndex(self.__classRX, txt) == 0 and
391 self.editor.indentation(curLine) < indentation 390 self.editor.indentation(curLine) < indentation
392 ): 391 ):
393 return True 392 return True
394 elif ( 393 elif (
395 self.__defRX.indexIn(txt) == 0 and 394 rxIndex(self.__defRX, txt) == 0 and
396 self.editor.indentation(curLine) <= indentation 395 self.editor.indentation(curLine) <= indentation
397 ): 396 ):
398 return False 397 return False
399 curLine -= 1 398 curLine -= 1
400 return False 399 return False
408 """ 407 """
409 line, col = self.editor.getCursorPosition() 408 line, col = self.editor.getCursorPosition()
410 indentation = self.editor.indentation(line) 409 indentation = self.editor.indentation(line)
411 curLine = line - 1 410 curLine = line - 1
412 if ( 411 if (
413 self.__classmethodRX.indexIn(self.editor.text(curLine)) == 0 and 412 rxIndex(self.__classmethodRX, self.editor.text(curLine)) == 0 and
414 self.editor.indentation(curLine) == indentation 413 self.editor.indentation(curLine) == indentation
415 ): 414 ):
416 return True 415 return True
417 return False 416 return False
418 417
425 """ 424 """
426 line, col = self.editor.getCursorPosition() 425 line, col = self.editor.getCursorPosition()
427 indentation = self.editor.indentation(line) 426 indentation = self.editor.indentation(line)
428 curLine = line - 1 427 curLine = line - 1
429 if ( 428 if (
430 self.__staticmethodRX.indexIn(self.editor.text(curLine)) == 0 and 429 rxIndex(self.__staticmethodRX, self.editor.text(curLine)) == 0 and
431 self.editor.indentation(curLine) == indentation 430 self.editor.indentation(curLine) == indentation
432 ): 431 ):
433 return True 432 return True
434 return False 433 return False
435 434

eric ide

mercurial