1 // Scintilla source code edit control
2 /** @file LexScriptol.cxx
17 #include "Scintilla.h"
20 static void ClassifyWordSol(unsigned int start
, unsigned int end
, WordList
&keywords
, Accessor
&styler
, char *prevWord
)
23 bool wordIsNumber
= isdigit(styler
[start
]) != 0;
24 for (unsigned int i
= 0; i
< end
- start
+ 1 && i
< 30; i
++)
26 s
[i
] = styler
[start
+ i
];
29 char chAttr
= SCE_SCRIPTOL_IDENTIFIER
;
30 if (0 == strcmp(prevWord
, "class")) chAttr
= SCE_SCRIPTOL_CLASSNAME
;
31 else if (wordIsNumber
) chAttr
= SCE_SCRIPTOL_NUMBER
;
32 else if (keywords
.InList(s
)) chAttr
= SCE_SCRIPTOL_KEYWORD
;
33 else for (unsigned int i
= 0; i
< end
- start
+ 1; i
++) // test dotted idents
35 if (styler
[start
+ i
] == '.')
37 styler
.ColourTo(start
+ i
- 1, chAttr
);
38 styler
.ColourTo(start
+ i
, SCE_SCRIPTOL_OPERATOR
);
41 styler
.ColourTo(end
, chAttr
);
45 static bool IsSolComment(Accessor
&styler
, int pos
, int len
)
51 if(c
== '`') return true;
57 if(c
== '/') return true;
58 if(c
== '*') return true;
65 static bool IsSolStringStart(char ch
)
67 if (ch
== '\'' || ch
== '"') return true;
71 static bool IsSolWordStart(char ch
)
73 return (iswordchar(ch
) && !IsSolStringStart(ch
));
77 static int GetSolStringState(Accessor
&styler
, int i
, int *nextIndex
)
79 char ch
= styler
.SafeGetCharAt(i
);
80 char chNext
= styler
.SafeGetCharAt(i
+ 1);
82 if (ch
!= '\"' && ch
!= '\'')
85 return SCE_SCRIPTOL_DEFAULT
;
87 // ch is either single or double quotes in string
88 // code below seem non-sense but is here for future extensions
89 if (ch
== chNext
&& ch
== styler
.SafeGetCharAt(i
+ 2))
92 if(ch
== '\"') return SCE_SCRIPTOL_TRIPLE
;
93 if(ch
== '\'') return SCE_SCRIPTOL_TRIPLE
;
94 return SCE_SCRIPTOL_STRING
;
99 if (ch
== '"') return SCE_SCRIPTOL_STRING
;
100 else return SCE_SCRIPTOL_STRING
;
105 static void ColouriseSolDoc(unsigned int startPos
, int length
, int initStyle
,
106 WordList
*keywordlists
[], Accessor
&styler
)
109 int lengthDoc
= startPos
+ length
;
110 char stringType
= '\"';
114 int lineCurrent
= styler
.GetLine(startPos
);
117 startPos
= styler
.LineStart(lineCurrent
-1);
118 if (startPos
== 0) initStyle
= SCE_SCRIPTOL_DEFAULT
;
119 else initStyle
= styler
.StyleAt(startPos
-1);
123 styler
.StartAt(startPos
, 127);
125 WordList
&keywords
= *keywordlists
[0];
127 int whingeLevel
= styler
.GetPropertyInt("tab.timmy.whinge.level");
130 if (length
== 0) return;
132 int state
= initStyle
& 31;
137 char chNext
= styler
[startPos
];
138 styler
.StartSegment(startPos
);
139 bool atStartLine
= true;
141 for (int i
= startPos
; i
< lengthDoc
; i
++)
146 char chBad
= static_cast<char>(64);
147 char chGood
= static_cast<char>(0);
148 char chFlags
= chGood
;
150 if (whingeLevel
== 1)
152 chFlags
= (spaceFlags
& wsInconsistent
) ? chBad
: chGood
;
154 else if (whingeLevel
== 2)
156 chFlags
= (spaceFlags
& wsSpaceTab
) ? chBad
: chGood
;
158 else if (whingeLevel
== 3)
160 chFlags
= (spaceFlags
& wsSpace
) ? chBad
: chGood
;
162 else if (whingeLevel
== 4)
164 chFlags
= (spaceFlags
& wsTab
) ? chBad
: chGood
;
166 styler
.SetFlags(chFlags
, static_cast<char>(state
));
171 chNext
= styler
.SafeGetCharAt(i
+ 1);
173 if ((ch
== '\r' && chNext
!= '\n') || (ch
== '\n') || (i
== lengthDoc
))
175 if ((state
== SCE_SCRIPTOL_DEFAULT
) ||
176 (state
== SCE_SCRIPTOL_TRIPLE
) ||
177 (state
== SCE_SCRIPTOL_COMMENTBLOCK
))
179 styler
.ColourTo(i
, state
);
184 if (styler
.IsLeadByte(ch
))
186 chNext
= styler
.SafeGetCharAt(i
+ 2);
193 if (state
== SCE_SCRIPTOL_STRINGEOL
)
195 if (ch
!= '\r' && ch
!= '\n')
197 styler
.ColourTo(i
- 1, state
);
198 state
= SCE_SCRIPTOL_DEFAULT
;
202 if (state
== SCE_SCRIPTOL_DEFAULT
)
204 if (IsSolWordStart(ch
))
206 styler
.ColourTo(i
- 1, state
);
207 state
= SCE_SCRIPTOL_KEYWORD
;
211 styler
.ColourTo(i
- 1, state
);
212 state
= SCE_SCRIPTOL_COMMENTLINE
;
216 styler
.ColourTo(i
- 1, state
);
217 if(chNext
== '/') state
= SCE_SCRIPTOL_CSTYLE
;
218 if(chNext
== '*') state
= SCE_SCRIPTOL_COMMENTBLOCK
;
221 else if (IsSolStringStart(ch
))
223 styler
.ColourTo(i
- 1, state
);
224 state
= GetSolStringState(styler
, i
, &nextIndex
);
225 if(state
== SCE_SCRIPTOL_STRING
)
229 if (nextIndex
!= i
+ 1)
234 chNext
= styler
.SafeGetCharAt(i
+ 1);
237 else if (isoperator(ch
))
239 styler
.ColourTo(i
- 1, state
);
240 styler
.ColourTo(i
, SCE_SCRIPTOL_OPERATOR
);
243 else if (state
== SCE_SCRIPTOL_KEYWORD
)
247 ClassifyWordSol(styler
.GetStartSegment(), i
- 1, keywords
, styler
, prevWord
);
248 state
= SCE_SCRIPTOL_DEFAULT
;
251 state
= chNext
== '`' ? SCE_SCRIPTOL_PERSISTENT
: SCE_SCRIPTOL_COMMENTLINE
;
253 else if (IsSolStringStart(ch
))
255 styler
.ColourTo(i
- 1, state
);
256 state
= GetSolStringState(styler
, i
, &nextIndex
);
257 if (nextIndex
!= i
+ 1)
262 chNext
= styler
.SafeGetCharAt(i
+ 1);
265 else if (isoperator(ch
))
267 styler
.ColourTo(i
, SCE_SCRIPTOL_OPERATOR
);
273 if (state
== SCE_SCRIPTOL_COMMENTLINE
||
274 state
== SCE_SCRIPTOL_PERSISTENT
||
275 state
== SCE_SCRIPTOL_CSTYLE
)
277 if (ch
== '\r' || ch
== '\n')
279 styler
.ColourTo(i
- 1, state
);
280 state
= SCE_SCRIPTOL_DEFAULT
;
283 else if(state
== SCE_SCRIPTOL_COMMENTBLOCK
)
285 if(chPrev
== '*' && ch
== '/')
287 styler
.ColourTo(i
, state
);
288 state
= SCE_SCRIPTOL_DEFAULT
;
291 else if ((state
== SCE_SCRIPTOL_STRING
) ||
292 (state
== SCE_SCRIPTOL_CHARACTER
))
294 if ((ch
== '\r' || ch
== '\n') && (chPrev
!= '\\'))
296 styler
.ColourTo(i
- 1, state
);
297 state
= SCE_SCRIPTOL_STRINGEOL
;
301 if (chNext
== '\"' || chNext
== '\'' || chNext
== '\\')
305 chNext
= styler
.SafeGetCharAt(i
+ 1);
308 else if ((ch
== '\"') || (ch
== '\''))
310 // must match the entered quote type
313 styler
.ColourTo(i
, state
);
314 state
= SCE_SCRIPTOL_DEFAULT
;
318 else if (state
== SCE_SCRIPTOL_TRIPLE
)
320 if ((ch
== '\'' && chPrev
== '\'' && chPrev2
== '\'') ||
321 (ch
== '\"' && chPrev
== '\"' && chPrev2
== '\"'))
323 styler
.ColourTo(i
, state
);
324 state
= SCE_SCRIPTOL_DEFAULT
;
332 if (state
== SCE_SCRIPTOL_KEYWORD
)
334 ClassifyWordSol(styler
.GetStartSegment(),
335 lengthDoc
-1, keywords
, styler
, prevWord
);
339 styler
.ColourTo(lengthDoc
-1, state
);
343 static void FoldSolDoc(unsigned int startPos
, int length
, int initStyle
,
344 WordList
*[], Accessor
&styler
)
346 int lengthDoc
= startPos
+ length
;
348 int lineCurrent
= styler
.GetLine(startPos
);
354 startPos
= styler
.LineStart(lineCurrent
);
356 initStyle
= SCE_SCRIPTOL_DEFAULT
;
358 initStyle
= styler
.StyleAt(startPos
-1);
361 int state
= initStyle
& 31;
363 int indentCurrent
= styler
.IndentAmount(lineCurrent
, &spaceFlags
, IsSolComment
);
364 if ((state
== SCE_SCRIPTOL_TRIPLE
))
365 indentCurrent
|= SC_FOLDLEVELWHITEFLAG
;
366 char chNext
= styler
[startPos
];
367 for (int i
= startPos
; i
< lengthDoc
; i
++)
370 chNext
= styler
.SafeGetCharAt(i
+ 1);
371 int style
= styler
.StyleAt(i
) & 31;
373 if ((ch
== '\r' && chNext
!= '\n') || (ch
== '\n') || (i
== lengthDoc
))
375 int lev
= indentCurrent
;
376 int indentNext
= styler
.IndentAmount(lineCurrent
+ 1, &spaceFlags
, IsSolComment
);
377 if (style
== SCE_SCRIPTOL_TRIPLE
)
378 indentNext
|= SC_FOLDLEVELWHITEFLAG
;
379 if (!(indentCurrent
& SC_FOLDLEVELWHITEFLAG
))
381 // Only non whitespace lines can be headers
382 if ((indentCurrent
& SC_FOLDLEVELNUMBERMASK
) < (indentNext
& SC_FOLDLEVELNUMBERMASK
))
384 lev
|= SC_FOLDLEVELHEADERFLAG
;
386 else if (indentNext
& SC_FOLDLEVELWHITEFLAG
)
388 // Line after is blank so check the next - maybe should continue further?
390 int indentNext2
= styler
.IndentAmount(lineCurrent
+ 2, &spaceFlags2
, IsSolComment
);
391 if ((indentCurrent
& SC_FOLDLEVELNUMBERMASK
) < (indentNext2
& SC_FOLDLEVELNUMBERMASK
))
393 lev
|= SC_FOLDLEVELHEADERFLAG
;
397 indentCurrent
= indentNext
;
398 styler
.SetLevel(lineCurrent
, lev
);
404 LexerModule
lmScriptol(SCLEX_SCRIPTOL
, ColouriseSolDoc
, "scriptol", FoldSolDoc
);