]>
git.saurik.com Git - wxWidgets.git/blob - contrib/src/stc/scintilla/src/LexPython.cxx
c6c5e6d342861ab518a77acf6b9203c5d34ead20
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
, StylingContext
&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(StylingContext
&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
[], StylingContext
&styler
) {
47 // Python uses a different mask because bad indentation is marked by oring with 32
48 styler
.StartAt(startPos
, 127);
50 WordList
&keywords
= *keywordlists
[0];
52 //Platform::DebugPrintf("Python coloured\n");
53 bool fold
= styler
.GetPropSet().GetInt("fold");
54 int whingeLevel
= styler
.GetPropSet().GetInt("tab.timmy.whinge.level");
59 int lineCurrent
= styler
.GetLine(startPos
);
61 // TODO: Need to check previous line for indentation for both folding and bad indentation
62 int indentCurrent
= styler
.IndentAmount(lineCurrent
, &spaceFlags
, IsPyComment
);
64 int state
= initStyle
& 31;
67 char chNext
= styler
[startPos
];
68 char chNext2
= styler
[startPos
];
69 styler
.StartSegment(startPos
);
70 int lengthDoc
= startPos
+ length
;
71 bool atStartLine
= true;
72 for (int i
= startPos
; i
<= lengthDoc
; i
++) {
75 if (whingeLevel
== 1) {
76 styler
.SetFlags((spaceFlags
& wsInconsistent
) ? 64 : 0, state
);
77 } else if (whingeLevel
== 2) {
78 styler
.SetFlags((spaceFlags
& wsSpaceTab
) ? 64 : 0, state
);
79 } else if (whingeLevel
== 3) {
80 styler
.SetFlags((spaceFlags
& wsSpace
) ? 64 : 0, state
);
81 } else if (whingeLevel
== 4) {
82 styler
.SetFlags((spaceFlags
& wsTab
) ? 64 : 0, state
);
88 chNext
= styler
.SafeGetCharAt(i
+ 1);
89 chNext2
= styler
.SafeGetCharAt(i
+ 2);
91 if ((ch
== '\r' && chNext
!= '\n') || (ch
== '\n') || (i
== lengthDoc
)) {
92 if ((state
== SCE_P_DEFAULT
) || (state
== SCE_P_TRIPLE
) || (state
== SCE_P_TRIPLEDOUBLE
)) {
93 // Perform colourisation of white space and triple quoted strings at end of each line to allow
94 // tab marking to work inside white space and triple quoted strings
95 styler
.ColourTo(i
, state
);
98 int lev
= indentCurrent
;
99 int indentNext
= styler
.IndentAmount(lineCurrent
+ 1, &spaceFlags
, IsPyComment
);
100 if (!(indentCurrent
& SC_FOLDLEVELWHITEFLAG
)) {
101 // Only non whitespace lines can be headers
102 if ((indentCurrent
& SC_FOLDLEVELNUMBERMASK
) < (indentNext
& SC_FOLDLEVELNUMBERMASK
)) {
103 lev
|= SC_FOLDLEVELHEADERFLAG
;
104 } else if (indentNext
& SC_FOLDLEVELWHITEFLAG
) {
105 // Line after is blank so check the next - maybe should continue further?
107 int indentNext2
= styler
.IndentAmount(lineCurrent
+ 2, &spaceFlags2
, IsPyComment
);
108 if ((indentCurrent
& SC_FOLDLEVELNUMBERMASK
) < (indentNext2
& SC_FOLDLEVELNUMBERMASK
)) {
109 lev
|= SC_FOLDLEVELHEADERFLAG
;
113 indentCurrent
= indentNext
;
115 styler
.SetLevel(lineCurrent
, lev
);
121 if (styler
.IsLeadByte(ch
)) {
122 chNext
= styler
.SafeGetCharAt(i
+ 2);
129 if (state
== SCE_P_STRINGEOL
) {
130 if (ch
!= '\r' && ch
!= '\n') {
131 styler
.ColourTo(i
- 1, state
);
132 state
= SCE_P_DEFAULT
;
135 if (state
== SCE_P_DEFAULT
) {
136 if (iswordstart(ch
)) {
137 styler
.ColourTo(i
- 1, state
);
139 } else if (ch
== '#') {
140 styler
.ColourTo(i
- 1, state
);
141 state
= chNext
== '#' ? SCE_P_COMMENTBLOCK
: SCE_P_COMMENTLINE
;
142 } else if (ch
== '\"') {
143 styler
.ColourTo(i
- 1, state
);
144 if (chNext
== '\"' && chNext2
== '\"') {
146 state
= SCE_P_TRIPLEDOUBLE
;
149 chNext
= styler
.SafeGetCharAt(i
+ 1);
151 state
= SCE_P_STRING
;
153 } else if (ch
== '\'') {
154 styler
.ColourTo(i
- 1, state
);
155 if (chNext
== '\'' && chNext2
== '\'') {
157 state
= SCE_P_TRIPLE
;
160 chNext
= styler
.SafeGetCharAt(i
+ 1);
162 state
= SCE_P_CHARACTER
;
164 } else if (isoperator(ch
)) {
165 styler
.ColourTo(i
- 1, state
);
166 styler
.ColourTo(i
, SCE_P_OPERATOR
);
168 } else if (state
== SCE_P_WORD
) {
169 if (!iswordchar(ch
)) {
170 classifyWordPy(styler
.GetStartSegment(), i
- 1, keywords
, styler
, prevWord
);
171 state
= SCE_P_DEFAULT
;
173 state
= chNext
== '#' ? SCE_P_COMMENTBLOCK
: SCE_P_COMMENTLINE
;
174 } else if (ch
== '\"') {
175 if (chNext
== '\"' && chNext2
== '\"') {
177 state
= SCE_P_TRIPLEDOUBLE
;
180 chNext
= styler
.SafeGetCharAt(i
+ 1);
182 state
= SCE_P_STRING
;
184 } else if (ch
== '\'') {
185 if (chNext
== '\'' && chNext2
== '\'') {
187 state
= SCE_P_TRIPLE
;
190 chNext
= styler
.SafeGetCharAt(i
+ 1);
192 state
= SCE_P_CHARACTER
;
194 } else if (isoperator(ch
)) {
195 styler
.ColourTo(i
, SCE_P_OPERATOR
);
199 if (state
== SCE_P_COMMENTLINE
|| state
== SCE_P_COMMENTBLOCK
) {
200 if (ch
== '\r' || ch
== '\n') {
201 styler
.ColourTo(i
- 1, state
);
202 state
= SCE_P_DEFAULT
;
204 } else if (state
== SCE_P_STRING
) {
205 if ((ch
== '\r' || ch
== '\n') && (chPrev
!= '\\')) {
206 styler
.ColourTo(i
- 1, state
);
207 state
= SCE_P_STRINGEOL
;
208 } else if (ch
== '\\') {
209 if (chNext
== '\"' || chNext
== '\'' || chNext
== '\\') {
212 chNext
= styler
.SafeGetCharAt(i
+ 1);
214 } else if (ch
== '\"') {
215 styler
.ColourTo(i
, state
);
216 state
= SCE_P_DEFAULT
;
218 } else if (state
== SCE_P_CHARACTER
) {
219 if ((ch
== '\r' || ch
== '\n') && (chPrev
!= '\\')) {
220 styler
.ColourTo(i
- 1, state
);
221 state
= SCE_P_STRINGEOL
;
222 } else if (ch
== '\\') {
223 if (chNext
== '\"' || chNext
== '\'' || chNext
== '\\') {
226 chNext
= styler
.SafeGetCharAt(i
+ 1);
228 } else if (ch
== '\'') {
229 styler
.ColourTo(i
, state
);
230 state
= SCE_P_DEFAULT
;
232 } else if (state
== SCE_P_TRIPLE
) {
233 if (ch
== '\'' && chPrev
== '\'' && chPrev2
== '\'') {
234 styler
.ColourTo(i
, state
);
235 state
= SCE_P_DEFAULT
;
237 } else if (state
== SCE_P_TRIPLEDOUBLE
) {
238 if (ch
== '\"' && chPrev
== '\"' && chPrev2
== '\"') {
239 styler
.ColourTo(i
, state
);
240 state
= SCE_P_DEFAULT
;
247 if (state
== SCE_P_WORD
) {
248 classifyWordPy(styler
.GetStartSegment(), lengthDoc
, keywords
, styler
, prevWord
);
250 styler
.ColourTo(lengthDoc
, state
);
254 LexerModule
lmPython(SCLEX_PYTHON
, ColourisePyDoc
);