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