]>
git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/LexR.cxx
67e779f55f779eef47a3f3189c3e128a169a38a9
1 // Scintilla source code edit control
3 ** Lexer for R, S, SPlus Statistics Program (Heavily derived from CPP Lexer).
6 // Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
7 // The License.txt file describes the conditions under which this software may be distributed.
19 #include "StyleContext.h"
21 #include "Scintilla.h"
25 using namespace Scintilla
;
28 static inline bool IsAWordChar(const int ch
) {
29 return (ch
< 0x80) && (isalnum(ch
) || ch
== '.' || ch
== '_');
32 static inline bool IsAWordStart(const int ch
) {
33 return (ch
< 0x80) && (isalnum(ch
) || ch
== '_');
36 static inline bool IsAnOperator(const int ch
) {
37 if (isascii(ch
) && isalnum(ch
))
39 // '.' left out as it is used to make up numbers
40 if (ch
== '-' || ch
== '+' || ch
== '!' || ch
== '~' ||
41 ch
== '?' || ch
== ':' || ch
== '*' || ch
== '/' ||
42 ch
== '^' || ch
== '<' || ch
== '>' || ch
== '=' ||
43 ch
== '&' || ch
== '|' || ch
== '$' || ch
== '(' ||
44 ch
== ')' || ch
== '}' || ch
== '{' || ch
== '[' ||
50 static void ColouriseRDoc(unsigned int startPos
, int length
, int initStyle
, WordList
*keywordlists
[],
53 WordList
&keywords
= *keywordlists
[0];
54 WordList
&keywords2
= *keywordlists
[1];
55 WordList
&keywords3
= *keywordlists
[2];
58 // Do not leak onto next line
59 if (initStyle
== SCE_R_INFIXEOL
)
60 initStyle
= SCE_R_DEFAULT
;
63 StyleContext
sc(startPos
, length
, initStyle
, styler
);
65 for (; sc
.More(); sc
.Forward()) {
67 if (sc
.atLineStart
&& (sc
.state
== SCE_R_STRING
)) {
68 // Prevent SCE_R_STRINGEOL from leaking back to previous line
69 sc
.SetState(SCE_R_STRING
);
72 // Determine if the current state should terminate.
73 if (sc
.state
== SCE_R_OPERATOR
) {
74 sc
.SetState(SCE_R_DEFAULT
);
75 } else if (sc
.state
== SCE_R_NUMBER
) {
76 if (!IsADigit(sc
.ch
) && !(sc
.ch
== '.' && IsADigit(sc
.chNext
))) {
77 sc
.SetState(SCE_R_DEFAULT
);
79 } else if (sc
.state
== SCE_R_IDENTIFIER
) {
80 if (!IsAWordChar(sc
.ch
) || (sc
.ch
== '.')) {
82 sc
.GetCurrentLowered(s
, sizeof(s
));
83 if (keywords
.InList(s
)) {
84 sc
.ChangeState(SCE_R_KWORD
);
85 } else if (keywords2
.InList(s
)) {
86 sc
.ChangeState(SCE_R_BASEKWORD
);
87 } else if (keywords3
.InList(s
)) {
88 sc
.ChangeState(SCE_R_OTHERKWORD
);
90 sc
.SetState(SCE_R_DEFAULT
);
92 } else if (sc
.state
== SCE_R_COMMENT
) {
93 if (sc
.ch
== '\r' || sc
.ch
== '\n') {
94 sc
.SetState(SCE_R_DEFAULT
);
96 } else if (sc
.state
== SCE_R_STRING
) {
98 if (sc
.chNext
== '\"' || sc
.chNext
== '\'' || sc
.chNext
== '\\') {
101 } else if (sc
.ch
== '\"') {
102 sc
.ForwardSetState(SCE_R_DEFAULT
);
104 } else if (sc
.state
== SCE_R_INFIX
) {
106 sc
.ForwardSetState(SCE_R_DEFAULT
);
107 } else if (sc
.atLineEnd
) {
108 sc
.ChangeState(SCE_R_INFIXEOL
);
109 sc
.ForwardSetState(SCE_R_DEFAULT
);
111 }else if (sc
.state
== SCE_R_STRING2
) {
113 if (sc
.chNext
== '\"' || sc
.chNext
== '\'' || sc
.chNext
== '\\') {
116 } else if (sc
.ch
== '\'') {
117 sc
.ForwardSetState(SCE_R_DEFAULT
);
121 // Determine if a new state should be entered.
122 if (sc
.state
== SCE_R_DEFAULT
) {
123 if (IsADigit(sc
.ch
) || (sc
.ch
== '.' && IsADigit(sc
.chNext
))) {
124 sc
.SetState(SCE_R_NUMBER
);
125 } else if (IsAWordStart(sc
.ch
) ) {
126 sc
.SetState(SCE_R_IDENTIFIER
);
127 } else if (sc
.Match('#')) {
128 sc
.SetState(SCE_R_COMMENT
);
129 } else if (sc
.ch
== '\"') {
130 sc
.SetState(SCE_R_STRING
);
131 } else if (sc
.ch
== '%') {
132 sc
.SetState(SCE_R_INFIX
);
133 } else if (sc
.ch
== '\'') {
134 sc
.SetState(SCE_R_STRING2
);
135 } else if (IsAnOperator(sc
.ch
)) {
136 sc
.SetState(SCE_R_OPERATOR
);
143 // Store both the current line's fold level and the next lines in the
144 // level store to make it easy to pick up with each increment
145 // and to make it possible to fiddle the current level for "} else {".
146 static void FoldRDoc(unsigned int startPos
, int length
, int, WordList
*[],
148 bool foldCompact
= styler
.GetPropertyInt("fold.compact", 1) != 0;
149 bool foldAtElse
= styler
.GetPropertyInt("fold.at.else", 0) != 0;
150 unsigned int endPos
= startPos
+ length
;
151 int visibleChars
= 0;
152 int lineCurrent
= styler
.GetLine(startPos
);
153 int levelCurrent
= SC_FOLDLEVELBASE
;
155 levelCurrent
= styler
.LevelAt(lineCurrent
-1) >> 16;
156 int levelMinCurrent
= levelCurrent
;
157 int levelNext
= levelCurrent
;
158 char chNext
= styler
[startPos
];
159 int styleNext
= styler
.StyleAt(startPos
);
160 for (unsigned int i
= startPos
; i
< endPos
; i
++) {
162 chNext
= styler
.SafeGetCharAt(i
+ 1);
163 int style
= styleNext
;
164 styleNext
= styler
.StyleAt(i
+ 1);
165 bool atEOL
= (ch
== '\r' && chNext
!= '\n') || (ch
== '\n');
166 if (style
== SCE_R_OPERATOR
) {
168 // Measure the minimum before a '{' to allow
169 // folding on "} else {"
170 if (levelMinCurrent
> levelNext
) {
171 levelMinCurrent
= levelNext
;
174 } else if (ch
== '}') {
179 int levelUse
= levelCurrent
;
181 levelUse
= levelMinCurrent
;
183 int lev
= levelUse
| levelNext
<< 16;
184 if (visibleChars
== 0 && foldCompact
)
185 lev
|= SC_FOLDLEVELWHITEFLAG
;
186 if (levelUse
< levelNext
)
187 lev
|= SC_FOLDLEVELHEADERFLAG
;
188 if (lev
!= styler
.LevelAt(lineCurrent
)) {
189 styler
.SetLevel(lineCurrent
, lev
);
192 levelCurrent
= levelNext
;
193 levelMinCurrent
= levelCurrent
;
196 if (!isspacechar(ch
))
202 static const char * const RWordLists
[] = {
204 "Base / Default package function",
205 "Other Package Functions",
213 LexerModule
lmR(SCLEX_R
, ColouriseRDoc
, "r", FoldRDoc
, RWordLists
);