diff -r 411df92e881f -r 3b34efa2857c src/eric7/QScintilla/Editor.py --- a/src/eric7/QScintilla/Editor.py Sun Dec 03 14:54:00 2023 +0100 +++ b/src/eric7/QScintilla/Editor.py Mon Jan 01 11:10:45 2024 +0100 @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2002 - 2023 Detlev Offenbach <detlev@die-offenbachs.de> +# Copyright (c) 2002 - 2024 Detlev Offenbach <detlev@die-offenbachs.de> # """ @@ -51,7 +51,7 @@ from eric7.EricWidgets import EricFileDialog, EricMessageBox from eric7.EricWidgets.EricApplication import ericApp from eric7.Globals import recentNameBreakpointConditions -from eric7.SystemUtilities import OSUtilities, PythonUtilities +from eric7.SystemUtilities import FileSystemUtilities, OSUtilities, PythonUtilities from eric7.UI import PythonDisViewer from eric7.Utilities import MouseUtilities @@ -146,12 +146,14 @@ settingsRead = pyqtSignal() mouseDoubleClick = pyqtSignal(QPoint, Qt.MouseButton) + # TODO: convert to an enum.Enum WarningCode = 1 WarningPython = 2 WarningStyle = 3 WarningInfo = 4 WarningError = 5 + # TODO: convert to an enum.IntEnum (also in Assistant plugin) # Autocompletion icon definitions ClassID = 1 ClassProtectedID = 2 @@ -418,7 +420,10 @@ if not Utilities.MimeTypes.isTextFile(self.fileName): raise OSError() - if self.isLocalFile() and pathlib.Path(self.fileName).exists(): + if ( + FileSystemUtilities.isPlainFileName(self.fileName) + and pathlib.Path(self.fileName).exists() + ): fileSizeKB = pathlib.Path(self.fileName).stat().st_size // 1024 if fileSizeKB > Preferences.getEditor("RejectFilesize"): EricMessageBox.warning( @@ -632,43 +637,19 @@ """ renamed = self.fileName != name + oldFileName = self.fileName self.fileName = name if renamed: self.vm.setEditorName(self, self.fileName) + self.vm.removeWatchedFilePath(oldFileName) + self.vm.addWatchedFilePath(self.fileName) if self.fileName: self.__fileNameExtension = os.path.splitext(self.fileName)[1][1:].lower() else: self.__fileNameExtension = "" - def isLocalFile(self): - """ - Public method to check, if the editor contains a local file. - - @return flag indicating a local file - @rtype bool - """ - return not self.fileName.startswith(("device:", "remote:")) - - def isDeviceFile(self): - """ - Public method to check, if the editor contains a MCU device file. - - @return flag indicating a MCU device file - @rtype bool - """ - return self.fileName.startswith("device:") - - def isRemoteFile(self): - """ - Public method to check, if the editor contains a remote file. - - @return flag indicating a remote file - @rtype bool - """ - return self.fileName.startswith("remote:") - def __registerImages(self): """ Private method to register images for autocompletion lists. @@ -767,8 +748,9 @@ Private method to generate a dummy filename for binding a lexer. @param line0 first line of text to use in the generation process - (string) - @return dummy file name to be used for binding a lexer (string) + @type str + @return dummy file name to be used for binding a lexer + @rtype str """ bindName = "" line0 = line0.lower() @@ -842,8 +824,10 @@ """ Public method to get a reference to the main context menu or a submenu. - @param menuName name of the menu (string) - @return reference to the requested menu (QMenu) or None + @param menuName name of the menu + @type str + @return reference to the requested menu or None + @rtype QMenu """ try: return self.__menus[menuName] @@ -854,7 +838,8 @@ """ Public method to check the miniMenu flag. - @return flag indicating a minimized context menu (boolean) + @return flag indicating a minimized context menu + @rtype bool """ return self.miniMenu @@ -1214,8 +1199,7 @@ self.supportedLanguages = {} supportedLanguages = Lexers.getSupportedLanguages() - languages = sorted(supportedLanguages.keys()) - for language in languages: + for language in sorted(supportedLanguages): if language != "Guessed": self.supportedLanguages[language] = supportedLanguages[language][:2] act = menu.addAction( @@ -1525,7 +1509,8 @@ """ Public method to export the file. - @param exporterFormat format the file should be exported into (string) + @param exporterFormat format the file should be exported into + @type str """ if exporterFormat: exporter = Exporters.getExporter(exporterFormat, self) @@ -1565,7 +1550,8 @@ """ Private method to select a specific pygments lexer. - @return name of the selected pygments lexer (string) + @return name of the selected pygments lexer + @rtype str """ from pygments.lexers import get_all_lexers # __IGNORE_WARNING_I102__ @@ -1593,7 +1579,8 @@ """ Private method to handle the selection of a lexer language. - @param act reference to the action that was triggered (QAction) + @param act reference to the action that was triggered + @type QAction """ if act == self.noLanguageAct: self.__resetLanguage() @@ -1616,8 +1603,10 @@ """ Private method handling a change of a connected editor's language. - @param language language to be set (string) - @param propagate flag indicating to propagate the change (boolean) + @param language language to be set + @type str + @param propagate flag indicating to propagate the change + @type bool """ if language == "": self.__resetLanguage(propagate=propagate) @@ -1637,7 +1626,8 @@ """ Private method used to reset the language selection. - @param propagate flag indicating to propagate the change (boolean) + @param propagate flag indicating to propagate the change + @type bool """ if self.lexer_ is not None and ( self.lexer_.lexer() == "container" or self.lexer_.lexer() is None @@ -1671,11 +1661,15 @@ Public method to set a lexer language. @param filename filename used to determine the associated lexer - language (string) + language + @type str @param initTextDisplay flag indicating an initialization of the text - display is required as well (boolean) - @param propagate flag indicating to propagate the change (boolean) - @param pyname name of the pygments lexer to use (string) + display is required as well + @type bool + @param propagate flag indicating to propagate the change + @type bool + @param pyname name of the pygments lexer to use + @type str """ # clear all warning and syntax error markers self.clearSyntaxError() @@ -1738,7 +1732,8 @@ """ Private method to handle the selection of an encoding. - @param act reference to the action that was triggered (QAction) + @param act reference to the action that was triggered + @type QAction """ encoding = act.data() self.setModified(True) @@ -1773,8 +1768,10 @@ """ Private method to calculate the normalized encoding string. - @param encoding encoding to be normalized (string) - @return normalized encoding (string) + @param encoding encoding to be normalized + @type str + @return normalized encoding + @rtype str """ if not encoding: encoding = self.encoding @@ -1795,7 +1792,8 @@ """ Private method to handle the selection of an eol type. - @param act reference to the action that was triggered (QAction) + @param act reference to the action that was triggered + @type QAction """ eol = act.data() self.setEolModeByEolString(eol) @@ -1821,6 +1819,19 @@ self.eolChanged.emit(eol) self.inEolChanged = False + def convertEols(self, eolMode): + """ + Public method to convert the end-of-line marker. + + This variant of the method emits a signal to update the IDE after + the original method was called. + + @param eolMode end-of-line mode + @type QsciScintilla.EolMode + """ + super().convertEols(eolMode) + self.__eolChanged() + @pyqtSlot() def __showContextMenuSpellCheck(self): """ @@ -2019,7 +2030,8 @@ """ Public method to retrieve a reference to the lexer object. - @return the lexer object (Lexer) + @return the lexer object + @rtype Lexer """ return self.lexer_ @@ -2028,10 +2040,13 @@ Public method to retrieve the language of the editor. @param normalized flag indicating to normalize some Pygments - lexer names (boolean) + lexer names + @type bool @param forPygments flag indicating to normalize some lexer - names for Pygments (boolean) - @return language of the editor (string) + names for Pygments + @type bool + @return language of the editor + @rtype str """ if self.apiLanguage == "Guessed" or self.apiLanguage.startswith("Pygments|"): lang = self.lexer_.name() @@ -2082,7 +2097,8 @@ """ Public method to retrieve a reference to the completer object. - @return the completer object (CompleterBase) + @return the completer object + @rtype CompleterBase """ return self.completer @@ -2162,7 +2178,8 @@ """ Public method to set the display string for an unnamed editor. - @param noName display string for this unnamed editor (string) + @param noName display string for this unnamed editor + @type str """ self.noName = noName @@ -2170,7 +2187,8 @@ """ Public method to get the display string for an unnamed editor. - @return display string for this unnamed editor (string) + @return display string for this unnamed editor + @rtype str """ return self.noName @@ -2178,7 +2196,8 @@ """ Public method to return the name of the file being displayed. - @return filename of the displayed file (string) + @return filename of the displayed file + @rtype str """ return self.fileName @@ -2186,7 +2205,8 @@ """ Public method to return the type of the file being displayed. - @return type of the displayed file (string) + @return type of the displayed file + @rtype str """ return self.filetype @@ -2196,7 +2216,8 @@ eflag: marker. @return type of the displayed file, if set by an eflag: marker or an - empty string (string) + empty string + @rtype str """ if self.filetypeByFlag: return self.filetype @@ -2207,7 +2228,8 @@ """ Public method to determine the file type using various tests. - @return type of the displayed file or an empty string (string) + @return type of the displayed file or an empty string + @rtype str """ ftype = self.filetype if not ftype: @@ -2225,7 +2247,8 @@ """ Public method to return the current encoding. - @return current encoding (string) + @return current encoding + @rtype str """ return self.encoding @@ -2234,7 +2257,8 @@ Private method to return the Python main version or 0 if it's not a Python file at all. - @return Python version or 0 if it's not a Python file (int) + @return Python version or 0 if it's not a Python file + @rtype int """ return PythonUtilities.determinePythonVersion(self.fileName, self.text(0), self) @@ -2242,7 +2266,8 @@ """ Public method to return a flag indicating a Python (2 or 3) file. - @return flag indicating a Python3 file (boolean) + @return flag indicating a Python3 file + @rtype bool """ return self.__getPyVersion() == 3 @@ -2250,7 +2275,8 @@ """ Public method to return a flag indicating a Python3 file. - @return flag indicating a Python3 file (boolean) + @return flag indicating a Python3 file + @rtype bool """ return self.__getPyVersion() == 3 @@ -2282,7 +2308,8 @@ """ Public method to return a flag indicating a Ruby file. - @return flag indicating a Ruby file (boolean) + @return flag indicating a Ruby file + @rtype bool """ if self.filetype == "Ruby": return True @@ -2305,7 +2332,8 @@ """ Public method to return a flag indicating a Javascript file. - @return flag indicating a Javascript file (boolean) + @return flag indicating a Javascript file + @rtype bool """ if self.filetype == "JavaScript": return True @@ -2346,10 +2374,13 @@ """ Public method to highlight [or de-highlight] a particular line. - @param line line number to highlight (integer) + @param line line number to highlight + @type int @param error flag indicating whether the error highlight should be - used (boolean) - @param syntaxError flag indicating a syntax error (boolean) + used + @type bool + @param syntaxError flag indicating a syntax error + @type bool """ if line is None: self.lastHighlight = None @@ -2376,7 +2407,8 @@ """ Public method to return the position of the highlight bar. - @return line number of the highlight bar (integer) + @return line number of the highlight bar + @rtype int """ if self.lastHighlight is not None: return self.markerLine(self.lastHighlight) @@ -2403,17 +2435,26 @@ """ Private method to handle changes of the number of lines. - @param pos start position of change (integer) - @param mtype flags identifying the change (integer) - @param text text that is given to the Undo system (string) - @param length length of the change (integer) - @param linesAdded number of added/deleted lines (integer) - @param line line number of a fold level or marker change (integer) - @param foldNow new fold level (integer) - @param foldPrev previous fold level (integer) + @param pos start position of change + @type int + @param mtype flags identifying the change + @type int + @param text text that is given to the Undo system + @type str + @param length length of the change + @type int + @param linesAdded number of added/deleted lines + @type int + @param line line number of a fold level or marker change + @type int + @param foldNow new fold level + @type int + @param foldPrev previous fold level + @type int @param token ??? + @type int @param annotationLinesAdded number of added/deleted annotation lines - (integer) + @type int """ if mtype & (self.SC_MOD_INSERTTEXT | self.SC_MOD_DELETETEXT): # 1. set/reset the autosave timer @@ -2528,7 +2569,8 @@ Note: This doesn't clear the breakpoint in the debugger, it just deletes it from the editor internal list of breakpoints. - @param line line number of the breakpoint (integer) + @param line line number of the breakpoint + @type int """ if self.inLinesChanged: return @@ -2544,9 +2586,11 @@ """ Public method to set a new breakpoint and its properties. - @param line line number of the breakpoint (integer) - @param properties properties for the breakpoint (tuple) + @param line line number of the breakpoint + @type int + @param properties properties for the breakpoint (condition, temporary flag, enabled flag, ignore count) + @type tuple of (str, bool, bool, int) """ if not properties[2]: marker = self.dbreakpoint @@ -2565,8 +2609,10 @@ """ Private method to toggle a breakpoint. - @param line line number of the breakpoint (integer) - @param temporary flag indicating a temporary breakpoint (boolean) + @param line line number of the breakpoint + @type int + @param temporary flag indicating a temporary breakpoint + @type bool """ for handle in self.breaks: if self.markerLine(handle) == line - 1: @@ -2588,8 +2634,10 @@ """ Private method to add a new breakpoint. - @param line line number of the breakpoint (integer) - @param temporary flag indicating a temporary breakpoint (boolean) + @param line line number of the breakpoint + @type int + @param temporary flag indicating a temporary breakpoint + @type bool """ if self.fileName and self.isPyFile(): linestarts = PythonDisViewer.linestarts(self.text()) @@ -2620,7 +2668,8 @@ """ Private method to toggle a breakpoints enabled status. - @param line line number of the breakpoint (integer) + @param line line number of the breakpoint + @type int """ for handle in self.breaks: if self.markerLine(handle) == line - 1: @@ -2635,7 +2684,8 @@ Public method to check for the presence of a breakpoint at the current line. - @return flag indicating the presence of a breakpoint (boolean) + @return flag indicating the presence of a breakpoint + @rtype bool """ line, _ = self.getCursorPosition() return self.markersAtLine(line) & self.breakpointMask != 0 @@ -2644,7 +2694,8 @@ """ Public method to get the lines containing a breakpoint. - @return list of lines containing a breakpoint (list of integer) + @return list of lines containing a breakpoint + @rtype list of int """ lines = [] line = -1 @@ -2660,7 +2711,8 @@ """ Public method to check for the presence of breakpoints. - @return flag indicating the presence of breakpoints (boolean) + @return flag indicating the presence of breakpoints + @rtype bool """ return len(self.breaks) > 0 @@ -2822,7 +2874,8 @@ """ Public method to toggle a bookmark. - @param line line number of the bookmark (integer) + @param line line number of the bookmark + @type int """ for handle in self.bookmarks: if self.markerLine(handle) == line - 1: @@ -2841,7 +2894,7 @@ Public method to retrieve the bookmarks. @return sorted list of all lines containing a bookmark - (list of integer) + @rtype list of int """ bmlist = [] for handle in self.bookmarks: @@ -2854,7 +2907,8 @@ """ Public method to get the lines containing a bookmark. - @return list of lines containing a bookmark (list of integer) + @return list of lines containing a bookmark + @rtype list of int """ lines = [] line = -1 @@ -2870,7 +2924,8 @@ """ Public method to check for the presence of bookmarks. - @return flag indicating the presence of bookmarks (boolean) + @return flag indicating the presence of bookmarks + @rtype bool """ return len(self.bookmarks) > 0 @@ -2998,7 +3053,7 @@ Private slot to generate a print preview. @param printer reference to the printer object - (QScintilla.Printer.Printer) + @type QScintilla.Printer.Printer """ printer.printRange(self) @@ -3010,7 +3065,8 @@ """ Public method to get the lines containing a task. - @return list of lines containing a task (list of integer) + @return list of lines containing a task + @rtype list of int """ lines = [] line = -1 @@ -3026,7 +3082,8 @@ """ Public method to determine, if this editor contains any task markers. - @return flag indicating the presence of task markers (boolean) + @return flag indicating the presence of task markers + @rtype bool """ return self.__hasTaskMarkers @@ -3117,9 +3174,12 @@ """ Private method to create a pixmap for the change markers. - @param key key of the color to use (string) - @param size size of the pixmap (integer) - @return create pixmap (QPixmap) + @param key key of the color to use + @type str + @param size size of the pixmap + @type int + @return create pixmap + @rtype QPixmap """ pixmap = QPixmap(size, size) pixmap.fill(Qt.GlobalColor.transparent) @@ -3240,7 +3300,8 @@ """ Public method to get the lines containing a change. - @return list of lines containing a change (list of integer) + @return list of lines containing a change + @rtype list of int """ lines = [] line = -1 @@ -3256,7 +3317,8 @@ """ Public method to determine, if this editor contains any change markers. - @return flag indicating the presence of change markers (boolean) + @return flag indicating the presence of change markers + @rtype bool """ return self.__hasChangeMarkers @@ -3306,7 +3368,8 @@ """ Private method to extract flags and process them. - @return list of change flags (list of string) + @return list of change flags + @rtype list of str """ txt = self.text() flags = Utilities.extractFlags(txt) @@ -3338,7 +3401,8 @@ """ Public method to check dirty status and open a message window. - @return flag indicating successful reset of the dirty flag (boolean) + @return flag indicating successful reset of the dirty flag + @rtype bool """ if self.isModified(): fn = self.fileName @@ -3348,7 +3412,9 @@ self, self.tr("File Modified"), self.tr("<p>The file <b>{0}</b> has unsaved changes.</p>").format(fn), - self.saveFile if not self.isRemoteFile() else None, + self.saveFile + if not FileSystemUtilities.isRemoteFileName(self.fileName) + else None, ) if res: self.vm.setEditorName(self, self.fileName) @@ -3376,15 +3442,20 @@ break # Couldn't find the unmodified state - def readFile(self, fn, createIt=False, encoding=""): + def readFile(self, fn, createIt=False, encoding="", noempty=False): """ Public method to read the text from a file. - @param fn filename to read from (string) + @param fn filename to read from + @type str @param createIt flag indicating the creation of a new file, if the - given one doesn't exist (boolean) - @param encoding encoding to be used to read the file (string) + given one doesn't exist (defaults to False) + @type bool (optional) + @param encoding encoding to be used to read the file (defaults to "") (Note: this parameter overrides encoding detection) + @type str (optional) + @param noempty flag indicating to not set an empty text (defaults to False) + @type bool (optional) """ self.__loadEditorConfig(fileName=fn) @@ -3412,10 +3483,12 @@ ) raise + if noempty and not bool(txt): + return + with EricOverrideCursor(): - modified = False - self.setText(txt) + self.setModified(False) # get eric specific flags self.__processFlags() @@ -3428,10 +3501,10 @@ else: fileEol = self.detectEolString(txt) self.setEolModeByEolString(fileEol) + self.__eolChanged() self.extractTasks() - self.setModified(modified) self.lastModified = pathlib.Path(fn).stat().st_mtime @pyqtSlot() @@ -3539,8 +3612,10 @@ """ Private method to get the name of the file to be saved. - @param path directory to save the file in (string) - @return file name (string) + @param path directory to save the file in + @type str + @return file name + @rtype str """ # save to project, if a project is loaded if self.project.isOpen(): @@ -3602,8 +3677,10 @@ """ Public method to save a copy of the file. - @param path directory to save the file in (string) - @return flag indicating success (boolean) + @param path directory to save the file in + @type str + @return flag indicating success + @rtype bool """ fn = self.__getSaveFileName(path) if not fn: @@ -3620,15 +3697,20 @@ """ Public method to save the text to a file. - @param saveas flag indicating a 'save as' action (boolean) - @param path directory to save the file in (string) - @return flag indicating success (boolean) - """ - if not saveas and (not self.isModified() or self.isRemoteFile()): + @param saveas flag indicating a 'save as' action + @type bool + @param path directory to save the file in + @type str + @return flag indicating success + @rtype bool + """ + if not saveas and ( + not self.isModified() or FileSystemUtilities.isRemoteFileName(self.fileName) + ): # do nothing if text wasn't changed or is a remote file return False - if self.isDeviceFile(): + if FileSystemUtilities.isDeviceFileName(self.fileName): return self.__saveDeviceFile(saveas=saveas) newName = None @@ -3738,8 +3820,10 @@ fn = fn.replace("\\", "/") if "/" in fn: dn = fn.rsplit("/", 1)[0] - filemanager.makedirs(dn.replace("device:", "")) - success = filemanager.writeFile(fn.replace("device:", ""), self.text()) + filemanager.makedirs(FileSystemUtilities.plainFileName(dn)) + success = filemanager.writeFile( + FileSystemUtilities.plainFileName(fn), self.text() + ) if success: self.setFileName(fn) self.setModified(False) @@ -3752,7 +3836,8 @@ """ Public method to handle the editorRenamed signal. - @param fn filename to be set for the editor (string). + @param fn filename to be set for the editor + @type str """ self.__clearBreakpoints(fn) @@ -3938,9 +4023,12 @@ """ Public method to get the word to the left of a position. - @param line number of line to look at (int) - @param index position to look at (int) - @return the word to the left of that position (string) + @param line number of line to look at + @type int + @param index position to look at + @type int + @return the word to the left of that position + @rtype str """ return self.getWord(line, index, 1) @@ -3948,9 +4036,12 @@ """ Public method to get the word to the right of a position. - @param line number of line to look at (int) - @param index position to look at (int) - @return the word to the right of that position (string) + @param line number of line to look at + @type int + @param index position to look at + @type int + @return the word to the right of that position + @rtype str """ return self.getWord(line, index, 2) @@ -3958,7 +4049,8 @@ """ Public method to get the word at the current position. - @return the word at that current position (string) + @return the word at that current position + @rtype str """ line, index = self.getCursorPosition() return self.getWord(line, index) @@ -3968,7 +4060,7 @@ Public method to get the word boundaries at the current position. @return tuple with start and end indexes of the current word - (integer, integer) + @rtype tuple of (int, int) """ line, index = self.getCursorPosition() return self.getWordBoundaries(line, index) @@ -3977,8 +4069,10 @@ """ Public method to select the word at a position. - @param line number of line to look at (int) - @param index position to look at (int) + @param line number of line to look at + @type int + @param index position to look at + @type int """ start, end = self.getWordBoundaries(line, index) self.setSelection(line, start, line, end) @@ -3995,9 +4089,11 @@ Private method to get the character to the left of the current position in the current line. - @param pos position to get character at (integer) - @return requested character or "", if there are no more (string) and - the next position (i.e. pos - 1) + @param pos position to get character at + @type int + @return requested character or "", if there are no more and the next position + (i.e. pos - 1) + @rtype tuple of (str, int) """ if pos <= 0: return "", pos @@ -4017,8 +4113,10 @@ next search operation. @param selectionOnly flag indicating that only selected text should be - returned (boolean) - @return selection or current word (string) + returned + @type bool + @return selection or current word + @rtype str """ if self.hasSelectedText(): text = self.selectedText() @@ -4039,8 +4137,10 @@ """ Public method to set a search indicator for the given range. - @param startPos start position of the indicator (integer) - @param indicLength length of the indicator (integer) + @param startPos start position of the indicator + @type int + @param indicLength length of the indicator + @type int """ self.setIndicatorRange(self.searchIndicator, startPos, indicLength) line = self.lineIndexFromPosition(startPos)[0] @@ -4113,7 +4213,8 @@ """ Public method to get the lines containing a search indicator. - @return list of lines containing a search indicator (list of integer) + @return list of lines containing a search indicator + @rtype list of int """ return self.__searchIndicatorLines[:] @@ -4176,9 +4277,12 @@ Private method to check, if the given line is a comment line as produced by the configured comment rules. - @param line text of the line to check (string) - @param commentStr comment string to check against (string) - @return flag indicating a commented line (boolean) + @param line text of the line to check + @type str + @param commentStr comment string to check against + @type str + @return flag indicating a commented line + @rtype bool """ if Preferences.getEditor("CommentColumn0"): return line.startswith(commentStr) @@ -4186,9 +4290,24 @@ return line.strip().startswith(commentStr) @pyqtSlot() - def toggleCommentBlock(self): - """ - Public slot to toggle the comment of a block. + def toggleComment(self): + """ + Public slot to toggle a block or stream comment. + + If the lexer supports a block comment, that is used for toggling the + comment. Otherwise a stream comment is used if that is supported. If + none of these are supported, the request is ignored silently. + """ + if self.lexer_ is not None: + if self.lexer_.canBlockComment(): + self.__toggleBlockComment() + elif self.lexer_.canStreamComment(): + self.__toggleStreamComment() + + @pyqtSlot() + def __toggleBlockComment(self): + """ + Private slot to toggle the comment of a block. If the editor contains selected text and the start line is not commented, it will be commented. Otherwise the selection will be un-commented. In case there @@ -4234,9 +4353,9 @@ self.setCursorPosition(line, index - len(commentStr)) @pyqtSlot() - def commentLine(self): - """ - Public slot to comment the current line. + def __commentLine(self): + """ + Private slot to comment the current line. """ if self.lexer_ is None or not self.lexer_.canBlockComment(): return @@ -4252,9 +4371,9 @@ self.endUndoAction() @pyqtSlot() - def uncommentLine(self): - """ - Public slot to uncomment the current line. + def __uncommentLine(self): + """ + Private slot to uncomment the current line. """ if self.lexer_ is None or not self.lexer_.canBlockComment(): return @@ -4279,9 +4398,9 @@ self.endUndoAction() @pyqtSlot() - def commentSelection(self): - """ - Public slot to comment the current selection. + def __commentSelection(self): + """ + Private slot to comment the current selection. """ if self.lexer_ is None or not self.lexer_.canBlockComment(): return @@ -4310,9 +4429,9 @@ self.endUndoAction() @pyqtSlot() - def uncommentSelection(self): - """ - Public slot to uncomment the current selection. + def __uncommentSelection(self): + """ + Private slot to uncomment the current selection. """ if self.lexer_ is None or not self.lexer_.canBlockComment(): return @@ -4362,42 +4481,140 @@ def commentLineOrSelection(self): """ Public slot to comment the current line or current selection. - """ - if self.hasSelectedText(): - self.commentSelection() - else: - self.commentLine() + + If the lexer supports a block comment, that is used for commenting. + Otherwise a stream comment is used if that is supported. If none of + these are supported, the request is ignored silently. + """ + if self.lexer_ is not None: + if self.lexer_.canBlockComment(): + if self.hasSelectedText(): + self.__commentSelection() + else: + self.__commentLine() + elif self.lexer_.canStreamComment(): + # delegate to the stream comment method + self.streamCommentLineOrSelection() @pyqtSlot() def uncommentLineOrSelection(self): """ Public slot to uncomment the current line or current selection. - """ - if self.hasSelectedText(): - self.uncommentSelection() - else: - self.uncommentLine() - - @pyqtSlot() - def streamCommentLine(self): - """ - Public slot to stream comment the current line. + + If the lexer supports a block comment, that is used for uncommenting. + Otherwise a stream comment is used if that is supported. If none of + these are supported, the request is ignored silently. + """ + if self.lexer_ is not None: + if self.lexer_.canBlockComment(): + if self.hasSelectedText(): + self.__uncommentSelection() + else: + self.__uncommentLine() + elif self.lexer_.canStreamComment(): + # delegate to the stream uncomment method + self.streamUncommentLineOrSelection() + + def __isStreamCommentedLine(self, line, streamCommentStr): + """ + Private method to check, if the line is commented by a stream comment. + + @param line text of the line to check + @type str + @param streamCommentStr dictionary containing the stream comment start and + end strings + @type dict + @return flag indicating a stream commented line + @rtype bool + """ + line = line.strip() + return line.startswith(streamCommentStr["start"]) and line.endswith( + streamCommentStr["end"] + ) + + @pyqtSlot() + def __toggleStreamComment(self): + """ + Private slot to toggle the comment of a block. + + If the editor contains selected text and the start line is not commented, it + will be commented. Otherwise the selection will be un-commented. In case there + is no selected text and the current line is not commented, it will be commented. + If is commented, the comment block will be removed. """ if self.lexer_ is None or not self.lexer_.canStreamComment(): return - commentStr = self.lexer_.streamCommentStr() + streamCommentStr = self.lexer_.streamCommentStr() + line, index = self.getCursorPosition() + + if self.hasSelectedText(): + # Check if the selection starts with a stream comment string. + if self.text(self.getSelection()[0]).startswith(streamCommentStr["start"]): + self.streamUncommentLineOrSelection() + else: + self.streamCommentLineOrSelection() + elif self.__isStreamCommentedLine(self.text(line), streamCommentStr): + # It is a stream commented line. + self.streamUncommentLineOrSelection() + elif self.text(line).lstrip(" \t").startswith(streamCommentStr["start"]): + # The cursor is at the first line of a stream comment. + pos = len(self.text(line).replace(self.text(line).lstrip(" \t"), "")) + endline = line + lines = self.lines() + while endline < lines and not self.text(endline).rstrip().endswith( + streamCommentStr["end"] + ): + endline += 1 + + # Uncomment the determined block and reset the cursor position + self.setSelection(line, pos, endline, self.lineLength(endline)) + self.uncommentLineOrSelection() + self.setCursorPosition(line, index - len(streamCommentStr["start"])) + elif self.text(line).rstrip().endswith(streamCommentStr["end"]): + # The cursor is at the last line of a stream comment. + begline = line + while begline > 0 and not self.text(begline).lstrip(" \t").startswith( + streamCommentStr["start"] + ): + begline -= 1 + pos = len(self.text(begline).replace(self.text(begline).lstrip(" \t"), "")) + + # Uncomment the determined block and reset the cursor position + self.setSelection(begline, pos, line, self.lineLength(line)) + self.uncommentLineOrSelection() + self.setCursorPosition( + line, min(index, self.lineLength(line) - len(self.getLineSeparator())) + ) + else: + # No selected text and the current line does not start with a stream comment + # string, so comment the line. + self.streamCommentLineOrSelection() + + @pyqtSlot() + def __streamCommentLine(self): + """ + Private slot to stream comment the current line. + """ + if self.lexer_ is None or not self.lexer_.canStreamComment(): + return + + streamCommentStr = self.lexer_.streamCommentStr() line, index = self.getCursorPosition() self.beginUndoAction() - self.insertAt(commentStr["end"], line, self.lineLength(line)) - self.insertAt(commentStr["start"], line, 0) + self.insertAt( + streamCommentStr["end"], + line, + self.lineLength(line) - len(self.getLineSeparator()), + ) + self.insertAt(streamCommentStr["start"], line, 0) self.endUndoAction() @pyqtSlot() - def streamCommentSelection(self): - """ - Public slot to comment the current selection. + def __streamCommentSelection(self): + """ + Private slot to comment the current selection. """ if self.lexer_ is None or not self.lexer_.canStreamComment(): return @@ -4405,63 +4622,158 @@ if not self.hasSelectedText(): return - commentStr = self.lexer_.streamCommentStr() + streamCommentStr = self.lexer_.streamCommentStr() # get the selection boundaries lineFrom, indexFrom, lineTo, indexTo = self.getSelection() if indexTo == 0: endLine = lineTo - 1 - endIndex = self.lineLength(endLine) + endIndex = self.lineLength(endLine) - len(self.getLineSeparator()) else: endLine = lineTo endIndex = indexTo self.beginUndoAction() - self.insertAt(commentStr["end"], endLine, endIndex) - self.insertAt(commentStr["start"], lineFrom, indexFrom) + self.insertAt(streamCommentStr["end"], endLine, endIndex) + self.insertAt(streamCommentStr["start"], lineFrom, indexFrom) # change the selection accordingly if indexTo > 0: - indexTo += len(commentStr["end"]) + indexTo += len(streamCommentStr["end"]) if lineFrom == endLine: - indexTo += len(commentStr["start"]) + indexTo += len(streamCommentStr["start"]) self.setSelection(lineFrom, indexFrom, lineTo, indexTo) self.endUndoAction() @pyqtSlot() + def __streamUncommentLine(self): + """ + Private slot to stream uncomment the current line. + """ + if self.lexer_ is None or not self.lexer_.canStreamComment(): + return + + streamCommentStr = self.lexer_.streamCommentStr() + line, index = self.getCursorPosition() + + # check if line starts and ends with the stream comment strings + if not self.__isStreamCommentedLine(self.text(line), streamCommentStr): + return + + self.beginUndoAction() + # 1. remove comment end string + self.setSelection( + line, + self.lineLength(line) + - len(self.getLineSeparator()) + - len(streamCommentStr["end"]), + line, + self.lineLength(line) - len(self.getLineSeparator()), + ) + self.removeSelectedText() + + # 2. remove comment start string + lineText = self.text(line) + pos = len(lineText.replace(lineText.lstrip(" \t"), "")) + self.setSelection(line, pos, line, pos + len(streamCommentStr["start"])) + self.removeSelectedText() + self.endUndoAction() + + @pyqtSlot() + def __streamUncommentSelection(self): + """ + Private slot to stream uncomment the current selection. + """ + if self.lexer_ is None or not self.lexer_.canStreamComment(): + return + + if not self.hasSelectedText(): + return + + streamCommentStr = self.lexer_.streamCommentStr() + + # get the selection boundaries + lineFrom, indexFrom, lineTo, indexTo = self.getSelection() + if indexTo == 0: + endLine = lineTo - 1 + endIndex = self.lineLength(endLine) - len(self.getLineSeparator()) + else: + endLine = lineTo + endIndex = indexTo + + self.beginUndoAction() + self.setSelection(lineFrom, indexFrom, endLine, endIndex) + selTxt = self.selectedText() + if selTxt.endswith(streamCommentStr["end"]): + self.setSelection( + endLine, endIndex - len(streamCommentStr["end"]), endLine, endIndex + ) + self.removeSelectedText() + + # modify selection end accordingly + if indexTo > 0: + indexTo -= len(streamCommentStr["end"]) + if selTxt.startswith(streamCommentStr["start"]): + self.setSelection( + lineFrom, + indexFrom, + lineFrom, + indexFrom + len(streamCommentStr["start"]), + ) + self.removeSelectedText() + + # modify selection end accordingly + if lineFrom == lineTo and indexTo > 0: + indexTo -= len(streamCommentStr["start"]) + self.endUndoAction() + + # now set the new selection + self.setSelection(lineFrom, indexFrom, lineTo, indexTo) + + @pyqtSlot() def streamCommentLineOrSelection(self): """ Public slot to stream comment the current line or current selection. """ if self.hasSelectedText(): - self.streamCommentSelection() - else: - self.streamCommentLine() - - @pyqtSlot() - def boxCommentLine(self): - """ - Public slot to box comment the current line. + self.__streamCommentSelection() + else: + self.__streamCommentLine() + + @pyqtSlot() + def streamUncommentLineOrSelection(self): + """ + Public slot to stream uncomment the current line or current selection. + """ + if self.hasSelectedText(): + self.__streamUncommentSelection() + else: + self.__streamUncommentLine() + + @pyqtSlot() + def __boxCommentLine(self): + """ + Private slot to box comment the current line. """ if self.lexer_ is None or not self.lexer_.canBoxComment(): return - commentStr = self.lexer_.boxCommentStr() + boxCommentStr = self.lexer_.boxCommentStr() line, index = self.getCursorPosition() eol = self.getLineSeparator() self.beginUndoAction() self.insertAt(eol, line, self.lineLength(line)) - self.insertAt(commentStr["end"], line + 1, 0) - self.insertAt(commentStr["middle"], line, 0) + self.insertAt(boxCommentStr["end"], line + 1, 0) + self.insertAt(boxCommentStr["middle"], line, 0) self.insertAt(eol, line, 0) - self.insertAt(commentStr["start"], line, 0) + self.insertAt(boxCommentStr["start"], line, 0) self.endUndoAction() @pyqtSlot() - def boxCommentSelection(self): - """ - Public slot to box comment the current selection. + def __boxCommentSelection(self): + """ + Private slot to box comment the current selection. """ if self.lexer_ is None or not self.lexer_.canBoxComment(): return @@ -4469,7 +4781,7 @@ if not self.hasSelectedText(): return - commentStr = self.lexer_.boxCommentStr() + boxCommentStr = self.lexer_.boxCommentStr() # get the selection boundaries lineFrom, indexFrom, lineTo, indexTo = self.getSelection() @@ -4478,14 +4790,14 @@ self.beginUndoAction() # iterate over the lines for line in range(lineFrom, endLine + 1): - self.insertAt(commentStr["middle"], line, 0) + self.insertAt(boxCommentStr["middle"], line, 0) # now do the comments before and after the selection eol = self.getLineSeparator() self.insertAt(eol, endLine, self.lineLength(endLine)) - self.insertAt(commentStr["end"], endLine + 1, 0) + self.insertAt(boxCommentStr["end"], endLine + 1, 0) self.insertAt(eol, lineFrom, 0) - self.insertAt(commentStr["start"], lineFrom, 0) + self.insertAt(boxCommentStr["start"], lineFrom, 0) # change the selection accordingly self.setSelection(lineFrom, 0, endLine + 3, 0) @@ -4497,9 +4809,9 @@ Public slot to box comment the current line or current selection. """ if self.hasSelectedText(): - self.boxCommentSelection() - else: - self.boxCommentLine() + self.__boxCommentSelection() + else: + self.__boxCommentLine() ########################################################################### ## Indentation handling methods below @@ -4509,9 +4821,10 @@ """ Private method to indent or unindent the current line. - @param indent flag indicating an indent operation (boolean) - <br />If the flag is true, an indent operation is performed. - Otherwise the current line is unindented. + @param indent flag indicating an indent operation + <br />If the flag is true, an indent operation is performed. + Otherwise the current line is unindented. + @type bool """ line, index = self.getCursorPosition() self.beginUndoAction() @@ -4529,9 +4842,10 @@ """ Private method to indent or unindent the current selection. - @param indent flag indicating an indent operation (boolean) - <br />If the flag is true, an indent operation is performed. - Otherwise the current line is unindented. + @param indent flag indicating an indent operation + <br />If the flag is true, an indent operation is performed. + Otherwise the current line is unindented. + @type bool """ if not self.hasSelectedText(): return @@ -4648,7 +4962,8 @@ """ Public method to check, if a last edit position is available. - @return flag indicating availability (boolean) + @return flag indicating availability + @rtype bool """ return self.__lastEditPosition is not None @@ -4663,7 +4978,8 @@ """ Public method to go to the next Python method or class definition. - @param goUp flag indicating the move direction (boolean) + @param goUp flag indicating the move direction + @type bool """ if self.isPyFile() or self.isRubyFile(): lineNo = self.getCursorPosition()[0] @@ -5212,7 +5528,8 @@ """ Public method to check for API availablity. - @return flag indicating autocompletion from APIs is available (boolean) + @return flag indicating autocompletion from APIs is available + @rtype bool """ return self.acAPI @@ -5247,7 +5564,7 @@ Public method to enable/disable autocompletion. @param enable flag indicating the desired autocompletion status - (boolean) + @type bool """ if enable: autoCompletionSource = Preferences.getEditor("AutoCompletionSource") @@ -5323,8 +5640,10 @@ Private method to check, if a character is an autocompletion start character. - @param ch character to be checked (one character string) - @return flag indicating the result (boolean) + @param ch character to be checked + @type str + @return flag indicating the result + @rtype bool """ if self.lexer_ is None: return False @@ -5412,8 +5731,9 @@ Public method to start auto-completion. @param auto flag indicating a call from the __charAdded method - (boolean) - @param context flag indicating to complete a context (boolean) + @type bool + @param context flag indicating to complete a context + @type bool """ if auto and not Preferences.getEditor("AutoCompletionEnabled"): # auto-completion is disabled @@ -5464,7 +5784,7 @@ Private method to start auto-completion via plug-ins. @param auto flag indicating a call from the __charAdded method - (boolean) + @type bool @param context flag indicating to complete a context @type bool or None """ @@ -5635,7 +5955,7 @@ Public method to test the dynamic auto-completion availability. @return flag indicating the availability of dynamic auto-completion - (boolean) + @rtype bool """ return ( self.acAPI @@ -5702,7 +6022,8 @@ """ Public method to test the calltips availability. - @return flag indicating the availability of calltips (boolean) + @return flag indicating the availability of calltips + @rtype bool """ return self.acAPI or bool(self.__ctHookFunctions) @@ -5828,9 +6149,12 @@ """ Private method to calculate an adjusted position for showing calltips. - @param ctshift amount the calltip shall be shifted (integer) - @param pos position into the text (integer) - @return new position for the calltip (integer) + @param ctshift amount the calltip shall be shifted + @type int + @param pos position into the text + @type int + @return new position for the calltip + @rtype int """ ct = pos if ctshift: @@ -5863,8 +6187,10 @@ """ Private method to calculate the margin number based on a x position. - @param xPos x position (integer) + @param xPos x position + @type int @return margin number (integer, -1 for no margin) + @rtype int """ width = 0 for margin in range(5): @@ -6166,7 +6492,8 @@ Private method to handle the rereading of the file with a selected encoding. - @param act reference to the action that was triggered (QAction) + @param act reference to the action that was triggered + @type QAction """ encoding = act.data() self.readFile(self.fileName, encoding=encoding) @@ -6305,7 +6632,8 @@ """ Private method to check the autosave flags. - @return flag indicating this editor should be saved (boolean) + @return flag indicating this editor should be saved + @rtype bool """ return ( bool(self.fileName) @@ -6585,7 +6913,8 @@ """ Public method to get the lines containing a coverage marker. - @return list of lines containing a coverage marker (list of integer) + @return list of lines containing a coverage marker + @rtype list of int """ lines = [] line = -1 @@ -6601,7 +6930,8 @@ """ Public method to test, if there are coverage markers. - @return flag indicating the presence of coverage markers (boolean) + @return flag indicating the presence of coverage markers + @rtype bool """ return len(self.notcoveredMarkers) > 0 @@ -6752,7 +7082,7 @@ self.setCursorPosition(line - 1, index) self.ensureLineVisible(line - 1) else: - for handle in list(self.syntaxerrors.keys()): + for handle in list(self.syntaxerrors): if self.markerLine(handle) == line - 1: del self.syntaxerrors[handle] self.markerDeleteHandle(handle) @@ -6765,7 +7095,8 @@ """ Public method to get the lines containing a syntax error. - @return list of lines containing a syntax error (list of integer) + @return list of lines containing a syntax error + @rtype list of int """ lines = [] line = -1 @@ -6781,7 +7112,8 @@ """ Public method to check for the presence of syntax errors. - @return flag indicating the presence of syntax errors (boolean) + @return flag indicating the presence of syntax errors + @rtype bool """ return len(self.syntaxerrors) > 0 @@ -6804,7 +7136,7 @@ """ Public slot to handle the 'Clear all syntax error' context menu action. """ - for handle in list(self.syntaxerrors.keys()): + for handle in list(self.syntaxerrors): line = self.markerLine(handle) + 1 self.toggleSyntaxError(line, 0, False) @@ -6909,7 +7241,7 @@ ): self._warnings[handle].append(warn) else: - for handle in list(self._warnings.keys()): + for handle in list(self._warnings): if self.markerLine(handle) == line - 1: del self._warnings[handle] self.markerDeleteHandle(handle) @@ -6923,7 +7255,8 @@ """ Public method to get the lines containing a warning. - @return list of lines containing a warning (list of integer) + @return list of lines containing a warning + @rtype list of int """ lines = [] line = -1 @@ -6939,7 +7272,8 @@ """ Public method to check for the presence of warnings. - @return flag indicating the presence of warnings (boolean) + @return flag indicating the presence of warnings + @rtype bool """ return len(self._warnings) > 0 @@ -7021,8 +7355,9 @@ @param warningKind kind of warning to clear (Editor.WarningCode, Editor.WarningPython, Editor.WarningStyle) - """ - for handle in list(self._warnings.keys()): + @type int + """ + for handle in list(self._warnings): issues = [] for msg, warningType in self._warnings[handle]: if warningType == warningKind: @@ -7139,7 +7474,8 @@ """ Private method to set the annotations for the given line. - @param line number of the line that needs annotation (integer) + @param line number of the line that needs annotation + @type int """ if hasattr(QsciScintilla, "annotate"): warningAnnotations = [] @@ -7283,7 +7619,8 @@ Private method to select a macro name from the list of macros. @return Tuple of macro name and a flag, indicating, if the user - pressed ok or canceled the operation. (string, boolean) + pressed ok or canceled the operation. + @rtype tuple of (str, bool) """ qs = [] for s in self.macros: @@ -7473,7 +7810,8 @@ ViewManager.closeEditor, which in turn calls our closeIt method. - @return flag indicating a successful close of the editor (boolean) + @return flag indicating a successful close of the editor + @rtype bool """ return self.vm.closeEditor(self) @@ -7567,50 +7905,16 @@ @type QFocusEvent """ self.recolor() + self.vm.editActGrp.setEnabled(True) self.vm.editorActGrp.setEnabled(True) self.vm.copyActGrp.setEnabled(True) self.vm.viewActGrp.setEnabled(True) self.vm.searchActGrp.setEnabled(True) + with contextlib.suppress(AttributeError): self.setCaretWidth(self.caretWidth) self.__updateReadOnly(False) - if ( - self.vm.editorsCheckFocusInEnabled() - and not self.inReopenPrompt - and self.fileName - and pathlib.Path(self.fileName).exists() - and pathlib.Path(self.fileName).stat().st_mtime != self.lastModified - ): - self.inReopenPrompt = True - if Preferences.getEditor("AutoReopen") and not self.isModified(): - self.refresh() - else: - msg = self.tr( - """<p>The file <b>{0}</b> has been changed while it""" - """ was opened in eric. Reread it?</p>""" - ).format(self.fileName) - yesDefault = True - if self.isModified(): - msg += self.tr( - """<br><b>Warning:</b> You will lose""" - """ your changes upon reopening it.""" - ) - yesDefault = False - res = EricMessageBox.yesNo( - self, - self.tr("File changed"), - msg, - icon=EricMessageBox.Warning, - yesDefault=yesDefault, - ) - if res: - self.refresh() - else: - # do not prompt for this change again... - self.lastModified = pathlib.Path(self.fileName).stat().st_mtime - self.inReopenPrompt = False - self.setCursorFlashTime(QApplication.cursorFlashTime()) super().focusInEvent(event) @@ -7793,8 +8097,11 @@ @param bForce True to force change, False to only update and emit signal if there was an attribute change. - """ - if self.fileName == "" or not self.isLocalFile(): + @type bool + """ + if self.fileName == "" or not FileSystemUtilities.isPlainFileName( + self.fileName + ): return readOnly = self.checkReadOnly() @@ -7816,10 +8123,57 @@ @rtype bool """ return ( - self.isLocalFile() and not os.access(self.fileName, os.W_OK) + FileSystemUtilities.isPlainFileName(self.fileName) + and not os.access(self.fileName, os.W_OK) ) or self.isReadOnly() @pyqtSlot() + def checkRereadFile(self): + """ + Public slot to check, if the file needs to be re-read, and refresh it if + needed. + """ + if ( + self.fileName + and pathlib.Path(self.fileName).exists() + and pathlib.Path(self.fileName).stat().st_mtime != self.lastModified + ): + if Preferences.getEditor("AutoReopen") and not self.isModified(): + self.refresh() + else: + msg = self.tr( + """<p>The file <b>{0}</b> has been changed while it""" + """ was opened in eric. Reread it?</p>""" + ).format(self.fileName) + yesDefault = True + if self.isModified(): + msg += self.tr( + """<br><b>Warning:</b> You will lose""" + """ your changes upon reopening it.""" + ) + yesDefault = False + res = EricMessageBox.yesNo( + self, + self.tr("File changed"), + msg, + icon=EricMessageBox.Warning, + yesDefault=yesDefault, + ) + if res: + self.refresh() + else: + # do not prompt for this change again... + self.lastModified = pathlib.Path(self.fileName).stat().st_mtime + + @pyqtSlot() + def recordModificationTime(self): + """ + Public slot to record the modification time of our file. + """ + if self.fileName and pathlib.Path(self.fileName).exists(): + self.lastModified = pathlib.Path(self.fileName).stat().st_mtime + + @pyqtSlot() def refresh(self): """ Public slot to refresh the editor contents. @@ -7849,7 +8203,7 @@ # reread the file try: - self.readFile(self.fileName) + self.readFile(self.fileName, noempty=True) except OSError: # do not prompt for this change again... self.lastModified = QDateTime.currentDateTime() @@ -7880,7 +8234,8 @@ """ Public method to set/reset a monospaced font. - @param on flag to indicate usage of a monospace font (boolean) + @param on flag to indicate usage of a monospace font + @type bool """ if on: if not self.lexer_: @@ -7912,7 +8267,8 @@ """ Protected method to handle the drag enter event. - @param event the drag enter event (QDragEnterEvent) + @param event the drag enter event + @type QDragEnterEvent """ self.inDragDrop = event.mimeData().hasUrls() if self.inDragDrop: @@ -7924,7 +8280,8 @@ """ Protected method to handle the drag move event. - @param event the drag move event (QDragMoveEvent) + @param event the drag move event + @type QDragMoveEvent """ if self.inDragDrop: event.accept() @@ -7935,7 +8292,8 @@ """ Protected method to handle the drag leave event. - @param event the drag leave event (QDragLeaveEvent) + @param event the drag leave event + @type QDragLeaveEvent """ if self.inDragDrop: self.inDragDrop = False @@ -7947,7 +8305,8 @@ """ Protected method to handle the drop event. - @param event the drop event (QDropEvent) + @param event the drop event + @type QDropEvent """ if event.mimeData().hasUrls(): for url in event.mimeData().urls(): @@ -7977,7 +8336,8 @@ """ Private method used to setup the Resources context sub menu. - @return reference to the generated menu (QMenu) + @return reference to the generated menu + @rtype QMenu """ menu = QMenu(self.tr("Resources")) @@ -8210,6 +8570,7 @@ Public method to perform a simple editor command. @param cmd the scintilla command to be performed + @type int """ if cmd == QsciScintilla.SCI_TAB: try: @@ -8271,9 +8632,11 @@ """ Private method to apply a template by name. - @param templateName name of the template to apply (string) + @param templateName name of the template to apply + @type str @param language name of the language (group) to get the template - from (string) + from + @type str """ try: templateViewer = ericApp().getObject("TemplateViewer") @@ -8360,9 +8723,12 @@ """ Private method to set the spell checking language. - @param language spell checking language to be set (string) - @param pwl name of the personal/project word list (string) - @param pel name of the personal/project exclude list (string) + @param language spell checking language to be set + @type str + @param pwl name of the personal/project word list + @type str + @param pel name of the personal/project exclude list + @type str """ if self.spell and self.spell.getLanguage() != language: self.spell.setLanguage(language, pwl=pwl, pel=pel) @@ -8603,7 +8969,7 @@ @return tuple indicating, if the editor is sharable, the sharing status, if it is inside a locally initiated shared edit session and if it is inside a remotely initiated shared edit session - (boolean, boolean, boolean, boolean) + @rtype tuple of (bool, bool, bool, bool) """ return ( ( @@ -8620,7 +8986,8 @@ """ Public method to handle a change of the connected state. - @param connected flag indicating the connected state (boolean) + @param connected flag indicating the connected state + @type bool """ if not connected: self.__inRemoteSharedEdit = False @@ -8634,7 +9001,8 @@ """ Public method to set the shared status of the editor. - @param share flag indicating the share status (boolean) + @param share flag indicating the share status + @type bool """ self.__isShared = share if not share: @@ -8671,7 +9039,8 @@ """ Public method to cancel a shared edit session for the editor. - @param send flag indicating to send the CancelEdit command (boolean) + @param send flag indicating to send the CancelEdit command + @type bool """ self.__inSharedEdit = False self.__savedText = "" @@ -8682,8 +9051,10 @@ """ Private method to send an editor command to remote editors. - @param token command token (string) - @param args arguments for the command (string) + @param token command token + @type str + @param args arguments for the command + @type str """ if self.vm.isConnected(): msg = "" @@ -8719,7 +9090,8 @@ """ Private method to dispatch received commands. - @param command command to be processed (string) + @param command command to be processed + @type str """ token, argsString = command.split(Editor.Separator, 1) if token == Editor.StartEditToken: @@ -8762,9 +9134,12 @@ Private method to determine change commands to convert old text into new text. - @param old old text (string) - @param new new text (string) - @return commands to change old into new (string) + @param old old text + @type str + @param new new text + @type str + @return commands to change old into new + @rtype str """ oldL = old.splitlines() newL = new.splitlines() @@ -8894,7 +9269,8 @@ """ Private slot to search the next occurrence of the current word. - @param forward flag indicating the search direction (boolean) + @param forward flag indicating the search direction + @type bool """ self.hideFindIndicator() line, index = self.getCursorPosition() @@ -8992,7 +9368,7 @@ eol = self.getLineSeparator() lastWithEol = True newLines = [] - for txt in sorted(selText.keys(), key=keyFun, reverse=reverse): + for txt in sorted(selText, key=keyFun, reverse=reverse): for line in selText[txt]: txt = txtLines[line] if not txt.endswith(eol): @@ -9135,7 +9511,7 @@ @param name name of the plug-in @type str """ - for key in list(self.__mouseClickHandlers.keys()): + for key in list(self.__mouseClickHandlers): if self.__mouseClickHandlers[key][0] == name: del self.__mouseClickHandlers[key] @@ -9225,7 +9601,7 @@ """ editorConfig = {} - if fileName and self.isLocalFile(): + if fileName and FileSystemUtilities.isPlainFileName(self.fileName): try: editorConfig = editorconfig.get_properties(fileName) except editorconfig.EditorConfigError: @@ -9258,7 +9634,7 @@ @type dict @return value of requested setting or None if nothing was found and nodefault parameter was True - @rtype any + @rtype Any """ if config is None: config = self.__editorConfig @@ -9319,7 +9695,7 @@ @param option Preferences option key @type str @return value of requested setting - @rtype any + @rtype Any """ return self.__getEditorConfig(option) @@ -9330,7 +9706,7 @@ @param option Preferences option key @type str @return override value; None in case nothing is defined - @rtype any + @rtype Any """ if option in ("TabWidth", "IndentWidth"): overrides = Preferences.getEditor("TabIndentOverride")