]>
git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/LexLisp.cxx
1 // Scintilla source code edit control
4 ** Written by Alexey Yutkin.
6 // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
7 // The License.txt file describes the conditions under which this software may be distributed.
20 #include "Scintilla.h"
22 #include "StyleContext.h"
24 #define SCE_LISP_CHARACTER 29
25 #define SCE_LISP_MACRO 30
26 #define SCE_LISP_MACRO_DISPATCH 31
28 static inline bool isLispoperator(char ch
) {
29 if (isascii(ch
) && isalnum(ch
))
31 if (ch
== '\'' || ch
== '`' || ch
== '(' || ch
== ')' )
36 static inline bool isLispwordstart(char ch
) {
37 return isascii(ch
) && ch
!= ';' && !isspacechar(ch
) && !isLispoperator(ch
) &&
38 ch
!= '\n' && ch
!= '\r' && ch
!= '\"';
42 static void classifyWordLisp(unsigned int start
, unsigned int end
, WordList
&keywords
, WordList
&keywords_kw
, Accessor
&styler
) {
43 PLATFORM_ASSERT(end
>= start
);
46 bool digit_flag
= true;
47 for (i
= 0; (i
< end
- start
+ 1) && (i
< 99); i
++) {
48 s
[i
] = styler
[start
+ i
];
50 if (!isdigit(s
[i
]) && (s
[i
] != '.')) digit_flag
= false;
52 char chAttr
= SCE_LISP_IDENTIFIER
;
54 if(digit_flag
) chAttr
= SCE_LISP_NUMBER
;
56 if (keywords
.InList(s
)) {
57 chAttr
= SCE_LISP_KEYWORD
;
58 } else if (keywords_kw
.InList(s
)) {
59 chAttr
= SCE_LISP_KEYWORD_KW
;
60 } else if ((s
[0] == '*' && s
[i
-1] == '*') ||
61 (s
[0] == '+' && s
[i
-1] == '+')) {
62 chAttr
= SCE_LISP_SPECIAL
;
65 styler
.ColourTo(end
, chAttr
);
70 static void ColouriseLispDoc(unsigned int startPos
, int length
, int initStyle
, WordList
*keywordlists
[],
73 WordList
&keywords
= *keywordlists
[0];
74 WordList
&keywords_kw
= *keywordlists
[1];
76 styler
.StartAt(startPos
);
78 int state
= initStyle
, radix
= -1;
79 char chNext
= styler
[startPos
];
80 unsigned int lengthDoc
= startPos
+ length
;
81 styler
.StartSegment(startPos
);
82 for (unsigned int i
= startPos
; i
< lengthDoc
; i
++) {
84 chNext
= styler
.SafeGetCharAt(i
+ 1);
86 bool atEOL
= (ch
== '\r' && chNext
!= '\n') || (ch
== '\n');
88 if (styler
.IsLeadByte(ch
)) {
89 chNext
= styler
.SafeGetCharAt(i
+ 2);
94 if (state
== SCE_LISP_DEFAULT
) {
96 styler
.ColourTo(i
- 1, state
);
98 state
= SCE_LISP_MACRO_DISPATCH
;
99 } else if (isLispwordstart(ch
)) {
100 styler
.ColourTo(i
- 1, state
);
101 state
= SCE_LISP_IDENTIFIER
;
103 else if (ch
== ';') {
104 styler
.ColourTo(i
- 1, state
);
105 state
= SCE_LISP_COMMENT
;
107 else if (isLispoperator(ch
) || ch
=='\'') {
108 styler
.ColourTo(i
- 1, state
);
109 styler
.ColourTo(i
, SCE_LISP_OPERATOR
);
110 if (ch
=='\'' && isLispwordstart(chNext
)) {
111 state
= SCE_LISP_SYMBOL
;
114 else if (ch
== '\"') {
115 styler
.ColourTo(i
- 1, state
);
116 state
= SCE_LISP_STRING
;
118 } else if (state
== SCE_LISP_IDENTIFIER
|| state
== SCE_LISP_SYMBOL
) {
119 if (!isLispwordstart(ch
)) {
120 if (state
== SCE_LISP_IDENTIFIER
) {
121 classifyWordLisp(styler
.GetStartSegment(), i
- 1, keywords
, keywords_kw
, styler
);
123 styler
.ColourTo(i
- 1, state
);
125 state
= SCE_LISP_DEFAULT
;
127 if (isLispoperator(ch
) || ch
=='\'') {
128 styler
.ColourTo(i
- 1, state
);
129 styler
.ColourTo(i
, SCE_LISP_OPERATOR
);
130 if (ch
=='\'' && isLispwordstart(chNext
)) {
131 state
= SCE_LISP_SYMBOL
;
134 } else if (state
== SCE_LISP_MACRO_DISPATCH
) {
136 if (ch
!= 'r' && ch
!= 'R' && (i
- styler
.GetStartSegment()) > 1) {
137 state
= SCE_LISP_DEFAULT
;
140 case '|': state
= SCE_LISP_MULTI_COMMENT
; break;
142 case 'O': radix
= 8; state
= SCE_LISP_MACRO
; break;
144 case 'X': radix
= 16; state
= SCE_LISP_MACRO
; break;
146 case 'B': radix
= 2; state
= SCE_LISP_MACRO
; break;
147 case '\\': state
= SCE_LISP_CHARACTER
; break;
150 case '+': state
= SCE_LISP_MACRO
; break;
151 case '\'': if (isLispwordstart(chNext
)) {
152 state
= SCE_LISP_SPECIAL
;
154 styler
.ColourTo(i
- 1, SCE_LISP_DEFAULT
);
155 styler
.ColourTo(i
, SCE_LISP_OPERATOR
);
156 state
= SCE_LISP_DEFAULT
;
159 default: if (isLispoperator(ch
)) {
160 styler
.ColourTo(i
- 1, SCE_LISP_DEFAULT
);
161 styler
.ColourTo(i
, SCE_LISP_OPERATOR
);
163 state
= SCE_LISP_DEFAULT
;
168 } else if (state
== SCE_LISP_MACRO
) {
169 if (isLispwordstart(ch
) && (radix
== -1 || IsADigit(ch
, radix
))) {
170 state
= SCE_LISP_SPECIAL
;
172 state
= SCE_LISP_DEFAULT
;
174 } else if (state
== SCE_LISP_CHARACTER
) {
175 if (isLispoperator(ch
)) {
176 styler
.ColourTo(i
, SCE_LISP_SPECIAL
);
177 state
= SCE_LISP_DEFAULT
;
178 } else if (isLispwordstart(ch
)) {
179 styler
.ColourTo(i
, SCE_LISP_SPECIAL
);
180 state
= SCE_LISP_SPECIAL
;
182 state
= SCE_LISP_DEFAULT
;
184 } else if (state
== SCE_LISP_SPECIAL
) {
185 if (!isLispwordstart(ch
) || (radix
!= -1 && !IsADigit(ch
, radix
))) {
186 styler
.ColourTo(i
- 1, state
);
187 state
= SCE_LISP_DEFAULT
;
189 if (isLispoperator(ch
) || ch
=='\'') {
190 styler
.ColourTo(i
- 1, state
);
191 styler
.ColourTo(i
, SCE_LISP_OPERATOR
);
192 if (ch
=='\'' && isLispwordstart(chNext
)) {
193 state
= SCE_LISP_SYMBOL
;
197 if (state
== SCE_LISP_COMMENT
) {
199 styler
.ColourTo(i
- 1, state
);
200 state
= SCE_LISP_DEFAULT
;
202 } else if (state
== SCE_LISP_MULTI_COMMENT
) {
203 if (ch
== '|' && chNext
== '#') {
205 chNext
= styler
.SafeGetCharAt(i
+ 1);
206 styler
.ColourTo(i
, state
);
207 state
= SCE_LISP_DEFAULT
;
209 } else if (state
== SCE_LISP_STRING
) {
211 if (chNext
== '\"' || chNext
== '\'' || chNext
== '\\') {
213 chNext
= styler
.SafeGetCharAt(i
+ 1);
215 } else if (ch
== '\"') {
216 styler
.ColourTo(i
, state
);
217 state
= SCE_LISP_DEFAULT
;
223 styler
.ColourTo(lengthDoc
- 1, state
);
226 static void FoldLispDoc(unsigned int startPos
, int length
, int /* initStyle */, WordList
*[],
228 unsigned int lengthDoc
= startPos
+ length
;
229 int visibleChars
= 0;
230 int lineCurrent
= styler
.GetLine(startPos
);
231 int levelPrev
= styler
.LevelAt(lineCurrent
) & SC_FOLDLEVELNUMBERMASK
;
232 int levelCurrent
= levelPrev
;
233 char chNext
= styler
[startPos
];
234 int styleNext
= styler
.StyleAt(startPos
);
235 for (unsigned int i
= startPos
; i
< lengthDoc
; i
++) {
237 chNext
= styler
.SafeGetCharAt(i
+ 1);
238 int style
= styleNext
;
239 styleNext
= styler
.StyleAt(i
+ 1);
240 bool atEOL
= (ch
== '\r' && chNext
!= '\n') || (ch
== '\n');
241 if (style
== SCE_LISP_OPERATOR
) {
244 } else if (ch
== ')') {
250 if (visibleChars
== 0)
251 lev
|= SC_FOLDLEVELWHITEFLAG
;
252 if ((levelCurrent
> levelPrev
) && (visibleChars
> 0))
253 lev
|= SC_FOLDLEVELHEADERFLAG
;
254 if (lev
!= styler
.LevelAt(lineCurrent
)) {
255 styler
.SetLevel(lineCurrent
, lev
);
258 levelPrev
= levelCurrent
;
261 if (!isspacechar(ch
))
264 // Fill in the real level of the next line, keeping the current flags as they will be filled in later
265 int flagsNext
= styler
.LevelAt(lineCurrent
) & ~SC_FOLDLEVELNUMBERMASK
;
266 styler
.SetLevel(lineCurrent
, levelPrev
| flagsNext
);
269 static const char * const lispWordListDesc
[] = {
270 "Functions and special operators",
275 LexerModule
lmLISP(SCLEX_LISP
, ColouriseLispDoc
, "lisp", FoldLispDoc
, lispWordListDesc
);