--- a/QScintilla/Editor.py Thu Feb 01 19:25:47 2018 +0100 +++ b/QScintilla/Editor.py Thu Feb 01 19:26:11 2018 +0100 @@ -39,6 +39,8 @@ import UI.PixmapCache +from ThirdParty.EditorConfig import editorconfig + EditorAutoCompletionListID = 1 TemplateCompletionListID = 2 @@ -192,11 +194,13 @@ self.notcoveredMarkers = [] # just a list of marker handles self.showingNotcoveredMarkers = False + self.__loadEditorConfig() + self.condHistory = [] self.lexer_ = None self.__lexerReset = False self.completer = None - self.encoding = Preferences.getEditor("DefaultEncoding") + self.encoding = self.__getEditorConfig("DefaultEncoding") self.apiLanguage = '' self.lastModified = 0 self.line = -1 @@ -2960,6 +2964,9 @@ if createIt and not os.path.exists(fn): f = open(fn, "w") f.close() + if encoding == "": + encoding = self.__getEditorConfig("DefaultEncoding", + nodefault=True) if encoding: txt, self.encoding = Utilities.readEncodedFileWithEncoding( fn, encoding) @@ -2978,6 +2985,7 @@ fileEol = self.detectEolString(txt) modified = False + # TODO: editorconfig: indent_style if (not Preferences.getEditor("TabForIndentation")) and \ Preferences.getEditor("ConvertTabsOnLoad") and \ not (self.lexer_ and @@ -2994,7 +3002,9 @@ self.__processFlags() # perform automatic eol conversion - if Preferences.getEditor("AutomaticEOLConversion"): + # TODO: editorconfig: end_of_line + if self.__getEditorConfig("EOLMode", nodefault=True) or \ + Preferences.getEditor("AutomaticEOLConversion"): self.convertEols(self.eolMode()) else: self.setEolModeByEolString(fileEol) @@ -3027,12 +3037,14 @@ @param backup flag indicating to save a backup (boolean) @return flag indicating success (boolean) """ + # TODO: editorconfig: trim_trailing_whitespace if Preferences.getEditor("StripTrailingWhitespace"): self.__removeTrailingWhitespace() txt = self.text() # work around glitch in scintilla: always make sure, # that the last line is terminated properly + # TODO: editorconfig: insert_final_newline eol = self.getLineSeparator() if eol: if len(txt) >= len(eol): @@ -3066,7 +3078,10 @@ # now write text to the file fn try: - self.encoding = Utilities.writeEncodedFile(fn, txt, self.encoding) + editorConfigEncoding = self.__getEditorConfig( + "DefaultEncoding", nodefault=True) + self.encoding = Utilities.writeEncodedFile( + fn, txt, self.encoding, forcedEncoding=editorConfigEncoding) if createBackup and perms_valid: os.chmod(fn, permissions) return True @@ -3186,11 +3201,13 @@ # save to project, if a project is loaded if self.project.isOpen() and \ self.project.startswithProjectPath(fn): + # TODO: check against editorconfig self.setEolModeByEolString(self.project.getEolString()) self.convertEols(self.eolMode()) else: fn = self.fileName + self.__loadEditorConfig(fn) self.editorAboutToBeSaved.emit(self.fileName) if self.writeFile(fn): if saveas: @@ -3253,6 +3270,8 @@ self.fileName = fn self.setWindowTitle(self.fileName) + self.__loadEditorConfig() + if self.lexer_ is None: self.setLanguage(self.fileName) @@ -4317,8 +4336,11 @@ """ Private method to configure the text display. """ + # TODO: editorconfig: tab_width self.setTabWidth(Preferences.getEditor("TabWidth")) + # TODO: editorconfig: indent_size self.setIndentationWidth(Preferences.getEditor("IndentWidth")) + # TODO: editorconfig: indent_style if self.lexer_ and self.lexer_.alwaysKeepTabs(): self.setIndentationsUseTabs(True) else: @@ -4440,9 +4462,13 @@ if self.fileName and \ self.project.isOpen() and \ self.project.isProjectFile(self.fileName): - self.setEolModeByEolString(self.project.getEolString()) - else: - eolMode = Preferences.getEditor("EOLMode") + # TODO: editorconfig: end_of_line + eolMode = self.__getEditorConfig("EOLMode") + if eolMode is None: + eolMode = self.project.getEolString() + self.setEolModeByEolString(eolMode) + else: + eolMode = self.__getEditorConfig("EOLMode") eolMode = QsciScintilla.EolMode(eolMode) self.setEolMode(eolMode) self.__eolChanged() @@ -8016,3 +8042,78 @@ """ txt = self.selectedText() e5App().getObject("Shell").executeLines(txt) + + ####################################################################### + ## Methods implementing the interface to EditorConfig + ####################################################################### + + def __loadEditorConfig(self, fileName=""): + """ + Private method to load the EditorConfig properties. + + @param fileName name of the file + @type str + """ + if not fileName: + fileName = self.fileName + + if fileName: + try: + self.__editorConfig = \ + editorconfig.get_properties(fileName) + except editorconfig.EditorConfigError: + E5MessageBox.warning( + self, + self.tr("EditorConfig Properties"), + self.tr("""<p>The EditorConfig properties for file""" + """ <b>{0}</b> could not be loaded.</p>""") + .format(self.fileName)) + self.__editorConfig = {} + else: + self.__editorConfig = {} + + def __getEditorConfig(self, option, nodefault=False): + """ + Private method to get the requested option via EditorConfig. + + If there is no EditorConfig defined, the equivalent built-in option + will be used (Preferences.getEditor(). The option must be given as the + Preferences option key. The mapping to the EditorConfig option name + will be done within this method. + + @param option Preferences option key + @type str + @param nodefault flag indicating to not get the default value from + Preferences but return None instead + @type bool + @return value of requested setting or None if nothing was found and + nodefault parameter was True + @rtype any + """ + if not self.__editorConfig: + if nodefault: + return None + else: + return Preferences.getEditor(option) + + try: + if option == "EOLMode": + value = self.__editorConfig["end_of_line"] + if value == "lf": + value = QsciScintilla.EolUnix + elif value == "crlf": + value = QsciScintilla.EolWindows + elif value == "cr": + value = QsciScintilla.EolMac + else: + value = None + elif option == "DefaultEncoding": + value = self.__editorConfig["charset"] + except KeyError: + value = None + + if value is None and not nodefault: + # use Preferences in case of error + value = Preferences.getEditor(option) + + return value