]>
git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/LexPython.cxx
492d21c7d97ba660ee588e31fa6f029bb2dfd8e1
1 // SciTE - Scintilla based Text Editor
2 // LexPython.cxx - lexer for Python
3 // Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
4 // The License.txt file describes the conditions under which this software may be distributed.
17 #include "Scintilla.h"
20 static void ClassifyWordPy(unsigned int start
, unsigned int end
, WordList
&keywords
, Accessor
&styler
, char *prevWord
) {
22 bool wordIsNumber
= isdigit(styler
[start
]);
23 for (unsigned int i
= 0; i
< end
- start
+ 1 && i
< 30; i
++) {
24 s
[i
] = styler
[start
+ i
];
27 char chAttr
= SCE_P_IDENTIFIER
;
28 if (0 == strcmp(prevWord
, "class"))
29 chAttr
= SCE_P_CLASSNAME
;
30 else if (0 == strcmp(prevWord
, "def"))
31 chAttr
= SCE_P_DEFNAME
;
32 else if (wordIsNumber
)
33 chAttr
= SCE_P_NUMBER
;
34 else if (keywords
.InList(s
))
36 // make sure that dot-qualifiers inside the word are lexed correct
37 else for (unsigned int i
= 0; i
< end
- start
+ 1; i
++) {
38 if (styler
[start
+ i
] == '.') {
39 styler
.ColourTo(start
+ i
- 1, chAttr
);
40 styler
.ColourTo(start
+ i
, SCE_P_OPERATOR
);
43 styler
.ColourTo(end
, chAttr
);
47 static bool IsPyComment(Accessor
&styler
, int pos
, int len
) {
48 return len
>0 && styler
[pos
]=='#';
51 static void ColourisePyDoc(unsigned int startPos
, int length
, int initStyle
,
52 WordList
*keywordlists
[], Accessor
&styler
) {
54 int lengthDoc
= startPos
+ length
;
56 // Backtrack to previous line in case need to fix its fold status or tab whinging
57 int lineCurrent
= styler
.GetLine(startPos
);
59 if (lineCurrent
> 0) {
61 startPos
= styler
.LineStart(lineCurrent
);
63 initStyle
= SCE_P_DEFAULT
;
65 initStyle
= styler
.StyleAt(startPos
-1);
69 // Python uses a different mask because bad indentation is marked by oring with 32
70 styler
.StartAt(startPos
, 127);
72 WordList
&keywords
= *keywordlists
[0];
74 bool fold
= styler
.GetPropertyInt("fold");
75 int whingeLevel
= styler
.GetPropertyInt("tab.timmy.whinge.level");
82 int state
= initStyle
& 31;
84 int indentCurrent
= styler
.IndentAmount(lineCurrent
, &spaceFlags
, IsPyComment
);
85 if ((state
== SCE_P_TRIPLE
) || (state
== SCE_P_TRIPLEDOUBLE
))
86 indentCurrent
|= SC_FOLDLEVELWHITEFLAG
;
90 char chNext
= styler
[startPos
];
91 styler
.StartSegment(startPos
);
92 bool atStartLine
= true;
93 for (int i
= startPos
; i
< lengthDoc
; i
++) {
96 char chBad
= static_cast<char>(64);
97 char chGood
= static_cast<char>(0);
98 char chFlags
= chGood
;
99 if (whingeLevel
== 1) {
100 chFlags
= (spaceFlags
& wsInconsistent
) ? chBad
: chGood
;
101 } else if (whingeLevel
== 2) {
102 chFlags
= (spaceFlags
& wsSpaceTab
) ? chBad
: chGood
;
103 } else if (whingeLevel
== 3) {
104 chFlags
= (spaceFlags
& wsSpace
) ? chBad
: chGood
;
105 } else if (whingeLevel
== 4) {
106 chFlags
= (spaceFlags
& wsTab
) ? chBad
: chGood
;
108 styler
.SetFlags(chFlags
, static_cast<char>(state
));
113 chNext
= styler
.SafeGetCharAt(i
+ 1);
114 char chNext2
= styler
.SafeGetCharAt(i
+ 2);
116 if ((ch
== '\r' && chNext
!= '\n') || (ch
== '\n') || (i
== lengthDoc
)) {
117 if ((state
== SCE_P_DEFAULT
) || (state
== SCE_P_TRIPLE
) || (state
== SCE_P_TRIPLEDOUBLE
)) {
118 // Perform colourisation of white space and triple quoted strings at end of each line to allow
119 // tab marking to work inside white space and triple quoted strings
120 styler
.ColourTo(i
, state
);
123 int lev
= indentCurrent
;
124 int indentNext
= styler
.IndentAmount(lineCurrent
+ 1, &spaceFlags
, IsPyComment
);
125 if ((state
== SCE_P_TRIPLE
) || (state
== SCE_P_TRIPLEDOUBLE
))
126 indentNext
|= SC_FOLDLEVELWHITEFLAG
;
127 if (!(indentCurrent
& SC_FOLDLEVELWHITEFLAG
)) {
128 // Only non whitespace lines can be headers
129 if ((indentCurrent
& SC_FOLDLEVELNUMBERMASK
) < (indentNext
& SC_FOLDLEVELNUMBERMASK
)) {
130 lev
|= SC_FOLDLEVELHEADERFLAG
;
131 } else if (indentNext
& SC_FOLDLEVELWHITEFLAG
) {
132 // Line after is blank so check the next - maybe should continue further?
134 int indentNext2
= styler
.IndentAmount(lineCurrent
+ 2, &spaceFlags2
, IsPyComment
);
135 if ((indentCurrent
& SC_FOLDLEVELNUMBERMASK
) < (indentNext2
& SC_FOLDLEVELNUMBERMASK
)) {
136 lev
|= SC_FOLDLEVELHEADERFLAG
;
140 indentCurrent
= indentNext
;
142 styler
.SetLevel(lineCurrent
, lev
);
148 if (styler
.IsLeadByte(ch
)) {
149 chNext
= styler
.SafeGetCharAt(i
+ 2);
156 if (state
== SCE_P_STRINGEOL
) {
157 if (ch
!= '\r' && ch
!= '\n') {
158 styler
.ColourTo(i
- 1, state
);
159 state
= SCE_P_DEFAULT
;
162 if (state
== SCE_P_DEFAULT
) {
163 if (iswordstart(ch
)) {
164 styler
.ColourTo(i
- 1, state
);
166 } else if (ch
== '#') {
167 styler
.ColourTo(i
- 1, state
);
168 state
= chNext
== '#' ? SCE_P_COMMENTBLOCK
: SCE_P_COMMENTLINE
;
169 } else if (ch
== '\"') {
170 styler
.ColourTo(i
- 1, state
);
171 if (chNext
== '\"' && chNext2
== '\"') {
173 state
= SCE_P_TRIPLEDOUBLE
;
176 chNext
= styler
.SafeGetCharAt(i
+ 1);
178 state
= SCE_P_STRING
;
180 } else if (ch
== '\'') {
181 styler
.ColourTo(i
- 1, state
);
182 if (chNext
== '\'' && chNext2
== '\'') {
184 state
= SCE_P_TRIPLE
;
187 chNext
= styler
.SafeGetCharAt(i
+ 1);
189 state
= SCE_P_CHARACTER
;
191 } else if (isoperator(ch
)) {
192 styler
.ColourTo(i
- 1, state
);
193 styler
.ColourTo(i
, SCE_P_OPERATOR
);
195 } else if (state
== SCE_P_WORD
) {
196 if (!iswordchar(ch
)) {
197 ClassifyWordPy(styler
.GetStartSegment(), i
- 1, keywords
, styler
, prevWord
);
198 state
= SCE_P_DEFAULT
;
200 state
= chNext
== '#' ? SCE_P_COMMENTBLOCK
: SCE_P_COMMENTLINE
;
201 } else if (ch
== '\"') {
202 if (chNext
== '\"' && chNext2
== '\"') {
204 state
= SCE_P_TRIPLEDOUBLE
;
207 chNext
= styler
.SafeGetCharAt(i
+ 1);
209 state
= SCE_P_STRING
;
211 } else if (ch
== '\'') {
212 if (chNext
== '\'' && chNext2
== '\'') {
214 state
= SCE_P_TRIPLE
;
217 chNext
= styler
.SafeGetCharAt(i
+ 1);
219 state
= SCE_P_CHARACTER
;
221 } else if (isoperator(ch
)) {
222 styler
.ColourTo(i
, SCE_P_OPERATOR
);
226 if (state
== SCE_P_COMMENTLINE
|| state
== SCE_P_COMMENTBLOCK
) {
227 if (ch
== '\r' || ch
== '\n') {
228 styler
.ColourTo(i
- 1, state
);
229 state
= SCE_P_DEFAULT
;
231 } else if (state
== SCE_P_STRING
) {
232 if ((ch
== '\r' || ch
== '\n') && (chPrev
!= '\\')) {
233 styler
.ColourTo(i
- 1, state
);
234 state
= SCE_P_STRINGEOL
;
235 } else if (ch
== '\\') {
236 if (chNext
== '\"' || chNext
== '\'' || chNext
== '\\') {
239 chNext
= styler
.SafeGetCharAt(i
+ 1);
241 } else if (ch
== '\"') {
242 styler
.ColourTo(i
, state
);
243 state
= SCE_P_DEFAULT
;
245 } else if (state
== SCE_P_CHARACTER
) {
246 if ((ch
== '\r' || ch
== '\n') && (chPrev
!= '\\')) {
247 styler
.ColourTo(i
- 1, state
);
248 state
= SCE_P_STRINGEOL
;
249 } else if (ch
== '\\') {
250 if (chNext
== '\"' || chNext
== '\'' || chNext
== '\\') {
253 chNext
= styler
.SafeGetCharAt(i
+ 1);
255 } else if (ch
== '\'') {
256 styler
.ColourTo(i
, state
);
257 state
= SCE_P_DEFAULT
;
259 } else if (state
== SCE_P_TRIPLE
) {
260 if (ch
== '\'' && chPrev
== '\'' && chPrev2
== '\'') {
261 styler
.ColourTo(i
, state
);
262 state
= SCE_P_DEFAULT
;
264 } else if (state
== SCE_P_TRIPLEDOUBLE
) {
265 if (ch
== '\"' && chPrev
== '\"' && chPrev2
== '\"') {
266 styler
.ColourTo(i
, state
);
267 state
= SCE_P_DEFAULT
;
274 if (state
== SCE_P_WORD
) {
275 ClassifyWordPy(styler
.GetStartSegment(), lengthDoc
, keywords
, styler
, prevWord
);
277 styler
.ColourTo(lengthDoc
, state
);
281 LexerModule
lmPython(SCLEX_PYTHON
, ColourisePyDoc
);