QScintilla/Editor.py

changeset 6099
a7fecbc392d7
parent 6092
f0d60c3de700
child 6101
b854a825d483
equal deleted inserted replaced
6098:a1d10c6ce103 6099:a7fecbc392d7
36 import Utilities 36 import Utilities
37 from Utilities import MouseUtilities 37 from Utilities import MouseUtilities
38 from Globals import qVersionTuple 38 from Globals import qVersionTuple
39 39
40 import UI.PixmapCache 40 import UI.PixmapCache
41
42 from ThirdParty.EditorConfig import editorconfig
41 43
42 EditorAutoCompletionListID = 1 44 EditorAutoCompletionListID = 1
43 TemplateCompletionListID = 2 45 TemplateCompletionListID = 2
44 46
45 47
190 # key: marker handle 192 # key: marker handle
191 # value: list of (warning message, warning type) 193 # value: list of (warning message, warning type)
192 self.notcoveredMarkers = [] # just a list of marker handles 194 self.notcoveredMarkers = [] # just a list of marker handles
193 self.showingNotcoveredMarkers = False 195 self.showingNotcoveredMarkers = False
194 196
197 self.__loadEditorConfig()
198
195 self.condHistory = [] 199 self.condHistory = []
196 self.lexer_ = None 200 self.lexer_ = None
197 self.__lexerReset = False 201 self.__lexerReset = False
198 self.completer = None 202 self.completer = None
199 self.encoding = Preferences.getEditor("DefaultEncoding") 203 self.encoding = self.__getEditorConfig("DefaultEncoding")
200 self.apiLanguage = '' 204 self.apiLanguage = ''
201 self.lastModified = 0 205 self.lastModified = 0
202 self.line = -1 206 self.line = -1
203 self.inReopenPrompt = False 207 self.inReopenPrompt = False
204 # true if the prompt to reload a changed source is present 208 # true if the prompt to reload a changed source is present
2958 2962
2959 try: 2963 try:
2960 if createIt and not os.path.exists(fn): 2964 if createIt and not os.path.exists(fn):
2961 f = open(fn, "w") 2965 f = open(fn, "w")
2962 f.close() 2966 f.close()
2967 if encoding == "":
2968 encoding = self.__getEditorConfig("DefaultEncoding",
2969 nodefault=True)
2963 if encoding: 2970 if encoding:
2964 txt, self.encoding = Utilities.readEncodedFileWithEncoding( 2971 txt, self.encoding = Utilities.readEncodedFileWithEncoding(
2965 fn, encoding) 2972 fn, encoding)
2966 else: 2973 else:
2967 txt, self.encoding = Utilities.readEncodedFile(fn) 2974 txt, self.encoding = Utilities.readEncodedFile(fn)
2976 QApplication.restoreOverrideCursor() 2983 QApplication.restoreOverrideCursor()
2977 raise 2984 raise
2978 fileEol = self.detectEolString(txt) 2985 fileEol = self.detectEolString(txt)
2979 2986
2980 modified = False 2987 modified = False
2988 # TODO: editorconfig: indent_style
2981 if (not Preferences.getEditor("TabForIndentation")) and \ 2989 if (not Preferences.getEditor("TabForIndentation")) and \
2982 Preferences.getEditor("ConvertTabsOnLoad") and \ 2990 Preferences.getEditor("ConvertTabsOnLoad") and \
2983 not (self.lexer_ and 2991 not (self.lexer_ and
2984 self.lexer_.alwaysKeepTabs()): 2992 self.lexer_.alwaysKeepTabs()):
2985 txtExpanded = txt.expandtabs(Preferences.getEditor("TabWidth")) 2993 txtExpanded = txt.expandtabs(Preferences.getEditor("TabWidth"))
2992 3000
2993 # get eric specific flags 3001 # get eric specific flags
2994 self.__processFlags() 3002 self.__processFlags()
2995 3003
2996 # perform automatic eol conversion 3004 # perform automatic eol conversion
2997 if Preferences.getEditor("AutomaticEOLConversion"): 3005 # TODO: editorconfig: end_of_line
3006 if self.__getEditorConfig("EOLMode", nodefault=True) or \
3007 Preferences.getEditor("AutomaticEOLConversion"):
2998 self.convertEols(self.eolMode()) 3008 self.convertEols(self.eolMode())
2999 else: 3009 else:
3000 self.setEolModeByEolString(fileEol) 3010 self.setEolModeByEolString(fileEol)
3001 3011
3002 self.extractTasks() 3012 self.extractTasks()
3025 3035
3026 @param fn filename to write to (string) 3036 @param fn filename to write to (string)
3027 @param backup flag indicating to save a backup (boolean) 3037 @param backup flag indicating to save a backup (boolean)
3028 @return flag indicating success (boolean) 3038 @return flag indicating success (boolean)
3029 """ 3039 """
3040 # TODO: editorconfig: trim_trailing_whitespace
3030 if Preferences.getEditor("StripTrailingWhitespace"): 3041 if Preferences.getEditor("StripTrailingWhitespace"):
3031 self.__removeTrailingWhitespace() 3042 self.__removeTrailingWhitespace()
3032 3043
3033 txt = self.text() 3044 txt = self.text()
3034 # work around glitch in scintilla: always make sure, 3045 # work around glitch in scintilla: always make sure,
3035 # that the last line is terminated properly 3046 # that the last line is terminated properly
3047 # TODO: editorconfig: insert_final_newline
3036 eol = self.getLineSeparator() 3048 eol = self.getLineSeparator()
3037 if eol: 3049 if eol:
3038 if len(txt) >= len(eol): 3050 if len(txt) >= len(eol):
3039 if txt[-len(eol):] != eol: 3051 if txt[-len(eol):] != eol:
3040 txt += eol 3052 txt += eol
3064 # if there was an error, ignore it 3076 # if there was an error, ignore it
3065 pass 3077 pass
3066 3078
3067 # now write text to the file fn 3079 # now write text to the file fn
3068 try: 3080 try:
3069 self.encoding = Utilities.writeEncodedFile(fn, txt, self.encoding) 3081 editorConfigEncoding = self.__getEditorConfig(
3082 "DefaultEncoding", nodefault=True)
3083 self.encoding = Utilities.writeEncodedFile(
3084 fn, txt, self.encoding, forcedEncoding=editorConfigEncoding)
3070 if createBackup and perms_valid: 3085 if createBackup and perms_valid:
3071 os.chmod(fn, permissions) 3086 os.chmod(fn, permissions)
3072 return True 3087 return True
3073 except (IOError, Utilities.CodingError, UnicodeError) as why: 3088 except (IOError, Utilities.CodingError, UnicodeError) as why:
3074 E5MessageBox.critical( 3089 E5MessageBox.critical(
3184 newName = fn 3199 newName = fn
3185 3200
3186 # save to project, if a project is loaded 3201 # save to project, if a project is loaded
3187 if self.project.isOpen() and \ 3202 if self.project.isOpen() and \
3188 self.project.startswithProjectPath(fn): 3203 self.project.startswithProjectPath(fn):
3204 # TODO: check against editorconfig
3189 self.setEolModeByEolString(self.project.getEolString()) 3205 self.setEolModeByEolString(self.project.getEolString())
3190 self.convertEols(self.eolMode()) 3206 self.convertEols(self.eolMode())
3191 else: 3207 else:
3192 fn = self.fileName 3208 fn = self.fileName
3193 3209
3210 self.__loadEditorConfig(fn)
3194 self.editorAboutToBeSaved.emit(self.fileName) 3211 self.editorAboutToBeSaved.emit(self.fileName)
3195 if self.writeFile(fn): 3212 if self.writeFile(fn):
3196 if saveas: 3213 if saveas:
3197 self.__clearBreakpoints(self.fileName) 3214 self.__clearBreakpoints(self.fileName)
3198 self.fileName = fn 3215 self.fileName = fn
3250 """ 3267 """
3251 self.__clearBreakpoints(fn) 3268 self.__clearBreakpoints(fn)
3252 3269
3253 self.fileName = fn 3270 self.fileName = fn
3254 self.setWindowTitle(self.fileName) 3271 self.setWindowTitle(self.fileName)
3272
3273 self.__loadEditorConfig()
3255 3274
3256 if self.lexer_ is None: 3275 if self.lexer_ is None:
3257 self.setLanguage(self.fileName) 3276 self.setLanguage(self.fileName)
3258 3277
3259 self.lastModified = QFileInfo(self.fileName).lastModified() 3278 self.lastModified = QFileInfo(self.fileName).lastModified()
4315 4334
4316 def __setTextDisplay(self): 4335 def __setTextDisplay(self):
4317 """ 4336 """
4318 Private method to configure the text display. 4337 Private method to configure the text display.
4319 """ 4338 """
4339 # TODO: editorconfig: tab_width
4320 self.setTabWidth(Preferences.getEditor("TabWidth")) 4340 self.setTabWidth(Preferences.getEditor("TabWidth"))
4341 # TODO: editorconfig: indent_size
4321 self.setIndentationWidth(Preferences.getEditor("IndentWidth")) 4342 self.setIndentationWidth(Preferences.getEditor("IndentWidth"))
4343 # TODO: editorconfig: indent_style
4322 if self.lexer_ and self.lexer_.alwaysKeepTabs(): 4344 if self.lexer_ and self.lexer_.alwaysKeepTabs():
4323 self.setIndentationsUseTabs(True) 4345 self.setIndentationsUseTabs(True)
4324 else: 4346 else:
4325 self.setIndentationsUseTabs( 4347 self.setIndentationsUseTabs(
4326 Preferences.getEditor("TabForIndentation")) 4348 Preferences.getEditor("TabForIndentation"))
4438 Private method to configure the eol mode of the editor. 4460 Private method to configure the eol mode of the editor.
4439 """ 4461 """
4440 if self.fileName and \ 4462 if self.fileName and \
4441 self.project.isOpen() and \ 4463 self.project.isOpen() and \
4442 self.project.isProjectFile(self.fileName): 4464 self.project.isProjectFile(self.fileName):
4443 self.setEolModeByEolString(self.project.getEolString()) 4465 # TODO: editorconfig: end_of_line
4444 else: 4466 eolMode = self.__getEditorConfig("EOLMode")
4445 eolMode = Preferences.getEditor("EOLMode") 4467 if eolMode is None:
4468 eolMode = self.project.getEolString()
4469 self.setEolModeByEolString(eolMode)
4470 else:
4471 eolMode = self.__getEditorConfig("EOLMode")
4446 eolMode = QsciScintilla.EolMode(eolMode) 4472 eolMode = QsciScintilla.EolMode(eolMode)
4447 self.setEolMode(eolMode) 4473 self.setEolMode(eolMode)
4448 self.__eolChanged() 4474 self.__eolChanged()
4449 4475
4450 def __setAutoCompletion(self): 4476 def __setAutoCompletion(self):
8014 """ 8040 """
8015 Private slot to execute the selected text in the shell window. 8041 Private slot to execute the selected text in the shell window.
8016 """ 8042 """
8017 txt = self.selectedText() 8043 txt = self.selectedText()
8018 e5App().getObject("Shell").executeLines(txt) 8044 e5App().getObject("Shell").executeLines(txt)
8045
8046 #######################################################################
8047 ## Methods implementing the interface to EditorConfig
8048 #######################################################################
8049
8050 def __loadEditorConfig(self, fileName=""):
8051 """
8052 Private method to load the EditorConfig properties.
8053
8054 @param fileName name of the file
8055 @type str
8056 """
8057 if not fileName:
8058 fileName = self.fileName
8059
8060 if fileName:
8061 try:
8062 self.__editorConfig = \
8063 editorconfig.get_properties(fileName)
8064 except editorconfig.EditorConfigError:
8065 E5MessageBox.warning(
8066 self,
8067 self.tr("EditorConfig Properties"),
8068 self.tr("""<p>The EditorConfig properties for file"""
8069 """ <b>{0}</b> could not be loaded.</p>""")
8070 .format(self.fileName))
8071 self.__editorConfig = {}
8072 else:
8073 self.__editorConfig = {}
8074
8075 def __getEditorConfig(self, option, nodefault=False):
8076 """
8077 Private method to get the requested option via EditorConfig.
8078
8079 If there is no EditorConfig defined, the equivalent built-in option
8080 will be used (Preferences.getEditor(). The option must be given as the
8081 Preferences option key. The mapping to the EditorConfig option name
8082 will be done within this method.
8083
8084 @param option Preferences option key
8085 @type str
8086 @param nodefault flag indicating to not get the default value from
8087 Preferences but return None instead
8088 @type bool
8089 @return value of requested setting or None if nothing was found and
8090 nodefault parameter was True
8091 @rtype any
8092 """
8093 if not self.__editorConfig:
8094 if nodefault:
8095 return None
8096 else:
8097 return Preferences.getEditor(option)
8098
8099 try:
8100 if option == "EOLMode":
8101 value = self.__editorConfig["end_of_line"]
8102 if value == "lf":
8103 value = QsciScintilla.EolUnix
8104 elif value == "crlf":
8105 value = QsciScintilla.EolWindows
8106 elif value == "cr":
8107 value = QsciScintilla.EolMac
8108 else:
8109 value = None
8110 elif option == "DefaultEncoding":
8111 value = self.__editorConfig["charset"]
8112 except KeyError:
8113 value = None
8114
8115 if value is None and not nodefault:
8116 # use Preferences in case of error
8117 value = Preferences.getEditor(option)
8118
8119 return value

eric ide

mercurial