]>
git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/LexEiffel.cxx
03dea5e73d36b754a9d25414a7684b55c6fcd006
1 // Scintilla source code edit control
2 /** @file LexEiffel.cxx
5 // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
6 // The License.txt file describes the conditions under which this software may be distributed.
18 #include "StyleContext.h"
20 #include "Scintilla.h"
24 using namespace Scintilla
;
27 static inline bool isEiffelOperator(unsigned int ch
) {
28 // '.' left out as it is used to make up numbers
29 return ch
== '*' || ch
== '/' || ch
== '\\' || ch
== '-' || ch
== '+' ||
30 ch
== '(' || ch
== ')' || ch
== '=' ||
31 ch
== '{' || ch
== '}' || ch
== '~' ||
32 ch
== '[' || ch
== ']' || ch
== ';' ||
33 ch
== '<' || ch
== '>' || ch
== ',' ||
34 ch
== '.' || ch
== '^' || ch
== '%' || ch
== ':' ||
35 ch
== '!' || ch
== '@' || ch
== '?';
38 static inline bool IsAWordChar(unsigned int ch
) {
39 return (ch
< 0x80) && (isalnum(ch
) || ch
== '_');
42 static inline bool IsAWordStart(unsigned int ch
) {
43 return (ch
< 0x80) && (isalnum(ch
) || ch
== '_');
46 static void ColouriseEiffelDoc(unsigned int startPos
,
49 WordList
*keywordlists
[],
52 WordList
&keywords
= *keywordlists
[0];
54 StyleContext
sc(startPos
, length
, initStyle
, styler
);
56 for (; sc
.More(); sc
.Forward()) {
58 if (sc
.state
== SCE_EIFFEL_STRINGEOL
) {
59 if (sc
.ch
!= '\r' && sc
.ch
!= '\n') {
60 sc
.SetState(SCE_EIFFEL_DEFAULT
);
62 } else if (sc
.state
== SCE_EIFFEL_OPERATOR
) {
63 sc
.SetState(SCE_EIFFEL_DEFAULT
);
64 } else if (sc
.state
== SCE_EIFFEL_WORD
) {
65 if (!IsAWordChar(sc
.ch
)) {
67 sc
.GetCurrentLowered(s
, sizeof(s
));
68 if (!keywords
.InList(s
)) {
69 sc
.ChangeState(SCE_EIFFEL_IDENTIFIER
);
71 sc
.SetState(SCE_EIFFEL_DEFAULT
);
73 } else if (sc
.state
== SCE_EIFFEL_NUMBER
) {
74 if (!IsAWordChar(sc
.ch
)) {
75 sc
.SetState(SCE_EIFFEL_DEFAULT
);
77 } else if (sc
.state
== SCE_EIFFEL_COMMENTLINE
) {
78 if (sc
.ch
== '\r' || sc
.ch
== '\n') {
79 sc
.SetState(SCE_EIFFEL_DEFAULT
);
81 } else if (sc
.state
== SCE_EIFFEL_STRING
) {
84 } else if (sc
.ch
== '\"') {
86 sc
.SetState(SCE_EIFFEL_DEFAULT
);
88 } else if (sc
.state
== SCE_EIFFEL_CHARACTER
) {
89 if (sc
.ch
== '\r' || sc
.ch
== '\n') {
90 sc
.SetState(SCE_EIFFEL_STRINGEOL
);
91 } else if (sc
.ch
== '%') {
93 } else if (sc
.ch
== '\'') {
95 sc
.SetState(SCE_EIFFEL_DEFAULT
);
99 if (sc
.state
== SCE_EIFFEL_DEFAULT
) {
100 if (sc
.ch
== '-' && sc
.chNext
== '-') {
101 sc
.SetState(SCE_EIFFEL_COMMENTLINE
);
102 } else if (sc
.ch
== '\"') {
103 sc
.SetState(SCE_EIFFEL_STRING
);
104 } else if (sc
.ch
== '\'') {
105 sc
.SetState(SCE_EIFFEL_CHARACTER
);
106 } else if (IsADigit(sc
.ch
) || (sc
.ch
== '.')) {
107 sc
.SetState(SCE_EIFFEL_NUMBER
);
108 } else if (IsAWordStart(sc
.ch
)) {
109 sc
.SetState(SCE_EIFFEL_WORD
);
110 } else if (isEiffelOperator(sc
.ch
)) {
111 sc
.SetState(SCE_EIFFEL_OPERATOR
);
118 static bool IsEiffelComment(Accessor
&styler
, int pos
, int len
) {
119 return len
>1 && styler
[pos
]=='-' && styler
[pos
+1]=='-';
122 static void FoldEiffelDocIndent(unsigned int startPos
, int length
, int,
123 WordList
*[], Accessor
&styler
) {
124 int lengthDoc
= startPos
+ length
;
126 // Backtrack to previous line in case need to fix its fold status
127 int lineCurrent
= styler
.GetLine(startPos
);
129 if (lineCurrent
> 0) {
131 startPos
= styler
.LineStart(lineCurrent
);
135 int indentCurrent
= styler
.IndentAmount(lineCurrent
, &spaceFlags
, IsEiffelComment
);
136 char chNext
= styler
[startPos
];
137 for (int i
= startPos
; i
< lengthDoc
; i
++) {
139 chNext
= styler
.SafeGetCharAt(i
+ 1);
141 if ((ch
== '\r' && chNext
!= '\n') || (ch
== '\n') || (i
== lengthDoc
)) {
142 int lev
= indentCurrent
;
143 int indentNext
= styler
.IndentAmount(lineCurrent
+ 1, &spaceFlags
, IsEiffelComment
);
144 if (!(indentCurrent
& SC_FOLDLEVELWHITEFLAG
)) {
145 // Only non whitespace lines can be headers
146 if ((indentCurrent
& SC_FOLDLEVELNUMBERMASK
) < (indentNext
& SC_FOLDLEVELNUMBERMASK
)) {
147 lev
|= SC_FOLDLEVELHEADERFLAG
;
148 } else if (indentNext
& SC_FOLDLEVELWHITEFLAG
) {
149 // Line after is blank so check the next - maybe should continue further?
151 int indentNext2
= styler
.IndentAmount(lineCurrent
+ 2, &spaceFlags2
, IsEiffelComment
);
152 if ((indentCurrent
& SC_FOLDLEVELNUMBERMASK
) < (indentNext2
& SC_FOLDLEVELNUMBERMASK
)) {
153 lev
|= SC_FOLDLEVELHEADERFLAG
;
157 indentCurrent
= indentNext
;
158 styler
.SetLevel(lineCurrent
, lev
);
164 static void FoldEiffelDocKeyWords(unsigned int startPos
, int length
, int /* initStyle */, WordList
*[],
166 unsigned int lengthDoc
= startPos
+ length
;
167 int visibleChars
= 0;
168 int lineCurrent
= styler
.GetLine(startPos
);
169 int levelPrev
= styler
.LevelAt(lineCurrent
) & SC_FOLDLEVELNUMBERMASK
;
170 int levelCurrent
= levelPrev
;
171 char chNext
= styler
[startPos
];
173 int styleNext
= styler
.StyleAt(startPos
);
174 // lastDeferred should be determined by looking back to last keyword in case
175 // the "deferred" is on a line before "class"
176 bool lastDeferred
= false;
177 for (unsigned int i
= startPos
; i
< lengthDoc
; i
++) {
179 chNext
= styler
.SafeGetCharAt(i
+ 1);
180 int style
= styleNext
;
181 styleNext
= styler
.StyleAt(i
+ 1);
182 bool atEOL
= (ch
== '\r' && chNext
!= '\n') || (ch
== '\n');
183 if ((stylePrev
!= SCE_EIFFEL_WORD
) && (style
== SCE_EIFFEL_WORD
)) {
186 while ((j
< (sizeof(s
) - 1)) && (iswordchar(styler
[i
+ j
]))) {
187 s
[j
] = styler
[i
+ j
];
193 (strcmp(s
, "check") == 0) ||
194 (strcmp(s
, "debug") == 0) ||
195 (strcmp(s
, "deferred") == 0) ||
196 (strcmp(s
, "do") == 0) ||
197 (strcmp(s
, "from") == 0) ||
198 (strcmp(s
, "if") == 0) ||
199 (strcmp(s
, "inspect") == 0) ||
200 (strcmp(s
, "once") == 0)
203 if (!lastDeferred
&& (strcmp(s
, "class") == 0))
205 if (strcmp(s
, "end") == 0)
207 lastDeferred
= strcmp(s
, "deferred") == 0;
212 if (visibleChars
== 0)
213 lev
|= SC_FOLDLEVELWHITEFLAG
;
214 if ((levelCurrent
> levelPrev
) && (visibleChars
> 0))
215 lev
|= SC_FOLDLEVELHEADERFLAG
;
216 if (lev
!= styler
.LevelAt(lineCurrent
)) {
217 styler
.SetLevel(lineCurrent
, lev
);
220 levelPrev
= levelCurrent
;
223 if (!isspacechar(ch
))
227 // Fill in the real level of the next line, keeping the current flags as they will be filled in later
228 int flagsNext
= styler
.LevelAt(lineCurrent
) & ~SC_FOLDLEVELNUMBERMASK
;
229 styler
.SetLevel(lineCurrent
, levelPrev
| flagsNext
);
232 static const char * const eiffelWordListDesc
[] = {
237 LexerModule
lmEiffel(SCLEX_EIFFEL
, ColouriseEiffelDoc
, "eiffel", FoldEiffelDocIndent
, eiffelWordListDesc
);
238 LexerModule
lmEiffelkw(SCLEX_EIFFELKW
, ColouriseEiffelDoc
, "eiffelkw", FoldEiffelDocKeyWords
, eiffelWordListDesc
);