updated Scintilla to 2.29
[TortoiseGit.git] / ext / scintilla / lexers / LexScriptol.cxx
blob92c7ff5a65a1ea1b294432ef69d36b90d982a3c8
1 // Scintilla source code edit control
2 /** @file LexScriptol.cxx
3 ** Lexer for Scriptol.
4 **/
6 #include <stdlib.h>
7 #include <string.h>
8 #include <stdio.h>
9 #include <stdarg.h>
10 #include <assert.h>
11 #include <ctype.h>
13 #include "ILexer.h"
14 #include "Scintilla.h"
15 #include "SciLexer.h"
17 #include "WordList.h"
18 #include "LexAccessor.h"
19 #include "Accessor.h"
20 #include "StyleContext.h"
21 #include "CharacterSet.h"
22 #include "LexerModule.h"
24 #ifdef SCI_NAMESPACE
25 using namespace Scintilla;
26 #endif
28 static void ClassifyWordSol(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord)
30 char s[100];
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];
35 s[i + 1] = '\0';
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);
50 strcpy(prevWord, s);
53 static bool IsSolComment(Accessor &styler, int pos, int len)
55 if(len > 0)
57 char c = styler[pos];
58 if(c == '`') return true;
59 if(len > 1)
61 if(c == '/')
63 c = styler[pos + 1];
64 if(c == '/') return true;
65 if(c == '*') return true;
69 return false;
72 static bool IsSolStringStart(char ch)
74 if (ch == '\'' || ch == '"') return true;
75 return false;
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 != '\'')
91 *nextIndex = i + 1;
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))
98 *nextIndex = i + 3;
99 if(ch == '\"') return SCE_SCRIPTOL_TRIPLE;
100 if(ch == '\'') return SCE_SCRIPTOL_TRIPLE;
101 return SCE_SCRIPTOL_STRING;
103 else
105 *nextIndex = i + 1;
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 = '\"';
119 if (startPos > 0)
121 int lineCurrent = styler.GetLine(startPos);
122 if (lineCurrent > 0)
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, 127);
132 WordList &keywords = *keywordlists[0];
134 int whingeLevel = styler.GetPropertyInt("tab.timmy.whinge.level");
135 char prevWord[200];
136 prevWord[0] = '\0';
137 if (length == 0) return;
139 int state = initStyle & 31;
141 int nextIndex = 0;
142 char chPrev = ' ';
143 char chPrev2 = ' ';
144 char chNext = styler[startPos];
145 styler.StartSegment(startPos);
146 bool atStartLine = true;
147 int spaceFlags = 0;
148 for (int i = startPos; i < lengthDoc; i++)
151 if (atStartLine)
153 char chBad = static_cast<char>(64);
154 char chGood = static_cast<char>(0);
155 char chFlags = chGood;
157 if (whingeLevel == 1)
159 chFlags = (spaceFlags & wsInconsistent) ? chBad : chGood;
161 else if (whingeLevel == 2)
163 chFlags = (spaceFlags & wsSpaceTab) ? chBad : chGood;
165 else if (whingeLevel == 3)
167 chFlags = (spaceFlags & wsSpace) ? chBad : chGood;
169 else if (whingeLevel == 4)
171 chFlags = (spaceFlags & wsTab) ? chBad : chGood;
173 styler.SetFlags(chFlags, static_cast<char>(state));
174 atStartLine = false;
177 char ch = chNext;
178 chNext = styler.SafeGetCharAt(i + 1);
180 if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc))
182 if ((state == SCE_SCRIPTOL_DEFAULT) ||
183 (state == SCE_SCRIPTOL_TRIPLE) ||
184 (state == SCE_SCRIPTOL_COMMENTBLOCK))
186 styler.ColourTo(i, state);
188 atStartLine = true;
191 if (styler.IsLeadByte(ch))
193 chNext = styler.SafeGetCharAt(i + 2);
194 chPrev = ' ';
195 chPrev2 = ' ';
196 i += 1;
197 continue;
200 if (state == SCE_SCRIPTOL_STRINGEOL)
202 if (ch != '\r' && ch != '\n')
204 styler.ColourTo(i - 1, state);
205 state = SCE_SCRIPTOL_DEFAULT;
209 if (state == SCE_SCRIPTOL_DEFAULT)
211 if (IsSolWordStart(ch))
213 styler.ColourTo(i - 1, state);
214 state = SCE_SCRIPTOL_KEYWORD;
216 else if (ch == '`')
218 styler.ColourTo(i - 1, state);
219 state = SCE_SCRIPTOL_COMMENTLINE;
221 else if (ch == '/')
223 styler.ColourTo(i - 1, state);
224 if(chNext == '/') state = SCE_SCRIPTOL_CSTYLE;
225 if(chNext == '*') state = SCE_SCRIPTOL_COMMENTBLOCK;
228 else if (IsSolStringStart(ch))
230 styler.ColourTo(i - 1, state);
231 state = GetSolStringState(styler, i, &nextIndex);
232 if(state == SCE_SCRIPTOL_STRING)
234 stringType = ch;
236 if (nextIndex != i + 1)
238 i = nextIndex - 1;
239 ch = ' ';
240 chPrev = ' ';
241 chNext = styler.SafeGetCharAt(i + 1);
244 else if (isoperator(ch))
246 styler.ColourTo(i - 1, state);
247 styler.ColourTo(i, SCE_SCRIPTOL_OPERATOR);
250 else if (state == SCE_SCRIPTOL_KEYWORD)
252 if (!iswordchar(ch))
254 ClassifyWordSol(styler.GetStartSegment(), i - 1, keywords, styler, prevWord);
255 state = SCE_SCRIPTOL_DEFAULT;
256 if (ch == '`')
258 state = chNext == '`' ? SCE_SCRIPTOL_PERSISTENT : SCE_SCRIPTOL_COMMENTLINE;
260 else if (IsSolStringStart(ch))
262 styler.ColourTo(i - 1, state);
263 state = GetSolStringState(styler, i, &nextIndex);
264 if (nextIndex != i + 1)
266 i = nextIndex - 1;
267 ch = ' ';
268 chPrev = ' ';
269 chNext = styler.SafeGetCharAt(i + 1);
272 else if (isoperator(ch))
274 styler.ColourTo(i, SCE_SCRIPTOL_OPERATOR);
278 else
280 if (state == SCE_SCRIPTOL_COMMENTLINE ||
281 state == SCE_SCRIPTOL_PERSISTENT ||
282 state == SCE_SCRIPTOL_CSTYLE)
284 if (ch == '\r' || ch == '\n')
286 styler.ColourTo(i - 1, state);
287 state = SCE_SCRIPTOL_DEFAULT;
290 else if(state == SCE_SCRIPTOL_COMMENTBLOCK)
292 if(chPrev == '*' && ch == '/')
294 styler.ColourTo(i, state);
295 state = SCE_SCRIPTOL_DEFAULT;
298 else if ((state == SCE_SCRIPTOL_STRING) ||
299 (state == SCE_SCRIPTOL_CHARACTER))
301 if ((ch == '\r' || ch == '\n') && (chPrev != '\\'))
303 styler.ColourTo(i - 1, state);
304 state = SCE_SCRIPTOL_STRINGEOL;
306 else if (ch == '\\')
308 if (chNext == '\"' || chNext == '\'' || chNext == '\\')
310 i++;
311 ch = chNext;
312 chNext = styler.SafeGetCharAt(i + 1);
315 else if ((ch == '\"') || (ch == '\''))
317 // must match the entered quote type
318 if(ch == stringType)
320 styler.ColourTo(i, state);
321 state = SCE_SCRIPTOL_DEFAULT;
325 else if (state == SCE_SCRIPTOL_TRIPLE)
327 if ((ch == '\'' && chPrev == '\'' && chPrev2 == '\'') ||
328 (ch == '\"' && chPrev == '\"' && chPrev2 == '\"'))
330 styler.ColourTo(i, state);
331 state = SCE_SCRIPTOL_DEFAULT;
336 chPrev2 = chPrev;
337 chPrev = ch;
339 if (state == SCE_SCRIPTOL_KEYWORD)
341 ClassifyWordSol(styler.GetStartSegment(),
342 lengthDoc-1, keywords, styler, prevWord);
344 else
346 styler.ColourTo(lengthDoc-1, state);
350 static void FoldSolDoc(unsigned int startPos, int length, int initStyle,
351 WordList *[], Accessor &styler)
353 int lengthDoc = startPos + length;
355 int lineCurrent = styler.GetLine(startPos);
356 if (startPos > 0)
358 if (lineCurrent > 0)
360 lineCurrent--;
361 startPos = styler.LineStart(lineCurrent);
362 if (startPos == 0)
363 initStyle = SCE_SCRIPTOL_DEFAULT;
364 else
365 initStyle = styler.StyleAt(startPos-1);
368 int state = initStyle & 31;
369 int spaceFlags = 0;
370 int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsSolComment);
371 if ((state == SCE_SCRIPTOL_TRIPLE))
372 indentCurrent |= SC_FOLDLEVELWHITEFLAG;
373 char chNext = styler[startPos];
374 for (int i = startPos; i < lengthDoc; i++)
376 char ch = chNext;
377 chNext = styler.SafeGetCharAt(i + 1);
378 int style = styler.StyleAt(i) & 31;
380 if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc))
382 int lev = indentCurrent;
383 int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsSolComment);
384 if (style == SCE_SCRIPTOL_TRIPLE)
385 indentNext |= SC_FOLDLEVELWHITEFLAG;
386 if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG))
388 // Only non whitespace lines can be headers
389 if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK))
391 lev |= SC_FOLDLEVELHEADERFLAG;
393 else if (indentNext & SC_FOLDLEVELWHITEFLAG)
395 // Line after is blank so check the next - maybe should continue further?
396 int spaceFlags2 = 0;
397 int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsSolComment);
398 if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK))
400 lev |= SC_FOLDLEVELHEADERFLAG;
404 indentCurrent = indentNext;
405 styler.SetLevel(lineCurrent, lev);
406 lineCurrent++;
411 LexerModule lmScriptol(SCLEX_SCRIPTOL, ColouriseSolDoc, "scriptol", FoldSolDoc);