]>
git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/LexPython.cxx
df8b7085bfde7ca13d0d1cc19c7acd7f5d64cfe4
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 styler
.ColourTo(end
, chAttr
);
40 static bool IsPyComment(Accessor
&styler
, int pos
, int len
) {
41 return len
>0 && styler
[pos
]=='#';
44 static void ColourisePyDoc(unsigned int startPos
, int length
, int initStyle
,
45 WordList
*keywordlists
[], Accessor
&styler
) {
47 int lengthDoc
= startPos
+ length
;
49 // Backtrack to previous line in case need to fix its fold status or tab whinging
50 int lineCurrent
= styler
.GetLine(startPos
);
52 if (lineCurrent
> 0) {
54 startPos
= styler
.LineStart(lineCurrent
);
56 initStyle
= SCE_P_DEFAULT
;
58 initStyle
= styler
.StyleAt(startPos
-1);
62 // Python uses a different mask because bad indentation is marked by oring with 32
63 styler
.StartAt(startPos
, 127);
65 WordList
&keywords
= *keywordlists
[0];
67 bool fold
= styler
.GetPropertyInt("fold");
68 int whingeLevel
= styler
.GetPropertyInt("tab.timmy.whinge.level");
75 int state
= initStyle
& 31;
77 int indentCurrent
= styler
.IndentAmount(lineCurrent
, &spaceFlags
, IsPyComment
);
78 if ((state
== SCE_P_TRIPLE
) || (state
== SCE_P_TRIPLEDOUBLE
))
79 indentCurrent
|= SC_FOLDLEVELWHITEFLAG
;
83 char chNext
= styler
[startPos
];
84 styler
.StartSegment(startPos
);
85 bool atStartLine
= true;
86 for (int i
= startPos
; i
< lengthDoc
; i
++) {
89 char chBad
= static_cast<char>(64);
90 char chGood
= static_cast<char>(0);
91 char chFlags
= chGood
;
92 if (whingeLevel
== 1) {
93 chFlags
= (spaceFlags
& wsInconsistent
) ? chBad
: chGood
;
94 } else if (whingeLevel
== 2) {
95 chFlags
= (spaceFlags
& wsSpaceTab
) ? chBad
: chGood
;
96 } else if (whingeLevel
== 3) {
97 chFlags
= (spaceFlags
& wsSpace
) ? chBad
: chGood
;
98 } else if (whingeLevel
== 4) {
99 chFlags
= (spaceFlags
& wsTab
) ? chBad
: chGood
;
101 styler
.SetFlags(chFlags
, static_cast<char>(state
));
106 chNext
= styler
.SafeGetCharAt(i
+ 1);
107 char chNext2
= styler
.SafeGetCharAt(i
+ 2);
109 if ((ch
== '\r' && chNext
!= '\n') || (ch
== '\n') || (i
== lengthDoc
)) {
110 if ((state
== SCE_P_DEFAULT
) || (state
== SCE_P_TRIPLE
) || (state
== SCE_P_TRIPLEDOUBLE
)) {
111 // Perform colourisation of white space and triple quoted strings at end of each line to allow
112 // tab marking to work inside white space and triple quoted strings
113 styler
.ColourTo(i
, state
);
116 int lev
= indentCurrent
;
117 int indentNext
= styler
.IndentAmount(lineCurrent
+ 1, &spaceFlags
, IsPyComment
);
118 if ((state
== SCE_P_TRIPLE
) || (state
== SCE_P_TRIPLEDOUBLE
))
119 indentNext
|= SC_FOLDLEVELWHITEFLAG
;
120 if (!(indentCurrent
& SC_FOLDLEVELWHITEFLAG
)) {
121 // Only non whitespace lines can be headers
122 if ((indentCurrent
& SC_FOLDLEVELNUMBERMASK
) < (indentNext
& SC_FOLDLEVELNUMBERMASK
)) {
123 lev
|= SC_FOLDLEVELHEADERFLAG
;
124 } else if (indentNext
& SC_FOLDLEVELWHITEFLAG
) {
125 // Line after is blank so check the next - maybe should continue further?
127 int indentNext2
= styler
.IndentAmount(lineCurrent
+ 2, &spaceFlags2
, IsPyComment
);
128 if ((indentCurrent
& SC_FOLDLEVELNUMBERMASK
) < (indentNext2
& SC_FOLDLEVELNUMBERMASK
)) {
129 lev
|= SC_FOLDLEVELHEADERFLAG
;
133 indentCurrent
= indentNext
;
135 styler
.SetLevel(lineCurrent
, lev
);
141 if (styler
.IsLeadByte(ch
)) {
142 chNext
= styler
.SafeGetCharAt(i
+ 2);
149 if (state
== SCE_P_STRINGEOL
) {
150 if (ch
!= '\r' && ch
!= '\n') {
151 styler
.ColourTo(i
- 1, state
);
152 state
= SCE_P_DEFAULT
;
155 if (state
== SCE_P_DEFAULT
) {
156 if (iswordstart(ch
)) {
157 styler
.ColourTo(i
- 1, state
);
159 } else if (ch
== '#') {
160 styler
.ColourTo(i
- 1, state
);
161 state
= chNext
== '#' ? SCE_P_COMMENTBLOCK
: SCE_P_COMMENTLINE
;
162 } else if (ch
== '\"') {
163 styler
.ColourTo(i
- 1, state
);
164 if (chNext
== '\"' && chNext2
== '\"') {
166 state
= SCE_P_TRIPLEDOUBLE
;
169 chNext
= styler
.SafeGetCharAt(i
+ 1);
171 state
= SCE_P_STRING
;
173 } else if (ch
== '\'') {
174 styler
.ColourTo(i
- 1, state
);
175 if (chNext
== '\'' && chNext2
== '\'') {
177 state
= SCE_P_TRIPLE
;
180 chNext
= styler
.SafeGetCharAt(i
+ 1);
182 state
= SCE_P_CHARACTER
;
184 } else if (isoperator(ch
)) {
185 styler
.ColourTo(i
- 1, state
);
186 styler
.ColourTo(i
, SCE_P_OPERATOR
);
188 } else if (state
== SCE_P_WORD
) {
189 if (!iswordchar(ch
)) {
190 ClassifyWordPy(styler
.GetStartSegment(), i
- 1, keywords
, styler
, prevWord
);
191 state
= SCE_P_DEFAULT
;
193 state
= chNext
== '#' ? SCE_P_COMMENTBLOCK
: SCE_P_COMMENTLINE
;
194 } else if (ch
== '\"') {
195 if (chNext
== '\"' && chNext2
== '\"') {
197 state
= SCE_P_TRIPLEDOUBLE
;
200 chNext
= styler
.SafeGetCharAt(i
+ 1);
202 state
= SCE_P_STRING
;
204 } else if (ch
== '\'') {
205 if (chNext
== '\'' && chNext2
== '\'') {
207 state
= SCE_P_TRIPLE
;
210 chNext
= styler
.SafeGetCharAt(i
+ 1);
212 state
= SCE_P_CHARACTER
;
214 } else if (isoperator(ch
)) {
215 styler
.ColourTo(i
, SCE_P_OPERATOR
);
219 if (state
== SCE_P_COMMENTLINE
|| state
== SCE_P_COMMENTBLOCK
) {
220 if (ch
== '\r' || ch
== '\n') {
221 styler
.ColourTo(i
- 1, state
);
222 state
= SCE_P_DEFAULT
;
224 } else if (state
== SCE_P_STRING
) {
225 if ((ch
== '\r' || ch
== '\n') && (chPrev
!= '\\')) {
226 styler
.ColourTo(i
- 1, state
);
227 state
= SCE_P_STRINGEOL
;
228 } else if (ch
== '\\') {
229 if (chNext
== '\"' || chNext
== '\'' || chNext
== '\\') {
232 chNext
= styler
.SafeGetCharAt(i
+ 1);
234 } else if (ch
== '\"') {
235 styler
.ColourTo(i
, state
);
236 state
= SCE_P_DEFAULT
;
238 } else if (state
== SCE_P_CHARACTER
) {
239 if ((ch
== '\r' || ch
== '\n') && (chPrev
!= '\\')) {
240 styler
.ColourTo(i
- 1, state
);
241 state
= SCE_P_STRINGEOL
;
242 } else if (ch
== '\\') {
243 if (chNext
== '\"' || chNext
== '\'' || chNext
== '\\') {
246 chNext
= styler
.SafeGetCharAt(i
+ 1);
248 } else if (ch
== '\'') {
249 styler
.ColourTo(i
, state
);
250 state
= SCE_P_DEFAULT
;
252 } else if (state
== SCE_P_TRIPLE
) {
253 if (ch
== '\'' && chPrev
== '\'' && chPrev2
== '\'') {
254 styler
.ColourTo(i
, state
);
255 state
= SCE_P_DEFAULT
;
257 } else if (state
== SCE_P_TRIPLEDOUBLE
) {
258 if (ch
== '\"' && chPrev
== '\"' && chPrev2
== '\"') {
259 styler
.ColourTo(i
, state
);
260 state
= SCE_P_DEFAULT
;
267 if (state
== SCE_P_WORD
) {
268 ClassifyWordPy(styler
.GetStartSegment(), lengthDoc
, keywords
, styler
, prevWord
);
270 styler
.ColourTo(lengthDoc
, state
);
274 LexerModule
lmPython(SCLEX_PYTHON
, ColourisePyDoc
);