]>
git.saurik.com Git - wxWidgets.git/blob - contrib/src/stc/scintilla/src/LexEiffel.cxx
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.
19 #include "StyleContext.h"
21 #include "Scintilla.h"
24 inline bool isEiffelOperator(unsigned int ch
) {
25 // '.' left out as it is used to make up numbers
26 return ch
== '*' || ch
== '/' || ch
== '\\' || ch
== '-' || ch
== '+' ||
27 ch
== '(' || ch
== ')' || ch
== '=' ||
28 ch
== '{' || ch
== '}' || ch
== '~' ||
29 ch
== '[' || ch
== ']' || ch
== ';' ||
30 ch
== '<' || ch
== '>' || ch
== ',' ||
31 ch
== '.' || ch
== '^' || ch
== '%' || ch
== ':' ||
32 ch
== '!' || ch
== '@' || ch
== '?';
35 inline bool IsAWordChar(unsigned int ch
) {
36 return (ch
< 0x80) && (isalnum(ch
) || ch
== '.' || ch
== '_');
39 inline bool IsAWordStart(unsigned int ch
) {
40 return (ch
< 0x80) && (isalnum(ch
) || ch
== '_');
43 static void ColouriseEiffelDoc(unsigned int startPos
,
46 WordList
*keywordlists
[],
49 WordList
&keywords
= *keywordlists
[0];
51 StyleContext
sc(startPos
, length
, initStyle
, styler
);
53 for (; sc
.More(); sc
.Forward()) {
55 if (sc
.state
== SCE_EIFFEL_STRINGEOL
) {
56 if (sc
.ch
!= '\r' && sc
.ch
!= '\n') {
57 sc
.SetState(SCE_EIFFEL_DEFAULT
);
59 } else if (sc
.state
== SCE_EIFFEL_OPERATOR
) {
60 sc
.SetState(SCE_EIFFEL_DEFAULT
);
61 } else if (sc
.state
== SCE_EIFFEL_WORD
) {
62 if (!IsAWordChar(sc
.ch
)) {
64 sc
.GetCurrentLowered(s
, sizeof(s
));
65 if (!keywords
.InList(s
)) {
66 sc
.ChangeState(SCE_EIFFEL_IDENTIFIER
);
68 sc
.SetState(SCE_EIFFEL_DEFAULT
);
70 } else if (sc
.state
== SCE_EIFFEL_NUMBER
) {
71 if (!IsAWordChar(sc
.ch
)) {
72 sc
.SetState(SCE_EIFFEL_DEFAULT
);
74 } else if (sc
.state
== SCE_EIFFEL_COMMENTLINE
) {
75 if (sc
.ch
== '\r' || sc
.ch
== '\n') {
76 sc
.SetState(SCE_EIFFEL_DEFAULT
);
78 } else if (sc
.state
== SCE_EIFFEL_STRING
) {
81 } else if (sc
.ch
== '\"') {
83 sc
.SetState(SCE_EIFFEL_DEFAULT
);
85 } else if (sc
.state
== SCE_EIFFEL_CHARACTER
) {
86 if (sc
.ch
== '\r' || sc
.ch
== '\n') {
87 sc
.SetState(SCE_EIFFEL_STRINGEOL
);
88 } else if (sc
.ch
== '%') {
90 } else if (sc
.ch
== '\'') {
92 sc
.SetState(SCE_EIFFEL_DEFAULT
);
96 if (sc
.state
== SCE_EIFFEL_DEFAULT
) {
97 if (sc
.ch
== '-' && sc
.chNext
== '-') {
98 sc
.SetState(SCE_EIFFEL_COMMENTLINE
);
99 } else if (sc
.ch
== '\"') {
100 sc
.SetState(SCE_EIFFEL_STRING
);
101 } else if (sc
.ch
== '\'') {
102 sc
.SetState(SCE_EIFFEL_CHARACTER
);
103 } else if (IsADigit(sc
.ch
) || (sc
.ch
== '.')) {
104 sc
.SetState(SCE_EIFFEL_NUMBER
);
105 } else if (IsAWordStart(sc
.ch
)) {
106 sc
.SetState(SCE_EIFFEL_WORD
);
107 } else if (isEiffelOperator(sc
.ch
)) {
108 sc
.SetState(SCE_EIFFEL_OPERATOR
);
115 static bool IsEiffelComment(Accessor
&styler
, int pos
, int len
) {
116 return len
>1 && styler
[pos
]=='-' && styler
[pos
+1]=='-';
119 static void FoldEiffelDocIndent(unsigned int startPos
, int length
, int,
120 WordList
*[], Accessor
&styler
) {
121 int lengthDoc
= startPos
+ length
;
123 // Backtrack to previous line in case need to fix its fold status
124 int lineCurrent
= styler
.GetLine(startPos
);
126 if (lineCurrent
> 0) {
128 startPos
= styler
.LineStart(lineCurrent
);
132 int indentCurrent
= styler
.IndentAmount(lineCurrent
, &spaceFlags
, IsEiffelComment
);
133 char chNext
= styler
[startPos
];
134 for (int i
= startPos
; i
< lengthDoc
; i
++) {
136 chNext
= styler
.SafeGetCharAt(i
+ 1);
138 if ((ch
== '\r' && chNext
!= '\n') || (ch
== '\n') || (i
== lengthDoc
)) {
139 int lev
= indentCurrent
;
140 int indentNext
= styler
.IndentAmount(lineCurrent
+ 1, &spaceFlags
, IsEiffelComment
);
141 if (!(indentCurrent
& SC_FOLDLEVELWHITEFLAG
)) {
142 // Only non whitespace lines can be headers
143 if ((indentCurrent
& SC_FOLDLEVELNUMBERMASK
) < (indentNext
& SC_FOLDLEVELNUMBERMASK
)) {
144 lev
|= SC_FOLDLEVELHEADERFLAG
;
145 } else if (indentNext
& SC_FOLDLEVELWHITEFLAG
) {
146 // Line after is blank so check the next - maybe should continue further?
148 int indentNext2
= styler
.IndentAmount(lineCurrent
+ 2, &spaceFlags2
, IsEiffelComment
);
149 if ((indentCurrent
& SC_FOLDLEVELNUMBERMASK
) < (indentNext2
& SC_FOLDLEVELNUMBERMASK
)) {
150 lev
|= SC_FOLDLEVELHEADERFLAG
;
154 indentCurrent
= indentNext
;
155 styler
.SetLevel(lineCurrent
, lev
);
161 static void FoldEiffelDocKeyWords(unsigned int startPos
, int length
, int /* initStyle */, WordList
*[],
163 unsigned int lengthDoc
= startPos
+ length
;
164 int visibleChars
= 0;
165 int lineCurrent
= styler
.GetLine(startPos
);
166 int levelPrev
= styler
.LevelAt(lineCurrent
) & SC_FOLDLEVELNUMBERMASK
;
167 int levelCurrent
= levelPrev
;
168 char chNext
= styler
[startPos
];
170 int styleNext
= styler
.StyleAt(startPos
);
171 // lastDeferred should be determined by looking back to last keyword in case
172 // the "deferred" is on a line before "class"
173 bool lastDeferred
= false;
174 for (unsigned int i
= startPos
; i
< lengthDoc
; i
++) {
176 chNext
= styler
.SafeGetCharAt(i
+ 1);
177 int style
= styleNext
;
178 styleNext
= styler
.StyleAt(i
+ 1);
179 bool atEOL
= (ch
== '\r' && chNext
!= '\n') || (ch
== '\n');
180 if ((stylePrev
!= SCE_EIFFEL_WORD
) && (style
== SCE_EIFFEL_WORD
)) {
183 while ((j
< (sizeof(s
) - 1)) && (iswordchar(styler
[i
+ j
]))) {
184 s
[j
] = styler
[i
+ j
];
190 (strcmp(s
, "check") == 0) ||
191 (strcmp(s
, "debug") == 0) ||
192 (strcmp(s
, "deferred") == 0) ||
193 (strcmp(s
, "do") == 0) ||
194 (strcmp(s
, "from") == 0) ||
195 (strcmp(s
, "if") == 0) ||
196 (strcmp(s
, "inspect") == 0) ||
197 (strcmp(s
, "once") == 0)
200 if (!lastDeferred
&& (strcmp(s
, "class") == 0))
202 if (strcmp(s
, "end") == 0)
204 lastDeferred
= strcmp(s
, "deferred") == 0;
209 if (visibleChars
== 0)
210 lev
|= SC_FOLDLEVELWHITEFLAG
;
211 if ((levelCurrent
> levelPrev
) && (visibleChars
> 0))
212 lev
|= SC_FOLDLEVELHEADERFLAG
;
213 if (lev
!= styler
.LevelAt(lineCurrent
)) {
214 styler
.SetLevel(lineCurrent
, lev
);
217 levelPrev
= levelCurrent
;
220 if (!isspacechar(ch
))
224 // Fill in the real level of the next line, keeping the current flags as they will be filled in later
225 int flagsNext
= styler
.LevelAt(lineCurrent
) & ~SC_FOLDLEVELNUMBERMASK
;
226 styler
.SetLevel(lineCurrent
, levelPrev
| flagsNext
);
229 LexerModule
lmEiffel(SCLEX_EIFFEL
, ColouriseEiffelDoc
, "eiffel", FoldEiffelDocIndent
);
230 LexerModule
lmEiffelkw(SCLEX_EIFFELKW
, ColouriseEiffelDoc
, "eiffelkw", FoldEiffelDocKeyWords
);