QScintilla/Editor.py

changeset 88
3701923bccf2
parent 68
f1e3dff6dda1
child 92
30ffedc3e418
equal deleted inserted replaced
87:4cc5c8d1184d 88:3701923bccf2
34 34
35 from .Printer import Printer 35 from .Printer import Printer
36 36
37 import Preferences 37 import Preferences
38 import Utilities 38 import Utilities
39 from Utilities.py3flakes.checker import Checker
40 from Utilities.py3flakes.messages import ImportStarUsed
39 41
40 import UI.PixmapCache 42 import UI.PixmapCache
41 43
42 EditorAutoCompletionListID = 1 44 EditorAutoCompletionListID = 1
43 TemplateCompletionListID = 2 45 TemplateCompletionListID = 2
130 # enabled, ignorecount) 132 # enabled, ignorecount)
131 self.bookmarks = [] # bookmarks are just a list of handles to the 133 self.bookmarks = [] # bookmarks are just a list of handles to the
132 # bookmark markers 134 # bookmark markers
133 self.syntaxerrors = {} # key: marker handle 135 self.syntaxerrors = {} # key: marker handle
134 # value: error message 136 # value: error message
137 self.warnings = {} # key: marker handle
138 # value: warning message
135 self.notcoveredMarkers = [] # just a list of marker handles 139 self.notcoveredMarkers = [] # just a list of marker handles
136 140
137 self.condHistory = [] 141 self.condHistory = []
138 self.lexer_ = None 142 self.lexer_ = None
139 self.__lexerReset = False 143 self.__lexerReset = False
906 self.__showSyntaxError) 910 self.__showSyntaxError)
907 self.marginMenuActs["ClearSyntaxError"] = \ 911 self.marginMenuActs["ClearSyntaxError"] = \
908 self.indicMarginMenu.addAction(self.trUtf8('Clear syntax error'), 912 self.indicMarginMenu.addAction(self.trUtf8('Clear syntax error'),
909 self.clearSyntaxError) 913 self.clearSyntaxError)
910 self.indicMarginMenu.addSeparator() 914 self.indicMarginMenu.addSeparator()
915 self.marginMenuActs["NextWarningMarker"] = \
916 self.indicMarginMenu.addAction(self.trUtf8("Next warning"),
917 self.nextFlakesWarning)
918 self.marginMenuActs["PreviousWarningMarker"] = \
919 self.indicMarginMenu.addAction(self.trUtf8("Previous warning"),
920 self.previousFlakesWarning)
921 self.marginMenuActs["ShowWarning"] = \
922 self.indicMarginMenu.addAction(self.trUtf8('Show warning message'),
923 self.__showFlakesWarning)
924 self.marginMenuActs["ClearWarnings"] = \
925 self.indicMarginMenu.addAction(self.trUtf8('Clear warnings'),
926 self.clearFlakesWarnings)
927 self.indicMarginMenu.addSeparator()
911 self.marginMenuActs["NextCoverageMarker"] = \ 928 self.marginMenuActs["NextCoverageMarker"] = \
912 self.indicMarginMenu.addAction(self.trUtf8('Next uncovered line'), 929 self.indicMarginMenu.addAction(self.trUtf8('Next uncovered line'),
913 self.nextUncovered) 930 self.nextUncovered)
914 self.marginMenuActs["PreviousCoverageMarker"] = \ 931 self.marginMenuActs["PreviousCoverageMarker"] = \
915 self.indicMarginMenu.addAction(self.trUtf8('Previous uncovered line'), 932 self.indicMarginMenu.addAction(self.trUtf8('Previous uncovered line'),
950 self.marginMenu.addAction(self.trUtf8('Show syntax error message'), 967 self.marginMenu.addAction(self.trUtf8('Show syntax error message'),
951 self.__showSyntaxError) 968 self.__showSyntaxError)
952 self.marginMenuActs["ClearSyntaxError"] = \ 969 self.marginMenuActs["ClearSyntaxError"] = \
953 self.marginMenu.addAction(self.trUtf8('Clear syntax error'), 970 self.marginMenu.addAction(self.trUtf8('Clear syntax error'),
954 self.clearSyntaxError) 971 self.clearSyntaxError)
972 self.marginMenu.addSeparator()
973 self.marginMenuActs["NextWarningMarker"] = \
974 self.marginMenu.addAction(self.trUtf8("Next warning"),
975 self.nextFlakesWarning)
976 self.marginMenuActs["PreviousWarningMarker"] = \
977 self.marginMenu.addAction(self.trUtf8("Previous warning"),
978 self.previousFlakesWarning)
979 self.marginMenuActs["ShowWarning"] = \
980 self.marginMenu.addAction(self.trUtf8('Show warning message'),
981 self.__showFlakesWarning)
982 self.marginMenuActs["ClearWarnings"] = \
983 self.marginMenu.addAction(self.trUtf8('Clear warnings'),
984 self.clearFlakesWarnings)
955 self.marginMenu.addSeparator() 985 self.marginMenu.addSeparator()
956 self.marginMenuActs["Breakpoint"] = \ 986 self.marginMenuActs["Breakpoint"] = \
957 self.marginMenu.addAction(self.trUtf8('Toggle breakpoint'), 987 self.marginMenu.addAction(self.trUtf8('Toggle breakpoint'),
958 self.menuToggleBreakpoint) 988 self.menuToggleBreakpoint)
959 self.marginMenuActs["TempBreakpoint"] = \ 989 self.marginMenuActs["TempBreakpoint"] = \
2463 else: 2493 else:
2464 self.__toggleBreakpoint(line + 1) 2494 self.__toggleBreakpoint(line + 1)
2465 elif modifiers & Qt.KeyboardModifiers(Qt.ControlModifier): 2495 elif modifiers & Qt.KeyboardModifiers(Qt.ControlModifier):
2466 if self.markersAtLine(line) & (1 << self.syntaxerror): 2496 if self.markersAtLine(line) & (1 << self.syntaxerror):
2467 self.__showSyntaxError(line) 2497 self.__showSyntaxError(line)
2498 elif self.markersAtLine(line) & (1 << self.warning):
2499 self.__showFlakesWarning(line)
2468 else: 2500 else:
2469 if self.marginMenuActs["LMBbreakpoints"].isChecked(): 2501 if self.marginMenuActs["LMBbreakpoints"].isChecked():
2470 self.__toggleBreakpoint(line + 1) 2502 self.__toggleBreakpoint(line + 1)
2471 else: 2503 else:
2472 self.toggleBookmark(line + 1) 2504 self.toggleBookmark(line + 1)
2476 elif margin == self.__bpMargin: 2508 elif margin == self.__bpMargin:
2477 self.__toggleBreakpoint(line + 1) 2509 self.__toggleBreakpoint(line + 1)
2478 elif margin == self.__indicMargin: 2510 elif margin == self.__indicMargin:
2479 if self.markersAtLine(line) & (1 << self.syntaxerror): 2511 if self.markersAtLine(line) & (1 << self.syntaxerror):
2480 self.__showSyntaxError(line) 2512 self.__showSyntaxError(line)
2513 elif self.markersAtLine(line) & (1 << self.warning):
2514 self.__showFlakesWarning(line)
2481 2515
2482 def handleMonospacedEnable(self): 2516 def handleMonospacedEnable(self):
2483 """ 2517 """
2484 Private slot to handle the Use Monospaced Font context menu entry. 2518 Private slot to handle the Use Monospaced Font context menu entry.
2485 """ 2519 """
3891 else: 3925 else:
3892 self.marginMenuActs["GotoSyntaxError"].setEnabled(False) 3926 self.marginMenuActs["GotoSyntaxError"].setEnabled(False)
3893 self.marginMenuActs["ClearSyntaxError"].setEnabled(False) 3927 self.marginMenuActs["ClearSyntaxError"].setEnabled(False)
3894 self.marginMenuActs["ShowSyntaxError"].setEnabled(False) 3928 self.marginMenuActs["ShowSyntaxError"].setEnabled(False)
3895 3929
3930 if len(self.warnings):
3931 self.marginMenuActs["NextWarningMarker"].setEnabled(True)
3932 self.marginMenuActs["PreviousWarningMarker"].setEnabled(True)
3933 self.marginMenuActs["ClearWarnings"].setEnabled(True)
3934 if self.markersAtLine(self.line) & (1 << self.warning):
3935 self.marginMenuActs["ShowWarning"].setEnabled(True)
3936 else:
3937 self.marginMenuActs["ShowWarning"].setEnabled(False)
3938 else:
3939 self.marginMenuActs["NextWarningMarker"].setEnabled(False)
3940 self.marginMenuActs["PreviousWarningMarker"].setEnabled(True)
3941 self.marginMenuActs["ClearWarnings"].setEnabled(False)
3942 self.marginMenuActs["ShowWarning"].setEnabled(False)
3943
3896 if self.notcoveredMarkers: 3944 if self.notcoveredMarkers:
3897 self.marginMenuActs["NextCoverageMarker"].setEnabled(True) 3945 self.marginMenuActs["NextCoverageMarker"].setEnabled(True)
3898 self.marginMenuActs["PreviousCoverageMarker"].setEnabled(True) 3946 self.marginMenuActs["PreviousCoverageMarker"].setEnabled(True)
3899 else: 3947 else:
3900 self.marginMenuActs["NextCoverageMarker"].setEnabled(False) 3948 self.marginMenuActs["NextCoverageMarker"].setEnabled(False)
3998 """ 4046 """
3999 Private method to perform an automatic syntax check of the file. 4047 Private method to perform an automatic syntax check of the file.
4000 """ 4048 """
4001 if Preferences.getEditor("AutoCheckSyntax"): 4049 if Preferences.getEditor("AutoCheckSyntax"):
4002 self.clearSyntaxError() 4050 self.clearSyntaxError()
4051 self.clearFlakesWarnings()
4003 if self.isPy3File(): 4052 if self.isPy3File():
4004 syntaxError, _fn, errorline, _code, _error = \ 4053 syntaxError, _fn, errorline, _code, _error = \
4005 Utilities.compile(self.fileName, self.text()) 4054 Utilities.compile(self.fileName, self.text())
4006 if syntaxError: 4055 if syntaxError:
4007 self.toggleSyntaxError(int(errorline), 1, _error) 4056 self.toggleSyntaxError(int(errorline), True, _error)
4057 else:
4058 if Preferences.getFlakes("IncludeInSyntaxCheck"):
4059 ignoreStarImportWarnings = \
4060 Preferences.getFlakes("IgnoreStarImportWarnings")
4061 warnings = Checker(self.text(), self.fileName)
4062 warnings.messages.sort(key = lambda a: a.lineno)
4063 for warning in warnings.messages:
4064 if ignoreStarImportWarnings and \
4065 isinstance(warning, ImportStarUsed):
4066 continue
4067
4068 _fn, lineno, message = warning.getMessageData()
4069 self.toggleFlakesWarning(lineno, True, message)
4008 4070
4009 def __showCodeMetrics(self): 4071 def __showCodeMetrics(self):
4010 """ 4072 """
4011 Private method to handle the code metrics context menu action. 4073 Private method to handle the code metrics context menu action.
4012 """ 4074 """
4272 selist.sort() 4334 selist.sort()
4273 return selist 4335 return selist
4274 4336
4275 def hasSyntaxErrors(self): 4337 def hasSyntaxErrors(self):
4276 """ 4338 """
4277 Public method to check for the presence of bookmarks. 4339 Public method to check for the presence of syntax errors.
4278 4340
4279 @return flag indicating the presence of bookmarks (boolean) 4341 @return flag indicating the presence of syntax errors (boolean)
4280 """ 4342 """
4281 return len(self.syntaxerrors) > 0 4343 return len(self.syntaxerrors) > 0
4282 4344
4283 def gotoSyntaxError(self): 4345 def gotoSyntaxError(self):
4284 """ 4346 """
4314 break 4376 break
4315 else: 4377 else:
4316 QMessageBox.critical(None, 4378 QMessageBox.critical(None,
4317 self.trUtf8("Syntax Error"), 4379 self.trUtf8("Syntax Error"),
4318 self.trUtf8("No syntax error message available.")) 4380 self.trUtf8("No syntax error message available."))
4381
4382 ############################################################################
4383 ## Flakes warning handling methods below
4384 ############################################################################
4385
4386 def toggleFlakesWarning(self, line, warning, msg = ""):
4387 """
4388 Public method to toggle a flakes warning indicator.
4389
4390 @param line line number of the flakes warning
4391 @param erwarningror flag indicating if the warning marker should be
4392 set or deleted (boolean)
4393 @param msg warning message (string)
4394 """
4395 if line == 0:
4396 line = 1
4397 # hack to show a warning marker, if line is reported to be 0
4398 if warning:
4399 # set a new warning marker
4400 markers = self.markersAtLine(line - 1)
4401 if not (markers & (1 << self.warning)):
4402 handle = self.markerAdd(line - 1, self.warning)
4403 self.warnings[handle] = msg
4404 self.emit(SIGNAL('syntaxerrorToggled'), self)
4405 else:
4406 for handle in list(self.warnings.keys()):
4407 if self.markerLine(handle) == line - 1:
4408 del self.warnings[handle]
4409 self.markerDeleteHandle(handle)
4410 self.emit(SIGNAL('syntaxerrorToggled'), self)
4411
4412 def getFlakesWarnings(self):
4413 """
4414 Public method to retrieve the flakes warning markers.
4415
4416 @return sorted list of all lines containing a flakes warning
4417 (list of integer)
4418 """
4419 fwlist = []
4420 for handle in list(self.warnings.keys()):
4421 fwlist.append(self.markerLine(handle) + 1)
4422
4423 fwlist.sort()
4424 return fwlist
4425
4426 def hasFlakesWarnings(self):
4427 """
4428 Public method to check for the presence of flakes warnings.
4429
4430 @return flag indicating the presence of flakes warnings (boolean)
4431 """
4432 return len(self.warnings) > 0
4433
4434 def nextFlakesWarning(self):
4435 """
4436 Public slot to handle the 'Next warning' context menu action.
4437 """
4438 line, index = self.getCursorPosition()
4439 if line == self.lines() - 1:
4440 line = 0
4441 else:
4442 line += 1
4443 fwline = self.markerFindNext(line, 1 << self.warning)
4444 if fwline < 0:
4445 # wrap around
4446 fwline = self.markerFindNext(0, 1 << self.warning)
4447 if fwline >= 0:
4448 self.setCursorPosition(fwline, 0)
4449 self.ensureLineVisible(fwline)
4450
4451 def previousFlakesWarning(self):
4452 """
4453 Public slot to handle the 'Previous warning' context menu action.
4454 """
4455 line, index = self.getCursorPosition()
4456 if line == 0:
4457 line = self.lines() - 1
4458 else:
4459 line -= 1
4460 fwline = self.markerFindPrevious(line, 1 << self.warning)
4461 if fwline < 0:
4462 # wrap around
4463 fwline = self.markerFindPrevious(self.lines() - 1, 1 << self.warning)
4464 if fwline >= 0:
4465 self.setCursorPosition(fwline, 0)
4466 self.ensureLineVisible(fwline)
4467
4468 def clearFlakesWarnings(self):
4469 """
4470 Public slot to handle the 'Clear all warnings' context menu action.
4471 """
4472 for handle in self.warnings:
4473 self.markerDeleteHandle(handle)
4474 self.warnings = {}
4475 self.emit(SIGNAL('syntaxerrorToggled'), self)
4476
4477 def __showFlakesWarning(self, line = -1):
4478 """
4479 Private slot to handle the 'Show warning' context menu action.
4480
4481 @param line line number to show the flakes warning for (integer)
4482 """
4483 if line == -1:
4484 line = self.line
4485
4486 for handle in list(self.warnings.keys()):
4487 if self.markerLine(handle) == line:
4488 QMessageBox.warning(None,
4489 self.trUtf8("py3flakes Warning"),
4490 self.warnings[handle])
4491 break
4492 else:
4493 QMessageBox.warning(None,
4494 self.trUtf8("py3flakes Warning"),
4495 self.trUtf8("No py3flakes warning message available."))
4319 4496
4320 ################################################################# 4497 #################################################################
4321 ## Macro handling methods 4498 ## Macro handling methods
4322 ################################################################# 4499 #################################################################
4323 4500
4696 self.clearBookmarks() 4873 self.clearBookmarks()
4697 4874
4698 # clear syntax error markers 4875 # clear syntax error markers
4699 self.clearSyntaxError() 4876 self.clearSyntaxError()
4700 4877
4878 # clear flakes warning markers
4879 self.clearFlakesWarnings()
4880
4701 # clear breakpoint markers 4881 # clear breakpoint markers
4702 for handle in list(self.breaks.keys()): 4882 for handle in list(self.breaks.keys()):
4703 self.markerDeleteHandle(handle) 4883 self.markerDeleteHandle(handle)
4704 self.breaks = {} 4884 self.breaks = {}
4705 4885

eric ide

mercurial