QScintilla/MiniEditor.py

changeset 6101
b854a825d483
parent 6073
a679240821cb
child 6105
cbd34d558bd9
--- a/QScintilla/MiniEditor.py	Thu Feb 01 19:32:19 2018 +0100
+++ b/QScintilla/MiniEditor.py	Fri Feb 02 19:42:01 2018 +0100
@@ -34,6 +34,8 @@
 import Utilities
 import Preferences
 
+from ThirdParty.EditorConfig import editorconfig
+
 
 class MiniScintilla(QsciScintillaCompat):
     """
@@ -120,7 +122,7 @@
         self.__textEdit.clearSearchIndicators = self.clearSearchIndicators
         self.__textEdit.setSearchIndicator = self.setSearchIndicator
         self.__textEdit.setUtf8(True)
-        self.encoding = Preferences.getEditor("DefaultEncoding")
+        
         
         self.srHistory = {
             "search": [],
@@ -184,9 +186,11 @@
         self.__textEdit.selectionChanged.connect(
             self.__replaceWidget.selectionChanged)
         
-        self.__setCurrentFile("")
         if filename:
             self.__loadFile(filename, filetype)
+        else:
+            self.__setCurrentFile("")
+            self.encoding = self.__getEditorConfig("DefaultEncoding")
         
         self.__checkActions()
 
@@ -252,25 +256,8 @@
         fileName = E5FileDialog.getSaveFileName(self)
         if not fileName:
             return
-    
-        QApplication.setOverrideCursor(Qt.WaitCursor)
-        txt = self.__textEdit.text()
-        try:
-            self.encoding = Utilities.writeEncodedFile(
-                fileName, txt, self.encoding)
-        except (IOError, Utilities.CodingError, UnicodeError) as why:
-            E5MessageBox.critical(
-                self, self.tr('Save File'),
-                self.tr('<p>The file <b>{0}</b> could not be saved.<br/>'
-                        'Reason: {1}</p>')
-                .format(fileName, str(why)))
-            QApplication.restoreOverrideCursor()
-            return
         
-        QApplication.restoreOverrideCursor()
-        self.__statusBar.showMessage(self.tr("File saved"), 2000)
-        
-        return
+        self.__writeFile(fileName)
     
     def __about(self):
         """
@@ -2304,10 +2291,18 @@
         @param fileName name of the file to load (string)
         @param filetype type of the source file (string)
         """
+        self.__loadEditorConfig(fileName=fileName)
+        
         QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
         
         try:
-            txt, self.encoding = Utilities.readEncodedFile(fileName)
+            encoding = self.__getEditorConfig("DefaultEncoding",
+                                              nodefault=True)
+            if encoding:
+                txt, self.encoding = Utilities.readEncodedFileWithEncoding(
+                    fileName, encoding)
+            else:
+                txt, self.encoding = Utilities.readEncodedFile(fileName)
         except (UnicodeDecodeError, IOError) as why:
             QApplication.restoreOverrideCursor()
             E5MessageBox.critical(
@@ -2328,6 +2323,7 @@
         self.__setCurrentFile(fileName)
         
         fileEol = self.__textEdit.detectEolString(txt)
+        # TODO: editorconfig: end_of_line
         self.__textEdit.setEolModeByEolString(fileEol)
         
         self.__statusBar.showMessage(self.tr("File loaded"), 2000)
@@ -2336,36 +2332,57 @@
         """
         Private method to save to the given file.
         
