1 // Scintilla source code edit control
2 /** @file LexScriptol.cxx
17 #include "Scintilla.h"
21 using namespace Scintilla
;
24 static void ClassifyWordSol(unsigned int start
, unsigned int end
, WordList
&keywords
, Accessor
&styler
, char *prevWord
)
27 bool wordIsNumber
= isdigit(styler
[start
]) != 0;
28 for (unsigned int i
= 0; i
< end
- start
+ 1 && i
< 30; i
++)
30 s
[i
] = styler
[start
+ i
];
33 char chAttr
= SCE_SCRIPTOL_IDENTIFIER
;
34 if (0 == strcmp(prevWord
, "class")) chAttr
= SCE_SCRIPTOL_CLASSNAME
;
35 else if (wordIsNumber
) chAttr
= SCE_SCRIPTOL_NUMBER
;
36 else if (keywords
.InList(s
)) chAttr
= SCE_SCRIPTOL_KEYWORD
;
37 else for (unsigned int i
= 0; i
< end
- start
+ 1; i
++) // test dotted idents
39 if (styler
[start
+ i
] == '.')
41 styler
.ColourTo(start
+ i
- 1, chAttr
);
42 styler
.ColourTo(start
+ i
, SCE_SCRIPTOL_OPERATOR
);
45 styler
.ColourTo(end
, chAttr
);
49 static bool IsSolComment(Accessor
&styler
, int pos
, int len
)
55 if(c
== '`') return true;
61 if(c
== '/') return true;
62 if(c
== '*') return true;
69 static bool IsSolStringStart(char ch
)
71 if (ch
== '\'' || ch
== '"') return true;
75 static bool IsSolWordStart(char ch
)
77 return (iswordchar(ch
) && !IsSolStringStart(ch
));
81 static int GetSolStringState(Accessor
&styler
, int i
, int *nextIndex
)
83 char ch
= styler
.SafeGetCharAt(i
);
84 char chNext
= styler
.SafeGetCharAt(i
+ 1);
86 if (ch
!= '\"' && ch
!= '\'')
89 return SCE_SCRIPTOL_DEFAULT
;
91 // ch is either single or double quotes in string
92 // code below seem non-sense but is here for future extensions
93 if (ch
== chNext
&& ch
== styler
.SafeGetCharAt(i
+ 2))
96 if(ch
== '\"') return SCE_SCRIPTOL_TRIPLE
;
97 if(ch
== '\'') return SCE_SCRIPTOL_TRIPLE
;
98 return SCE_SCRIPTOL_STRING
;
103 if (ch
== '"') return SCE_SCRIPTOL_STRING
;
104 else return SCE_SCRIPTOL_STRING
;
109 static void ColouriseSolDoc(unsigned int startPos
, int length
, int initStyle
,
110 WordList
*keywordlists
[], Accessor
&styler
)
113 int lengthDoc
= startPos
+ length
;
114 char stringType
= '\"';
118 int lineCurrent
= styler
.GetLine(startPos
);
121 startPos
= styler
.LineStart(lineCurrent
-1);
122 if (startPos
== 0) initStyle
= SCE_SCRIPTOL_DEFAULT
;
123 else initStyle
= styler
.StyleAt(startPos
-1);
127 styler
.StartAt(startPos
, 127);
129 WordList
&keywords
= *keywordlists
[0];
131 int whingeLevel
= styler
.GetPropertyInt("tab.timmy.whinge.level");
134 if (length
== 0) return;
136 int state
= initStyle
& 31;
141 char chNext
= styler
[startPos
];
142 styler
.StartSegment(startPos
);
143 bool atStartLine
= true;
145 for (int i
= startPos
; i
< lengthDoc
; i
++)
150 char chBad
= static_cast<char>(64);
151 char chGood
= static_cast<char>(0);
152 char chFlags
= chGood
;
154 if (whingeLevel
== 1)
156 chFlags
= (spaceFlags
& wsInconsistent
) ? chBad
: chGood
;
158 else if (whingeLevel
== 2)
160 chFlags
= (spaceFlags
& wsSpaceTab
) ? chBad
: chGood
;
162 else if (whingeLevel
== 3)
164 chFlags
= (spaceFlags
& wsSpace
) ? chBad
: chGood
;
166 else if (whingeLevel
== 4)
168 chFlags
= (spaceFlags
& wsTab
) ? chBad
: chGood
;
170 styler
.SetFlags(chFlags
, static_cast<char>(state
));
175 chNext
= styler
.SafeGetCharAt(i
+ 1);
177 if ((ch
== '\r' && chNext
!= '\n') || (ch
== '\n') || (i
== lengthDoc
))
179 if ((state
== SCE_SCRIPTOL_DEFAULT
) ||
180 (state
== SCE_SCRIPTOL_TRIPLE
) ||
181 (state
== SCE_SCRIPTOL_COMMENTBLOCK
))
183 styler
.ColourTo(i
, state
);
188 if (styler
.IsLeadByte(ch
))
190 chNext
= styler
.SafeGetCharAt(i
+ 2);
197 if (state
== SCE_SCRIPTOL_STRINGEOL
)
199 if (ch
!= '\r' && ch
!= '\n')
201 styler
.ColourTo(i
- 1, state
);
202 state
= SCE_SCRIPTOL_DEFAULT
;
206 if (state
== SCE_SCRIPTOL_DEFAULT
)
208 if (IsSolWordStart(ch
))
210 styler
.ColourTo(i
- 1, state
);
211 state
= SCE_SCRIPTOL_KEYWORD
;
215 styler
.ColourTo(i
- 1, state
);
216 state
= SCE_SCRIPTOL_COMMENTLINE
;
220 styler
.ColourTo(i
- 1, state
);
221 if(chNext
== '/') state
= SCE_SCRIPTOL_CSTYLE
;
222 if(chNext
== '*') state
= SCE_SCRIPTOL_COMMENTBLOCK
;
225 else if (IsSolStringStart(ch
))
227 styler
.ColourTo(i
- 1, state
);
228 state
= GetSolStringState(styler
, i
, &nextIndex
);
229 if(state
== SCE_SCRIPTOL_STRING
)
233 if (nextIndex
!= i
+ 1)
238 chNext
= styler
.SafeGetCharAt(i
+ 1);
241 else if (isoperator(ch
))
243 styler
.ColourTo(i
- 1, state
);
244 styler
.ColourTo(i
, SCE_SCRIPTOL_OPERATOR
);
247 else if (state
== SCE_SCRIPTOL_KEYWORD
)
251 ClassifyWordSol(styler
.GetStartSegment(), i
- 1, keywords
, styler
, prevWord
);
252 state
= SCE_SCRIPTOL_DEFAULT
;
255 state
= chNext
== '`' ? SCE_SCRIPTOL_PERSISTENT
: SCE_SCRIPTOL_COMMENTLINE
;
257 else if (IsSolStringStart(ch
))
259 styler
.ColourTo(i
- 1, state
);
260 state
= GetSolStringState(styler
, i
, &nextIndex
);
261 if (nextIndex
!= i
+ 1)
266 chNext
= styler
.SafeGetCharAt(i
+ 1);
269 else if (isoperator(ch
))
271 styler
.ColourTo(i
, SCE_SCRIPTOL_OPERATOR
);
277 if (state
== SCE_SCRIPTOL_COMMENTLINE
||
278 state
== SCE_SCRIPTOL_PERSISTENT
||
279 state
== SCE_SCRIPTOL_CSTYLE
)
281 if (ch
== '\r' || ch
== '\n')
283 styler
.ColourTo(i
- 1, state
);
284 state
= SCE_SCRIPTOL_DEFAULT
;
287 else if(state
== SCE_SCRIPTOL_COMMENTBLOCK
)
289 if(chPrev
== '*' && ch
== '/')
291 styler
.ColourTo(i
, state
);
292 state
= SCE_SCRIPTOL_DEFAULT
;
295 else if ((state
== SCE_SCRIPTOL_STRING
) ||
296 (state
== SCE_SCRIPTOL_CHARACTER
))
298 if ((ch
== '\r' || ch
== '\n') && (chPrev
!= '\\'))
300 styler
.ColourTo(i
- 1, state
);
301 state
= SCE_SCRIPTOL_STRINGEOL
;
305 if (chNext
== '\"' || chNext
== '\'' || chNext
== '\\')
309 chNext
= styler
.SafeGetCharAt(i
+ 1);
312 else if ((ch
== '\"') || (ch
== '\''))
314 // must match the entered quote type
317 styler
.ColourTo(i
, state
);
318 state
= SCE_SCRIPTOL_DEFAULT
;
322 else if (state
== SCE_SCRIPTOL_TRIPLE
)
324 if ((ch
== '\'' && chPrev
== '\'' && chPrev2
== '\'') ||
325 (ch
== '\"' && chPrev
== '\"' && chPrev2
== '\"'))
327 styler
.ColourTo(i
, state
);
328 state
= SCE_SCRIPTOL_DEFAULT
;
336 if (state
== SCE_SCRIPTOL_KEYWORD
)
338 ClassifyWordSol(styler
.GetStartSegment(),
339 lengthDoc
-1, keywords
, styler
, prevWord
);
343 styler
.ColourTo(lengthDoc
-1, state
);
347 static void FoldSolDoc(unsigned int startPos
, int length
, int initStyle
,
348 WordList
*[], Accessor
&styler
)
350 int lengthDoc
= startPos
+ length
;
352 int lineCurrent
= styler
.GetLine(startPos
);
358 startPos
= styler
.LineStart(lineCurrent
);
360 initStyle
= SCE_SCRIPTOL_DEFAULT
;
362 initStyle
= styler
.StyleAt(startPos
-1);
365 int state
= initStyle
& 31;
367 int indentCurrent
= styler
.IndentAmount(lineCurrent
, &spaceFlags
, IsSolComment
);
368 if ((state
== SCE_SCRIPTOL_TRIPLE
))
369 indentCurrent
|= SC_FOLDLEVELWHITEFLAG
;
370 char chNext
= styler
[startPos
];
371 for (int i
= startPos
; i
< lengthDoc
; i
++)
374 chNext
= styler
.SafeGetCharAt(i
+ 1);
375 int style
= styler
.StyleAt(i
) & 31;
377 if ((ch
== '\r' && chNext
!= '\n') || (ch
== '\n') || (i
== lengthDoc
))
379 int lev
= indentCurrent
;
380 int indentNext
= styler
.IndentAmount(lineCurrent
+ 1, &spaceFlags
, IsSolComment
);
381 if (style
== SCE_SCRIPTOL_TRIPLE
)
382 indentNext
|= SC_FOLDLEVELWHITEFLAG
;
383 if (!(indentCurrent
& SC_FOLDLEVELWHITEFLAG
))
385 // Only non whitespace lines can be headers
386 if ((indentCurrent
& SC_FOLDLEVELNUMBERMASK
) < (indentNext
& SC_FOLDLEVELNUMBERMASK
))
388 lev
|= SC_FOLDLEVELHEADERFLAG
;
390 else if (indentNext
& SC_FOLDLEVELWHITEFLAG
)
392 // Line after is blank so check the next - maybe should continue further?
394 int indentNext2
= styler
.IndentAmount(lineCurrent
+ 2, &spaceFlags2
, IsSolComment
);
395 if ((indentCurrent
& SC_FOLDLEVELNUMBERMASK
) < (indentNext2
& SC_FOLDLEVELNUMBERMASK
))
397 lev
|= SC_FOLDLEVELHEADERFLAG
;
401 indentCurrent
= indentNext
;
402 styler
.SetLevel(lineCurrent
, lev
);
408 LexerModule
lmScriptol(SCLEX_SCRIPTOL
, ColouriseSolDoc
, "scriptol", FoldSolDoc
);