src/eric7/QScintilla/Lexers/LexerPython.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9359
8d3f5cf4f819
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
18 18
19 class LexerPython(SubstyledLexer, QsciLexerPython): 19 class LexerPython(SubstyledLexer, QsciLexerPython):
20 """ 20 """
21 Subclass to implement some additional lexer dependant methods. 21 Subclass to implement some additional lexer dependant methods.
22 """ 22 """
23
23 def __init__(self, variant="", parent=None): 24 def __init__(self, variant="", parent=None):
24 """ 25 """
25 Constructor 26 Constructor
26 27
27 @param variant name of the language variant (string) 28 @param variant name of the language variant (string)
28 @param parent parent widget of this lexer 29 @param parent parent widget of this lexer
29 """ 30 """
30 QsciLexerPython.__init__(self, parent) 31 QsciLexerPython.__init__(self, parent)
31 SubstyledLexer.__init__(self) 32 SubstyledLexer.__init__(self)
32 33
33 self.variant = variant 34 self.variant = variant
34 self.commentString = "#" 35 self.commentString = "#"
35 36
36 self.keywordSetDescriptions = [ 37 self.keywordSetDescriptions = [
37 self.tr("Keywords"), 38 self.tr("Keywords"),
38 self.tr("Highlighted identifiers"), 39 self.tr("Highlighted identifiers"),
39 ] 40 ]
40 41
41 ############################################################## 42 ##############################################################
42 ## default sub-style definitions 43 ## default sub-style definitions
43 ############################################################## 44 ##############################################################
44 45
45 # list of style numbers, that support sub-styling 46 # list of style numbers, that support sub-styling
46 self.baseStyles = [11] 47 self.baseStyles = [11]
47 48
48 self.defaultSubStyles = { 49 self.defaultSubStyles = {
49 11: { 50 11: {
50 0: { 51 0: {
51 "Description": self.tr("Standard Library Modules"), 52 "Description": self.tr("Standard Library Modules"),
52 "Words": """ 53 "Words": """
73 weakref webbrowser winreg winsound wsgiref xdrlib xml xmlrpc zipapp zipfile 74 weakref webbrowser winreg winsound wsgiref xdrlib xml xmlrpc zipapp zipfile
74 zipimport zlib zoneinfo""", 75 zipimport zlib zoneinfo""",
75 "Style": { 76 "Style": {
76 "fore": 0xDD9900, 77 "fore": 0xDD9900,
77 "font_bold": True, 78 "font_bold": True,
78 } 79 },
79 }, 80 },
80 1: { 81 1: {
81 "Description": self.tr("__future__ Imports"), 82 "Description": self.tr("__future__ Imports"),
82 "Words": """ 83 "Words": """
83 __future__ absolute_import annotations division generators generator_stop 84 __future__ absolute_import annotations division generators generator_stop
84 nested_scopes print_function unicode_literals with_statement""", 85 nested_scopes print_function unicode_literals with_statement""",
85 "Style": { 86 "Style": {
86 "fore": 0xEE00AA, 87 "fore": 0xEE00AA,
87 "font_italic": True, 88 "font_italic": True,
88 } 89 },
89 }, 90 },
90 2: { 91 2: {
91 "Description": self.tr("PyQt5/6 Modules"), 92 "Description": self.tr("PyQt5/6 Modules"),
92 "Words": """ 93 "Words": """
93 PyQt5 PyQt6 Qsci Qt Qt3DAnimation Qt3DCore Qt3DExtras Qt3DInput Qt3DLogic 94 PyQt5 PyQt6 Qsci Qt Qt3DAnimation Qt3DCore Qt3DExtras Qt3DInput Qt3DLogic
100 QtWebEngineWidgets QtWebSockets QtWidgets QtWinExtras QtX11Extras QtXml 101 QtWebEngineWidgets QtWebSockets QtWidgets QtWinExtras QtX11Extras QtXml
101 QtXmlPatterns sip""", 102 QtXmlPatterns sip""",
102 "Style": { 103 "Style": {
103 "fore": 0x44AADD, 104 "fore": 0x44AADD,
104 "font_bold": True, 105 "font_bold": True,
105 } 106 },
106 }, 107 },
107 3: { 108 3: {
108 "Description": self.tr("Cython Specifics"), 109 "Description": self.tr("Cython Specifics"),
109 "Words": "cython pyximport Cython __cinit__ __dealloc__", 110 "Words": "cython pyximport Cython __cinit__ __dealloc__",
110 "Style": { 111 "Style": {
111 "fore": 0xdd0000, 112 "fore": 0xDD0000,
112 "font_bold": True, 113 "font_bold": True,
113 } 114 },
114 }, 115 },
115 }, 116 },
116 } 117 }
117 118
118 def language(self): 119 def language(self):
119 """ 120 """
120 Public method to get the lexer language. 121 Public method to get the lexer language.
121 122
122 @return lexer language (string) 123 @return lexer language (string)
123 """ 124 """
124 if not self.variant: 125 if not self.variant:
125 return QsciLexerPython.language(self) 126 return QsciLexerPython.language(self)
126 else: 127 else:
127 return self.variant 128 return self.variant
128 129
129 def initProperties(self): 130 def initProperties(self):
130 """ 131 """
131 Public slot to initialize the properties. 132 Public slot to initialize the properties.
132 """ 133 """
133 self.setIndentationWarning( 134 self.setIndentationWarning(Preferences.getEditor("PythonBadIndentation"))
134 Preferences.getEditor("PythonBadIndentation"))
135 self.setFoldComments(Preferences.getEditor("PythonFoldComment")) 135 self.setFoldComments(Preferences.getEditor("PythonFoldComment"))
136 self.setFoldQuotes(Preferences.getEditor("PythonFoldString")) 136 self.setFoldQuotes(Preferences.getEditor("PythonFoldString"))
137 if not Preferences.getEditor("PythonAutoIndent"): 137 if not Preferences.getEditor("PythonAutoIndent"):
138 self.setAutoIndentStyle(QsciScintilla.AiMaintain) 138 self.setAutoIndentStyle(QsciScintilla.AiMaintain)
139 with contextlib.suppress(AttributeError): 139 with contextlib.suppress(AttributeError):
140 self.setV2UnicodeAllowed( 140 self.setV2UnicodeAllowed(Preferences.getEditor("PythonAllowV2Unicode"))
141 Preferences.getEditor("PythonAllowV2Unicode")) 141 self.setV3BinaryOctalAllowed(Preferences.getEditor("PythonAllowV3Binary"))
142 self.setV3BinaryOctalAllowed(
143 Preferences.getEditor("PythonAllowV3Binary"))
144 self.setV3BytesAllowed(Preferences.getEditor("PythonAllowV3Bytes")) 142 self.setV3BytesAllowed(Preferences.getEditor("PythonAllowV3Bytes"))
145 with contextlib.suppress(AttributeError): 143 with contextlib.suppress(AttributeError):
146 self.setFoldQuotes(Preferences.getEditor("PythonFoldQuotes")) 144 self.setFoldQuotes(Preferences.getEditor("PythonFoldQuotes"))
147 self.setStringsOverNewlineAllowed( 145 self.setStringsOverNewlineAllowed(
148 Preferences.getEditor("PythonStringsOverNewLineAllowed")) 146 Preferences.getEditor("PythonStringsOverNewLineAllowed")
147 )
149 with contextlib.suppress(AttributeError): 148 with contextlib.suppress(AttributeError):
150 self.setHighlightSubidentifiers( 149 self.setHighlightSubidentifiers(
151 Preferences.getEditor("PythonHighlightSubidentifier")) 150 Preferences.getEditor("PythonHighlightSubidentifier")
152 151 )
152
153 def getIndentationDifference(self, line, editor): 153 def getIndentationDifference(self, line, editor):
154 """ 154 """
155 Public method to determine the difference for the new indentation. 155 Public method to determine the difference for the new indentation.
156 156
157 @param line line to perform the calculation for (integer) 157 @param line line to perform the calculation for (integer)
158 @param editor QScintilla editor 158 @param editor QScintilla editor
159 @return amount of difference in indentation (integer) 159 @return amount of difference in indentation (integer)
160 """ 160 """
161 indent_width = editor.getEditorConfig('IndentWidth') 161 indent_width = editor.getEditorConfig("IndentWidth")
162 162
163 lead_spaces = editor.indentation(line) 163 lead_spaces = editor.indentation(line)
164 164
165 pline = line - 1 165 pline = line - 1
166 while pline >= 0 and re.match(r'^\s*(#.*)?$', editor.text(pline)): 166 while pline >= 0 and re.match(r"^\s*(#.*)?$", editor.text(pline)):
167 pline -= 1 167 pline -= 1
168 168
169 if pline < 0: 169 if pline < 0:
170 last = 0 170 last = 0
171 else: 171 else:
172 previous_lead_spaces = editor.indentation(pline) 172 previous_lead_spaces = editor.indentation(pline)
173 # trailing spaces 173 # trailing spaces
174 m = re.search(r':\s*(#.*)?$', editor.text(pline)) 174 m = re.search(r":\s*(#.*)?$", editor.text(pline))
175 last = previous_lead_spaces 175 last = previous_lead_spaces
176 if m: 176 if m:
177 last += indent_width 177 last += indent_width
178 else: 178 else:
179 # special cases, like pass (unindent) or return (also unindent) 179 # special cases, like pass (unindent) or return (also unindent)
180 m = re.search(r'(pass\s*(#.*)?$)|(^[^#]return)', 180 m = re.search(r"(pass\s*(#.*)?$)|(^[^#]return)", editor.text(pline))
181 editor.text(pline))
182 if m: 181 if m:
183 last -= indent_width 182 last -= indent_width
184 183
185 indentDifference = ( 184 indentDifference = (
186 last - lead_spaces 185 last - lead_spaces
187 if (lead_spaces % indent_width != 0 or 186 if (
188 lead_spaces == 0 or 187 lead_spaces % indent_width != 0
189 self.lastIndented != line) else 188 or lead_spaces == 0
190 -indent_width # __IGNORE_WARNING_W503__ 189 or self.lastIndented != line
190 )
191 else -indent_width # __IGNORE_WARNING_W503__
191 ) 192 )
192 193
193 return indentDifference 194 return indentDifference
194 195
195 def autoCompletionWordSeparators(self): 196 def autoCompletionWordSeparators(self):
196 """ 197 """
197 Public method to return the list of separators for autocompletion. 198 Public method to return the list of separators for autocompletion.
198 199
199 @return list of separators (list of strings) 200 @return list of separators (list of strings)
200 """ 201 """
201 return ['.'] 202 return ["."]
202 203
203 def isCommentStyle(self, style): 204 def isCommentStyle(self, style):
204 """ 205 """
205 Public method to check, if a style is a comment style. 206 Public method to check, if a style is a comment style.
206 207
207 @param style style to check (integer) 208 @param style style to check (integer)
208 @return flag indicating a comment style (boolean) 209 @return flag indicating a comment style (boolean)
209 """ 210 """
210 return style in [QsciLexerPython.Comment, 211 return style in [QsciLexerPython.Comment, QsciLexerPython.CommentBlock]
211 QsciLexerPython.CommentBlock] 212
212
213 def isStringStyle(self, style): 213 def isStringStyle(self, style):
214 """ 214 """
215 Public method to check, if a style is a string style. 215 Public method to check, if a style is a string style.
216 216
217 @param style style to check (integer) 217 @param style style to check (integer)
218 @return flag indicating a string style (boolean) 218 @return flag indicating a string style (boolean)
219 """ 219 """
220 return style in [QsciLexerPython.DoubleQuotedString, 220 return style in [
221 QsciLexerPython.SingleQuotedString, 221 QsciLexerPython.DoubleQuotedString,
222 QsciLexerPython.TripleDoubleQuotedString, 222 QsciLexerPython.SingleQuotedString,
223 QsciLexerPython.TripleSingleQuotedString, 223 QsciLexerPython.TripleDoubleQuotedString,
224 QsciLexerPython.UnclosedString] 224 QsciLexerPython.TripleSingleQuotedString,
225 225 QsciLexerPython.UnclosedString,
226 ]
227
226 def defaultKeywords(self, kwSet): 228 def defaultKeywords(self, kwSet):
227 """ 229 """
228 Public method to get the default keywords. 230 Public method to get the default keywords.
229 231
230 @param kwSet number of the keyword set (integer) 232 @param kwSet number of the keyword set (integer)
231 @return string giving the keywords (string) or None 233 @return string giving the keywords (string) or None
232 """ 234 """
233 if kwSet == 1: 235 if kwSet == 1:
234 if self.language() == "Python3": 236 if self.language() == "Python3":
235 import keyword 237 import keyword
238
236 keywords = " ".join(keyword.kwlist) 239 keywords = " ".join(keyword.kwlist)
237 elif self.language() == "MicroPython": 240 elif self.language() == "MicroPython":
238 keywords = ("False None True and as assert break class " 241 keywords = (
239 "continue def del elif else except finally for " 242 "False None True and as assert break class "
240 "from global if import in is lambda nonlocal not " 243 "continue def del elif else except finally for "
241 "or pass raise return try while with yield") 244 "from global if import in is lambda nonlocal not "
245 "or pass raise return try while with yield"
246 )
242 elif self.language() == "Cython": 247 elif self.language() == "Cython":
243 keywords = ("False None True and as assert break class " 248 keywords = (
244 "continue def del elif else except finally for " 249 "False None True and as assert break class "
245 "from global if import in is lambda nonlocal not " 250 "continue def del elif else except finally for "
246 "or pass raise return try while with yield " 251 "from global if import in is lambda nonlocal not "
247 "cdef cimport cpdef ctypedef") 252 "or pass raise return try while with yield "
253 "cdef cimport cpdef ctypedef"
254 )
248 else: 255 else:
249 keywords = QsciLexerPython.keywords(self, kwSet) 256 keywords = QsciLexerPython.keywords(self, kwSet)
250 else: 257 else:
251 keywords = QsciLexerPython.keywords(self, kwSet) 258 keywords = QsciLexerPython.keywords(self, kwSet)
252 259
253 return keywords 260 return keywords
254 261
255 def maximumKeywordSet(self): 262 def maximumKeywordSet(self):
256 """ 263 """
257 Public method to get the maximum keyword set. 264 Public method to get the maximum keyword set.
258 265
259 @return maximum keyword set (integer) 266 @return maximum keyword set (integer)
260 """ 267 """
261 return 2 268 return 2

eric ide

mercurial