-        @param fileName name of the file to save to (string)
-        @return flag indicating success (boolean)
+        @param fileName name of the file to save to
+        @type str
+        @return flag indicating success
+        @rtype bool
         """
+        res = self.__writeFile(fileName)
+        
+        if res:
+            self.editorSaved.emit()
+            self.__setCurrentFile(fileName)
+        
+        self.__checkActions()
+        
+        return res
+    
+    def __writeFile(self, fileName):
+        """
+        Private method to write the current editor text to a file.
+        
+        @param fileName name of the file to be written to
+        @type str
+        @return flag indicating success
+        @rtype bool
+        """
+        # TODO: editorconfig: apply end_of_line, trim_trailing_whitespace,
+        #       insert_final_newline
+        config = self.__loadEditorConfigObject(fileName)
+        
         QApplication.setOverrideCursor(Qt.WaitCursor)
         txt = self.__textEdit.text()
+        # TODO: editorconfig: insert_final_newline
         try:
+            editorConfigEncoding = self.__getEditorConfig(
+                "DefaultEncoding", nodefault=True, config=config)
             self.encoding = Utilities.writeEncodedFile(
-                fileName, txt, self.encoding)
+                fileName, txt, self.encoding,
+                forcedEncoding=editorConfigEncoding)
         except (IOError, Utilities.CodingError, UnicodeError) as why:
+            QApplication.restoreOverrideCursor()
             E5MessageBox.critical(
                 self, self.tr('Save File'),
                 self.tr('<p>The file <b>{0}</b> could not be saved.<br/>'
                         'Reason: {1}</p>')
                 .format(fileName, str(why)))
-            QApplication.restoreOverrideCursor()
-        
-            self.__checkActions()
-            
             return False
         
         QApplication.restoreOverrideCursor()
-        self.editorSaved.emit()
-        
-        self.__setCurrentFile(fileName)
         self.__statusBar.showMessage(self.tr("File saved"), 2000)
         
-        self.__checkActions()
-        
         return True
-
+    
     def __setCurrentFile(self, fileName):
         """
         Private method to register the file name of the current file.
@@ -2386,6 +2403,8 @@
         self.setWindowModified(False)
         
         self.setLanguage(self.__bindName(self.__textEdit.text(0)))
+        
+        self.__loadEditorConfig()
 
     def getFileName(self):
         """
@@ -2506,9 +2525,14 @@
         """
         Private method to configure the text display.
         """
+        # TODO: editorconfig: move these to separate method called, when
+        #   EditorConfig has been loaded
+        # TODO: editorconfig: tab_width
         self.__textEdit.setTabWidth(Preferences.getEditor("TabWidth"))
+        # TODO: editorconfig: indent_size
         self.__textEdit.setIndentationWidth(
             Preferences.getEditor("IndentWidth"))
+        # TODO: editorconfig: indent_style
         if self.lexer_ and self.lexer_.alwaysKeepTabs():
             self.__textEdit.setIndentationsUseTabs(True)
         else:
@@ -2610,6 +2634,7 @@
         """
         Private method to configure the eol mode of the editor.
         """
+        # TODO: editorconfig: end_of_line
         eolMode = Preferences.getEditor("EOLMode")
         eolMode = QsciScintilla.EolMode(eolMode)
         self.__textEdit.setEolMode(eolMode)
@@ -3239,7 +3264,100 @@
         else:
             self.filetype = filetype
         
+        # TODO: editorconfig: end_of_line
         fileEol = self.__textEdit.detectEolString(txt)
         self.__textEdit.setEolModeByEolString(fileEol)
         
         self.__textEdit.setModified(False)
+    
+    #######################################################################
+    ## 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.__curFile
+        
+        self.__editorConfig = self.__loadEditorConfigObject(fileName)
+    
+    def __loadEditorConfigObject(self, fileName):
+        """
+        Private method to load the EditorConfig properties for the given
+        file name.
+        
+        @param fileName name of the file
+        @type str
+        @return EditorConfig dictionary
+        @rtype dict
+        """
+        editorConfig = {}
+        
+        if fileName:
+            try:
+                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(fileName))
+        
+        return editorConfig
+    
+    def __getEditorConfig(self, option, nodefault=False, config=None):
+        """
+        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
+        @param config reference to an EditorConfig object or None
+        @type dict
+        @return value of requested setting or None if nothing was found and
+            nodefault parameter was True
+        @rtype any
+        """
+        if config is None:
+            config = self.__editorConfig
+        
+        if not config:
+            if nodefault:
+                return None
+            else:
+                return Preferences.getEditor(option)
+        
+        try:
+            if option == "EOLMode":
+                value = config["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 = config["charset"]
+        except KeyError:
+            value = None
+        
+        if value is None and not nodefault:
+            # use Preferences in case of error
+            value = Preferences.getEditor(option)
+        
+        return value

eric ide

mercurial