1 // Scintilla source code edit control
2 /** @file LexScriptol.cxx
14 #include "Scintilla.h"
18 #include "LexAccessor.h"
20 #include "StyleContext.h"
21 #include "CharacterSet.h"
22 #include "LexerModule.h"
25 using namespace Scintilla
;
28 static void ClassifyWordSol(unsigned int start
, unsigned int end
, WordList
&keywords
, Accessor
&styler
, char *prevWord
)
31 bool wordIsNumber
= isdigit(styler
[start
]) != 0;
32 for (unsigned int i
= 0; i
< end
- start
+ 1 && i
< 30; i
++)
34 s
[i
] = styler
[start
+ i
];
37 char chAttr
= SCE_SCRIPTOL_IDENTIFIER
;
38 if (0 == strcmp(prevWord
, "class")) chAttr
= SCE_SCRIPTOL_CLASSNAME
;
39 else if (wordIsNumber
) chAttr
= SCE_SCRIPTOL_NUMBER
;
40 else if (keywords
.InList(s
)) chAttr
= SCE_SCRIPTOL_KEYWORD
;
41 else for (unsigned int i
= 0; i
< end
- start
+ 1; i
++) // test dotted idents
43 if (styler
[start
+ i
] == '.')
45 styler
.ColourTo(start
+ i
- 1, chAttr
);
46 styler
.ColourTo(start
+ i
, SCE_SCRIPTOL_OPERATOR
);
49 styler
.ColourTo(end
, chAttr
);
53 static bool IsSolComment(Accessor
&styler
, int pos
, int len
)
58 if(c
== '`') return true;
64 if(c
== '/') return true;
65 if(c
== '*') return true;
72 static bool IsSolStringStart(char ch
)
74 if (ch
== '\'' || ch
== '"') return true;
78 static bool IsSolWordStart(char ch
)
80 return (iswordchar(ch
) && !IsSolStringStart(ch
));
84 static int GetSolStringState(Accessor
&styler
, int i
, int *nextIndex
)
86 char ch
= styler
.SafeGetCharAt(i
);
87 char chNext
= styler
.SafeGetCharAt(i
+ 1);
89 if (ch
!= '\"' && ch
!= '\'')
92 return SCE_SCRIPTOL_DEFAULT
;
94 // ch is either single or double quotes in string
95 // code below seem non-sense but is here for future extensions
96 if (ch
== chNext
&& ch
== styler
.SafeGetCharAt(i
+ 2))
99 if(ch
== '\"') return SCE_SCRIPTOL_TRIPLE
;
100 if(ch
== '\'') return SCE_SCRIPTOL_TRIPLE
;
101 return SCE_SCRIPTOL_STRING
;
106 if (ch
== '"') return SCE_SCRIPTOL_STRING
;
107 else return SCE_SCRIPTOL_STRING
;
112 static void ColouriseSolDoc(unsigned int startPos
, int length
, int initStyle
,
113 WordList
*keywordlists
[], Accessor
&styler
)
116 int lengthDoc
= startPos
+ length
;
117 char stringType
= '\"';
121 int lineCurrent
= styler
.GetLine(startPos
);
124 startPos
= styler
.LineStart(lineCurrent
-1);
125 if (startPos
== 0) initStyle
= SCE_SCRIPTOL_DEFAULT
;
126 else initStyle
= styler
.StyleAt(startPos
-1);
130 styler
.StartAt(startPos
);
132 WordList
&keywords
= *keywordlists
[0];
136 if (length
== 0) return;
138 int state
= initStyle
& 31;
143 char chNext
= styler
[startPos
];
144 styler
.StartSegment(startPos
);
145 for (int i
= startPos
; i
< lengthDoc
; i
++)
149 chNext
= styler
.SafeGetCharAt(i
+ 1);
151 if ((ch
== '\r' && chNext
!= '\n') || (ch
== '\n') || (i
== lengthDoc
))
153 if ((state
== SCE_SCRIPTOL_DEFAULT
) ||
154 (state
== SCE_SCRIPTOL_TRIPLE
) ||
155 (state
== SCE_SCRIPTOL_COMMENTBLOCK
))
157 styler
.ColourTo(i
, state
);
161 if (styler
.IsLeadByte(ch
))
163 chNext
= styler
.SafeGetCharAt(i
+ 2);
170 if (state
== SCE_SCRIPTOL_STRINGEOL
)
172 if (ch
!= '\r' && ch
!= '\n')
174 styler
.ColourTo(i
- 1, state
);
175 state
= SCE_SCRIPTOL_DEFAULT
;
179 if (state
== SCE_SCRIPTOL_DEFAULT
)
181 if (IsSolWordStart(ch
))
183 styler
.ColourTo(i
- 1, state
);
184 state
= SCE_SCRIPTOL_KEYWORD
;
188 styler
.ColourTo(i
- 1, state
);
189 state
= SCE_SCRIPTOL_COMMENTLINE
;
193 styler
.ColourTo(i
- 1, state
);
194 if(chNext
== '/') state
= SCE_SCRIPTOL_CSTYLE
;
195 if(chNext
== '*') state
= SCE_SCRIPTOL_COMMENTBLOCK
;
198 else if (IsSolStringStart(ch
))
200 styler
.ColourTo(i
- 1, state
);
201 state
= GetSolStringState(styler
, i
, &nextIndex
);
202 if(state
== SCE_SCRIPTOL_STRING
)
206 if (nextIndex
!= i
+ 1)
211 chNext
= styler
.SafeGetCharAt(i
+ 1);
214 else if (isoperator(ch
))
216 styler
.ColourTo(i
- 1, state
);
217 styler
.ColourTo(i
, SCE_SCRIPTOL_OPERATOR
);
220 else if (state
== SCE_SCRIPTOL_KEYWORD
)
224 ClassifyWordSol(styler
.GetStartSegment(), i
- 1, keywords
, styler
, prevWord
);
225 state
= SCE_SCRIPTOL_DEFAULT
;
228 state
= chNext
== '`' ? SCE_SCRIPTOL_PERSISTENT
: SCE_SCRIPTOL_COMMENTLINE
;
230 else if (IsSolStringStart(ch
))
232 styler
.ColourTo(i
- 1, state
);
233 state
= GetSolStringState(styler
, i
, &nextIndex
);
234 if (nextIndex
!= i
+ 1)
239 chNext
= styler
.SafeGetCharAt(i
+ 1);
242 else if (isoperator(ch
))
244 styler
.ColourTo(i
, SCE_SCRIPTOL_OPERATOR
);
250 if (state
== SCE_SCRIPTOL_COMMENTLINE
||
251 state
== SCE_SCRIPTOL_PERSISTENT
||
252 state
== SCE_SCRIPTOL_CSTYLE
)
254 if (ch
== '\r' || ch
== '\n')
256 styler
.ColourTo(i
- 1, state
);
257 state
= SCE_SCRIPTOL_DEFAULT
;
260 else if(state
== SCE_SCRIPTOL_COMMENTBLOCK
)
262 if(chPrev
== '*' && ch
== '/')
264 styler
.ColourTo(i
, state
);
265 state
= SCE_SCRIPTOL_DEFAULT
;
268 else if ((state
== SCE_SCRIPTOL_STRING
) ||
269 (state
== SCE_SCRIPTOL_CHARACTER
))
271 if ((ch
== '\r' || ch
== '\n') && (chPrev
!= '\\'))
273 styler
.ColourTo(i
- 1, state
);
274 state
= SCE_SCRIPTOL_STRINGEOL
;
278 if (chNext
== '\"' || chNext
== '\'' || chNext
== '\\')
282 chNext
= styler
.SafeGetCharAt(i
+ 1);
285 else if ((ch
== '\"') || (ch
== '\''))
287 // must match the entered quote type
290 styler
.ColourTo(i
, state
);
291 state
= SCE_SCRIPTOL_DEFAULT
;
295 else if (state
== SCE_SCRIPTOL_TRIPLE
)
297 if ((ch
== '\'' && chPrev
== '\'' && chPrev2
== '\'') ||
298 (ch
== '\"' && chPrev
== '\"' && chPrev2
== '\"'))
300 styler
.ColourTo(i
, state
);
301 state
= SCE_SCRIPTOL_DEFAULT
;
309 if (state
== SCE_SCRIPTOL_KEYWORD
)
311 ClassifyWordSol(styler
.GetStartSegment(),
312 lengthDoc
-1, keywords
, styler
, prevWord
);
316 styler
.ColourTo(lengthDoc
-1, state
);
320 static void FoldSolDoc(unsigned int startPos
, int length
, int initStyle
,
321 WordList
*[], Accessor
&styler
)
323 int lengthDoc
= startPos
+ length
;
325 int lineCurrent
= styler
.GetLine(startPos
);
331 startPos
= styler
.LineStart(lineCurrent
);
333 initStyle
= SCE_SCRIPTOL_DEFAULT
;
335 initStyle
= styler
.StyleAt(startPos
-1);
338 int state
= initStyle
& 31;
340 int indentCurrent
= styler
.IndentAmount(lineCurrent
, &spaceFlags
, IsSolComment
);
341 if (state
== SCE_SCRIPTOL_TRIPLE
)
342 indentCurrent
|= SC_FOLDLEVELWHITEFLAG
;
343 char chNext
= styler
[startPos
];
344 for (int i
= startPos
; i
< lengthDoc
; i
++)
347 chNext
= styler
.SafeGetCharAt(i
+ 1);
348 int style
= styler
.StyleAt(i
) & 31;
350 if ((ch
== '\r' && chNext
!= '\n') || (ch
== '\n') || (i
== lengthDoc
))
352 int lev
= indentCurrent
;
353 int indentNext
= styler
.IndentAmount(lineCurrent
+ 1, &spaceFlags
, IsSolComment
);
354 if (style
== SCE_SCRIPTOL_TRIPLE
)
355 indentNext
|= SC_FOLDLEVELWHITEFLAG
;
356 if (!(indentCurrent
& SC_FOLDLEVELWHITEFLAG
))
358 // Only non whitespace lines can be headers
359 if ((indentCurrent
& SC_FOLDLEVELNUMBERMASK
) < (indentNext
& SC_FOLDLEVELNUMBERMASK
))
361 lev
|= SC_FOLDLEVELHEADERFLAG
;
363 else if (indentNext
& SC_FOLDLEVELWHITEFLAG
)
365 // Line after is blank so check the next - maybe should continue further?
367 int indentNext2
= styler
.IndentAmount(lineCurrent
+ 2, &spaceFlags2
, IsSolComment
);
368 if ((indentCurrent
& SC_FOLDLEVELNUMBERMASK
) < (indentNext2
& SC_FOLDLEVELNUMBERMASK
))
370 lev
|= SC_FOLDLEVELHEADERFLAG
;
374 indentCurrent
= indentNext
;
375 styler
.SetLevel(lineCurrent
, lev
);
381 LexerModule
lmScriptol(SCLEX_SCRIPTOL
, ColouriseSolDoc
, "scriptol", FoldSolDoc
);