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"
24 static inline bool isLispoperator(char ch
) {
25 if (isascii(ch
) && isalnum(ch
))
27 if (ch
== '\'' || ch
== '(' || ch
== ')' )
32 static inline bool isLispwordstart(char ch
) {
33 return isascii(ch
) && ch
!= ';' && !isspacechar(ch
) && !isLispoperator(ch
) &&
34 ch
!= '\n' && ch
!= '\r' && ch
!= '\"';
38 static void classifyWordLisp(unsigned int start
, unsigned int end
, WordList
&keywords
, Accessor
&styler
) {
39 PLATFORM_ASSERT(end
>= start
);
42 bool digit_flag
= true;
43 for (i
= 0; (i
< end
- start
+ 1) && (i
< 99); i
++) {
44 s
[i
] = styler
[start
+ i
];
46 if (!isdigit(s
[i
]) && (s
[i
] != '.')) digit_flag
= false;
48 char chAttr
= SCE_LISP_IDENTIFIER
;
50 if(digit_flag
) chAttr
= SCE_LISP_NUMBER
;
52 if (keywords
.InList(s
)) {
53 chAttr
= SCE_LISP_KEYWORD
;
56 styler
.ColourTo(end
, chAttr
);
61 static void ColouriseLispDoc(unsigned int startPos
, int length
, int initStyle
, WordList
*keywordlists
[],
64 WordList
&keywords
= *keywordlists
[0];
66 styler
.StartAt(startPos
);
68 int state
= initStyle
;
69 char chNext
= styler
[startPos
];
70 unsigned int lengthDoc
= startPos
+ length
;
71 styler
.StartSegment(startPos
);
72 for (unsigned int i
= startPos
; i
< lengthDoc
; i
++) {
74 chNext
= styler
.SafeGetCharAt(i
+ 1);
76 bool atEOL
= (ch
== '\r' && chNext
!= '\n') || (ch
== '\n');
78 if (styler
.IsLeadByte(ch
)) {
79 chNext
= styler
.SafeGetCharAt(i
+ 2);
84 if (state
== SCE_LISP_DEFAULT
) {
85 if (isLispwordstart(ch
)) {
86 styler
.ColourTo(i
- 1, state
);
87 state
= SCE_LISP_IDENTIFIER
;
90 styler
.ColourTo(i
- 1, state
);
91 state
= SCE_LISP_COMMENT
;
93 else if (isLispoperator(ch
) || ch
=='\'') {
94 styler
.ColourTo(i
- 1, state
);
95 styler
.ColourTo(i
, SCE_LISP_OPERATOR
);
97 else if (ch
== '\"') {
98 styler
.ColourTo(i
- 1, state
);
99 state
= SCE_LISP_STRING
;
101 } else if (state
== SCE_LISP_IDENTIFIER
) {
102 if (!isLispwordstart(ch
)) {
103 classifyWordLisp(styler
.GetStartSegment(), i
- 1, keywords
, styler
);
104 state
= SCE_LISP_DEFAULT
;
106 if (isLispoperator(ch
) || ch
=='\'') {
107 styler
.ColourTo(i
- 1, state
);
108 styler
.ColourTo(i
, SCE_LISP_OPERATOR
);
112 if (state
== SCE_LISP_COMMENT
) {
114 styler
.ColourTo(i
- 1, state
);
115 state
= SCE_LISP_DEFAULT
;
117 } else if (state
== SCE_LISP_STRING
) {
119 if (chNext
== '\"' || chNext
== '\'' || chNext
== '\\') {
121 chNext
= styler
.SafeGetCharAt(i
+ 1);
123 } else if (ch
== '\"') {
124 styler
.ColourTo(i
, state
);
125 state
= SCE_LISP_DEFAULT
;
131 styler
.ColourTo(lengthDoc
- 1, state
);
134 static void FoldLispDoc(unsigned int startPos
, int length
, int /* initStyle */, WordList
*[],
136 unsigned int lengthDoc
= startPos
+ length
;
137 int visibleChars
= 0;
138 int lineCurrent
= styler
.GetLine(startPos
);
139 int levelPrev
= styler
.LevelAt(lineCurrent
) & SC_FOLDLEVELNUMBERMASK
;
140 int levelCurrent
= levelPrev
;
141 char chNext
= styler
[startPos
];
142 int styleNext
= styler
.StyleAt(startPos
);
143 for (unsigned int i
= startPos
; i
< lengthDoc
; i
++) {
145 chNext
= styler
.SafeGetCharAt(i
+ 1);
146 int style
= styleNext
;
147 styleNext
= styler
.StyleAt(i
+ 1);
148 bool atEOL
= (ch
== '\r' && chNext
!= '\n') || (ch
== '\n');
149 if (style
== SCE_LISP_OPERATOR
) {
152 } else if (ch
== ')') {
158 if (visibleChars
== 0)
159 lev
|= SC_FOLDLEVELWHITEFLAG
;
160 if ((levelCurrent
> levelPrev
) && (visibleChars
> 0))
161 lev
|= SC_FOLDLEVELHEADERFLAG
;
162 if (lev
!= styler
.LevelAt(lineCurrent
)) {
163 styler
.SetLevel(lineCurrent
, lev
);
166 levelPrev
= levelCurrent
;
169 if (!isspacechar(ch
))
172 // Fill in the real level of the next line, keeping the current flags as they will be filled in later
173 int flagsNext
= styler
.LevelAt(lineCurrent
) & ~SC_FOLDLEVELNUMBERMASK
;
174 styler
.SetLevel(lineCurrent
, levelPrev
| flagsNext
);
177 static const char * const lispWordListDesc
[] = {
182 LexerModule
lmLISP(SCLEX_LISP
, ColouriseLispDoc
, "lisp", FoldLispDoc
, lispWordListDesc
);