12 |
12 |
13 class Lexer: |
13 class Lexer: |
14 """ |
14 """ |
15 Class to implement the lexer mixin class. |
15 Class to implement the lexer mixin class. |
16 """ |
16 """ |
|
17 |
17 def __init__(self): |
18 def __init__(self): |
18 """ |
19 """ |
19 Constructor |
20 Constructor |
20 """ |
21 """ |
21 self.commentString = '' |
22 self.commentString = "" |
22 self.streamCommentString = { |
23 self.streamCommentString = {"start": "", "end": ""} |
23 'start': '', |
24 self.boxCommentString = {"start": "", "middle": "", "end": ""} |
24 'end': '' |
25 |
25 } |
|
26 self.boxCommentString = { |
|
27 'start': '', |
|
28 'middle': '', |
|
29 'end': '' |
|
30 } |
|
31 |
|
32 # last indented line wrapper |
26 # last indented line wrapper |
33 self.lastIndented = -1 |
27 self.lastIndented = -1 |
34 self.lastIndentedIndex = -1 |
28 self.lastIndentedIndex = -1 |
35 |
29 |
36 # always keep tabs (for languages where tabs are esential |
30 # always keep tabs (for languages where tabs are esential |
37 self._alwaysKeepTabs = False |
31 self._alwaysKeepTabs = False |
38 |
32 |
39 # descriptions for keyword sets |
33 # descriptions for keyword sets |
40 self.keywordSetDescriptions = [] |
34 self.keywordSetDescriptions = [] |
41 |
35 |
42 def initProperties(self): |
36 def initProperties(self): |
43 """ |
37 """ |
44 Public slot to initialize the properties. |
38 Public slot to initialize the properties. |
45 """ |
39 """ |
46 # default implementation is a do nothing |
40 # default implementation is a do nothing |
47 return |
41 return |
48 |
42 |
49 def commentStr(self): |
43 def commentStr(self): |
50 """ |
44 """ |
51 Public method to return the comment string. |
45 Public method to return the comment string. |
52 |
46 |
53 @return comment string (string) |
47 @return comment string (string) |
54 """ |
48 """ |
55 return self.commentString |
49 return self.commentString |
56 |
50 |
57 def canBlockComment(self): |
51 def canBlockComment(self): |
58 """ |
52 """ |
59 Public method to determine, whether the lexer language supports a |
53 Public method to determine, whether the lexer language supports a |
60 block comment. |
54 block comment. |
61 |
55 |
62 @return flag (boolean) |
56 @return flag (boolean) |
63 """ |
57 """ |
64 return self.commentString != "" |
58 return self.commentString != "" |
65 |
59 |
66 def streamCommentStr(self): |
60 def streamCommentStr(self): |
67 """ |
61 """ |
68 Public method to return the stream comment strings. |
62 Public method to return the stream comment strings. |
69 |
63 |
70 @return stream comment strings (dictionary with two strings) |
64 @return stream comment strings (dictionary with two strings) |
71 """ |
65 """ |
72 return self.streamCommentString |
66 return self.streamCommentString |
73 |
67 |
74 def canStreamComment(self): |
68 def canStreamComment(self): |
75 """ |
69 """ |
76 Public method to determine, whether the lexer language supports a |
70 Public method to determine, whether the lexer language supports a |
77 stream comment. |
71 stream comment. |
78 |
72 |
79 @return flag (boolean) |
73 @return flag (boolean) |
80 """ |
74 """ |
81 return ( |
75 return ( |
82 self.streamCommentString['start'] != "" and |
76 self.streamCommentString["start"] != "" |
83 self.streamCommentString['end'] != "" |
77 and self.streamCommentString["end"] != "" |
84 ) |
78 ) |
85 |
79 |
86 def boxCommentStr(self): |
80 def boxCommentStr(self): |
87 """ |
81 """ |
88 Public method to return the box comment strings. |
82 Public method to return the box comment strings. |
89 |
83 |
90 @return box comment strings (dictionary with three QStrings) |
84 @return box comment strings (dictionary with three QStrings) |
91 """ |
85 """ |
92 return self.boxCommentString |
86 return self.boxCommentString |
93 |
87 |
94 def canBoxComment(self): |
88 def canBoxComment(self): |
95 """ |
89 """ |
96 Public method to determine, whether the lexer language supports a |
90 Public method to determine, whether the lexer language supports a |
97 box comment. |
91 box comment. |
98 |
92 |
99 @return flag (boolean) |
93 @return flag (boolean) |
100 """ |
94 """ |
101 return ( |
95 return ( |
102 (self.boxCommentString['start'] != "") and |
96 (self.boxCommentString["start"] != "") |
103 (self.boxCommentString['middle'] != "") and |
97 and (self.boxCommentString["middle"] != "") |
104 (self.boxCommentString['end'] != "") |
98 and (self.boxCommentString["end"] != "") |
105 ) |
99 ) |
106 |
100 |
107 def alwaysKeepTabs(self): |
101 def alwaysKeepTabs(self): |
108 """ |
102 """ |
109 Public method to check, if tab conversion is allowed. |
103 Public method to check, if tab conversion is allowed. |
110 |
104 |
111 @return flag indicating to keep tabs (boolean) |
105 @return flag indicating to keep tabs (boolean) |
112 """ |
106 """ |
113 return self._alwaysKeepTabs |
107 return self._alwaysKeepTabs |
114 |
108 |
115 def hasSmartIndent(self): |
109 def hasSmartIndent(self): |
116 """ |
110 """ |
117 Public method indicating whether lexer can do smart indentation. |
111 Public method indicating whether lexer can do smart indentation. |
118 |
112 |
119 @return flag indicating availability of smartIndentLine and |
113 @return flag indicating availability of smartIndentLine and |
120 smartIndentSelection methods (boolean) |
114 smartIndentSelection methods (boolean) |
121 """ |
115 """ |
122 return hasattr(self, 'getIndentationDifference') |
116 return hasattr(self, "getIndentationDifference") |
123 |
117 |
124 def smartIndentLine(self, editor): |
118 def smartIndentLine(self, editor): |
125 """ |
119 """ |
126 Public method to handle smart indentation for a line. |
120 Public method to handle smart indentation for a line. |
127 |
121 |
128 @param editor reference to the QScintilla editor object |
122 @param editor reference to the QScintilla editor object |
129 """ |
123 """ |
130 cline, cindex = editor.getCursorPosition() |
124 cline, cindex = editor.getCursorPosition() |
131 |
125 |
132 # get leading spaces |
126 # get leading spaces |
133 lead_spaces = editor.indentation(cline) |
127 lead_spaces = editor.indentation(cline) |
134 |
128 |
135 # get the indentation difference |
129 # get the indentation difference |
136 indentDifference = self.getIndentationDifference(cline, editor) |
130 indentDifference = self.getIndentationDifference(cline, editor) |
137 |
131 |
138 if indentDifference != 0: |
132 if indentDifference != 0: |
139 editor.setIndentation(cline, lead_spaces + indentDifference) |
133 editor.setIndentation(cline, lead_spaces + indentDifference) |
140 editor.setCursorPosition(cline, cindex + indentDifference) |
134 editor.setCursorPosition(cline, cindex + indentDifference) |
141 |
135 |
142 self.lastIndented = cline |
136 self.lastIndented = cline |
143 |
137 |
144 def smartIndentSelection(self, editor): |
138 def smartIndentSelection(self, editor): |
145 """ |
139 """ |
146 Public method to handle smart indentation for a selection of lines. |
140 Public method to handle smart indentation for a selection of lines. |
147 |
141 |
148 Note: The assumption is, that the first line determines the new |
142 Note: The assumption is, that the first line determines the new |
149 indentation level. |
143 indentation level. |
150 |
144 |
151 @param editor reference to the QScintilla editor object |
145 @param editor reference to the QScintilla editor object |
152 """ |
146 """ |
153 if not editor.hasSelectedText(): |
147 if not editor.hasSelectedText(): |
154 return |
148 return |
155 |
149 |
156 # get the selection |
150 # get the selection |
157 lineFrom, indexFrom, lineTo, indexTo = editor.getSelection() |
151 lineFrom, indexFrom, lineTo, indexTo = editor.getSelection() |
158 if lineFrom != self.lastIndented: |
152 if lineFrom != self.lastIndented: |
159 self.lastIndentedIndex = indexFrom |
153 self.lastIndentedIndex = indexFrom |
160 |
154 |
161 endLine = lineTo if indexTo else lineTo - 1 |
155 endLine = lineTo if indexTo else lineTo - 1 |
162 |
156 |
163 # get the indentation difference |
157 # get the indentation difference |
164 indentDifference = self.getIndentationDifference(lineFrom, editor) |
158 indentDifference = self.getIndentationDifference(lineFrom, editor) |
165 |
159 |
166 editor.beginUndoAction() |
160 editor.beginUndoAction() |
167 # iterate over the lines |
161 # iterate over the lines |
168 for line in range(lineFrom, endLine + 1): |
162 for line in range(lineFrom, endLine + 1): |
169 editor.setIndentation( |
163 editor.setIndentation(line, editor.indentation(line) + indentDifference) |
170 line, editor.indentation(line) + indentDifference) |
|
171 editor.endUndoAction() |
164 editor.endUndoAction() |
172 |
165 |
173 indexStart = ( |
166 indexStart = indexFrom + indentDifference if self.lastIndentedIndex != 0 else 0 |
174 indexFrom + indentDifference |
|
175 if self.lastIndentedIndex != 0 else |
|
176 0 |
|
177 ) |
|
178 if indexStart < 0: |
167 if indexStart < 0: |
179 indexStart = 0 |
168 indexStart = 0 |
180 indexEnd = indexTo != 0 and (indexTo + indentDifference) or 0 |
169 indexEnd = indexTo != 0 and (indexTo + indentDifference) or 0 |
181 if indexEnd < 0: |
170 if indexEnd < 0: |
182 indexEnd = 0 |
171 indexEnd = 0 |
183 editor.setSelection(lineFrom, indexStart, lineTo, indexEnd) |
172 editor.setSelection(lineFrom, indexStart, lineTo, indexEnd) |
184 |
173 |
185 self.lastIndented = lineFrom |
174 self.lastIndented = lineFrom |
186 |
175 |
187 def autoCompletionWordSeparators(self): |
176 def autoCompletionWordSeparators(self): |
188 """ |
177 """ |
189 Public method to return the list of separators for autocompletion. |
178 Public method to return the list of separators for autocompletion. |
190 |
179 |
191 @return list of separators (list of strings) |
180 @return list of separators (list of strings) |
192 """ |
181 """ |
193 return [] |
182 return [] |
194 |
183 |
195 def isCommentStyle(self, style): |
184 def isCommentStyle(self, style): |
196 """ |
185 """ |
197 Public method to check, if a style is a comment style. |
186 Public method to check, if a style is a comment style. |
198 |
187 |
199 @param style style to check (integer) |
188 @param style style to check (integer) |
200 @return flag indicating a comment style (boolean) |
189 @return flag indicating a comment style (boolean) |
201 """ |
190 """ |
202 return True |
191 return True |
203 |
192 |
204 def isStringStyle(self, style): |
193 def isStringStyle(self, style): |
205 """ |
194 """ |
206 Public method to check, if a style is a string style. |
195 Public method to check, if a style is a string style. |
207 |
196 |
208 @param style style to check (integer) |
197 @param style style to check (integer) |
209 @return flag indicating a string style (boolean) |
198 @return flag indicating a string style (boolean) |
210 """ |
199 """ |
211 return True |
200 return True |
212 |
201 |
213 def keywords(self, kwSet): |
202 def keywords(self, kwSet): |
214 """ |
203 """ |
215 Public method to get the keywords. |
204 Public method to get the keywords. |
216 |
205 |
217 @param kwSet number of the keyword set |
206 @param kwSet number of the keyword set |
218 @type int |
207 @type int |
219 @return space separated list of keywords |
208 @return space separated list of keywords |
220 @rtype str or None |
209 @rtype str or None |
221 """ |
210 """ |
226 return self.defaultKeywords(kwSet) |
215 return self.defaultKeywords(kwSet) |
227 else: |
216 else: |
228 return kw |
217 return kw |
229 else: |
218 else: |
230 return self.defaultKeywords(kwSet) |
219 return self.defaultKeywords(kwSet) |
231 |
220 |
232 def keywordsDescription(self, kwSet): |
221 def keywordsDescription(self, kwSet): |
233 """ |
222 """ |
234 Public method to get the description for a keywords set. |
223 Public method to get the description for a keywords set. |
235 |
224 |
236 @param kwSet number of the keyword set |
225 @param kwSet number of the keyword set |
237 @type int |
226 @type int |
238 @return description of the keyword set |
227 @return description of the keyword set |
239 @rtype str |
228 @rtype str |
240 """ |
229 """ |
241 if kwSet > len(self.keywordSetDescriptions): |
230 if kwSet > len(self.keywordSetDescriptions): |
242 return "" |
231 return "" |
243 else: |
232 else: |
244 return self.keywordSetDescriptions[kwSet - 1] |
233 return self.keywordSetDescriptions[kwSet - 1] |
245 |
234 |
246 def defaultKeywords(self, kwSet): |
235 def defaultKeywords(self, kwSet): |
247 """ |
236 """ |
248 Public method to get the default keywords. |
237 Public method to get the default keywords. |
249 |
238 |
250 @param kwSet number of the keyword set |
239 @param kwSet number of the keyword set |
251 @type int |
240 @type int |
252 @return space separated list of keywords |
241 @return space separated list of keywords |
253 @rtype str or None |
242 @rtype str or None |
254 """ |
243 """ |
255 return None # __IGNORE_WARNING_M831__ |
244 return None # __IGNORE_WARNING_M831__ |
256 |
245 |
257 def maximumKeywordSet(self): |
246 def maximumKeywordSet(self): |
258 """ |
247 """ |
259 Public method to get the maximum keyword set. |
248 Public method to get the maximum keyword set. |
260 |
249 |
261 Note: A return value of 0 indicates to determine this dynamically. |
250 Note: A return value of 0 indicates to determine this dynamically. |
262 |
251 |
263 @return maximum keyword set |
252 @return maximum keyword set |
264 @rtype int |
253 @rtype int |
265 """ |
254 """ |
266 return len(self.keywordSetDescriptions) |
255 return len(self.keywordSetDescriptions) |
267 |
256 |
268 def lexerName(self): |
257 def lexerName(self): |
269 """ |
258 """ |
270 Public method to return the lexer name. |
259 Public method to return the lexer name. |
271 |
260 |
272 @return lexer name (string) |
261 @return lexer name (string) |
273 """ |
262 """ |
274 return self.lexer() |
263 return self.lexer() |
275 |
264 |
276 def hasSubstyles(self): |
265 def hasSubstyles(self): |
277 """ |
266 """ |
278 Public method to indicate the support of sub-styles. |
267 Public method to indicate the support of sub-styles. |
279 |
268 |
280 @return flag indicating sub-styling support |
269 @return flag indicating sub-styling support |
281 @rtype bool |
270 @rtype bool |
282 """ |
271 """ |
283 return False |
272 return False |