1
// Scintilla source code edit control
4
** Based on LexPascal.cxx
5
** Written by Laurent le Tynevez
6
** Updated by Simon Steele <s.steele@pnotepad.org> September 2002
7
** Updated by Mathias Rauen <scite@madshi.net> May 2003 (Delphi adjustments)
8
** Updated by Rod Falck, Aug 2006 Converted to TAL
22
#include "Scintilla.h"
24
#include "StyleContext.h"
27
using namespace Scintilla;
30
inline bool isTALoperator(char ch)
32
return ch == '\'' || ch == '@' || ch == '#' || isoperator(ch);
35
inline bool isTALwordchar(char ch)
37
return ch == '$' || ch == '^' || iswordchar(ch);
40
inline bool isTALwordstart(char ch)
42
return ch == '$' || ch == '^' || iswordstart(ch);
45
static void getRange(unsigned int start,
51
while ((i < end - start + 1) && (i < len-1)) {
52
s[i] = static_cast<char>(tolower(styler[start + i]));
58
static bool IsStreamCommentStyle(int style) {
59
return style == SCE_C_COMMENT ||
60
style == SCE_C_COMMENTDOC ||
61
style == SCE_C_COMMENTDOCKEYWORD ||
62
style == SCE_C_COMMENTDOCKEYWORDERROR;
65
static void ColourTo(Accessor &styler, unsigned int end, unsigned int attr, bool bInAsm) {
66
if ((bInAsm) && (attr == SCE_C_OPERATOR || attr == SCE_C_NUMBER || attr == SCE_C_DEFAULT || attr == SCE_C_WORD || attr == SCE_C_IDENTIFIER)) {
67
styler.ColourTo(end, SCE_C_REGEX);
69
styler.ColourTo(end, attr);
72
// returns 1 if the item starts a class definition, and -1 if the word is "end", and 2 if the word is "asm"
73
static int classifyWordTAL(unsigned int start, unsigned int end, /*WordList &keywords*/WordList *keywordlists[], Accessor &styler, bool bInAsm) {
76
WordList& keywords = *keywordlists[0];
77
WordList& builtins = *keywordlists[1];
78
WordList& nonreserved_keywords = *keywordlists[2];
81
getRange(start, end, styler, s, sizeof(s));
83
char chAttr = SCE_C_IDENTIFIER;
84
if (isdigit(s[0]) || (s[0] == '.')) {
85
chAttr = SCE_C_NUMBER;
88
if (keywords.InList(s)) {
91
if (strcmp(s, "asm") == 0) {
94
else if (strcmp(s, "end") == 0) {
98
else if (s[0] == '$' || builtins.InList(s)) {
101
else if (nonreserved_keywords.InList(s)) {
105
ColourTo(styler, end, chAttr, (bInAsm && ret != -1));
109
static int classifyFoldPointTAL(const char* s) {
111
if (!(isdigit(s[0]) || (s[0] == '.'))) {
112
if (strcmp(s, "begin") == 0 ||
113
strcmp(s, "block") == 0) {
115
} else if (strcmp(s, "end") == 0) {
122
static void ColouriseTALDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
125
styler.StartAt(startPos);
127
int state = initStyle;
128
if (state == SCE_C_CHARACTER) // Does not leak onto next line
129
state = SCE_C_DEFAULT;
131
char chNext = styler[startPos];
132
unsigned int lengthDoc = startPos + length;
134
bool bInClassDefinition;
136
int currentLine = styler.GetLine(startPos);
137
if (currentLine > 0) {
138
styler.SetLineState(currentLine, styler.GetLineState(currentLine-1));
139
bInClassDefinition = (styler.GetLineState(currentLine) == 1);
141
styler.SetLineState(currentLine, 0);
142
bInClassDefinition = false;
145
bool bInAsm = (state == SCE_C_REGEX);
147
state = SCE_C_DEFAULT;
149
styler.StartSegment(startPos);
150
int visibleChars = 0;
151
for (unsigned int i = startPos; i < lengthDoc; i++) {
154
chNext = styler.SafeGetCharAt(i + 1);
156
if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
157
// Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
158
// Avoid triggering two times on Dos/Win
160
if (state == SCE_C_CHARACTER) {
161
ColourTo(styler, i, state, bInAsm);
162
state = SCE_C_DEFAULT;
166
styler.SetLineState(currentLine, (bInClassDefinition ? 1 : 0));
169
if (styler.IsLeadByte(ch)) {
170
chNext = styler.SafeGetCharAt(i + 2);
176
if (state == SCE_C_DEFAULT) {
177
if (isTALwordstart(ch)) {
178
ColourTo(styler, i-1, state, bInAsm);
179
state = SCE_C_IDENTIFIER;
180
} else if (ch == '!' && chNext != '*') {
181
ColourTo(styler, i-1, state, bInAsm);
182
state = SCE_C_COMMENT;
183
} else if (ch == '!' && chNext == '*') {
184
ColourTo(styler, i-1, state, bInAsm);
185
state = SCE_C_COMMENTDOC;
186
} else if (ch == '-' && chNext == '-') {
187
ColourTo(styler, i-1, state, bInAsm);
188
state = SCE_C_COMMENTLINE;
189
} else if (ch == '"') {
190
ColourTo(styler, i-1, state, bInAsm);
191
state = SCE_C_STRING;
192
} else if (ch == '?' && visibleChars == 0) {
193
ColourTo(styler, i-1, state, bInAsm);
194
state = SCE_C_PREPROCESSOR;
195
} else if (isTALoperator(ch)) {
196
ColourTo(styler, i-1, state, bInAsm);
197
ColourTo(styler, i, SCE_C_OPERATOR, bInAsm);
199
} else if (state == SCE_C_IDENTIFIER) {
200
if (!isTALwordchar(ch)) {
201
int lStateChange = classifyWordTAL(styler.GetStartSegment(), i - 1, keywordlists, styler, bInAsm);
203
if(lStateChange == 1) {
204
styler.SetLineState(currentLine, 1);
205
bInClassDefinition = true;
206
} else if(lStateChange == 2) {
208
} else if(lStateChange == -1) {
209
styler.SetLineState(currentLine, 0);
210
bInClassDefinition = false;
214
state = SCE_C_DEFAULT;
215
chNext = styler.SafeGetCharAt(i + 1);
216
if (ch == '!' && chNext != '*') {
217
state = SCE_C_COMMENT;
218
} else if (ch == '!' && chNext == '*') {
219
ColourTo(styler, i-1, state, bInAsm);
220
state = SCE_C_COMMENTDOC;
221
} else if (ch == '-' && chNext == '-') {
222
state = SCE_C_COMMENTLINE;
223
} else if (ch == '"') {
224
state = SCE_C_STRING;
225
} else if (isTALoperator(ch)) {
226
ColourTo(styler, i, SCE_C_OPERATOR, bInAsm);
230
if (state == SCE_C_PREPROCESSOR) {
231
if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) {
232
ColourTo(styler, i-1, state, bInAsm);
233
state = SCE_C_DEFAULT;
235
} else if (state == SCE_C_COMMENT) {
236
if (ch == '!' || (ch == '\r' || ch == '\n') ) {
237
ColourTo(styler, i, state, bInAsm);
238
state = SCE_C_DEFAULT;
240
} else if (state == SCE_C_COMMENTDOC) {
241
if (ch == '!' || (ch == '\r' || ch == '\n')) {
242
if (((i > styler.GetStartSegment() + 2) || (
243
(initStyle == SCE_C_COMMENTDOC) &&
244
(styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) {
245
ColourTo(styler, i, state, bInAsm);
246
state = SCE_C_DEFAULT;
249
} else if (state == SCE_C_COMMENTLINE) {
250
if (ch == '\r' || ch == '\n') {
251
ColourTo(styler, i-1, state, bInAsm);
252
state = SCE_C_DEFAULT;
254
} else if (state == SCE_C_STRING) {
256
ColourTo(styler, i, state, bInAsm);
257
state = SCE_C_DEFAULT;
261
if (!isspacechar(ch))
265
ColourTo(styler, lengthDoc - 1, state, bInAsm);
268
static void FoldTALDoc(unsigned int startPos, int length, int initStyle, WordList *[],
270
bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
271
bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
272
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
273
unsigned int endPos = startPos + length;
274
int visibleChars = 0;
275
int lineCurrent = styler.GetLine(startPos);
276
int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
277
int levelCurrent = levelPrev;
278
char chNext = styler[startPos];
279
int styleNext = styler.StyleAt(startPos);
280
int style = initStyle;
281
bool was_end = false;
282
bool section = false;
286
for (unsigned int i = startPos; i < endPos; i++) {
288
chNext = styler.SafeGetCharAt(i + 1);
289
int stylePrev = style;
291
styleNext = styler.StyleAt(i + 1);
292
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
294
if (stylePrev == SCE_C_DEFAULT && (style == SCE_C_WORD || style == SCE_C_UUID || style == SCE_C_PREPROCESSOR))
296
// Store last word start point.
300
if (stylePrev == SCE_C_WORD || style == SCE_C_UUID || stylePrev == SCE_C_PREPROCESSOR) {
301
if(isTALwordchar(ch) && !isTALwordchar(chNext)) {
303
getRange(lastStart, i, styler, s, sizeof(s));
304
if (stylePrev == SCE_C_PREPROCESSOR && strcmp(s, "?section") == 0)
310
else if (stylePrev == SCE_C_WORD || stylePrev == SCE_C_UUID)
312
if (strcmp(s, "block") == 0)
314
// block keyword is ignored immediately after end keyword
319
levelCurrent += classifyFoldPointTAL(s);
320
if (strcmp(s, "end") == 0)
332
if (foldComment && (style == SCE_C_COMMENTLINE)) {
333
if ((ch == '/') && (chNext == '/')) {
334
char chNext2 = styler.SafeGetCharAt(i + 2);
335
if (chNext2 == '{') {
337
} else if (chNext2 == '}') {
343
if (foldPreprocessor && (style == SCE_C_PREPROCESSOR)) {
344
if (ch == '{' && chNext == '$') {
345
unsigned int j=i+2; // skip {$
346
while ((j<endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
349
if (styler.Match(j, "region") || styler.Match(j, "if")) {
351
} else if (styler.Match(j, "end")) {
357
if (foldComment && IsStreamCommentStyle(style)) {
358
if (!IsStreamCommentStyle(stylePrev)) {
360
} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
361
// Comments don't end at end of line and the next character may be unstyled.
367
int lev = levelPrev | SC_FOLDLEVELBASE;
368
if (visibleChars == 0 && foldCompact)
369
lev |= SC_FOLDLEVELWHITEFLAG;
370
if ((levelCurrent > levelPrev || section) && (visibleChars > 0))
371
lev |= SC_FOLDLEVELHEADERFLAG;
372
if (lev != styler.LevelAt(lineCurrent)) {
373
styler.SetLevel(lineCurrent, lev);
376
levelPrev = levelCurrent;
381
if (!isspacechar(ch))
385
// Fill in the real level of the next line, keeping the current flags as they will be filled in later
386
int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
387
styler.SetLevel(lineCurrent, levelPrev | flagsNext);
390
static const char * const TALWordListDesc[] = {
396
LexerModule lmTAL(SCLEX_TAL, ColouriseTALDoc, "TAL", FoldTALDoc, TALWordListDesc);