1
// Scintilla source code edit control
2
// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
4
This is the Lexer for Gui4Cli, included in SciLexer.dll
5
- by d. Keletsekis, 2/10/2003
7
To add to SciLexer.dll:
8
1. Add the values below to INCLUDE\Scintilla.iface
9
2. Run the include/HFacer.py script
10
3. Run the src/lexGen.py script
13
val SCE_GC_COMMENTLINE=1
14
val SCE_GC_COMMENTBLOCK=2
17
val SCE_GC_ATTRIBUTE=5
34
#include "StyleContext.h"
36
#include "Scintilla.h"
40
using namespace Scintilla;
43
#define debug Platform::DebugPrintf
45
static inline bool IsAWordChar(const int ch) {
46
return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch =='\\');
49
static inline bool IsAWordStart(const int ch) {
50
return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.');
53
inline bool isGCOperator(int ch)
56
// '.' left out as it is used to make up numbers
57
if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
58
ch == '(' || ch == ')' || ch == '=' || ch == '%' ||
59
ch == '[' || ch == ']' || ch == '<' || ch == '>' ||
60
ch == ',' || ch == ';' || ch == ':')
65
#define isSpace(x) ((x)==' ' || (x)=='\t')
66
#define isNL(x) ((x)=='\n' || (x)=='\r')
67
#define isSpaceOrNL(x) (isSpace(x) || isNL(x))
69
#define isFoldPoint(x) ((styler.LevelAt(x) & SC_FOLDLEVELNUMBERMASK) == 1024)
71
static void colorFirstWord(WordList *keywordlists[], Accessor &styler,
72
StyleContext *sc, char *buff, int length, int)
75
while (sc->More() && isSpaceOrNL(sc->ch))
78
styler.ColourTo(sc->currentPos - 1, sc->state);
80
if (!IsAWordChar(sc->ch)) // comment, marker, etc..
83
while (sc->More() && !isSpaceOrNL(sc->ch) && (c < length-1) && !isGCOperator(sc->ch))
84
{ buff[c] = static_cast<char>(sc->ch);
89
while (*p) // capitalize..
90
{ if (islower(*p)) *p = static_cast<char>(toupper(*p));
94
WordList &kGlobal = *keywordlists[0]; // keyword lists set by the user
95
WordList &kEvent = *keywordlists[1];
96
WordList &kAttribute = *keywordlists[2];
97
WordList &kControl = *keywordlists[3];
98
WordList &kCommand = *keywordlists[4];
101
// int level = styler.LevelAt(line) & SC_FOLDLEVELNUMBERMASK;
102
// debug ("line = %d, level = %d", line, level);
104
if (kGlobal.InList(buff)) state = SCE_GC_GLOBAL;
105
else if (kAttribute.InList(buff)) state = SCE_GC_ATTRIBUTE;
106
else if (kControl.InList(buff)) state = SCE_GC_CONTROL;
107
else if (kCommand.InList(buff)) state = SCE_GC_COMMAND;
108
else if (kEvent.InList(buff)) state = SCE_GC_EVENT;
111
{ sc->ChangeState(state);
112
styler.ColourTo(sc->currentPos - 1, sc->state);
113
sc->ChangeState(SCE_GC_DEFAULT);
116
{ sc->ChangeState(SCE_GC_DEFAULT);
117
styler.ColourTo(sc->currentPos - 1, sc->state);
121
// Main colorizing function called by Scintilla
123
ColouriseGui4CliDoc(unsigned int startPos, int length, int initStyle,
124
WordList *keywordlists[], Accessor &styler)
126
styler.StartAt(startPos);
128
int quotestart = 0, oldstate, currentline = styler.GetLine(startPos);
129
styler.StartSegment(startPos);
131
char buff[BUFFSIZE+1]; // buffer for command name
133
StyleContext sc(startPos, length, initStyle, styler);
134
buff[0] = '\0'; // cbuff = 0;
136
if (sc.state != SCE_GC_COMMENTBLOCK) // colorize 1st word..
137
colorFirstWord(keywordlists, styler, &sc, buff, BUFFSIZE, currentline);
145
if (sc.state == SCE_GC_COMMENTBLOCK || sc.state == SCE_GC_STRING)
147
if (sc.chNext == '/') // line comment
148
{ sc.SetState (SCE_GC_COMMENTLINE);
150
styler.ColourTo(sc.currentPos, sc.state);
152
else if (sc.chNext == '*') // block comment
153
{ sc.SetState(SCE_GC_COMMENTBLOCK);
155
styler.ColourTo(sc.currentPos, sc.state);
158
styler.ColourTo(sc.currentPos, sc.state);
161
case '*': // end of comment block, or operator..
162
if (sc.state == SCE_GC_STRING)
164
if (sc.state == SCE_GC_COMMENTBLOCK && sc.chNext == '/')
166
styler.ColourTo(sc.currentPos, sc.state);
167
sc.ChangeState (SCE_GC_DEFAULT);
170
styler.ColourTo(sc.currentPos, sc.state);
173
case '\'': case '\"': // strings..
174
if (sc.state == SCE_GC_COMMENTBLOCK || sc.state == SCE_GC_COMMENTLINE)
176
if (sc.state == SCE_GC_STRING)
177
{ if (sc.ch == quotestart) // match same quote char..
178
{ styler.ColourTo(sc.currentPos, sc.state);
179
sc.ChangeState(SCE_GC_DEFAULT);
183
{ styler.ColourTo(sc.currentPos - 1, sc.state);
184
sc.ChangeState(SCE_GC_STRING);
189
case ';': // end of commandline character
190
if (sc.state != SCE_GC_COMMENTBLOCK && sc.state != SCE_GC_COMMENTLINE &&
191
sc.state != SCE_GC_STRING)
193
styler.ColourTo(sc.currentPos - 1, sc.state);
194
styler.ColourTo(sc.currentPos, SCE_GC_OPERATOR);
195
sc.ChangeState(SCE_GC_DEFAULT);
197
colorFirstWord(keywordlists, styler, &sc, buff, BUFFSIZE, currentline);
198
noforward = 1; // don't move forward - already positioned at next char..
202
case '+': case '-': case '=': case '!': // operators..
203
case '<': case '>': case '&': case '|': case '$':
204
if (sc.state != SCE_GC_COMMENTBLOCK && sc.state != SCE_GC_COMMENTLINE &&
205
sc.state != SCE_GC_STRING)
207
styler.ColourTo(sc.currentPos - 1, sc.state);
208
styler.ColourTo(sc.currentPos, SCE_GC_OPERATOR);
209
sc.ChangeState(SCE_GC_DEFAULT);
213
case '\\': // escape - same as operator, but also mark in strings..
214
if (sc.state != SCE_GC_COMMENTBLOCK && sc.state != SCE_GC_COMMENTLINE)
217
styler.ColourTo(sc.currentPos - 1, sc.state);
218
sc.Forward(); // mark also the next char..
219
styler.ColourTo(sc.currentPos, SCE_GC_OPERATOR);
220
sc.ChangeState(oldstate);
224
case '\n': case '\r':
226
if (sc.state == SCE_GC_COMMENTLINE)
227
{ styler.ColourTo(sc.currentPos, sc.state);
228
sc.ChangeState (SCE_GC_DEFAULT);
230
else if (sc.state != SCE_GC_COMMENTBLOCK)
231
{ colorFirstWord(keywordlists, styler, &sc, buff, BUFFSIZE, currentline);
232
noforward = 1; // don't move forward - already positioned at next char..
236
// case ' ': case '\t':
240
if (!noforward) sc.Forward();
246
// Main folding function called by Scintilla - (based on props (.ini) files function)
247
static void FoldGui4Cli(unsigned int startPos, int length, int,
248
WordList *[], Accessor &styler)
250
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
252
unsigned int endPos = startPos + length;
253
int visibleChars = 0;
254
int lineCurrent = styler.GetLine(startPos);
256
char chNext = styler[startPos];
257
int styleNext = styler.StyleAt(startPos);
258
bool headerPoint = false;
260
for (unsigned int i = startPos; i < endPos; i++)
263
chNext = styler[i+1];
265
int style = styleNext;
266
styleNext = styler.StyleAt(i + 1);
267
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
269
if (style == SCE_GC_EVENT || style == SCE_GC_GLOBAL)
270
{ headerPoint = true; // fold at events and globals
274
{ int lev = SC_FOLDLEVELBASE+1;
277
lev = SC_FOLDLEVELBASE;
279
if (visibleChars == 0 && foldCompact)
280
lev |= SC_FOLDLEVELWHITEFLAG;
283
lev |= SC_FOLDLEVELHEADERFLAG;
285
if (lev != styler.LevelAt(lineCurrent)) // set level, if not already correct
286
{ styler.SetLevel(lineCurrent, lev);
289
lineCurrent++; // re-initialize our flags
294
if (!(isspacechar(ch))) // || (style == SCE_GC_COMMENTLINE) || (style != SCE_GC_COMMENTBLOCK)))
298
int lev = headerPoint ? SC_FOLDLEVELBASE : SC_FOLDLEVELBASE+1;
299
int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
300
styler.SetLevel(lineCurrent, lev | flagsNext);
303
// I have no idea what these are for.. probably accessible by some message.
304
static const char * const gui4cliWordListDesc[] = {
305
"Globals", "Events", "Attributes", "Control", "Commands",
309
// Declare language & pass our function pointers to Scintilla
310
LexerModule lmGui4Cli(SCLEX_GUI4CLI, ColouriseGui4CliDoc, "gui4cli", FoldGui4Cli, gui4cliWordListDesc);