1 // SciTE - Scintilla based Text Editor
\r
2 // LexBullant.cxx - lexer for Bullant
\r
10 #include "Platform.h"
\r
12 #include "PropSet.h"
\r
13 #include "Accessor.h"
\r
14 #include "KeyWords.h"
\r
15 #include "Scintilla.h"
\r
16 #include "SciLexer.h"
\r
18 #ifdef SCI_NAMESPACE
\r
19 using namespace Scintilla;
\r
22 static int classifyWordBullant(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
\r
24 for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
\r
25 s[i] = static_cast<char>(tolower(styler[start + i]));
\r
29 char chAttr = SCE_C_IDENTIFIER;
\r
30 if (isdigit(s[0]) || (s[0] == '.')){
\r
31 chAttr = SCE_C_NUMBER;
\r
34 if (keywords.InList(s)) {
\r
35 chAttr = SCE_C_WORD;
\r
36 if (strcmp(s, "end") == 0)
\r
38 else if (strcmp(s, "method") == 0 ||
\r
39 strcmp(s, "case") == 0 ||
\r
40 strcmp(s, "class") == 0 ||
\r
41 strcmp(s, "debug") == 0 ||
\r
42 strcmp(s, "test") == 0 ||
\r
43 strcmp(s, "if") == 0 ||
\r
44 strcmp(s, "lock") == 0 ||
\r
45 strcmp(s, "transaction") == 0 ||
\r
46 strcmp(s, "trap") == 0 ||
\r
47 strcmp(s, "until") == 0 ||
\r
48 strcmp(s, "while") == 0)
\r
52 styler.ColourTo(end, chAttr);
\r
56 static void ColouriseBullantDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
\r
58 WordList &keywords = *keywordlists[0];
\r
60 styler.StartAt(startPos);
\r
62 bool fold = styler.GetPropertyInt("fold") != 0;
\r
63 int lineCurrent = styler.GetLine(startPos);
\r
64 int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
\r
65 int levelCurrent = levelPrev;
\r
67 int state = initStyle;
\r
68 if (state == SCE_C_STRINGEOL) // Does not leak onto next line
\r
69 state = SCE_C_DEFAULT;
\r
71 char chNext = styler[startPos];
\r
72 unsigned int lengthDoc = startPos + length;
\r
73 int visibleChars = 0;
\r
74 styler.StartSegment(startPos);
\r
75 int endFoundThisLine = 0;
\r
76 for (unsigned int i = startPos; i < lengthDoc; i++) {
\r
78 chNext = styler.SafeGetCharAt(i + 1);
\r
80 if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
\r
81 // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
\r
82 // Avoid triggering two times on Dos/Win
\r
84 endFoundThisLine = 0;
\r
85 if (state == SCE_C_STRINGEOL) {
\r
86 styler.ColourTo(i, state);
\r
87 state = SCE_C_DEFAULT;
\r
90 int lev = levelPrev;
\r
91 if (visibleChars == 0)
\r
92 lev |= SC_FOLDLEVELWHITEFLAG;
\r
93 if ((levelCurrent > levelPrev) && (visibleChars > 0))
\r
94 lev |= SC_FOLDLEVELHEADERFLAG;
\r
95 styler.SetLevel(lineCurrent, lev);
\r
97 levelPrev = levelCurrent;
\r
101 /* int indentBlock = GetLineIndentation(lineCurrent);
\r
102 if (blockChange==1){
\r
104 int pos=SetLineIndentation(lineCurrent, indentBlock + indentSize);
\r
105 } else if (blockChange==-1) {
\r
106 indentBlock -= indentSize;
\r
107 if (indentBlock < 0)
\r
109 SetLineIndentation(lineCurrent, indentBlock);
\r
117 if (styler.IsLeadByte(ch)) {
\r
118 chNext = styler.SafeGetCharAt(i + 2);
\r
124 if (state == SCE_C_DEFAULT) {
\r
125 if (iswordstart(ch)) {
\r
126 styler.ColourTo(i-1, state);
\r
127 state = SCE_C_IDENTIFIER;
\r
128 } else if (ch == '@' && chNext == 'o') {
\r
129 if ((styler.SafeGetCharAt(i+2) =='f') && (styler.SafeGetCharAt(i+3) == 'f')) {
\r
130 styler.ColourTo(i-1, state);
\r
131 state = SCE_C_COMMENT;
\r
133 } else if (ch == '#') {
\r
134 styler.ColourTo(i-1, state);
\r
135 state = SCE_C_COMMENTLINE;
\r
136 } else if (ch == '\"') {
\r
137 styler.ColourTo(i-1, state);
\r
138 state = SCE_C_STRING;
\r
139 } else if (ch == '\'') {
\r
140 styler.ColourTo(i-1, state);
\r
141 state = SCE_C_CHARACTER;
\r
142 } else if (isoperator(ch)) {
\r
143 styler.ColourTo(i-1, state);
\r
144 styler.ColourTo(i, SCE_C_OPERATOR);
\r
146 } else if (state == SCE_C_IDENTIFIER) {
\r
147 if (!iswordchar(ch)) {
\r
148 int levelChange = classifyWordBullant(styler.GetStartSegment(), i - 1, keywords, styler);
\r
149 state = SCE_C_DEFAULT;
\r
150 chNext = styler.SafeGetCharAt(i + 1);
\r
152 state = SCE_C_COMMENTLINE;
\r
153 } else if (ch == '\"') {
\r
154 state = SCE_C_STRING;
\r
155 } else if (ch == '\'') {
\r
156 state = SCE_C_CHARACTER;
\r
157 } else if (isoperator(ch)) {
\r
158 styler.ColourTo(i, SCE_C_OPERATOR);
\r
160 if (endFoundThisLine == 0)
\r
161 levelCurrent+=levelChange;
\r
162 if (levelChange == -1)
\r
163 endFoundThisLine=1;
\r
165 } else if (state == SCE_C_COMMENT) {
\r
166 if (ch == '@' && chNext == 'o') {
\r
167 if (styler.SafeGetCharAt(i+2) == 'n') {
\r
168 styler.ColourTo(i+2, state);
\r
169 state = SCE_C_DEFAULT;
\r
173 } else if (state == SCE_C_COMMENTLINE) {
\r
174 if (ch == '\r' || ch == '\n') {
\r
175 endFoundThisLine = 0;
\r
176 styler.ColourTo(i-1, state);
\r
177 state = SCE_C_DEFAULT;
\r
179 } else if (state == SCE_C_STRING) {
\r
181 if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
\r
184 chNext = styler.SafeGetCharAt(i + 1);
\r
186 } else if (ch == '\"') {
\r
187 styler.ColourTo(i, state);
\r
188 state = SCE_C_DEFAULT;
\r
189 } else if (chNext == '\r' || chNext == '\n') {
\r
190 endFoundThisLine = 0;
\r
191 styler.ColourTo(i-1, SCE_C_STRINGEOL);
\r
192 state = SCE_C_STRINGEOL;
\r
194 } else if (state == SCE_C_CHARACTER) {
\r
195 if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) {
\r
196 endFoundThisLine = 0;
\r
197 styler.ColourTo(i-1, SCE_C_STRINGEOL);
\r
198 state = SCE_C_STRINGEOL;
\r
199 } else if (ch == '\\') {
\r
200 if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
\r
203 chNext = styler.SafeGetCharAt(i + 1);
\r
205 } else if (ch == '\'') {
\r
206 styler.ColourTo(i, state);
\r
207 state = SCE_C_DEFAULT;
\r
212 styler.ColourTo(lengthDoc - 1, state);
\r
214 // Fill in the real level of the next line, keeping the current flags as they will be filled in later
\r
216 int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
\r
217 //styler.SetLevel(lineCurrent, levelCurrent | flagsNext);
\r
218 styler.SetLevel(lineCurrent, levelPrev | flagsNext);
\r
223 static const char * const bullantWordListDesc[] = {
\r
228 LexerModule lmBullant(SCLEX_BULLANT, ColouriseBullantDoc, "bullant", 0, bullantWordListDesc);
\r